subport.c (132539B)
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: subport.c 8 * Purpose: XGS5 Subport CoE common driver. 9 */ 10 11 #include <soc/defs.h> 12 13 #include <shared/bsl.h> 14 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 15 16 #include <soc/drv.h> 17 #include <soc/scache_dictionary.h> 18 #include <soc/debug.h> 19 #include <soc/trident2.h> 20 #include <soc/td2_td2p.h> 21 #include <soc/bondoptions.h> 22 #include <bcm_int/esw/subport.h> 23 #include <bcm_int/esw/xgs5.h> 24 #include <bcm_int/esw/xgs3.h> 25 #include <bcm_int/esw/port.h> 26 #include <bcm_int/esw/stack.h> 27 #include <bcm_int/esw/trident2plus.h> 28 #include <bcm_int/esw_dispatch.h> 29 #include <bcm_int/esw/xgs5.h> 30 #include <bcm/error.h> 31 #include <bcm/debug.h> 32 #include <bcm_int/esw/firebolt.h> 33 #include <bcm_int/esw/vlan.h> 34 #include <bcm_int/esw/trx.h> 35 #include <bcm_int/esw/triumph.h> 36 #include <bcm_int/esw/triumph2.h> 37 #define BCMI_MAX_SHORT_VALUE 65535 38 39 /* 40 * SUBPORT HW Definition Table 41 */ 42 static bcmi_xgs5_subport_coe_hw_defs_t *bcmi_xgs5_subport_coe_hw_defs[BCM_MAX_NUM_UNITS] = {0}; 43 44 #define SUBPORT_COE_HW(u_) (bcmi_xgs5_subport_coe_hw_defs[(u_)]) 45 46 #define SUBPORT_COE_HW_ING_PORT(u_) \ 47 (bcmi_xgs5_subport_coe_hw_defs[(u_)]->igr_port) 48 #define SUBPORT_COE_HW_EGR_PORT(u_) \ 49 (bcmi_xgs5_subport_coe_hw_defs[(u_)]->egr_port) 50 #define SUBPORT_COE_HW_MODPORT_MAP_SUBPORT(u_) \ 51 (bcmi_xgs5_subport_coe_hw_defs[(u_)]->modport_map_subport) 52 #define SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(u_) \ 53 (bcmi_xgs5_subport_coe_hw_defs[(u_)]->subport_tag_sgpp) 54 #define SUBPORT_COE_HW_EGR_SUBPORT_TAG_DOT1P(u_) \ 55 (bcmi_xgs5_subport_coe_hw_defs[(u_)]->egr_subport_tag_dot1p) 56 57 #define SUBPORT_COE_HW_ING_PORT_MEM(u_) \ 58 (SUBPORT_COE_HW_ING_PORT(u_)->mem) 59 #define SUBPORT_COE_HW_EGR_PORT_MEM(u_) \ 60 (SUBPORT_COE_HW_EGR_PORT(u_)->mem) 61 #define SUBPORT_COE_HW_MODPORT_MAP_SUBPORT_MEM(u_) \ 62 (SUBPORT_COE_HW_MODPORT_MAP_SUBPORT(u_)->mem) 63 #define SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP_MEM(u_) \ 64 (SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(u_)->mem) 65 #define SUBPORT_COE_HW_EGR_SUBPORT_TAG_DOT1P_MEM(u_) \ 66 (SUBPORT_COE_HW_EGR_SUBPORT_TAG_DOT1P(u_)->mem) 67 68 #define BCM_FAILURE_CLEANUP(rv, label) \ 69 do { if (SOC_FAILURE(rv)) { goto label; } } while(0) 70 71 72 STATIC int _bcm_subport_coe_port_count[BCM_MAX_NUM_UNITS] = { 0 }; 73 74 STATIC int 75 bcmi_xgs5_subtag_subport_init(int unit) 76 { 77 bcm_port_t port; 78 int num_vlan = 0, index = 0; 79 soc_info_t *si = &SOC_INFO(unit); 80 BCM_IF_ERROR_RETURN 81 (soc_mem_clear(unit, SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP_MEM(unit), 82 COPYNO_ALL, TRUE)); 83 num_vlan = soc_mem_index_count(unit, VLAN_TABm); 84 85 BCM_PBMP_ITER(si->subtag_allowed_pbm, port) { 86 87 if (port < SOC_MAX_NUM_PORTS) { 88 89 /* SubTag VLAN ID bitmap to keep track of the VLAN ID used per 90 * SubTag enabled port. 91 */ 92 if (_bcm_subtag_vlan_id_bitmap[unit][port] == NULL) { 93 94 _bcm_subtag_vlan_id_bitmap[unit][port] = 95 sal_alloc(SHR_BITALLOCSIZE(num_vlan), 96 "_bcm_subtag_vlan_id_bitmap"); 97 98 if (_bcm_subtag_vlan_id_bitmap[unit][port] == NULL) { 99 LOG_ERROR(BSL_LS_BCM_SUBPORT, 100 (BSL_META_U(unit,"ERROR:_bcm_subtag_vlan_id_bitmap " 101 " alloc failed\n"))); 102 103 return BCM_E_MEMORY; 104 } 105 } 106 sal_memset(_bcm_subtag_vlan_id_bitmap[unit][port], 0, 107 SHR_BITALLOCSIZE(num_vlan)); 108 } 109 } 110 111 /* SubTag subport group bitmap to keep track of used SubTag groups */ 112 if (_bcm_subtag_group_bitmap[unit] == NULL) { 113 114 _bcm_subtag_group_bitmap[unit] = 115 sal_alloc(SHR_BITALLOCSIZE(si->max_subport_coe_groups), 116 "subtag_subport_group_bitmap"); 117 118 if (_bcm_subtag_group_bitmap[unit] == NULL) { 119 LOG_ERROR(BSL_LS_BCM_SUBPORT, 120 (BSL_META_U(unit,"ERROR:subtag group bitmap " 121 "alloc failed\n"))); 122 123 return BCM_E_MEMORY; 124 } 125 } 126 127 sal_memset(_bcm_subtag_group_bitmap[unit], 0, 128 SHR_BITALLOCSIZE(si->max_subport_coe_groups)); 129 130 /* SubTag subport port info per subport group per subport port */ 131 if (_bcm_subtag_subport_port_info[unit] == NULL) { 132 _bcm_subtag_subport_port_info[unit] = 133 sal_alloc((si->max_subport_coe_ports * 134 sizeof(_bcm_subtag_subport_port_info_t)), 135 "subtag_subport_port_info"); 136 if (_bcm_subtag_subport_port_info[unit] == NULL) { 137 LOG_ERROR(BSL_LS_BCM_SUBPORT, 138 (BSL_META_U(unit,"ERROR: " 139 " subtag_subport_port_info alloc failed\n"))); 140 141 return BCM_E_MEMORY; 142 } 143 } 144 145 for (index = 0; index < si->max_subport_coe_ports; index++) { 146 _bcm_subtag_subport_port_info[unit][index].group = BCM_GPORT_INVALID; 147 _bcm_subtag_subport_port_info[unit][index].vlan = BCM_VLAN_INVALID; 148 _bcm_subtag_subport_port_info[unit][index].subtag_tcam_hw_idx = -1; 149 _bcm_subtag_subport_port_info[unit][index].subport_modport = -1; 150 _bcm_subtag_subport_port_info[unit][index].subport_port = -1; 151 _bcm_subtag_subport_port_info[unit][index].nh_index = -1; 152 _bcm_subtag_subport_port_info[unit][index].valid = 0; 153 _bcm_subtag_subport_port_info[unit][index].modport_subport_idx = 0; 154 _bcm_subtag_subport_port_info[unit][index].phb_valid = 0; 155 _bcm_subtag_subport_port_info[unit][index].priority = 0; 156 _bcm_subtag_subport_port_info[unit][index].color = 0; 157 } 158 /* Set the Ingress/Egress EtherTypes to a specific default */ 159 BCM_IF_ERROR_RETURN(bcmi_xgs5_subport_coe_ether_type_size_set( 160 unit, bcmSwitchSubportCoEEtherType, 161 BCM_SUBPORT_COE_DEFAULT_ETHERTYPE)); 162 BCM_IF_ERROR_RETURN(bcmi_xgs5_subport_coe_ether_type_size_set( 163 unit, bcmSwitchSubportEgressTpid, 164 BCM_SUBPORT_COE_DEFAULT_ETHERTYPE)); 165 BCM_IF_ERROR_RETURN(bcmi_xgs5_subport_coe_ether_type_size_set( 166 unit, bcmSwitchSubportEgressWideTpid, 167 BCM_SUBPORT_COE_DEFAULT_ETHERTYPE)); 168 return BCM_E_NONE; 169 } 170 171 STATIC void 172 bcmi_xgs5_subport_free_resource(int unit) 173 { 174 bcm_port_t port; 175 176 if(_bcm_subport_group_bitmap[unit] != NULL) { 177 sal_free(_bcm_subport_group_bitmap[unit]); 178 _bcm_subport_group_bitmap[unit] = NULL; 179 } 180 181 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 182 183 if(_bcm_subtag_group_bitmap[unit] != NULL) { 184 sal_free(_bcm_subtag_group_bitmap[unit]); 185 _bcm_subtag_group_bitmap[unit] = NULL; 186 } 187 188 if (_bcm_subtag_subport_port_info[unit] != NULL) { 189 sal_free(_bcm_subtag_subport_port_info[unit]); 190 _bcm_subtag_subport_port_info[unit] = NULL; 191 } 192 193 if (BCM_PBMP_NOT_NULL(SOC_INFO(unit).subtag_allowed_pbm)) { 194 BCM_PBMP_ITER(SOC_INFO(unit).subtag_allowed_pbm, port) { 195 /* check to fix coverity static overrun error */ 196 if (port < SOC_MAX_NUM_PORTS) { 197 if (_bcm_subtag_vlan_id_bitmap[unit][port] != NULL) { 198 sal_free(_bcm_subtag_vlan_id_bitmap[unit][port]); 199 _bcm_subtag_vlan_id_bitmap[unit][port] = NULL; 200 } 201 } 202 } 203 } 204 205 } /* end of soc_feature_hgproxy_subtag_coe */ 206 207 if (_bcm_subport_group_subport_port_count[unit] != NULL) { 208 sal_free(_bcm_subport_group_subport_port_count[unit]); 209 _bcm_subport_group_subport_port_count[unit] = NULL; 210 } 211 212 if (_bcm_subport_mutex[unit] != NULL) { 213 sal_mutex_destroy(_bcm_subport_mutex[unit]); 214 _bcm_subport_mutex[unit] = NULL; 215 } 216 217 } 218 219 /* 220 * Function: 221 * bcmi_xgs5_subport_init 222 * Purpose: 223 * Initialize the Subport subsystem 224 * Parameters: 225 * unit - (IN) Unit number. 226 * Returns: 227 * int - Result of init 228 */ 229 int 230 bcmi_xgs5_subport_init(int unit, 231 bcm_esw_subport_drv_t *drv, 232 bcmi_xgs5_subport_coe_hw_defs_t *hw_defs) 233 { 234 int rv = BCM_E_NONE; 235 236 #ifdef BCM_HGPROXY_COE_SUPPORT 237 soc_info_t *si = &SOC_INFO(unit); 238 #endif 239 240 /* Do this only for the Newer CoE implementations */ 241 #ifdef BCM_HGPROXY_COE_SUPPORT 242 243 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 244 245 /* Subport group bitmap to keep track of used subport groups */ 246 if (_bcm_subport_group_bitmap[unit] == NULL) { 247 248 _bcm_subport_group_bitmap[unit] = 249 sal_alloc(SHR_BITALLOCSIZE(si->max_subport_coe_groups), 250 "subport_group_bitmap"); 251 252 if (_bcm_subport_group_bitmap[unit] == NULL) { 253 LOG_ERROR(BSL_LS_BCM_SUBPORT, 254 (BSL_META_U(unit,"ERROR:subport_init: group bitmap " 255 "alloc failed\n"))); 256 257 bcmi_xgs5_subport_free_resource(unit); 258 259 return BCM_E_MEMORY; 260 } 261 262 } 263 264 sal_memset(_bcm_subport_group_bitmap[unit], 0, 265 SHR_BITALLOCSIZE(si->max_subport_coe_groups)); 266 267 _bcm_subport_group_count[unit] = 0; 268 269 /* Keep Count of subport port created per subport group */ 270 if (_bcm_subport_group_subport_port_count[unit] == NULL) { 271 _bcm_subport_group_subport_port_count[unit] = 272 sal_alloc((si->max_subport_coe_groups * sizeof(int)), 273 "subport_group_subport_port_count"); 274 if (_bcm_subport_group_subport_port_count[unit] == NULL) { 275 LOG_ERROR(BSL_LS_BCM_SUBPORT, 276 (BSL_META_U(unit,"ERROR: " 277 "subport_group_subport_port_count alloc failed\n"))); 278 279 return BCM_E_MEMORY; 280 } 281 } 282 283 sal_memset(_bcm_subport_group_subport_port_count[unit], 0, 284 (si->max_subport_coe_groups * sizeof(int))); 285 286 /* Subtag CoE subport initialization */ 287 288 if(hw_defs) { 289 SUBPORT_COE_HW(unit) = hw_defs; 290 } 291 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 292 BCM_PBMP_NOT_NULL(si->subtag_allowed_pbm)) { 293 rv = bcmi_xgs5_subtag_subport_init(unit); 294 if (SOC_FAILURE(rv)) { 295 LOG_ERROR(BSL_LS_BCM_SUBPORT, 296 (BSL_META_U(unit,"ERROR: SubTag init failed.\n"))); 297 298 bcmi_xgs5_subport_free_resource(unit); 299 return rv; 300 } 301 } 302 303 _bcm_subport_coe_port_count[unit] = 0; 304 305 /* Create subport mutex */ 306 if (NULL == _bcm_subport_mutex[unit]) { 307 _bcm_subport_mutex[unit] = 308 sal_mutex_create("subtag subport mutex"); 309 310 if (_bcm_subport_mutex[unit] == NULL) { 311 LOG_ERROR(BSL_LS_BCM_SUBPORT, 312 (BSL_META_U(unit,"ERROR:subtag subport mutex " 313 "create failed\n"))); 314 315 return BCM_E_MEMORY; 316 } 317 } 318 } 319 320 #ifdef BCM_WARM_BOOT_SUPPORT 321 if(SOC_WARM_BOOT(unit)) { 322 rv = _bcmi_xgs5_subport_reinit(unit); 323 if (rv != BCM_E_NONE) { 324 } 325 } 326 #endif /* BCM_WARM_BOOT_SUPPORT */ 327 328 329 #endif 330 331 /* Install Tables */ 332 /* If a driver is not assigned already, assign the driver */ 333 if(BCM_ESW_SUBPORT_DRV(unit) == NULL) { 334 BCM_ESW_SUBPORT_DRV(unit) = drv; 335 } 336 337 return BCM_E_NONE; 338 } 339 340 int _bcmi_xgs5_subport_reinit(int unit) 341 { 342 343 return 0; 344 } 345 346 int _bcm_coe_subtag_subport_port_get(int unit, 347 bcm_gport_t subport_port_gport, 348 bcm_subport_config_t *config) 349 { 350 bcm_gport_t subport_group; 351 int i = 0; 352 soc_info_t *si = &SOC_INFO(unit); 353 354 if (config == NULL) { 355 return BCM_E_PARAM; 356 } 357 358 if(_bcm_subtag_subport_port_info[unit] == NULL) { 359 return BCM_E_NOT_FOUND; 360 } 361 362 /* Check if the passed in port is of 'subtag' type */ 363 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, subport_port_gport)) { 364 365 /* Find the entry corresponding to the subport */ 366 for (i=0; i < si->max_subport_coe_ports; i++) { 367 if((_bcm_subtag_subport_port_info[unit][i].valid) && 368 (_bcm_subtag_subport_port_info[unit][i].subport_port == 369 subport_port_gport)) { 370 /* Entry found, break */ 371 break; 372 } 373 } 374 375 /* Flag error if subport not found */ 376 if(i == si->max_subport_coe_ports) { 377 LOG_VERBOSE(BSL_LS_BCM_SUBPORT, 378 (BSL_META_U(unit, "ERROR:Invalid SubTag subport" 379 " port gport 0x%x\n"), 380 subport_port_gport)); 381 return BCM_E_NOT_FOUND; 382 } 383 384 /* Get the group id and ensure it is valid */ 385 subport_group = _bcm_subtag_subport_port_info[unit][i].group; 386 387 if (!BCM_GPORT_IS_SUBPORT_GROUP(subport_group)) { 388 LOG_VERBOSE(BSL_LS_BCM_SUBPORT, 389 (BSL_META_U(unit, "ERROR:Invalid SubTag subport" 390 " group gport 0x%x\n"), 391 subport_port_gport)); 392 return BCM_E_PARAM; 393 } 394 395 /* Fill in needed data */ 396 config->group = subport_group; 397 config->pkt_vlan = 398 _bcm_subtag_subport_port_info[unit][i].vlan; 399 /* Put togethe the CoE (mod,port) associated with this subtag */ 400 config->subport_modport = 401 _bcm_subtag_subport_port_info[unit][i].subport_modport; 402 403 /* Fill in the PHB data */ 404 if(_bcm_subtag_subport_port_info[unit][i].phb_valid) { 405 config->prop_flags |= BCM_SUBPORT_PROPERTY_PHB; 406 config->int_pri = 407 _bcm_subtag_subport_port_info[unit][i].priority; 408 config->color = 409 _bcm_subtag_subport_port_info[unit][i].color; 410 } else { 411 config->prop_flags &= ~BCM_SUBPORT_PROPERTY_PHB; 412 config->int_pri = 0; 413 config->color = 0; 414 } 415 } else { 416 return BCM_E_PARAM; 417 } 418 419 return BCM_E_NONE; 420 } 421 422 423 int bcmi_xgs5_subport_coe_port_get(int unit, 424 bcm_gport_t subport_port_gport, 425 bcm_subport_config_t *config) 426 { 427 int rv = BCM_E_NONE; 428 429 if (config == NULL) { 430 return BCM_E_PARAM; 431 } 432 433 _BCM_SUBPORT_COE_CHECK_INIT(unit); 434 435 if (!BCM_GPORT_IS_SUBPORT_PORT(subport_port_gport)) { 436 LOG_ERROR(BSL_LS_BCM_SUBPORT, 437 (BSL_META_U(unit,"ERROR: gport 0x%x is not " 438 "subport port gport\n"), 439 subport_port_gport)); 440 return BCM_E_PARAM; 441 } 442 443 _BCM_SUBPORT_COE_LOCK(unit); 444 445 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 446 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, subport_port_gport)) { 447 rv = _bcm_coe_subtag_subport_port_get(unit, 448 subport_port_gport, config); 449 } 450 451 if (SOC_FAILURE(rv)) { 452 LOG_VERBOSE(BSL_LS_BCM_SUBPORT, 453 (BSL_META_U(unit, "ERROR: Subport port 0x%x " 454 "get failed. rv=%d(%s)\n"), 455 subport_port_gport, rv, soc_errmsg(rv))); 456 _BCM_SUBPORT_COE_UNLOCK(unit); 457 return rv; 458 } 459 460 _BCM_SUBPORT_COE_UNLOCK(unit); 461 462 return BCM_E_NONE; 463 } 464 465 /* 466 * Function: 467 * _bcm_coe_subtag_subport_default_lport_entry_set 468 * Purpose: 469 * Add a deafult lport entry for this Source Trunk Map entry 470 * Parameters: 471 * unit - (IN) Device Number 472 * port - (IN) Physical port which this coe port belong to 473 * stm_index - (IN) Source Trunk Map Index to update the LPORT at 474 * Returns: 475 * BCM_E_XXX 476 */ 477 478 STATIC int 479 _bcm_coe_subtag_subport_default_lport_entry_set(int unit, bcm_port_t port, 480 int stm_index) 481 { 482 source_trunk_map_table_entry_t stm_entry; 483 lport_tab_entry_t lport_entry; 484 void *entries[1]; 485 uint32 lport_index; 486 int key_type_value = 0; 487 int value; 488 int rv = BCM_E_NONE; 489 490 sal_memcpy(&lport_entry, soc_mem_entry_null(unit, LPORT_TABm), 491 soc_mem_entry_words(unit, LPORT_TABm) * sizeof(uint32)); 492 493 /* Inherrit the default properties from its cascaded port*/ 494 495 /* Enable outer_tpid_enable */ 496 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, OUTER_TPID_ENABLEf)) { 497 soc_LPORT_TABm_field32_set(unit, &lport_entry, OUTER_TPID_ENABLEf, 1); 498 } 499 500 /* Switching VLAN. */ 501 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, OUTER_TPIDf)) { 502 soc_LPORT_TABm_field32_set(unit, &lport_entry, OUTER_TPIDf, 0x8100); 503 } 504 505 /* Set default vlan id(pvid) for port. */ 506 soc_LPORT_TABm_field32_set(unit, &lport_entry, PORT_VIDf, BCM_VLAN_DEFAULT); 507 508 /* Enable mac based vlan classification. */ 509 soc_LPORT_TABm_field32_set(unit, &lport_entry, MAC_BASED_VID_ENABLEf, 1); 510 511 /* Enable subnet based vlan classification. */ 512 soc_LPORT_TABm_field32_set(unit, &lport_entry, SUBNET_BASED_VID_ENABLEf, 1); 513 514 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, TRUST_INCOMING_VIDf)) { 515 soc_LPORT_TABm_field32_set(unit, &lport_entry, TRUST_INCOMING_VIDf, 1); 516 517 /* Set identify mapping for pri/cfi re-mapping */ 518 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, PRI_MAPPINGf)) { 519 soc_LPORT_TABm_field32_set(unit, &lport_entry, PRI_MAPPINGf, 0xfac688); 520 soc_LPORT_TABm_field32_set(unit, &lport_entry, CFI_0_MAPPINGf, 0); 521 soc_LPORT_TABm_field32_set(unit, &lport_entry, CFI_1_MAPPINGf, 1); 522 } 523 524 /* Set identify mapping for ipri/icfi re-mapping */ 525 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, IPRI_MAPPINGf)) { 526 soc_LPORT_TABm_field32_set(unit, &lport_entry, IPRI_MAPPINGf, 0xfac688); 527 soc_LPORT_TABm_field32_set(unit, &lport_entry, ICFI_0_MAPPINGf, 0); 528 soc_LPORT_TABm_field32_set(unit, &lport_entry, ICFI_1_MAPPINGf, 1); 529 } 530 531 /* Set the CML to PVP_CML_SWITCH by default (hw learn and forward) */ 532 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, CML_FLAGS_NEWf)) { 533 soc_LPORT_TABm_field32_set(unit, &lport_entry, CML_FLAGS_NEWf, 0x8); 534 soc_LPORT_TABm_field32_set(unit, &lport_entry, CML_FLAGS_MOVEf, 0x8); 535 } 536 /* Set first VLAN_XLATE key-type to {outer,port}. 537 * Set second VLAN_XLATE key-type to {inner,port}. 538 */ 539 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, VT_KEY_TYPEf)) { 540 BCM_IF_ERROR_RETURN 541 (_bcm_esw_pt_vtkey_type_value_get(unit, 542 VLXLT_HASH_KEY_TYPE_OVID, &key_type_value)); 543 soc_LPORT_TABm_field32_set(unit, &lport_entry, VT_KEY_TYPEf, 544 key_type_value); 545 } 546 547 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, VT_KEY_TYPE_USE_GLPf)) { 548 soc_LPORT_TABm_field32_set(unit, &lport_entry, VT_KEY_TYPE_USE_GLPf, 1); 549 } 550 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, VT_PORT_TYPE_SELECTf)) { 551 soc_LPORT_TABm_field32_set(unit, &lport_entry, VT_PORT_TYPE_SELECTf, 1); 552 } 553 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, VT_KEY_TYPE_2f)) { 554 BCM_IF_ERROR_RETURN 555 (_bcm_esw_pt_vtkey_type_value_get(unit, 556 VLXLT_HASH_KEY_TYPE_IVID, &key_type_value)); 557 soc_LPORT_TABm_field32_set(unit, &lport_entry, VT_KEY_TYPE_2f, 558 key_type_value); 559 } 560 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, VT_KEY_TYPE_2_USE_GLPf)) { 561 soc_LPORT_TABm_field32_set(unit, &lport_entry, VT_KEY_TYPE_2_USE_GLPf, 1); 562 } 563 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, VT_PORT_TYPE_SELECT_2f)) { 564 soc_LPORT_TABm_field32_set(unit, &lport_entry, VT_PORT_TYPE_SELECT_2f, 1); 565 } 566 567 /* Trust the outer tag pri/cfi (to be backwards compatible) */ 568 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, TRUST_OUTER_DOT1Pf)) { 569 soc_LPORT_TABm_field32_set(unit, &lport_entry, TRUST_OUTER_DOT1Pf, 1); 570 } 571 } 572 573 /* Enable IFP. */ 574 soc_LPORT_TABm_field32_set(unit, &lport_entry, FILTER_ENABLEf, 1); 575 576 /* Enable VFP. */ 577 soc_LPORT_TABm_field32_set(unit, &lport_entry, VFP_ENABLEf, 1); 578 579 /* Set port field select index to PFS index max - 1. */ 580 if(SOC_MEM_FIELD_VALID(unit, LPORT_TABm, FP_PORT_FIELD_SEL_INDEXf)) { 581 soc_LPORT_TABm_field32_set(unit, &lport_entry, FP_PORT_FIELD_SEL_INDEXf, 582 (soc_mem_index_max(unit, FP_PORT_FIELD_SELm) 583 - 1)); 584 } 585 586 /* Enable V4 L3 termination */ 587 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, V4L3_ENABLEf)) { 588 BCM_IF_ERROR_RETURN( 589 _bcm_esw_port_tab_get(unit, port, V4L3_ENABLEf, &value)); 590 591 soc_LPORT_TABm_field32_set(unit, &lport_entry, V4L3_ENABLEf, value); 592 } 593 594 /* Enable V6 L3 termination */ 595 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, V6L3_ENABLEf)) { 596 BCM_IF_ERROR_RETURN( 597 _bcm_esw_port_tab_get(unit, port, V6L3_ENABLEf, &value)); 598 soc_LPORT_TABm_field32_set(unit, &lport_entry, V6L3_ENABLEf, value); 599 } 600 601 /* Enable V4 IPMC */ 602 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, V4IPMC_ENABLEf)) { 603 BCM_IF_ERROR_RETURN( 604 _bcm_esw_port_tab_get(unit, port, V4IPMC_ENABLEf, &value)); 605 soc_LPORT_TABm_field32_set(unit, &lport_entry, V4IPMC_ENABLEf, value); 606 } 607 608 /* Enable V6 IPMC */ 609 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, V6IPMC_ENABLEf)) { 610 BCM_IF_ERROR_RETURN( 611 _bcm_esw_port_tab_get(unit, port, V6IPMC_ENABLEf, &value)); 612 soc_LPORT_TABm_field32_set(unit, &lport_entry, V6IPMC_ENABLEf, value); 613 } 614 615 /* IPMC DO VLAN enable */ 616 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, IPMC_DO_VLANf)) { 617 BCM_IF_ERROR_RETURN( 618 _bcm_esw_port_tab_get(unit, port, IPMC_DO_VLANf, &value)); 619 soc_LPORT_TABm_field32_set(unit, &lport_entry, IPMC_DO_VLANf, value); 620 } 621 622 /* Enable MPLS */ 623 if (SOC_MEM_FIELD_VALID(unit, LPORT_TABm, MPLS_ENABLEf)) { 624 BCM_IF_ERROR_RETURN( 625 _bcm_esw_port_tab_get(unit, port, MPLS_ENABLEf, &value)); 626 soc_LPORT_TABm_field32_set(unit, &lport_entry, MPLS_ENABLEf, value); 627 } 628 629 if (SOC_IS_TRIDENT3X(unit)) { 630 soc_LPORT_TABm_field32_set(unit, &lport_entry, PRI_MAPPINGf, 0xfac688); 631 soc_LPORT_TABm_field32_set(unit, &lport_entry, CFI_0_MAPPINGf, 0); 632 soc_LPORT_TABm_field32_set(unit, &lport_entry, CFI_1_MAPPINGf, 1); 633 soc_LPORT_TABm_field32_set(unit, &lport_entry, IPRI_MAPPINGf, 0xfac688); 634 soc_LPORT_TABm_field32_set(unit, &lport_entry, ICFI_0_MAPPINGf, 0); 635 soc_LPORT_TABm_field32_set(unit, &lport_entry, ICFI_1_MAPPINGf, 1); 636 soc_LPORT_TABm_field32_set(unit, &lport_entry, CML_FLAGS_NEWf, 0x8); 637 soc_LPORT_TABm_field32_set(unit, &lport_entry, CML_FLAGS_MOVEf, 0x8); 638 soc_LPORT_TABm_field32_set(unit, &lport_entry, TAG_ACTION_PROFILE_PTRf, 0x1); 639 640 BCM_IF_ERROR_RETURN 641 (_bcm_esw_pt_vtkey_type_value_get(unit, 642 VLXLT_HASH_KEY_TYPE_OVID, &key_type_value)); 643 soc_LPORT_TABm_field32_set(unit, &lport_entry, VT_KEY_TYPEf, 644 key_type_value); 645 646 soc_LPORT_TABm_field32_set(unit, &lport_entry, VT_PORT_TYPE_SELECT_1f, 1); 647 648 BCM_IF_ERROR_RETURN 649 (_bcm_esw_pt_vtkey_type_value_get(unit, 650 VLXLT_HASH_KEY_TYPE_IVID, &key_type_value)); 651 soc_LPORT_TABm_field32_set(unit, &lport_entry, VT_KEY_TYPE_2f, 652 key_type_value); 653 654 soc_LPORT_TABm_field32_set(unit, &lport_entry, VT_PORT_TYPE_SELECT_2f, 1); 655 } 656 657 /* Add LPORT default entry */ 658 entries[0] = &lport_entry; 659 BCM_IF_ERROR_RETURN( 660 _bcm_lport_ind_profile_entry_add(unit, entries, 1, &lport_index)); 661 662 soc_mem_lock(unit, SOURCE_TRUNK_MAP_TABLEm); 663 664 /* Get the current entry programmed at the specified index */ 665 rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, 666 stm_index, &stm_entry); 667 668 if(BCM_FAILURE(rv)) { 669 soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm); 670 return rv; 671 } 672 673 /* Update STM LPORT profile index */ 674 soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, 675 LPORT_PROFILE_IDXf, 676 lport_index); 677 678 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, OUTER_TPID_ENABLEf)) { 679 soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, 680 OUTER_TPID_ENABLEf, 1); 681 } 682 /* Write the data back */ 683 rv = WRITE_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, 684 stm_index, &stm_entry); 685 686 soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm); 687 688 return rv; 689 } 690 691 STATIC int 692 _bcm_coe_subtag_subport_default_egr_lport_entry_set(int unit, int port) 693 { 694 uint32 values[] = {0, 1, 1, 0}; 695 soc_field_t fields[] = { 696 EN_EFILTERf, 697 EM_SRCMOD_CHANGEf, 698 EFP_FILTER_ENABLEf, 699 EGR_QOS_PROFILE_INDEXf 700 }; 701 702 BCM_IF_ERROR_RETURN( 703 bcm_esw_port_egr_lport_fields_set( 704 unit, port, EGR_LPORT_PROFILEm, 4, fields, values)); 705 706 if (SOC_MEM_FIELD_VALID(unit, EGR_PORT_1m, OUTER_TPID_ENABLEf)) { 707 BCM_IF_ERROR_RETURN( 708 bcm_esw_port_egr_lport_field_set( 709 unit, port, EGR_PORT_1m, OUTER_TPID_ENABLEf, 1)); 710 711 } 712 if (SOC_MEM_FIELD_VALID(unit, EGR_LPORT_PROFILEm, VXLT_CTRL_IDf)) { 713 BCM_IF_ERROR_RETURN( 714 bcm_esw_port_egr_lport_field_set( 715 unit, port, EGR_LPORT_PROFILEm, VXLT_CTRL_IDf, 1)); 716 717 } 718 return BCM_E_NONE; 719 } 720 721 /* 722 * Function: 723 * _bcm_coe_subtag_subport_lport_entry_delete 724 * Purpose: 725 * Delete the lport profile for this Source Trunk Map entry 726 * Parameters: 727 * unit - (IN) Device Number 728 * stm_index - (IN) Source Trunk Map Index to update the LPORT at 729 * Returns: 730 * BCM_E_XXX 731 */ 732 733 STATIC int 734 _bcm_coe_subtag_subport_lport_entry_delete(int unit, int stm_index) 735 { 736 source_trunk_map_table_entry_t stm_entry; 737 uint32 lport_index; 738 739 /* Read the entry in question */ 740 SOC_IF_ERROR_RETURN 741 (READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, 742 stm_index, &stm_entry)); 743 744 /* Extract the lport index from the entry */ 745 lport_index = 746 soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry, 747 LPORT_PROFILE_IDXf); 748 749 /* Delete the profile entry for this index*/ 750 BCM_IF_ERROR_RETURN( 751 _bcm_lport_ind_profile_entry_delete(unit, lport_index)); 752 753 return BCM_E_NONE; 754 } 755 756 /* 757 * Function: 758 * _bcm_coe_subtag_subport_port_delete 759 * Purpose: 760 * Add a subport to a subport group 761 * Parameters: 762 * unit - (IN) Device Number 763 * subport_port_gport - (IN) Subport to delete 764 * Returns: 765 * BCM_E_XXX 766 */ 767 768 STATIC int 769 _bcm_coe_subtag_subport_port_delete(int unit, bcm_gport_t subport) 770 { 771 int rv = BCM_E_NONE, group_id = 0, idx = 0; 772 int port = 0, subport_group = -1; 773 int subtag_to_subport_port_tab_idx = -1; 774 bcm_vlan_t vlan_id; 775 soc_mem_t mem; 776 subport_tag_sgpp_map_entry_t subport_tag_to_sgpp_port_map_entry; 777 soc_info_t *si = &SOC_INFO(unit); 778 779 if (!_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, subport)) { 780 LOG_ERROR(BSL_LS_BCM_SUBPORT, 781 (BSL_META_U(unit,"ERROR: gport 0x%x is not SubTag " 782 "subport port type.\n"), 783 subport)); 784 return BCM_E_PARAM; 785 } 786 787 for (idx=0; idx < si->max_subport_coe_ports; idx++) { 788 if(_bcm_subtag_subport_port_info[unit][idx].subport_port == 789 subport) { 790 break; 791 } 792 } 793 794 if(idx >= si->max_subport_coe_ports) { 795 LOG_ERROR(BSL_LS_BCM_SUBPORT, 796 (BSL_META_U(unit,"ERROR: subport_gport 0x%x " 797 "not configured.\n"), 798 subport)); 799 return BCM_E_NOT_FOUND; 800 } 801 802 if (!_BCM_SUBPORT_COE_SUBTAG_PORT_INFO_VALID_GET(unit, idx)) { 803 LOG_ERROR(BSL_LS_BCM_SUBPORT, 804 (BSL_META_U(unit,"ERROR: SubTag subport port " 805 "gport 0x%x is invalid\n"), 806 subport)); 807 return BCM_E_NOT_FOUND; 808 } 809 810 /* Extract the associated group */ 811 subport_group = 812 _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_GROUP_GET(unit, idx); 813 814 /* Extract the associated front panel port */ 815 port = _BCM_SUBPORT_COE_GROUP_PORT_GET(subport_group); 816 817 /* Get the idx associated with 'SUBPORT_TAG_SGPP_MAPm' entry */ 818 subtag_to_subport_port_tab_idx = 819 _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_TCAM_HW_ID_GET(unit, idx); 820 821 mem = SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP_MEM(unit); 822 if (subtag_to_subport_port_tab_idx < 0 || 823 subtag_to_subport_port_tab_idx > soc_mem_index_max(unit,mem)) { 824 LOG_ERROR(BSL_LS_BCM_SUBPORT, 825 (BSL_META_U(unit,"ERROR: SubTag subport port gport " 826 "0x%x is not found.\n" 827 "subtag_to_pp_port tcam idx = %d\n") 828 ,subport, 829 subtag_to_subport_port_tab_idx)); 830 return BCM_E_NOT_FOUND; 831 } 832 833 /* Get the associated VLAN */ 834 vlan_id = _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_VLAN_GET(unit, idx) & 835 0xFFF; 836 837 /* Make sure the VLAN is indeed configured */ 838 if (!_BCM_COE_SUBTAG_VLAN_ID_USED_GET(unit, port, vlan_id)) { 839 LOG_ERROR(BSL_LS_BCM_SUBPORT, 840 (BSL_META_U(unit,"ERROR: SubTag subport port gport " 841 "0x%x is not found.\n" 842 "VLAN id = %d is not set for " 843 "port %d\n"), 844 subport, vlan_id, port)); 845 return BCM_E_NOT_FOUND; 846 } 847 848 /* 849 * Clean port, VLAN ID to subport mapping 850 */ 851 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, subtag_to_subport_port_tab_idx, 852 &subport_tag_to_sgpp_port_map_entry); 853 soc_mem_field32_set(unit, mem, 854 (uint32 *)&subport_tag_to_sgpp_port_map_entry, 855 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->subport_tag, 856 0); 857 soc_mem_field32_set(unit, mem, 858 (uint32 *)&subport_tag_to_sgpp_port_map_entry, 859 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->valid, 0); 860 861 /* Clean PHB for the subport */ 862 soc_mem_field32_set(unit, mem, 863 (uint32 *)&subport_tag_to_sgpp_port_map_entry, 864 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->phb_enable, 0); 865 soc_mem_field32_set(unit, mem, 866 (uint32 *)&subport_tag_to_sgpp_port_map_entry, 867 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->int_pri, 0); 868 soc_mem_field32_set(unit, mem, 869 (uint32 *)&subport_tag_to_sgpp_port_map_entry, 870 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->cng, 0); 871 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, 872 subtag_to_subport_port_tab_idx, 873 &subport_tag_to_sgpp_port_map_entry); 874 if (SOC_FAILURE(rv)) { 875 LOG_ERROR(BSL_LS_BCM_SUBPORT, 876 (BSL_META_U(unit,"ERROR: subport_tag %d to sgpp %d " 877 "map failed.\n"), vlan_id, 878 subtag_to_subport_port_tab_idx)); 879 return rv; 880 } 881 882 /* 883 * Clean SGPP to Physical port mapping 884 */ 885 886 mem = SUBPORT_COE_HW_MODPORT_MAP_SUBPORT_MEM(unit); 887 rv = soc_mem_field32_modify(unit, mem, 888 _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_MODPORT_IDX_GET(unit, idx), 889 SUBPORT_COE_HW_MODPORT_MAP_SUBPORT(unit)->dest, 0); 890 891 rv = soc_mem_field32_modify(unit, mem, 892 _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_MODPORT_IDX_GET(unit, idx), 893 SUBPORT_COE_HW_MODPORT_MAP_SUBPORT(unit)->enable, 0); 894 895 if (SOC_FAILURE(rv)) { 896 LOG_ERROR(BSL_LS_BCM_SUBPORT, 897 (BSL_META_U(unit,"ERROR: Cleaning mod_port to subport id " 898 "%d to physical port " 899 "map failed.\n"), subport)); 900 return rv; 901 } 902 903 #if defined(INCLUDE_L3) 904 /* Adjust the encoded offset and delete the allocated next-hop */ 905 if(_bcm_subtag_subport_port_info[unit][idx].nh_index != -1) { 906 BCM_IF_ERROR_RETURN(bcm_xgs3_nh_del(unit, 0, 907 _bcm_subtag_subport_port_info[unit][idx].nh_index - 908 BCM_XGS3_DVP_EGRESS_IDX_MIN(unit))); 909 } 910 #endif 911 912 BCM_IF_ERROR_RETURN(_bcm_coe_subtag_subport_lport_entry_delete(unit, 913 _bcm_subtag_subport_port_info[unit][idx].modport_subport_idx)); 914 915 _BCM_COE_SUBTAG_VLAN_ID_USED_CLR(unit, port, vlan_id); 916 917 group_id = _BCM_SUBPORT_COE_GROUP_ID_GET(subport_group); 918 *(_bcm_subport_group_subport_port_count[unit] + group_id) -= 1; 919 920 _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_SET(unit, idx, 921 subtag_to_subport_port_tab_idx, 922 BCM_GPORT_INVALID, 923 BCM_VLAN_INVALID, 924 -1, -1, -1, -1, -1, FALSE, -1); 925 926 #ifdef BCM_WARM_BOOT_SUPPORT 927 SOC_CONTROL_LOCK(unit); 928 SOC_CONTROL(unit)->scache_dirty = 1; 929 SOC_CONTROL_UNLOCK(unit); 930 #endif 931 932 return rv; 933 } 934 935 936 int bcmi_xgs5_subport_coe_port_delete(int unit, bcm_gport_t subport) 937 { 938 int rv = BCM_E_NONE; 939 940 _BCM_SUBPORT_COE_CHECK_INIT(unit); 941 942 if (!BCM_GPORT_IS_SUBPORT_PORT(subport)) { 943 LOG_ERROR(BSL_LS_BCM_SUBPORT, 944 (BSL_META_U(unit,"ERROR: gport 0x%x is not " 945 "subport port gport\n"), 946 subport)); 947 return BCM_E_PARAM; 948 } 949 950 _BCM_SUBPORT_COE_LOCK(unit); 951 952 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 953 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, subport)) { 954 rv = _bcm_coe_subtag_subport_port_delete(unit, subport); 955 } 956 957 if (SOC_FAILURE(rv)) { 958 LOG_ERROR(BSL_LS_BCM_SUBPORT, 959 (BSL_META_U(unit,"ERROR: Subport port 0x%x " 960 "delete failed. rv = %d(%s)\n"), 961 subport, rv, soc_errmsg(rv))); 962 _BCM_SUBPORT_COE_UNLOCK(unit); 963 return rv; 964 } 965 966 _BCM_SUBPORT_COE_UNLOCK(unit); 967 968 #ifdef BCM_WARM_BOOT_SUPPORT 969 SOC_CONTROL_LOCK(unit); 970 SOC_CONTROL(unit)->scache_dirty = 1; 971 SOC_CONTROL_UNLOCK(unit); 972 #endif 973 974 return rv; 975 976 } 977 978 /* 979 * Function: 980 * _bcm_coe_subtag_subport_group_create 981 * Purpose: 982 * Create a SubTag subport group 983 * Parameters: 984 * unit - (IN) Device Number 985 * port - (IN) Front panel port 986 * group_id - (IN) Group Id being configured 987 * group - (OUT) GPORT (generic port) identifier 988 * Returns: 989 * BCM_E_XXX 990 */ 991 STATIC int 992 _bcm_coe_subtag_subport_group_create(int unit, bcm_port_t port, 993 int group_id, bcm_gport_t *group) 994 { 995 996 int rv = BCM_E_NONE; 997 998 _BCM_SUBPORT_COE_CHECK_INIT(unit); 999 1000 _BCM_SUBPORT_COE_SUBTAG_GROUP_SET(*group, port, group_id); 1001 _BCM_SUBPORT_COE_GROUP_TYPE_CASCADED_SET(*group); 1002 1003 _BCM_SUBPORT_COE_SUBTAG_GROUP_USED_SET(unit, group_id); 1004 _bcm_subtag_subport_group_count[unit]++; 1005 1006 /* Also, set the SUBPORT_TAG_NAMESPACE to be same as the port number */ 1007 1008 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, 1009 _BCM_CPU_TABS_NONE, SUBPORT_TAG_NAMESPACEf, port)); 1010 1011 return rv; 1012 } 1013 1014 /* 1015 * Function: 1016 * bcmi_xgs5_subport_coe_group_create 1017 * Purpose: 1018 * Create a subport group 1019 * Parameters: 1020 * unit - (IN) Device Number 1021 * config - (IN) Subport group config information 1022 * group - (OUT) GPORT (generic port) identifier 1023 * Returns: 1024 * BCM_E_XXX 1025 */ 1026 int bcmi_xgs5_subport_coe_group_create(int unit, 1027 bcm_subport_group_config_t *config, 1028 bcm_gport_t *group) 1029 { 1030 int rv = BCM_E_NONE, group_id = 0, i = 0; 1031 bcm_port_t port; 1032 soc_info_t *si = &SOC_INFO(unit); 1033 1034 /* Ensure the subport module is initialized */ 1035 _BCM_SUBPORT_COE_CHECK_INIT(unit); 1036 1037 if (!(config->flags & BCM_SUBPORT_GROUP_TYPE_SUBPORT_TAG)) { 1038 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1039 (BSL_META_U(unit,"ERROR: The group type has to " 1040 "be SUBPORT_TAG\n"))); 1041 return BCM_E_PARAM; 1042 } 1043 1044 /* Validate the passed in front panel port */ 1045 rv = _bcm_esw_port_gport_validate(unit, config->port, &port); 1046 if (SOC_FAILURE(rv)) { 1047 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1048 (BSL_META_U(unit,"ERROR: Invalid gport 0x%x for " 1049 "subport group create.\n"), 1050 config->port)); 1051 return BCM_E_PORT; 1052 } 1053 1054 /* Ensure that the physical port can be a cascaded port */ 1055 if ((config->flags & BCM_SUBPORT_GROUP_TYPE_SUBPORT_TAG) && 1056 !BCM_PBMP_MEMBER(si->subtag_pbm, port)) { 1057 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1058 (BSL_META_U(unit,"ERROR: SubportTag/CoE " 1059 "should be enabled" 1060 " for port %d\n"), port)); 1061 return BCM_E_PORT; 1062 } 1063 1064 /* If max groups aready taken up, error out */ 1065 if (_bcm_subport_group_count[unit] == si->max_subport_coe_groups) { 1066 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1067 (BSL_META_U(unit,"ERROR: All %d subport " 1068 "groups already used.\n"), 1069 si->max_subport_coe_groups)); 1070 return BCM_E_FULL; 1071 } 1072 1073 if (config->flags & BCM_SUBPORT_GROUP_WITH_ID) { 1074 group_id = BCM_GPORT_SUBPORT_GROUP_GET(*group); 1075 /* Group id should be within 0 to 512. 1076 * BCM_GPORT_SUBPORT_GROUP_MASK is 0xffffff (for all chips) 1077 * but subtag group id is only first 9 bits (8-0). 1078 * Check that only subtag group id bits (8-0) are configured*/ 1079 if ((group_id >> _BCM_SUBPORT_COE_GROUP_PORT_SHIFT) 1080 & _SHR_GPORT_SUBPORT_GROUP_MASK) { 1081 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1082 (BSL_META_U(unit,"ERROR: subport group id = %d " 1083 "should be within 0 to" 1084 " %d\n"), 1085 group_id, 1086 si->max_subport_coe_groups-1)); 1087 return BCM_E_PARAM; 1088 } 1089 if (_BCM_SUBPORT_COE_GROUP_USED_GET(unit, group_id)) { 1090 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1091 (BSL_META_U(unit,"ERROR: subport group id = %d " 1092 "is already used\n"), group_id)); 1093 return BCM_E_EXISTS; 1094 } 1095 } else { 1096 /* If without Id, grab a free group */ 1097 for (i =0; i < si->max_subport_coe_groups; i++) { 1098 if (!_BCM_SUBPORT_COE_GROUP_USED_GET(unit, i)) { 1099 group_id = i; 1100 break; 1101 } 1102 } 1103 1104 if (i == si->max_subport_coe_groups) { 1105 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1106 (BSL_META_U(unit,"ERROR: All %d subport groups " 1107 "already used.\n"), i)); 1108 return BCM_E_FULL; 1109 } 1110 } 1111 1112 _BCM_SUBPORT_COE_LOCK(unit); 1113 1114 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 1115 (config->flags & BCM_SUBPORT_GROUP_TYPE_SUBPORT_TAG)) { 1116 rv =_bcm_coe_subtag_subport_group_create(unit, port, 1117 group_id, group); 1118 if (SOC_FAILURE(rv)) { 1119 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1120 (BSL_META_U(unit,"ERROR: SubTag subport group " 1121 "create failed" 1122 " for port %d. rv = %d(%s)\n"), 1123 config->port, rv, soc_errmsg(rv))); 1124 _BCM_SUBPORT_COE_UNLOCK(unit); 1125 return rv; 1126 } 1127 } 1128 1129 _BCM_SUBPORT_COE_GROUP_USED_SET(unit, group_id); 1130 _bcm_subport_group_count[unit]++; 1131 1132 _BCM_SUBPORT_COE_UNLOCK(unit); 1133 1134 1135 #ifdef BCM_WARM_BOOT_SUPPORT 1136 SOC_CONTROL_LOCK(unit); 1137 SOC_CONTROL(unit)->scache_dirty = 1; 1138 SOC_CONTROL_UNLOCK(unit); 1139 #endif 1140 1141 return BCM_E_NONE; 1142 } 1143 1144 /* 1145 * Function: 1146 * _bcm_coe_subtag_subport_group_destroy 1147 * Purpose: 1148 * Create a SubTag subport group 1149 * Parameters: 1150 * unit - (IN) Device Number 1151 * port - (IN) Front panel port 1152 * group_id - (IN) Group Id being configured 1153 * group - (OUT) GPORT (generic port) identifier 1154 * Returns: 1155 * BCM_E_XXX 1156 */ 1157 STATIC int 1158 _bcm_coe_subtag_subport_group_destroy(int unit, bcm_gport_t group) 1159 { 1160 int group_id = -1, i = 0; 1161 int pp_port = 0, rv = BCM_E_NONE; 1162 int subtag_subport_count = 0; 1163 soc_info_t *si = &SOC_INFO(unit); 1164 1165 _BCM_SUBPORT_COE_CHECK_INIT(unit); 1166 1167 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(group)) { 1168 1169 group_id = _BCM_SUBPORT_COE_GROUP_ID_GET(group); 1170 1171 if (!_BCM_SUBPORT_COE_SUBTAG_GROUP_USED_GET(unit, group_id)) { 1172 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1173 (BSL_META_U(unit,"ERROR: SubTag subport group " 1174 "0x%x not found.\n"), group)); 1175 return BCM_E_NOT_FOUND; 1176 } 1177 1178 subtag_subport_count = 1179 *(_bcm_subport_group_subport_port_count[unit] + group_id); 1180 1181 for (i=0; i < si->max_subport_coe_ports; i++) { 1182 1183 if (subtag_subport_count == 0) { 1184 break; 1185 } 1186 1187 if (!_BCM_SUBPORT_COE_SUBTAG_PORT_INFO_VALID_GET(unit, i)) { 1188 continue; 1189 } 1190 1191 if (group != 1192 _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_GROUP_GET(unit, i)) { 1193 continue; 1194 } 1195 1196 rv = _bcm_coe_subtag_subport_port_delete(unit, 1197 _bcm_subtag_subport_port_info[unit][i].subport_port); 1198 if (SOC_FAILURE(rv)) { 1199 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1200 (BSL_META_U(unit,"ERROR: SubTag subport group " 1201 "0x%x destroy failed \n" 1202 " to delete subport port (subport group id %d, " 1203 " subport id %d)\n"), group, group_id, pp_port)); 1204 return rv; 1205 } 1206 subtag_subport_count--; 1207 } 1208 1209 *(_bcm_subport_group_subport_port_count[unit] + group_id) = 0; 1210 /* delete the subport group */ 1211 _bcm_subport_group_count[unit]--; 1212 _BCM_SUBPORT_COE_GROUP_USED_CLR(unit, group_id); 1213 _bcm_subtag_subport_group_count[unit]--; 1214 _BCM_SUBPORT_COE_SUBTAG_GROUP_USED_CLR(unit, group_id); 1215 1216 } 1217 1218 return BCM_E_NONE; 1219 } 1220 1221 /* 1222 * Function: 1223 * bcmi_xgs5_subport_coe_group_destroy 1224 * Purpose: 1225 * Destroy a subport group and all subport ports attached to it. 1226 * Parameters: 1227 * unit - (IN) Device Number 1228 * group - (IN) GPORT (generic port) identifier for subport group 1229 * Returns: 1230 * BCM_E_XXX 1231 */ 1232 int bcmi_xgs5_subport_coe_group_destroy(int unit, bcm_gport_t group) 1233 { 1234 int rv = BCM_E_NONE; 1235 soc_info_t *si = &SOC_INFO(unit); 1236 1237 _BCM_SUBPORT_COE_CHECK_INIT(unit); 1238 1239 if (!BCM_GPORT_IS_SUBPORT_GROUP(group)) { 1240 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1241 (BSL_META_U(unit,"ERROR: group 0x%x is not subport " 1242 "group gport\n"), group)); 1243 return BCM_E_PARAM; 1244 } 1245 1246 _BCM_SUBPORT_COE_LOCK(unit); 1247 1248 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 1249 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(group)) { 1250 if (BCM_PBMP_IS_NULL(si->subtag_pbm)) { 1251 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1252 (BSL_META_U(unit,"ERROR: SubTag ports not " 1253 "configured\n"))); 1254 _BCM_SUBPORT_COE_UNLOCK(unit); 1255 return BCM_E_PARAM; 1256 } 1257 rv = _bcm_coe_subtag_subport_group_destroy(unit, group); 1258 } 1259 1260 if (SOC_FAILURE(rv)) { 1261 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1262 (BSL_META_U(unit,"ERROR: subport group 0x%x " 1263 "destroy failed. rv= %d(%s)\n"), 1264 group, rv, soc_errmsg(rv))); 1265 _BCM_SUBPORT_COE_UNLOCK(unit); 1266 return rv; 1267 } 1268 1269 _BCM_SUBPORT_COE_UNLOCK(unit); 1270 1271 #ifdef BCM_WARM_BOOT_SUPPORT 1272 SOC_CONTROL_LOCK(unit); 1273 SOC_CONTROL(unit)->scache_dirty = 1; 1274 SOC_CONTROL_UNLOCK(unit); 1275 #endif 1276 1277 return BCM_E_NONE; 1278 } 1279 1280 /* 1281 * Function: 1282 * _bcm_coe_subtag_subport_group_get 1283 * Purpose: 1284 * Create a SubTag subport group 1285 * Parameters: 1286 * unit - (IN) Device Number 1287 * group_id - (IN) Group Id being configured 1288 * group - (OUT) GPORT (generic port) identifier 1289 * Returns: 1290 * BCM_E_XXX 1291 */ 1292 STATIC int 1293 _bcm_coe_subtag_subport_group_get(int unit, bcm_gport_t group, 1294 bcm_subport_group_config_t *config) 1295 { 1296 int group_id = -1; 1297 1298 _BCM_SUBPORT_COE_CHECK_INIT(unit); 1299 1300 if (config == NULL) { 1301 return BCM_E_PARAM; 1302 } 1303 1304 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(group)) { 1305 group_id = _BCM_SUBPORT_COE_GROUP_ID_GET(group); 1306 if (!_BCM_SUBPORT_COE_SUBTAG_GROUP_USED_GET(unit, group_id)) { 1307 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1308 (BSL_META_U(unit,"ERROR: SubTag subport " 1309 "group 0x%x not found.\n"), group)); 1310 return BCM_E_NOT_FOUND;; 1311 } 1312 config->flags |= BCM_SUBPORT_GROUP_TYPE_SUBPORT_TAG; 1313 config->port = _BCM_SUBPORT_COE_GROUP_PORT_GET(group); 1314 } else { 1315 return BCM_E_PARAM; 1316 } 1317 1318 return BCM_E_NONE; 1319 } 1320 1321 /* 1322 * Function: 1323 * bcmi_xgs5_subport_coe_group_get 1324 * Purpose: 1325 * Get a subport group 1326 * Parameters: 1327 * unit - (IN) Device Number 1328 * group - (IN) GPORT (generic port) identifier 1329 * config - (OUT) Subport group config information 1330 * Returns: 1331 * BCM_E_XXX 1332 */ 1333 1334 int bcmi_xgs5_subport_coe_group_get(int unit, bcm_gport_t group, 1335 bcm_subport_group_config_t *config) 1336 { 1337 int rv = BCM_E_NONE; 1338 soc_info_t *si = &SOC_INFO(unit); 1339 1340 _BCM_SUBPORT_COE_CHECK_INIT(unit); 1341 1342 if (config == NULL) { 1343 return BCM_E_PARAM; 1344 } 1345 1346 if (!BCM_GPORT_IS_SUBPORT_GROUP(group)) { 1347 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1348 (BSL_META_U(unit,"ERROR: group 0x%x is not " 1349 "subport group gport\n"), 1350 group)); 1351 return BCM_E_PARAM; 1352 } 1353 1354 _BCM_SUBPORT_COE_LOCK(unit); 1355 1356 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 1357 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(group)) { 1358 if (BCM_PBMP_IS_NULL(si->subtag_pbm)) { 1359 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1360 (BSL_META_U(unit,"ERROR: SubTag ports not " 1361 "configured\n"))); 1362 _BCM_SUBPORT_COE_UNLOCK(unit); 1363 return BCM_E_PARAM; 1364 } 1365 rv = _bcm_coe_subtag_subport_group_get(unit, group, config); 1366 } 1367 1368 if (SOC_FAILURE(rv)) { 1369 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1370 (BSL_META_U(unit,"ERROR: subport group get " 1371 "failed for 0x%x, rv = %d(%s)\n"), 1372 group, rv, soc_errmsg(rv))); 1373 _BCM_SUBPORT_COE_UNLOCK(unit); 1374 return rv; 1375 } 1376 1377 _BCM_SUBPORT_COE_UNLOCK(unit); 1378 1379 return BCM_E_NONE; 1380 } 1381 1382 1383 /* 1384 * Function: 1385 * _bcm_coe_subtag_subport_group_traverse 1386 * Purpose: 1387 * Traverse all valid subports for given SubTag subport group 1388 * and call the user supplied callback routine. 1389 * Parameters: 1390 * unit - Device Number 1391 * group - Subport group GPORT identifier 1392 * cb - User callback function, called once per subport. 1393 * user_data - cookie 1394 */ 1395 1396 STATIC int 1397 _bcm_coe_subtag_subport_group_traverse(int unit, 1398 bcm_gport_t group, 1399 bcm_subport_port_traverse_cb cb, 1400 void *user_data) 1401 { 1402 1403 int rv = BCM_E_NONE, group_id = 0, i = 0; 1404 int subtag_subport_count = 0; 1405 bcm_subport_config_t config; 1406 soc_info_t *si = &SOC_INFO(unit); 1407 1408 _BCM_SUBPORT_COE_CHECK_INIT(unit); 1409 1410 bcm_subport_config_t_init(&config); 1411 1412 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(group)) { 1413 group_id = _BCM_SUBPORT_COE_GROUP_ID_GET(group); 1414 1415 if (!_BCM_SUBPORT_COE_SUBTAG_GROUP_USED_GET(unit, group_id)) { 1416 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1417 (BSL_META_U(unit,"ERROR: SubTag subport group " 1418 "0x%x not found.\n"), group)); 1419 return BCM_E_NOT_FOUND; 1420 } 1421 1422 subtag_subport_count = 1423 *(_bcm_subport_group_subport_port_count[unit] + group_id); 1424 1425 1426 for (i=0; i < si->max_subport_coe_ports; i++) { 1427 1428 if (subtag_subport_count == 0) { 1429 break; 1430 } 1431 1432 if (!_BCM_SUBPORT_COE_SUBTAG_PORT_INFO_VALID_GET(unit, i)) { 1433 continue; 1434 } 1435 1436 if (group != 1437 _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_GROUP_GET(unit, i)) { 1438 continue; 1439 } 1440 1441 rv = _bcm_coe_subtag_subport_port_get(unit, 1442 _bcm_subtag_subport_port_info[unit][i].subport_port, 1443 &config); 1444 if (SOC_FAILURE(rv)) { 1445 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1446 (BSL_META_U(unit,"ERROR: SubTag subport group " 1447 "0x%x traverse failed \n" 1448 "to get subport port (group id %d, " 1449 "subport id %d)\n"), 1450 group, group_id, 1451 _bcm_subtag_subport_port_info[unit][i].subport_port)); 1452 return rv; 1453 } 1454 /* coverity[returned_value] */ 1455 rv = cb(unit, 1456 _bcm_subtag_subport_port_info[unit][i].subport_port, 1457 &config, 1458 user_data); 1459 #ifdef BCM_CB_ABORT_ON_ERR 1460 if (BCM_FAILURE(rv) && SOC_CB_ABORT_ON_ERR(unit)) { 1461 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1462 (BSL_META_U(unit,"ERROR: subport group 0x%x " 1463 "traverse failed \n" 1464 "to callback for subport " 1465 "port (group id %d, subport id %d)\n"), 1466 group, group_id, 1467 _bcm_subtag_subport_port_info[unit][i].subport_port)); 1468 return rv; 1469 } 1470 #endif 1471 subtag_subport_count--; 1472 } 1473 } else { 1474 return BCM_E_PARAM; 1475 } 1476 return BCM_E_NONE; 1477 } 1478 1479 /* 1480 * Function: 1481 * bcmi_xgs5_subport_coe_group_traverse 1482 * Purpose: 1483 * Traverse all valid subports for given subport group and call the user 1484 * supplied callback routine. 1485 * Parameters: 1486 * unit - Device Number 1487 * group - Subport group GPORT identifier 1488 * cb - User callback function, called once per subport. 1489 * user_data - cookie 1490 */ 1491 1492 int bcmi_xgs5_subport_coe_group_traverse(int unit, bcm_gport_t group, 1493 bcm_subport_port_traverse_cb cb, 1494 void *user_data) 1495 { 1496 int rv = BCM_E_NONE; 1497 soc_info_t *si = &SOC_INFO(unit); 1498 1499 _BCM_SUBPORT_COE_CHECK_INIT(unit); 1500 1501 if (!BCM_GPORT_IS_SUBPORT_GROUP(group)) { 1502 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1503 (BSL_META_U(unit,"ERROR: group 0x%x is not subport " 1504 "group gport\n"), group)); 1505 return BCM_E_PARAM; 1506 } 1507 1508 _BCM_SUBPORT_COE_LOCK(unit); 1509 1510 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 1511 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(group)) { 1512 if (BCM_PBMP_IS_NULL(si->subtag_pbm)) { 1513 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1514 (BSL_META_U(unit,"ERROR: SubTag ports not " 1515 "configured\n"))); 1516 _BCM_SUBPORT_COE_UNLOCK(unit); 1517 return BCM_E_PARAM; 1518 } 1519 rv =_bcm_coe_subtag_subport_group_traverse(unit, group, cb, user_data); 1520 } 1521 1522 if (SOC_FAILURE(rv)) { 1523 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1524 (BSL_META_U(unit,"ERROR: subport group traverse failed for " 1525 "0x%x, rv = %d(%s)\n"), 1526 group, rv, soc_errmsg(rv))); 1527 _BCM_SUBPORT_COE_UNLOCK(unit); 1528 return rv; 1529 } 1530 1531 _BCM_SUBPORT_COE_UNLOCK(unit); 1532 1533 return BCM_E_NONE; 1534 } 1535 1536 /* 1537 * Function: 1538 * _bcm_coe_subport_free_entry_find 1539 * Purpose: 1540 * Search for unused entry in the SUBPORT_TAG_SGPP_MAP table 1541 * Parameters: 1542 * unit - Device unit number 1543 * index - (OUT) index where found 1544 * Returns: 1545 * BOC_E_NONE - free entry found 1546 * BOC_E_FULL - no free entries found 1547 */ 1548 STATIC int 1549 _bcm_coe_subport_free_entry_find(int unit, int *free_index) 1550 { 1551 int index; 1552 soc_info_t *si=&SOC_INFO(unit); 1553 1554 if(_bcm_subtag_subport_port_info[unit] == NULL) { 1555 return BCM_E_INTERNAL; 1556 } 1557 for (index = 0; index < si->max_subport_coe_ports; index++) { 1558 if (_bcm_subtag_subport_port_info[unit][index].valid == 0) { 1559 /* Return the first unused entry*/ 1560 *free_index = index; 1561 return BCM_E_NONE; 1562 } 1563 } 1564 1565 /* If we fall through, the table is full */ 1566 return BCM_E_FULL; 1567 } 1568 1569 /* 1570 * Function: 1571 * _bcm_coe_subport_allocate_modport 1572 * Purpose: 1573 * Search for unused entry from CoE modules configured 1574 * Parameters: 1575 * unit - Device unit number 1576 * mod - (OUT) ModuleId of free module 1577 * port - (OUT) Port num of free free port on the module 1578 * Returns: 1579 * BOC_E_NONE - free entry found 1580 * BOC_E_FULL - no free entries found 1581 */ 1582 STATIC int 1583 _bcm_coe_subport_allocate_modport(int unit,int *mod, int *port) 1584 { 1585 int i, j, rv; 1586 bcm_stk_modid_config_t modIdInfo[TD2P_MAX_COE_MODULES]; 1587 bcm_gport_t coe_system_gport; 1588 soc_info_t *si=&SOC_INFO(unit); 1589 SHR_BITDCL *mod_port_bitmap[TD2P_MAX_COE_MODULES] = { NULL }; 1590 int mod_port_used[TD2P_MAX_COE_MODULES] = { 0 }; 1591 int modid, portid; 1592 unsigned int size; 1593 1594 if(_bcm_subtag_subport_port_info[unit] == NULL) { 1595 return BCM_E_INTERNAL; 1596 } 1597 1598 /* Initialize the (mod,port) info */ 1599 for(i = 0; i < si->num_coe_modules; i++) { 1600 modIdInfo[i].modid = modIdInfo[i].num_ports = -1; 1601 size = SHR_BITALLOCSIZE(TD2P_MAX_SUBPORT_COE_PORT_PER_MOD); 1602 mod_port_bitmap[i] = 1603 sal_alloc(size, "mod_port_bitmap"); 1604 if (mod_port_bitmap[i] == NULL) { 1605 rv = BCM_E_MEMORY; 1606 goto cleanup; 1607 } 1608 sal_memset(mod_port_bitmap[i], 0, size); 1609 } 1610 1611 /* Get the configured CoE module-port info */ 1612 _bcm_stk_aux_modport_info_get(unit, BCM_MODID_TYPE_COE, modIdInfo); 1613 1614 /* Create mod port bitmap */ 1615 for (i = 0; i < si->max_subport_coe_ports; i++){ 1616 if(_BCM_SUBPORT_COE_SUBTAG_PORT_INFO_VALID_GET(unit, i)) { 1617 coe_system_gport = 1618 _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_SUBPORT_MODPORT_GET(unit, i); 1619 modid = BCM_GPORT_MODPORT_MODID_GET(coe_system_gport); 1620 portid = BCM_GPORT_MODPORT_PORT_GET(coe_system_gport); 1621 for (j = 0; j < si->num_coe_modules; j++) { 1622 if (modid == modIdInfo[j].modid) { 1623 mod_port_used[j]++; 1624 /* coverity[negative_shift: FALSE] */ 1625 SHR_BITSET(mod_port_bitmap[j], portid); 1626 } 1627 } 1628 } 1629 } 1630 1631 /* Get a unused (mod,port) from the CoE modules */ 1632 rv = BCM_E_FULL; 1633 for (i = 0; i < si->num_coe_modules; i++) { 1634 if((modIdInfo[i].modid != BCM_MODID_INVALID) && 1635 (modIdInfo[i].num_ports != -1) && 1636 (mod_port_used[i] < modIdInfo[i].num_ports)) { 1637 for(j = 0; j < modIdInfo[i].num_ports; j++) { 1638 if (!SHR_BITGET(mod_port_bitmap[i],j)){ 1639 *mod = modIdInfo[i].modid; 1640 *port = j; 1641 rv = BCM_E_NONE; 1642 goto cleanup; 1643 } 1644 } 1645 } 1646 } 1647 1648 cleanup: 1649 for(i = 0; i < si->num_coe_modules; i++) { 1650 if (mod_port_bitmap[i] != NULL) { 1651 sal_free(mod_port_bitmap[i]); 1652 } 1653 } 1654 return rv; 1655 } 1656 1657 /* 1658 * Function: 1659 * _bcm_xgs5_subport_coe_mod_port_local 1660 * Purpose: 1661 * Check if a given (mod,port) is local 1662 * Parameters: 1663 * unit - (IN) Device Number 1664 * modid - (IN) Mod Id value 1665 * portid - (IN) Port Id value 1666 * Returns: 1667 * TRUE if local, FALSE otherwise 1668 */ 1669 1670 int _bcm_xgs5_subport_coe_mod_port_local(int unit, int modid, bcm_port_t portid) 1671 { 1672 int rv; 1673 1674 /* Check if the passed in (mod,port) is valid on the local device */ 1675 rv = _bcm_stk_aux_modport_valid(unit, BCM_MODID_TYPE_COE, modid, portid); 1676 1677 return ((rv == BCM_E_NONE) ? TRUE : FALSE); 1678 } 1679 1680 1681 /* 1682 * Function: 1683 * _bcm_xgs5_subport_coe_gport_local 1684 * Purpose: 1685 * Check if a given coe-subport-gport is local 1686 * Parameters: 1687 * unit - (IN) Device Number 1688 * modid - (IN) Mod Id value 1689 * portid - (IN) Port Id value 1690 * Returns: 1691 * TRUE if local, FALSE otherwise 1692 */ 1693 1694 int _bcm_xgs5_subport_coe_gport_local(int unit, bcm_gport_t gport) 1695 { 1696 int rv; 1697 1698 /* Check if the passed in (mod,port) is valid on the local device */ 1699 rv = _bcm_stk_aux_modport_valid(unit, BCM_MODID_TYPE_COE, 1700 _BCM_SUBPORT_COE_PORT_ID_MOD_GET(gport), 1701 _BCM_SUBPORT_COE_PORT_ID_PORT_GET(gport)); 1702 1703 if(rv == BCM_E_NONE) { 1704 return TRUE; 1705 } else { 1706 return FALSE; 1707 } 1708 } 1709 1710 /* 1711 * Function: 1712 * _bcm_xgs5_subport_coe_mod_local 1713 * Purpose: 1714 * Check if a given mod is a local-coe-module 1715 * Parameters: 1716 * unit - (IN) Device Number 1717 * modid - (IN) Mod Id value 1718 * Returns: 1719 * TRUE if local, FALSE otherwise 1720 */ 1721 1722 int _bcm_xgs5_subport_coe_mod_local(int unit, int modid) 1723 { 1724 int rv; 1725 1726 /* Check if the passed in (mod,port) is valid on the local device */ 1727 rv = _bcm_stk_aux_mod_valid(unit, BCM_MODID_TYPE_COE, modid); 1728 1729 if(rv == BCM_E_NONE) { 1730 return TRUE; 1731 } else { 1732 return FALSE; 1733 } 1734 } 1735 1736 /* 1737 * Function: 1738 * _bcm_coe_subtag_subport_port_add 1739 * Purpose: 1740 * Add a subport to a subport group 1741 * Parameters: 1742 * unit - (IN) Device Number 1743 * config - (IN) Subport config information 1744 * gport - (OUT) Subport_port GPORT (generic port) identifier 1745 * Returns: 1746 * BCM_E_XXX 1747 */ 1748 1749 STATIC int 1750 _bcm_coe_subtag_subport_port_add(int unit, 1751 bcm_subport_config_t *config, 1752 bcm_gport_t *gport) 1753 { 1754 int rv = BCM_E_NONE, subtag_index = -1, subtag_hw_index = -1; 1755 int sp_group_idx = -1, mod_port_index = 0, modid = 0, portid = 0, port; 1756 uint16 vlan_id = 0, phb_val = 0; 1757 soc_mem_t mem; 1758 uint32 subtag_to_sgpp_entry[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer.*/ 1759 #ifdef BCM_TRIDENT3_SUPPORT 1760 uint32 subtag_to_sgpp_key[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer.*/ 1761 #endif 1762 modport_map_subport_entry_t sgpp_to_port_entry; 1763 #if defined(INCLUDE_L3) 1764 bcm_l3_egress_t nh_info; 1765 egr_l3_next_hop_entry_t egr_nh; 1766 int nh_index; 1767 #endif 1768 soc_info_t *si = &SOC_INFO(unit); 1769 1770 sal_memset(subtag_to_sgpp_entry, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 1771 1772 /* Ensure subport module is initialized */ 1773 _BCM_SUBPORT_COE_CHECK_INIT(unit); 1774 1775 /* Ensyre group is of the proper type */ 1776 if (!BCM_GPORT_IS_SUBPORT_GROUP(config->group)) { 1777 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1778 (BSL_META_U(unit,"ERROR: group 0x%x is not " 1779 "subport group gport\n"), 1780 config->group)); 1781 return BCM_E_PARAM; 1782 } 1783 1784 /* Make sure the group is of correct type */ 1785 if (!_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(config->group)) { 1786 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1787 (BSL_META_U(unit,"ERROR: subport group 0x%x is not " 1788 "SubTag group\n"), 1789 config->group)); 1790 return BCM_E_PARAM; 1791 } 1792 1793 /* Get the group Idx */ 1794 sp_group_idx = _BCM_SUBPORT_COE_GROUP_ID_GET(config->group); 1795 1796 /* Make sure the group exists */ 1797 if (!_BCM_SUBPORT_COE_SUBTAG_GROUP_USED_GET(unit, sp_group_idx)) { 1798 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1799 (BSL_META_U(unit,"ERROR: group 0x%x does not exist. " 1800 "group id =%d\n"), 1801 config->group, sp_group_idx)); 1802 return BCM_E_NOT_FOUND; 1803 } 1804 1805 /* Get the physical port number from the group Id */ 1806 port = _BCM_SUBPORT_COE_GROUP_PORT_GET(config->group); 1807 1808 /* Check if port is member of pbmp_subtag */ 1809 if (!SOC_PBMP_MEMBER(si->subtag_pbm, port)) { 1810 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1811 (BSL_META_U(unit,"ERROR: Port %d is not member " 1812 "of pbmp_subport\n"), port)); 1813 return BCM_E_PORT; 1814 } 1815 1816 /* Ensure the port in question is configured to host 'subtended' port */ 1817 if (si->port_num_subport[port] <= 0) { 1818 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1819 (BSL_META_U(unit,"ERROR: %d number of subports " 1820 "available for port %d\n"), 1821 si->port_num_subport[port], port)); 1822 return BCM_E_CONFIG; 1823 } 1824 1825 /* Check if the number of subports on this physical port 1826 is already reached at the configured values */ 1827 if(*(_bcm_subport_group_subport_port_count[unit] + sp_group_idx) >= 1828 si->port_num_subport[port]) { 1829 return BCM_E_FULL; 1830 } 1831 1832 /* Ensure that the passed in subport_tag is valid */ 1833 if ((config->pkt_vlan & 0xFFF) <= BCM_VLAN_NONE) { 1834 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1835 (BSL_META_U(unit,"ERROR: (config->pkt_vlan & 0xFFF) " 1836 "%d is invalid\n"), 1837 (config->pkt_vlan & 0xFFF))); 1838 return BCM_E_PARAM; 1839 } 1840 1841 /* If the PHB is set, check the PRI and Color for sanity */ 1842 if (config->prop_flags & BCM_SUBPORT_PROPERTY_PHB) { 1843 if (config->int_pri < 0 || config->int_pri > 15) { 1844 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1845 (BSL_META_U(unit,"ERROR: int_pri %d is invalid\n"), 1846 config->int_pri)); 1847 return BCM_E_PARAM; 1848 } 1849 if ((config->color != bcmColorGreen) && 1850 (config->color != bcmColorYellow) && 1851 (config->color != bcmColorRed)) { 1852 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1853 (BSL_META_U(unit,"ERROR: color %d is invalid\n"), 1854 config->color)); 1855 return BCM_E_PARAM; 1856 } 1857 } 1858 1859 /* Check if the VLAN passed is valid */ 1860 VLAN_CHK_ID(unit, config->pkt_vlan); 1861 1862 /* Check if VLAN id is alredy used for the port */ 1863 vlan_id = config->pkt_vlan & 0xFFF; 1864 1865 if (_BCM_COE_SUBTAG_VLAN_ID_USED_GET(unit, port, vlan_id)) { 1866 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1867 (BSL_META_U(unit,"ERROR: VLAN id %d already " 1868 "used for port %d\n"), 1869 vlan_id, port)); 1870 return BCM_E_EXISTS; 1871 } 1872 1873 /* If the MODPORT is set in the passed in 'system_gport' we will use the 1874 (mod,port) which is a part of it, if it is valid. Else allocate one 1875 from the configured CoE modules */ 1876 1877 /* If a valid gport is supplied use it, else allocate one */ 1878 if(BCM_GPORT_IS_MODPORT(config->subport_modport)) { 1879 modid = BCM_GPORT_MODPORT_MODID_GET(config->subport_modport); 1880 portid = BCM_GPORT_MODPORT_PORT_GET(config->subport_modport); 1881 /* Check if the supplied CoE-(mod,port) is valid */ 1882 if(_bcm_stk_aux_modport_valid(unit, BCM_MODID_TYPE_COE, 1883 modid, portid) != BCM_E_NONE) { 1884 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1885 (BSL_META_U(unit,"ERROR: Supplied (mod,port) (%d,%d) " 1886 "not valid\n"), 1887 modid, portid)); 1888 return BCM_E_PARAM; 1889 } 1890 1891 } else { 1892 rv = _bcm_coe_subport_allocate_modport(unit, &modid, &portid); 1893 if(rv != BCM_E_NONE) { 1894 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1895 (BSL_META_U(unit,"ERROR: Free CoE (mod,port) " 1896 "not found\n"))); 1897 return rv; 1898 } 1899 /* Put together a CoE-MODPORT for subsequent use */ 1900 BCM_GPORT_MODPORT_SET(config->subport_modport, modid, portid); 1901 1902 } 1903 1904 /* Find a free entry in SUBPORT_TAG_SGPP_MAPm table */ 1905 mem = SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP_MEM(unit); 1906 rv = _bcm_coe_subport_free_entry_find(unit, &subtag_index); 1907 if (SOC_FAILURE(rv)) { 1908 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1909 (BSL_META_U(unit,"ERROR: Free entry not found in " 1910 " subtag to sgpp map table\n"))); 1911 return rv; 1912 } 1913 1914 if (soc_mem_is_cam(unit, mem)) { 1915 subtag_hw_index = subtag_index; 1916 /* Read entry and map VLAN ID (Subtag) to (mod,port) */ 1917 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, subtag_hw_index, 1918 &subtag_to_sgpp_entry); 1919 if (BCM_FAILURE(rv)) { 1920 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1921 (BSL_META_U(unit,"SUBPORT_TAG_SGPP_MAPm read " 1922 "failed at index %d\n"), 1923 subtag_index)); 1924 return rv; 1925 } 1926 /* Make sure the entry allocated is unused*/ 1927 if (soc_mem_field32_get(unit, mem, (uint32 *)&subtag_to_sgpp_entry, 1928 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->valid)) { 1929 LOG_ERROR(BSL_LS_BCM_SUBPORT, 1930 (BSL_META_U(unit,"SUBPORT_TAG_SGPP_MAPm entry " 1931 "at index %d is been used\n"), 1932 subtag_index)); 1933 return BCM_E_FAIL; 1934 } 1935 } 1936 1937 /* Set the TAG, Namespace, (MOD,PORT), VALID and related fields */ 1938 soc_mem_field32_set(unit, mem, (uint32 *)&subtag_to_sgpp_entry, 1939 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->subport_tag, 1940 config->pkt_vlan); 1941 1942 /* Assign the physical port to the namespace */ 1943 soc_mem_field32_set(unit, mem, (uint32 *)&subtag_to_sgpp_entry, 1944 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->subport_tag_namespace, 1945 _BCM_SUBPORT_COE_GROUP_PORT_GET(config->group)); 1946 1947 /* Assign the modId and port */ 1948 1949 if (SOC_IS_TRIDENT3X(unit)) { 1950 /* In Trident3 chip,src port is SGPP(7,0), src modid is SGPP(15,8) */ 1951 soc_mem_field32_set(unit, mem, (uint32 *)&subtag_to_sgpp_entry, 1952 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->src_port, 1953 ((modid << 0x8) | portid)); 1954 } else { 1955 soc_mem_field32_set(unit, mem, (uint32 *)&subtag_to_sgpp_entry, 1956 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->src_modid, 1957 modid); 1958 1959 soc_mem_field32_set(unit, mem, (uint32 *)&subtag_to_sgpp_entry, 1960 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->src_port, 1961 portid); 1962 } 1963 1964 /* Set the 'valid' field */ 1965 soc_mem_field32_set(unit, mem, (uint32 *)&subtag_to_sgpp_entry, 1966 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->valid, 1967 1); 1968 1969 /* Setup the masks */ 1970 if (SOC_MEM_FIELD_VALID(unit, mem, 1971 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->subport_tag_mask)) { 1972 soc_mem_field32_set(unit, mem, (uint32 *)&subtag_to_sgpp_entry, 1973 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->subport_tag_mask, 1974 0xFFF); 1975 soc_mem_field32_set(unit, mem, (uint32 *)&subtag_to_sgpp_entry, 1976 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->subport_tag_namespace_mask, 1977 0x7F); 1978 } 1979 1980 /* Set PHB for the subport */ 1981 if (config->prop_flags & BCM_SUBPORT_PROPERTY_PHB) { 1982 soc_mem_field32_set(unit, mem, (uint32 *)&subtag_to_sgpp_entry, 1983 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->phb_enable, 1); 1984 soc_mem_field32_set(unit, mem, (uint32 *)&subtag_to_sgpp_entry, 1985 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->int_pri, 1986 config->int_pri); 1987 soc_mem_field32_set(unit, mem, (uint32 *)&subtag_to_sgpp_entry, 1988 SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP(unit)->cng, 1989 _BCM_COLOR_ENCODING(unit, config->color)); 1990 phb_val = 1; 1991 } 1992 1993 /* Write the entry to HW */ 1994 if (soc_mem_is_hashed(unit, mem)) { 1995 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ALL, &subtag_to_sgpp_entry); 1996 if (SOC_FAILURE(rv) && rv != SOC_E_EXISTS) { 1997 return rv; 1998 } 1999 } else { 2000 if (subtag_hw_index >= 0) { 2001 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, subtag_hw_index, 2002 &subtag_to_sgpp_entry); 2003 /* Bail on error */ 2004 if (SOC_FAILURE(rv)) { 2005 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2006 (BSL_META_U(unit,"ERROR: (VLAN id %d, port %d) " 2007 "to subtag_index %d " 2008 "map failed.\n"), 2009 vlan_id, port, subtag_index)); 2010 return rv; 2011 } 2012 } 2013 } 2014 2015 /* Map Subtag to Physical port mapping using MODPORT_MAP_SUBPORTm. 2016 * Note: subtag_index should be released below if failed. 2017 */ 2018 2019 /* Compute the (mod,port) index */ 2020 rv = _bcm_esw_src_mod_port_table_index_get(unit, modid, 2021 portid, &mod_port_index); 2022 BCM_FAILURE_CLEANUP(rv, cleanup); 2023 2024 /* Read the entry at the index and update needed fields */ 2025 mem = SUBPORT_COE_HW_MODPORT_MAP_SUBPORT_MEM(unit); 2026 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, mod_port_index, 2027 &sgpp_to_port_entry); 2028 BCM_FAILURE_CLEANUP(rv, cleanup); 2029 2030 /* Set the physical port as the destination */ 2031 soc_mem_field32_set(unit, mem, (uint32 *)&sgpp_to_port_entry, 2032 SUBPORT_COE_HW_MODPORT_MAP_SUBPORT(unit)->dest, port); 2033 /* Set the isTrunk as 0, we change if trunking is added */ 2034 soc_mem_field32_set(unit, mem, (uint32 *)&sgpp_to_port_entry, 2035 SUBPORT_COE_HW_MODPORT_MAP_SUBPORT(unit)->is_trunk, 0); 2036 /* Set 1 'enable' the entry */ 2037 soc_mem_field32_set(unit, mem, (uint32 *)&sgpp_to_port_entry, 2038 SUBPORT_COE_HW_MODPORT_MAP_SUBPORT(unit)->enable, 1); 2039 2040 /* Write the entry to HW */ 2041 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, mod_port_index, 2042 &sgpp_to_port_entry); 2043 BCM_FAILURE_CLEANUP(rv, cleanup); 2044 2045 /* Update the ports SOURCE_TRUNK_MAP entry with a default 2046 LPORT porperty */ 2047 rv = _bcm_coe_subtag_subport_default_lport_entry_set(unit, port, 2048 mod_port_index); 2049 BCM_FAILURE_CLEANUP(rv, cleanup); 2050 2051 /* With the index also update the EGR_GPP_ATTRIBUTES, with the subtag 2052 * to be used on egress. 2053 * Note: lport profile should be released below if failed. 2054 */ 2055 rv = soc_mem_field32_modify(unit, EGR_GPP_ATTRIBUTESm, 2056 mod_port_index, 2057 SUBPORT_TAGf, vlan_id); 2058 2059 /* Bail on error */ 2060 if (SOC_FAILURE(rv)) { 2061 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2062 (BSL_META_U(unit,"ERROR: (mod,port) (%d,%d) " 2063 "to physical port %d " 2064 "map failed.\n"), 2065 modid, portid, port)); 2066 BCM_FAILURE_CLEANUP(rv, cleanup_lport); 2067 } 2068 2069 /* We need to reserve a egress-object for this subport */ 2070 2071 /* Allocate a next hop index */ 2072 #if defined(INCLUDE_L3) 2073 bcm_l3_egress_t_init(&nh_info); 2074 2075 rv = bcm_xgs3_nh_add(unit, _BCM_L3_SHR_MATCH_DISABLE | 2076 _BCM_L3_SHR_WRITE_DISABLE, &nh_info, &nh_index); 2077 2078 if (SOC_FAILURE(rv)) { 2079 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2080 (BSL_META_U(unit,"ERROR: Next hop allocation failed. " 2081 "Coe (mod,port): (%d,%d), physical port %d"), 2082 modid, portid, port)); 2083 BCM_FAILURE_CLEANUP(rv, cleanup_lport); 2084 } 2085 2086 sal_memset(&egr_nh, 0, sizeof(egr_l3_next_hop_entry_t)); 2087 2088 /* SD-tag entry type */ 2089 if (SOC_IS_TRIDENT3X(unit)) { 2090 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 2091 DATA_TYPEf, 2); 2092 } else { 2093 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 2094 ENTRY_TYPEf, 2); 2095 } 2096 2097 /* Setup the mod, port associated with the NH entry */ 2098 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 2099 SD_TAG__HG_MC_DST_MODIDf, modid); 2100 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 2101 SD_TAG__HG_MC_DST_PORT_NUMf, portid); 2102 2103 /* Write EGR_L3_NEXT_HOP entry */ 2104 rv = soc_mem_write(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ALL, 2105 nh_index, &egr_nh); 2106 if (SOC_FAILURE(rv)) { 2107 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2108 (BSL_META_U(unit,"ERROR: Next hop update failed. " 2109 "Coe (mod,port): (%d,%d), " 2110 "physical port %d"), 2111 modid, portid, port)); 2112 BCM_FAILURE_CLEANUP(rv, cleanup_nh); 2113 } 2114 2115 /* Adjust the offset and assign the nh_index */ 2116 _bcm_subtag_subport_port_info[unit][subtag_index].nh_index = 2117 BCM_XGS3_DVP_EGRESS_IDX_MIN(unit) + nh_index; 2118 #endif 2119 2120 /* Update software book keeping. 2121 * Note: subtag_index, nh_index and software book keeping 2122 * should be released below if failed. 2123 */ 2124 2125 #ifdef BCM_TRIDENT3_SUPPORT 2126 if (soc_mem_is_hashed(unit, SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP_MEM(unit))) { 2127 /* Search the hash table for hw index */ 2128 sal_memset(subtag_to_sgpp_key, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 2129 soc_SUBPORT_ID_TO_SGPP_MAPm_field32_set(unit, &subtag_to_sgpp_key, 2130 BASE_VALIDf, 1); 2131 soc_SUBPORT_ID_TO_SGPP_MAPm_field32_set(unit, &subtag_to_sgpp_key, 2132 SUBPORT_ID_NAMESPACEf, 2133 _BCM_SUBPORT_COE_GROUP_PORT_GET(config->group)); 2134 soc_SUBPORT_ID_TO_SGPP_MAPm_field32_set(unit, &subtag_to_sgpp_key, 2135 SUBPORT_IDf, 2136 config->pkt_vlan); 2137 rv = (soc_mem_search(unit, SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP_MEM(unit), 2138 MEM_BLOCK_ANY, 2139 &subtag_hw_index, &subtag_to_sgpp_key, &subtag_to_sgpp_entry, 0)); 2140 BCM_FAILURE_CLEANUP(rv, cleanup_nh); 2141 } 2142 #endif 2143 /* Update bitmap to indicate the subtag/vlan_id is now in use, 2144 for this port */ 2145 _BCM_COE_SUBTAG_VLAN_ID_USED_SET(unit, port, vlan_id); 2146 2147 /* Encode our outgoing parameter as GPORT_SUBPORT type and 2148 fill in the associated (mod,port) */ 2149 _BCM_SUBPORT_COE_PORT_ID_SET(*gport, modid, portid); 2150 2151 /* Set the bit on the outgoing param indicating this is subtag type */ 2152 _BCM_SUBPORT_COE_PORT_TYPE_SET(*gport, _BCM_SUBPORT_COE_TYPE_SUBTAG); 2153 2154 /* Save the related port info indexed by the subtag_index */ 2155 _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_SET(unit, subtag_index, subtag_hw_index, 2156 config->group, config->pkt_vlan, *gport, config->subport_modport, 2157 phb_val, config->int_pri, config->color, TRUE, mod_port_index); 2158 2159 /* Increment number of subports on this group */ 2160 *(_bcm_subport_group_subport_port_count[unit] + sp_group_idx) += 1; 2161 2162 rv = _bcm_coe_subtag_subport_default_egr_lport_entry_set(unit, *gport); 2163 BCM_FAILURE_CLEANUP(rv, cleanup_nh); 2164 2165 #ifdef BCM_WARM_BOOT_SUPPORT 2166 SOC_CONTROL_LOCK(unit); 2167 SOC_CONTROL(unit)->scache_dirty = 1; 2168 SOC_CONTROL_UNLOCK(unit); 2169 #endif 2170 return rv; 2171 2172 /* Free/invalidate the resources that have been allocated.*/ 2173 cleanup_nh: 2174 #if defined(INCLUDE_L3) 2175 bcm_xgs3_nh_del(unit, 0, nh_index); 2176 #endif 2177 2178 _BCM_COE_SUBTAG_VLAN_ID_USED_CLR(unit, port, vlan_id); 2179 2180 _bcm_subtag_subport_port_info[unit][subtag_index].nh_index = -1; 2181 *(_bcm_subport_group_subport_port_count[unit] + sp_group_idx) -= 1; 2182 2183 _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_SET(unit, subtag_index, subtag_hw_index, 2184 BCM_GPORT_INVALID, 2185 BCM_VLAN_INVALID, 2186 -1, -1, -1, -1, -1, FALSE, -1); 2187 2188 cleanup_lport: 2189 _bcm_coe_subtag_subport_lport_entry_delete(unit, mod_port_index); 2190 2191 cleanup: 2192 /* Free/invalidate the SUBPORT_TAG_SGPP_MAP table entry */ 2193 /* coverity[check_return : FALSE] */ 2194 soc_mem_field32_modify(unit, SUBPORT_COE_HW_SUBPORT_SUBTAG_SGPP_MEM(unit), 2195 subtag_hw_index, VALIDf, 0); 2196 return rv; 2197 } 2198 2199 2200 /* 2201 * Function: 2202 * bcmi_xgs5_subport_coe_port_add 2203 * Purpose: 2204 * Add a subport to a subport group 2205 * Parameters: 2206 * unit - (IN) Device Number 2207 * config - (IN) Subport config information 2208 * port - (OUT) Subport_port GPORT (generic port) identifier 2209 * Returns: 2210 * BCM_E_XXX 2211 */ 2212 2213 int bcmi_xgs5_subport_coe_port_add(int unit, bcm_subport_config_t *config, 2214 bcm_gport_t *port) 2215 { 2216 int rv = BCM_E_NONE; 2217 uint16 group_id; 2218 soc_info_t *si = &SOC_INFO(unit); 2219 2220 _BCM_SUBPORT_COE_CHECK_INIT(unit); 2221 2222 if (!BCM_GPORT_IS_SUBPORT_GROUP(config->group)) { 2223 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2224 (BSL_META_U(unit,"ERROR: config->group 0x%x is not " 2225 "subport group gport\n"), 2226 config->group)); 2227 return BCM_E_PARAM; 2228 } 2229 2230 group_id = _BCM_SUBPORT_COE_GROUP_ID_GET(config->group); 2231 if(!_BCM_SUBPORT_COE_GROUP_USED_GET(unit, group_id)) { 2232 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2233 (BSL_META_U(unit,"ERROR:config->group 0x%x " 2234 "is not found\n"), config->group)); 2235 return BCM_E_NOT_FOUND; 2236 } 2237 2238 if (_bcm_subport_coe_port_count[unit] == si->max_subport_coe_ports) { 2239 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2240 (BSL_META_U(unit,"ERROR:All %d subport's in use\n"), 2241 si->max_subport_coe_ports)); 2242 return BCM_E_FULL; 2243 } 2244 2245 _BCM_SUBPORT_COE_LOCK(unit); 2246 2247 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 2248 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(config->group)) { 2249 if (BCM_PBMP_IS_NULL(si->subtag_pbm)) { 2250 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2251 (BSL_META_U(unit,"ERROR: SubTag ports not " 2252 "configured\n"))); 2253 _BCM_SUBPORT_COE_UNLOCK(unit); 2254 return BCM_E_PARAM; 2255 } 2256 rv = _bcm_coe_subtag_subport_port_add(unit, config, port); 2257 } 2258 2259 if (SOC_FAILURE(rv)) { 2260 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2261 (BSL_META_U(unit,"ERROR: Subport port add failed. " 2262 "rv = %d(%s)\n"), 2263 rv, soc_errmsg(rv))); 2264 _BCM_SUBPORT_COE_UNLOCK(unit); 2265 return rv; 2266 } 2267 2268 _BCM_SUBPORT_COE_UNLOCK(unit); 2269 2270 #ifdef BCM_WARM_BOOT_SUPPORT 2271 SOC_CONTROL_LOCK(unit); 2272 SOC_CONTROL(unit)->scache_dirty = 1; 2273 SOC_CONTROL_UNLOCK(unit); 2274 #endif 2275 2276 return rv; 2277 } 2278 2279 int bcmi_xgs5_subport_coe_port_traverse(int unit, 2280 bcm_subport_port_traverse_cb cb, 2281 void *user_data) 2282 { 2283 int i = 0, rv; 2284 bcm_subport_config_t config; 2285 soc_info_t *si = &SOC_INFO(unit); 2286 2287 if(_bcm_subtag_subport_port_info[unit] == NULL) { 2288 return BCM_E_NONE; 2289 } 2290 2291 for (i=0; i < si->max_subport_coe_ports; i++) { 2292 if(_bcm_subtag_subport_port_info[unit][i].valid) { 2293 2294 bcm_subport_config_t_init(&config); 2295 2296 rv = _bcm_coe_subtag_subport_port_get(unit, 2297 _bcm_subtag_subport_port_info[unit][i].subport_port, 2298 &config); 2299 2300 if (BCM_FAILURE(rv)) { 2301 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2302 (BSL_META_U(unit,"ERROR: subport port traverse failed \n" 2303 "to get SubTag subport id %d index: %d\n"), 2304 _bcm_subtag_subport_port_info[unit][i].subport_port, i)); 2305 return rv; 2306 } 2307 2308 rv = cb(unit, 2309 _bcm_subtag_subport_port_info[unit][i].subport_port, 2310 &config, 2311 user_data); 2312 2313 COMPILER_REFERENCE(rv); 2314 2315 #ifdef BCM_CB_ABORT_ON_ERR 2316 if (BCM_FAILURE(rv) && SOC_CB_ABORT_ON_ERR(unit)) { 2317 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2318 (BSL_META_U(unit,"ERROR: subport port traverse failed \n" 2319 "to callback for subport port " 2320 "(subport_port id %d)\n"), 2321 _bcm_subtag_subport_port_info[unit][i].subport_port)); 2322 return rv; 2323 } 2324 #endif 2325 } 2326 } 2327 2328 return BCM_E_NONE; 2329 } 2330 2331 /* 2332 * Function: 2333 * _bcm_coe_subtag_subport_cleanup 2334 * Purpose: 2335 * Delate all valid subport ports and all valid subport groups. 2336 Also clean up software resources. 2337 * Parameters: 2338 * unit - Device Number 2339 * Returns: 2340 * BCM_E_XXX 2341 */ 2342 int _bcm_coe_subtag_subport_cleanup(int unit) 2343 { 2344 int group_id = 0, rv = BCM_E_NONE, i = 0; 2345 bcm_port_t port; 2346 bcm_gport_t subport_group; 2347 soc_mem_t mem; 2348 soc_info_t *si = &SOC_INFO(unit); 2349 2350 _BCM_SUBPORT_COE_CHECK_INIT(unit); 2351 2352 /* Delete all SubTag subport ports */ 2353 for (i=0; i < si->max_subport_coe_ports; i++) { 2354 2355 if (!_BCM_SUBPORT_COE_SUBTAG_PORT_INFO_VALID_GET(unit, i)) { 2356 continue; 2357 } 2358 2359 rv = _bcm_coe_subtag_subport_port_delete(unit, 2360 _bcm_subtag_subport_port_info[unit][i].subport_port); 2361 if (SOC_FAILURE(rv)) { 2362 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2363 (BSL_META_U(unit,"ERROR: SubTag subport port " 2364 "delete failed (subport id %d)\n"), 2365 _bcm_subtag_subport_port_info[unit][i].subport_port)); 2366 return rv; 2367 } 2368 2369 subport_group = 2370 _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_GROUP_GET(unit, i); 2371 2372 group_id = _BCM_SUBPORT_COE_GROUP_ID_GET(subport_group); 2373 2374 if (*(_bcm_subport_group_subport_port_count[unit] + group_id) == 0) { 2375 /* delete the subport group */ 2376 _bcm_subport_group_count[unit]--; 2377 _BCM_SUBPORT_COE_GROUP_USED_CLR(unit, group_id); 2378 _bcm_subtag_subport_group_count[unit]--; 2379 _BCM_SUBPORT_COE_SUBTAG_GROUP_USED_CLR(unit, group_id); 2380 } 2381 } 2382 2383 /* Unset the 'Cascaded' type on port */ 2384 BCM_PBMP_ITER(SOC_INFO(unit).subtag_pbm, port) { 2385 mem = SUBPORT_COE_HW_ING_PORT_MEM(unit); 2386 if (SOC_MEM_FIELD_VALID(unit, mem, 2387 SUBPORT_COE_HW_ING_PORT(unit)->port_type)) { 2388 BCM_IF_ERROR_RETURN(soc_mem_field32_modify 2389 (unit, mem, 2390 port, 2391 SUBPORT_COE_HW_ING_PORT(unit)->port_type, 2392 _BCM_COE_PORT_TYPE_ETHERNET)); 2393 } 2394 2395 mem = SUBPORT_COE_HW_EGR_PORT_MEM(unit); 2396 if (SOC_MEM_FIELD_VALID(unit, mem, 2397 SUBPORT_COE_HW_EGR_PORT(unit)->port_type)) { 2398 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, mem, port, 2399 SUBPORT_COE_HW_EGR_PORT(unit)->port_type, 2400 _BCM_COE_PORT_TYPE_ETHERNET)); 2401 } 2402 } 2403 2404 return BCM_E_NONE; 2405 } 2406 2407 /* 2408 * Function: 2409 * bcmi_xgs5_subport_coe_cleanup 2410 * Purpose: 2411 * Delate all valid subport ports and all valid subport groups. 2412 Also clean up software resources. 2413 * Parameters: 2414 * unit - Device Number 2415 * Returns: 2416 * BCM_E_XXX 2417 */ 2418 int bcmi_xgs5_subport_coe_cleanup(int unit) 2419 { 2420 2421 int rv = BCM_E_NONE; 2422 soc_info_t *si = &SOC_INFO(unit); 2423 2424 _BCM_SUBPORT_COE_CHECK_INIT(unit); 2425 2426 if (0 == SOC_HW_ACCESS_DISABLE(unit)) { 2427 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 2428 if (BCM_PBMP_NOT_NULL(si->subtag_allowed_pbm)) { 2429 rv = _bcm_coe_subtag_subport_cleanup(unit); 2430 if (SOC_FAILURE(rv)) { 2431 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2432 (BSL_META_U(unit,"ERROR: SubTag cleanup failed\n"))); 2433 return rv; 2434 } 2435 } 2436 } 2437 } 2438 2439 bcmi_xgs5_subport_free_resource(unit); 2440 2441 return BCM_E_NONE; 2442 } 2443 2444 /* 2445 * Function: 2446 * bcmi_xgs5_subport_egr_subtag_dot1p_map_add 2447 * Purpose: 2448 * Map the egress SubTag CoE packet's PHB (internal priority and color) 2449 * to subport tag's 'Priority' and 'Color'. 2450 * Parameters: 2451 * unit - (IN) Device Number 2452 * map - (IN) qos map 2453 * Returns: 2454 * BCM_E_XXX 2455 */ 2456 2457 int bcmi_xgs5_subport_egr_subtag_dot1p_map_add(int unit, 2458 bcm_qos_map_t *map) 2459 { 2460 soc_mem_t mem; 2461 int index; 2462 uint32 tab_ent[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer. */ 2463 2464 mem = SUBPORT_COE_HW_EGR_SUBPORT_TAG_DOT1P_MEM(unit); 2465 2466 if (!soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 2467 return BCM_E_UNAVAIL; 2468 } 2469 2470 if (map->etag_pcp > 7 || 2471 map->etag_de > 1 || 2472 map->int_pri < 0 || map->int_pri > 15 || 2473 ((map->color != bcmColorGreen) && 2474 (map->color != bcmColorYellow) && 2475 (map->color != bcmColorRed))) { 2476 return BCM_E_PARAM; 2477 } 2478 2479 /* EGR_SUBPORT_TAG_DOT1P_MAPm table is indexed with 2480 * internal priority - 4 bits [5:2] and color - 2 bits[1:0] 2481 */ 2482 index = ((map->int_pri << 2) | map->color) & soc_mem_index_max(unit, mem); 2483 2484 sal_memset(tab_ent, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 2485 soc_mem_field32_set(unit, mem, tab_ent, 2486 SUBPORT_COE_HW_EGR_SUBPORT_TAG_DOT1P(unit)->subport_tag_priority, 2487 map->etag_pcp); 2488 if (SOC_IS_TRIDENT3X(unit)) { 2489 /* TD3 only supports 4-byte SUBPORT-TAG */ 2490 soc_mem_field32_set(unit, mem, tab_ent, 2491 SUBPORT_COE_HW_EGR_SUBPORT_TAG_DOT1P(unit)->subport_tag_cfi, 2492 map->etag_de); 2493 } else { 2494 soc_mem_field32_set(unit, mem, tab_ent, 2495 SUBPORT_COE_HW_EGR_SUBPORT_TAG_DOT1P(unit)->subport_tag_color, 2496 map->color); 2497 soc_mem_field32_set(unit, mem, tab_ent, 2498 SUBPORT_COE_HW_EGR_SUBPORT_TAG_DOT1P(unit)->subport_tag_cfi, 2499 map->etag_de); 2500 } 2501 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, 2502 tab_ent)); 2503 return BCM_E_NONE; 2504 } 2505 2506 /* 2507 * Function: 2508 * bcmi_xgs5_subport_egr_subtag_dot1p_map_delete 2509 * Purpose: 2510 * Delete the map the egress SubTag CoE packet's 2511 * PHB (internal priority and color) 2512 * to subport tag's 'Priority' and 'Color'. 2513 * Parameters: 2514 * unit - (IN) Device Number 2515 * map - (IN) qos map 2516 * Returns: 2517 * BCM_E_XXX 2518 */ 2519 int 2520 bcmi_xgs5_subport_egr_subtag_dot1p_map_delete(int unit, 2521 bcm_qos_map_t *map) 2522 { 2523 soc_mem_t mem; 2524 int index; 2525 uint32 tab_ent[SOC_MAX_MEM_FIELD_WORDS]; /* HW entry buffer. */ 2526 2527 mem = SUBPORT_COE_HW_EGR_SUBPORT_TAG_DOT1P_MEM(unit); 2528 2529 if (!soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 2530 return BCM_E_UNAVAIL; 2531 } 2532 2533 if (map->etag_pcp > 7 || 2534 map->etag_de > 1 || 2535 map->int_pri < 0 || map->int_pri > 15 || 2536 ((map->color != bcmColorGreen) && 2537 (map->color != bcmColorYellow) && 2538 (map->color != bcmColorRed))) { 2539 return BCM_E_PARAM; 2540 } 2541 2542 /* EGR_SUBPORT_TAG_DOT1P_MAPm table is indexed with 2543 * internal priority - 4 bits [5:2] and color - 2 bits[1:0] 2544 */ 2545 index = ((map->int_pri << 2) | map->color) & soc_mem_index_max(unit, mem); 2546 2547 sal_memset(tab_ent, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 2548 soc_mem_field32_set(unit, mem, tab_ent, 2549 SUBPORT_COE_HW_EGR_SUBPORT_TAG_DOT1P(unit)->subport_tag_priority, 0); 2550 soc_mem_field32_set(unit, mem, tab_ent, 2551 SUBPORT_COE_HW_EGR_SUBPORT_TAG_DOT1P(unit)->subport_tag_cfi, 0); 2552 /* Trident3 only support 4-byte SUBPORT-TAG */ 2553 if (!SOC_IS_TRIDENT3X(unit)) { 2554 soc_mem_field32_set(unit, mem, tab_ent, 2555 SUBPORT_COE_HW_EGR_SUBPORT_TAG_DOT1P(unit)->subport_tag_color, 0); 2556 } 2557 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, 2558 tab_ent)); 2559 return BCM_E_NONE; 2560 } 2561 2562 /* 2563 * Function: 2564 * bcmi_xgs5_subport_subtag_port_tpid_set 2565 * Description: 2566 * Set the default Tag Protocol ID for a SubTag port. 2567 * Parameters: 2568 * unit - (IN) Device number 2569 * gport - (IN) SubTag group gport (Ignored) 2570 * tpid - (IN) Tag Protocol ID 2571 * Return Value: 2572 * BCM_E_XXX 2573 */ 2574 2575 2576 2577 int 2578 bcmi_xgs5_subport_subtag_port_tpid_set(int unit, 2579 bcm_gport_t gport, 2580 uint16 tpid) 2581 { 2582 uint32 regval = 0; 2583 soc_reg_t reg; 2584 2585 reg = SUBPORT_TAG_TPIDr; 2586 2587 if (!(soc_reg_field_valid(unit, reg, TPIDf) || 2588 soc_reg_field_valid(unit, reg, ENABLEf))) { 2589 return BCM_E_UNAVAIL; 2590 } 2591 2592 soc_reg_field_set(unit, reg, ®val, TPIDf, tpid); 2593 soc_reg_field_set(unit, reg, ®val, ENABLEf, 1); 2594 2595 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, regval)); 2596 2597 reg = EGR_SUBPORT_TAG_TPIDr; 2598 if (!(soc_reg_field_valid(unit, reg, TPID_8BYTE_TAGf) || 2599 soc_reg_field_valid(unit, reg, TPID_4BYTE_TAGf))) { 2600 return BCM_E_UNAVAIL; 2601 } 2602 2603 soc_reg_field_set(unit, reg, ®val, TPID_8BYTE_TAGf, tpid); 2604 soc_reg_field_set(unit, reg, ®val, TPID_4BYTE_TAGf, tpid); 2605 2606 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, regval)); 2607 2608 return BCM_E_NONE; 2609 } 2610 2611 /* 2612 * Function: 2613 * bcmi_xgs5_subport_subtag_port_tpid_get 2614 * Description: 2615 * Retrieve the default Tag Protocol ID for a SubTag port. 2616 * Parameters: 2617 * unit - (IN) Device number 2618 * gport - (IN)SubTag group gport (Ignored) 2619 * tpid - (OUT) Tag Protocol ID 2620 * Return Value: 2621 * BCM_E_XXX 2622 */ 2623 2624 int 2625 bcmi_xgs5_subport_subtag_port_tpid_get(int unit, 2626 bcm_gport_t gport, 2627 uint16 *tpid) 2628 { 2629 uint32 regval = 0; 2630 soc_reg_t reg; 2631 2632 reg = SUBPORT_TAG_TPIDr; 2633 SOC_IF_ERROR_RETURN( 2634 soc_reg32_get(unit, reg, REG_PORT_ANY, 0, ®val)); 2635 2636 if(soc_reg_field_get(unit, reg, regval, VALIDf)) { 2637 *tpid = soc_reg_field_get(unit, reg, regval, TPIDf); 2638 return BCM_E_NONE; 2639 } 2640 2641 return BCM_E_UNAVAIL; 2642 } 2643 2644 2645 /* 2646 * Function: 2647 * bcmi_xgs5_subport_subtag_port_tpid_delete 2648 * Description: 2649 * Delete allowed TPID for a SubTag port. 2650 * Parameters: 2651 * unit - (IN) Device number 2652 * gport - (IN) SubTag group gport (Ignored) 2653 * tpid - (IN) Tag Protocol ID 2654 * Return Value: 2655 * BCM_E_XXX 2656 */ 2657 2658 int 2659 bcmi_xgs5_subport_subtag_port_tpid_delete(int unit, 2660 bcm_gport_t gport, 2661 uint16 tpid) 2662 { 2663 uint32 regval = 0; 2664 soc_reg_t reg; 2665 2666 reg = SUBPORT_TAG_TPIDr; 2667 if (!(soc_reg_field_valid(unit, reg, TPIDf) || 2668 soc_reg_field_valid(unit, reg, ENABLEf))) { 2669 return BCM_E_UNAVAIL; 2670 } 2671 2672 soc_reg_field_set(unit, reg, ®val, TPIDf, 0); 2673 soc_reg_field_set(unit, reg, ®val, ENABLEf, 0); 2674 2675 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, regval)); 2676 2677 reg = EGR_SUBPORT_TAG_TPIDr; 2678 if (!(soc_reg_field_valid(unit, reg, TPID_8BYTE_TAGf) || 2679 soc_reg_field_valid(unit, reg, TPID_4BYTE_TAGf))) { 2680 return BCM_E_UNAVAIL; 2681 } 2682 2683 soc_reg_field_set(unit, reg, ®val, TPID_8BYTE_TAGf, 0); 2684 soc_reg_field_set(unit, reg, ®val, TPID_4BYTE_TAGf, 0); 2685 2686 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, regval)); 2687 2688 return BCM_E_NONE; 2689 } 2690 2691 /* 2692 * Function: 2693 * bcmi_xgs5_port_control_subtag_status_set 2694 * Description: 2695 * Set the SubTag status for a given port. 2696 * Parameters: 2697 * unit - (IN) Device number 2698 * port - (IN) port 2699 * value - (IN) Enable/Disable status 2700 * Return Value: 2701 * BCM_E_XXX 2702 * Note: The application need to delete all subport groups/ports, if any, 2703 * before disabling the SubTag CoE for given port. 2704 */ 2705 2706 int bcmi_xgs5_port_control_subtag_status_set(int unit, 2707 bcm_port_t port, int value) 2708 { 2709 int rv = BCM_E_NONE; 2710 /* int start = 0, end = 0; */ 2711 uint32 port_type; 2712 soc_info_t *si = &SOC_INFO(unit); 2713 2714 _BCM_SUBPORT_COE_CHECK_INIT(unit); 2715 2716 if (!soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 2717 return BCM_E_UNAVAIL; 2718 } 2719 2720 if (!BCM_PBMP_MEMBER(si->subtag_allowed_pbm, port)) { 2721 return BCM_E_PORT; 2722 } 2723 _BCM_SUBPORT_COE_LOCK(unit); 2724 2725 port_type = value ? _BCM_COE_PORT_TYPE_CASCADED : 2726 _BCM_COE_PORT_TYPE_ETHERNET; 2727 2728 rv = _bcm_esw_port_tab_set(unit, port, 2729 _BCM_CPU_TABS_NONE, PORT_TYPEf, port_type); 2730 2731 if (BCM_FAILURE(rv)) { 2732 _BCM_SUBPORT_COE_UNLOCK(unit); 2733 return rv; 2734 } 2735 rv = _bcm_esw_egr_port_tab_set(unit, port, 2736 PORT_TYPEf, port_type); 2737 if (BCM_FAILURE(rv)) { 2738 _BCM_SUBPORT_COE_UNLOCK(unit); 2739 return rv; 2740 } 2741 2742 2743 2744 2745 /* start = si->port_subport_base[port] - KT2_MIN_SUBPORT_INDEX; 2746 end = start + si->port_num_subport[port] - 1; 2747 */ 2748 if (value) { 2749 BCM_PBMP_PORT_ADD(si->subtag_pbm, port); 2750 BCM_PBMP_PORT_ADD(si->subtag.bitmap, port); 2751 /**** 2752 SOC_IF_ERROR_RETURN 2753 (soc_kt2_cosq_port_coe_linkphy_status_set(unit, port, 1)); 2754 SOC_IF_ERROR_RETURN 2755 (soc_kt2_cosq_s1_range_set(unit, port, start, end, 0)); 2756 SOC_IF_ERROR_RETURN 2757 (soc_kt2_cosq_repl_map_set(unit, port, start, end, 1)); 2758 */ 2759 } else { 2760 if (BCM_PBMP_MEMBER(si->subtag_pbm, port)) { 2761 BCM_PBMP_PORT_REMOVE(si->subtag_pbm, port); 2762 BCM_PBMP_PORT_REMOVE(si->subtag.bitmap, port); 2763 /**** 2764 SOC_IF_ERROR_RETURN 2765 (soc_kt2_cosq_port_coe_linkphy_status_set(unit, port, 0)); 2766 SOC_IF_ERROR_RETURN 2767 (soc_kt2_cosq_s1_range_set(unit, port, 0, 0, 0)); 2768 SOC_IF_ERROR_RETURN 2769 (soc_kt2_cosq_repl_map_set(unit, port, start, end, 0)); 2770 */ 2771 } 2772 } 2773 _BCM_SUBPORT_COE_UNLOCK(unit); 2774 return rv; 2775 } 2776 /* 2777 * Function: 2778 * bcmi_xgs5_port_control_subtag_status_get 2779 * Description: 2780 * Get the SubTag status for a given port. 2781 * Parameters: 2782 * unit - (IN) Device number 2783 * port - (IN) port 2784 * value - (OUT) Enable/Disable status 2785 * Return Value: 2786 * BCM_E_XXX 2787 */ 2788 2789 int bcmi_xgs5_port_control_subtag_status_get(int unit, 2790 bcm_port_t port, 2791 int *value) 2792 { 2793 int rv = BCM_E_NONE; 2794 soc_mem_t mem; 2795 soc_info_t *si = &SOC_INFO(unit); 2796 port_tab_entry_t port_tab_entry; 2797 2798 _BCM_SUBPORT_COE_CHECK_INIT(unit); 2799 2800 if (!soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 2801 return BCM_E_UNAVAIL; 2802 } 2803 if (!BCM_PBMP_MEMBER(si->subtag_allowed_pbm, port)) { 2804 return BCM_E_PORT; 2805 } 2806 2807 _BCM_SUBPORT_COE_LOCK(unit); 2808 2809 *value = 0; 2810 mem = SUBPORT_COE_HW_ING_PORT_MEM(unit); 2811 2812 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, 2813 &port_tab_entry); 2814 if (SOC_FAILURE(rv)) { 2815 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2816 (BSL_META_U(unit,"ERROR:PORT_TABLEm read failed\n"))); 2817 _BCM_SUBPORT_COE_UNLOCK(unit); 2818 return rv; 2819 } 2820 if ((soc_mem_field32_get(unit, mem, &port_tab_entry, 2821 PORT_TYPEf) == _BCM_COE_PORT_TYPE_CASCADED)) { 2822 *value = 1; 2823 } 2824 2825 _BCM_SUBPORT_COE_UNLOCK(unit); 2826 2827 return rv; 2828 } 2829 2830 /* 2831 * Function: 2832 * _bcmi_xgs5_subport_group_resolve 2833 * Purpose: 2834 * Resolve physical port associated with the subtag subport group 2835 */ 2836 2837 int 2838 _bcmi_xgs5_subport_group_resolve(int unit, 2839 bcm_gport_t subport_group_gport, 2840 bcm_module_t *modid, bcm_port_t *port, 2841 bcm_trunk_t *trunk_id, int *id) 2842 2843 { 2844 bcm_module_t my_modid; 2845 uint16 group_id; 2846 2847 _BCM_SUBPORT_COE_CHECK_INIT(unit); 2848 2849 *modid = -1; 2850 *port = -1; 2851 *id = -1; 2852 *trunk_id = BCM_TRUNK_INVALID; 2853 2854 if (!BCM_GPORT_IS_SUBPORT_GROUP(subport_group_gport)) { 2855 LOG_WARN(BSL_LS_BCM_SUBPORT, 2856 (BSL_META_U(unit,"gport 0x%x is not subport gport\n"), 2857 subport_group_gport)); 2858 return BCM_E_NONE; 2859 } 2860 2861 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 2862 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_GROUP(subport_group_gport))) { 2863 2864 group_id = _BCM_SUBPORT_COE_GROUP_ID_GET(subport_group_gport); 2865 if(!_BCM_SUBPORT_COE_GROUP_USED_GET(unit, group_id)) { 2866 LOG_WARN(BSL_LS_BCM_SUBPORT, 2867 (BSL_META_U(unit,"subport gport 0x%x is not used\n"), 2868 subport_group_gport)); 2869 return BCM_E_NONE; 2870 } 2871 2872 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 2873 *modid = my_modid; 2874 *port = _BCM_SUBPORT_COE_GROUP_PORT_GET(subport_group_gport); 2875 } else if (soc_feature(unit, soc_feature_subport_enhanced)) { 2876 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 2877 return _bcm_tr2_subport_group_resolve(unit, subport_group_gport, 2878 modid, port, trunk_id,id); 2879 #endif 2880 } else if (soc_feature(unit, soc_feature_subport)) { 2881 #if defined (BCM_TRX_SUPPORT) && defined(INCLUDE_L3) 2882 return _bcm_tr_subport_group_resolve(unit, subport_group_gport, 2883 modid, port, trunk_id, id); 2884 #endif 2885 } 2886 2887 return BCM_E_NONE; 2888 } 2889 2890 2891 /* 2892 * Function: 2893 * _bcmi_coe_subport_physical_port_get 2894 * Purpose: 2895 * Given a subport-group/subport-port GPORT, return the physical port 2896 */ 2897 int 2898 _bcmi_coe_subport_physical_port_get(int unit, bcm_gport_t subport, 2899 int *local_port) 2900 { 2901 int i = 0; 2902 soc_info_t *si = &SOC_INFO(unit); 2903 2904 if(_bcm_subtag_subport_port_info[unit] == NULL) { 2905 return BCM_E_NOT_FOUND; 2906 } 2907 2908 if (BCM_GPORT_IS_SET(subport)) { 2909 if (BCM_GPORT_IS_SUBPORT_PORT(subport)) { 2910 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, subport)){ 2911 2912 /* Find the entry corresponding to the subport */ 2913 for (i = 0; i < si->max_subport_coe_ports; i++) { 2914 if((_bcm_subtag_subport_port_info[unit][i].valid) && 2915 (_bcm_subtag_subport_port_info[unit][i].subport_port == 2916 subport)) { 2917 /* Entry found, break */ 2918 break; 2919 } 2920 } 2921 2922 /* If not found, return */ 2923 if (i == si->max_subport_coe_ports) { 2924 return BCM_E_PORT; 2925 } 2926 2927 /* Get the physical port associated with the subport-group in 2928 question */ 2929 2930 *local_port = _BCM_SUBPORT_COE_GROUP_PORT_GET( 2931 _bcm_subtag_subport_port_info[unit][i].group); 2932 } else if (BCM_GPORT_IS_SUBPORT_GROUP(subport)) { 2933 *local_port = _BCM_SUBPORT_COE_GROUP_PORT_GET(subport); 2934 } 2935 } 2936 } 2937 2938 return BCM_E_NONE; 2939 } 2940 2941 /* 2942 * Function: 2943 * _bcmi_coe_subport_mod_port_physical_port_get 2944 * Purpose: 2945 * Given a coe-(mod,port), return the physical port 2946 */ 2947 int 2948 _bcmi_coe_subport_mod_port_physical_port_get(int unit, bcm_module_t modid, bcm_port_t portid, 2949 int *local_port) 2950 { 2951 int subport_gport; 2952 2953 /* Encode type and fill in the associated (mod,port) */ 2954 _BCM_SUBPORT_COE_PORT_ID_SET(subport_gport, modid, portid); 2955 /* Set the bit on the outgoing param indicating this is subtag type */ 2956 _BCM_SUBPORT_COE_PORT_TYPE_SET(subport_gport, _BCM_SUBPORT_COE_TYPE_SUBTAG); 2957 2958 return _bcmi_coe_subport_physical_port_get(unit, subport_gport, local_port); 2959 } 2960 2961 /* 2962 * Function: 2963 * _bcm_xgs5_subport_port_resolve 2964 * Purpose: 2965 * Resolve subport_port to related (mod,port) 2966 */ 2967 2968 int 2969 _bcm_xgs5_subport_port_resolve(int unit, 2970 bcm_gport_t subport_port_gport, 2971 bcm_module_t *modid, bcm_port_t *port, 2972 bcm_trunk_t *trunk_id, int *id) 2973 { 2974 2975 #ifdef INCLUDE_L3 2976 bcm_subport_config_t config; 2977 int rv = BCM_E_NONE; 2978 2979 _BCM_SUBPORT_COE_CHECK_INIT(unit); 2980 2981 *modid = -1; 2982 *port = -1; 2983 *id = -1; 2984 *trunk_id = BCM_TRUNK_INVALID; 2985 2986 if (!BCM_GPORT_IS_SUBPORT_PORT(subport_port_gport)) { 2987 LOG_ERROR(BSL_LS_BCM_SUBPORT, 2988 (BSL_META_U(unit,"ERROR: gport 0x%x is not subport gport\n"), 2989 subport_port_gport)); 2990 return BCM_E_PARAM; 2991 } 2992 2993 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 2994 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, subport_port_gport))) { 2995 2996 bcm_subport_config_t_init(&config); 2997 rv = _bcm_coe_subtag_subport_port_get(unit, subport_port_gport, 2998 &config); 2999 if(rv == BCM_E_NONE) { 3000 *modid = _BCM_SUBPORT_COE_PORT_ID_MOD_GET(subport_port_gport); 3001 *port = _BCM_SUBPORT_COE_PORT_ID_PORT_GET(subport_port_gport); 3002 } 3003 } else if (soc_feature(unit, soc_feature_subport_enhanced)) { 3004 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 3005 return _bcm_tr2_subport_port_resolve(unit,subport_port_gport, 3006 modid, port, trunk_id, id); 3007 #endif /* defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) */ 3008 } else if (soc_feature(unit, soc_feature_subport)) { 3009 #if defined (BCM_TRX_SUPPORT) && defined(INCLUDE_L3) 3010 return _bcm_tr_subport_port_resolve(unit, subport_port_gport, 3011 modid, port, trunk_id, id); 3012 #endif 3013 } 3014 3015 return rv; 3016 3017 #else 3018 return BCM_E_UNAVAIL; 3019 #endif 3020 } 3021 3022 3023 /* 3024 * Function: 3025 * bcmi_xgs5_subport_gport_modport_get 3026 * Purpose: 3027 * Given a subport-gport, return teh corresponding mod-port 3028 * Parameters: 3029 * unit - (IN) Device Number 3030 * subport_gport - (IN) GPORT (generic port) identifier 3031 * module - (OUT) Module associated with the subport 3032 * port - (OUT) Port associated with the subport 3033 * Returns: 3034 * BCM_E_XXX 3035 */ 3036 3037 int bcmi_xgs5_subport_gport_modport_get(int unit, 3038 bcm_gport_t subport_gport, bcm_module_t *module, bcm_port_t *port) 3039 { 3040 bcm_trunk_t trunk_id; 3041 int id = 0; 3042 3043 BCM_IF_ERROR_RETURN(_bcm_xgs5_subport_port_resolve(unit, subport_gport, 3044 module, port, &trunk_id, &id)); 3045 3046 return BCM_E_NONE; 3047 } 3048 3049 /* 3050 * Function: 3051 * _bcm_xgs5_subport_gport_validate 3052 * Description: 3053 * Helper funtion to validate port/gport parameter 3054 * Parameters: 3055 * unit - (IN) BCM device number 3056 * port_in - (IN) Port / Gport to validate 3057 * port_out - (OUT) Port number if valid. 3058 * Return Value: 3059 * BCM_E_NONE - Port OK 3060 * BCM_E_PORT - Port Invalid 3061 */ 3062 int 3063 _bcm_xgs5_subport_gport_validate(int unit, bcm_port_t port_in, 3064 bcm_port_t *port_out) 3065 { 3066 if (BCM_GPORT_IS_SET(port_in)) { 3067 if (BCM_GPORT_IS_SUBPORT_PORT(port_in) && 3068 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port_in)) { 3069 return bcm_esw_port_local_get(unit, port_in, port_out); 3070 } else { 3071 return BCM_E_PORT; 3072 } 3073 } else if (SOC_PORT_VALID(unit, port_in)) { 3074 *port_out = port_in; 3075 } else { 3076 return BCM_E_PORT; 3077 } 3078 3079 return BCM_E_NONE; 3080 3081 } 3082 3083 /* 3084 * Function: 3085 * _bcmi_coe_subport_tcam_idx_get 3086 * Purpose: 3087 * Given a subport-port GPORT, return its TCAM h/w idx 3088 */ 3089 int 3090 _bcmi_coe_subport_tcam_idx_get(int unit, bcm_gport_t subport, 3091 int *hw_idx) 3092 { 3093 int i = 0; 3094 soc_info_t *si = &SOC_INFO(unit); 3095 3096 if(hw_idx == NULL) { 3097 return BCM_E_PARAM; 3098 } 3099 3100 if(_bcm_subtag_subport_port_info[unit] == NULL) { 3101 return BCM_E_NOT_FOUND; 3102 } 3103 3104 if (BCM_GPORT_IS_SET(subport)) { 3105 if (BCM_GPORT_IS_SUBPORT_PORT(subport)) { 3106 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, subport)){ 3107 3108 /* Find the entry corresponding to the subport */ 3109 for (i = 0; i < si->max_subport_coe_ports; i++) { 3110 if((_bcm_subtag_subport_port_info[unit][i].valid) && 3111 (_bcm_subtag_subport_port_info[unit][i].subport_port == 3112 subport)) { 3113 /* Entry found, break */ 3114 break; 3115 } 3116 } 3117 3118 /* If not found, return error */ 3119 if (i == si->max_subport_coe_ports) { 3120 return BCM_E_PORT; 3121 } 3122 3123 /* Get the associated hw idx */ 3124 *hw_idx = _BCM_SUBPORT_COE_SUBTAG_PORT_INFO_TCAM_HW_ID_GET(unit, i); 3125 return BCM_E_NONE; 3126 } 3127 } 3128 } 3129 3130 return BCM_E_PORT; 3131 } 3132 3133 /* 3134 * Function: 3135 * _bcmi_coe_multicast_subport_encap_get 3136 * Purpose: 3137 * Get the Encap ID for NIV virtual port. 3138 * Parameters: 3139 * unit - (IN) Unit number. 3140 * subport_port - (IN) Multicast group ID. 3141 * encap_id - (OUT) Encap ID. 3142 * Returns: 3143 * BCM_E_XXX 3144 * Notes: 3145 */ 3146 int 3147 _bcmi_coe_multicast_subport_encap_get(int unit, bcm_gport_t subport_port, 3148 bcm_if_t *encap_id) 3149 { 3150 int i = 0; 3151 soc_info_t *si = &SOC_INFO(unit); 3152 3153 if(_bcm_subtag_subport_port_info[unit] == NULL) { 3154 return BCM_E_NOT_FOUND; 3155 } 3156 3157 if (BCM_GPORT_IS_SET(subport_port)) { 3158 if (BCM_GPORT_IS_SUBPORT_PORT(subport_port)) { 3159 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, subport_port)){ 3160 3161 /* Find the entry corresponding to the subport */ 3162 for (i=0; i < si->max_subport_coe_ports; i++) { 3163 if((_bcm_subtag_subport_port_info[unit][i].valid) && 3164 (_bcm_subtag_subport_port_info[unit][i].subport_port == 3165 subport_port)) { 3166 /* Entry found, break */ 3167 break; 3168 } 3169 } 3170 3171 /* If not found, return */ 3172 if (i == si->max_subport_coe_ports) { 3173 return BCM_E_NOT_FOUND; 3174 } 3175 3176 /* Get the encap id */ 3177 *encap_id = _bcm_subtag_subport_port_info[unit][i].nh_index; 3178 return BCM_E_NONE; 3179 } 3180 } 3181 } 3182 3183 return BCM_E_NONE; 3184 } 3185 3186 int bcmi_xgs5_subport_coe_ether_type_size_set(int unit, 3187 bcm_switch_control_t type, 3188 int arg) 3189 { 3190 uint32 rval; 3191 3192 if (arg > BCMI_MAX_SHORT_VALUE || arg < 0) { 3193 return BCM_E_PARAM; 3194 } 3195 3196 #if defined(BCM_ESW_SUPPORT) && defined(BCM_IPROC_SUPPORT) 3197 if (soc_feature(unit, soc_feature_untethered_otp)) { 3198 if ((type == bcmSwitchSubportCoEEtherType) || 3199 (type == bcmSwitchSubportEgressTpid)) { 3200 /* 0x8100 is not a valid subtag tpid */ 3201 if (SOC_BOND_INFO_FEATURE_GET(unit, 3202 socBondInfoFeatureNoCoeSubtag8100) && (arg == 0x8100)) { 3203 return BCM_E_PARAM; 3204 } 3205 } 3206 } 3207 #endif /* BCM_ESW_SUPPORT && BCM_IPROC_SUPPORT */ 3208 3209 switch (type) { 3210 case bcmSwitchSubportCoEEtherType: 3211 BCM_IF_ERROR_RETURN(READ_SUBPORT_TAG_TPIDr(unit, &rval)); 3212 soc_reg_field_set(unit, SUBPORT_TAG_TPIDr, &rval, TPIDf, 3213 arg); 3214 /* If the TPID is being set to '0', clear the ENABLEf */ 3215 if(arg) { 3216 soc_reg_field_set(unit, SUBPORT_TAG_TPIDr, &rval, ENABLEf, 3217 1); 3218 } else { 3219 soc_reg_field_set(unit, SUBPORT_TAG_TPIDr, &rval, ENABLEf, 3220 0); 3221 } 3222 SOC_IF_ERROR_RETURN(WRITE_SUBPORT_TAG_TPIDr(unit, rval)); 3223 break; 3224 3225 case bcmSwitchSubportEgressTpid: 3226 BCM_IF_ERROR_RETURN(READ_EGR_SUBPORT_TAG_TPIDr(unit, &rval)); 3227 soc_reg_field_set(unit, EGR_SUBPORT_TAG_TPIDr, &rval, TPID_4BYTE_TAGf, 3228 arg); 3229 SOC_IF_ERROR_RETURN(WRITE_EGR_SUBPORT_TAG_TPIDr(unit, rval)); 3230 break; 3231 3232 case bcmSwitchSubportEgressWideTpid: 3233 BCM_IF_ERROR_RETURN(READ_EGR_SUBPORT_TAG_TPIDr(unit, &rval)); 3234 soc_reg_field_set(unit, EGR_SUBPORT_TAG_TPIDr, &rval, TPID_8BYTE_TAGf, 3235 arg); 3236 SOC_IF_ERROR_RETURN(WRITE_EGR_SUBPORT_TAG_TPIDr(unit, rval)); 3237 break; 3238 3239 default: 3240 /* Return 'BCM_E_UNAVAIL' by default */ 3241 return BCM_E_UNAVAIL; 3242 } 3243 3244 return BCM_E_NONE; 3245 } 3246 3247 int bcmi_xgs5_subport_coe_ether_type_size_get(int unit, 3248 bcm_switch_control_t type, 3249 int *arg) 3250 { 3251 uint32 rval; 3252 3253 switch (type) { 3254 case bcmSwitchSubportCoEEtherType: 3255 BCM_IF_ERROR_RETURN(READ_SUBPORT_TAG_TPIDr(unit, &rval)); 3256 *arg = soc_reg_field_get(unit, SUBPORT_TAG_TPIDr, rval, 3257 TPIDf); 3258 break; 3259 3260 case bcmSwitchSubportEgressTpid: 3261 3262 BCM_IF_ERROR_RETURN(READ_EGR_SUBPORT_TAG_TPIDr(unit, &rval)); 3263 *arg = soc_reg_field_get(unit, EGR_SUBPORT_TAG_TPIDr, rval, 3264 TPID_4BYTE_TAGf); 3265 break; 3266 3267 case bcmSwitchSubportEgressWideTpid: 3268 3269 BCM_IF_ERROR_RETURN(READ_EGR_SUBPORT_TAG_TPIDr(unit, &rval)); 3270 *arg = soc_reg_field_get(unit, EGR_SUBPORT_TAG_TPIDr, rval, 3271 TPID_8BYTE_TAGf); 3272 3273 break; 3274 3275 default: 3276 /* Return 'BCM_E_UNAVAIL' by default */ 3277 return BCM_E_UNAVAIL; 3278 } 3279 3280 return BCM_E_NONE; 3281 } 3282 3283 int bcmi_xgs5_subport_subtag_port_override_set(int unit, int port, int arg) 3284 { 3285 bcm_module_t modid; 3286 bcm_port_t portid; 3287 bcm_trunk_t trunk_id; 3288 int id = 0, index = 0, rv = BCM_E_UNAVAIL; 3289 egr_port_entry_t egr_port_entry; 3290 3291 if (arg > BCMI_MAX_SHORT_VALUE || arg < 0) { 3292 return BCM_E_PARAM; 3293 } 3294 #if defined(BCM_HGPROXY_COE_SUPPORT) 3295 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 3296 BCM_GPORT_IS_SET(port) && 3297 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) && 3298 SOC_MEM_FIELD_VALID(unit, EGR_LPORT_PROFILEm, VT_SYS_PORT_OVERRIDEf)) { 3299 return bcm_esw_port_egr_lport_field_set( 3300 unit, port, EGR_LPORT_PROFILEm, 3301 VT_SYS_PORT_OVERRIDEf, arg ? 1 : 0); 3302 } 3303 #endif 3304 3305 if(BCM_GPORT_IS_SUBPORT_PORT(port)) { 3306 /* Resolve the subport */ 3307 BCM_IF_ERROR_RETURN( 3308 _bcm_xgs5_subport_port_resolve(unit, port, &modid, &portid, 3309 &trunk_id, &id)); 3310 /* Get the associated index */ 3311 BCM_IF_ERROR_RETURN( 3312 _bcm_esw_src_mod_port_table_index_get(unit, modid, portid, 3313 &index)); 3314 } else { 3315 index = port; 3316 } 3317 3318 3319 BCM_IF_ERROR_RETURN( 3320 soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ALL, 3321 index, &egr_port_entry)); 3322 3323 soc_mem_field32_set(unit, EGR_PORTm, &egr_port_entry, 3324 VT_SYS_PORT_OVERRIDEf, arg ? 1 : 0); 3325 3326 rv = soc_mem_write(unit, EGR_PORTm, MEM_BLOCK_ALL, 3327 index, &egr_port_entry); 3328 3329 return rv; 3330 } 3331 3332 int bcmi_xgs5_subport_subtag_port_override_get(int unit, int port, int *arg) 3333 { 3334 bcm_module_t modid; 3335 bcm_port_t portid; 3336 bcm_trunk_t trunk_id; 3337 int id = 0, index = 0; 3338 egr_port_entry_t egr_port_entry; 3339 #if defined(BCM_HGPROXY_COE_SUPPORT) 3340 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 3341 BCM_GPORT_IS_SET(port) && 3342 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) && 3343 SOC_MEM_FIELD_VALID(unit, EGR_LPORT_PROFILEm, VT_SYS_PORT_OVERRIDEf)) { 3344 return bcm_esw_port_egr_lport_field_get( 3345 unit, port, EGR_LPORT_PROFILEm, 3346 VT_SYS_PORT_OVERRIDEf, (uint32 *)arg); 3347 } 3348 #endif 3349 3350 if(BCM_GPORT_IS_SUBPORT_PORT(port)) { 3351 /* Resolve the subport */ 3352 BCM_IF_ERROR_RETURN( 3353 _bcm_xgs5_subport_port_resolve(unit, port, &modid, &portid, 3354 &trunk_id, &id)); 3355 /* Get the associated index */ 3356 BCM_IF_ERROR_RETURN( 3357 _bcm_esw_src_mod_port_table_index_get(unit, modid, portid, 3358 &index)); 3359 } else { 3360 index = port; 3361 } 3362 3363 3364 BCM_IF_ERROR_RETURN(soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ALL, 3365 index, &egr_port_entry)); 3366 3367 *arg = soc_mem_field32_get(unit, EGR_PORTm, &egr_port_entry, 3368 VT_SYS_PORT_OVERRIDEf); 3369 3370 return BCM_E_NONE; 3371 } 3372 3373 /* 3374 * Function: 3375 * bcmi_xgs5_subport_port_learn_set 3376 * Purpose: 3377 * Set the CML bits for a CoE subport. 3378 * Returns: 3379 * BCM_E_XXX 3380 */ 3381 int 3382 bcmi_xgs5_subport_port_learn_set(int unit, bcm_gport_t subport_port_id, 3383 uint32 flags) 3384 { 3385 int cml = 0, rv = BCM_E_NONE; 3386 soc_field_t fields[2]; 3387 uint32 values[2]; 3388 3389 /* Ensure the subport module is initialized */ 3390 _BCM_SUBPORT_COE_CHECK_INIT(unit); 3391 3392 cml = 0; 3393 if (!(flags & BCM_PORT_LEARN_FWD)) { 3394 cml |= (1 << 0); 3395 } 3396 if (flags & BCM_PORT_LEARN_CPU) { 3397 cml |= (1 << 1); 3398 } 3399 if (flags & BCM_PORT_LEARN_PENDING) { 3400 cml |= (1 << 2); 3401 } 3402 if (flags & BCM_PORT_LEARN_ARL) { 3403 cml |= (1 << 3); 3404 } 3405 3406 /* Setup the fields */ 3407 fields[0] = CML_FLAGS_MOVEf; 3408 fields[1] = CML_FLAGS_NEWf; 3409 /* Set the values */ 3410 values[0] = values[1] = cml; 3411 3412 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, subport_port_id, 3413 _BCM_CPU_TABS_NONE, fields[0], values[0])); 3414 3415 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, subport_port_id, 3416 _BCM_CPU_TABS_NONE, fields[1], values[1])); 3417 3418 return rv; 3419 } 3420 3421 /* 3422 * Function: 3423 * bcmi_xgs5_subport_port_learn_get 3424 * Purpose: 3425 * Get the CML bits for a CoE subport. 3426 * Returns: 3427 * BCM_E_XXX 3428 */ 3429 int 3430 bcmi_xgs5_subport_port_learn_get(int unit, bcm_gport_t subport_port_id, 3431 uint32 *flags) 3432 { 3433 int32 cml = 0; 3434 3435 /* Ensure the subport module is initialized */ 3436 _BCM_SUBPORT_COE_CHECK_INIT(unit); 3437 3438 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, subport_port_id, 3439 CML_FLAGS_NEWf, &cml)); 3440 3441 *flags = 0; 3442 if (!(cml & (1 << 0))) { 3443 *flags |= BCM_PORT_LEARN_FWD; 3444 } 3445 if (cml & (1 << 1)) { 3446 *flags |= BCM_PORT_LEARN_CPU; 3447 } 3448 if (cml & (1 << 2)) { 3449 *flags |= BCM_PORT_LEARN_PENDING; 3450 } 3451 if (cml & (1 << 3)) { 3452 *flags |= BCM_PORT_LEARN_ARL; 3453 } 3454 3455 return BCM_E_NONE; 3456 } 3457 3458 3459 #ifdef BCM_WARM_BOOT_SUPPORT 3460 3461 #define SCACHE_ALLOC_SIZE_INIT(_var_) \ 3462 do { \ 3463 (_var_) = 0; (_scache_ofst_) = 0; \ 3464 LOG_VERBOSE(BSL_LS_BCM_SUBPORT, \ 3465 (BSL_META_U(unit, \ 3466 "WarmBoot: Scache offset initialized to 0\n"))); \ 3467 } while (0) 3468 3469 #define SCACHE_ALLOC_SIZE_INCR(_var_, _count_) \ 3470 do { \ 3471 (_var_) += (_count_); (_scache_ofst_) += (_count_); \ 3472 LOG_VERBOSE(BSL_LS_BCM_SUBPORT, \ 3473 (BSL_META_U(unit, \ 3474 "WarmBoot: Scache offset incr by %d to %d\n"), \ 3475 (int)(_count_), (_scache_ofst_) \ 3476 )); \ 3477 } while (0) 3478 3479 #define SCACHE_BYTE_INIT(_scache_ptr_) \ 3480 do { \ 3481 _scache_ofst_ = 0; \ 3482 LOG_VERBOSE(BSL_LS_BCM_SUBPORT, \ 3483 (BSL_META_U(unit, \ 3484 "WarmBoot: Scache offset initialized to 0\n") \ 3485 )); \ 3486 } while (0) 3487 3488 #define SCACHE_BYTE_COPY(_scache_ptr_, _local_var_, _size_) \ 3489 do { \ 3490 sal_memcpy(_scache_ptr_, _local_var_, _size_); \ 3491 _scache_ptr_ += (_size_); \ 3492 (_scache_ofst_) += (_size_); \ 3493 LOG_VERBOSE(BSL_LS_BCM_SUBPORT, \ 3494 (BSL_META_U(unit, \ 3495 "WarmBoot: Scache offset incr by %d to %d\n"),\ 3496 (int)(_size_), (_scache_ofst_) \ 3497 )); \ 3498 } while (0) 3499 3500 #define SCACHE_BYTE_RESTORE(_scache_ptr_, _local_var_, _size_) \ 3501 do { \ 3502 sal_memcpy(_local_var_, _scache_ptr_, _size_); \ 3503 _scache_ptr_ += (_size_); \ 3504 (_scache_ofst_) += (_size_); \ 3505 LOG_VERBOSE(BSL_LS_BCM_SUBPORT, \ 3506 (BSL_META_U(unit, \ 3507 "WarmBoot: Scache offset incr by %d to %d\n"),\ 3508 (int)(_size_), (_scache_ofst_) \ 3509 )); \ 3510 } while (0) 3511 3512 #define SCACHE_BYTE_RESTORE2(_scache_ptr_, _local_var_, _scache_sz_, _local_sz_)\ 3513 do { \ 3514 SOC_SCACHE_SIZE_MIN_RECOVER(_scache_ptr_, _local_var_, _scache_sz_, _local_sz_);\ 3515 (_scache_ofst_) += (_scache_sz_); \ 3516 LOG_VERBOSE(BSL_LS_BCM_SUBPORT, \ 3517 (BSL_META_U(unit, \ 3518 "WarmBoot: Scache offset incr by %d to %d\n"),\ 3519 (int)(_scache_sz_), (_scache_ofst_) \ 3520 )); \ 3521 } while (0) 3522 3523 /* 3524 * Function: 3525 * bcmi_xgs5_subport_wb_scache_alloc 3526 * Purpose: 3527 * Allocate scache memory for individual entries to be saved for L2 warm-boot 3528 * Parameters: 3529 * unit - (IN) StrataSwitch unit number. 3530 * version - (IN) version number 3531 * alloc_sz - (OUT) The allocated size 3532 * Returns: 3533 * BCM_E_XXX 3534 */ 3535 int 3536 bcmi_xgs5_subport_wb_scache_alloc(int unit, uint16 version, int *alloc_sz) 3537 { 3538 int num_vlan = 0; 3539 soc_info_t *si = &SOC_INFO(unit); 3540 int incr_sz; 3541 uint32 _scache_ofst_ = 0; 3542 3543 SCACHE_ALLOC_SIZE_INIT(*alloc_sz); 3544 3545 /* Num subport groups (_bcm_subport_group_count) */ 3546 SCACHE_ALLOC_SIZE_INCR(*alloc_sz, sizeof(int)); 3547 3548 /* Subport-group bitmap (_bcm_subport_group_bitmap) */ 3549 SCACHE_ALLOC_SIZE_INCR(*alloc_sz, 3550 SHR_BITALLOCSIZE(si->max_subport_coe_groups)); 3551 3552 /* Subport-subtag-group bitmap (_bcm_subtag_group_bitmap) */ 3553 SCACHE_ALLOC_SIZE_INCR(*alloc_sz, 3554 SHR_BITALLOCSIZE(si->max_subport_coe_groups)); 3555 3556 /* Number of Subport ports per group 3557 (_bcm_subport_group_subport_port_count)*/ 3558 SCACHE_ALLOC_SIZE_INCR(*alloc_sz, 3559 (si->max_subport_coe_groups * sizeof(int))); 3560 3561 incr_sz = SOC_SCACHE_SIZE_MIN(sizeof(pbmp_t), 3562 SHR_BITALLOCSIZE(SOC_MAX_NUM_PORTS)); 3563 /* Bitmap of subtended ports */ 3564 SCACHE_ALLOC_SIZE_INCR(*alloc_sz, incr_sz); 3565 3566 /* VLAN ID array bimap (_bcm_subtag_vlan_id_bitmap) */ 3567 num_vlan = soc_mem_index_count(unit, VLAN_TABm); 3568 SCACHE_ALLOC_SIZE_INCR(*alloc_sz, 3569 SOC_MAX_NUM_PORTS * SHR_BITALLOCSIZE(num_vlan)); 3570 3571 /* Subport port info (_bcm_subtag_subport_port_info_t) */ 3572 SCACHE_ALLOC_SIZE_INCR(*alloc_sz, 3573 (si->max_subport_coe_ports * sizeof(_bcm_subtag_subport_port_info_t))); 3574 3575 3576 return BCM_E_NONE; 3577 } 3578 3579 /* 3580 * Function: 3581 * bcmi_xgs5_subport_wb_sync 3582 * Purpose: 3583 * Sync desired subport data to scache passed in 3584 * Parameters: 3585 * unit - (IN) StrataSwitch unit number. 3586 * version - (IN) version number 3587 * scache_ptr - (IN) Pointer to scache where data will be synced 3588 * Returns: 3589 * BCM_E_XXX 3590 */ 3591 3592 int 3593 bcmi_xgs5_subport_wb_sync(int unit, uint16 version, uint8 **scache_ptr) 3594 { 3595 int value = 0, num_vlan = 0, port = 0; 3596 soc_info_t *si = &SOC_INFO(unit); 3597 int copy_sz; 3598 uint32 _scache_ofst_ = 0; 3599 3600 SCACHE_BYTE_INIT(*scache_ptr); 3601 3602 /* If the 'subtag_allowed_pbm' is non-null, it means subport 3603 config is in effect and we need to sync it to scache */ 3604 if (BCM_PBMP_NOT_NULL(SOC_INFO(unit).subtag_allowed_pbm)) { 3605 3606 /* Num subport groups (_bcm_subport_group_count) */ 3607 value = _bcm_subport_group_count[unit]; 3608 SCACHE_BYTE_COPY(*scache_ptr, &value, sizeof(int)); 3609 3610 /* Subport-group bitmap (_bcm_subport_group_bitmap) */ 3611 SCACHE_BYTE_COPY(*scache_ptr, _bcm_subport_group_bitmap[unit], 3612 SHR_BITALLOCSIZE(si->max_subport_coe_groups)); 3613 3614 /* Subport-group bitmap (_bcm_subtag_group_bitmap) */ 3615 SCACHE_BYTE_COPY(*scache_ptr, _bcm_subtag_group_bitmap[unit], 3616 SHR_BITALLOCSIZE(si->max_subport_coe_groups)); 3617 3618 /* Number of Subport ports per group 3619 (_bcm_subport_group_subport_port_count)*/ 3620 SCACHE_BYTE_COPY(*scache_ptr, 3621 _bcm_subport_group_subport_port_count[unit], 3622 (si->max_subport_coe_groups * sizeof(int))); 3623 3624 copy_sz = SOC_SCACHE_SIZE_MIN(sizeof(pbmp_t), 3625 SHR_BITALLOCSIZE(SOC_MAX_NUM_PORTS)); 3626 /* Bitmap of subtended ports */ 3627 /* coverity[overrun-buffer-arg] */ 3628 SCACHE_BYTE_COPY(*scache_ptr, &si->subtag_pbm, copy_sz); 3629 3630 /* VLAN ID array bimap (_bcm_subtag_vlan_id_bitmap) */ 3631 num_vlan = soc_mem_index_count(unit, VLAN_TABm); 3632 3633 /* Copy over each configured port's vlan bitmap */ 3634 BCM_PBMP_ITER(si->subtag_pbm, port) { 3635 3636 SCACHE_BYTE_COPY(*scache_ptr, _bcm_subtag_vlan_id_bitmap[unit][port], 3637 SHR_BITALLOCSIZE(num_vlan)); 3638 } 3639 3640 /* Copy over the subport port info */ 3641 SCACHE_BYTE_COPY(*scache_ptr, _bcm_subtag_subport_port_info[unit], 3642 (si->max_subport_coe_ports * sizeof(_bcm_subtag_subport_port_info_t))); 3643 } 3644 3645 return BCM_E_NONE; 3646 } 3647 3648 /* 3649 * Function: 3650 * bcmi_xgs5_subport_wb_recover 3651 * Purpose: 3652 * Recover subport data that was sync'd before. 3653 * Parameters: 3654 * unit - (IN) StrataSwitch unit number. 3655 * version - (IN) version number 3656 * scache_ptr - (IN) Pointer to scache where data will be recovered from 3657 * Returns: 3658 * BCM_E_XXX 3659 */ 3660 3661 int 3662 bcmi_xgs5_subport_wb_recover(int unit, uint16 version, uint8 **scache_ptr) 3663 { 3664 int num_vlan = 0, port = 0; 3665 soc_info_t *si = &SOC_INFO(unit); 3666 int max_num_ports, pbmp_port_max, scache_sz; 3667 uint32 _scache_ofst_ = 0; 3668 3669 SCACHE_BYTE_INIT(*scache_ptr); 3670 3671 /* If the 'subtag_allowed_pbm' is non-null, it means subport 3672 config is in effect and we need to sync it to scache */ 3673 if (BCM_PBMP_NOT_NULL(SOC_INFO(unit).subtag_allowed_pbm)) { 3674 3675 /* Recover SOC_MAX_NUM_PORTS from scache */ 3676 max_num_ports = soc_scache_dictionary_entry_get(unit, 3677 ssden_SOC_MAX_NUM_PORTS, 3678 SOC_MAX_NUM_PORTS); 3679 pbmp_port_max = soc_scache_dictionary_entry_get(unit, 3680 ssden_SOC_PBMP_PORT_MAX, 3681 SOC_PBMP_PORT_MAX); 3682 /* Num subport groups (_bcm_subport_group_count) */ 3683 SCACHE_BYTE_RESTORE(*scache_ptr, &_bcm_subport_group_count[unit], 3684 sizeof(int)); 3685 3686 /* Subport-group bitmap (_bcm_subport_group_bitmap) */ 3687 SCACHE_BYTE_RESTORE(*scache_ptr, _bcm_subport_group_bitmap[unit], 3688 SHR_BITALLOCSIZE(si->max_subport_coe_groups)); 3689 3690 /* Subport-group bitmap (_bcm_subtag_group_bitmap) */ 3691 SCACHE_BYTE_RESTORE(*scache_ptr, _bcm_subtag_group_bitmap[unit], 3692 SHR_BITALLOCSIZE(si->max_subport_coe_groups)); 3693 3694 /* Number of Subport ports per group 3695 (_bcm_subport_group_subport_port_count)*/ 3696 /* coverity[overrun-buffer-arg] */ 3697 SCACHE_BYTE_RESTORE(*scache_ptr, 3698 _bcm_subport_group_subport_port_count[unit], 3699 (si->max_subport_coe_groups * sizeof(int))); 3700 3701 scache_sz = SOC_SCACHE_SIZE_MIN(SHR_BITALLOCSIZE(pbmp_port_max), 3702 SHR_BITALLOCSIZE(max_num_ports)); 3703 /* Bitmap of subtended ports */ 3704 SCACHE_BYTE_RESTORE2(*scache_ptr, &si->subtag_pbm, 3705 scache_sz, sizeof(pbmp_t)); 3706 3707 sal_memcpy(&si->subtag.bitmap, &si->subtag_pbm, sizeof(pbmp_t)); 3708 3709 /* VLAN ID array bimap (_bcm_subtag_vlan_id_bitmap) */ 3710 num_vlan = soc_mem_index_count(unit, VLAN_TABm); 3711 3712 /* Copy over each configured port's vlan bitmap */ 3713 BCM_PBMP_ITER(si->subtag_pbm, port) { 3714 3715 SCACHE_BYTE_RESTORE(*scache_ptr, 3716 _bcm_subtag_vlan_id_bitmap[unit][port], 3717 SHR_BITALLOCSIZE(num_vlan)); 3718 } 3719 3720 /* Copy over the subport port info */ 3721 SCACHE_BYTE_RESTORE(*scache_ptr, _bcm_subtag_subport_port_info[unit], 3722 (si->max_subport_coe_ports * 3723 sizeof(_bcm_subtag_subport_port_info_t))); 3724 } 3725 3726 return BCM_E_NONE; 3727 } 3728 3729 #endif /* BCM_WARM_BOOT_SUPPORT */ 3730 3731 3732 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP 3733 3734 /* 3735 * Function: 3736 * _bcm_coe_subport_sw_dump 3737 * Purpose: 3738 * Print Subport module s/w state 3739 * Parameters: 3740 * unit - (IN) StrataSwitch unit number. 3741 * Returns: 3742 * Void 3743 */ 3744 3745 void 3746 _bcm_coe_subport_sw_dump(int unit) 3747 { 3748 int idx = 0, port = 0, num_vlan = 0; 3749 soc_info_t *si = &SOC_INFO(unit); 3750 3751 LOG_CLI((BSL_META_U(unit, 3752 "Total Subport Groups: %d\n"), 3753 _bcm_subport_group_count[unit])); 3754 3755 LOG_CLI((BSL_META_U(unit, 3756 "Subport Groups and ports per group\n"))); 3757 for(idx = 0; idx < si->max_subport_coe_groups; idx++) { 3758 if(_BCM_SUBPORT_COE_GROUP_USED_GET(unit, idx)) { 3759 LOG_CLI((BSL_META_U(unit, "%d "), idx)); 3760 LOG_CLI((BSL_META_U(unit, ":%d "), 3761 _bcm_subport_group_subport_port_count[unit][idx])); 3762 } 3763 } 3764 3765 LOG_CLI((BSL_META_U(unit, 3766 "VLAN Ids per port\n"))); 3767 3768 /* Run thru all ports and print their VLAN ID bimap */ 3769 num_vlan = soc_mem_index_count(unit, VLAN_TABm); 3770 3771 BCM_PBMP_ITER(si->subtag_allowed_pbm, port) { 3772 3773 LOG_CLI((BSL_META_U(unit, "VLAN List for Port: %d "), port)); 3774 3775 for(idx = 0; idx < num_vlan; idx++) { 3776 if(_BCM_COE_SUBTAG_VLAN_ID_USED_GET(unit, port, idx)) { 3777 LOG_CLI((BSL_META_U(unit, "Vlan: %d "), idx)); 3778 } 3779 } 3780 } 3781 3782 /* Run through the subports configured and dump their details */ 3783 LOG_CLI((BSL_META_U(unit, 3784 "Subport Ports:\n"))); 3785 3786 for (idx = 0; idx < si->max_subport_coe_ports; idx++) { 3787 if(_bcm_subtag_subport_port_info[unit][idx].valid) { 3788 3789 LOG_CLI((BSL_META_U(unit, 3790 "Group: 0x%x vlan: %d subtag_tcam_idx: %d " 3791 "subport_modport: 0x%x subport_port: 0x%x\n" 3792 "nh_index: %d valid: %d modport_subport_idx: 0x%x " 3793 "phb_valid: %d priority: %d color: %d\n"), 3794 _bcm_subtag_subport_port_info[unit][idx].group, 3795 _bcm_subtag_subport_port_info[unit][idx].vlan, 3796 _bcm_subtag_subport_port_info[unit][idx].subtag_tcam_hw_idx, 3797 _bcm_subtag_subport_port_info[unit][idx].subport_modport, 3798 _bcm_subtag_subport_port_info[unit][idx].subport_port, 3799 _bcm_subtag_subport_port_info[unit][idx].nh_index, 3800 _bcm_subtag_subport_port_info[unit][idx].valid, 3801 _bcm_subtag_subport_port_info[unit][idx].modport_subport_idx, 3802 _bcm_subtag_subport_port_info[unit][idx].phb_valid, 3803 _bcm_subtag_subport_port_info[unit][idx].priority, 3804 _bcm_subtag_subport_port_info[unit][idx].color)); 3805 } 3806 } 3807 3808 LOG_CLI((BSL_META_U(unit, 3809 "\n----\n"))); 3810 3811 } 3812 #endif /* BCM_WARM_BOOT_SUPPORT_SW_DUMP */ 3813 3814 #else /* BCM_TRIDENT2PLUS_SUPPORT */ 3815 int bcm_esw_td2p_subport_not_empty; 3816 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 3817