vlan.c (64907B)
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: vlan.c 8 * Purpose: Broadcom StrataSwitch VLAN switch API for TH3. 9 */ 10 #include <soc/drv.h> 11 #include <soc/rcpu.h> 12 #include <bcm/error.h> 13 #include <bcm_int/common/lock.h> 14 #include <bcm_int/esw/vlan.h> 15 #include <bcm_int/esw/mbcm.h> 16 #include <bcm_int/esw/firebolt.h> 17 18 #ifdef BCM_TOMAHAWK3_SUPPORT 19 #include <bcm_int/tomahawk3_dispatch.h> 20 #include <bcm_int/esw/tomahawk3.h> 21 22 #define CHECK_INIT(unit) \ 23 do { \ 24 if (!vlan_info[unit].init) { \ 25 return BCM_E_INIT; \ 26 } \ 27 } while(0) \ 28 29 #define CHECK_INIT_AND_VLAN_ID(unit, vlan) \ 30 do { \ 31 CHECK_INIT(unit); \ 32 VLAN_CHK_ID(unit, vlan); \ 33 } while(0) 34 35 #define BCM_TH3_VLAN_CONTROL_VLAN_ALL_VALID_MASK \ 36 (BCM_VLAN_CONTROL_VLAN_VRF_MASK | \ 37 BCM_VLAN_CONTROL_VLAN_FORWARDING_VLAN_MASK | \ 38 BCM_VLAN_CONTROL_VLAN_INGRESS_IF_MASK | \ 39 BCM_VLAN_CONTROL_VLAN_OUTER_TPID_MASK | \ 40 BCM_VLAN_CONTROL_VLAN_IP6_MCAST_FLOOD_MODE_MASK | \ 41 BCM_VLAN_CONTROL_VLAN_IP4_MCAST_FLOOD_MODE_MASK | \ 42 BCM_VLAN_CONTROL_VLAN_L2_MCAST_FLOOD_MODE_MASK | \ 43 BCM_VLAN_CONTROL_VLAN_IF_CLASS_MASK | \ 44 BCM_VLAN_CONTROL_VLAN_FORWARDING_MODE_MASK | \ 45 BCM_VLAN_CONTROL_VLAN_BROADCAST_GROUP_MASK | \ 46 BCM_VLAN_CONTROL_VLAN_UNKNOWN_MULTICAST_GROUP_MASK | \ 47 BCM_VLAN_CONTROL_VLAN_UNKNOWN_UNICAST_GROUP_MASK | \ 48 BCM_VLAN_CONTROL_VLAN_PROTOCOL_PKT_MASK | \ 49 BCM_VLAN_CONTROL_VLAN_L3_IF_CLASS_MASK) 50 51 #define BCM_TH3_VLAN_CONTROL_VLAN_SUPPORTED_CTRL_FLAGS \ 52 (BCM_VLAN_LEARN_DISABLE | \ 53 BCM_VLAN_ICMP_REDIRECT_TOCPU | \ 54 BCM_VLAN_IGMP_SNOOP_DISABLE | \ 55 BCM_VLAN_IP4_DISABLE | \ 56 BCM_VLAN_IP4_MCAST_DISABLE | \ 57 BCM_VLAN_IP4_MCAST_L2_DISABLE | \ 58 BCM_VLAN_IP6_DISABLE | \ 59 BCM_VLAN_IP6_MCAST_DISABLE | \ 60 BCM_VLAN_IP6_MCAST_L2_DISABLE | \ 61 BCM_VLAN_IPMC_DO_VLAN_DISABLE | \ 62 BCM_VLAN_L2_CLASS_ID_ONLY | \ 63 BCM_VLAN_L3_CLASS_ID | \ 64 BCM_VLAN_L3_VRF_GLOBAL_DISABLE | \ 65 BCM_VLAN_MPLS_DISABLE | \ 66 BCM_VLAN_NON_UCAST_DROP | \ 67 BCM_VLAN_NON_UCAST_TOCPU | \ 68 BCM_VLAN_UNKNOWN_IP4_MCAST_TOCPU | \ 69 BCM_VLAN_UNKNOWN_IP6_MCAST_TOCPU | \ 70 BCM_VLAN_UNKNOWN_UCAST_DROP | \ 71 BCM_VLAN_UNKNOWN_UCAST_TOCPU) 72 73 #define BCM_TH3_VLAN_GPORT_ADD_SUPPORTED_FLAGS \ 74 (BCM_VLAN_GPORT_ADD_UNTAGGED | \ 75 BCM_VLAN_GPORT_ADD_INGRESS_ONLY | \ 76 BCM_VLAN_GPORT_ADD_EGRESS_ONLY | \ 77 BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY) 78 79 typedef enum bcm_th3_cmd_e { 80 BCM_TH3_GET, 81 BCM_TH3_SET, 82 BCM_TH3_DEL 83 } bcm_th3_cmd_t; 84 85 #if defined(BCM_WARM_BOOT_SUPPORT) 86 #include <soc/scache.h> 87 #include <bcm/module.h> 88 #include <bcm_int/esw/switch.h> 89 90 #define BCM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 91 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_1_0 92 93 /* 94 * Function: 95 * _bcm_th3_vlan_reinit 96 * 97 * Purpose: 98 * Recover VLAN state from hardware (reload) 99 * 100 * Parameters: 101 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 102 * 103 * Returns: 104 * BCM_E_NONE - Success. 105 * BCM_E_XXX - Other failures. 106 * 107 * Note: 108 */ 109 STATIC int 110 _bcm_th3_vlan_reinit(int unit) 111 { 112 bcm_vlan_info_t *vi = &vlan_info[unit]; 113 int rv; 114 soc_scache_handle_t scache_handle; 115 uint8 *vlan_scache_ptr; 116 uint8 flood_mode; 117 uint16 recovered_ver = BCM_WB_VERSION_1_0; 118 119 /* Clean up existing vlan_info */ 120 vi->init = TRUE; 121 BCM_IF_ERROR_RETURN(_bcm_vlan_cleanup(unit)); 122 123 #ifdef BCM_MCAST_FLOOD_DEFAULT 124 BCM_IF_ERROR_RETURN 125 (_bcm_esw_vlan_flood_default_set(unit, BCM_MCAST_FLOOD_DEFAULT)); 126 #else 127 BCM_IF_ERROR_RETURN 128 (_bcm_esw_vlan_flood_default_set(unit, BCM_VLAN_MCAST_FLOOD_UNKNOWN)); 129 #endif 130 131 /* 132 * Initialize software structures 133 */ 134 vi->defl = BCM_VLAN_DEFAULT; 135 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_VLAN, 0); 136 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 137 0, &vlan_scache_ptr, 138 BCM_WB_DEFAULT_VERSION, &recovered_ver); 139 if (rv == SOC_E_NOT_FOUND) { 140 /* Use non-Level 2 case */ 141 } else if (SOC_FAILURE(rv)) { 142 return rv; 143 } else { 144 /* Success, recover default VLAN */ 145 sal_memcpy(&vi->defl, vlan_scache_ptr, sizeof(vi->defl)); 146 vlan_scache_ptr += sizeof(vi->defl); 147 148 /* Flood mode */ 149 /* Type for 'flood_mode' is an enum, which values fit in uint8 */ 150 sal_memcpy(&flood_mode, vlan_scache_ptr, sizeof(flood_mode)); 151 vi->flood_mode = flood_mode; 152 vlan_scache_ptr += sizeof(flood_mode); 153 } 154 155 vi->count = 0; 156 157 /* Reinit the VLAN Cross Connect Internal Database */ 158 BCM_IF_ERROR_RETURN(_bcm_th3_vlan_xconnect_db_reinit(unit)); 159 160 vi->init = TRUE; 161 162 BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->bmp)); 163 BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->pre_cfg_bmp)); 164 165 BCM_IF_ERROR_RETURN 166 (mbcm_driver[unit]->mbcm_vlan_reload(unit, &vi->bmp, &vi->count)); 167 168 if (0 == _BCM_VBMP_LOOKUP(vi->bmp, vi->defl)) { 169 LOG_WARN(BSL_LS_BCM_VLAN, 170 (BSL_META_U(unit, 171 "Warm Reboot: Default VLAN %4d does not exist!\n"), 172 vi->defl)); 173 } 174 175 return BCM_E_NONE; 176 } 177 178 /* 179 * Function: 180 * _bcm_th3_esw_vlan_sync 181 * 182 * Purpose: 183 * Record VLAN module persisitent info for Level 2 Warm Boot 184 * 185 * Parameters: 186 * unit - StrataSwitch unit number. 187 * 188 * Returns: 189 * BCM_E_XXX 190 * 191 * Note: 192 */ 193 int 194 _bcm_th3_vlan_sync(int unit) 195 { 196 bcm_vlan_info_t *vi = &vlan_info[unit]; 197 soc_scache_handle_t scache_handle; 198 uint8 *vlan_scache_ptr; 199 uint8 flood_mode; 200 201 CHECK_INIT(unit); 202 203 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_VLAN, 0); 204 BCM_IF_ERROR_RETURN 205 (_bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 206 0, &vlan_scache_ptr, 207 BCM_WB_DEFAULT_VERSION, NULL)); 208 /* Default VLAN */ 209 sal_memcpy(vlan_scache_ptr, &vi->defl, sizeof(vi->defl)); 210 vlan_scache_ptr += sizeof(vi->defl); 211 212 /* Flood mode */ 213 /* Type for 'flood_mode' is an enum, which values fit in uint8 */ 214 flood_mode = vlan_info[unit].flood_mode; 215 sal_memcpy(vlan_scache_ptr, &flood_mode, sizeof(flood_mode)); 216 vlan_scache_ptr += sizeof(flood_mode); 217 218 return BCM_E_NONE; 219 } 220 #endif /* BCM_WARM_BOOT_SUPPORT */ 221 222 /* 223 * Function: 224 * _bcm_th3_vlan_port_add 225 * 226 * Purpose: 227 * Main part of bcm_vlan_port_add; assumes locking already done. 228 * 229 * Parameters: 230 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 231 * vid - (IN) VLAN ID to add port to as a member. 232 * pbmp - (IN) egress port bitmap for members of VLAN 233 * ubmp - (IN) untagged members of VLAN 234 * ing_pbmp - (IN) ingress port bitmap for members of VLAN 235 * flags - (IN) VLAN_PORT flags qualifying the member ports. 236 * 237 * Returns: 238 * BCM_E_NONE - Success. 239 * BCM_E_XXX - Other failures. 240 * 241 * Note: 242 */ 243 STATIC int 244 _bcm_th3_vlan_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp, 245 pbmp_t ing_pbmp, int flags) 246 { 247 pbmp_t vlan_pbmp, vlan_ubmp, vlan_ing_pbmp, orig_pbmp; 248 249 /* No such thing as untagged CPU */ 250 SOC_PBMP_REMOVE(ubmp, PBMP_CMIC(unit)); 251 252 /* Remove internal loopback port from vlan port bitmaps. Hardware does not 253 * perform ingress/egress VLAN membership checks on internal loopback port. 254 */ 255 SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit)); 256 SOC_PBMP_REMOVE(ubmp, PBMP_LB(unit)); 257 SOC_PBMP_REMOVE(ing_pbmp, PBMP_LB(unit)); 258 259 /* Don't add ports that are already there */ 260 BCM_IF_ERROR_RETURN 261 (mbcm_driver[unit]->mbcm_vlan_port_get( 262 unit, vid, &vlan_pbmp, &vlan_ubmp, &vlan_ing_pbmp)); 263 264 SOC_PBMP_ASSIGN(orig_pbmp, pbmp); 265 COMPILER_REFERENCE(orig_pbmp); 266 /* But do allow for making the port tagged/ 267 * untagged if its already added to the vlan 268 */ 269 SOC_PBMP_XOR(vlan_ubmp, ubmp); 270 SOC_PBMP_REMOVE(vlan_pbmp, vlan_ubmp); 271 SOC_PBMP_REMOVE(pbmp, vlan_pbmp); 272 SOC_PBMP_REMOVE(ubmp, vlan_pbmp); 273 SOC_PBMP_REMOVE(ing_pbmp, vlan_ing_pbmp); 274 275 if (SOC_PBMP_NOT_NULL(pbmp) || 276 SOC_PBMP_NOT_NULL(ubmp) || SOC_PBMP_NOT_NULL(ing_pbmp)) { 277 BCM_IF_ERROR_RETURN( 278 mbcm_driver[unit]->mbcm_vlan_port_add( 279 unit, vid, pbmp, ubmp, ing_pbmp)); 280 } 281 if (soc_feature(unit, soc_feature_vlan_egress_membership_l3_only) && 282 (flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) { 283 if (SOC_PBMP_NOT_NULL(pbmp)) { 284 SOC_PBMP_CLEAR(ing_pbmp); 285 SOC_PBMP_CLEAR(ubmp); 286 BCM_IF_ERROR_RETURN 287 (_bcm_xgs3_vlan_table_port_remove(unit, vid, pbmp, ubmp, 288 ing_pbmp, VLAN_2_TABm)); 289 } 290 } 291 292 return BCM_E_NONE; 293 } 294 295 /* 296 * Function: 297 * _bcm_th3_vlan_control_port_resolve 298 * 299 * Purpose: 300 * Internal function to validate the given port to be a valid port or 301 * supported GPORT. Once validation successfully completes, resolve the 302 * given port to its local port representation. 303 * 304 * Parameters: 305 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 306 * in_port - (IN) port/gport to be validated and resolved. 307 * only_allow_gport - (IN) in_port has to be a gport. 308 * out_port - (OUT) local port. If NULL then the function would only 309 * validate the given port. 310 * 311 * Returns: 312 * BCM_E_NONE - Success 313 * BCM_E_PORT - If the given port is not supported for TH3 VLAN operation 314 * or in_port is not a gport and only_allow_gport is nonzero 315 * 316 * Note: 317 */ 318 STATIC INLINE int 319 _bcm_th3_vlan_control_port_resolve( 320 int unit, bcm_port_t in_port, uint8 only_allow_gport, bcm_port_t *out_port) 321 { 322 int rv; 323 int local_modid; 324 bcm_port_t local_port; 325 326 /* Check for TH3 supported port/gports */ 327 if (BCM_GPORT_IS_SET(in_port)) { 328 if (BCM_GPORT_IS_LOCAL(in_port)) { 329 local_port = BCM_GPORT_LOCAL_GET(in_port); 330 } else if (BCM_GPORT_IS_LOCAL_CPU(in_port)) { 331 local_port = CMIC_PORT(unit); 332 } else if (BCM_GPORT_IS_DEVPORT(in_port)) { 333 local_port = BCM_GPORT_DEVPORT_PORT_GET(in_port); 334 if (unit != BCM_GPORT_DEVPORT_DEVID_GET(in_port)) { 335 return BCM_E_PORT; 336 } 337 } else if (BCM_GPORT_IS_MODPORT(in_port)) { 338 rv = bcm_esw_stk_my_modid_get(unit, &local_modid); 339 if (BCM_FAILURE(rv) || 340 (local_modid != BCM_GPORT_MODPORT_MODID_GET(in_port))) { 341 return BCM_E_PORT; 342 } 343 local_port = BCM_GPORT_MODPORT_PORT_GET(in_port); 344 } else { 345 /* All other GPORTS are not supported for the VLAN operations */ 346 return BCM_E_PORT; 347 } 348 } else if (TRUE == only_allow_gport) { 349 return BCM_E_PORT; 350 } else { 351 local_port = in_port; 352 } 353 354 /* Check validity of deduced local port */ 355 if (!SOC_PORT_VALID(unit, local_port)) { 356 return BCM_E_PORT; 357 } 358 359 /* If caller wants the port resolution then provide */ 360 if (out_port) { 361 *out_port = local_port; 362 } 363 return BCM_E_NONE; 364 } 365 366 /* 367 * Function: 368 * _bcm_th3_vlan_control_port_config_command 369 * 370 * Purpose: 371 * Internal function to get/set port based VLAN configuration 372 * 373 * Parameters: 374 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 375 * localport - (IN) port on which the VLAN configuration has to be applied 376 * type - (IN) value from bcm_vlan_control_port_t enumeration list 377 * cmd - (IN) If BCM_TH3_SET then SET the setting else GET it 378 * arg - (INOUT) value to be set or to be retrieved is stored 379 * 380 * Returns: 381 * BCM_E_NONE - Success 382 * BCM_E_PARAM - Given arg is NULL or type is not supported 383 * BCM_E_XXX - Other failures 384 * 385 * Note: 386 * It is assumed that localport parameter is a valid port and hence no 387 * further checks performed. 388 */ 389 STATIC int 390 _bcm_th3_vlan_control_port_config_command(int unit, 391 bcm_port_t localport, bcm_vlan_control_port_t type, uint8 cmd, int *arg) 392 { 393 uint32 data, evc; 394 395 if (NULL == arg) { 396 return BCM_E_PARAM; 397 } 398 399 switch (type) { 400 case bcmVlanPortVerifyOuterTpid: 401 /* Call the appr. port module interface */ 402 if (BCM_TH3_SET == cmd) { 403 return (_bcm_esw_port_config_set( 404 unit, localport, _bcmPortVerifyOuterTpid, !!*arg)); 405 } else { 406 return (_bcm_esw_port_config_get( 407 unit, localport, _bcmPortVerifyOuterTpid, arg)); 408 } 409 410 case bcmVlanPortOuterTpidSelect: 411 /* 412 * Access and/or Modify the OUTER_TPID_SEL field in the register 413 * EGR_VLAN_CONTROL_1 which is indexed by the given port parameter 414 */ 415 if (BCM_TH3_SET == cmd) { 416 if (*arg != BCM_PORT_OUTER_TPID && 417 *arg != BCM_VLAN_OUTER_TPID) { 418 return BCM_E_PARAM; 419 } 420 SOC_IF_ERROR_RETURN( 421 READ_EGR_VLAN_CONTROL_1r(unit, localport, &evc)); 422 data = evc; 423 soc_reg_field_set( 424 unit, EGR_VLAN_CONTROL_1r, &evc, OUTER_TPID_SELf, *arg); 425 if (evc != data) { 426 SOC_IF_ERROR_RETURN( 427 WRITE_EGR_VLAN_CONTROL_1r(unit, localport, evc)); 428 } 429 } else { 430 SOC_IF_ERROR_RETURN(READ_EGR_VLAN_CONTROL_1r(unit, localport, &evc)); 431 *arg = soc_reg_field_get( 432 unit, EGR_VLAN_CONTROL_1r, evc, OUTER_TPID_SELf); 433 } 434 return BCM_E_NONE; 435 436 default: 437 return BCM_E_UNAVAIL; 438 } 439 } 440 441 /* 442 * Function: 443 * _bcm_th3_vlan_port_get 444 * 445 * Purpose: 446 * Helper routine to retrieve the list of 447 * the member ports of an existing VLAN. 448 * 449 * Parameters: 450 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 451 * vlan - (IN) VLAN ID to retrieve the gport from. 452 * pbmp - (OUT) EGRESS port bitmap 453 * ubmp - (OUT) Untagged EGRESS port bitmap 454 * ing_pbmp - (OUT) INGRESS port bitmap 455 * 456 * Returns: 457 * BCM_E_NONE - Success 458 * BCM_E_NOT_FOUND - VLAN ID not existing 459 * BCM_E_PARAM 460 * BCM_E_UNAVAIL - Feature unavailable 461 * BCM_E_FAIL - Other failures 462 * 463 * Note: 464 */ 465 STATIC INLINE int 466 _bcm_th3_vlan_port_get( 467 int unit, bcm_vlan_t vid, pbmp_t *pbmp, pbmp_t *ubmp, pbmp_t *ing_pbmp) 468 { 469 int rv; 470 471 /* Check if the given VLAN ID is an existing vlan */ 472 if (0 == _BCM_VBMP_LOOKUP(vlan_info[unit].bmp, vid)) { 473 return BCM_E_NOT_FOUND; 474 } 475 476 /* Init all given port bitmaps */ 477 if (pbmp) { 478 BCM_PBMP_CLEAR(*pbmp); 479 } 480 if (ubmp) { 481 BCM_PBMP_CLEAR(*ubmp); 482 } 483 if (ing_pbmp) { 484 BCM_PBMP_CLEAR(*ing_pbmp); 485 } 486 487 /* Call lower level routine to retrieve bounded ports */ 488 BCM_LOCK(unit); 489 rv = mbcm_driver[unit]-> 490 mbcm_vlan_port_get(unit, vid, pbmp, ubmp, ing_pbmp); 491 BCM_UNLOCK(unit); 492 493 return rv; 494 } 495 496 /* 497 * Function: 498 * _bcm_th3_ing_vlan_tag_action_command 499 * 500 * Purpose: 501 * Generic function to get/set/delete the port's ingress vlan tag actions 502 * 503 * Parameters: 504 * unit - (IN) BCM unit. 505 * port - (IN) Port number. 506 * cmd - (IN) One of the values from ENUM bcm_th3_cmd_t. 507 * action - (IN/OUT) Vlan tag actions 508 * 509 * Returns: 510 * BCM_E_XXX 511 * 512 * Note: 513 * Based on the value of 'cmd', the parameter 'action' changes its behavior 514 * .It is dont care if cmd is BCM_TH3_DEL. If BCM_TH3_GET then 'action' is 515 * OUT direction, else if BCM_TH3_SET then it is IN direction. 516 */ 517 STATIC int 518 _bcm_th3_ing_vlan_tag_action_command ( 519 int unit, bcm_port_t port, uint8 cmd, bcm_vlan_action_set_t *action) { 520 521 int rv = BCM_E_UNAVAIL; 522 bcm_port_t local_port; 523 524 if (soc_feature(unit, soc_feature_vlan_action)) { 525 526 /* Validate and resolve the given gport parameter */ 527 BCM_IF_ERROR_RETURN( 528 _bcm_th3_vlan_control_port_resolve(unit, port, FALSE, &local_port)); 529 530 /* Lock the PORT TABLE as the operation on 531 * VLAN table and Port table has to be atomic 532 */ 533 soc_mem_lock(unit, PORT_TABm); 534 /* Based on the type of API, call appropriate internal functions */ 535 if (BCM_TH3_GET == cmd) { 536 rv = 537 _bcm_th3_vlan_port_default_action_get(unit, local_port, action); 538 } else if (BCM_TH3_SET == cmd) { 539 rv = 540 _bcm_th3_vlan_port_default_action_set(unit, local_port, action); 541 } else if (BCM_TH3_DEL == cmd) { 542 rv = _bcm_th3_vlan_port_default_action_delete(unit, local_port); 543 } 544 /* Unlock the PORT Table */ 545 soc_mem_unlock(unit, PORT_TABm); 546 } 547 548 return rv; 549 } 550 551 /* 552 * Function: 553 * _bcm_th3_egr_vlan_tag_action_command 554 * 555 * Purpose: 556 * Generic function to get/set/delete the port's egress vlan tag actions 557 * 558 * Parameters: 559 * unit - (IN) BCM unit. 560 * port - (IN) Port number. 561 * cmd - (IN) One of the values from ENUM bcm_th3_cmd_t. 562 * action - (IN/OUT) Vlan tag actions 563 * 564 * Returns: 565 * BCM_E_XXX 566 * 567 * Note: 568 * Based on the value of 'cmd', the parameter 'action' changes its behavior 569 * .It is dont care if cmd is BCM_TH3_DEL. If BCM_TH3_GET then 'action' is 570 * OUT direction, else if BCM_TH3_SET then it is IN direction. 571 */ 572 STATIC int 573 _bcm_th3_egr_vlan_tag_action_command ( 574 int unit, bcm_port_t port, uint8 cmd, bcm_vlan_action_set_t *action) { 575 576 int rv = BCM_E_UNAVAIL; 577 bcm_port_t local_port; 578 579 if (soc_feature(unit, soc_feature_vlan_action)) { 580 581 /* Validate and resolve the given gport parameter */ 582 BCM_IF_ERROR_RETURN( 583 _bcm_th3_vlan_control_port_resolve(unit, port, FALSE, &local_port)); 584 585 /* Based on the type of API, call appropriate internal functions */ 586 if (BCM_TH3_GET == cmd) { 587 rv = _bcm_th3_vlan_port_egress_default_action_get(unit, 588 local_port, 589 action); 590 } else if (BCM_TH3_SET == cmd) { 591 rv = _bcm_th3_vlan_port_egress_default_action_set(unit, 592 local_port, 593 action); 594 } else if (BCM_TH3_DEL == cmd) { 595 rv = 596 _bcm_th3_vlan_port_egress_default_action_delete(unit, local_port); 597 if (BCM_SUCCESS(rv)) { 598 _bcm_th3_egr_vlan_action_profile_entry_increment( 599 unit, BCM_TH3_EGR_ACTION_PROFILE_DEFAULT); 600 } 601 } 602 } 603 604 return rv; 605 } 606 607 /* 608 * Function: 609 * bcm_vlan_init 610 * 611 * Purpose: 612 * Initialize the VLAN module. 613 * 614 * Parameters: 615 * unit - StrataSwitch PCI device unit number (driver internal). 616 * 617 * Returns: 618 * BCM_E_NONE - Success. 619 * BCM_E_INTERNAL - Chip access failure. 620 * 621 * Note: 622 */ 623 int 624 bcm_tomahawk3_vlan_init(int unit) 625 { 626 bcm_vlan_info_t *vi = &vlan_info[unit]; 627 int rv = BCM_E_NONE; 628 #ifdef BCM_WARM_BOOT_SUPPORT 629 soc_scache_handle_t scache_handle; 630 uint8 *vlan_scache_ptr; 631 uint32 vlan_scache_size; 632 #endif /* BCM_WARM_BOOT_SUPPORT */ 633 634 /* Set the auto stack as 0 as stacking not supported on TH3 */ 635 vi->vlan_auto_stack = 0; 636 637 #ifdef BCM_WARM_BOOT_SUPPORT 638 if (SOC_WARM_BOOT(unit)) { 639 return(_bcm_th3_vlan_reinit(unit)); 640 } else 641 #endif /* BCM_WARM_BOOT_SUPPORT */ 642 { 643 bcm_vlan_data_t vd; 644 bcm_pbmp_t temp_pbmp; 645 646 /* 647 * Initialize hardware tables 648 */ 649 BCM_PBMP_CLEAR(temp_pbmp); 650 BCM_PBMP_ASSIGN(temp_pbmp, PBMP_ALL(unit)); 651 652 vd.vlan_tag = BCM_VLAN_DEFAULT; 653 BCM_PBMP_ASSIGN(vd.port_bitmap, temp_pbmp); 654 BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_LB(unit)); 655 BCM_PBMP_ASSIGN(vd.ut_port_bitmap, temp_pbmp); 656 BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_CMIC(unit)); 657 BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_LB(unit)); 658 659 /* 660 * A compile-time application policy may prefer to not add 661 * Ethernet or CPU ports to the default VLAN. 662 */ 663 #ifdef BCM_VLAN_NO_DEFAULT_ETHER 664 BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_E_ALL(unit)); 665 BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_E_ALL(unit)); 666 #endif /* BCM_VLAN_NO_DEFAULT_ETHER */ 667 #ifdef BCM_VLAN_NO_DEFAULT_CPU 668 BCM_PBMP_REMOVE(vd.port_bitmap, PBMP_CMIC(unit)); 669 #endif /* BCM_VLAN_NO_DEFAULT_CPU */ 670 671 #if defined(BCM_RCPU_SUPPORT) 672 if (SOC_IS_RCPU_ONLY(unit) && vlan_info[unit].init) { 673 bcm_vlan_t idx; 674 soc_rcpu_cfg_t cfg; 675 676 if (SOC_E_NONE != soc_cm_get_rcpu_cfg(unit, &cfg)) { 677 cfg.vlan = BCM_VLAN_INVALID; 678 } 679 680 /* Destroy previous VLANs */ 681 for (idx = BCM_VLAN_MIN; idx < BCM_VLAN_COUNT; idx++) { 682 if ((idx != vlan_info[unit].defl) && 683 (idx != cfg.vlan) && 684 (_BCM_VBMP_LOOKUP(vlan_info[unit].bmp, idx))) { 685 BCM_IF_ERROR_RETURN 686 (mbcm_driver[unit]->mbcm_vlan_destroy(unit, idx)); 687 } 688 } 689 } 690 #endif /* BCM_RCPU_SUPPORT */ 691 692 #ifdef BCM_MCAST_FLOOD_DEFAULT 693 BCM_IF_ERROR_RETURN 694 (_bcm_esw_vlan_flood_default_set(unit, BCM_MCAST_FLOOD_DEFAULT)); 695 #else 696 BCM_IF_ERROR_RETURN 697 (_bcm_esw_vlan_flood_default_set(unit, 698 BCM_VLAN_MCAST_FLOOD_UNKNOWN)); 699 #endif 700 701 BCM_IF_ERROR_RETURN 702 (mbcm_driver[unit]->mbcm_vlan_init(unit, &vd)); 703 704 /* 705 * Initialize software structures 706 */ 707 vi->defl = BCM_VLAN_DEFAULT; 708 709 #ifdef BCM_WARM_BOOT_SUPPORT 710 /* Warm boot level 2 cache size */ 711 /* Type for 'flood_mode' is an enum, which values fit in uint8 */ 712 vlan_scache_size = sizeof(vi->defl);/* Default VLAN */ 713 vlan_scache_size += sizeof(uint8); /* Flood mode */ 714 715 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_VLAN, 0); 716 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, 717 vlan_scache_size, 718 &vlan_scache_ptr, 719 BCM_WB_DEFAULT_VERSION, NULL); 720 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 721 return rv; 722 } 723 rv = BCM_E_NONE; 724 #endif /* BCM_WARM_BOOT_SUPPORT */ 725 726 /* In case bcm_vlan_init is called more than once */ 727 BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->bmp)); 728 _BCM_VBMP_INSERT(vi->bmp, vd.vlan_tag); 729 730 BCM_IF_ERROR_RETURN(_bcm_vbmp_init(&vi->pre_cfg_bmp)); 731 732 /* Free vlan translation arrays if any as not supported. */ 733 if (NULL != vi->egr_trans) { 734 sal_free(vi->egr_trans); 735 vi->egr_trans = NULL; 736 } 737 if (NULL != vi->ing_trans) { 738 sal_free(vi->ing_trans); 739 vi->ing_trans = NULL; 740 } 741 vi->count = 1; 742 } 743 744 /* 745 * Initialize Cross Connect Internal Database 746 */ 747 BCM_IF_ERROR_RETURN(_bcm_th3_vlan_xconnect_db_init(unit)); 748 749 vi->init = TRUE; 750 751 #if defined(BCM_RCPU_SUPPORT) 752 if (SOC_IS_RCPU_ONLY(unit)) { 753 soc_rcpu_cfg_t cfg; 754 if (SOC_E_NONE == soc_cm_get_rcpu_cfg(unit, &cfg) && 755 BCM_VLAN_DEFAULT != cfg.vlan) { 756 /* 757 * RCPU vlan should have been created in remote device, sync 758 * software status. 759 */ 760 _BCM_VBMP_INSERT(vlan_info[unit].bmp, cfg.vlan); 761 vlan_info[unit].count++; 762 } 763 } 764 #endif /* BCM_RCPU_SUPPORT */ 765 766 return rv; 767 } 768 769 /* 770 * Function: 771 * bcm_vlan_detach 772 * 773 * Purpose: 774 * De-initialize the VLAN module. 775 * 776 * Parameters: 777 * unit - StrataSwitch PCI device unit number (driver internal). 778 * 779 * Returns: 780 * BCM_E_XXX 781 * 782 * Note: 783 */ 784 int 785 bcm_tomahawk3_vlan_detach(int unit) 786 { 787 bcm_vlan_info_t *vi = &vlan_info[unit]; 788 int rv = BCM_E_NONE; 789 790 BCM_LOCK(unit); 791 792 _bcm_vbmp_destroy(&vi->bmp); 793 BCM_IF_ERROR_RETURN(_bcm_vbmp_destroy(&vi->pre_cfg_bmp)); 794 795 if (vi->egr_trans != NULL) { 796 sal_free(vi->egr_trans); 797 vi->egr_trans = NULL; 798 } 799 if (vi->ing_trans != NULL) { 800 sal_free(vi->ing_trans); 801 vi->ing_trans = NULL; 802 } 803 804 vi->init = 0; 805 806 #if defined(BCM_FIREBOLT2_SUPPORT) 807 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 808 rv = _bcm_xgs3_vlan_profile_detach(unit); 809 } 810 #endif /* BCM_FIREBOLT2_SUPPORT */ 811 812 BCM_IF_ERROR_RETURN(_bcm_th3_vlan_xconnect_db_destroy(unit)); 813 814 BCM_UNLOCK(unit); 815 return rv; 816 } 817 818 /* 819 * Function: 820 * bcm_vlan_port_add 821 * 822 * Purpose: 823 * Add ports to the specified vlan. 824 * 825 * Parameters: 826 * unit - StrataSwitch PCI device unit number (driver internal). 827 * vid - VLAN ID to add port to as a member. 828 * pbmp - port bitmap for members of VLAN 829 * ubmp - untagged members of VLAN 830 * 831 * Returns: 832 * BCM_E_NONE - Success. 833 * BCM_E_INTERNAL - Chip access failure. 834 * BCM_E_NOT_FOUND - VLAN ID not in use. 835 * 836 * Note: 837 */ 838 int 839 bcm_tomahawk3_vlan_port_add(int unit, bcm_vlan_t vid, pbmp_t pbmp, pbmp_t ubmp) 840 { 841 int rv = BCM_E_NONE; 842 bcm_pbmp_t pbm, ubm; 843 844 CHECK_INIT_AND_VLAN_ID(unit, vid); 845 846 BCM_PBMP_CLEAR(pbm); 847 BCM_PBMP_CLEAR(ubm); 848 849 /* we need to check if pbmp and ubmp are valid as well */ 850 BCM_PBMP_ASSIGN(pbm,PBMP_ALL(unit)); 851 BCM_PBMP_ASSIGN(ubm,PBMP_ALL(unit)); 852 BCM_PBMP_AND(pbm,pbmp); 853 BCM_PBMP_AND(ubm,ubmp); 854 855 if(!(BCM_PBMP_EQ(pbm, pbmp) && BCM_PBMP_EQ(ubm, ubmp))) { 856 return BCM_E_PARAM; 857 } 858 859 LOG_VERBOSE(BSL_LS_BCM_VLAN, 860 (BSL_META_U(unit, 861 "VLAN %d: port add: vid %d. pbm 0x%x. upbm 0x%x\n"), 862 unit, vid, SOC_PBMP_WORD_GET(pbmp, 0), 863 SOC_PBMP_WORD_GET(ubmp, 0))); 864 865 BCM_LOCK(unit); 866 rv = _bcm_th3_vlan_port_add(unit, vid, pbmp, ubmp, pbmp, 0); 867 BCM_UNLOCK(unit); 868 869 return rv; 870 } 871 872 /* 873 * Function: 874 * bcm_vlan_port_remove 875 * 876 * Purpose: 877 * Remove ports from a specified vlan. 878 * 879 * Parameters: 880 * unit - StrataSwitch PCI device unit number (driver internal). 881 * vid - VLAN ID to remove port(s) from. 882 * pbmp - port bitmap for ports to remove. 883 * 884 * Returns: 885 * BCM_E_NONE - Success. 886 * BCM_E_INTERNAL - Chip access failure. 887 * BCM_E_NOT_FOUND - VLAN ID not in use. 888 * 889 * Note: 890 */ 891 int 892 bcm_tomahawk3_vlan_port_remove(int unit, bcm_vlan_t vid, pbmp_t pbmp) 893 { 894 int rv = BCM_E_NONE; 895 896 LOG_VERBOSE(BSL_LS_BCM_VLAN, 897 (BSL_META_U(unit, 898 "VLAN %d: port remove: vid %d. pbm 0x%x.\n"), 899 unit, vid, SOC_PBMP_WORD_GET(pbmp, 0))); 900 901 CHECK_INIT_AND_VLAN_ID(unit, vid); 902 /* As we are passing only one pbmp parameter to API bcm_vlan_port_remove, 903 * the expected result is to remove same pbmp from PORT_BITMAPf, UT_BITMAPf 904 * and ING_PORT_BITMAPf. Hence, same pbmp is passed as argument for ubmp 905 * and ing_pbmp 906 */ 907 BCM_LOCK(unit); 908 rv = mbcm_driver[unit]->mbcm_vlan_port_remove( 909 unit, vid, pbmp, pbmp, pbmp); 910 BCM_UNLOCK(unit); 911 912 return rv; 913 } 914 915 /* 916 * Function: 917 * bcm_vlan_control_vlan_selective_get 918 * 919 * Purpose: 920 * Get per VLAN configuration. 921 * 922 * Parameters: 923 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 924 * vid - (IN) VLAN to get the setting for. 925 * valid_fields - (IN) Valid fields for VLAN control 926 * structure, BCM_VLAN_CONTROL_VLAN_XXX_MASK. 927 * control - (OUT) VLAN control structure 928 * 929 * Returns: 930 * BCM_E_NONE - Success. 931 * BCM_E_XXX 932 * 933 * Note: 934 */ 935 int 936 bcm_tomahawk3_vlan_control_vlan_selective_get(int unit, bcm_vlan_t vlan, 937 uint32 valid_fields, bcm_vlan_control_vlan_t *control) 938 { 939 int rv = BCM_E_UNAVAIL; 940 941 CHECK_INIT_AND_VLAN_ID(unit, vlan); 942 if (NULL == control) { 943 return (BCM_E_PARAM); 944 } 945 946 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 947 948 /* Check incoming fields validity for TH3 specific support */ 949 if (valid_fields & ~BCM_TH3_VLAN_CONTROL_VLAN_ALL_VALID_MASK) { 950 return (BCM_E_PARAM); 951 } 952 953 BCM_LOCK(unit); 954 rv = _bcm_xgs3_vlan_control_vlan_get(unit, vlan, valid_fields, control); 955 BCM_UNLOCK(unit); 956 /* 957 * Clean the flag BCM_VLAN_L3_URPF_DEFAULT_ROUTE_CHECK_DISABLE from the 958 * control->flags as URPF is not supported by TH3, but underlying layer 959 * would check for the URPF support and if it does not find it, the 960 * default outcome is chosen i.e. l3_urpf_default_route_check_disable. 961 * However, for TH3 we do not want to provide this default flag to Appl. 962 */ 963 control->flags &= ~BCM_VLAN_L3_URPF_DEFAULT_ROUTE_CHECK_DISABLE; 964 965 /* Check for TH3 specific output validity */ 966 if (control->flags & ~BCM_TH3_VLAN_CONTROL_VLAN_SUPPORTED_CTRL_FLAGS) { 967 return BCM_E_CONFIG; 968 } 969 970 if (valid_fields & BCM_VLAN_CONTROL_VLAN_FORWARDING_MODE_MASK) { 971 if (control->forwarding_mode != bcmVlanForwardBridging && 972 control->forwarding_mode != bcmVlanForwardSingleCrossConnect) { 973 974 return BCM_E_CONFIG; 975 } 976 } 977 } 978 979 return rv; 980 } 981 982 /* 983 * Function: 984 * bcm_vlan_control_vlan_selective_set 985 * 986 * Purpose: 987 * Set per VLAN configuration. 988 * 989 * Parameters: 990 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 991 * vid - (IN) VLAN to set the configuration for. 992 * valid_fields - (IN) Valid fields for VLAN control structure, 993 * BCM_VLAN_CONTROL_VLAN_XXX_MASK. 994 * control - (IN) VLAN control structure 995 * 996 * Returns: 997 * BCM_E_NONE - Success. 998 * BCM_E_XXX 999 * 1000 * Note: 1001 */ 1002 int 1003 bcm_tomahawk3_vlan_control_vlan_selective_set(int unit, bcm_vlan_t vlan, 1004 uint32 valid_fields, bcm_vlan_control_vlan_t *control) 1005 { 1006 int rv = BCM_E_UNAVAIL; 1007 1008 CHECK_INIT_AND_VLAN_ID(unit, vlan); 1009 1010 /* Perform incoming parameter validity for TH3 device chip */ 1011 if (NULL == control) { 1012 return (BCM_E_PARAM); 1013 } 1014 1015 if (valid_fields & ~BCM_TH3_VLAN_CONTROL_VLAN_ALL_VALID_MASK) { 1016 return (BCM_E_PARAM); 1017 } 1018 if (control->flags & ~BCM_TH3_VLAN_CONTROL_VLAN_SUPPORTED_CTRL_FLAGS) { 1019 return (BCM_E_PARAM); 1020 } 1021 if ((0 != control->learn_flags) || (0 != control->sr_flags)) { 1022 return (BCM_E_PARAM); 1023 } 1024 if ((control->vrf > SOC_VRF_MAX(unit))) { 1025 return (BCM_E_PARAM); 1026 } 1027 if (bcmVlanUrpfDisable != control->urpf_mode) { 1028 return (BCM_E_PARAM); 1029 } 1030 if (valid_fields & BCM_VLAN_CONTROL_VLAN_FORWARDING_MODE_MASK) { 1031 if ((control->forwarding_mode != bcmVlanForwardBridging) && 1032 (control->forwarding_mode != bcmVlanForwardSingleCrossConnect)) { 1033 return (BCM_E_PARAM); 1034 } 1035 } 1036 1037 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 1038 BCM_LOCK(unit); 1039 rv = _bcm_xgs3_vlan_control_vlan_set(unit, vlan, valid_fields, control); 1040 BCM_UNLOCK(unit); 1041 } 1042 1043 return rv; 1044 } 1045 1046 /* 1047 * Function: 1048 * bcm_vlan_control_vlan_get 1049 * 1050 * Purpose: 1051 * Get all supported per VLAN configurations. 1052 * 1053 * Parameters: 1054 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 1055 * vid - (IN) VLAN to get the setting for. 1056 * control - (OUT) VLAN control structure 1057 * 1058 * Returns: 1059 * BCM_E_NONE - Success. 1060 * BCM_E_XXX 1061 * 1062 * Note: 1063 * No checks are performed here as the callee function will do all checks 1064 */ 1065 int 1066 bcm_tomahawk3_vlan_control_vlan_get(int unit, bcm_vlan_t vid, 1067 bcm_vlan_control_vlan_t *control) 1068 { 1069 return( 1070 bcm_tomahawk3_vlan_control_vlan_selective_get(unit, vid, 1071 (uint32)BCM_TH3_VLAN_CONTROL_VLAN_ALL_VALID_MASK, control)); 1072 } 1073 1074 /* 1075 * Function: 1076 * bcm_vlan_control_vlan_set 1077 * 1078 * Purpose: 1079 * Set per VLAN configuration. 1080 * 1081 * Parameters: 1082 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 1083 * vid - (IN) VLAN to get the flood setting for. 1084 * control - (IN) VLAN control structure 1085 * 1086 * Returns: 1087 * BCM_E_NONE - Success. 1088 * BCM_E_XXX 1089 * 1090 * Note: 1091 * No checks are performed here as the callee function will do all checks 1092 */ 1093 int 1094 bcm_tomahawk3_vlan_control_vlan_set(int unit, bcm_vlan_t vid, 1095 /* coverity[pass_by_value] */ 1096 bcm_vlan_control_vlan_t control) 1097 { 1098 return ( 1099 bcm_tomahawk3_vlan_control_vlan_selective_set(unit, vid, 1100 (uint32)BCM_TH3_VLAN_CONTROL_VLAN_ALL_VALID_MASK, &control)); 1101 } 1102 1103 /* 1104 * Function 1105 * bcm_vlan_vector_flags_set 1106 * Purpose 1107 * Set a one or more VLAN control vlan flags on a vlan_vector on this unit 1108 * 1109 * Parameters 1110 * (in) int unit = unit number 1111 * (in) bcm_vlan_vector_t vlan_vector = Vlan vector for values to be set 1112 * (in) uint32 flags_mask 1113 * (in) uint32 flags_value 1114 * 1115 * Returns 1116 * bcm_error_t = BCM_E_NONE if successful 1117 * BCM_E_* appropriately if not 1118 * 1119 * Note 1120 */ 1121 int 1122 bcm_tomahawk3_vlan_vector_flags_set(int unit, 1123 bcm_vlan_vector_t vlan_vector, 1124 uint32 flags_mask, 1125 uint32 flags_value) 1126 { 1127 int rv; 1128 1129 bcm_vlan_t vid; 1130 bcm_vlan_control_vlan_t control; 1131 1132 /* non-supported vector fields */ 1133 if (flags_mask & ~BCM_TH3_VLAN_CONTROL_VLAN_SUPPORTED_CTRL_FLAGS) { 1134 return BCM_E_PARAM; 1135 } 1136 1137 /* Optimistically assume success from here */ 1138 rv = BCM_E_NONE; 1139 1140 for (vid = BCM_VLAN_MIN + 1; vid < BCM_VLAN_MAX; vid++) { 1141 1142 if (BCM_VLAN_VEC_GET(vlan_vector, vid)) { 1143 1144 bcm_vlan_control_vlan_t_init(&control); 1145 1146 rv = bcm_tomahawk3_vlan_control_vlan_selective_get(unit, vid, 1147 (uint32)BCM_TH3_VLAN_CONTROL_VLAN_ALL_VALID_MASK, &control); 1148 1149 if (BCM_SUCCESS(rv)) { 1150 control.flags = 1151 (~flags_mask & control.flags) | (flags_mask & flags_value); 1152 1153 rv = bcm_tomahawk3_vlan_control_vlan_selective_set( 1154 unit, 1155 vid, 1156 (uint32)BCM_TH3_VLAN_CONTROL_VLAN_ALL_VALID_MASK, 1157 &control); 1158 if (BCM_FAILURE(rv)) { 1159 break; 1160 } 1161 } 1162 } 1163 } 1164 return rv; 1165 } 1166 1167 /* 1168 * Function: 1169 * bcm_vlan_control_set 1170 * 1171 * Purpose: 1172 * Set miscellaneous VLAN-specific chip options 1173 * 1174 * Parameters: 1175 * unit - StrataSwitch PCI device unit number (driver internal). 1176 * type - A value from bcm_vlan_control_t enumeration list 1177 * arg - state whose meaning is dependent on 'type' 1178 * 1179 * Returns: 1180 * BCM_E_NONE - Success 1181 * BCM_E_INTERNAL - Chip access failure. 1182 * BCM_E_UNAVAIL - type not supported on unit 1183 * 1184 * Note: 1185 */ 1186 int 1187 bcm_tomahawk3_vlan_control_set(int unit, bcm_vlan_control_t type, int arg) 1188 { 1189 uint32 data; 1190 uint32 vlan_ctrl; 1191 1192 LOG_VERBOSE(BSL_LS_BCM_VLAN, 1193 (BSL_META_U(unit, 1194 "VLAN %d: control set: type %d, arg %d\n"), 1195 unit, type, arg)); 1196 1197 if (SOC_IS_XGS3_FABRIC(unit)) { 1198 return BCM_E_UNAVAIL; 1199 } 1200 1201 switch (type) { 1202 case bcmVlanDropUnknown: 1203 return bcm_esw_switch_control_port_set(unit, 1204 CMIC_PORT(unit), 1205 bcmSwitchUnknownVlanToCpu, 1206 !arg); 1207 case bcmVlanShared: 1208 arg = (arg ? 1 : 0); 1209 SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &vlan_ctrl)); 1210 data = vlan_ctrl; 1211 soc_reg_field_set(unit, VLAN_CTRLr, &vlan_ctrl, 1212 USE_LEARN_VIDf, arg); 1213 if (data != vlan_ctrl) { 1214 SOC_IF_ERROR_RETURN(WRITE_VLAN_CTRLr(unit, vlan_ctrl)); 1215 SOC_IF_ERROR_RETURN( 1216 soc_reg_field32_modify(unit, 1217 EGR_CONFIGr, CMIC_PORT(unit), USE_LEARN_VIDf, arg)); 1218 } 1219 break; 1220 1221 case bcmVlanSharedID: 1222 VLAN_CHK_ID(unit, arg); 1223 SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &vlan_ctrl)); 1224 data = vlan_ctrl; 1225 soc_reg_field_set(unit, VLAN_CTRLr, &vlan_ctrl, 1226 LEARN_VIDf, arg); 1227 if (data != vlan_ctrl) { 1228 SOC_IF_ERROR_RETURN(WRITE_VLAN_CTRLr(unit, vlan_ctrl)); 1229 SOC_IF_ERROR_RETURN( 1230 soc_reg_field32_modify(unit, 1231 EGR_CONFIGr, CMIC_PORT(unit), LEARN_VIDf, arg)); 1232 } 1233 break; 1234 1235 default: 1236 return BCM_E_UNAVAIL; 1237 } 1238 1239 return BCM_E_NONE; 1240 } 1241 1242 /* 1243 * Function: 1244 * bcm_vlan_control_get 1245 * 1246 * Purpose: 1247 * Get miscellaneous VLAN-specific chip options 1248 * 1249 * Parameters: 1250 * unit - StrataSwitch PCI device unit number (driver internal). 1251 * type - A value from bcm_vlan_control_t enumeration list 1252 * arg - (OUT) state whose meaning is dependent on 'type' 1253 * 1254 * Returns: 1255 * BCM_E_NONE - Success 1256 * BCM_E_PARAM - arg points to NULL 1257 * BCM_E_INTERNAL - Chip access failure. 1258 * BCM_E_UNAVAIL - type not supported on unit 1259 * 1260 * Note: 1261 */ 1262 int 1263 bcm_tomahawk3_vlan_control_get(int unit, bcm_vlan_control_t type, int *arg) 1264 { 1265 int rv = BCM_E_NONE; 1266 uint32 vlan_ctrl; 1267 1268 if (NULL == arg) { 1269 return BCM_E_PARAM; 1270 } 1271 1272 if (SOC_IS_XGS3_FABRIC(unit)) { 1273 return BCM_E_UNAVAIL; 1274 } 1275 1276 switch (type) { 1277 case bcmVlanDropUnknown: 1278 rv = bcm_esw_switch_control_port_get(unit, 1279 CMIC_PORT(unit), 1280 bcmSwitchUnknownVlanToCpu, 1281 arg); 1282 if (BCM_SUCCESS(rv)) { 1283 *arg = !(*arg); 1284 } 1285 break; 1286 1287 case bcmVlanShared: 1288 SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &vlan_ctrl)); 1289 *arg = soc_reg_field_get(unit, VLAN_CTRLr, 1290 vlan_ctrl, USE_LEARN_VIDf); 1291 break; 1292 1293 case bcmVlanSharedID: 1294 SOC_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &vlan_ctrl)); 1295 *arg = soc_reg_field_get(unit, VLAN_CTRLr, 1296 vlan_ctrl, LEARN_VIDf); 1297 break; 1298 1299 default: 1300 rv = BCM_E_UNAVAIL; 1301 break; 1302 } 1303 1304 return rv; 1305 } 1306 1307 /* 1308 * Function: 1309 * bcm_tomahawk3_vlan_control_port_set 1310 * 1311 * Purpose: 1312 * BCM dispatched API to set port based VLAN configuration. 1313 * 1314 * Parameters: 1315 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 1316 * port - (IN) port/gport on which the VLAN configuration has to be applied 1317 * type - (IN) value from bcm_vlan_control_port_t enumeration list 1318 * arg - (IN) value to be set for the given type 1319 * 1320 * Returns: 1321 * BCM_E_NONE - Success 1322 * BCM_E_PORT - If the given port/gport is not supported for TH3 VLAN module 1323 * BCM_E_PARAM - Given arg or type is not supported for TH3 1324 * BCM_E_XXX - Other failures 1325 * 1326 * Note: 1327 * If the given port is -1 then apply the setting to all the local ports. 1328 */ 1329 int 1330 bcm_tomahawk3_vlan_control_port_set(int unit, bcm_port_t port, 1331 bcm_vlan_control_port_t type, int arg) 1332 { 1333 int rv = BCM_E_NONE; 1334 bcm_pbmp_t temp_pbmp; 1335 1336 if (-1 == port) { 1337 BCM_PBMP_CLEAR(temp_pbmp); 1338 BCM_PBMP_ASSIGN(temp_pbmp, PBMP_E_ALL(unit)); 1339 1340 /* Iterate through all local ports and apply the VLAN configuration */ 1341 PBMP_ITER(temp_pbmp, port) { 1342 BCM_IF_ERROR_RETURN( 1343 _bcm_th3_vlan_control_port_config_command( 1344 unit, port, type, BCM_TH3_SET, &arg)); 1345 } 1346 } else { 1347 /* Validate and resolve the given port parameter */ 1348 BCM_IF_ERROR_RETURN( 1349 _bcm_th3_vlan_control_port_resolve(unit, port, FALSE, &port)); 1350 rv = _bcm_th3_vlan_control_port_config_command( 1351 unit, port, type, BCM_TH3_SET, &arg); 1352 } 1353 return rv; 1354 } 1355 1356 1357 /* 1358 * Function: 1359 * bcm_tomahawk3_vlan_control_port_get 1360 * 1361 * Purpose: 1362 * BCM dispatched API to get port based VLAN configuration. 1363 * 1364 * Parameters: 1365 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 1366 * port - (IN) port/gport for which the VLAN config has to be retrieved 1367 * type - (IN) value from bcm_vlan_control_port_t enumeration list 1368 * arg - (OUT) retrieved config value is to be stored in here 1369 * 1370 * Returns: 1371 * BCM_E_NONE - Success 1372 * BCM_E_PORT - If the given port/gport is not supported for TH3 VLAN module 1373 * BCM_E_PARAM - Given arg is NULL or type is not supported for TH3 1374 * BCM_E_XXX - Other failures 1375 * 1376 * Note: 1377 */ 1378 int 1379 bcm_tomahawk3_vlan_control_port_get(int unit, bcm_port_t port, 1380 bcm_vlan_control_port_t type, int *arg) 1381 { 1382 /* Validate and resolve the given port parameter */ 1383 BCM_IF_ERROR_RETURN( 1384 _bcm_th3_vlan_control_port_resolve(unit, port, FALSE, &port)); 1385 1386 return (_bcm_th3_vlan_control_port_config_command( 1387 unit, port, type, BCM_TH3_GET, arg)); 1388 } 1389 1390 /* 1391 * Function: 1392 * bcm_vlan_gport_add 1393 * 1394 * Purpose: 1395 * Add a Gport to the specified vlan. 1396 * 1397 * Parameters: 1398 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 1399 * vlan - (IN) VLAN ID to retrieve the gport from. 1400 * gport - (IN) Gport to be deleted from the VLAN. 1401 * flags - (IN) VLAN_PORT flags qualifying the GPORT. 1402 * 1403 * Returns: 1404 * BCM_E_NONE - Success. 1405 * BCM_E_INIT - VLAN module is not initialized. 1406 * BCM_E_PARAM - Given parameter validation failed. 1407 * BCM_E_PORT - Given GPORT not supported. 1408 * BCM_E_NOT_FOUND - VLAN ID not in use. 1409 * BCM_E_XXX - Other failures 1410 * 1411 * Note: 1412 */ 1413 int 1414 bcm_tomahawk3_vlan_gport_add( 1415 int unit, bcm_vlan_t vlan, bcm_gport_t gport, int flags) 1416 { 1417 int rv; 1418 bcm_pbmp_t pbmp; 1419 bcm_pbmp_t ubmp; 1420 bcm_pbmp_t ing_pbmp; 1421 bcm_port_t local_port; 1422 1423 /* Validate given VLAN ID */ 1424 CHECK_INIT_AND_VLAN_ID(unit, vlan); 1425 1426 /* Validate and resolve the given gport parameter */ 1427 BCM_IF_ERROR_RETURN( 1428 _bcm_th3_vlan_control_port_resolve(unit, gport, TRUE, &local_port)); 1429 1430 /* Validate the given flags */ 1431 if (flags & ~BCM_TH3_VLAN_GPORT_ADD_SUPPORTED_FLAGS) { 1432 return BCM_E_PARAM; 1433 } 1434 1435 /* If EGRESS_L3_ONLY is set then check if it is supported */ 1436 if ((flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY) && 1437 !soc_feature(unit, soc_feature_vlan_egress_membership_l3_only)) { 1438 return BCM_E_UNAVAIL; 1439 } 1440 1441 /* Both EGRESS_ONLY and EGREE_L3_ONLY cannot be set */ 1442 if ((flags & BCM_VLAN_GPORT_ADD_EGRESS_ONLY) && 1443 (flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) { 1444 return BCM_E_PARAM; 1445 } 1446 1447 /* With INGRESS flag EGRESS_(L3)_ONLY or UNTAGGED flags cannot be set */ 1448 if (flags & BCM_VLAN_GPORT_ADD_INGRESS_ONLY) { 1449 if (flags & BCM_VLAN_GPORT_ADD_UNTAGGED) { 1450 return BCM_E_PARAM; 1451 } 1452 1453 if ((flags & BCM_VLAN_GPORT_ADD_EGRESS_ONLY) || 1454 (flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) { 1455 return BCM_E_PARAM; 1456 } 1457 } 1458 1459 /* Based on the VLAN_GPORT_ADD flags form the port bitmaps appropriately */ 1460 if (flags & 1461 (BCM_VLAN_GPORT_ADD_EGRESS_ONLY | BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) { 1462 BCM_PBMP_CLEAR(ing_pbmp); 1463 } else { 1464 BCM_PBMP_PORT_SET(ing_pbmp, local_port); 1465 } 1466 if (flags & BCM_VLAN_GPORT_ADD_INGRESS_ONLY) { 1467 BCM_PBMP_CLEAR(pbmp); 1468 } else { 1469 BCM_PBMP_PORT_SET(pbmp, local_port); 1470 } 1471 if (flags & BCM_VLAN_GPORT_ADD_UNTAGGED) { 1472 BCM_PBMP_PORT_SET(ubmp, local_port); 1473 } else { 1474 BCM_PBMP_CLEAR(ubmp); 1475 } 1476 1477 /* Call low level routine to add the local physical port to the VLAN */ 1478 BCM_LOCK(unit); 1479 rv = _bcm_th3_vlan_port_add(unit, vlan, pbmp, ubmp, ing_pbmp, flags); 1480 BCM_UNLOCK(unit); 1481 1482 return rv; 1483 } 1484 1485 /* 1486 * Function: 1487 * bcm_vlan_gport_delete 1488 * 1489 * Purpose: 1490 * Delete a given Gport from the specified vlan. 1491 * 1492 * Parameters: 1493 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 1494 * vlan - (IN) VLAN ID to retrieve the gport from. 1495 * gport - (IN) Gport to be deleted from the VLAN 1496 * 1497 * Returns: 1498 * BCM_E_NONE - Success. 1499 * BCM_E_INIT - VLAN module is not initialized. 1500 * BCM_E_PARAM - Given parameter validation failed. 1501 * BCM_E_PORT - Given GPORT not supported. 1502 * BCM_E_NOT_FOUND - VLAN ID not in use. 1503 * BCM_E_XXX - Other failures 1504 * 1505 * Note: 1506 */ 1507 int 1508 bcm_tomahawk3_vlan_gport_delete(int unit, bcm_vlan_t vlan, bcm_gport_t gport) 1509 { 1510 int rv; 1511 bcm_pbmp_t pbmp; 1512 bcm_port_t local_port; 1513 1514 /* Validate given VLAN ID */ 1515 CHECK_INIT_AND_VLAN_ID(unit, vlan); 1516 1517 /* Validate and resolve the given gport parameter */ 1518 BCM_IF_ERROR_RETURN( 1519 _bcm_th3_vlan_control_port_resolve(unit, gport, TRUE, &local_port)); 1520 1521 /* Create a port bitmap from the retrieved local physical port */ 1522 BCM_PBMP_CLEAR(pbmp); 1523 BCM_PBMP_PORT_ADD(pbmp, local_port); 1524 1525 /* Call low level routine to remove the retrieved local phys port */ 1526 BCM_LOCK(unit); 1527 /* As we are passing only one pbmp parameter to API bcm_vlan_port_remove, 1528 * the expected result is to remove same pbmp from PORT_BITMAPf, UT_BITMAPf 1529 * and ING_PORT_BITMAPf. Hence, same pbmp is passed as argument for ubmp 1530 * and ing_pbmp 1531 */ 1532 rv = mbcm_driver[unit]->mbcm_vlan_port_remove( 1533 unit, vlan, pbmp, pbmp, pbmp); 1534 BCM_UNLOCK(unit); 1535 1536 return rv; 1537 } 1538 1539 /* 1540 * Function: 1541 * bcm_vlan_gport_extended_delete 1542 * 1543 * Purpose: 1544 * Delete the Gport qualified by the given VLAN_PORT 1545 * flags from the specified vlan. 1546 * 1547 * Parameters: 1548 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 1549 * vlan - (IN) VLAN ID to retrieve the gport from. 1550 * gport - (IN) Gport to be deleted from the VLAN 1551 * flags - (IN) VLAN_PORT flags qualifying the GPORT. 1552 * 1553 * Returns: 1554 * BCM_E_NONE - Success. 1555 * BCM_E_INIT - VLAN module is not initialized. 1556 * BCM_E_PARAM - Given parameter validation failed. 1557 * BCM_E_PORT - Given GPORT not supported. 1558 * BCM_E_NOT_FOUND - VLAN ID not in use. 1559 * BCM_E_XXX - Other failures 1560 * 1561 * Note: 1562 */ 1563 int 1564 bcm_tomahawk3_vlan_gport_extended_delete( 1565 int unit, bcm_vlan_t vlan, bcm_gport_t gport, int flags) 1566 { 1567 int rv; 1568 bcm_pbmp_t pbmp; 1569 bcm_pbmp_t ubmp; 1570 bcm_pbmp_t ing_pbmp; 1571 bcm_port_t local_port; 1572 1573 /* Validate given VLAN ID */ 1574 CHECK_INIT_AND_VLAN_ID(unit, vlan); 1575 1576 /* Validate and resolve the given gport parameter */ 1577 BCM_IF_ERROR_RETURN( 1578 _bcm_th3_vlan_control_port_resolve(unit, gport, TRUE, &local_port)); 1579 1580 /* Validate the given flags */ 1581 if (flags & ~BCM_TH3_VLAN_GPORT_ADD_SUPPORTED_FLAGS) { 1582 return BCM_E_PARAM; 1583 } 1584 1585 if (flags & BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY) { 1586 if (!soc_feature(unit, soc_feature_vlan_egress_membership_l3_only)) { 1587 return BCM_E_PARAM; 1588 } 1589 } 1590 1591 if (flags & 1592 (BCM_VLAN_PORT_EGRESS_ONLY | BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY)) { 1593 BCM_PBMP_CLEAR(ing_pbmp); 1594 } else { 1595 BCM_PBMP_PORT_SET(ing_pbmp, local_port); 1596 } 1597 if (flags & BCM_VLAN_PORT_INGRESS_ONLY) { 1598 BCM_PBMP_CLEAR(pbmp); 1599 } else { 1600 BCM_PBMP_PORT_SET(pbmp, local_port); 1601 } 1602 if (flags & BCM_VLAN_PORT_UNTAGGED) { 1603 BCM_PBMP_PORT_SET(ubmp, local_port); 1604 } else { 1605 BCM_PBMP_CLEAR(ubmp); 1606 } 1607 1608 /* Call low level routine to remove the retrieved local phys port */ 1609 BCM_LOCK(unit); 1610 rv = mbcm_driver[unit]->mbcm_vlan_port_remove( 1611 unit, vlan, pbmp, ubmp, ing_pbmp); 1612 BCM_UNLOCK(unit); 1613 1614 return rv; 1615 } 1616 1617 /* 1618 * Function: 1619 * bcm_vlan_gport_delete_all 1620 * 1621 * Purpose: 1622 * Delete all Gports from the specified vlan. 1623 * 1624 * Parameters: 1625 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 1626 * vlan - (IN) VLAN ID to retrieve the gport from. 1627 * 1628 * Returns: 1629 * BCM_E_NONE - Success. 1630 * BCM_E_INIT - VLAN module is not initialized. 1631 * BCM_E_PARAM - Given parameter validation failed. 1632 * BCM_E_NOT_FOUND - VLAN ID not in use. 1633 * BCM_E_XXX - Other failures 1634 * 1635 * Note: 1636 */ 1637 int 1638 bcm_tomahawk3_vlan_gport_delete_all(int unit, bcm_vlan_t vlan) 1639 { 1640 int rv; 1641 bcm_pbmp_t pbmp; 1642 bcm_pbmp_t ubmp; 1643 bcm_pbmp_t ing_pbmp; 1644 1645 /* Validate given VLAN ID */ 1646 CHECK_INIT_AND_VLAN_ID(unit, vlan); 1647 1648 /* Retrieve all local physical ports bound to the given VLAN */ 1649 BCM_IF_ERROR_RETURN( 1650 _bcm_th3_vlan_port_get(unit, vlan, &pbmp, &ubmp, &ing_pbmp)); 1651 1652 LOG_VERBOSE(BSL_LS_BCM_VLAN, 1653 (BSL_META_U(unit, 1654 "Vlan %d: gport rem all: pbm 0x%x, upbm 0x%x.\n"), vlan, 1655 SOC_PBMP_WORD_GET(pbmp, 0), SOC_PBMP_WORD_GET(ubmp, 0))); 1656 1657 /* Call low level routine to remove all local physical ports */ 1658 BCM_LOCK(unit); 1659 rv = mbcm_driver[unit]-> 1660 mbcm_vlan_port_remove(unit, vlan, pbmp, ubmp, ing_pbmp); 1661 BCM_UNLOCK(unit); 1662 1663 return rv; 1664 } 1665 1666 /* 1667 * Function: 1668 * bcm_vlan_gport_get 1669 * 1670 * Purpose: 1671 * Retrieve VLAN_PORT flags for the given Gport on the specified vlan. 1672 * 1673 * Parameters: 1674 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 1675 * vlan - (IN) VLAN ID to retrieve the gport and its flags from. 1676 * port - (IN) Gport for which the flags are to be retrieved. 1677 * flags - (OUT) VLAN_PORT flags to be stored here. 1678 * 1679 * Returns: 1680 * BCM_E_NONE - Success. 1681 * BCM_E_INIT - VLAN module is not initialized. 1682 * BCM_E_PARAM - Given parameter validation failed. 1683 * BCM_E_PORT - Not supported Gport. 1684 * BCM_E_NOT_FOUND - VLAN ID not in use or invalid flags on the VLAN. 1685 * BCM_E_XXX - Other failures 1686 * 1687 * Note: 1688 */ 1689 int 1690 bcm_tomahawk3_vlan_gport_get( 1691 int unit, bcm_vlan_t vlan, bcm_gport_t gport, int *flags) 1692 { 1693 uint32 local_flags = 0; 1694 bcm_pbmp_t pbmp; 1695 bcm_pbmp_t ubmp; 1696 bcm_pbmp_t ing_pbmp; 1697 bcm_port_t local_port; 1698 1699 /* Validate given VLAN ID */ 1700 CHECK_INIT_AND_VLAN_ID(unit, vlan); 1701 1702 /* Validate other input parameters */ 1703 if (NULL == flags) { 1704 return BCM_E_PARAM; 1705 } 1706 1707 /* Validate and resolve the given gport parameter */ 1708 BCM_IF_ERROR_RETURN( 1709 _bcm_th3_vlan_control_port_resolve(unit, gport, TRUE, &local_port)); 1710 1711 /* Retrieve all local physical ports bound to the given VLAN */ 1712 BCM_IF_ERROR_RETURN( 1713 _bcm_th3_vlan_port_get(unit, vlan, &pbmp, &ubmp, &ing_pbmp)); 1714 1715 /* Deduce the VLAN_PORT flags */ 1716 if (!BCM_PBMP_MEMBER(pbmp, local_port)) { 1717 local_flags |= BCM_VLAN_PORT_INGRESS_ONLY; 1718 } 1719 if (!BCM_PBMP_MEMBER(ing_pbmp, local_port)) { 1720 local_flags |= BCM_VLAN_PORT_EGRESS_ONLY; 1721 } 1722 if (local_flags == 1723 (BCM_VLAN_PORT_INGRESS_ONLY | BCM_VLAN_PORT_EGRESS_ONLY)) { 1724 return BCM_E_NOT_FOUND; 1725 } 1726 if (BCM_PBMP_MEMBER(ubmp, local_port)) { 1727 local_flags |= BCM_VLAN_PORT_UNTAGGED; 1728 } 1729 if ((local_flags & BCM_VLAN_PORT_EGRESS_ONLY) && 1730 soc_feature(unit, soc_feature_vlan_egress_membership_l3_only)) { 1731 1732 BCM_PBMP_CLEAR(pbmp); 1733 BCM_IF_ERROR_RETURN( 1734 _bcm_xgs3_vlan_table_port_get( 1735 unit, vlan, &pbmp, NULL, NULL, VLAN_2_TABm)); 1736 1737 if (!BCM_PBMP_MEMBER(pbmp, local_port)) { 1738 local_flags &= ~BCM_VLAN_PORT_EGRESS_ONLY; 1739 local_flags |= BCM_VLAN_GPORT_ADD_EGRESS_L3_ONLY; 1740 } 1741 } 1742 1743 /* Store the scrutinized Flags value */ 1744 *flags = local_flags; 1745 return BCM_E_NONE; 1746 } 1747 1748 /* 1749 * Function: 1750 * bcm_vlan_gport_get_all 1751 * 1752 * Purpose: 1753 * Retrieve VLAN_PORT flags for all Gports from the specified vlan. 1754 * 1755 * Parameters: 1756 * unit - (IN) StrataSwitch PCI device unit number (driver internal). 1757 * vlan - (IN) VLAN ID to retrieve all gports from. 1758 * array_max - (IN) Max slize for the provided arrays. 1759 * gport_array - (OUT) Array to be stored with the gports. 1760 * flags_array - (OUT) Array to be stored with VLAN_PORT flags. 1761 * array_size - (OUT) Number of retrieved gports. 1762 * 1763 * Returns: 1764 * BCM_E_NONE - Success. 1765 * BCM_E_INIT - VLAN module is not initialized. 1766 * BCM_E_PARAM - Given parameter validation failed. 1767 * BCM_E_NOT_FOUND - VLAN ID not in use or no gports on the VLAN. 1768 * BCM_E_XXX - Other failures 1769 * 1770 * Note: 1771 * 1) Parameter 'array_max' should be passed with positive value. 1772 * 2) Paremeter 'gport_array' and 'flags_array' are optional. If not 1773 * given then API would just return number of gports atatched to 1774 * the given VLAN. If either of the parameter is given then that 1775 * information is filled in by the API. 1776 */ 1777 int 1778 bcm_tomahawk3_vlan_gport_get_all(int unit, bcm_vlan_t vlan, 1779 int array_max, bcm_gport_t *gport_array, int *flags_array, int* array_size) 1780 { 1781 int rv = BCM_E_NONE; 1782 int local_modid; 1783 int port_cnt = 0; 1784 uint32 local_flags = 0; 1785 bcm_pbmp_t bmp; 1786 bcm_pbmp_t pbmp; 1787 bcm_pbmp_t ubmp; 1788 bcm_pbmp_t ing_pbmp; 1789 bcm_port_t port; 1790 bcm_gport_t gport; 1791 _bcm_gport_dest_t gport_dest; 1792 1793 /* Validate given VLAN ID */ 1794 CHECK_INIT_AND_VLAN_ID(unit, vlan); 1795 1796 /* Validate other incoming parameters */ 1797 if ((NULL == array_size) || (array_max <= 0)) { 1798 return BCM_E_PARAM; 1799 } 1800 1801 /* Retrieve the local mod id */ 1802 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &local_modid)); 1803 1804 /* Retrieve the local physical ports bound to the given VLAN */ 1805 BCM_IF_ERROR_RETURN( 1806 _bcm_th3_vlan_port_get(unit, vlan, &pbmp, &ubmp, &ing_pbmp)); 1807 1808 /* Prepare a superset of bitmaps to iterate over */ 1809 BCM_PBMP_ASSIGN(bmp, pbmp); 1810 BCM_PBMP_OR(bmp, ubmp); 1811 BCM_PBMP_OR(bmp, ing_pbmp); 1812 1813 /* Iterate through the list of ports from superset */ 1814 BCM_PBMP_ITER(bmp, port) { 1815 1816 /* Check for boundary conditions */ 1817 if ((port_cnt == array_max) && gport_array) { 1818 break; 1819 } 1820 1821 /* Formulate the MODPORT gport from the chosen local port */ 1822 gport_dest.port = port; 1823 gport_dest.modid = local_modid; 1824 gport_dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 1825 BCM_IF_ERROR_RETURN( 1826 _bcm_esw_gport_construct(unit, &gport_dest, &gport)); 1827 1828 /* Deduce the VLAN_PORT flags */ 1829 local_flags = 0; 1830 if (!BCM_PBMP_MEMBER(pbmp, port)) { 1831 local_flags |= BCM_VLAN_PORT_INGRESS_ONLY; 1832 } 1833 if (!BCM_PBMP_MEMBER(ing_pbmp, port)) { 1834 local_flags |= BCM_VLAN_PORT_EGRESS_ONLY; 1835 } 1836 if (local_flags == 1837 (BCM_VLAN_PORT_INGRESS_ONLY | BCM_VLAN_PORT_EGRESS_ONLY)) { 1838 continue; 1839 } 1840 1841 /* Fill in the flags for the chosen port, if the flags_array given */ 1842 if (flags_array) { 1843 if (BCM_PBMP_MEMBER(ubmp, port)) { 1844 local_flags |= BCM_VLAN_PORT_UNTAGGED; 1845 } 1846 flags_array[port_cnt] = local_flags; 1847 } 1848 1849 /* Fill in the gport for the chosen port, if the gport_array given */ 1850 if (gport_array) { 1851 gport_array[port_cnt] = gport; 1852 } 1853 1854 port_cnt++; 1855 } 1856 1857 /* If all attempts found nothing return not found */ 1858 if (port_cnt) { 1859 *array_size = port_cnt; 1860 } else { 1861 rv = BCM_E_NOT_FOUND; 1862 } 1863 1864 return rv; 1865 } 1866 1867 /* 1868 * Function: 1869 * bcm_vlan_port_default_action_set 1870 * 1871 * Purpose: 1872 * Set the port's default vlan tag actions 1873 * 1874 * Parameters: 1875 * unit - (IN) BCM unit. 1876 * port - (IN) Port number (Gport or Local). 1877 * action - (IN) Vlan tag actions 1878 * 1879 * Returns: 1880 * BCM_E_XXX 1881 * 1882 * Note: 1883 */ 1884 int 1885 bcm_tomahawk3_vlan_port_default_action_set( 1886 int unit, bcm_port_t port, bcm_vlan_action_set_t *action) 1887 { 1888 return( 1889 _bcm_th3_ing_vlan_tag_action_command(unit, port, BCM_TH3_SET, action)); 1890 } 1891 1892 /* 1893 * Function: 1894 * bcm_vlan_port_default_action_get 1895 * 1896 * Purpose: 1897 * Get the port's default vlan tag actions 1898 * 1899 * Parameters: 1900 * unit - (IN) BCM unit. 1901 * port - (IN) Port number. 1902 * action - (OUT) Vlan tag actions 1903 * 1904 * Returns: 1905 * BCM_E_XXX 1906 * 1907 * Note: 1908 */ 1909 int 1910 bcm_tomahawk3_vlan_port_default_action_get( 1911 int unit, bcm_port_t port, bcm_vlan_action_set_t *action) 1912 { 1913 return( 1914 _bcm_th3_ing_vlan_tag_action_command(unit, port, BCM_TH3_GET, action)); 1915 } 1916 1917 /* 1918 * Function: 1919 * bcm_vlan_port_default_action_delete 1920 * 1921 * Purpose: 1922 * Delete the port's default vlan tag actions 1923 * 1924 * Parameters: 1925 * unit - (IN) BCM unit. 1926 * port - (IN) Port number. 1927 * 1928 * Returns: 1929 * BCM_E_XXX 1930 * 1931 * Note: 1932 */ 1933 int 1934 bcm_tomahawk3_vlan_port_default_action_delete(int unit, bcm_port_t port) 1935 { 1936 return(_bcm_th3_ing_vlan_tag_action_command(unit, port, BCM_TH3_DEL, NULL)); 1937 } 1938 1939 /* 1940 * Function: 1941 * bcm_vlan_port_egress_default_action_set 1942 * 1943 * Purpose: 1944 * Set the egress port's default vlan tag actions 1945 * 1946 * Parameters: 1947 * unit - (IN) BCM unit. 1948 * port - (IN) Port number (Gport or Local). 1949 * action - (IN) Vlan tag actions 1950 * 1951 * Returns: 1952 * BCM_E_XXX 1953 * 1954 * Note: 1955 */ 1956 int 1957 bcm_tomahawk3_vlan_port_egress_default_action_set( 1958 int unit, bcm_port_t port, bcm_vlan_action_set_t *action) 1959 { 1960 return( 1961 _bcm_th3_egr_vlan_tag_action_command(unit, port, BCM_TH3_SET, action)); 1962 } 1963 1964 /* 1965 * Function: 1966 * bcm_vlan_port_egress_default_action_get 1967 * 1968 * Purpose: 1969 * Get the port's egress default vlan tag actions 1970 * 1971 * Parameters: 1972 * unit - (IN) BCM unit. 1973 * port - (IN) Port number. 1974 * action - (OUT) Vlan tag actions 1975 * 1976 * Returns: 1977 * BCM_E_XXX 1978 * 1979 * Note: 1980 */ 1981 int 1982 bcm_tomahawk3_vlan_port_egress_default_action_get( 1983 int unit, bcm_port_t port, bcm_vlan_action_set_t *action) 1984 { 1985 return( 1986 _bcm_th3_egr_vlan_tag_action_command(unit, port, BCM_TH3_GET, action)); 1987 } 1988 1989 /* 1990 * Function: 1991 * bcm_vlan_port_egress_default_action_delete 1992 * 1993 * Purpose: 1994 * Delete the port's egress default vlan tag actions 1995 * 1996 * Parameters: 1997 * unit - (IN) BCM unit. 1998 * port - (IN) Port number. 1999 * 2000 * Returns: 2001 * BCM_E_XXX 2002 * 2003 * Note: 2004 */ 2005 int 2006 bcm_tomahawk3_vlan_port_egress_default_action_delete(int unit, bcm_port_t port) 2007 { 2008 return _bcm_th3_egr_vlan_tag_action_command(unit, port, BCM_TH3_DEL, NULL); 2009 } 2010 2011 /* 2012 * Function: 2013 * bcm_vlan_cross_connect_add 2014 * 2015 * Purpose: 2016 * Add a VLAN cross connect entry 2017 * 2018 * Parameters: 2019 * unit - (IN) BCM unit. 2020 * outer_vlan - (IN) Outer vlan ID 2021 * inner_vlan - (IN) Inner vlan ID 2022 * port_1 - (IN) First port in the cross-connect 2023 * port_2 - (IN) Second port in the cross-connect 2024 * 2025 * Returns: 2026 * BCM_E_NONE - Success. 2027 * BCM_E_PARAM - Vlan IDs are invalid 2028 * BCM_E_PORT - Given gports are invalid or not supported 2029 * BCM_E_XXX - Other failures 2030 * 2031 * Note: 2032 */ 2033 int 2034 bcm_tomahawk3_vlan_cross_connect_add(int unit, bcm_vlan_t outer_vlan, 2035 bcm_vlan_t inner_vlan, bcm_gport_t port_1, bcm_gport_t port_2) 2036 { 2037 int rv; 2038 int dest_val[2]; 2039 uint8 is_trunk_gport[2] = {0, 0}; 2040 2041 /* Validate if the VLAN module has been initialized */ 2042 CHECK_INIT(unit); 2043 2044 /* Validate the outer and inner VLAN ID values */ 2045 if (BCM_VLAN_INVALID != inner_vlan) { 2046 return BCM_E_UNAVAIL; 2047 } 2048 2049 if ((outer_vlan < BCM_VLAN_DEFAULT) || (outer_vlan > BCM_VLAN_MAX)) { 2050 return BCM_E_PARAM; 2051 } 2052 2053 /* Validate and resolve the given gport parameters */ 2054 rv = _bcm_th3_vlan_control_port_resolve(unit, port_1, TRUE, &dest_val[0]); 2055 2056 if (BCM_E_NONE != rv) { 2057 /* _bcm_th3_vlan_control_port_resolve does not check for Trunk 2058 * GPORT. Check for it explicitly and retrieve the trunk ID 2059 */ 2060 if (BCM_GPORT_IS_TRUNK(port_1)) { 2061 is_trunk_gport[0] = 1; 2062 dest_val[0] = BCM_GPORT_TRUNK_GET(port_1); 2063 } else { 2064 return rv; 2065 } 2066 } 2067 2068 rv = _bcm_th3_vlan_control_port_resolve(unit, port_2, TRUE, &dest_val[1]); 2069 if (BCM_E_NONE != rv) { 2070 /* _bcm_th3_vlan_control_port_resolve does not check for Trunk 2071 * GPORT. Check for it explicitly and retrieve the trunk ID 2072 */ 2073 if (BCM_GPORT_IS_TRUNK(port_2)) { 2074 is_trunk_gport[1] = 1; 2075 dest_val[1] = BCM_GPORT_TRUNK_GET(port_2); 2076 } else { 2077 return rv; 2078 } 2079 } 2080 2081 return _bcm_th3_vlan_xconnect_db_entry_add( 2082 unit, outer_vlan, is_trunk_gport, dest_val); 2083 } 2084 2085 /* 2086 * Function: 2087 * bcm_vlan_cross_connect_delete 2088 * 2089 * Purpose: 2090 * Delete a VLAN cross connect entry 2091 * 2092 * Parameters: 2093 * unit - (IN) BCM unit. 2094 * outer_vlan - (IN) Outer vlan ID 2095 * inner_vlan - (IN) Inner vlan ID 2096 * 2097 * Returns: 2098 * BCM_E_NONE - Success. 2099 * BCM_E_PARAM - Vlan IDs are invalid 2100 * BCM_E_XXX - Other failures 2101 * 2102 * Note: 2103 */ 2104 int 2105 bcm_tomahawk3_vlan_cross_connect_delete( 2106 int unit, bcm_vlan_t outer_vlan, bcm_vlan_t inner_vlan) 2107 { 2108 /* Validate if the VLAN module has been initialized */ 2109 CHECK_INIT(unit); 2110 2111 /* Validate the inner VLAN ID value */ 2112 if (BCM_VLAN_INVALID != inner_vlan) { 2113 return BCM_E_UNAVAIL; 2114 } 2115 2116 return _bcm_th3_vlan_xconnect_db_entry_delete(unit, outer_vlan); 2117 } 2118 2119 /* 2120 * Function: 2121 * bcm_vlan_cross_connect_delete_all 2122 * 2123 * Purpose: 2124 * Delete all VLAN cross connect entries 2125 * 2126 * Parameters: 2127 * unit - (IN) BCM unit. 2128 * 2129 * Returns: 2130 * BCM_E_NONE - Success. 2131 * BCM_E_XXX - Other failures 2132 * 2133 * Note: 2134 */ 2135 int 2136 bcm_tomahawk3_vlan_cross_connect_delete_all(int unit) 2137 { 2138 /* Validate if the VLAN module has been initialized */ 2139 CHECK_INIT(unit); 2140 2141 return _bcm_th3_vlan_xconnect_db_entry_delete_all(unit); 2142 } 2143 2144 /* 2145 * Function: 2146 * bcm_vlan_cross_connect_traverse 2147 * 2148 * Purpose: 2149 * Walks through the valid cross connect entries and calls 2150 * the user supplied callback function for each entry. 2151 * 2152 * Parameters: 2153 * unit - (IN) BCM unit. 2154 * cb - (IN) Callback function. 2155 * user_data - (IN) User data to be passed to callback function. 2156 * 2157 * Returns: 2158 * BCM_E_NONE - Success. 2159 * BCM_E_PARAM - Call back function not provided 2160 * BCM_E_XXX - Other failures 2161 * 2162 * Note: 2163 */ 2164 int 2165 bcm_tomahawk3_vlan_cross_connect_traverse(int unit, 2166 bcm_vlan_cross_connect_traverse_cb cb, 2167 void *user_data) 2168 { 2169 /* Validate if the VLAN module has been initialized */ 2170 CHECK_INIT(unit); 2171 2172 if (NULL == cb) { 2173 return BCM_E_PARAM; 2174 } 2175 2176 return _bcm_th3_vlan_xconnect_traverse(unit, cb, user_data); 2177 } 2178 2179 #endif /* BCM_TOMAHAWK3_SUPPORT */