port.c (2297937B)
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-2020 Broadcom Inc. All rights reserved. 6 * 7 * File: port.c 8 * Purpose: Tracks and manages ports. 9 * P-VLAN table is managed directly. 10 * MAC/PHY interfaces are managed through respective drivers. 11 */ 12 13 #include <shared/bsl.h> 14 15 #include <assert.h> 16 17 #include <sal/core/libc.h> 18 #include <sal/core/boot.h> 19 #include <shared/bsl.h> 20 21 #include <soc/cm.h> 22 #include <soc/drv.h> 23 #include <soc/scache.h> 24 #include <soc/phy.h> 25 #include <soc/ll.h> 26 #include <soc/ptable.h> 27 #include <soc/firebolt.h> 28 #include <soc/xaui.h> 29 #include <soc/phyctrl.h> 30 #include <soc/phyreg.h> 31 #include <soc/higig.h> 32 #include <soc/hash.h> 33 #include <soc/macutil.h> 34 35 #include <bcm/port.h> 36 #include <bcm/error.h> 37 #include <bcm/mirror.h> 38 39 #ifdef SW_AUTONEG_SUPPORT 40 #include <bcm_int/common/sw_an.h> 41 #endif 42 43 #include <bcm_int/api_xlate_port.h> 44 #include <bcm_int/common/lock.h> 45 #include <bcm_int/common/tx.h> 46 #include <bcm_int/common/sat.h> 47 #include <bcm_int/esw/mbcm.h> 48 #include <bcm_int/esw/port.h> 49 #include <bcm_int/esw/link.h> 50 #include <bcm_int/esw/mirror.h> 51 #include <bcm_int/esw/stack.h> 52 #include <bcm_int/esw/stat.h> 53 #include <bcm_int/esw/timesync.h> 54 #include <bcm_int/esw/firebolt.h> 55 #include <bcm_int/esw/portctrl.h> 56 #include <bcm_int/esw/vxlan.h> 57 #if defined(BCM_TRIUMPH_SUPPORT) 58 #include <bcm_int/esw/triumph.h> 59 #include <bcm_int/esw/virtual.h> 60 #endif /* BCM_TRIUMPH_SUPPORT */ 61 #if defined(BCM_SCORPION_SUPPORT) 62 #include <bcm_int/esw/scorpion.h> 63 #include <bcm_int/esw/triumph.h> 64 #endif /* BCM_SCORPION_SUPPORT */ 65 #if defined(BCM_TRX_SUPPORT) 66 #include <bcm_int/esw/trx.h> 67 #endif /* BCM_TRX_SUPPORT */ 68 #if defined(BCM_TRIUMPH2_SUPPORT) 69 #include <bcm_int/esw/triumph2.h> 70 #include <soc/triumph2.h> 71 #endif /* BCM_TRIUMPH2_SUPPORT */ 72 #if defined(BCM_TRIDENT_SUPPORT) 73 #include <bcm_int/esw/trident.h> 74 #endif /* BCM_TRIUMPH2_SUPPORT */ 75 #if defined(BCM_KATANA_SUPPORT) 76 #include <bcm_int/esw/katana.h> 77 #endif /* BCM_KATANA_SUPPORT */ 78 #if defined(BCM_APACHE_SUPPORT) 79 #include <bcm_int/esw/monterey.h> 80 #include <soc/monterey.h> 81 #endif /* BCM_MONTEREY_SUPPORT */ 82 #if defined(BCM_APACHE_SUPPORT) 83 #include <bcm_int/esw/apache.h> 84 #include <soc/apache.h> 85 #endif /* BCM_APACHE_SUPPORT */ 86 #if defined(BCM_ENDURO_SUPPORT) 87 #include <bcm_int/esw/enduro.h> 88 #endif /* BCM_ENDURO_SUPPORT */ 89 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 90 #include <bcm_int/esw/hurricane.h> 91 #endif /* BCM_HURRICANE_SUPPORT */ 92 #if defined(BCM_HURRICANE2_SUPPORT) 93 #include <soc/hurricane2.h> 94 #endif /* BCM_HURRICANE_SUPPORT */ 95 #if defined(BCM_SHADOW_SUPPORT) 96 #include <soc/shadow.h> 97 #endif /* BCM_SHADOW_SUPPORT */ 98 #if defined(BCM_TRIUMPH3_SUPPORT) 99 #include <bcm_int/esw/triumph3.h> 100 #include <soc/triumph3.h> 101 #include <bcm_int/esw/extender.h> 102 #endif /* BCM_TRIUMPH3_SUPPORT */ 103 #if defined(BCM_TRIDENT2_SUPPORT) 104 #include <bcm_int/esw/trident2.h> 105 #include <soc/trident2.h> 106 #include <bcm_int/esw/trunk.h> 107 #endif /* BCM_TRIDENT2_SUPPORT */ 108 #if defined(BCM_TOMAHAWK_SUPPORT) 109 #include <bcm_int/esw/tomahawk.h> 110 #include <soc/tomahawk.h> 111 #endif /* BCM_TOMAHAWK_SUPPORT */ 112 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 113 #include <bcm_int/esw/trident2plus.h> 114 #include <soc/td2_td2p.h> 115 #include <bcm_int/esw/subport.h> 116 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 117 #if defined(BCM_TRIDENT3_SUPPORT) 118 #include <soc/esw/cancun.h> 119 #include <bcm_int/esw/trident3.h> 120 #include <soc/trident3.h> 121 #endif /* BCM_TRIDENT3_SUPPORT */ 122 #if defined(BCM_HELIX5_SUPPORT) 123 #include <soc/esw/cancun.h> 124 #include <bcm_int/esw/helix5.h> 125 #include <soc/helix5.h> 126 #endif /* BCM_HELIX5_SUPPORT */ 127 #if defined(BCM_MAVERICK2_SUPPORT) 128 #include <soc/esw/cancun.h> 129 #include <bcm_int/esw/maverick2.h> 130 #include <soc/maverick2.h> 131 #endif /* BCM_MAVERICK2_SUPPORT */ 132 #if defined(BCM_TOMAHAWK3_SUPPORT) 133 #include <bcm_int/esw/tomahawk3.h> 134 #include <bcm_int/esw/pfc.h> 135 #include <bcm_int/esw/xgs5.h> 136 #include <soc/tomahawk3.h> 137 #endif /* BCM_TOMAHAWK3_SUPPORT */ 138 #if defined(BCM_HURRICANE4_SUPPORT) 139 #include <soc/esw/cancun.h> 140 #include <bcm_int/esw/hurricane4.h> 141 #include <soc/hurricane4.h> 142 #endif /* BCM_HURRICANE4_SUPPORT */ 143 #if defined(BCM_FIREBOLT6_SUPPORT) 144 #include <soc/esw/cancun.h> 145 #include <bcm_int/esw/firebolt6.h> 146 #include <soc/firebolt6.h> 147 #endif /* BCM_FIREBOLT6_SUPPORT */ 148 #if defined (BCM_HGPROXY_COE_SUPPORT) 149 #include <bcm_int/esw/xgs5.h> 150 #include <bcm_int/esw/subport.h> 151 #endif /* BCM_HGPROXY_COE_SUPPORT */ 152 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 153 #include <bcm_int/esw/tomahawk2.h> 154 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */ 155 #if defined(BCM_TOMAHAWK2_SUPPORT) 156 #include <bcm_int/esw/xgs5.h> 157 #include <soc/tomahawk2.h> 158 #endif /* BCM_TOMAHAWK2_SUPPORT */ 159 #include <bcm_int/esw/xgs3.h> 160 161 #include <bcm_int/esw/flex_ctr.h> 162 #include <bcm_int/esw/policer.h> 163 #if defined(BCM_KATANA2_SUPPORT) 164 #include <bcm_int/esw/subport.h> 165 #include <bcm_int/esw/katana2.h> 166 #include <soc/katana2.h> 167 #include <bcm/subport.h> 168 #endif /* BCM_KATANA2_SUPPORT */ 169 #if defined(BCM_SABER2_SUPPORT) 170 #include <bcm_int/esw/saber2.h> 171 #include <soc/saber2.h> 172 #endif /* BCM_SABER2_SUPPORT */ 173 #if defined(BCM_METROLITE_SUPPORT) 174 #include <bcm_int/esw/metrolite.h> 175 #include <soc/metrolite.h> 176 #endif /* BCM_METROLITE_SUPPORT */ 177 #if defined(BCM_GREYHOUND_SUPPORT) 178 #include <bcm_int/esw/greyhound.h> 179 #endif /* BCM_GREYHOUND_SUPPORT */ 180 #if defined(BCM_HURRICANE3_SUPPORT) 181 #include <bcm_int/esw/hurricane3.h> 182 #include <soc/hurricane3.h> 183 #endif /* BCM_HURRICANE3_SUPPORT */ 184 #if defined(BCM_GREYHOUND2_SUPPORT) 185 #include <bcm_int/esw/greyhound2.h> 186 #endif /* BCM_GREYHOUND2_SUPPORT */ 187 #if defined (BCM_EP_REDIRECT_VERSION_2) 188 #include <bcm_int/esw/xgs5.h> 189 #endif 190 #if defined(BCM_HGPROXY_COE_SUPPORT) 191 #include <bcm_int/esw/subport.h> 192 #include <bcm_int/esw/xgs5.h> 193 #endif /* BCM_HGPROXY_COE_SUPPORT */ 194 #if defined(BCM_PREEMPTION_SUPPORT) 195 #include <bcm_int/esw/preemption.h> 196 #include <bcm_int/esw/preemption_cnt.h> 197 #endif /* BCM_PREEMPTION_SUPPORT */ 198 #include <bcm_int/esw_dispatch.h> 199 200 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_WARM_BOOT_SUPPORT) 201 #include <bcm_int/esw/switch.h> 202 #endif /* BCM_WARM_BOOT_SUPPORT */ 203 204 #if defined(BCM_TRIUMPH2_SUPPORT) 205 #include <bcm_int/esw/qos.h> 206 #endif /* BCM_TRIUMPH2_SUPPORT */ 207 208 #ifdef PORTMOD_SUPPORT 209 #include <soc/portmod/portmod.h> 210 #endif /* PORTMOD_SUPPORT */ 211 212 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT 213 #include <bcm_int/esw/xgs5.h> 214 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */ 215 216 #ifdef INCLUDE_FCMAP 217 #include <../../phyident.h> 218 #endif 219 220 #define BCMI_GPORT_TYPE_VALID(port) \ 221 (BCM_GPORT_IS_VLAN_PORT(port) || \ 222 BCM_GPORT_IS_NIV_PORT(port) || \ 223 BCM_GPORT_IS_EXTENDER_PORT(port) || \ 224 BCM_GPORT_IS_SUBPORT_PORT(port) || \ 225 BCM_GPORT_IS_VXLAN_PORT(port) || \ 226 BCM_GPORT_IS_L2GRE_PORT(port) || \ 227 BCM_GPORT_IS_MIM_PORT(port) || \ 228 BCM_GPORT_IS_MPLS_PORT(port) || \ 229 BCM_GPORT_IS_FLOW_PORT(port) || \ 230 BCM_GPORT_IS_TRUNK(port)) 231 232 233 #if defined (BCM_EP_REDIRECT_VERSION_2) 234 #define BCMI_EP_REDIRECT_PORT (74) 235 #endif 236 237 #define _BCM_QOS_MAP_CHUNK_EGR_DSCP 64 238 #define _BCM_I2E_CLASS_ID_MAX 0x1ff 239 240 /* 241 * Define the macro for measuring the benchmark of speed change. 242 */ 243 #define BCM_PORT_SPEED_CHANGE_BENCHMARK 244 245 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 246 #define MODULE_ID_LOWER_6_BITS(a) ((a) = ((a) & 0x3f)) 247 #endif 248 249 /* 250 * Port Function Vector Driver 251 */ 252 bcm_esw_port_drv_t *bcm_esw_port_drv[BCM_MAX_NUM_UNITS] = {0}; 253 254 /* 255 * Variable: 256 * bcm_port_info 257 * Purpose: 258 * One entry for each SOC device containing port information 259 * for that device. Use the PORT macro to access it. 260 */ 261 static _bcm_port_info_t *bcm_port_info[BCM_MAX_NUM_UNITS]; 262 263 STATIC _bcm_port_force_forward_linkstate_t p_linkstate[BCM_MAX_NUM_UNITS]; 264 265 #define PORT(unit, port) bcm_port_info[unit][port] 266 267 extern int inside_bcm_shutdown[BCM_MAX_NUM_UNITS]; 268 269 #if defined(BCM_XMAC_SUPPORT) 270 extern int _mac_x_reinit(int unit, soc_port_t port); 271 #endif 272 273 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 274 extern src_modid_base_index_bookkeeping_t *src_modid_base_index_bk[BCM_MAX_NUM_UNITS]; 275 #endif 276 277 #if defined(BCM_TRIDENT3_SUPPORT) 278 extern int 279 _bcm_fb2_egr_vlan_control_field_get(int unit, bcm_port_t port, 280 soc_field_t field, uint32 *value); 281 extern int 282 _bcm_fb2_port_tpid_enable_set(int unit, bcm_port_t port, uint32 tpid_enable); 283 extern int 284 _bcm_fb2_port_tpid_enable_get(int unit, bcm_port_t port, uint32 *tpid_enable); 285 #endif 286 287 /* Accessor to bcm_port_info used by other modules */ 288 void _bcm_port_info_access(int unit, bcm_port_t port, _bcm_port_info_t **info) 289 { 290 (bcm_port_info[unit] != NULL) ? (*info = &PORT(unit, port)):(*info = NULL); 291 return; 292 } 293 294 /* Return On error with port mutex unlocked */ 295 #define _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(op) \ 296 do { \ 297 int __rv__; \ 298 if (((__rv__ = (op)) < 0)) { \ 299 PORT_UNLOCK(unit); \ 300 _SHR_ERROR_TRACE(__rv__); \ 301 return(__rv__); \ 302 } \ 303 } while(0) 304 305 int 306 _bcm_esw_port_gport_phyn_validate(int unit, bcm_port_t port, 307 bcm_port_t *local_port, int *phyn, 308 int *phy_lane, int *sys_side); 309 310 #if defined(BCM_KATANA2_SUPPORT) 311 int _bcm_kt2_update_port_mode(int unit, uint8 port, int speed); 312 int _bcm_kt2_cosq_dynamic_port_encap_change(int unit, bcm_port_t port); 313 #endif 314 315 #if defined(BCM_METROLITE_SUPPORT) 316 int _bcm_ml_update_port_mode(int unit, uint8 port, int speed); 317 #endif 318 #if defined(BCM_SABER2_SUPPORT) 319 int _bcm_sb2_update_port_mode(int unit, uint8 port, int speed); 320 #ifdef BCM_WARM_BOOT_SUPPORT 321 int bcm_sb2_wb_v2_flexio_update = 0; 322 #endif 323 #endif 324 #if defined(BCM_TRIUMPH3_SUPPORT) 325 STATIC int 326 _bcm_port_force_forward_add(int unit, bcm_port_t local_port, 327 bcm_port_t egr_port); 328 329 STATIC int 330 _bcm_port_force_forward_init(int unit); 331 332 STATIC int 333 _bcm_port_force_forward_deinit(int unit); 334 335 #ifdef BCM_WARM_BOOT_SUPPORT 336 STATIC int 337 _bcm_port_force_forward_sync(int unit, uint8 **scache_ptr); 338 339 STATIC int 340 _bcm_port_force_forward_reinit(int unit, uint8 **scache_ptr); 341 342 STATIC int 343 _bcm_port_force_forward_scache_size(int unit, int *size); 344 #endif /* BCM_WARM_BOOT_SUPPORT */ 345 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */ 346 347 /* 348 * Define: 349 * PORT_INIT 350 * Purpose: 351 * Causes a routine to return BCM_E_INIT if port is not yet initialized. 352 */ 353 354 #define PORT_INIT(unit) \ 355 if (bcm_port_info[unit] == NULL) { return BCM_E_INIT; } 356 357 /* 358 * Define: 359 * PORT_PARAM_CHECK 360 * Purpose: 361 * Check unit and port parameters for most bcm_port api calls 362 */ 363 #define PORT_PARAM_CHECK(unit, port) do { \ 364 PORT_INIT(unit); \ 365 if (!SOC_PORT_VALID(unit, port)) { return BCM_E_PORT; } \ 366 } while (0); 367 368 /* 369 * Define: 370 * PORT_SWITCHED_CHECK 371 * Purpose: 372 * Check unit and port for switching feature support 373 */ 374 #define PORT_SWITCHED_CHECK(unit, port) do { \ 375 if (IS_ST_PORT(unit, port)) { \ 376 return BCM_E_PORT; \ 377 } else { \ 378 if (IS_CPU_PORT(unit, port)) { \ 379 if (!soc_feature(unit, soc_feature_cpuport_switched)) { \ 380 return BCM_E_PORT; \ 381 } \ 382 } \ 383 } \ 384 } while (0); 385 386 387 /* 388 * Define: 389 * PORT_INFO_RX_LOS_SET 390 * Purpose: 391 * Records the SW RX LOS configuration used for warmboot recovery 392 */ 393 #define PORT_INFO_RX_LOS_SET(_u, _p, _type, _val) do { \ 394 if (_type == BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS) { \ 395 PORT(_u, _p).rx_los = _val; \ 396 } \ 397 } while (0); 398 399 400 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) \ 401 || defined(BCM_TRIUMPH3_SUPPORT) 402 #define BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ 64 403 #endif 404 #ifdef BCM_TRIUMPH2_SUPPORT 405 typedef int _port_src_mod_egr_prof_ptr_t; 406 STATIC _port_src_mod_egr_prof_ptr_t 407 port_src_mod_egr_prof_ptr[BCM_MAX_NUM_UNITS][SOC_MAX_NUM_PORTS]; 408 #define PORT_SRC_MOD_EGR_PROF_PTR(_u, _p) port_src_mod_egr_prof_ptr[_u][_p] 409 410 STATIC soc_profile_mem_t *_bcm_src_mod_egr_profile[BCM_MAX_NUM_UNITS]; 411 #define PORT_SRC_MOD_EGR_PROFILE(_u) _bcm_src_mod_egr_profile[_u] 412 413 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 414 STATIC 415 bcm_error_t _bcm_esw_port_stat_get_table_info( 416 int unit, 417 bcm_gport_t port, 418 uint32 *num_of_tables, 419 bcm_stat_flex_table_info_t *table_info); 420 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT */ 421 #endif /* BCM_TRIUMPH2_SUPPORT */ 422 423 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) ||\ 424 defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 425 /* EEE standard compliance Work Around: 426 * To Maintain software state of native eee in MAC*/ 427 STATIC int eee_cfg[BCM_MAX_NUM_UNITS][SOC_MAX_NUM_PORTS]; 428 #endif 429 430 #ifdef BCM_TRIUMPH3_SUPPORT 431 STATIC int _bcm_tr3_port_lanes_set(int unit, bcm_port_t port, int value); 432 STATIC int _bcm_tr3_port_lanes_get(int unit, bcm_port_t port, int *value); 433 #endif /* BCM_TRIUMPH3_SUPPORT */ 434 435 /* 436 * The Port Monitor Thread is intended for handling work-arounds 437 * that are unneeded in most cases. In order to avoid unnecessary 438 * processing overhead the thread is not started by default, but 439 * only if so requested through configuration parameters. 440 */ 441 442 typedef struct _port_mon_ctrl_s 443 { 444 char taskname[16]; 445 sal_sem_t sema; 446 int interval; 447 int running; 448 int stop; 449 int unit; 450 uint32 gtuc; 451 uint32 gtmca; 452 uint32 gtbca; 453 uint32 gtlcl; 454 uint32 gtpok; 455 } _port_mon_ctrl_t; 456 457 STATIC _port_mon_ctrl_t _bcm_esw_port_mon_ctrl[BCM_MAX_NUM_UNITS]; 458 459 #define PORT_MON_CTRL(_u) (&_bcm_esw_port_mon_ctrl[_u]) 460 461 #define PORT_MON_INTERVAL_MIN 100000 462 463 int 464 _bcm_port_mac_init(int unit, bcm_port_t port, int *okay); 465 466 #if defined(BCM_TRIDENT3_SUPPORT) 467 STATIC int 468 _bcm_esw_td3_asf_init(int unit, soc_td3_asf_mode_e asf_mode); 469 STATIC int 470 _bcm_esw_td3_port_asf_mode_set(int unit, bcm_port_t port, int mode); 471 #endif 472 473 #if defined(BCM_MAVERICK2_SUPPORT) 474 STATIC int 475 _bcm_esw_mv2_asf_init(int unit, soc_mv2_asf_mode_e asf_mode); 476 STATIC int 477 _bcm_esw_mv2_port_asf_mode_set(int unit, bcm_port_t port, int mode); 478 #endif 479 480 #if defined(BCM_TOMAHAWK_SUPPORT) 481 STATIC int 482 _bcm_esw_asf_init(int unit, soc_th_asf_mode_e asf_mode); 483 484 STATIC int 485 _bcm_esw_asf_deinit(int unit); 486 487 #ifdef BCM_WARM_BOOT_SUPPORT 488 STATIC int 489 _bcm_esw_asf_wb_memsz_get(int unit, uint32* const mem_sz, uint16 scache_ver); 490 491 STATIC int 492 _bcm_esw_asf_wb_sync(int unit, uint8* wb_data); 493 494 STATIC int 495 _bcm_esw_asf_wb_recover(int unit, uint8* const wb_data, uint16 scache_ver); 496 497 STATIC int 498 _bcm_esw_sflow_wb_recover(int unit); 499 500 STATIC int 501 _bcm_esw_sflow_counter_wb_recover(int unit, soc_mem_t mem); 502 #endif /* BCM_WARM_BOOT_SUPPORT */ 503 #endif /* BCM_TOMAHAWK_SUPPORT */ 504 505 #ifdef BCM_WARM_BOOT_SUPPORT 506 507 /* Enum mapped to string for scache printing. 508 * Usage format is SPT_<enum> */ 509 #define SCACHE_PORT_DEFS \ 510 SCACHE_PORT_DEF(PBVL, "pbvl") \ 511 SCACHE_PORT_DEF(VLAN_PROT_PTR, "vlan_prot_ptr") \ 512 SCACHE_PORT_DEF(VP_COUNT, "vp_count") \ 513 SCACHE_PORT_DEF(DTM_PBMP, "dtm_pbmp") \ 514 SCACHE_PORT_DEF(COSMASK, "cosmask") \ 515 SCACHE_PORT_DEF(METERING_INFO, "metering_info") \ 516 SCACHE_PORT_DEF(PORT_FLAGS, "port_flags") \ 517 SCACHE_PORT_DEF(PORT_NUM_LANES, "port_num_lanes") \ 518 SCACHE_PORT_DEF(RX_LOS, "rx_los") \ 519 SCACHE_PORT_DEF(PORT_ENABLE, "port_enable") \ 520 SCACHE_PORT_DEF(ASF, "asf") \ 521 SCACHE_PORT_DEF(LATENCY, "latency") \ 522 SCACHE_PORT_DEF(IFG, "ifg") \ 523 SCACHE_PORT_DEF(DSCP_MAP, "dscp_map") \ 524 SCACHE_PORT_DEF(PORT_INTF_TYPE, "port_intf_type") 525 526 typedef enum scache_port_type_e { 527 #define SCACHE_PORT_DEF(_e, _s) SPT_##_e, 528 SCACHE_PORT_DEFS 529 #undef SCACHE_PORT_DEF 530 SCACHE_PORT_TYPE_MAX 531 } scache_port_type_t; 532 533 static const char *port_scache_strs[] = { 534 #define SCACHE_PORT_DEF(_e, _s) _s, 535 SCACHE_PORT_DEFS 536 #undef SCACHE_PORT_DEF 537 "invalid" 538 }; 539 540 typedef struct scache_port_print_port_s { 541 struct scache_port_print_port_s *next; /* pointer to next */ 542 uint8 *val; /* pointer to value in scache */ 543 int len; /* len of value in scache */ 544 int port; /* logical port number */ 545 } scache_port_print_port_t; 546 547 /* pointers to head of linked list */ 548 static scache_port_print_port_t *scache_head[SCACHE_PORT_TYPE_MAX]; 549 /* pointers to tail of linked list */ 550 static scache_port_print_port_t *scache_tail[SCACHE_PORT_TYPE_MAX]; 551 552 STATIC int 553 _bcm_esw_port_ifg_wb_sync(int unit, uint8 **scache_ptr); 554 555 STATIC int 556 _bcm_esw_port_ifg_wb_reinit(int unit, uint8 **scache_ptr); 557 #endif 558 559 STATIC int 560 bcmi_esw_port_encap_validate(int unit, bcm_port_t port, int mode, int speed); 561 STATIC int 562 _bcm_esw_port_encap_set(int unit, bcm_port_t port, int mode); 563 564 565 #if defined(BCM_GREYHOUND_SUPPORT) 566 /* Treat Packet Priority as dot1p ref_cnt structure */ 567 typedef struct bcmi_esw_treat_pktpri_as_dot1p_s { 568 sal_mutex_t ref_cnt_mutex; 569 int ref_cnt; 570 } bcmi_esw_treat_pktpri_as_dot1p_t; 571 572 STATIC bcmi_esw_treat_pktpri_as_dot1p_t 573 bcmi_treat_pktpri_as_dot1p[BCM_MAX_NUM_UNITS]; 574 575 /* Treat Packet Priority as dot1p ref_cnt lock/unlock */ 576 #define TREAT_PKTPRI_AS_DOT1P_LOCK(_unit_) \ 577 sal_mutex_take(bcmi_treat_pktpri_as_dot1p[_unit_].ref_cnt_mutex, \ 578 sal_mutex_FOREVER) 579 #define TREAT_PKTPRI_AS_DOT1P_UNLOCK(_unit_) \ 580 sal_mutex_give(bcmi_treat_pktpri_as_dot1p[_unit_].ref_cnt_mutex) 581 582 /* 583 * Function: 584 * bcmi_esw_port_treat_pktpri_as_dot1p_cleanup 585 * Purpose: 586 * cleanup resource after detach 587 * Parameters: 588 * unit - (IN) Device Number 589 * Return Value: 590 * BCM_E_XXX 591 * Notes: 592 */ 593 STATIC int 594 bcmi_esw_port_treat_pktpri_as_dot1p_cleanup(int unit) 595 { 596 if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex != NULL) { 597 sal_mutex_destroy(bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex); 598 bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex = NULL; 599 } 600 601 return BCM_E_NONE; 602 } 603 604 /* 605 * Function: 606 * bcmi_esw_port_treat_pktpri_as_dot1p_init 607 * Purpose: 608 * Initialize the ref_cnt of enabling treat packet priority 609 * as dot1p priority for different packet types or port controls. 610 * Parameters: 611 * unit - (IN) Device Number 612 * Return Value: 613 * BCM_E_XXX 614 * Notes: 615 * The ref_cnt of treat packet priority as dot1p priority is system-wise. 616 */ 617 STATIC int 618 bcmi_esw_port_treat_pktpri_as_dot1p_init(int unit) 619 { 620 if (!soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 621 return BCM_E_UNAVAIL; 622 } 623 624 /* Create protection mutex. */ 625 if (NULL == bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex) { 626 bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex = 627 sal_mutex_create("treat_pktpri_as_dot1p.lock"); 628 if (NULL == bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex) { 629 return BCM_E_RESOURCE; 630 } 631 } 632 633 bcmi_treat_pktpri_as_dot1p[unit].ref_cnt = 0; 634 635 return BCM_E_NONE; 636 } 637 638 /* 639 * Function: 640 * bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 641 * Purpose: 642 * Update the ref_cnt of enabling treat packet priority 643 * as dot1p priority for various packet types or port controls. 644 * Parameters: 645 * unit - (IN) Device Number 646 * incr_decr_flag - (IN) If TRUE, increment ref_cnt, else decrease ref_cnt 647 * Return Value: 648 * BCM_E_XXX 649 * Notes: 650 * The ref_cnt of treat packet priority as dot1p priority is system-wise. 651 */ 652 STATIC int 653 bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update( 654 int unit, int incr_decr_flag) 655 { 656 int rv = BCM_E_NONE; 657 uint64 regval64; 658 659 if (!soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 660 return BCM_E_UNAVAIL; 661 } 662 663 /* Input parameter check */ 664 if ((incr_decr_flag != 1) && (incr_decr_flag != -1)) { 665 return BCM_E_PARAM; 666 } 667 668 TREAT_PKTPRI_AS_DOT1P_LOCK(unit); 669 if (incr_decr_flag == 1) { 670 /* Increment */ 671 /* Need to set TREAT_PKTPRI_AS_DOT1Pf for the first ref_cnt */ 672 if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt == 0) { 673 COMPILER_64_ZERO(regval64); 674 rv = READ_ING_CONFIG_64r(unit, ®val64); 675 if (BCM_FAILURE(rv)) { 676 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit); 677 return rv; 678 } 679 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®val64, 680 TREAT_PKTPRI_AS_DOT1Pf, 1); 681 rv = WRITE_ING_CONFIG_64r(unit, regval64); 682 if (BCM_FAILURE(rv)) { 683 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit); 684 return rv; 685 } 686 } 687 bcmi_treat_pktpri_as_dot1p[unit].ref_cnt++; 688 } else { 689 /* Decrement */ 690 if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt >= 1) { 691 bcmi_treat_pktpri_as_dot1p[unit].ref_cnt--; 692 /* Need to unset TREAT_PKTPRI_AS_DOT1Pf when ref_cnt = 0 */ 693 if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt == 0) { 694 COMPILER_64_ZERO(regval64); 695 rv = READ_ING_CONFIG_64r(unit, ®val64); 696 if (BCM_FAILURE(rv)) { 697 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit); 698 return rv; 699 } 700 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®val64, 701 TREAT_PKTPRI_AS_DOT1Pf, 0); 702 rv = WRITE_ING_CONFIG_64r(unit, regval64); 703 if (BCM_FAILURE(rv)) { 704 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit); 705 return rv; 706 } 707 } 708 } 709 } 710 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit); 711 712 return rv; 713 } 714 715 #ifdef BCM_WARM_BOOT_SUPPORT 716 /* 717 * Function: 718 * bcmi_esw_port_treat_pktpri_as_dot1p_reinit 719 * Purpose: 720 * Recovery the ref_cnt of enabling treat packet priority 721 * as dot1p priority for different packet types or port contols. 722 * Parameters: 723 * unit - (IN) Device Number 724 * Return Value: 725 * BCM_E_XXX 726 */ 727 STATIC int 728 bcmi_esw_port_treat_pktpri_as_dot1p_reinit(int unit) 729 { 730 int rv = BCM_E_NONE; 731 bcm_port_t port_idx; 732 int pri_en = 0; 733 uint64 regval64; 734 735 if (!soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 736 return BCM_E_UNAVAIL; 737 } 738 739 bcmi_treat_pktpri_as_dot1p[unit].ref_cnt = 0; 740 741 COMPILER_64_ZERO(regval64); 742 BCM_IF_ERROR_RETURN( 743 READ_ING_CONFIG_64r(unit, ®val64)); 744 if (soc_reg64_field32_get(unit, ING_CONFIG_64r, regval64, 745 TREAT_PKTPRI_AS_DOT1Pf) == 0x1) { 746 BCM_PBMP_ITER(PBMP_PORT_ALL(unit), port_idx) { 747 /* Recover ref_cnt for Egress VLAN internal priority mapping */ 748 rv = bcm_esw_port_control_get 749 (unit, port_idx, 750 bcmPortControlEgressVlanPriUsesPktPri, &pri_en); 751 if (BCM_FAILURE(rv)) { 752 return rv; 753 } 754 if (pri_en) { 755 BCM_IF_ERROR_RETURN( 756 bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 757 (unit, 1)); 758 } 759 760 /* Recover ref_cnt for ETAG internal priority mapping */ 761 if (soc_feature(unit, soc_feature_port_extension)) { 762 rv = bcm_esw_port_control_get(unit, port_idx, 763 bcmPortControlUseEtagPri, &pri_en); 764 if (BCM_FAILURE(rv)) { 765 return rv; 766 } 767 if (pri_en) { 768 BCM_IF_ERROR_RETURN( 769 bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 770 (unit, 1)); 771 } 772 } 773 #ifdef BCM_HURRICANE3_SUPPORT 774 /* Recover ref_cnt for MiML internal priority mapping */ 775 if (soc_feature(unit, soc_feature_miml)) { 776 rv = bcm_esw_port_control_get(unit, port_idx, 777 bcmPortControlTrustMimlPri, &pri_en); 778 if (BCM_FAILURE(rv)) { 779 return rv; 780 } 781 if (pri_en) { 782 BCM_IF_ERROR_RETURN( 783 bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 784 (unit, 1)); 785 } 786 } 787 #endif /* BCM_HURRICANE3_SUPPORT */ 788 } 789 } 790 791 return rv; 792 } 793 #endif /* BCM_WARM_BOOT_SUPPORT */ 794 #endif /* BCM_GREYHOUND_SUPPORT */ 795 796 /* 797 * Function: 798 * _bcm_esw_port_mon_unimac_lock_up 799 * Description: 800 * Check for UniMAC half duplex collision lock-up issue 801 * Parameters: 802 * pmc - (IN) port monitor control data 803 * Return Value: 804 * None 805 * Notes: 806 * See errata 56020-ES105-R for additional details. 807 */ 808 STATIC void 809 _bcm_esw_port_mon_unimac_lock_up(_port_mon_ctrl_t *pmc) 810 { 811 int unit = pmc->unit; 812 int port, rv, link_up, fulld, lock_up; 813 uint32 gtuc, gtmca, gtbca, gtlcl, gtpok; 814 uint32 ccnt, rcnt, txfifo; 815 816 if (!soc_feature(unit, soc_feature_unimac)) { 817 return; 818 } 819 820 PBMP_E_ITER(unit, port) { 821 /* Check only half duplex ports */ 822 rv = _bcm_esw_link_get(unit, port, &link_up); 823 if (BCM_FAILURE(rv) || !link_up) { 824 continue; 825 } 826 rv = MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &fulld); 827 if (BCM_FAILURE(rv) || fulld) { 828 continue; 829 } 830 831 lock_up = 0; 832 rv = 0; 833 834 /* Collect test counters */ 835 rv += soc_counter_get32(unit, port, GTUCr, 0, >uc); 836 rv += soc_counter_get32(unit, port, GTMCAr, 0, >mca); 837 rv += soc_counter_get32(unit, port, GTBCAr, 0, >bca); 838 rv += soc_counter_get32(unit, port, GTLCLr, 0, >lcl); 839 rv += soc_counter_get32(unit, port, GTPOKr, 0, >pok); 840 841 /* Test lock-up conditions */ 842 if (gtuc == pmc->gtuc && 843 gtmca == pmc->gtmca && 844 gtbca == pmc->gtbca) { 845 if (gtlcl != pmc->gtlcl && 846 gtpok != pmc->gtpok) { 847 lock_up = 2; 848 } else { 849 rcnt = ccnt = 0; 850 if (SOC_REG_IS_VALID(unit, GE0_GBODE_CELL_CNTr)) { 851 uint32 reg, addr, idx; 852 idx = (port < 6) ? (port - 1) : ((port - 6) % 12); 853 reg = GE0_GBODE_CELL_CNTr; 854 addr = soc_reg_addr(unit, reg, port, 0); 855 addr += idx; 856 rv += soc_reg32_read(unit, addr, &ccnt); 857 reg = GE0_GBODE_CELL_REQ_CNTr; 858 addr = soc_reg_addr(unit, reg, port, 0); 859 addr += idx; 860 rv += soc_reg32_read(unit, addr, &rcnt); 861 } else if (SOC_REG_IS_VALID(unit, GE_GBODE_CELL_CNTr)) { 862 rv += READ_GE_GBODE_CELL_CNTr(unit, port, &ccnt); 863 rv += READ_GE_GBODE_CELL_REQ_CNTr(unit, port, &rcnt); 864 } 865 if (gtlcl && rcnt == 0 && ccnt == 4) { 866 lock_up = 1; 867 } 868 } 869 } 870 if (lock_up == 0) { 871 rv += READ_TXFIFO_STATr(unit, port, &txfifo); 872 if (soc_reg_field_get(unit, TXFIFO_STATr, 873 txfifo, TXFIFO_UNDERRUNf)) { 874 lock_up = 2; 875 } 876 } 877 878 /* Reset MAC if lock-up is detected */ 879 if (rv == 0 && lock_up) { 880 LOG_VERBOSE(BSL_LS_BCM_PORT, 881 (BSL_META_U(unit, 882 "Port %s: UniMAC lock up (%d) detected\n"), 883 SOC_PORT_NAME(unit, port), lock_up)); 884 PORT_LOCK(unit); 885 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 886 SOC_MAC_CONTROL_SW_RESET, TRUE); 887 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 888 SOC_MAC_CONTROL_SW_RESET, FALSE); 889 PORT_UNLOCK(unit); 890 } 891 892 /* Sync test counters */ 893 pmc->gtuc = gtuc; 894 pmc->gtmca = gtmca; 895 pmc->gtbca = gtbca; 896 pmc->gtlcl = gtlcl; 897 pmc->gtpok = gtpok; 898 } 899 } 900 901 /* 902 * Function: 903 * _bcm_esw_port_mon_ctrl_thread 904 * Description: 905 * Port monitor thread 906 * Parameters: 907 * context - (IN) Port monitor control data 908 * Return Value: 909 * None 910 */ 911 STATIC void 912 _bcm_esw_port_mon_ctrl_thread(void *context) 913 { 914 _port_mon_ctrl_t *pmc = (_port_mon_ctrl_t *)context; 915 916 LOG_VERBOSE(BSL_LS_BCM_PORT, 917 (BSL_META("Port monitor started on unit %d\n"), pmc->unit)); 918 919 pmc->running = 1; 920 while (!pmc->stop) { 921 _bcm_esw_port_mon_unimac_lock_up(pmc); 922 (void)sal_sem_take(pmc->sema, pmc->interval); 923 } 924 pmc->running = 0; 925 } 926 927 /* 928 * Function: 929 * _bcm_esw_port_mon_start 930 * Description: 931 * Start port monitor thread 932 * Parameters: 933 * unit - (IN) BCM device number 934 * Return Value: 935 * BCM_E_NONE if thread started successfully 936 */ 937 int 938 _bcm_esw_port_mon_start(int unit) 939 { 940 _port_mon_ctrl_t *pmc = PORT_MON_CTRL(unit); 941 int cnt; 942 943 pmc->interval = soc_property_get(unit, spn_PORTMON_INTERVAL, 0); 944 if (pmc->interval == 0) { 945 return BCM_E_NONE; 946 } 947 948 if (pmc->interval < PORT_MON_INTERVAL_MIN) { 949 pmc->interval = PORT_MON_INTERVAL_MIN; 950 } 951 952 pmc->unit = unit; 953 if (pmc->running) { 954 LOG_VERBOSE(BSL_LS_BCM_PORT, 955 (BSL_META_U(unit, 956 "Port monitor already running on unit %d\n"), 957 pmc->unit)); 958 } else { 959 if (pmc->sema == NULL) { 960 pmc->sema = sal_sem_create("port_mon_SLEEP", sal_sem_BINARY, 0); 961 if (pmc->sema == NULL) { 962 return BCM_E_MEMORY; 963 } 964 } 965 sal_snprintf(pmc->taskname, sizeof (pmc->taskname), 966 "bcmPortMon.%d", unit); 967 pmc->stop = 0; 968 if (sal_thread_create(pmc->taskname, SAL_THREAD_STKSZ, 969 soc_property_get(unit, 970 spn_PORTMON_THREAD_PRI, 971 50), 972 _bcm_esw_port_mon_ctrl_thread, 973 pmc) == SAL_THREAD_ERROR) { 974 return BCM_E_MEMORY; 975 } 976 cnt = 10; 977 while (!pmc->running && cnt--) { 978 sal_usleep(100000); 979 } 980 if (!pmc->running) { 981 LOG_ERROR(BSL_LS_BCM_PORT, 982 (BSL_META_U(unit, 983 "%s: Thread did not start\n"), pmc->taskname)); 984 return BCM_E_TIMEOUT; 985 } 986 } 987 return BCM_E_NONE; 988 } 989 990 /* 991 * Function: 992 * _bcm_esw_port_mon_stop 993 * Description: 994 * Stop port monitor thread 995 * Parameters: 996 * unit - (IN) BCM device number 997 * Return Value: 998 * BCM_E_NONE if thread stopped successfully 999 */ 1000 int 1001 _bcm_esw_port_mon_stop(int unit) 1002 { 1003 int cnt; 1004 _port_mon_ctrl_t *pmc = PORT_MON_CTRL(unit); 1005 1006 if (pmc->sema == NULL) { 1007 return BCM_E_NONE; 1008 } 1009 1010 pmc->stop = 1; 1011 sal_sem_give(pmc->sema); 1012 cnt = 10; 1013 while (pmc->running && cnt--) { 1014 sal_usleep(100000); 1015 } 1016 if (pmc->running) { 1017 LOG_ERROR(BSL_LS_BCM_PORT, 1018 (BSL_META_U(unit, 1019 "%s: Thread did not start\n"), pmc->taskname)); 1020 return BCM_E_TIMEOUT; 1021 } 1022 sal_sem_destroy(pmc->sema); 1023 pmc->sema = NULL; 1024 1025 return BCM_E_NONE; 1026 } 1027 1028 #ifdef BCM_TRIUMPH3_SUPPORT 1029 static _port_ibod_ctrl_t *_port_ibod_ctrl[BCM_MAX_NUM_UNITS]; 1030 static int txerr_trigger_flag[SOC_MAX_NUM_PORTS]; 1031 1032 #define IBOD_RECOVERY_GROUP_MAX ((SOC_MAX_NUM_PORTS + 3) /4) 1033 #define IBOD_RECOVERY_GROUP_VALID(grp) ((grp) >= 0 && (grp) < IBOD_RECOVERY_GROUP_MAX) 1034 #define IBOD_RECOVERY_GROUP(phy_port) ((phy_port - 1)/4) 1035 static sal_mutex_t ibod_port_group_recovery_lock[BCM_MAX_NUM_UNITS][IBOD_RECOVERY_GROUP_MAX]; 1036 1037 #define TR3_IARB_TDM_TABLE_LENGTH 512 1038 1039 #define IBOD_IF_ERROR_RETURN_UNLOCK(unit,port,rv) \ 1040 if (SOC_FAILURE(rv)) { \ 1041 soc_ibod_recovery_in_progress_set(unit, 0); \ 1042 _bcm_esw_ibod_recovery_port_unlock(unit, port); \ 1043 PORT_UNLOCK(unit); \ 1044 return rv; \ 1045 } 1046 1047 #define TXERR_IF_ERROR_RETURN_UNLOCK(unit,port,rv) \ 1048 if (SOC_FAILURE(rv)) { \ 1049 _bcm_esw_ibod_recovery_port_unlock(unit, port); \ 1050 PORT_UNLOCK(unit); \ 1051 _bcm_esw_lc_unlock(unit);\ 1052 return rv; \ 1053 } 1054 1055 /*#define IBOD_DEBUG 1056 #define TXERR_DEBUG */ 1057 1058 int _ibod_debug_flag = 0; 1059 1060 void _bcm_esw_ibod_debug_flag_set(int unit, int flag) 1061 { 1062 _ibod_debug_flag = flag; 1063 cli_out("IBOD debug flag:0X%x\n", _ibod_debug_flag); 1064 } 1065 1066 static int _bcm_esw_ibod_recovery_lock_init(int unit) 1067 { 1068 int rv = BCM_E_NONE; 1069 int group, rollback_group; 1070 1071 for (group = 0; group < IBOD_RECOVERY_GROUP_MAX; group++) { 1072 ibod_port_group_recovery_lock[unit][group] = sal_mutex_create("IBOD_GROUP_LOCK"); 1073 if (ibod_port_group_recovery_lock[unit][group] == NULL) { 1074 rv = BCM_E_MEMORY; 1075 break; 1076 } 1077 } 1078 /* Recycle the memory */ 1079 if (SOC_FAILURE(rv)) { 1080 for (rollback_group = group - 1; rollback_group >= 0; rollback_group--) { 1081 sal_mutex_destroy(ibod_port_group_recovery_lock[unit][rollback_group]); 1082 } 1083 } 1084 return BCM_E_NONE; 1085 } 1086 1087 static void _bcm_esw_ibod_recovery_lock_deinit(int unit) 1088 { 1089 int group; 1090 1091 for (group = 0; group < IBOD_RECOVERY_GROUP_MAX; group++) { 1092 if (ibod_port_group_recovery_lock[unit][group] != NULL) { 1093 sal_mutex_destroy(ibod_port_group_recovery_lock[unit][group]); 1094 } 1095 } 1096 } 1097 1098 void _bcm_esw_ibod_recovery_port_lock(int unit, bcm_port_t port) 1099 { 1100 int phy_port; 1101 int group; 1102 /* coverity[overrun-local : FALSE] */ 1103 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 1104 group = IBOD_RECOVERY_GROUP(phy_port); 1105 if (IBOD_RECOVERY_GROUP_VALID(group) && 1106 ibod_port_group_recovery_lock[unit][group] != NULL) { 1107 sal_mutex_take(ibod_port_group_recovery_lock[unit][group], sal_mutex_FOREVER); 1108 } 1109 } 1110 1111 void _bcm_esw_ibod_recovery_port_unlock(int unit, bcm_port_t port) 1112 { 1113 int phy_port; 1114 int group; 1115 1116 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 1117 group = IBOD_RECOVERY_GROUP(phy_port); 1118 if (IBOD_RECOVERY_GROUP_VALID(group) && 1119 ibod_port_group_recovery_lock[unit][group] != NULL) { 1120 sal_mutex_give(ibod_port_group_recovery_lock[unit][group]); 1121 } 1122 } 1123 1124 STATIC int _bcm_tr3_port_is_control_port(int unit, soc_port_t port) 1125 { 1126 int phy_port, phy_port_base; 1127 soc_info_t *si = &SOC_INFO(unit); 1128 1129 phy_port = si->port_l2p_mapping[port]; 1130 if (phy_port == -1) { 1131 return FALSE; 1132 } 1133 1134 phy_port_base = ((phy_port - 1) & ~0x3) + 1; 1135 if (phy_port == phy_port_base) { 1136 return TRUE; 1137 } 1138 1139 return FALSE; 1140 } 1141 1142 STATIC int 1143 _bcm_tr3_ibod_mac_x_enable_set(int unit, soc_port_t port, int enable) 1144 { 1145 uint64 ctrl, octrl; 1146 pbmp_t mask; 1147 1148 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl)); 1149 octrl = ctrl; 1150 /* Don't disable TX since it stops egress and hangs if CPU sends */ 1151 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, TX_ENf, 1); 1152 if (enable) { 1153 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 1); 1154 } else { 1155 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 0); 1156 } 1157 if (COMPILER_64_NE(ctrl, octrl)) { 1158 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl)); 1159 sal_udelay(10); 1160 } 1161 1162 /* Put the XMAC in a soft reset state when disabled to allow packets to 1163 * drain from the TX FIFO */ 1164 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, SOFT_RESETf, 1165 enable ? 0 : 1); 1166 if (COMPILER_64_NE(ctrl, octrl)) { 1167 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl)); 1168 } 1169 1170 if (enable) { 1171 SOC_IF_ERROR_RETURN(soc_phyctrl_notify(unit, port, phyEventResume, 1172 PHY_STOP_MAC_DIS)); 1173 } else { 1174 soc_link_mask2_get(unit, &mask); 1175 SOC_PBMP_PORT_REMOVE(mask, port); 1176 SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask)); 1177 SOC_IF_ERROR_RETURN(_mac_x_drain_cells(unit, port, 0)); 1178 SOC_IF_ERROR_RETURN(soc_phyctrl_notify(unit, port, phyEventStop, 1179 PHY_STOP_MAC_DIS)); 1180 } 1181 1182 return SOC_E_NONE; 1183 } 1184 1185 STATIC int 1186 _bcm_tr3_ibod_port_isolate(int unit, int port_enable, bcm_port_t port, 1187 int *port_dis_untag, int *port_dis_tag) 1188 { 1189 port_tab_entry_t ptab_entry; 1190 1191 /* Isolate, drain and remove port from epc link */ 1192 BCM_IF_ERROR_RETURN 1193 (_bcm_tr3_ibod_mac_x_enable_set(unit, port, FALSE)); 1194 1195 if (port_enable) { 1196 LOG_VERBOSE(BSL_LS_BCM_PORT, 1197 (BSL_META_U(unit, 1198 "Port %d enable case..\n"), port)); 1199 /* Enable phy so that packets can loopback */ 1200 SOC_IF_ERROR_RETURN 1201 (soc_phyctrl_enable_set(unit, port, TRUE)); 1202 } else { 1203 LOG_VERBOSE(BSL_LS_BCM_PORT, 1204 (BSL_META_U(unit, 1205 "Port %d Runt received case..\n"), port)); 1206 } 1207 1208 SOC_IF_ERROR_RETURN(MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, TRUE)); 1209 1210 /* Enable MAC so that packets can loopback from phy */ 1211 BCM_IF_ERROR_RETURN 1212 (_bcm_tr3_ibod_mac_x_enable_set(unit, port, TRUE)); 1213 1214 /* Discard tag and untag packet at IP before send packets */ 1215 BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port, &ptab_entry)); 1216 *port_dis_untag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf); 1217 *port_dis_tag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf); 1218 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, 1); 1219 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, 1); 1220 BCM_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port, &ptab_entry)); 1221 1222 return SOC_E_NONE; 1223 } 1224 1225 STATIC int 1226 _bcm_tr3_ibod_port_resume(int unit, bcm_port_t port, int port_dis_untag, int port_dis_tag) 1227 { 1228 pbmp_t epc_pbm; 1229 port_tab_entry_t ptab_entry; 1230 1231 /* Remove MAC loopback */ 1232 SOC_IF_ERROR_RETURN(MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, FALSE)); 1233 1234 /* Restore port discard tag and untag at IP */ 1235 BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port, &ptab_entry)); 1236 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, port_dis_untag); 1237 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, port_dis_tag); 1238 BCM_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port, &ptab_entry)); 1239 1240 /* Restore port in epc link bmap */ 1241 soc_link_mask2_get(unit, &epc_pbm); 1242 SOC_PBMP_PORT_ADD(epc_pbm, port); 1243 SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, epc_pbm)); 1244 1245 return SOC_E_NONE; 1246 } 1247 1248 STATIC int 1249 _bcm_hx4_ibod_sync_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, int port_group_iter, 1250 bcm_port_t port) 1251 { 1252 bcm_pbmp_t pbmp; 1253 bcm_port_t port_iter; 1254 uint32 port_mode; 1255 uint32 rval, rval_1, port_dis_tag=0, port_dis_untag=0, xmac_mode=0; 1256 uint64 rval64,tmp64; 1257 uint64 egress_meter[4]; 1258 int unit=ibod_ctrl->unit; 1259 int rv = BCM_E_NONE; 1260 bcm_pkt_t *pkt = &ibod_ctrl->pkt; 1261 pbmp_t mask, mask1, mask1_restore, mask_restore; 1262 uint64 rrpkt, rrbyt, count64, count64_1; 1263 int count, count_1, i; 1264 soc_timeout_t timeout; 1265 egr_enable_entry_t egr_en; 1266 soc_info_t *si = &SOC_INFO(unit); 1267 port_tab_entry_t ptab_entry; 1268 egr_mmu_requests_entry_t mmu_entry; 1269 int rx_llfc_en[4], rx_pfc_en[4], pause_rx[4], rx_lss[4], rx_lss_1[4], rx_en[4]; 1270 uint32 max_used_entry, ep_level, overflow0, overflow1, total_cell; 1271 static const soc_reg_t lls_port_credit_reg[] = { 1272 LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr, 1273 LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr, 1274 LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr, 1275 LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr, 1276 LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr, 1277 LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr, 1278 LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr, 1279 LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr, 1280 LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr, 1281 LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr, 1282 LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr, 1283 LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr, 1284 LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr, 1285 LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr, 1286 LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr, 1287 LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr, 1288 LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr, 1289 LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr, 1290 LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr, 1291 LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr, 1292 LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr 1293 }; 1294 sal_usecs_t time1, time2; 1295 1296 time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 1297 1298 rv = bcm_esw_port_subsidiary_ports_get(unit, port, &pbmp); 1299 if (BCM_FAILURE(rv)) { 1300 LOG_ERROR(BSL_LS_BCM_PORT, 1301 (BSL_META_U(unit, "\n Error in retreiving the subsidiary ports" 1302 "for port %s"), SOC_PORT_NAME(unit,port))); 1303 return BCM_E_NONE; 1304 } 1305 1306 count=0; 1307 BCM_PBMP_ITER(pbmp, port_iter) { 1308 rv = READ_XMAC_MODEr(unit, port_iter, &rval64); 1309 if (BCM_FAILURE(rv)) { 1310 return BCM_E_NONE; 1311 } 1312 xmac_mode = soc_reg64_field32_get(unit, XMAC_MODEr,rval64, HDR_MODEf); 1313 if ((xmac_mode == 1) || (xmac_mode == 2)) { 1314 count++; 1315 } 1316 } 1317 1318 if (!count) { 1319 return BCM_E_NONE; 1320 } 1321 1322 BCM_PBMP_ITER(pbmp, port_iter) { 1323 SOC_IF_ERROR_RETURN(READ_PORT_CDC_TXFIFO_OVRFLWr(unit, port_iter, &rval)); 1324 if (rval) { 1325 LOG_ERROR(BSL_LS_BCM_PORT, 1326 (BSL_META_U(unit, "ENTER VALIDATE PORT_CDC_TXFIFO_OVRFLW ERR" 1327 " failed on port:%d\n\r"), port_iter )); 1328 } 1329 } 1330 1331 _bcm_esw_lc_lock(unit); 1332 1333 soc_link_fwd_get(unit, &mask1); 1334 SOC_PBMP_ASSIGN(mask1_restore,mask1); 1335 BCM_PBMP_ITER(pbmp, port_iter) { 1336 BCM_PBMP_PORT_REMOVE(mask1,port_iter); 1337 } 1338 rv = soc_link_fwd_set(unit, mask1); 1339 if (BCM_FAILURE(rv)) { 1340 _bcm_esw_lc_unlock(unit); 1341 LOG_ERROR(BSL_LS_BCM_PORT, 1342 (BSL_META_U(unit, "\n Error in setting the mask FWD" 1343 " for WAR on port %s"), SOC_PORT_NAME(unit,port))); 1344 return BCM_E_NONE; 1345 } 1346 1347 /* Hold the ibod recovery port group lock */ 1348 _bcm_esw_ibod_recovery_port_lock(unit, port); 1349 PORT_LOCK(unit); 1350 1351 soc_link_mask2_get(unit, &mask); 1352 SOC_PBMP_ASSIGN(mask_restore, mask); 1353 BCM_PBMP_ITER(pbmp, port_iter) { 1354 BCM_PBMP_PORT_REMOVE(mask,port_iter); 1355 } 1356 rv = soc_link_mask2_set(unit, mask); 1357 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1358 1359 1360 BCM_PBMP_ITER(pbmp, port_iter) { 1361 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port_iter, 1362 &ptab_entry); 1363 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1364 port_dis_untag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf); 1365 port_dis_tag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf); 1366 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, 1); 1367 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, 1); 1368 rv = soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port_iter, 1369 &ptab_entry); 1370 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1371 } 1372 1373 count=0; 1374 BCM_PBMP_ITER(pbmp, port_iter) { 1375 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1376 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1377 rx_en[count] = soc_reg64_field32_get(unit, XMAC_CTRLr, rval64, RX_ENf); 1378 count++; 1379 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 0); 1380 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1381 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1382 } 1383 1384 BCM_PBMP_ITER(pbmp, port_iter) { 1385 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1386 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1387 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 0); 1388 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1389 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1390 } 1391 1392 BCM_PBMP_ITER(pbmp, port_iter) { 1393 rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64); 1394 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1395 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 1); 1396 rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64); 1397 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1398 } 1399 1400 BCM_PBMP_ITER(pbmp, port_iter) { 1401 rv = READ_XPORT_TO_MMU_BKPr(unit, port_iter, &rval); 1402 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1403 soc_reg_field_set(unit, XPORT_TO_MMU_BKPr, &rval, PRI15_0_BKPf, 0); 1404 rv = WRITE_XPORT_TO_MMU_BKPr(unit, port_iter, 0); 1405 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1406 } 1407 1408 count=0; 1409 BCM_PBMP_ITER(pbmp, port_iter) { 1410 rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64); 1411 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1412 pause_rx[count] = soc_reg64_field32_get(unit, XMAC_PAUSE_CTRLr, rval64, RX_PAUSE_ENf); 1413 soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, 0); 1414 rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64); 1415 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1416 1417 rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64); 1418 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1419 rx_pfc_en[count] = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval64, RX_PFC_ENf); 1420 soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, 0); 1421 rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64); 1422 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1423 1424 rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64); 1425 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1426 rx_llfc_en[count] = soc_reg64_field32_get(unit, XMAC_LLFC_CTRLr, rval64, RX_LLFC_ENf); 1427 soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, 0); 1428 rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64); 1429 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1430 count++; 1431 } 1432 1433 count=0; 1434 BCM_PBMP_ITER(pbmp, port_iter) { 1435 rv = READ_EGRMETERINGCONFIG_64r(unit, port_iter, &rval64); 1436 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1437 egress_meter[count]=rval64; 1438 COMPILER_64_ZERO(tmp64); 1439 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, tmp64); 1440 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1441 count++; 1442 } 1443 1444 count=0; 1445 BCM_PBMP_ITER(pbmp, port_iter) { 1446 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 1447 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1448 rx_lss[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64, 1449 DROP_TX_DATA_ON_LOCAL_FAULTf); 1450 rx_lss_1[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64, 1451 DROP_TX_DATA_ON_REMOTE_FAULTf); 1452 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1); 1453 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1); 1454 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 1455 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1456 count++; 1457 } 1458 1459 COMPILER_64_SET(tmp64, pbmp.pbits[1], pbmp.pbits[0]); 1460 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 1461 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1462 soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, tmp64); 1463 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 1464 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1465 1466 BCM_PBMP_ITER(pbmp, port_iter) { 1467 rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval); 1468 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1469 soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 1); 1470 rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval); 1471 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1472 } 1473 1474 count_1=0; 1475 soc_timeout_init(&timeout, 30000, 0); 1476 do { 1477 if (soc_timeout_check(&timeout)) { 1478 rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval); 1479 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1480 soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1); 1481 rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval); 1482 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1483 /* coverity[overrun-local : FALSE] */ 1484 rv = READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL, 1485 si->port_l2p_mapping[port], 1486 &max_used_entry); 1487 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1488 ep_level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf); 1489 if(ep_level == 0) { 1490 ibod_ctrl->drain_timeout_flag = 1; 1491 } 1492 else { 1493 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0); 1494 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1495 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1); 1496 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1497 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &total_cell); 1498 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1499 LOG_ERROR(BSL_LS_BCM_PORT, 1500 (BSL_META_U(unit, "\n IBOD recovery Timeout Drain packets %d PORT: %s, " 1501 "ep_level:%d, overflow0:%d, overflow1:%d,total_cell:%d\n"), 1502 ibod_ctrl->unit, SOC_PORT_NAME(unit,port), ep_level, overflow0, overflow1,total_cell)); 1503 } 1504 break; 1505 } else { 1506 BCM_PBMP_ITER(pbmp, port_iter) { 1507 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 1508 REG_PORT_ANY, 0, &rval); 1509 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1510 if (!rval) { 1511 count_1++; 1512 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, 1513 si->port_l2p_mapping[port_iter], 1514 &mmu_entry); 1515 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1516 rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 1517 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 1518 REG_PORT_ANY, 0, rval); 1519 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1520 } 1521 } 1522 count=0; 1523 BCM_PBMP_ITER(pbmp, port_iter) { 1524 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port_iter, &rval); 1525 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1526 count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf); 1527 rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port_iter, &rval); 1528 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1529 count += soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf); 1530 } 1531 } 1532 } while (count); 1533 1534 BCM_PBMP_ITER(pbmp, port_iter) { 1535 /* coverity[overrun-local : FALSE] */ 1536 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, 1537 si->port_l2p_mapping[port_iter], &mmu_entry); 1538 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1539 rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 1540 /* coverity[overrun-local : FALSE] */ 1541 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 1542 REG_PORT_ANY, 0, &rval_1); 1543 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1544 if (rval != rval_1) { 1545 /* coverity[overrun-local : FALSE] */ 1546 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 1547 REG_PORT_ANY, 0, rval); 1548 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1549 } 1550 } 1551 1552 count = 0; 1553 BCM_PBMP_ITER(pbmp, port_iter) { 1554 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, egress_meter[count]); 1555 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1556 count++; 1557 } 1558 1559 rv = READ_PORT_MODE_REGr(unit, port, &rval); 1560 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1561 port_mode = soc_reg_field_get(unit, PORT_MODE_REGr, 1562 rval, XPORT0_CORE_PORT_MODEf); 1563 1564 BCM_PBMP_ITER(pbmp, port_iter) { 1565 rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64); 1566 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1567 soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 1); 1568 rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64); 1569 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1570 } 1571 1572 BCM_PBMP_ITER(pbmp, port_iter) { 1573 rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64); 1574 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1575 soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 0); 1576 rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64); 1577 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1578 } 1579 1580 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 1581 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1582 soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0); 1583 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 1584 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1585 1586 BCM_PBMP_ITER(pbmp, port_iter) { 1587 rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval); 1588 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1589 soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 0); 1590 rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval); 1591 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1592 } 1593 1594 BCM_PBMP_ITER(pbmp, port_iter) { 1595 rv = READ_RRPKTr(unit, port_iter, &rrpkt); 1596 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1597 rv = READ_RRBYTr(unit, port_iter, &rrbyt); 1598 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1599 /* coverity[overrun-local : FALSE] */ 1600 ibod_ctrl->rrpkt[port_iter] = rrpkt; 1601 ibod_ctrl->rrbyt[port_iter] = rrbyt; 1602 } 1603 1604 BCM_PBMP_ITER(pbmp, port_iter) { 1605 /* coverity[overrun-local : FALSE] */ 1606 rv = READ_EGR_ENABLEm( 1607 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1608 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1609 soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 0); 1610 rv = WRITE_EGR_ENABLEm( 1611 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1612 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1613 } 1614 1615 BCM_PBMP_ITER(pbmp, port_iter) { 1616 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1617 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1618 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 1); 1619 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1620 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1621 } 1622 1623 rv = READ_PORT_ENABLE_REGr(unit, port, &rval); 1624 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1625 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 0); 1626 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 0); 1627 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 0); 1628 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 0); 1629 rv = WRITE_PORT_ENABLE_REGr(unit, port, rval); 1630 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1631 1632 rv = READ_PORT_MODE_REGr(unit, port, &rval); 1633 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1634 port_mode=soc_reg_field_get(unit, PORT_MODE_REGr, 1635 rval, XPORT0_CORE_PORT_MODEf); 1636 if(port_mode) { 1637 soc_reg_field_set(unit, PORT_MODE_REGr, 1638 &rval, XPORT0_CORE_PORT_MODEf,0); 1639 } 1640 else { 1641 soc_reg_field_set(unit, PORT_MODE_REGr, 1642 &rval, XPORT0_CORE_PORT_MODEf,1); 1643 } 1644 rv = WRITE_PORT_MODE_REGr(unit, port, rval); 1645 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1646 rv = READ_PORT_MODE_REGr(unit, port, &rval); 1647 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1648 soc_reg_field_set(unit, PORT_MODE_REGr, 1649 &rval, XPORT0_CORE_PORT_MODEf,port_mode); 1650 rv = WRITE_PORT_MODE_REGr(unit, port, rval); 1651 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1652 1653 rv = READ_PORT_ENABLE_REGr(unit, port, &rval); 1654 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1655 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 1); 1656 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 1); 1657 if (port_mode == 2) { 1658 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 1); 1659 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 1); 1660 } 1661 rv = WRITE_PORT_ENABLE_REGr(unit, port, rval); 1662 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1663 1664 BCM_PBMP_ITER(pbmp, port_iter) { 1665 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1666 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1667 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 0); 1668 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1669 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1670 } 1671 1672 BCM_PBMP_ITER(pbmp, port_iter) { 1673 rv = READ_EGR_ENABLEm( 1674 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1675 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1676 soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 1); 1677 rv = WRITE_EGR_ENABLEm( 1678 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1679 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1680 } 1681 1682 BCM_PBMP_ITER(pbmp, port_iter) { 1683 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1684 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1685 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, LINE_LOCAL_LPBKf, 1); 1686 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1687 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1688 } 1689 1690 BCM_PBMP_ITER(pbmp, port_iter) { 1691 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1692 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1693 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 1); 1694 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 1); 1695 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1696 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1697 } 1698 BCM_PBMP_ITER(pbmp, port_iter) { 1699 rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64); 1700 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1701 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 0); 1702 rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64); 1703 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1704 } 1705 sal_udelay(200); 1706 /* Send 80-byte packets to fill IBOD FIFO */ 1707 BCM_PBMP_ITER(pbmp, port_iter) { 1708 rv = READ_RPKTr(unit, port_iter, &rval64); 1709 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1710 count64 = soc_reg64_field_get(unit, RPKTr, rval64, COUNTf); 1711 for (i=0;i<2;i++) 1712 { 1713 BCM_PKT_TX_LEN_SET(pkt, 68); 1714 BCM_PKT_HDR_VTAG_CONTROL_SET(pkt, VLAN_CTRL(0, 0, 1)); 1715 BCM_PKT_PORT_SET(pkt, port_iter, FALSE, FALSE); 1716 rv = bcm_common_tx(unit, pkt, NULL); 1717 if (BCM_FAILURE(rv)) { 1718 LOG_ERROR(BSL_LS_BCM_PORT,(BSL_META_U(unit,"IBOD 80-byte packet transmit" 1719 "failed[%d] on port:%d\n\r"), rv, port_iter)); 1720 ibod_ctrl->port_recovery_failed_flag = 1; 1721 break; 1722 } 1723 sal_udelay(200); 1724 1725 } 1726 if (ibod_ctrl->port_recovery_failed_flag) { 1727 break; 1728 } 1729 1730 rv = READ_RPKTr(unit, port_iter, &rval64); 1731 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1732 count64_1 = soc_reg64_field_get(unit, RPKTr, rval64, COUNTf); 1733 COMPILER_64_SET(tmp64, 0, 2); 1734 COMPILER_64_SUB_64(count64_1, count64); 1735 if (COMPILER_64_LT(count64_1, tmp64)) { 1736 sal_udelay(1000); 1737 rv = READ_RPKTr(unit, port_iter, &rval64); 1738 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1739 count64_1 = soc_reg64_field_get(unit, RPKTr, rval64, COUNTf); 1740 COMPILER_64_SUB_64(count64_1, count64); 1741 if (COMPILER_64_LT(count64_1, tmp64)) { 1742 LOG_WARN(BSL_LS_BCM_PORT, 1743 (BSL_META_U(unit,"\n HELIX4 IBOD loopback packet" 1744 " not received in port %s"),SOC_PORT_NAME(unit,port_iter))); 1745 } 1746 } 1747 } 1748 1749 BCM_PBMP_ITER(pbmp, port_iter) { 1750 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1751 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1752 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 0); 1753 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1754 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1755 } 1756 1757 BCM_PBMP_ITER(pbmp, port_iter) { 1758 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1759 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1760 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 0); 1761 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1762 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1763 } 1764 1765 BCM_PBMP_ITER(pbmp, port_iter) { 1766 rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64); 1767 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1768 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 1); 1769 rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64); 1770 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1771 } 1772 1773 BCM_PBMP_ITER(pbmp, port_iter) { 1774 rv = READ_EGR_ENABLEm( 1775 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1776 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1777 soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 0); 1778 rv = WRITE_EGR_ENABLEm( 1779 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1780 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1781 } 1782 1783 BCM_PBMP_ITER(pbmp, port_iter) { 1784 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1785 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1786 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 1); 1787 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1788 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1789 } 1790 1791 rv = READ_PORT_ENABLE_REGr(unit, port, &rval); 1792 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1793 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 0); 1794 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 0); 1795 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 0); 1796 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 0); 1797 rv = WRITE_PORT_ENABLE_REGr(unit, port, rval); 1798 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1799 1800 rv = READ_PORT_MODE_REGr(unit, port, &rval); 1801 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1802 port_mode=soc_reg_field_get(unit, PORT_MODE_REGr, 1803 rval, XPORT0_CORE_PORT_MODEf); 1804 if(port_mode) { 1805 soc_reg_field_set(unit, PORT_MODE_REGr, 1806 &rval, XPORT0_CORE_PORT_MODEf,0); 1807 } 1808 else { 1809 soc_reg_field_set(unit, PORT_MODE_REGr, 1810 &rval, XPORT0_CORE_PORT_MODEf,1); 1811 } 1812 rv = WRITE_PORT_MODE_REGr(unit, port, rval); 1813 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1814 rv = READ_PORT_MODE_REGr(unit, port, &rval); 1815 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1816 soc_reg_field_set(unit, PORT_MODE_REGr, 1817 &rval, XPORT0_CORE_PORT_MODEf,port_mode); 1818 rv = WRITE_PORT_MODE_REGr(unit, port, rval); 1819 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1820 1821 rv = READ_PORT_ENABLE_REGr(unit, port, &rval); 1822 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1823 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 1); 1824 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 1); 1825 if (port_mode == 2) { 1826 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 1); 1827 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 1); 1828 } 1829 rv = WRITE_PORT_ENABLE_REGr(unit, port, rval); 1830 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1831 1832 BCM_PBMP_ITER(pbmp, port_iter) { 1833 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1834 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1835 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 0); 1836 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1837 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1838 } 1839 1840 BCM_PBMP_ITER(pbmp, port_iter) { 1841 rv = READ_EGR_ENABLEm( 1842 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1843 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1844 soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 1); 1845 rv = WRITE_EGR_ENABLEm( 1846 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1847 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1848 } 1849 1850 switch(port_group_iter) { 1851 case 0: 1852 rv = READ_IBOD_INTR_STATUSr(unit, &rval); 1853 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1854 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 1855 &rval, CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf, 1); 1856 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 1857 &rval, CL0_CTRL_FIFO_FULL_ERR_INTR_STATUSf, 1); 1858 rv = WRITE_IBOD_INTR_STATUSr(unit, rval); 1859 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1860 break; 1861 case 1: 1862 rv = READ_IBOD_INTR_STATUSr(unit, &rval); 1863 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1864 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 1865 &rval, CL1_DATA_FIFO_FULL_ERR_INTR_STATUSf, 1); 1866 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 1867 &rval, CL1_CTRL_FIFO_FULL_ERR_INTR_STATUSf, 1); 1868 rv = WRITE_IBOD_INTR_STATUSr(unit, rval); 1869 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1870 break; 1871 case 2: 1872 rv = READ_IBOD_INTR_STATUSr(unit, &rval); 1873 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1874 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 1875 &rval, CL2_DATA_FIFO_FULL_ERR_INTR_STATUSf, 1); 1876 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 1877 &rval, CL2_CTRL_FIFO_FULL_ERR_INTR_STATUSf, 1); 1878 rv = WRITE_IBOD_INTR_STATUSr(unit, rval); 1879 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1880 break; 1881 default: 1882 break; 1883 } 1884 1885 rv = READ_MEM_FAIL_INT_STAT_64r(unit, &rval64); 1886 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1887 soc_reg64_field32_set(unit, MEM_FAIL_INT_STAT_64r, 1888 &rval64, START_BY_START_ERRf, 0); 1889 rv = WRITE_MEM_FAIL_INT_STAT_64r(unit, rval64); 1890 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1891 1892 rv = READ_MEM_FAIL_INT_CTRr(unit, &rval); 1893 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1894 soc_reg_field_set(unit, MEM_FAIL_INT_CTRr, &rval, INT_CTRf, 0); 1895 rv = WRITE_MEM_FAIL_INT_CTRr(unit, rval); 1896 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1897 1898 BCM_PBMP_ITER(pbmp, port_iter) { 1899 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1900 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1901 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, LINE_LOCAL_LPBKf, 0); 1902 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1903 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1904 } 1905 1906 BCM_PBMP_ITER(pbmp, port_iter) { 1907 rv = soc_mem_read( 1908 unit, PORT_TABm, MEM_BLOCK_ANY, port_iter, &ptab_entry); 1909 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1910 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, port_dis_untag); 1911 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, port_dis_tag); 1912 rv = soc_mem_write( 1913 unit, PORT_TABm, MEM_BLOCK_ALL, port_iter, &ptab_entry); 1914 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1915 } 1916 1917 count=0; 1918 BCM_PBMP_ITER(pbmp, port_iter) { 1919 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 1920 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1921 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, rx_lss[count]); 1922 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, rx_lss_1[count]); 1923 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 1924 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1925 count++; 1926 } 1927 1928 count=0; 1929 BCM_PBMP_ITER(pbmp, port_iter) { 1930 rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64); 1931 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1932 soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, pause_rx[count]); 1933 rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64); 1934 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1935 1936 rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64); 1937 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1938 soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, rx_pfc_en[count]); 1939 rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64); 1940 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1941 1942 rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64); 1943 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1944 soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, rx_llfc_en[count]); 1945 rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64); 1946 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1947 count++; 1948 } 1949 1950 BCM_PBMP_ITER(pbmp, port_iter) { 1951 rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64); 1952 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1953 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 0); 1954 rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64); 1955 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1956 } 1957 1958 count=0; 1959 BCM_PBMP_ITER(pbmp, port_iter) { 1960 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1961 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1962 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 1); 1963 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, rx_en[count]); 1964 count++; 1965 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1966 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1967 } 1968 sal_udelay(200); 1969 rv = soc_link_mask2_set(unit, mask_restore); 1970 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1971 1972 PORT_UNLOCK(unit); 1973 /* Release the ibod recovery port group lock */ 1974 _bcm_esw_ibod_recovery_port_unlock(unit, port); 1975 1976 rv = soc_link_fwd_set(unit, mask1_restore); 1977 if (BCM_FAILURE(rv)) { 1978 _bcm_esw_lc_unlock(unit); 1979 LOG_ERROR(BSL_LS_BCM_PORT, 1980 (BSL_META_U(unit,"\n Error in re-setting the mask FWD" 1981 " for WAR on port %s"), SOC_PORT_NAME(unit,port))); 1982 return BCM_E_NONE; 1983 } 1984 _bcm_esw_lc_unlock(unit); 1985 1986 BCM_PBMP_ITER(pbmp, port_iter) { 1987 SOC_IF_ERROR_RETURN( 1988 READ_PORT_CDC_TXFIFO_OVRFLWr(unit, port_iter, &rval)); 1989 if (rval) { 1990 LOG_ERROR(BSL_LS_BCM_PORT, 1991 (BSL_META_U(unit," EXIT VALIDATE PORT_CDC_TXFIFO_OVRFLW ERR" 1992 " failed on port:%d\n\r"), port_iter)); 1993 } 1994 } 1995 time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 1996 ibod_ctrl->event_count++; 1997 ibod_ctrl->port_avg_time = (ibod_ctrl->port_avg_time*(ibod_ctrl->event_count - 1) + 1998 time2 - time1) /ibod_ctrl->event_count; 1999 2000 return SOC_E_NONE; 2001 2002 } 2003 2004 STATIC int 2005 _bcm_hx4_txerr_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, 2006 bcm_port_t port) 2007 { 2008 bcm_pbmp_t pbmp; 2009 bcm_port_t port_iter; 2010 uint32 port_mode; 2011 uint32 rval, rval_1; 2012 uint64 rval64, txerr, flush_enable_pbm, tmp64; 2013 uint64 egress_meter[4]; 2014 int unit=ibod_ctrl->unit, okay=0, rv = BCM_E_NONE; 2015 pbmp_t mask, mask1, mask1_restore, mask_restore; 2016 soc_timeout_t timeout; 2017 int count,count_1; 2018 soc_info_t *si = &SOC_INFO(unit); 2019 egr_mmu_requests_entry_t mmu_entry; 2020 int rx_llfc_en[4],rx_pfc_en[4],pause_rx[4], rx_lss[4], rx_lss_1[4]; 2021 uint32 max_used_entry, ep_level, overflow0, overflow1; 2022 static const soc_reg_t lls_port_credit_reg[] = { 2023 LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr, 2024 LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr, 2025 LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr, 2026 LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr, 2027 LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr, 2028 LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr, 2029 LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr, 2030 LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr, 2031 LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr, 2032 LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr, 2033 LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr, 2034 LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr, 2035 LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr, 2036 LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr, 2037 LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr, 2038 LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr, 2039 LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr, 2040 LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr, 2041 LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr, 2042 LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr, 2043 LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr 2044 }; 2045 sal_usecs_t time1, time2; 2046 2047 time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 2048 2049 SOC_IF_ERROR_RETURN(READ_PORT_MODE_REGr(unit, port, &rval)); 2050 port_mode=soc_reg_field_get(unit, PORT_MODE_REGr, 2051 rval, XPORT0_CORE_PORT_MODEf); 2052 sal_memset(&pbmp, 0, sizeof(bcm_pbmp_t)); 2053 if (port_mode) { 2054 rv = bcm_esw_port_subsidiary_ports_get(unit, port, &pbmp); 2055 if (BCM_FAILURE(rv)) { 2056 LOG_ERROR(BSL_LS_BCM_PORT, 2057 (BSL_META_U(unit,"\n Error in retreiving the subsidiary ports" 2058 " for port %s"), SOC_PORT_NAME(unit,port))); 2059 return BCM_E_NONE; 2060 } 2061 } else { 2062 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay)); 2063 if (okay) { 2064 SOC_PBMP_PORT_ADD(pbmp, port); 2065 } else { 2066 return SOC_E_NONE; 2067 } 2068 } 2069 2070 BCM_PBMP_ITER(pbmp, port_iter) { 2071 SOC_IF_ERROR_RETURN(READ_PORT_CDC_TXFIFO_OVRFLWr(unit, port_iter, &rval)); 2072 if (rval) { 2073 LOG_ERROR(BSL_LS_BCM_PORT, 2074 (BSL_META_U(unit,"IBOD PORT_CDC_TXFIFO_OVRFLW ERR" 2075 " failed on port:%d\n\r"), port_iter)); 2076 } 2077 } 2078 2079 count=0; 2080 BCM_PBMP_ITER(pbmp, port_iter) { 2081 SOC_IF_ERROR_RETURN(READ_TERRr(unit, port_iter, &txerr)); 2082 /* coverity[overrun-local : FALSE] */ 2083 if (COMPILER_64_NE(ibod_ctrl->txerrpkt[port_iter], txerr)) { 2084 ibod_ctrl->txerrpkt[port_iter] = txerr; 2085 count++; 2086 } 2087 } 2088 BCM_PBMP_ITER(pbmp, port_iter) { 2089 SOC_IF_ERROR_RETURN(READ_XMAC_FIFO_STATUSr(unit, port_iter, &rval64)); 2090 if (!count) { 2091 count = soc_reg64_field32_get(unit, XMAC_FIFO_STATUSr, rval64, TX_PKT_UNDERFLOWf); 2092 } 2093 } 2094 2095 if (!count) { 2096 return SOC_E_NONE; 2097 } 2098 2099 LOG_VERBOSE(BSL_LS_BCM_PORT, 2100 (BSL_META_U(unit,"\n WAR Trigerred by TXERR in subports %s"),SOC_PORT_NAME(unit,port))); 2101 2102 _bcm_esw_lc_lock(unit); 2103 soc_link_fwd_get(unit, &mask1); 2104 SOC_PBMP_ASSIGN(mask1_restore,mask1); 2105 BCM_PBMP_ITER(pbmp, port_iter) { 2106 BCM_PBMP_PORT_REMOVE(mask1,port_iter); 2107 } 2108 rv = soc_link_fwd_set(unit, mask1); 2109 if (BCM_FAILURE(rv)) { 2110 _bcm_esw_lc_unlock(unit); 2111 LOG_ERROR(BSL_LS_BCM_PORT, 2112 (BSL_META_U(unit,"\n Error in setting the mask FWD" 2113 " for WAR on port %s"), SOC_PORT_NAME(unit,port))); 2114 return BCM_E_NONE; 2115 } 2116 2117 /* Hold the ibod recovery port group lock */ 2118 _bcm_esw_ibod_recovery_port_lock(unit, port); 2119 PORT_LOCK(unit); 2120 2121 soc_link_mask2_get(unit, &mask); 2122 SOC_PBMP_ASSIGN(mask_restore,mask); 2123 BCM_PBMP_ITER(pbmp, port_iter) { 2124 BCM_PBMP_PORT_REMOVE(mask,port_iter); 2125 } 2126 rv = soc_link_mask2_set(unit, mask); 2127 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2128 2129 2130 count=0; 2131 BCM_PBMP_ITER(pbmp, port_iter) { 2132 rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64); 2133 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2134 pause_rx[count] = soc_reg64_field32_get(unit, XMAC_PAUSE_CTRLr, rval64, RX_PAUSE_ENf); 2135 soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, 0); 2136 rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64); 2137 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2138 2139 rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64); 2140 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2141 rx_pfc_en[count] = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval64, RX_PFC_ENf); 2142 soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, 0); 2143 rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64); 2144 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2145 2146 rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64); 2147 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2148 rx_llfc_en[count] = soc_reg64_field32_get(unit, XMAC_LLFC_CTRLr, rval64, RX_LLFC_ENf); 2149 soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, 0); 2150 rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64); 2151 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2152 count++; 2153 } 2154 2155 count=0; 2156 BCM_PBMP_ITER(pbmp, port_iter) { 2157 rv = READ_EGRMETERINGCONFIG_64r(unit, port_iter, &rval64); 2158 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2159 egress_meter[count] = rval64; 2160 COMPILER_64_ZERO(tmp64); 2161 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, tmp64); 2162 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2163 count++; 2164 } 2165 2166 count=0; 2167 BCM_PBMP_ITER(pbmp, port_iter) { 2168 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 2169 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2170 rx_lss[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64, 2171 DROP_TX_DATA_ON_LOCAL_FAULTf); 2172 rx_lss_1[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64, 2173 DROP_TX_DATA_ON_REMOTE_FAULTf); 2174 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1); 2175 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1); 2176 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 2177 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2178 count++; 2179 } 2180 2181 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 2182 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2183 COMPILER_64_SET(flush_enable_pbm, pbmp.pbits[1], pbmp.pbits[0]); 2184 soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, flush_enable_pbm); 2185 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 2186 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2187 2188 BCM_PBMP_ITER(pbmp, port_iter) { 2189 rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval); 2190 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2191 soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 1); 2192 rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval); 2193 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2194 } 2195 rv = READ_PORT_MODE_REGr(unit, port, &rval); 2196 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2197 port_mode = soc_reg_field_get(unit, PORT_MODE_REGr, 2198 rval, XPORT0_CORE_PORT_MODEf); 2199 2200 soc_timeout_init(&timeout, 30000, 0); 2201 count_1=0; 2202 do { 2203 if (soc_timeout_check(&timeout)) { 2204 ep_level = 0; 2205 BCM_PBMP_ITER(pbmp, port_iter) { 2206 rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval); 2207 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2208 soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1); 2209 rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval); 2210 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2211 /* coverity[overrun-local : FALSE] */ 2212 rv = READ_EGR_MAX_USED_ENTRIESm( 2213 unit, MEM_BLOCK_ALL, si->port_l2p_mapping[port_iter], 2214 &max_used_entry); 2215 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2216 ep_level += soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf); 2217 } 2218 if(ep_level == 0) { 2219 ibod_ctrl->drain_timeout_flag = 1; 2220 } 2221 else { 2222 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0); 2223 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2224 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1); 2225 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2226 LOG_ERROR(BSL_LS_BCM_PORT, 2227 (BSL_META_U(unit, "\n IBOD recovery Timeout Drain packets %d PORT: %s, " 2228 "total ep_level:%d, overflow0:%d, overflow1:%d\n"), 2229 ibod_ctrl->unit, SOC_PORT_NAME(unit,port), ep_level, overflow0, overflow1)); 2230 } 2231 break; 2232 } else { 2233 BCM_PBMP_ITER(pbmp, port_iter) { 2234 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 2235 REG_PORT_ANY, 0, &rval); 2236 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2237 if (!rval) { 2238 count_1++; 2239 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, 2240 si->port_l2p_mapping[port_iter], 2241 &mmu_entry); 2242 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2243 rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 2244 rv = soc_reg32_set(unit, 2245 lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 2246 REG_PORT_ANY, 0, rval); 2247 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2248 } 2249 } 2250 count=0; 2251 BCM_PBMP_ITER(pbmp, port_iter) { 2252 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port_iter, &rval); 2253 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2254 count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf); 2255 rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port_iter, &rval); 2256 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2257 count += soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf); 2258 2259 } 2260 } 2261 } while (count); 2262 2263 BCM_PBMP_ITER(pbmp, port_iter) { 2264 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, 2265 si->port_l2p_mapping[port_iter], &mmu_entry); 2266 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2267 rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 2268 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 2269 REG_PORT_ANY, 0, &rval_1); 2270 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2271 if (rval != rval_1) { 2272 rv = soc_reg32_set(unit, 2273 lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 2274 REG_PORT_ANY, 0, rval); 2275 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2276 } 2277 } 2278 2279 BCM_PBMP_ITER(pbmp, port_iter) { 2280 rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64); 2281 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2282 soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 1); 2283 rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64); 2284 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2285 } 2286 2287 BCM_PBMP_ITER(pbmp, port_iter) { 2288 rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64); 2289 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2290 soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 0); 2291 rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64); 2292 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2293 } 2294 2295 count=0; 2296 BCM_PBMP_ITER(pbmp, port_iter) { 2297 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, egress_meter[count]); 2298 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2299 count++; 2300 } 2301 2302 BCM_PBMP_ITER(pbmp, port_iter) { 2303 rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval); 2304 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2305 soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 0); 2306 rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval); 2307 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2308 } 2309 2310 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 2311 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2312 soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0); 2313 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 2314 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2315 2316 count=0; 2317 BCM_PBMP_ITER(pbmp, port_iter) { 2318 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 2319 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2320 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, rx_lss[count]); 2321 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, rx_lss_1[count]); 2322 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 2323 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2324 count++; 2325 } 2326 2327 count=0; 2328 BCM_PBMP_ITER(pbmp, port_iter) { 2329 rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64); 2330 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2331 soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, pause_rx[count]); 2332 rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64); 2333 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2334 2335 rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64); 2336 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2337 soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, rx_pfc_en[count]); 2338 rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64); 2339 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2340 2341 rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64); 2342 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2343 soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, rx_llfc_en[count]); 2344 rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64); 2345 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2346 count++; 2347 } 2348 2349 rv = soc_link_mask2_set(unit, mask_restore); 2350 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2351 PORT_UNLOCK(unit); 2352 /* Release the ibod recovery port group lock */ 2353 _bcm_esw_ibod_recovery_port_unlock(unit, port); 2354 2355 rv = soc_link_fwd_set(unit, mask1_restore); 2356 if (BCM_FAILURE(rv)) { 2357 _bcm_esw_lc_unlock(unit); 2358 LOG_ERROR(BSL_LS_BCM_PORT, 2359 (BSL_META_U(unit,"\n Error in re-setting the mask FWD" 2360 " for WAR on port %s"), SOC_PORT_NAME(unit,port))); 2361 return BCM_E_NONE; 2362 } 2363 2364 _bcm_esw_lc_unlock(unit); 2365 time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 2366 ibod_ctrl->txerr_count++; 2367 ibod_ctrl->txerr_avg_time = (ibod_ctrl->txerr_avg_time*(ibod_ctrl->txerr_count-1) + 2368 time2 - time1) /ibod_ctrl->txerr_count; 2369 2370 return SOC_E_NONE; 2371 } 2372 2373 2374 STATIC int 2375 _bcm_tr3_mmu_recovery(_port_ibod_ctrl_t *ibod_ctrl) 2376 { 2377 mac_driver_t *macd; 2378 bcm_port_t port_iter; 2379 uint32 rval, rval_1, count; 2380 uint64 rval64,txerr, val64; 2381 int unit=ibod_ctrl->unit, rv = BCM_E_NONE; 2382 soc_info_t *si = &SOC_INFO(unit); 2383 egr_mmu_requests_entry_t mmu_entry; 2384 int linkscan_interval, counter_interval; 2385 uint32 counter_flags; 2386 uint32 l2x_flags; 2387 int scan_rate, l2x_running = 0, mem_scan_running = 0; 2388 sal_usecs_t l2x_interval, scan_interval; 2389 bcm_pbmp_t rx_en_pbmp, rx_llfc_en_pbmp, tx_llfc_en_pbmp; 2390 bcm_pbmp_t rx_pfc_en_pbmp, tx_pfc_en_pbmp; 2391 bcm_pbmp_t pause_rx_pbmp, pause_tx_pbmp; 2392 bcm_pbmp_t rx_lss_local_pbmp,rx_lss_remote_pbmp, counter_pbmp; 2393 uint64 egrmeteringconfig[_SOC_TR3_MAX_NUM_LPORTS]; 2394 soc_timeout_t timeout; 2395 int num_mmu_port, mmu_port, phy_port, port; 2396 pbmp_t pbm; 2397 epc_link_bmap_entry_t entry, epc_lin_bmap_entry; 2398 static const soc_reg_t lls_port_credit_reg[] = { 2399 LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr, 2400 LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr, 2401 LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr, 2402 LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr, 2403 LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr, 2404 LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr, 2405 LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr, 2406 LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr, 2407 LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr, 2408 LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr, 2409 LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr, 2410 LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr, 2411 LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr, 2412 LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr, 2413 LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr, 2414 LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr, 2415 LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr, 2416 LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr, 2417 LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr, 2418 LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr, 2419 LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr 2420 }; 2421 sal_usecs_t time1, time2; 2422 2423 time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 2424 2425 /*****"Preparation and Stop ingress traffic Start*****/ 2426 /*1. Disable all back ground threads to prevent any SBUS acitivities (software handling)*/ 2427 BCM_IF_ERROR_RETURN(bcm_esw_linkscan_enable_get(unit, &linkscan_interval)); 2428 BCM_IF_ERROR_RETURN(bcm_esw_linkscan_enable_set(unit, 0)); 2429 BCM_IF_ERROR_RETURN(soc_counter_status(unit, &counter_flags, 2430 &counter_interval, &counter_pbmp)); 2431 BCM_IF_ERROR_RETURN(soc_counter_stop(unit)); 2432 if (soc_l2x_running(unit, &l2x_flags, &l2x_interval)) { 2433 l2x_running = 1; 2434 BCM_IF_ERROR_RETURN(soc_l2x_stop(unit)); 2435 } 2436 #ifdef INCLUDE_MEM_SCAN 2437 if (soc_mem_scan_running(unit, &scan_rate, &scan_interval)) { 2438 mem_scan_running = 1; 2439 BCM_IF_ERROR_RETURN(soc_mem_scan_stop(unit)); 2440 } 2441 #endif 2442 2443 /*2. Disable "TX" API to prevent CPU packet from going into MMU (software handling)*/ 2444 PBMP_PORT_ITER(unit, port_iter){ 2445 _bcm_esw_ibod_recovery_port_lock(unit, port_iter); 2446 } 2447 2448 /*3. Stop all ingress ports traffic to prevent any packet from going into MMU */ 2449 sal_memset(&rx_en_pbmp, 0, sizeof(bcm_pbmp_t)); 2450 PBMP_PORT_ITER(unit, port_iter){ 2451 macd = PORT(unit, port_iter).p_mac; 2452 rv = MAC_CONTROL_GET(macd,unit, port_iter, SOC_MAC_CONTROL_RX_SET, (int *)&rval); 2453 if (BCM_FAILURE(rv)) { 2454 goto end; 2455 } 2456 if (rval) { 2457 BCM_PBMP_PORT_ADD(rx_en_pbmp, port_iter); 2458 } 2459 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_RX_SET, 0); 2460 if (BCM_FAILURE(rv)) { 2461 goto end; 2462 } 2463 } 2464 2465 /*4. Stop all AXP traffic to prevent any packet from going into MMU */ 2466 sal_memset(&pbm, 0, sizeof(pbmp_t)); 2467 /* coverity[check_return] */ 2468 rv = READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry); 2469 if (BCM_FAILURE(rv)) { 2470 goto end; 2471 } 2472 sal_memcpy(&epc_lin_bmap_entry, &entry, sizeof(epc_link_bmap_entry_t)); 2473 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm); 2474 rv = WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry); 2475 if (BCM_FAILURE(rv)) { 2476 goto end; 2477 } 2478 /*****"Preparation and Stop ingress traffic End*****/ 2479 2480 /*****Packet Drain Start*****/ 2481 /* 1.Stop all pauses to speed up draining*/ 2482 sal_memset(&pause_rx_pbmp, 0, sizeof(bcm_pbmp_t)); 2483 sal_memset(&pause_tx_pbmp, 0, sizeof(bcm_pbmp_t)); 2484 2485 PBMP_PORT_ITER(unit, port_iter){ 2486 macd = PORT(unit, port_iter).p_mac; 2487 rv = MAC_PAUSE_GET(macd, unit, port_iter, (int *)&rval, (int *)&rval_1); 2488 if (BCM_FAILURE(rv)) { 2489 goto end; 2490 } 2491 if (rval) { 2492 BCM_PBMP_PORT_ADD(pause_tx_pbmp, port_iter); 2493 } 2494 if (rval_1) { 2495 BCM_PBMP_PORT_ADD(pause_rx_pbmp, port_iter); 2496 } 2497 rv = MAC_PAUSE_SET(macd, unit, port_iter, 0, 0); 2498 if (BCM_FAILURE(rv)) { 2499 goto end; 2500 } 2501 } 2502 2503 sal_memset(&rx_llfc_en_pbmp, 0, sizeof(bcm_pbmp_t)); 2504 sal_memset(&tx_llfc_en_pbmp, 0, sizeof(bcm_pbmp_t)); 2505 PBMP_PORT_ITER(unit, port_iter){ 2506 macd = PORT(unit, port_iter).p_mac; 2507 rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_TX_ENABLE, (int *)&rval); 2508 if (BCM_FAILURE(rv)) { 2509 goto end; 2510 } 2511 if (rval) { 2512 BCM_PBMP_PORT_ADD(tx_llfc_en_pbmp, port_iter); 2513 } 2514 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_TX_ENABLE, 0); 2515 if (BCM_FAILURE(rv)) { 2516 goto end; 2517 } 2518 rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_RX_ENABLE, (int *)&rval); 2519 if (BCM_FAILURE(rv)) { 2520 goto end; 2521 } 2522 if (rval) { 2523 BCM_PBMP_PORT_ADD(rx_llfc_en_pbmp, port_iter); 2524 } 2525 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_RX_ENABLE, 0); 2526 if (BCM_FAILURE(rv)) { 2527 goto end; 2528 } 2529 } 2530 2531 sal_memset(&tx_pfc_en_pbmp, 0, sizeof(bcm_pbmp_t)); 2532 sal_memset(&rx_pfc_en_pbmp, 0, sizeof(bcm_pbmp_t)); 2533 PBMP_PORT_ITER(unit, port_iter){ 2534 macd = PORT(unit, port_iter).p_mac; 2535 rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_TX_ENABLE, (int *)&rval); 2536 if (BCM_FAILURE(rv)) { 2537 goto end; 2538 } 2539 if (rval) { 2540 BCM_PBMP_PORT_ADD(tx_pfc_en_pbmp, port_iter); 2541 } 2542 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_TX_ENABLE, 0); 2543 if (BCM_FAILURE(rv)) { 2544 goto end; 2545 } 2546 rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_RX_ENABLE, (int *)&rval); 2547 if (BCM_FAILURE(rv)) { 2548 goto end; 2549 } 2550 if (rval) { 2551 BCM_PBMP_PORT_ADD(rx_pfc_en_pbmp, port_iter); 2552 } 2553 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_RX_ENABLE, 0); 2554 if (BCM_FAILURE(rv)) { 2555 goto end; 2556 } 2557 } 2558 2559 /*2. Set XMAC LLS CTRL to ignore Serdes fault signal which may prevent packets from draining at cable unplug case*/ 2560 sal_memset(&rx_lss_local_pbmp, 0, sizeof(bcm_pbmp_t)); 2561 sal_memset(&rx_lss_remote_pbmp, 0, sizeof(bcm_pbmp_t)); 2562 PBMP_PORT_ITER(unit, port_iter){ 2563 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 2564 if (BCM_FAILURE(rv)) { 2565 goto end; 2566 } 2567 rval = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64, 2568 DROP_TX_DATA_ON_LOCAL_FAULTf); 2569 if (0 == rval) { 2570 BCM_PBMP_PORT_ADD(rx_lss_local_pbmp, port_iter); 2571 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1); 2572 } 2573 2574 rval = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64, 2575 DROP_TX_DATA_ON_REMOTE_FAULTf); 2576 if (0 == rval) { 2577 BCM_PBMP_PORT_ADD(rx_lss_remote_pbmp, port_iter); 2578 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1); 2579 } 2580 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 2581 if (BCM_FAILURE(rv)) { 2582 goto end; 2583 } 2584 } 2585 2586 /*3. Enable IPMC fast flush */ 2587 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 2588 if (BCM_FAILURE(rv)) { 2589 goto end; 2590 } 2591 2592 COMPILER_64_SET(val64, 0x3fffffff, 0xffffffff); 2593 soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, val64); 2594 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 2595 if (BCM_FAILURE(rv)) { 2596 goto end; 2597 } 2598 2599 /*4. Set PORT fast flush */ 2600 PBMP_PORT_ITER(unit, port_iter){ 2601 rv = soc_reg_field32_modify(unit, PORT_TXFIFO_PKT_DROP_CTLr, port_iter, 2602 DROP_ENf, 1); 2603 if (BCM_FAILURE(rv)) { 2604 goto end; 2605 } 2606 } 2607 2608 /*5.Stop MMU egress */ 2609 PBMP_PORT_ITER(unit, port_iter){ 2610 rv = READ_EGRMETERINGCONFIG_64r(unit, port_iter, &rval64); 2611 if (BCM_FAILURE(rv)) { 2612 goto end; 2613 } 2614 2615 COMPILER_64_SET(egrmeteringconfig[port_iter], COMPILER_64_HI(rval64), COMPILER_64_LO(rval64)); 2616 COMPILER_64_SET(val64, 0, 0); 2617 soc_reg64_field_set(unit, EGRMETERINGCONFIG_64r, &rval64, REFRESHf, val64); 2618 COMPILER_64_SET(val64, 0, 1); 2619 soc_reg64_field_set(unit, EGRMETERINGCONFIG_64r, &rval64, THD_SELf, val64); 2620 COMPILER_64_SET(val64, 0, 0); 2621 soc_reg64_field_set(unit, EGRMETERINGCONFIG_64r, &rval64, METER_GRANf, val64); 2622 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, rval64); 2623 if (BCM_FAILURE(rv)) { 2624 goto end; 2625 } 2626 } 2627 2628 /*6.Wait until all PORT TXFIFO count == 0*/ 2629 soc_timeout_init(&timeout, 30000, 0); 2630 do { 2631 if (soc_timeout_check(&timeout)) { 2632 LOG_ERROR(BSL_LS_BCM_PORT, 2633 (BSL_META_U(unit, "\n MMU Recovery Timeout Ports Drain packets unit:%d"), ibod_ctrl->unit)); 2634 break; 2635 } 2636 count=0; 2637 PBMP_PORT_ITER(unit, port_iter){ 2638 rv = READ_PORT_CDC_TXFIFO_CELL_CNTr(unit, port_iter, &rval); 2639 if (BCM_FAILURE(rv)) { 2640 goto end; 2641 } 2642 count += soc_reg_field_get(unit, PORT_CDC_TXFIFO_CELL_CNTr,rval, CELL_CNTf); 2643 rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port_iter, &rval); 2644 if (BCM_FAILURE(rv)) { 2645 goto end; 2646 } 2647 count += soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf); 2648 } 2649 } while (count); 2650 2651 /*****Packet Drain End*****/ 2652 2653 /*****MMU reset Start*****/ 2654 /*1. Backup all necessary MMU configurations */ 2655 rv = soc_tr3_mmu_register_store(unit); 2656 if (BCM_FAILURE(rv)) { 2657 goto end; 2658 } 2659 rv = soc_tr3_mmu_memory_store(unit); 2660 if (BCM_FAILURE(rv)) { 2661 goto end; 2662 } 2663 2664 /*2. Do TOP level MMU reset*/ 2665 rv = READ_TOP_SOFT_RESET_REGr(unit, &rval); 2666 if (BCM_FAILURE(rv)) { 2667 goto end; 2668 } 2669 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 0); 2670 rv = WRITE_TOP_SOFT_RESET_REGr(unit, rval); 2671 if (BCM_FAILURE(rv)) { 2672 goto end; 2673 } 2674 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1); 2675 rv = WRITE_TOP_SOFT_RESET_REGr(unit, rval); 2676 if (BCM_FAILURE(rv)) { 2677 goto end; 2678 } 2679 /* 3. REFRESH_ENF*/ 2680 rv = soc_reg32_get(unit, MISCCONFIGr, REG_PORT_ANY, 0, &rval); 2681 if (BCM_FAILURE(rv)) { 2682 goto end; 2683 } 2684 soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1); 2685 rv = soc_reg32_set(unit, MISCCONFIGr, REG_PORT_ANY, 0, rval); 2686 if(BCM_FAILURE(rv)) { 2687 goto end; 2688 } 2689 2690 /*4. Call soc_mmu_init to init MMU*/ 2691 rv = soc_mmu_init(unit); 2692 if (BCM_FAILURE(rv)) { 2693 goto end; 2694 } 2695 2696 /*5.Restore Registers/Memories which are called in MMU init (following MMU init sequence)*/ 2697 rv = soc_tr3_mmu_init_restore(unit); 2698 if (BCM_FAILURE(rv)) { 2699 goto end; 2700 } 2701 2702 /*6.Restore other MMU registers without sequence*/ 2703 rv = soc_tr3_mmu_register_restore(unit); 2704 if (BCM_FAILURE(rv)) { 2705 goto end; 2706 } 2707 2708 /*7.Restore other MMU memories without sequence*/ 2709 rv = soc_tr3_mmu_memory_restore(unit); 2710 if (BCM_FAILURE(rv)) { 2711 goto end; 2712 } 2713 2714 /*8.Restore MMU2PHY port mapping and MMU2LOGIC port mapping*/ 2715 num_mmu_port = SOC_REG_NUMELS(unit, MMU_TO_PHY_PORT_MAPPINGr); 2716 for (mmu_port = 0; mmu_port < num_mmu_port; mmu_port++) { 2717 phy_port = si->port_m2p_mapping[mmu_port]; 2718 port = phy_port == -1 ? -1 : si->port_p2l_mapping[phy_port]; 2719 2720 rval = 0; 2721 soc_reg_field_set(unit, MMU_TO_PHY_PORT_MAPPINGr, &rval, PHY_PORTf, 2722 phy_port == -1 ? 0x7f : phy_port); 2723 rv = WRITE_MMU_TO_PHY_PORT_MAPPINGr(unit, mmu_port, rval); 2724 if (BCM_FAILURE(rv)) { 2725 goto end; 2726 } 2727 rval = 0; 2728 soc_reg_field_set(unit, MMU_TO_LOGIC_PORT_MAPPINGr, &rval, LOGIC_PORTf, 2729 port == -1 ? 0x3f : port); 2730 rv = WRITE_MMU_TO_LOGIC_PORT_MAPPINGr(unit, mmu_port, rval); 2731 if (BCM_FAILURE(rv)) { 2732 goto end; 2733 } 2734 } 2735 2736 /* 9. Restore MMU to EP credicts after EP restore because EP port enable will update EGR_MMU_REQUESTSm*/ 2737 PBMP_ALL_ITER(unit, port_iter){ 2738 if (!IS_CPU_PORT(unit, port_iter) && !IS_PORT(unit, port_iter)) { 2739 continue; 2740 } 2741 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port_iter], &mmu_entry); 2742 if (BCM_FAILURE(rv)) { 2743 goto end; 2744 } 2745 rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 2746 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 2747 REG_PORT_ANY, 0, &rval_1); 2748 if (BCM_FAILURE(rv)) { 2749 goto end; 2750 } 2751 if (rval != rval_1) { 2752 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 2753 REG_PORT_ANY, 0, rval); 2754 if(BCM_FAILURE(rv)) { 2755 goto end; 2756 } 2757 } 2758 } 2759 /*restore axp credit*/ 2760 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[58]]], 2761 REG_PORT_ANY, 0, 0x14); 2762 if (BCM_FAILURE(rv)) { 2763 goto end; 2764 } 2765 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[59]]], 2766 REG_PORT_ANY, 0, 0x14); 2767 if (BCM_FAILURE(rv)) { 2768 goto end; 2769 } 2770 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[60]]], 2771 REG_PORT_ANY, 0, 4); 2772 if (BCM_FAILURE(rv)) { 2773 goto end; 2774 } 2775 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[61]]], 2776 REG_PORT_ANY, 0, 0x14); 2777 if (BCM_FAILURE(rv)) { 2778 goto end; 2779 } 2780 /*****MMU reset End*****/ 2781 2782 /***** Resume ingress traffic Start*****/ 2783 /*1.Restore XMAC_RX_LSS_CTRL setting*/ 2784 BCM_PBMP_ITER(rx_lss_local_pbmp, port_iter){ 2785 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 2786 if (BCM_FAILURE(rv)) { 2787 goto end; 2788 } 2789 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 0); 2790 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 2791 if (BCM_FAILURE(rv)) { 2792 goto end; 2793 } 2794 } 2795 BCM_PBMP_ITER(rx_lss_remote_pbmp, port_iter){ 2796 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 2797 if (BCM_FAILURE(rv)) { 2798 goto end; 2799 } 2800 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 0); 2801 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 0); 2802 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 2803 if (BCM_FAILURE(rv)) { 2804 goto end; 2805 } 2806 } 2807 2808 /*2.Restore MMU egress */ 2809 PBMP_PORT_ITER(unit, port_iter){ 2810 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, egrmeteringconfig[port_iter]); 2811 if (BCM_FAILURE(rv)) { 2812 goto end; 2813 } 2814 } 2815 2816 /*3.Disable PORT fast flush*/ 2817 PBMP_PORT_ITER(unit, port_iter){ 2818 rv = soc_reg_field32_modify(unit, PORT_TXFIFO_PKT_DROP_CTLr, port_iter, 2819 DROP_ENf, 0); 2820 if (BCM_FAILURE(rv)) { 2821 goto end; 2822 } 2823 } 2824 /*4.Disable IPMC fast flush */ 2825 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 2826 if (BCM_FAILURE(rv)) { 2827 goto end; 2828 } 2829 soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0); 2830 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 2831 if (BCM_FAILURE(rv)) { 2832 goto end; 2833 } 2834 /* 5.Restore pause settings*/ 2835 BCM_PBMP_ITER(pause_tx_pbmp, port_iter){ 2836 macd = PORT(unit, port_iter).p_mac; 2837 rv = MAC_PAUSE_GET(macd, unit, port_iter, (int *)&rval, (int *)&rval_1); 2838 if (BCM_FAILURE(rv)) { 2839 goto end; 2840 } 2841 rv = MAC_PAUSE_SET(macd, unit, port_iter, 1, rval_1); 2842 if (BCM_FAILURE(rv)) { 2843 goto end; 2844 } 2845 } 2846 BCM_PBMP_ITER(pause_rx_pbmp, port_iter){ 2847 macd = PORT(unit, port_iter).p_mac; 2848 rv = MAC_PAUSE_GET(macd, unit, port_iter, (int *)&rval, (int *)&rval_1); 2849 if (BCM_FAILURE(rv)) { 2850 goto end; 2851 } 2852 rv = MAC_PAUSE_SET(macd, unit, port_iter, rval, 1); 2853 if (BCM_FAILURE(rv)) { 2854 goto end; 2855 } 2856 } 2857 BCM_PBMP_ITER(tx_llfc_en_pbmp, port_iter){ 2858 macd = PORT(unit, port_iter).p_mac; 2859 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_TX_ENABLE, 1); 2860 if (BCM_FAILURE(rv)) { 2861 goto end; 2862 } 2863 } 2864 BCM_PBMP_ITER(rx_llfc_en_pbmp, port_iter){ 2865 macd = PORT(unit, port_iter).p_mac; 2866 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_RX_ENABLE, 1); 2867 if (BCM_FAILURE(rv)) { 2868 goto end; 2869 } 2870 } 2871 BCM_PBMP_ITER(tx_pfc_en_pbmp, port_iter){ 2872 macd = PORT(unit, port_iter).p_mac; 2873 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_TX_ENABLE, 1); 2874 if (BCM_FAILURE(rv)) { 2875 goto end; 2876 } 2877 } 2878 BCM_PBMP_ITER(rx_pfc_en_pbmp, port_iter){ 2879 macd = PORT(unit, port_iter).p_mac; 2880 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_RX_ENABLE, 1); 2881 if (BCM_FAILURE(rv)) { 2882 goto end; 2883 } 2884 } 2885 /* 6. Refresh FLOW CONTROL XOFF state*/ 2886 PBMP_PORT_ITER(unit, port_iter){ 2887 rv = WRITE_FLOW_CONTROL_XOFF_STATEr(unit, port_iter, 0xff); 2888 if (BCM_FAILURE(rv)) { 2889 goto end; 2890 } 2891 rv = WRITE_FLOW_CONTROL_XOFF_STATEr(unit, port_iter, 0); 2892 if (BCM_FAILURE(rv)) { 2893 goto end; 2894 } 2895 } 2896 /*Wait until all EDATABUF FIFO count == 0 (Optional ?)*/ 2897 /*7.Do IBOD reset for all ports*/ 2898 rv = READ_IBOD_BOD_FIFO_CONTROLr(unit, &rval); 2899 if (BCM_FAILURE(rv)) { 2900 goto end; 2901 } 2902 soc_reg_field_set(unit, IBOD_BOD_FIFO_CONTROLr, &rval, BOD_SW_RST_Lf, 0); 2903 rv = WRITE_IBOD_BOD_FIFO_CONTROLr(unit, rval); 2904 if (BCM_FAILURE(rv)) { 2905 goto end; 2906 } 2907 soc_reg_field_set(unit, IBOD_BOD_FIFO_CONTROLr, &rval, BOD_SW_RST_Lf, 1); 2908 rv = WRITE_IBOD_BOD_FIFO_CONTROLr(unit, rval); 2909 if (BCM_FAILURE(rv)) { 2910 goto end; 2911 } 2912 2913 /*8. Restore EPC link*/ 2914 rv = WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&epc_lin_bmap_entry); 2915 if (BCM_FAILURE(rv)) { 2916 goto end; 2917 } 2918 2919 if (SOC_IS_HELIX4(unit)) { 2920 /*9. Update txerrpkt after modules reset*/ 2921 PBMP_ITER(PBMP_XW_ALL(unit), port) { 2922 rv = READ_TERRr(unit, port, &txerr); 2923 if (SOC_FAILURE(rv)) { 2924 continue; 2925 } 2926 /* coverity[overrun-local : FALSE] */ 2927 ibod_ctrl->txerrpkt[port] = txerr; 2928 } 2929 } 2930 else { 2931 /*9. Update txerrpkt and tuflpkt after modules reset*/ 2932 PBMP_CL_ITER(unit, port_iter){ 2933 rv = READ_TERRr(unit, port_iter, &rval64); 2934 if(BCM_FAILURE(rv)) { 2935 goto end; 2936 } 2937 COMPILER_64_SET(ibod_ctrl->txerrpkt[port_iter], 2938 COMPILER_64_HI(rval64), COMPILER_64_LO(rval64)); 2939 rv = READ_TUFLr(unit, port_iter, &rval64); 2940 if(BCM_FAILURE(rv)) { 2941 goto end; 2942 } 2943 COMPILER_64_SET(ibod_ctrl->tuflpkt[port_iter], 2944 COMPILER_64_HI(rval64), COMPILER_64_LO(rval64)); 2945 } 2946 2947 /* MAC RESET*/ 2948 PBMP_PORT_ITER(unit, port_iter){ 2949 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port_iter, &rval64)); 2950 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 1); 2951 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 2952 if (BCM_FAILURE(rv)) { 2953 goto end; 2954 } 2955 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 0); 2956 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 2957 if (BCM_FAILURE(rv)) { 2958 goto end; 2959 } 2960 } 2961 } 2962 2963 /*10.Resume ingress traffic*/ 2964 BCM_PBMP_ITER(rx_en_pbmp, port_iter){ 2965 macd = PORT(unit, port_iter).p_mac; 2966 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_RX_SET, 1); 2967 if (BCM_FAILURE(rv)) { 2968 goto end; 2969 } 2970 } 2971 /***** Resume ingress traffic End*****/ 2972 2973 /***** Enable software handling Start*****/ 2974 /*1. Enable all back ground threads to prevent any SBUS acitivities (software handling)*/ 2975 rv = bcm_esw_linkscan_enable_set(unit, linkscan_interval); 2976 if (BCM_FAILURE(rv)) { 2977 goto end; 2978 } 2979 rv = soc_counter_start(unit, counter_flags, counter_interval, counter_pbmp); 2980 if (BCM_FAILURE(rv)) { 2981 goto end; 2982 } 2983 if (l2x_running) { 2984 rv = soc_l2x_start(unit, l2x_flags, l2x_interval); 2985 if (BCM_FAILURE(rv)) { 2986 goto end; 2987 } 2988 } 2989 #ifdef INCLUDE_MEM_SCAN 2990 if (mem_scan_running) { 2991 rv = soc_mem_scan_start(unit, scan_rate, scan_interval); 2992 if (BCM_FAILURE(rv)) { 2993 goto end; 2994 } 2995 } 2996 #endif 2997 2998 end: 2999 /*2. Enable "TX" API to prevent CPU packet from going into MMU (software handling)*/ 3000 PBMP_PORT_ITER(unit, port_iter){ 3001 _bcm_esw_ibod_recovery_port_unlock(unit, port_iter); 3002 } 3003 3004 /***** Enable software handling End*****/ 3005 time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 3006 ibod_ctrl->mmu_war_count++; 3007 ibod_ctrl->mmu_avg_time= (ibod_ctrl->mmu_avg_time*(ibod_ctrl->mmu_war_count-1) 3008 + time2 - time1) /ibod_ctrl->mmu_war_count; 3009 3010 return rv; 3011 } 3012 3013 STATIC int 3014 _bcm_tr3_mmu_check_and_recovery(_port_ibod_ctrl_t *ibod_ctrl) 3015 { 3016 int rv = BCM_E_NONE; 3017 uint32 overflow0,overflow1; 3018 int ibod_timeout_flag = 0; 3019 int txerr_timeout_flag = 0; 3020 int port_recovery_failed_flag = 0; 3021 int unit = ibod_ctrl->unit; 3022 3023 overflow0 = 0; 3024 overflow1 = 0; 3025 3026 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0); 3027 if (SOC_FAILURE(rv)) { 3028 LOG_ERROR(BSL_LS_BCM_PORT, 3029 (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW0"))); 3030 return rv; 3031 } 3032 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1); 3033 if (SOC_FAILURE(rv)) { 3034 LOG_ERROR(BSL_LS_BCM_PORT, 3035 (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW1"))); 3036 return rv; 3037 } 3038 3039 _soc_egress_drain_timeout_flag_get(unit, &ibod_timeout_flag); 3040 txerr_timeout_flag = ibod_ctrl->drain_timeout_flag; 3041 port_recovery_failed_flag = ibod_ctrl->port_recovery_failed_flag; 3042 3043 if ((overflow0 != 0) || (overflow1 != 0) || ibod_timeout_flag || txerr_timeout_flag 3044 || port_recovery_failed_flag || (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER)) { 3045 rv = _bcm_tr3_mmu_recovery(ibod_ctrl); 3046 if (txerr_timeout_flag) { 3047 ibod_ctrl->drain_timeout_flag = 0; 3048 ibod_ctrl->drain_timeout_count++; 3049 } 3050 if (port_recovery_failed_flag) { 3051 ibod_ctrl->port_recovery_failed_flag = 0; 3052 ibod_ctrl->port_recovery_failed_count++; 3053 } 3054 if (ibod_timeout_flag) { 3055 _soc_egress_drain_timeout_flag_set(unit, 0); 3056 ibod_ctrl->egress_drain_timeout_count++; 3057 } 3058 if (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER) { 3059 _ibod_debug_flag &= (~_PORT_IBOD_FLAG_MMU_TRIGGER); 3060 } 3061 if (SOC_FAILURE(rv)) { 3062 LOG_ERROR(BSL_LS_BCM_PORT, 3063 (BSL_META_U(unit, "\n Error in MMU recovery "))); 3064 } 3065 } 3066 3067 return rv; 3068 } 3069 3070 STATIC int 3071 _bcm_tr3_txerr_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, 3072 bcm_port_t port) 3073 { 3074 bcm_pbmp_t pbmp; 3075 uint32 rval; 3076 uint64 rval64, txerr, tufl, flush_enable_pbm, tmp64; 3077 uint64 egress_meter; 3078 int unit=ibod_ctrl->unit, okay=0, rv = BCM_E_NONE; 3079 pbmp_t mask, mask1, mask1_restore, mask_restore; 3080 soc_timeout_t timeout; 3081 int txerr_status,tufl_status, underflow_status, lanes; 3082 uint32 cur_cells, new_cells, mmu_cells,credit_set; 3083 uint32 cdc_fifo_cells, tx_fifo_cells; 3084 uint32 overflow0, overflow1, total_cell; 3085 soc_info_t *si = &SOC_INFO(unit); 3086 egr_mmu_requests_entry_t mmu_entry; 3087 uint32 max_used_entry; 3088 #ifdef TXERR_DEBUG 3089 uint64 tpkt, tfcs; 3090 uint32 ep_max_level = 0; 3091 #endif 3092 uint32 credit, mmu_req, ep_level; 3093 int rx_llfc_en,rx_pfc_en,pause_rx, rx_lss, rx_lss_1; 3094 soc_reg_t temp_reg_id; 3095 static const soc_reg_t lls_port_credit_reg[] = { 3096 LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr, 3097 LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr, 3098 LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr, 3099 LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr, 3100 LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr, 3101 LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr, 3102 LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr, 3103 LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr, 3104 LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr, 3105 LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr, 3106 LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr, 3107 LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr, 3108 LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr, 3109 LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr, 3110 LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr, 3111 LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr, 3112 LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr, 3113 LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr, 3114 LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr, 3115 LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr, 3116 LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr 3117 }; 3118 sal_usecs_t time1, time2; 3119 3120 sal_memset(&pbmp, 0, sizeof(bcm_pbmp_t)); 3121 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay)); 3122 if (okay) { 3123 SOC_PBMP_PORT_ADD(pbmp, port); 3124 } else { 3125 return SOC_E_NONE; 3126 } 3127 3128 txerr_status = 0; 3129 /* check and update tx err counter */ 3130 SOC_IF_ERROR_RETURN(READ_TERRr(unit, port, &txerr)); 3131 if (COMPILER_64_NE(ibod_ctrl->txerrpkt[port], txerr)) { 3132 ibod_ctrl->txerrpkt[port] = txerr; 3133 txerr_status = 1; 3134 } 3135 3136 tufl_status = 0; 3137 /* check and update tx underflow counter */ 3138 SOC_IF_ERROR_RETURN(READ_TUFLr(unit, port, &tufl)); 3139 if (COMPILER_64_NE(ibod_ctrl->tuflpkt[port], tufl)) { 3140 ibod_ctrl->tuflpkt[port] = tufl; 3141 tufl_status = 1; 3142 } 3143 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_FIFO_STATUSr : XMAC_FIFO_STATUSr; 3144 BCM_IF_ERROR_RETURN(soc_reg64_get(unit, temp_reg_id, port, 0, &rval64)); 3145 underflow_status = soc_reg64_field32_get(unit, temp_reg_id, rval64, TX_PKT_UNDERFLOWf); 3146 3147 /* check tx error and tx underflow */ 3148 if ((txerr_status == 0) && (tufl_status == 0) &&(underflow_status == 0) && 3149 (txerr_trigger_flag[port] == 0)) { 3150 return SOC_E_NONE; 3151 } 3152 3153 if ((txerr_status != 0) || (tufl_status != 0) || (underflow_status != 0)) { 3154 txerr_trigger_flag[port] = 1; 3155 } 3156 else if (txerr_trigger_flag[port] == 1) { 3157 txerr_trigger_flag[port] = 0; 3158 } 3159 3160 #ifdef TXERR_DEBUG 3161 cli_out("WAR TER Trigerred [port %d]:txerr_status:%d, tufl_status:%d, underflow_status:%d\r\n", 3162 port, txerr_status, tufl_status, underflow_status); 3163 #endif 3164 rv = (soc_tr3_port_lanes_get(unit, port, &lanes)); 3165 if (BCM_FAILURE(rv)) { 3166 return rv; 3167 } 3168 3169 switch (lanes) { 3170 case 10: /* 100G */ 3171 si->port_credit[port] = 108; 3172 break; 3173 case 4: /* SINGLE */ 3174 si->port_credit[port] = 36; 3175 break; 3176 case 2: /* DUAL */ 3177 si->port_credit[port] = 18; 3178 break; 3179 case 1: /* QUAD */ 3180 si->port_credit[port] = 9; 3181 break; 3182 default: 3183 si->port_credit[port] = 36; 3184 break; 3185 } 3186 3187 time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 3188 3189 _bcm_esw_lc_lock(unit); 3190 soc_link_fwd_get(unit, &mask1); 3191 SOC_PBMP_ASSIGN(mask1_restore,mask1); 3192 BCM_PBMP_PORT_REMOVE(mask1,port); 3193 rv = soc_link_fwd_set(unit, mask1); 3194 if (BCM_FAILURE(rv)) { 3195 _bcm_esw_lc_unlock(unit); 3196 LOG_ERROR(BSL_LS_BCM_PORT, 3197 (BSL_META_U(unit,"\n Error in setting the mask FWD" 3198 " for WAR on port %s"), SOC_PORT_NAME(unit,port))); 3199 return BCM_E_NONE; 3200 } 3201 3202 PORT_LOCK(unit); 3203 _bcm_esw_ibod_recovery_port_lock(unit, port); 3204 3205 /* move port from EPC_LINK_BMAP */ 3206 soc_link_mask2_get(unit, &mask); 3207 SOC_PBMP_ASSIGN(mask_restore,mask); 3208 BCM_PBMP_PORT_REMOVE(mask,port); 3209 rv = soc_link_mask2_set(unit, mask); 3210 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3211 3212 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PAUSE_CTRLr : XMAC_PAUSE_CTRLr; 3213 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3214 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3215 pause_rx = soc_reg64_field32_get(unit, temp_reg_id, rval64, RX_PAUSE_ENf); 3216 soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PAUSE_ENf, 0); 3217 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3218 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3219 3220 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PFC_CTRLr : XMAC_PFC_CTRLr; 3221 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3222 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3223 rx_pfc_en = soc_reg64_field32_get(unit, temp_reg_id, rval64, RX_PFC_ENf); 3224 soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PFC_ENf, 0); 3225 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3226 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3227 3228 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_LLFC_CTRLr : XMAC_LLFC_CTRLr; 3229 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3230 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3231 rx_llfc_en = soc_reg64_field32_get(unit, temp_reg_id, rval64, RX_LLFC_ENf); 3232 soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_LLFC_ENf, 0); 3233 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3234 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3235 3236 rv = READ_EGRMETERINGCONFIG_64r(unit, port, &rval64); 3237 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3238 egress_meter = rval64; 3239 COMPILER_64_ZERO(tmp64); 3240 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, tmp64); 3241 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3242 3243 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_RX_LSS_CTRLr : XMAC_RX_LSS_CTRLr; 3244 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3245 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3246 rx_lss = soc_reg64_field32_get(unit, temp_reg_id, rval64, 3247 DROP_TX_DATA_ON_LOCAL_FAULTf); 3248 rx_lss_1 = soc_reg64_field32_get(unit, temp_reg_id, rval64, 3249 DROP_TX_DATA_ON_REMOTE_FAULTf); 3250 soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1); 3251 soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1); 3252 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3253 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3254 3255 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 3256 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3257 COMPILER_64_SET(flush_enable_pbm, pbmp.pbits[1], pbmp.pbits[0]); 3258 soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, flush_enable_pbm); 3259 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 3260 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3261 3262 /* drop packets */ 3263 rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, &rval); 3264 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3265 soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 1); 3266 rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, rval); 3267 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3268 3269 cur_cells = 0xffffffff; 3270 soc_timeout_init(&timeout, 30000, 0); 3271 3272 while(1) { 3273 #ifdef TXERR_DEBUG 3274 /* check epc_link_bmap for debug */ 3275 pbmp_t pbm; 3276 epc_link_bmap_entry_t entry; 3277 READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry); 3278 soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm); 3279 if (SOC_PBMP_MEMBER(pbm, port)) { 3280 LOG_WARN(BSL_LS_BCM_PORT, 3281 (BSL_META_U(unit, "TXERR recovery:uint %d port %d still in epc link bitmap 0x%x\r\n"), 3282 unit, port, pbm.pbits[0])); 3283 } 3284 #endif 3285 new_cells=0; 3286 3287 /*1. check MMU cell */ 3288 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &rval); 3289 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3290 mmu_cells = soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf); 3291 new_cells += mmu_cells; 3292 3293 /*2. check port CDC fifo */ 3294 rv = READ_PORT_CDC_TXFIFO_CELL_CNTr(unit, port, &rval); 3295 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3296 cdc_fifo_cells = soc_reg_field_get(unit, PORT_CDC_TXFIFO_CELL_CNTr, rval, CELL_CNTf); 3297 new_cells += cdc_fifo_cells; 3298 3299 /*3. check port tx fifo */ 3300 rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port, &rval); 3301 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3302 tx_fifo_cells = soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf); 3303 new_cells += tx_fifo_cells; 3304 3305 /* read MMU credit */ 3306 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit); 3307 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3308 3309 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry); 3310 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3311 mmu_req = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 3312 3313 /* read EP level */ 3314 rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval); 3315 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3316 soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1); 3317 rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval); 3318 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3319 rv = READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL, si->port_l2p_mapping[port], &max_used_entry); 3320 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3321 ep_level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf); 3322 3323 /* Update cur_cells and give more time to drain packets. */ 3324 if (new_cells < cur_cells) { 3325 soc_timeout_init(&timeout, 30000, 0); 3326 cur_cells = new_cells; 3327 } 3328 else { 3329 #ifdef TXERR_DEBUG 3330 cli_out("TXERR reovery: mmu cells not draining 1: %d cells remain,cur_cells %d, mmu_cells %d, level %d, credit %d mmu_req %d \r\n", 3331 new_cells, cur_cells, mmu_cells, ep_level, credit, mmu_req); 3332 #endif 3333 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, si->port_credit[port]); 3334 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3335 } 3336 3337 if (soc_timeout_check(&timeout)) { 3338 if(ep_level == 0) { 3339 ibod_ctrl->drain_timeout_flag = 1; 3340 } 3341 else { 3342 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0); 3343 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3344 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1); 3345 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3346 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit,port, &total_cell); 3347 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3348 LOG_ERROR(BSL_LS_BCM_PORT, 3349 (BSL_META_U(unit, "\n TXERR recovery Timeout Drain packets %d PORT: %s, " 3350 "ep_level:%d, overflow0:%d, overflow1:%d total_cell %d " 3351 "credit %d mmu_req %d \n"), 3352 ibod_ctrl->unit, SOC_PORT_NAME(unit,port), ep_level, overflow0, 3353 overflow1, total_cell, credit, mmu_req)); 3354 } 3355 break; 3356 } 3357 #ifdef TXERR_DEBUG 3358 /* for debug */ 3359 uint32 mmu_req_1; 3360 3361 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry); 3362 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3363 mmu_req_1 = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 3364 if(mmu_req_1 != mmu_req){ 3365 cli_out("TXERR recovery: credit %d mmu_req %d is not equal mmu_req_1 %d !!!!!\r\n",credit, mmu_req, mmu_req_1); 3366 3367 } 3368 #endif 3369 /* All packets were drained */ 3370 if (new_cells == 0) { 3371 if (_soc_egress_drain_credit_calc(credit, si->port_credit[port], mmu_req, ep_level, &credit_set)) { 3372 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, credit_set); 3373 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3374 } 3375 #ifdef TXERR_DEBUG 3376 rv = _soc_egress_drain_ep_max_level_get(unit, port, &ep_max_level); 3377 if(rv == BCM_E_NONE) 3378 { 3379 cli_out("TXERR recovery: MacDrainOK max_level %d !!!!!\r\n", ep_max_level); 3380 } 3381 3382 rv = READ_TPKTr(unit, port, &tpkt); 3383 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3384 rv = READ_TFCSr(unit, port, &tfcs); 3385 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3386 3387 cli_out("TXERR recovery: MacDrainOK credit = %d, Port:%d, tpkt:%lld, tfcs=%lld\r\n", credit, port, tpkt, tfcs); 3388 #endif 3389 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit); 3390 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3391 if(credit == 0) { 3392 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], 3393 REG_PORT_ANY, 0, si->port_credit[port]); 3394 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3395 } 3396 break; 3397 } 3398 else if (mmu_cells){ /* some packets still stay in MMU */ 3399 if((credit == 0)) { 3400 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit); 3401 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3402 if(credit == 0) { 3403 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry); 3404 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3405 mmu_req = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 3406 3407 if (_soc_egress_drain_credit_calc(credit, si->port_credit[port], mmu_req, ep_level, &credit_set)) { 3408 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, credit_set); 3409 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3410 } 3411 } 3412 else { 3413 #ifdef TXERR_DEBUG 3414 _soc_egress_drain_debug(unit, port, lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]]); 3415 #endif 3416 } 3417 } 3418 else { 3419 #ifdef TXERR_DEBUG 3420 _soc_egress_drain_debug(unit, port, lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]]); 3421 #endif 3422 } 3423 } 3424 } 3425 3426 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_CLEAR_FIFO_STATUSr : XMAC_CLEAR_FIFO_STATUSr; 3427 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3428 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3429 soc_reg64_field32_set(unit, temp_reg_id, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 1); 3430 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3431 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3432 3433 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3434 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3435 soc_reg64_field32_set(unit, temp_reg_id, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 0); 3436 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3437 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3438 3439 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, egress_meter); 3440 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3441 3442 rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, &rval); 3443 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3444 soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 0); 3445 rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, rval); 3446 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3447 3448 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 3449 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3450 soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0); 3451 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 3452 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3453 3454 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_RX_LSS_CTRLr : XMAC_RX_LSS_CTRLr; 3455 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3456 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3457 soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, rx_lss); 3458 soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, rx_lss_1); 3459 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3460 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3461 3462 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PAUSE_CTRLr : XMAC_PAUSE_CTRLr; 3463 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3464 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3465 soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PAUSE_ENf, pause_rx); 3466 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3467 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3468 3469 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PFC_CTRLr : XMAC_PFC_CTRLr; 3470 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3471 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3472 soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PFC_ENf, rx_pfc_en); 3473 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3474 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3475 3476 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_LLFC_CTRLr : XMAC_LLFC_CTRLr; 3477 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3478 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3479 soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_LLFC_ENf, rx_llfc_en); 3480 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3481 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3482 3483 /* restore port from EPC_LINK_BMAP */ 3484 rv = soc_link_mask2_set(unit, mask_restore); 3485 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3486 3487 _bcm_esw_ibod_recovery_port_unlock(unit, port); 3488 PORT_UNLOCK(unit); 3489 rv = soc_link_fwd_set(unit, mask1_restore); 3490 if (BCM_FAILURE(rv)) { 3491 _bcm_esw_lc_unlock(unit); 3492 LOG_ERROR(BSL_LS_BCM_PORT, 3493 (BSL_META_U(unit,"\n Error in re-setting the mask FWD" 3494 " for WAR on port %s"), SOC_PORT_NAME(unit,port))); 3495 return BCM_E_NONE; 3496 } 3497 3498 _bcm_esw_lc_unlock(unit); 3499 3500 time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 3501 ibod_ctrl->txerr_count++; 3502 ibod_ctrl->txerr_avg_time = (ibod_ctrl->txerr_avg_time*(ibod_ctrl->txerr_count-1) + 3503 time2 - time1) /ibod_ctrl->txerr_count; 3504 3505 return SOC_E_NONE; 3506 } 3507 3508 STATIC int 3509 _bcm_tr3_ibod_port_check( 3510 _port_ibod_ctrl_t *ibod_ctrl, bcm_port_t port, int *need_recovery) 3511 { 3512 int rv, unit = ibod_ctrl->unit; 3513 uint64 rrpkt, rrbyt; 3514 uint64 rrpkt_diff, rrbyt_diff; 3515 uint64 rval64; 3516 int runt_threshold; 3517 3518 /* Only check HG port */ 3519 if (!IS_HG_PORT(unit, port)) { 3520 return BCM_E_NONE; 3521 } 3522 3523 /* Check if any new runt packet logged in RRPKT */ 3524 rv = READ_RRPKTr(unit, port, &rrpkt); 3525 if (SOC_FAILURE(rv)) { 3526 return BCM_E_FAIL; 3527 } 3528 if (COMPILER_64_EQ(rrpkt, ibod_ctrl->rrpkt[port])) { 3529 return BCM_E_NONE; 3530 } 3531 3532 /* Check total runt byte count */ 3533 rv = READ_RRBYTr(unit, port, &rrbyt); 3534 if (SOC_FAILURE(rv)) { 3535 return BCM_E_FAIL; 3536 } 3537 3538 /* It's very unlikely both packet and byte counters wrap around 3539 * and stop at 0, the code assume this is from clear counter */ 3540 if (COMPILER_64_IS_ZERO(rrpkt) && COMPILER_64_IS_ZERO(rrbyt)) { 3541 ibod_ctrl->rrpkt_old[port] = ibod_ctrl->rrpkt[port]; 3542 ibod_ctrl->rrbyt_old[port] = ibod_ctrl->rrbyt[port]; 3543 ibod_ctrl->rrpkt[port] = rrpkt; 3544 ibod_ctrl->rrbyt[port] = rrbyt; 3545 return BCM_E_NONE; 3546 } 3547 3548 rrpkt_diff = rrpkt; 3549 rrbyt_diff = rrbyt; 3550 COMPILER_64_SUB_64(rrpkt_diff, ibod_ctrl->rrpkt[port]); 3551 COMPILER_64_SUB_64(rrbyt_diff, ibod_ctrl->rrbyt[port]); 3552 ibod_ctrl->rrpkt_old[port] = ibod_ctrl->rrpkt[port]; 3553 ibod_ctrl->rrbyt_old[port] = ibod_ctrl->rrbyt[port]; 3554 ibod_ctrl->rrpkt[port] = rrpkt; 3555 ibod_ctrl->rrbyt[port] = rrbyt; 3556 #ifdef IBOD_DEBUG 3557 cli_out("WAR IBOD Check [port %d] rrbyt %lld rrpkt %lld, rrpkt_diff %lld rrbyt_diff %lld\r\n", 3558 port, ibod_ctrl->rrbyt[port], ibod_ctrl->rrpkt[port], rrpkt_diff, rrbyt_diff); 3559 #endif 3560 rv = READ_XMAC_RX_CTRLr(unit,port, &rval64); 3561 if (SOC_FAILURE(rv)) { 3562 return BCM_E_FAIL; 3563 } 3564 3565 runt_threshold = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval64, RUNT_THRESHOLDf); 3566 3567 /* Recovery is needed only for packet size between 33 and threshold */ 3568 if (COMPILER_64_HI(rrpkt_diff) == 0 && 3569 COMPILER_64_LO(rrpkt_diff) == 1) { 3570 if (COMPILER_64_LO(rrbyt_diff) >= runt_threshold) { 3571 return BCM_E_NONE; 3572 } 3573 } 3574 if (COMPILER_64_HI(rrbyt_diff) == 0 && 3575 COMPILER_64_LO(rrbyt_diff) <= 32) { 3576 return BCM_E_NONE; 3577 } 3578 3579 *need_recovery = TRUE; 3580 3581 return BCM_E_NONE; 3582 } 3583 3584 STATIC int 3585 _bcm_tr3_ibod_sync_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, int port_set, 3586 bcm_port_t port) 3587 { 3588 int idx, fifo_len, send_time; 3589 int rv = BCM_E_NONE; 3590 int rv1 = BCM_E_NONE; 3591 int enable, tdm_length; 3592 uint64 rrpkt, rrbyt; 3593 uint64 rpkt, tpkt; 3594 pbmp_t pbm; 3595 epc_link_bmap_entry_t entry; 3596 int lanes, unit = ibod_ctrl->unit; 3597 soc_info_t *si = &SOC_INFO(unit); 3598 int phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 3599 uint32 *tdm_array; 3600 int port_dis_tag=0, port_dis_untag=0; 3601 bcm_pkt_t *pkt = &ibod_ctrl->pkt; 3602 SHR_BITDCLNAME(used_bmp, TR3_IARB_TDM_TABLE_LENGTH); 3603 uint32 _tdm_array_hw[380] = {-1}; 3604 int pause_tx, pause_rx, pfc_rx, llfc_rx; 3605 iarb_tdm_table_entry_t new_entry; 3606 uint32 rval; 3607 pbmp_t mask, mask1, mask1_restore; 3608 int ibod_data_fifo_full_intr_status = 0; 3609 soc_field_t cl_data_fifo_full_err_intr_status = 0; 3610 soc_field_t cl_ctrl_fifo_full_err_intr_status = 0; 3611 #ifdef IBOD_DEBUG 3612 uint64 rpkt, tpkt; 3613 uint64 rpkt_fin, tpkt_fin, rrpkt_fin, rrbyt_fin; 3614 #endif 3615 3616 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 3617 rv = (soc_tr3_port_lanes_get(unit, port, &lanes)); 3618 if (BCM_FAILURE(rv)) { 3619 return rv; 3620 } 3621 3622 switch (lanes) { 3623 case 10: /* 100G */ 3624 fifo_len = 34; 3625 si->port_credit[port] = 108; 3626 break; 3627 case 4: /* SINGLE */ 3628 fifo_len = 34; 3629 si->port_credit[port] = 36; 3630 break; 3631 case 2: /* DUAL */ 3632 fifo_len = 34; 3633 si->port_credit[port] = 18; 3634 break; 3635 case 1: /* QUAD */ 3636 fifo_len = 34; 3637 si->port_credit[port] = 9; 3638 break; 3639 default: 3640 fifo_len = 34; 3641 si->port_credit[port] = 36; 3642 break; 3643 } 3644 3645 3646 if ((phy_port >= 53) && (phy_port <= 64 )){ 3647 cl_data_fifo_full_err_intr_status = CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf; 3648 cl_ctrl_fifo_full_err_intr_status = CL0_CTRL_FIFO_FULL_ERR_INTR_STATUSf; 3649 } 3650 else if ((phy_port >= 69) && (phy_port <= 80)) { 3651 cl_data_fifo_full_err_intr_status = CL1_DATA_FIFO_FULL_ERR_INTR_STATUSf; 3652 cl_ctrl_fifo_full_err_intr_status = CL1_CTRL_FIFO_FULL_ERR_INTR_STATUSf; 3653 } 3654 else { 3655 LOG_ERROR(BSL_LS_BCM_PORT, 3656 (BSL_META_U(unit, "IBOD port:%d is not CL port\n\r"), port)); 3657 return BCM_E_PORT; 3658 } 3659 fifo_len = soc_property_get(unit, "ibod_fifo_len", fifo_len); 3660 3661 soc_link_fwd_get(unit, &mask1); 3662 SOC_PBMP_ASSIGN(mask1_restore,mask1); 3663 BCM_PBMP_PORT_REMOVE(mask1,port); 3664 rv = soc_link_fwd_set(unit, mask1); 3665 if (BCM_FAILURE(rv)) { 3666 LOG_ERROR(BSL_LS_BCM_PORT, 3667 (BSL_META_U(unit, 3668 "IBOD Link fwd set failed[%d] on port:%d\n\r"), 3669 rv, port)); 3670 return rv; 3671 } 3672 3673 PORT_LOCK(unit); /* Begin port atomic */ 3674 _bcm_esw_ibod_recovery_port_lock(unit, port); 3675 soc_ibod_recovery_in_progress_set(unit, 1); 3676 3677 if (port_set == 0) { 3678 soc_link_mask2_get(unit, &mask); 3679 rv = bcm_esw_port_enable_get(unit, port, &enable); 3680 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3681 /* port is disabled */ 3682 if ((enable == 0) || !SOC_PBMP_MEMBER(mask, port)) { 3683 soc_ibod_recovery_in_progress_set(unit, 0); 3684 _bcm_esw_ibod_recovery_port_unlock(unit, port); 3685 PORT_UNLOCK(unit); 3686 rv = soc_link_fwd_set(unit, mask1_restore); 3687 /* 3688 * Since the recovery is not run when the port is down the 3689 * rrpkt is updated back to the original value, as the 3690 * recovery will happen when the port is up 3691 */ 3692 ibod_ctrl->rrpkt[port] = ibod_ctrl->rrpkt_old[port]; 3693 ibod_ctrl->rrbyt[port] = ibod_ctrl->rrbyt_old[port]; 3694 LOG_INFO(BSL_LS_BCM_PORT, 3695 (BSL_META_U(unit, 3696 "Skip ibod sync war if port %d is disabled %d.\n"), 3697 port, enable)); 3698 return rv; 3699 } 3700 } 3701 3702 /* Isolate port */ 3703 rv = _bcm_tr3_ibod_port_isolate(unit, port_set, port, &port_dis_untag, &port_dis_tag); 3704 if (BCM_FAILURE(rv)) { 3705 soc_ibod_recovery_in_progress_set(unit, 0); 3706 _bcm_esw_ibod_recovery_port_unlock(unit, port); 3707 PORT_UNLOCK(unit); 3708 rv1 = soc_link_fwd_set(unit, mask1_restore); 3709 LOG_ERROR(BSL_LS_BCM_PORT, 3710 (BSL_META_U(unit, "IBOD port(%d) isolate Failed[%d %d]\n\r"), 3711 port, rv, rv1)); 3712 return rv; 3713 } 3714 3715 sal_memset(&used_bmp, 0, sizeof(used_bmp)); 3716 3717 /* Remove the port from IARB_TDM_TABLE */ 3718 tdm_length = _soc_tr3_tdm_size; 3719 for (idx = 0; idx < _soc_tr3_tdm_size; idx++) { 3720 /* coverity[unchecked_value] */ 3721 (void)soc_mem_read(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx,&new_entry); 3722 _tdm_array_hw[idx] = 3723 soc_mem_field32_get(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf); 3724 } 3725 tdm_array = _tdm_array_hw; 3726 3727 sal_memset(&new_entry, 0, sizeof(iarb_tdm_table_entry_t)); 3728 soc_mem_field32_set(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf, 127); 3729 for (idx = 0; idx < _soc_tr3_tdm_size; idx++) { 3730 if (tdm_array[idx] != phy_port) { 3731 continue; 3732 } 3733 (void)soc_mem_write(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx, 3734 &new_entry); 3735 SHR_BITSET(used_bmp, idx); 3736 } 3737 sal_udelay(10000); 3738 3739 /* Disable pause/pfc/llfc function */ 3740 rv = soc_mac_x.md_pause_get(unit, port, &pause_tx, &pause_rx); 3741 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3742 3743 rv = soc_mac_x.md_pause_set(unit, port, 0, 0); 3744 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3745 3746 rv = soc_mac_x.md_control_get(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, &pfc_rx); 3747 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3748 3749 rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, 0); 3750 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3751 3752 rv = soc_mac_x.md_control_get(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,&llfc_rx); 3753 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3754 3755 rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,0); 3756 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3757 3758 /* check epc_link_bmap */ 3759 /* coverity[check_return] */ 3760 READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry); 3761 soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm); 3762 if (SOC_PBMP_MEMBER(pbm, port)) { 3763 LOG_WARN(BSL_LS_BCM_PORT, 3764 (BSL_META_U(unit, "uint %d port %d still in epc link bitmap 0x%x\r\n"), 3765 unit, port, pbm.pbits[0])); 3766 } 3767 3768 rv = READ_RRBYTr(unit, port, &rrbyt); 3769 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3770 3771 rv = READ_RRPKTr(unit, port, &rrpkt); 3772 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3773 3774 rv = READ_RPKTr(unit, port, &rpkt); 3775 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3776 rv = READ_TPKTr(unit, port, &tpkt); 3777 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3778 #ifdef IBOD_DEBUG 3779 cli_out("WAR Trigerred IBOD recovery [port %d] enable %d orign rrbyt %lld rrpkt %lld rpkt %lld tpkt %lld\r\n", 3780 port, port_set, rrbyt, rrpkt, rpkt, tpkt ); 3781 #endif 3782 send_time = 0; 3783 3784 /* send loopback packets untill fifo full error occurred. */ 3785 do { 3786 /* Send 80-byte packets to fill IBOD FIFO */ 3787 for (idx = 0; idx < fifo_len; idx++) { 3788 BCM_PKT_TX_LEN_SET(pkt, 68); 3789 BCM_PKT_PORT_SET(pkt, port, TRUE, FALSE); 3790 BCM_PKT_HGHDR_REQUIRE(pkt); 3791 rv = bcm_common_tx(unit, pkt, NULL); 3792 if (BCM_FAILURE(rv)) { 3793 LOG_ERROR(BSL_LS_BCM_PORT, 3794 (BSL_META_U(unit, "IBOD 80-byte packet transmit" 3795 " failed[%d] on port:%d, send_time:%d\n\r"), rv, port, send_time)); 3796 ibod_ctrl->port_recovery_failed_flag = 1; 3797 break; 3798 } 3799 } 3800 if (ibod_ctrl->port_recovery_failed_flag) { 3801 break; 3802 } 3803 3804 send_time ++; 3805 rv = READ_IBOD_INTR_STATUSr(unit, &rval); 3806 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3807 ibod_data_fifo_full_intr_status = soc_reg_field_get(unit, IBOD_INTR_STATUSr, 3808 rval, cl_data_fifo_full_err_intr_status); 3809 #ifdef IBOD_DEBUG 3810 if (!ibod_data_fifo_full_intr_status){ 3811 cli_out("%s IBOD intr data fifo full err status is 0 !!!!!!!%d\r\n", 3812 (cl_data_fifo_full_err_intr_status == CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf)?"CL0":"CL1", ibod_data_fifo_full_intr_status); 3813 } 3814 #endif 3815 3816 if (send_time >= 5) { 3817 #ifdef IBOD_DEBUG 3818 int lb = 0; 3819 MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &lb); 3820 3821 rv = READ_RPKTr(unit, port, &rpkt_fin); 3822 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3823 rv = READ_TPKTr(unit, port, &tpkt_fin); 3824 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3825 3826 LOG_ERROR(BSL_LS_BCM_PORT, (BSL_META_U(unit,"\n IBOD recovery (unit %d PORT: %s) fill IBOD FIFO full failed: rpkt_fin %lld tpkt_fin %lld loopback %d\r\n"), 3827 ibod_ctrl->unit, SOC_PORT_NAME(unit,port),rpkt_fin,tpkt_fin, lb)); 3828 #else 3829 LOG_ERROR(BSL_LS_BCM_PORT, 3830 (BSL_META_U(unit,"\n IBOD recovery (unit %d PORT: %s) fill IBOD FIFO full failed\r\n"), 3831 unit, SOC_PORT_NAME(unit,port))); 3832 #endif 3833 ibod_ctrl->port_recovery_failed_flag = 1; 3834 break; 3835 } 3836 }while (ibod_data_fifo_full_intr_status == 0); 3837 3838 #ifdef IBOD_DEBUG 3839 rv = READ_RRBYTr(unit, port, &rrbyt); 3840 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3841 3842 rv = READ_RRPKTr(unit, port, &rrpkt); 3843 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3844 3845 rv = READ_RPKTr(unit, port, &rpkt_fin); 3846 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3847 3848 rv = READ_TPKTr(unit, port, &tpkt_fin); 3849 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3850 cli_out("WAR Trigerred IBOD recovery [port %d] normal rrbyt %lld rrpkt %lld rpkt_fin %lld tpkt_fin %lld send_time %d\r\n", 3851 port, rrbyt, rrpkt, rpkt_fin,tpkt_fin, send_time); 3852 if((rpkt_fin - rpkt) != fifo_len * send_time ) { 3853 cli_out("IBOD recovery loopback regular counter is not right!!!!!!! \r\n"); 3854 if((rpkt_fin - rpkt) < fifo_len * send_time ) { 3855 cli_out("IBOD recovery loopback regular counter is less than tx!!!!!!!! \r\n"); 3856 } 3857 } 3858 #endif 3859 /* Restore IARB_TDM_TABLE */ 3860 soc_mem_field32_set(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf, 3861 phy_port); 3862 for (idx = 0; idx < tdm_length; idx++) { 3863 if (!SHR_BITGET(used_bmp, idx)) { 3864 continue; 3865 } 3866 (void)soc_mem_write(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx, 3867 &new_entry); 3868 } 3869 3870 for (idx = 0; idx < tdm_length; idx++) { 3871 if (tdm_array[idx] != phy_port) { 3872 continue; 3873 } 3874 #ifdef IBOD_DEBUG 3875 (void)soc_mem_read(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx,&new_entry); 3876 _tdm_array_hw[idx] = soc_mem_field32_get(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf); 3877 if(_tdm_array_hw[idx] != phy_port){ 3878 cli_out("IBOD IARB TDM port number idx %d _tdm_array_hw[idx] %d !!!!!!\r\n",idx, _tdm_array_hw[idx]); 3879 } 3880 #endif 3881 } 3882 /* waiting for IARB_TDM_TABLE ready */ 3883 sal_udelay(30000); 3884 /* Send 72-byte RUNT packet */ 3885 if (BCM_SUCCESS(rv)) { 3886 BCM_PKT_TX_LEN_SET(pkt, 60); 3887 BCM_PKT_PORT_SET(pkt, port, TRUE, FALSE); 3888 rv = bcm_common_tx(unit, pkt, NULL); 3889 if (BCM_FAILURE(rv)) { 3890 LOG_ERROR(BSL_LS_BCM_PORT, 3891 (BSL_META_U(unit, 3892 "IBOD Runt Pkt transmit failed[%d] on port:%d\n\r"), 3893 rv, port)); 3894 ibod_ctrl->port_recovery_failed_flag = 1; 3895 } 3896 } 3897 3898 #ifdef IBOD_DEBUG 3899 rv = READ_RRPKTr(unit, port, &rrpkt_fin); 3900 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3901 rv = READ_RRBYTr(unit, port, &rrbyt_fin); 3902 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3903 rv = READ_RPKTr(unit, port, &rpkt_fin); 3904 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3905 rv = READ_TPKTr(unit, port, &tpkt_fin); 3906 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3907 3908 cli_out("recovery runt rrbyt_fin %lld rrpkt_fin %lld rpkt_fin %lld tpkt_fin %lld\r\n",rrbyt_fin, rrpkt_fin, 3909 rpkt_fin, tpkt_fin); 3910 3911 if((rrpkt_fin - rrpkt) != 1 ) { 3912 cli_out("IBOD recovery loopback runt counter is not right!!!! \r\n"); 3913 } 3914 #endif 3915 /* Update ibod_ctrl rrbyt and rrpkt */ 3916 rv = READ_RRPKTr(unit, port, &rrpkt); 3917 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3918 rv = READ_RRBYTr(unit, port, &rrbyt); 3919 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3920 3921 ibod_ctrl->rrpkt[port] = rrpkt; 3922 ibod_ctrl->rrbyt[port] = rrbyt; 3923 3924 /* Restore original pause/pfc/llfc configuration */ 3925 rv = soc_mac_x.md_pause_set(unit, port, pause_tx, pause_rx); 3926 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3927 3928 rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, pfc_rx); 3929 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3930 rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,llfc_rx); 3931 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3932 3933 /* clear and check IBOD FIFO full interrupt */ 3934 rv = READ_IBOD_INTR_STATUSr(unit, &rval); 3935 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3936 ibod_data_fifo_full_intr_status = soc_reg_field_get(unit, IBOD_INTR_STATUSr, 3937 rval, cl_data_fifo_full_err_intr_status); 3938 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 3939 &rval, cl_data_fifo_full_err_intr_status, 1); 3940 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 3941 &rval, cl_ctrl_fifo_full_err_intr_status, 1); 3942 rv = WRITE_IBOD_INTR_STATUSr(unit, rval); 3943 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3944 #ifdef IBOD_DEBUG 3945 READ_IBOD_INTR_STATUSr(unit, &rval); 3946 ibod_data_fifo_full_intr_status = soc_reg_field_get(unit, IBOD_INTR_STATUSr, 3947 rval, cl_data_fifo_full_err_intr_status); 3948 cli_out("after set. %s IBOD intr data fifo full err status %d\r\n", 3949 (cl_data_fifo_full_err_intr_status == CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf)?"CL0":"CL1", ibod_data_fifo_full_intr_status); 3950 #endif 3951 /* Restore port operation */ 3952 rv = _bcm_tr3_ibod_port_resume(unit, port, port_dis_untag, port_dis_tag); 3953 if (BCM_FAILURE(rv)) { 3954 soc_ibod_recovery_in_progress_set(unit, 0); 3955 _bcm_esw_ibod_recovery_port_unlock(unit, port); 3956 PORT_UNLOCK(unit); 3957 rv1 = soc_link_fwd_set(unit, mask1_restore); 3958 LOG_ERROR(BSL_LS_BCM_PORT, 3959 (BSL_META_U(unit, 3960 "IBOD Port[%d] Resume failed[%d %d]\n\r"), port, rv, rv1)); 3961 return rv; 3962 } 3963 3964 soc_ibod_recovery_in_progress_set(unit, 0); 3965 _bcm_esw_ibod_recovery_port_unlock(unit, port); 3966 PORT_UNLOCK(unit); /* End port atomic */ 3967 3968 rv = soc_link_fwd_set(unit, mask1_restore); 3969 if (BCM_FAILURE(rv)) { 3970 LOG_ERROR(BSL_LS_BCM_PORT, 3971 (BSL_META_U(unit, 3972 "IBOD link fwd set failed[%d] on port:%d\n\r"), rv, port)); 3973 return rv; 3974 } 3975 3976 return rv; 3977 } 3978 3979 STATIC int 3980 _bcm_tr3_ibod_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, bcm_port_t port) 3981 { 3982 int rv = BCM_E_NONE; 3983 int need_recovery = FALSE; 3984 sal_usecs_t time1, time2; 3985 3986 /* Check and update runt counter */ 3987 rv = _bcm_tr3_ibod_port_check(ibod_ctrl, port, &need_recovery); 3988 if (BCM_FAILURE(rv)) { 3989 LOG_ERROR(BSL_LS_BCM_PORT, 3990 (BSL_META_U(ibod_ctrl->unit, 3991 "Ibod recovery port %d check error\n"), port)); 3992 return rv; 3993 } 3994 else if(need_recovery == FALSE){ 3995 return BCM_E_NONE; 3996 } 3997 3998 time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 3999 4000 rv = _bcm_tr3_ibod_sync_recovery_port(ibod_ctrl, 0, port); 4001 4002 time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 4003 ibod_ctrl->event_count++; 4004 ibod_ctrl->port_avg_time = (ibod_ctrl->port_avg_time*(ibod_ctrl->event_count-1) + 4005 time2 - time1) /ibod_ctrl->event_count; 4006 4007 return rv; 4008 } 4009 4010 STATIC void 4011 _bcm_tr3_ibod_sync_recovery_thread(void *context) 4012 { 4013 _port_ibod_ctrl_t *ibod_ctrl = context; 4014 int port, rv, unit = ibod_ctrl->unit; 4015 4016 LOG_VERBOSE(BSL_LS_BCM_PORT, 4017 (BSL_META_U(unit, 4018 "IBOD recovery started on unit %d\n"), ibod_ctrl->unit)); 4019 4020 ibod_ctrl->running = 1; 4021 while (!ibod_ctrl->stop) { 4022 if (!SOC_IS_DONE_INIT(unit)) { 4023 (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval); 4024 continue; 4025 } 4026 /* Need to wait until warmboot recovery of ibod related stats is done */ 4027 if (!SOC_WARM_BOOT(unit)) { 4028 PBMP_CL_ITER(unit, port) { 4029 if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) { 4030 continue; 4031 } 4032 ibod_ctrl->start_time = sal_time_usecs(); 4033 if(!IS_C_PORT(unit, port)) { 4034 (void)_bcm_tr3_ibod_recovery_port(ibod_ctrl, port); 4035 } 4036 4037 rv = _bcm_tr3_txerr_recovery_port(ibod_ctrl, port); 4038 if (SOC_FAILURE(rv)) { 4039 LOG_ERROR(BSL_LS_BCM_PORT, 4040 (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,port))); 4041 } 4042 } 4043 4044 rv = _bcm_tr3_mmu_check_and_recovery(ibod_ctrl); 4045 if (SOC_FAILURE(rv)) { 4046 LOG_ERROR(BSL_LS_BCM_PORT, 4047 (BSL_META_U(unit, "\n Error in MMU recovery "))); 4048 } 4049 4050 } 4051 (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval); 4052 } 4053 ibod_ctrl->running = 0; 4054 } 4055 4056 STATIC void 4057 _bcm_hx4_ibod_sync_recovery_thread(void *context) 4058 { 4059 _port_ibod_ctrl_t *ibod_ctrl = context; 4060 int port, flex_port=0, rv, unit = ibod_ctrl->unit; 4061 uint64 rrpkt, rrbyt; 4062 uint64 rrpkt_diff, rrbyt_diff; 4063 uint32 rval,rval_1,port_mode=0,encap_mode=0,next_flex_port=0; 4064 int port_group_iter; 4065 int flex_port_arr[3]={-1,-1,-1},cou,i; 4066 uint64 rval64; 4067 int runt_threshold; 4068 uint64 txerr; 4069 int egress_drain_timeout, port_drain_timeout, port_recovery_failed_flag; 4070 4071 LOG_VERBOSE(BSL_LS_BCM_PORT, 4072 (BSL_META_U(unit, "IBOD recovery started on unit %d\n"),ibod_ctrl->unit)); 4073 4074 cou=0; 4075 PBMP_ITER(PBMP_XW_ALL(unit), port) { 4076 (void) READ_PORT_MODE_REGr(unit, port, &rval); 4077 port_mode=soc_reg_field_get(unit, PORT_MODE_REGr, 4078 rval, XPORT0_CORE_PORT_MODEf); 4079 4080 if (port_mode != 3) { 4081 /* coverity[overrun-call : FALSE] */ 4082 if (_bcm_tr3_port_is_control_port(unit, port)) { 4083 flex_port_arr[cou] = port; 4084 cou++; 4085 } 4086 } 4087 rv = READ_RRPKTr(unit, port, &rrpkt); 4088 if (SOC_FAILURE(rv)) { 4089 LOG_ERROR(BSL_LS_BCM_PORT, 4090 (BSL_META_U(unit, "Error in reading RRPKTr %d\n"),ibod_ctrl->unit)); 4091 4092 } 4093 4094 rv = READ_RRBYTr(unit, port, &rrbyt); 4095 if (SOC_FAILURE(rv)) { 4096 LOG_ERROR(BSL_LS_BCM_PORT, 4097 (BSL_META_U(unit, "Error in reading RRBYTr %d\n"),ibod_ctrl->unit)); 4098 } 4099 /* coverity[overrun-local : FALSE] */ 4100 ibod_ctrl->rrpkt[port] = rrpkt; 4101 /* coverity[overrun-local : FALSE] */ 4102 ibod_ctrl->rrbyt[port] = rrbyt; 4103 } 4104 4105 ibod_ctrl->running = 1; 4106 while (!ibod_ctrl->stop) { 4107 if (!SOC_IS_DONE_INIT(unit)) { 4108 (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval); 4109 continue; 4110 } 4111 /* Need to wait until warmboot recovery of ibod related stats is done */ 4112 if (!SOC_WARM_BOOT(unit)) { 4113 next_flex_port=0; 4114 port_group_iter=-1; 4115 PBMP_ITER(PBMP_XW_ALL(unit), port) { 4116 if (!((IS_HG_PORT(unit,port)) || (IS_XE_PORT(unit,port)))) { 4117 continue; 4118 } 4119 /* coverity[overrun-local : FALSE] */ 4120 if (SOC_INFO(unit).port_speed_max[port] >= 100000) { 4121 continue; 4122 } 4123 ibod_ctrl->start_time = sal_time_usecs(); 4124 /* coverity[overrun-call : FALSE] */ 4125 if (_bcm_tr3_port_is_control_port(unit, port)) { 4126 flex_port=port; 4127 next_flex_port=0; 4128 port_group_iter++; 4129 } 4130 if (next_flex_port) { 4131 continue; 4132 } 4133 (void) READ_PORT_EHG_RX_CONTROLr(unit, port, &rval); 4134 encap_mode = soc_reg_field_get(unit, PORT_EHG_RX_CONTROLr, 4135 rval, MODEf); 4136 if (encap_mode) { 4137 (void) READ_PORT_EHG_RX_PKT_DROPr(unit, port, &rval); 4138 if (rval) { 4139 LOG_VERBOSE(BSL_LS_BCM_PORT, 4140 (BSL_META_U(unit, "\n WAR Trigerred by Embedded HG RX control"))); 4141 rv = BCM_E_NONE; 4142 /* coverity[overrun-call : FALSE] */ 4143 rv = _bcm_hx4_ibod_sync_recovery_port(ibod_ctrl, port_group_iter, flex_port); 4144 if (SOC_FAILURE(rv)) { 4145 PORT_UNLOCK(unit); 4146 /* Release the ibod recovery port group lock */ 4147 /* coverity[overrun-call : FALSE] */ 4148 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port); 4149 _bcm_esw_lc_unlock(unit); 4150 LOG_ERROR(BSL_LS_BCM_PORT, 4151 (BSL_META_U(unit, "\n Error in RRPKT WAR %s"),SOC_PORT_NAME(unit,flex_port))); 4152 } 4153 soc_event_generate(unit, SOC_SWITCH_EVENT_RUNT_DETECT, port, 0, 0); 4154 for (i=0; i<3; i++) { 4155 if ((flex_port_arr[i] != flex_port) && (flex_port_arr[i] != -1)) { 4156 rv = BCM_E_NONE; 4157 rv = _bcm_hx4_txerr_recovery_port(ibod_ctrl, flex_port_arr[i]); 4158 if (SOC_FAILURE(rv)) { 4159 PORT_UNLOCK(unit); 4160 /* Release the ibod recovery port group lock */ 4161 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port_arr[i]); 4162 _bcm_esw_lc_unlock(unit); 4163 LOG_ERROR(BSL_LS_BCM_PORT, 4164 (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,flex_port_arr[i]))); 4165 } 4166 } 4167 } 4168 next_flex_port=1; 4169 continue; 4170 } 4171 } 4172 4173 rv = READ_TERRr(unit, port, &txerr); 4174 if (SOC_FAILURE(rv)) { 4175 continue; 4176 } 4177 /* coverity[overrun-local : FALSE] */ 4178 if (COMPILER_64_NE(txerr, ibod_ctrl->txerrpkt[port])) { 4179 /* coverity[overrun-call : FALSE] */ 4180 rv = _bcm_hx4_txerr_recovery_port(ibod_ctrl, flex_port); 4181 if (SOC_FAILURE(rv)) { 4182 PORT_UNLOCK(unit); 4183 /* Release the ibod recovery port group lock */ 4184 /* coverity[overrun-call : FALSE] */ 4185 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port); 4186 _bcm_esw_lc_unlock(unit); 4187 LOG_ERROR(BSL_LS_BCM_PORT, 4188 (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,flex_port))); 4189 } 4190 } 4191 /* Check if any new runt packet logged in RRPKT */ 4192 rv = READ_RRPKTr(unit, port, &rrpkt); 4193 if (SOC_FAILURE(rv)) { 4194 continue; 4195 } 4196 if (COMPILER_64_EQ(rrpkt, ibod_ctrl->rrpkt[port])) { 4197 continue; 4198 } 4199 /* Check total runt byte count */ 4200 rv = READ_RRBYTr(unit, port, &rrbyt); 4201 if (SOC_FAILURE(rv)) { 4202 continue; 4203 } 4204 4205 /* It's very unlikely both packet and byte counters wrap around 4206 * and stop at 0, the code assume this is from clear counter */ 4207 if (COMPILER_64_IS_ZERO(rrpkt) && COMPILER_64_IS_ZERO(rrbyt)) { 4208 ibod_ctrl->rrpkt[port] = rrpkt; 4209 ibod_ctrl->rrbyt[port] = rrbyt; 4210 continue; 4211 } 4212 4213 rrpkt_diff = rrpkt; 4214 rrbyt_diff = rrbyt; 4215 COMPILER_64_SUB_64(rrpkt_diff, ibod_ctrl->rrpkt[port]); 4216 COMPILER_64_SUB_64(rrbyt_diff, ibod_ctrl->rrbyt[port]); 4217 ibod_ctrl->rrpkt[port] = rrpkt; 4218 ibod_ctrl->rrbyt[port] = rrbyt; 4219 4220 rv = READ_XMAC_RX_CTRLr(unit,port, &rval64); 4221 if (SOC_FAILURE(rv)) { 4222 continue; 4223 } 4224 runt_threshold = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval64, RUNT_THRESHOLDf); 4225 4226 /* Recovery is needed only for packet size between 33 and 76 */ 4227 if (COMPILER_64_HI(rrpkt_diff) == 0 && 4228 COMPILER_64_LO(rrpkt_diff) == 1) { 4229 if (COMPILER_64_LO(rrbyt_diff) >= runt_threshold) { 4230 continue; 4231 } 4232 } 4233 if (COMPILER_64_HI(rrbyt_diff) == 0 && 4234 COMPILER_64_LO(rrbyt_diff) <= 32) { 4235 continue; 4236 } 4237 LOG_VERBOSE(BSL_LS_BCM_PORT, 4238 (BSL_META_U(unit,"\n WAR Trigerred by RRPKT/RRBYT"))); 4239 /* coverity[overrun-call : FALSE] */ 4240 rv = _bcm_hx4_ibod_sync_recovery_port(ibod_ctrl, port_group_iter, flex_port); 4241 if (SOC_FAILURE(rv)) { 4242 PORT_UNLOCK(unit); 4243 /* Release the ibod recovery port group lock */ 4244 /* coverity[overrun-call : FALSE] */ 4245 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port); 4246 _bcm_esw_lc_unlock(unit); 4247 LOG_ERROR(BSL_LS_BCM_PORT, 4248 (BSL_META_U(unit, "\n Error in RRPKT WAR %s"),SOC_PORT_NAME(unit,flex_port))); 4249 } 4250 soc_event_generate(unit, SOC_SWITCH_EVENT_RUNT_DETECT, port, 0, 0); 4251 for (i=0; i<3; i++) { 4252 if ((flex_port_arr[i] != flex_port) && (flex_port_arr[i] != -1)) { 4253 rv = BCM_E_NONE; 4254 rv = _bcm_hx4_txerr_recovery_port(ibod_ctrl, flex_port_arr[i]); 4255 if (SOC_FAILURE(rv)) { 4256 PORT_UNLOCK(unit); 4257 /* Release the ibod recovery port group lock */ 4258 /* coverity[overrun-call : FALSE] */ 4259 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port_arr[i]); 4260 _bcm_esw_lc_unlock(unit); 4261 LOG_ERROR(BSL_LS_BCM_PORT, 4262 (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,flex_port_arr[i]))); 4263 } 4264 } 4265 } 4266 next_flex_port=1; 4267 } 4268 4269 _soc_egress_drain_timeout_flag_get(unit, &egress_drain_timeout); 4270 port_drain_timeout = ibod_ctrl->drain_timeout_flag; 4271 port_recovery_failed_flag = ibod_ctrl->port_recovery_failed_flag; 4272 4273 rv = READ_PQEFIFOOVERFLOW0r(unit, &rval); 4274 if (SOC_FAILURE(rv)) { 4275 LOG_ERROR(BSL_LS_BCM_PORT, 4276 (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW0"))); 4277 } 4278 rv = READ_PQEFIFOOVERFLOW1r(unit, &rval_1); 4279 if (SOC_FAILURE(rv)) { 4280 LOG_ERROR(BSL_LS_BCM_PORT, 4281 (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW1"))); 4282 } 4283 4284 if ((rval != 0) || (rval_1 != 0) || (egress_drain_timeout != 0) || (port_drain_timeout != 0) 4285 || port_recovery_failed_flag || (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER)) { 4286 rv = _bcm_tr3_mmu_recovery(ibod_ctrl); 4287 ibod_ctrl->drain_timeout_flag = 0; 4288 _soc_egress_drain_timeout_flag_set(unit, 0); 4289 if (port_drain_timeout) { 4290 ibod_ctrl->drain_timeout_flag = 0; 4291 ibod_ctrl->drain_timeout_count++; 4292 } 4293 if (egress_drain_timeout) { 4294 _soc_egress_drain_timeout_flag_set(unit, 0); 4295 ibod_ctrl->egress_drain_timeout_count++; 4296 } 4297 if (port_recovery_failed_flag) { 4298 ibod_ctrl->port_recovery_failed_flag = 0; 4299 ibod_ctrl->port_recovery_failed_count++; 4300 } 4301 if (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER) { 4302 _ibod_debug_flag &= (~_PORT_IBOD_FLAG_MMU_TRIGGER); 4303 } 4304 if (SOC_FAILURE(rv)) { 4305 LOG_ERROR(BSL_LS_BCM_PORT, 4306 (BSL_META_U(unit, "\n Error in MMU recovery "))); 4307 } 4308 } 4309 } 4310 (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval); 4311 } 4312 ibod_ctrl->running = 0; 4313 } 4314 4315 int _bcm_esw_ibod_syn_port_down (int unit, int port) 4316 { 4317 _port_ibod_ctrl_t *ibod_ctrl = _port_ibod_ctrl[unit]; 4318 int rv; 4319 uint64 rrpkt, rrbyt,rval64; 4320 uint64 rrpkt_diff, rrbyt_diff; 4321 int runt_threshold; 4322 uint32 port_mode, rval; 4323 4324 if (!SOC_IS_TRIUMPH3(unit) || !ibod_ctrl) { 4325 return BCM_E_NONE; 4326 } 4327 4328 if (SOC_IS_HELIX4(unit)) { 4329 if (!IS_XE_PORT(unit, port) && !IS_HG_PORT(unit, port)) { 4330 return SOC_E_NONE; 4331 } 4332 } else { 4333 if (!IS_HG_PORT(unit, port)) { 4334 return SOC_E_NONE; 4335 } 4336 } 4337 4338 if (SOC_INFO(unit).port_speed_max[port] >= 100000 || 4339 !(SOC_CONTROL(unit)->soc_flags & SOC_F_INITED)) { 4340 return SOC_E_NONE; 4341 } 4342 4343 BCM_IF_ERROR_RETURN(READ_PORT_MODE_REGr(unit, port, &rval)); 4344 port_mode=soc_reg_field_get(unit, PORT_MODE_REGr, 4345 rval, XPORT0_CORE_PORT_MODEf); 4346 4347 /* Port mode must be Dual or Qual */ 4348 if ((port_mode != 1) && (port_mode != 2)) { 4349 return SOC_E_NONE; 4350 } 4351 4352 /* Check if any new runt packet logged in RRPKT */ 4353 rv = READ_RRPKTr(unit, port, &rrpkt); 4354 if (SOC_FAILURE(rv)) { 4355 return SOC_E_NONE; 4356 } 4357 if (COMPILER_64_EQ(rrpkt, ibod_ctrl->rrpkt[port])) { 4358 return SOC_E_NONE; 4359 } 4360 /* Check total runt byte count */ 4361 rv = READ_RRBYTr(unit, port, &rrbyt); 4362 if (SOC_FAILURE(rv)) { 4363 return SOC_E_NONE; 4364 } 4365 4366 /* It's very unlikely both packet and byte counters wrap around 4367 * and stop at 0, the code assume this is from clear counter */ 4368 if (COMPILER_64_IS_ZERO(rrpkt) && COMPILER_64_IS_ZERO(rrbyt)) { 4369 ibod_ctrl->rrpkt[port] = rrpkt; 4370 ibod_ctrl->rrbyt[port] = rrbyt; 4371 return SOC_E_NONE; 4372 } 4373 4374 rrpkt_diff = rrpkt; 4375 rrbyt_diff = rrbyt; 4376 COMPILER_64_SUB_64(rrpkt_diff, ibod_ctrl->rrpkt[port]); 4377 COMPILER_64_SUB_64(rrbyt_diff, ibod_ctrl->rrbyt[port]); 4378 ibod_ctrl->rrpkt[port] = rrpkt; 4379 ibod_ctrl->rrbyt[port] = rrbyt; 4380 4381 rv = READ_XMAC_RX_CTRLr(unit,port, &rval64); 4382 if (SOC_FAILURE(rv)) { 4383 return SOC_E_NONE; 4384 } 4385 runt_threshold = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval64, RUNT_THRESHOLDf); 4386 4387 /* Recovery is needed only for packet size between 33 and 76 */ 4388 if (COMPILER_64_HI(rrpkt_diff) == 0 && 4389 COMPILER_64_LO(rrpkt_diff) == 1) { 4390 if (COMPILER_64_LO(rrbyt_diff) >= runt_threshold) { 4391 return SOC_E_NONE; 4392 } 4393 } 4394 if (COMPILER_64_HI(rrbyt_diff) == 0 && 4395 COMPILER_64_LO(rrbyt_diff) <= 32) { 4396 return SOC_E_NONE; 4397 } 4398 4399 ibod_ctrl->start_time = sal_time_usecs(); 4400 if (SOC_IS_HELIX4(unit)) { 4401 int port_group_iter, port_iter, flex_port=0; 4402 bcm_pbmp_t pbmp; 4403 4404 port_group_iter=-1; 4405 PBMP_ITER(PBMP_XW_ALL(unit), port_iter) { 4406 /* coverity[overrun-call : FALSE] */ 4407 if (!(_bcm_tr3_port_is_control_port(unit, port_iter))) { 4408 continue; 4409 } 4410 flex_port = port_iter; 4411 port_group_iter++; 4412 BCM_IF_ERROR_RETURN(bcm_esw_port_subsidiary_ports_get(unit, flex_port, &pbmp)); 4413 if (SOC_PBMP_MEMBER(pbmp, port)) { 4414 break; 4415 } 4416 } 4417 /* coverity[overrun-call : FALSE] */ 4418 rv = _bcm_hx4_ibod_sync_recovery_port(ibod_ctrl, port_group_iter, flex_port); 4419 if (SOC_FAILURE(rv)) { 4420 PORT_UNLOCK(unit); 4421 /* Release the ibod recovery port group lock */ 4422 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port); 4423 _bcm_esw_lc_unlock(unit); 4424 } 4425 } else { 4426 rv = _bcm_tr3_ibod_sync_recovery_port(ibod_ctrl, 1, port); 4427 } 4428 4429 if (SOC_FAILURE(rv)) { 4430 LOG_ERROR(BSL_LS_BCM_PORT, 4431 (BSL_META_U(unit, "\n Error in RRPKT WAR %s"), SOC_PORT_NAME(unit, port))); 4432 } 4433 return SOC_E_NONE; 4434 4435 } 4436 4437 int 4438 _bcm_esw_ibod_sync_recovery_start(int unit, sal_usecs_t interval) 4439 { 4440 int cnt; 4441 bcm_pkt_t *pkt; 4442 uint8 *buf; 4443 int buf_size = 72; 4444 uint32 rval; 4445 int rv = BCM_E_NONE; 4446 _port_ibod_ctrl_t *ibod_ctrl; 4447 4448 if (!SOC_IS_TRIUMPH3(unit)) { 4449 return BCM_E_NONE; 4450 } 4451 4452 ibod_ctrl = _port_ibod_ctrl[unit]; 4453 if (ibod_ctrl == NULL) { 4454 ibod_ctrl = sal_alloc(sizeof(_port_ibod_ctrl_t), "_port_ibod_ctrl_t"); 4455 if (ibod_ctrl == NULL) { 4456 return BCM_E_MEMORY; 4457 } 4458 sal_memset(ibod_ctrl, 0, sizeof(_port_ibod_ctrl_t)); 4459 _port_ibod_ctrl[unit] = ibod_ctrl; 4460 } 4461 4462 ibod_ctrl->interval = interval; 4463 4464 if (ibod_ctrl->interval < IBOD_SYNC_INTERVAL_MIN) { 4465 ibod_ctrl->interval = IBOD_SYNC_INTERVAL_MIN; 4466 } 4467 4468 if (ibod_ctrl->running) { 4469 return BCM_E_NONE; 4470 } 4471 4472 ibod_ctrl->unit = unit; 4473 4474 /* Setup packet field */ 4475 pkt = &ibod_ctrl->pkt; 4476 buf = soc_cm_salloc(unit, buf_size, "pkt alloc data"); 4477 if (buf == NULL) { 4478 return BCM_E_MEMORY; 4479 } 4480 BCM_PKT_ONE_BUF_SETUP(pkt, buf, buf_size); 4481 pkt->unit = unit; 4482 pkt->flags = BCM_TX_CRC_APPEND | BCM_TX_HG_READY | BCM_TX_NO_PAD | 4483 BCM_TX_LINKDOWN_TRANSMIT; 4484 pkt->opcode = BCM_PKT_OPCODE_UC; /* do not to CPU */ 4485 4486 if (ibod_ctrl->sema == NULL) { 4487 ibod_ctrl->sema = sal_sem_create("ibod recovery", sal_sem_BINARY, 0); 4488 if (ibod_ctrl->sema == NULL) { 4489 return BCM_E_MEMORY; 4490 } 4491 } 4492 4493 sal_snprintf(ibod_ctrl->taskname, sizeof (ibod_ctrl->taskname), 4494 "bcmIbodSync.%d", unit); 4495 ibod_ctrl->stop = 0; 4496 SOC_IF_ERROR_RETURN(_bcm_esw_ibod_recovery_lock_init(unit)); 4497 rv = soc_tr3_mmu_store_alloc(unit); 4498 if(BCM_FAILURE(rv)) { 4499 return rv; 4500 } 4501 soc_ibod_recovery_in_progress_set(unit, 0); 4502 _soc_egress_drain_timeout_flag_set(unit, 0); 4503 sal_memset(txerr_trigger_flag, 0, sizeof(txerr_trigger_flag)); 4504 if (SOC_IS_HELIX4(unit)) { 4505 SOC_IF_ERROR_RETURN(READ_IBOD_INTR_MASKr(unit, &rval)); 4506 soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL0_CTRL_FIFO_FULL_ERR_INTR_MASKf, 1); 4507 soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL0_DATA_FIFO_FULL_ERR_INTR_MASKf, 1); 4508 soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL1_CTRL_FIFO_FULL_ERR_INTR_MASKf, 1); 4509 soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL1_DATA_FIFO_FULL_ERR_INTR_MASKf, 1); 4510 soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL2_CTRL_FIFO_FULL_ERR_INTR_MASKf, 1); 4511 soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL2_DATA_FIFO_FULL_ERR_INTR_MASKf, 1); 4512 SOC_IF_ERROR_RETURN(WRITE_IBOD_INTR_MASKr(unit, rval)); 4513 if (sal_thread_create(ibod_ctrl->taskname, SAL_THREAD_STKSZ, 4514 soc_property_get(unit, spn_IBOD_SYNC_THREAD_PRI, 50), 4515 _bcm_hx4_ibod_sync_recovery_thread, 4516 ibod_ctrl) == SAL_THREAD_ERROR) { 4517 return BCM_E_MEMORY; 4518 } 4519 } else { 4520 if (sal_thread_create(ibod_ctrl->taskname, SAL_THREAD_STKSZ, 4521 soc_property_get(unit, spn_IBOD_SYNC_THREAD_PRI, 50), 4522 _bcm_tr3_ibod_sync_recovery_thread, 4523 ibod_ctrl) == SAL_THREAD_ERROR) { 4524 return BCM_E_MEMORY; 4525 } 4526 } 4527 cnt = 10; 4528 while (!ibod_ctrl->running && cnt--) { 4529 sal_usleep(100000); 4530 } 4531 if (!ibod_ctrl->running) { 4532 LOG_ERROR(BSL_LS_BCM_PORT, 4533 (BSL_META_U(unit, 4534 "%s: Thread did not start\n"), ibod_ctrl->taskname)); 4535 return BCM_E_TIMEOUT; 4536 } 4537 return BCM_E_NONE; 4538 } 4539 4540 int 4541 _bcm_esw_ibod_sync_recovery_stop(int unit) 4542 { 4543 int cnt; 4544 bcm_pkt_t *pkt; 4545 _port_ibod_ctrl_t *ibod_ctrl = _port_ibod_ctrl[unit]; 4546 4547 if (ibod_ctrl == NULL) { 4548 return BCM_E_NONE; 4549 } 4550 4551 ibod_ctrl->stop = 1; 4552 if (ibod_ctrl->sema != NULL) { 4553 sal_sem_give(ibod_ctrl->sema); 4554 } 4555 cnt = 10; 4556 while (ibod_ctrl->running && cnt--) { 4557 sal_usleep(100000); 4558 } 4559 if (ibod_ctrl->running) { 4560 LOG_ERROR(BSL_LS_BCM_PORT, 4561 (BSL_META_U(unit, 4562 "%s: Thread did not start\n"), ibod_ctrl->taskname)); 4563 return BCM_E_TIMEOUT; 4564 } 4565 pkt = &ibod_ctrl->pkt; 4566 if (pkt->_pkt_data.data != NULL) { 4567 soc_cm_sfree(unit, pkt->_pkt_data.data); 4568 pkt->_pkt_data.data = NULL; 4569 pkt->_pkt_data.len = 0; 4570 } 4571 if (ibod_ctrl->sema != NULL) { 4572 sal_sem_destroy(ibod_ctrl->sema); 4573 } 4574 4575 sal_free(ibod_ctrl); 4576 _port_ibod_ctrl[unit] = NULL; 4577 4578 _bcm_esw_ibod_recovery_lock_deinit(unit); 4579 4580 soc_tr3_mmu_store_free(unit); 4581 return BCM_E_NONE; 4582 } 4583 4584 int _bcm_esw_ibod_sync_recovery_running(int unit, _port_ibod_ctrl_t *ibod_ctrl) 4585 { 4586 if (_port_ibod_ctrl[unit] == NULL) { 4587 return BCM_E_FAIL; 4588 } 4589 if(ibod_ctrl != NULL) { 4590 sal_memcpy(ibod_ctrl, _port_ibod_ctrl[unit], sizeof(_port_ibod_ctrl_t)); 4591 } 4592 return BCM_E_NONE; 4593 } 4594 4595 STATIC int _bcm_tr3_xmac_fifo_check(int unit, bcm_port_t port, uint8 lu_tpo) 4596 { 4597 int rv_xmac_fifo = BCM_E_NONE; 4598 int rv = BCM_E_NONE; 4599 bcm_pkt_t *pkt = NULL; 4600 uint8 *payload; 4601 uint32 req_cnt = 0, cell_cnt = 0; 4602 uint64 rval64; 4603 int rx_enable_org = 0,speed_mode=0,port_enable; 4604 pbmp_t act_tx_pbmp, tx_pbmp; 4605 4606 COMPILER_64_ZERO(rval64); 4607 SOC_PBMP_CLEAR(act_tx_pbmp); 4608 SOC_PBMP_CLEAR(tx_pbmp); 4609 4610 /* Create test packet */ 4611 pkt = soc_cm_salloc(unit, sizeof(bcm_pkt_t), "pkt buffer"); 4612 if (pkt == NULL) { 4613 return BCM_E_FAIL; 4614 } 4615 4616 sal_memset(pkt, 0, sizeof(bcm_pkt_t)); 4617 payload = soc_cm_salloc(unit, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ, 4618 "pkt alloc data"); 4619 if (payload == NULL) { 4620 soc_cm_sfree(unit, pkt); 4621 return BCM_E_FAIL; 4622 } 4623 sal_memset(payload, 0, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ); 4624 BCM_PKT_ONE_BUF_SETUP(pkt, payload, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ); 4625 pkt->unit = unit; 4626 pkt->flags = BCM_TX_CRC_APPEND | BCM_TX_HG_READY | BCM_TX_NO_PAD | 4627 BCM_TX_LINKDOWN_TRANSMIT; 4628 pkt->call_back = NULL; 4629 4630 #ifdef BCM_PORT_DEFAULT_DISABLE 4631 port_enable = FALSE; 4632 #else 4633 port_enable = TRUE; 4634 #endif /* BCM_PORT_DEFAULT_DISABLE */ 4635 4636 if (BCM_E_NONE != 4637 (rv = MAC_ENABLE_GET(PORT(unit, port).p_mac, unit, port, &port_enable))) { 4638 goto cleanup; 4639 } 4640 /* Put the port in MAC loopback and enable it for transmit */ 4641 if (BCM_E_NONE != 4642 (rv = MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, TRUE))) { 4643 goto cleanup; 4644 } 4645 if (BCM_E_NONE != 4646 (rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE))) { 4647 goto cleanup; 4648 } 4649 /* Ensure that we are in MAC line-side loopback */ 4650 if (SOC_E_NONE != (rv = READ_XMAC_CTRLr(unit, port, &rval64))) { 4651 goto cleanup; 4652 } 4653 4654 rx_enable_org = soc_reg64_field32_get(unit, XMAC_CTRLr, rval64, RX_ENf); 4655 /* RX Disable */ 4656 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 0); 4657 /* Line local LB */ 4658 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, LINE_LOCAL_LPBKf, 1); 4659 /* Core local LB */ 4660 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, CORE_LOCAL_LPBKf, 0); 4661 if (SOC_E_NONE != (rv = WRITE_XMAC_CTRLr(unit, port, rval64))) { 4662 goto cleanup; 4663 } 4664 /* Ensure that we are back in same MAC MODE*/ 4665 if (SOC_E_NONE != (rv = READ_XMAC_MODEr(unit, port, &rval64))) { 4666 goto cleanup; 4667 } 4668 speed_mode = soc_reg64_field32_get(unit, XMAC_MODEr, rval64, SPEED_MODEf); 4669 4670 /* Stall the XMAC's transmit FIFO */ 4671 if (SOC_E_NONE != 4672 (rv = soc_reg_field32_modify(unit, XMAC_MODEr, port, SPEED_MODEf, 4))) { 4673 goto cleanup; 4674 } 4675 4676 if (SOC_E_NONE != 4677 (rv = soc_reg_field32_modify(unit, XMAC_MACSEC_CTRLr, port, 4678 MACSEC_TX_LAUNCH_ENf, 1))) { 4679 goto cleanup; 4680 } 4681 4682 /* EPC_LINK */ 4683 soc_link_mask2_get(unit, &act_tx_pbmp); 4684 SOC_PBMP_PORT_ADD(tx_pbmp, port); 4685 if (!lu_tpo) { 4686 /* Use original state and add new ports as well */ 4687 SOC_PBMP_OR(tx_pbmp, act_tx_pbmp); 4688 } 4689 if (SOC_E_NONE != (rv = soc_link_mask2_set(unit, tx_pbmp))) { 4690 goto cleanup; 4691 } 4692 /* Transmit the test packet */ 4693 BCM_PKT_TX_LEN_SET(pkt, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ); 4694 BCM_PKT_PORT_SET(pkt, port, TRUE, FALSE); 4695 rv = bcm_esw_tx(unit, pkt, NULL); 4696 if (BCM_FAILURE(rv)) { 4697 rv = BCM_E_FAIL; 4698 goto cleanup; 4699 } 4700 4701 /* Wait for a short period of time to allow 4702 the packet to reach the end of the EP */ 4703 sal_udelay(1000); 4704 4705 /* Read the request count value */ 4706 if (SOC_E_NONE != 4707 (rv = READ_PORT_TXFIFO_CELL_REQ_CNTr(unit, port, &req_cnt))) { 4708 goto cleanup; 4709 } 4710 /* Read the cell count value */ 4711 if (SOC_E_NONE != 4712 (rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port, &cell_cnt))) { 4713 goto cleanup; 4714 } 4715 LOG_VERBOSE(BSL_LS_BCM_PORT, 4716 (BSL_META_U(unit, 4717 "Check: cell_req_cnt: %d cell_cnt: %d\n"), 4718 req_cnt, cell_cnt)); 4719 /* Check to make sure that the request count is exactly zero */ 4720 if (req_cnt != 0) { 4721 rv_xmac_fifo = BCM_E_INTERNAL; 4722 goto cleanup; 4723 } 4724 4725 cleanup: 4726 /* free packet memory */ 4727 if (payload != NULL) { 4728 soc_cm_sfree(unit, payload); 4729 } 4730 if (pkt != NULL) { 4731 soc_cm_sfree(unit, pkt); 4732 } 4733 /* Clear the MAC loopback (flushes the test packet) */ 4734 if (SOC_E_NONE != MAC_LOOPBACK_SET(PORT(unit, port).p_mac, 4735 unit, port, FALSE)) { 4736 rv = BCM_E_FAIL; 4737 } 4738 /* Clear the MAC Enable Set */ 4739 if (SOC_E_NONE != MAC_ENABLE_SET(PORT(unit, port).p_mac, 4740 unit, port, FALSE)) { 4741 rv = BCM_E_FAIL; 4742 } 4743 /* Restoring the MAC Enable Set */ 4744 if (port_enable) { 4745 if (SOC_E_NONE != 4746 (rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE))) { 4747 rv = BCM_E_FAIL; 4748 } 4749 } 4750 /* Remove the MAC FIFO stall */ 4751 if (SOC_E_NONE != soc_reg_field32_modify(unit, XMAC_MODEr, port, 4752 SPEED_MODEf, speed_mode)) { 4753 rv = BCM_E_FAIL; 4754 } 4755 if (SOC_E_NONE != soc_reg_field32_modify(unit, XMAC_MACSEC_CTRLr, port, 4756 MACSEC_TX_LAUNCH_ENf, 0)) { 4757 rv = BCM_E_FAIL; 4758 } 4759 /* revert rx_enable */ 4760 if (SOC_E_NONE != soc_reg_field32_modify(unit, XMAC_CTRLr, port, RX_ENf, 4761 rx_enable_org)) { 4762 rv = BCM_E_FAIL; 4763 } 4764 /* EPC_LINK restore */ 4765 if (SOC_E_NONE != soc_link_mask2_set(unit, act_tx_pbmp)) { 4766 rv = BCM_E_FAIL; 4767 } 4768 /* Clear the counters from tx port*/ 4769 SOC_PBMP_PORT_SET(tx_pbmp, port); 4770 if (SOC_E_NONE != soc_counter_set32_by_port(unit, tx_pbmp, 0)) { 4771 rv = BCM_E_FAIL; 4772 } 4773 if (BCM_E_NONE != rv) { 4774 return rv; 4775 } else { 4776 return rv_xmac_fifo; 4777 } 4778 } 4779 4780 #define _BCM_TR3_PORT_UR_RETRY_MAX 15 4781 int _bcm_tr3_port_ur_chk(int unit, int num_ports, bcm_port_t port) 4782 { 4783 uint8 lu_tpo = 0; /* link up test port only */ 4784 int retry = _BCM_TR3_PORT_UR_RETRY_MAX; 4785 int fifo_underrun = FALSE, issue_overcome = TRUE; 4786 soc_info_t *si = &SOC_INFO(unit); 4787 int rv = BCM_E_NONE; 4788 int okay = 0; 4789 uint32 expected_cell_req_cnt, cell_req_cnt, cell_cnt; 4790 soc_block_type_t pbt; 4791 int _num_ports = (num_ports == -1) ? 4 : num_ports; 4792 int phy_port = SOC_IS_HELIX4(unit) ? 4793 _SOC_HX4_MGMT_PHY_PORT : _SOC_TR3_MGMT_PHY_PORT; 4794 4795 #ifdef BCM_TRIUMPH3_SUPPORT 4796 if (!(SOC_IS_HELIX4(unit))) { 4797 /* Skipping in for Disabled Ports */ 4798 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay)); 4799 if (!okay) { 4800 return BCM_E_NONE; 4801 } 4802 } 4803 #endif 4804 #ifdef BCM_HELIX4_SUPPORT 4805 if ( SOC_IS_HELIX4(unit) && 4806 ((_tr3_port_config_id[unit] == 463)|| 4807 (_tr3_port_config_id[unit] == 413)) && 4808 (57 == si->port_l2p_mapping[port] || 61 == si->port_l2p_mapping[port])) 4809 { 4810 switch (_num_ports) { 4811 case 1: expected_cell_req_cnt = 8; break; 4812 case 2: expected_cell_req_cnt = 4; break; 4813 case 4: expected_cell_req_cnt = 4; break; 4814 default: expected_cell_req_cnt = 4; 4815 } 4816 }else 4817 #endif 4818 { 4819 switch (_num_ports) { 4820 case 1: expected_cell_req_cnt = 16; break; 4821 case 2: expected_cell_req_cnt = 8; break; 4822 case 4: expected_cell_req_cnt = 4; break; 4823 default: expected_cell_req_cnt = 4; 4824 } 4825 } 4826 if (-1 == port) { 4827 lu_tpo = 1; 4828 port = si->port_p2l_mapping[phy_port]; 4829 } else { 4830 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 4831 } 4832 LOG_VERBOSE(BSL_LS_BCM_PORT, 4833 (BSL_META_U(unit, 4834 "UR test: %s\n"), SOC_PORT_NAME(unit, port))); 4835 4836 /* nothing to do if port is not a valid port */ 4837 if (!SOC_PORT_VALID(unit, port)) { 4838 LOG_VERBOSE(BSL_LS_BCM_PORT, (BSL_META_U(unit, 4839 "Port %s is not valid - skipping WAR\n"), 4840 SOC_PORT_NAME(unit, port))); 4841 return BCM_E_NONE; 4842 } 4843 4844 pbt = SOC_BLOCK_TYPE(unit, SOC_PORT_BLOCK(unit, phy_port)); 4845 while (retry--) { 4846 rv = _bcm_tr3_xmac_fifo_check(unit, port, lu_tpo); 4847 if (BCM_E_INTERNAL == rv) { 4848 if (num_ports != -1 && (_num_ports > 1)) { 4849 /* This is a case of flex port transform to dual or quad lane 4850 mode and one of the newly created ports is failing */ 4851 return BCM_E_PORT; 4852 } 4853 fifo_underrun = TRUE; 4854 issue_overcome = FALSE; 4855 4856 if (SOC_E_NONE != (rv = _soc_tr3_ur_port_reset(unit, _num_ports, port, pbt))) { 4857 rv = BCM_E_INTERNAL; 4858 goto cleanup; 4859 } 4860 if ((rv = _bcm_port_mac_init(unit, port, &okay)) != BCM_E_NONE) { 4861 goto cleanup; 4862 } 4863 /* Read cell req count value to see if reset cleared it */ 4864 if ((rv = READ_PORT_TXFIFO_CELL_REQ_CNTr( 4865 unit, port, &cell_req_cnt)) != SOC_E_NONE) { 4866 goto cleanup; 4867 } 4868 /* Read cell count value again to see if reset cleared it */ 4869 if ((rv = READ_PORT_TXFIFO_CELL_CNTr( 4870 unit, port, &cell_cnt))!= SOC_E_NONE) { 4871 goto cleanup; 4872 } 4873 LOG_VERBOSE(BSL_LS_BCM_PORT, 4874 (BSL_META_U(unit, 4875 "After reset: cell_req_cnt: " 4876 "%d cell_cnt: %d\n"), cell_req_cnt, cell_cnt)); 4877 /* Check to make sure that the request count is exactly zero */ 4878 if ((cell_req_cnt != expected_cell_req_cnt) || (cell_cnt != 0)) { 4879 rv = BCM_E_INTERNAL; 4880 goto cleanup; 4881 } 4882 } else { 4883 if (BCM_E_NONE != rv) { 4884 goto cleanup; 4885 } 4886 if (TRUE == fifo_underrun) { 4887 issue_overcome = TRUE; 4888 } 4889 /* either underrun didn't occur or war fixed it */ 4890 break; 4891 } 4892 }/* while */ 4893 4894 if (fifo_underrun) { 4895 rv = BCM_E_INTERNAL; 4896 if (issue_overcome) { 4897 rv = BCM_E_NONE; 4898 LOG_VERBOSE(BSL_LS_BCM_PORT, 4899 (BSL_META_U(unit, 4900 "Port %s recovered from XMAC FIFO underrun\n"), 4901 SOC_PORT_NAME(unit, port))); 4902 } else { 4903 LOG_ERROR(BSL_LS_BCM_PORT, 4904 (BSL_META_U(unit, 4905 "Port %s did not recover from XMAC FIFO underrun\n"), 4906 SOC_PORT_NAME(unit, port))); 4907 } 4908 } 4909 4910 cleanup: 4911 if (BCM_E_NONE != rv) { 4912 LOG_ERROR(BSL_LS_BCM_PORT, 4913 (BSL_META_U(unit, 4914 "Port %s, failed while checking/recovering " 4915 "XL port underrun\n"), 4916 SOC_PORT_NAME(unit, port))); 4917 } 4918 4919 return rv; 4920 } 4921 #endif /* BCM_TRIUMPH3_SUPPORT */ 4922 4923 4924 /* 4925 * Function: 4926 * _bcm_esw_port_gport_validate 4927 * Description: 4928 * Helper funtion to validate port/gport parameter 4929 * Parameters: 4930 * unit - (IN) BCM device number 4931 * port_in - (IN) Port / Gport to validate 4932 * port_out - (OUT) Port number if valid. 4933 * Return Value: 4934 * BCM_E_NONE - Port OK 4935 * BCM_E_INIT - Not initialized 4936 * BCM_E_PORT - Port Invalid 4937 */ 4938 int 4939 _bcm_esw_port_gport_validate(int unit, bcm_port_t port_in, bcm_port_t *port_out) 4940 { 4941 if (bcm_port_info[unit] == NULL) { 4942 return BCM_E_INIT; 4943 } 4944 4945 #if defined (BCM_HGPROXY_COE_SUPPORT) 4946 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 4947 soc_feature(unit, soc_feature_channelized_switching)) && 4948 BCM_GPORT_IS_SUBPORT_PORT(port_in)) { 4949 return _bcm_xgs5_subport_gport_validate(unit, 4950 port_in, 4951 port_out); 4952 } else 4953 #endif /* defined (BCM_HGPROXY_COE_SUPPORT) */ 4954 4955 #ifdef BCM_KATANA2_SUPPORT 4956 if (soc_feature(unit, soc_feature_linkphy_coe) || 4957 soc_feature(unit, soc_feature_subtag_coe)) { 4958 return _bcm_kt2_port_gport_validate(unit, port_in, port_out); 4959 } 4960 #endif 4961 4962 if (BCM_GPORT_IS_SET(port_in)) { 4963 BCM_IF_ERROR_RETURN( 4964 bcm_esw_port_local_get(unit, port_in, port_out)); 4965 } else if (SOC_PORT_VALID(unit, port_in)) { 4966 *port_out = port_in; 4967 } else { 4968 return BCM_E_PORT; 4969 } 4970 4971 return BCM_E_NONE; 4972 } 4973 4974 /* 4975 * Function: 4976 * _bcm_port_link_delay_update 4977 * Description: 4978 * Helper funtion: Update link delay based on configured values 4979 * Parameters: 4980 * unit - (IN) BCM device number 4981 * port - (IN) Port number 4982 * speed - (IN) New speed 4983 * Return Value: 4984 * BCM_E_XXX 4985 */ 4986 int 4987 _bcm_esw_port_link_delay_update(int unit, bcm_port_t port, int speed) 4988 { 4989 int32 link_delay; 4990 int mac_rx_latency = 0; 4991 _bcm_port_info_t *port_info; 4992 int rv; 4993 4994 _bcm_port_info_access(unit, port, &port_info); 4995 rv = MAC_CONTROL_GET(port_info->p_mac, unit, port, 4996 SOC_MAC_CONTROL_EXPECTED_RX_LATENCY, 4997 &mac_rx_latency); 4998 if (rv != BCM_E_NONE) { 4999 LOG_INFO(BSL_LS_BCM_PORT, (BSL_META( 5000 "Port updating LINK_DELAY, but MAC doesn't have a default value\n") 5001 )); 5002 } 5003 5004 link_delay = (int32)soc_property_port_get(unit, port, spn_LINK_DELAY(speed), mac_rx_latency); 5005 /* use bcmPortControl1588P2PDelay control field as an offset from this value */ 5006 link_delay += PORT(unit, port).link_delay_offset; 5007 5008 if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) { 5009 BCM_IF_ERROR_RETURN( 5010 soc_reg_field32_modify(unit, EGR_1588_LINK_DELAYr, 5011 port, LINK_DELAYf, (uint32)link_delay)); 5012 } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) { 5013 BCM_IF_ERROR_RETURN( 5014 soc_reg_above_64_field32_modify(unit, EGR_1588_LINK_DELAY_64r, 5015 port, 0, LINK_DELAYf, (uint32)link_delay)); 5016 } else { 5017 /* No LINK_DELAY register, so no-op */ 5018 } 5019 5020 return BCM_E_NONE; 5021 } 5022 5023 STATIC int 5024 _bcm_esw_port_link_delay_recover(int unit, bcm_port_t port, int speed) 5025 { 5026 uint32 link_delay = 0; 5027 uint32 mac_rx_latency = 0; 5028 5029 mac_rx_latency = soc_property_port_get(unit, port, spn_LINK_DELAY(speed), mac_rx_latency); 5030 5031 if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) { 5032 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, EGR_1588_LINK_DELAYr, port, LINK_DELAYf, &link_delay)); 5033 } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) { 5034 SOC_IF_ERROR_RETURN(soc_reg_above_64_field32_read(unit, EGR_1588_LINK_DELAY_64r, 5035 port, 0, LINK_DELAYf, &link_delay)); 5036 } 5037 5038 PORT(unit, port).link_delay_offset = link_delay - mac_rx_latency; 5039 5040 return BCM_E_NONE; 5041 } 5042 5043 /* 5044 * Function: 5045 * _bcm_port_info_get 5046 * Description: 5047 * Helper funtion 5048 * Parameters: 5049 * unit - (IN) BCM device number 5050 * port - (IN) Port number 5051 * pinfo - (OUT) Port info. 5052 * Return Value: 5053 * BCM_E_XXX 5054 */ 5055 int 5056 _bcm_port_info_get(int unit, bcm_port_t port, _bcm_port_info_t **pinfo) 5057 { 5058 /* Input parameters check. */ 5059 if (NULL == pinfo) { 5060 return (BCM_E_PARAM); 5061 } 5062 5063 PORT_INIT(unit); 5064 5065 *pinfo = &PORT(unit, port); 5066 return (BCM_E_NONE); 5067 } 5068 5069 /* 5070 * Function: 5071 * _bcm_esw_iport_tab_set 5072 * Description: 5073 * Set field in either IPORT_TABLE or the special CPU Higig entry in 5074 * the PORT_TAB. 5075 * Parameters: 5076 * unit - Device number 5077 * port - Port number 5078 * field - Field name within PORT_TAB table entry 5079 * value - new field value 5080 * Return Value: 5081 * BCM_E_NONE 5082 * BCM_E_XXX - an error occurred accessing PORT_TAB table. 5083 */ 5084 int 5085 _bcm_esw_iport_tab_set(int unit, bcm_port_t port, 5086 soc_field_t field, int value) 5087 5088 { 5089 port_tab_entry_t pent; 5090 soc_mem_t mem; 5091 int rv, index, cpu_hg_index, cur_val; 5092 5093 cpu_hg_index = SOC_IS_KATANA2(unit) ? 5094 SOC_INFO(unit).cpu_hg_pp_port_index : 5095 SOC_INFO(unit).cpu_hg_index; 5096 5097 if (SOC_MEM_IS_VALID(unit, IPORT_TABLEm)) { 5098 mem = IPORT_TABLEm; 5099 index = SOC_PORT_MOD_OFFSET(unit, port); 5100 } else if (IS_CPU_PORT(unit, port) && cpu_hg_index != -1) { 5101 mem = PORT_TABm; 5102 index = cpu_hg_index; 5103 } else { 5104 return BCM_E_NONE; 5105 } 5106 5107 if (!SOC_MEM_FIELD_VALID(unit, mem, field)) { 5108 return (BCM_E_UNAVAIL); 5109 } 5110 5111 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &pent); 5112 if (BCM_SUCCESS(rv)) { 5113 cur_val = soc_mem_field32_get(unit, mem, &pent, field); 5114 if (value != cur_val) { 5115 soc_mem_field32_set(unit, mem, &pent, field, value); 5116 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &pent); 5117 } 5118 } 5119 return rv; 5120 } 5121 5122 /* 5123 * Function: 5124 * _bcm_phy_cb_xlate_port 5125 * Description: 5126 * Provides port translation for API call-backs 5127 * Parameter: 5128 * unit -- unit number 5129 * port -- port number to be translated 5130 * Returns: 5131 * SOC_E_xxx 5132 */ 5133 STATIC int 5134 _bcm_phy_cb_xlate_port(int unit, int *port) 5135 { 5136 BCM_API_XLATE_PORT_P2A(unit, port); 5137 5138 return BCM_E_NONE; 5139 } 5140 5141 /* 5142 * Function: 5143 * _bcm_port_autoneg_advert_remote_get 5144 * Purpose: 5145 * Main part of bcm_port_advert_get_remote 5146 */ 5147 5148 STATIC int 5149 _bcm_port_autoneg_advert_remote_get(int unit, bcm_port_t port, 5150 bcm_port_ability_t *ability_mask) 5151 { 5152 int an, an_done; 5153 5154 if(bcm_common_oamp_port_enable_get(unit, port)) { 5155 LOG_ERROR(BSL_LS_BCM_PORT, 5156 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 5157 port)); 5158 return BCM_E_PARAM; 5159 } 5160 5161 SOC_IF_ERROR_RETURN 5162 (soc_phyctrl_auto_negotiate_get(unit, port, 5163 &an, &an_done)); 5164 5165 if (an && an_done) { 5166 SOC_IF_ERROR_RETURN 5167 (soc_phyctrl_ability_remote_get(unit, port, ability_mask)); 5168 } 5169 5170 return BCM_E_NONE; 5171 } 5172 5173 /* 5174 * Function: 5175 * _bcm_port_ability_local_get 5176 * Purpose: 5177 * Main part of bcm_port_ability_local_get 5178 */ 5179 5180 STATIC int 5181 _bcm_port_ability_local_get(int unit, bcm_port_t port, 5182 bcm_port_ability_t *ability_mask) 5183 { 5184 soc_port_ability_t mac_ability, phy_ability; 5185 soc_pa_encap_t encap_ability; 5186 #ifdef BCM_TRIUMPH3_SUPPORT 5187 int lanes; 5188 #endif 5189 #ifdef INCLUDE_MACSEC 5190 phy_ctrl_t *ext_pc; 5191 ext_pc = EXT_PHY_SW_STATE(unit, port); 5192 #endif /* INCLUDE_MACSEC */ 5193 sal_memset(&phy_ability, 0, sizeof(soc_port_ability_t)); 5194 sal_memset(&mac_ability, 0, sizeof(soc_port_ability_t)); 5195 5196 if(bcm_common_oamp_port_enable_get(unit, port)) { 5197 LOG_ERROR(BSL_LS_BCM_PORT, 5198 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 5199 port)); 5200 return BCM_E_PARAM; 5201 } 5202 5203 SOC_IF_ERROR_RETURN 5204 (soc_phyctrl_ability_local_get(unit, port, &phy_ability)); 5205 5206 if (!(IS_TDM_PORT(unit, port))) { 5207 SOC_IF_ERROR_RETURN 5208 (MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit, 5209 port, &mac_ability)); 5210 } 5211 5212 /* Combine MAC and PHY abilities */ 5213 5214 #ifdef INCLUDE_MACSEC 5215 /* 5216 MACSEC phys have their own MAC. If macsec is enabled, 5217 phy's MAC is used for MAC operation on the line side. 5218 Check added to use half duplex ability of phy/MAC. 5219 */ 5220 if((NULL != ext_pc) && ext_pc->macsec_enable) { 5221 ability_mask->speed_half_duplex = phy_ability.speed_half_duplex; 5222 } else 5223 #endif /* INCLUDE_MACSEC */ 5224 { 5225 ability_mask->speed_half_duplex = 5226 mac_ability.speed_half_duplex & phy_ability.speed_half_duplex; 5227 } 5228 ability_mask->speed_full_duplex = 5229 mac_ability.speed_full_duplex & phy_ability.speed_full_duplex; 5230 ability_mask->pause = mac_ability.pause & phy_ability.pause; 5231 if (phy_ability.interface == 0) { 5232 ability_mask->interface = mac_ability.interface; 5233 } else { 5234 ability_mask->interface = phy_ability.interface; 5235 } 5236 ability_mask->medium = phy_ability.medium; 5237 ability_mask->channel = phy_ability.channel; 5238 ability_mask->fec = phy_ability.fec; 5239 /* mac_ability.eee without phy_ability.eee makes no sense */ 5240 ability_mask->eee = phy_ability.eee; 5241 ability_mask->loopback = mac_ability.loopback | phy_ability.loopback | 5242 BCM_PORT_ABILITY_LB_NONE; 5243 ability_mask->flags = mac_ability.flags | phy_ability.flags; 5244 5245 /* Get port encapsulation ability */ 5246 encap_ability = mac_ability.encap; 5247 5248 if ((soc_feature(unit, soc_feature_embedded_higig)) 5249 && IS_E_PORT(unit, port)) { 5250 encap_ability |= BCM_PA_ENCAP_HIGIG2_L2; 5251 encap_ability |= BCM_PA_ENCAP_HIGIG2_IP_GRE; 5252 } 5253 5254 #if defined(BCM_RAPTOR_SUPPORT) 5255 if ((SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit)) && 5256 IS_S_PORT(unit, port)) { 5257 encap_ability |= BCM_PA_ENCAP_HIGIG2; 5258 /* should be HiGig-Lite, not Higig2 */ 5259 encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE; 5260 } 5261 #endif 5262 5263 #ifdef BCM_TRIUMPH2_SUPPORT 5264 if (IS_HL_PORT(unit, port) && (SOC_IS_APOLLO(unit) || 5265 SOC_IS_TRIUMPH2(unit) || 5266 SOC_IS_VALKYRIE2(unit))) { 5267 /* HiGig-Lite port */ 5268 encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE; 5269 } 5270 #endif 5271 5272 if (IS_HL_PORT(unit, port) && 5273 (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) || 5274 SOC_IS_KATANA2(unit) )) { 5275 encap_ability |= BCM_PA_ENCAP_HIGIG2; 5276 /* should be HiGig-Lite, not Higig2 */ 5277 encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE; 5278 } 5279 5280 #ifdef BCM_GREYHOUND_SUPPORT 5281 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 5282 SOC_IS_GREYHOUND2(unit)) { 5283 if (IS_HL_PORT(unit, port)) { 5284 encap_ability |= BCM_PA_ENCAP_HIGIG2; 5285 encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE; 5286 } else if (IS_HG_PORT(unit, port)) { 5287 encap_ability |= BCM_PA_ENCAP_HIGIG; 5288 } 5289 } 5290 #endif /* BCM_GREYHOUND_SUPPORT */ 5291 5292 #if defined (BCM_HURRICANE_SUPPORT) 5293 if (IS_XQ_PORT(unit, port) && SOC_IS_HURRICANEX(unit) && (CMDEV(unit).dev.rev_id == BCM56142_A0_REV_ID) ) { 5294 ability_mask->speed_half_duplex &= ~(BCM_PORT_ABILITY_100MB); 5295 ability_mask->speed_full_duplex &= ~(BCM_PORT_ABILITY_100MB); 5296 } 5297 #endif 5298 5299 #if defined (BCM_TRIUMPH3_SUPPORT) 5300 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) && 5301 (_tr3_port_config_id[unit] == 112 || _tr3_port_config_id[unit] == 12) && 5302 (port == 54 || port == 55)) { 5303 if (IS_XE_PORT(unit, port)) { 5304 BCM_IF_ERROR_RETURN(_bcm_tr3_port_lanes_get(unit, port, &lanes)); 5305 if (lanes == 1) { 5306 /* In one lanes mode, only support 100Mbps&1000Mbps */ 5307 ability_mask->speed_full_duplex = (BCM_PORT_ABILITY_100MB|BCM_PORT_ABILITY_1000MB); 5308 } else if (lanes == 4) { 5309 /* In four lanes mode, remove the 100Mbps&1000Mbps ability */ 5310 ability_mask->speed_full_duplex &= ~(BCM_PORT_ABILITY_100MB|BCM_PORT_ABILITY_1000MB); 5311 } 5312 } 5313 } 5314 #endif 5315 5316 #ifdef BCM_SABER2_SUPPORT 5317 if (SOC_IS_SABER2(unit)) { 5318 if (IS_XE_PORT(unit, port) && IS_MXQ_PORT(unit, port)) { 5319 /* XE port, only support 10Gbps */ 5320 ability_mask->speed_full_duplex = (BCM_PORT_ABILITY_10GB); 5321 } 5322 } 5323 #endif 5324 5325 ability_mask->encap = encap_ability; 5326 return BCM_E_NONE; 5327 } 5328 5329 int 5330 bcm_esw_port_lport_prof_src_check(int unit, int port_type, int *src_tbl_is_stm) 5331 { 5332 int rv = BCM_E_NONE; 5333 #if defined(CANCUN_SUPPORT) 5334 if (soc_feature(unit, soc_feature_cancun)) { 5335 if (src_tbl_is_stm != NULL) { 5336 switch (port_type) { 5337 case _BCM_ESW_PT_COE: 5338 case _BCM_ESW_PT_HGPROXY: 5339 *src_tbl_is_stm = 1; 5340 break; 5341 default: 5342 *src_tbl_is_stm = 0; 5343 break; 5344 } 5345 } 5346 } 5347 #endif 5348 return rv; 5349 } 5350 5351 #ifdef BCM_TRIUMPH2_SUPPORT 5352 /* 5353 * Function: 5354 * bcm_esw_port_lport_profile_recover 5355 * Description: 5356 * Recovers the LPORT profile reference count in the 5357 * Source Trunk Map Table. 5358 * Parameters: 5359 * unit - (IN) Device number 5360 * Return Value: 5361 * BCM_E_NONE 5362 * BCM_E_XXX 5363 * Note: 5364 * - Called when LPORT profile is supported. 5365 */ 5366 STATIC int 5367 bcm_esw_port_lport_profile_recover(int unit) 5368 { 5369 int rv = BCM_E_NONE; 5370 #ifdef BCM_TOMAHAWK3_SUPPORT 5371 int entries_per_pipe; 5372 #endif 5373 #if defined(BCM_TRX_SUPPORT) 5374 int i, m; 5375 uint32 lport_index; 5376 soc_mem_t src_mem[2] = {SOURCE_TRUNK_MAP_TABLEm, INVALIDm}; 5377 int entry_count; 5378 int table_sz; 5379 uint32 *src_table; 5380 uint32 *src_entry; 5381 uint32 rtag7_index; 5382 lport_tab_entry_t lport_entry; 5383 5384 /* Make sure port module is initialized. */ 5385 PORT_INIT(unit); 5386 5387 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 5388 src_mem[1] = ING_DEVICE_PORTm; 5389 } 5390 5391 for (m = 0; m < 2; m++) { 5392 if (src_mem[m] == INVALIDm) { 5393 continue; 5394 } 5395 5396 /* Alloc DMA memory */ 5397 entry_count = soc_mem_index_count(unit, src_mem[m]); 5398 table_sz = SOC_MEM_TABLE_BYTES(unit, src_mem[m]); 5399 src_table = soc_cm_salloc(unit, table_sz, "LPORT index recover\n"); 5400 if (src_table == NULL) { 5401 return BCM_E_MEMORY; 5402 } 5403 sal_memset(src_table, 0, table_sz); 5404 5405 /* DMA Read */ 5406 rv = soc_mem_read_range(unit, src_mem[m], MEM_BLOCK_ANY, 5407 soc_mem_index_min(unit, src_mem[m]), 5408 soc_mem_index_max(unit, src_mem[m]), 5409 src_table); 5410 /* Recover LPORT index reference count from Source Trunk Map table */ 5411 if (BCM_SUCCESS(rv)) { 5412 for (i = 0; i < entry_count; i++) { 5413 src_entry = 5414 soc_mem_table_idx_to_pointer(unit, src_mem[m], void *, 5415 src_table, i); 5416 lport_index = soc_mem_field32_get(unit, src_mem[m], src_entry, 5417 LPORT_PROFILE_IDXf); 5418 5419 if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) { 5420 rv = _bcm_lport_ind_profile_mem_reference(unit, lport_index, 1); 5421 if (BCM_FAILURE(rv)) { 5422 break; 5423 } 5424 rv = READ_LPORT_TABm(unit, MEM_BLOCK_ANY, lport_index, &lport_entry); 5425 if (BCM_FAILURE(rv)) { 5426 break; 5427 } 5428 rtag7_index = soc_LPORT_TABm_field32_get( 5429 unit, &lport_entry, RTAG7_PORT_PROFILE_INDEXf); 5430 rv = _bcm_rtag7_ind_profile_mem_reference(unit, rtag7_index, 1); 5431 5432 } else { 5433 #ifdef BCM_TOMAHAWK3_SUPPORT 5434 if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 5435 entries_per_pipe = SOC_MEM_SIZE(unit, LPORT_TABm); 5436 rv = _bcm_lport_profile_mem_reference_unique(unit, lport_index, 5437 1, i/entries_per_pipe); 5438 } else 5439 #endif 5440 { 5441 rv = _bcm_lport_profile_mem_reference(unit, lport_index, 1); 5442 } 5443 } 5444 if (BCM_FAILURE(rv)) { 5445 break; 5446 } 5447 } 5448 } 5449 5450 soc_cm_sfree(unit, src_table); 5451 if (BCM_FAILURE(rv)) { 5452 break; 5453 } 5454 } 5455 5456 #endif /* BCM_TRX_SUPPORT */ 5457 5458 return rv; 5459 } 5460 5461 STATIC int 5462 _bcm_td3_port_egr_lport_profile_recover(int unit) 5463 { 5464 int rv = BCM_E_NONE; 5465 int i, m; 5466 uint32 egr_lport_index; 5467 soc_mem_t ep_mem[2] = {EGR_GPP_ATTRIBUTESm, INVALIDm}; 5468 int ega_num_entries; 5469 int ega_table_size; 5470 void *ep_tbl; 5471 void *ep_ent; 5472 5473 /* Make sure port module is initialized. */ 5474 PORT_INIT(unit); 5475 5476 if (SOC_IS_TRIDENT3X(unit)) { 5477 ep_mem[1] = EGR_PORTm; 5478 } 5479 5480 /* Alloc DMA memory */ 5481 for (m = 0; m < 2; m++) { 5482 if (ep_mem[m] == INVALIDm) { 5483 continue; 5484 } 5485 ega_num_entries = soc_mem_index_count(unit, ep_mem[m]); 5486 ega_table_size = soc_mem_entry_words(unit, ep_mem[m]) * 4 * ega_num_entries; 5487 ep_tbl = soc_cm_salloc(unit, ega_table_size, 5488 "EGA for EGR LPORT index recover\n"); 5489 if (ep_tbl == NULL) { 5490 return BCM_E_MEMORY; 5491 } 5492 sal_memset(ep_tbl, 0, ega_table_size); 5493 5494 /* DMA Read */ 5495 rv = soc_mem_read_range(unit, ep_mem[m], MEM_BLOCK_ANY, 5496 soc_mem_index_min(unit, ep_mem[m]), 5497 soc_mem_index_max(unit, ep_mem[m]), 5498 ep_tbl); 5499 /* Recover EGR LPORT index reference count from EGR GPP Attributes table */ 5500 if (SOC_SUCCESS(rv)) { 5501 for (i = 0; i < ega_num_entries; i++) { 5502 ep_ent = 5503 soc_mem_table_idx_to_pointer(unit, ep_mem[m], 5504 void *, ep_tbl, i); 5505 egr_lport_index = 5506 soc_mem_field32_get(unit, ep_mem[m], ep_ent, EGR_LPORT_PROFILE_IDXf); 5507 rv = _bcm_egr_lport_profile_mem_reference(unit, egr_lport_index, 1); 5508 if (BCM_FAILURE(rv)) { 5509 break; 5510 } 5511 } 5512 } 5513 5514 soc_cm_sfree(unit, ep_tbl); 5515 5516 if (BCM_FAILURE(rv)) { 5517 break; 5518 } 5519 } 5520 5521 return rv; 5522 } 5523 5524 /* 5525 * Function: 5526 * bcm_esw_port_egr_lport_profile_recover 5527 * Description: 5528 * Recovers the EGR LPORT profile reference count in the 5529 * EGR GPP Attributes Table. 5530 * Parameters: 5531 * unit - (IN) Device number 5532 * Return Value: 5533 * BCM_E_NONE 5534 * BCM_E_XXX 5535 * Note: 5536 * - Called when EGR LPORT profile is supported. 5537 */ 5538 STATIC int 5539 bcm_esw_port_egr_lport_profile_recover(int unit) 5540 { 5541 int rv = BCM_E_NONE; 5542 int i; 5543 uint32 egr_lport_index; 5544 soc_mem_t ega_mem; 5545 int ega_num_entries; 5546 int ega_table_size; 5547 egr_gpp_attributes_entry_t *ega_table; 5548 egr_gpp_attributes_entry_t *ega_entry; 5549 5550 /* Make sure port module is initialized. */ 5551 PORT_INIT(unit); 5552 5553 if (SOC_IS_TRIDENT3X(unit)) { 5554 return _bcm_td3_port_egr_lport_profile_recover(unit); 5555 } 5556 5557 /* Alloc DMA memory */ 5558 ega_mem = EGR_GPP_ATTRIBUTESm; 5559 ega_num_entries = soc_mem_index_count(unit, ega_mem); 5560 ega_table_size = sizeof(egr_gpp_attributes_entry_t ) * ega_num_entries; 5561 ega_table = soc_cm_salloc(unit, ega_table_size, 5562 "EGA for EGR LPORT index recover\n"); 5563 if (ega_table == NULL) { 5564 return BCM_E_MEMORY; 5565 } 5566 sal_memset(ega_table, 0, ega_table_size); 5567 5568 /* DMA Read */ 5569 rv = soc_mem_read_range(unit, ega_mem, MEM_BLOCK_ANY, 5570 soc_mem_index_min(unit, ega_mem), 5571 soc_mem_index_max(unit, ega_mem), 5572 ega_table); 5573 5574 /* Recover EGR LPORT index reference count from EGR GPP Attributes table */ 5575 if (SOC_SUCCESS(rv)) { 5576 for (i = 0; i < ega_num_entries; i++) { 5577 ega_entry = 5578 soc_mem_table_idx_to_pointer(unit, ega_mem, 5579 egr_gpp_attributes_entry_t *, 5580 ega_table, i); 5581 egr_lport_index = 5582 soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, ega_entry, 5583 EGR_LPORT_PROFILE_IDXf); 5584 rv = _bcm_egr_lport_profile_mem_reference(unit, egr_lport_index, 1); 5585 if (BCM_FAILURE(rv)) { 5586 break; 5587 } 5588 } 5589 } 5590 5591 soc_cm_sfree(unit, ega_table); 5592 5593 return rv; 5594 } 5595 #endif /* BCM_TRIUMPH2_SUPPORT */ 5596 5597 int 5598 bcm_esw_port_egr_lport_prof_src_get(int unit, 5599 bcm_module_t modid, bcm_port_t port, int *src_tbl_is_gpp) 5600 { 5601 int rv = BCM_E_NONE; 5602 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT) 5603 bcm_xflow_macsec_port_info_t port_info; 5604 port_info.enable = 0; 5605 #endif 5606 5607 #if defined(CANCUN_SUPPORT) 5608 bcm_gport_t gport; 5609 5610 if (soc_feature(unit, soc_feature_cancun)) { 5611 soc_mem_t pfs_mem = EGR_PKT_FLOW_SELECT_TCAMm; 5612 5613 gport = _bcm_esw_port_gport_get_from_modport(unit, modid, port); 5614 /* COE flows use the port attrs from the EGR_GPP_ATTRIBUTES 5615 table, rest all flows use the EGR_PORT table */ 5616 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) { 5617 *src_tbl_is_gpp = 1; 5618 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT) 5619 } else if (SOC_IS_HURRICANE4(unit) && soc_feature(unit, soc_feature_xflow_macsec) && 5620 (BCM_E_NONE == bcm_common_xflow_macsec_port_info_get(unit, port, &port_info)) && 5621 (port_info.enable == 1)) { 5622 *src_tbl_is_gpp = 1; 5623 #endif 5624 } else if (SOC_MEM_IS_VALID(unit, pfs_mem)) { 5625 *src_tbl_is_gpp = 0; 5626 } 5627 } 5628 #endif 5629 5630 return rv; 5631 } 5632 5633 #if defined(BCM_TRX_SUPPORT) 5634 /* 5635 * Function: 5636 * bcm_esw_port_separate_lport_rtag7_profile_fields_set 5637 * Description: 5638 * Sets the fields in the LPORT Profile Table and updates 5639 * the corresponding reference index in the Source Trunk Map Table. 5640 * Parameters: 5641 * unit - (IN) Device number 5642 * modid - (IN) Module number for port 5643 * port - (IN) Port number (NON gport) 5644 * table_id - (IN) Index of table to modify, LPORT or RTAG7 5645 * field_count - (IN) Number of fields to modify 5646 * fields - (IN) Array of fields to modify 5647 * values - (IN) Array of new field values 5648 * Return Value: 5649 * BCM_E_NONE 5650 * BCM_E_XXX 5651 * Note: 5652 * - Assumes: lock, 5653 * valid bcm module id and port number, 5654 * valid table id, 5655 * valid HW fields. 5656 * - Called when LPORT profile is supported. 5657 * - Helper routine for bcm_esw_port_lport_fields_set(); 5658 * callers should be calling bcm_esw_port_lport_fields_set() instead. 5659 */ 5660 STATIC int 5661 bcm_esw_port_separate_lport_rtag7_profile_fields_set(int unit, int port_type, 5662 bcm_module_t modid, bcm_port_t port, 5663 int table_id, int field_count, 5664 soc_field_t *fields, uint32 *values) 5665 { 5666 int i, rv; 5667 int src_index; 5668 uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS]; 5669 lport_tab_entry_t lport_entry; 5670 rtag7_port_based_hash_entry_t rtag7_entry; 5671 uint32 lport_index, rtag7_index, old_lport_index, old_rtag7_index = 0; 5672 soc_mem_t mem; 5673 void *entries[2], *entry; 5674 5675 int src_tbl_is_stm = 1; 5676 soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm; 5677 5678 /* Make sure port module is initialized. */ 5679 PORT_INIT(unit); 5680 5681 BCM_IF_ERROR_RETURN 5682 (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm)); 5683 if (!src_tbl_is_stm) { 5684 src_mem = ING_DEVICE_PORTm; 5685 } 5686 5687 soc_mem_lock(unit, src_mem); 5688 5689 if (src_tbl_is_stm) { 5690 rv = _bcm_esw_src_mod_port_table_index_get(unit, modid, port, 5691 &src_index); 5692 if (BCM_FAILURE(rv)) { 5693 soc_mem_unlock(unit, src_mem); 5694 return rv; 5695 } 5696 } else { 5697 src_index = port; 5698 } 5699 5700 rv = soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent); 5701 if (BCM_FAILURE(rv)) { 5702 soc_mem_unlock(unit, src_mem); 5703 return rv; 5704 } 5705 5706 old_lport_index = 5707 soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf); 5708 5709 if (table_id == LPORT_PROFILE_RTAG7_TAB) { 5710 5711 /* Get the associated LPORT entry */ 5712 rv = READ_LPORT_TABm(unit, MEM_BLOCK_ANY, old_lport_index, 5713 &lport_entry); 5714 if(BCM_FAILURE(rv)) { 5715 soc_mem_unlock(unit, src_mem); 5716 return rv; 5717 } 5718 5719 /* Get the current RTAG7 index from there */ 5720 old_rtag7_index = 5721 soc_LPORT_TABm_field32_get(unit, &lport_entry, 5722 RTAG7_PORT_PROFILE_INDEXf); 5723 } 5724 5725 if (table_id == LPORT_PROFILE_LPORT_TAB) { 5726 entries[0] = &lport_entry; 5727 rv = _bcm_lport_ind_profile_entry_get(unit, old_lport_index, 5728 1, entries); 5729 } else { 5730 entries[0] = &rtag7_entry; 5731 rv = _bcm_rtag7_ind_profile_entry_get(unit, old_rtag7_index, 5732 1, entries); 5733 } 5734 5735 if(BCM_FAILURE(rv)) { 5736 soc_mem_unlock(unit, src_mem); 5737 return rv; 5738 } 5739 5740 /* Update fields */ 5741 entry = entries[0]; 5742 if (table_id == LPORT_PROFILE_LPORT_TAB) { 5743 mem = LPORT_TABm; 5744 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 5745 mem = RTAG7_PORT_BASED_HASHm; 5746 } else { 5747 soc_mem_unlock(unit, src_mem); 5748 return BCM_E_INTERNAL; 5749 } 5750 5751 for (i = 0; i < field_count; i++) { 5752 soc_mem_field32_set(unit, mem, entry, fields[i], values[i]); 5753 } 5754 5755 /* Note that when 'soc_feature_separate_ing_lport_rtag7_profiling' is in 5756 effect, the LPORT and RTAG7 tables are profiled separately, due to which 5757 we will be making separate calls and not a generic single call like 5758 earlier */ 5759 if (table_id == LPORT_PROFILE_LPORT_TAB) { 5760 5761 #ifdef BCM_MONTEREY_SUPPORT 5762 if (SOC_IS_MONTEREY(unit)) { 5763 soc_mem_field32_set(unit, mem, entry, MISC_PORT_PROFILE_INDEXf, port); 5764 } 5765 #endif 5766 5767 rv = _bcm_lport_ind_profile_entry_add(unit, entries, 1, &lport_index); 5768 5769 } else { 5770 rv = _bcm_rtag7_ind_profile_entry_add(unit, entries, 1, &rtag7_index); 5771 } 5772 5773 if(BCM_FAILURE(rv)) { 5774 soc_mem_unlock(unit, src_mem); 5775 return rv; 5776 } 5777 5778 if (table_id == LPORT_PROFILE_LPORT_TAB) { 5779 /* Update Source Table LPORT profile index */ 5780 soc_mem_field32_set(unit, src_mem, src_ent, LPORT_PROFILE_IDXf, 5781 lport_index); 5782 rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL, src_index, src_ent); 5783 } else { 5784 /* Write to the LPORT table here */ 5785 soc_LPORT_TABm_field32_set(unit, &lport_entry, RTAG7_PORT_PROFILE_INDEXf, 5786 rtag7_index); 5787 if (SOC_IS_TRIDENT3X(unit)) { 5788 entries[0] = &lport_entry; 5789 rv = _bcm_lport_ind_profile_entry_add(unit, entries, 1, &lport_index); 5790 5791 if(BCM_FAILURE(rv)) { 5792 soc_mem_unlock(unit, src_mem); 5793 return rv; 5794 } 5795 /* Update Source Table LPORT profile index */ 5796 soc_mem_field32_set(unit, src_mem, src_ent, LPORT_PROFILE_IDXf, 5797 lport_index); 5798 rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL, 5799 src_index, src_ent); 5800 } else { 5801 rv = WRITE_LPORT_TABm(unit, MEM_BLOCK_ANY, old_lport_index, &lport_entry); 5802 } 5803 } 5804 5805 soc_mem_unlock(unit, src_mem); 5806 if(BCM_FAILURE(rv)) { 5807 return rv; 5808 } 5809 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT) 5810 if (SOC_IS_HURRICANE4(unit) && 5811 (port_type == _BCM_ESW_PT_MACSEC_PORT)) { 5812 /* Also update STM LPORT profile index */ 5813 src_mem = SOURCE_TRUNK_MAP_TABLEm; 5814 soc_mem_lock(unit, src_mem); 5815 rv = _bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index); 5816 if (BCM_FAILURE(rv)) { 5817 soc_mem_unlock(unit, src_mem); 5818 return rv; 5819 } 5820 rv = soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent); 5821 if (BCM_FAILURE(rv)) { 5822 soc_mem_unlock(unit, src_mem); 5823 return rv; 5824 } 5825 if (old_lport_index != lport_index) { 5826 soc_mem_field32_set(unit, src_mem, src_ent, 5827 LPORT_PROFILE_IDXf, lport_index); 5828 rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL, 5829 src_index, src_ent); 5830 } 5831 soc_mem_unlock(unit, src_mem); 5832 if (BCM_FAILURE(rv)) { 5833 return rv; 5834 } 5835 } 5836 #endif 5837 5838 /* 5839 * Entry must be 'deleted' because the mem profile 'add' routine 5840 * always increments count even though the same entry is used. 5841 */ 5842 if (table_id == LPORT_PROFILE_LPORT_TAB) { 5843 BCM_IF_ERROR_RETURN 5844 (_bcm_lport_ind_profile_entry_delete(unit, old_lport_index)); 5845 5846 } else { 5847 if (SOC_IS_TRIDENT3X(unit)) { 5848 BCM_IF_ERROR_RETURN 5849 (_bcm_lport_ind_profile_entry_delete(unit, old_lport_index)); 5850 } 5851 BCM_IF_ERROR_RETURN 5852 (_bcm_rtag7_ind_profile_entry_delete(unit, old_rtag7_index)); 5853 } 5854 5855 return BCM_E_NONE; 5856 } 5857 #endif /* BCM_TRX_SUPPORT */ 5858 5859 /* 5860 * Function: 5861 * bcm_esw_port_lport_profile_fields_set 5862 * Description: 5863 * Sets the fields in the LPORT Profile Table and updates 5864 * the corresponding reference index in the Source Trunk Map Table. 5865 * Parameters: 5866 * unit - (IN) Device number 5867 * modid - (IN) Module number for port 5868 * port - (IN) Port number (NON gport) 5869 * table_id - (IN) Index of table to modify, LPORT or RTAG7 5870 * field_count - (IN) Number of fields to modify 5871 * fields - (IN) Array of fields to modify 5872 * values - (IN) Array of new field values 5873 * Return Value: 5874 * BCM_E_NONE 5875 * BCM_E_XXX 5876 * Note: 5877 * - Assumes: lock, 5878 * valid bcm module id and port number, 5879 * valid table id, 5880 * valid HW fields. 5881 * - Called when LPORT profile is supported. 5882 * - Helper routine for bcm_esw_port_lport_fields_set(); 5883 * callers should be calling bcm_esw_port_lport_fields_set() instead. 5884 */ 5885 STATIC int 5886 bcm_esw_port_lport_profile_fields_set(int unit, int port_type, 5887 bcm_module_t modid, bcm_port_t port, 5888 int table_id, int field_count, 5889 soc_field_t *fields, uint32 *values) 5890 { 5891 #if defined(BCM_TRX_SUPPORT) 5892 int i; 5893 int src_index; 5894 uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS]; 5895 int src_tbl_is_stm = 1; 5896 soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm; 5897 lport_tab_entry_t lport_entry; 5898 rtag7_port_based_hash_entry_t rtag7_entry; 5899 uint32 lport_index, old_lport_index; 5900 void *entries[2]; 5901 soc_mem_t mem; 5902 void *entry; 5903 int rv; 5904 int pipe = 0; 5905 int num_entries_per_pipe = 0; 5906 5907 if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) { 5908 return bcm_esw_port_separate_lport_rtag7_profile_fields_set(unit, 5909 port_type, modid, port, table_id, field_count, 5910 fields, values); 5911 } 5912 5913 /* Make sure port module is initialized. */ 5914 PORT_INIT(unit); 5915 5916 BCM_IF_ERROR_RETURN 5917 (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm)); 5918 #if defined(CANCUN_SUPPORT) 5919 if (soc_feature(unit, soc_feature_cancun) && src_tbl_is_stm == 0) { 5920 src_mem = ING_DEVICE_PORTm; 5921 } 5922 #endif 5923 5924 soc_mem_lock(unit, src_mem); 5925 5926 /* Get LPORT profile index Source table */ 5927 if (src_tbl_is_stm) { 5928 rv = _bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index); 5929 if (BCM_FAILURE(rv)) { 5930 soc_mem_unlock(unit, src_mem); 5931 return rv; 5932 } 5933 } else { 5934 src_index = port; 5935 } 5936 5937 rv = soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent); 5938 if (BCM_FAILURE(rv)) { 5939 soc_mem_unlock(unit, src_mem); 5940 return rv; 5941 } 5942 5943 old_lport_index = 5944 soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf); 5945 5946 /* Get LPORT profile entry */ 5947 entries[0] = &lport_entry; 5948 entries[1] = &rtag7_entry; 5949 5950 /* Tomahawk 3 split this memory into a per pipe unique access, 5951 * so it is indexed in SOURCE_TRUNK_MAP on a per pipe basis */ 5952 if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 5953 pipe = SOC_INFO(unit).port_pipe[src_index]; 5954 mem = SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)[pipe]; 5955 num_entries_per_pipe = SOC_MEM_SIZE(unit, mem); 5956 5957 /* the profile cache is stored in one large logical table (all the pipes 5958 * put together), so we need to index into the pipe being used so that 5959 * we can access the index of that one big logical table */ 5960 old_lport_index += pipe*num_entries_per_pipe; 5961 } 5962 5963 rv = _bcm_lport_profile_entry_get(unit, old_lport_index, 1, entries); 5964 if (BCM_FAILURE(rv)) { 5965 soc_mem_unlock(unit, src_mem); 5966 return rv; 5967 } 5968 5969 /* Update fields */ 5970 if (table_id == LPORT_PROFILE_LPORT_TAB) { 5971 mem = LPORT_TABm; 5972 entry = entries[0]; 5973 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 5974 mem = RTAG7_PORT_BASED_HASHm; 5975 entry = entries[1]; 5976 } else { 5977 soc_mem_unlock(unit, src_mem); 5978 return BCM_E_INTERNAL; 5979 } 5980 5981 for (i = 0; i < field_count; i++) { 5982 soc_mem_field32_set(unit, mem, entry, fields[i], values[i]); 5983 } 5984 5985 /* Tomahawk 3 split this memory into a per pipe unique access, 5986 * so it must be handled differently */ 5987 if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 5988 /* Restore the old_lport_index to its per pipe index because the call 5989 * below to entry_add_unique will get its lport_index based on a per 5990 * pipe index and they will be compared. */ 5991 old_lport_index -= pipe*num_entries_per_pipe; 5992 5993 rv = _bcm_lport_profile_entry_add_unique(unit, entries, 1, pipe, &lport_index); 5994 } else { 5995 rv = _bcm_lport_profile_entry_add(unit, entries, 1, &lport_index); 5996 } 5997 if(BCM_FAILURE(rv)) { 5998 soc_mem_unlock(unit, src_mem); 5999 return rv; 6000 } 6001 6002 /* Update STM LPORT profile index */ 6003 if (old_lport_index != lport_index) { 6004 soc_mem_field32_set(unit, src_mem, src_ent, 6005 LPORT_PROFILE_IDXf, lport_index); 6006 rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL, 6007 src_index, src_ent); 6008 } 6009 6010 soc_mem_unlock(unit, src_mem); 6011 if (BCM_FAILURE(rv)) { 6012 return rv; 6013 } 6014 /* 6015 * Entry must be 'deleted' because the mem profile 'add' routine 6016 * always increments count even though the same entry is used. 6017 */ 6018 if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 6019 BCM_IF_ERROR_RETURN 6020 (_bcm_lport_profile_entry_delete_unique(unit, old_lport_index, pipe)); 6021 } else { 6022 BCM_IF_ERROR_RETURN 6023 (_bcm_lport_profile_entry_delete(unit, old_lport_index)); 6024 } 6025 6026 return BCM_E_NONE; 6027 #else 6028 return BCM_E_UNAVAIL; 6029 #endif /* BCM_TRX_SUPPORT */ 6030 } 6031 6032 /* 6033 * Function: 6034 * bcm_esw_port_egr_lport_profile_fields_set 6035 * Description: 6036 * Sets the fields in the EGR_LPORT Profile Table and updates 6037 * the corresponding reference index in the Source Trunk Map Table. 6038 * Parameters: 6039 * unit - (IN) Device number 6040 * modid - (IN) Module number for port 6041 * port - (IN) Port number (NON gport) 6042 * mem - (IN) Table to modify 6043 * field_count - (IN) Number of fields to modify 6044 * fields - (IN) Array of fields to modify 6045 * values - (IN) Array of new field values 6046 * Return Value: 6047 * BCM_E_NONE 6048 * BCM_E_XXX 6049 * Note: 6050 * - Assumes: lock, 6051 * valid bcm module id and port number, 6052 * valid table id, 6053 * valid HW fields. 6054 * - Called when EGR_LPORT profile is supported. 6055 * - Helper routine for bcm_esw_port_egr_lport_fields_set(); 6056 * callers should be calling bcm_esw_port_egr_lport_fields_set() instead. 6057 */ 6058 STATIC int 6059 bcm_esw_port_egr_lport_profile_fields_set(int unit, 6060 bcm_module_t modid, bcm_port_t port, 6061 soc_mem_t mem, int field_count, 6062 soc_field_t *fields, uint32 *values) 6063 { 6064 #if defined(BCM_TRX_SUPPORT) 6065 int i, index; 6066 int egr_gpp_index = 0; 6067 egr_gpp_attributes_entry_t egr_gpp_entry; 6068 egr_lport_profile_entry_t egr_lport_entry; 6069 egr_vlan_control_1_entry_t egr_vlan_control_1; 6070 egr_vlan_control_2_entry_t egr_vlan_control_2; 6071 egr_vlan_control_3_entry_t egr_vlan_control_3; 6072 egr_ipmc_cfg2_entry_t egr_ipmc_cfg2; 6073 egr_mtu_entry_t egr_mtu; 6074 egr_port_1_entry_t egr_port_1; 6075 egr_counter_control_entry_t egr_counter_control; 6076 egr_shaping_control_entry_t egr_shaping_control; 6077 egr_port_entry_t egr_port; 6078 uint32 egr_lport_index, old_egr_lport_index; 6079 void *entries[_BCM_EGR_LPROF_MEM_COUNT]; 6080 void *entry; 6081 int use_gpp_index = 1; 6082 6083 /* Make sure port module is initialized. */ 6084 PORT_INIT(unit); 6085 6086 if (mem == EGR_GPP_ATTRIBUTESm) { 6087 BCM_IF_ERROR_RETURN 6088 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 6089 &egr_gpp_index)); 6090 BCM_IF_ERROR_RETURN 6091 (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6092 egr_gpp_index, &egr_gpp_entry)); 6093 for (i = 0; i < field_count; i++) { 6094 soc_mem_field32_set(unit, EGR_GPP_ATTRIBUTESm, 6095 &egr_gpp_entry, fields[i], values[i]); 6096 } 6097 BCM_IF_ERROR_RETURN 6098 (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ALL, 6099 egr_gpp_index, &egr_gpp_entry)); 6100 6101 return BCM_E_NONE; 6102 } 6103 6104 BCM_IF_ERROR_RETURN( 6105 bcm_esw_port_egr_lport_prof_src_get(unit, modid, port, &use_gpp_index)); 6106 6107 if (use_gpp_index) { 6108 /* Get LPORT profile index Source Trunk Map table */ 6109 BCM_IF_ERROR_RETURN 6110 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 6111 &egr_gpp_index)); 6112 BCM_IF_ERROR_RETURN 6113 (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6114 egr_gpp_index, &egr_gpp_entry)); 6115 old_egr_lport_index = 6116 soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_entry, 6117 EGR_LPORT_PROFILE_IDXf); 6118 } else { 6119 BCM_IF_ERROR_RETURN 6120 (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &egr_port)); 6121 old_egr_lport_index = 6122 soc_mem_field32_get(unit, EGR_PORTm, &egr_port, 6123 EGR_LPORT_PROFILE_IDXf); 6124 } 6125 6126 /* Get LPORT profile entry */ 6127 index = 0; 6128 if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) { 6129 entries[index++] = &egr_lport_entry; 6130 } 6131 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) { 6132 entries[index++] = &egr_vlan_control_1; 6133 } 6134 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) { 6135 entries[index++] = &egr_vlan_control_2; 6136 } 6137 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) { 6138 entries[index++] = &egr_vlan_control_3; 6139 } 6140 if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) { 6141 entries[index++] = &egr_ipmc_cfg2; 6142 } 6143 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 6144 entries[index++] = &egr_mtu; 6145 } 6146 if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) { 6147 entries[index++] = &egr_port_1; 6148 } 6149 if (soc_feature(unit, soc_feature_egr_all_profile) == 0) { 6150 if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) { 6151 entries[index++] = &egr_counter_control; 6152 } 6153 if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) { 6154 entries[index++] = &egr_shaping_control; 6155 } 6156 } 6157 6158 BCM_IF_ERROR_RETURN 6159 (_bcm_egr_lport_profile_entry_get(unit, old_egr_lport_index, 1, entries)); 6160 6161 BCM_IF_ERROR_RETURN 6162 (_bcm_egr_lport_profile_mem_index_get(unit, mem, &index)); 6163 entry = entries[index]; 6164 /* Update fields */ 6165 for (i = 0; i < field_count; i++) { 6166 soc_mem_field32_set(unit, mem, entry, fields[i], values[i]); 6167 } 6168 6169 BCM_IF_ERROR_RETURN 6170 (_bcm_egr_lport_profile_entry_add(unit, entries, 1, &egr_lport_index)); 6171 6172 /* Update STM LPORT profile index */ 6173 if (use_gpp_index) { 6174 soc_EGR_GPP_ATTRIBUTESm_field32_set(unit, &egr_gpp_entry, 6175 EGR_LPORT_PROFILE_IDXf, 6176 egr_lport_index); 6177 BCM_IF_ERROR_RETURN 6178 (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6179 egr_gpp_index, &egr_gpp_entry)); 6180 } else { 6181 soc_mem_field32_set(unit, EGR_PORTm, &egr_port, 6182 EGR_LPORT_PROFILE_IDXf, egr_lport_index); 6183 BCM_IF_ERROR_RETURN 6184 (WRITE_EGR_PORTm(unit, MEM_BLOCK_ALL, port, &egr_port)); 6185 } 6186 /* 6187 * Entry must be 'deleted' because the mem profile 'add' routine 6188 * always increments count even though the same entry is used. 6189 */ 6190 if (old_egr_lport_index != 0) { 6191 BCM_IF_ERROR_RETURN 6192 (_bcm_egr_lport_profile_entry_delete(unit, old_egr_lport_index)); 6193 } 6194 6195 return BCM_E_NONE; 6196 #else 6197 return BCM_E_UNAVAIL; 6198 #endif /* BCM_TRX_SUPPORT */ 6199 } 6200 6201 /* 6202 * Function: 6203 * bcm_esw_port_egr_lport_profile_clear 6204 * Description: 6205 * Similar function as bcm_esw_port_egr_lport_profile_fields_set, 6206 * for clear purpose only. 6207 */ 6208 STATIC int 6209 bcm_esw_port_egr_lport_profile_clear(int unit, 6210 bcm_module_t modid, bcm_port_t port, 6211 soc_mem_t mem) 6212 { 6213 #if defined(BCM_TRX_SUPPORT) 6214 int index; 6215 int egr_gpp_index = 0; 6216 egr_gpp_attributes_entry_t egr_gpp_entry; 6217 egr_lport_profile_entry_t egr_lport_entry; 6218 egr_vlan_control_1_entry_t egr_vlan_control_1; 6219 egr_vlan_control_2_entry_t egr_vlan_control_2; 6220 egr_vlan_control_3_entry_t egr_vlan_control_3; 6221 egr_ipmc_cfg2_entry_t egr_ipmc_cfg2; 6222 egr_mtu_entry_t egr_mtu; 6223 egr_port_1_entry_t egr_port_1; 6224 egr_counter_control_entry_t egr_counter_control; 6225 egr_shaping_control_entry_t egr_shaping_control; 6226 egr_port_entry_t egr_port; 6227 uint32 egr_lport_index, old_egr_lport_index; 6228 void *entries[_BCM_EGR_LPROF_MEM_COUNT]; 6229 void *entry; 6230 int ent_size[_BCM_EGR_LPROF_MEM_COUNT] = {0}; 6231 int use_gpp_index = 1; 6232 6233 /* Make sure port module is initialized. */ 6234 PORT_INIT(unit); 6235 6236 if (mem == EGR_GPP_ATTRIBUTESm) { 6237 BCM_IF_ERROR_RETURN 6238 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 6239 &egr_gpp_index)); 6240 BCM_IF_ERROR_RETURN 6241 (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6242 egr_gpp_index, &egr_gpp_entry)); 6243 sal_memset(&egr_gpp_entry, 0, sizeof(egr_gpp_entry)); 6244 BCM_IF_ERROR_RETURN 6245 (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ALL, 6246 egr_gpp_index, &egr_gpp_entry)); 6247 6248 return BCM_E_NONE; 6249 } 6250 6251 BCM_IF_ERROR_RETURN( 6252 bcm_esw_port_egr_lport_prof_src_get(unit, modid, port, &use_gpp_index)); 6253 6254 if (use_gpp_index) { 6255 /* Get LPORT profile index Source Trunk Map table */ 6256 BCM_IF_ERROR_RETURN 6257 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 6258 &egr_gpp_index)); 6259 BCM_IF_ERROR_RETURN 6260 (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6261 egr_gpp_index, &egr_gpp_entry)); 6262 old_egr_lport_index = 6263 soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_entry, 6264 EGR_LPORT_PROFILE_IDXf); 6265 } else { 6266 BCM_IF_ERROR_RETURN 6267 (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &egr_port)); 6268 old_egr_lport_index = 6269 soc_mem_field32_get(unit, EGR_PORTm, &egr_port, 6270 EGR_LPORT_PROFILE_IDXf); 6271 } 6272 6273 /* Get LPORT profile entry */ 6274 index = 0; 6275 if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) { 6276 ent_size[index] = sizeof(egr_lport_entry); 6277 entries[index++] = &egr_lport_entry; 6278 } 6279 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) { 6280 ent_size[index] = sizeof(egr_vlan_control_1); 6281 entries[index++] = &egr_vlan_control_1; 6282 } 6283 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) { 6284 ent_size[index] = sizeof(egr_vlan_control_2); 6285 entries[index++] = &egr_vlan_control_2; 6286 } 6287 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) { 6288 ent_size[index] = sizeof(egr_vlan_control_3); 6289 entries[index++] = &egr_vlan_control_3; 6290 } 6291 if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) { 6292 ent_size[index] = sizeof(egr_ipmc_cfg2); 6293 entries[index++] = &egr_ipmc_cfg2; 6294 } 6295 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 6296 ent_size[index] = sizeof(egr_mtu); 6297 entries[index++] = &egr_mtu; 6298 } 6299 if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) { 6300 ent_size[index] = sizeof(egr_port_1); 6301 entries[index++] = &egr_port_1; 6302 } 6303 if (soc_feature(unit, soc_feature_egr_all_profile) == 0) { 6304 if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) { 6305 ent_size[index] = sizeof(egr_counter_control); 6306 entries[index++] = &egr_counter_control; 6307 } 6308 if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) { 6309 ent_size[index] = sizeof(egr_shaping_control); 6310 entries[index++] = &egr_shaping_control; 6311 } 6312 } 6313 6314 BCM_IF_ERROR_RETURN 6315 (_bcm_egr_lport_profile_entry_get(unit, old_egr_lport_index, 1, entries)); 6316 6317 BCM_IF_ERROR_RETURN 6318 (_bcm_egr_lport_profile_mem_index_get(unit, mem, &index)); 6319 entry = entries[index]; 6320 /* Clear fields */ 6321 sal_memset(entry, 0, ent_size[index]); 6322 6323 BCM_IF_ERROR_RETURN 6324 (_bcm_egr_lport_profile_entry_add(unit, entries, 1, &egr_lport_index)); 6325 6326 /* Update STM LPORT profile index */ 6327 if (use_gpp_index) { 6328 soc_EGR_GPP_ATTRIBUTESm_field32_set(unit, &egr_gpp_entry, 6329 EGR_LPORT_PROFILE_IDXf, 6330 egr_lport_index); 6331 BCM_IF_ERROR_RETURN 6332 (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6333 egr_gpp_index, &egr_gpp_entry)); 6334 } else { 6335 soc_mem_field32_set(unit, EGR_PORTm, &egr_port, 6336 EGR_LPORT_PROFILE_IDXf, egr_lport_index); 6337 BCM_IF_ERROR_RETURN 6338 (WRITE_EGR_PORTm(unit, MEM_BLOCK_ALL, port, &egr_port)); 6339 } 6340 /* 6341 * Entry must be 'deleted' because the mem profile 'add' routine 6342 * always increments count even though the same entry is used. 6343 */ 6344 if (old_egr_lport_index != 0) { 6345 BCM_IF_ERROR_RETURN 6346 (_bcm_egr_lport_profile_entry_delete(unit, old_egr_lport_index)); 6347 } 6348 6349 return BCM_E_NONE; 6350 #else 6351 return BCM_E_UNAVAIL; 6352 #endif /* BCM_TRX_SUPPORT */ 6353 } 6354 6355 /* 6356 * Function: 6357 * _bcm_esw_egr_port_tab_multi_set 6358 * Description: 6359 * Function to set multiple fields in EGR port tables 6360 * Parameters: 6361 * unit - Device number 6362 * port - Port number 6363 * field_count - Number of fields to modify 6364 * fields - Array of fields to modify 6365 * values - Array of new field values 6366 * Return Value: 6367 * BCM_E_NONE 6368 * BCM_E_XXX - an error occurred accessing EGR_PORT table. 6369 */ 6370 int 6371 _bcm_esw_egr_port_tab_multi_set(int unit, bcm_port_t port, int field_count, 6372 soc_field_t *fields, uint32 *values) 6373 6374 { 6375 soc_mem_t mem = EGR_PORTm; 6376 int rv = BCM_E_NONE, i, index; 6377 6378 soc_field_t egr_port_tab_fields[SOC_MAX_MEM_FIELD_NUM]; 6379 uint32 egr_port_tab_values[SOC_MAX_MEM_FIELD_NUM]; 6380 int egr_port_tab_field_count = 0; 6381 soc_field_t egr_lport_tab_fields[SOC_MAX_MEM_FIELD_NUM]; 6382 uint32 egr_lport_tab_values[SOC_MAX_MEM_FIELD_NUM]; 6383 int egr_lport_tab_field_count = 0; 6384 soc_field_t egr_gpp_fields[SOC_MAX_MEM_FIELD_NUM]; 6385 uint32 egr_gpp_values[SOC_MAX_MEM_FIELD_NUM]; 6386 int egr_gpp_field_count = 0; 6387 #if defined BCM_HGPROXY_COE_SUPPORT 6388 int is_lport_cfg = 0; 6389 #endif 6390 6391 6392 if ((fields == NULL) || (values == NULL) ) { 6393 return BCM_E_PARAM; 6394 } 6395 if (field_count <= 0) { 6396 return BCM_E_NONE; 6397 } 6398 6399 #if defined BCM_HGPROXY_COE_SUPPORT 6400 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 6401 (soc_feature(unit, soc_feature_channelized_switching))) && 6402 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 6403 is_lport_cfg = 1; 6404 } 6405 6406 if (is_lport_cfg == 1) { 6407 mem = EGR_LPORT_PROFILEm; 6408 } else 6409 #endif 6410 if (BCM_GPORT_IS_SET(port)) { 6411 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 6412 } 6413 6414 for(i = 0; i < field_count; i++) { 6415 #if defined(CANCUN_SUPPORT) 6416 if (SOC_IS_TRIDENT3X(unit)) { 6417 if (soc_cancun_cmh_check(unit, mem, fields[i]) == SOC_E_NONE) { 6418 rv = soc_cancun_cmh_mem_set(unit, mem, port, fields[i], 6419 values[i]); 6420 } 6421 _bcm_td3_egr_port_tab_conv(unit, &fields[i], &mem); 6422 } 6423 #endif 6424 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 6425 return (SOC_E_UNAVAIL); 6426 } 6427 6428 switch (mem) { 6429 case EGR_GPP_ATTRIBUTESm: 6430 soc_mem_set_field_value_array(egr_gpp_fields, fields[i], 6431 egr_gpp_values, values[i], 6432 egr_gpp_field_count); 6433 break; 6434 case EGR_PORTm: 6435 soc_mem_set_field_value_array(egr_port_tab_fields, fields[i], 6436 egr_port_tab_values, values[i], 6437 egr_port_tab_field_count); 6438 break; 6439 case EGR_LPORT_PROFILEm: 6440 soc_mem_set_field_value_array(egr_lport_tab_fields, fields[i], 6441 egr_lport_tab_values, values[i], 6442 egr_lport_tab_field_count); 6443 break; 6444 default: 6445 BCM_IF_ERROR_RETURN 6446 (soc_mem_field32_modify(unit, mem, port, fields[i], 6447 values[i])); 6448 break; 6449 } 6450 } 6451 6452 #if defined BCM_HGPROXY_COE_SUPPORT 6453 if (is_lport_cfg == 1) { /* remote port */ 6454 return bcm_esw_port_egr_lport_fields_set(unit, port, 6455 EGR_LPORT_PROFILEm, 6456 egr_lport_tab_field_count, 6457 egr_lport_tab_fields, 6458 egr_lport_tab_values); 6459 } 6460 #endif 6461 6462 index = SOC_PORT_MOD_OFFSET(unit, port); 6463 6464 if (egr_port_tab_field_count) { 6465 rv = soc_mem_fields32_modify(unit, EGR_PORTm, index, 6466 egr_port_tab_field_count, 6467 egr_port_tab_fields, egr_port_tab_values); 6468 } 6469 6470 if (egr_lport_tab_field_count && BCM_SUCCESS(rv)) { 6471 rv = bcm_esw_port_egr_lport_fields_set(unit, index, 6472 EGR_LPORT_PROFILEm, egr_lport_tab_field_count, 6473 egr_lport_tab_fields, egr_lport_tab_values); 6474 } 6475 6476 if (egr_gpp_field_count && BCM_SUCCESS(rv)) { 6477 rv = bcm_esw_port_egr_lport_fields_set(unit, index, 6478 EGR_GPP_ATTRIBUTESm, egr_gpp_field_count, 6479 egr_gpp_fields, egr_gpp_values); 6480 } 6481 6482 return rv; 6483 } 6484 6485 /* 6486 * Function: 6487 * _bcm_esw_egr_port_tab_set 6488 * Description: 6489 * Helper funtion for bcm_esw_port_control_set. 6490 * Parameters: 6491 * unit - Device number 6492 * port - Port number 6493 * field - Field name within EGR_PORT table entry 6494 * value - new field value 6495 * Return Value: 6496 * BCM_E_NONE 6497 * BCM_E_XXX - an error occurred accessing EGR_PORT table. 6498 */ 6499 int 6500 _bcm_esw_egr_port_tab_set(int unit, bcm_port_t port, 6501 soc_field_t field, uint32 value) 6502 6503 { 6504 return (_bcm_esw_egr_port_tab_multi_set(unit, port, 1, &field, &value)); 6505 } 6506 6507 /* 6508 * Function: 6509 * _bcm_esw_egr_port_tab_get 6510 * Description: 6511 * Helper funtion for bcm_esw_port_control_get. 6512 * Parameters: 6513 * unit - Device number 6514 * port - Port number 6515 * field - Field name within PORT_TAB table entry 6516 * value - (OUT) field value 6517 * Return Value: 6518 * BCM_E_NONE 6519 * BCM_E_XXX - an error occurred accessing PORT_TAB table. 6520 * Notes: 6521 * Due to the large number of callers for this routine, 6522 * function is expanded to take a GPORT PROXY, which 6523 * get the property from the LPORT profile table. 6524 * 6525 * Current valid port types are: 6526 * GPORT SUBPORT 6527 * BCM port (non-gport), assumes a valid local physical port 6528 */ 6529 6530 int 6531 _bcm_esw_egr_port_tab_get(int unit, bcm_port_t port, 6532 soc_field_t field, int *value) 6533 { 6534 int rv = BCM_E_UNAVAIL; 6535 egr_port_entry_t pent; 6536 soc_mem_t mem; 6537 int index, is_lport_cfg = 0, is_gpp_attr = 0; 6538 uint32 value32; 6539 6540 mem = EGR_PORTm; 6541 #if defined(BCM_TRIDENT3_SUPPORT) 6542 if (SOC_IS_TRIDENT3X(unit)) { 6543 BCM_IF_ERROR_RETURN(_bcm_td3_egr_port_tab_conv(unit, &field, &mem)); 6544 if (mem == EGR_GPP_ATTRIBUTESm) { 6545 is_gpp_attr = 1; 6546 } else if (mem != EGR_PORTm) { 6547 is_lport_cfg = 1; 6548 } 6549 } 6550 #endif 6551 6552 if (!SOC_MEM_FIELD_VALID(unit, mem, field)) { 6553 return (BCM_E_UNAVAIL); 6554 } 6555 6556 #if defined BCM_HGPROXY_COE_SUPPORT 6557 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 6558 soc_feature(unit, soc_feature_channelized_switching)) && 6559 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 6560 is_lport_cfg = 1; 6561 } else 6562 #endif 6563 if (BCM_GPORT_IS_PROXY(port)) { 6564 is_lport_cfg = 1; 6565 } 6566 6567 /* If LPORT, then get property from LPORT table */ 6568 if (is_lport_cfg) { 6569 rv = bcm_esw_port_egr_lport_field_get(unit, port, 6570 EGR_LPORT_PROFILEm, 6571 field, &value32); 6572 *value = value32; 6573 return rv; 6574 } else if (is_gpp_attr) { 6575 rv = bcm_esw_port_egr_lport_field_get(unit, port, 6576 EGR_GPP_ATTRIBUTESm, 6577 field, &value32); 6578 *value = value32; 6579 return rv; 6580 } 6581 6582 /* At this point, 'port' needs to be a BCM port (non-gport) */ 6583 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 6584 6585 index = SOC_PORT_MOD_OFFSET(unit, port); 6586 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &pent); 6587 6588 if (BCM_SUCCESS(rv)) { 6589 *value = soc_mem_field32_get(unit, mem, &pent, field); 6590 } 6591 6592 return rv; 6593 } 6594 6595 6596 #if defined(BCM_TRX_SUPPORT) 6597 /* 6598 * Function: 6599 * bcm_esw_port_separate_lport_rtag7_profile_fields_get 6600 * Description: 6601 * Gets the fields from the LPORT Profile Table. 6602 * Parameters: 6603 * unit - (IN) Device number 6604 * modid - (IN) Module number for port 6605 * port - (IN) Port number (NON gport) 6606 * table_id - (IN) Index of table to modify, LPORT or RTAG7 6607 * field_count - (IN) Number of fields to read 6608 * fields - (IN) Array of fields to return 6609 * values - (OUT) Array of return values 6610 * Return Value: 6611 * BCM_E_NONE 6612 * BCM_E_XXX 6613 * Note: 6614 * - Assumes: lock, 6615 * valid bcm module id and port number, 6616 * valid table id, 6617 * valid HW fields. 6618 * - Called when LPORT profile is supported. 6619 * - Helper routine for bcm_esw_port_lport_fields_get(); 6620 * callers should be calling bcm_esw_port_lport_fields_get() instead. 6621 */ 6622 STATIC int 6623 bcm_esw_port_separate_lport_rtag7_profile_fields_get(int unit, int port_type, 6624 bcm_module_t modid, bcm_port_t port, 6625 int table_id, int field_count, 6626 soc_field_t *fields, uint32 *values) 6627 { 6628 int i; 6629 int src_index; 6630 uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS]; 6631 int src_tbl_is_stm = 1; 6632 soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm; 6633 lport_tab_entry_t lport_entry; 6634 rtag7_port_based_hash_entry_t rtag7_entry; 6635 uint32 lport_index = 0, rtag7_index = 0; 6636 void *entries[1]; 6637 soc_mem_t mem; 6638 void *entry; 6639 6640 BCM_IF_ERROR_RETURN 6641 (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm)); 6642 6643 /* Get LPORT profile index Source table */ 6644 if (src_tbl_is_stm) { 6645 BCM_IF_ERROR_RETURN 6646 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index)); 6647 } else { 6648 src_mem = ING_DEVICE_PORTm; 6649 src_index = port; 6650 } 6651 6652 BCM_IF_ERROR_RETURN 6653 (soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, 6654 src_index, src_ent)); 6655 6656 lport_index = 6657 soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf); 6658 6659 /* If this is a RTAG7 table, extract the RTAG7 index from the LPORT table */ 6660 if(table_id == LPORT_PROFILE_RTAG7_TAB) { 6661 6662 /* Get the associated LPORT entry */ 6663 BCM_IF_ERROR_RETURN 6664 (READ_LPORT_TABm(unit, MEM_BLOCK_ANY, lport_index, &lport_entry)); 6665 6666 rtag7_index = 6667 soc_LPORT_TABm_field32_get(unit, &lport_entry, 6668 RTAG7_PORT_PROFILE_INDEXf); 6669 } 6670 6671 /* Read the appropriate profile table entry */ 6672 if (table_id == LPORT_PROFILE_LPORT_TAB) { 6673 mem = LPORT_TABm; 6674 entries[0] = &lport_entry; 6675 entry = entries[0]; 6676 BCM_IF_ERROR_RETURN 6677 (_bcm_lport_ind_profile_entry_get(unit, lport_index, 6678 1, entries)); 6679 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 6680 mem = RTAG7_PORT_BASED_HASHm; 6681 entries[0] = &rtag7_entry; 6682 entry = entries[0]; 6683 BCM_IF_ERROR_RETURN 6684 (_bcm_rtag7_ind_profile_entry_get(unit, rtag7_index, 6685 1, entries)); 6686 } else { 6687 return BCM_E_INTERNAL; 6688 } 6689 6690 for (i = 0; i < field_count; i++) { 6691 values[i] = soc_mem_field32_get(unit, mem, entry, fields[i]); 6692 } 6693 6694 return BCM_E_NONE; 6695 } 6696 #endif /* BCM_TRX_SUPPORT */ 6697 6698 6699 /* 6700 * Function: 6701 * bcm_esw_port_egr_lport_profile_fields_get 6702 * Description: 6703 * Gets the fields from the LPORT Profile Table. 6704 * Parameters: 6705 * unit - (IN) Device number 6706 * modid - (IN) Module number for port 6707 * port - (IN) Port number (NON gport) 6708 * mem - (IN) Table to modify 6709 * field_count - (IN) Number of fields to read 6710 * fields - (IN) Array of fields to return 6711 * values - (OUT) Array of return values 6712 * Return Value: 6713 * BCM_E_NONE 6714 * BCM_E_XXX 6715 * Note: 6716 * - Assumes: lock, 6717 * valid bcm module id and port number, 6718 * valid table id, 6719 * valid HW fields. 6720 * - Called when LPORT profile is supported. 6721 * - Helper routine for bcm_esw_port_egr_lport_fields_get(); 6722 * callers should be calling bcm_esw_port_egr_lport_fields_get() instead. 6723 */ 6724 STATIC int 6725 bcm_esw_port_egr_lport_profile_fields_get(int unit, 6726 bcm_module_t modid, bcm_port_t port, 6727 soc_mem_t mem, int field_count, 6728 soc_field_t *fields, uint32 *values) 6729 { 6730 #if defined(BCM_TRX_SUPPORT) 6731 int i, index; 6732 int egr_gpp_index = 0; 6733 egr_gpp_attributes_entry_t egr_gpp_entry; 6734 egr_lport_profile_entry_t egr_lport_entry; 6735 egr_vlan_control_1_entry_t egr_vlan_control_1; 6736 egr_vlan_control_2_entry_t egr_vlan_control_2; 6737 egr_vlan_control_3_entry_t egr_vlan_control_3; 6738 egr_ipmc_cfg2_entry_t egr_ipmc_cfg2; 6739 egr_mtu_entry_t egr_mtu; 6740 egr_port_1_entry_t egr_port_1; 6741 egr_counter_control_entry_t egr_counter_control; 6742 egr_shaping_control_entry_t egr_shaping_control; 6743 uint32 egr_lport_index; 6744 void *entries[_BCM_EGR_LPROF_MEM_COUNT]; 6745 void *entry = NULL; 6746 int use_gpp_index = 1; 6747 6748 if (mem == EGR_GPP_ATTRIBUTESm) { 6749 BCM_IF_ERROR_RETURN 6750 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 6751 &egr_gpp_index)); 6752 BCM_IF_ERROR_RETURN 6753 (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6754 egr_gpp_index, &egr_gpp_entry)); 6755 for (i = 0; i < field_count; i++) { 6756 values[i] = soc_mem_field32_get(unit, EGR_GPP_ATTRIBUTESm, 6757 &egr_gpp_entry, fields[i]); 6758 } 6759 return BCM_E_NONE; 6760 } 6761 6762 BCM_IF_ERROR_RETURN( 6763 bcm_esw_port_egr_lport_prof_src_get(unit, modid, port, &use_gpp_index)); 6764 6765 if (use_gpp_index) { 6766 /* Get LPORT profile index Source Trunk Map table */ 6767 BCM_IF_ERROR_RETURN 6768 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 6769 &egr_gpp_index)); 6770 BCM_IF_ERROR_RETURN 6771 (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6772 egr_gpp_index, &egr_gpp_entry)); 6773 egr_lport_index = 6774 soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_entry, 6775 EGR_LPORT_PROFILE_IDXf); 6776 } else { 6777 egr_port_entry_t entry2; 6778 BCM_IF_ERROR_RETURN 6779 (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &entry2)); 6780 egr_lport_index = 6781 soc_mem_field32_get(unit, EGR_PORTm, &entry2, 6782 EGR_LPORT_PROFILE_IDXf); 6783 } 6784 6785 /* Get EGR_LPORT profile entry */ 6786 index = 0; 6787 if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) { 6788 entries[index++] = &egr_lport_entry; 6789 } 6790 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) { 6791 entries[index++] = &egr_vlan_control_1; 6792 } 6793 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) { 6794 entries[index++] = &egr_vlan_control_2; 6795 } 6796 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) { 6797 entries[index++] = &egr_vlan_control_3; 6798 } 6799 if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) { 6800 entries[index++] = &egr_ipmc_cfg2; 6801 } 6802 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 6803 entries[index++] = &egr_mtu; 6804 } 6805 if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) { 6806 entries[index++] = &egr_port_1; 6807 } 6808 if (soc_feature(unit, soc_feature_egr_all_profile) == 0) { 6809 if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) { 6810 entries[index++] = &egr_counter_control; 6811 } 6812 if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) { 6813 entries[index++] = &egr_shaping_control; 6814 } 6815 } 6816 6817 BCM_IF_ERROR_RETURN 6818 (_bcm_egr_lport_profile_entry_get(unit, egr_lport_index, 1, entries)); 6819 6820 BCM_IF_ERROR_RETURN 6821 (_bcm_egr_lport_profile_mem_index_get(unit, mem, &index)); 6822 entry = entries[index]; 6823 /* Get fields */ 6824 6825 for (i = 0; i < field_count; i++) { 6826 values[i] = soc_mem_field32_get(unit, mem, entry, fields[i]); 6827 } 6828 6829 return BCM_E_NONE; 6830 #else 6831 return BCM_E_UNAVAIL; 6832 #endif /* BCM_TRX_SUPPORT */ 6833 } 6834 6835 /* 6836 * Function: 6837 * bcm_esw_port_lport_profile_fields_get 6838 * Description: 6839 * Gets the fields from the LPORT Profile Table. 6840 * Parameters: 6841 * unit - (IN) Device number 6842 * modid - (IN) Module number for port 6843 * port - (IN) Port number (NON gport) 6844 * table_id - (IN) Index of table to modify, LPORT or RTAG7 6845 * field_count - (IN) Number of fields to read 6846 * fields - (IN) Array of fields to return 6847 * values - (OUT) Array of return values 6848 * Return Value: 6849 * BCM_E_NONE 6850 * BCM_E_XXX 6851 * Note: 6852 * - Assumes: lock, 6853 * valid bcm module id and port number, 6854 * valid table id, 6855 * valid HW fields. 6856 * - Called when LPORT profile is supported. 6857 * - Helper routine for bcm_esw_port_lport_fields_get(); 6858 * callers should be calling bcm_esw_port_lport_fields_get() instead. 6859 */ 6860 STATIC int 6861 bcm_esw_port_lport_profile_fields_get(int unit, int port_type, 6862 bcm_module_t modid, bcm_port_t port, 6863 int table_id, int field_count, 6864 soc_field_t *fields, uint32 *values) 6865 { 6866 #if defined(BCM_TRX_SUPPORT) 6867 int i; 6868 int src_index; 6869 uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS]; 6870 int src_tbl_is_stm = 1; 6871 soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm; 6872 lport_tab_entry_t lport_entry; 6873 rtag7_port_based_hash_entry_t rtag7_entry; 6874 uint32 lport_index; 6875 void *entries[2]; 6876 soc_mem_t mem; 6877 void *entry; 6878 int pipe; 6879 6880 if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) { 6881 return bcm_esw_port_separate_lport_rtag7_profile_fields_get(unit, 6882 port_type, modid, port, table_id, field_count, fields, values); 6883 } 6884 6885 BCM_IF_ERROR_RETURN 6886 (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm)); 6887 6888 /* Get LPORT profile index Source table */ 6889 if (src_tbl_is_stm) { 6890 BCM_IF_ERROR_RETURN 6891 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index)); 6892 } else { 6893 src_mem = ING_DEVICE_PORTm; 6894 src_index = port; 6895 } 6896 6897 BCM_IF_ERROR_RETURN 6898 (soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent)); 6899 6900 lport_index = 6901 soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf); 6902 6903 /* Get LPORT profile entry */ 6904 entries[0] = &lport_entry; 6905 entries[1] = &rtag7_entry; 6906 if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 6907 pipe = SOC_INFO(unit).port_pipe[src_index]; 6908 mem = SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)[pipe]; 6909 /* Need to index into the proper entry of the profile table, 6910 * which is stored as one logical table while LPORT_PROFILE_IDX 6911 * is from 0-19 of each pipe */ 6912 lport_index += pipe*SOC_MEM_SIZE(unit, mem); 6913 } 6914 6915 BCM_IF_ERROR_RETURN 6916 (_bcm_lport_profile_entry_get(unit, lport_index, 1, entries)); 6917 6918 /* Get fields */ 6919 if (table_id == LPORT_PROFILE_LPORT_TAB) { 6920 mem = LPORT_TABm; 6921 if (SOC_MEM_UNIQUE_ACC(unit, mem)) { 6922 int pipe = SOC_INFO(unit).port_pipe[src_index]; 6923 mem = SOC_MEM_UNIQUE_ACC(unit, mem)[pipe]; 6924 } 6925 entry = entries[0]; 6926 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 6927 mem = RTAG7_PORT_BASED_HASHm; 6928 entry = entries[1]; 6929 } else { 6930 return BCM_E_INTERNAL; 6931 } 6932 6933 for (i = 0; i < field_count; i++) { 6934 values[i] = soc_mem_field32_get(unit, mem, entry, fields[i]); 6935 } 6936 6937 return BCM_E_NONE; 6938 #else 6939 return BCM_E_UNAVAIL; 6940 #endif /* BCM_TRX_SUPPORT */ 6941 } 6942 6943 /* 6944 * Function: 6945 * bcm_esw_port_lport_non_profile_fields_set 6946 * Description: 6947 * Sets the fields only in the LPORT Table for local HG ports. 6948 * There is no reference update to the SOURCE TRUNK MAP table. 6949 * Parameters: 6950 * unit - (IN) Device number 6951 * port - (IN) Local Port number (NON gport) 6952 * field_count - (IN) Number of fields to modify 6953 * fields - (IN) Array of fields to modify 6954 * values - (IN) Array of new field values 6955 * Return Value: 6956 * BCM_E_NONE 6957 * BCM_E_XXX 6958 * Note: 6959 * Assumes: lock, 6960 * valid bcm port number, 6961 * valid HW fields. 6962 * - Maintained for backwards compatibility with old code. This only 6963 * updates local HG ports. 6964 * - Called when LPORT profile is NOT supported. 6965 * - Helper routine for bcm_esw_port_lport_fields_set(); 6966 * callers should be calling bcm_esw_port_lport_fields_set() instead. 6967 */ 6968 STATIC int 6969 bcm_esw_port_lport_non_profile_fields_set(int unit, bcm_port_t port, 6970 int field_count, 6971 soc_field_t *fields, uint32 *values) 6972 { 6973 bcm_port_config_t port_config; 6974 soc_mem_t mem = LPORT_TABm; 6975 int lport_index; 6976 6977 BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &port_config)); 6978 6979 if (PBMP_MEMBER(port_config.hg, port) == 0) { 6980 return BCM_E_NONE; 6981 } 6982 6983 lport_index = SOC_PORT_MOD_OFFSET(unit, port); 6984 6985 return soc_mem_fields32_modify(unit, mem, lport_index, 6986 field_count, fields, values); 6987 } 6988 6989 /* 6990 * Function: 6991 * bcm_esw_port_lport_non_profile_fields_get 6992 * Description: 6993 * Gets the fields from the LPORT Table for local HG ports. 6994 * Parameters: 6995 * unit - (IN) Device number 6996 * port - (IN) Local Port number (NON gport) 6997 * field_count - (IN) Number of fields to read 6998 * fields - (IN) Array of fields to return 6999 * values - (OUT) Array of return values 7000 * Return Value: 7001 * BCM_E_NONE 7002 * BCM_E_XXX 7003 * Note: 7004 * Assumes: lock, 7005 * valid bcm port number, 7006 * valid HW fields. 7007 * - Maintained for backwards compatibility with old code. This only 7008 * updates local HG ports. 7009 * - Called when LPORT profile is NOT supported. 7010 * - Helper routine for bcm_esw_port_lport_fields_get(); 7011 * callers should be calling bcm_esw_port_lport_fields_get() instead. 7012 */ 7013 STATIC int 7014 bcm_esw_port_lport_non_profile_fields_get(int unit, bcm_port_t port, 7015 int field_count, 7016 soc_field_t *fields, uint32 *values) 7017 { 7018 lport_tab_entry_t lport_entry; 7019 int lport_index; 7020 int i; 7021 7022 if (!IS_HG_PORT(unit,port)) { 7023 return BCM_E_NONE; 7024 } 7025 7026 lport_index = SOC_PORT_MOD_OFFSET(unit, port); 7027 7028 BCM_IF_ERROR_RETURN 7029 (READ_LPORT_TABm(unit, MEM_BLOCK_ANY, lport_index, &lport_entry)); 7030 7031 for (i = 0; i < field_count; i++) { 7032 values[i] = soc_LPORT_TABm_field32_get(unit, &lport_entry, fields[i]); 7033 } 7034 7035 return BCM_E_NONE; 7036 } 7037 7038 /* 7039 * Function: 7040 * bcm_esw_port_lport_resolve 7041 * Description: 7042 * Resolves given port to use in the LPORT table as follows. 7043 * Current valid "port" for LPORT are: 7044 * GPORT_PROXY - Resolve to module ID and port 7045 * GPORT_xxx - Should result in a valid local physical port 7046 * Not GPORT - Should be a valid local port number 7047 * Parameters: 7048 * unit - (IN) Device number 7049 * port - (IN) Port number or GPORT 7050 * modid_out - (OUT) Module ID 7051 * port_out - (OUT) Port number 7052 * Return Value: 7053 * BCM_E_XXX 7054 * Notes: 7055 * If port is GPORT_PROXY, then module-id is derived from GPORT. 7056 * Else, module-is is the id of the local device. 7057 */ 7058 STATIC int 7059 bcm_esw_port_lport_resolve(int unit, bcm_port_t port, 7060 bcm_module_t *modid_out, bcm_port_t *port_out) 7061 { 7062 bcm_trunk_t trunk; 7063 int id, rv; 7064 7065 /* Make sure port module is initialized. */ 7066 PORT_INIT(unit); 7067 7068 /* Resolve port */ 7069 if (BCM_GPORT_IS_PROXY(port)) { 7070 if (!soc_feature(unit, soc_feature_proxy_port_property)) { 7071 return BCM_E_PORT; 7072 } 7073 BCM_IF_ERROR_RETURN 7074 (_bcm_esw_gport_resolve(unit, port, 7075 modid_out, port_out, 7076 &trunk, &id)); 7077 } else { 7078 7079 #if defined BCM_HGPROXY_COE_SUPPORT 7080 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 7081 soc_feature(unit, soc_feature_channelized_switching)) && 7082 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 7083 BCM_IF_ERROR_RETURN 7084 (_bcm_esw_gport_resolve(unit, port, 7085 modid_out, port_out, 7086 &trunk, &id)); 7087 } else 7088 #endif 7089 7090 #if defined(BCM_KATANA2_SUPPORT) 7091 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port) && 7092 (soc_feature(unit, soc_feature_subtag_coe) || 7093 soc_feature(unit, soc_feature_linkphy_coe))) { 7094 BCM_IF_ERROR_RETURN 7095 (_bcm_esw_gport_resolve(unit, port, 7096 modid_out, port_out, 7097 &trunk, &id)); 7098 } else 7099 #endif 7100 7101 { 7102 /* Gport should resolve to a local valid port */ 7103 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, modid_out)); 7104 rv = _bcm_esw_port_gport_validate(unit, port, port_out); 7105 7106 if (rv == BCM_E_PORT && 7107 SOC_IS_TRIDENT3X(unit) && 7108 SOC_INFO(unit).cpu_hg_index == port) { 7109 *port_out = port; 7110 rv = BCM_E_NONE; 7111 } 7112 BCM_IF_ERROR_RETURN(rv); 7113 } 7114 } 7115 7116 return BCM_E_NONE; 7117 } 7118 7119 /* 7120 * Function: 7121 * bcm_esw_port_egr_lport_resolve 7122 * Description: 7123 * Resolves given port to use in the EGR_LPORT table as follows. 7124 * Current valid "port" for EGR_LPORT are: 7125 * GPORT_SUBPORT - Resolve to module ID and port 7126 * Parameters: 7127 * unit - (IN) Device number 7128 * port - (IN) Port number or GPORT 7129 * modid_out - (OUT) Module ID 7130 * port_out - (OUT) Port number 7131 * Return Value: 7132 * BCM_E_XXX 7133 * Notes: 7134 * If port is GPORT_PROXY, then module-id is derived from GPORT. 7135 * Else, module-is is the id of the local device. 7136 */ 7137 STATIC int 7138 bcm_esw_port_egr_lport_resolve(int unit, bcm_port_t port, 7139 bcm_module_t *modid_out, bcm_port_t *port_out) 7140 { 7141 #if defined BCM_HGPROXY_COE_SUPPORT 7142 bcm_trunk_t trunk; 7143 int id; 7144 #endif 7145 7146 /* Make sure port module is initialized. */ 7147 PORT_INIT(unit); 7148 7149 /* Resolve port */ 7150 #if defined BCM_HGPROXY_COE_SUPPORT 7151 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 7152 (soc_feature(unit, soc_feature_channelized_switching))) && 7153 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 7154 BCM_IF_ERROR_RETURN 7155 (_bcm_esw_gport_resolve(unit, port, 7156 modid_out, port_out, 7157 &trunk, &id)); 7158 } else 7159 #endif 7160 { 7161 /* Gport should resolve to a local valid port */ 7162 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, modid_out)); 7163 BCM_IF_ERROR_RETURN 7164 (_bcm_esw_port_gport_validate(unit, port, port_out)); 7165 } 7166 7167 return BCM_E_NONE; 7168 } 7169 7170 7171 /* 7172 * Function: 7173 * bcm_esw_port_lport_fields_set 7174 * Description: 7175 * Sets the fields in the LPORT Table as follows: 7176 * - If LPORT profile is available, update fields in the 7177 * LPORT Profile Table and corresponding index in the 7178 * Source Trunk Map table. 7179 * - Else, update fields in the LPORT table only (old logic). 7180 * Parameters: 7181 * unit - (IN) Device number 7182 * port - (IN) Port number or GPORT (see Notes) 7183 * table_id - (IN) Index of table to modify, LPORT or RTAG7 7184 * field_count - (IN) Number of fields to modify 7185 * fields - (IN) Array of fields to modify 7186 * values - (IN) Array of new field values 7187 * Return Value: 7188 * BCM_E_XXX 7189 * Notes: 7190 * Current valid port/gport types: 7191 * GPORT_PROXY 7192 * GPORT_xxx - should result in a valid local physical port 7193 * Not GPORT - assumes a valid local port number 7194 */ 7195 int 7196 bcm_esw_port_lport_fields_set(int unit, bcm_port_t port, 7197 int table_id, int field_count, 7198 soc_field_t *fields, uint32 *values) 7199 { 7200 int rv = BCM_E_NONE; 7201 int i; 7202 soc_mem_t mem; 7203 bcm_module_t lmodid; 7204 bcm_port_t lport; 7205 int ptype = _BCM_ESW_PT_PORT; 7206 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT) 7207 bcm_xflow_macsec_port_info_t port_info; 7208 port_info.enable =0; 7209 #endif 7210 7211 /* Make sure port module is initialized. */ 7212 PORT_INIT(unit); 7213 7214 #if defined BCM_HGPROXY_COE_SUPPORT 7215 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 7216 (soc_feature(unit, soc_feature_channelized_switching))) && 7217 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 7218 ptype = _BCM_ESW_PT_COE; 7219 } else 7220 #endif 7221 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT) 7222 if (SOC_IS_HURRICANE4(unit) && soc_feature(unit, soc_feature_xflow_macsec) && 7223 (BCM_E_NONE == bcm_common_xflow_macsec_port_info_get(unit, port, &port_info)) && 7224 (port_info.enable == 1)) { 7225 ptype = _BCM_ESW_PT_MACSEC_PORT; 7226 } else 7227 #endif 7228 if (BCM_GPORT_IS_PROXY(port)) { 7229 ptype = _BCM_ESW_PT_HGPROXY; 7230 } 7231 7232 /* Check table */ 7233 if (table_id == LPORT_PROFILE_LPORT_TAB) { 7234 mem = LPORT_TABm; 7235 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 7236 if (!SOC_MEM_IS_VALID(unit, RTAG7_PORT_BASED_HASHm)) { 7237 return BCM_E_UNAVAIL; 7238 } 7239 mem = RTAG7_PORT_BASED_HASHm; 7240 } else { 7241 return BCM_E_INTERNAL; 7242 } 7243 7244 /* Check all fields are valid */ 7245 for (i = 0; i < field_count; i++) { 7246 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 7247 return BCM_E_UNAVAIL; 7248 } 7249 } 7250 7251 /* Resolve port */ 7252 BCM_IF_ERROR_RETURN 7253 (bcm_esw_port_lport_resolve(unit, port, 7254 &lmodid, &lport)); 7255 7256 if (soc_feature(unit, soc_feature_lport_tab_profile)) { 7257 rv = bcm_esw_port_lport_profile_fields_set(unit, ptype, 7258 lmodid, lport, table_id, field_count, fields, values); 7259 } else { 7260 rv = bcm_esw_port_lport_non_profile_fields_set(unit, 7261 lport, field_count, fields, values); 7262 } 7263 7264 return rv; 7265 } 7266 7267 /* 7268 * Function: 7269 * bcm_esw_port_egr_lport_fields_set 7270 * Description: 7271 * Sets the fields in the LPORT Table as follows: 7272 * - If LPORT profile is available, update fields in the 7273 * LPORT Profile Table and corresponding index in the 7274 * Source Trunk Map table. 7275 * - Else, update fields in the LPORT table only (old logic). 7276 * Parameters: 7277 * unit - (IN) Device number 7278 * port - (IN) Port number or GPORT (see Notes) 7279 * mem - (IN) Table to modify 7280 * field_count - (IN) Number of fields to modify 7281 * fields - (IN) Array of fields to modify 7282 * values - (IN) Array of new field values 7283 * Return Value: 7284 * BCM_E_XXX 7285 * Notes: 7286 * Current valid port/gport types: 7287 * GPORT_PROXY 7288 * GPORT_xxx - should result in a valid local physical port 7289 * Not GPORT - assumes a valid local port number 7290 */ 7291 int 7292 bcm_esw_port_egr_lport_fields_set(int unit, bcm_port_t port, 7293 soc_mem_t mem, int field_count, 7294 soc_field_t *fields, uint32 *values) 7295 { 7296 int rv = BCM_E_NONE; 7297 int i; 7298 bcm_module_t lmodid; 7299 bcm_port_t lport; 7300 7301 /* Make sure port module is initialized. */ 7302 PORT_INIT(unit); 7303 7304 /* Check all fields are valid */ 7305 for (i = 0; i < field_count; i++) { 7306 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 7307 return BCM_E_UNAVAIL; 7308 } 7309 } 7310 7311 /* Resolve port */ 7312 BCM_IF_ERROR_RETURN 7313 (bcm_esw_port_egr_lport_resolve(unit, port, 7314 &lmodid, &lport)); 7315 7316 PORT_LOCK(unit); 7317 if (soc_feature(unit, soc_feature_egr_lport_tab_profile)) { 7318 rv = bcm_esw_port_egr_lport_profile_fields_set(unit, lmodid, lport, 7319 mem, field_count, 7320 fields, values); 7321 } 7322 7323 PORT_UNLOCK(unit); 7324 7325 return rv; 7326 } 7327 7328 /* 7329 * Function: 7330 * bcm_esw_port_egr_lport_fields_clear 7331 * Description: 7332 * Similar function as bcm_esw_port_egr_lport_fields_set. 7333 * For clear purpose only. 7334 * Parameters: 7335 * unit - (IN) Device number 7336 * port - (IN) Port number or GPORT (see Notes) 7337 * mem - (IN) Table to modify 7338 * Return Value: 7339 * BCM_E_XXX 7340 * Notes: 7341 * Current valid port/gport types: 7342 * GPORT_PROXY 7343 * GPORT_xxx - should result in a valid local physical port 7344 * Not GPORT - assumes a valid local port number 7345 */ 7346 int 7347 bcm_esw_port_egr_lport_fields_clear(int unit, bcm_port_t port, 7348 soc_mem_t mem) 7349 { 7350 int rv = BCM_E_NONE; 7351 bcm_module_t lmodid; 7352 bcm_port_t lport; 7353 7354 /* Make sure port module is initialized. */ 7355 PORT_INIT(unit); 7356 7357 /* Resolve port */ 7358 BCM_IF_ERROR_RETURN 7359 (bcm_esw_port_egr_lport_resolve(unit, port, 7360 &lmodid, &lport)); 7361 7362 PORT_LOCK(unit); 7363 if (soc_feature(unit, soc_feature_egr_lport_tab_profile)) { 7364 rv = bcm_esw_port_egr_lport_profile_clear(unit, lmodid, lport, mem); 7365 } 7366 7367 PORT_UNLOCK(unit); 7368 7369 return rv; 7370 } 7371 7372 /* 7373 * Function: 7374 * bcm_esw_port_lport_fields_get 7375 * Description: 7376 * Gets the values from the LPORT Table fields as follows: 7377 * - If LPORT profile is available, gets fields from the 7378 * LPORT Profile Table and corresponding index in the 7379 * Source Trunk Map table. 7380 * - Else, get fields from the LPORT table only (old logic). 7381 * Parameters: 7382 * unit - (IN) Device number 7383 * port - (IN) Port number or GPORT (see Notes) 7384 * table_id - (IN) Index of table to modify, LPORT or RTAG7 7385 * field_count - (IN) Number of fields to get 7386 * fields - (IN) Array of fields values to get 7387 * values - (OUT) Array of returned values 7388 * Return Value: 7389 * BCM_E_XXX 7390 * Notes: 7391 * Current valid port/gport types: 7392 * GPORT_PROXY 7393 * GPORT_xxx - should result in a valid local physical port 7394 * Not GPORT - assumes a valid local port number 7395 */ 7396 int 7397 bcm_esw_port_lport_fields_get(int unit, bcm_port_t port, 7398 int table_id, int field_count, 7399 soc_field_t *fields, uint32 *values) 7400 { 7401 int rv = BCM_E_NONE; 7402 int i; 7403 soc_mem_t mem; 7404 bcm_module_t lmodid; 7405 bcm_port_t lport; 7406 int ptype = _BCM_ESW_PT_PORT; 7407 7408 /* Make sure port module is initialized. */ 7409 PORT_INIT(unit); 7410 7411 #if defined BCM_HGPROXY_COE_SUPPORT 7412 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 7413 (soc_feature(unit, soc_feature_channelized_switching))) && 7414 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 7415 ptype = _BCM_ESW_PT_COE; 7416 } else 7417 #endif 7418 if (BCM_GPORT_IS_PROXY(port)) { 7419 ptype = _BCM_ESW_PT_HGPROXY; 7420 } 7421 7422 /* Check table */ 7423 if (table_id == LPORT_PROFILE_LPORT_TAB) { 7424 mem = LPORT_TABm; 7425 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 7426 if (!SOC_MEM_IS_VALID(unit, RTAG7_PORT_BASED_HASHm)) { 7427 return BCM_E_UNAVAIL; 7428 } 7429 mem = RTAG7_PORT_BASED_HASHm; 7430 } else { 7431 return BCM_E_INTERNAL; 7432 } 7433 7434 /* Check all fields are valid */ 7435 for (i = 0; i < field_count; i++) { 7436 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 7437 return BCM_E_UNAVAIL; 7438 } 7439 } 7440 7441 /* Resolve port */ 7442 BCM_IF_ERROR_RETURN 7443 (bcm_esw_port_lport_resolve(unit, port, 7444 &lmodid, &lport)); 7445 7446 if (soc_feature(unit, soc_feature_lport_tab_profile)) { 7447 rv = bcm_esw_port_lport_profile_fields_get(unit, ptype, 7448 lmodid, lport, table_id, field_count, fields, values); 7449 } else { 7450 rv = bcm_esw_port_lport_non_profile_fields_get(unit, lport, 7451 field_count, fields, values); 7452 } 7453 7454 return rv; 7455 } 7456 7457 /* 7458 * Function: 7459 * bcm_esw_port_egr_lport_fields_get 7460 * Description: 7461 * Gets the values from the LPORT Table fields as follows: 7462 * - If LPORT profile is available, gets fields from the 7463 * LPORT Profile Table and corresponding index in the 7464 * Source Trunk Map table. 7465 * - Else, get fields from the LPORT table only (old logic). 7466 * Parameters: 7467 * unit - (IN) Device number 7468 * port - (IN) Port number or GPORT (see Notes) 7469 * mem - (IN) Table to modify 7470 * field_count - (IN) Number of fields to get 7471 * fields - (IN) Array of fields values to get 7472 * values - (OUT) Array of returned values 7473 * Return Value: 7474 * BCM_E_XXX 7475 * Notes: 7476 * Current valid port/gport types: 7477 * GPORT_PROXY 7478 * GPORT_xxx - should result in a valid local physical port 7479 * Not GPORT - assumes a valid local port number 7480 */ 7481 int 7482 bcm_esw_port_egr_lport_fields_get(int unit, bcm_port_t port, 7483 soc_mem_t mem, int field_count, 7484 soc_field_t *fields, uint32 *values) 7485 { 7486 int rv = BCM_E_NONE; 7487 int i; 7488 bcm_module_t lmodid; 7489 bcm_port_t lport; 7490 7491 /* Sanity check */ 7492 if ((fields == NULL) || (values == NULL)) { 7493 return BCM_E_PARAM; 7494 } 7495 7496 /* Make sure port module is initialized. */ 7497 PORT_INIT(unit); 7498 7499 /* Check all fields are valid */ 7500 for (i = 0; i < field_count; i++) { 7501 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 7502 return BCM_E_UNAVAIL; 7503 } 7504 } 7505 7506 /* Resolve port */ 7507 BCM_IF_ERROR_RETURN 7508 (bcm_esw_port_egr_lport_resolve(unit, port, 7509 &lmodid, &lport)); 7510 7511 PORT_LOCK(unit); 7512 rv = bcm_esw_port_egr_lport_profile_fields_get(unit, lmodid, lport, 7513 mem, field_count, 7514 fields, values); 7515 PORT_UNLOCK(unit); 7516 7517 return rv; 7518 } 7519 7520 /* 7521 * Function: 7522 * bcm_esw_port_lport_field_set 7523 * Description: 7524 * Sets given field in the LPORT Table as follows: 7525 * - If LPORT profile is available, update field in the 7526 * LPORT Profile Table and corresponding index in the 7527 * Source Trunk Map table. 7528 * - Else, update field in the LPORT table only (old logic). 7529 * Parameters: 7530 * unit - (IN) Device number 7531 * port - (IN) Port number or GPORT (see Notes) 7532 * table_id - (IN) Index of table to modify, LPORT or RTAG7 7533 * field - (IN) Field to modify 7534 * value - (IN) New field value 7535 * Return Value: 7536 * BCM_E_XXX 7537 * Notes: 7538 * See bcm_esw_port_lport_fields_set(). 7539 */ 7540 int 7541 bcm_esw_port_lport_field_set(int unit, bcm_port_t port, 7542 int table_id, soc_field_t field, uint32 value) 7543 { 7544 /* Make sure port module is initialized. */ 7545 PORT_INIT(unit); 7546 7547 return bcm_esw_port_lport_fields_set(unit, port, 7548 table_id, 1, &field, &value); 7549 } 7550 7551 /* 7552 * Function: 7553 * bcm_esw_port_egr_lport_field_set 7554 * Description: 7555 * Sets given field in the LPORT Table as follows: 7556 * - If LPORT profile is available, update field in the 7557 * LPORT Profile Table and corresponding index in the 7558 * Source Trunk Map table. 7559 * - Else, update field in the LPORT table only (old logic). 7560 * Parameters: 7561 * unit - (IN) Device number 7562 * port - (IN) Port number or GPORT (see Notes) 7563 * mem - (IN) Table to modify 7564 * field - (IN) Field to modify 7565 * value - (IN) New field value 7566 * Return Value: 7567 * BCM_E_XXX 7568 * Notes: 7569 * See bcm_esw_port_egr_lport_fields_set(). 7570 */ 7571 int 7572 bcm_esw_port_egr_lport_field_set(int unit, bcm_port_t port, soc_mem_t mem, 7573 soc_field_t field, uint32 value) 7574 { 7575 /* Make sure port module is initialized. */ 7576 PORT_INIT(unit); 7577 7578 return bcm_esw_port_egr_lport_fields_set(unit, port, mem, 1, &field, &value); 7579 } 7580 7581 7582 /* 7583 * Function: 7584 * bcm_esw_port_lport_field_get 7585 * Description: 7586 * Gets given field from the LPORT Table as follows: 7587 * - If LPORT profile is available, gets fields from the 7588 * LPORT Profile Table and corresponding index in the 7589 * Source Trunk Map table. 7590 * - Else, get fields from the LPORT table only (old logic). 7591 * Parameters: 7592 * unit - (IN) Device number 7593 * port - (IN) Port number or GPORT (see Notes) 7594 * table_id - (IN) Index of table to modify, LPORT or RTAG7 7595 * field - (IN) Field value to get 7596 * value - (OUT) Returned value 7597 * Return Value: 7598 * BCM_E_XXX 7599 * Notes: 7600 * See bcm_esw_port_lport_fields_get(). 7601 */ 7602 int 7603 bcm_esw_port_lport_field_get(int unit, bcm_port_t port, 7604 int table_id, soc_field_t field, uint32 *value) 7605 { 7606 /* Make sure port module is initialized. */ 7607 PORT_INIT(unit); 7608 7609 return bcm_esw_port_lport_fields_get(unit, port, 7610 table_id, 1, &field, value); 7611 } 7612 7613 7614 /* 7615 * Function: 7616 * bcm_esw_port_egr_lport_field_get 7617 * Description: 7618 * Gets given field from the LPORT Table as follows: 7619 * - If LPORT profile is available, gets fields from the 7620 * LPORT Profile Table and corresponding index in the 7621 * Source Trunk Map table. 7622 * - Else, get fields from the LPORT table only (old logic). 7623 * Parameters: 7624 * unit - (IN) Device number 7625 * port - (IN) Port number or GPORT (see Notes) 7626 * mem - (IN) Table to modify 7627 * field - (IN) Field value to get 7628 * value - (OUT) Returned value 7629 * Return Value: 7630 * BCM_E_XXX 7631 * Notes: 7632 * See bcm_esw_port_egr_lport_fields_get(). 7633 */ 7634 int 7635 bcm_esw_port_egr_lport_field_get(int unit, bcm_port_t port, soc_mem_t mem, 7636 soc_field_t field, uint32 *value) 7637 { 7638 /* Make sure port module is initialized. */ 7639 PORT_INIT(unit); 7640 7641 return bcm_esw_port_egr_lport_fields_get(unit, port, mem, 1, &field, value); 7642 } 7643 7644 /* 7645 * Function: 7646 * _bcm_esw_port_tab_multi_set 7647 * Description: 7648 * Sets multiple port property fields in the HW table. 7649 * Helper funtion for bcm_esw_port_control_set. 7650 * Parameters: 7651 * unit - Device number 7652 * port - Port number (see Notes for valid port formats) 7653 * cpu_tabs - If CPU port, which ingress tables should be written? 7654 * field_count - Number of fields to modify 7655 * fields - Array of fields to modify 7656 * values - Array of new field values 7657 * Return Value: 7658 * BCM_E_NONE 7659 * BCM_E_XXX - an error occurred accessing PORT_TAB table. 7660 * Notes: 7661 * Due to the large number of callers for this routine, 7662 * function is expanded to take a GPORT PROXY, which 7663 * sets the property in the LPORT profile table (similar 7664 * to what was done for the GPORT_WLAN_PORT). 7665 * 7666 * Current valid port types are: 7667 * GPORT WLAN 7668 * GPORT PROXY 7669 * GPORT SUBPORT 7670 * BCM port (non-gport), assumes a valid local physical port 7671 * 7672 * For GPORT PROXY port, this routine only accesses the properties 7673 * in the LPORT table (not the RTAG7). 7674 */ 7675 int 7676 _bcm_esw_port_tab_multi_set(int unit, bcm_port_t port, int cpu_tabs, 7677 int field_count, soc_field_t *fields, 7678 uint32 *values) 7679 { 7680 soc_mem_t port_tab_mem = PORT_TABm; 7681 int rv = BCM_E_NONE, i, cpu_hg_index = -1; 7682 int is_lport_cfg=0, is_wlan_cfg = 0, is_in_warm_boot = 0; 7683 int index = 0, is_local_port = 0; 7684 int ptype = _BCM_ESW_PT_PORT; 7685 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 7686 && defined(INCLUDE_L3)) 7687 bcm_port_t wport = 0; 7688 #endif 7689 port_tab_entry_t pent; 7690 7691 soc_field_t port_tab_fields[SOC_MAX_MEM_FIELD_NUM]; 7692 uint32 port_tab_values[SOC_MAX_MEM_FIELD_NUM]; 7693 int port_tab_field_count = 0; 7694 soc_field_t lport_tab_fields[SOC_MAX_MEM_FIELD_NUM]; 7695 uint32 lport_tab_values[SOC_MAX_MEM_FIELD_NUM]; 7696 int lport_tab_field_count = 0; 7697 soc_field_t ing_dev_port_fields[SOC_MAX_MEM_FIELD_NUM]; 7698 uint32 ing_dev_port_values[SOC_MAX_MEM_FIELD_NUM]; 7699 int ing_dev_port_field_count = 0; 7700 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT) 7701 bcm_xflow_macsec_port_info_t port_info; 7702 port_info.enable =0; 7703 #endif 7704 7705 if ((fields == NULL) || (values == NULL) ) { 7706 return BCM_E_PARAM; 7707 } 7708 if (field_count <= 0) { 7709 return BCM_E_NONE; 7710 } 7711 7712 #if defined BCM_HGPROXY_COE_SUPPORT 7713 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 7714 (soc_feature(unit, soc_feature_channelized_switching))) && 7715 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 7716 is_lport_cfg = 1; 7717 ptype = _BCM_ESW_PT_COE; 7718 } else 7719 #endif 7720 #if defined(INCLUDE_XFLOW_MACSEC) && defined(BCM_HURRICANE4_SUPPORT) 7721 if (SOC_IS_HURRICANE4(unit) && soc_feature(unit, soc_feature_xflow_macsec) && 7722 (BCM_E_NONE == bcm_common_xflow_macsec_port_info_get(unit, port, &port_info)) && 7723 (port_info.enable == 1)) { 7724 ptype = _BCM_ESW_PT_MACSEC_PORT; 7725 } else 7726 #endif 7727 if (BCM_GPORT_IS_PROXY(port)) { 7728 is_lport_cfg = 1; 7729 ptype = _BCM_ESW_PT_HGPROXY; 7730 if(bcm_esw_port_local_get(unit, port, &port) == BCM_E_NONE) { 7731 is_local_port = 1; 7732 index = SOC_PORT_MOD_OFFSET(unit, port); 7733 } 7734 } 7735 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 7736 && defined(INCLUDE_L3)) 7737 else if (BCM_GPORT_IS_WLAN_PORT(port)) { 7738 is_wlan_cfg = 1; 7739 wport = port; 7740 } 7741 #endif 7742 7743 if (is_lport_cfg) { 7744 port_tab_mem = LPORT_TABm; 7745 } else if (!is_wlan_cfg) { 7746 /* 7747 * At this point, 'port' needs to be a BCM port (non-gport) 7748 * convert the gport to local port 7749 */ 7750 if (BCM_GPORT_IS_SET(port)) { 7751 BCM_IF_ERROR_RETURN( 7752 _bcm_esw_port_gport_validate(unit, port, &port)); 7753 } 7754 index = SOC_PORT_MOD_OFFSET(unit, port); 7755 port_tab_mem = SOC_PORT_MEM_TAB(unit, port); 7756 } 7757 7758 if (!is_wlan_cfg && port_tab_mem == PORT_TABm && 7759 (!IS_CPU_PORT(unit, port) || (cpu_tabs & _BCM_CPU_TABS_ETHER))) { 7760 sal_memset(&pent, 0, sizeof(pent)); 7761 if (port_tab_mem == PORT_TABm && 7762 SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 7763 port_tab_mem = ING_DEVICE_PORTm; 7764 } 7765 BCM_IF_ERROR_RETURN( 7766 soc_mem_read(unit, port_tab_mem, MEM_BLOCK_ANY, index, &pent)); 7767 } 7768 7769 /* Loop to set field values into corresponding memory */ 7770 for (i = 0; i < field_count; i++) { 7771 /* If LPORT, then set property in LPORT table */ 7772 if (is_lport_cfg) { 7773 #if defined(CANCUN_SUPPORT) 7774 if(SOC_IS_TRIDENT3X(unit)) { 7775 if(soc_cancun_cmh_check(unit, port_tab_mem, fields[i]) 7776 == SOC_E_NONE) { 7777 rv = soc_cancun_cmh_mem_set(unit, port_tab_mem, port, 7778 fields[i], values[i]); 7779 } 7780 _bcm_td3_port_tab_conv(unit, &fields[i], &port_tab_mem); 7781 } 7782 #endif 7783 soc_mem_set_field_value_array(lport_tab_fields, fields[i], 7784 lport_tab_values, values[i], 7785 lport_tab_field_count); 7786 7787 /* Synchronize PORT and LPORT profile tables if port is local*/ 7788 if(is_local_port) { 7789 if(SOC_MEM_FIELD_VALID(unit, port_tab_mem, fields[i])) { 7790 soc_mem_set_field_value_array(port_tab_fields, fields[i], 7791 port_tab_values, values[i], 7792 port_tab_field_count); 7793 } 7794 } 7795 7796 continue; 7797 } 7798 7799 /* GPORT WLAN */ 7800 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 7801 && defined(INCLUDE_L3)) 7802 7803 if (is_wlan_cfg) { 7804 #if defined(BCM_TRIUMPH3_SUPPORT) 7805 if (soc_feature(unit, soc_feature_axp)) { 7806 rv = _bcm_tr3_wlan_port_set(unit, wport, fields[i], values[i]); 7807 } else 7808 #endif /* BCM_TRIUMPH3_SUPPORT */ 7809 if (soc_feature(unit, soc_feature_wlan)) { 7810 rv = _bcm_tr2_wlan_port_set(unit, wport, fields[i], values[i]); 7811 } 7812 if (rv != BCM_E_NONE) { 7813 return rv; 7814 } 7815 continue; 7816 } 7817 #endif 7818 7819 /* BCM port (non-gport) */ 7820 #if defined(CANCUN_SUPPORT) 7821 if (SOC_IS_TRIDENT3X(unit)) { 7822 port_tab_mem = PORT_TABm; 7823 if (soc_cancun_cmh_check(unit, port_tab_mem, fields[i]) 7824 == SOC_E_NONE) { 7825 rv = soc_cancun_cmh_mem_set(unit, port_tab_mem, port, 7826 fields[i], values[i]); 7827 continue; 7828 } 7829 _bcm_td3_port_tab_conv(unit, &fields[i], &port_tab_mem); 7830 } 7831 #endif 7832 if (!SOC_MEM_FIELD_VALID(unit, port_tab_mem, fields[i])) { 7833 LOG_INFO(BSL_LS_SOC_CANCUN, (BSL_META_U(unit, 7834 "%s.%s is INVALID\n"), 7835 SOC_MEM_NAME(unit, port_tab_mem), 7836 SOC_FIELD_NAME(unit, fields[i]))); 7837 return (BCM_E_UNAVAIL); 7838 } 7839 7840 if ((!IS_CPU_PORT(unit, port) || (cpu_tabs & _BCM_CPU_TABS_ETHER)) || 7841 (IS_CPU_PORT(unit, port) && 7842 (cpu_tabs & _BCM_CPU_TABS_HIGIG) && 7843 (port_tab_mem == PORT_TABm))) { 7844 switch (port_tab_mem) { 7845 #ifdef BCM_TUCANA_SUPPORT 7846 case PORT_TAB1m: 7847 #endif 7848 case PORT_TABm: 7849 if ((soc_mem_field32_get(unit, port_tab_mem, 7850 &pent, fields[i]) != values[i]) || 7851 (fields[i] == TRILL_ENABLEf) || 7852 (fields[i] == ALLOW_TRILL_FRAMESf) || 7853 (fields[i] == ALLOW_NON_TRILL_FRAMESf) || 7854 (fields[i] == COPY_CORE_IS_IS_TO_CPUf) || 7855 (fields[i] == RTAG7_HASH_CFG_SEL_TRILL_ECMPf)) { 7856 soc_mem_field32_set(unit, port_tab_mem, 7857 &pent, fields[i], values[i]); 7858 soc_mem_set_field_value_array(port_tab_fields, 7859 fields[i], port_tab_values, values[i], 7860 port_tab_field_count); 7861 if ((SOC_MEM_IS_VALID(unit, LPORT_TABm)) && 7862 (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TD2P_TT2P(unit) || 7863 SOC_IS_APACHE(unit) || 7864 soc_feature(unit, 7865 soc_feature_sync_port_lport_tab))) { 7866 soc_mem_set_field_value_array(lport_tab_fields, 7867 fields[i], lport_tab_values, values[i], 7868 lport_tab_field_count); 7869 } 7870 } 7871 break; 7872 case LPORT_TABm: 7873 soc_mem_set_field_value_array(lport_tab_fields, fields[i], 7874 lport_tab_values, values[i], 7875 lport_tab_field_count); 7876 break; 7877 case ING_DEVICE_PORTm: 7878 soc_mem_set_field_value_array(ing_dev_port_fields, 7879 fields[i], 7880 ing_dev_port_values, 7881 values[i], 7882 ing_dev_port_field_count); 7883 break; 7884 default: 7885 soc_mem_field32_modify(unit, port_tab_mem, port, 7886 fields[i], values[i]); 7887 continue; 7888 } 7889 } 7890 } 7891 7892 /* wlan_cfg is handled outside of this function */ 7893 if (is_wlan_cfg == 1) { 7894 return BCM_E_NONE; 7895 } 7896 7897 is_in_warm_boot = (inside_bcm_shutdown[unit] == TRUE) || 7898 SOC_WARM_BOOT(unit); 7899 7900 /* Apply the changes to tables their field_count is not 0 */ 7901 if (port_tab_field_count != 0) { 7902 if (port_tab_mem == PORT_TABm && 7903 (!IS_CPU_PORT(unit, port) || (cpu_tabs & _BCM_CPU_TABS_ETHER))) { 7904 BCM_IF_ERROR_RETURN 7905 (soc_mem_write(unit, port_tab_mem, MEM_BLOCK_ALL, index, &pent)); 7906 } else { 7907 if ((!IS_CPU_PORT(unit, port)) || 7908 (IS_CPU_PORT(unit, port) && (cpu_tabs & _BCM_CPU_TABS_ETHER))) { 7909 BCM_IF_ERROR_RETURN 7910 (soc_mem_fields32_modify(unit, port_tab_mem, index, 7911 port_tab_field_count, port_tab_fields, 7912 port_tab_values)); 7913 } 7914 } 7915 } 7916 7917 if (ing_dev_port_field_count != 0) { 7918 if(is_in_warm_boot) { 7919 SOC_WARM_BOOT_DONE(unit); 7920 } 7921 7922 BCM_IF_ERROR_RETURN 7923 (soc_mem_fields32_modify(unit, ING_DEVICE_PORTm, index, 7924 ing_dev_port_field_count, 7925 ing_dev_port_fields, 7926 ing_dev_port_values)); 7927 if(is_in_warm_boot) { 7928 SOC_WARM_BOOT_START(unit); 7929 } 7930 } 7931 7932 if (lport_tab_field_count != 0) { 7933 #if defined(BCM_KATANA2_SUPPORT) 7934 if (SOC_IS_KATANA2(unit) && (port > KT2_MAX_PHYSICAL_PORTS)) { 7935 /* Skip programming */; 7936 } else 7937 #endif 7938 #if defined(BCM_SABER2_SUPPORT) 7939 if (SOC_IS_SABER2(unit) && (port > SB2_MAX_PHYSICAL_PORTS)) { 7940 /* Skip programming */; 7941 } else 7942 #endif 7943 { 7944 if (is_in_warm_boot) { 7945 SOC_WARM_BOOT_DONE(unit); 7946 } 7947 7948 if (is_lport_cfg == 1) { /* remote port */ 7949 rv = bcm_esw_port_lport_fields_set(unit, port, 7950 LPORT_PROFILE_LPORT_TAB, 7951 lport_tab_field_count, 7952 lport_tab_fields, 7953 lport_tab_values); 7954 7955 if (is_in_warm_boot) { 7956 SOC_WARM_BOOT_START(unit); 7957 } 7958 return rv; 7959 } 7960 7961 BCM_IF_ERROR_RETURN 7962 (bcm_esw_port_lport_fields_set(unit, 7963 index, 7964 LPORT_PROFILE_LPORT_TAB, 7965 lport_tab_field_count, 7966 lport_tab_fields, 7967 lport_tab_values)); 7968 if (is_in_warm_boot) { 7969 SOC_WARM_BOOT_START(unit); 7970 } 7971 } 7972 } 7973 7974 /* Copy to Higig port if needed */ 7975 if (IS_CPU_PORT(unit, port) && (cpu_tabs & _BCM_CPU_TABS_HIGIG)) { 7976 cpu_hg_index = SOC_IS_KATANA2(unit) ? 7977 SOC_INFO(unit).cpu_hg_pp_port_index : 7978 SOC_INFO(unit).cpu_hg_index; 7979 7980 if (SOC_MEM_IS_VALID(unit, IPORT_TABLEm)) { 7981 if (port_tab_field_count != 0) { 7982 BCM_IF_ERROR_RETURN 7983 (soc_mem_fields32_modify(unit, IPORT_TABLEm, index, 7984 port_tab_field_count, 7985 port_tab_fields, port_tab_values)); 7986 } 7987 } else if (cpu_hg_index != -1) { 7988 if (port_tab_field_count != 0) { 7989 BCM_IF_ERROR_RETURN 7990 (soc_mem_fields32_modify(unit, port_tab_mem, cpu_hg_index, 7991 port_tab_field_count, 7992 port_tab_fields, 7993 port_tab_values)); 7994 } 7995 if (ing_dev_port_field_count != 0) { 7996 BCM_IF_ERROR_RETURN 7997 (soc_mem_fields32_modify(unit, ING_DEVICE_PORTm, 7998 cpu_hg_index, 7999 ing_dev_port_field_count, 8000 ing_dev_port_fields, 8001 ing_dev_port_values)); 8002 } 8003 if (lport_tab_field_count != 0) { 8004 if (SOC_IS_TRIDENT3X(unit)) { 8005 /* TD3TBD Should use a feature check? */ 8006 int my_modid = 0; 8007 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 8008 if (soc_feature(unit, soc_feature_lport_tab_profile)) { 8009 BCM_IF_ERROR_RETURN( 8010 bcm_esw_port_lport_profile_fields_set(unit, ptype, 8011 my_modid, cpu_hg_index, LPORT_PROFILE_LPORT_TAB, 8012 lport_tab_field_count, lport_tab_fields, 8013 lport_tab_values)); 8014 } 8015 } 8016 } 8017 } 8018 } 8019 8020 return rv; 8021 } 8022 8023 int 8024 _bcm_esw_port_tab_set_without_portlock(int unit, bcm_port_t port, int cpu_tabs, 8025 soc_field_t field, int value) 8026 { 8027 return (_bcm_esw_port_tab_multi_set(unit, port, cpu_tabs, 1, &field, 8028 (uint32*) &value)); 8029 } 8030 8031 /* 8032 * Function: 8033 * _bcm_esw_port_tab_set 8034 * Description: 8035 * Sets the port property field in the HW table. 8036 * Helper funtion for bcm_esw_port_control_set. 8037 * Parameters: 8038 * unit - Device number 8039 * port - Port number (see Notes for valid port formats) 8040 * cpu_tabs - If CPU port, which ingress tables should be written? 8041 * field - Field name within PORT_TAB table entry 8042 * value - new field value 8043 * Return Value: 8044 * BCM_E_NONE 8045 * BCM_E_XXX - an error occurred accessing PORT_TAB table. 8046 * Notes: 8047 * Due to the large number of callers for this routine, 8048 * function is expanded to take a GPORT PROXY, which 8049 * sets the property in the LPORT profile table (similar 8050 * to what was done for the GPORT_WLAN_PORT). 8051 * 8052 * Current valid port types are: 8053 * GPORT WLAN 8054 * GPORT PROXY 8055 * GPORT SUBPORT 8056 * BCM port (non-gport), assumes a valid local physical port 8057 * 8058 * For GPORT PROXY port, this routine only accesses the properties 8059 * in the LPORT table (not the RTAG7). 8060 */ 8061 int 8062 _bcm_esw_port_tab_set(int unit, bcm_port_t port, int cpu_tabs, 8063 soc_field_t field, int value) 8064 { 8065 int rv = BCM_E_UNAVAIL; 8066 8067 PORT_LOCK(unit); 8068 rv = _bcm_esw_port_tab_set_without_portlock(unit, port, cpu_tabs, field, 8069 value); 8070 PORT_UNLOCK(unit); 8071 8072 return rv; 8073 } 8074 8075 #if defined(BCM_TRX_SUPPORT) 8076 /* 8077 * Function: 8078 * _bcm_esw_iport_tab_get 8079 * Description: 8080 * Helper funtion for bcm_esw_port_control_get. 8081 * Parameters: 8082 * unit - Device number 8083 * port - Port number 8084 * field - Field name within IPORT_TAB table entry 8085 * value - (OUT) field value 8086 * Return Value: 8087 * BCM_E_NONE 8088 * BCM_E_XXX - an error occurred accessing IPORT_TAB table. 8089 */ 8090 STATIC int 8091 _bcm_esw_iport_tab_get(int unit, bcm_port_t port, 8092 soc_field_t field, int *value) 8093 { 8094 port_tab_entry_t pent; 8095 soc_mem_t mem = INVALIDm; 8096 int rv, index = -1; 8097 8098 if (SOC_MEM_IS_VALID(unit, IPORT_TABLEm)) { 8099 mem = IPORT_TABLEm; 8100 index = SOC_PORT_MOD_OFFSET(unit, port); 8101 } else if (IS_CPU_PORT(unit, port)) { 8102 int cpu_hg_index; 8103 8104 cpu_hg_index = SOC_IS_KATANA2(unit) ? 8105 SOC_INFO(unit).cpu_hg_pp_port_index : 8106 SOC_INFO(unit).cpu_hg_index; 8107 if (cpu_hg_index != -1){ 8108 mem = PORT_TABm; 8109 index = cpu_hg_index; 8110 } 8111 } 8112 if (index == -1) { 8113 return BCM_E_UNAVAIL; 8114 } 8115 8116 if (!SOC_MEM_FIELD_VALID(unit, mem, field)) { 8117 return (BCM_E_UNAVAIL); 8118 } 8119 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 8120 index, &pent); 8121 8122 if (BCM_SUCCESS(rv)) { 8123 *value = soc_mem_field32_get(unit, mem, &pent, field); 8124 } 8125 8126 return rv; 8127 } 8128 #endif /* BCM_TRX_SUPPORT */ 8129 8130 /* 8131 * Function: 8132 * _bcm_esw_port_tab_get 8133 * Description: 8134 * Helper funtion for bcm_esw_port_control_get. 8135 * Parameters: 8136 * unit - Device number 8137 * port - Port number 8138 * field - Field name within PORT_TAB table entry 8139 * value - (OUT) field value 8140 * Return Value: 8141 * BCM_E_NONE 8142 * BCM_E_XXX - an error occurred accessing PORT_TAB table. 8143 * Notes: 8144 * Due to the large number of callers for this routine, 8145 * function is expanded to take a GPORT PROXY, which 8146 * get the property from the LPORT profile table (similar 8147 * to what was done for the GPORT_WLAN_PORT). 8148 * 8149 * Current valid port types are: 8150 * GPORT WLAN 8151 * GPORT PROXY 8152 * GPORT SUBPORT 8153 * BCM port (non-gport), assumes a valid local physical port 8154 * GPORT Local 8155 * 8156 * For GPORT PROXY port, this routine only accesses the properties 8157 * in the LPORT table (not the RTAG7). 8158 */ 8159 int 8160 _bcm_esw_port_tab_get(int unit, bcm_port_t port, 8161 soc_field_t field, int *value) 8162 { 8163 int rv = BCM_E_UNAVAIL; 8164 port_tab_entry_t pent; 8165 soc_mem_t mem; 8166 int index, is_lport_cfg = 0; 8167 uint32 value32; 8168 8169 mem = SOC_PORT_MEM_TAB(unit, port); 8170 #if defined(BCM_TRIDENT3_SUPPORT) 8171 if (SOC_IS_TRIDENT3X(unit)) { 8172 _bcm_td3_port_tab_conv(unit, &field, &mem); 8173 if (mem == LPORT_TABm) { 8174 is_lport_cfg = 1; 8175 } 8176 } 8177 #endif 8178 8179 #if defined BCM_HGPROXY_COE_SUPPORT 8180 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 8181 (soc_feature(unit, soc_feature_channelized_switching))) && 8182 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 8183 is_lport_cfg = 1; 8184 } else 8185 #endif 8186 if (BCM_GPORT_IS_PROXY(port)) { 8187 is_lport_cfg = 1; 8188 } 8189 8190 /* If LPORT, then get property from LPORT table */ 8191 if (is_lport_cfg) { 8192 rv = bcm_esw_port_lport_field_get(unit, port, 8193 LPORT_PROFILE_LPORT_TAB, 8194 field, &value32); 8195 *value = value32; 8196 return rv; 8197 } 8198 8199 /* GPORT WLAN */ 8200 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 8201 && defined(INCLUDE_L3)) 8202 if (BCM_GPORT_IS_WLAN_PORT(port)) { 8203 #if defined(BCM_TRIUMPH3_SUPPORT) 8204 if (soc_feature(unit, soc_feature_axp)) { 8205 rv = bcm_tr3_wlan_lport_field_get(unit, port, field, value); 8206 } else 8207 #endif /* BCM_TRIUMPH3_SUPPORT */ 8208 if (soc_feature(unit, soc_feature_wlan)) { 8209 rv = bcm_tr2_wlan_lport_field_get(unit, port, field, value); 8210 } 8211 return rv; 8212 } 8213 #endif 8214 8215 /* At this point, 'port' needs to be a BCM port (non-gport). 8216 * convert the gport to local port. 8217 */ 8218 if (BCM_GPORT_IS_SET(port)) { 8219 BCM_IF_ERROR_RETURN( 8220 _bcm_esw_port_gport_validate(unit, port, &port)); 8221 } 8222 8223 #if defined(CANCUN_SUPPORT) 8224 if (soc_feature(unit, soc_feature_cancun)) { 8225 if (soc_cancun_cmh_check(unit, mem, field) == SOC_E_NONE) { 8226 rv = soc_cancun_cmh_mem_get(unit, mem, port, 8227 field, (void *)value); 8228 if (!BCM_SUCCESS(rv)) { 8229 return rv; 8230 } 8231 } 8232 } 8233 #endif 8234 8235 index = SOC_PORT_MOD_OFFSET(unit, port); 8236 if (!SOC_MEM_FIELD_VALID(unit, mem, field)) { 8237 return (BCM_E_UNAVAIL); 8238 } 8239 8240 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 8241 index, &pent); 8242 8243 if (BCM_SUCCESS(rv)) { 8244 *value = soc_mem_field32_get(unit, mem, &pent, field); 8245 } 8246 8247 return rv; 8248 } 8249 8250 /* 8251 * Function: 8252 * bcm_port_untagged_vlan_get 8253 * Purpose: 8254 * Retrieve the default VLAN ID for the port. 8255 * This is the VLAN ID assigned to received untagged packets. 8256 * Parameters: 8257 * unit - StrataSwitch unit number. 8258 * port - StrataSwitch port number of port to get info for 8259 * vid_ptr - (OUT) Pointer to VLAN ID for return 8260 * Returns: 8261 * BCM_E_NONE 8262 * BCM_E_INTERNAL if table read failed. 8263 */ 8264 8265 int 8266 bcm_esw_port_untagged_vlan_get(int unit, bcm_port_t port, bcm_vlan_t *vid_ptr) 8267 { 8268 bcm_port_cfg_t pcfg; 8269 int vid; 8270 int rv; 8271 8272 /* Make sure port module is initialized. */ 8273 PORT_INIT(unit); 8274 8275 if(bcm_common_oamp_port_enable_get(unit, port)) { 8276 LOG_ERROR(BSL_LS_BCM_PORT, 8277 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 8278 port)); 8279 return BCM_E_PARAM; 8280 } 8281 8282 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 8283 && defined(INCLUDE_L3)) 8284 if (BCM_GPORT_IS_WLAN_PORT(port)) { 8285 #if defined(BCM_TRIUMPH3_SUPPORT) 8286 if (SOC_IS_TRIUMPH3(unit)) { 8287 return bcm_tr3_wlan_port_untagged_vlan_get(unit, port, vid_ptr); 8288 } else 8289 #endif /* BCM_TRIUMPH3_SUPPORT */ 8290 { 8291 return bcm_tr2_wlan_port_untagged_vlan_get(unit, port, vid_ptr); 8292 } 8293 } 8294 #endif 8295 8296 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 8297 if (BCM_GPORT_IS_NIV_PORT(port)) { 8298 return bcm_trident_niv_port_untagged_vlan_get(unit, port, vid_ptr); 8299 } 8300 #endif 8301 8302 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 8303 if (BCM_GPORT_IS_EXTENDER_PORT(port)) { 8304 return bcm_tr3_extender_port_untagged_vlan_get(unit, port, vid_ptr); 8305 } 8306 #endif 8307 8308 #ifdef BCM_HGPROXY_COE_SUPPORT 8309 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 8310 (soc_feature(unit, soc_feature_channelized_switching))) && 8311 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 8312 rv = _bcm_esw_port_tab_get(unit, port, PORT_VIDf, &vid); 8313 } else 8314 #endif 8315 { 8316 BCM_IF_ERROR_RETURN( 8317 _bcm_esw_port_gport_validate(unit, port, &port)); 8318 8319 PORT_LOCK(unit); 8320 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 8321 PORT_UNLOCK(unit); 8322 vid = pcfg.pc_vlan; 8323 } 8324 8325 if (BCM_SUCCESS(rv)) { 8326 *vid_ptr = vid; 8327 } else { 8328 *vid_ptr = BCM_VLAN_INVALID; 8329 } 8330 8331 LOG_INFO(BSL_LS_BCM_PORT, 8332 (BSL_META_U(unit, 8333 "bcm_port_untagged_vlan_get: u=%d p=%d vid=%d rv=%d\n"), 8334 unit, port, *vid_ptr, rv)); 8335 8336 return rv; 8337 } 8338 8339 8340 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_SCORPION_SUPPORT) 8341 /* 8342 * Function: 8343 * _bcm_port_mmu_update 8344 * Purpose: 8345 * Adjust MMU settings depending on port status. 8346 * Parameters: 8347 * unit - StrataSwitch Unit #. 8348 * port - StrataSwitch port #. 8349 * link - True if link is active, false if link is inactive. 8350 * Returns: 8351 * BCM_E_NONE 8352 * BCM_E_XXX 8353 */ 8354 8355 STATIC int 8356 _bcm_port_mmu_update(int unit, bcm_port_t port, int link) 8357 { 8358 int pause_tx, pause_rx, q_limit_enable, cos; 8359 uint32 psl_rval, opc_rval, oqc_rval; 8360 8361 if (!SOC_IS_HBX(unit)) { 8362 return (BCM_E_UNAVAIL); 8363 } 8364 8365 if (link < 0) { 8366 SOC_IF_ERROR_RETURN 8367 (bcm_esw_port_link_status_get(unit, port, &link)); 8368 } 8369 8370 SOC_IF_ERROR_RETURN 8371 (MAC_PAUSE_GET(PORT(unit, port).p_mac, unit, port, 8372 &pause_tx, &pause_rx)); 8373 8374 SOC_IF_ERROR_RETURN(READ_PORT_SHARED_LIMITr(unit, port, &psl_rval)); 8375 SOC_IF_ERROR_RETURN(READ_OP_PORT_CONFIGr(unit, port, &opc_rval)); 8376 if (link && pause_tx) { 8377 soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval, 8378 PORT_SHARED_LIMITf, 8379 SOC_IS_SC_CQ(unit) ? 0x5 : 0x3); 8380 soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval, 8381 PORT_SHARED_DYNAMICf, 1); 8382 soc_reg_field_set(unit, OP_PORT_CONFIGr, &opc_rval, 8383 PORT_LIMIT_ENABLEf, 1); 8384 q_limit_enable = 0; 8385 } else { 8386 /* Turn off */ 8387 soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval, 8388 PORT_SHARED_LIMITf, 8389 SOC_IS_SC_CQ(unit) ? 0x3fff : 0x3000); 8390 soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval, 8391 PORT_SHARED_DYNAMICf, 0); 8392 soc_reg_field_set(unit, OP_PORT_CONFIGr, &opc_rval, 8393 PORT_LIMIT_ENABLEf, 0); 8394 q_limit_enable = 1; 8395 } 8396 SOC_IF_ERROR_RETURN(WRITE_PORT_SHARED_LIMITr(unit, port, psl_rval)); 8397 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_CONFIGr(unit, port, opc_rval)); 8398 for (cos = 0; cos < NUM_COS(unit); cos++) { 8399 SOC_IF_ERROR_RETURN 8400 (READ_OP_QUEUE_CONFIGr(unit, port, cos, &oqc_rval)); 8401 soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &oqc_rval, 8402 Q_LIMIT_ENABLEf, q_limit_enable); 8403 SOC_IF_ERROR_RETURN 8404 (WRITE_OP_QUEUE_CONFIGr(unit, port, cos, oqc_rval)); 8405 } 8406 8407 return (BCM_E_NONE); 8408 } 8409 #endif /* BCM_BRADLEY_SUPPORT || BCM_SCORPION_SUPPORT */ 8410 8411 /* 8412 * Function: 8413 * _bcm_port_untagged_vlan_set 8414 * Purpose: 8415 * Main part of bcm_port_untagged_vlan_set. 8416 * Notes: 8417 * Port does not have to be a member of the VLAN. 8418 */ 8419 8420 STATIC int 8421 _bcm_port_untagged_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vid) 8422 { 8423 bcm_port_cfg_t pcfg; 8424 int ut_prio; 8425 #if defined(BCM_FIREBOLT_SUPPORT) 8426 bcm_vlan_t pdvid; 8427 #endif /* BCM_FIREBOLT_SUPPORT */ 8428 8429 #ifdef BCM_TRX_SUPPORT 8430 if (soc_feature(unit, soc_feature_vlan_action)) { 8431 bcm_port_t local_port; 8432 bcm_vlan_action_set_t action; 8433 #if defined(BCM_TOMAHAWK_SUPPORT) 8434 bcm_port_cfg_t pcfg; 8435 #endif 8436 BCM_IF_ERROR_RETURN( 8437 _bcm_esw_port_gport_validate(unit, port, &local_port)); 8438 8439 #if defined(BCM_TOMAHAWK3_SUPPORT) 8440 if (SOC_IS_TOMAHAWK3(unit)) { 8441 BCM_IF_ERROR_RETURN 8442 (_bcm_th3_vlan_port_default_action_get(unit, port, &action)); 8443 } else 8444 #endif 8445 { 8446 BCM_IF_ERROR_RETURN 8447 (_bcm_trx_vlan_port_default_action_get(unit, port, &action)); 8448 } 8449 action.new_outer_vlan = vid; 8450 action.priority = PORT(unit, local_port).p_ut_prio; 8451 #if defined(BCM_TOMAHAWK_SUPPORT) 8452 if (soc_feature(unit, soc_feature_decouple_protocol_vlan)){ 8453 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, &action)); 8454 BCM_IF_ERROR_RETURN 8455 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 8456 pcfg.pc_vlan = action.new_outer_vlan; 8457 if (action.priority >= BCM_PRIO_MIN && 8458 action.priority <= BCM_PRIO_MAX) { 8459 pcfg.pc_new_opri = action.priority; 8460 } 8461 return (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 8462 } 8463 #endif /* BCM_TOMAHAWK2_SUPPORT */ 8464 #if defined(BCM_TOMAHAWK3_SUPPORT) 8465 if(SOC_IS_TOMAHAWK3(unit)) { 8466 return _bcm_th3_vlan_port_default_action_set(unit, port, &action); 8467 } else 8468 #endif 8469 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 8470 if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 8471 return _bcm_trx_vlan_port_default_action_profile_set(unit, port, &action); 8472 } else 8473 #endif 8474 { 8475 return _bcm_trx_vlan_port_default_action_set(unit, port, &action); 8476 } 8477 } 8478 #endif 8479 8480 BCM_IF_ERROR_RETURN 8481 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 8482 8483 #if defined(BCM_FIREBOLT_SUPPORT) 8484 pdvid = pcfg.pc_vlan; 8485 #endif /* BCM_FIREBOLT_SUPPORT */ 8486 pcfg.pc_vlan = vid; 8487 8488 BCM_IF_ERROR_RETURN 8489 (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 8490 8491 #if defined(BCM_FIREBOLT_SUPPORT) 8492 if (SOC_IS_FBX(unit)) { 8493 /* 8494 * Update default VLAN ID in VLAN_PROTOCOL_DATA 8495 */ 8496 int rv = _bcm_fb_port_untagged_vlan_data_update(unit, port, 8497 pdvid, vid); 8498 if (rv != BCM_E_NONE) { 8499 LOG_ERROR(BSL_LS_BCM_PORT, 8500 (BSL_META_U(unit, 8501 "failed updating default VLAN ID " 8502 "in VLAN_PROTOCOL_DATA: %s\n"), bcm_errmsg(rv))); 8503 } 8504 } 8505 #endif /* BCM_FIREBOLT_SUPPORT */ 8506 8507 if (!soc_feature(unit, soc_feature_remap_ut_prio)) { 8508 /* Reset the untagged port priority filter entry, if any */ 8509 8510 BCM_IF_ERROR_RETURN 8511 (bcm_esw_port_untagged_priority_get(unit, port, &ut_prio)); 8512 8513 BCM_IF_ERROR_RETURN 8514 (bcm_esw_port_untagged_priority_set(unit, port, ut_prio)); 8515 } 8516 8517 return BCM_E_NONE; 8518 } 8519 8520 /* 8521 * Function: 8522 * bcm_port_untagged_vlan_set 8523 * Purpose: 8524 * Set the default VLAN ID for the port. 8525 * This is the VLAN ID assigned to received untagged packets. 8526 * Parameters: 8527 * unit - StrataSwitch unit number. 8528 * port - StrataSwitch port number. 8529 * vid - VLAN ID used for packets that ingress the port untagged 8530 * Returns: 8531 * BCM_E_NONE 8532 * BCM_E_NOT_FOUND if vid not in VTABLE 8533 * BCM_E_INTERNAL if table read failed. 8534 * BCM_E_CONFIG - port does not belong to the VLAN 8535 * Notes: 8536 * BCM_LOCK is used because bcm_vlan_port_get is called internally 8537 * which also takes it. BCM_LOCK must be taken before PORT_LOCK. 8538 */ 8539 8540 int 8541 bcm_esw_port_untagged_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vid) 8542 { 8543 int rv; 8544 8545 VLAN_CHK_ID(unit, vid); 8546 8547 /* Make sure port module is initialized. */ 8548 PORT_INIT(unit); 8549 8550 if(bcm_common_oamp_port_enable_get(unit, port)) { 8551 LOG_ERROR(BSL_LS_BCM_PORT, 8552 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 8553 port)); 8554 return BCM_E_PARAM; 8555 } 8556 8557 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 8558 && defined(INCLUDE_L3)) 8559 if (BCM_GPORT_IS_WLAN_PORT(port)) { 8560 #if defined(BCM_TRIUMPH3_SUPPORT) 8561 if (SOC_IS_TRIUMPH3(unit)) { 8562 return bcm_tr3_wlan_port_untagged_vlan_set(unit, port, vid); 8563 } else 8564 #endif /* BCM_TRIUMPH3_SUPPORT */ 8565 { 8566 return bcm_tr2_wlan_port_untagged_vlan_set(unit, port, vid); 8567 } 8568 } 8569 #endif 8570 8571 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 8572 if (BCM_GPORT_IS_NIV_PORT(port)) { 8573 return bcm_trident_niv_port_untagged_vlan_set(unit, port, vid); 8574 } 8575 #endif 8576 8577 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 8578 if (BCM_GPORT_IS_EXTENDER_PORT(port)) { 8579 return bcm_tr3_extender_port_untagged_vlan_set(unit, port, vid); 8580 } 8581 #endif 8582 8583 #ifdef BCM_HGPROXY_COE_SUPPORT 8584 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 8585 (soc_feature(unit, soc_feature_channelized_switching))) && 8586 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 8587 } else 8588 #endif 8589 { 8590 BCM_IF_ERROR_RETURN( 8591 _bcm_esw_port_gport_validate(unit, port, &port)); 8592 } 8593 8594 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TD2P_TT2P(unit) || 8595 SOC_IS_TRIDENT3X(unit) || 8596 SOC_IS_KATANAX(unit) || SOC_IS_SABER2(unit)) { 8597 BCM_IF_ERROR_RETURN 8598 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 8599 PORT_VIDf, vid)); 8600 } 8601 8602 PORT_LOCK(unit); 8603 rv = _bcm_port_untagged_vlan_set(unit, port, vid); 8604 PORT_UNLOCK(unit); 8605 8606 LOG_INFO(BSL_LS_BCM_PORT, 8607 (BSL_META_U(unit, 8608 "bcm_port_untagged_vlan_set: u=%d p=%d vid=%d rv=%d\n"), 8609 unit, port, vid, rv)); 8610 8611 return rv; 8612 } 8613 8614 /* 8615 * Function: 8616 * _bcm_esw_port_ingress_dest_enable 8617 * Purpose: 8618 * Enables/disables all forwarding to port in the last stage 8619 * of the ingress pipeline, including SOBMH and all 8620 * other types of traffic. Works for all egress ports, 8621 * including CPU port. 8622 * Parameters: 8623 * unit - (IN) Device number. 8624 * port - (IN) Port number. 8625 * enable - (IN) TRUE, forward traffic 8626 * FALSE, block traffic 8627 * Returns: 8628 * BCM_E_XXX 8629 */ 8630 int 8631 _bcm_esw_port_ingress_dest_enable(int unit, bcm_port_t port, int enable) 8632 { 8633 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT) 8634 ing_dest_port_enable_entry_t dest_e; 8635 bcm_pbmp_t dest_e_pbmp; 8636 sal_usecs_t delay; 8637 int speed; 8638 int change = FALSE; 8639 8640 SOC_IF_ERROR_RETURN 8641 (READ_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ANY, 0, &dest_e)); 8642 8643 soc_mem_pbmp_field_get(unit, ING_DEST_PORT_ENABLEm, 8644 &dest_e, PORT_BITMAPf, &dest_e_pbmp); 8645 8646 if (enable) { 8647 if (!SOC_PBMP_MEMBER(dest_e_pbmp, port)) { 8648 SOC_PBMP_PORT_ADD(dest_e_pbmp, port); 8649 change = TRUE; 8650 } 8651 } else { 8652 if (SOC_PBMP_MEMBER(dest_e_pbmp, port)) { 8653 SOC_PBMP_PORT_REMOVE(dest_e_pbmp, port); 8654 change = TRUE; 8655 } 8656 } 8657 8658 if (change) { 8659 soc_mem_pbmp_field_set(unit, ING_DEST_PORT_ENABLEm, 8660 &dest_e, PORT_BITMAPf, &dest_e_pbmp); 8661 SOC_IF_ERROR_RETURN 8662 (WRITE_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ANY, 0, &dest_e)); 8663 8664 /* 8665 * On a disable operation, ensure that no further cells 8666 * arrive to MMU in order to reconfigure the MMU safely, 8667 * and the flush mechanism in the MMU to work properly. 8668 * 8669 * This requires a delay to ensure packet EOP has arrived at MMU 8670 * (the is the only method. The time is based on the largest 8671 * possible frame at the slowest possible source port speed. 8672 */ 8673 if (!enable) { 8674 BCM_IF_ERROR_RETURN 8675 (bcm_esw_port_speed_get(unit, port, &speed)); 8676 8677 if ((speed == 10) || (speed == 100)) { 8678 delay = 8000; /* 8 msecs */ 8679 } else { 8680 /* 8681 * This assumes the CPU port can sustain 1GE performance 8682 * over the duration of an MTU. 8683 */ 8684 delay = 80; /* 80 usecs */ 8685 } 8686 sal_udelay(delay); 8687 } 8688 } 8689 8690 return BCM_E_NONE; 8691 #else /* BCM_TRIDENT2PLUS_SUPPORT */ 8692 return BCM_E_UNAVAIL; 8693 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 8694 } 8695 8696 /* 8697 * Function: 8698 * _bcmi_esw_port_linkphy_subport_dfc_update 8699 * Purpose: 8700 * Updates the DFC for the stream ids associated with Linkphy gport. 8701 * Parameters: 8702 * unit - (IN) Device number. 8703 * subport_gport - (IN) Linkphy gport. 8704 * enable - (IN) Port enable/disable status. 8705 * Returns: 8706 * BCM_E_XXX 8707 */ 8708 8709 #ifdef BCM_KATANA2_SUPPORT 8710 int 8711 _bcmi_esw_port_linkphy_subport_dfc_update(int unit, bcm_port_t subport_gport, 8712 int enable) 8713 { 8714 bcm_subport_config_t config; 8715 int stream_id = 0; 8716 8717 BCM_IF_ERROR_RETURN(bcm_esw_subport_port_get(unit, subport_gport, &config)); 8718 8719 /* Run through the streams and perform needed actions */ 8720 for (stream_id = 0; stream_id < config.num_streams; stream_id++) { 8721 BCM_IF_ERROR_RETURN(_bcmi_linkphy_subport_stream_dfc_update(unit, 8722 &config, 8723 _BCM_KT2_SUBPORT_PORT_ID_GET(subport_gport), 8724 config.stream_id_array[stream_id], enable)); 8725 } 8726 8727 return BCM_E_NONE; 8728 } 8729 8730 int 8731 _bcmi_esw_port_linkphy_subport_flush(int unit, bcm_port_t subport_gport) 8732 { 8733 bcm_subport_config_t config; 8734 int stream_id = 0; 8735 8736 BCM_IF_ERROR_RETURN(bcm_esw_subport_port_get(unit, subport_gport, &config)); 8737 8738 /* Run through the streams and perform needed actions */ 8739 for (stream_id = 0; stream_id < config.num_streams; stream_id++) { 8740 BCM_IF_ERROR_RETURN(_bcmi_linkphy_subport_stream_flush(unit, 8741 &config, 8742 _BCM_KT2_SUBPORT_PORT_ID_GET(subport_gport), 8743 config.stream_id_array[stream_id])); 8744 } 8745 8746 return BCM_E_NONE; 8747 } 8748 #endif 8749 8750 /* 8751 * Function: 8752 * _bcmi_esw_port_subport_enable_set 8753 * Purpose: 8754 * Enable/disable a subport. 8755 * Parameters: 8756 * unit - StrataSwitch unit #. 8757 * port - StrataSwitch port #. 8758 * is_subtag_port - TRUE if this is subtag port, linkphy otherwise 8759 * enable - TRUE, port is enabled, FALSE port is disabled. 8760 * Returns: 8761 * BCM_E_XXX 8762 */ 8763 int 8764 _bcmi_esw_port_subport_enable_set(int unit, bcm_port_t port, 8765 int is_subtag_port, int enable) 8766 { 8767 8768 int rv = BCM_E_NONE; 8769 8770 #ifdef BCM_KATANA2_SUPPORT 8771 pbmp_t mask; 8772 int subport_gport = port; 8773 8774 BCM_IF_ERROR_RETURN( 8775 _bcm_esw_port_gport_validate(unit, port, &port)); 8776 8777 /* Set/Unset the port in the relevant enabled pbmp */ 8778 if(is_subtag_port) { 8779 8780 /* Check if the setting is already in effect */ 8781 if((enable && 8782 BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_subtag_pp_port_pbm, 8783 port)) || 8784 (!enable && 8785 !(BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_subtag_pp_port_pbm, 8786 port)))) { 8787 /* Already in effect, return OK */ 8788 return BCM_E_NONE; 8789 } 8790 8791 if(enable) { 8792 BCM_PBMP_PORT_ADD(SOC_INFO(unit).enabled_subtag_pp_port_pbm, 8793 port); 8794 } else { 8795 BCM_PBMP_PORT_REMOVE(SOC_INFO(unit).enabled_subtag_pp_port_pbm, 8796 port); 8797 } 8798 } else { 8799 8800 /* Check if the setting is already in effect */ 8801 if((enable && 8802 BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_linkphy_pp_port_pbm, 8803 port)) || 8804 (!enable && 8805 !(BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_linkphy_pp_port_pbm, 8806 port)))) { 8807 /* Already in effect, return OK */ 8808 return BCM_E_NONE; 8809 } 8810 8811 if(enable) { 8812 BCM_PBMP_PORT_ADD(SOC_INFO(unit).enabled_linkphy_pp_port_pbm, 8813 port); 8814 } else { 8815 BCM_PBMP_PORT_REMOVE(SOC_INFO(unit).enabled_linkphy_pp_port_pbm, 8816 port); 8817 } 8818 } 8819 8820 /* Get the current mask */ 8821 soc_link_mask2_get(unit, &mask); 8822 /* Make a call so that the enable/disable we did above take effect, 8823 * note that 'soc_link_mask2_set' works on the pbmps we updated above, 8824 * we still pass the existing bpmp since it gets re-assigned 8825 */ 8826 SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask)); 8827 8828 /* Some special processing needed for enable/disable of LinkPhy ports */ 8829 if (!is_subtag_port) { 8830 8831 /* Updates DFC for the streams */ 8832 BCM_IF_ERROR_RETURN(_bcmi_esw_port_linkphy_subport_dfc_update(unit, 8833 subport_gport, enable)); 8834 if (!enable) { 8835 /* Flush the related MMU queues */ 8836 BCM_IF_ERROR_RETURN(bcm_kt2_cosq_port_flush(unit, 8837 port, bcmCosqFlushTypeQueue)); 8838 8839 /* Flush the relevant RXLP */ 8840 BCM_IF_ERROR_RETURN(_bcmi_esw_port_linkphy_subport_flush(unit, 8841 subport_gport)); 8842 } 8843 } 8844 8845 #endif 8846 8847 return rv; 8848 } 8849 8850 /* 8851 * Function: 8852 * _bcmi_esw_port_subport_enable_get 8853 * Purpose: 8854 * Get Enable/disable state of a subport. 8855 * Parameters: 8856 * unit - StrataSwitch unit #. 8857 * port - StrataSwitch port #. 8858 * is_subtag_port - TRUE if this is subtag port, linkphy otherwise 8859 * *enable - Return enable value. 8860 * Returns: 8861 * BCM_E_XXX 8862 */ 8863 int 8864 _bcmi_esw_port_subport_enable_get(int unit, bcm_port_t port, 8865 int is_subtag_port, int *enable) 8866 { 8867 int rv = BCM_E_NONE; 8868 8869 #ifdef BCM_KATANA2_SUPPORT 8870 /* Start with enabled set to 0 */ 8871 *enable = 0; 8872 8873 BCM_IF_ERROR_RETURN( 8874 _bcm_esw_port_gport_validate(unit, port, &port)); 8875 8876 /* Depending on subtag/linkphy, check if the port is enabled */ 8877 if(is_subtag_port) { 8878 if (BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_subtag_pp_port_pbm, 8879 port)) { 8880 *enable = 1; 8881 } 8882 } else { 8883 if (BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_linkphy_pp_port_pbm, 8884 port)) { 8885 *enable = 1; 8886 } 8887 } 8888 rv = BCM_E_NONE; 8889 #endif 8890 8891 return rv; 8892 } 8893 8894 /* 8895 * Function: 8896 * bcm_port_enable_set 8897 * Purpose: 8898 * Physically enable/disable the MAC/PHY on this port. 8899 * Parameters: 8900 * unit - StrataSwitch unit #. 8901 * port - StrataSwitch port #. 8902 * enable - TRUE, port is enabled, FALSE port is disabled. 8903 * Returns: 8904 * BCM_E_XXX 8905 * Notes: 8906 * If linkscan is running, it also controls the MAC enable state. 8907 */ 8908 8909 int 8910 bcm_esw_port_enable_set(int unit, bcm_port_t port, int enable) 8911 { 8912 int rv = BCM_E_NONE; 8913 int link, loopback = BCM_PORT_LOOPBACK_NONE; 8914 pbmp_t mask; 8915 8916 #if defined (BCM_TRIUMPH3_SUPPORT) || defined (BCM_MONTEREY_SUPPPORT) 8917 int skip_phy_en = 0; 8918 #endif /* BCM_TRIUMPH3_SUPPORT */ 8919 soc_persist_t *sop = SOC_PERSIST(unit); 8920 8921 #if defined(BCM_KATANA2_SUPPORT) 8922 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 8923 uint8 is_subtag_port = FALSE, is_linkphy_port = FALSE; 8924 #endif 8925 /* Make sure port module is initialized. */ 8926 PORT_INIT(unit); 8927 8928 #ifdef BCM_KATANA2_SUPPORT 8929 if(BCM_GPORT_IS_SUBPORT_PORT(port)) { 8930 if (soc_feature(unit, soc_feature_subtag_coe) && 8931 _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 8932 is_subtag_port = TRUE; 8933 } else if (soc_feature(unit, soc_feature_linkphy_coe) && 8934 _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)) { 8935 is_linkphy_port = TRUE; 8936 } 8937 if(is_subtag_port || is_linkphy_port) { 8938 PORT_LOCK(unit); 8939 rv = _bcmi_esw_port_subport_enable_set(unit, port, 8940 is_subtag_port, enable); 8941 PORT_UNLOCK(unit); 8942 return rv; 8943 } 8944 } 8945 #endif 8946 8947 /* Call Port Control module */ 8948 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 8949 return (bcmi_esw_portctrl_enable_set(unit, port, enable)); 8950 } 8951 8952 if(bcm_common_oamp_port_enable_get(unit, port)) { 8953 LOG_ERROR(BSL_LS_BCM_PORT, 8954 (BSL_META("Error: Cannot enable OAMP Port %d.\n"), 8955 port)); 8956 return BCM_E_PARAM; 8957 } 8958 8959 #if defined(BCM_KATANA2_SUPPORT) 8960 #if defined(BCM_SABER2_SUPPORT) 8961 if(SOC_IS_SABER2(unit)) { 8962 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 8963 } 8964 #endif 8965 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 8966 (!((port >= 1) && (port <= max_phy_port)))) { 8967 return BCM_E_PORT; 8968 } 8969 #endif 8970 8971 if (!BCM_GPORT_IS_SET(port)) { 8972 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)) { 8973 return BCM_E_PORT; 8974 } 8975 } 8976 8977 BCM_IF_ERROR_RETURN( 8978 _bcm_esw_port_gport_validate(unit, port, &port)); 8979 8980 #ifdef BCM_RCPU_SUPPORT 8981 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 8982 return BCM_E_PORT; 8983 } 8984 #endif /* BCM_RCPU_SUPPORT */ 8985 8986 #ifdef BCM_TRIUMPH3_SUPPORT 8987 if (SOC_IS_TRIUMPH3(unit) && !enable) { 8988 _bcm_esw_ibod_syn_port_down(unit, port); 8989 } 8990 #endif /* BCM_TRIUMPH3_SUPPORT */ 8991 8992 PORT_LOCK(unit); 8993 8994 bcm_esw_port_loopback_get(unit, port, &loopback); 8995 8996 if (enable) { 8997 if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) { 8998 PORT_UNLOCK(unit); 8999 return BCM_E_NONE; 9000 } 9001 9002 #ifdef BCM_TRIUMPH3_SUPPORT 9003 if (!skip_phy_en) { 9004 #endif /* BCM_TRIUMPH3_SUPPORT */ 9005 #ifdef BCM_TRIDENT2_SUPPORT 9006 /* 9007 * When the PHY is TSC and port is configured to MAC loopback, 9008 * need to unsquelch TX LANE. 9009 */ 9010 if ((SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit)) 9011 && !(SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) 9012 && (loopback == BCM_PORT_LOOPBACK_MAC)) { 9013 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, FALSE); 9014 } 9015 #endif /* BCM_TRIDENT2_SUPPORT */ 9016 rv = soc_phyctrl_enable_set(unit, port, TRUE); 9017 #ifdef BCM_TRIUMPH3_SUPPORT 9018 } 9019 #endif /* BCM_TRIUMPH3_SUPPORT */ 9020 if (SOC_SUCCESS(rv)) { 9021 /* Get link status after PHY state has been set */ 9022 rv = bcm_esw_port_link_status_get(unit, port, &link); 9023 if (BCM_FAILURE(rv)) { 9024 if (rv == BCM_E_INIT) { 9025 link = FALSE; 9026 rv = BCM_E_NONE; 9027 } else { 9028 PORT_UNLOCK(unit); 9029 return rv; 9030 } 9031 } 9032 9033 if (link || (loopback != BCM_PORT_LOOPBACK_NONE) 9034 || SOC_PBMP_MEMBER(sop->lc_pbm_fc, port) 9035 || SOC_PBMP_MEMBER(sop->lc_pbm_linkdown_tx, port)) { 9036 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE); 9037 if (loopback == BCM_PORT_LOOPBACK_MAC) { 9038 /* Add port to EPC_LINK */ 9039 soc_link_mask2_get(unit, &mask); 9040 SOC_PBMP_PORT_ADD(mask, port); 9041 rv = soc_link_mask2_set(unit, mask); 9042 if (BCM_FAILURE(rv)) { 9043 PORT_UNLOCK(unit); 9044 return (rv); 9045 } 9046 } 9047 } 9048 } 9049 9050 if (SOC_SUCCESS(rv)) { 9051 /* Enable forwarding traffic */ 9052 if (soc_feature(unit, soc_feature_ingress_dest_port_enable)) { 9053 rv = _bcm_esw_port_ingress_dest_enable(unit, port, enable); 9054 if (BCM_FAILURE(rv)) { 9055 PORT_UNLOCK(unit); 9056 return rv; 9057 } 9058 } 9059 } 9060 9061 } else { 9062 9063 /* Disable all forwarding traffic */ 9064 if (soc_feature(unit, soc_feature_ingress_dest_port_enable)) { 9065 rv = _bcm_esw_port_ingress_dest_enable(unit, port, enable); 9066 if (BCM_FAILURE(rv)) { 9067 PORT_UNLOCK(unit); 9068 return rv; 9069 } 9070 } 9071 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) 9072 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 9073 bcm_port_info_t tmp_port_info; 9074 bcm_port_info_t_init(&tmp_port_info); 9075 tmp_port_info.linkstatus = BCM_PORT_LINK_STATUS_DOWN; 9076 SOC_LINKSCAN_MODPORT_MAP_LOCK(unit); 9077 rv = _bcm_td_stk_modport_map_linkscan_handler(unit, port, 9078 &tmp_port_info); 9079 SOC_LINKSCAN_MODPORT_MAP_UNLOCK(unit); 9080 if (BCM_FAILURE(rv)) { 9081 PORT_UNLOCK(unit); 9082 return (rv); 9083 } 9084 } 9085 #endif /* #(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) */ 9086 /* Remove from EPC_LINK to prevent packet queued to this port from TX */ 9087 soc_link_mask2_get(unit, &mask); 9088 SOC_PBMP_PORT_REMOVE(mask, port); 9089 rv = soc_link_mask2_set(unit, mask); 9090 if (BCM_FAILURE(rv)) { 9091 PORT_UNLOCK(unit); 9092 return (rv); 9093 } 9094 #ifdef BCM_HURRICANE4_SUPPORT 9095 /* Wait 8ms. For non-MAC LB case its handled in MAC RESET */ 9096 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port) && 9097 (loopback == BCM_PORT_LOOPBACK_MAC)) { 9098 int wait_us = 8000; 9099 if (SAL_BOOT_QUICKTURN) { 9100 wait_us += 10000; 9101 } 9102 sal_usleep(wait_us); 9103 } 9104 #endif 9105 LOG_VERBOSE(BSL_LS_BCM_PORT, 9106 (BSL_META_U(unit, 9107 "Disable and isolate port %d..\n"), 9108 port)); 9109 if ((!SOC_IS_TD2_TT2(unit) && (loopback != BCM_PORT_LOOPBACK_MAC)) || 9110 (SOC_IS_TOMAHAWKX(unit) && (loopback != BCM_PORT_LOOPBACK_MAC))) { 9111 /* Disable MAC RX to prevent traffic going into this port */ 9112 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 9113 SOC_MAC_CONTROL_RX_SET, FALSE); 9114 sal_udelay(100); /* Wait for 1 jumbo packet transmission time */ 9115 } 9116 9117 #ifdef BCM_KATANA_SUPPORT 9118 if (SOC_IS_KATANA(unit)) { 9119 /* 9120 * When the port is configured to MAC loopback, 9121 * can't disabling MAC. 9122 * But in Saber2, credits are released when MAC goes down. 9123 */ 9124 if (SOC_IS_SABER2(unit) || (loopback != BCM_PORT_LOOPBACK_MAC)) { 9125 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE); 9126 } 9127 if ((SOC_SUCCESS(rv))) { 9128 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 9129 SOC_MAC_CONTROL_DISABLE_PHY, TRUE); 9130 rv = soc_phyctrl_enable_set(unit, port, FALSE); 9131 if (BCM_FAILURE(rv)) { 9132 LOG_WARN(BSL_LS_BCM_PORT, 9133 (BSL_META_U(unit, 9134 "u=%d p=%d soc_phyctrl_enable_set rv=%d\n"), 9135 unit, port, rv)); 9136 } 9137 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 9138 SOC_MAC_CONTROL_DISABLE_PHY, FALSE); 9139 } 9140 } else 9141 #endif /* BCM_KATANA_SUPPORT */ 9142 { 9143 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 9144 SOC_MAC_CONTROL_DISABLE_PHY, TRUE); 9145 9146 #ifdef BCM_TRIDENT2_SUPPORT 9147 /* 9148 * When the PHY is TSC and port is configured to MAC loopback, 9149 * need to squelch the TX lane instead of disabling PHY. 9150 */ 9151 if ((SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit)) 9152 && !(SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) 9153 && (loopback == BCM_PORT_LOOPBACK_MAC)) { 9154 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, TRUE); 9155 } else 9156 #endif /* BCM_TRIDENT2_SUPPORT */ 9157 { 9158 rv = soc_phyctrl_enable_set(unit, port, FALSE); 9159 } 9160 9161 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 9162 SOC_MAC_CONTROL_DISABLE_PHY, FALSE); 9163 /* 9164 * When the port is configured to MAC loopback, 9165 * can't disabling MAC. 9166 */ 9167 if (SOC_IS_SABER2(unit) || (loopback != BCM_PORT_LOOPBACK_MAC)) { 9168 if (SOC_SUCCESS(rv)) { 9169 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE); 9170 } 9171 } 9172 } 9173 } 9174 9175 #ifdef BCM_SABER2_SUPPORT 9176 if (SOC_IS_SABER2(unit)) { 9177 rv = soc_saber2_port_enable_set(unit, port, enable); 9178 if (BCM_FAILURE(rv)) { 9179 LOG_WARN(BSL_LS_BCM_PORT, 9180 (BSL_META_U(unit, 9181 "u=%d p=%d soc_saber2_port_enable_set rv=%d\n"), 9182 unit, port, rv)); 9183 } 9184 } else 9185 #endif 9186 #ifdef BCM_KATANA2_SUPPORT 9187 if (SOC_IS_KATANA2(unit)) { 9188 rv = soc_katana2_port_enable_set(unit, port, enable); 9189 if (BCM_FAILURE(rv)) { 9190 LOG_WARN(BSL_LS_BCM_PORT, 9191 (BSL_META_U(unit, 9192 "u=%d p=%d soc_katana2_port_enable_set rv=%d\n"), 9193 unit, port, rv)); 9194 } 9195 } 9196 #endif 9197 #ifdef BCM_TRIDENT2_SUPPORT 9198 if (SOC_IS_TD2_TT2(unit)) { 9199 PORT(unit, port).enable = enable; 9200 } 9201 #endif /* BCM_TRIDENT2_SUPPORT */ 9202 9203 #ifdef SW_AUTONEG_SUPPORT 9204 rv = _bcm_esw_port_notify_link_down_evt(unit, port); 9205 if (BCM_FAILURE(rv)) { 9206 LOG_WARN(BSL_LS_BCM_PORT, 9207 (BSL_META_U(unit, 9208 "u=%d p=%d NOTIFY LINK DOWN EVT rv=%d\n"), 9209 unit, port, rv)); 9210 PORT_UNLOCK(unit); 9211 return rv; 9212 } 9213 #endif 9214 9215 PORT_UNLOCK(unit); 9216 9217 if (loopback != BCM_PORT_LOOPBACK_NONE) { 9218 if (loopback == BCM_PORT_LOOPBACK_MAC) { 9219 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, TRUE); 9220 } else { 9221 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, enable); 9222 } 9223 } 9224 LOG_INFO(BSL_LS_BCM_PORT, 9225 (BSL_META_U(unit, 9226 "bcm_port_enable_set: u=%d p=%d enable=%d rv=%d\n"), 9227 unit, port, enable, rv)); 9228 9229 #ifdef BCM_WARM_BOOT_SUPPORT 9230 SOC_CONTROL_LOCK(unit); 9231 SOC_CONTROL(unit)->scache_dirty = 1; 9232 SOC_CONTROL_UNLOCK(unit); 9233 #endif 9234 9235 return rv; 9236 } 9237 9238 /* 9239 * Function: 9240 * bcm_port_enable_get 9241 * Purpose: 9242 * Gets the enable state as defined by bcm_port_enable_set() 9243 * Parameters: 9244 * unit - StrataSwitch unit #. 9245 * port - StrataSwitch port #. 9246 * enable - (OUT) TRUE, port is enabled, FALSE port is disabled. 9247 * Returns: 9248 * BCM_E_XXX 9249 * Notes: 9250 * The PHY enable holds the port enable state set by the user. 9251 * The MAC enable transitions up and down automatically via linkscan 9252 * even if user port enable is always up. 9253 */ 9254 9255 int 9256 bcm_esw_port_enable_get(int unit, bcm_port_t port, int *enable) 9257 { 9258 int rv=BCM_E_NONE; 9259 #if defined(BCM_KATANA2_SUPPORT) 9260 uint8 is_subtag_port = FALSE, is_linkphy_port = FALSE; 9261 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 9262 #endif 9263 9264 /* Make sure port module is initialized. */ 9265 PORT_INIT(unit); 9266 9267 /* Check for PortMod */ 9268 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 9269 return bcmi_esw_portctrl_enable_get(unit, port, enable); 9270 } 9271 9272 if(bcm_common_oamp_port_enable_get(unit, port)) { 9273 LOG_ERROR(BSL_LS_BCM_PORT, 9274 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 9275 port)); 9276 return BCM_E_PARAM; 9277 } 9278 9279 #if defined(BCM_KATANA2_SUPPORT) 9280 #if defined(BCM_SABER2_SUPPORT) 9281 if(SOC_IS_SABER2(unit)) { 9282 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 9283 } 9284 #endif 9285 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 9286 (!((port >= 1) && (port <= max_phy_port)))) { 9287 return BCM_E_PORT; 9288 } 9289 #endif 9290 9291 9292 #ifdef BCM_KATANA2_SUPPORT 9293 if(BCM_GPORT_IS_SUBPORT_PORT(port)) { 9294 if (soc_feature(unit, soc_feature_subtag_coe) && 9295 _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 9296 is_subtag_port = TRUE; 9297 } else if (soc_feature(unit, soc_feature_linkphy_coe) && 9298 _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)) { 9299 is_linkphy_port = TRUE; 9300 } 9301 9302 if (is_subtag_port || is_linkphy_port) { 9303 return _bcmi_esw_port_subport_enable_get(unit, port, 9304 is_subtag_port, enable); 9305 } 9306 } 9307 #endif 9308 9309 BCM_IF_ERROR_RETURN( 9310 _bcm_esw_port_gport_validate(unit, port, &port)); 9311 9312 if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) { 9313 *enable = 0; 9314 return BCM_E_NONE; 9315 } 9316 9317 PORT_LOCK(unit); 9318 rv = soc_phyctrl_enable_get(unit, port, enable); 9319 #ifdef BCM_TRIDENT2_SUPPORT 9320 if (SOC_IS_TD2_TT2(unit)) { 9321 *enable = (PORT(unit, port).enable) & (*enable); 9322 } 9323 #endif /* BCM_TRIDENT2_SUPPORT */ 9324 9325 PORT_UNLOCK(unit); 9326 9327 LOG_INFO(BSL_LS_BCM_PORT, 9328 (BSL_META_U(unit, 9329 "bcm_port_enable_get: u=%d p=%d rv=%d enable=%d\n"), 9330 unit, port, rv, *enable)); 9331 9332 return rv; 9333 } 9334 9335 /* 9336 * Function: 9337 * _bcm_port_mode_setup 9338 * Purpose: 9339 * Set initial operating mode for a port. 9340 * Parameters: 9341 * unit - StrataSwitch unit #. 9342 * port - StrataSwitch port #. 9343 * enable - Whether to enable or disable 9344 * Returns: 9345 * BCM_E_XXX 9346 * Notes: 9347 * Must be called with PORT_LOCK held. 9348 */ 9349 9350 int 9351 _bcm_port_mode_setup(int unit, bcm_port_t port, int enable) 9352 { 9353 soc_port_if_t pif; 9354 bcm_port_ability_t local_pa, advert_pa; 9355 9356 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 9357 return (bcmi_esw_portctrl_mode_setup(unit, port, enable)); 9358 } 9359 9360 sal_memset(&local_pa, 0, sizeof(bcm_port_ability_t)); 9361 sal_memset(&advert_pa, 0, sizeof(bcm_port_ability_t)); 9362 9363 LOG_INFO(BSL_LS_BCM_PORT, 9364 (BSL_META_U(unit, 9365 "_bcm_port_mode_setup: u=%d p=%d\n"), unit, port)); 9366 9367 SOC_IF_ERROR_RETURN(bcm_esw_port_ability_local_get(unit, port, &local_pa)); 9368 9369 if (IS_TDM_PORT(unit, port)) { 9370 return BCM_E_NONE; 9371 } 9372 9373 /* If MII supported, enable it, otherwise use TBI */ 9374 if (local_pa.interface & (SOC_PA_INTF_MII | SOC_PA_INTF_GMII | 9375 SOC_PA_INTF_SGMII | SOC_PA_INTF_XGMII)) { 9376 if (IS_GE_PORT(unit, port)) { 9377 pif = SOC_PORT_IF_GMII; 9378 } else if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)) { 9379 if (local_pa.interface & SOC_PA_INTF_XGMII) { 9380 pif = SOC_PORT_IF_XGMII; 9381 } else { /* external GbE phy in xe port mode */ 9382 pif = SOC_PORT_IF_SGMII; 9383 } 9384 } else { 9385 pif = SOC_PORT_IF_MII; 9386 } 9387 } else if (local_pa.interface & SOC_PA_INTF_CGMII) { 9388 pif = SOC_PORT_IF_CGMII; 9389 } else { 9390 pif = SOC_PORT_IF_TBI; 9391 } 9392 9393 SOC_IF_ERROR_RETURN 9394 (soc_phyctrl_interface_set(unit, port, pif)); 9395 SOC_IF_ERROR_RETURN 9396 (MAC_INTERFACE_SET(PORT(unit, port).p_mac, unit, port, pif)); 9397 9398 if (IS_ST_PORT(unit, port)) { 9399 9400 /* Since stacking port doesn't support flow control, 9401 * make sure that PHY is not advertising flow control capabilities. 9402 */ 9403 SOC_IF_ERROR_RETURN( 9404 soc_phyctrl_ability_advert_get(unit, port, &advert_pa)); 9405 advert_pa.pause &= ~(SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM); 9406 SOC_IF_ERROR_RETURN( 9407 soc_phyctrl_ability_advert_set(unit, port, &advert_pa)); 9408 } 9409 9410 if (!SOC_WARM_BOOT(unit) && 9411 !(SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) ) { 9412 #ifdef BCM_RCPU_SUPPORT 9413 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 9414 /* Do not enable/disable rcpu port. */ 9415 return BCM_E_NONE; 9416 } 9417 #endif /* BCM_RCPU_SUPPORT */ 9418 SOC_IF_ERROR_RETURN 9419 (MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, enable)); 9420 } 9421 9422 return BCM_E_NONE; 9423 } 9424 9425 STATIC int 9426 _bcm_esw_port_e2ecc_hdr_set(int unit, int port, soc_higig_e2ecc_hdr_t *e2ecc_hdr) 9427 { 9428 uint64 rval64; 9429 9430 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 9431 return bcmi_esw_portctrl_e2ecc_hdr_set(unit, port, e2ecc_hdr); 9432 } 9433 9434 if (!e2ecc_hdr) { 9435 return BCM_E_PARAM; 9436 } 9437 9438 if (SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 9439 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 9440 if (IS_CL_PORT(unit, port)) { 9441 COMPILER_64_ZERO(rval64); 9442 soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_0r, &rval64, 9443 E2ECC_MODULE_HDR_0_HIf, e2ecc_hdr->overlay1.words[0]); 9444 soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_0r, &rval64, 9445 E2ECC_MODULE_HDR_0_LOf, e2ecc_hdr->overlay1.words[1]); 9446 BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_MODULE_HDR_0r, 9447 port, 0, rval64)); 9448 9449 COMPILER_64_ZERO(rval64); 9450 soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_1r, &rval64, 9451 E2ECC_MODULE_HDR_1_HIf, e2ecc_hdr->overlay1.words[2]); 9452 soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_1r, &rval64, 9453 E2ECC_MODULE_HDR_1_LOf, e2ecc_hdr->overlay1.words[3]); 9454 BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_MODULE_HDR_1r, 9455 port, 0, rval64)); 9456 9457 COMPILER_64_ZERO(rval64); 9458 soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_0r, &rval64, 9459 E2ECC_DATA_HDR_0_HIf, e2ecc_hdr->overlay1.words[4]); 9460 soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_0r, &rval64, 9461 E2ECC_DATA_HDR_0_LOf, e2ecc_hdr->overlay1.words[5]); 9462 BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_DATA_HDR_0r, 9463 port, 0, rval64)); 9464 9465 COMPILER_64_ZERO(rval64); 9466 soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_1r, &rval64, 9467 E2ECC_DATA_HDR_1_HIf, e2ecc_hdr->overlay1.words[6]); 9468 soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_1r, &rval64, 9469 E2ECC_DATA_HDR_1_LOf, e2ecc_hdr->overlay1.words[7]); 9470 BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_DATA_HDR_1r, 9471 port, 0, rval64)); 9472 } else { 9473 COMPILER_64_ZERO(rval64); 9474 soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_0r, &rval64, 9475 E2ECC_MODULE_HDR_0_HIf, e2ecc_hdr->overlay1.words[0]); 9476 soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_0r, &rval64, 9477 E2ECC_MODULE_HDR_0_LOf, e2ecc_hdr->overlay1.words[1]); 9478 BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_MODULE_HDR_0r, 9479 port, 0, rval64)); 9480 9481 COMPILER_64_ZERO(rval64); 9482 soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_1r, &rval64, 9483 E2ECC_MODULE_HDR_1_HIf, e2ecc_hdr->overlay1.words[2]); 9484 soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_1r, &rval64, 9485 E2ECC_MODULE_HDR_1_LOf, e2ecc_hdr->overlay1.words[3]); 9486 BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_MODULE_HDR_1r, 9487 port, 0, rval64)); 9488 9489 COMPILER_64_ZERO(rval64); 9490 soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_0r, &rval64, 9491 E2ECC_DATA_HDR_0_HIf, e2ecc_hdr->overlay1.words[4]); 9492 soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_0r, &rval64, 9493 E2ECC_DATA_HDR_0_LOf, e2ecc_hdr->overlay1.words[5]); 9494 BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_DATA_HDR_0r, 9495 port, 0, rval64)); 9496 9497 COMPILER_64_ZERO(rval64); 9498 soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_1r, &rval64, 9499 E2ECC_DATA_HDR_1_HIf, e2ecc_hdr->overlay1.words[6]); 9500 soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_1r, &rval64, 9501 E2ECC_DATA_HDR_1_LOf, e2ecc_hdr->overlay1.words[7]); 9502 BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_DATA_HDR_1r, 9503 port, 0, rval64)); 9504 } 9505 } else { 9506 SOC_IF_ERROR_RETURN 9507 (WRITE_XHOL_MH0r(unit, port, e2ecc_hdr->overlay1.words[0])); 9508 SOC_IF_ERROR_RETURN 9509 (WRITE_XHOL_MH1r(unit, port, e2ecc_hdr->overlay1.words[1])); 9510 SOC_IF_ERROR_RETURN 9511 (WRITE_XHOL_MH2r(unit, port, e2ecc_hdr->overlay1.words[2])); 9512 SOC_IF_ERROR_RETURN 9513 (WRITE_XHOL_MH3r(unit, port, e2ecc_hdr->overlay1.words[3])); 9514 9515 SOC_IF_ERROR_RETURN 9516 (WRITE_XHOL_D0r(unit, port, e2ecc_hdr->overlay1.words[4])); 9517 SOC_IF_ERROR_RETURN 9518 (WRITE_XHOL_D1r(unit, port, e2ecc_hdr->overlay1.words[5])); 9519 SOC_IF_ERROR_RETURN 9520 (WRITE_XHOL_D2r(unit, port, e2ecc_hdr->overlay1.words[6])); 9521 SOC_IF_ERROR_RETURN 9522 (WRITE_XHOL_D3r(unit, port, e2ecc_hdr->overlay1.words[7])); 9523 } 9524 9525 return BCM_E_NONE; 9526 } 9527 9528 #ifdef BCM_WARM_BOOT_SUPPORT 9529 #if defined(BCM_TRX_SUPPORT) 9530 STATIC int 9531 _bcm_esw_port_e2ecc_hdr_get(int unit, int port, soc_higig_e2ecc_hdr_t *e2ecc_hdr) 9532 { 9533 uint64 rval64; 9534 9535 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 9536 return bcmi_esw_portctrl_e2ecc_hdr_get(unit, port, e2ecc_hdr); 9537 } 9538 9539 if (!e2ecc_hdr) { 9540 return BCM_E_PARAM; 9541 } 9542 9543 sal_memset(e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t)); 9544 9545 if (SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 9546 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 9547 if (IS_CL_PORT(unit, port)) { 9548 BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_MODULE_HDR_0r, 9549 port, 0, &rval64)); 9550 e2ecc_hdr->overlay1.words[0] = soc_reg64_field32_get(unit, 9551 CLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_HIf); 9552 e2ecc_hdr->overlay1.words[1] = soc_reg64_field32_get(unit, 9553 CLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_LOf); 9554 9555 BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_MODULE_HDR_1r, 9556 port, 0, &rval64)); 9557 e2ecc_hdr->overlay1.words[2] = soc_reg64_field32_get(unit, 9558 CLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_HIf); 9559 e2ecc_hdr->overlay1.words[3] = soc_reg64_field32_get(unit, 9560 CLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_LOf); 9561 9562 BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_DATA_HDR_0r, 9563 port, 0, &rval64)); 9564 e2ecc_hdr->overlay1.words[4] = soc_reg64_field32_get(unit, 9565 CLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_HIf); 9566 e2ecc_hdr->overlay1.words[5] = soc_reg64_field32_get(unit, 9567 CLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_LOf); 9568 9569 BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_DATA_HDR_1r, 9570 port, 0, &rval64)); 9571 e2ecc_hdr->overlay1.words[6] = soc_reg64_field32_get(unit, 9572 CLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_HIf); 9573 e2ecc_hdr->overlay1.words[7] = soc_reg64_field32_get(unit, 9574 CLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_LOf); 9575 } else { 9576 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_MODULE_HDR_0r, 9577 port, 0, &rval64)); 9578 e2ecc_hdr->overlay1.words[0] = soc_reg64_field32_get(unit, 9579 XLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_HIf); 9580 e2ecc_hdr->overlay1.words[1] = soc_reg64_field32_get(unit, 9581 XLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_LOf); 9582 9583 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_MODULE_HDR_1r, 9584 port, 0, &rval64)); 9585 e2ecc_hdr->overlay1.words[2] = soc_reg64_field32_get(unit, 9586 XLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_HIf); 9587 e2ecc_hdr->overlay1.words[3] = soc_reg64_field32_get(unit, 9588 XLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_LOf); 9589 9590 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_DATA_HDR_0r, 9591 port, 0, &rval64)); 9592 e2ecc_hdr->overlay1.words[4] = soc_reg64_field32_get(unit, 9593 XLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_HIf); 9594 e2ecc_hdr->overlay1.words[5] = soc_reg64_field32_get(unit, 9595 XLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_LOf); 9596 9597 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_DATA_HDR_1r, 9598 port, 0, &rval64)); 9599 e2ecc_hdr->overlay1.words[6] = soc_reg64_field32_get(unit, 9600 XLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_HIf); 9601 e2ecc_hdr->overlay1.words[7] = soc_reg64_field32_get(unit, 9602 XLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_LOf); 9603 } 9604 } else { 9605 SOC_IF_ERROR_RETURN 9606 (READ_XHOL_MH0r(unit, port, &e2ecc_hdr->overlay1.words[0])); 9607 SOC_IF_ERROR_RETURN 9608 (READ_XHOL_MH1r(unit, port, &e2ecc_hdr->overlay1.words[1])); 9609 SOC_IF_ERROR_RETURN 9610 (READ_XHOL_MH2r(unit, port, &e2ecc_hdr->overlay1.words[2])); 9611 SOC_IF_ERROR_RETURN 9612 (READ_XHOL_MH3r(unit, port, &e2ecc_hdr->overlay1.words[3])); 9613 9614 SOC_IF_ERROR_RETURN 9615 (READ_XHOL_D0r(unit, port, &e2ecc_hdr->overlay1.words[4])); 9616 SOC_IF_ERROR_RETURN 9617 (READ_XHOL_D1r(unit, port, &e2ecc_hdr->overlay1.words[5])); 9618 SOC_IF_ERROR_RETURN 9619 (READ_XHOL_D2r(unit, port, &e2ecc_hdr->overlay1.words[6])); 9620 SOC_IF_ERROR_RETURN 9621 (READ_XHOL_D3r(unit, port, &e2ecc_hdr->overlay1.words[7])); 9622 } 9623 9624 return BCM_E_NONE; 9625 } 9626 #endif 9627 #endif /* BCM_WARM_BOOT_SUPPORT */ 9628 9629 #ifdef BCM_WARM_BOOT_SUPPORT 9630 9631 STATIC int 9632 _bcm_port_vd_pbvl_reinit(int unit) 9633 { 9634 9635 #if defined(BCM_TRX_SUPPORT) 9636 if (SOC_IS_TRX(unit)) { 9637 /* 9638 * Reinit of vd_pbvl takes place at the end of function 9639 * _bcm_trx_vlan_action_profile_init(). This routine initializes 9640 * the VLAN profile tables first, which need to happen before 9641 * the vd_pbvl data is recovered. 9642 */ 9643 return BCM_E_NONE; 9644 } 9645 #endif /* BCM_TRX_SUPPORT */ 9646 9647 #ifdef BCM_FIREBOLT_SUPPORT 9648 if (SOC_IS_FBX(unit)) { 9649 bcm_port_t port; 9650 _bcm_port_info_t *pinfo; 9651 int idxmin, idx, i, index; 9652 int start, end; 9653 vlan_protocol_data_entry_t vde; 9654 vlan_protocol_entry_t vpe; 9655 bcm_vlan_t cvid, defvid; 9656 uint32 ft; 9657 bcm_pbmp_t all_pbmp; 9658 9659 BCM_PBMP_CLEAR(all_pbmp); 9660 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 9661 9662 #ifdef BCM_KATANA2_SUPPORT 9663 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 9664 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 9665 } 9666 if (soc_feature(unit, soc_feature_linkphy_coe) || 9667 soc_feature(unit, soc_feature_subtag_coe)) { 9668 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 9669 } 9670 #endif 9671 9672 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOL_DATAm); 9673 idx = soc_mem_index_min(unit, VLAN_PROTOCOLm); 9674 PBMP_ITER(all_pbmp, port) { 9675 9676 start = idxmin + port*16; 9677 end = start + 16; 9678 BCM_IF_ERROR_RETURN 9679 (bcm_esw_port_untagged_vlan_get(unit, port, &defvid)); 9680 for (i = start; i < end; i++) { 9681 9682 SOC_IF_ERROR_RETURN 9683 (READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, 9684 i, &vde)); 9685 cvid = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, 9686 VLAN_IDf); 9687 if ((cvid == 0) || (cvid == defvid)) { 9688 9689 continue; 9690 } 9691 9692 /* 9693 * Check against the VLAN_PROTOCOL table to see if a 9694 * valid entry exists for matching the packet protocol 9695 */ 9696 index = i - start; 9697 SOC_IF_ERROR_RETURN 9698 (READ_VLAN_PROTOCOLm(unit, MEM_BLOCK_ANY, 9699 idx+index, &vpe)); 9700 ft = 0; 9701 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, ETHERIIf)) { 9702 ft |= BCM_PORT_FRAMETYPE_ETHER2; 9703 } 9704 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, SNAPf)) { 9705 ft |= BCM_PORT_FRAMETYPE_8023; 9706 } 9707 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, LLCf)) { 9708 ft |= BCM_PORT_FRAMETYPE_LLC; 9709 } 9710 if (ft == 0) { 9711 /* 9712 * Something wrong here.. bail out 9713 */ 9714 continue; 9715 } 9716 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 9717 if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, idx+index)) { 9718 /* Set as explicit VID */ 9719 _BCM_PORT_VD_PBVL_SET(pinfo, idx+index); 9720 } 9721 } 9722 } 9723 return BCM_E_NONE; 9724 } 9725 #endif /* BCM_FIREBOLT_SUPPORT */ 9726 9727 return BCM_E_NONE; 9728 } 9729 9730 #if defined(BCM_TRX_SUPPORT) 9731 /* Recover the port dtag_mode from Warm Boot cached info, if available. */ 9732 STATIC int 9733 _bcm_trx_port_dtag_mode_reinit(int unit, bcm_pbmp_t dtm_pbmp, int use_pbmp) 9734 { 9735 uint32 tpid_enable; 9736 bcm_port_t port; 9737 _bcm_port_info_t *pinfo; 9738 bcm_vlan_action_set_t action; 9739 bcm_pbmp_t all_pbmp; 9740 9741 BCM_PBMP_CLEAR(all_pbmp); 9742 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 9743 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 9744 9745 #ifdef BCM_KATANA2_SUPPORT 9746 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 9747 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 9748 } 9749 if (soc_feature(unit, soc_feature_linkphy_coe) || 9750 soc_feature(unit, soc_feature_subtag_coe)) { 9751 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 9752 } 9753 #endif 9754 9755 #if defined(BCM_SABER2_SUPPORT) 9756 if(SOC_IS_SABER2(unit)){ 9757 int oamp_enable; 9758 (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable); 9759 /* Skip OAMP port for saber2 device */ 9760 if(oamp_enable) { 9761 SOC_PBMP_PORT_REMOVE(all_pbmp, 9762 _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER); 9763 } 9764 } 9765 #endif 9766 9767 PBMP_ITER(all_pbmp, port) { 9768 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 9769 BCM_IF_ERROR_RETURN 9770 (_bcm_esw_port_tab_get(unit, port, OUTER_TPID_ENABLEf, (int *)&tpid_enable)); 9771 9772 if (0 == tpid_enable) { 9773 if (use_pbmp && !BCM_PBMP_MEMBER(dtm_pbmp, port)) { 9774 /* Bitmap claims this is DT mode NONE, but it is 9775 * configured for EXTERNAL */ 9776 BCM_IF_ERROR_RETURN 9777 (soc_event_generate(unit, 9778 BCM_SWITCH_EVENT_STABLE_ERROR, 9779 SOC_STABLE_STALE, 9780 SOC_STABLE_BASIC, 0)); 9781 use_pbmp = FALSE; /* Cached info is not trustworthy */ 9782 } else { 9783 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_EXTERNAL; 9784 } 9785 } else { 9786 if (use_pbmp && BCM_PBMP_MEMBER(dtm_pbmp, port)) { 9787 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_INTERNAL; 9788 } else { 9789 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_NONE; 9790 } 9791 } 9792 9793 if (!SOC_IS_SHADOW(unit) && !SOC_IS_TOMAHAWK3(unit)) { 9794 if (soc_feature(unit, soc_feature_vlan_action)) { 9795 BCM_IF_ERROR_RETURN 9796 (_bcm_trx_vlan_port_default_action_get(unit, port, &action)); 9797 9798 9799 if (bcmVlanActionAdd == action.ut_inner) { 9800 pinfo->dtag_mode |= BCM_PORT_DTAG_ADD_EXTERNAL_TAG; 9801 } 9802 9803 9804 BCM_IF_ERROR_RETURN 9805 (_bcm_trx_vlan_port_egress_default_action_get(unit, port, 9806 &action)); 9807 if ((bcmVlanActionDelete == action.dt_inner) && 9808 (bcmVlanActionDelete == action.dt_inner_prio)) { 9809 pinfo->dtag_mode |= BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG; 9810 } 9811 } 9812 } 9813 } 9814 return BCM_E_NONE; 9815 } 9816 9817 /** 9818 * Function: 9819 * _bcm_esw_hcfc_ingress_enable_check(); 9820 * Purpose: 9821 * check HCFC ingress enable status of unit. If any port ingress enable, enable =1; 9822 * 9823 * Parameters: 9824 * unit - (IN)device number 9825 * enable - (OUT) hcfc ingress enable 9826 * 9827 * Returns: 9828 * BCM_E_xxx 9829 * Notes: 9830 */ 9831 STATIC int 9832 _bcm_esw_hcfc_ingress_enable_check(int unit, int *enable) 9833 { 9834 soc_reg_t reg0, reg1; 9835 uint64 rval64, fval64; 9836 9837 if (SOC_REG_IS_VALID(unit, OOBFC_ING_PORT_EN0_64r)) { 9838 reg0 = OOBFC_ING_PORT_EN0_64r; 9839 reg1 = OOBFC_ING_PORT_EN1_64r; 9840 } else { 9841 reg0 = OOBFC_ING_PORT_EN_0_64r; 9842 reg1 = OOBFC_ING_PORT_EN_1_64r; 9843 } 9844 9845 if (!(SOC_REG_IS_VALID(unit, reg0) && SOC_REG_IS_VALID(unit, reg1))) { 9846 *enable = 0; 9847 return BCM_E_NONE; 9848 } 9849 9850 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg0, REG_PORT_ANY, 0, &rval64)); 9851 fval64 = soc_reg64_field_get(unit, reg0, rval64, ING_PORT_ENf); 9852 if(0 != fval64) { 9853 *enable = 1; 9854 return BCM_E_NONE; 9855 } 9856 else { 9857 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg1, REG_PORT_ANY, 0, &rval64)); 9858 fval64 = soc_reg64_field_get(unit, reg1, rval64, ING_PORT_ENf); 9859 if(0 != fval64) { 9860 *enable = 1; 9861 return BCM_E_NONE; 9862 } 9863 } 9864 9865 return BCM_E_NONE; 9866 } 9867 9868 /** 9869 * Function: 9870 * _bcm_esw_hcfc_egress_enable_check(); 9871 * Purpose: 9872 * check HCFC ingress enable status of unit. If any port egress enable, enable =1; 9873 * 9874 * Parameters: 9875 * unit - (IN)device number 9876 * enable - (OUT) hcfc egress enable 9877 * 9878 * Returns: 9879 * BCM_E_xxx 9880 * Notes: 9881 */ 9882 STATIC int 9883 _bcm_esw_hcfc_egress_enable_check(int unit, int *enable) 9884 { 9885 soc_reg_t reg0, reg1; 9886 uint64 rval64, fval64; 9887 9888 if (SOC_REG_IS_VALID(unit, OOBFC_ENG_PORT_EN0_64r)) { 9889 reg0 = OOBFC_ENG_PORT_EN0_64r; 9890 reg1 = OOBFC_ENG_PORT_EN1_64r; 9891 } else { 9892 reg0 = OOBFC_ENG_PORT_EN_0_64r; 9893 reg1 = OOBFC_ENG_PORT_EN_1_64r; 9894 } 9895 9896 if (!(SOC_REG_IS_VALID(unit, reg0) && SOC_REG_IS_VALID(unit, reg1))) { 9897 *enable = 0; 9898 return BCM_E_NONE; 9899 } 9900 9901 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg0, REG_PORT_ANY, 0, &rval64)); 9902 fval64 = soc_reg64_field_get(unit, reg0, rval64, ENG_PORT_ENf); 9903 if(0 != fval64) { 9904 *enable = 1; 9905 return BCM_E_NONE; 9906 } 9907 else { 9908 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg1, REG_PORT_ANY, 0, &rval64)); 9909 fval64 = soc_reg64_field_get(unit, reg1, rval64, ENG_PORT_ENf); 9910 if(0 != fval64) { 9911 *enable = 1; 9912 return BCM_E_NONE; 9913 } 9914 } 9915 9916 return BCM_E_NONE; 9917 } 9918 9919 /** 9920 * Function: 9921 * _bcm_esw_port_hcfc_ingress_enable_check(); 9922 * Purpose: 9923 * check HCFC ingress enable status of given port. 9924 * 9925 * Parameters: 9926 * unit - (IN)device number 9927 * port - (IN)port number 9928 * enable - (OUT)hcfc ingress enable 9929 * 9930 * Returns: 9931 * BCM_E_xxx 9932 * Notes: 9933 */ 9934 STATIC int 9935 _bcm_esw_port_hcfc_ingress_enable_check(int unit, bcm_port_t port, int *enable) 9936 { 9937 soc_reg_t reg, reg0, reg1; 9938 int len; 9939 uint64 rval64, fval64; 9940 uint32 fval_hi, fval_lo; 9941 9942 if (!SOC_PORT_VALID(unit, port)) { 9943 return BCM_E_PORT; 9944 } 9945 9946 if (SOC_REG_IS_VALID(unit, OOBFC_ING_PORT_EN0_64r)) { 9947 reg0 = OOBFC_ING_PORT_EN0_64r; 9948 reg1 = OOBFC_ING_PORT_EN1_64r; 9949 } else { 9950 reg0 = OOBFC_ING_PORT_EN_0_64r; 9951 reg1 = OOBFC_ING_PORT_EN_1_64r; 9952 } 9953 if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) { 9954 *enable = 0; 9955 return BCM_E_NONE; 9956 } 9957 9958 /* Configure ingress status reporting */ 9959 len = soc_reg_field_length(unit, reg0, ING_PORT_ENf); 9960 if (len < 1) { 9961 return BCM_E_PORT; 9962 } 9963 if (port < len) { /* First half of logical ports (not mmu port) */ 9964 reg = reg0; 9965 } else { /* Second half of logical ports (not mmu port) */ 9966 reg = reg1; 9967 } 9968 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 9969 fval64 = soc_reg64_field_get(unit, reg, rval64, ING_PORT_ENf); 9970 fval_hi = COMPILER_64_HI(fval64); 9971 fval_lo = COMPILER_64_LO(fval64); 9972 9973 if (port < len) { 9974 if ( port < 32 ) { 9975 *enable = fval_lo & (1 << port); 9976 } else { 9977 /* coverity[large_shift : FALSE] */ 9978 *enable = fval_hi & (1 << (port - 32)); 9979 } 9980 } else { 9981 int port_offset = port - len; 9982 if ( port_offset < 32 ) { 9983 *enable = fval_lo & (1 << port_offset); 9984 } else { 9985 *enable = fval_hi & (1 << (port_offset - 32)); 9986 } 9987 } 9988 9989 return BCM_E_NONE; 9990 } 9991 9992 /** 9993 * Function: 9994 * _bcm_esw_port_hcfc_egress_enable_check(); 9995 * Purpose: 9996 * check HCFC egress enable status of given port. 9997 * 9998 * Parameters: 9999 * unit - (IN)device number 10000 * port - (IN)port number 10001 * enable - (OUT)hcfc egress enable 10002 * 10003 * Returns: 10004 * BCM_E_xxx 10005 * Notes: 10006 */ 10007 STATIC int 10008 _bcm_esw_port_hcfc_egress_enable_check(int unit, bcm_port_t port, int *enable) 10009 { 10010 soc_reg_t reg, reg0, reg1; 10011 int len; 10012 uint64 rval64, fval64; 10013 uint32 fval_hi, fval_lo; 10014 10015 if (!SOC_PORT_VALID(unit, port)) { 10016 return BCM_E_PORT; 10017 } 10018 10019 if (SOC_REG_IS_VALID(unit, OOBFC_ENG_PORT_EN0_64r)) { 10020 reg0 = OOBFC_ENG_PORT_EN0_64r; 10021 reg1 = OOBFC_ENG_PORT_EN1_64r; 10022 } else { 10023 reg0 = OOBFC_ENG_PORT_EN_0_64r; 10024 reg1 = OOBFC_ENG_PORT_EN_1_64r; 10025 } 10026 if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) { 10027 *enable = 0; 10028 return BCM_E_NONE; 10029 } 10030 10031 /* Configure egress status reporting */ 10032 len = soc_reg_field_length(unit, reg0, ENG_PORT_ENf); 10033 if (len < 1) { 10034 return BCM_E_PORT; 10035 } 10036 if (port < len) { /* First half of logical ports (not mmu port) */ 10037 reg = reg0; 10038 } else { /* Second half of logical ports (not mmu port) */ 10039 reg = reg1; 10040 } 10041 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 10042 fval64 = soc_reg64_field_get(unit, reg, rval64, ENG_PORT_ENf); 10043 fval_hi = COMPILER_64_HI(fval64); 10044 fval_lo = COMPILER_64_LO(fval64); 10045 if (port < len) { 10046 if ( port < 32 ) { 10047 *enable = fval_lo & (1 << port); 10048 } else { 10049 /* coverity[large_shift : FALSE] */ 10050 *enable = fval_hi & (1 << (port - 32)); 10051 } 10052 } else { 10053 int port_offset = port - len; 10054 if ( port_offset < 32 ) { 10055 *enable = fval_lo & (1 << port_offset); 10056 } else { 10057 *enable = fval_hi & (1 << (port_offset - 32)); 10058 } 10059 } 10060 10061 return BCM_E_NONE; 10062 } 10063 10064 10065 STATIC int 10066 _bcm_esw_port_e2ecc_reinit(int unit) 10067 { 10068 bcm_port_t port, phy_port; 10069 bcm_port_congestion_config_t *config; 10070 int time_unit_sel = 0, time_units = 0; 10071 soc_higig_e2ecc_hdr_t e2ecc_hdr; 10072 int src_modid, src_pid; 10073 uint64 regval64; 10074 uint32 regval, field_val = 0; 10075 int tx_enabled = FALSE, rx_enabled = FALSE; 10076 int port_tx_enabled, port_rx_enabled, voqfc = 0; 10077 int hcfc_tx = 0, hcfc_rx = 0; 10078 int port_hcfc_tx = 0, port_hcfc_rx = 0; 10079 int blk, blk_num = -1, bindex = 0; 10080 #ifdef BCM_KATANA2_SUPPORT 10081 uint16 dev_id; 10082 uint8 rev_id; 10083 int e2ecc_coe = 0; 10084 int e2ecc_strict = 0; 10085 #endif 10086 #ifdef BCM_TRIDENT2PLUS_SUPPORT 10087 int fc_format; 10088 int copy_to_cpu = 0 ; 10089 #endif 10090 if (SOC_IS_SC_CQ(unit)) { 10091 SOC_IF_ERROR_RETURN(READ_E2E_HOL_ENr(unit, ®val)); 10092 if (0 != soc_reg_field_get(unit, E2E_HOL_ENr, regval, ENf)) { 10093 tx_enabled = TRUE; 10094 } 10095 } else { 10096 SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_ENr(unit, ®val)); 10097 if (0 != soc_reg_field_get(unit, E2ECC_HOL_ENr, regval, ENf)) { 10098 tx_enabled = TRUE; 10099 } 10100 } 10101 10102 BCM_IF_ERROR_RETURN(_bcm_esw_hcfc_egress_enable_check(unit, &hcfc_tx)); 10103 if (hcfc_tx) { 10104 tx_enabled = TRUE; 10105 } 10106 10107 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, ®val64)); 10108 if (0 == soc_reg64_field32_get(unit, ING_CONFIG_64r, regval64, 10109 DISABLE_E2E_HOL_CHECKf)) { 10110 rx_enabled = TRUE; 10111 } 10112 10113 BCM_IF_ERROR_RETURN(_bcm_esw_hcfc_ingress_enable_check(unit, &hcfc_rx)); 10114 if (hcfc_rx) { 10115 rx_enabled = TRUE; 10116 } 10117 10118 if (!tx_enabled && !rx_enabled) { 10119 /* Nothing further to do */ 10120 return BCM_E_NONE; 10121 } 10122 10123 PBMP_HG_ITER(unit, port) { 10124 port_tx_enabled = port_rx_enabled = FALSE; 10125 10126 if (tx_enabled) { 10127 if (hcfc_tx) { 10128 port_hcfc_tx = 0; 10129 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_egress_enable_check(unit, port, &port_hcfc_tx)); 10130 if (port_hcfc_tx) { 10131 port_tx_enabled = 1; 10132 } 10133 } 10134 else { 10135 if (soc_reg_field_valid(unit, XPORT_CONFIGr, E2E_HOL_ENf)) { 10136 SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, ®val)); 10137 port_tx_enabled = 10138 (0 != soc_reg_field_get(unit, XPORT_CONFIGr, regval, 10139 E2E_HOL_ENf)); 10140 } else { 10141 if (soc_feature(unit, soc_feature_logical_port_num)) { 10142 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 10143 } else { 10144 phy_port = port; 10145 } 10146 blk = SOC_PORT_BLOCK(unit, phy_port); 10147 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 10148 if (SOC_IS_TRIDENT2X(unit)) { 10149 blk_num = SOC_INFO(unit).port_serdes[port]; 10150 } else 10151 #endif 10152 { 10153 blk_num = SOC_BLOCK_INFO(unit, blk).number; 10154 } 10155 bindex = SOC_PORT_BINDEX(unit, phy_port); 10156 /* In TR3 E2ECC is implemented only in blocks CL, XL1 */ 10157 if (!SOC_IS_TRIUMPH3(unit) || (IS_CL_PORT(unit, port) || (blk == 13))) { 10158 if (SOC_IS_TRIUMPH3(unit)) { 10159 if (IS_CL_PORT(unit, port)) { 10160 blk_num = (blk_num ? 4 + bindex/4 : bindex/4); 10161 bindex = bindex%4; 10162 } else { 10163 blk_num = 3; 10164 } 10165 } 10166 if (SOC_IS_KATANA2(unit)) { 10167 /* In KT2 E2ECC is implemented only in blocks 6..9 */ 10168 if (blk_num >= 6) { 10169 blk_num -= 6; 10170 } 10171 } 10172 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num, 10173 ®val)); 10174 if ((regval & (1 << bindex))) { 10175 port_tx_enabled= TRUE; 10176 } 10177 } 10178 } 10179 } 10180 } 10181 10182 if (rx_enabled) { 10183 if (hcfc_rx) { 10184 port_hcfc_rx = 0; 10185 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_ingress_enable_check(unit, port, &port_hcfc_rx)); 10186 if (port_hcfc_rx) { 10187 port_rx_enabled = 1; 10188 } 10189 } 10190 else { 10191 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 10192 port_rx_enabled = 0; 10193 voqfc = 0; 10194 if (0 != soc_reg_field_get(unit, IE2E_CONTROLr, regval, HOL_ENABLEf)) { 10195 port_rx_enabled = 1; 10196 } 10197 10198 if (soc_reg_field_valid(unit, IE2E_CONTROLr, VOQFC_ENABLEf)) { 10199 if (0 != soc_reg_field_get(unit, IE2E_CONTROLr, 10200 regval, VOQFC_ENABLEf)) { 10201 port_rx_enabled = 1; 10202 voqfc = 1; 10203 } 10204 } 10205 } 10206 } 10207 10208 /* For HX4 and TR3, tx restore from OP_QUEUE_CONFIG1_CELLr */ 10209 if (SOC_IS_TRIUMPH3(unit)) { 10210 BCM_IF_ERROR_RETURN(READ_OP_QUEUE_CONFIG1_CELLr(unit, port, 0, ®val)); 10211 port_tx_enabled = soc_reg_field_get(unit,OP_QUEUE_CONFIG1_CELLr, regval, Q_E2E_DS_EN_CELLf); 10212 } 10213 10214 if (!port_tx_enabled && !port_rx_enabled) { 10215 /* On to the next port */ 10216 continue; 10217 } 10218 10219 /* Allocate space for the E2ECC configuration */ 10220 if (PORT(unit, port).e2ecc_config == NULL) { 10221 PORT(unit, port).e2ecc_config = 10222 sal_alloc(sizeof(bcm_port_congestion_config_t), 10223 "bcm_port_congestion_config"); 10224 if (PORT(unit, port).e2ecc_config == NULL) { 10225 LOG_ERROR(BSL_LS_BCM_PORT, 10226 (BSL_META_U(unit, 10227 "Error: unable to allocate memory for" 10228 " bcm_port_congestion_config.\n"))); 10229 return BCM_E_MEMORY; 10230 } 10231 } else { 10232 /* This is initialized to NULL pointers by 10233 * port init. How did it get changed? */ 10234 return BCM_E_INTERNAL; 10235 } 10236 10237 config = PORT(unit, port).e2ecc_config; 10238 bcm_port_congestion_config_t_init(config); 10239 10240 if (port_tx_enabled) { 10241 if (port_hcfc_tx) { 10242 config->flags |= BCM_PORT_CONGESTION_CONFIG_HCFC| 10243 BCM_PORT_CONGESTION_CONFIG_TX; 10244 } else { 10245 /* Recover TX state */ 10246 config->flags |= BCM_PORT_CONGESTION_CONFIG_E2ECC | 10247 BCM_PORT_CONGESTION_CONFIG_TX; 10248 10249 /* Message timer paramters to packets/sec */ 10250 if (SOC_IS_SC_CQ(unit)) { 10251 SOC_IF_ERROR_RETURN(READ_E2E_MAX_TX_TIMERr(unit, ®val)); 10252 time_unit_sel = soc_reg_field_get(unit, E2E_MAX_TX_TIMERr, 10253 regval, LGf); 10254 time_units = soc_reg_field_get(unit, E2E_MAX_TX_TIMERr, 10255 regval, TIMERf); 10256 } else { 10257 SOC_IF_ERROR_RETURN(READ_E2ECC_MAX_TX_TIMERr(unit, ®val)); 10258 time_unit_sel = soc_reg_field_get(unit, E2ECC_MAX_TX_TIMERr, 10259 regval, LGf); 10260 time_units = soc_reg_field_get(unit, E2ECC_MAX_TX_TIMERr, 10261 regval, TIMERf); 10262 SOC_IF_ERROR_RETURN(WRITE_E2ECC_MAX_TX_TIMERr(unit, regval)); 10263 } 10264 10265 /* See _bcm_esw_port_e2ecc_tx for an explanation of 10266 * the timer calculation. */ 10267 config->packets_per_sec = time_unit_sel ? 10268 (40000 / time_units) : (4000000 / time_units); 10269 10270 /* Recover the E2ECC module header 10271 * (see _bcm_esw_port_e2ecc_tx for the header format) */ 10272 BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hdr_get(unit, port, &e2ecc_hdr)); 10273 10274 config->traffic_class = 10275 (e2ecc_hdr.overlay1.words[0] >> 16) & 0x0F; 10276 config->multicast_id = e2ecc_hdr.overlay1.words[0] & 0xFFFF; 10277 10278 src_modid = (e2ecc_hdr.overlay1.words[1] >> 24) & 0xFF; 10279 src_pid = (e2ecc_hdr.overlay1.words[1] >> 16) & 0xFF; 10280 BCM_GPORT_MODPORT_SET(config->src_port, src_modid, src_pid); 10281 10282 config->color = (e2ecc_hdr.overlay1.words[1] >> 6) & 0x3; 10283 10284 config->pri = (e2ecc_hdr.overlay1.words[3] >> 29) & 0x7; 10285 config->cfi = (e2ecc_hdr.overlay1.words[3] >> 28) & 0x1; 10286 config->vlan = (e2ecc_hdr.overlay1.words[3] >> 16) & 0xfff; 10287 10288 config->dest_mac[0] = 10289 ((e2ecc_hdr.overlay1.words[4] >> 24) & 0xff); 10290 config->dest_mac[1] = 10291 ((e2ecc_hdr.overlay1.words[4] >> 16) & 0xff); 10292 config->dest_mac[2] = 10293 ((e2ecc_hdr.overlay1.words[4] >> 8) & 0xff); 10294 config->dest_mac[3] = 10295 (e2ecc_hdr.overlay1.words[4] & 0xff); 10296 config->dest_mac[4] = 10297 ((e2ecc_hdr.overlay1.words[5] >> 24) & 0xff); 10298 config->dest_mac[5] = 10299 ((e2ecc_hdr.overlay1.words[5] >> 16) & 0xff); 10300 10301 config->src_mac[0] = 10302 ((e2ecc_hdr.overlay1.words[5] >> 8) & 0xff); 10303 config->src_mac[1] = 10304 (e2ecc_hdr.overlay1.words[5] & 0xff); 10305 config->src_mac[2] = 10306 ((e2ecc_hdr.overlay1.words[6] >> 24) & 0xff); 10307 config->src_mac[3] = 10308 ((e2ecc_hdr.overlay1.words[6] >> 16) & 0xff); 10309 config->src_mac[4] = 10310 ((e2ecc_hdr.overlay1.words[6] >> 8) & 0xff); 10311 config->src_mac[5] = 10312 (e2ecc_hdr.overlay1.words[6] & 0xff); 10313 10314 config->ethertype = 10315 (e2ecc_hdr.overlay1.words[7] >> 16) & 0xFFFF; 10316 config->opcode = e2ecc_hdr.overlay1.words[7] & 0xFFFF; 10317 10318 /* All the info from RX is encoded in the header, so 10319 * just mark if it is enabled. */ 10320 if (port_rx_enabled) { 10321 config->flags |= BCM_PORT_CONGESTION_CONFIG_RX; 10322 } 10323 } 10324 } else if (port_rx_enabled) { 10325 /* Recover RX state */ 10326 config->flags |= BCM_PORT_CONGESTION_CONFIG_RX; 10327 10328 if (port_hcfc_rx) { 10329 config->flags |= BCM_PORT_CONGESTION_CONFIG_HCFC; 10330 } else if (voqfc) { 10331 config->flags |= BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL; 10332 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_MSr(unit, ®val)); 10333 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_MSr, 10334 regval, DAf); 10335 config->dest_mac[0] = ((field_val >> 8) & 0xff); 10336 config->dest_mac[1] = (field_val & 0xff); 10337 10338 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_LSr(unit, ®val)); 10339 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_LSr, 10340 regval, DAf); 10341 config->dest_mac[2] = ((field_val >> 24) & 0xff); 10342 config->dest_mac[3] = ((field_val >> 16) & 0xff); 10343 config->dest_mac[4] = ((field_val >> 8) & 0xff); 10344 config->dest_mac[5] = (field_val & 0xff); 10345 10346 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, ®val)); 10347 config->ethertype = 10348 soc_reg_field_get(unit, ING_VOQFC_IDr, regval, LENGTH_TYPEf); 10349 config->opcode = 10350 soc_reg_field_get(unit, ING_VOQFC_IDr, regval, OPCODEf); 10351 10352 } else { 10353 config->flags |= BCM_PORT_CONGESTION_CONFIG_E2ECC; 10354 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_MSr(unit, ®val)); 10355 field_val = soc_reg_field_get(unit, E2E_HOL_RX_DA_MSr, 10356 regval, DAf); 10357 config->dest_mac[0] = ((field_val >> 8) & 0xff); 10358 config->dest_mac[1] = (field_val & 0xff); 10359 10360 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_LSr(unit, ®val)); 10361 field_val = soc_reg_field_get(unit, E2E_HOL_RX_DA_LSr, 10362 regval, DAf); 10363 config->dest_mac[2] = ((field_val >> 24) & 0xff); 10364 config->dest_mac[3] = ((field_val >> 16) & 0xff); 10365 config->dest_mac[4] = ((field_val >> 8) & 0xff); 10366 config->dest_mac[5] = (field_val & 0xff); 10367 10368 SOC_IF_ERROR_RETURN 10369 (READ_E2E_HOL_RX_LENGTH_TYPEr(unit, ®val)); 10370 config->ethertype = 10371 soc_reg_field_get(unit, E2E_HOL_RX_LENGTH_TYPEr, 10372 regval, LENGTH_TYPEf); 10373 10374 SOC_IF_ERROR_RETURN 10375 (READ_E2E_HOL_RX_OPCODEr(unit, ®val)); 10376 config->opcode = 10377 soc_reg_field_get(unit, E2E_HOL_RX_OPCODEr, 10378 regval, OPCODEf); 10379 } 10380 } 10381 } 10382 #ifdef BCM_TRIDENT2PLUS_SUPPORT 10383 if (SOC_IS_TRIDENT2PLUS(unit) || 10384 (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit))) { 10385 PBMP_ALL_ITER(unit, port) { 10386 10387 if (IS_HG_PORT(unit, port)) { 10388 continue; 10389 } 10390 SOC_IF_ERROR_RETURN( 10391 READ_COE_FLOW_CONTROL_CONFIGr (unit, port, ®val)); 10392 10393 fc_format = soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr, 10394 regval, FLOW_CONTROL_FORMATf); 10395 copy_to_cpu = soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr, 10396 regval, COPY_TO_CPUf); 10397 if(!fc_format) 10398 { 10399 continue; 10400 } 10401 10402 /* Allocate space for the E2ECC configuration */ 10403 if (PORT(unit, port).e2ecc_config == NULL) { 10404 PORT(unit, port).e2ecc_config = 10405 sal_alloc(sizeof(bcm_port_congestion_config_t), 10406 "bcm_port_congestion_config"); 10407 if (PORT(unit, port).e2ecc_config == NULL) { 10408 LOG_ERROR(BSL_LS_BCM_PORT, 10409 (BSL_META_U(unit, 10410 "Error: unable to allocate memory for" 10411 " bcm_port_congestion_config.\n"))); 10412 return BCM_E_MEMORY; 10413 } 10414 } else { 10415 /* This is initialized to NULL pointers by 10416 * port init. How did it get changed? */ 10417 return BCM_E_INTERNAL; 10418 } 10419 10420 config = PORT(unit, port).e2ecc_config; 10421 bcm_port_congestion_config_t_init(config); 10422 10423 /* Recover RX state */ 10424 config->flags |= BCM_PORT_CONGESTION_CONFIG_RX; 10425 if (copy_to_cpu == 1) { 10426 config->flags |= 10427 BCM_PORT_CONGESTION_CONFIG_COPY_TO_CPU; 10428 } 10429 if (fc_format == 1) { 10430 config->flags |= 10431 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE; 10432 SOC_IF_ERROR_RETURN( 10433 READ_ING_VOQFC_MACDA_MSr(unit, ®val)); 10434 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_MSr, 10435 regval, DAf); 10436 config->dest_mac[0] = ((field_val >> 8) & 0xff); 10437 config->dest_mac[1] = (field_val & 0xff); 10438 SOC_IF_ERROR_RETURN( 10439 READ_ING_VOQFC_MACDA_LSr(unit, ®val)); 10440 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_LSr, 10441 regval, DAf); 10442 config->dest_mac[2] = ((field_val >> 24) & 0xff); 10443 config->dest_mac[3] = ((field_val >> 16) & 0xff); 10444 config->dest_mac[4] = ((field_val >> 8) & 0xff); 10445 config->dest_mac[5] = (field_val & 0xff); 10446 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, ®val)); 10447 config->ethertype = 10448 soc_reg_field_get(unit, ING_VOQFC_IDr, 10449 regval, LENGTH_TYPEf); 10450 config->opcode = 10451 soc_reg_field_get(unit, ING_VOQFC_IDr, 10452 regval, OPCODEf); 10453 10454 } else if (fc_format == 2) { 10455 config->flags |= 10456 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE; 10457 SOC_IF_ERROR_RETURN( 10458 READ_COE_VLAN_PAUSE_MACDA_MSr(unit, ®val)); 10459 field_val = soc_reg_field_get(unit, COE_VLAN_PAUSE_MACDA_MSr, 10460 regval, DAf); 10461 config->dest_mac[0] = ((field_val >> 8) & 0xff); 10462 config->dest_mac[1] = (field_val & 0xff); 10463 SOC_IF_ERROR_RETURN( 10464 READ_COE_VLAN_PAUSE_MACDA_LSr(unit, ®val)); 10465 field_val = soc_reg_field_get(unit, COE_VLAN_PAUSE_MACDA_LSr, 10466 regval, DAf); 10467 config->dest_mac[2] = ((field_val >> 24) & 0xff); 10468 config->dest_mac[3] = ((field_val >> 16) & 0xff); 10469 config->dest_mac[4] = ((field_val >> 8) & 0xff); 10470 config->dest_mac[5] = (field_val & 0xff); 10471 SOC_IF_ERROR_RETURN(READ_COE_VLAN_PAUSE_IDr(unit, ®val)); 10472 config->ethertype = 10473 soc_reg_field_get(unit, COE_VLAN_PAUSE_IDr, 10474 regval, LENGTH_TYPEf); 10475 config->opcode = 10476 soc_reg_field_get(unit, COE_VLAN_PAUSE_IDr, 10477 regval, OPCODEf); 10478 } 10479 10480 } 10481 } 10482 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 10483 #ifdef BCM_KATANA2_SUPPORT 10484 if (SOC_IS_KATANA2(unit)) { 10485 PBMP_ALL_ITER(unit, port) { 10486 port_rx_enabled = 0; 10487 e2ecc_coe = 0; 10488 10489 if (IS_HG_PORT(unit, port)) { 10490 continue; 10491 } 10492 soc_cm_get_id(unit, &dev_id, &rev_id); 10493 10494 if ((rev_id >= BCM56450_B0_REV_ID) || SOC_IS_SABER2(unit)) { 10495 SOC_IF_ERROR_RETURN( 10496 READ_COE_FLOW_CONTROL_CONFIGr (unit, port, ®val)); 10497 10498 if (soc_reg_field_valid(unit, COE_FLOW_CONTROL_CONFIGr, 10499 FLOW_CONTROL_FORMATf)) { 10500 if (0 != soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr, 10501 regval, FLOW_CONTROL_FORMATf)) { 10502 port_rx_enabled = 1; 10503 e2ecc_coe = 1; 10504 e2ecc_strict = soc_reg_field_get(unit, 10505 COE_FLOW_CONTROL_CONFIGr, 10506 regval, E2ECC_MODEf); 10507 } 10508 } 10509 } else if (rev_id == BCM56450_A0_REV_ID) { 10510 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 10511 if (soc_reg_field_valid(unit, IE2E_CONTROLr, VOQFC_ENABLEf)) { 10512 if (0 != soc_reg_field_get(unit, IE2E_CONTROLr, 10513 regval, VOQFC_ENABLEf)) { 10514 port_rx_enabled = 1; 10515 e2ecc_coe = 1; 10516 } 10517 } 10518 } 10519 if (!port_rx_enabled) { 10520 /* On to the next port */ 10521 continue; 10522 } 10523 10524 /* Allocate space for the E2ECC configuration */ 10525 if (PORT(unit, port).e2ecc_config == NULL) { 10526 PORT(unit, port).e2ecc_config = 10527 10528 sal_alloc(sizeof(bcm_port_congestion_config_t), 10529 "bcm_port_congestion_config"); 10530 if (PORT(unit, port).e2ecc_config == NULL) { 10531 LOG_ERROR(BSL_LS_BCM_PORT, 10532 (BSL_META_U(unit, 10533 "Error: unable to allocate memory for" 10534 " bcm_port_congestion_config.\n"))); 10535 return BCM_E_MEMORY; 10536 } 10537 } else { 10538 /* This is initialized to NULL pointers by 10539 * port init. How did it get changed? */ 10540 return BCM_E_INTERNAL; 10541 } 10542 10543 config = PORT(unit, port).e2ecc_config; 10544 bcm_port_congestion_config_t_init(config); 10545 10546 if (port_rx_enabled) { 10547 /* Recover RX state */ 10548 config->flags |= BCM_PORT_CONGESTION_CONFIG_RX; 10549 if (e2ecc_coe) { 10550 if ((rev_id >= BCM56450_B0_REV_ID) || SOC_IS_SABER2(unit)) { 10551 if (e2ecc_strict) { 10552 config->flags |= 10553 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE; 10554 } else { 10555 config->flags |= 10556 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE; 10557 } 10558 } else if (rev_id == BCM56450_A0_REV_ID) { 10559 config->flags |= 10560 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE; 10561 } 10562 SOC_IF_ERROR_RETURN( 10563 READ_ING_VOQFC_MACDA_MSr(unit, ®val)); 10564 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_MSr, 10565 regval, DAf); 10566 config->dest_mac[0] = ((field_val >> 8) & 0xff); 10567 config->dest_mac[1] = (field_val & 0xff); 10568 10569 SOC_IF_ERROR_RETURN( 10570 READ_ING_VOQFC_MACDA_LSr(unit, ®val)); 10571 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_LSr, 10572 regval, DAf); 10573 config->dest_mac[2] = ((field_val >> 24) & 0xff); 10574 config->dest_mac[3] = ((field_val >> 16) & 0xff); 10575 config->dest_mac[4] = ((field_val >> 8) & 0xff); 10576 config->dest_mac[5] = (field_val & 0xff); 10577 10578 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, ®val)); 10579 config->ethertype = 10580 soc_reg_field_get(unit, ING_VOQFC_IDr, 10581 regval, LENGTH_TYPEf); 10582 config->opcode = 10583 soc_reg_field_get(unit, ING_VOQFC_IDr, 10584 regval, OPCODEf); 10585 } 10586 } 10587 } 10588 } 10589 #endif /* BCM_KATANA2_SUPPORT */ 10590 10591 return BCM_E_NONE; 10592 } 10593 #endif /* BCM_TRX_SUPPORT */ 10594 10595 STATIC void 10596 _scache_port_print_ll_init(int unit) 10597 { 10598 int i; 10599 10600 for (i = 0; i < SCACHE_PORT_TYPE_MAX; i++) { 10601 scache_head[i] = NULL; 10602 scache_tail[i] = NULL; 10603 } 10604 } 10605 10606 STATIC void 10607 _scache_port_print_clear_ll(int unit, scache_port_type_t type) 10608 { 10609 scache_port_print_port_t *entry; 10610 10611 if (bsl_check(bslLayerShared, bslSourceScache, 10612 bslSeverityVerbose, unit)) { 10613 assert(type < SCACHE_PORT_TYPE_MAX); 10614 10615 /* delete from the head */ 10616 while (scache_head[type] != NULL) { 10617 entry = scache_head[type]; 10618 scache_head[type] = scache_head[type]->next; 10619 sal_free(entry); 10620 } 10621 /* now that the list is empty and head is NULL, make tail pointer NULL */ 10622 scache_tail[type] = NULL; 10623 } 10624 } 10625 10626 STATIC void 10627 _scache_port_print_clear_all(int unit) 10628 { 10629 int i; 10630 10631 for (i = 0; i < SCACHE_PORT_TYPE_MAX; i++) { 10632 _scache_port_print_clear_ll(unit, i); 10633 } 10634 } 10635 10636 STATIC void 10637 _scache_port_print_add_ll(int unit, scache_port_type_t type, 10638 scache_port_print_port_t * entry) 10639 { 10640 if (NULL == entry) { 10641 return; 10642 } 10643 10644 /* Head of linked list is NULL */ 10645 if (scache_head[type] == NULL) { 10646 scache_head[type] = entry; 10647 scache_tail[type] = entry; 10648 } else { 10649 /* put the entry at the end */ 10650 10651 /* Update the current tail's next */ 10652 scache_tail[type]->next = entry; 10653 10654 /* Store the entry at the end */ 10655 scache_tail[type] = entry; 10656 } 10657 } 10658 10659 STATIC int 10660 _scache_port_print_add(int unit, int port, scache_port_type_t type, int len, 10661 uint8 *val) 10662 { 10663 scache_port_print_port_t *new_entry; 10664 10665 if (bsl_check(bslLayerShared, bslSourceScache, 10666 bslSeverityVerbose, unit)) { 10667 assert(type < SCACHE_PORT_TYPE_MAX); 10668 10669 new_entry = (scache_port_print_port_t *) 10670 sal_alloc(sizeof(scache_port_print_port_t), "scache_port"); 10671 if (NULL == new_entry) { 10672 return BCM_E_MEMORY; 10673 } 10674 10675 new_entry->next = NULL; 10676 new_entry->val = val; 10677 new_entry->len = len; 10678 new_entry->port = port; 10679 10680 _scache_port_print_add_ll(unit, type, new_entry); 10681 } 10682 10683 return BCM_E_NONE; 10684 } 10685 10686 STATIC void 10687 _scache_port_print(int unit, scache_port_type_t type) 10688 { 10689 uint8 *scache_runner; 10690 scache_port_print_port_t *runner; 10691 10692 if (bsl_check(bslLayerShared, bslSourceScache, 10693 bslSeverityVerbose, unit)) { 10694 assert(type < SCACHE_PORT_TYPE_MAX); 10695 10696 runner = scache_head[type]; 10697 10698 /* No scache entries in this type */ 10699 if (runner == NULL) { 10700 return; 10701 } 10702 10703 /* If port == -1, not a port based entry */ 10704 if (runner->port == -1) { 10705 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10706 (BSL_META_U(unit, 10707 "\nS$BEGIN:<port>:<%s>"), 10708 port_scache_strs[type])); 10709 10710 while(NULL != runner) { 10711 if (runner->len == sizeof(uint8)) { 10712 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10713 (BSL_META_U(unit, 10714 "\n{0x%02x}"), 10715 *(int *)(runner->val) & 0xff)); 10716 } else if (runner->len == sizeof(uint16) || 10717 runner->len == sizeof(uint32)) { 10718 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10719 (BSL_META_U(unit, 10720 "\n{%d}"), 10721 *(int *)(runner->val))); 10722 } else { 10723 /* larger than 32 bits */ 10724 scache_runner = runner->val; 10725 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10726 (BSL_META_U(unit, 10727 "\n{"))); 10728 while (scache_runner < runner->val + runner->len) { 10729 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10730 (BSL_META_U(unit, 10731 "%d%s"), *(int *)(runner->val), 10732 ((scache_runner+sizeof(int)) < 10733 (runner->val + runner->len))?" ":"")); 10734 scache_runner += sizeof(int); 10735 } 10736 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10737 (BSL_META_U(unit, 10738 "}"))); 10739 } 10740 10741 /* Go to the next entry */ 10742 runner = runner->next; 10743 } 10744 } else { 10745 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10746 (BSL_META_U(unit, 10747 "\nS$BEGIN:<port>:<port;%s>"), 10748 port_scache_strs[type])); 10749 10750 while(NULL != runner) { 10751 if (runner->len == sizeof(uint8)) { 10752 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10753 (BSL_META_U(unit, 10754 "\n{%d;0x%02x}"), runner->port, 10755 *(int *)(runner->val) & 0xff)); 10756 } else if (runner->len == sizeof(uint16) || 10757 runner->len == sizeof(uint32)) { 10758 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10759 (BSL_META_U(unit, 10760 "\n{%d;%d}"), runner->port, 10761 *(int *)(runner->val))); 10762 } else { 10763 /* larger than 32 bits */ 10764 scache_runner = runner->val; 10765 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10766 (BSL_META_U(unit, 10767 "\n{%d;"), runner->port)); 10768 while (scache_runner < runner->val + runner->len) { 10769 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10770 (BSL_META_U(unit, 10771 "%d%s"), *(int *)(runner->val), 10772 ((scache_runner+sizeof(int)) < 10773 (runner->val + runner->len))?" ":"")); 10774 scache_runner += sizeof(int); 10775 } 10776 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10777 (BSL_META_U(unit, 10778 "}"))); 10779 } 10780 10781 /* Go to the next entry */ 10782 runner = runner->next; 10783 } 10784 } 10785 10786 10787 LOG_VERBOSE(BSL_LS_SHARED_SCACHE, 10788 (BSL_META_U(unit, 10789 "\nS$END:port\n"))); 10790 } 10791 } 10792 10793 STATIC void 10794 _scache_port_print_all(int unit) 10795 { 10796 int i; 10797 10798 for (i = 0; i < SCACHE_PORT_TYPE_MAX; i++) { 10799 _scache_port_print(unit, i); 10800 } 10801 } 10802 10803 STATIC int 10804 _bcm_esw_port_sync_scache(int unit, uint8 *port_state, int stable_size, 10805 uint32 asf_wbmem_sz, uint32 latency_wbmem_sz, 10806 bcm_pbmp_t *all_pbmp) 10807 { 10808 bcm_port_t port; 10809 bcm_pbmp_t dtm_pbmp; 10810 _bcm_port_info_t *pinfo = NULL; 10811 int rv = BCM_E_NONE; 10812 #ifdef BCM_TRIDENT_SUPPORT 10813 soc_info_t *si = &SOC_INFO(unit); 10814 #endif 10815 10816 BCM_PBMP_CLEAR(dtm_pbmp); 10817 10818 PBMP_ITER(*all_pbmp, port) { 10819 if (port < SOC_MAX_NUM_PORTS) { 10820 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 10821 } 10822 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 10823 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) { 10824 int idxmin, idxmax, idx; 10825 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm); 10826 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm); 10827 10828 for (idx = idxmin; idx <= idxmax; idx++) { 10829 if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, idx)) { 10830 sal_memcpy(port_state, &idx, sizeof(int)); 10831 port_state += sizeof(int); 10832 10833 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, 10834 SPT_PBVL, sizeof(int), port_state - sizeof(int))); 10835 break; 10836 } 10837 } 10838 if (idx > idxmax) { 10839 idx = -1; 10840 sal_memcpy(port_state, &idx, sizeof(int)); 10841 port_state += sizeof(int); 10842 10843 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, SPT_PBVL, 10844 sizeof(int), port_state - sizeof(int))); 10845 } 10846 10847 sal_memcpy(port_state, &(pinfo->vlan_prot_ptr), 10848 sizeof(uint32)); 10849 port_state += sizeof(uint32); 10850 10851 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, 10852 SPT_VLAN_PROT_PTR, sizeof(uint32), 10853 port_state - sizeof(uint32))); 10854 } 10855 #endif 10856 /* In Apache information is saved and recovered for 76 ports which is 10857 * greater than SOC_MAX_NUM_PORTS value of 75. These checks are 10858 * needed to prevent invalid memory access. 10859 */ 10860 if (port < SOC_MAX_NUM_PORTS) { 10861 if (0 != (pinfo->dtag_mode & 10862 (BCM_PORT_DTAG_MODE_INTERNAL | BCM_PORT_DTAG_MODE_EXTERNAL))) { 10863 /* Some sort of double-tagged mode */ 10864 BCM_PBMP_PORT_ADD(dtm_pbmp, port); 10865 } 10866 sal_memcpy(port_state, &(pinfo->vp_count), sizeof(pinfo->vp_count)); 10867 } 10868 port_state += sizeof(int); 10869 10870 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, SPT_VP_COUNT, 10871 sizeof(int), port_state - sizeof(int))); 10872 } 10873 sal_memcpy(port_state, &dtm_pbmp, sizeof(dtm_pbmp)); 10874 port_state += sizeof(dtm_pbmp); 10875 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, -1, SPT_DTM_PBMP, 10876 sizeof(dtm_pbmp), port_state - sizeof(dtm_pbmp))); 10877 10878 PBMP_ITER(*all_pbmp, port) { 10879 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 10880 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 10881 if (port < SOC_MAX_NUM_PORTS) { 10882 sal_memcpy(port_state, &(PORT(unit, port).cosmask), sizeof(uint32)); 10883 } 10884 port_state += sizeof(uint32); 10885 10886 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, 10887 SPT_COSMASK, sizeof(uint32), port_state - sizeof(uint32))); 10888 } else { 10889 if (port < SOC_MAX_NUM_PORTS) { 10890 sal_memcpy(port_state, &(PORT(unit, port).m_info), 10891 sizeof(_bcm_port_metering_info_t)); 10892 } 10893 port_state += sizeof(_bcm_port_metering_info_t); 10894 10895 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, SPT_METERING_INFO, 10896 sizeof(_bcm_port_metering_info_t), 10897 port_state - sizeof(_bcm_port_metering_info_t))); 10898 } 10899 if (port < SOC_MAX_NUM_PORTS) { 10900 sal_memcpy(port_state, &(PORT(unit, port).flags), sizeof(uint8)); 10901 } 10902 port_state += sizeof(uint8); 10903 10904 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, 10905 SPT_PORT_FLAGS, sizeof(uint8), 10906 port_state - sizeof(uint8))); 10907 } 10908 10909 } 10910 #ifdef BCM_TRIDENT_SUPPORT 10911 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) && 10912 soc_feature(unit, soc_feature_flex_port)) { 10913 /* coverity[overrun-local] */ 10914 PBMP_ALL_ITER(unit, port) { 10915 if (port < SOC_MAX_NUM_PORTS) { 10916 sal_memcpy(port_state, &(si->port_num_lanes[port]), sizeof(int)); 10917 } 10918 port_state += sizeof(int); 10919 10920 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, 10921 SPT_PORT_NUM_LANES, sizeof(int), 10922 port_state - sizeof(int))); 10923 } 10924 } 10925 #endif 10926 10927 /* Restore SW RX LOS status */ 10928 PBMP_ITER(*all_pbmp, port) { 10929 if (port < SOC_MAX_NUM_PORTS) { 10930 sal_memcpy(port_state, &(PORT(unit, port).rx_los), sizeof(uint8)); 10931 } 10932 port_state += sizeof(uint8); 10933 10934 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, SPT_RX_LOS, 10935 sizeof(uint8), port_state - sizeof(uint8))); 10936 } 10937 10938 10939 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_FIRELIGHT_SUPPORT) 10940 if (SOC_IS_TD2_TT2(unit) || SOC_IS_FIRELIGHT(unit)) { 10941 /* Restore port enable status */ 10942 PBMP_ITER(*all_pbmp, port) { 10943 if (port < SOC_MAX_NUM_PORTS) { 10944 sal_memcpy(port_state, &(PORT(unit, port).enable), sizeof(int)); 10945 } 10946 port_state += sizeof(int); 10947 10948 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, 10949 SPT_PORT_ENABLE, sizeof(int), port_state - sizeof(int))); 10950 } 10951 } 10952 #endif /* BCM_TRIDENT2_SUPPORT */ 10953 #ifdef BCM_TRIUMPH3_SUPPORT 10954 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) { 10955 if (_port_ibod_ctrl[unit]) { 10956 sal_memcpy(port_state, _port_ibod_ctrl[unit]->rrbyt, 10957 sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)); 10958 port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrbyt); 10959 sal_memcpy(port_state, _port_ibod_ctrl[unit]->rrpkt, 10960 sizeof(((_port_ibod_ctrl_t *)0)->rrpkt)); 10961 port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrpkt); 10962 sal_memcpy(port_state, &(_port_ibod_ctrl[unit]->event_count), 10963 sizeof(((_port_ibod_ctrl_t *)0)->event_count)); 10964 port_state += sizeof(((_port_ibod_ctrl_t *)0)->event_count); 10965 } else { 10966 sal_memset(port_state, 0, 10967 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt) 10968 + sizeof((((_port_ibod_ctrl_t *)0)->event_count))); 10969 port_state += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt) 10970 + sizeof((((_port_ibod_ctrl_t *)0)->event_count)); 10971 } 10972 10973 } 10974 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 10975 BCM_IF_ERROR_RETURN(_bcm_port_force_forward_sync(unit, &port_state)); 10976 } 10977 #endif /* BCM_TRIUMPH3_SUPPORT */ 10978 10979 #ifdef BCM_TOMAHAWK_SUPPORT 10980 /* ASF WB */ 10981 BCM_IF_ERROR_RETURN(_bcm_esw_asf_wb_sync(unit, port_state)); 10982 port_state += asf_wbmem_sz; 10983 10984 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, -1, SPT_ASF, asf_wbmem_sz, 10985 port_state - asf_wbmem_sz)); 10986 10987 /* Switch Latency Bypass WB */ 10988 BCM_IF_ERROR_RETURN(bcmi_esw_switch_latency_wb_sync(unit, port_state)); 10989 port_state += latency_wbmem_sz; 10990 10991 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, -1, SPT_LATENCY, 10992 latency_wbmem_sz, port_state - latency_wbmem_sz)); 10993 10994 #endif /* BCM_TOMAHAWK_SUPPORT */ 10995 10996 /*IFG WB*/ 10997 if (soc_feature(unit, soc_feature_xmac) || 10998 soc_feature(unit, soc_feature_xlmac) || 10999 soc_feature(unit, soc_feature_cmac) || 11000 soc_feature(unit, soc_feature_clmac)) { 11001 11002 BCM_IF_ERROR_RETURN(_bcm_esw_port_ifg_wb_sync(unit, &port_state)); 11003 } 11004 /* PORT DSCP MAP SETTING */ 11005 if (soc_feature(unit, soc_feature_dscp) && 11006 soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 11007 /* Allocate size for port dscp map setting status */ 11008 PBMP_ITER(*all_pbmp, port) { 11009 sal_memcpy(port_state, &(PORT(unit, port).port_dscp_map_set), sizeof(int)); 11010 port_state += sizeof(int); 11011 11012 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, SPT_DSCP_MAP, 11013 sizeof(int), port_state - sizeof(int))); 11014 } 11015 } 11016 11017 #if defined(BCM_CLMAC_SUPPORT) 11018 if (SOC_IS_TOMAHAWK(unit)) { 11019 soc_port_if_t pif; 11020 /* Restore port interface type */ 11021 PBMP_ITER(*all_pbmp, port) { 11022 if (IS_XE_PORT(unit, port) || 11023 IS_CE_PORT(unit, port) || 11024 IS_HG_PORT(unit, port) || 11025 IS_GE_PORT(unit, port) || 11026 IS_MANAGEMENT_PORT(unit, port)) { 11027 BCM_IF_ERROR_RETURN(soc_phyctrl_interface_get(unit, port, &pif)); 11028 sal_memcpy(port_state, &pif, sizeof(int)); 11029 port_state += sizeof(int); 11030 11031 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, 11032 SPT_PORT_INTF_TYPE, sizeof(int), 11033 port_state - sizeof(int))); 11034 } 11035 } 11036 } 11037 #endif 11038 11039 if (soc_feature(unit, soc_feature_phy_interface_wb)) { 11040 soc_port_if_t pif; 11041 11042 /* Restore port interface type */ 11043 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 11044 rv = soc_phyctrl_interface_get(unit, port, &pif); 11045 if (BCM_FAILURE(rv)) { 11046 pif = 0; 11047 } 11048 sal_memcpy(port_state, &pif, sizeof(int)); 11049 port_state += sizeof(int); 11050 11051 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, 11052 SPT_PORT_INTF_TYPE, 11053 sizeof(int), port_state - sizeof(int))); 11054 } 11055 } 11056 11057 return BCM_E_NONE; 11058 } 11059 /* 11060 * Function: 11061 * _bcm_esw_port_sync 11062 * Purpose: 11063 * Record Port module persisitent info for Level 2 Warm Boot 11064 * 11065 * Warm Boot Version Map: 11066 * Fields for previous version to be documented 11067 * BCM_PORT_WB_VERSION_1_0 11068 * ... 11069 * BCM_PORT_WB_VERSION_1_1 11070 * ... 11071 * BCM_PORT_WB_VERSION_1_2 11072 * rx_los SW RX LOS 11073 * ... 11074 * BCM_PORT_WB_VERSION_1_3 11075 * enable port eanble status 11076 * 11077 * Parameters: 11078 * unit - StrataSwitch unit number. 11079 * Returns: 11080 * BCM_E_XXX 11081 */ 11082 int 11083 _bcm_esw_port_sync(int unit) 11084 { 11085 int rv = BCM_E_NONE; 11086 11087 #if defined(BCM_TRX_SUPPORT) 11088 if (SOC_IS_TRX(unit)) { 11089 int alloc_sz; 11090 bcm_port_t port; 11091 uint8 *port_state; 11092 bcm_pbmp_t dtm_pbmp; 11093 int stable_size; 11094 soc_scache_handle_t scache_handle; 11095 bcm_pbmp_t all_pbmp; 11096 uint32 asf_wbmem_sz = 0; 11097 /* Switch Latency Bypass WB will move to a different module later */ 11098 uint32 latency_wbmem_sz = 0; 11099 11100 BCM_PBMP_CLEAR(all_pbmp); 11101 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 11102 11103 #ifdef BCM_KATANA2_SUPPORT 11104 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 11105 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 11106 } 11107 if (soc_feature(unit, soc_feature_linkphy_coe) || 11108 soc_feature(unit, soc_feature_subtag_coe)) { 11109 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 11110 } 11111 #endif 11112 11113 #ifdef BCM_TRIDENT2PLUS_SUPPORT 11114 if (SOC_IS_TD2P_TT2P(unit)) { 11115 BCM_IF_ERROR_RETURN(bcm_td2p_flexport_pbmp_update(unit, 11116 &all_pbmp)); 11117 } 11118 #endif 11119 #ifdef BCM_MONTEREY_SUPPORT 11120 if (SOC_IS_MONTEREY(unit)) { 11121 BCM_IF_ERROR_RETURN(bcm_monterey_flexport_pbmp_update(unit, &all_pbmp)); 11122 } 11123 #endif 11124 #ifdef BCM_APACHE_SUPPORT 11125 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 11126 BCM_IF_ERROR_RETURN(bcm_apache_flexport_pbmp_update(unit, &all_pbmp)); 11127 } 11128 #endif 11129 11130 alloc_sz = 0; 11131 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 11132 PBMP_ITER(all_pbmp, port) { 11133 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 11134 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) { 11135 /* vp entry and vlan prot ptr */ 11136 alloc_sz += (sizeof(int) + sizeof(uint32)); 11137 } 11138 #endif 11139 alloc_sz += sizeof(int); /* vp count */ 11140 } 11141 alloc_sz += sizeof(dtm_pbmp); /* Bitmap of dtag_mode set */ 11142 11143 PBMP_ITER(all_pbmp, port) { 11144 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 11145 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 11146 alloc_sz += sizeof(uint32); 11147 } else { 11148 alloc_sz += sizeof(_bcm_port_metering_info_t); 11149 } 11150 alloc_sz += sizeof(uint8); /* flags */ 11151 } 11152 } 11153 11154 #ifdef BCM_TRIDENT_SUPPORT 11155 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) && 11156 soc_feature(unit, soc_feature_flex_port)) { 11157 /* Number of lanes per port needs to be stored.*/ 11158 alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int)); 11159 } 11160 #endif 11161 11162 /* Size for SW RX LOS status */ 11163 PBMP_ITER(all_pbmp, port) { 11164 alloc_sz += sizeof(uint8); 11165 } 11166 11167 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_FIRELIGHT_SUPPORT) 11168 if (SOC_IS_TD2_TT2(unit) || SOC_IS_FIRELIGHT(unit)) { 11169 /* Size for port enable status */ 11170 PBMP_ITER(all_pbmp, port) { 11171 alloc_sz += sizeof(int); 11172 } 11173 } 11174 #endif /* BCM_TRIDENT2_SUPPORT */ 11175 #ifdef BCM_TRIUMPH3_SUPPORT 11176 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) { 11177 alloc_sz += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt) 11178 + sizeof((((_port_ibod_ctrl_t *)0)->event_count)); 11179 } 11180 #endif /* BCM_TRIUMPH3_SUPPORT */ 11181 #if defined(BCM_TRIUMPH3_SUPPORT) 11182 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 11183 int port_forward_size; 11184 BCM_IF_ERROR_RETURN( 11185 _bcm_port_force_forward_scache_size(unit, 11186 &port_forward_size)); 11187 alloc_sz += port_forward_size; 11188 } 11189 #endif 11190 11191 #ifdef BCM_TOMAHAWK_SUPPORT 11192 /* ASF WB */ 11193 rv = _bcm_esw_asf_wb_memsz_get(unit, &asf_wbmem_sz, 11194 BCM_PORT_WB_DEFAULT_VERSION); 11195 if (BCM_E_NONE == rv) { 11196 alloc_sz += asf_wbmem_sz; 11197 } 11198 11199 /* Switch Latency Bypass WB */ 11200 rv = bcmi_esw_switch_latency_wb_memsz_get(unit, &latency_wbmem_sz, 11201 BCM_PORT_WB_DEFAULT_VERSION); 11202 if (BCM_E_NONE == rv) { 11203 alloc_sz += latency_wbmem_sz; 11204 } 11205 #endif /* BCM_TOMAHAWK_SUPPORT */ 11206 11207 /*IFG WB*/ 11208 if (soc_feature(unit, soc_feature_xmac) || 11209 soc_feature(unit, soc_feature_xlmac) || 11210 soc_feature(unit, soc_feature_cmac) || 11211 soc_feature(unit, soc_feature_clmac)) { 11212 PBMP_ITER(all_pbmp, port) { 11213 alloc_sz += sizeof(uint32); 11214 } 11215 } 11216 /* PORT DSCP MAP SETTING */ 11217 if (soc_feature(unit, soc_feature_dscp) && 11218 soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 11219 /* Allocate size for port dscp map setting status */ 11220 PBMP_ITER(all_pbmp, port) { 11221 alloc_sz += sizeof(int); 11222 } 11223 } 11224 11225 #ifdef BCM_TOMAHAWK_SUPPORT 11226 if (SOC_IS_TOMAHAWK(unit)) { 11227 /* Allocate size for port interface type */ 11228 PBMP_ITER(all_pbmp, port) { 11229 alloc_sz += sizeof(int); 11230 } 11231 } 11232 #endif /* BCM_TOMAHAWK_SUPPORT */ 11233 11234 if (soc_feature(unit, soc_feature_phy_interface_wb)) { 11235 /* Allocate size for port interface type */ 11236 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 11237 alloc_sz += sizeof(int); 11238 } 11239 } 11240 11241 SOC_SCACHE_HANDLE_SET(scache_handle, 11242 unit, BCM_MODULE_PORT, 11243 BCM_PORT_WB_SCACHE_PART_DEFAULT); 11244 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 11245 alloc_sz, (uint8**)&port_state, 11246 BCM_PORT_WB_DEFAULT_VERSION, NULL); 11247 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 11248 return rv; 11249 } 11250 11251 _scache_port_print_ll_init(unit); 11252 11253 PORT_LOCK(unit); 11254 11255 rv = _bcm_esw_port_sync_scache(unit, port_state, stable_size, asf_wbmem_sz, latency_wbmem_sz, 11256 &all_pbmp); 11257 11258 PORT_UNLOCK(unit); 11259 11260 if (BCM_SUCCESS(rv)) { 11261 _scache_port_print_all(unit); 11262 } 11263 _scache_port_print_clear_all(unit); 11264 if (BCM_FAILURE(rv)) { 11265 return rv; 11266 } 11267 } 11268 #endif /* BCM_TRX_SUPPORT */ 11269 11270 #ifdef BCM_PREEMPTION_SUPPORT 11271 if (BCM_SUCCESS(rv) && soc_feature(unit, soc_feature_preemption)) { 11272 soc_scache_handle_t scache_handle; 11273 11274 SOC_SCACHE_HANDLE_SET(scache_handle, 11275 unit, BCM_MODULE_PORT, 11276 BCM_PORT_WB_SCACHE_PART_PREMMPTION); 11277 11278 rv = bcmi_esw_preemption_sync(unit, scache_handle); 11279 } 11280 #endif /* BCM_PREEMPTION_SUPPORT */ 11281 return rv; 11282 } 11283 11284 int 11285 _bcm_esw_port_wb_alloc(int unit) 11286 { 11287 11288 #if defined(BCM_TRX_SUPPORT) 11289 if (SOC_IS_TRX(unit)) { 11290 int alloc_sz, rv = BCM_E_NONE; 11291 bcm_port_t port; 11292 uint8 *port_state; 11293 int stable_size; 11294 bcm_pbmp_t all_pbmp; 11295 soc_scache_handle_t scache_handle; 11296 #ifdef BCM_TOMAHAWK_SUPPORT 11297 uint32 asf_wbmem_sz = 0; 11298 11299 /* Switch Latency Bypass WB will move to a different module later */ 11300 uint32 latency_wbmem_sz = 0; 11301 #endif /* BCM_TOMAHAWK_SUPPORT */ 11302 11303 BCM_PBMP_CLEAR(all_pbmp); 11304 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 11305 11306 #ifdef BCM_KATANA2_SUPPORT 11307 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 11308 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 11309 } 11310 if (soc_feature(unit, soc_feature_linkphy_coe) || 11311 soc_feature(unit, soc_feature_subtag_coe)) { 11312 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 11313 } 11314 #endif 11315 11316 #ifdef BCM_TRIDENT2PLUS_SUPPORT 11317 if (SOC_IS_TD2P_TT2P(unit)) { 11318 BCM_IF_ERROR_RETURN(bcm_td2p_flexport_pbmp_update(unit, 11319 &all_pbmp)); 11320 } 11321 #endif 11322 #ifdef BCM_MONTEREY_SUPPORT 11323 if (SOC_IS_MONTEREY(unit)) { 11324 BCM_IF_ERROR_RETURN(bcm_monterey_flexport_pbmp_update(unit, &all_pbmp)); 11325 } 11326 #endif 11327 #ifdef BCM_APACHE_SUPPORT 11328 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 11329 BCM_IF_ERROR_RETURN(bcm_apache_flexport_pbmp_update(unit, &all_pbmp)); 11330 } 11331 #endif 11332 alloc_sz = 0; 11333 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 11334 PBMP_ITER(all_pbmp, port) { 11335 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 11336 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) { 11337 /* vp entry and vlan prot ptr */ 11338 alloc_sz += (sizeof(int) + sizeof(uint32)); 11339 } 11340 #endif 11341 alloc_sz += sizeof(int); /* vp count */ 11342 } 11343 alloc_sz += sizeof(bcm_pbmp_t); /* Bitmap of dtag_mode == NONE */ 11344 PBMP_ITER(all_pbmp, port) { 11345 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 11346 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 11347 alloc_sz += sizeof(uint32); 11348 } else { 11349 alloc_sz += sizeof(_bcm_port_metering_info_t); 11350 } 11351 alloc_sz += sizeof(uint8); /* flags */ 11352 } 11353 } 11354 11355 #ifdef BCM_TRIDENT_SUPPORT 11356 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) && 11357 soc_feature(unit, soc_feature_flex_port)) { 11358 alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int)); 11359 } 11360 #endif 11361 11362 /* Restore SW RX LOS status */ 11363 PBMP_ITER(all_pbmp, port) { 11364 alloc_sz += sizeof(uint8); 11365 } 11366 11367 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_FIRELIGHT_SUPPORT) 11368 if (SOC_IS_TD2_TT2(unit) || SOC_IS_FIRELIGHT(unit)) { 11369 /* Allocate size for port enable status */ 11370 PBMP_ITER(all_pbmp, port) { 11371 alloc_sz += sizeof(int); 11372 } 11373 } 11374 #endif /* BCM_TRIDENT2_SUPPORT */ 11375 #ifdef BCM_TRIUMPH3_SUPPORT 11376 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) { 11377 alloc_sz += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt) 11378 + sizeof((((_port_ibod_ctrl_t *)0)->event_count)); 11379 } 11380 #endif /* BCM_TRIUMPH3_SUPPORT */ 11381 #if defined(BCM_TRIUMPH3_SUPPORT) 11382 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 11383 int port_forward_size; 11384 BCM_IF_ERROR_RETURN( 11385 _bcm_port_force_forward_scache_size(unit, &port_forward_size)); 11386 alloc_sz += port_forward_size; 11387 } 11388 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */ 11389 11390 #ifdef BCM_TOMAHAWK_SUPPORT 11391 /* ASF WB */ 11392 rv = _bcm_esw_asf_wb_memsz_get(unit, &asf_wbmem_sz, BCM_PORT_WB_DEFAULT_VERSION); 11393 if (BCM_E_NONE == rv) { 11394 alloc_sz += asf_wbmem_sz; 11395 } 11396 11397 /* Switch Latency Bypass WB */ 11398 rv = bcmi_esw_switch_latency_wb_memsz_get(unit, &latency_wbmem_sz, 11399 BCM_PORT_WB_DEFAULT_VERSION); 11400 if (BCM_E_NONE == rv) { 11401 alloc_sz += latency_wbmem_sz; 11402 } 11403 #endif /* BCM_TOMAHAWK_SUPPORT */ 11404 11405 /*IFG WB*/ 11406 if (soc_feature(unit, soc_feature_xmac) || 11407 soc_feature(unit, soc_feature_xlmac) || 11408 soc_feature(unit, soc_feature_cmac) || 11409 soc_feature(unit, soc_feature_clmac)) { 11410 PBMP_ITER(all_pbmp, port) { 11411 alloc_sz += sizeof(uint32); 11412 } 11413 } 11414 /* PORT DSCP MAP SETTING */ 11415 if (soc_feature(unit, soc_feature_dscp) && 11416 soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 11417 /* Allocate size for port dscp map setting status */ 11418 PBMP_ITER(all_pbmp, port) { 11419 alloc_sz += sizeof(int); 11420 } 11421 } 11422 11423 #ifdef BCM_TOMAHAWK_SUPPORT 11424 if (SOC_IS_TOMAHAWK(unit)) { 11425 /* Allocate size for port interface type */ 11426 PBMP_ITER(all_pbmp, port) { 11427 alloc_sz += sizeof(int); 11428 } 11429 } 11430 #endif /* BCM_TOMAHAWK_SUPPORT */ 11431 11432 if (soc_feature(unit, soc_feature_phy_interface_wb)) { 11433 /* Allocate size for port interface type */ 11434 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 11435 alloc_sz += sizeof(int); 11436 } 11437 } 11438 11439 SOC_SCACHE_HANDLE_SET(scache_handle, 11440 unit, BCM_MODULE_PORT, 11441 BCM_PORT_WB_SCACHE_PART_DEFAULT); 11442 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, 11443 alloc_sz, (uint8**)&port_state, 11444 BCM_PORT_WB_DEFAULT_VERSION, NULL); 11445 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 11446 return rv; 11447 } 11448 } 11449 #endif /* BCM_TRX_SUPPORT */ 11450 11451 #ifdef BCM_PREEMPTION_SUPPORT 11452 if (soc_feature(unit, soc_feature_preemption)) { 11453 soc_scache_handle_t scache_handle; 11454 11455 SOC_SCACHE_HANDLE_SET(scache_handle, 11456 unit, BCM_MODULE_PORT, 11457 BCM_PORT_WB_SCACHE_PART_PREMMPTION); 11458 BCM_IF_ERROR_RETURN( 11459 bcmi_esw_preemption_wb_alloc(unit, scache_handle)); 11460 } 11461 #endif /* BCM_PREEMPTION_SUPPORT */ 11462 11463 return BCM_E_NONE; 11464 } 11465 11466 #ifdef BCM_TRIUMPH2_SUPPORT 11467 /* 11468 * Function: 11469 * _bcm_tr2_flexport_recover 11470 * Purpose: 11471 * To recover/reconstruct the HL port configuration 11472 * during warmboot. This is a 'level one' warmboot 11473 * recovery. It depends on the reg configuration of 11474 * EDATABUF_XQP_FLEXPORT_CONFIGr which maintains the 11475 * flexport config of the HL ports that was done 11476 * in coldboot mode. 11477 * Parameters: 11478 * unit - StrataSwitch unit number. 11479 * port - Port number of the HL 11480 * flexport controlling port. 11481 * Returns: 11482 * BCM_E_XXX 11483 */ 11484 STATIC int 11485 _bcm_tr2_flexport_recover(int unit, bcm_port_t port) 11486 { 11487 uint8 rev_id; 11488 uint16 dev_id; 11489 uint32 port_type; 11490 int i, old_value, rv; 11491 bcm_port_t it_port; 11492 port_tab_entry_t pent; 11493 soc_info_t *si = &SOC_INFO(unit); 11494 11495 soc_cm_get_id(unit, &dev_id, &rev_id); 11496 BCM_IF_ERROR_RETURN(_bcm_tr2_port_lanes_get(unit, port, &old_value)); 11497 11498 #define RECONFIGURE_TR2_PORT_TYPE_INFO(ptype) \ 11499 si->ptype.num = 0; \ 11500 si->ptype.min = si->ptype.max = -1; \ 11501 PBMP_ITER(si->ptype.bitmap, it_port) { \ 11502 si->ptype.port[si->ptype.num++] = it_port; \ 11503 if (si->ptype.min < 0) { \ 11504 si->ptype.min = it_port; \ 11505 } \ 11506 if (it_port > si->ptype.max) { \ 11507 si->ptype.max = it_port; \ 11508 } \ 11509 } 11510 11511 /* Step 1: Change the SOC bitmaps */ 11512 if ((old_value == 1)) { 11513 /* The block originally had 4 GE ports */ 11514 SOC_CONTROL_LOCK(unit); 11515 SOC_PBMP_PORT_REMOVE(si->st.bitmap, port); 11516 SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port); 11517 SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port); 11518 SOC_PBMP_PORT_ADD(si->ether.bitmap, port); 11519 SOC_PBMP_PORT_ADD(si->ge.bitmap, port); 11520 si->port_speed_max[port] = 1000; 11521 soc_port_cmap_set(unit, port, SOC_CTR_TYPE_GE); 11522 for (i = port + 1; i < port + 4; i++) { 11523 SOC_PBMP_PORT_REMOVE(si->ge.disabled_bitmap, i); 11524 SOC_PBMP_PORT_REMOVE(si->ether.disabled_bitmap, i); 11525 SOC_PBMP_PORT_REMOVE(si->port.disabled_bitmap, i); 11526 SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, i); 11527 si->port_speed_max[i] = 1000; 11528 soc_port_cmap_set(unit, i, SOC_CTR_TYPE_GE); 11529 } 11530 RECONFIGURE_TR2_PORT_TYPE_INFO(ether); 11531 RECONFIGURE_TR2_PORT_TYPE_INFO(st); 11532 RECONFIGURE_TR2_PORT_TYPE_INFO(hg); 11533 RECONFIGURE_TR2_PORT_TYPE_INFO(xe); 11534 RECONFIGURE_TR2_PORT_TYPE_INFO(ge); 11535 SOC_CONTROL_UNLOCK(unit); 11536 } else if (old_value == 4) { 11537 /* The block was originally a single high-speed port */ 11538 SOC_CONTROL_LOCK(unit); 11539 rv = soc_mem_read(unit, SOC_PORT_MEM_TAB(unit, port), 11540 MEM_BLOCK_ANY, SOC_PORT_MOD_OFFSET(unit, port), &pent); 11541 if (BCM_FAILURE(rv)) { 11542 SOC_CONTROL_UNLOCK(unit); 11543 return rv; 11544 } 11545 port_type = soc_PORT_TABm_field32_get(unit, &pent, PORT_TYPEf); 11546 switch(port_type) { 11547 case 0 : /* xe */ 11548 SOC_PBMP_PORT_ADD(si->xe.bitmap, port); 11549 SOC_PBMP_PORT_ADD(si->ether.bitmap, port); 11550 SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port); 11551 SOC_PBMP_PORT_REMOVE(si->st.bitmap, port); 11552 break; 11553 case 1 : /* hg */ 11554 SOC_PBMP_PORT_ADD(si->hg.bitmap, port); 11555 SOC_PBMP_PORT_ADD(si->st.bitmap, port); 11556 SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port); 11557 SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port); 11558 default: 11559 break; 11560 } 11561 SOC_PBMP_PORT_REMOVE(si->ge.bitmap, port); 11562 switch (dev_id) { 11563 case BCM56526_DEVICE_ID: 11564 si->port_speed_max[port] = 13000; 11565 break; 11566 case BCM56636_DEVICE_ID: 11567 case BCM56638_DEVICE_ID: 11568 si->port_speed_max[port] = 12000; 11569 break; 11570 default: 11571 si->port_speed_max[port] = 10000; 11572 } 11573 soc_port_cmap_set(unit, port, SOC_CTR_TYPE_XE); 11574 for (i = port + 1; i < port + 4; i++) { 11575 SOC_PBMP_PORT_ADD(si->ge.disabled_bitmap, i); 11576 SOC_PBMP_PORT_ADD(si->ether.disabled_bitmap, i); 11577 SOC_PBMP_PORT_ADD(si->port.disabled_bitmap, i); 11578 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, i); 11579 } 11580 RECONFIGURE_TR2_PORT_TYPE_INFO(ether); 11581 RECONFIGURE_TR2_PORT_TYPE_INFO(st); 11582 RECONFIGURE_TR2_PORT_TYPE_INFO(hg); 11583 RECONFIGURE_TR2_PORT_TYPE_INFO(ge); 11584 SOC_CONTROL_UNLOCK(unit); 11585 } 11586 #undef RECONFIGURE_PORT_TYPE_INFO 11587 soc_dport_map_update(unit); 11588 11589 return BCM_E_NONE; 11590 } 11591 #endif /* BCM_TRIUMPH2_SUPPORT */ 11592 11593 #ifdef BCM_TRIDENT2_SUPPORT 11594 /* 11595 * Function: 11596 * _bcm_td2_flexport_recover 11597 * Purpose: 11598 * To recover/reconstruct the HL port configuration 11599 * during warmboot. This is a 'level one' warmboot 11600 * recovery. It depends on the reg configuration of 11601 * XLPORT_MODE_REGr which maintains the 11602 * flexport config of the HL ports that was done 11603 * in coldboot mode. 11604 * Parameters: 11605 * unit - StrataSwitch unit number. 11606 * port - Port number of the HL 11607 * flexport controlling port. 11608 * Returns: 11609 * BCM_E_XXX 11610 */ 11611 STATIC int 11612 _bcm_td2_flexport_recover(int unit, bcm_port_t port) 11613 { 11614 soc_info_t *si = &SOC_INFO(unit); 11615 int i, phy_port, phy_port_base, port_base, lp; 11616 int mode, phy_port_actived[4]; 11617 uint32 rval; 11618 11619 phy_port = si->port_l2p_mapping[port]; 11620 phy_port_base = (phy_port & ~0x3) + 1; 11621 port_base = si->port_p2l_mapping[phy_port_base]; 11622 11623 if (phy_port == -1 || phy_port != phy_port_base) { 11624 return BCM_E_NONE; 11625 } 11626 11627 sal_memset(phy_port_actived, 0, sizeof(phy_port_actived)); 11628 11629 /* Get the current mode */ 11630 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 11631 BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_mode_get(unit, port, &mode)); 11632 } else { 11633 SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port_base, &rval)); 11634 mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, 11635 XPORT0_CORE_PORT_MODEf); 11636 } 11637 11638 switch(mode) { 11639 case SOC_TD2_PORT_MODE_QUAD: 11640 phy_port_actived[0] = 11641 phy_port_actived[1] = 11642 phy_port_actived[2] = 11643 phy_port_actived[3] = 1; 11644 break; 11645 case SOC_TD2_PORT_MODE_TRI_012: 11646 phy_port_actived[0] = 11647 phy_port_actived[1] = 11648 phy_port_actived[2] = 1; 11649 break; 11650 case SOC_TD2_PORT_MODE_TRI_023: 11651 phy_port_actived[0] = 11652 phy_port_actived[2] = 11653 phy_port_actived[3] = 1; 11654 break; 11655 case SOC_TD2_PORT_MODE_DUAL: 11656 phy_port_actived[0] = 11657 phy_port_actived[2] = 1; 11658 break; 11659 case SOC_TD2_PORT_MODE_SINGLE: 11660 phy_port_actived[0] = 1; 11661 break; 11662 default: 11663 return SOC_E_FAIL; 11664 } 11665 11666 SOC_CONTROL_LOCK(unit); 11667 for (i = 0; i < 4; i++) { 11668 lp = si->port_p2l_mapping[phy_port_base + i]; 11669 if (lp != -1 && 11670 BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), lp)) { 11671 if (phy_port_actived[i]) { 11672 SOC_PBMP_PORT_REMOVE(/* port(s) to be added */ 11673 SOC_PORT_DISABLED_BITMAP(unit, all), lp); 11674 } else { 11675 SOC_PBMP_PORT_ADD( /* port(s) to be removed */ 11676 SOC_PORT_DISABLED_BITMAP(unit, all), lp); 11677 } 11678 } 11679 } 11680 SOC_CONTROL_UNLOCK(unit); 11681 11682 return SOC_E_NONE; 11683 } 11684 #endif /* BCM_TRIDENT2_SUPPORT */ 11685 11686 void bcm_esw_port_mdix_wb_update(int unit) 11687 { 11688 int p; 11689 bcm_port_mdix_t mdix; 11690 11691 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 11692 /* Intentionally return value is not checked as this function 11693 * is called to wb update mdix value for the port, if it exists. 11694 */ 11695 #ifdef BCM_HURRICANE4_SUPPORT 11696 if (SOC_IS_HURRICANE4(unit) && 11697 !IS_EGPHY_PORT(unit, p)) { 11698 continue; 11699 } 11700 #endif /* BCM_HURRICANE4_SUPPORT */ 11701 bcm_esw_port_mdix_get(unit,p,&mdix); 11702 LOG_VERBOSE(BSL_LS_BCM_PORT, 11703 (BSL_META_U(unit, "Port %d MDIX udate in wb !!\n"), p)); 11704 } 11705 } 11706 11707 STATIC int 11708 _bcm_esw_port_wb_recover_scache(int unit, uint16 recovered_ver, 11709 uint8 *port_state, int stable_size, uint32 asf_wbmem_sz, 11710 uint32 latency_wbmem_sz, uint32 oamp_status, 11711 soc_scache_handle_t scache_handle, int *use_pbmp, pbmp_t *port_bitmap, 11712 bcm_pbmp_t *dtm_pbmp, bcm_pbmp_t *all_pbmp) 11713 { 11714 int rv = BCM_E_NONE; 11715 #if defined(BCM_TRX_SUPPORT) 11716 bcm_port_t port; 11717 _bcm_port_info_t *pinfo; 11718 int realloc_size = 0; 11719 #ifdef BCM_TRIUMPH2_SUPPORT 11720 #ifdef BCM_TRIDENT_SUPPORT 11721 soc_info_t *si = &SOC_INFO(unit); 11722 int _port_lanes_valid = 0; 11723 #ifdef BCM_TRIUMPH3_SUPPORT 11724 int _port_num_lanes[SOC_MAX_NUM_PORTS] = {0}; 11725 #endif /* BCM_TRIUMPH3_SUPPORT */ 11726 #endif /* BCM_TRIDENT_SUPPORT */ 11727 #endif /* BCM_TRIUMPH2_SUPPORT */ 11728 11729 PBMP_ITER(*all_pbmp, port) { 11730 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 11731 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 11732 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) && 11733 (recovered_ver >= BCM_PORT_WB_VERSION_1_9)) { 11734 /* Recover vp entry and vlan prot ptr */ 11735 uint32 vlan_protocol_data_index = 0; 11736 int idxmin, idxmax, vpentry = 0; 11737 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm); 11738 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm); 11739 11740 sal_memcpy(&vpentry, port_state, sizeof(int)); 11741 port_state += sizeof(int); 11742 11743 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, SPT_PBVL, 11744 sizeof(int), port_state - sizeof(int))); 11745 11746 if ((vpentry >= idxmin) && (vpentry <= idxmax) && 11747 (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, vpentry))) { 11748 /* Set as explicit VID */ 11749 _BCM_PORT_VD_PBVL_SET(pinfo, vpentry); 11750 } 11751 11752 sal_memcpy(&vlan_protocol_data_index, port_state, 11753 sizeof(uint32)); 11754 port_state += sizeof(uint32); 11755 11756 BCM_IF_ERROR_RETURN(_scache_port_print_add(unit, port, 11757 SPT_VLAN_PROT_PTR, 11758 sizeof(uint32), port_state - sizeof(uint32))); 11759 11760 pinfo->vp_count = 0; 11761 /* update vlan port protocol data memory */ 11762 if (!IS_LB_PORT(unit, port)) { 11763 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, 11764 _BCM_CPU_TABS_ETHER, 11765 VLAN_PROTOCOL_DATA_INDEXf, 11766 vlan_protocol_data_index / 16)); 11767 11768 pinfo->vlan_prot_ptr = vlan_protocol_data_index; 11769 BCM_IF_ERROR_RETURN( 11770 _bcm_port_vlan_protocol_data_entry_reference (unit, 11771 vlan_protocol_data_index, 16)); 11772 } 11773 } 11774 #endif 11775 /* In Apache information is saved and recovered for 76 ports which is 11776 * greater than SOC_MAX_NUM_PORTS value of 75. These checks are 11777 * needed to prevent invalid memory access. 11778 */ 11779 if (port < SOC_MAX_NUM_PORTS) { 11780 /* Recover VP reference counts */ 11781 sal_memcpy(&(pinfo->vp_count), port_state, sizeof(pinfo->vp_count)); 11782 } 11783 port_state += sizeof(int); 11784 11785 BCM_IF_ERROR_RETURN( 11786 _scache_port_print_add(unit, port, SPT_VP_COUNT, sizeof(int), 11787 port_state - sizeof(int))); 11788 } 11789 #ifdef BCM_KATANA2_SUPPORT 11790 if (SOC_IS_KATANA2(unit) && (recovered_ver >= BCM_PORT_WB_VERSION_1_9)) { 11791 /* Keep one extra reference to the default profile */ 11792 BCM_IF_ERROR_RETURN( 11793 _bcm_port_vlan_protocol_data_entry_reference (unit, 11794 0, 16)); 11795 } 11796 #endif 11797 /* Recover dtag_mode port bitmap */ 11798 sal_memcpy(dtm_pbmp, port_state, sizeof(bcm_pbmp_t)); 11799 port_state += sizeof(bcm_pbmp_t); 11800 *use_pbmp = TRUE; /* Cached info available */ 11801 11802 BCM_IF_ERROR_RETURN( 11803 _scache_port_print_add(unit, -1, SPT_DTM_PBMP, sizeof(bcm_pbmp_t), 11804 port_state - sizeof(bcm_pbmp_t))); 11805 11806 if (recovered_ver >= BCM_PORT_WB_VERSION_1_1) { 11807 PBMP_ITER(*all_pbmp, port) { 11808 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 11809 /* Recover port tx stop related info */ 11810 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 11811 if (port < SOC_MAX_NUM_PORTS) { 11812 sal_memcpy(&(PORT(unit, port).cosmask), port_state, 11813 sizeof(uint32)); 11814 } 11815 port_state += sizeof(uint32); 11816 11817 BCM_IF_ERROR_RETURN( 11818 _scache_port_print_add(unit, port, SPT_COSMASK, 11819 sizeof(uint32), port_state - sizeof(uint32))); 11820 } else { 11821 if (port < SOC_MAX_NUM_PORTS) { 11822 sal_memcpy(&(PORT(unit, port).m_info), port_state, 11823 sizeof(_bcm_port_metering_info_t)); 11824 } 11825 port_state += sizeof(_bcm_port_metering_info_t); 11826 11827 BCM_IF_ERROR_RETURN( 11828 _scache_port_print_add(unit, port, SPT_METERING_INFO, 11829 sizeof(_bcm_port_metering_info_t), 11830 port_state - sizeof(_bcm_port_metering_info_t))); 11831 } 11832 if (port < SOC_MAX_NUM_PORTS) { 11833 /* Recover flags */ 11834 sal_memcpy(&(PORT(unit, port).flags), port_state, sizeof(uint8)); 11835 } 11836 port_state += sizeof(uint8); 11837 11838 BCM_IF_ERROR_RETURN( 11839 _scache_port_print_add(unit, port, SPT_PORT_FLAGS, sizeof(uint8), 11840 port_state - sizeof(uint8))); 11841 } 11842 } 11843 #if defined(BCM_TOMAHAWK_SUPPORT) 11844 if (SOC_IS_TOMAHAWK(unit)) { 11845 PBMP_ALL_ITER(unit, port) { 11846 BCM_IF_ERROR_RETURN(soc_th_port_speed_recover(unit, port)); 11847 } 11848 } 11849 #endif 11850 #ifdef BCM_TRIDENT_SUPPORT 11851 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) && 11852 soc_feature(unit, soc_feature_flex_port)) { 11853 int num_lanes = 0; 11854 if (SOC_IS_TD_TT(unit)) { 11855 PBMP_ALL_ITER(unit, port) { 11856 sal_memcpy(&num_lanes, port_state, sizeof(int)); 11857 port_state += sizeof(int); 11858 11859 BCM_IF_ERROR_RETURN( 11860 _scache_port_print_add(unit, port, SPT_PORT_NUM_LANES, 11861 sizeof(int), port_state - sizeof(int))); 11862 #ifdef BCM_HURRICANE4_SUPPORT 11863 if (SOC_IS_HURRICANE4(unit) && 11864 (IS_MACSEC_PORT(unit, port) || 11865 IS_LB_PORT(unit,port))) { 11866 continue; 11867 } 11868 #endif 11869 if (si->port_num_lanes[port] != num_lanes) { 11870 #if defined(BCM_TOMAHAWK_SUPPORT) 11871 if (SOC_IS_TOMAHAWK(unit)) { 11872 BCM_IF_ERROR_RETURN( 11873 soc_th_flexport_recover(unit, port)); 11874 } 11875 #endif /* BCM_TOMAHAWK_SUPPORT */ 11876 #ifdef BCM_TRIDENT2_SUPPORT 11877 if (SOC_IS_TD2_TT2(unit) && 11878 (!(SOC_IS_TD2P_TT2P(unit) || 11879 SOC_IS_APACHE(unit) || 11880 SOC_IS_TOMAHAWK2(unit)))) { 11881 BCM_IF_ERROR_RETURN( 11882 _bcm_td2_flexport_recover(unit, port)); 11883 } 11884 #endif /* BCM_TRIDENT2_SUPPORT */ 11885 si->port_num_lanes[port] = num_lanes; 11886 _port_lanes_valid++; 11887 } 11888 } 11889 } 11890 #ifdef BCM_TRIUMPH3_SUPPORT 11891 else if (SOC_IS_TRIUMPH3(unit)) { 11892 PBMP_ALL_ITER(unit, port) { 11893 sal_memcpy(&_port_num_lanes[port], port_state, 11894 sizeof(int)); 11895 port_state += sizeof(int); 11896 _port_lanes_valid++; 11897 } 11898 } 11899 #endif /* BCM_TRIUMPH2_SUPPORT */ 11900 if (SOC_IS_TD_TT(unit) && (_port_lanes_valid > 0)) { 11901 /* Call PHY probe for flex port config to take effect */ 11902 if ((rv = bcm_esw_port_probe(unit, PBMP_PORT_ALL(unit), 11903 port_bitmap)) != BCM_E_NONE) { 11904 LOG_ERROR(BSL_LS_BCM_PORT, \ 11905 (BSL_META_U(unit, \ 11906 "Error unit %d:\ 11907 Failed port probe: %s\n"), 11908 unit, bcm_errmsg(rv))); 11909 return rv; 11910 } 11911 } 11912 } 11913 #endif /* BCM_TRIDENT_SUPPORT */ 11914 } else { 11915 PBMP_ITER(*all_pbmp, port) { 11916 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 11917 /* Recover port tx stop related info */ 11918 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 11919 realloc_size += sizeof(uint32); 11920 } else { 11921 realloc_size += sizeof(_bcm_port_metering_info_t); 11922 } 11923 /* Recover flags */ 11924 realloc_size += sizeof(uint8); 11925 } 11926 } 11927 } 11928 11929 if (recovered_ver >= BCM_PORT_WB_VERSION_1_2) { 11930 uint8 rx_los = 0; 11931 PBMP_ITER(*all_pbmp, port) { 11932 #if defined(BCM_SABER2_SUPPORT) 11933 if(SOC_IS_SABER2(unit)) { 11934 if ((port == SOC_SB2_SAT_OAMP_PHY_PORT_NUMBER) && (oamp_status == 1)){ 11935 continue; 11936 } 11937 } 11938 #endif 11939 /* Recover RX_LOS */ 11940 rx_los = *port_state; 11941 port_state += sizeof(uint8); 11942 11943 BCM_IF_ERROR_RETURN( 11944 _scache_port_print_add(unit, port, SPT_RX_LOS, sizeof(uint8), 11945 port_state - sizeof(uint8))); 11946 11947 if (IS_E_PORT(unit, port)) { 11948 /* Call PHY control for RX_lOS config to take effect */ 11949 if (rx_los == BCM_PORT_PHY_CONTROL_RX_LOS_NONE || 11950 rx_los == BCM_PORT_PHY_CONTROL_RX_LOS_SOFTWARE) { 11951 11952 if (!soc_feature(unit, soc_feature_no_sw_rx_los)){ 11953 rv = bcm_esw_port_phy_control_set(unit, port, 11954 BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, rx_los); 11955 if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) { 11956 LOG_ERROR(BSL_LS_BCM_PORT, 11957 (BSL_META_U(unit, 11958 "Error unit %d: " 11959 "Failed port phy control set: %s\n"), 11960 unit, bcm_errmsg(rv))); 11961 return rv; 11962 } 11963 } 11964 } 11965 } 11966 } 11967 } else { 11968 PBMP_ITER(*all_pbmp, port) { 11969 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) 11970 && (stable_size > 0)) { 11971 /* Recover SW RX LOS status */ 11972 realloc_size += sizeof(uint8); 11973 } 11974 } 11975 } 11976 11977 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_FIRELIGHT_SUPPORT) 11978 if (SOC_IS_TD2_TT2(unit) || SOC_IS_FIRELIGHT(unit)) { 11979 if (recovered_ver >= BCM_PORT_WB_VERSION_1_3) { 11980 PBMP_ITER(*all_pbmp, port) { 11981 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) 11982 && (stable_size > 0)) { 11983 if (port < SOC_MAX_NUM_PORTS) { 11984 /* Recover port enable status */ 11985 sal_memcpy(&(PORT(unit, port).enable), 11986 port_state, sizeof(int)); 11987 } 11988 port_state += sizeof(int); 11989 11990 BCM_IF_ERROR_RETURN( 11991 _scache_port_print_add(unit, port, SPT_PORT_ENABLE, 11992 sizeof(int), port_state - sizeof(int))); 11993 } 11994 } 11995 } else { 11996 PBMP_ITER(*all_pbmp, port) { 11997 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) 11998 && (stable_size > 0)) { 11999 /* Recover SW port enable status */ 12000 realloc_size += sizeof(int); 12001 } 12002 } 12003 } 12004 } 12005 #endif /* BCM_TRIDENT2_SUPPORT */ 12006 #ifdef BCM_TRIUMPH3_SUPPORT 12007 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) { 12008 if ((recovered_ver >= BCM_PORT_WB_VERSION_1_4) && _port_ibod_ctrl[unit]) { 12009 sal_memcpy(_port_ibod_ctrl[unit]->rrbyt, port_state, 12010 sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)); 12011 port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrbyt); 12012 sal_memcpy(_port_ibod_ctrl[unit]->rrpkt, port_state, 12013 sizeof(((_port_ibod_ctrl_t *)0)->rrpkt)); 12014 port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrpkt); 12015 sal_memcpy(&(_port_ibod_ctrl[unit]->event_count), port_state, 12016 sizeof(((_port_ibod_ctrl_t *)0)->event_count)); 12017 port_state += sizeof(((_port_ibod_ctrl_t *)0)->event_count); 12018 } else { 12019 realloc_size += sizeof(((_port_ibod_ctrl_t *)0)->rrbyt); 12020 realloc_size += sizeof(((_port_ibod_ctrl_t *)0)->rrpkt); 12021 realloc_size += sizeof(((_port_ibod_ctrl_t *)0)->event_count); 12022 } 12023 } 12024 /* 12025 * Recover the port force forward information from scache. 12026 * If the recovered version is lower than 1.5, allocate 12027 * space in scache for any further sync. 12028 */ 12029 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 12030 if (recovered_ver >= BCM_PORT_WB_VERSION_1_5) { 12031 BCM_IF_ERROR_RETURN( 12032 _bcm_port_force_forward_reinit(unit, &port_state)); 12033 } else { 12034 bcm_port_t egr_port; 12035 int enabled = 0; 12036 int port_forward_size = 0; 12037 PBMP_ITER(*all_pbmp, port) { 12038 BCM_IF_ERROR_RETURN( 12039 bcm_esw_port_force_forward_get(unit, port, 12040 &egr_port, &enabled)); 12041 if (enabled) { 12042 _bcm_port_force_forward_add(unit, port, 12043 egr_port); 12044 } 12045 } 12046 BCM_IF_ERROR_RETURN(_bcm_port_force_forward_scache_size(unit, 12047 &port_forward_size)); 12048 realloc_size += port_forward_size; 12049 } 12050 } 12051 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */ 12052 12053 #ifdef BCM_TOMAHAWK_SUPPORT 12054 if (recovered_ver >= BCM_PORT_WB_VERSION_1_6) { 12055 /* ASF WB Recovery */ 12056 rv = _bcm_esw_asf_wb_recover(unit, port_state, recovered_ver); 12057 if (BCM_E_NONE != rv) { 12058 LOG_ERROR(BSL_LS_BCM_PORT, \ 12059 (BSL_META_U(unit, \ 12060 "Error unit %d:\ 12061 ASF Warmboot Recovery Failed: %s\n"), \ 12062 unit, bcm_errmsg(rv))); 12063 return rv; 12064 } 12065 port_state += asf_wbmem_sz; 12066 12067 BCM_IF_ERROR_RETURN( 12068 _scache_port_print_add(unit, -1, SPT_ASF, asf_wbmem_sz, 12069 port_state - asf_wbmem_sz)); 12070 } 12071 12072 if (recovered_ver >= BCM_PORT_WB_VERSION_1_6) { 12073 /* Switch Latency Bypass WB Recovery */ 12074 rv = bcmi_esw_switch_latency_wb_recover(unit, port_state, recovered_ver); 12075 if (BCM_E_NONE != rv) { 12076 LOG_ERROR(BSL_LS_BCM_PORT, \ 12077 (BSL_META_U(unit, \ 12078 "Error unit %d:\ 12079 Switch Latency Bypass \ 12080 Warmboot Recovery Failed: %s\n"), \ 12081 unit, bcm_errmsg(rv))); 12082 return rv; 12083 } 12084 port_state += latency_wbmem_sz; 12085 12086 BCM_IF_ERROR_RETURN( 12087 _scache_port_print_add(unit, -1, SPT_LATENCY, latency_wbmem_sz, 12088 port_state - latency_wbmem_sz)); 12089 } 12090 12091 /* sflow WB recovery */ 12092 rv = _bcm_esw_sflow_wb_recover(unit); 12093 if (BCM_E_NONE != rv) { 12094 LOG_ERROR(BSL_LS_BCM_PORT, (BSL_META_U(unit, "Error \ 12095 unit %d: sflow Warmboot Recovery Failed: %s\n"), unit, 12096 bcm_errmsg(rv))); 12097 return rv; 12098 } 12099 #endif /* BCM_TOMAHAWK_SUPPORT */ 12100 /*IFG WB*/ 12101 if (soc_feature(unit, soc_feature_xmac) || 12102 soc_feature(unit, soc_feature_xlmac) || 12103 soc_feature(unit, soc_feature_cmac) || 12104 soc_feature(unit, soc_feature_clmac)) { 12105 if (recovered_ver >= BCM_PORT_WB_VERSION_1_7) { 12106 BCM_IF_ERROR_RETURN( 12107 _bcm_esw_port_ifg_wb_reinit(unit, &port_state)); 12108 } else { 12109 PBMP_ITER(*all_pbmp, port) { 12110 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) 12111 && (stable_size > 0)) { 12112 realloc_size += sizeof(uint32); 12113 } 12114 } 12115 } 12116 } 12117 /* PORT DSCP MAP SETTING */ 12118 if (soc_feature(unit, soc_feature_dscp) && 12119 soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 12120 if (recovered_ver >= BCM_PORT_WB_VERSION_1_11) { 12121 PBMP_ITER(*all_pbmp, port) { 12122 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) 12123 && (stable_size > 0)) { 12124 /* Recover port dscp map status */ 12125 sal_memcpy(&(PORT(unit, port).port_dscp_map_set), 12126 port_state, sizeof(int)); 12127 port_state += sizeof(int); 12128 12129 BCM_IF_ERROR_RETURN( 12130 _scache_port_print_add(unit, port, SPT_DSCP_MAP, 12131 sizeof(int), port_state - sizeof(int))); 12132 12133 if (PORT(unit, port).port_dscp_map_set) { 12134 BCM_IF_ERROR_RETURN( 12135 _bcm_egr_dscp_table_entry_reference( 12136 unit, port * _BCM_QOS_MAP_CHUNK_EGR_DSCP, 12137 _BCM_QOS_MAP_CHUNK_EGR_DSCP)); 12138 } 12139 } 12140 } 12141 } else { 12142 PBMP_ITER(*all_pbmp, port) { 12143 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) 12144 && (stable_size > 0)) { 12145 /* Recover SW port dscp map status */ 12146 realloc_size += sizeof(int); 12147 } 12148 } 12149 } 12150 } 12151 12152 #ifdef BCM_TOMAHAWK_SUPPORT 12153 if (SOC_IS_TOMAHAWK(unit) && recovered_ver >= BCM_PORT_WB_VERSION_1_12) { 12154 /* Recover port interface type */ 12155 int pif; 12156 PBMP_ITER(*all_pbmp, port) { 12157 if (IS_XE_PORT(unit, port) || 12158 IS_CE_PORT(unit, port) || 12159 IS_HG_PORT(unit, port) || 12160 IS_GE_PORT(unit, port) || 12161 IS_MANAGEMENT_PORT(unit, port)) { 12162 12163 sal_memcpy(&pif, port_state, sizeof(int)); 12164 port_state += sizeof(int); 12165 12166 BCM_IF_ERROR_RETURN( 12167 _scache_port_print_add(unit, port, SPT_PORT_INTF_TYPE, 12168 sizeof(int), port_state - sizeof(int))); 12169 12170 BCM_IF_ERROR_RETURN(soc_phyctrl_interface_set(unit, port, pif)); 12171 } 12172 } 12173 } 12174 #endif /* BCM_TOMAHAWK_SUPPORT */ 12175 if (soc_feature(unit, soc_feature_phy_interface_wb) && 12176 (recovered_ver >= BCM_PORT_WB_VERSION_1_13)) { 12177 /* Recover port interface type */ 12178 int pif; 12179 12180 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 12181 sal_memcpy(&pif, port_state, sizeof(int)); 12182 port_state += sizeof(int); 12183 12184 BCM_IF_ERROR_RETURN( 12185 _scache_port_print_add(unit, port, SPT_PORT_INTF_TYPE, 12186 sizeof(int), port_state - sizeof(int))); 12187 12188 if (pif) { 12189 BCM_IF_ERROR_RETURN( 12190 soc_phyctrl_interface_set(unit, port, pif)); 12191 } 12192 } 12193 } 12194 12195 if (realloc_size > 0) { 12196 BCM_IF_ERROR_RETURN( 12197 soc_scache_realloc(unit, scache_handle, realloc_size)); 12198 } 12199 #endif /* BCM_TRX_SUPPORT */ 12200 12201 return rv; 12202 } 12203 12204 int 12205 _bcm_esw_port_wb_recover(int unit) 12206 { 12207 int rv = BCM_E_NONE; 12208 12209 #if defined(BCM_TRX_SUPPORT) 12210 if (SOC_IS_TRX(unit)) { 12211 int alloc_sz, use_pbmp = FALSE; 12212 uint8 *port_state; 12213 uint16 recovered_ver; 12214 bcm_port_t port; 12215 bcm_pbmp_t dtm_pbmp; 12216 int stable_size; 12217 soc_scache_handle_t scache_handle; 12218 uint32 oamp_status = 0; 12219 #if defined(BCM_SABER2_SUPPORT) 12220 uint32 rval = 0; 12221 #endif 12222 pbmp_t port_bitmap; 12223 bcm_pbmp_t all_pbmp; 12224 uint32 asf_wbmem_sz = 0; 12225 /* Switch Latency Bypass WB will move to a different module later */ 12226 uint32 latency_wbmem_sz = 0; 12227 #ifdef BCM_TOMAHAWK_SUPPORT 12228 uint16 scache_ver = BCM_PORT_WB_DEFAULT_VERSION; 12229 12230 #endif 12231 12232 BCM_PBMP_CLEAR(all_pbmp); 12233 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 12234 12235 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_PORT, 12236 BCM_PORT_WB_SCACHE_PART_DEFAULT); 12237 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 12238 0, (uint8**)&port_state, 12239 BCM_PORT_WB_DEFAULT_VERSION, &recovered_ver); 12240 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 12241 return rv; 12242 } 12243 12244 #if defined(BCM_SABER2_SUPPORT) 12245 if(SOC_IS_SABER2(unit)) { 12246 SOC_IF_ERROR_RETURN(READ_OAMP_ENABLEr(unit, &rval)); 12247 oamp_status = soc_reg_field_get(unit, OAMP_ENABLEr, rval, ENABLEf); 12248 } 12249 #endif 12250 #ifdef BCM_KATANA2_SUPPORT 12251 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 12252 #if defined(BCM_SABER2_SUPPORT) 12253 if ( SOC_IS_SABER2(unit) && !SOC_IS_METROLITE(unit) && 12254 (recovered_ver < BCM_PORT_WB_VERSION_1_10) ) { 12255 BCM_IF_ERROR_RETURN(_bcm_sb2_wb_v1_flexio_pbmp_update(unit, &all_pbmp)); 12256 } else 12257 #endif 12258 { 12259 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 12260 #if defined(BCM_SABER2_SUPPORT) 12261 bcm_sb2_wb_v2_flexio_update = 1; 12262 #endif 12263 } 12264 } 12265 if (soc_feature(unit, soc_feature_linkphy_coe) || 12266 soc_feature(unit, soc_feature_subtag_coe)) { 12267 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 12268 } 12269 #endif 12270 #ifdef BCM_TRIDENT2PLUS_SUPPORT 12271 if (SOC_IS_TD2P_TT2P(unit)) { 12272 BCM_IF_ERROR_RETURN(bcm_td2p_flexport_pbmp_update(unit, 12273 &all_pbmp)); 12274 } 12275 #endif 12276 #ifdef BCM_MONTEREY_SUPPORT 12277 if (SOC_IS_MONTEREY(unit)) { 12278 BCM_IF_ERROR_RETURN(bcm_monterey_flexport_pbmp_update(unit, &all_pbmp)); 12279 } 12280 #endif 12281 #ifdef BCM_APACHE_SUPPORT 12282 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 12283 BCM_IF_ERROR_RETURN(bcm_apache_flexport_pbmp_update(unit, &all_pbmp)); 12284 } 12285 #endif 12286 12287 alloc_sz = 0; 12288 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 12289 PBMP_ITER(all_pbmp, port) { 12290 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 12291 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) { 12292 /* vp entry and vlan prot ptr */ 12293 alloc_sz += (sizeof(int) + sizeof(uint32)); 12294 } 12295 #endif 12296 alloc_sz += sizeof(int); /* vp count */ 12297 } 12298 alloc_sz += sizeof(bcm_pbmp_t); /* Bitmap of dtag_mode == NONE */ 12299 PBMP_ITER(all_pbmp, port) { 12300 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 12301 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 12302 alloc_sz += sizeof(uint32); 12303 } else { 12304 alloc_sz += sizeof(_bcm_port_metering_info_t); 12305 } 12306 alloc_sz += sizeof(uint8); 12307 } 12308 } 12309 12310 #ifdef BCM_TRIDENT_SUPPORT 12311 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) && 12312 soc_feature(unit, soc_feature_flex_port)) { 12313 alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int)); 12314 } 12315 #endif 12316 12317 /* Restore SW RX LOS status */ 12318 PBMP_ITER(all_pbmp, port) { 12319 alloc_sz += sizeof(uint8); 12320 } 12321 12322 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_FIRELIGHT_SUPPORT) 12323 if (SOC_IS_TD2_TT2(unit) || SOC_IS_FIRELIGHT(unit)) { 12324 /* Allocate size for port enable status */ 12325 PBMP_ITER(all_pbmp, port) { 12326 alloc_sz += sizeof(int); 12327 } 12328 } 12329 #endif /* BCM_TRIDENT2_SUPPORT */ 12330 #ifdef BCM_TRIUMPH3_SUPPORT 12331 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) { 12332 alloc_sz += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt) 12333 + sizeof((((_port_ibod_ctrl_t *)0)->event_count)); 12334 } 12335 #endif /* BCM_TRIUMPH3_SUPPORT */ 12336 #if defined(BCM_TRIUMPH3_SUPPORT) 12337 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 12338 int port_forward_size; 12339 BCM_IF_ERROR_RETURN( 12340 _bcm_port_force_forward_scache_size(unit, &port_forward_size)); 12341 alloc_sz += port_forward_size; 12342 } 12343 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */ 12344 12345 #ifdef BCM_TOMAHAWK_SUPPORT 12346 if (SOC_WARM_BOOT(unit)) { 12347 BCM_IF_ERROR_RETURN( 12348 bcm_esw_scache_ver_get(unit, BCM_MODULE_PORT, &scache_ver)); 12349 } 12350 /* ASF WB */ 12351 rv = _bcm_esw_asf_wb_memsz_get(unit, &asf_wbmem_sz, scache_ver); 12352 if (BCM_E_NONE == rv) { 12353 alloc_sz += asf_wbmem_sz; 12354 } 12355 12356 /* Switch Latency Bypass WB */ 12357 rv = bcmi_esw_switch_latency_wb_memsz_get(unit, &latency_wbmem_sz, 12358 scache_ver); 12359 if (BCM_E_NONE == rv) { 12360 alloc_sz += latency_wbmem_sz; 12361 } 12362 #endif /* BCM_TOMAHAWK_SUPPORT */ 12363 12364 /*IFG WB*/ 12365 if (soc_feature(unit, soc_feature_xmac) || 12366 soc_feature(unit, soc_feature_xlmac) || 12367 soc_feature(unit, soc_feature_cmac) || 12368 soc_feature(unit, soc_feature_clmac)) { 12369 PBMP_ITER(all_pbmp, port) { 12370 alloc_sz += sizeof(uint32); 12371 } 12372 } 12373 /* PORT DSCP MAP SETTING */ 12374 if (soc_feature(unit, soc_feature_dscp) && 12375 soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 12376 /* Allocate size for port dscp map setting status */ 12377 PBMP_ITER(all_pbmp, port) { 12378 alloc_sz += sizeof(int); 12379 } 12380 } 12381 12382 #ifdef BCM_TOMAHAWK_SUPPORT 12383 if (SOC_IS_TOMAHAWK(unit)) { 12384 /* Allocate size for port interface type */ 12385 PBMP_ITER(all_pbmp, port) { 12386 alloc_sz += sizeof(int); 12387 } 12388 } 12389 #endif /* BCM_TOMAHAWK_SUPPORT */ 12390 12391 if (soc_feature(unit, soc_feature_phy_interface_wb)) { 12392 /* Allocate size for port interface type */ 12393 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 12394 alloc_sz += sizeof(int); 12395 } 12396 } 12397 12398 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_PORT, 12399 BCM_PORT_WB_SCACHE_PART_DEFAULT); 12400 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 12401 alloc_sz, (uint8**)&port_state, 12402 BCM_PORT_WB_DEFAULT_VERSION, &recovered_ver); 12403 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 12404 return rv; 12405 } 12406 if (BCM_SUCCESS(rv)) { 12407 _scache_port_print_ll_init(unit); 12408 12409 rv = _bcm_esw_port_wb_recover_scache(unit, recovered_ver, port_state, 12410 stable_size, asf_wbmem_sz, latency_wbmem_sz, oamp_status, 12411 scache_handle, &use_pbmp, &port_bitmap, &dtm_pbmp, &all_pbmp); 12412 12413 if (BCM_SUCCESS(rv) || rv == BCM_E_UNAVAIL) { 12414 _scache_port_print_all(unit); 12415 } 12416 _scache_port_print_clear_all(unit); 12417 12418 if (BCM_FAILURE(rv) && rv != BCM_E_UNAVAIL) { 12419 return rv; 12420 } 12421 } else { 12422 /* 12423 * No level-2 cache configured. Proceed to Level-1 only recovery 12424 */ 12425 BCM_PBMP_CLEAR(dtm_pbmp); /* Default is dtag_mode == NONE */ 12426 #if defined(BCM_TRIUMPH3_SUPPORT) 12427 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 12428 bcm_port_t egr_port; 12429 int enabled = 0; 12430 12431 PBMP_ITER(all_pbmp, port) { 12432 SOC_IF_ERROR_RETURN 12433 (bcm_esw_port_force_forward_get(unit, port, 12434 &egr_port, &enabled)); 12435 if (enabled) { 12436 _bcm_port_force_forward_add(unit, port, 12437 egr_port); 12438 } 12439 } 12440 } 12441 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */ 12442 } 12443 12444 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || \ 12445 defined(BCM_KATANA2_SUPPORT) 12446 if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TOMAHAWK2(unit) || 12447 SOC_IS_TRIDENT3X(unit) || SOC_IS_KATANA2(unit)) { 12448 /* Recover port vlan action profile */ 12449 rv = _bcm_th_port_vlan_action_profile_reinit(unit); 12450 if (BCM_FAILURE(rv)) { 12451 return rv; 12452 } 12453 } 12454 #endif 12455 12456 /* Recover DT mode */ 12457 rv = _bcm_trx_port_dtag_mode_reinit(unit, dtm_pbmp, use_pbmp); 12458 if (BCM_FAILURE(rv)) { 12459 return rv; 12460 } 12461 #ifdef BCM_TRIUMPH2_SUPPORT 12462 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 12463 /* Recover ING_PRI_CNG_MAP references */ 12464 port_tab_entry_t pent; 12465 int ptr; 12466 uint32 ipc_ref_bmp[3]; 12467 /* Required: ING_PRI_CNG_MAP size <= 3 * 32 * 16 = 1536 */ 12468 12469 SHR_BITCLR_RANGE(ipc_ref_bmp, 0, 3*32); 12470 12471 /* Read port pointer, recover reference count */ 12472 PBMP_ITER(all_pbmp, port) { 12473 #ifdef BCM_TRIDENT3_SUPPORT 12474 if (SOC_IS_TRIDENT3X(unit)) { 12475 rv = _bcm_esw_port_tab_get(unit, port, 12476 TRUST_DOT1P_PTRf, &ptr); 12477 if (BCM_FAILURE(rv)) { 12478 break; 12479 } 12480 if (0 != ptr) { 12481 rv = _bcm_ing_pri_cng_map_entry_reference(unit, 12482 ptr * _BCM_TD3_PRI_CNG_MAP_SIZE, 12483 _BCM_TD3_PRI_CNG_MAP_SIZE); 12484 if (BCM_FAILURE(rv)) { 12485 break; 12486 } 12487 } 12488 12489 /* Recover PROTOCOL_PKT_CONTROL & 12490 * IGMP_MLD_PKT_CONTROL references */ 12491 if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype == 12492 soc_portreg) { 12493 /* Memory not allocated so no need to proceed */ 12494 continue; 12495 } 12496 rv = _bcm_esw_port_tab_get(unit, port, 12497 PROTOCOL_PKT_INDEXf, &ptr); 12498 if (BCM_FAILURE(rv)) { 12499 break; 12500 } 12501 if (0 != ptr) { 12502 rv = _bcm_prot_pkt_ctrl_reference(unit, ptr); 12503 if (BCM_FAILURE(rv)) { 12504 break; 12505 } 12506 /* Remove default reference */ 12507 rv = _bcm_prot_pkt_ctrl_delete(unit, 0); 12508 if (BCM_FAILURE(rv)) { 12509 break; 12510 } 12511 } 12512 } else 12513 #endif 12514 { 12515 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, 12516 SOC_PORT_MOD_OFFSET(unit, port), &pent); 12517 if (BCM_FAILURE(rv)) { 12518 break; 12519 } 12520 if (soc_feature(unit, soc_feature_color)) { 12521 ptr = soc_PORT_TABm_field32_get(unit, &pent, 12522 TRUST_DOT1P_PTRf); 12523 if (0 != ptr) { 12524 rv = _bcm_ing_pri_cng_map_entry_reference(unit, 12525 ptr * _BCM_TR2_PRI_CNG_MAP_SIZE, 12526 _BCM_TR2_PRI_CNG_MAP_SIZE); 12527 if (BCM_FAILURE(rv)) { 12528 break; 12529 } 12530 } 12531 } 12532 12533 /* Recover PROTOCOL_PKT_CONTROL & 12534 * IGMP_MLD_PKT_CONTROL references */ 12535 if (soc_mem_field_valid(unit, PORT_TABm, 12536 PROTOCOL_PKT_INDEXf)) { 12537 if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype == 12538 soc_portreg) { 12539 /* ========================================== */ 12540 /* Memory not allocated so no need to proceed */ 12541 /* if (SOC_IS_HURRICANE(unit)) */ 12542 /* ========================================== */ 12543 continue; 12544 } 12545 ptr = soc_PORT_TABm_field32_get(unit, &pent, 12546 PROTOCOL_PKT_INDEXf); 12547 if (0 != ptr) { 12548 rv = _bcm_prot_pkt_ctrl_reference(unit, ptr); 12549 if (BCM_FAILURE(rv)) { 12550 break; 12551 } 12552 /* Remove default reference */ 12553 rv = _bcm_prot_pkt_ctrl_delete(unit, 0); 12554 if (BCM_FAILURE(rv)) { 12555 break; 12556 } 12557 } 12558 } 12559 } 12560 } 12561 } 12562 if (BCM_FAILURE(rv)) { 12563 return rv; 12564 } 12565 #endif /* BCM_TRIUMPH2_SUPPORT */ 12566 #ifdef BCM_TRIDENT2PLUS_SUPPORT 12567 if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) { 12568 port_tab_entry_t pent; 12569 int ptr; 12570 PBMP_ITER(all_pbmp, port) { 12571 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, 12572 SOC_PORT_MOD_OFFSET(unit, port), &pent); 12573 if (BCM_FAILURE(rv)) { 12574 break; 12575 } 12576 ptr = soc_PORT_TABm_field32_get(unit, &pent, 12577 MISC_PORT_PROFILE_INDEXf); 12578 if (0 != ptr) { 12579 rv = _bcm_misc_port_profile_mem_reference(unit, ptr, 1); 12580 if (BCM_FAILURE(rv)) { 12581 break; 12582 } 12583 } 12584 } 12585 } 12586 if (BCM_FAILURE(rv)) { 12587 return rv; 12588 } 12589 #endif 12590 12591 if (soc_feature(unit, soc_feature_e2ecc)) { 12592 rv = _bcm_esw_port_e2ecc_reinit(unit); 12593 } 12594 if (BCM_FAILURE(rv)) { 12595 return rv; 12596 } 12597 12598 #ifdef BCM_TRIUMPH2_SUPPORT 12599 /* Recover source modid egress blocking profiles */ 12600 if (soc_feature(unit, soc_feature_src_modid_blk_profile)) { 12601 uint32 regval, srcmod_index; 12602 int i, modid_count; 12603 12604 modid_count = SOC_MODID_MAX(unit) + 1; 12605 12606 PBMP_ITER(all_pbmp, port) { 12607 BCM_IF_ERROR_RETURN 12608 (READ_SRC_MODID_EGRESS_SELr(unit, port, ®val)); 12609 if (soc_reg_field_get(unit, 12610 SRC_MODID_EGRESS_SELr, regval, ENABLEf)) { 12611 srcmod_index = soc_reg_field_get(unit, 12612 SRC_MODID_EGRESS_SELr, regval, SRCMOD_INDEXf); 12613 PORT_SRC_MOD_EGR_PROF_PTR(unit, port) = srcmod_index; 12614 srcmod_index *= modid_count; 12615 for (i = 0; i < modid_count; i++) { 12616 SOC_PROFILE_MEM_REFERENCE(unit, 12617 PORT_SRC_MOD_EGR_PROFILE(unit), 12618 srcmod_index + i, 1); 12619 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, 12620 PORT_SRC_MOD_EGR_PROFILE(unit), 12621 srcmod_index + i, 12622 modid_count); 12623 } 12624 } 12625 } 12626 } 12627 #endif /* BCM_TRIUMPH2_SUPPORT */ 12628 12629 #ifdef BCM_TRIUMPH2_SUPPORT 12630 if ((SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 12631 SOC_IS_VALKYRIE2(unit)) && 12632 soc_feature(unit, soc_feature_flex_port)) { 12633 PBMP_ALL_ITER(unit, port) { 12634 if (_bcm_esw_valid_flex_port_controlling_port(unit, port)) { 12635 BCM_IF_ERROR_RETURN(_bcm_tr2_flexport_recover(unit, port)); 12636 } 12637 } 12638 /* Call PHY probe for config to take effect */ 12639 if ((rv = bcm_esw_port_probe(unit, PBMP_PORT_ALL(unit), 12640 &port_bitmap)) != BCM_E_NONE) { 12641 LOG_ERROR(BSL_LS_BCM_PORT, \ 12642 (BSL_META_U(unit, \ 12643 "Error unit %d:\ 12644 Failed port probe: %s\n"), 12645 unit, bcm_errmsg(rv))); 12646 return rv; 12647 } 12648 } 12649 #endif /* BCM_TRIUMPH2_SUPPORT */ 12650 12651 #if defined(BCM_GREYHOUND_SUPPORT) 12652 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 12653 /* 12654 * Recover the ref_cnt of enabling treat packet priority as 12655 * dot1p priority for different packet types or port controls, 12656 * if available. 12657 */ 12658 rv = bcmi_esw_port_treat_pktpri_as_dot1p_reinit(unit); 12659 if (BCM_FAILURE(rv)) { 12660 return rv; 12661 } 12662 } 12663 #endif /* BCM_GREYHOUND_SUPPORT */ 12664 12665 if (SOC_IS_HURRICANEX(unit) || SOC_IS_TRIUMPH2(unit) || \ 12666 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA(unit) || \ 12667 SOC_IS_ENDURO(unit) || SOC_IS_GREYHOUND(unit) || \ 12668 SOC_IS_VALKYRIE(unit) || SOC_IS_HURRICANE4(unit)) { 12669 bcm_esw_port_mdix_wb_update(unit); 12670 } 12671 } 12672 #endif /* BCM_TRX_SUPPORT */ 12673 #if defined(BCM_RAVEN_SUPPORT) 12674 if (SOC_IS_RAVEN(unit)) { 12675 bcm_esw_port_mdix_wb_update(unit); 12676 } 12677 #endif /* BCM_RAVEN_SUPPORT */ 12678 #ifdef BCM_PREEMPTION_SUPPORT 12679 if (soc_feature(unit, soc_feature_preemption)) { 12680 soc_scache_handle_t scache_handle; 12681 12682 SOC_SCACHE_HANDLE_SET(scache_handle, 12683 unit, BCM_MODULE_PORT, 12684 BCM_PORT_WB_SCACHE_PART_PREMMPTION); 12685 rv = bcmi_esw_preemption_recover(unit, scache_handle); 12686 if (BCM_FAILURE(rv)) { 12687 return rv; 12688 } 12689 } 12690 #endif /* BCM_PREEMPTION_SUPPORT */ 12691 12692 return rv; 12693 } 12694 #else 12695 #define _bcm_port_vd_pbvl_reinit(u) (BCM_E_NONE) 12696 #define _bcm_esw_port_wb_recover(u) (BCM_E_NONE) 12697 #define _bcm_esw_port_wb_alloc(u) (BCM_E_NONE) 12698 #endif /* BCM_WARM_BOOT_SUPPORT */ 12699 12700 #ifndef BCM_SW_STATE_DUMP_DISABLE 12701 /* 12702 * Function: 12703 * _bcm_esw_flexport_sw_dump 12704 * Purpose: 12705 * Displays port information after flexport. 12706 * Parameters: 12707 * unit - Device unit number 12708 * Returns: 12709 * None 12710 * Note: 12711 */ 12712 void 12713 _bcm_esw_flexport_sw_dump(int unit) 12714 { 12715 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 12716 if (SOC_IS_TRIDENT2PLUS(unit)) { 12717 soc_flexport_sw_dump(unit); 12718 } 12719 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 12720 12721 #if defined(BCM_TOMAHAWK3_SUPPORT) 12722 if (SOC_IS_TOMAHAWK3(unit)) { 12723 soc_th3_flexport_sw_dump(unit); 12724 } 12725 #endif /* BCM_TOMAHAWK3_SUPPORT */ 12726 12727 #if defined(BCM_TOMAHAWK2_SUPPORT) 12728 if (SOC_IS_TOMAHAWK2(unit)) { 12729 soc_th2_flexport_sw_dump(unit); 12730 } 12731 #endif /* BCM_TOMAHAWK2_SUPPORT */ 12732 12733 #if defined(BCM_TOMAHAWK_SUPPORT) 12734 if (SOC_IS_TOMAHAWK(unit)) { 12735 soc_th_flexport_sw_dump(unit); 12736 } 12737 #endif /* BCM_TOMAHAWK_SUPPORT */ 12738 12739 } 12740 12741 void 12742 _bcm_esw_flexport_sw_pipe_speed_group_dump( 12743 int unit, 12744 int pipe, 12745 int speed_id) 12746 { 12747 #if defined(BCM_TOMAHAWK_SUPPORT) 12748 if (SOC_IS_TOMAHAWK(unit)) { 12749 soc_th_flexport_sw_pipe_speed_group_dump( 12750 unit, pipe, speed_id); 12751 } 12752 #endif /* BCM_TOMAHAWK_SUPPORT */ 12753 } 12754 12755 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 12756 12757 static int 12758 _bcm_esw_glp_bits_pos(int unit, 12759 uint8 *trunk_pos, uint8 *max_modid, 12760 uint8 *modid_pos, uint8 *max_port); 12761 12762 #if defined(BCM_FIREBOLT_SUPPORT) 12763 /* 12764 * Function: 12765 * _bcm_port_vd_pbvl_init 12766 * Purpose: 12767 * Initialization of vd_pbvl bitmap in port 12768 * Parameters: 12769 * unit - StrataSwitch unit number. 12770 * Returns: 12771 * BCM_E_NONE - success (or already initialized) 12772 * BCM_E_MEMORY - failed to allocate required memory. 12773 */ 12774 12775 STATIC int 12776 _bcm_port_vd_pbvl_init(int unit) 12777 { 12778 bcm_port_t port; 12779 int idxmax; 12780 int inds_bytes; 12781 bcm_pbmp_t all_pbmp; 12782 12783 #if defined(BCM_TOMAHAWK3_SUPPORT) 12784 /* TH3 does not support VLAN Protocol feature. Return doing nothing */ 12785 if (SOC_IS_TOMAHAWK3(unit)) { 12786 return BCM_E_NONE; 12787 } 12788 #endif 12789 12790 idxmax = soc_mem_index_count(unit, VLAN_PROTOCOLm); 12791 /* Round to the next entry */ 12792 inds_bytes = 12793 (idxmax + (_BCM_PORT_VD_PBVL_ESIZE - 1)) / _BCM_PORT_VD_PBVL_ESIZE; 12794 12795 BCM_PBMP_CLEAR(all_pbmp); 12796 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 12797 12798 #ifdef BCM_KATANA2_SUPPORT 12799 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 12800 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 12801 } 12802 if (soc_feature(unit, soc_feature_linkphy_coe) || 12803 soc_feature(unit, soc_feature_subtag_coe)) { 12804 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 12805 } 12806 #endif 12807 12808 PBMP_ITER(all_pbmp, port) { 12809 PORT(unit, port).p_vd_pbvl = sal_alloc(inds_bytes, "vdv_info"); 12810 if (NULL == PORT(unit, port).p_vd_pbvl) { 12811 return (BCM_E_MEMORY); 12812 } 12813 12814 sal_memset(PORT(unit, port).p_vd_pbvl, 0, inds_bytes); 12815 } 12816 12817 #ifdef BCM_WARM_BOOT_SUPPORT 12818 if (SOC_WARM_BOOT(unit)) { 12819 BCM_IF_ERROR_RETURN(_bcm_port_vd_pbvl_reinit(unit)); 12820 } 12821 #endif 12822 12823 return BCM_E_NONE; 12824 } 12825 #endif /* BCM_FIREBOLT_SUPPORT */ 12826 12827 /* 12828 * Function: 12829 * _bcm_esw_port_software_detach 12830 * Purpose: 12831 * De-initialization of software for port subsystem. 12832 * Parameters: 12833 * unit - StrataSwitch unit number. 12834 * Returns: 12835 * BCM_E_NONE - success (or already initialized) 12836 * BCM_E_INTERNAL- failed to write PTABLE entries 12837 * BCM_E_MEMORY - failed to allocate required memory. 12838 */ 12839 12840 int 12841 _bcm_esw_port_software_detach(int unit) 12842 { 12843 bcm_port_t port; 12844 bcm_pbmp_t all_pbmp; 12845 12846 BCM_PBMP_CLEAR(all_pbmp); 12847 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 12848 12849 #ifdef BCM_KATANA2_SUPPORT 12850 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 12851 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 12852 } 12853 if (soc_feature(unit, soc_feature_linkphy_coe) || 12854 soc_feature(unit, soc_feature_subtag_coe)) { 12855 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 12856 } 12857 #endif 12858 12859 if (bcm_port_info[unit] == NULL) { 12860 return (BCM_E_NONE); 12861 } 12862 12863 PBMP_ITER(all_pbmp, port) { 12864 if (NULL != PORT(unit, port).p_vd_pbvl) { 12865 sal_free(PORT(unit, port).p_vd_pbvl); 12866 PORT(unit, port).p_vd_pbvl = NULL; 12867 } 12868 12869 if (NULL != PORT(unit, port).e2ecc_config) { 12870 sal_free(PORT(unit, port).e2ecc_config); 12871 PORT(unit, port).e2ecc_config = NULL; 12872 } 12873 } 12874 12875 SOC_IF_ERROR_RETURN(soc_phy_common_detach(unit)); 12876 12877 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 12878 || defined(BCM_RAVEN_SUPPORT) 12879 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 12880 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_detach(unit)); 12881 } 12882 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT \ 12883 || BCM_RAPTOR_SUPPORT */ 12884 12885 #ifdef BCM_TRIUMPH2_SUPPORT 12886 if (NULL != PORT_SRC_MOD_EGR_PROFILE(unit)) { 12887 BCM_IF_ERROR_RETURN 12888 (soc_profile_mem_destroy(unit, PORT_SRC_MOD_EGR_PROFILE(unit))); 12889 sal_free(PORT_SRC_MOD_EGR_PROFILE(unit)); 12890 PORT_SRC_MOD_EGR_PROFILE(unit) = NULL; 12891 } 12892 #endif /* BCM_TRIUMPH2_SUPPORT */ 12893 #if defined(BCM_TRIDENT_SUPPORT) 12894 if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 12895 BCM_IF_ERROR_RETURN(bcm_td_port_deinit(unit)); 12896 } 12897 #endif /* BCM_TRIDENT_SUPPORT */ 12898 12899 sal_free (bcm_port_info[unit]); 12900 bcm_port_info[unit] = NULL; 12901 12902 return BCM_E_NONE; 12903 } 12904 12905 /* 12906 * Function: 12907 * _bcm_port_software_init 12908 * Purpose: 12909 * Initialization of software for port subsystem. 12910 * Parameters: 12911 * unit - StrataSwitch unit number. 12912 * Returns: 12913 * BCM_E_NONE - success (or already initialized) 12914 * BCM_E_INTERNAL- failed to write PTABLE entries 12915 * BCM_E_MEMORY - failed to allocate required memory. 12916 */ 12917 12918 STATIC int 12919 _bcm_port_software_init(int unit) 12920 { 12921 bcm_port_t port = 0; 12922 int max_num_port = 0; 12923 bcm_pbmp_t all_pbmp; 12924 12925 BCM_PBMP_CLEAR(all_pbmp); 12926 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 12927 max_num_port = SOC_MAX_NUM_PORTS; 12928 12929 #ifdef BCM_KATANA2_SUPPORT 12930 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 12931 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 12932 } 12933 if (soc_feature(unit, soc_feature_linkphy_coe) || 12934 soc_feature(unit, soc_feature_subtag_coe)) { 12935 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 12936 max_num_port = SOC_MAX_NUM_PP_PORTS; 12937 } 12938 #endif 12939 12940 if (bcm_port_info[unit] != NULL) { 12941 PBMP_ITER(all_pbmp, port) { 12942 if (PORT(unit, port).p_vd_pbvl != NULL) { 12943 sal_free(PORT(unit, port).p_vd_pbvl); 12944 PORT(unit, port).p_vd_pbvl = NULL; 12945 } 12946 12947 if (PORT(unit, port).e2ecc_config != NULL) { 12948 sal_free(PORT(unit, port).e2ecc_config); 12949 PORT(unit, port).e2ecc_config = NULL; 12950 } 12951 12952 PORT(unit, port).flags = 0; 12953 #ifdef BCM_TRIDENT2_SUPPORT 12954 if (SOC_IS_TD2_TT2(unit)) { 12955 PORT(unit, port).enable = TRUE; 12956 } 12957 #endif /* BCM_TRIDENT2_SUPPORT */ 12958 } 12959 } 12960 12961 if (bcm_port_info[unit] == NULL) { 12962 bcm_port_info[unit] = sal_alloc(sizeof(_bcm_port_info_t) * max_num_port, 12963 "bcm_port_info"); 12964 if (bcm_port_info[unit] == NULL) { 12965 return BCM_E_MEMORY; 12966 } 12967 } 12968 sal_memset(bcm_port_info[unit], 0, sizeof(_bcm_port_info_t) * max_num_port); 12969 12970 SOC_IF_ERROR_RETURN(soc_phy_common_init(unit)); 12971 #if defined(BCM_FIREBOLT_SUPPORT) 12972 if (SOC_IS_FBX(unit)) { 12973 BCM_IF_ERROR_RETURN(_bcm_port_vd_pbvl_init(unit)); 12974 } 12975 #endif /* BCM_FIREBOLT_SUPPORT */ 12976 12977 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 12978 || defined(BCM_RAVEN_SUPPORT) 12979 if (SOC_WARM_BOOT(unit)) { 12980 #ifdef BCM_TRIUMPH2_SUPPORT 12981 /* Moved to here for TD3 since the warm boot function call order changed */ 12982 if (soc_feature(unit, soc_feature_lport_tab_profile)) { 12983 BCM_IF_ERROR_RETURN(bcm_esw_port_lport_profile_recover(unit)); 12984 } 12985 if (soc_feature(unit, soc_feature_egr_lport_tab_profile)) { 12986 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_profile_recover(unit)); 12987 } 12988 #endif 12989 } 12990 12991 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 12992 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_init(unit)); 12993 } 12994 if (soc_feature(unit, soc_feature_color_prio_map)) { 12995 BCM_IF_ERROR_RETURN(_bcm_fb2_priority_map_init(unit)); 12996 } 12997 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT \ 12998 || BCM_RAPTOR_SUPPORT */ 12999 13000 #if defined(BCM_TRX_SUPPORT) 13001 if (SOC_IS_TRX(unit)) { 13002 for (port = 0; port < max_num_port; port++) { 13003 PORT(unit, port).dtag_mode = BCM_PORT_DTAG_MODE_NONE; 13004 } 13005 } 13006 #endif 13007 13008 #ifdef BCM_WARM_BOOT_SUPPORT 13009 if (SOC_WARM_BOOT(unit) || SOC_FAST_REBOOT(unit)) { 13010 #if defined(BCM_XGS_SWITCH_SUPPORT) 13011 if (soc_feature(unit, soc_feature_remap_ut_prio)) { 13012 bcm_port_cfg_t pcfg; 13013 PBMP_ITER(all_pbmp, port) { 13014 SOC_IF_ERROR_RETURN 13015 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, 13016 &pcfg)); 13017 PORT(unit, port).p_ut_prio = pcfg.pc_new_opri; 13018 } 13019 } 13020 #ifdef BCM_TRIDENT2_SUPPORT 13021 if (SOC_IS_TD2_TT2(unit)) { 13022 PBMP_ITER(all_pbmp, port) { 13023 PORT(unit, port).enable = TRUE; 13024 } 13025 } 13026 #endif /* BCM_TRIDENT2_SUPPORT */ 13027 #endif /* BCM_XGS_SWITCH_SUPPORT */ 13028 #if defined(BCM_TRX_SUPPORT) 13029 if (SOC_IS_TRX(unit)) { 13030 PBMP_ITER(all_pbmp, port) { 13031 /* Recover port's dtag_mode */ 13032 PORT(unit, port).dtag_mode = BCM_PORT_DTAG_MODE_NONE; 13033 } 13034 } 13035 #endif /* BCM_TRX_SUPPORT */ 13036 } 13037 #endif /* BCM_WARM_BOOT_SUPPORT */ 13038 13039 return BCM_E_NONE; 13040 } 13041 13042 /* 13043 * Function: 13044 * _bcm_port_settings_init 13045 * Purpose: 13046 * Initialize port settings if they are to be different from the 13047 * default ones 13048 * Parameters: 13049 * unit - StrataSwitch unit number. 13050 * port - port number 13051 * Returns: 13052 * BCM_E_NONE - success (or already initialized) 13053 * BCM_E_INTERNAL- failed to write PTABLE entries 13054 * Notes: 13055 * This function initializes port settings based on the folowing config 13056 * variables: 13057 * port_init_speed 13058 * port_init_duplex 13059 * port_init_adv 13060 * port_init_autoneg 13061 * If a variable is not set, then no additional initialization of the 13062 * corresponding parameter is done (and the defaults will normally be 13063 * advertize everything you can do and use autonegotiation). 13064 * 13065 * A typical use would be to set: 13066 * port_init_adv=0 13067 * port_init_autoneg=1 13068 * to force link down in the beginning. 13069 * 13070 * Another setup that makes sense is something like: 13071 * port_init_speed=10 13072 * port_init_duplex=0 13073 * port_init_autoneg=0 13074 * in order to force link into a certain mode. (It is very important to 13075 * disable autonegotiation in this case). 13076 * 13077 * PLEASE NOTE: 13078 * The standard rc.soc forces autoneg=on on all the ethernet ports 13079 * (FE and GE). Thus, to use the second example one has to edit rc.soc 13080 * as well. 13081 * 13082 * This function has been declared as global, but not exported. This will 13083 * make port initialization easier when using VxWorks shell. 13084 */ 13085 int 13086 bcm_port_settings_init(int unit, bcm_port_t port) 13087 { 13088 int val; 13089 bcm_port_info_t info; 13090 13091 LOG_INFO(BSL_LS_BCM_PORT, 13092 (BSL_META_U(unit, 13093 "bcm_port_settings_init: u=%d p=%d\n"),unit, port)); 13094 13095 bcm_port_info_t_init(&info); 13096 13097 val = soc_property_port_get(unit, port, spn_PORT_INIT_SPEED, -1); 13098 if (val != -1) { 13099 info.speed = val; 13100 info.action_mask |= BCM_PORT_ATTR_SPEED_MASK; 13101 } 13102 13103 val = soc_property_port_get(unit, port, spn_PORT_INIT_DUPLEX, -1); 13104 if (val != -1) { 13105 info.duplex = val; 13106 info.action_mask |= BCM_PORT_ATTR_DUPLEX_MASK; 13107 } 13108 13109 val = soc_property_port_get(unit, port, spn_PORT_INIT_ADV, -1); 13110 if (val != -1) { 13111 info.local_advert = val; 13112 info.action_mask |= BCM_PORT_ATTR_LOCAL_ADVERT_MASK; 13113 } 13114 13115 val = soc_property_port_get(unit, port, spn_PORT_INIT_AUTONEG, -1); 13116 if (val != -1) { 13117 info.autoneg = val; 13118 info.action_mask |= BCM_PORT_ATTR_AUTONEG_MASK; 13119 } 13120 return bcm_esw_port_selective_set(unit, port, &info); 13121 } 13122 13123 #ifdef BCM_TRIUMPH2_SUPPORT 13124 /* Helper function to program logical to physical (and reverse) port mapping */ 13125 STATIC int 13126 _bcm_port_remap_set(int unit, bcm_port_t phys, bcm_port_t logical) 13127 { 13128 port_tab_entry_t ptab; 13129 sys_portmap_entry_t sys_portmap; 13130 uint32 regval; 13131 13132 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, 13133 MEM_BLOCK_ANY, phys, &ptab)); 13134 soc_PORT_TABm_field32_set(unit, &ptab, SRC_SYS_PORT_IDf, logical); 13135 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm, 13136 MEM_BLOCK_ALL, phys, &ptab)); 13137 13138 SOC_IF_ERROR_RETURN(soc_mem_read(unit, SYS_PORTMAPm, 13139 MEM_BLOCK_ANY, logical, &sys_portmap)); 13140 soc_SYS_PORTMAPm_field32_set(unit, &sys_portmap, PHYS_PORT_IDf, phys); 13141 SOC_IF_ERROR_RETURN(soc_mem_write(unit, SYS_PORTMAPm, 13142 MEM_BLOCK_ALL, logical, &sys_portmap)); 13143 13144 /* Configure E2ECC port mapping register */ 13145 SOC_IF_ERROR_RETURN(READ_E2ECC_PORT_MAPPINGr(unit, phys, ®val)); 13146 soc_reg_field_set(unit, E2ECC_PORT_MAPPINGr, ®val, MAPPED_PORT_NUMf, logical); 13147 SOC_IF_ERROR_RETURN(WRITE_E2ECC_PORT_MAPPINGr(unit, phys, regval)); 13148 13149 return BCM_E_NONE; 13150 } 13151 13152 STATIC int 13153 _bcm_tr2_system_tpid_init(int unit) 13154 { 13155 int tpid_index, sys_index, rv = BCM_E_NONE; 13156 bcm_module_t module; 13157 bcm_port_t port; 13158 system_config_table_entry_t systab; 13159 uint32 tpid_enable; 13160 uint16 tpid; 13161 13162 tpid = _bcm_fb2_outer_tpid_default_get(unit); 13163 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_lkup(unit, tpid, &tpid_index)); 13164 13165 for (module = 0; module <= SOC_MODID_MAX(unit); module++) { 13166 for (port = 0; port < 64; port++) { 13167 sys_index = module * 64 + port; 13168 rv = READ_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ANY, 13169 sys_index, &systab); 13170 BCM_IF_ERROR_RETURN(rv); 13171 tpid_enable = (1 << tpid_index); 13172 soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &systab, 13173 OUTER_TPID_ENABLEf, 13174 tpid_enable); 13175 rv = WRITE_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ALL, 13176 sys_index, &systab); 13177 BCM_IF_ERROR_RETURN(rv); 13178 } 13179 } 13180 return rv; 13181 } 13182 #endif 13183 13184 /* 13185 * Function: 13186 * _bcm_esw_port_deinit 13187 * Purpose: 13188 * De-initialize the PORT interface layer for the specified SOC device. 13189 * Parameters: 13190 * unit - StrataSwitch unit number. 13191 * Returns: 13192 * BCM_E_XXX 13193 */ 13194 int 13195 _bcm_esw_port_deinit(int unit) 13196 { 13197 int rv; 13198 13199 if (NULL == bcm_port_info[unit]) { 13200 return (BCM_E_NONE); 13201 } 13202 13203 rv = _bcm_esw_port_software_detach(unit); 13204 BCM_IF_ERROR_RETURN(rv); 13205 13206 #ifdef BCM_TRX_SUPPORT 13207 if (soc_feature(unit, soc_feature_vlan_action) || 13208 soc_feature(unit,soc_feature_egr_vlan_action)) { 13209 #ifdef BCM_TRIUMPH2_SUPPORT 13210 if (soc_feature(unit, soc_feature_vpd_profile)) { 13211 _bcm_tr2_port_vpd_bitmap_free(unit); 13212 } 13213 #endif /* BCM_TRIUMPH2_SUPPORT */ 13214 13215 /* Initialize the vlan action profile table */ 13216 #if defined(BCM_TOMAHAWK3_SUPPORT) 13217 if (SOC_IS_TOMAHAWK3(unit)) { 13218 rv = _bcm_th3_vlan_action_profile_detach(unit); 13219 } else 13220 #endif /* BCM_TOMAHAWK3_SUPPORT */ 13221 { 13222 rv = _bcm_trx_vlan_action_profile_detach(unit); 13223 } 13224 BCM_IF_ERROR_RETURN(rv); 13225 } 13226 #endif /* BCM_TRX_SUPPORT */ 13227 13228 #ifdef BCM_TRIUMPH2_SUPPORT 13229 if (soc_feature(unit, soc_feature_gport_service_counters)) { 13230 rv = _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeGport); 13231 BCM_IF_ERROR_RETURN(rv); 13232 } 13233 #endif /* BCM_TRIUMPH2_SUPPORT */ 13234 13235 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \ 13236 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) 13237 if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) || 13238 SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 13239 SOC_IS_APACHE(unit)) && 13240 (soc_feature(unit,soc_feature_timesync_support))) { 13241 _bcm_esw_port_timesync_profile_delete(unit); 13242 } 13243 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || 13244 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */ 13245 13246 #if defined(BCM_TRIUMPH3_SUPPORT) 13247 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 13248 rv = _bcm_port_force_forward_deinit(unit); 13249 if(BCM_FAILURE(rv)) { 13250 return rv; 13251 } 13252 } 13253 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/ 13254 #if defined(BCM_TOMAHAWK_SUPPORT) 13255 if (soc_feature(unit, soc_feature_asf_multimode)) { 13256 /* deinit ASF (cutthrough) subsystem */ 13257 BCM_IF_ERROR_RETURN(_bcm_esw_asf_deinit(unit)); 13258 } 13259 #endif 13260 #ifdef BCM_TRIUMPH3_SUPPORT 13261 if (SOC_IS_TRIUMPH3(unit)) { 13262 _bcm_esw_ibod_sync_recovery_stop(unit); 13263 } 13264 #endif 13265 #ifdef BCM_PREEMPTION_SUPPORT 13266 if (soc_feature(unit, soc_feature_preemption)) { 13267 bcmi_esw_preemption_cleanup(unit); 13268 } 13269 if (soc_feature(unit, soc_feature_preemption_cnt)) { 13270 bcmi_esw_preemption_counter_cleanup(unit); 13271 } 13272 #endif /* BCM_PREEMPTION_SUPPORT */ 13273 #if defined(BCM_GREYHOUND_SUPPORT) 13274 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 13275 BCM_IF_ERROR_RETURN( 13276 bcmi_esw_port_treat_pktpri_as_dot1p_cleanup(unit)); 13277 } 13278 #endif /* BCM_GREYHOUND_SUPPORT */ 13279 13280 return BCM_E_NONE; 13281 } 13282 13283 /* 13284 * Function: 13285 * _bcm_esw_port_portmod_thread_stop 13286 * Purpose: 13287 * Stop the portmod thread. 13288 * Parameters: 13289 * unit - StrataSwitch unit number. 13290 * Returns: 13291 * BCM_E_XXX 13292 */ 13293 int _bcm_esw_port_portmod_thread_stop(int unit) 13294 { 13295 int rv = BCM_E_NONE; 13296 rv = bcmi_esw_portctrl_portmod_thread_stop(unit); 13297 return rv; 13298 } 13299 13300 #ifdef BCM_TRIDENT_SUPPORT 13301 #ifdef BCM_WARM_BOOT_SUPPORT 13302 /* 13303 * Function: 13304 * _bcm_td_phymode_reconfigure 13305 * Purpose: 13306 * Reconfigure the mode of the phys during warmboot. 13307 * This function has code copied from _soc_trident_misc_init 13308 * to keep the phy modes consistent in cold and warmboot modes. 13309 * This is required to be called before the phy probe routines 13310 * in order for the mode to be configured correctly. 13311 * Parameters: 13312 * unit - StrataSwitch unit number. 13313 * Returns: 13314 * BCM_E_XXX 13315 */ 13316 STATIC int 13317 _bcm_td_phymode_reconfigure(int unit) { 13318 13319 soc_info_t *si = &SOC_INFO(unit); 13320 int port, blk, blk_port, num_lanes, phy_port, bindex; 13321 13322 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 13323 blk_port = SOC_BLOCK_PORT(unit, blk); 13324 if (blk_port < 0) { 13325 continue; 13326 } 13327 /* 13328 * Program XLPORT mode and default Warpcore lanes setting 13329 * core_mode: the number of ports on the system side of XMAC 13330 * phy_mode: the number of ports on the Warpcore side of XMAC 13331 * num_lanes: the number of lanes on the line side of Warpcore 13332 */ 13333 if (si->port_speed_max[blk_port] > 20000) { 13334 num_lanes = 4; 13335 } else if (si->port_speed_max[blk_port] > 10000) { 13336 if (si->port_speed_max[blk_port] == 20000 && 13337 si->port_num_lanes[blk_port] == 4) { 13338 num_lanes = 4; 13339 } else { 13340 num_lanes = 2; 13341 } 13342 } else { 13343 num_lanes = 1; 13344 } 13345 13346 phy_port = ((si->port_l2p_mapping[blk_port] - 1) & ~0x3) + 1; 13347 for (bindex = 0; bindex < 4; bindex++) { 13348 port = si->port_p2l_mapping[phy_port + bindex]; 13349 if (port == -1) { 13350 continue; 13351 } 13352 si->port_num_lanes[port] = num_lanes; 13353 } 13354 } 13355 return BCM_E_NONE; 13356 } 13357 #endif /* BCM_WARM_BOOT_SUPPORT */ 13358 #endif /* BCM_TRIDENT_SUPPORT */ 13359 13360 #ifdef BCM_WARM_BOOT_SUPPORT 13361 #ifdef BCM_TRIUMPH3_SUPPORT 13362 STATIC int _bcm_tr3_flexport_wb_recover(int unit) 13363 { 13364 int rv = BCM_E_NONE; 13365 int alloc_sz = 0; 13366 uint8 *port_state; 13367 uint16 recovered_ver; 13368 bcm_port_t port; 13369 int stable_size; 13370 soc_scache_handle_t scache_handle; 13371 soc_info_t *si = &SOC_INFO(unit); 13372 int _port_lanes_valid = 0; 13373 int _port_num_lanes[SOC_MAX_NUM_PORTS] = {0}; 13374 bcm_pbmp_t all_pbmp; 13375 13376 BCM_PBMP_CLEAR(all_pbmp); 13377 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 13378 13379 /* Calculate the offset of port_num_lanes */ 13380 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 13381 PBMP_ITER(all_pbmp, port) { 13382 alloc_sz += sizeof(int); /* vp count */ 13383 } 13384 alloc_sz += sizeof(bcm_pbmp_t); /* Bitmap of dtag_mode == NONE */ 13385 PBMP_ITER(all_pbmp, port) { 13386 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 13387 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 13388 alloc_sz += sizeof(uint32); 13389 } else { 13390 alloc_sz += sizeof(_bcm_port_metering_info_t); 13391 } 13392 alloc_sz += sizeof(uint8); /* flags */ 13393 } 13394 } 13395 alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int)); /* num lanes of port */ 13396 13397 /* Get port_num_lanes from scahe */ 13398 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_PORT, 13399 BCM_PORT_WB_SCACHE_PART_DEFAULT); 13400 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 13401 alloc_sz, (uint8**)&port_state, 13402 BCM_PORT_WB_DEFAULT_VERSION, &recovered_ver); 13403 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 13404 return rv; 13405 } 13406 13407 port_state += (alloc_sz - (SOC_MAX_NUM_PORTS * sizeof(int))); 13408 if (recovered_ver >= BCM_PORT_WB_VERSION_1_1) { 13409 PBMP_ALL_ITER(unit, port) { 13410 sal_memcpy(&_port_num_lanes[port], port_state, 13411 sizeof(int)); 13412 port_state += sizeof(int); 13413 _port_lanes_valid++; 13414 } 13415 } 13416 13417 /* Recover port_num_lanes */ 13418 if (_port_lanes_valid) { 13419 PBMP_ALL_ITER(unit, port) { 13420 if (soc_tr3_port_is_flex_port(unit, port) && 13421 (si->port_num_lanes[port] != _port_num_lanes[port])) { 13422 LOG_VERBOSE(BSL_LS_BCM_PORT, 13423 (BSL_META_U(unit, 13424 "Port %d needs flex transform !!\n"), 13425 port)); 13426 if ((rv = _bcm_tr3_port_lanes_set(unit, port, 13427 _port_num_lanes[port])) != BCM_E_NONE) { 13428 LOG_ERROR(BSL_LS_BCM_PORT, \ 13429 (BSL_META_U(unit, \ 13430 "Error unit %d: "\ 13431 "Failed port lanes set: %s\n"), 13432 unit, bcm_errmsg(rv))); 13433 return rv; 13434 } 13435 } 13436 } 13437 (void)soc_port_type_verify(unit); 13438 } 13439 13440 return rv; 13441 } 13442 13443 STATIC void 13444 _bcm_tr3_port_info_reconfig(int unit) 13445 { 13446 soc_port_t port; 13447 13448 PBMP_ALL_ITER(unit, port) { 13449 if (IS_AXP_PORT(unit, port)) { 13450 /* Physical port table index doesn't exist for AXP ports */ 13451 continue; 13452 } 13453 /* cache num of port lanes */ 13454 (void)soc_tr3_port_lanes_gen(unit, port, &SOC_INFO(unit).port_num_lanes[port], NULL); 13455 } 13456 13457 if (soc_feature(unit, soc_feature_flex_port)) { 13458 _bcm_tr3_flexport_wb_recover(unit); 13459 } 13460 } 13461 #endif /* BCM_TRIUMPH3_SUPPORT */ 13462 #endif /* BCM_WARM_BOOT_SUPPORT */ 13463 13464 #ifdef BCM_HIGIG2_SUPPORT 13465 /* 13466 * Function: 13467 * _bcm_esw_port_higig2_mode_set 13468 * Purpose: 13469 * Set port Higig2 mode 13470 * Parameters: 13471 * unit - StrataSwitch unit # 13472 * port - StrataSwitch port # 13473 * higig2_mode - Higig2 mode 13474 * Returns: 13475 * BCM_E_XXX 13476 */ 13477 int 13478 _bcm_esw_port_higig2_mode_set(int unit, bcm_port_t port, int higig2_mode) 13479 { 13480 soc_reg_t egr_port_reg; 13481 soc_mem_t egr_port_mem; 13482 13483 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 13484 return bcmi_esw_portctrl_higig2_mode_set(unit, port, higig2_mode); 13485 } 13486 13487 if (!SOC_IS_KATANA2(unit)) { 13488 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, 13489 _BCM_CPU_TABS_NONE, HIGIG2f, higig2_mode)); 13490 } 13491 egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 13492 SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) || 13493 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ? 13494 EGR_PORT_64r : EGR_PORTr; 13495 if (SOC_REG_FIELD_VALID(unit, egr_port_reg, HIGIG2f)) { 13496 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, egr_port_reg, port, 13497 HIGIG2f, higig2_mode)); 13498 } else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, HIGIG2f)) { 13499 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, EGR_PORTm, port, 13500 HIGIG2f, higig2_mode)); 13501 } 13502 13503 #if defined(BCM_SABER2_SUPPORT) 13504 if(SOC_IS_SABER2(unit)) { 13505 /* For Saber2, configure IECELL along with XLPORT */ 13506 if (SOC_REG_PORT_VALID(unit, IECELL_CONFIGr, port)) { 13507 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 13508 IECELL_CONFIGr, port, HIGIG2_MODEf, higig2_mode)); 13509 13510 } 13511 } 13512 #endif 13513 13514 if (IS_CL_PORT(unit, port) && 13515 SOC_REG_FIELD_VALID(unit, CLPORT_CONFIGr, HIGIG2_MODEf)) { 13516 uint32 clp_hg2_mode = higig2_mode; 13517 13518 #ifdef BCM_GREYHOUND2_SUPPORT 13519 if (SOC_IS_GREYHOUND2(unit)) { 13520 /* GH2 for CL port has PGW interface config for HG2/HG2-Lite */ 13521 #ifdef BCM_FIRELIGHT_SUPPORT 13522 if (soc_feature(unit, soc_feature_fl)) { 13523 BCM_IF_ERROR_RETURN(soc_firelight_pgw_encap_field_modify( 13524 unit, port, HIGIG2_MODEf, higig2_mode)); 13525 } else 13526 #endif /* BCM_FIRELIGHT_SUPPORT */ 13527 { 13528 BCM_IF_ERROR_RETURN(soc_greyhound2_pgw_encap_field_modify( 13529 unit, port, HIGIG2_MODEf, higig2_mode)); 13530 } 13531 13532 /* GH2 sepcial design to set CLPORT_CONFIGr as IEEE encap mode for 13533 * HG2-Lite. Thus the CLPORT_CONFIGr.HIGIG2_MODEf must be 0 here. 13534 */ 13535 if (IS_HL_PORT(unit, port)) { 13536 clp_hg2_mode = 0; 13537 } 13538 } 13539 #endif /* GREYHOUND2 */ 13540 13541 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CLPORT_CONFIGr, port, 13542 HIGIG2_MODEf, clp_hg2_mode)); 13543 } else if (IS_C_PORT(unit, port) && 13544 SOC_REG_FIELD_VALID(unit, CPORT_CONFIGr, HIGIG2_MODEf)) { 13545 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CPORT_CONFIGr, port, 13546 HIGIG2_MODEf, higig2_mode)); 13547 } else if (SOC_REG_FIELD_VALID(unit, XLPORT_CONFIGr, HIGIG2_MODEf)) { 13548 uint32 xlp_hg2_mode = higig2_mode; 13549 13550 #ifdef BCM_GREYHOUND_SUPPORT 13551 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 13552 SOC_IS_GREYHOUND2(unit)){ 13553 BCM_IF_ERROR_RETURN(soc_greyhound_pgw_encap_field_modify(unit, 13554 port, HIGIG2_MODEf, higig2_mode)); 13555 13556 /* GH sepcial design to set XLPORT_CONFIGr as IEEE encap mode for 13557 * HG2-Lite. Thus the XLPORT_CONFIGr.HIGIG2_MODEf must be 0 here. 13558 */ 13559 if (IS_HL_PORT(unit, port)) { 13560 xlp_hg2_mode = 0; 13561 } 13562 } 13563 #endif /* BCM_GREYHOUND_SUPPORT */ 13564 13565 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XLPORT_CONFIGr, port, 13566 HIGIG2_MODEf, xlp_hg2_mode)); 13567 } else if (SOC_REG_FIELD_VALID(unit, XPORT_CONFIGr, HIGIG2_MODEf)) { 13568 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XPORT_CONFIGr, port, 13569 HIGIG2_MODEf, higig2_mode)); 13570 } else if (SOC_REG_FIELD_VALID(unit, PORT_CONFIGr, HIGIG2_MODEf)) { 13571 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, PORT_CONFIGr, port, 13572 HIGIG2_MODEf, higig2_mode)); 13573 } 13574 if (soc_feature(unit, soc_feature_wh2)) { 13575 SOC_IF_ERROR_RETURN( 13576 soc_reg_field32_modify(unit, PGW_GE_CONFIGr, port, 13577 HIGIG2_MODEf, higig2_mode)); 13578 } 13579 13580 egr_port_mem = SOC_IS_KATANA2(unit) ? EGR_PHYSICAL_PORTm : EGR_ING_PORTm; 13581 if (SOC_MEM_FIELD_VALID(unit, egr_port_mem, HIGIG2f)) { 13582 if (IS_CPU_PORT(unit, port)) { 13583 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, egr_port_mem, 13584 SOC_INFO(unit).cpu_hg_index, HIGIG2f, higig2_mode)); 13585 } else { 13586 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, egr_port_mem, 13587 port, HIGIG2f, higig2_mode)); 13588 } 13589 } 13590 13591 return BCM_E_NONE; 13592 } 13593 #endif /* BCM_HIGIG2_SUPPORT */ 13594 13595 #ifdef BCM_TRIUMPH3_SUPPORT 13596 /* 13597 * Function: 13598 * _bcm_esw_tr3_port_lanes_init 13599 * Purpose: 13600 * Initialize port lanes settings for 40g port of 13601 * Triumph3(56541,56542, 56545 and 56546) 13602 * Parameters: 13603 * unit - StrataSwitch unit number. 13604 * port - port number 13605 * Returns: 13606 * BCM_E_NONE - success (or already initialized) 13607 * BCM_E_INTERNAL- failed to set lane mode 13608 * Notes: 13609 * This function initializes port lanes settings based on the following config 13610 * variables: 13611 * port_max_speed 13612 * If a variable is not set, then no additional initialization of the 13613 * parameter is done. 13614 * 13615 * If user want to use 100Mbps on WC ports(xe4,xe5), configuration 13616 * must be setted as below: 13617 * port_max_speed=100 13618 */ 13619 int 13620 _bcm_esw_tr3_port_lanes_init(int unit) 13621 { 13622 int rv; 13623 int max_speed; 13624 int old_lanes = 0, new_lanes = -1; 13625 int enable; 13626 bcm_port_t port; 13627 PBMP_PORT_ITER(unit, port) { 13628 if (port != 54 && port != 55) { 13629 continue; 13630 } 13631 if (soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, 0)) { 13632 max_speed = soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, 0); 13633 if ((max_speed == 100) || (max_speed == 1000)) { 13634 new_lanes = 1; 13635 } else if ((max_speed != 100) && (max_speed != 1000)) { 13636 new_lanes = 4; 13637 } 13638 BCM_IF_ERROR_RETURN(_bcm_tr3_port_lanes_get(unit, port, &old_lanes)); 13639 if (new_lanes > 0 && old_lanes != new_lanes) { 13640 /* Cache original configurations */ 13641 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable)); 13642 COUNTER_LOCK(unit); 13643 rv = _bcm_tr3_port_lanes_set(unit, port, new_lanes); 13644 COUNTER_UNLOCK(unit); 13645 BCM_IF_ERROR_RETURN(rv); 13646 bcm_port_settings_init(unit, port); 13647 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, enable)); 13648 } 13649 } 13650 } 13651 return BCM_E_NONE; 13652 } 13653 #endif 13654 13655 #if defined(BCM_TRIDENT3_SUPPORT) && defined(CANCUN_SUPPORT) 13656 /* 13657 * Function: 13658 * _bcm_esw_td3_port_cmh_ctrl_set 13659 * Description: 13660 * Configure CANCUN redefined port control. 13661 * Parameters: 13662 * unit - Device number 13663 * port - Port number 13664 * type - Enum value of the feature 13665 * value - value to be set 13666 * Return Value: 13667 * BCM_E_NONE 13668 * BCM_E_UNAVAIL - Functionality not available 13669 */ 13670 int 13671 _bcm_esw_td3_port_cmh_ctrl_set(int unit, bcm_port_t port, 13672 bcm_port_control_t type, int value) 13673 { 13674 int rv = BCM_E_NONE; 13675 uint32 entry[SOC_MAX_MEM_WORDS]; 13676 bcm_module_t my_modid = 0, modid_out; 13677 bcm_port_t port_out; 13678 bcm_trunk_t trunk_out; 13679 int src_trk_idx = 0, id_out; 13680 soc_mem_t mem = SOURCE_TRUNK_MAP_TABLEm; 13681 13682 if (BCM_GPORT_IS_SET(port)) { 13683 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 13684 &modid_out, &port_out, &trunk_out, &id_out)); 13685 } else { 13686 port_out = port; 13687 } 13688 13689 if (!soc_cancun_cmh_check(unit, LPORT_TABm, VXLAN_SVP_ASSIGNMENT_KEY_TYPEf)) { 13690 return rv; 13691 } 13692 13693 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 13694 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, my_modid, 13695 port_out, &src_trk_idx)); 13696 13697 mem = SOURCE_TRUNK_MAP_TABLEm; 13698 sal_memset(entry, 0, sizeof(entry)); 13699 soc_mem_lock(unit, mem); 13700 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, src_trk_idx, entry); 13701 if (SOC_SUCCESS(rv)) { 13702 soc_mem_field32_set(unit, mem, entry, CTRL_PROFILE_IDX_0f, 13703 value? 0x1: 0x0); 13704 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, src_trk_idx, entry); 13705 } 13706 soc_mem_unlock(unit, mem); 13707 13708 return rv; 13709 } 13710 13711 #endif 13712 13713 /* 13714 * Function: 13715 * bcm_port_init 13716 * Purpose: 13717 * Initialize the PORT interface layer for the specified SOC device. 13718 * Parameters: 13719 * unit - StrataSwitch unit number. 13720 * Returns: 13721 * BCM_E_NONE - success (or already initialized) 13722 * BCM_E_INTERNAL- failed to write PTABLE entries 13723 * BCM_E_MEMORY - failed to allocate required memory. 13724 * Notes: 13725 * By default ports come up enabled. They can be made to come up disabled 13726 * at startup by a compile-time application policy flag in your Make.local 13727 * PTABLE initialized. 13728 */ 13729 int 13730 bcm_esw_port_init(int unit) 13731 { 13732 int rv, port_enable, length_check; 13733 bcm_port_t p; 13734 int p_speed; 13735 pbmp_t okay_ports; 13736 bcm_vlan_data_t vd; 13737 char pfmtok[SOC_PBMP_FMT_LEN], 13738 pfmtall[SOC_PBMP_FMT_LEN]; 13739 bcm_pbmp_t all_pbmp; 13740 #ifdef BCM_TRX_SUPPORT 13741 bcm_pbmp_t hg_pbmp; 13742 #endif /* BCM_TRX_SUPPORT */ 13743 #if defined(BCM_KATANA2_SUPPORT) 13744 uint32 entry[SOC_MAX_MEM_WORDS]; 13745 #endif /* BCM_KATANA_SUPPORT */ 13746 uint32 rx_los; 13747 #ifdef BCM_TRIDENT2_SUPPORT 13748 int enable; 13749 #endif /* BCM_TRIDENT2_SUPPORT */ 13750 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 13751 int index; 13752 mmu_intfi_st_trans_tbl_entry_t st_trans_entry; 13753 #endif 13754 #if defined(BCM_FIREBOLT6_SUPPORT) 13755 egr_port_min_pkt_size_entry_t egr_port_mem_pkt_size_ent; 13756 #endif 13757 13758 int port_iter; 13759 #ifdef BCM_METROLITE_SUPPORT 13760 uint16 dev_id=0; 13761 uint8 rev_id=0; 13762 bcm_pbmp_t non_sat_port_pbmp; 13763 soc_cm_get_id(unit, &dev_id, &rev_id); 13764 #endif 13765 13766 LOG_VERBOSE(BSL_LS_BCM_PORT, 13767 (BSL_META_U(unit, 13768 "bcm_port_init: unit %d\n"), unit)); 13769 assert(unit < BCM_MAX_NUM_UNITS); 13770 if ((rv = _bcm_port_software_init(unit)) != BCM_E_NONE) { 13771 LOG_ERROR(BSL_LS_BCM_PORT, 13772 (BSL_META_U(unit, 13773 "Error unit %d: Failed software port init: %s\n"), 13774 unit, bcm_errmsg(rv))); 13775 return rv; 13776 } 13777 if (SAL_BOOT_SIMULATION && 13778 soc_property_get(unit, "skip_port_hw_init", 0)) { 13779 return BCM_E_NONE; 13780 } 13781 13782 /* Initialize Port Function driver */ 13783 BCM_ESW_PORT_DRV(unit) = NULL; 13784 13785 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT 13786 #if defined(BCM_KATANA2_SUPPORT) 13787 if (SOC_IS_KATANA2(unit)) { 13788 BCM_IF_ERROR_RETURN(bcmi_katana2_port_fn_drv_init(unit)); 13789 } else 13790 #endif 13791 #if defined(BCM_MONTEREY_SUPPORT) 13792 if (SOC_IS_MONTEREY(unit)) { 13793 BCM_IF_ERROR_RETURN(bcmi_monterey_port_fn_drv_init(unit)); 13794 } else 13795 #endif 13796 #if defined(BCM_APACHE_SUPPORT) 13797 if (SOC_IS_APACHE(unit)) { 13798 BCM_IF_ERROR_RETURN(bcmi_apache_port_fn_drv_init(unit)); 13799 } else 13800 #endif 13801 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 13802 if (SOC_IS_TD2P_TT2P(unit)) { 13803 BCM_IF_ERROR_RETURN(bcmi_td2p_port_fn_drv_init(unit)); 13804 } else 13805 #endif 13806 #ifdef BCM_TRIDENT3_SUPPORT 13807 if (SOC_IS_TRIDENT3(unit)) { 13808 BCM_IF_ERROR_RETURN(bcmi_td3_port_fn_drv_init(unit)); 13809 } else 13810 #endif 13811 #ifdef BCM_HURRICANE4_SUPPORT 13812 if (SOC_IS_HURRICANE4(unit)) { 13813 BCM_IF_ERROR_RETURN(bcmi_hr4_port_fn_drv_init(unit)); 13814 } else 13815 #endif 13816 #ifdef BCM_HELIX5_SUPPORT 13817 if (SOC_IS_HELIX5(unit)) { 13818 BCM_IF_ERROR_RETURN(bcmi_hx5_port_fn_drv_init(unit)); 13819 } else 13820 #endif 13821 #ifdef BCM_MAVERICK2_SUPPORT 13822 if (SOC_IS_MAVERICK2(unit)) { 13823 BCM_IF_ERROR_RETURN(bcmi_mv2_port_fn_drv_init(unit)); 13824 } else 13825 #endif 13826 #ifdef BCM_TOMAHAWK2_SUPPORT 13827 if (SOC_IS_TOMAHAWK2(unit)) { 13828 BCM_IF_ERROR_RETURN(bcmi_th2_port_fn_drv_init(unit)); 13829 } else 13830 #endif 13831 #ifdef BCM_TOMAHAWK3_SUPPORT 13832 if (SOC_IS_TOMAHAWK3(unit)) { 13833 BCM_IF_ERROR_RETURN(bcmi_th3_port_fn_drv_init(unit)); 13834 } else 13835 #endif 13836 #ifdef BCM_HURRICANE4_SUPPORT 13837 if (SOC_IS_HURRICANE4(unit)) { 13838 BCM_IF_ERROR_RETURN(bcmi_hr4_port_fn_drv_init(unit)); 13839 } else 13840 #endif 13841 #ifdef BCM_FIREBOLT6_SUPPORT 13842 if (SOC_IS_FIREBOLT6(unit)) { 13843 BCM_IF_ERROR_RETURN(bcmi_fb6_port_fn_drv_init(unit)); 13844 } else 13845 #endif 13846 { 13847 } 13848 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */ 13849 13850 SOC_PBMP_CLEAR(all_pbmp); 13851 13852 #ifdef BCM_TRX_SUPPORT 13853 SOC_PBMP_CLEAR(hg_pbmp); 13854 13855 if (soc_feature(unit, soc_feature_vlan_action) || 13856 soc_feature(unit, soc_feature_egr_vlan_action)) { 13857 bcm_vlan_action_set_t action; 13858 13859 bcm_vlan_action_set_t_init(&action); 13860 13861 #ifdef BCM_TRIUMPH2_SUPPORT 13862 if (soc_feature(unit, soc_feature_vpd_profile)) { 13863 BCM_IF_ERROR_RETURN(_bcm_tr2_port_vpd_bitmap_alloc(unit)); 13864 } 13865 #endif 13866 13867 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 13868 13869 #ifdef BCM_KATANA2_SUPPORT 13870 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 13871 /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which 13872 * causes the outer tag to be removed from packets that don't have 13873 * a hit in the egress vlan tranlation table. Set to 0 to disable this. 13874 */ 13875 uint32 rval = 0; 13876 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, VT_MISS_UNTAGf, 0); 13877 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf,1); 13878 13879 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 13880 PBMP_ITER(all_pbmp, p) { 13881 BCM_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, p, rval)); 13882 } 13883 } 13884 13885 if (soc_feature(unit, soc_feature_linkphy_coe) || 13886 soc_feature(unit, soc_feature_subtag_coe)) { 13887 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 13888 13889 13890 } 13891 #endif 13892 13893 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 13894 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) 13895 || SOC_IS_TRIDENT3X(unit)) && 13896 (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOL_DATAm) && 13897 soc_mem_index_max(unit, VLAN_PROTOCOL_DATAm) > 0)) { 13898 vlan_protocol_data_entry_t vlan_protocol_data_entries[16]; 13899 uint32 vlan_protocol_data_index =0; 13900 void *entries_buf[1]; 13901 int i, count = 0; 13902 vlan_protocol_data_entry_t vde; 13903 13904 /* Create the default VLAN_PROTOCOL_DATA profile */ 13905 sal_memset(vlan_protocol_data_entries, 0, 13906 sizeof(vlan_protocol_data_entries)); 13907 13908 entries_buf[0] = &vlan_protocol_data_entries; 13909 BCM_IF_ERROR_RETURN( 13910 _bcm_port_vlan_protocol_data_entry_add(unit, entries_buf, 13911 16, (uint32 *)&vlan_protocol_data_index)); 13912 13913 /* First 16 entries of VLAN_PROTOCOL_DATA table are used for 13914 * default profile for Katana2 */ 13915 for (i = 0; i < soc_mem_index_count(unit, VLAN_PROTOCOLm); i++) { 13916 sal_memset(&vde, 0, sizeof(vlan_protocol_data_entry_t)); 13917 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde, 13918 OVIDf, BCM_VLAN_DEFAULT); 13919 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde, 13920 TAG_ACTION_PROFILE_PTRf, 0); 13921 BCM_IF_ERROR_RETURN(WRITE_VLAN_PROTOCOL_DATAm(unit, 13922 MEM_BLOCK_ALL, i, &vde)); 13923 } 13924 13925 count = 0; 13926 PBMP_ITER(all_pbmp, p) { 13927 PORT(unit, p).vp_count = 0; 13928 if (!IS_LB_PORT(unit, p) && !SOC_WARM_BOOT(unit)) { 13929 13930 /* Set vlan_protocol_data_ptr profile index in port table. */ 13931 BCM_IF_ERROR_RETURN( 13932 _bcm_esw_port_tab_set(unit, p, 13933 _BCM_CPU_TABS_ETHER, 13934 VLAN_PROTOCOL_DATA_INDEXf, 13935 vlan_protocol_data_index / 16)); 13936 PORT(unit, p).vlan_prot_ptr = vlan_protocol_data_index; 13937 count++; 13938 } 13939 } 13940 13941 /* Keep one extra reference to the default profile */ 13942 for (i = 1; i < count + 1; i++) { 13943 BCM_IF_ERROR_RETURN( 13944 _bcm_port_vlan_protocol_data_entry_reference (unit, 13945 vlan_protocol_data_index, 16)); 13946 } 13947 } else 13948 13949 #endif 13950 { 13951 PBMP_ITER(all_pbmp, p) { 13952 PORT(unit, p).vp_count = 0; 13953 if (!IS_LB_PORT(unit, p)) { 13954 if (!SOC_IS_TOMAHAWKX(unit) && 13955 !SOC_IS_TOMAHAWK3(unit) && !SOC_IS_TRIDENT3(unit)) { 13956 /* there are more ports the profile */ 13957 #ifdef BCM_TRIUMPH2_SUPPORT 13958 if (soc_feature(unit, soc_feature_vpd_profile)) { 13959 BCM_IF_ERROR_RETURN 13960 (_bcm_port_vlan_prot_index_alloc 13961 (unit, &(PORT(unit, p).vlan_prot_ptr))); 13962 } else 13963 #endif 13964 { 13965 PORT(unit, p).vlan_prot_ptr = p * soc_mem_index_count 13966 (unit, VLAN_PROTOCOLm); 13967 } 13968 } 13969 } 13970 } 13971 } 13972 13973 if (!SOC_WARM_BOOT(unit)) { 13974 /* Clear the profile ptr of source table */ 13975 PBMP_ALL_ITER(unit, p) { 13976 BCM_IF_ERROR_RETURN 13977 (_bcm_trx_vlan_port_egress_action_profile_clear(unit, p)); 13978 } 13979 } 13980 13981 #ifdef BCM_FIREBOLT6_SUPPORT 13982 if (SOC_IS_FIREBOLT6(unit)) { 13983 PBMP_ALL_ITER(unit, p) { 13984 SOC_IF_ERROR_RETURN( 13985 soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, p, 13986 SRC_SUBPORT_NUMf, p)); 13987 SOC_IF_ERROR_RETURN( 13988 soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, p, 13989 PP_PORT_NUMf, p)); 13990 } 13991 13992 /* Set egr min pkt size to default value of 0x40 */ 13993 for (index = 0; index < soc_mem_index_count(unit, 13994 EGR_PORT_MIN_PKT_SIZEm); index++) { 13995 SOC_IF_ERROR_RETURN(READ_EGR_PORT_MIN_PKT_SIZEm( 13996 unit, MEM_BLOCK_ALL, index, 13997 &egr_port_mem_pkt_size_ent)); 13998 soc_mem_field32_set(unit, EGR_PORT_MIN_PKT_SIZEm, 13999 &egr_port_mem_pkt_size_ent, MIN_PKT_SIZEf, 0x40); 14000 SOC_IF_ERROR_RETURN(WRITE_EGR_PORT_MIN_PKT_SIZEm( 14001 unit, MEM_BLOCK_ALL, index, 14002 &egr_port_mem_pkt_size_ent)); 14003 } 14004 } 14005 #endif 14006 14007 /* Initialize the vlan action profile table */ 14008 #if defined(BCM_TOMAHAWK3_SUPPORT) 14009 if (SOC_IS_TOMAHAWK3(unit)) { 14010 BCM_IF_ERROR_RETURN (_bcm_th3_vlan_action_profile_init(unit)); 14011 } else 14012 #endif /* BCM_TOMAHAWK3_SUPPORT */ 14013 { 14014 BCM_IF_ERROR_RETURN (_bcm_trx_vlan_action_profile_init(unit)); 14015 } 14016 14017 if (SOC_IS_KATANA2(unit)) { 14018 SOC_PBMP_ASSIGN(hg_pbmp,PBMP_ST_ALL(unit)); 14019 } else { 14020 SOC_PBMP_ASSIGN(hg_pbmp,PBMP_HG_ALL(unit)); 14021 } 14022 14023 if (!SOC_IS_TRIDENT3X(unit)) { 14024 PBMP_ITER(hg_pbmp, p) { 14025 BCM_IF_ERROR_RETURN 14026 (_bcm_trx_vlan_port_egress_default_action_get(unit, 14027 p, &action)); 14028 /* Backward compatible defaults */ 14029 action.ot_outer = bcmVlanActionDelete; 14030 action.dt_outer = bcmVlanActionDelete; 14031 BCM_IF_ERROR_RETURN 14032 (_bcm_trx_vlan_port_egress_default_action_set(unit, 14033 p, &action)); 14034 } 14035 } 14036 } 14037 #endif /* BCM_TRX_SUPPORT*/ 14038 14039 #ifdef BCM_TRIDENT2PLUS_SUPPORT 14040 if (soc_feature(unit, soc_feature_higig_over_ethernet)) { 14041 #ifdef BCM_WARM_BOOT_SUPPORT 14042 if (SOC_WARM_BOOT(unit)) { 14043 uint32 port_type, hg_type, update = 0; 14044 bcm_pbmp_t e_pbm; 14045 soc_info_t *si; 14046 egr_port_entry_t egr_port; 14047 14048 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 14049 si = &SOC_INFO(unit); 14050 SOC_PBMP_ASSIGN(e_pbm, PBMP_E_ALL(unit)); 14051 PBMP_ITER(e_pbm, p) { 14052 BCM_IF_ERROR_RETURN 14053 (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, p, &egr_port)); 14054 port_type = 14055 soc_mem_field32_get(unit, EGR_PORTm, &egr_port, PORT_TYPEf); 14056 hg_type = 14057 soc_mem_field32_get(unit, EGR_PORTm, &egr_port, HG_TYPEf); 14058 if ((port_type == 1) && 14059 (hg_type == BCM_PORT_HG_TYPE_HGOE_TRANSPORT)) { 14060 SOC_PBMP_PORT_ADD(si->st.bitmap, p); 14061 SOC_PBMP_PORT_REMOVE(si->ether.bitmap, p); 14062 SOC_PBMP_PORT_REMOVE(si->hg2_pbm, p); 14063 update = 1; 14064 } 14065 } 14066 #define RECONFIGURE_PORT_TYPE_INFO(ptype) \ 14067 si->ptype.num = 0; \ 14068 si->ptype.min = si->ptype.max = -1; \ 14069 PBMP_ITER(si->ptype.bitmap, p) { \ 14070 si->ptype.port[si->ptype.num++] = p; \ 14071 if (si->ptype.min < 0) { \ 14072 si->ptype.min = p; \ 14073 } \ 14074 if (p > si->ptype.max) { \ 14075 si->ptype.max = p; \ 14076 } \ 14077 } 14078 14079 if (update) { 14080 /* Recalculate port type data */ 14081 RECONFIGURE_PORT_TYPE_INFO(ether); 14082 RECONFIGURE_PORT_TYPE_INFO(st); 14083 } 14084 #undef RECONFIGURE_PORT_TYPE_INFO 14085 } 14086 } 14087 #endif /* BCM_WARM_BOOT_SUPPORT */ 14088 } 14089 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 14090 14091 #ifdef BCM_TRIUMPH2_SUPPORT 14092 if (soc_feature(unit, soc_feature_gport_service_counters)) { 14093 #ifdef BCM_WARM_BOOT_SUPPORT 14094 if (SOC_WARM_BOOT(unit)) { 14095 port_tab_entry_t ptab; 14096 int fs_idx; 14097 bcm_gport_t gport; 14098 14099 #ifdef BCM_TRIDENT_SUPPORT 14100 if (SOC_IS_TD_TT(unit)) { 14101 BCM_IF_ERROR_RETURN(_bcm_td_phymode_reconfigure(unit)); 14102 } 14103 #endif /* BCM_TRIDENT_SUPPORT */ 14104 PBMP_ITER(all_pbmp, p) { 14105 BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, 14106 MEM_BLOCK_ANY, p, &ptab)); 14107 fs_idx = 14108 soc_mem_field32_get(unit, PORT_TABm, &ptab, 14109 VINTF_CTR_IDXf); 14110 if (fs_idx) { 14111 BCM_IF_ERROR_RETURN 14112 (bcm_esw_port_gport_get(unit, p, &gport)); 14113 _bcm_esw_flex_stat_reinit_add(unit, 14114 _bcmFlexStatTypeGport, fs_idx, gport); 14115 } 14116 } 14117 } 14118 #endif /* BCM_WARM_BOOT_SUPPORT */ 14119 } 14120 #endif /* BCM_TRIUMPH2_SUPPORT */ 14121 14122 #ifdef BCM_WARM_BOOT_SUPPORT 14123 #ifdef BCM_TRIUMPH3_SUPPORT 14124 if (SOC_IS_TRIUMPH3(unit)) { 14125 if (SOC_WARM_BOOT(unit)) { 14126 _bcm_tr3_port_info_reconfig(unit); 14127 } 14128 } 14129 #endif /* BCM_TRIUMPH3_SUPPORT */ 14130 #endif /* BCM_WARM_BOOT_SUPPORT */ 14131 if (!SOC_WARM_BOOT(unit)) { 14132 /* 14133 * Write port configuration tables to contain the Initial System 14134 * Configuration (see init.c). 14135 */ 14136 14137 SOC_PBMP_CLEAR(all_pbmp); 14138 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 14139 14140 #ifdef BCM_KATANA2_SUPPORT 14141 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 14142 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 14143 } 14144 #endif 14145 14146 SOC_PBMP_REMOVE(all_pbmp, PBMP_TDM(unit)); 14147 14148 #ifdef BCM_KATANA2_SUPPORT 14149 if (soc_feature(unit, soc_feature_linkphy_coe) || 14150 soc_feature(unit, soc_feature_subtag_coe)) { 14151 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 14152 } 14153 #endif 14154 14155 vd.vlan_tag = BCM_VLAN_DEFAULT; 14156 BCM_PBMP_ASSIGN(vd.port_bitmap, all_pbmp); 14157 BCM_PBMP_ASSIGN(vd.ut_port_bitmap, all_pbmp); 14158 BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_CMIC(unit)); 14159 PBMP_ITER(all_pbmp, p) { 14160 BCM_IF_ERROR_RETURN 14161 (mbcm_driver[unit]->mbcm_port_cfg_init(unit, p, &vd)); 14162 } 14163 14164 if (SOC_IS_TRIDENT3X(unit)) { 14165 /* Initialize inner TPID 14166 * (WAR)Set to 0x9100 then change back to take effort 14167 */ 14168 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, VLAN_CTRLr, 14169 REG_PORT_ANY, INNER_TPIDf, 0x9100)); 14170 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, VLAN_CTRLr, 14171 REG_PORT_ANY, INNER_TPIDf, 0x8100)); 14172 14173 if (SOC_REG_FIELD_VALID(unit, EGR_CONFIG_1_64r, INNER_TPIDf)) { 14174 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1_64r, 14175 REG_PORT_ANY, INNER_TPIDf, 0x9100)); 14176 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1_64r, 14177 REG_PORT_ANY, INNER_TPIDf, 0x8100)); 14178 } 14179 } 14180 14181 /* 14182 * Clear egress port blocking table 14183 */ 14184 if (SOC_IS_XGS_SWITCH(unit)) { 14185 #ifdef BCM_SHADOW_SUPPORT 14186 if (!SOC_IS_SHADOW(unit)) { 14187 #endif 14188 if (!SAL_BOOT_SIMULATION || SAL_BOOT_QUICKTURN) { 14189 SOC_IF_ERROR_RETURN 14190 (soc_mem_clear(unit, MAC_BLOCKm, COPYNO_ALL, TRUE)); 14191 } 14192 #ifdef BCM_SHADOW_SUPPORT 14193 } 14194 #endif 14195 } 14196 } 14197 14198 #ifdef BCM_SHADOW_SUPPORT 14199 if (SOC_IS_SHADOW(unit)) { 14200 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 14201 if (BCM_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, p)) { 14202 SOC_PBMP_PORT_REMOVE(PBMP_PORT_ALL(unit), p); 14203 } 14204 } 14205 } 14206 #endif 14207 #ifdef BCM_PREEMPTION_SUPPORT 14208 if (soc_feature(unit, soc_feature_preemption)) { 14209 BCM_IF_ERROR_RETURN(bcmi_esw_preemption_init(unit)); 14210 } 14211 #endif 14212 14213 /* Probe for ports */ 14214 SOC_PBMP_CLEAR(okay_ports); 14215 14216 /* Fast reboot will NOT cold boot portmod and the serdes because we 14217 * want to keep the link up 14218 */ 14219 if (SOC_FAST_REBOOT(unit)) { 14220 SOC_WARM_BOOT_START(unit); 14221 } 14222 #ifdef BCM_METROLITE_SUPPORT 14223 if (SOC_IS_METROLITE(unit) && 14224 (dev_id == BCM56272_DEVICE_ID)) { 14225 BCM_PBMP_CLEAR(non_sat_port_pbmp); 14226 BCM_PBMP_ASSIGN(non_sat_port_pbmp, PBMP_PORT_ALL(unit)); 14227 if(SOC_PBMP_MEMBER(non_sat_port_pbmp, _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER)) { 14228 /* TSC0 is OFF */ 14229 SOC_PBMP_PORT_REMOVE(non_sat_port_pbmp, 14230 _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER); 14231 } 14232 rv = bcm_esw_port_probe(unit, non_sat_port_pbmp, &okay_ports); 14233 } else 14234 #endif 14235 { 14236 rv = bcm_esw_port_probe(unit, PBMP_PORT_ALL(unit), &okay_ports); 14237 } 14238 if (rv != BCM_E_NONE) { 14239 LOG_ERROR(BSL_LS_BCM_PORT, 14240 (BSL_META_U(unit, 14241 "Error unit %d: Failed port probe: %s\n"), 14242 unit, bcm_errmsg(rv))); 14243 return rv; 14244 } 14245 14246 LOG_VERBOSE(BSL_LS_BCM_PORT, 14247 (BSL_META_U(unit, 14248 "Probed ports okay: %s of %s\n"), 14249 SOC_PBMP_FMT(okay_ports, pfmtok), 14250 SOC_PBMP_FMT(PBMP_PORT_ALL(unit), pfmtall))); 14251 14252 if (SOC_FAST_REBOOT(unit)) { 14253 SOC_WARM_BOOT_DONE(unit); 14254 14255 /* Add all ports that would have been added during portmod init to 14256 * the pbmp because the rest of the cold boot sequence is going 14257 * to need it 14258 */ 14259 PBMP_PORT_ITER(unit, port_iter) { 14260 if (IS_CPU_PORT(unit, port_iter) || IS_LB_PORT(unit, port_iter)) { 14261 continue; 14262 } 14263 SOC_PBMP_PORT_ADD(okay_ports, port_iter); 14264 } 14265 14266 } 14267 14268 /* 14269 * A compile-time application policy may prefer to disable ports 14270 * when switch boots up 14271 */ 14272 #ifdef BCM_PORT_DEFAULT_DISABLE 14273 port_enable = FALSE; 14274 #else 14275 port_enable = TRUE; 14276 #endif /* BCM_PORT_DEFAULT_DISABLE */ 14277 14278 if(SOC_IS_SABER2(unit) && (!SOC_WARM_BOOT(unit))) { 14279 PBMP_ITER(okay_ports, p) { 14280 if ((rv = bcm_esw_port_enable_set(unit, p, port_enable)) < 0) { 14281 LOG_WARN(BSL_LS_BCM_PORT, 14282 (BSL_META_U(unit, 14283 "Warning: Unit %d Port %s: " 14284 "Failed to %s port: %s\n"), 14285 unit, SOC_PORT_NAME(unit, p),(port_enable) ? \ 14286 "enable" : "disable" ,bcm_errmsg(rv))); 14287 } 14288 } 14289 } 14290 14291 14292 14293 length_check = soc_property_get(unit, spn_MAC_LENGTH_CHECK_ENABLE, 0); 14294 14295 /* Probe and initialize MAC and PHY drivers for ports that were OK */ 14296 PBMP_ITER(okay_ports, p) { 14297 LOG_VERBOSE(BSL_LS_BCM_PORT, 14298 (BSL_META_U(unit, 14299 "bcm_port_init: unit %d port %s\n"), 14300 unit, SOC_PORT_NAME(unit, p))); 14301 14302 PORT_LOCK(unit); 14303 14304 14305 if (SOC_PORT_USE_PORTCTRL(unit, p)) { 14306 } else { 14307 if ((rv = _bcm_port_mode_setup(unit, p, TRUE)) < 0) { 14308 LOG_WARN(BSL_LS_BCM_PORT, 14309 (BSL_META_U(unit, 14310 "Warning: Port %s: " 14311 "Failed to set initial mode: %s\n"), 14312 SOC_PORT_NAME(unit, p), bcm_errmsg(rv))); 14313 } 14314 } 14315 PORT_UNLOCK(unit); 14316 14317 #ifdef BCM_RCPU_SUPPORT 14318 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, p)) { 14319 if (SOC_PORT_USE_PORTCTRL(unit, p)) { 14320 bcmi_esw_portctrl_phy_enable_set(unit, p, TRUE); 14321 } else { 14322 soc_phyctrl_enable_set(unit, p, TRUE); 14323 } 14324 continue; 14325 } 14326 #endif /* BCM_RCPU_SUPPORT */ 14327 14328 #ifdef BCM_WARM_BOOT_SUPPORT 14329 if (SOC_WARM_BOOT(unit) || SOC_FAST_REBOOT(unit)) { 14330 continue; 14331 } 14332 #endif /* BCM_WARM_BOOT_SUPPORT */ 14333 if ((rv = bcm_port_settings_init(unit, p)) < 0) { 14334 LOG_WARN(BSL_LS_BCM_PORT, 14335 (BSL_META_U(unit, 14336 "Warning: Port %s: " 14337 "Failed to configure initial settings: %s\n"), 14338 SOC_PORT_NAME(unit, p), bcm_errmsg(rv))); 14339 } 14340 14341 #ifdef BCM_TRIDENT2_SUPPORT 14342 if (soc_feature(unit, soc_feature_pgw_mac_rsv_mask_remap)) { 14343 uint32 addr; 14344 int block; 14345 uint8 acc_type; 14346 uint32 rval; 14347 14348 addr = soc_reg_addr_get(unit, PGW_MAC_RSV_MASKr, p, 0, 14349 SOC_REG_ADDR_OPTION_NONE, &block, 14350 &acc_type); 14351 addr &= 0xffffff00; 14352 /* coverity[overrun-local : FALSE] */ 14353 addr |= (SOC_INFO(unit).port_l2p_mapping[p] - 1) & 0xf; 14354 SOC_IF_ERROR_RETURN(_soc_reg32_get(unit, block, acc_type, addr, 14355 &rval)); 14356 if (length_check) { 14357 rval |= 0x20; /* set bit 5 to enable frame length check */ 14358 } else { 14359 rval &= ~0x20; /* clear bit 5 to disable frame length check */ 14360 } 14361 rval |= 1 << 18; /* set PFC frame detected indicator */ 14362 SOC_IF_ERROR_RETURN(_soc_reg32_set(unit, block, acc_type, addr, 14363 rval)); 14364 } else 14365 #endif /* BCM_TRIDENT2_SUPPORT */ 14366 /* Control 802.3 frame length field check in MAC for 14367 * XL, XLB0, XT, CL, CLG2, XW (helix4) or MXQ blocks */ 14368 if (IS_XL_PORT(unit, p) || IS_XLB0_PORT(unit, p) || IS_XT_PORT(unit, p) || 14369 IS_CL_PORT(unit, p) || IS_CLG2_PORT(unit, p) || IS_MXQ_PORT(unit,p) || 14370 IS_XW_PORT(unit,p) || IS_CD_PORT(unit, p)) { 14371 uint32 rval; 14372 soc_reg_t reg = INVALIDr; 14373 14374 if ((IS_CL_PORT(unit, p) || IS_CLG2_PORT(unit, p)) && 14375 SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) { 14376 reg = CLPORT_MAC_RSV_MASKr; 14377 } else if (IS_CD_PORT(unit, p)) { 14378 reg = CDMAC_RSV_MASKr; 14379 } else if (SOC_REG_IS_VALID(unit, PGW_MAC_RSV_MASKr)) { 14380 reg = PGW_MAC_RSV_MASKr; 14381 } else if (SOC_IS_SABER2(unit) && SOC_REG_PORT_VALID(unit, XLPORT_MAC_RSV_MASKr, p)) { 14382 reg = XLPORT_MAC_RSV_MASKr; 14383 } else if (SOC_REG_IS_VALID(unit, MAC_RSV_MASKr)) { 14384 reg = MAC_RSV_MASKr; 14385 } else if (SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) { 14386 reg = XLPORT_MAC_RSV_MASKr; 14387 } 14388 14389 if (reg != INVALIDr) { 14390 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, p, 0, &rval)); 14391 if (length_check) { 14392 rval |= 0x20; /* set bit 5 to enable frame length check */ 14393 } else { 14394 rval &= ~0x20; /* clear bit 5 to disable frame length check */ 14395 } 14396 if (SOC_IS_TD2_TT2(unit)|| SOC_IS_HELIX4(unit)) { 14397 rval |= 1 << 18; /* set PFC frame detected indicator */ 14398 } 14399 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, p, 0, rval)); 14400 } 14401 } 14402 14403 /* 14404 * A compile-time application policy may prefer to disable ports 14405 * when switch boots up 14406 */ 14407 14408 #ifdef BCM_PORT_DEFAULT_DISABLE 14409 port_enable = FALSE; 14410 #else 14411 port_enable = TRUE; 14412 #endif /* BCM_PORT_DEFAULT_DISABLE */ 14413 14414 if(!SOC_IS_SABER2(unit)) { 14415 if ((rv = bcm_esw_port_enable_set(unit, p, port_enable)) < 0) { 14416 LOG_WARN(BSL_LS_BCM_PORT, 14417 (BSL_META_U(unit, 14418 "Warning: Port %s: " 14419 "Failed to %s port: %s\n"), 14420 SOC_PORT_NAME(unit, p),(port_enable) ? \ 14421 "enable" : "disable" ,bcm_errmsg(rv))); 14422 } 14423 } 14424 14425 /* 14426 * JAM should be enabled by default 14427 */ 14428 if (IS_E_PORT(unit, p)) { 14429 if (soc_mem_field_valid(unit, PORT_TABm, JAM_ENf) || 14430 soc_reg_field_valid(unit, GE_PORT_CONFIGr, JAM_ENf) || 14431 soc_feature(unit, soc_feature_unimac)) { 14432 14433 #if defined(BCM_HURRICANE_SUPPORT) 14434 if (SOC_IS_HURRICANEX(unit) || SOC_IS_GREYHOUND(unit) || 14435 SOC_IS_GREYHOUND2(unit)) { 14436 rv = bcm_esw_port_jam_set(unit, p, 0); 14437 } else 14438 #endif 14439 { 14440 rv = bcm_esw_port_jam_set(unit, p, 1); 14441 } 14442 if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) { 14443 LOG_WARN(BSL_LS_BCM_PORT, 14444 (BSL_META_U(unit, 14445 "Warning: Port %s: " 14446 "Failed to enable JAM %s\n"), 14447 SOC_PORT_NAME(unit, p), bcm_errmsg(rv))); 14448 } 14449 } 14450 } 14451 #ifdef BCM_TRIUMPH2_SUPPORT 14452 if (soc_feature(unit, soc_feature_unimac_tx_crs) && IS_XQ_PORT(unit, p) 14453 && IS_GE_PORT(unit, p)) { 14454 BCM_IF_ERROR_RETURN 14455 (soc_reg_field32_modify(unit, XPORT_CONFIGr, p, 14456 UNIMAC_HD_ECO_ENABLEf, 1)); 14457 } 14458 #endif 14459 #ifdef BCM_RCPU_SUPPORT 14460 if ((uint32)p == soc_property_get(unit, spn_RCPU_PORT, -1)) { 14461 BCM_IF_ERROR_RETURN 14462 (bcm_esw_port_frame_max_set(unit, p, BCM_PORT_JUMBO_MAXSZ)); 14463 } 14464 #endif /* BCM_RCPU_SUPPORT */ 14465 } 14466 14467 #if defined(BCM_GREYHOUND_SUPPORT) 14468 if (SOC_IS_GREYHOUND(unit)) { 14469 BCM_IF_ERROR_RETURN(bcm_gh_port_init(unit)); 14470 } 14471 #endif 14472 14473 #if defined(BCM_HURRICANE3_SUPPORT) 14474 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 14475 BCM_IF_ERROR_RETURN(bcm_hr3_port_init(unit)); 14476 } 14477 #endif 14478 14479 #if defined(BCM_TRIDENT_SUPPORT) 14480 if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 14481 BCM_IF_ERROR_RETURN(bcm_td_port_init(unit)); 14482 } 14483 #endif /* BCM_TRIDENT_SUPPORT */ 14484 14485 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 14486 defined(BCM_TRX_SUPPORT) 14487 if (!SOC_WARM_BOOT(unit) && !SOC_IS_RELOADING(unit)) { 14488 /* Enable the default outer TPID. */ 14489 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 14490 /* if (soc_feature(unit, soc_feature_vlan_ctrl) && * SOC_IS_SHADOW(unit)) { */ 14491 14492 SOC_PBMP_CLEAR(all_pbmp); 14493 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 14494 14495 #ifdef BCM_KATANA2_SUPPORT 14496 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 14497 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 14498 } 14499 #endif 14500 14501 SOC_PBMP_REMOVE(all_pbmp, PBMP_TDM(unit)); 14502 14503 #ifdef BCM_KATANA2_SUPPORT 14504 if (soc_feature(unit, soc_feature_linkphy_coe) || 14505 soc_feature(unit, soc_feature_subtag_coe)) { 14506 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 14507 } 14508 #endif 14509 14510 #if defined(BCM_SABER2_SUPPORT) 14511 /* If OAMP is enabled by default, skip the port init for oamp port */ 14512 if(SOC_IS_SABER2(unit)) { 14513 int oamp_enable; 14514 (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable); 14515 14516 if (soc_feature(unit, soc_feature_sat) && 14517 ((!SOC_WARM_BOOT(unit) && 14518 soc_property_get(unit, spn_SAT_ENABLE, 0)) || 14519 (SOC_WARM_BOOT(unit) && (oamp_enable == TRUE)))) { 14520 SOC_PBMP_PORT_REMOVE(all_pbmp, 14521 _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER); 14522 } 14523 } 14524 #endif 14525 PBMP_ITER(all_pbmp, p) { 14526 rv = bcm_esw_port_tpid_set(unit, p, 14527 _bcm_fb2_outer_tpid_default_get(unit)); 14528 if (BCM_FAILURE(rv)) { 14529 LOG_WARN(BSL_LS_BCM_PORT, 14530 (BSL_META_U(unit, 14531 "Warning: " 14532 "Failed to set %s port default TPID: %s\n"), 14533 SOC_PORT_NAME(unit, p), bcm_errmsg(rv))); 14534 } 14535 if (soc_feature(unit, soc_feature_inner_tpid_enable)) { 14536 /* Enable the default inner TPID. */ 14537 rv = bcm_esw_port_inner_tpid_set(unit, p, 14538 _bcm_fb2_outer_tpid_default_get(unit)); 14539 if (BCM_FAILURE(rv)) { 14540 LOG_WARN(BSL_LS_BCM_PORT, 14541 (BSL_META_U(unit, 14542 "Warning: " 14543 "Failed to set %s port default inner TPID: %s\n"), 14544 SOC_PORT_NAME(unit, p), bcm_errmsg(rv))); 14545 } 14546 } 14547 } 14548 } 14549 } 14550 #endif 14551 14552 #ifdef BCM_XGS3_FABRIC_SUPPORT 14553 if (SOC_IS_XGS3_FABRIC(unit)) { 14554 PBMP_ALL_ITER(unit, p) { 14555 bcm_esw_port_learn_set(unit, p, BCM_PORT_LEARN_FWD); 14556 } 14557 } 14558 #endif 14559 if (SAL_BOOT_SIMULATION && 14560 soc_property_get(unit, "skip_partial_port_hw_init", 0)) { 14561 return BCM_E_NONE; 14562 } 14563 #ifdef BCM_TRIUMPH2_SUPPORT 14564 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 14565 SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) || 14566 SOC_IS_TD_TT(unit) || SOC_IS_HURRICANEX(unit) || 14567 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit) || 14568 SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit)) { 14569 uint32 regval, profile_index; 14570 bcm_pbmp_t port_pbmp; 14571 14572 /* Set the chip-wide E2ECC port mapping enable bit */ 14573 if (soc_feature(unit, soc_feature_sysport_remap)) { 14574 SOC_IF_ERROR_RETURN(READ_E2ECC_PORT_MAPPING_CONFIGr(unit, ®val)); 14575 soc_reg_field_set(unit, E2ECC_PORT_MAPPING_CONFIGr, ®val, PORT_MAPPING_ENf, 1); 14576 SOC_IF_ERROR_RETURN(WRITE_E2ECC_PORT_MAPPING_CONFIGr(unit, regval)); 14577 } 14578 14579 SOC_PBMP_CLEAR(all_pbmp); 14580 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 14581 SOC_PBMP_CLEAR(port_pbmp); 14582 SOC_PBMP_ASSIGN(port_pbmp, PBMP_PORT_ALL(unit)); 14583 14584 #ifdef BCM_KATANA2_SUPPORT 14585 if (soc_feature(unit, soc_feature_linkphy_coe) || 14586 soc_feature(unit, soc_feature_subtag_coe)) { 14587 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 14588 _bcm_kt2_subport_pbmp_update(unit, &port_pbmp); 14589 } 14590 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 14591 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 14592 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &port_pbmp)); 14593 } 14594 #endif 14595 14596 PBMP_ITER(all_pbmp, p) { 14597 /* Initialize the logical to physical port mapping */ 14598 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 14599 !SOC_IS_TD_TT(unit) && !SOC_IS_TRIUMPH3(unit) && 14600 !SOC_IS_KATANAX(unit) && !SOC_IS_GREYHOUND(unit) && 14601 !SOC_IS_GREYHOUND2(unit)) { 14602 bcm_port_t sp = p; 14603 if (soc_feature(unit, soc_feature_sysport_remap)) { 14604 BCM_XLATE_SYSPORT_P2S(unit, &sp); 14605 } 14606 _bcm_port_remap_set(unit, p, sp); 14607 } 14608 14609 /* Initialize egress block profile pointer to invalid value */ 14610 PORT_SRC_MOD_EGR_PROF_PTR(unit, p) = -1; 14611 14612 /* Program the VLAN_PROTOCOL_DATA / FP_PORT_FIELD_SEL_INDEX 14613 / PROTOCOL_PKT_INDEX pointers */ 14614 if (!IS_LB_PORT(unit, p) && !IS_TDM_PORT(unit, p)) { 14615 int value = 0; 14616 if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOLm)) { 14617 value = PORT(unit, p).vlan_prot_ptr / 14618 soc_mem_index_count(unit, VLAN_PROTOCOLm); 14619 } 14620 if ((0 != value) && 14621 (soc_mem_index_max(unit, VLAN_PROTOCOL_DATAm) > 0)) { 14622 BCM_IF_ERROR_RETURN( 14623 _bcm_esw_port_tab_set(unit, p, 14624 _BCM_CPU_TABS_ETHER, 14625 VLAN_PROTOCOL_DATA_INDEXf, 14626 BCM_PBMP_MEMBER(port_pbmp, p) ? value : 0)); 14627 } 14628 14629 if (soc_mem_field_valid(unit, PORT_TABm, 14630 FP_PORT_FIELD_SEL_INDEXf)) { 14631 BCM_IF_ERROR_RETURN( 14632 _bcm_esw_port_tab_set(unit, p, 14633 _BCM_CPU_TABS_ETHER, 14634 FP_PORT_FIELD_SEL_INDEXf, p)); 14635 } 14636 if (soc_mem_field_valid(unit, PORT_TABm, PROTOCOL_PKT_INDEXf) || 14637 soc_mem_field_valid(unit, LPORT_TABm, 14638 PROTOCOL_PKT_INDEXf)) { 14639 if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype == 14640 soc_portreg) { 14641 BCM_IF_ERROR_RETURN( 14642 _bcm_esw_port_tab_set(unit, p, 14643 _BCM_CPU_TABS_ETHER, 14644 PROTOCOL_PKT_INDEXf, 14645 p)); 14646 } else { 14647 BCM_IF_ERROR_RETURN 14648 (_bcm_prot_pkt_ctrl_add(unit, 0, 0, 14649 &profile_index)); 14650 BCM_IF_ERROR_RETURN( 14651 _bcm_esw_port_tab_set(unit, p, 14652 _BCM_CPU_TABS_ETHER, 14653 PROTOCOL_PKT_INDEXf, 14654 profile_index)); 14655 } 14656 } 14657 14658 if (soc_feature(unit, soc_feature_embedded_higig) 14659 && IS_E_PORT(unit, p)) { 14660 uint32 buffer[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ]; 14661 uint32 mask[SOC_MAX_MEM_FIELD_WORDS]; 14662 14663 sal_memset(buffer, 0, 14664 WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ)); 14665 sal_memset(mask, 0xFF, sizeof(mask)); 14666 /* coverity[overrun-call : FALSE] */ 14667 BCM_IF_ERROR_RETURN( 14668 _bcm_port_ehg_header_write(unit, p, buffer, buffer, mask, 14669 _BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ)); 14670 } 14671 } 14672 } 14673 14674 if (!SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLE_MODBASEm) && 14675 !SOC_MEM_IS_VALID(unit, SOURCE_TRUNK_MAP_MODBASEm) && 14676 SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLEm)) { 14677 BCM_IF_ERROR_RETURN(_bcm_tr2_system_tpid_init(unit)); 14678 } 14679 } 14680 #endif /* BCM_TRIUMPH2_SUPPORT */ 14681 14682 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \ 14683 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) 14684 if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) || 14685 SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 14686 SOC_IS_APACHE(unit)) && 14687 (soc_feature(unit,soc_feature_timesync_support))) { 14688 _bcm_esw_port_timesync_profile_init(unit); 14689 } 14690 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || 14691 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */ 14692 14693 #ifdef BCM_SHADOW_SUPPORT 14694 /* Static port load balancing configuration for shadow */ 14695 if (SOC_IS_SHADOW(unit)) { 14696 port_tab_entry_t ptab; 14697 14698 for (p = 0; p <= 16; p++) { 14699 /* Enable IPV4 and IPV6 */ 14700 BCM_IF_ERROR_RETURN( 14701 _bcm_esw_port_tab_set(unit, p, 14702 _BCM_CPU_TABS_ETHER, 14703 IPV4_ENABLEf, 1)); 14704 14705 BCM_IF_ERROR_RETURN( 14706 _bcm_esw_port_tab_set(unit, p, 14707 _BCM_CPU_TABS_ETHER, 14708 IPV6_ENABLEf, 1)); 14709 } 14710 14711 /* For shadow-petrab mode, configure uflow_A(xe0) and uflow_b(xe1)*/ 14712 if(soc_property_get(unit, spn_BCM88732_DEVICE_MODE, 0) && 14713 ((soc_property_get(unit, spn_BCM88732_2X40_1X40, 0)) || 14714 (soc_property_get(unit, spn_BCM88732_2X40_2X40, 0)))) { 14715 BCM_IF_ERROR_RETURN( 14716 _bcm_esw_port_tab_set(unit, 1, 14717 _BCM_CPU_TABS_ETHER, 14718 AGGREGATION_GROUP_SELECTf, 0)); 14719 14720 /* port 5 (xe1) configure uflow_b for static load balancing */ 14721 BCM_IF_ERROR_RETURN( 14722 _bcm_esw_port_tab_set(unit, 5, 14723 _BCM_CPU_TABS_ETHER, 14724 AGGREGATION_GROUP_SELECTf, 1)); 14725 14726 /* Enable SAND interop header for Interlaken ports */ 14727 for (p = 9; p <= 16; p++) { 14728 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p, 14729 _BCM_CPU_TABS_ETHER, 14730 SAND_COS_ENABLEf, 1)); 14731 } 14732 } 14733 if(soc_property_get(unit, spn_BCM88732_2X40_8X10, 0)) { 14734 sal_memset(&ptab, 0, sizeof(ptab)); 14735 /* port 1 (xe0) configure uflow_a for static load balancing */ 14736 SOC_IF_ERROR_RETURN( 14737 READ_PORT_TABm(unit, MEM_BLOCK_ANY, 1, &ptab)); 14738 soc_PORT_TABm_field32_set(unit, &ptab, AGGREGATION_GROUP_SELECTf, 0); 14739 SOC_IF_ERROR_RETURN( 14740 WRITE_PORT_TABm(unit,MEM_BLOCK_ALL, 1, &ptab)); 14741 14742 /* port 5 (xe1) configure uflow_b for static load balancing */ 14743 SOC_IF_ERROR_RETURN( 14744 READ_PORT_TABm(unit, MEM_BLOCK_ANY, 5, &ptab)); 14745 soc_PORT_TABm_field32_set(unit, &ptab, AGGREGATION_GROUP_SELECTf, 1); 14746 SOC_IF_ERROR_RETURN( 14747 WRITE_PORT_TABm(unit,MEM_BLOCK_ALL, 5, &ptab)); 14748 14749 } 14750 14751 /* By default Disable VLAN checks and enable TPID in port table */ 14752 for (p = 0; p <= 16; p++) { 14753 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p, 14754 _BCM_CPU_TABS_ETHER, 14755 DISABLE_VLAN_CHECKSf, 1)); 14756 14757 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p, 14758 _BCM_CPU_TABS_ETHER, 14759 OUTER_TPID_ENABLEf, 1)); 14760 } 14761 } 14762 #endif /* BCM_SHADOW_SUPPORT */ 14763 14764 #ifdef BCM_TRIDENT_SUPPORT 14765 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) { 14766 uint32 regval; 14767 int blk; 14768 int blk_num = -1; 14769 int bindex = 0; 14770 int tx_pbm = 0; 14771 bcm_pbmp_t all_pbmp; 14772 14773 if (SOC_IS_TRIUMPH3(unit)) { 14774 /* Clear all bits for flex port considerations */ 14775 for (blk_num = 0; blk_num < 7; blk_num++) { 14776 SOC_IF_ERROR_RETURN 14777 (WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, 0)); 14778 } 14779 } 14780 14781 SOC_PBMP_CLEAR(all_pbmp); 14782 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 14783 14784 #ifdef BCM_KATANA2_SUPPORT 14785 if (soc_feature(unit, soc_feature_linkphy_coe) || 14786 soc_feature(unit, soc_feature_subtag_coe)) { 14787 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 14788 } 14789 #endif 14790 14791 PBMP_ITER(all_pbmp, p) { 14792 if (!IS_LB_PORT(unit, p) && !IS_TDM_PORT(unit, p)) { 14793 if (soc_mem_field_valid(unit, PORT_TABm, 14794 FP_PORT_FIELD_SEL_INDEXf)) { 14795 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p, 14796 _BCM_CPU_TABS_ETHER, 14797 FP_PORT_FIELD_SEL_INDEXf, p)); 14798 } 14799 } 14800 } 14801 14802 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 14803 /* In Trident all ports are enabled to send E2ECC messages by 14804 * default. Disable E2ECC message TX here until congestion config 14805 * set enables the port. 14806 */ 14807 14808 if (soc_feature(unit, soc_feature_logical_port_num)) { 14809 /* coverity[overrun-local : FALSE] */ 14810 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[p]); 14811 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[p]); 14812 } else{ 14813 blk = SOC_PORT_BLOCK(unit, p); 14814 bindex = SOC_PORT_BINDEX(unit, p); 14815 } 14816 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 14817 if (SOC_IS_TRIDENT2X(unit)) { 14818 blk_num = SOC_INFO(unit).port_serdes[p]; 14819 } else 14820 #endif 14821 { 14822 blk_num = SOC_BLOCK_INFO(unit, blk).number; 14823 } 14824 if (SOC_IS_KATANA2(unit)) { 14825 if (!IS_HG_PORT(unit, p)) { 14826 continue; 14827 } 14828 /* In KT2 E2ECC is implemented only in blocks 6..9 */ 14829 if (blk_num >= 6) { 14830 blk_num -= 6; 14831 } else { 14832 continue; 14833 } 14834 } 14835 if (!SOC_IS_TRIUMPH3(unit) && 14836 SOC_REG_IS_VALID(unit, E2ECC_TX_ENABLE_BMPr)) { 14837 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num, 14838 ®val)); 14839 tx_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval, 14840 TX_ENABLE_BMPf); 14841 tx_pbm &= ~(1 << bindex); 14842 soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, ®val, 14843 TX_ENABLE_BMPf, tx_pbm); 14844 SOC_IF_ERROR_RETURN(WRITE_E2ECC_TX_ENABLE_BMPr(unit, 14845 blk_num, regval)); 14846 } 14847 } 14848 /* Set the chip-wide E2ECC port mapping enable bit */ 14849 if (soc_feature(unit, soc_feature_sysport_remap)) { 14850 SOC_IF_ERROR_RETURN(READ_E2ECC_PORT_MAPPING_CONFIGr(unit, ®val)); 14851 soc_reg_field_set(unit, E2ECC_PORT_MAPPING_CONFIGr, ®val, 14852 PORT_MAPPING_ENf, 1); 14853 SOC_IF_ERROR_RETURN(WRITE_E2ECC_PORT_MAPPING_CONFIGr(unit, regval)); 14854 } 14855 } 14856 #endif 14857 14858 #if defined (BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) \ 14859 || defined (BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 14860 || defined (BCM_HURRICANE2_SUPPORT) 14861 if (SOC_IS_HURRICANE (unit) || SOC_IS_TD_TT (unit) || 14862 SOC_IS_HAWKEYE (unit) || SOC_IS_SHADOW(unit) || 14863 SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || 14864 SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || 14865 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 14866 if (soc_feature (unit, soc_feature_eee)) { 14867 int mac_val = 0; 14868 _bcm_port_info_t *port_info; 14869 PBMP_ALL_ITER(unit, p) { 14870 if (!IS_LB_PORT(unit, p) && !IS_CPU_PORT (unit, p) && !IS_FAE_PORT (unit, p) && 14871 !IS_TDM_PORT(unit, p) && !IS_RDB_PORT(unit,p) && !IS_MACSEC_PORT(unit,p)) { 14872 /* EEE standard compliance Work Around: 14873 * Initialize the software state of native eee in MAC 14874 */ 14875 eee_cfg[unit][p] = 0; 14876 /* Check if MAC supports Native EEE and set the value of 14877 * eee_cfg by reading the EEE status from MAC*/ 14878 if (SOC_PORT_USE_PORTCTRL(unit, p)) { 14879 rv = bcmi_esw_portctrl_eee_enable_get(unit, p, 14880 &mac_val); 14881 14882 } else { 14883 _bcm_port_info_access(unit, p, &port_info); 14884 rv = MAC_CONTROL_GET(port_info->p_mac, unit, p, 14885 SOC_MAC_CONTROL_EEE_ENABLE, 14886 &mac_val); 14887 } 14888 if (rv != BCM_E_UNAVAIL) { 14889 eee_cfg[unit][p] = mac_val; 14890 } 14891 } 14892 } 14893 } 14894 } 14895 #endif /* (BCM_HURRICANE_SUPPORT) || (BCM_TRIDENT_SUPPORT) || (BCM_HAWKEYE_SUPPORT)*/ 14896 14897 /* 14898 * CES TDM Port initialization 14899 */ 14900 /* Set Higig/Higig2 mode */ 14901 if (!SOC_WARM_BOOT(unit)) { 14902 if (SOC_USE_PORTCTRL(unit)) { 14903 int hg_port; 14904 PBMP_HG_ITER(unit, hg_port) { 14905 BCM_IF_ERROR_RETURN 14906 (bcmi_esw_portctrl_higig_mode_set(unit, hg_port, TRUE)); 14907 } 14908 } 14909 #ifdef BCM_HIGIG2_SUPPORT 14910 if (soc_feature(unit, soc_feature_higig2)) { 14911 int hg_port; 14912 #if defined(BCM_KATANA_SUPPORT) 14913 int hl_port; 14914 14915 if (SOC_IS_KATANA(unit)) { 14916 PBMP_HL_ITER(unit, hl_port) { 14917 BCM_IF_ERROR_RETURN 14918 (_bcm_esw_port_higig2_mode_set(unit, hl_port, TRUE)); 14919 SOC_HG2_ENABLED_PORT_ADD(unit, hl_port); 14920 } 14921 } 14922 #endif 14923 PBMP_HG_ITER(unit, hg_port) { 14924 /* 14925 * Make all HG ports default to HiGig2, when 14926 * 1. spn_HIGIG2_HDR_MODE = 1. Or 14927 * 2. portmod is enabled 14928 */ 14929 if (soc_property_port_get(unit, hg_port, spn_HIGIG2_HDR_MODE, 14930 soc_feature(unit, soc_feature_no_higig_plus) ? 1 : 0) || 14931 SOC_USE_PORTCTRL(unit)) { 14932 BCM_IF_ERROR_RETURN 14933 (_bcm_esw_port_higig2_mode_set(unit, hg_port, TRUE)); 14934 SOC_HG2_ENABLED_PORT_ADD(unit, hg_port); 14935 } 14936 } 14937 } 14938 #endif /* BCM_HIGIG2_SUPPORT */ 14939 } 14940 14941 BCM_IF_ERROR_RETURN(_bcm_esw_port_mon_start(unit)); 14942 #ifdef BCM_TRIUMPH3_SUPPORT 14943 if (SOC_IS_TRIUMPH3(unit)) { 14944 BCM_IF_ERROR_RETURN 14945 (_bcm_esw_ibod_sync_recovery_start(unit, 14946 soc_property_get(unit, spn_PORTMON_INTERVAL, IBOD_SYNC_INTERVAL_MIN))); 14947 } 14948 #endif /* BCM_TRIUMPH3_SUPPORT */ 14949 /* Port translation call-back function for PHY drivers */ 14950 soc_phy_cb_xlate_port_func = _bcm_phy_cb_xlate_port; 14951 14952 #ifdef BCM_TRIUMPH2_SUPPORT 14953 if (soc_feature(unit, soc_feature_src_modid_blk_profile)) { 14954 soc_mem_t mem = SRC_MODID_EGRESSm; 14955 int mem_words; 14956 int rv; 14957 14958 if (SOC_MEM_IS_VALID(unit, mem)) { 14959 if (NULL == PORT_SRC_MOD_EGR_PROFILE(unit)) { 14960 PORT_SRC_MOD_EGR_PROFILE(unit) = 14961 sal_alloc(sizeof(soc_profile_mem_t), 14962 "SRC_MODID_EGRESS Profile Mem"); 14963 if (NULL == PORT_SRC_MOD_EGR_PROFILE(unit)) { 14964 return BCM_E_MEMORY; 14965 } 14966 soc_profile_mem_t_init(PORT_SRC_MOD_EGR_PROFILE(unit)); 14967 14968 mem_words = sizeof(src_modid_egress_entry_t) / 14969 sizeof(uint32); 14970 14971 rv = soc_profile_mem_create(unit, &mem, &mem_words, 1, 14972 PORT_SRC_MOD_EGR_PROFILE(unit)); 14973 if (rv < 0) { 14974 sal_free(PORT_SRC_MOD_EGR_PROFILE(unit)); 14975 PORT_SRC_MOD_EGR_PROFILE(unit) = NULL; 14976 return rv; 14977 } 14978 } 14979 } 14980 } 14981 #endif /* BCM_TRIUMPH2_SUPPORT */ 14982 14983 #if defined(BCM_KATANA2_SUPPORT) 14984 if (SOC_IS_KATANA2(unit)) { 14985 /* Enable EGR_ENABLEm:PRT_ENABLEf for cpu port */ 14986 LOG_VERBOSE(BSL_LS_BCM_PORT, 14987 (BSL_META_U(unit, 14988 "\nEnable EGR_ENABLEm:PRT_ENABLEf for cpu port \n"))); 14989 sal_memset(entry, 0, sizeof(egr_enable_entry_t)); 14990 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1); 14991 SOC_IF_ERROR_RETURN( 14992 WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, CMIC_PORT(unit), entry)); 14993 SOC_IF_ERROR_RETURN( 14994 WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, LB_PORT(unit), entry)); 14995 } 14996 #endif /* BCM_KATANA_SUPPORT */ 14997 14998 if (!soc_feature(unit, soc_feature_no_sw_rx_los)){ 14999 /* Get Initial SW RX LOS configuration from PHY driver */ 15000 PBMP_ITER(all_pbmp, p) { 15001 if (IS_E_PORT(unit, p)) { 15002 rv = bcm_esw_port_phy_control_get(unit, p, 15003 BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, 15004 &rx_los); 15005 if (BCM_SUCCESS(rv)) { 15006 PORT(unit, p).rx_los = rx_los; 15007 } 15008 } 15009 } 15010 } 15011 15012 /* set link delay offset */ 15013 PBMP_ITER(all_pbmp, p) { 15014 PORT(unit, p).link_delay_offset = 0; 15015 if (SOC_WARM_BOOT(unit)) { 15016 rv = bcm_esw_port_speed_get(unit, p, &p_speed); 15017 if (BCM_FAILURE(rv)) { 15018 continue; 15019 } 15020 BCM_IF_ERROR_RETURN(_bcm_esw_port_link_delay_recover(unit, p, p_speed)); 15021 } 15022 } 15023 15024 /* set port dscp map set to zero */ 15025 PBMP_ITER(all_pbmp, p) { 15026 PORT(unit, p).port_dscp_map_set = 0; 15027 } 15028 15029 #ifdef BCM_TRIDENT2_SUPPORT 15030 if (SOC_IS_TD2_TT2(unit)) { 15031 /* Get Initial SW port enable status from HW */ 15032 PBMP_ITER(all_pbmp, p) { 15033 if (IS_E_PORT(unit, p)) { 15034 rv = bcm_esw_port_enable_get(unit, p, &enable); 15035 if (BCM_SUCCESS(rv)) { 15036 PORT(unit, p).enable = enable; 15037 } 15038 } 15039 } 15040 } 15041 #endif /* BCM_TRIDENT2_SUPPORT */ 15042 15043 PBMP_PORT_ITER(unit, p) { 15044 rv = bcm_esw_port_speed_get(unit, p, &p_speed); 15045 if (BCM_FAILURE(rv)) { 15046 continue; 15047 } 15048 _bcm_esw_port_link_delay_update(unit, p, p_speed); 15049 } 15050 15051 #if defined(BCM_TRIUMPH3_SUPPORT) 15052 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 15053 rv = _bcm_port_force_forward_init(unit); 15054 if (BCM_FAILURE(rv)) { 15055 return rv; 15056 } 15057 } 15058 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/ 15059 15060 #if defined(BCM_TOMAHAWK_SUPPORT) 15061 /* TH ASF */ 15062 if (soc_feature(unit, soc_feature_asf_multimode) 15063 #ifdef BCM_WARM_BOOT_SUPPORT 15064 && !SOC_WARM_BOOT(unit) 15065 /* WB recovery happens in _bcm_esw_port_wb_recover context */ 15066 #endif /* BCM_WARM_BOOT_SUPPORT */ 15067 ) { 15068 #ifdef BCM_MAVERICK2_SUPPORT 15069 if (SOC_IS_MAVERICK2(unit)) { 15070 BCM_IF_ERROR_RETURN( 15071 _bcm_esw_mv2_asf_init(unit, _SOC_MV2_ASF_MODE_INIT)); 15072 } else 15073 #endif 15074 #ifdef BCM_TRIDENT3_SUPPORT 15075 if (SOC_IS_TRIDENT3X(unit)) { 15076 BCM_IF_ERROR_RETURN( 15077 _bcm_esw_td3_asf_init(unit, _SOC_TD3_ASF_MODE_INIT)); 15078 } else 15079 #endif 15080 { 15081 BCM_IF_ERROR_RETURN( 15082 _bcm_esw_asf_init(unit, _SOC_TH_ASF_MODE_INIT)); 15083 } 15084 } 15085 #endif 15086 15087 #if defined (BCM_EP_REDIRECT_VERSION_2) 15088 /* Mark the RDB port as loopback mode */ 15089 if (soc_feature(unit, soc_feature_ep_redirect_v2)) { 15090 SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, PORT_TABm, 15091 BCMI_EP_REDIRECT_PORT, PORT_TYPEf, 2)); 15092 } 15093 #endif 15094 15095 #ifdef BCM_PREEMPTION_SUPPORT 15096 if (soc_feature(unit, soc_feature_preemption_cnt)) { 15097 BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_init(unit)); 15098 } 15099 #endif 15100 15101 #if defined(BCM_GREYHOUND_SUPPORT) 15102 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 15103 /* 15104 * The ref_cnt of system-wise treat packet priority as dot1p priority 15105 * for different packet types or port controls. 15106 */ 15107 BCM_IF_ERROR_RETURN( 15108 bcmi_esw_port_treat_pktpri_as_dot1p_init(unit)); 15109 } 15110 #endif /* BCM_GREYHOUND_SUPPORT */ 15111 15112 if (SOC_WARM_BOOT(unit)) { 15113 return (_bcm_esw_port_wb_recover(unit)); 15114 } 15115 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \ 15116 defined(BCM_APACHE_SUPPORT) 15117 else { 15118 if(SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT2(unit) || SOC_IS_APACHE(unit)) { 15119 /* 15120 * Hardcoding the MMU_INTFI_ST_TRANS_TBL so the 15121 * congestion data is written as it is 15122 * in FC_ST_TABLE, This we are doing so that 15123 * congestion data is updated as it is how 15124 * it recevied 15125 */ 15126 for (index=0 ; index < soc_mem_index_count(unit, 15127 MMU_INTFI_ST_TRANS_TBLm); index++) { 15128 SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm( 15129 unit, MEM_BLOCK_ALL,index, 15130 &st_trans_entry)); 15131 soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm, 15132 &st_trans_entry, FC_ST_XLATEf, 15133 index % (SOC_IS_KATANA2(unit) ? 256 : 16)); 15134 SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm( 15135 unit, MEM_BLOCK_ALL, index, 15136 &st_trans_entry)); 15137 } 15138 } 15139 } 15140 #endif 15141 #if defined(BCM_GREYHOUND2_SUPPORT) 15142 if (SOC_IS_GREYHOUND2(unit)) { 15143 if (soc_feature(unit, soc_feature_e2efc)) { 15144 bcmi_gh2_port_e2efc_remote_port_init(unit); 15145 } 15146 } 15147 #endif /* BCM_GHREYHOUND2 */ 15148 return (_bcm_esw_port_wb_alloc(unit)); 15149 } 15150 15151 /* 15152 * Function: 15153 * bcm_port_clear 15154 * Purpose: 15155 * Initialize the PORT interface layer for the specified SOC device 15156 * without resetting stacking ports. 15157 * Parameters: 15158 * unit - StrataSwitch unit number. 15159 * Returns: 15160 * BCM_E_NONE - success (or already initialized) 15161 * BCM_E_INTERNAL- failed to write PTABLE entries 15162 * BCM_E_MEMORY - failed to allocate required memory. 15163 * Notes: 15164 * By default ports come up enabled. They can be made to come up disabled 15165 * at startup by a compile-time application policy flag in your Make.local 15166 * A call to bcm_port_clear should exhibit similar behavior for 15167 * non-stacking ethernet ports 15168 * PTABLE initialized. 15169 */ 15170 15171 int 15172 bcm_esw_port_clear(int unit) 15173 { 15174 bcm_port_config_t port_config; 15175 bcm_pbmp_t reset_ports; 15176 bcm_port_t port; 15177 int rv, port_enable; 15178 15179 PORT_INIT(unit); 15180 15181 BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &port_config)); 15182 15183 /* Clear all non-stacking ethernet ports */ 15184 BCM_PBMP_ASSIGN(reset_ports, port_config.e); 15185 BCM_PBMP_REMOVE(reset_ports, SOC_PBMP_STACK_CURRENT(unit)); 15186 15187 PBMP_ITER(reset_ports, port) { 15188 LOG_VERBOSE(BSL_LS_BCM_PORT, 15189 (BSL_META_U(unit, 15190 "bcm_port_clear: unit %d port %s\n"), 15191 unit, SOC_PORT_NAME(unit, port))); 15192 15193 PORT_LOCK(unit); 15194 if ((rv = _bcm_port_mode_setup(unit, port, TRUE)) < 0) { 15195 LOG_WARN(BSL_LS_BCM_PORT, 15196 (BSL_META_U(unit, 15197 "Warning: Port %s: " 15198 "Failed to set initial mode: %s\n"), 15199 SOC_PORT_NAME(unit, port), bcm_errmsg(rv))); 15200 } 15201 PORT_UNLOCK(unit); 15202 15203 #ifdef BCM_RCPU_SUPPORT 15204 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 15205 /* Do not enable/disable rcpu port. */ 15206 continue; 15207 } 15208 #endif /* BCM_RCPU_SUPPORT */ 15209 15210 /* 15211 * A compile-time application policy may prefer to disable 15212 * ports at startup. The same behavior should be observed 15213 * when bcm_port_clear gets called. 15214 */ 15215 15216 #ifdef BCM_PORT_DEFAULT_DISABLE 15217 port_enable = FALSE; 15218 #else 15219 port_enable = TRUE; 15220 #endif /* BCM_PORT_DEFAULT_DISABLE */ 15221 15222 15223 if ((rv = bcm_esw_port_enable_set(unit, port, port_enable)) < 0) { 15224 LOG_WARN(BSL_LS_BCM_PORT, 15225 (BSL_META_U(unit, 15226 "Warning: Port %s: " 15227 "Failed to %s port: %s\n"), 15228 SOC_PORT_NAME(unit, port),(port_enable) ?\ 15229 "enable" : "disable" ,bcm_errmsg(rv))); 15230 } 15231 15232 } 15233 15234 return BCM_E_NONE; 15235 } 15236 15237 /* 15238 * Function: 15239 * _bcm_port_phy_probe 15240 * Purpose: 15241 * Probe the phy and set up the phy of the indicated port 15242 * Parameters: 15243 * unit - StrataSwitch unit number. 15244 * port - Port to probe 15245 * okay - Output parameter indicates port can be enabled. 15246 * Returns: 15247 * BCM_E_NONE 15248 * BCM_E_INTERNAL - internal error. 15249 * Notes: 15250 * If error is returned, the port should not be enabled. 15251 */ 15252 int 15253 _bcm_port_phy_probe(int unit, bcm_port_t port, int *okay) 15254 { 15255 int rv; 15256 bcm_pbmp_t pbmp; 15257 bcm_pbmp_t okay_pbmp; 15258 15259 /* Check for PortMod */ 15260 if(SOC_PORT_USE_PORTCTRL(unit, port)) { 15261 return BCM_E_UNAVAIL; 15262 } 15263 15264 *okay = FALSE; 15265 15266 LOG_VERBOSE(BSL_LS_BCM_PORT, 15267 (BSL_META_U(unit, 15268 "Init port %d PHY...\n"), port)); 15269 15270 BCM_PBMP_CLEAR(okay_pbmp); 15271 BCM_PBMP_CLEAR(pbmp); 15272 BCM_PBMP_PORT_SET(pbmp, port); 15273 15274 rv = soc_phyctrl_pbm_probe_init(unit,pbmp,&okay_pbmp); 15275 if (rv != BCM_E_NONE) { 15276 LOG_ERROR(BSL_LS_BCM_PORT, \ 15277 (BSL_META_U(unit, \ 15278 "Error unit %d:\ 15279 Failed port init probe: %s\n"), 15280 unit, bcm_errmsg(rv))); 15281 return rv; 15282 } 15283 15284 if (!SOC_WARM_BOOT(unit)) { 15285 /* Probe function should leave port disabled */ 15286 if ((rv = soc_phyctrl_enable_set(unit, port, 0)) < 0) { 15287 return rv; 15288 } 15289 } 15290 15291 *okay = TRUE; 15292 15293 return BCM_E_NONE; 15294 } 15295 15296 /* 15297 * Function: 15298 * _bcm_port_mac_init 15299 * Purpose: 15300 * Set up the mac of the indicated port 15301 * Parameters: 15302 * unit - StrataSwitch unit number. 15303 * port - Port to setup 15304 * okay - Output parameter indicates port can be enabled. 15305 * Returns: 15306 * BCM_E_NONE 15307 * BCM_E_INTERNAL - internal error. 15308 * Notes: 15309 * If error is returned, the port should not be enabled. 15310 */ 15311 int 15312 _bcm_port_mac_init(int unit, bcm_port_t port, int *okay) 15313 { 15314 int rv; 15315 mac_driver_t *macd; 15316 15317 /* Check for PortMod */ 15318 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 15319 return BCM_E_UNAVAIL; 15320 } 15321 15322 *okay = FALSE; 15323 15324 LOG_VERBOSE(BSL_LS_BCM_PORT, 15325 (BSL_META_U(unit, 15326 "Init port %d MAC...\n"), port)); 15327 15328 if ((rv = soc_mac_probe(unit, port, &macd)) < 0) { 15329 LOG_WARN(BSL_LS_BCM_PORT, 15330 (BSL_META_U(unit, 15331 "Port %s: Failed to probe MAC: %s\n"), 15332 SOC_PORT_NAME(unit, port), soc_errmsg(rv))); 15333 return rv; 15334 } 15335 15336 PORT(unit, port).p_mac = macd; 15337 15338 if (!SOC_WARM_BOOT(unit) && !SOC_IS_RELOADING(unit)) { 15339 15340 #ifdef BCM_RCPU_SUPPORT 15341 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 15342 *okay = TRUE; 15343 return BCM_E_NONE; 15344 } 15345 #endif /* BCM_RCPU_SUPPORT */ 15346 15347 if ((rv = MAC_INIT(PORT(unit, port).p_mac, unit, port)) < 0) { 15348 LOG_WARN(BSL_LS_BCM_PORT, 15349 (BSL_META_U(unit, 15350 "Port %s: Failed to initialize MAC: %s\n"), 15351 SOC_PORT_NAME(unit, port), soc_errmsg(rv))); 15352 return rv; 15353 } 15354 15355 /* Probe function should leave port disabled */ 15356 if ((rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, 0)) < 0) { 15357 return rv; 15358 } 15359 } 15360 15361 *okay = TRUE; 15362 15363 return BCM_E_NONE; 15364 } 15365 15366 /* 15367 * Function: 15368 * _bcm_port_probe 15369 * Purpose: 15370 * Probe the phy and set up the phy and mac of the indicated port 15371 * Parameters: 15372 * unit - StrataSwitch unit number. 15373 * port - Port to probe 15374 * okay - Output parameter indicates port can be enabled. 15375 * Returns: 15376 * BCM_E_NONE 15377 * BCM_E_INTERNAL - internal error. 15378 * Notes: 15379 * If error is returned, the port should not be enabled. 15380 */ 15381 15382 int 15383 _bcm_port_probe(int unit, bcm_port_t port, int *okay) 15384 { 15385 /* Check for PortMod */ 15386 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 15387 return bcmi_esw_portctrl_probe(unit, port, 0, NULL, okay); 15388 } 15389 15390 BCM_IF_ERROR_RETURN(_bcm_port_phy_probe(unit, port, okay)); 15391 15392 /* 15393 * Currently initializing MAC after PHY is required because of 15394 * phy_5690_notify_init(). 15395 */ 15396 BCM_IF_ERROR_RETURN(_bcm_port_mac_init(unit, port, okay)); 15397 15398 return BCM_E_NONE; 15399 } 15400 15401 /* 15402 * Function: 15403 * bcm_port_probe 15404 * Purpose: 15405 * Probe the PHY and set up the PHY and MAC for the specified ports. 15406 * This is purely a discovery routine and does no configuration. 15407 * Parameters: 15408 * unit - StrataSwitch unit number. 15409 * pbmp - Bitmap of ports to probe. 15410 * okay_pbmp (OUT) - Ports which were successfully probed. 15411 * Returns: 15412 * BCM_E_NONE 15413 * BCM_E_INTERNAL - internal error. 15414 * Notes: 15415 * If error is returned, the port should not be enabled. 15416 * Assumes port_init done. 15417 * Note that if a PHY is not present, the port will still probe 15418 * successfully. The default driver will be installed. 15419 */ 15420 int 15421 bcm_esw_port_probe(int unit, pbmp_t pbmp, pbmp_t *okay_pbmp) 15422 { 15423 int rv = BCM_E_NONE; 15424 bcm_port_t port; 15425 int okay; 15426 int skip_mac_reset = 0; 15427 soc_persist_t *sop; 15428 #ifdef BCM_TRIDENT_SUPPORT 15429 int port_speed; 15430 soc_port_ability_t mac_ability; 15431 #endif 15432 pbmp_t pbmp_portmod; 15433 pbmp_t pbmp_legacy; 15434 pbmp_t okay_pbmp_portmod; 15435 pbmp_t okay_pbmp_legacy; 15436 15437 SOC_PBMP_CLEAR(*okay_pbmp); 15438 15439 PORT_INIT(unit); 15440 PORT_LOCK(unit); 15441 15442 SOC_PBMP_CLEAR(pbmp_portmod); 15443 SOC_PBMP_CLEAR(pbmp_legacy); 15444 SOC_PBMP_CLEAR(okay_pbmp_portmod); 15445 SOC_PBMP_CLEAR(okay_pbmp_legacy); 15446 if (SOC_USE_PORTCTRL(unit)) { 15447 #ifdef BCM_HURRICANE4_SUPPORT 15448 if (SOC_IS_HURRICANE4(unit)) { 15449 PBMP_ITER(pbmp, port) { 15450 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 15451 SOC_PBMP_PORT_ADD(pbmp_portmod, port); 15452 } else { 15453 SOC_PBMP_PORT_ADD(pbmp_legacy, port); 15454 } 15455 } 15456 } else 15457 #endif 15458 { 15459 SOC_PBMP_ASSIGN(pbmp_portmod, pbmp); 15460 } 15461 } else { 15462 SOC_PBMP_ASSIGN(pbmp_legacy, pbmp); 15463 } 15464 15465 #ifdef BCM_TOMAHAWK2_SUPPORT 15466 if (SOC_IS_TOMAHAWK2(unit)) { 15467 rv = bcmi_th2_tsc_xgxs_reset(unit, pbmp); 15468 if (SOC_FAILURE(rv)) { 15469 PORT_UNLOCK(unit); 15470 return (rv); 15471 } 15472 } else 15473 #endif /* BCM_TOMAHAWK2_SUPPORT */ 15474 { 15475 #ifdef BCM_TRIDENT2_SUPPORT 15476 if (SOC_IS_TD2_TT2(unit)) { 15477 soc_info_t *si; 15478 uint32 tsc_map, reset_tsc_map; 15479 int tsc, ports[32]; 15480 15481 si = &SOC_INFO(unit); 15482 /* Construct tsc_map covered by the specified pbmp */ 15483 tsc_map = 0; 15484 PBMP_ITER(pbmp, port) { 15485 tsc = si->port_serdes[port]; 15486 if (tsc != -1) { 15487 tsc_map |= 1 << tsc; 15488 } 15489 } 15490 15491 reset_tsc_map = 0; 15492 PBMP_PORT_ITER(unit, port) { 15493 tsc = si->port_serdes[port]; 15494 #ifdef BCM_HURRICANE4_SUPPORT 15495 /* No TSC for EGPHY */ 15496 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) { 15497 continue; 15498 } 15499 #endif 15500 if (tsc_map & (1 << tsc)) { 15501 if (PORT(unit, port).flags & _PORT_INFO_PROBE_RESET_SERDES) { 15502 PORT(unit, port).flags &= ~_PORT_INFO_PROBE_RESET_SERDES; 15503 reset_tsc_map |= 1 << tsc; 15504 ports[tsc] = port; 15505 } 15506 } 15507 } 15508 for (tsc = 0; tsc < 32; tsc++) { 15509 if (reset_tsc_map & (1 << tsc)) { 15510 rv = soc_tsc_xgxs_reset(unit, ports[tsc], 0); 15511 if (SOC_FAILURE(rv)) { 15512 PORT_UNLOCK(unit); 15513 return (rv); 15514 } 15515 } 15516 } 15517 } 15518 #endif /* BCM_TRIDENT2_SUPPORT */ 15519 } 15520 #if defined(BCM_SABER2_SUPPORT) 15521 /* If OAMP is enabled by default, skip the port init for oamp port */ 15522 if(SOC_IS_SABER2(unit)) { 15523 int oamp_enable; 15524 (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable); 15525 15526 if (soc_feature(unit, soc_feature_sat) && 15527 ((!SOC_WARM_BOOT(unit) && 15528 soc_property_get(unit, spn_SAT_ENABLE, 0)) || 15529 (SOC_WARM_BOOT(unit) && (oamp_enable == TRUE)))) { 15530 SOC_PBMP_PORT_REMOVE(pbmp, _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER); 15531 SOC_PBMP_PORT_REMOVE(*okay_pbmp, 15532 _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER); 15533 } 15534 } 15535 #endif 15536 /* Check for PortMod */ 15537 if (SOC_USE_PORTCTRL(unit) && SOC_PBMP_NOT_NULL(pbmp_portmod)) { 15538 rv = bcmi_esw_portctrl_probe_pbmp(unit, pbmp_portmod, &okay_pbmp_portmod); 15539 SOC_PBMP_OR((*okay_pbmp), okay_pbmp_portmod); 15540 if (SOC_FAILURE(rv) || SOC_PBMP_IS_NULL(pbmp_legacy)) { 15541 PORT_UNLOCK(unit); 15542 return (rv); 15543 } 15544 } 15545 15546 rv = soc_phyctrl_pbm_probe_init(unit,pbmp_legacy,&okay_pbmp_legacy); 15547 if (!SOC_WARM_BOOT(unit)) { 15548 PBMP_ITER(okay_pbmp_legacy, port) { 15549 /* Probe function should leave port disabled */ 15550 if ((rv = soc_phyctrl_enable_set(unit, port, 0)) < 0) { 15551 break; 15552 } 15553 } 15554 } 15555 if (soc_property_get(unit, spn_SAME_SPEED_INTF_DO_NOT_OVERWRITE, 15556 (SAL_BOOT_BCMSIM || SAL_BOOT_XGSSIM))) { 15557 PBMP_ITER(okay_pbmp_legacy, port) { 15558 if ((rv = bcm_esw_port_interface_get(unit, port, &(PORT(unit, port).intf))) < 0) { 15559 PORT(unit, port).intf = 0; 15560 continue; 15561 } 15562 } 15563 } 15564 15565 if (SOC_IS_GREYHOUND(unit) || SOC_IS_SABER2(unit) || 15566 SOC_IS_TOMAHAWKX(unit) || SOC_IS_APACHE(unit) || 15567 SOC_IS_HURRICANE4(unit)) { 15568 /* XLPORT_MAC_CONTROLr.XMAC0_RESETf has been toggled duirng soc_reset */ 15569 skip_mac_reset = 1; 15570 } 15571 15572 if (SOC_REG_IS_VALID(unit, GPORT_UMAC_CONTROLr)) { 15573 int blk; 15574 uint32 rval; 15575 pbmp_t block_pbmp; 15576 int port_blk_index; 15577 int i; 15578 15579 SOC_BLOCK_ITER(unit, blk, SOC_BLK_GPORT) { 15580 rval = 0; 15581 BCM_PBMP_ASSIGN(block_pbmp, SOC_BLOCK_BITMAP(unit, blk)); 15582 BCM_PBMP_AND(block_pbmp, pbmp); 15583 if (BCM_PBMP_IS_NULL(block_pbmp)) { 15584 continue; 15585 } 15586 15587 /* get the port number */ 15588 SOC_PBMP_ITER(block_pbmp, i) 15589 { 15590 /* get the index of the port in blk*/ 15591 port_blk_index = SOC_PORT_BLOCK_INDEX(unit, i); 15592 rval |= 1 << port_blk_index; 15593 } 15594 15595 port = SOC_BLOCK_PORT(unit, blk); 15596 /* just Write.. No need for RMW as no other field is there.. */ 15597 /* (void)READ_GPORT_UMAC_CONTROLr(unit, port, &rval); */ 15598 /* Set UMAC0_RESETf..UMAC7_RESETf */ 15599 #ifdef BCM_RCPU_SUPPORT 15600 if (SOC_IS_RCPU_ONLY(unit) && 15601 SOC_PORT_VALID(unit, RCPU_PORT(unit)) && 15602 BCM_PBMP_MEMBER(block_pbmp, RCPU_PORT(unit))) { 15603 rval &= ~ (1 << SOC_PORT_BLOCK_INDEX(unit, RCPU_PORT(unit))); 15604 } 15605 #endif /* BCM_RCPU_SUPPORT */ 15606 (void)WRITE_GPORT_UMAC_CONTROLr(unit, port, rval); 15607 sal_udelay(10); 15608 rval = 0; /* Reset UMAC0_RESETf..UMAC7_RESETf */ 15609 (void)WRITE_GPORT_UMAC_CONTROLr(unit, port, rval); 15610 } 15611 } 15612 15613 if (SOC_REG_IS_VALID(unit, XLPORT_MAC_CONTROLr) && !skip_mac_reset) { 15614 int blk, port; 15615 15616 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 15617 port = SOC_BLOCK_PORT(unit, blk); 15618 if (port == -1) { 15619 continue; 15620 } 15621 15622 if (SOC_INFO(unit).port_speed_max[port] >= 100000) { 15623 continue; 15624 } 15625 15626 /* Reset the entire block only if it is called from port init */ 15627 if (PORT(unit, port).p_mac != NULL) { 15628 continue; 15629 } 15630 15631 #ifdef BCM_RCPU_SUPPORT 15632 if (SOC_IS_RCPU_ONLY(unit) && 15633 SOC_PORT_VALID(unit, RCPU_PORT(unit)) && 15634 BCM_PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), RCPU_PORT(unit))) { 15635 continue; 15636 } 15637 #endif /* BCM_RCPU_SUPPORT */ 15638 15639 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15640 (soc_reg_field32_modify(unit, XLPORT_MAC_CONTROLr, port, 15641 XMAC0_RESETf, 1)); 15642 sal_udelay(10); 15643 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15644 (soc_reg_field32_modify(unit, XLPORT_MAC_CONTROLr, port, 15645 XMAC0_RESETf, 0)); 15646 if (soc_feature (unit, soc_feature_xlmac_timestamp_disable)) { 15647 if (soc_reg_field_valid(unit, XLPORT_MAC_CONTROLr, XLMAC_TS_DISABLEf)) { 15648 /* Disable MAC timestamp by default */ 15649 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15650 (soc_reg_field32_modify(unit, XLPORT_MAC_CONTROLr, port, 15651 XLMAC_TS_DISABLEf, 1)); 15652 } 15653 } 15654 } 15655 } 15656 15657 if (SOC_REG_IS_VALID(unit, GPORT_UMAC_CONTROLr)) { 15658 int blk, port; 15659 15660 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CPORT) { 15661 port = SOC_BLOCK_PORT(unit, blk); 15662 if (port == -1) { 15663 continue; 15664 } 15665 15666 if (SOC_INFO(unit).port_speed_max[port] < 100000) { 15667 continue; 15668 } 15669 15670 /* Reset the entire block only if it is called from port init */ 15671 if (PORT(unit, port).p_mac != NULL) { 15672 continue; 15673 } 15674 15675 #ifdef BCM_RCPU_SUPPORT 15676 if (SOC_IS_RCPU_ONLY(unit) && 15677 SOC_PORT_VALID(unit, RCPU_PORT(unit)) && 15678 BCM_PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), RCPU_PORT(unit))) { 15679 continue; 15680 } 15681 #endif /* BCM_RCPU_SUPPORT */ 15682 15683 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15684 (soc_reg_field32_modify(unit, CPORT_MAC_CONTROLr, port, 15685 CMAC_RESETf, 1)); 15686 if (SOC_REG_IS_VALID(unit, CPORT_SOFT_RESETr)) { 15687 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15688 (soc_reg_field32_modify(unit, CPORT_SOFT_RESETr, port, 15689 CPORT_COREf, 1)); 15690 } 15691 sal_udelay(10); 15692 if (SOC_REG_IS_VALID(unit, CPORT_SOFT_RESETr)) { 15693 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15694 (soc_reg_field32_modify(unit, CPORT_SOFT_RESETr, port, 15695 CPORT_COREf, 0)); 15696 } 15697 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15698 (soc_reg_field32_modify(unit, CPORT_MAC_CONTROLr, port, 15699 CMAC_RESETf, 0)); 15700 } 15701 } 15702 15703 if (SOC_REG_IS_VALID(unit, XLPORT_XMAC_CONTROLr)) { 15704 int blk; 15705 uint32 rval; 15706 pbmp_t block_pbmp; 15707 15708 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 15709 BCM_PBMP_ASSIGN(block_pbmp, SOC_BLOCK_BITMAP(unit, blk)); 15710 BCM_PBMP_AND(block_pbmp, pbmp); 15711 if (BCM_PBMP_IS_NULL(block_pbmp)) { 15712 continue; 15713 } 15714 15715 port = SOC_BLOCK_PORT(unit, blk); 15716 15717 /* Reset the entire block only if it is called from port init */ 15718 if (PORT(unit, port).p_mac != NULL) { 15719 continue; 15720 } 15721 15722 #ifdef BCM_RCPU_SUPPORT 15723 if (SOC_IS_RCPU_ONLY(unit) && 15724 SOC_PORT_VALID(unit, RCPU_PORT(unit)) && 15725 BCM_PBMP_MEMBER(block_pbmp, RCPU_PORT(unit))) { 15726 continue; 15727 } 15728 #endif /* BCM_RCPU_SUPPORT */ 15729 15730 (void)READ_XLPORT_XMAC_CONTROLr(unit, port, &rval); 15731 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 15732 1); 15733 (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval); 15734 sal_udelay(10); 15735 15736 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 15737 0); 15738 (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval); 15739 } 15740 } 15741 #ifdef BCM_SHADOW_SUPPORT 15742 /* Interlaken need to be taken out of reset after PHY is initialized */ 15743 if (SOC_IS_SHADOW(unit)) { 15744 int active_il = 0; 15745 uint32 rval; 15746 15747 if (soc_property_get(unit, spn_BCM88732_2X40_1X40, 0) || 15748 soc_property_get(unit, spn_BCM88732_8X10_1X40, 0)) { 15749 active_il = 1; 15750 } else { 15751 if (soc_property_get(unit, spn_BCM88732_1X40_4X10, 0) || 15752 soc_property_get(unit, spn_BCM88732_4X10_4X10, 0) || 15753 soc_property_get(unit, spn_BCM88732_2X40_2X40, 0) || 15754 soc_property_get(unit, spn_BCM88732_2X40_8X12, 0) || 15755 soc_property_get(unit, spn_BCM88732_8X10_8X12, 0) || 15756 soc_property_get(unit, spn_BCM88732_2X40_8X10, 0) || 15757 soc_property_get(unit, spn_BCM88732_8X10_8X10, 0) || 15758 soc_property_get(unit, spn_BCM88732_8X10_4X12, 0) || 15759 soc_property_get(unit, spn_BCM88732_8X10_2X12, 0) || 15760 soc_property_get(unit, spn_BCM88732_1X40_4X10_8X12, 0) || 15761 soc_property_get(unit, spn_BCM88732_4X10_1X40_8X12, 0) || 15762 soc_property_get(unit, spn_BCM88732_6X10_2X12, 0)) { 15763 active_il = 0; 15764 } else { 15765 active_il = 2; 15766 } 15767 } 15768 if (active_il) { 15769 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15770 (READ_IL_GLOBAL_CONTROLr(unit, 9, &rval)); 15771 soc_reg_field_set(unit, IL_GLOBAL_CONTROLr, &rval, SOFT_RESETf, 0); 15772 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15773 (WRITE_IL_GLOBAL_CONTROLr(unit, 9, rval)); 15774 } 15775 if (active_il == 2) { 15776 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15777 (READ_IL_GLOBAL_CONTROLr(unit, 13, &rval)); 15778 soc_reg_field_set(unit, IL_GLOBAL_CONTROLr, &rval, SOFT_RESETf, 0); 15779 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15780 (WRITE_IL_GLOBAL_CONTROLr(unit, 13, rval)); 15781 } 15782 } 15783 #endif /* BCM_SHADOW_SUPPORT */ 15784 15785 if (SOC_REG_IS_VALID(unit, XPORT_XMAC_CONTROLr)) { 15786 int blk; 15787 uint32 rval; 15788 pbmp_t block_pbmp; 15789 15790 SOC_BLOCK_ITER(unit, blk, SOC_BLK_MXQPORT) { 15791 BCM_PBMP_ASSIGN(block_pbmp, SOC_BLOCK_BITMAP(unit, blk)); 15792 BCM_PBMP_AND(block_pbmp, pbmp); 15793 if (BCM_PBMP_IS_NULL(block_pbmp)) { 15794 continue; 15795 } 15796 15797 port = SOC_BLOCK_PORT(unit, blk); 15798 15799 /* Reset the entire block only if it is called from port init */ 15800 if (PORT(unit, port).p_mac != NULL) { 15801 continue; 15802 } 15803 15804 #ifdef BCM_RCPU_SUPPORT 15805 if (SOC_IS_RCPU_ONLY(unit) && 15806 SOC_PORT_VALID(unit, RCPU_PORT(unit)) && 15807 BCM_PBMP_MEMBER(block_pbmp, RCPU_PORT(unit))) { 15808 continue; 15809 } 15810 #endif /* BCM_RCPU_SUPPORT */ 15811 15812 (void)READ_XPORT_XMAC_CONTROLr(unit, port, &rval); 15813 soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 15814 1); 15815 (void)WRITE_XPORT_XMAC_CONTROLr(unit, port, rval); 15816 sal_udelay(10); 15817 15818 soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 15819 0); 15820 (void)WRITE_XPORT_XMAC_CONTROLr(unit, port, rval); 15821 } 15822 } 15823 15824 #ifdef BCM_TRIUMPH3_SUPPORT 15825 if (SOC_IS_TRIUMPH3(unit)) { 15826 uint8 rev_id; 15827 uint16 dev_id; 15828 soc_info_t *si; 15829 soc_port_t port; 15830 int phy, lane, blk, block_has_ports, high_speed_port; 15831 uint32 rval; 15832 15833 si = &SOC_INFO(unit); 15834 soc_cm_get_id(unit, &dev_id, &rev_id); 15835 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) { 15836 block_has_ports = FALSE; 15837 high_speed_port = -1; 15838 for (phy = 0; phy < _SOC_TR3_PHY_PER_PORT_BLOCK; phy++) { 15839 for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) { 15840 port = si->port_p2l_mapping[si->blk_fpp[blk] + 15841 ((phy * _SOC_TR3_LANES_PER_PHY) + lane)]; 15842 /* coverity[overrun-local : FALSE] */ 15843 if (SOC_PORT_VALID(unit, port) && 15844 si->port_speed_max[port] >= 100000) { 15845 /* Save the 100G+ speed port becuase we must 15846 * init the other two PHYs, even though they don't 15847 * match a valid port. */ 15848 high_speed_port = port; 15849 } else if (high_speed_port >= 0) { 15850 port = high_speed_port; 15851 } 15852 if (SOC_PORT_VALID(unit, port)) { 15853 block_has_ports |= 1 << phy; 15854 break; /* Only need to reset PHY once */ 15855 } 15856 } 15857 } 15858 if (!block_has_ports) { 15859 continue; /* All ports disabled */ 15860 } 15861 port = SOC_BLOCK_PORT(unit, blk); 15862 15863 /* Reset only when called from port init */ 15864 if (PORT(unit, port).p_mac != NULL) { 15865 continue; 15866 } 15867 15868 rv = READ_PORT_MAC_CONTROLr(unit, port, &rval); 15869 if (SOC_FAILURE(rv)) { 15870 PORT_UNLOCK(unit); 15871 return (rv); 15872 } 15873 if ((soc_feature(unit, soc_feature_cmac)) && (high_speed_port >= 0)) { 15874 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15875 CMAC_RESETf, 1); 15876 } 15877 if (block_has_ports & 1) { 15878 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15879 XMAC0_RESETf, 1); 15880 } 15881 if (block_has_ports & 2) { 15882 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15883 XMAC1_RESETf, 1); 15884 } 15885 if (block_has_ports & 4) { 15886 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15887 XMAC2_RESETf, 1); 15888 } 15889 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 15890 if (SOC_FAILURE(rv)) { 15891 PORT_UNLOCK(unit); 15892 return (rv); 15893 } 15894 15895 sal_udelay(10); 15896 if ((soc_feature(unit, soc_feature_cmac)) && (high_speed_port >= 0)) { 15897 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15898 CMAC_RESETf, 0); 15899 } 15900 if (block_has_ports & 1) { 15901 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15902 XMAC0_RESETf, 0); 15903 } 15904 if (block_has_ports & 2) { 15905 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15906 XMAC1_RESETf, 0); 15907 } 15908 if (block_has_ports & 4) { 15909 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15910 XMAC2_RESETf, 0); 15911 } 15912 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 15913 if (SOC_FAILURE(rv)) { 15914 PORT_UNLOCK(unit); 15915 return (rv); 15916 } 15917 } 15918 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XTPORT) { 15919 block_has_ports = FALSE; 15920 for (phy = 0; phy < _SOC_TR3_PHY_PER_PORT_BLOCK; phy++) { 15921 for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) { 15922 port = si->port_p2l_mapping[si->blk_fpp[blk] + 15923 ((phy * _SOC_TR3_LANES_PER_PHY) + lane)]; 15924 if (SOC_PORT_VALID(unit, port)) { 15925 block_has_ports |= 1 << phy; 15926 break; /* Only need to reset PHY once */ 15927 } 15928 } 15929 } 15930 if (!block_has_ports) { 15931 continue; /* All ports disabled */ 15932 } 15933 port = SOC_BLOCK_PORT(unit, blk); 15934 15935 /* Reset only when called from port init */ 15936 if (PORT(unit, port).p_mac != NULL) { 15937 continue; 15938 } 15939 15940 rv = READ_PORT_MAC_CONTROLr(unit, port, &rval); 15941 if (SOC_FAILURE(rv)) { 15942 PORT_UNLOCK(unit); 15943 return (rv); 15944 } 15945 if (block_has_ports & 1) { 15946 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15947 XMAC0_RESETf, 1); 15948 } 15949 if (block_has_ports & 2) { 15950 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15951 XMAC1_RESETf, 1); 15952 } 15953 if (block_has_ports & 4) { 15954 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15955 XMAC2_RESETf, 1); 15956 } 15957 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 15958 if (SOC_FAILURE(rv)) { 15959 PORT_UNLOCK(unit); 15960 return (rv); 15961 } 15962 sal_udelay(10); 15963 if (block_has_ports & 1) { 15964 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15965 XMAC0_RESETf, 0); 15966 } 15967 if (block_has_ports & 2) { 15968 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15969 XMAC1_RESETf, 0); 15970 } 15971 if (block_has_ports & 4) { 15972 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15973 XMAC2_RESETf, 0); 15974 } 15975 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 15976 if (SOC_FAILURE(rv)) { 15977 PORT_UNLOCK(unit); 15978 return (rv); 15979 } 15980 } 15981 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 15982 block_has_ports = FALSE; 15983 /* Only one PHY per XLPORT */ 15984 for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) { 15985 port = si->port_p2l_mapping[si->blk_fpp[blk] + lane]; 15986 if (SOC_PORT_VALID(unit, port)) { 15987 block_has_ports = TRUE; 15988 break; 15989 } 15990 } 15991 if (!block_has_ports) { 15992 continue; /* All ports disabled */ 15993 } 15994 port = SOC_BLOCK_PORT(unit, blk); 15995 15996 /* Reset only when called from port init */ 15997 if (PORT(unit, port).p_mac != NULL) { 15998 continue; 15999 } 16000 16001 rv = READ_PORT_MAC_CONTROLr(unit, port, &rval); 16002 if (SOC_FAILURE(rv)) { 16003 PORT_UNLOCK(unit); 16004 return (rv); 16005 } 16006 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 16007 XMAC0_RESETf, 1); 16008 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 16009 if (SOC_FAILURE(rv)) { 16010 PORT_UNLOCK(unit); 16011 return (rv); 16012 } 16013 sal_udelay(10); 16014 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 16015 XMAC0_RESETf, 0); 16016 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 16017 if (SOC_FAILURE(rv)) { 16018 PORT_UNLOCK(unit); 16019 return (rv); 16020 } 16021 } 16022 #ifdef BCM_HELIX4_SUPPORT 16023 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XWPORT) { 16024 block_has_ports = FALSE; 16025 /* Only one PHY per XWPORT */ 16026 for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) { 16027 port = si->port_p2l_mapping[si->blk_fpp[blk] + lane]; 16028 if (SOC_PORT_VALID(unit, port)) { 16029 block_has_ports = TRUE; 16030 break; 16031 } 16032 } 16033 if (!block_has_ports) { 16034 continue; /* All ports disabled */ 16035 } 16036 port = SOC_BLOCK_PORT(unit, blk); 16037 16038 /* Reset only when called from port init */ 16039 if (PORT(unit, port).p_mac != NULL) { 16040 continue; 16041 } 16042 16043 rv = READ_PORT_MAC_CONTROLr(unit, port, &rval); 16044 if (SOC_FAILURE(rv)) { 16045 PORT_UNLOCK(unit); 16046 return (rv); 16047 } 16048 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 16049 XMAC0_RESETf, 1); 16050 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 16051 if (SOC_FAILURE(rv)) { 16052 PORT_UNLOCK(unit); 16053 return (rv); 16054 } 16055 sal_udelay(10); 16056 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 16057 XMAC0_RESETf, 0); 16058 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 16059 if (SOC_FAILURE(rv)) { 16060 PORT_UNLOCK(unit); 16061 return (rv); 16062 } 16063 } 16064 #endif /* BCM_HELIX4_SUPPORT */ 16065 } 16066 #endif /* BCM_TRIUMPH3_SUPPORT */ 16067 16068 PBMP_ITER(pbmp_legacy, port) { 16069 if (!(IS_TDM_PORT(unit, port)) && 16070 !SOC_PORT_USE_PORTCTRL(unit, port)) { 16071 rv = _bcm_port_mac_init(unit, port, &okay); 16072 16073 if (!okay) { 16074 SOC_PBMP_PORT_REMOVE(okay_pbmp_legacy, port); 16075 #if defined(BCM_ESW_SUPPORT) 16076 soc_counter_port_pbmp_remove(unit, port); 16077 #endif 16078 } 16079 if (rv < 0) { 16080 LOG_WARN(BSL_LS_BCM_PORT, 16081 (BSL_META_U(unit, 16082 "MAC init failed on port %s\n"), 16083 SOC_PORT_NAME(unit, port))); 16084 break; 16085 } 16086 16087 #ifdef BCM_TRIDENT_SUPPORT 16088 if (SOC_IS_TD_TT(unit) && 16089 (!SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) && 16090 (!(SOC_IS_HURRICANE4(unit) && SOC_WARM_BOOT(unit)))) { 16091 soc_ipg_t *si; 16092 int ifg, duplex; 16093 16094 rv = MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &duplex); 16095 if (rv < 0) { 16096 LOG_WARN(BSL_LS_BCM_PORT, 16097 (BSL_META_U(unit, 16098 "MAC_DUPLEX_GET failed on port %s\n"), 16099 SOC_PORT_NAME(unit, port))); 16100 break; 16101 } 16102 16103 si = &SOC_PERSIST(unit)->ipg[port]; 16104 if (IS_HG_PORT(unit, port)) { 16105 ifg = si->fd_hg = SOC_AVERAGE_IPG_HG; 16106 } else { 16107 ifg = si->fd_xe = SOC_AVERAGE_IPG_IEEE; 16108 } 16109 16110 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_HURRICANE4(unit)) { 16111 port_speed = (0 != SOC_INFO(unit).port_init_speed[port]) ? 16112 SOC_INFO(unit).port_init_speed[port] : SOC_INFO(unit).port_speed_max[port]; 16113 } else if (SOC_IS_TRIDENT2(unit)) { 16114 sal_memset(&mac_ability, 0, sizeof(soc_port_ability_t)); 16115 rv = MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit, port, 16116 &mac_ability); 16117 if (rv < 0) { 16118 LOG_WARN(BSL_LS_BCM_PORT, 16119 (BSL_META_U(unit, 16120 "MAC_ABILITY_LOCAL_GET failed on port %s\n"), 16121 SOC_PORT_NAME(unit, port))); 16122 break; 16123 } 16124 port_speed = BCM_PORT_ABILITY_SPEED_MAX(mac_ability.speed_full_duplex); 16125 } else { 16126 port_speed = SOC_INFO(unit).port_speed_max[port]; 16127 } 16128 16129 rv = MAC_IFG_SET(PORT(unit, port).p_mac, unit, port, 16130 port_speed, duplex, ifg); 16131 if (rv < 0) { 16132 LOG_WARN(BSL_LS_BCM_PORT, 16133 (BSL_META_U(unit, 16134 "MAC_IFG_SET failed on port %s\n"), 16135 SOC_PORT_NAME(unit, port))); 16136 break; 16137 } 16138 } 16139 #endif 16140 #ifdef BCM_HURRICANE4_SUPPORT 16141 if (SOC_IS_HURRICANE4(unit) && (!SOC_WARM_BOOT(unit))) { 16142 rv = MAC_FRAME_MAX_SET(PORT(unit, port).p_mac, 16143 unit, port, SOC_INFO(unit).max_mtu); 16144 if (rv < 0) { 16145 LOG_WARN(BSL_LS_BCM_PORT, 16146 (BSL_META_U(unit, 16147 "MAC_FRAME_MAX_SET failed on port %s\n"), 16148 SOC_PORT_NAME(unit, port))); 16149 break; 16150 } 16151 } 16152 #endif 16153 } 16154 16155 /* This is needed for run-time probing */ 16156 sop = SOC_PERSIST(unit); 16157 if (soc_property_port_get(unit, port, spn_FCMAP_ENABLE, 0)) { 16158 SOC_PBMP_PORT_ADD(sop->lc_pbm_fc, port); 16159 } else { 16160 SOC_PBMP_PORT_REMOVE(sop->lc_pbm_fc, port); 16161 } 16162 16163 /* Check if the external phy is set in EBE/EtherRAM buffer mode */ 16164 if (soc_property_port_get(unit, port, spn_PHY_OPERATIONAL_MODE, 0) == 3) { 16165 SOC_PBMP_PORT_ADD(sop->lc_pbm_eth_buffer_mode, port); 16166 } else { 16167 SOC_PBMP_PORT_REMOVE(sop->lc_pbm_eth_buffer_mode, port); 16168 } 16169 16170 } 16171 16172 SOC_PBMP_OR((*okay_pbmp), okay_pbmp_legacy); 16173 16174 PORT_UNLOCK(unit); 16175 16176 return rv; 16177 } 16178 16179 /* 16180 * Function: 16181 * _bcm_port_detach 16182 * Purpose: 16183 * Main part of bcm_port_detach 16184 */ 16185 16186 int 16187 _bcm_port_detach(int unit, pbmp_t pbmp, pbmp_t *detached) 16188 { 16189 bcm_port_t port; 16190 int rv; 16191 soc_persist_t *sop = SOC_PERSIST(unit); 16192 16193 SOC_PBMP_CLEAR(*detached); 16194 16195 PBMP_ITER(pbmp, port) { 16196 BCM_IF_ERROR_RETURN(bcm_esw_port_stp_set(unit, port, BCM_STG_STP_DISABLE)); 16197 PORT_LOCK(unit); 16198 rv = _bcm_port_mode_setup(unit, port, FALSE); 16199 PORT_UNLOCK(unit); 16200 BCM_IF_ERROR_RETURN(rv); 16201 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port)); 16202 SOC_PBMP_PORT_ADD(*detached, port); 16203 16204 if (SOC_PBMP_MEMBER(sop->lc_pbm_fc, port)) { 16205 /* Bring down the internal PHY */ 16206 rv = bcm_esw_port_update(unit, port, FALSE); 16207 BCM_IF_ERROR_RETURN(rv); 16208 SOC_PBMP_PORT_REMOVE(sop->lc_pbm_fc, port); 16209 } 16210 } 16211 #ifdef BCM_TRIUMPH2_SUPPORT 16212 if (soc_feature(unit, soc_feature_vpd_profile)) { 16213 _bcm_tr2_port_vpd_bitmap_free(unit); 16214 } 16215 #endif 16216 return BCM_E_NONE; 16217 } 16218 16219 /* 16220 * Function: 16221 * bcm_port_detach 16222 * Purpose: 16223 * Detach a port. Set phy driver to no connection. 16224 * Parameters: 16225 * unit - StrataSwitch unit number. 16226 * pbmp - Bitmap of ports to detach. 16227 * detached (OUT) - Bitmap of ports successfully detached. 16228 * Returns: 16229 * BCM_E_NONE 16230 * BCM_E_INTERNAL - internal error. 16231 * Notes: 16232 * If a port to be detached does not appear in detached, its 16233 * state is not defined. 16234 */ 16235 16236 int 16237 bcm_esw_port_detach(int unit, pbmp_t pbmp, pbmp_t *detached) 16238 { 16239 int rv; 16240 #ifdef BROADCOM_DEBUG 16241 char pfmtp[SOC_PBMP_FMT_LEN], 16242 pfmtd[SOC_PBMP_FMT_LEN]; 16243 #endif /* BROADCOM_DEBUG */ 16244 pbmp_t pbmp_portmod; 16245 pbmp_t pbmp_legacy; 16246 pbmp_t detached_portmod; 16247 pbmp_t detached_legacy; 16248 16249 PORT_INIT(unit); 16250 16251 if (detached == NULL) { 16252 return BCM_E_PARAM; 16253 } 16254 16255 SOC_PBMP_CLEAR(pbmp_portmod); 16256 SOC_PBMP_CLEAR(pbmp_legacy); 16257 SOC_PBMP_CLEAR(detached_portmod); 16258 SOC_PBMP_CLEAR(detached_legacy); 16259 SOC_PBMP_CLEAR(*detached); 16260 16261 if (SOC_USE_PORTCTRL(unit)) { 16262 #ifdef BCM_HURRICANE4_SUPPORT 16263 if (SOC_IS_HURRICANE4(unit)) { 16264 bcm_port_t port; 16265 PBMP_ITER(pbmp, port) { 16266 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 16267 SOC_PBMP_PORT_ADD(pbmp_portmod, port); 16268 } else { 16269 SOC_PBMP_PORT_ADD(pbmp_legacy, port); 16270 } 16271 } 16272 } else 16273 #endif 16274 { 16275 SOC_PBMP_ASSIGN(pbmp_portmod, pbmp); 16276 } 16277 } else { 16278 SOC_PBMP_ASSIGN(pbmp_legacy, pbmp); 16279 } 16280 16281 if (SOC_USE_PORTCTRL(unit) && SOC_PBMP_NOT_NULL(pbmp_portmod)) { 16282 rv = bcmi_esw_portctrl_detach(unit, pbmp_portmod, &detached_portmod); 16283 SOC_PBMP_OR((*detached), detached_portmod); 16284 if (SOC_FAILURE(rv) || SOC_PBMP_IS_NULL(pbmp_legacy)) { 16285 return (rv); 16286 } 16287 } 16288 16289 PORT_LOCK(unit); 16290 rv = _bcm_port_detach(unit, pbmp_legacy, &detached_legacy); 16291 PORT_UNLOCK(unit); 16292 SOC_PBMP_OR((*detached), detached_legacy); 16293 #ifdef BROADCOM_DEBUG 16294 LOG_INFO(BSL_LS_BCM_PORT, 16295 (BSL_META_U(unit, 16296 "bcm_port_detach: u=%d pbmp=%s det=%s rv=%d\n"), 16297 unit, 16298 SOC_PBMP_FMT(pbmp, pfmtp), 16299 SOC_PBMP_FMT(*detached, pfmtd), 16300 rv)); 16301 #endif 16302 return rv; 16303 } 16304 16305 /* 16306 * Function: 16307 * bcm_port_config_get 16308 * Purpose: 16309 * Get port configuration of a device 16310 * Parameters: 16311 * unit - StrataSwitch Unit #. 16312 * config - (OUT) Structure returning configuration 16313 * Returns: 16314 * BCM_E_XXX 16315 */ 16316 16317 int 16318 bcm_esw_port_config_get(int unit, bcm_port_config_t *config) 16319 { 16320 int i; 16321 16322 PORT_INIT(unit); 16323 PORT_LOCK(unit); 16324 16325 config->fe = PBMP_FE_ALL(unit); 16326 config->ge = PBMP_GE_ALL(unit); 16327 config->xe = PBMP_XE_ALL(unit); 16328 config->ce = PBMP_CE_ALL(unit); 16329 config->cd = PBMP_CDE_ALL(unit); 16330 config->e = PBMP_E_ALL(unit); 16331 config->hg = PBMP_HG_ALL(unit); 16332 config->tdm = PBMP_TDM_ALL(unit); 16333 config->port = PBMP_PORT_ALL(unit); 16334 config->cpu = PBMP_CMIC(unit); 16335 config->roe = PBMP_ROE_ALL(unit); 16336 config->all = PBMP_ALL(unit); 16337 /* Remove LB and RDB port from the PBMP_ALL bitmap for backward compatibility */ 16338 SOC_PBMP_REMOVE(config->all, PBMP_LB(unit)); 16339 SOC_PBMP_REMOVE(config->all, PBMP_RDB_ALL(unit)); 16340 SOC_PBMP_REMOVE(config->all, PBMP_FAE_ALL(unit)); 16341 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_HURRICANE4_SUPPORT) 16342 if (SOC_IS_MONTEREY(unit) || SOC_IS_HURRICANE4(unit)) { 16343 SOC_PBMP_REMOVE(config->all, PBMP_MACSEC_ALL(unit)); 16344 } 16345 #endif 16346 config->stack_ext = PBMP_ST_ALL(unit); 16347 16348 16349 BCM_PBMP_CLEAR(config->stack_int); 16350 BCM_PBMP_CLEAR(config->sci); 16351 BCM_PBMP_CLEAR(config->sfi); 16352 BCM_PBMP_CLEAR(config->spi); 16353 BCM_PBMP_CLEAR(config->spi_subport); 16354 16355 for (i = 0; i < NUM_PIPE(unit); i++) { 16356 config->per_pipe[i] = PBMP_PIPE(unit, i); 16357 SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_LB(unit)); 16358 SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_RDB_ALL(unit)); 16359 SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_FAE_ALL(unit)); 16360 #if defined(BCM_MONTEREY_SUPPORT) || defined(BCM_HURRICANE4_SUPPORT) 16361 if (SOC_IS_MONTEREY(unit) || SOC_IS_HURRICANE4(unit)) { 16362 SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_MACSEC_ALL(unit)); 16363 } 16364 #endif 16365 } 16366 16367 #if defined(BCM_SABER2_SUPPORT) 16368 /* Remove OAMP port from port config list */ 16369 if(SOC_IS_SABER2(unit)) { 16370 soc_info_t *si = &SOC_INFO(unit); 16371 bcm_port_t oamp_port = _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER; 16372 16373 if(bcm_common_oamp_port_enable_get(unit, oamp_port)) { 16374 SOC_PBMP_PORT_REMOVE(config->port, oamp_port); 16375 SOC_PBMP_PORT_REMOVE(config->e, oamp_port); 16376 16377 if(si->port_speed_max[oamp_port] < 10000) { 16378 SOC_PBMP_PORT_REMOVE(config->ge, oamp_port); 16379 } else { 16380 SOC_PBMP_PORT_REMOVE(config->xe, oamp_port); 16381 } 16382 } 16383 } 16384 #endif 16385 16386 #if defined(BCM_TRIUMPH3_SUPPORT) 16387 if (SOC_IS_TRIUMPH3(unit)) { 16388 config->control = soc_tr3_get_control_port_bitmap(unit); 16389 } 16390 #endif 16391 16392 #if defined(BCM_KATANA2_SUPPORT) 16393 if (SOC_IS_KATANA2(unit) && (soc_feature(unit, soc_feature_linkphy_coe) || 16394 soc_feature(unit, soc_feature_subtag_coe))) { 16395 _bcm_kt2_subport_pbmp_update(unit, &(config->all)); 16396 } 16397 #endif 16398 16399 PORT_UNLOCK(unit); 16400 return BCM_E_NONE; 16401 } 16402 16403 STATIC int 16404 _bcm_td_port_mode_update(int unit, bcm_port_t port, int speed) 16405 { 16406 soc_info_t *si; 16407 int enable[2], duplex[2], loopback[2], pause_tx[2], pause_rx[2]; 16408 int frame_max[2], encap[2]; 16409 sal_mac_addr_t address[2]; 16410 bcm_port_t port_list[2], phy_port, cur_port; 16411 uint32 rval; 16412 int core_mode, phy_mode, old_phy_mode; 16413 int i; 16414 16415 /* Get the original phy_mode */ 16416 SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port, &rval)); 16417 core_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, 16418 CORE_PORT_MODEf); 16419 old_phy_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, 16420 PHY_PORT_MODEf); 16421 16422 si = &SOC_INFO(unit); 16423 /* speed is the only factor to determine phy_mode */ 16424 if ((speed > 20000) && si->port_speed_max[port] > 20000){ 16425 phy_mode = 0; 16426 } else if (speed > 10000) { 16427 if ((si->port_num_lanes[port] == 1) && (speed == 11000) && 16428 IS_HG_PORT(unit, port)) { 16429 phy_mode = 2; 16430 } else { 16431 phy_mode = 1; 16432 } 16433 } else { 16434 if ((si->port_num_lanes[port] == 2) && (speed == 10000) && 16435 IS_HG_PORT(unit, port)) { 16436 phy_mode = 1; /* Warpcore uses DXGXS 10.5G in HG mode */ 16437 } else if ((si->port_num_lanes[port] == 4) && (speed == 10000)) { 16438 phy_mode = 2; 16439 core_mode = 0; 16440 } else { 16441 phy_mode = 2; 16442 } 16443 } 16444 16445 if (phy_mode == old_phy_mode) { 16446 return BCM_E_NONE; 16447 } 16448 16449 port_list[0] = port; 16450 port_list[1] = -1; 16451 if (core_mode == 1) { /* dual mode */ 16452 si = &SOC_INFO(unit); 16453 phy_port = si->port_l2p_mapping[port]; 16454 port_list[1] = si->port_p2l_mapping[((phy_port - 1) ^ 2) + 1]; 16455 } 16456 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, PHY_PORT_MODEf, phy_mode); 16457 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, CORE_PORT_MODEf, core_mode); 16458 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval)); 16459 16460 /* Retain MAC setting */ 16461 for (i = 0; i < 2; i++) { 16462 if (port_list[i] == -1) { 16463 continue; 16464 } 16465 cur_port = port_list[i]; 16466 16467 /* no need to save speed since speed change trigger this, in addition, 16468 * mac may not be able to tell you exact speed in many cases */ 16469 SOC_IF_ERROR_RETURN 16470 (MAC_DUPLEX_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 16471 &duplex[i])); 16472 SOC_IF_ERROR_RETURN 16473 (MAC_PAUSE_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 16474 &pause_tx[i], &pause_rx[i])); 16475 SOC_IF_ERROR_RETURN 16476 (MAC_PAUSE_ADDR_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 16477 address[i])); 16478 SOC_IF_ERROR_RETURN 16479 (MAC_FRAME_MAX_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 16480 &frame_max[i])); 16481 /* not saving ifg setting */ 16482 SOC_IF_ERROR_RETURN 16483 (MAC_ENCAP_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 16484 &encap[i])); 16485 SOC_IF_ERROR_RETURN 16486 (MAC_LOOPBACK_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 16487 &loopback[i])); 16488 SOC_IF_ERROR_RETURN 16489 (MAC_ENABLE_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 16490 &enable[i])); 16491 } 16492 16493 /* Do XMAC hard reset when phy_mode changed */ 16494 (void)READ_XLPORT_XMAC_CONTROLr(unit, port, &rval); 16495 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1); 16496 (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval); 16497 sal_udelay(10); 16498 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0); 16499 (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval); 16500 16501 for (i = 0; i < 2; i++) { 16502 if (port_list[i] == -1) { 16503 continue; 16504 } 16505 cur_port = port_list[i]; 16506 16507 /* mac init */ 16508 SOC_IF_ERROR_RETURN 16509 (MAC_INIT(PORT(unit, cur_port).p_mac, unit, cur_port)); 16510 16511 /* Restore MAC setting */ 16512 /* no need to save speed since speed change trigger this, in addition, 16513 * mac may not be able to tell you exact speed in many cases */ 16514 /* coverity[uninit_use_in_call] : FALSE */ 16515 SOC_IF_ERROR_RETURN 16516 (MAC_DUPLEX_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 16517 duplex[i])); 16518 /* coverity[uninit_use_in_call] : FALSE */ 16519 SOC_IF_ERROR_RETURN 16520 (MAC_PAUSE_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 16521 pause_tx[i], pause_rx[i])); 16522 SOC_IF_ERROR_RETURN 16523 (MAC_PAUSE_ADDR_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 16524 address[i])); 16525 /* coverity[uninit_use_in_call] : FALSE */ 16526 SOC_IF_ERROR_RETURN 16527 (MAC_FRAME_MAX_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 16528 frame_max[i])); 16529 /* not saving ifg setting */ 16530 /* coverity[uninit_use_in_call] : FALSE */ 16531 SOC_IF_ERROR_RETURN 16532 (MAC_ENCAP_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 16533 encap[i])); 16534 /* coverity[uninit_use_in_call] : FALSE */ 16535 SOC_IF_ERROR_RETURN 16536 (MAC_LOOPBACK_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 16537 loopback[i])); 16538 /* coverity[uninit_use_in_call] : FALSE */ 16539 SOC_IF_ERROR_RETURN 16540 (MAC_ENABLE_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 16541 enable[i])); 16542 } 16543 16544 return BCM_E_NONE; 16545 } 16546 16547 STATIC int 16548 _bcm_tx_roe_port_update(int unit, bcm_port_t port, int link) 16549 { 16550 16551 /* Call Port Control module */ 16552 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 16553 return bcmi_esw_tx_roe_portctrl_update(unit, port, link); 16554 } 16555 return BCM_E_NONE; 16556 } 16557 16558 STATIC int 16559 _bcm_rx_roe_port_update(int unit, bcm_port_t port, int link) 16560 { 16561 16562 /* Call Port Control module */ 16563 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 16564 return bcmi_esw_rx_roe_portctrl_update(unit, port, link); 16565 } 16566 return BCM_E_NONE; 16567 } 16568 /* 16569 * Function: 16570 * _bcm_port_update 16571 * Purpose: 16572 * Get port characteristics from PHY and program MAC to match. 16573 * Parameters: 16574 * unit - StrataSwitch Unit #. 16575 * port - StrataSwitch port #. 16576 * link - True if link is active, false if link is inactive. 16577 * Returns: 16578 * BCM_E_NONE 16579 * BCM_E_XXX 16580 */ 16581 16582 STATIC int 16583 _bcm_port_update(int unit, bcm_port_t port, int link) 16584 { 16585 int rv; 16586 int duplex, speed, an, an_done; 16587 soc_port_if_t pif; 16588 int cur_mac_speed; 16589 int enable; 16590 #ifdef INCLUDE_MACSEC 16591 int policy = 0; 16592 int duplex_old = 0; 16593 #endif 16594 #ifdef INCLUDE_FCMAP 16595 phy_ctrl_t *pc; 16596 #endif 16597 16598 /* Call Port Control module */ 16599 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 16600 return bcmi_esw_portctrl_update(unit, port, link); 16601 } 16602 if(bcm_common_oamp_port_enable_get(unit, port)) { 16603 LOG_ERROR(BSL_LS_BCM_PORT, 16604 (BSL_META("Error: Not permitted on OAMP port %d.update.\n"), 16605 port)); 16606 return BCM_E_PARAM; 16607 } 16608 16609 if (PORT(unit, port).p_mac == NULL) { 16610 return BCM_E_INIT; 16611 } 16612 16613 if (!link) { 16614 /* PHY is down. Disable the MAC. */ 16615 #ifdef SW_AUTONEG_SUPPORT 16616 rv = _bcm_esw_port_notify_link_down_evt(unit, port); 16617 if (BCM_FAILURE(rv)) { 16618 LOG_WARN(BSL_LS_BCM_PORT, 16619 (BSL_META_U(unit, 16620 "u=%d p=%d NOTIFY LINK DOWN EVT rv=%d\n"), 16621 unit, port, rv)); 16622 return rv; 16623 } 16624 #endif 16625 16626 rv = (MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE)); 16627 if (BCM_FAILURE(rv)) { 16628 LOG_WARN(BSL_LS_BCM_PORT, 16629 (BSL_META_U(unit, 16630 "u=%d p=%d MAC_ENABLE_SET FALSE rv=%d\n"), 16631 unit, port, rv)); 16632 return rv; 16633 } 16634 /* PHY link down event */ 16635 rv = (soc_phyctrl_linkdn_evt(unit, port)); 16636 if (BCM_FAILURE(rv) && (BCM_E_UNAVAIL != rv)) { 16637 LOG_WARN(BSL_LS_BCM_PORT, 16638 (BSL_META_U(unit, 16639 "u=%d p=%d soc_phyctrl_linkdn_evt rv=%d\n"),unit, port, rv)); 16640 return rv; 16641 } 16642 return BCM_E_NONE; 16643 } 16644 16645 /* PHY link up event may not be support by all PHY driver. 16646 * Just ignore it if not supported */ 16647 rv = (soc_phyctrl_linkup_evt(unit, port)); 16648 if (BCM_FAILURE(rv) && (BCM_E_UNAVAIL != rv)) { 16649 LOG_WARN(BSL_LS_BCM_PORT, 16650 (BSL_META_U(unit, 16651 "u=%d p=%d soc_phyctrl_linkup_evt rv=%d\n"),unit, port, rv)); 16652 return rv; 16653 } 16654 16655 if (soc_feature(unit, soc_feature_internal_phy_link_check)) { 16656 int up = 0; 16657 16658 SOC_IF_ERROR_RETURN 16659 (soc_phyctrl_link_get(unit, port, &up)); 16660 16661 /* Wait internal PHY link when external PHY is link up */ 16662 if (up) { 16663 (void)soc_phyctrl_notify(unit, port, phyEventLinkWait, 0); 16664 } 16665 } 16666 16667 /* 16668 * Set MAC speed first, since for GTH ports, this will switch 16669 * between the 1000Mb/s or 10/100Mb/s MACs. 16670 */ 16671 16672 if (!IS_HG_PORT(unit, port) || IS_GX_PORT(unit, port)) { 16673 rv = (soc_phyctrl_speed_get(unit, port, &speed)); 16674 if (BCM_FAILURE(rv) && (BCM_E_UNAVAIL != rv)) { 16675 LOG_WARN(BSL_LS_BCM_PORT, 16676 (BSL_META_U(unit, 16677 "u=%d p=%d phyctrl_speed_get rv=%d\n"),unit, port, rv)); 16678 return rv; 16679 } 16680 if (IS_HG_PORT(unit, port) && speed < 5000) { 16681 speed = 0; 16682 } 16683 LOG_INFO(BSL_LS_BCM_PORT, 16684 (BSL_META_U(unit, 16685 "u=%d p=%d phyctrl_speed_get speed=%d\n"),unit, port, speed)); 16686 16687 if (BCM_E_UNAVAIL == rv ) { 16688 /* If PHY driver doesn't support speed_get, don't change 16689 * MAC speed. E.g, Null PHY driver 16690 */ 16691 rv = BCM_E_NONE; 16692 } else { 16693 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 16694 BCM_IF_ERROR_RETURN 16695 (_bcm_td_port_mode_update(unit, port, speed)); 16696 } 16697 #ifdef INCLUDE_FCMAP 16698 /* FOR MONTREAL-1 ONLY 16699 * 16700 * In FCMAP mode, the port is operating in FC-Mode. The switch and the 16701 * system side of the PHY operates in 10G, FullDuplex and Pause enabled 16702 * mode 16703 * For MT1, the phy max speed will always be 10G (never 25G which MT2 supports) 16704 */ 16705 if (soc_property_port_get(unit, port, spn_FCMAP_ENABLE, 0)) { 16706 16707 pc = EXT_PHY_SW_STATE(unit, port); 16708 16709 if ((pc != NULL) && !PHY_IS_BCM8806X(pc)) { 16710 speed = 10000; 16711 } 16712 LOG_WARN(BSL_LS_BCM_PORT, 16713 (BSL_META_U(unit, 16714 "u=%d p=%d speed_max=%d speed=%d\n"),unit, port, 16715 pc->speed_max, speed)); 16716 } 16717 #endif 16718 rv = (MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, &cur_mac_speed)); 16719 if (BCM_FAILURE(rv)) { 16720 LOG_WARN(BSL_LS_BCM_PORT, 16721 (BSL_META_U(unit, 16722 "u=%d p=%d MAC_SPEED_GET rv=%d\n"),unit, port, rv)); 16723 return rv; 16724 } 16725 16726 rv = (MAC_ENABLE_GET(PORT(unit, port).p_mac, unit, port, &enable)); 16727 if (BCM_FAILURE(rv)) { 16728 LOG_WARN(BSL_LS_BCM_PORT, 16729 (BSL_META_U(unit, 16730 "u=%d p=%d MAC_ENABLE_GET rv=%d\n"),unit, port, rv)); 16731 return rv; 16732 } 16733 16734 /* If current MAC speed is the same as PHY speed, no need set it again */ 16735 if (cur_mac_speed != speed || enable != TRUE) { 16736 rv = (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, speed)); 16737 } 16738 } 16739 if (BCM_FAILURE(rv)) { 16740 LOG_WARN(BSL_LS_BCM_PORT, 16741 (BSL_META_U(unit, 16742 "u=%d p=%d MAC_SPEED_SET speed=%d rv=%d\n"), 16743 unit, port, speed, rv)); 16744 return rv; 16745 } 16746 16747 rv = (soc_phyctrl_duplex_get(unit, port, &duplex)); 16748 if (BCM_FAILURE(rv)) { 16749 LOG_WARN(BSL_LS_BCM_PORT, 16750 (BSL_META_U(unit, 16751 "u=%d p=%d phyctrl_duplex_get rv=%d\n"), 16752 unit, port, rv)); 16753 return rv; 16754 } 16755 16756 #ifdef INCLUDE_MACSEC 16757 /* When macsec is enabled, the switch and system side of the PHY 16758 * operate in full-duplex mode. 16759 */ 16760 duplex_old = duplex; 16761 if ( soc_property_port_get(unit, port, spn_MACSEC_ENABLE, 0) ) { 16762 duplex = 1; 16763 } 16764 16765 policy = soc_property_port_get(unit, port, spn_MACSEC_SWITCH_SIDE_POLICY, 1); 16766 if ( (policy == 2) && (! duplex_old) ) { 16767 /* if line-side linked up at half-duplex under Duplex Gateway mode */ 16768 duplex = 1; /* force to full-duplex */ 16769 } 16770 #endif 16771 16772 #ifdef INCLUDE_FCMAP 16773 /* 16774 * In FCMAP mode, the port is operating in FC-Mode. The switch and the 16775 * system side of the PHY operates in 10G, FullDuplex and Pause enabled 16776 * mode 16777 */ 16778 if (soc_property_port_get(unit, port, spn_FCMAP_ENABLE, 0)) { 16779 duplex = 1; 16780 } 16781 #endif 16782 rv = (MAC_DUPLEX_SET(PORT(unit, port).p_mac, unit, port, duplex)); 16783 if (BCM_FAILURE(rv)) { 16784 LOG_WARN(BSL_LS_BCM_PORT, 16785 (BSL_META_U(unit, 16786 "u=%d p=%d MAC_DUPLEX_SET %s sp=%d rv=%d\n"), 16787 unit, port, 16788 duplex ? "FULL" : "HALF", speed, rv)); 16789 return rv; 16790 } 16791 } else { 16792 16793 duplex = 1; 16794 } 16795 16796 rv = (soc_phyctrl_interface_get(unit, port, &pif)); 16797 if (BCM_FAILURE(rv)) { 16798 LOG_WARN(BSL_LS_BCM_PORT, 16799 (BSL_META_U(unit, 16800 "u=%d p=%d phyctrl_interface_get rv=%d\n"), 16801 unit, port, rv)); 16802 return rv; 16803 } 16804 rv = (MAC_INTERFACE_SET(PORT(unit, port).p_mac, unit, port, pif)); 16805 if (BCM_FAILURE(rv)) { 16806 LOG_WARN(BSL_LS_BCM_PORT, 16807 (BSL_META_U(unit, 16808 "u=%d p=%d MAC_INTERFACE_GET rv=%d\n"), 16809 unit, port,rv)); 16810 return rv; 16811 } 16812 16813 SOC_IF_ERROR_RETURN 16814 (soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done)); 16815 16816 /* 16817 * If autonegotiating, check the negotiated PAUSE values, and program 16818 * MACs accordingly. Link can also be achieved thru parallel detect. 16819 * In this case, it should be treated as in the forced mode. 16820 */ 16821 if (an && an_done) { 16822 bcm_port_ability_t remote_advert, local_advert; 16823 int tx_pause, rx_pause; 16824 16825 sal_memset(&local_advert, 0, sizeof(bcm_port_ability_t)); 16826 sal_memset(&remote_advert, 0, sizeof(bcm_port_ability_t)); 16827 16828 rv = soc_phyctrl_ability_advert_get(unit, port, &local_advert); 16829 if (BCM_FAILURE(rv)) { 16830 LOG_WARN(BSL_LS_BCM_PORT, 16831 (BSL_META_U(unit, 16832 "u=%d p=%d soc_phyctrl_adv_local_get rv=%d\n"), 16833 unit, port, rv)); 16834 return rv; 16835 } 16836 rv = soc_phyctrl_ability_remote_get(unit, port, &remote_advert); 16837 if (BCM_FAILURE(rv)) { 16838 LOG_WARN(BSL_LS_BCM_PORT, 16839 (BSL_META_U(unit, 16840 "u=%d p=%d soc_phyctrl_adv_remote_get rv=%d\n"), 16841 unit, port, rv)); 16842 return rv; 16843 } 16844 16845 /* 16846 * IEEE 802.3 Flow Control Resolution. 16847 * Please see $SDK/doc/pause-resolution.txt for more information. 16848 */ 16849 16850 if (duplex) { 16851 tx_pause = 16852 ((remote_advert.pause & SOC_PA_PAUSE_RX) && 16853 (local_advert.pause & SOC_PA_PAUSE_RX)) || 16854 ((remote_advert.pause & SOC_PA_PAUSE_RX) && 16855 !(remote_advert.pause & SOC_PA_PAUSE_TX) && 16856 (local_advert.pause & SOC_PA_PAUSE_TX)); 16857 16858 rx_pause = 16859 ((remote_advert.pause & SOC_PA_PAUSE_RX) && 16860 (local_advert.pause & SOC_PA_PAUSE_RX)) || 16861 ((local_advert.pause & SOC_PA_PAUSE_RX) && 16862 (remote_advert.pause & SOC_PA_PAUSE_TX) && 16863 !(local_advert.pause & SOC_PA_PAUSE_TX)); 16864 } else { 16865 rx_pause = tx_pause = 0; 16866 } 16867 #ifdef INCLUDE_MACSEC 16868 if ( (policy == 2) && (! duplex_old) ) { 16869 /* if line-side linked up at half-duplex under Duplex Gateway mode */ 16870 rx_pause = 1; /* turn on flow control Rx pause frames */ 16871 } 16872 #endif 16873 rv = (MAC_PAUSE_SET(PORT(unit, port).p_mac, 16874 unit, port, tx_pause, rx_pause)); 16875 if (BCM_FAILURE(rv)) { 16876 LOG_WARN(BSL_LS_BCM_PORT, 16877 (BSL_META_U(unit, 16878 "u=%d p=%d MAC_PAUSE_SET rv=%d\n"), 16879 unit, port, rv)); 16880 return rv; 16881 } 16882 } 16883 16884 #ifdef INCLUDE_MACSEC 16885 { 16886 /* 16887 * In MACSEC based PHYs the switch side could be operating with 16888 * different speed,duplex and pause compared to line speed, duplex and 16889 * pause settings. The above setting will be overridden if the switch side 16890 * of the PHY is set to operate in fixed mode 16891 */ 16892 uint32 value; 16893 rv = (soc_phyctrl_control_get(unit, port, 16894 BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED, 16895 &value)); 16896 16897 if (BCM_E_UNAVAIL != rv) { /* Switch fixed speed is supported */ 16898 16899 if (value == 1) { 16900 /* Get and Set Speed */ 16901 rv = (soc_phyctrl_control_get(unit, port, 16902 BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED_SPEED, 16903 &value)); 16904 if (BCM_FAILURE(rv)) { 16905 LOG_WARN(BSL_LS_BCM_PORT, 16906 (BSL_META_U(unit, 16907 "u=%d p=%d phyctrl_control_get(speed) rv=%d\n"), 16908 unit, port, rv)); 16909 return rv; 16910 } 16911 16912 rv = (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, value)); 16913 if (BCM_FAILURE(rv)) { 16914 LOG_WARN(BSL_LS_BCM_PORT, 16915 (BSL_META_U(unit, 16916 "u=%d p=%d MAC_SPEED_SET speed=%d rv=%d\n"), 16917 unit, port, value, rv)); 16918 return rv; 16919 } 16920 16921 /* Get and Set Duplex */ 16922 rv = (soc_phyctrl_control_get(unit, port, 16923 BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED_DUPLEX, 16924 &value)); 16925 if (BCM_FAILURE(rv)) { 16926 LOG_WARN(BSL_LS_BCM_PORT, 16927 (BSL_META_U(unit, 16928 "u=%d p=%d phyctrl_control_get(duplex) rv=%d\n"), 16929 unit, port, rv)); 16930 return rv; 16931 } 16932 rv = (MAC_DUPLEX_SET(PORT(unit, port).p_mac, unit, port, value)); 16933 if (BCM_FAILURE(rv)) { 16934 LOG_WARN(BSL_LS_BCM_PORT, 16935 (BSL_META_U(unit, 16936 "u=%d p=%d MAC_DUPLEX_SET %s sp=%d rv=%d\n"), 16937 unit, port, 16938 value ? "FULL" : "HALF", value, rv)); 16939 return rv; 16940 } 16941 16942 /* Get and Set PAUSE */ 16943 rv = (soc_phyctrl_control_get(unit, port, 16944 BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED_PAUSE, 16945 &value)); 16946 if (BCM_FAILURE(rv)) { 16947 LOG_WARN(BSL_LS_BCM_PORT, 16948 (BSL_META_U(unit, 16949 "u=%d p=%d phyctrl_control_get(Pause) rv=%d\n"), 16950 unit, port, rv)); 16951 return rv; 16952 } 16953 if (value == 1) { 16954 /* 16955 * Flow control domain is between switch MAC and PHY MAC. 16956 * If the flow control domain is not between switch and PHY's 16957 * switch MAC, then the flow control domain is extended to that 16958 * of GPHY. 16959 */ 16960 rv = (MAC_PAUSE_SET(PORT(unit, port).p_mac, 16961 unit, port, value, value)); 16962 if (BCM_FAILURE(rv)) { 16963 LOG_WARN(BSL_LS_BCM_PORT, 16964 (BSL_META_U(unit, 16965 "u=%d p=%d MAC_PAUSE_SET rv=%d\n"), 16966 unit, port, rv)); 16967 return rv; 16968 } 16969 } 16970 16971 } 16972 } 16973 } 16974 #endif 16975 16976 /* Enable the MAC. */ 16977 rv = (MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE)); 16978 if (BCM_FAILURE(rv)) { 16979 LOG_WARN(BSL_LS_BCM_PORT, 16980 (BSL_META_U(unit, 16981 "u=%d p=%d MAC_ENABLE_SET TRUE rv=%d\n"), 16982 unit, port, rv)); 16983 return rv; 16984 } 16985 16986 #ifdef BCM_BRADLEY_SUPPORT 16987 /* When a link comes up, hardware will not update the 16988 * LINK_STATUS register until software has toggled the 16989 * the LAG_FAILOVER_CONFIG.LINK_STATUS_UP field. 16990 * When a link goes down, hardware will update the 16991 * LINK_STATUS register without software intervention. 16992 */ 16993 if ((SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr) && 16994 IS_GX_PORT(unit, port)) || 16995 (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) || 16996 (SOC_REG_IS_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr) && 16997 (IS_XL_PORT(unit, port) || IS_MXQ_PORT(unit, port) )) || 16998 (SOC_REG_IS_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr) && 16999 IS_CL_PORT(unit, port))) { 17000 soc_reg_t reg; 17001 uint32 rval; 17002 17003 if (SOC_IS_SABER2(unit) && SOC_REG_PORT_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr, port)) { 17004 reg = XLPORT_LAG_FAILOVER_CONFIGr; 17005 } else if (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) { 17006 reg = LAG_FAILOVER_CONFIGr; 17007 } else if (SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr)) { 17008 reg = GXPORT_LAG_FAILOVER_CONFIGr; 17009 } else if (SOC_REG_PORT_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr, port) && 17010 (SOC_IS_TOMAHAWKX(unit) || IS_CL_PORT(unit, port))) { 17011 reg = CLPORT_LAG_FAILOVER_CONFIGr; 17012 } else { 17013 reg = XLPORT_LAG_FAILOVER_CONFIGr; 17014 } 17015 17016 /* Toggle link bit to notify IPIPE on link up */ 17017 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 17018 soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 1); 17019 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 17020 soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 0); 17021 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 17022 } 17023 #endif /* BCM_BRADLEY_SUPPORT */ 17024 17025 return BCM_E_NONE; 17026 } 17027 17028 17029 17030 /* 17031 * Function: 17032 * bcm_port_update 17033 * Purpose: 17034 * Get port characteristics from PHY and program MAC to match. 17035 * Parameters: 17036 * unit - StrataSwitch Unit #. 17037 * port - StrataSwitch port #. 17038 * link - TRUE - process as link up. 17039 * FALSE - process as link down. 17040 * Returns: 17041 * BCM_E_NONE 17042 * BCM_E_XXX 17043 */ 17044 17045 int 17046 bcm_esw_port_update(int unit, bcm_port_t port, int link) 17047 { 17048 int rv = BCM_E_NONE; 17049 #if defined(BCM_KATANA2_SUPPORT) 17050 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 17051 #endif 17052 17053 /* Make sure port module is initialized. */ 17054 PORT_INIT(unit); 17055 17056 #if defined(BCM_KATANA2_SUPPORT) 17057 #if defined(BCM_SABER2_SUPPORT) 17058 if(SOC_IS_SABER2(unit)) { 17059 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 17060 } 17061 #endif 17062 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 17063 (!((port >= 1) && (port <= max_phy_port)))) { 17064 return BCM_E_PORT; 17065 } 17066 #endif 17067 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17068 17069 #if defined(BCM_RCPU_SUPPORT) 17070 if (SOC_IS_RCPU_ONLY(unit) && link) { 17071 /* Can not do this unless real phy driver is used for RCPU device. */ 17072 return BCM_E_NONE; 17073 } 17074 #endif /* BCM_RCPU_SUPPORT */ 17075 PORT_LOCK(unit); 17076 rv = _bcm_port_update(unit, port, link); 17077 if (BCM_FAILURE(rv)) { 17078 PORT_UNLOCK(unit); 17079 return (rv); 17080 } 17081 #if defined(BCM_BRADLEY_SUPPORT) 17082 if (SOC_IS_HBX(unit) && !SOC_IS_SHADOW(unit)) { 17083 rv = _bcm_port_mmu_update(unit, port, link); 17084 } 17085 #endif /* BCM_BRADLEY_SUPPORT */ 17086 17087 #if defined(BCM_KATANA2_SUPPORT) 17088 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 17089 rv = soc_katana2_mmu_port_enable_set(unit, port, link); 17090 } 17091 #endif 17092 17093 PORT_UNLOCK(unit); 17094 17095 LOG_INFO(BSL_LS_BCM_PORT, 17096 (BSL_META_U(unit, 17097 "bcm_port_update: u=%d p=%d link=%d rv=%d\n"), 17098 unit, port, link, rv)); 17099 17100 return(rv); 17101 } 17102 17103 /* 17104 * Function: 17105 * bcm_esw_roe_tx_port_update 17106 * Parameters: 17107 * unit - StrataSwitch Unit #. 17108 * port - StrataSwitch port #. 17109 * link - TRUE - process as link up. 17110 * FALSE - process as link down. 17111 * Returns: 17112 * BCM_E_NONE 17113 * BCM_E_XXX 17114 */ 17115 17116 int 17117 bcm_esw_roe_tx_port_update(int unit, bcm_port_t port, int link) 17118 { 17119 int rv = BCM_E_NONE; 17120 PORT_INIT(unit); 17121 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17122 17123 PORT_LOCK(unit); 17124 rv = _bcm_tx_roe_port_update(unit, port, link); 17125 if (BCM_FAILURE(rv)) { 17126 PORT_UNLOCK(unit); 17127 return (rv); 17128 } 17129 PORT_UNLOCK(unit); 17130 17131 LOG_INFO(BSL_LS_BCM_PORT, 17132 (BSL_META_U(unit, 17133 "bcm_tx_roe_port_update: u=%d p=%d link=%d rv=%d\n"), 17134 unit, port, link, rv)); 17135 17136 return(rv); 17137 } 17138 17139 /* 17140 * Function: 17141 * bcm_esw_roe_rx_port_update 17142 * Parameters: 17143 * unit - StrataSwitch Unit #. 17144 * port - StrataSwitch port #. 17145 * link - TRUE - process as link up. 17146 * FALSE - process as link down. 17147 * Returns: 17148 * BCM_E_NONE 17149 * BCM_E_XXX 17150 */ 17151 17152 int 17153 bcm_esw_roe_rx_port_update(int unit, bcm_port_t port, int link) 17154 { 17155 int rv = BCM_E_NONE; 17156 PORT_INIT(unit); 17157 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17158 17159 PORT_LOCK(unit); 17160 rv = _bcm_rx_roe_port_update(unit, port, link); 17161 if (BCM_FAILURE(rv)) { 17162 PORT_UNLOCK(unit); 17163 return (rv); 17164 } 17165 PORT_UNLOCK(unit); 17166 17167 LOG_INFO(BSL_LS_BCM_PORT, 17168 (BSL_META_U(unit, 17169 "bcm_rx_roe_port_update: u=%d p=%d link=%d rv=%d\n"), 17170 unit, port, link, rv)); 17171 17172 return(rv); 17173 } 17174 17175 17176 /* 17177 * Function: 17178 * bcm_port_stp_set 17179 * Purpose: 17180 * Set the spanning tree state for a port. 17181 * All STGs containing all VLANs containing the port are updated. 17182 * Parameters: 17183 * unit - StrataSwitch unit number. 17184 * port - StrataSwitch port number. 17185 * stp_state - State to place port in, one of BCM_PORT_STP_xxx. 17186 * Returns: 17187 * BCM_E_NONE 17188 * BCM_E_INTERNAL 17189 * Notes: 17190 * BCM_LOCK is taken so that the current list of VLANs 17191 * can't change during the operation. 17192 */ 17193 17194 int 17195 bcm_esw_port_stp_set(int unit, bcm_port_t port, int stp_state) 17196 { 17197 bcm_stg_t *list = NULL; 17198 int count = 0, i; 17199 int rv = BCM_E_NONE; 17200 17201 /* Make sure port module is initialized. */ 17202 PORT_INIT(unit); 17203 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17204 17205 #ifdef BCM_RCPU_SUPPORT 17206 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port) && 17207 !(stp_state == BCM_STG_STP_FORWARD)) { 17208 return BCM_E_PORT; 17209 } 17210 #endif /* BCM_RCPU_SUPPORT */ 17211 17212 BCM_LOCK(unit); 17213 17214 rv = bcm_esw_stg_list(unit, &list, &count); 17215 17216 if (rv == BCM_E_UNAVAIL) { 17217 if (stp_state == BCM_STG_STP_FORWARD) { 17218 rv = BCM_E_NONE; 17219 } else { 17220 rv = BCM_E_PARAM; 17221 } 17222 } else if (BCM_SUCCESS(rv)) { 17223 for (i = 0; i < count; i++) { 17224 if ((rv = bcm_esw_stg_stp_set(unit, list[i], 17225 port, stp_state)) < 0) { 17226 break; 17227 } 17228 } 17229 17230 bcm_esw_stg_list_destroy(unit, list, count); 17231 } 17232 17233 BCM_UNLOCK(unit); 17234 17235 LOG_INFO(BSL_LS_BCM_PORT, 17236 (BSL_META_U(unit, 17237 "bcm_port_stp_set: u=%d p=%d state=%d rv=%d\n"), 17238 unit, port, stp_state, rv)); 17239 17240 return rv; 17241 } 17242 17243 /* 17244 * Function: 17245 * bcm_port_stp_get 17246 * Purpose: 17247 * Get the spanning tree state for a port in the default STG. 17248 * Parameters: 17249 * unit - StrataSwitch unit number. 17250 * port - StrataSwitch port number. 17251 * stp_state - Pointer where state stored. 17252 * Returns: 17253 * BCM_E_NONE 17254 * BCM_E_INTERNAL 17255 */ 17256 17257 int 17258 bcm_esw_port_stp_get(int unit, bcm_port_t port, int *stp_state) 17259 { 17260 int stg_defl, rv; 17261 17262 /* Make sure port module is initialized. */ 17263 PORT_INIT(unit); 17264 17265 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17266 17267 rv = bcm_esw_stg_default_get(unit, &stg_defl); 17268 if (rv >= 0) { 17269 rv = bcm_esw_stg_stp_get(unit, stg_defl, port, stp_state); 17270 } else if (rv == BCM_E_UNAVAIL) { /* FABRIC switches, etc */ 17271 *stp_state = BCM_STG_STP_FORWARD; 17272 rv = BCM_E_NONE; 17273 } 17274 17275 LOG_INFO(BSL_LS_BCM_PORT, 17276 (BSL_META_U(unit, 17277 "bcm_port_stp_get: u=%d p=%d state=%d rv=%d\n"), 17278 unit, port, *stp_state, rv)); 17279 17280 return rv; 17281 } 17282 17283 /* 17284 * Function: 17285 * bcm_port_bpdu_enable_set 17286 * Purpose: 17287 * Enable/Disable BPDU reception on the specified port. 17288 * Parameters: 17289 * unit - SOC unit # 17290 * port - Port number (0 based) 17291 * enable - TRUE to enable, FALSE to disable (reject bpdu). 17292 * Returns: 17293 * BCM_E_NONE 17294 * BCM_E_INTERNAL 17295 */ 17296 17297 int 17298 bcm_esw_port_bpdu_enable_set(int unit, bcm_port_t port, int enable) 17299 { 17300 bcm_port_cfg_t pcfg; 17301 int rv; 17302 17303 /* Make sure port module is initialized. */ 17304 PORT_INIT(unit); 17305 17306 if(bcm_common_oamp_port_enable_get(unit, port)) { 17307 LOG_ERROR(BSL_LS_BCM_PORT, 17308 (BSL_META("Error: Cannot enable pbdu on OAMP Port %d.\n"), 17309 port)); 17310 return BCM_E_PARAM; 17311 } 17312 17313 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17314 17315 PORT_LOCK(unit); 17316 17317 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 17318 17319 if (BCM_SUCCESS(rv)) { 17320 pcfg.pc_bpdu_disable = !enable; 17321 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg); 17322 } 17323 17324 PORT_UNLOCK(unit); 17325 17326 return rv; 17327 } 17328 17329 /* 17330 * Function: 17331 * bcm_port_bpdu_enable_get 17332 * Purpose: 17333 * Return whether BPDU reception is enabled on the specified port. 17334 * Parameters: 17335 * unit - SOC unit # 17336 * port - Port number (0 based) 17337 * enable - (OUT) TRUE if enabled, FALSE if disabled 17338 * Returns: 17339 * BCM_E_NONE 17340 * BCM_E_INTERNAL 17341 */ 17342 17343 int 17344 bcm_esw_port_bpdu_enable_get(int unit, bcm_port_t port, int *enable) 17345 { 17346 bcm_port_cfg_t pcfg; 17347 int rv; 17348 17349 /* Make sure port module is initialized. */ 17350 PORT_INIT(unit); 17351 17352 if(bcm_common_oamp_port_enable_get(unit, port)) { 17353 LOG_ERROR(BSL_LS_BCM_PORT, 17354 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 17355 port)); 17356 return BCM_E_PARAM; 17357 } 17358 17359 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17360 17361 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 17362 17363 if (BCM_SUCCESS(rv)) { 17364 *enable = !pcfg.pc_bpdu_disable; 17365 } 17366 17367 return rv; 17368 } 17369 17370 /* 17371 * Function: 17372 * bcm_port_l3_enable_set 17373 * Purpose: 17374 * Enable/Disable L3 switching on the specified port. 17375 * Parameters: 17376 * unit - device number 17377 * port - port number 17378 * enable - TRUE to enable, FALSE to disable. 17379 * Returns: 17380 * BCM_E_XXX 17381 */ 17382 17383 int 17384 bcm_esw_port_l3_enable_set(int unit, bcm_port_t port, int enable) 17385 { 17386 int rv = BCM_E_UNAVAIL; 17387 #if defined(INCLUDE_L3) 17388 bcm_port_cfg_t pcfg; 17389 17390 /* Make sure port module is initialized. */ 17391 PORT_INIT(unit); 17392 17393 if(bcm_common_oamp_port_enable_get(unit, port)) { 17394 LOG_ERROR(BSL_LS_BCM_PORT, 17395 (BSL_META("Error: Cannot enable l3 on OAMP Port %d.\n"), 17396 port)); 17397 return BCM_E_PARAM; 17398 } 17399 17400 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17401 17402 PORT_LOCK(unit); 17403 17404 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 17405 17406 if (BCM_SUCCESS(rv)) { 17407 if (enable) { 17408 pcfg.pc_l3_flags |= (BCM_PORT_L3_V4_ENABLE | BCM_PORT_L3_V6_ENABLE); 17409 } else { 17410 pcfg.pc_l3_flags &= 17411 ~(BCM_PORT_L3_V4_ENABLE | BCM_PORT_L3_V6_ENABLE); 17412 } 17413 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg); 17414 } 17415 17416 PORT_UNLOCK(unit); 17417 #endif /* INCLUDE_L3 */ 17418 return rv; 17419 } 17420 17421 /* 17422 * Function: 17423 * bcm_port_l3_enable_get 17424 * Purpose: 17425 * Return whether L3 switching is enabled on the specified port. 17426 * Parameters: 17427 * unit - device number 17428 * port - port number 17429 * enable - (OUT) TRUE if enabled, FALSE if disabled 17430 * Returns: 17431 * BCM_E_XXX 17432 */ 17433 17434 int 17435 bcm_esw_port_l3_enable_get(int unit, bcm_port_t port, int *enable) 17436 { 17437 int rv = BCM_E_UNAVAIL; 17438 #if defined(INCLUDE_L3) 17439 bcm_port_cfg_t pcfg; 17440 17441 /* Make sure port module is initialized. */ 17442 PORT_INIT(unit); 17443 17444 if(bcm_common_oamp_port_enable_get(unit, port)) { 17445 LOG_ERROR(BSL_LS_BCM_PORT, 17446 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 17447 port)); 17448 return BCM_E_PARAM; 17449 } 17450 17451 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17452 17453 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 17454 17455 if (BCM_SUCCESS(rv)) { 17456 *enable = ((pcfg.pc_l3_flags & BCM_PORT_L3_V4_ENABLE) || 17457 (pcfg.pc_l3_flags & BCM_PORT_L3_V6_ENABLE)); 17458 } 17459 #endif /* INCLUDE_L3 */ 17460 17461 return rv; 17462 } 17463 17464 /* 17465 * Function: 17466 * bcm_port_tgid_get 17467 * Purpose: 17468 * Get the trunk group for a given port. 17469 * Parameters: 17470 * unit - SOC unit # 17471 * port - Port number (0 based) 17472 * tid - trunk ID 17473 * psc - trunk selection criterion 17474 * Returns: 17475 * BCM_E_NONE 17476 * BCM_E_INTERNAL 17477 */ 17478 17479 int 17480 bcm_esw_port_tgid_get(int unit, bcm_port_t port, int *tid, int *psc) 17481 { 17482 bcm_port_cfg_t pcfg; 17483 int rv; 17484 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 17485 soc_field_t tgid_fld = TGIDf; 17486 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SRC_TGIDf)) { 17487 tgid_fld = SRC_TGIDf; 17488 } 17489 #endif 17490 17491 /* Make sure port module is initialized. */ 17492 PORT_INIT(unit); 17493 17494 if(bcm_common_oamp_port_enable_get(unit, port)) { 17495 LOG_ERROR(BSL_LS_BCM_PORT, 17496 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 17497 port)); 17498 return BCM_E_PARAM; 17499 } 17500 17501 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17502 17503 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 17504 if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, tgid_fld)) { 17505 #if defined(BCM_KATANA2_SUPPORT) 17506 if (SOC_IS_KATANA2(unit)) { 17507 rv = _bcm_kt2_trunk_table_read(unit, port, tid); 17508 } else 17509 #endif 17510 { 17511 rv = _bcm_xgs3_trunk_table_read(unit, port, tid); 17512 } 17513 if (BCM_SUCCESS(rv)) { 17514 *psc = 0; 17515 } 17516 return rv; 17517 } 17518 #endif /* BCM_FIREBOLT_SUPPORT */ 17519 17520 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 17521 17522 if (BCM_SUCCESS(rv)) { 17523 *tid = pcfg.pc_tgid; 17524 *psc = 0; 17525 } 17526 17527 return rv; 17528 17529 } 17530 17531 /* 17532 * Function: 17533 * bcm_port_tgid_set 17534 * Purpose: 17535 * Set the trunk group for a given port. 17536 * Parameters: 17537 * unit - SOC unit # 17538 * port - Port number (0 based) 17539 * tid - trunk ID 17540 * psc - trunk selection criterion 17541 * Returns: 17542 * BCM_E_NONE 17543 * BCM_E_INTERNAL 17544 */ 17545 17546 int 17547 bcm_esw_port_tgid_set(int unit, bcm_port_t port, int tid, int psc) 17548 { 17549 bcm_port_cfg_t pcfg; 17550 int rv; 17551 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 17552 soc_field_t tgid_fld = TGIDf; 17553 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SRC_TGIDf)) { 17554 tgid_fld = SRC_TGIDf; 17555 } 17556 #endif 17557 17558 /* Make sure port module is initialized. */ 17559 PORT_INIT(unit); 17560 17561 if(bcm_common_oamp_port_enable_get(unit, port)) { 17562 LOG_ERROR(BSL_LS_BCM_PORT, 17563 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 17564 port)); 17565 return BCM_E_PARAM; 17566 } 17567 17568 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17569 17570 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 17571 if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, tgid_fld)) { 17572 #if defined(BCM_KATANA2_SUPPORT) 17573 if (SOC_IS_KATANA2(unit)) { 17574 return _bcm_kt2_trunk_table_write(unit, port, tid); 17575 } else 17576 #endif 17577 { 17578 return _bcm_xgs3_trunk_table_write(unit, port, tid); 17579 } 17580 } 17581 #endif /* BCM_FIREBOLT_SUPPORT */ 17582 17583 PORT_LOCK(unit); 17584 17585 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 17586 17587 if (BCM_SUCCESS(rv)) { 17588 if (tid != BCM_TRUNK_INVALID) { 17589 pcfg.pc_tgid = tid; 17590 pcfg.pc_trunk = 1; 17591 } else { 17592 pcfg.pc_tgid = 0; 17593 pcfg.pc_trunk = 0; 17594 } 17595 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg); 17596 } 17597 17598 PORT_UNLOCK(unit); 17599 17600 return rv; 17601 } 17602 17603 /* 17604 * Function: 17605 * _bcm_port_mirror_enable_get (internal) 17606 * Purpose: 17607 * Return whether mirroring is enabled on the specified port. 17608 * Parameters: 17609 * unit - (IN) BCM device number. 17610 * port - (IN) Port number (0 based). 17611 * enable - (OUT) Bitmap of ingress mirror enabled. 17612 * Returns: 17613 * BCM_E_NONE 17614 * BCM_E_INTERNAL 17615 */ 17616 17617 int 17618 _bcm_port_mirror_enable_get(int unit, bcm_port_t port, int *enable) 17619 { 17620 bcm_port_cfg_t pcfg; 17621 int rv; 17622 17623 /* Input parameters check. */ 17624 if (NULL == enable) { 17625 return (BCM_E_PARAM); 17626 } 17627 17628 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17629 17630 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 17631 17632 if (BCM_SUCCESS(rv)) { 17633 *enable = pcfg.pc_mirror_ing; 17634 } 17635 17636 return rv; 17637 } 17638 17639 /* 17640 * Function: 17641 * _bcm_port_mirror_enable_set (internal) 17642 * Purpose: 17643 * Enable/Disable mirroring for a given port. 17644 * Parameters: 17645 * unit - (IN) BCM unit # 17646 * port - (IN) Port number (0 based) 17647 * enable - (IN) Bitmap of ingress mirror enabled. 17648 * Returns: 17649 * BCM_E_NONE 17650 * BCM_E_INTERNAL 17651 */ 17652 17653 int 17654 _bcm_port_mirror_enable_set(int unit, bcm_port_t port, int enable) 17655 { 17656 bcm_port_cfg_t pcfg; 17657 int rv; 17658 17659 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17660 17661 PORT_LOCK(unit); 17662 17663 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 17664 17665 if (BCM_SUCCESS(rv)) { 17666 pcfg.pc_mirror_ing = enable; 17667 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg); 17668 } 17669 17670 PORT_UNLOCK(unit); 17671 17672 return rv; 17673 } 17674 17675 #ifdef BCM_TRIUMPH2_SUPPORT 17676 /* 17677 * Function: 17678 * _bcm_port_mirror_egress_true_enable_get (internal) 17679 * Purpose: 17680 * Return whether true egress mirroring is enabled on the 17681 * specified port. 17682 * Parameters: 17683 * unit - (IN) BCM device number. 17684 * port - (IN) Port number (0 based). 17685 * enable - (OUT) Bitmap of true egress mirrors enabled. 17686 * Returns: 17687 * BCM_E_NONE 17688 * BCM_E_INTERNAL 17689 */ 17690 17691 int 17692 _bcm_port_mirror_egress_true_enable_get(int unit, bcm_port_t port, 17693 int *enable) 17694 { 17695 int rv; 17696 17697 /* Input parameters check. */ 17698 if (NULL == enable) { 17699 return (BCM_E_PARAM); 17700 } 17701 17702 #if defined(BCM_TRIUMPH3_SUPPORT) 17703 if (soc_feature(unit, soc_feature_ep_redirect) || 17704 soc_feature(unit, soc_feature_ep_redirect_v2)) { 17705 egr_port_entry_t egr_port_entry; 17706 int ep_redirect_v2 = FALSE; 17707 17708 rv = READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, 17709 &egr_port_entry); 17710 17711 /* Check if this device supports version 2 of redirect, 17712 based on which we will access different fields below */ 17713 ep_redirect_v2 = soc_feature(unit, soc_feature_ep_redirect_v2); 17714 17715 if (BCM_SUCCESS(rv)) { 17716 if (SOC_EPT_REDIRECT_MIRROR == 17717 soc_mem_field32_get(unit, EGR_PORTm, &egr_port_entry, 17718 (ep_redirect_v2 ? ER_REDIR_DEST_TYPEf : 17719 REDIRECTION_TYPEf))) { 17720 *enable = soc_mem_field32_get(unit, EGR_PORTm, 17721 &egr_port_entry, 17722 (ep_redirect_v2 ? ER_REDIR_DESTINATIONf : 17723 REDIRECTION_DESTINATIONf)); 17724 } else { 17725 *enable = 0; 17726 } 17727 } 17728 } else 17729 #endif /* BCM_TRIUMPH3_SUPPORT */ 17730 17731 { 17732 uint64 egr_val64; 17733 17734 rv = READ_EGR_PORT_64r(unit, port, &egr_val64); 17735 if (BCM_SUCCESS(rv)) { 17736 *enable = soc_reg64_field32_get(unit, EGR_PORT_64r, 17737 egr_val64, MIRRORf); 17738 } 17739 } 17740 17741 return rv; 17742 } 17743 17744 /* 17745 * Function: 17746 * _bcm_port_mirror_egress_true_enable_set (internal) 17747 * Purpose: 17748 * Enable/Disable true egress mirroring for a given port. 17749 * Parameters: 17750 * unit - (IN) BCM unit # 17751 * port - (IN) Port number (0 based) 17752 * enable - (IN) Bitmap of true egress mirrors enabled. 17753 * Returns: 17754 * BCM_E_NONE 17755 * BCM_E_INTERNAL 17756 */ 17757 17758 int 17759 _bcm_port_mirror_egress_true_enable_set(int unit, bcm_port_t port, 17760 int enable) 17761 { 17762 int rv = BCM_E_NONE; 17763 17764 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17765 17766 PORT_LOCK(unit); 17767 17768 #if defined(BCM_TRIUMPH3_SUPPORT) 17769 if (soc_feature(unit, soc_feature_ep_redirect) || 17770 soc_feature(unit, soc_feature_ep_redirect_v2)) { 17771 17772 uint32 egr_port_vals[2]; 17773 soc_field_t egr_port_fields[2]; 17774 17775 /* Based on if the device support version 2 of redirect, 17776 select the appropriate fields */ 17777 if (soc_feature(unit, soc_feature_ep_redirect_v2)) { 17778 egr_port_fields[0] = ER_REDIR_DEST_TYPEf; 17779 egr_port_fields[1] = ER_REDIR_DESTINATIONf; 17780 } else { 17781 egr_port_fields[0] = REDIRECTION_TYPEf; 17782 egr_port_fields[1] = REDIRECTION_DESTINATIONf; 17783 } 17784 17785 egr_port_vals[0] = 17786 (0 != enable) ? SOC_EPT_REDIRECT_MIRROR : SOC_EPT_REDIRECT_NOOP; 17787 egr_port_vals[1] = enable; 17788 17789 /* Egress port table */ 17790 rv = soc_mem_fields32_modify(unit, EGR_PORTm, port, 2, 17791 egr_port_fields, egr_port_vals); 17792 17793 /* If ep-redirect-v2 also set the action, always-redirect vs do-not-redirect */ 17794 if(rv == BCM_E_NONE) { 17795 if (soc_feature(unit, soc_feature_ep_redirect_v2)) { 17796 rv = soc_mem_field32_modify(unit, EGR_PORTm, 17797 port, ER_REDIR_ACTIONf, 17798 (enable ? _BCM_REDIRECT_ALWAYS : _BCM_REDIRECT_NONE)); 17799 } 17800 } 17801 17802 } else 17803 #endif /* BCM_TRIUMPH3_SUPPORT */ 17804 17805 { 17806 rv = soc_reg_field32_modify(unit, EGR_PORT_64r, port, 17807 MIRRORf, enable); 17808 if (BCM_SUCCESS(rv) && IS_HG_PORT(unit, port)) { 17809 rv = soc_reg_field32_modify(unit, IEGR_PORT_64r, port, 17810 MIRRORf, enable); 17811 } 17812 } 17813 17814 PORT_UNLOCK(unit); 17815 return rv; 17816 } 17817 #endif /* BCM_TRIUMPH2_SUPPORT */ 17818 17819 /* 17820 * Function: 17821 * bcm_port_linkscan_get 17822 * Purpose: 17823 * Get the link scan state of the port 17824 * Parameters: 17825 * unit - StrataSwitch Unit #. 17826 * port - StrataSwitch port #. 17827 * linkscan - (OUT) Linkscan value (None, S/W, H/W) 17828 * Returns: 17829 * BCM_E_NONE 17830 * BCM_E_XXX 17831 */ 17832 17833 int 17834 bcm_esw_port_linkscan_get(int unit, bcm_port_t port, int *linkscan) 17835 { 17836 /* Make sure port module is initialized. */ 17837 PORT_INIT(unit); 17838 17839 return bcm_esw_linkscan_mode_get(unit, port, linkscan); 17840 } 17841 17842 /* 17843 * Function: 17844 * bcm_port_linkscan_set 17845 * Purpose: 17846 * Set the linkscan state for a given port 17847 * Parameters: 17848 * unit - StrataSwitch Unit #. 17849 * port - StrataSwitch port #. 17850 * linkscan - Linkscan value (None, S/W, H/W) 17851 * Returns: 17852 * BCM_E_NONE 17853 * BCM_E_XXX 17854 */ 17855 17856 int 17857 bcm_esw_port_linkscan_set(int unit, bcm_port_t port, int linkscan) 17858 { 17859 /* Make sure port module is initialized. */ 17860 PORT_INIT(unit); 17861 17862 if(bcm_common_oamp_port_enable_get(unit, port)) { 17863 LOG_ERROR(BSL_LS_BCM_PORT, 17864 (BSL_META("Error: Cannot enable linkscan on OAMP Port %d.\n"), 17865 port)); 17866 return BCM_E_PARAM; 17867 } 17868 17869 return bcm_esw_linkscan_mode_set(unit, port, linkscan); 17870 } 17871 17872 /* 17873 * Function: 17874 * bcm_port_autoneg_get 17875 * Purpose: 17876 * Get the autonegotiation state of the port 17877 * Parameters: 17878 * unit - StrataSwitch Unit #. 17879 * port - StrataSwitch port #. 17880 * autoneg - (OUT) Boolean value 17881 * Returns: 17882 * BCM_E_NONE 17883 * BCM_E_XXX 17884 */ 17885 17886 int 17887 bcm_esw_port_autoneg_get(int unit, bcm_port_t port, int *autoneg) 17888 { 17889 int done=0, rv=BCM_E_NONE; 17890 int phy_lane = -1; 17891 int phyn = 0, sys_side = 0; 17892 bcm_port_t local_port = -1; 17893 #if defined(BCM_KATANA2_SUPPORT) 17894 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 17895 #endif 17896 17897 /* Make sure port module is initialized. */ 17898 PORT_INIT(unit); 17899 17900 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 17901 return bcmi_esw_portctrl_autoneg_get(unit, port, autoneg); 17902 } 17903 17904 #if defined(BCM_KATANA2_SUPPORT) 17905 #if defined(BCM_SABER2_SUPPORT) 17906 if(SOC_IS_SABER2(unit)) { 17907 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 17908 } 17909 #endif 17910 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 17911 (!((port >= 1) && (port <= max_phy_port)))) { 17912 return BCM_E_PORT; 17913 } 17914 #endif 17915 17916 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port, 17917 &local_port, &phyn, &phy_lane, &sys_side)); 17918 17919 if (local_port == -1) { 17920 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17921 } 17922 17923 PORT_LOCK(unit); 17924 if (local_port == -1) { 17925 rv = soc_phyctrl_auto_negotiate_get(unit, port, autoneg, &done); 17926 } else { 17927 rv = soc_phyctrl_redirect_auto_negotiate_get(unit, local_port, phyn, 17928 phy_lane, sys_side, 17929 autoneg, &done); 17930 } 17931 PORT_UNLOCK(unit); 17932 LOG_INFO(BSL_LS_BCM_PORT, 17933 (BSL_META_U(unit, 17934 "bcm_port_autoneg_get: u=%d p=%d an=%d done=%d rv=%d\n"), 17935 unit, port, *autoneg, done, rv)); 17936 17937 return rv; 17938 } 17939 17940 /* 17941 * Function: 17942 * bcm_port_autoneg_set 17943 * Purpose: 17944 * Set the autonegotiation state for a given port 17945 * Parameters: 17946 * unit - StrataSwitch Unit #. 17947 * port - StrataSwitch port #. 17948 * autoneg - Boolean value 17949 * Returns: 17950 * BCM_E_NONE 17951 * BCM_E_XXX 17952 */ 17953 17954 int 17955 bcm_esw_port_autoneg_set(int unit, bcm_port_t port, int autoneg) 17956 { 17957 int rv=BCM_E_NONE; 17958 int phy_lane = -1; 17959 int phyn = 0, sys_side = 0; 17960 bcm_port_t local_port = -1; 17961 17962 #if defined(BCM_SABER2_SUPPORT) 17963 int phy_status; 17964 #endif 17965 #if defined(BCM_KATANA2_SUPPORT) 17966 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 17967 #endif 17968 17969 /* Make sure port module is initialized. */ 17970 PORT_INIT(unit); 17971 17972 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 17973 return bcmi_esw_portctrl_autoneg_set(unit, port, autoneg); 17974 } 17975 17976 if(bcm_common_oamp_port_enable_get(unit, port)) { 17977 LOG_ERROR(BSL_LS_BCM_PORT, 17978 (BSL_META("Error: Cannot set autoneg on OAMP Port %d.\n"), 17979 port)); 17980 return BCM_E_PARAM; 17981 } 17982 17983 #if defined(BCM_KATANA2_SUPPORT) 17984 #if defined(BCM_SABER2_SUPPORT) 17985 if(SOC_IS_SABER2(unit)) { 17986 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 17987 } 17988 #endif 17989 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 17990 (!((port >= 1) && (port <= max_phy_port)))) { 17991 return BCM_E_PORT; 17992 } 17993 #endif 17994 #ifdef BCM_RCPU_SUPPORT 17995 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 17996 return BCM_E_PORT; 17997 } 17998 #endif /* BCM_RCPU_SUPPORT */ 17999 18000 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port, 18001 &local_port, &phyn, &phy_lane, &sys_side)); 18002 18003 if (local_port == -1) { 18004 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18005 } 18006 18007 PORT_LOCK(unit); 18008 18009 #if defined(BCM_SABER2_SUPPORT) 18010 if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) { 18011 rv = soc_phyctrl_enable_get(unit, port, &phy_status); 18012 if (BCM_FAILURE(rv)) { 18013 PORT_UNLOCK(unit); 18014 return (rv); 18015 } 18016 if(phy_status == TRUE) { 18017 rv = soc_phyctrl_enable_set(unit, port, FALSE); 18018 if (BCM_FAILURE(rv)) { 18019 PORT_UNLOCK(unit); 18020 return (rv); 18021 } 18022 } 18023 } 18024 #endif 18025 18026 #ifdef SW_AUTONEG_SUPPORT 18027 if (soc_feature(unit, soc_feature_sw_autoneg)) { 18028 18029 int an_mode = 0; 18030 18031 an_mode = soc_property_port_get(unit, port, 18032 spn_PHY_AN_C73, an_mode); 18033 18034 /* phy_an_c73 value of 3 indicated MSA AN mode */ 18035 if ((an_mode == SW_AN_MODE_CL73_MSA) || 18036 (an_mode == SW_AN_MODE_MSA_ONLY)) { 18037 if (autoneg) { 18038 rv = bcm_sw_an_port_register(unit, port); 18039 if (rv == BCM_E_NONE) { 18040 PORT_UNLOCK(unit); 18041 return rv; 18042 } else if (rv == BCM_E_PORT) { 18043 /* when an_set is called during the init 18044 * ports wouldn't have been added to SW AN 18045 */ 18046 rv = BCM_E_NONE; 18047 PORT_UNLOCK(unit); 18048 return rv; 18049 } else { 18050 /* add bsl log */ 18051 PORT_UNLOCK(unit); 18052 return rv; 18053 } 18054 18055 } else { 18056 rv = bcm_sw_an_port_unregister(unit, port); 18057 if (rv == BCM_E_NONE) { 18058 PORT_UNLOCK(unit); 18059 return rv; 18060 } else if (rv == BCM_E_PORT) { 18061 /* when an_set is called during the init 18062 * ports wouldn't have been added to SW AN 18063 */ 18064 rv = BCM_E_NONE; 18065 PORT_UNLOCK(unit); 18066 return rv; 18067 } else { 18068 /* add bsl log */ 18069 PORT_UNLOCK(unit); 18070 return rv; 18071 } 18072 } 18073 } 18074 } 18075 #endif 18076 18077 if (local_port == -1) { 18078 rv = soc_phyctrl_auto_negotiate_set(unit, port, autoneg); 18079 } else { 18080 rv = soc_phyctrl_redirect_auto_negotiate_set(unit, local_port, phyn, 18081 phy_lane, sys_side, autoneg); 18082 } 18083 18084 #if defined(BCM_SABER2_SUPPORT) 18085 if(SOC_IS_SABER2(unit) && 18086 IS_XL_PORT(unit, port) && (phy_status == TRUE)) { 18087 /* Enable phy in tsc only if already enabled before config change */ 18088 rv = soc_phyctrl_enable_set(unit, port, TRUE); 18089 if (BCM_FAILURE(rv)) { 18090 PORT_UNLOCK(unit); 18091 return (rv); 18092 } 18093 } 18094 #endif 18095 18096 #if defined(BCM_XMAC_SUPPORT) 18097 if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) || 18098 SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 18099 uint32 vco_disturbed = 0; 18100 phy_ctrl_t *int_pc; 18101 if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) || 18102 IS_XE_PORT(unit, port))) { 18103 int_pc = INT_PHY_SW_STATE(unit, port); 18104 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed); 18105 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) { 18106 PORT_UNLOCK(unit); 18107 return rv; 18108 } 18109 if (vco_disturbed) { 18110 rv = _mac_x_reinit(unit, port); 18111 if (BCM_FAILURE(rv)) { 18112 PORT_UNLOCK(unit); 18113 return rv; 18114 } 18115 } 18116 } 18117 } 18118 #endif 18119 PORT_UNLOCK(unit); 18120 18121 LOG_INFO(BSL_LS_BCM_PORT, 18122 (BSL_META_U(unit, 18123 "bcm_port_autoneg_set: u=%d p=%d an=%d rv=%d\n"), 18124 unit, port, autoneg, rv)); 18125 18126 return rv; 18127 } 18128 18129 /* 18130 * Function: 18131 * bcm_port_speed_get 18132 * Purpose: 18133 * Getting the speed of the port 18134 * Parameters: 18135 * unit - StrataSwitch Unit #. 18136 * port - StrataSwitch port #. 18137 * speed - (OUT) Value in megabits/sec (10, 100, etc) 18138 * Returns: 18139 * BCM_E_NONE 18140 * BCM_E_XXX 18141 * Notes: 18142 * If port is in MAC loopback, the speed of the loopback is returned. 18143 */ 18144 18145 int 18146 bcm_esw_port_speed_get(int unit, bcm_port_t port, int *speed) 18147 { 18148 int rv = BCM_E_NONE; 18149 int mac_lb; 18150 int max_speed; 18151 #if defined(BCM_KATANA2_SUPPORT) 18152 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18153 #endif 18154 18155 /* Make sure port module is initialized. */ 18156 PORT_INIT(unit); 18157 18158 /* Check for PortMod */ 18159 if (SOC_PORT_USE_PORTCTRL(unit, port) && (port != CMIC_PORT(unit))) { 18160 return bcmi_esw_portctrl_speed_get(unit, port, speed); 18161 } 18162 18163 #if defined(BCM_KATANA2_SUPPORT) 18164 #if defined(BCM_SABER2_SUPPORT) 18165 if(SOC_IS_SABER2(unit)) { 18166 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18167 } 18168 #endif 18169 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18170 (!((port >= 1) && (port <= max_phy_port) && 18171 SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)))) { 18172 return BCM_E_PORT; 18173 } 18174 #endif 18175 18176 if(bcm_common_oamp_port_enable_get(unit, port)) { 18177 LOG_ERROR(BSL_LS_BCM_PORT, 18178 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 18179 port)); 18180 return BCM_E_PARAM; 18181 } 18182 18183 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18184 18185 PORT_LOCK(unit); 18186 18187 rv = MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb); 18188 18189 if (BCM_SUCCESS(rv)) { 18190 if (mac_lb) { 18191 rv = MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, speed); 18192 } else { 18193 rv = soc_phyctrl_speed_get(unit, port, speed); 18194 18195 if (BCM_E_UNAVAIL == rv) { 18196 /* PHY driver doesn't support speed_get. Get the speed from 18197 * MAC. 18198 */ 18199 rv = MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, speed); 18200 } 18201 if ((IS_HG_PORT(unit, port) && *speed < 5000) && !(IS_HL_PORT(unit,port))) { 18202 *speed = 0; 18203 } 18204 if (soc_feature(unit, soc_feature_port_encap_speed_max_config)) { 18205 rv = bcm_esw_port_speed_max(unit, port, &max_speed); 18206 if (BCM_FAILURE(rv)) { 18207 PORT_UNLOCK(unit); 18208 return (rv); 18209 } 18210 if (*speed > max_speed) { 18211 *speed = max_speed; 18212 } 18213 } 18214 } 18215 } 18216 18217 PORT_UNLOCK(unit); 18218 18219 LOG_INFO(BSL_LS_BCM_PORT, 18220 (BSL_META_U(unit, 18221 "bcm_port_speed_get: u=%d p=%d speed=%d rv=%d\n"), 18222 unit, port, BCM_SUCCESS(rv) ? *speed : 0, rv)); 18223 18224 return rv; 18225 } 18226 18227 /* 18228 * Function: 18229 * bcm_port_speed_max 18230 * Purpose: 18231 * Getting the maximum speed of the port 18232 * Parameters: 18233 * unit - StrataSwitch Unit #. 18234 * port - StrataSwitch port #. 18235 * speed - (OUT) Value in megabits/sec (10, 100, etc) 18236 * Returns: 18237 * BCM_E_NONE 18238 * BCM_E_XXX 18239 */ 18240 18241 int 18242 bcm_esw_port_speed_max(int unit, bcm_port_t port, int *speed) 18243 { 18244 bcm_port_ability_t ability, phy_ability; 18245 int rv; 18246 int phy_speed; 18247 #if defined(BCM_KATANA2_SUPPORT) 18248 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18249 #endif 18250 18251 if (NULL == speed) { 18252 return (BCM_E_PARAM); 18253 } 18254 18255 /* Make sure port module is initialized. */ 18256 PORT_INIT(unit); 18257 18258 18259 /* Check for PortMod */ 18260 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 18261 return bcmi_esw_portctrl_speed_max(unit, port, speed); 18262 } 18263 18264 #if defined(BCM_KATANA2_SUPPORT) 18265 #if defined(BCM_SABER2_SUPPORT) 18266 if(SOC_IS_SABER2(unit)) { 18267 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18268 } 18269 #endif 18270 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18271 (!((port >= 1) && (port <= max_phy_port)))) { 18272 return BCM_E_PORT; 18273 } 18274 #endif 18275 18276 if(bcm_common_oamp_port_enable_get(unit, port)) { 18277 LOG_ERROR(BSL_LS_BCM_PORT, 18278 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 18279 port)); 18280 return BCM_E_PARAM; 18281 } 18282 18283 18284 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18285 rv = bcm_esw_port_ability_local_get(unit, port, &ability); 18286 18287 if (BCM_SUCCESS(rv)) { 18288 18289 *speed = BCM_PORT_ABILITY_SPEED_MAX(ability.speed_full_duplex | 18290 ability.speed_half_duplex); 18291 18292 if (10000 == *speed) { 18293 if (IS_HG_PORT(unit, port) && SOC_INFO(unit).port_speed_max[port]) { 18294 *speed = SOC_INFO(unit).port_speed_max[port]; 18295 /* Retrieving the internal PHY ability */ 18296 rv = soc_phyctrl_ability_local_get(unit, port, &phy_ability); 18297 if (BCM_SUCCESS(rv)) { 18298 /* considering the common supported speed among phy and mac */ 18299 phy_speed = BCM_PORT_ABILITY_SPEED_MAX( 18300 phy_ability.speed_full_duplex | 18301 phy_ability.speed_half_duplex); 18302 *speed = (*speed > phy_speed) ? phy_speed : *speed; 18303 } else { 18304 *speed = 0; 18305 } 18306 } 18307 } 18308 } else { 18309 *speed = 0; 18310 } 18311 18312 LOG_INFO(BSL_LS_BCM_PORT, 18313 (BSL_META_U(unit, 18314 "bcm_port_speed_max: u=%d p=%d speed=%d rv=%d\n"), 18315 unit, port, *speed, rv)); 18316 18317 return rv; 18318 } 18319 18320 /* 18321 * Function : _bcm_port_speed_supported 18322 * Description : Determine whether port speed is supported based on 18323 * number of lanes configured 18324 * Parameters : unit (IN) 18325 * port (IN) 18326 * speed (IN) 18327 * Returns : BCM_E_XXX 18328 * Note : Caller needs to ensure soc_feature_flexport_based_speed_set 18329 * is defined 18330 */ 18331 STATIC bcm_error_t 18332 _bcm_port_speed_supported(int unit, bcm_port_t port, int speed) 18333 { 18334 #ifdef BCM_TOMAHAWK_SUPPORT 18335 if (SOC_IS_TOMAHAWKX(unit)) { 18336 BCM_IF_ERROR_RETURN(_bcm_th_port_speed_supported(unit, port, speed)); 18337 } 18338 #endif 18339 return BCM_E_NONE; 18340 } 18341 18342 /* 18343 * Function: 18344 * _bcm_port_speed_set 18345 * Purpose: 18346 * Main part of bcm_port_speed_set. 18347 */ 18348 18349 STATIC int 18350 _bcm_port_speed_set(int unit, bcm_port_t port, int speed) 18351 { 18352 int phy_lb, rv, enable; 18353 int mac_lb; 18354 int ignore_ability_check = FALSE; 18355 bcm_port_ability_t mac_ability, phy_ability, requested_ability; 18356 #if defined(BCM_SABER2_SUPPORT) 18357 int phy_status; 18358 #endif 18359 18360 #if defined(BCM_TOMAHAWK_SUPPORT) 18361 int cur_speed; 18362 #endif 18363 #if defined(BCM_KATANA2_SUPPORT) 18364 bcmMxqPhyPortMode_t phy_mode = bcmMxqPhyPortModeQuad; 18365 #endif 18366 18367 18368 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 18369 return bcmi_esw_portctrl_speed_set(unit, port, speed); 18370 } 18371 18372 if(bcm_common_oamp_port_enable_get(unit, port)) { 18373 LOG_ERROR(BSL_LS_BCM_PORT, 18374 (BSL_META("Error: Cannot set speed on OAMP Port %d.\n"), 18375 port)); 18376 return BCM_E_PARAM; 18377 } 18378 18379 sal_memset(&mac_ability, 0, sizeof(bcm_port_ability_t)); 18380 sal_memset(&phy_ability, 0, sizeof(bcm_port_ability_t)); 18381 sal_memset(&requested_ability, 0, sizeof(bcm_port_ability_t)); 18382 18383 /* 18384 * If port is in MAC loopback mode, do not try setting the PHY 18385 * speed. This allows MAC loopback at 10/100 even if the PHY is 18386 * 1000 only. Loopback diagnostic tests should enable loopback 18387 * before setting the speed, and vice versa when cleaning up. 18388 */ 18389 18390 SOC_IF_ERROR_RETURN 18391 (MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb)); 18392 18393 if (speed == 0) { 18394 /* if speed is 0, set the port speed to max */ 18395 SOC_IF_ERROR_RETURN 18396 (bcm_esw_port_speed_max(unit, port, &speed)); 18397 } 18398 18399 /* Make sure MAC can handle the requested speed. */ 18400 SOC_IF_ERROR_RETURN 18401 (MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit, port, 18402 &mac_ability)); 18403 requested_ability.speed_full_duplex = SOC_PA_SPEED(speed); 18404 requested_ability.speed_half_duplex = SOC_PA_SPEED(speed); 18405 LOG_INFO(BSL_LS_BCM_PHY, 18406 (BSL_META_U(unit, 18407 "_bcm_port_speed_set: u=%u p=%d " 18408 "MAC FD speed %08X MAC HD speed %08X " 18409 "Requested FD Speed %08X Requested HD Speed %08X\n"), 18410 unit, 18411 port, 18412 mac_ability.speed_full_duplex, 18413 mac_ability.speed_half_duplex, 18414 requested_ability.speed_full_duplex, 18415 requested_ability.speed_half_duplex)); 18416 /* 18417 * On certain devices such as TH speed set is a flexport operation, 18418 * due to changes needed to the calendar. This is not applicable to 18419 * mgmt ports on TH as they are guranteed a fixed amount of BW in the 18420 * calendar. 18421 */ 18422 if ((soc_feature(unit, soc_feature_flexport_based_speed_set)) && 18423 !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port)) { 18424 rv = _bcm_port_speed_supported(unit, port, speed); 18425 if (BCM_SUCCESS(rv)) { 18426 ignore_ability_check = TRUE; 18427 } 18428 } 18429 18430 #if defined(BCM_TOMAHAWK_SUPPORT) 18431 if (SOC_IS_TOMAHAWK(unit)) { 18432 int encap; 18433 BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, port, &encap)); 18434 18435 if (IS_HG2_SPEED(speed) && (encap == BCM_PORT_ENCAP_IEEE)) { 18436 LOG_ERROR(BSL_LS_BCM_PORT, 18437 (BSL_META_U(unit, 18438 "Speed and encapsulation configuration unmatch " 18439 "for port=%d, speed=%d, encap=%d\n"), 18440 port, speed, encap)); 18441 return BCM_E_CONFIG; 18442 } 18443 } 18444 #endif 18445 18446 if (((mac_ability.speed_full_duplex & 18447 requested_ability.speed_full_duplex) == 0) && 18448 ((mac_ability.speed_half_duplex & 18449 requested_ability.speed_half_duplex) == 0) && 18450 !ignore_ability_check) { 18451 LOG_ERROR(BSL_LS_BCM_PORT, 18452 (BSL_META_U(unit, 18453 "u=%d p=%d MAC doesn't support %d Mbps speed.\n"), 18454 unit, port, speed)); 18455 return SOC_E_CONFIG; 18456 } 18457 SOC_IF_ERROR_RETURN 18458 (soc_phyctrl_ability_local_get(unit, port, &phy_ability)); 18459 18460 if (((phy_ability.speed_full_duplex & 18461 requested_ability.speed_full_duplex) == 0) && 18462 ((phy_ability.speed_half_duplex & 18463 requested_ability.speed_half_duplex) == 0) && 18464 !ignore_ability_check) { 18465 LOG_VERBOSE(BSL_LS_BCM_PORT, 18466 (BSL_META_U(unit, 18467 "u=%d p=%d PHY doesn't support %d Mbps speed.\n"), 18468 unit, port, speed)); 18469 return SOC_E_CONFIG; 18470 } else { 18471 18472 #if defined(BCM_SABER2_SUPPORT) 18473 if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) { 18474 BCM_IF_ERROR_RETURN(soc_phyctrl_enable_get(unit, port, &phy_status)); 18475 if(phy_status == TRUE) { 18476 BCM_IF_ERROR_RETURN(soc_phyctrl_enable_set(unit, port, FALSE)); 18477 } 18478 } 18479 #endif 18480 18481 #if defined(BCM_TOMAHAWK_SUPPORT) 18482 if (SOC_IS_TOMAHAWKX(unit)) { 18483 SOC_IF_ERROR_RETURN 18484 (soc_phyctrl_speed_get(unit, port, &cur_speed)); 18485 } 18486 #endif 18487 #if defined(BCM_KATANA2_SUPPORT) 18488 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 18489 SOC_IF_ERROR_RETURN 18490 (soc_katana2_get_phy_port_mode(unit, port, speed, &phy_mode)); 18491 } 18492 #endif 18493 SOC_IF_ERROR_RETURN 18494 (soc_phyctrl_auto_negotiate_set(unit, port, FALSE)); 18495 SOC_IF_ERROR_RETURN 18496 (soc_phyctrl_speed_set(unit, port, speed)); 18497 18498 #if defined(BCM_SABER2_SUPPORT) 18499 if(SOC_IS_SABER2(unit) && 18500 IS_XL_PORT(unit, port) && (phy_status == TRUE)) { 18501 /* Enable phy in tsc only if already enabled before config change */ 18502 BCM_IF_ERROR_RETURN(soc_phyctrl_enable_set(unit, port, TRUE)); 18503 } 18504 #endif 18505 18506 #if defined(BCM_XMAC_SUPPORT) 18507 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) || 18508 SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 18509 uint32 vco_disturbed = 0; 18510 phy_ctrl_t *int_pc; 18511 if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) || 18512 IS_XE_PORT(unit, port))) { 18513 18514 int_pc = INT_PHY_SW_STATE(unit, port); 18515 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed); 18516 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) { 18517 return rv; 18518 } 18519 if (vco_disturbed) { 18520 BCM_IF_ERROR_RETURN(_mac_x_reinit(unit, port)); 18521 } 18522 } 18523 } 18524 #endif 18525 } 18526 18527 /* TSC needs no legacy war */ 18528 if (!SOC_IS_TD2_TT2(unit)) { 18529 /* Prevent PHY register access while resetting BigMAC and Fusion core */ 18530 if (IS_HG_PORT(unit, port)) { 18531 soc_phyctrl_enable_get(unit, port, &enable); 18532 soc_phyctrl_enable_set(unit, port, 0); 18533 soc_phyctrl_loopback_get(unit, port, &phy_lb); 18534 } 18535 } 18536 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 18537 BCM_IF_ERROR_RETURN(_bcm_td_port_mode_update(unit, port, speed)); 18538 } 18539 18540 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 18541 /* Reconfigure chip(PGW/TDM/IP/EP/MMU) for speed set change */ 18542 if (BCM_ESW_PORT_DRV(unit)!= NULL && 18543 !(SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port))) { 18544 if (BCM_ESW_PORT_DRV(unit)->resource_speed_set != NULL) { 18545 rv = BCM_ESW_PORT_DRV(unit)->resource_speed_set(unit, port, speed); 18546 if (BCM_FAILURE(rv)) { 18547 LOG_VERBOSE(BSL_LS_BCM_PORT, 18548 (BSL_META_UP(unit, port, 18549 "resource_speed_set failed: %s\n"), 18550 bcm_errmsg(rv))); 18551 return rv; 18552 } 18553 } 18554 } 18555 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT*/ 18556 18557 rv = MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, speed); 18558 if (BCM_FAILURE(rv)) { 18559 #if defined(BCM_TOMAHAWK_SUPPORT) 18560 if (SOC_IS_TOMAHAWKX(unit)) { 18561 /* Restore phy's speed state based on what was read periously */ 18562 SOC_IF_ERROR_RETURN 18563 (soc_phyctrl_speed_set(unit, port, cur_speed)); 18564 } 18565 #endif 18566 18567 LOG_VERBOSE(BSL_LS_BCM_PORT, 18568 (BSL_META_U(unit, 18569 "MAC_SPEED_SET failed: %s\n"), bcm_errmsg(rv))); 18570 } 18571 18572 if (!SOC_IS_MONTEREY(unit)) { 18573 /* TSC needs no legacy war */ 18574 if (!SOC_IS_TD2_TT2(unit)) { 18575 /* Restore PHY register access */ 18576 if (IS_HG_PORT(unit, port)) { 18577 soc_phyctrl_enable_set(unit, port, enable); 18578 soc_phyctrl_loopback_set(unit, port, phy_lb, TRUE); 18579 } 18580 } 18581 } 18582 18583 return rv; 18584 } 18585 18586 /* 18587 * Function: 18588 * bcm_port_speed_set 18589 * Purpose: 18590 * Setting the speed for a given port 18591 * Parameters: 18592 * unit - StrataSwitch Unit #. 18593 * port - StrataSwitch port #. 18594 * speed - Value in megabits/sec (10, 100, etc) 18595 * Returns: 18596 * BCM_E_NONE 18597 * BCM_E_XXX 18598 * Notes: 18599 * Turns off autonegotiation. Caller must make sure other forced 18600 * parameters (such as duplex) are set. 18601 */ 18602 18603 int 18604 bcm_esw_port_speed_set(int unit, bcm_port_t port, int speed) 18605 { 18606 int rv=BCM_E_NONE, max_speed, enable, rv1 = BCM_E_NONE; 18607 pbmp_t pbm; 18608 int curr_speed = 0; 18609 bcm_port_if_t curr_intf = 0; 18610 #if defined(BCM_KATANA2_SUPPORT) 18611 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18612 #endif 18613 18614 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK) 18615 sal_usecs_t time_start = 0; 18616 sal_usecs_t time_end = 0; 18617 #endif 18618 18619 /* Make sure port module is initialized. */ 18620 PORT_INIT(unit); 18621 18622 #if defined(BCM_TOMAHAWK3_SUPPORT) 18623 /* Don't allow PM8x50 to do bcm_port_speed_set */ 18624 if (SOC_IS_TOMAHAWK3(unit) && IS_CD_PORT(unit, port)) { 18625 return BCM_E_UNAVAIL; 18626 } 18627 #endif 18628 18629 if(bcm_common_oamp_port_enable_get(unit, port)) { 18630 LOG_ERROR(BSL_LS_BCM_PORT, 18631 (BSL_META("Error: Cannot set speed on OAMP Port %d.\n"), 18632 port)); 18633 return BCM_E_PARAM; 18634 } 18635 18636 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK) 18637 time_start = sal_time_usecs(); 18638 #endif 18639 18640 #if defined(BCM_KATANA2_SUPPORT) 18641 #if defined(BCM_SABER2_SUPPORT) 18642 if(SOC_IS_SABER2(unit)) { 18643 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18644 } 18645 #endif 18646 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18647 (!((port >= 1) && (port <= max_phy_port)))) { 18648 return BCM_E_PORT; 18649 } 18650 #endif 18651 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18652 18653 #if defined(BCM_FIREBOLT6_SUPPORT) 18654 if (SOC_IS_FIREBOLT6(unit)) { 18655 if (!(SAL_BOOT_SIMULATION)) { 18656 /* Validate speeds based on OTP. */ 18657 if (_soc_fb6_port_speed_validate(unit, port, -1, -1, -1, speed)) { 18658 return BCM_E_CONFIG; 18659 } 18660 } 18661 } 18662 #endif 18663 18664 if (soc_property_get(unit, spn_SAME_SPEED_INTF_DO_NOT_OVERWRITE, 18665 (SAL_BOOT_BCMSIM || SAL_BOOT_XGSSIM))) { 18666 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &curr_speed)); 18667 BCM_IF_ERROR_RETURN(bcm_esw_port_interface_get(unit, port, &curr_intf)); 18668 if((speed == curr_speed) && (PORT(unit, port).intf == curr_intf)) { 18669 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK) 18670 time_end = SAL_USECS_SUB(sal_time_usecs(), time_start); 18671 LOG_INFO(BSL_LS_BCM_BENCHMARK, 18672 (BSL_META_U(unit, 18673 "\nPort %d speed change to %d processing took %d usecs\n"), 18674 port, 18675 speed, 18676 time_end)); 18677 #endif 18678 return BCM_E_NONE; 18679 } 18680 } 18681 18682 #ifdef BCM_RCPU_SUPPORT 18683 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 18684 return BCM_E_PORT; 18685 } 18686 #endif /* BCM_RCPU_SUPPORT */ 18687 18688 /* coverity[uninit_use_in_call : FALSE] */ 18689 BCM_IF_ERROR_RETURN 18690 (bcm_esw_port_speed_max(unit,port, &max_speed)); 18691 18692 if (IS_XL_PORT(unit,port) && (speed == 12700)) { 18693 speed = 13000; 18694 } 18695 18696 if ((speed < 0) || (speed > max_speed)) { 18697 if ((speed > max_speed) && 18698 !soc_feature(unit, soc_feature_flexport_based_speed_set)) 18699 return BCM_E_CONFIG; 18700 } 18701 18702 #if defined(BCM_TOMAHAWK_SUPPORT) 18703 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit)) { 18704 int cur_speed; 18705 18706 BCM_IF_ERROR_RETURN 18707 (bcm_esw_port_speed_get(unit, port, &cur_speed)); 18708 if ((speed == 0) && (max_speed == cur_speed)) { 18709 /* no speed set is required */ 18710 return BCM_E_NONE; 18711 } 18712 } 18713 #endif /* BCM_TOMAHAWK_SUPPORT */ 18714 18715 /* 18716 * When performing flexport based speed changes, disable port 18717 * first prior to affecting speed change 18718 */ 18719 if (soc_feature(unit, soc_feature_flexport_based_speed_set) && 18720 !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port) && 18721 !SOC_PORT_USE_PORTCTRL(unit, port)) { 18722 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable)); 18723 if (TRUE == enable) { 18724 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, FALSE)); 18725 } 18726 } 18727 18728 PORT_LOCK(unit); /* multiple operations operation */ 18729 18730 rv = _bcm_port_speed_set(unit, port, speed); 18731 PORT_UNLOCK(unit); /* Unlock before link call */ 18732 /* 18733 * Restore port's enable state based on what was read prior 18734 * to setting speed 18735 */ 18736 if (soc_feature(unit, soc_feature_flexport_based_speed_set) && 18737 !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port) && 18738 !SOC_PORT_USE_PORTCTRL(unit, port)) { 18739 if (TRUE == enable) { 18740 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, TRUE)); 18741 } 18742 } 18743 18744 if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) { 18745 SOC_PBMP_CLEAR(pbm); 18746 SOC_PBMP_PORT_ADD(pbm, port); 18747 (void)bcm_esw_link_change(unit, pbm); 18748 } 18749 PORT_LOCK(unit); /* multiple operations operation */ 18750 rv1 = _bcm_esw_port_link_delay_update(unit, port, speed); 18751 PORT_UNLOCK(unit); /* Unlock before link call */ 18752 if (BCM_FAILURE(rv1)) { 18753 if (BCM_SUCCESS(rv)) { 18754 rv = rv1; 18755 } 18756 } 18757 18758 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK) 18759 time_end = SAL_USECS_SUB(sal_time_usecs(), time_start); 18760 LOG_INFO(BSL_LS_BCM_BENCHMARK, 18761 (BSL_META_U(unit, 18762 "\nPort %d speed change to %d processing took %d usecs\n"), 18763 port, 18764 speed, 18765 time_end)); 18766 #endif 18767 18768 LOG_INFO(BSL_LS_BCM_PORT, 18769 (BSL_META_U(unit, 18770 "bcm_port_speed_set: u=%d p=%d speed=%d rv=%d\n"), 18771 unit, port, speed, rv)); 18772 18773 return rv; 18774 } 18775 18776 /* 18777 * Function: 18778 * bcm_port_master_get 18779 * Purpose: 18780 * Getting the master status of the port 18781 * Parameters: 18782 * unit - StrataSwitch Unit #. 18783 * port - StrataSwitch port #. 18784 * ms - (OUT) BCM_PORT_MS_* 18785 * Returns: 18786 * BCM_E_NONE 18787 * BCM_E_XXX 18788 * Notes: 18789 * WARNING: assumes BCM_PORT_MS_* matches SOC_PORT_MS_* 18790 */ 18791 18792 int 18793 bcm_esw_port_master_get(int unit, bcm_port_t port, int *ms) 18794 { 18795 int rv=BCM_E_NONE; 18796 #if defined(BCM_KATANA2_SUPPORT) 18797 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18798 #endif 18799 18800 /* Make sure port module is initialized. */ 18801 PORT_INIT(unit); 18802 18803 /* Call Port Control module */ 18804 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 18805 return bcmi_esw_portctrl_master_get(unit, port, ms); 18806 } 18807 18808 #if defined(BCM_KATANA2_SUPPORT) 18809 #if defined(BCM_SABER2_SUPPORT) 18810 if(SOC_IS_SABER2(unit)) { 18811 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18812 } 18813 #endif 18814 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18815 (!((port >= 1) && (port <= max_phy_port)))) { 18816 return BCM_E_PORT; 18817 } 18818 #endif 18819 18820 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18821 PORT_LOCK(unit); 18822 rv = soc_phyctrl_master_get(unit, port, ms); 18823 PORT_UNLOCK(unit); 18824 return rv; 18825 } 18826 18827 /* 18828 * Function: 18829 * bcm_port_master_set 18830 * Purpose: 18831 * Setting the master status for a given port 18832 * Parameters: 18833 * unit - StrataSwitch Unit #. 18834 * port - StrataSwitch port #. 18835 * ms - BCM_PORT_MS_* 18836 * Returns: 18837 * BCM_E_NONE 18838 * BCM_E_XXX 18839 * Notes: 18840 * Ignored if not supported on port. 18841 * WARNING: assumes BCM_PORT_MS_* matches SOC_PORT_MS_* 18842 */ 18843 18844 int 18845 bcm_esw_port_master_set(int unit, bcm_port_t port, int ms) 18846 { 18847 int rv; 18848 pbmp_t pbm; 18849 #if defined(BCM_KATANA2_SUPPORT) 18850 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18851 #endif 18852 18853 /* Make sure port module is initialized. */ 18854 PORT_INIT(unit); 18855 18856 /* Call Port Control module */ 18857 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 18858 return bcmi_esw_portctrl_master_set(unit, port, ms); 18859 } 18860 18861 if(bcm_common_oamp_port_enable_get(unit, port)) { 18862 LOG_ERROR(BSL_LS_BCM_PORT, 18863 (BSL_META("Error: Cannot configure OAMP Port %d to be master.\n"), 18864 port)); 18865 return BCM_E_PARAM; 18866 } 18867 18868 #if defined(BCM_KATANA2_SUPPORT) 18869 #if defined(BCM_SABER2_SUPPORT) 18870 if(SOC_IS_SABER2(unit)) { 18871 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18872 } 18873 #endif 18874 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18875 (!((port >= 1) && (port <= max_phy_port)))) { 18876 return BCM_E_PORT; 18877 } 18878 #endif 18879 18880 /* Make sure port module is initialized. */ 18881 PORT_INIT(unit); 18882 18883 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18884 18885 #ifdef BCM_RCPU_SUPPORT 18886 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 18887 return BCM_E_PORT; 18888 } 18889 #endif /* BCM_RCPU_SUPPORT */ 18890 18891 PORT_LOCK(unit); /* multiple operations operation */ 18892 18893 rv = soc_phyctrl_master_set(unit, port, ms); 18894 if (BCM_FAILURE(rv)) { 18895 LOG_VERBOSE(BSL_LS_BCM_PORT, 18896 (BSL_META_U(unit, 18897 "PHY_MASTER_SETfailed:%s\n"), bcm_errmsg(rv))); 18898 } 18899 18900 #if defined(BCM_XMAC_SUPPORT) 18901 if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) || 18902 SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 18903 uint32 vco_disturbed = 0; 18904 phy_ctrl_t *int_pc; 18905 if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) || 18906 IS_XE_PORT(unit, port))) { 18907 18908 int_pc = INT_PHY_SW_STATE(unit, port); 18909 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed); 18910 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) { 18911 PORT_UNLOCK(unit); 18912 return rv; 18913 } 18914 if (vco_disturbed) { 18915 rv = _mac_x_reinit(unit, port); 18916 if (BCM_FAILURE(rv)) { 18917 PORT_UNLOCK(unit); 18918 return rv; 18919 } 18920 } 18921 } 18922 } 18923 #endif 18924 PORT_UNLOCK(unit); /* Unlock before link call */ 18925 18926 if (BCM_SUCCESS(rv)) { 18927 SOC_PBMP_CLEAR(pbm); 18928 SOC_PBMP_PORT_ADD(pbm, port); 18929 (void)bcm_esw_link_change(unit, pbm); 18930 } 18931 18932 return rv; 18933 } 18934 18935 /* 18936 * Function: 18937 * bcm_port_interface_get 18938 * Purpose: 18939 * Getting the interface type of a port 18940 * Parameters: 18941 * unit - StrataSwitch Unit #. 18942 * port - StrataSwitch port #. 18943 * intf - (OUT) BCM_PORT_IF_* 18944 * Returns: 18945 * BCM_E_NONE 18946 * BCM_E_XXX 18947 * Notes: 18948 * WARNING: assumes BCM_PORT_IF_* matches SOC_PORT_IF_* 18949 */ 18950 18951 int 18952 bcm_esw_port_interface_get(int unit, bcm_port_t port, bcm_port_if_t *intf) 18953 { 18954 int rv=BCM_E_NONE; 18955 #if defined(BCM_KATANA2_SUPPORT) 18956 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18957 #endif 18958 18959 /* Make sure port module is initialized. */ 18960 PORT_INIT(unit); 18961 18962 /* Call Port Control module */ 18963 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 18964 return bcmi_esw_portctrl_interface_get(unit, port, intf); 18965 } 18966 18967 if(bcm_common_oamp_port_enable_get(unit, port)) { 18968 LOG_ERROR(BSL_LS_BCM_PORT, 18969 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 18970 port)); 18971 return BCM_E_PARAM; 18972 } 18973 18974 #if defined(BCM_KATANA2_SUPPORT) 18975 #if defined(BCM_SABER2_SUPPORT) 18976 if(SOC_IS_SABER2(unit)) { 18977 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18978 } 18979 #endif 18980 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18981 (!((port >= 1) && (port <= max_phy_port)))) { 18982 return BCM_E_PORT; 18983 } 18984 #endif 18985 18986 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18987 18988 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) { 18989 return BCM_E_PORT; 18990 } 18991 PORT_LOCK(unit); 18992 rv = soc_phyctrl_interface_get(unit, port, intf); 18993 PORT_UNLOCK(unit); 18994 return rv; 18995 } 18996 18997 /* 18998 * Function: 18999 * bcm_port_interface_set 19000 * Purpose: 19001 * Setting the interface type for a given port 19002 * Parameters: 19003 * unit - StrataSwitch Unit #. 19004 * port - StrataSwitch port #. 19005 * if - BCM_PORT_IF_* 19006 * Returns: 19007 * BCM_E_NONE 19008 * BCM_E_XXX 19009 * Notes: 19010 * WARNING: assumes BCM_PORT_IF_* matches SOC_PORT_IF_* 19011 */ 19012 19013 int 19014 bcm_esw_port_interface_set(int unit, bcm_port_t port, bcm_port_if_t intf) 19015 { 19016 int rv; 19017 pbmp_t pbm; 19018 #if defined(BCM_KATANA2_SUPPORT) 19019 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19020 #endif 19021 19022 /* Make sure port module is initialized. */ 19023 PORT_INIT(unit); 19024 19025 /* Call Port Control module */ 19026 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 19027 return bcmi_esw_portctrl_interface_set(unit, port, intf); 19028 } 19029 19030 if(bcm_common_oamp_port_enable_get(unit, port)) { 19031 LOG_ERROR(BSL_LS_BCM_PORT, 19032 (BSL_META( 19033 "Error: Cannot set interface type on OAMP Port %d.\n"), 19034 port)); 19035 return BCM_E_PARAM; 19036 } 19037 19038 #if defined(BCM_KATANA2_SUPPORT) 19039 #if defined(BCM_SABER2_SUPPORT) 19040 if(SOC_IS_SABER2(unit)) { 19041 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19042 } 19043 #endif 19044 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19045 (!((port >= 1) && (port <= max_phy_port)))) { 19046 return BCM_E_PORT; 19047 } 19048 #endif 19049 19050 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19051 19052 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) { 19053 return BCM_E_PORT; 19054 } 19055 19056 #ifdef BCM_RCPU_SUPPORT 19057 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 19058 return BCM_E_PORT; 19059 } 19060 #endif /* BCM_RCPU_SUPPORT */ 19061 19062 PORT_LOCK(unit); /* multiple operations operation */ 19063 19064 rv = soc_phyctrl_interface_set(unit, port, intf); 19065 if (BCM_FAILURE(rv)) { 19066 LOG_VERBOSE(BSL_LS_BCM_PORT, 19067 (BSL_META_U(unit, 19068 "PHY_INTERFACE_SETfailed:%s\n"), bcm_errmsg(rv))); 19069 } 19070 #if defined(BCM_XMAC_SUPPORT) 19071 if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) || 19072 SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 19073 uint32 vco_disturbed = 0; 19074 phy_ctrl_t *int_pc; 19075 if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) || 19076 IS_XE_PORT(unit, port))) { 19077 19078 int_pc = INT_PHY_SW_STATE(unit, port); 19079 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed); 19080 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) { 19081 PORT_UNLOCK(unit); 19082 return rv; 19083 } 19084 if (vco_disturbed) { 19085 rv = _mac_x_reinit(unit, port); 19086 if (BCM_FAILURE(rv)) { 19087 PORT_UNLOCK(unit); 19088 return rv; 19089 } 19090 } 19091 } 19092 } 19093 #endif 19094 19095 PORT_UNLOCK(unit); /* Unlock before link call */ 19096 19097 if (BCM_SUCCESS(rv)) { 19098 SOC_PBMP_CLEAR(pbm); 19099 SOC_PBMP_PORT_ADD(pbm, port); 19100 (void)bcm_esw_link_change(unit, pbm); 19101 PORT(unit, port).intf = intf; 19102 } 19103 19104 return rv; 19105 } 19106 19107 /* 19108 * Function: 19109 * bcm_port_loopback_set 19110 * Purpose: 19111 * Setting the speed for a given port 19112 * Parameters: 19113 * unit - StrataSwitch Unit #. 19114 * port - StrataSwitch port #. 19115 * loopback - one of: 19116 * BCM_PORT_LOOPBACK_NONE 19117 * BCM_PORT_LOOPBACK_MAC 19118 * BCM_PORT_LOOPBACK_PHY 19119 * Returns: 19120 * BCM_E_NONE 19121 * BCM_E_XXX 19122 */ 19123 19124 int 19125 bcm_esw_port_loopback_set(int unit, bcm_port_t port, int loopback) 19126 { 19127 int rv, link = TRUE; 19128 int phy_lane = -1; 19129 int phyn = 0, sys_side = 0; 19130 bcm_port_t local_port = -1; 19131 #if defined(BCM_TOMAHAWK_SUPPORT) 19132 uint32 link_st = 0; 19133 soc_timeout_t to; 19134 int phy_port; 19135 #endif 19136 soc_persist_t *sop = SOC_PERSIST(unit); 19137 19138 #ifdef BCM_TRIDENT2_SUPPORT 19139 int enable; 19140 #endif /* BCM_TRIDENT2_SUPPORT */ 19141 #if defined(BCM_KATANA2_SUPPORT) 19142 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19143 #endif 19144 19145 /* Make sure port module is initialized. */ 19146 PORT_INIT(unit); 19147 19148 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 19149 /* Check if port have to force-loopback */ 19150 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 19151 if (BCM_ESW_PORT_DRV(unit)->force_lb_check != NULL) { 19152 rv = BCM_ESW_PORT_DRV(unit)->force_lb_check(unit, port, 19153 loopback); 19154 if (rv != BCM_E_NONE) { 19155 LOG_ERROR(BSL_LS_BCM_PORT, 19156 (BSL_META("Error: Port %d allow PHY internal " 19157 "loopback only.\n"), 19158 port)); 19159 return BCM_E_PARAM; 19160 } 19161 } 19162 } 19163 19164 return bcmi_esw_portctrl_loopback_set(unit, port, loopback); 19165 } 19166 19167 if(bcm_common_oamp_port_enable_get(unit, port)) { 19168 LOG_ERROR(BSL_LS_BCM_PORT, 19169 (BSL_META("Error: Cannot set loopback on OAMP Port %d.\n"), 19170 port)); 19171 return BCM_E_PARAM; 19172 } 19173 19174 #if defined(BCM_KATANA2_SUPPORT) 19175 #if defined(BCM_SABER2_SUPPORT) 19176 if(SOC_IS_SABER2(unit)) { 19177 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19178 } 19179 #endif 19180 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19181 (!((port >= 1) && (port <= max_phy_port)))) { 19182 return BCM_E_PORT; 19183 } 19184 #endif 19185 19186 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port, 19187 &local_port, &phyn, 19188 &phy_lane, &sys_side)); 19189 19190 if (local_port == -1) { 19191 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19192 } else { 19193 port = local_port; 19194 } 19195 19196 #if defined(BCM_TOMAHAWK_SUPPORT) 19197 if (SOC_IS_TOMAHAWKX(unit)) { 19198 BCM_IF_ERROR_RETURN(bcm_th_phy_lb_check(unit, port, loopback)); 19199 } 19200 #endif 19201 19202 #ifdef BCM_RCPU_SUPPORT 19203 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 19204 return BCM_E_PORT; 19205 } 19206 #endif /* BCM_RCPU_SUPPORT */ 19207 19208 PORT_LOCK(unit); 19209 soc_phyctrl_enable_get(unit, port, &link); 19210 PORT_UNLOCK(unit); 19211 if (TRUE == link) { 19212 if (SOC_PBMP_MEMBER(sop->lc_pbm_override_ports, port)) { 19213 if(!SOC_PBMP_MEMBER(sop->lc_pbm_override_link, port)) { 19214 link = FALSE; 19215 } 19216 } 19217 } 19218 19219 rv = BCM_E_NONE; 19220 /* 19221 * Always force link before changing hardware to avoid 19222 * race with the linkscan thread. 19223 */ 19224 if (!(loopback == BCM_PORT_LOOPBACK_NONE)) { 19225 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, FALSE); 19226 19227 if(rv == BCM_E_NONE) { 19228 /* Force the update function to be called so the state is 19229 updated */ 19230 if (_soc_linkscan_phy_flags_test(unit, port, PHY_FLAGS_EXTERNAL_PHY)) { 19231 rv = bcm_esw_port_update(unit, port, TRUE); 19232 } 19233 } 19234 } 19235 19236 PORT_LOCK(unit); 19237 19238 if (BCM_SUCCESS(rv)) { 19239 rv = MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, 19240 (loopback == BCM_PORT_LOOPBACK_MAC)); 19241 } 19242 if (BCM_SUCCESS(rv)) { 19243 if (local_port == -1) { 19244 if (loopback == BCM_PORT_LOOPBACK_PHY_REMOTE) { 19245 rv = soc_phyctrl_control_set(unit, port, 19246 SOC_PHY_CONTROL_LOOPBACK_REMOTE, 1); 19247 } else { 19248 if (loopback == BCM_PORT_LOOPBACK_NONE) { 19249 rv = soc_phyctrl_control_set(unit, port, 19250 SOC_PHY_CONTROL_LOOPBACK_REMOTE, 0); 19251 } 19252 19253 if (rv == SOC_E_NONE || rv == SOC_E_UNAVAIL) { 19254 rv = soc_phyctrl_loopback_set(unit, port, 19255 (loopback == BCM_PORT_LOOPBACK_PHY), 19256 TRUE); 19257 } 19258 } 19259 19260 } else { 19261 rv = soc_phyctrl_redirect_loopback_set 19262 (unit, port, phyn, 19263 phy_lane, sys_side, 19264 (loopback == BCM_PORT_LOOPBACK_PHY), 19265 TRUE); 19266 } 19267 } 19268 /* some mac loopback implementations require the phy to also be in loopback */ 19269 if (soc_feature(unit, soc_feature_phy_lb_needed_in_mac_lb) && 19270 (loopback == BCM_PORT_LOOPBACK_MAC)) { 19271 if (local_port == -1) { 19272 rv = soc_phyctrl_loopback_set(unit, port, 1, TRUE); 19273 } else { 19274 rv = soc_phyctrl_redirect_loopback_set(unit, port, phyn, 19275 phy_lane, sys_side, 19276 1, TRUE); 19277 } 19278 } 19279 19280 PORT_UNLOCK(unit); /* unlock before link call */ 19281 19282 if ((loopback == BCM_PORT_LOOPBACK_NONE) || !BCM_SUCCESS(rv)) { 19283 _bcm_esw_link_force(unit, 0 /*flags*/, port, FALSE, DONT_CARE); 19284 PORT_LOCK(unit); 19285 #ifdef BCM_TRIDENT2_SUPPORT 19286 /* When the PHY is TSC, need to unsquelch TX LANE. */ 19287 if (SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit) 19288 && !(SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port))){ 19289 enable = PORT(unit, port).enable; 19290 if ((FALSE == enable) && (loopback == BCM_PORT_LOOPBACK_NONE)) { 19291 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, FALSE); 19292 rv = soc_phyctrl_enable_set(unit, port, FALSE); 19293 if (SOC_FAILURE(rv)) { 19294 PORT_UNLOCK(unit); 19295 return (rv); 19296 } 19297 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE); 19298 } 19299 } else 19300 #endif /* BCM_TRIDENT2_SUPPORT */ 19301 { 19302 if ((FALSE == link) && (loopback == BCM_PORT_LOOPBACK_NONE)) { 19303 /* Disable MAC RX to prevent traffic going into this port */ 19304 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 19305 SOC_MAC_CONTROL_RX_SET, FALSE); 19306 sal_udelay(100); /* Wait for 1 jumbo packet transmission time */ 19307 19308 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE); 19309 } 19310 } 19311 PORT_UNLOCK(unit); 19312 } else { 19313 /* Enable only MAC instead of calling bcm_port_enable_set so 19314 * that this API doesn't silently enable the port if the 19315 * port is disabled by application. 19316 */ 19317 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE); 19318 19319 #ifdef BCM_TRIDENT2_SUPPORT 19320 /* When the PHY is TSC, need to enable the PHY to support MAC loopback 19321 * on a disabled port. In order to avoid link flap of link partner, 19322 * need to squelch TX LANE before enabling PHY. 19323 */ 19324 if (BCM_FAILURE(rv)) { 19325 return (rv); 19326 } 19327 if ((SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit)) 19328 && !(SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) 19329 && (FALSE == link) 19330 && (loopback == BCM_PORT_LOOPBACK_MAC)) { 19331 PORT_LOCK(unit); 19332 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, TRUE); 19333 rv = soc_phyctrl_enable_set(unit, port, TRUE); 19334 PORT_UNLOCK(unit); 19335 if (SOC_FAILURE(rv)) { 19336 return (rv); 19337 } 19338 } 19339 #endif /* BCM_TRIDENT2_SUPPORT */ 19340 19341 if (BCM_SUCCESS(rv)) { 19342 /* Make sure that the link status is updated only after the 19343 * MAC is enabled so that link_mask2 is set before the 19344 * calling thread synchronizes with linkscan thread in 19345 * _bcm_link_force call. 19346 * If the link is forced before MAC is enabled, there could 19347 * be a race condition in _soc_link_update where linkscan 19348 * may use an old view of link_mask2 and override the 19349 * EPC_LINK_BMAP after the mac_enable_set updates 19350 * link_mask2 and EPC_LINK_BMAP. 19351 */ 19352 if (loopback == BCM_PORT_LOOPBACK_MAC) { 19353 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, TRUE); 19354 } else { 19355 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, link); 19356 } 19357 } 19358 if (BCM_FAILURE(rv)) { 19359 return (rv); 19360 } 19361 19362 #if defined(BCM_BRADLEY_SUPPORT) 19363 /* 19364 * Call _bcm_port_mmu_update explicitly because linkscan 19365 * will not call bcm_port_update when the link is forced. 19366 */ 19367 if (SOC_IS_HBX(unit) && !SOC_IS_SHADOW(unit)) { 19368 rv = _bcm_port_mmu_update(unit, port, 1); 19369 } 19370 19371 /* When a link comes up, hardware will not update the 19372 * LINK_STATUS register until software has toggled the 19373 * the LAG_FAILOVER_CONFIG.LINK_STATUS_UP field. 19374 * Normally, this is done by bcm_port_update. But since 19375 * linkscan will not call bcm_port_update when a link is 19376 * forced up, the toggling of LAG_FAILOVER_CONFIG.LINK_STATUS_UP 19377 * is done here. 19378 */ 19379 if ((SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr) && 19380 IS_GX_PORT(unit, port)) || 19381 (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) || 19382 (SOC_REG_IS_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr) && 19383 (IS_XL_PORT(unit, port) || IS_MXQ_PORT(unit, port))) || 19384 (SOC_REG_IS_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr) && 19385 IS_CL_PORT(unit, port))) { 19386 soc_reg_t reg; 19387 uint32 rval; 19388 19389 if (SOC_IS_SABER2(unit) && SOC_REG_PORT_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr, port)) { 19390 reg = XLPORT_LAG_FAILOVER_CONFIGr; 19391 } else if (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) { 19392 reg = LAG_FAILOVER_CONFIGr; 19393 } else if (SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr)) { 19394 reg = GXPORT_LAG_FAILOVER_CONFIGr; 19395 } else if (SOC_REG_PORT_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr, port) && 19396 (SOC_IS_TOMAHAWKX(unit) || IS_CL_PORT(unit, port))) { 19397 reg = CLPORT_LAG_FAILOVER_CONFIGr; 19398 } else { 19399 reg = XLPORT_LAG_FAILOVER_CONFIGr; 19400 } 19401 19402 #if defined(BCM_TOMAHAWK_SUPPORT) 19403 if (SOC_IS_TOMAHAWK(unit)) { 19404 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 19405 if((phy_port == TH_MGMT_PORT0_NUM) || 19406 (phy_port == TH_MGMT_PORT1_NUM)) { 19407 reg = XLPORT_LAG_FAILOVER_CONFIGr; 19408 } 19409 /* Link status to IPIPE is updated by H/W and driven based on both the 19410 * rising edge of XLPORT_LAG_FAILOVER_CONFIG.LINK_STATUS_UP and 19411 * actual link up status from Serdes. 19412 * In some loopback scenarios it may take longer time to see Serdes link up status. 19413 */ 19414 soc_timeout_init(&to, 10000, 0); 19415 do { 19416 if (((phy_port != TH_MGMT_PORT0_NUM) && 19417 (phy_port != TH_MGMT_PORT1_NUM)) || 19418 (loopback == BCM_PORT_LOOPBACK_NONE)) { 19419 break; 19420 } 19421 19422 switch(phy_port) { 19423 case TH_MGMT_PORT0_NUM: 19424 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XLPORT_XGXS0_LN0_STATUS0_REGr, port, 0, &rval)); 19425 link_st = soc_reg_field_get(unit, XLPORT_XGXS0_LN0_STATUS0_REGr, rval, LINK_STATUSf); 19426 break; 19427 case TH_MGMT_PORT1_NUM: 19428 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XLPORT_XGXS0_LN2_STATUS0_REGr, port, 0, &rval)); 19429 link_st = soc_reg_field_get(unit, XLPORT_XGXS0_LN2_STATUS0_REGr, rval, LINK_STATUSf); 19430 break; 19431 } 19432 if(link_st) { 19433 break; 19434 } 19435 } while (!soc_timeout_check(&to)); 19436 } 19437 #endif 19438 /* Toggle link bit to notify IPIPE on link up */ 19439 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 19440 soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 1); 19441 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 19442 soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 0); 19443 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 19444 } 19445 #endif /* BCM_BRADLEY_SUPPORT */ 19446 } 19447 19448 LOG_INFO(BSL_LS_BCM_PORT, 19449 (BSL_META_U(unit, 19450 "bcm_port_loopback_set: u=%d p=%d lb=%d rv=%d\n"), 19451 unit, port, loopback, rv)); 19452 19453 return rv; 19454 } 19455 19456 /* 19457 * Function: 19458 * bcm_port_loopback_get 19459 * Purpose: 19460 * Recover the current loopback operation for the specified port. 19461 * Parameters: 19462 * unit - StrataSwitch Unit #. 19463 * port - StrataSwitch port #. 19464 * loopback - (OUT) one of: 19465 * BCM_PORT_LOOPBACK_NONE 19466 * BCM_PORT_LOOPBACK_MAC 19467 * BCM_PORT_LOOPBACK_PHY 19468 * Returns: 19469 * BCM_E_NONE 19470 * BCM_E_XXX 19471 */ 19472 19473 int 19474 bcm_esw_port_loopback_get(int unit, bcm_port_t port, int *loopback) 19475 { 19476 int rv = BCM_E_NONE; 19477 int phy_lb = 0; 19478 uint32 phy_rlb = 0; 19479 int mac_lb = 0; 19480 int phy_lane = -1; 19481 int phyn = 0, sys_side = 0; 19482 bcm_port_t local_port = -1; 19483 #if defined(BCM_KATANA2_SUPPORT) 19484 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19485 #endif 19486 19487 /* Make sure port module is initialized. */ 19488 PORT_INIT(unit); 19489 19490 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 19491 return bcmi_esw_portctrl_loopback_get(unit, port, loopback); 19492 } 19493 19494 if(bcm_common_oamp_port_enable_get(unit, port)) { 19495 LOG_ERROR(BSL_LS_BCM_PORT, 19496 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 19497 port)); 19498 return BCM_E_PARAM; 19499 } 19500 19501 #if defined(BCM_KATANA2_SUPPORT) 19502 #if defined(BCM_SABER2_SUPPORT) 19503 if(SOC_IS_SABER2(unit)) { 19504 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19505 } 19506 #endif 19507 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19508 (!((port >= 1) && (port <= max_phy_port)))) { 19509 return BCM_E_PORT; 19510 } 19511 #endif 19512 19513 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port, 19514 &local_port, &phyn, 19515 &phy_lane, &sys_side)); 19516 19517 if (local_port == -1) { 19518 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19519 } else { 19520 port = local_port; 19521 } 19522 PORT_LOCK(unit); /* multiple operations operation */ 19523 19524 if (local_port == -1) { 19525 /* Most ext-phys don't support remote loopback and return SOC_E_UNAVAIL. 19526 * When the return value is SOC_E_UNAVAIL, continue to get phy or mac 19527 * loopback mode 19528 */ 19529 rv = soc_phyctrl_control_get(unit, port, 19530 SOC_PHY_CONTROL_LOOPBACK_REMOTE, 19531 &phy_rlb); 19532 if (rv >= 0 || rv == SOC_E_UNAVAIL) { 19533 rv = soc_phyctrl_loopback_get(unit, port, &phy_lb); 19534 } 19535 } else { 19536 rv = soc_phyctrl_redirect_loopback_get(unit, port, phyn, 19537 phy_lane, sys_side, 19538 &phy_lb); 19539 } 19540 19541 rv = MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb); 19542 19543 PORT_UNLOCK(unit); 19544 if (rv >= 0) { 19545 if (mac_lb) { 19546 *loopback = BCM_PORT_LOOPBACK_MAC; 19547 } else if (phy_lb) { 19548 *loopback = BCM_PORT_LOOPBACK_PHY; 19549 } else if (phy_rlb) { 19550 *loopback = BCM_PORT_LOOPBACK_PHY_REMOTE; 19551 } else { 19552 *loopback = BCM_PORT_LOOPBACK_NONE; 19553 } 19554 } else { 19555 *loopback = BCM_PORT_LOOPBACK_NONE; 19556 } 19557 19558 LOG_INFO(BSL_LS_BCM_PORT, 19559 (BSL_META_U(unit, 19560 "bcm_port_loopback_get: u=%d p=%d lb=%d rv=%d\n"), 19561 unit, port, *loopback, rv)); 19562 19563 return rv; 19564 } 19565 19566 /* 19567 * Function: 19568 * bcm_port_duplex_get 19569 * Purpose: 19570 * Get the port duplex settings 19571 * Parameters: 19572 * unit - StrataSwitch Unit #. 19573 * port - StrataSwitch port #. 19574 * duplex - (OUT) Duplex setting, one of SOC_PORT_DUPLEX_xxx 19575 * Returns: 19576 * BCM_E_NONE 19577 * BCM_E_XXX 19578 */ 19579 19580 int 19581 bcm_esw_port_duplex_get(int unit, bcm_port_t port, int *duplex) 19582 { 19583 int phy_duplex; 19584 int rv=BCM_E_NONE; 19585 #if defined(BCM_KATANA2_SUPPORT) 19586 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19587 #endif 19588 19589 /* Make sure port module is initialized. */ 19590 PORT_INIT(unit); 19591 19592 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 19593 return bcmi_esw_portctrl_duplex_get(unit, port, duplex); 19594 } 19595 19596 if(bcm_common_oamp_port_enable_get(unit, port)) { 19597 LOG_ERROR(BSL_LS_BCM_PORT, 19598 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 19599 port)); 19600 return BCM_E_PARAM; 19601 } 19602 19603 #if defined(BCM_KATANA2_SUPPORT) 19604 #if defined(BCM_SABER2_SUPPORT) 19605 if(SOC_IS_SABER2(unit)) { 19606 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19607 } 19608 #endif 19609 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19610 (!((port >= 1) && (port <= max_phy_port)))) { 19611 return BCM_E_PORT; 19612 } 19613 #endif 19614 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19615 PORT_LOCK(unit); 19616 rv = soc_phyctrl_duplex_get(unit, port, &phy_duplex); 19617 PORT_UNLOCK(unit); 19618 19619 if (BCM_SUCCESS(rv)) { 19620 *duplex = phy_duplex ? SOC_PORT_DUPLEX_FULL : SOC_PORT_DUPLEX_HALF; 19621 } else { 19622 *duplex = SOC_PORT_DUPLEX_FULL; 19623 } 19624 19625 LOG_INFO(BSL_LS_BCM_PORT, 19626 (BSL_META_U(unit, 19627 "bcm_port_duplex_get: u=%d p=%d dup=%d rv=%d\n"), 19628 unit, port, *duplex, rv)); 19629 19630 return rv; 19631 } 19632 19633 /* 19634 * Function: 19635 * _bcm_port_duplex_ability_check 19636 * Purpose: 19637 * Check the port duplex ability. 19638 * Parameters: 19639 * unit - StrataSwitch Unit #. 19640 * port - StrataSwitch port #. 19641 * duplex - Duplex setting, one of SOC_PORT_DUPLEX_xxx 19642 * Returns: 19643 * BCM_E_NONE 19644 * BCM_E_XXX 19645 */ 19646 STATIC int 19647 _bcm_esw_port_duplex_ability_check(int unit, bcm_port_t port, int duplex) 19648 { 19649 bcm_port_ability_t ability_mask; 19650 int rv; 19651 int mac_lb; 19652 int speed = 0, full_duplex_speed, half_duplex_speed; 19653 uint32 pa_speed = 0; 19654 sal_memset(&ability_mask, 0, sizeof(bcm_port_ability_t)); 19655 rv = MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb); 19656 if (BCM_SUCCESS(rv)) { 19657 /* If the port is in mac loopback, we get mac_ability rather than port_ability. */ 19658 if(mac_lb) { 19659 rv = MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit,port, &ability_mask); 19660 } else { 19661 rv = bcm_esw_port_ability_local_get(unit, port, &ability_mask); 19662 } 19663 if (rv < 0) { 19664 LOG_VERBOSE(BSL_LS_BCM_PORT, 19665 (BSL_META("Error: Could not get port %d ability: %s\n"), 19666 port, bcm_errmsg(rv))); 19667 return rv; 19668 } 19669 if ((rv = bcm_esw_port_speed_get(unit, port, &speed)) < 0) { 19670 LOG_VERBOSE(BSL_LS_BCM_PORT, 19671 (BSL_META("Error: Could not get port %d speed: %s\n"), 19672 port, bcm_errmsg(rv))); 19673 return rv; 19674 } 19675 pa_speed = SOC_PA_SPEED(speed); 19676 full_duplex_speed = ability_mask.speed_full_duplex & pa_speed; 19677 half_duplex_speed = ability_mask.speed_half_duplex & pa_speed; 19678 if (!soc_feature(unit, soc_feature_flexport_based_speed_set) && (speed != 0)) { 19679 if (duplex) { 19680 if (!full_duplex_speed) { 19681 LOG_WARN(BSL_LS_BCM_PORT, 19682 (BSL_META_U(unit, "Warning: port %d does not support %d mbps full duplex\n"), 19683 port, speed)); 19684 return BCM_E_UNAVAIL; 19685 } 19686 } else { 19687 if (!half_duplex_speed) { 19688 LOG_WARN(BSL_LS_BCM_PORT, 19689 (BSL_META_U(unit, "Warning: port %d does not support %d mbps half duplex\n"), 19690 port, speed)); 19691 return BCM_E_UNAVAIL; 19692 } 19693 } 19694 } 19695 } 19696 return BCM_E_NONE; 19697 } 19698 19699 /* 19700 * Function: 19701 * bcm_port_duplex_set 19702 * Purpose: 19703 * Set the port duplex settings. 19704 * Parameters: 19705 * unit - StrataSwitch Unit #. 19706 * port - StrataSwitch port #. 19707 * duplex - Duplex setting, one of SOC_PORT_DUPLEX_xxx 19708 * Returns: 19709 * BCM_E_NONE 19710 * BCM_E_XXX 19711 * Notes: 19712 * Turns off autonegotiation. Caller must make sure other forced 19713 * parameters (such as speed) are set. 19714 */ 19715 19716 int 19717 bcm_esw_port_duplex_set(int unit, bcm_port_t port, int duplex) 19718 { 19719 int rv; 19720 pbmp_t pbm; 19721 int an = 0 ; 19722 int an_done=0; 19723 #if defined(BCM_SABER2_SUPPORT) 19724 int phy_status; 19725 #endif 19726 #if defined(BCM_KATANA2_SUPPORT) 19727 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19728 #endif 19729 19730 /* Make sure port module is initialized. */ 19731 PORT_INIT(unit); 19732 19733 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 19734 return bcmi_esw_portctrl_duplex_set(unit, port, duplex); 19735 } 19736 19737 if(bcm_common_oamp_port_enable_get(unit, port)) { 19738 LOG_ERROR(BSL_LS_BCM_PORT, 19739 (BSL_META("Error: Cannot set duplex mode on OAMP Port %d.\n"), 19740 port)); 19741 return BCM_E_PARAM; 19742 } 19743 19744 #if defined(BCM_KATANA2_SUPPORT) 19745 #if defined(BCM_SABER2_SUPPORT) 19746 if(SOC_IS_SABER2(unit)) { 19747 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19748 } 19749 #endif 19750 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19751 (!((port >= 1) && (port <= max_phy_port)))) { 19752 return BCM_E_PORT; 19753 } else 19754 #endif 19755 if((!BCM_GPORT_IS_SET(port)) && (!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)))) { 19756 return BCM_E_PORT; 19757 } 19758 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19759 19760 #ifdef BCM_RCPU_SUPPORT 19761 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 19762 return BCM_E_PORT; 19763 } 19764 #endif /* BCM_RCPU_SUPPORT */ 19765 19766 #if defined(BCM_TOMAHAWK_SUPPORT) 19767 if (SOC_IS_TOMAHAWK(unit)) { 19768 /*half-duplex is not supported at any speed Eagle & Falcon */ 19769 if (duplex == 0) { 19770 return BCM_E_UNAVAIL; 19771 } 19772 } 19773 #endif 19774 19775 /* in SIMULATION, port's alility_mask may not be correct due to NULL phy */ 19776 if (!SAL_BOOT_SIMULATION) { 19777 BCM_IF_ERROR_RETURN(_bcm_esw_port_duplex_ability_check(unit, port, duplex)); 19778 } 19779 19780 PORT_LOCK(unit); 19781 19782 #if defined(BCM_SABER2_SUPPORT) 19783 if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) { 19784 rv = soc_phyctrl_enable_get(unit, port, &phy_status); 19785 if (BCM_FAILURE(rv)) { 19786 PORT_UNLOCK(unit); 19787 return (rv); 19788 } 19789 if(phy_status == TRUE) { 19790 rv = soc_phyctrl_enable_set(unit, port, FALSE); 19791 if (BCM_FAILURE(rv)) { 19792 PORT_UNLOCK(unit); 19793 return (rv); 19794 } 19795 } 19796 } 19797 #endif 19798 rv = soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done); 19799 if (BCM_FAILURE(rv)) { 19800 LOG_VERBOSE(BSL_LS_BCM_PORT, 19801 (BSL_META_U(unit, 19802 "PHY_AUTONEG_GETfailed:%s\n"), bcm_errmsg(rv))); 19803 } 19804 if(an != FALSE) 19805 { 19806 rv = soc_phyctrl_auto_negotiate_set(unit, port, FALSE); 19807 if (BCM_FAILURE(rv)) { 19808 LOG_VERBOSE(BSL_LS_BCM_PORT, 19809 (BSL_META_U(unit, 19810 "PHY_AUTONEG_SETfailed:%s\n"), bcm_errmsg(rv))); 19811 } 19812 } 19813 19814 #if defined(BCM_SABER2_SUPPORT) 19815 if(SOC_IS_SABER2(unit) && 19816 IS_XL_PORT(unit, port) && (phy_status == TRUE)) { 19817 /* Enable phy in tsc only if already enabled before config change */ 19818 rv = soc_phyctrl_enable_set(unit, port, TRUE); 19819 if (BCM_FAILURE(rv)) { 19820 PORT_UNLOCK(unit); 19821 return (rv); 19822 } 19823 } 19824 #endif 19825 19826 if (BCM_SUCCESS(rv)) { 19827 rv = soc_phyctrl_duplex_set(unit, port, duplex); 19828 if (BCM_FAILURE(rv)) { 19829 LOG_VERBOSE(BSL_LS_BCM_PORT, 19830 (BSL_META_U(unit, 19831 "PHY_DUPLEX_SETfailed:%s\n"), bcm_errmsg(rv))); 19832 } 19833 } 19834 19835 if (BCM_SUCCESS(rv)) { 19836 rv = MAC_DUPLEX_SET(PORT(unit, port).p_mac, unit, port, duplex); 19837 if (BCM_FAILURE(rv)) { 19838 LOG_VERBOSE(BSL_LS_BCM_PORT, 19839 (BSL_META_U(unit, 19840 "MAC_DUPLEX_SETfailed:%s\n"), bcm_errmsg(rv))); 19841 } 19842 } 19843 #if defined(BCM_XMAC_SUPPORT) 19844 if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) || 19845 SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 19846 uint32 vco_disturbed = 0; 19847 phy_ctrl_t *int_pc; 19848 if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) || 19849 IS_XE_PORT(unit, port))) { 19850 19851 int_pc = INT_PHY_SW_STATE(unit, port); 19852 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed); 19853 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) { 19854 PORT_UNLOCK(unit); 19855 return rv; 19856 } 19857 if (vco_disturbed) { 19858 rv = _mac_x_reinit(unit, port); 19859 if (BCM_FAILURE(rv)) { 19860 PORT_UNLOCK(unit); 19861 return rv; 19862 } 19863 } 19864 } 19865 } 19866 #endif 19867 19868 PORT_UNLOCK(unit); /* Unlock before link call */ 19869 19870 if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) { 19871 SOC_PBMP_CLEAR(pbm); 19872 SOC_PBMP_PORT_ADD(pbm, port); 19873 (void)bcm_esw_link_change(unit, pbm); 19874 } 19875 19876 LOG_INFO(BSL_LS_BCM_PORT, 19877 (BSL_META_U(unit, 19878 "bcm_port_duplex_set: u=%d p=%d dup=%d rv=%d\n"), 19879 unit, port, duplex, rv)); 19880 19881 return rv; 19882 } 19883 19884 /* 19885 * Function: 19886 * bcm_port_pause_get 19887 * Purpose: 19888 * Get the source address for transmitted PAUSE frames. 19889 * Parameters: 19890 * unit - StrataSwitch Unit #. 19891 * port - StrataSwitch port #. 19892 * pause_tx - (OUT) Boolean value 19893 * pause_rx - (OUT) Boolean value 19894 * Returns: 19895 * BCM_E_NONE 19896 * BCM_E_XXX 19897 */ 19898 19899 int 19900 bcm_esw_port_pause_get(int unit, bcm_port_t port, int *pause_tx, int *pause_rx) 19901 { 19902 int rv; 19903 #if defined(BCM_KATANA2_SUPPORT) 19904 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19905 #endif 19906 19907 /* Make sure port module is initialized. */ 19908 PORT_INIT(unit); 19909 19910 /* Call Port Control module */ 19911 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 19912 return bcmi_esw_portctrl_pause_get(unit, port, pause_tx, pause_rx); 19913 } 19914 19915 if(bcm_common_oamp_port_enable_get(unit, port)) { 19916 LOG_ERROR(BSL_LS_BCM_PORT, 19917 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 19918 port)); 19919 return BCM_E_PARAM; 19920 } 19921 19922 #if defined(BCM_KATANA2_SUPPORT) 19923 #if defined(BCM_SABER2_SUPPORT) 19924 if(SOC_IS_SABER2(unit)) { 19925 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19926 } 19927 #endif 19928 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19929 (!((port >= 1) && (port <= max_phy_port)))) { 19930 return BCM_E_PORT; 19931 } 19932 #endif 19933 19934 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19935 19936 PORT_LOCK(unit); 19937 rv = MAC_PAUSE_GET(PORT(unit, port).p_mac, unit, port, pause_tx, pause_rx); 19938 PORT_UNLOCK(unit); 19939 19940 return rv; 19941 } 19942 19943 /* 19944 * Function: 19945 * bcm_port_pause_set 19946 * Purpose: 19947 * Set the pause state for a given port 19948 * Parameters: 19949 * unit - StrataSwitch Unit #. 19950 * port - StrataSwitch port #. 19951 * pause_tx - Boolean value, or -1 (don't change) 19952 * pause_rx - Boolean value, or -1 (don't change) 19953 * Returns: 19954 * BCM_E_NONE 19955 * BCM_E_XXX 19956 * Notes: 19957 * Symmetric pause requires the two "pause" values to be the same. 19958 */ 19959 19960 int 19961 bcm_esw_port_pause_set(int unit, bcm_port_t port, int pause_tx, int pause_rx) 19962 { 19963 int rv; 19964 #ifdef BCM_MONTEREY_SUPPORT 19965 uint32 enable = 0; 19966 #endif 19967 #if defined(BCM_KATANA2_SUPPORT) 19968 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19969 #endif 19970 19971 /* Make sure port module is initialized. */ 19972 PORT_INIT(unit); 19973 19974 /* Call Port Control module */ 19975 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 19976 #ifdef BCM_MONTEREY_SUPPORT 19977 if (SOC_IS_MONTEREY(unit)) { 19978 BCM_IF_ERROR_RETURN( 19979 bcmi_esw_portctrl_preemption_mac_config_get( 19980 unit, port, bcmPortPreemptControlEnableTx, &enable)); 19981 if (enable && (pause_tx || pause_rx)) { 19982 return BCM_E_PARAM; 19983 } 19984 } 19985 #endif 19986 return bcmi_esw_portctrl_pause_set(unit, port, pause_tx, pause_rx); 19987 } 19988 19989 if(bcm_common_oamp_port_enable_get(unit, port)) { 19990 LOG_ERROR(BSL_LS_BCM_PORT, 19991 (BSL_META("Error: Cannot set pause state on OAMP Port %d.\n"), 19992 port)); 19993 return BCM_E_PARAM; 19994 } 19995 19996 #if defined(BCM_KATANA2_SUPPORT) 19997 #if defined(BCM_SABER2_SUPPORT) 19998 if(SOC_IS_SABER2(unit)) { 19999 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20000 } 20001 #endif 20002 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20003 (!((port >= 1) && (port <= max_phy_port)))) { 20004 return BCM_E_PORT; 20005 } 20006 #endif 20007 20008 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20009 20010 PORT_LOCK(unit); 20011 rv = MAC_PAUSE_SET(PORT(unit, port).p_mac, unit, port, pause_tx, pause_rx); 20012 if (BCM_FAILURE(rv)) { 20013 PORT_UNLOCK(unit); 20014 return (rv); 20015 } 20016 20017 #if defined(BCM_BRADLEY_SUPPORT) 20018 if (SOC_IS_HBX(unit)) { 20019 #ifdef BCM_SHADOW_SUPPORT 20020 if (!SOC_IS_SHADOW(unit)) { 20021 #endif 20022 rv = _bcm_port_mmu_update(unit, port, -1); 20023 #ifdef BCM_SHADOW_SUPPORT 20024 } 20025 #endif 20026 } 20027 #endif /* BCM_BRADLEY_SUPPORT */ 20028 20029 PORT_UNLOCK(unit); 20030 return rv; 20031 } 20032 20033 /* 20034 * Function: 20035 * bcm_port_pause_sym_get 20036 * Purpose: 20037 * Get the current pause setting for pause 20038 * Parameters: 20039 * unit - StrataSwitch Unit #. 20040 * port - StrataSwitch port #. 20041 * pause - (OUT) returns a bcm_port_pause_e enum value 20042 * Returns: 20043 * BCM_E_NONE 20044 * BCM_E_XXX 20045 */ 20046 20047 int 20048 bcm_esw_port_pause_sym_get(int unit, bcm_port_t port, int *pause) 20049 { 20050 int pause_rx, pause_tx; 20051 #if defined(BCM_KATANA2_SUPPORT) 20052 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20053 #endif 20054 20055 #if defined(BCM_KATANA2_SUPPORT) 20056 #if defined(BCM_SABER2_SUPPORT) 20057 if(SOC_IS_SABER2(unit)) { 20058 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20059 } 20060 #endif 20061 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20062 (!((port >= 1) && (port <= max_phy_port)))) { 20063 return BCM_E_PORT; 20064 } 20065 #endif 20066 20067 /* Make sure port module is initialized. */ 20068 PORT_INIT(unit); 20069 20070 if(bcm_common_oamp_port_enable_get(unit, port)) { 20071 LOG_ERROR(BSL_LS_BCM_PORT, 20072 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 20073 port)); 20074 return BCM_E_PARAM; 20075 } 20076 20077 BCM_IF_ERROR_RETURN 20078 (bcm_esw_port_pause_get(unit, port, &pause_tx, &pause_rx)); 20079 if (pause_tx) { 20080 if (pause_rx) { 20081 *pause = BCM_PORT_PAUSE_SYM; 20082 } else { 20083 *pause = BCM_PORT_PAUSE_ASYM_TX; 20084 } 20085 } else if (pause_rx) { 20086 *pause = BCM_PORT_PAUSE_ASYM_RX; 20087 } else { 20088 *pause = BCM_PORT_PAUSE_NONE; 20089 } 20090 20091 return BCM_E_NONE; 20092 } 20093 20094 /* 20095 * Function: 20096 * bcm_port_pause_sym_set 20097 * Purpose: 20098 * Set the pause values for the port using single integer 20099 * Parameters: 20100 * unit - StrataSwitch Unit #. 20101 * port - StrataSwitch port #. 20102 * pause - a bcm_port_pause_e enum value 20103 * Returns: 20104 * BCM_E_NONE 20105 * BCM_E_XXX 20106 */ 20107 20108 int 20109 bcm_esw_port_pause_sym_set(int unit, bcm_port_t port, int pause) 20110 { 20111 int pause_rx, pause_tx; 20112 #if defined(BCM_KATANA2_SUPPORT) 20113 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20114 #endif 20115 20116 #if defined(BCM_KATANA2_SUPPORT) 20117 #if defined(BCM_SABER2_SUPPORT) 20118 if(SOC_IS_SABER2(unit)) { 20119 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20120 } 20121 #endif 20122 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20123 (!((port >= 1) && (port <= max_phy_port)))) { 20124 return BCM_E_PORT; 20125 } 20126 #endif 20127 /* Make sure port module is initialized. */ 20128 PORT_INIT(unit); 20129 20130 if(bcm_common_oamp_port_enable_get(unit, port)) { 20131 LOG_ERROR(BSL_LS_BCM_PORT, 20132 (BSL_META("Error: Cannot set pause values on OAMP Port %d.\n"), 20133 port)); 20134 return BCM_E_PARAM; 20135 } 20136 20137 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20138 20139 pause_tx = pause_rx = 0; 20140 20141 switch (pause) { 20142 case BCM_PORT_PAUSE_SYM: 20143 pause_tx = pause_rx = 1; 20144 break; 20145 case BCM_PORT_PAUSE_ASYM_RX: 20146 pause_rx = 1; 20147 break; 20148 case BCM_PORT_PAUSE_ASYM_TX: 20149 pause_tx = 1; 20150 break; 20151 case BCM_PORT_PAUSE_NONE: 20152 break; 20153 default: 20154 return BCM_E_PARAM; 20155 } 20156 20157 return bcm_esw_port_pause_set(unit, port, pause_tx, pause_rx); 20158 } 20159 20160 /* 20161 * Function: 20162 * bcm_port_pause_addr_get 20163 * Purpose: 20164 * Get the source address for transmitted PAUSE frames. 20165 * Parameters: 20166 * unit - StrataSwitch Unit #. 20167 * port - StrataSwitch port #. 20168 * mac - (OUT) MAC address sent with pause frames. 20169 * Returns: 20170 * BCM_E_NONE 20171 * BCM_E_XXX 20172 */ 20173 20174 int 20175 bcm_esw_port_pause_addr_get(int unit, bcm_port_t port, bcm_mac_t mac) 20176 { 20177 int rv; 20178 #if defined(BCM_KATANA2_SUPPORT) 20179 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20180 #endif 20181 20182 /* Make sure port module is initialized. */ 20183 PORT_INIT(unit); 20184 20185 /* Call Port Control module */ 20186 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20187 return bcmi_esw_portctrl_pause_addr_get(unit, port, mac); 20188 } 20189 20190 if(bcm_common_oamp_port_enable_get(unit, port)) { 20191 LOG_ERROR(BSL_LS_BCM_PORT, 20192 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 20193 port)); 20194 return BCM_E_PARAM; 20195 } 20196 20197 #if defined(BCM_KATANA2_SUPPORT) 20198 #if defined(BCM_SABER2_SUPPORT) 20199 if(SOC_IS_SABER2(unit)) { 20200 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20201 } 20202 #endif 20203 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20204 (!((port >= 1) && (port <= max_phy_port)))) { 20205 return BCM_E_PORT; 20206 } 20207 #endif 20208 20209 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20210 20211 PORT_LOCK(unit); 20212 rv = MAC_PAUSE_ADDR_GET(PORT(unit, port).p_mac, unit, port, mac); 20213 PORT_UNLOCK(unit); 20214 20215 return rv; 20216 } 20217 20218 /* 20219 * Function: 20220 * bcm_port_pause_addr_set 20221 * Purpose: 20222 * Set the source address for transmitted PAUSE frames. 20223 * Parameters: 20224 * unit - StrataSwitch Unit #. 20225 * port - StrataSwitch port #. 20226 * mac - station address used for pause frames. 20227 * Returns: 20228 * BCM_E_NONE 20229 * BCM_E_XXX 20230 * Notes: 20231 * Symmetric pause requires the two "pause" values to be the same. 20232 */ 20233 20234 int 20235 bcm_esw_port_pause_addr_set(int unit, bcm_port_t port, bcm_mac_t mac) 20236 { 20237 int rv; 20238 #if defined(BCM_KATANA2_SUPPORT) 20239 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20240 #endif 20241 20242 /* Make sure port module is initialized. */ 20243 PORT_INIT(unit); 20244 20245 /* Call Port Control module */ 20246 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20247 return bcmi_esw_portctrl_pause_addr_set(unit, port, mac); 20248 } 20249 20250 if(bcm_common_oamp_port_enable_get(unit, port)) { 20251 LOG_ERROR(BSL_LS_BCM_PORT, 20252 (BSL_META("Error: Cannot set pause addr on OAMP Port %d.\n"), 20253 port)); 20254 return BCM_E_PARAM; 20255 } 20256 20257 #if defined(BCM_KATANA2_SUPPORT) 20258 #if defined(BCM_SABER2_SUPPORT) 20259 if(SOC_IS_SABER2(unit)) { 20260 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20261 } 20262 #endif 20263 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20264 (!((port >= 1) && (port <= max_phy_port)))) { 20265 return BCM_E_PORT; 20266 } 20267 #endif 20268 20269 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20270 20271 PORT_LOCK(unit); 20272 rv = MAC_PAUSE_ADDR_SET(PORT(unit, port).p_mac, unit, port, mac); 20273 PORT_UNLOCK(unit); 20274 20275 return rv; 20276 } 20277 20278 /* 20279 * Function: 20280 * bcm_port_advert_get 20281 * Purpose: 20282 * Retrieve the local port advertisement for autonegotiation. 20283 * Parameters: 20284 * unit - StrataSwitch Unit #. 20285 * port - StrataSwitch port #. 20286 * ability_mask - (OUT) Local advertisement. 20287 * Returns: 20288 * BCM_E_NONE 20289 * BCM_E_XXX 20290 */ 20291 20292 int 20293 bcm_esw_port_advert_get(int unit, bcm_port_t port, bcm_port_abil_t *ability_mask) 20294 { 20295 int rv; 20296 bcm_port_ability_t ability; 20297 #if defined(BCM_KATANA2_SUPPORT) 20298 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20299 #endif 20300 20301 /* Make sure port module is initialized. */ 20302 PORT_INIT(unit); 20303 20304 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20305 return bcmi_esw_portctrl_ability_advert_get(unit, port, 20306 &ability, ability_mask); 20307 } 20308 sal_memset(&ability, 0, sizeof(bcm_port_ability_t)); 20309 20310 #if defined(BCM_KATANA2_SUPPORT) 20311 #if defined(BCM_SABER2_SUPPORT) 20312 if(SOC_IS_SABER2(unit)) { 20313 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20314 } 20315 #endif 20316 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20317 (!((port >= 1) && (port <= max_phy_port)))) { 20318 return BCM_E_PORT; 20319 } 20320 #endif 20321 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20322 20323 PORT_LOCK(unit); 20324 rv = soc_phyctrl_ability_advert_get(unit, port, &ability); 20325 if (BCM_SUCCESS(rv)) { 20326 rv = soc_port_ability_to_mode(&ability, ability_mask); 20327 } 20328 PORT_UNLOCK(unit); 20329 20330 20331 20332 LOG_INFO(BSL_LS_BCM_PORT, 20333 (BSL_META_U(unit, 20334 "bcm_port_advert_get: u=%d p=%d abil=0x%x rv=%d\n"), 20335 unit, port, *ability_mask, rv)); 20336 20337 return rv; 20338 } 20339 20340 /* 20341 * Function: 20342 * bcm_esw_port_ability_advert_get 20343 * Purpose: 20344 * Retrieve the local port advertisement for autonegotiation. 20345 * Parameters: 20346 * unit - StrataSwitch Unit #. 20347 * port - StrataSwitch port #. 20348 * ability_mask - (OUT) Local advertisement. 20349 * Returns: 20350 * BCM_E_NONE 20351 * BCM_E_XXX 20352 */ 20353 20354 int 20355 bcm_esw_port_ability_advert_get(int unit, bcm_port_t port, 20356 bcm_port_ability_t *ability_mask) 20357 { 20358 int rv=BCM_E_NONE; 20359 #if defined(BCM_KATANA2_SUPPORT) 20360 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20361 #endif 20362 20363 /* Make sure port module is initialized. */ 20364 PORT_INIT(unit); 20365 20366 /* Call Port Control module */ 20367 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20368 return bcmi_esw_portctrl_ability_advert_get(unit, port, 20369 ability_mask, NULL); 20370 } 20371 20372 if(bcm_common_oamp_port_enable_get(unit, port)) { 20373 LOG_ERROR(BSL_LS_BCM_PORT, 20374 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 20375 port)); 20376 return BCM_E_PARAM; 20377 } 20378 20379 #if defined(BCM_KATANA2_SUPPORT) 20380 #if defined(BCM_SABER2_SUPPORT) 20381 if(SOC_IS_SABER2(unit)) { 20382 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20383 } 20384 #endif 20385 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20386 (!((port >= 1) && (port <= max_phy_port)))) { 20387 return BCM_E_PORT; 20388 } 20389 #endif 20390 20391 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20392 20393 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) { 20394 return BCM_E_PORT; 20395 } 20396 20397 sal_memset(ability_mask, 0, sizeof(bcm_port_ability_t)); 20398 PORT_LOCK(unit); 20399 rv = soc_phyctrl_ability_advert_get(unit, port, ability_mask); 20400 PORT_UNLOCK(unit); 20401 20402 LOG_INFO(BSL_LS_BCM_PORT, 20403 (BSL_META_U(unit, 20404 "bcm_esw_port_ability_advert_get: u=%d p=%d rv=%d\n"), 20405 unit, port, rv)); 20406 20407 return rv; 20408 } 20409 /* 20410 * Function: 20411 * bcm_port_autoneg_ability_advert_get 20412 * Purpose: 20413 * Retrieve the local port abilities. 20414 * Parameters: 20415 * unit - StrataSwitch Unit #. 20416 * port - StrataSwitch port #. 20417 * max_num_ability -- the max num of autoneg ability this port can advertise 20418 * ability - (OUT) values indicating the ability this port advertise 20419 * actual_num_ability - (OUT) the actual num of ability that this port advertise 20420 * Returns: 20421 * BCM_E_NONE 20422 * BCM_E_XXX 20423 */ 20424 int 20425 bcm_esw_port_autoneg_ability_advert_get(int unit, 20426 bcm_port_t port, 20427 int max_num_ability, 20428 bcm_port_speed_ability_t *abilities, 20429 int *actual_num_ability) 20430 { 20431 int rv = BCM_E_UNAVAIL; 20432 20433 /* Make sure port module is initialized. */ 20434 PORT_INIT(unit); 20435 20436 /* Call Port Control module */ 20437 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20438 rv = bcmi_esw_portctrl_autoneg_ability_advert_get(unit, port, max_num_ability, 20439 abilities, actual_num_ability); 20440 } 20441 20442 return rv; 20443 } 20444 20445 20446 /* 20447 * Function: 20448 * bcm_port_advert_set 20449 * Purpose: 20450 * Set the local port advertisement for autonegotiation. 20451 * Parameters: 20452 * unit - StrataSwitch Unit #. 20453 * port - StrataSwitch port #. 20454 * ability_mask - Local advertisement. 20455 * Returns: 20456 * BCM_E_NONE 20457 * BCM_E_XXX 20458 * Notes: 20459 * This call MAY NOT restart autonegotiation (depending on the phy). 20460 * To do that, follow this call with bcm_port_autoneg_set(TRUE). 20461 */ 20462 20463 int 20464 bcm_esw_port_advert_set(int unit, bcm_port_t port, bcm_port_abil_t ability_mask) 20465 { 20466 int rv; 20467 bcm_port_ability_t given_ability, port_ability, temp_ability; 20468 #if defined(BCM_KATANA2_SUPPORT) 20469 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20470 #endif 20471 20472 /* Make sure port module is initialized. */ 20473 PORT_INIT(unit); 20474 20475 /* Call Port Control module */ 20476 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20477 return bcmi_esw_portctrl_ability_advert_set(unit, port, 20478 NULL, ability_mask); 20479 } 20480 20481 if(bcm_common_oamp_port_enable_get(unit, port)) { 20482 LOG_ERROR(BSL_LS_BCM_PORT, 20483 (BSL_META("Error: Cannot set port advert on OAMP Port %d.\n"), 20484 port)); 20485 return BCM_E_PARAM; 20486 } 20487 20488 #if defined(BCM_KATANA2_SUPPORT) 20489 #if defined(BCM_SABER2_SUPPORT) 20490 if(SOC_IS_SABER2(unit)) { 20491 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20492 } 20493 #endif 20494 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20495 (!((port >= 1) && (port <= max_phy_port)))) { 20496 return BCM_E_PORT; 20497 } 20498 #endif 20499 20500 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20501 20502 BCM_IF_ERROR_RETURN 20503 (bcm_esw_port_ability_local_get(unit, port, &port_ability)); 20504 20505 BCM_IF_ERROR_RETURN 20506 (bcm_esw_port_ability_advert_get(unit, port, &given_ability)); 20507 20508 BCM_IF_ERROR_RETURN( 20509 soc_port_mode_to_ability(ability_mask, &given_ability)); 20510 20511 /* temporary store ability of half duplex */ 20512 temp_ability.speed_half_duplex = given_ability.speed_half_duplex; 20513 /* make sure that the ability advertising in PHY is supported by MAC */ 20514 soc_port_ability_mask(&given_ability, &port_ability); 20515 /* restore half duplex ability */ 20516 given_ability.speed_half_duplex = temp_ability.speed_half_duplex; 20517 20518 if (IS_HG_PORT(unit, port) && SOC_INFO(unit).port_speed_max[port]) { 20519 if (SOC_INFO(unit).port_speed_max[port] < 16000) { 20520 given_ability.speed_full_duplex &= ~(BCM_PORT_ABILITY_16GB); 20521 given_ability.speed_half_duplex &= ~(BCM_PORT_ABILITY_16GB); 20522 } 20523 20524 if (SOC_INFO(unit).port_speed_max[port] < 13000) { 20525 given_ability.speed_full_duplex &= ~(BCM_PORT_ABILITY_13GB); 20526 given_ability.speed_half_duplex &= ~(BCM_PORT_ABILITY_13GB); 20527 } 20528 20529 if (SOC_INFO(unit).port_speed_max[port] < 12000) { 20530 given_ability.speed_full_duplex &= ~(BCM_PORT_ABILITY_12GB); 20531 given_ability.speed_half_duplex &= ~(BCM_PORT_ABILITY_12GB); 20532 } 20533 20534 if (IS_HL_PORT(unit, port)) { 20535 if (!(given_ability.speed_full_duplex & BCM_PORT_ABILITY_2500MB)) { 20536 return BCM_E_CONFIG; 20537 } 20538 } else if (!(given_ability.speed_full_duplex & (BCM_PORT_ABILITY_16GB | 20539 BCM_PORT_ABILITY_13GB | BCM_PORT_ABILITY_12GB | 20540 BCM_PORT_ABILITY_10GB))) { 20541 return BCM_E_CONFIG; 20542 } 20543 } 20544 20545 PORT_LOCK(unit); 20546 rv = soc_phyctrl_ability_advert_set(unit, port, &given_ability); 20547 PORT_UNLOCK(unit); 20548 20549 LOG_INFO(BSL_LS_BCM_PORT, 20550 (BSL_META_U(unit, 20551 "bcm_port_advert_set: u=%d p=%d abil=0x%x rv=%d\n"), 20552 unit, port, ability_mask, rv)); 20553 20554 return rv; 20555 } 20556 20557 /* 20558 * Function: 20559 * bcm_port_ability_advert_set 20560 * Purpose: 20561 * Set the local port advertisement for autonegotiation. 20562 * Parameters: 20563 * unit - StrataSwitch Unit #. 20564 * port - StrataSwitch port #. 20565 * ability_mask - Local advertisement. 20566 * Returns: 20567 * BCM_E_NONE 20568 * BCM_E_XXX 20569 * Notes: 20570 * This call MAY NOT restart autonegotiation (depending on the phy). 20571 * To do that, follow this call with bcm_port_autoneg_set(TRUE). 20572 */ 20573 20574 int 20575 bcm_esw_port_ability_advert_set(int unit, bcm_port_t port, 20576 bcm_port_ability_t *ability_mask) 20577 { 20578 int rv=BCM_E_NONE; 20579 bcm_port_ability_t port_ability, temp_ability; 20580 #if defined(BCM_KATANA2_SUPPORT) 20581 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20582 #endif 20583 20584 /* Make sure port module is initialized. */ 20585 PORT_INIT(unit); 20586 20587 /* Call Port Control module */ 20588 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20589 return bcmi_esw_portctrl_ability_advert_set(unit, port, 20590 ability_mask, 0); 20591 } 20592 20593 if(bcm_common_oamp_port_enable_get(unit, port)) { 20594 LOG_ERROR(BSL_LS_BCM_PORT, 20595 (BSL_META( 20596 "Error: Cannot set port ability on OAMP Port %d.\n"), 20597 port)); 20598 return BCM_E_PARAM; 20599 } 20600 20601 #if defined(BCM_KATANA2_SUPPORT) 20602 #if defined(BCM_SABER2_SUPPORT) 20603 if(SOC_IS_SABER2(unit)) { 20604 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20605 } 20606 #endif 20607 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20608 (!((port >= 1) && (port <= max_phy_port)))) { 20609 return BCM_E_PORT; 20610 } 20611 #endif 20612 20613 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20614 20615 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) { 20616 return BCM_E_PORT; 20617 } 20618 20619 BCM_IF_ERROR_RETURN 20620 (bcm_esw_port_ability_local_get(unit, port, &port_ability)); 20621 20622 /* temporary store speed_half_duplex ability */ 20623 temp_ability.speed_half_duplex = ability_mask->speed_half_duplex; 20624 /* Make sure to advertise only abilities supported by the port */ 20625 soc_port_ability_mask(&port_ability, ability_mask); 20626 /* restore speed_half_duplex ability even some mac don't support it */ 20627 port_ability.speed_half_duplex = temp_ability.speed_half_duplex; 20628 PORT_LOCK(unit); 20629 rv = soc_phyctrl_ability_advert_set(unit, port, &port_ability); 20630 PORT_UNLOCK(unit); 20631 LOG_INFO(BSL_LS_BCM_PORT, 20632 (BSL_META_U(unit, 20633 "bcm_port_ability_advert_set: u=%d p=%d rv=%d\n"), 20634 unit, port, rv)); 20635 LOG_VERBOSE(BSL_LS_BCM_PORT, 20636 (BSL_META_U(unit, 20637 "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x advert_set\n" 20638 "Interface=0x%08x Medium=0x%08x Loopback=0x%08x Flags=0x%08x\n"), 20639 port_ability.speed_half_duplex, 20640 port_ability.speed_full_duplex, 20641 port_ability.pause, port_ability.interface, 20642 port_ability.medium, port_ability.loopback, 20643 port_ability.flags)); 20644 20645 return rv; 20646 } 20647 20648 /* 20649 * Function: 20650 * bcm_port_autoneg_ability_advert_set 20651 * Purpose: 20652 * Set the local port advertisement for autonegotiation. 20653 * Parameters: 20654 * unit - StrataSwitch Unit #. 20655 * port - StrataSwitch port #. 20656 * num_ability - number of ability the port will advertise 20657 * ability - Local advertisement for each ability. 20658 * Returns: 20659 * BCM_E_NONE 20660 * BCM_E_XXX 20661 * Notes: 20662 * This call WILL NOT restart autonegotiation (depending on the phy). 20663 * To do that, follow this call with bcm_port_autoneg_set(TRUE). 20664 */ 20665 20666 int bcm_esw_port_autoneg_ability_advert_set(int unit, 20667 bcm_port_t port, 20668 int num_ability, 20669 bcm_port_speed_ability_t *abilities) 20670 { 20671 int rv = BCM_E_UNAVAIL; 20672 20673 /* Make sure port module is initialized. */ 20674 PORT_INIT(unit); 20675 20676 /* Call Port Control module */ 20677 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20678 rv = bcmi_esw_portctrl_autoneg_ability_advert_set(unit, port, 20679 num_ability, abilities); 20680 } 20681 20682 return rv; 20683 } 20684 20685 20686 /* 20687 * Function: 20688 * bcm_port_advert_remote_get 20689 * Purpose: 20690 * Retrieve the local port advertisement for autonegotiation. 20691 * Parameters: 20692 * unit - StrataSwitch Unit #. 20693 * port - StrataSwitch port #. 20694 * ability_mask - (OUT) Remote advertisement. 20695 * Returns: 20696 * BCM_E_NONE 20697 * BCM_E_XXX 20698 */ 20699 20700 int 20701 bcm_esw_port_advert_remote_get(int unit, bcm_port_t port, 20702 bcm_port_abil_t *ability_mask) 20703 { 20704 int rv; 20705 bcm_port_ability_t port_ability; 20706 #if defined(BCM_KATANA2_SUPPORT) 20707 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20708 #endif 20709 20710 /* Make sure port module is initialized. */ 20711 PORT_INIT(unit); 20712 20713 /* Call Port Control module */ 20714 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20715 return bcmi_esw_portctrl_ability_remote_get(unit, port, 20716 &port_ability, 20717 ability_mask); 20718 } 20719 20720 sal_memset(&port_ability, 0, sizeof(bcm_port_ability_t)); 20721 20722 #if defined(BCM_KATANA2_SUPPORT) 20723 #if defined(BCM_SABER2_SUPPORT) 20724 if(SOC_IS_SABER2(unit)) { 20725 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20726 } 20727 #endif 20728 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20729 (!((port >= 1) && (port <= max_phy_port)))) { 20730 return BCM_E_PORT; 20731 } 20732 #endif 20733 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20734 20735 PORT_LOCK(unit); 20736 rv = _bcm_port_autoneg_advert_remote_get(unit, port, &port_ability); 20737 if (BCM_SUCCESS(rv)) { 20738 rv = soc_port_ability_to_mode(&port_ability, ability_mask); 20739 } 20740 PORT_UNLOCK(unit); 20741 20742 LOG_INFO(BSL_LS_BCM_PORT, 20743 (BSL_META_U(unit, 20744 "bcm_port_advert_remote_get: u=%d p=%d abil=0x%x rv=%d\n"), 20745 unit, port, *ability_mask, rv)); 20746 20747 return rv; 20748 } 20749 20750 20751 /* 20752 * Function: 20753 * bcm_port_ability_remote_get 20754 * Purpose: 20755 * Retrieve the local port advertisement for autonegotiation. 20756 * Parameters: 20757 * unit - StrataSwitch Unit #. 20758 * port - StrataSwitch port #. 20759 * ability_mask - (OUT) Remote advertisement. 20760 * Returns: 20761 * BCM_E_NONE 20762 * BCM_E_XXX 20763 */ 20764 int 20765 bcm_esw_port_ability_remote_get(int unit, bcm_port_t port, 20766 bcm_port_ability_t *ability_mask) 20767 { 20768 int rv; 20769 #if defined(BCM_KATANA2_SUPPORT) 20770 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20771 #endif 20772 20773 /* Make sure port module is initialized. */ 20774 PORT_INIT(unit); 20775 20776 /* Call Port Control module */ 20777 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20778 return bcmi_esw_portctrl_ability_remote_get(unit, port, 20779 ability_mask, NULL); 20780 } 20781 20782 #if defined(BCM_KATANA2_SUPPORT) 20783 #if defined(BCM_SABER2_SUPPORT) 20784 if(SOC_IS_SABER2(unit)) { 20785 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20786 } 20787 #endif 20788 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20789 (!((port >= 1) && (port <= max_phy_port)))) { 20790 return BCM_E_PORT; 20791 } 20792 #endif 20793 20794 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20795 20796 sal_memset(ability_mask, 0, sizeof(bcm_port_ability_t)); 20797 PORT_LOCK(unit); 20798 rv = _bcm_port_autoneg_advert_remote_get(unit, port, ability_mask); 20799 PORT_UNLOCK(unit); 20800 20801 LOG_INFO(BSL_LS_BCM_PORT, 20802 (BSL_META_U(unit, 20803 "bcm_port_ability_remote_get: u=%d p=%d rv=%d\n"), 20804 unit, port, rv)); 20805 LOG_VERBOSE(BSL_LS_BCM_PORT, 20806 (BSL_META_U(unit, 20807 "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x remote_get\n" 20808 "Interface=0x%08x Medium=0x%08x Loopback=0x%08x Flags=0x%08x\n"), 20809 ability_mask->speed_half_duplex, 20810 ability_mask->speed_full_duplex, 20811 ability_mask->pause, ability_mask->interface, 20812 ability_mask->medium, ability_mask->loopback, 20813 ability_mask->flags)); 20814 20815 return rv; 20816 } 20817 /* 20818 * Function: 20819 * bcm_port_autoneg_ability_remote_get 20820 * Purpose: 20821 * Retrieve the local port abilities. 20822 * Parameters: 20823 * unit - StrataSwitch Unit #. 20824 * port - StrataSwitch port #. 20825 * max_num_ability -- the max num of speed ability remote partner can advertise 20826 * ability - (OUT) values indicating the ability of the MAC/PHY 20827 * actual_num_ability - (OUT) the actual num of ability that remote partner advertise 20828 * Returns: 20829 * BCM_E_NONE 20830 * BCM_E_XXX 20831 */ 20832 int 20833 bcm_esw_port_autoneg_ability_remote_get(int unit, 20834 bcm_port_t port, 20835 int max_num_ability, 20836 bcm_port_speed_ability_t *abilities, 20837 int *actual_num_ability) 20838 { 20839 int rv = BCM_E_UNAVAIL; 20840 20841 /* Make sure port module is initialized. */ 20842 PORT_INIT(unit); 20843 20844 /* Call Port Control module */ 20845 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20846 rv = bcmi_esw_portctrl_autoneg_ability_remote_get(unit, port, max_num_ability, 20847 abilities, actual_num_ability); 20848 } 20849 return rv; 20850 } 20851 20852 20853 /* 20854 * Function: 20855 * bcm_port_ability_get 20856 * Purpose: 20857 * Retrieve the local port abilities. 20858 * Parameters: 20859 * unit - StrataSwitch Unit #. 20860 * port - StrataSwitch port #. 20861 * ability_mask - (OUT) Mask of BCM_PORT_ABIL_ values indicating the 20862 * ability of the MAC/PHY. 20863 * Returns: 20864 * BCM_E_NONE 20865 * BCM_E_XXX 20866 */ 20867 20868 int 20869 bcm_esw_port_ability_get(int unit, bcm_port_t port, bcm_port_abil_t *ability_mask) 20870 { 20871 int rv; 20872 bcm_port_ability_t port_ability; 20873 #if defined(BCM_KATANA2_SUPPORT) 20874 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20875 #endif 20876 20877 /* Make sure port module is initialized. */ 20878 PORT_INIT(unit); 20879 20880 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20881 return bcmi_esw_portctrl_ability_get(unit, port, 20882 &port_ability, ability_mask); 20883 } 20884 20885 if(bcm_common_oamp_port_enable_get(unit, port)) { 20886 LOG_ERROR(BSL_LS_BCM_PORT, 20887 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 20888 port)); 20889 return BCM_E_PARAM; 20890 } 20891 20892 #if defined(BCM_KATANA2_SUPPORT) 20893 #if defined(BCM_SABER2_SUPPORT) 20894 if(SOC_IS_SABER2(unit)) { 20895 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20896 } 20897 #endif 20898 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20899 (!((port >= 1) && (port <= max_phy_port)))) { 20900 return BCM_E_PORT; 20901 } 20902 #endif 20903 20904 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20905 20906 if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) { 20907 return BCM_E_PORT; 20908 } 20909 20910 PORT_LOCK(unit); 20911 rv = _bcm_port_ability_local_get(unit, port, &port_ability); 20912 if (BCM_SUCCESS(rv)) { 20913 rv = soc_port_ability_to_mode(&port_ability, ability_mask); 20914 } 20915 PORT_UNLOCK(unit); 20916 20917 LOG_INFO(BSL_LS_BCM_PORT, 20918 (BSL_META_U(unit, 20919 "bcm_port_ability_get: u=%d p=%d abil=0x%x rv=%d\n"), 20920 unit, port, *ability_mask, rv)); 20921 20922 return rv; 20923 } 20924 20925 /* 20926 * Function: 20927 * bcm_port_ability_local_get 20928 * Purpose: 20929 * Retrieve the local port abilities. 20930 * Parameters: 20931 * unit - StrataSwitch Unit #. 20932 * port - StrataSwitch port #. 20933 * ability_mask - (OUT) Mask of BCM_PORT_ABIL_ values indicating the 20934 * ability of the MAC/PHY. 20935 * Returns: 20936 * BCM_E_NONE 20937 * BCM_E_XXX 20938 */ 20939 20940 int 20941 bcm_esw_port_ability_local_get(int unit, bcm_port_t port, 20942 bcm_port_ability_t *ability_mask) 20943 { 20944 int rv; 20945 #if defined(BCM_KATANA2_SUPPORT) 20946 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20947 #endif 20948 20949 /* Make sure port module is initialized. */ 20950 PORT_INIT(unit); 20951 20952 20953 /* Call Port Control module */ 20954 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 20955 return bcmi_esw_portctrl_ability_get(unit, port, 20956 ability_mask, NULL); 20957 } 20958 20959 if(bcm_common_oamp_port_enable_get(unit, port)) { 20960 LOG_ERROR(BSL_LS_BCM_PORT, 20961 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 20962 port)); 20963 return BCM_E_PARAM; 20964 } 20965 20966 #if defined(BCM_KATANA2_SUPPORT) 20967 #if defined(BCM_SABER2_SUPPORT) 20968 if(SOC_IS_SABER2(unit)) { 20969 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20970 } 20971 #endif 20972 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20973 (!((port >= 1) && (port <= max_phy_port)))) { 20974 return BCM_E_PORT; 20975 } 20976 #endif 20977 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20978 20979 sal_memset(ability_mask, 0, sizeof(bcm_port_ability_t)); 20980 PORT_LOCK(unit); 20981 rv = _bcm_port_ability_local_get(unit, port, ability_mask); 20982 PORT_UNLOCK(unit); 20983 20984 LOG_INFO(BSL_LS_BCM_PORT, 20985 (BSL_META_U(unit, 20986 "bcm_port_ability_local_get: u=%d p=%d rv=%d\n"), 20987 unit, port, rv)); 20988 LOG_VERBOSE(BSL_LS_BCM_PORT, 20989 (BSL_META_U(unit, 20990 "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x local_get\n" 20991 "Interface=0x%08x Medium=0x%08x EEE=0x%08x Loopback=0x%08x Flags=0x%08x\n"), 20992 ability_mask->speed_half_duplex, 20993 ability_mask->speed_full_duplex, 20994 ability_mask->pause, ability_mask->interface, 20995 ability_mask->medium, ability_mask->eee, 20996 ability_mask->loopback, ability_mask->flags)); 20997 20998 return rv; 20999 } 21000 /* 21001 * Function: 21002 * bcm_port_speed_ability_local_get 21003 * Purpose: 21004 * Retrieve the local port abilities. 21005 * Parameters: 21006 * unit - StrataSwitch Unit #. 21007 * port - StrataSwitch port #. 21008 * max_num_ability -- the max num of speed ability this port support 21009 * ability - (OUT) values indicating the ability of the MAC/PHY 21010 * actual_num_ability - (OUT) the actual num of ability that this port can support 21011 * Returns: 21012 * BCM_E_NONE 21013 * BCM_E_XXX 21014 */ 21015 int 21016 bcm_esw_port_speed_ability_local_get(int unit, 21017 bcm_port_t port, 21018 int max_num_ability, 21019 bcm_port_speed_ability_t *abilities, 21020 int *actual_num_ability) 21021 { 21022 int rv = BCM_E_UNAVAIL; 21023 21024 /* Make sure port module is initialized. */ 21025 PORT_INIT(unit); 21026 21027 /* Call Port Control module */ 21028 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 21029 rv = bcmi_esw_portctrl_speed_ability_local_get(unit, port, max_num_ability, 21030 abilities, actual_num_ability); 21031 } 21032 return rv; 21033 } 21034 21035 /* 21036 * Function: 21037 * bcm_port_discard_get 21038 * Purpose: 21039 * Get port discard attributes for the specified port 21040 * Parameters: 21041 * unit - StrataSwitch Unit #. 21042 * port - StrataSwitch port #. 21043 * mode - (OUT) Port discard mode, one of BCM_PORT_DISCARD_xxx 21044 * Returns: 21045 * BCM_E_NONE 21046 * BCM_E_XXX 21047 */ 21048 21049 int 21050 bcm_esw_port_discard_get(int unit, bcm_port_t port, int *mode) 21051 { 21052 bcm_port_cfg_t pcfg; 21053 int rv; 21054 21055 /* Make sure port module is initialized. */ 21056 PORT_INIT(unit); 21057 21058 if(bcm_common_oamp_port_enable_get(unit, port)) { 21059 LOG_ERROR(BSL_LS_BCM_PORT, 21060 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 21061 port)); 21062 return BCM_E_PARAM; 21063 } 21064 21065 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 21066 21067 if ((rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)) == 21068 BCM_E_NONE) { 21069 *mode = pcfg.pc_disc; 21070 } 21071 21072 return(rv); 21073 } 21074 21075 /* 21076 * Function: 21077 * bcm_port_discard_set 21078 * Purpose: 21079 * Set port discard attributes for the specified port. 21080 * Parameters: 21081 * unit - StrataSwitch Unit #. 21082 * port - StrataSwitch port #. 21083 * mode - Port discard mode, one of BCM_PORT_DISCARD_xxx 21084 * Returns: 21085 * BCM_E_NONE 21086 * BCM_E_XXX 21087 */ 21088 21089 int 21090 bcm_esw_port_discard_set(int unit, bcm_port_t port, int mode) 21091 { 21092 bcm_port_cfg_t pcfg; 21093 int rv; 21094 21095 /* Make sure port module is initialized. */ 21096 PORT_INIT(unit); 21097 21098 if(bcm_common_oamp_port_enable_get(unit, port)) { 21099 LOG_ERROR(BSL_LS_BCM_PORT, 21100 (BSL_META("Error: Cannot set discard attr on OAMP Port %d.\n"), 21101 port)); 21102 return BCM_E_PARAM; 21103 } 21104 21105 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 21106 21107 switch (mode) { 21108 case BCM_PORT_DISCARD_TAG: 21109 case BCM_PORT_DISCARD_NONE: 21110 case BCM_PORT_DISCARD_ALL: 21111 case BCM_PORT_DISCARD_UNTAG: 21112 break; 21113 default: 21114 return BCM_E_PARAM; 21115 } 21116 21117 PORT_LOCK(unit); 21118 21119 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 21120 21121 if (BCM_SUCCESS(rv)) { 21122 pcfg.pc_disc = mode; 21123 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg); 21124 } 21125 21126 PORT_UNLOCK(unit); 21127 21128 return rv; 21129 } 21130 21131 /* 21132 * Function: 21133 * _bcm_port_learn_modify 21134 * Purpose: 21135 * Main part of bcm_port_learn_modify. 21136 */ 21137 21138 STATIC int 21139 _bcm_port_learn_modify(int unit, bcm_port_t port, uint32 add, uint32 remove) 21140 { 21141 uint32 flags; 21142 21143 SOC_IF_ERROR_RETURN(bcm_esw_port_learn_get(unit, port, &flags)); 21144 21145 flags |= add; 21146 flags &= ~remove; 21147 21148 SOC_IF_ERROR_RETURN(bcm_esw_port_learn_set(unit, port, flags)); 21149 21150 return BCM_E_NONE; 21151 } 21152 21153 /* 21154 * Function: 21155 * bcm_port_learn_modify 21156 * Purpose: 21157 * Modify the port learn flags, adding add and removing remove flags. 21158 * Parameters: 21159 * unit - StrataSwitch Unit #. 21160 * port - StrataSwitch port #. 21161 * add - Flags to set. 21162 * remove - Flags to clear. 21163 * Returns: 21164 * BCM_E_NONE 21165 * BCM_E_XXX 21166 */ 21167 21168 int 21169 bcm_esw_port_learn_modify(int unit, bcm_port_t port, uint32 add, uint32 remove) 21170 { 21171 int rv; 21172 bcm_port_t port_out; 21173 21174 /* Make sure port module is initialized. */ 21175 PORT_INIT(unit); 21176 21177 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port_out)); 21178 21179 PORT_LOCK(unit); 21180 rv = _bcm_port_learn_modify(unit, port, add, remove); 21181 PORT_UNLOCK(unit); 21182 21183 return rv; 21184 } 21185 21186 /* 21187 * Function: 21188 * bcm_port_learn_get 21189 * Purpose: 21190 * Get the ARL hardware learning options for this port. 21191 * This defines what the hardware will do when a packet 21192 * is seen with an unknown address. 21193 * Parameters: 21194 * unit - StrataSwitch Unit #. 21195 * port - StrataSwitch port #. 21196 * flags - (OUT) Logical OR of BCM_PORT_LEARN_xxx flags 21197 * Returns: 21198 * BCM_E_NONE 21199 * BCM_E_XXX 21200 */ 21201 21202 int 21203 bcm_esw_port_learn_get(int unit, bcm_port_t port, uint32 *flags) 21204 { 21205 bcm_port_cfg_t pcfg; 21206 int rv; 21207 21208 /* Make sure port module is initialized. */ 21209 PORT_INIT(unit); 21210 21211 if(bcm_common_oamp_port_enable_get(unit, port)) { 21212 LOG_ERROR(BSL_LS_BCM_PORT, 21213 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 21214 port)); 21215 return BCM_E_PARAM; 21216 } 21217 21218 if (flags == NULL) { 21219 return BCM_E_PARAM; 21220 } 21221 21222 #if defined(BCM_TRX_SUPPORT) && defined(INCLUDE_L3) 21223 if (BCM_GPORT_IS_SUBPORT_GROUP(port)) { 21224 if (SOC_IS_SCORPION(unit)) { 21225 return BCM_E_UNAVAIL; 21226 } else { 21227 return bcm_tr_subport_learn_get(unit, (bcm_gport_t) port, flags); 21228 } 21229 } 21230 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */ 21231 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \ 21232 defined(INCLUDE_L3) 21233 if (BCM_GPORT_IS_MPLS_PORT(port)) { 21234 return bcm_tr_mpls_port_learn_get(unit, (bcm_gport_t) port, flags); 21235 } 21236 #endif 21237 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 21238 && defined(INCLUDE_L3)) 21239 if (BCM_GPORT_IS_MIM_PORT(port)) { 21240 return bcm_tr2_mim_port_learn_get(unit, (bcm_gport_t) port, flags); 21241 } 21242 if (BCM_GPORT_IS_WLAN_PORT(port)) { 21243 #if defined(BCM_TRIUMPH3_SUPPORT) 21244 if (SOC_IS_TRIUMPH3(unit)) { 21245 return bcm_tr3_wlan_port_learn_get(unit, (bcm_gport_t) port, flags); 21246 } else 21247 #endif /* BCM_TRIUMPH3_SUPPORT */ 21248 { 21249 return bcm_tr2_wlan_port_learn_get(unit, (bcm_gport_t) port, flags); 21250 } 21251 } 21252 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 21253 #if defined(BCM_TRIDENT_SUPPORT)&& defined(INCLUDE_L3) 21254 if (BCM_GPORT_IS_NIV_PORT(port)) { 21255 return bcm_trident_niv_port_learn_get(unit, (bcm_gport_t) port, flags); 21256 } 21257 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 21258 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 21259 if (SOC_IS_TD2_TT2(unit)) { 21260 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 21261 return bcm_td2_vxlan_port_learn_get(unit, (bcm_gport_t) port, flags); 21262 } 21263 } 21264 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 21265 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 21266 if (BCM_GPORT_IS_L2GRE_PORT(port)){ 21267 return bcm_tr3_l2gre_port_learn_get(unit, (bcm_gport_t) port, flags); 21268 } 21269 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 21270 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 21271 if (BCM_GPORT_IS_EXTENDER_PORT(port)){ 21272 if (soc_feature(unit, soc_feature_port_extension)) { 21273 return bcm_tr3_extender_port_learn_get(unit, port, flags); 21274 } 21275 } 21276 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 21277 #if defined(BCM_HGPROXY_COE_SUPPORT) && defined(INCLUDE_L3) 21278 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 21279 (soc_feature(unit, soc_feature_channelized_switching))) && 21280 BCM_GPORT_IS_SUBPORT_PORT(port)) { 21281 return bcmi_xgs5_subport_port_learn_get(unit, (bcm_gport_t) port, flags); 21282 } 21283 #endif /* BCM_HGPROXY_COE_SUPPORT && INCLUDE_L3 */ 21284 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 21285 if (BCM_GPORT_IS_TRUNK(port)){ 21286 if (soc_feature(unit, soc_feature_vp_lag)) { 21287 return bcm_td2_vp_lag_port_learn_get(unit, 21288 BCM_GPORT_TRUNK_GET(port), flags); 21289 } 21290 } 21291 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 21292 21293 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 21294 21295 PORT_LOCK(unit); 21296 21297 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 21298 21299 PORT_UNLOCK(unit); 21300 21301 BCM_IF_ERROR_RETURN(rv); 21302 21303 #ifdef BCM_TRX_SUPPORT 21304 if (SOC_IS_TRX(unit)) { 21305 *flags = 0; 21306 BCM_IF_ERROR_RETURN( 21307 _bcm_trx_port_cml_hw2flags(unit, pcfg.pc_cml, flags)); 21308 } else 21309 #endif 21310 { 21311 switch (pcfg.pc_cml) { 21312 case PVP_CML_SWITCH: 21313 *flags = (BCM_PORT_LEARN_ARL | 21314 BCM_PORT_LEARN_FWD | 21315 (pcfg.pc_cpu ? BCM_PORT_LEARN_CPU : 0)); 21316 break; 21317 case PVP_CML_CPU: 21318 *flags = BCM_PORT_LEARN_CPU; 21319 break; 21320 case PVP_CML_FORWARD: 21321 *flags = BCM_PORT_LEARN_FWD; 21322 break; 21323 case PVP_CML_DROP: 21324 *flags = 0; 21325 break; 21326 case PVP_CML_CPU_SWITCH: 21327 *flags = (BCM_PORT_LEARN_ARL | 21328 BCM_PORT_LEARN_CPU | 21329 BCM_PORT_LEARN_FWD); 21330 break; 21331 case PVP_CML_CPU_FORWARD: 21332 *flags = BCM_PORT_LEARN_CPU | BCM_PORT_LEARN_FWD; 21333 break; 21334 default: 21335 return BCM_E_INTERNAL; 21336 } 21337 } 21338 21339 return BCM_E_NONE; 21340 } 21341 21342 /* 21343 * Function: 21344 * bcm_port_learn_set 21345 * Purpose: 21346 * Set the ARL hardware learning options for this port. 21347 * This defines what the hardware will do when a packet 21348 * is seen with an unknown address. 21349 * Parameters: 21350 * unit - StrataSwitch Unit #. 21351 * port - StrataSwitch port #. 21352 * flags - Logical OR of BCM_PORT_LEARN_xxx flags 21353 * Returns: 21354 * BCM_E_NONE 21355 * BCM_E_XXX 21356 */ 21357 21358 #define Arl BCM_PORT_LEARN_ARL 21359 #define Cpu BCM_PORT_LEARN_CPU 21360 #define Fwd BCM_PORT_LEARN_FWD 21361 21362 int 21363 bcm_esw_port_learn_set(int unit, bcm_port_t port, uint32 flags) 21364 { 21365 bcm_port_cfg_t pcfg; 21366 int rv; 21367 21368 /* Make sure port module is initialized. */ 21369 PORT_INIT(unit); 21370 21371 if(bcm_common_oamp_port_enable_get(unit, port)) { 21372 LOG_ERROR(BSL_LS_BCM_PORT, 21373 (BSL_META("Error: Not permitted on OAMP Port %d.\n"), 21374 port)); 21375 return BCM_E_PARAM; 21376 } 21377 21378 #if defined(BCM_TRX_SUPPORT) && defined(INCLUDE_L3) 21379 if (BCM_GPORT_IS_SUBPORT_GROUP(port)) { 21380 if (SOC_IS_SCORPION(unit)) { 21381 return BCM_E_UNAVAIL; 21382 } else { 21383 return bcm_tr_subport_learn_set(unit, (bcm_gport_t) port, flags); 21384 } 21385 } 21386 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */ 21387 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \ 21388 defined(INCLUDE_L3) 21389 if (BCM_GPORT_IS_MPLS_PORT(port)) { 21390 return bcm_tr_mpls_port_learn_set(unit, (bcm_gport_t) port, flags); 21391 } 21392 #endif 21393 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 21394 && defined(INCLUDE_L3)) 21395 if (BCM_GPORT_IS_MIM_PORT(port)) { 21396 return bcm_tr2_mim_port_learn_set(unit, (bcm_gport_t) port, flags); 21397 } 21398 if (BCM_GPORT_IS_VLAN_PORT(port)) { 21399 if (soc_feature(unit, soc_feature_vlan_vp)) { 21400 return bcm_tr2_vlan_port_learn_set(unit, (bcm_gport_t) port, flags); 21401 } 21402 } 21403 if (BCM_GPORT_IS_WLAN_PORT(port)) { 21404 #if defined(BCM_TRIUMPH3_SUPPORT) 21405 if (SOC_IS_TRIUMPH3(unit)) { 21406 return bcm_tr3_wlan_port_learn_set(unit, (bcm_gport_t) port, flags); 21407 } else 21408 #endif /* BCM_TRIUMPH3_SUPPORT */ 21409 { 21410 return bcm_tr2_wlan_port_learn_set(unit, (bcm_gport_t) port, flags); 21411 } 21412 } 21413 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 21414 #if defined(BCM_TRIDENT_SUPPORT)&& defined(INCLUDE_L3) 21415 if (BCM_GPORT_IS_NIV_PORT(port)) { 21416 return bcm_trident_niv_port_learn_set(unit, (bcm_gport_t) port, flags); 21417 } 21418 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 21419 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 21420 if (SOC_IS_TD2_TT2(unit)) { 21421 if (BCM_GPORT_IS_VXLAN_PORT(port)){ 21422 return bcm_td2_vxlan_port_learn_set(unit, (bcm_gport_t) port, flags); 21423 } 21424 } 21425 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 21426 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 21427 if (BCM_GPORT_IS_L2GRE_PORT(port)){ 21428 return bcm_tr3_l2gre_port_learn_set(unit, (bcm_gport_t) port, flags); 21429 } 21430 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 21431 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 21432 if (BCM_GPORT_IS_EXTENDER_PORT(port)){ 21433 if (soc_feature(unit, soc_feature_port_extension)) { 21434 return bcm_tr3_extender_port_learn_set(unit, port, flags); 21435 } 21436 } 21437 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 21438 #if defined(BCM_HGPROXY_COE_SUPPORT) && defined(INCLUDE_L3) 21439 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 21440 (soc_feature(unit, soc_feature_channelized_switching))) && 21441 BCM_GPORT_IS_SUBPORT_PORT(port)) { 21442 return bcmi_xgs5_subport_port_learn_set(unit, (bcm_gport_t) port, flags); 21443 } 21444 #endif /* BCM_HGPROXY_COE_SUPPORT && INCLUDE_L3 */ 21445 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 21446 if (BCM_GPORT_IS_TRUNK(port)){ 21447 if (soc_feature(unit, soc_feature_vp_lag)) { 21448 return bcm_td2_vp_lag_port_learn_set(unit, 21449 BCM_GPORT_TRUNK_GET(port), flags); 21450 } 21451 } 21452 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 21453 21454 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 21455 21456 if (flags & BCM_PORT_LEARN_PENDING) { 21457 if (!soc_feature(unit, soc_feature_l2_pending)) { 21458 return BCM_E_UNAVAIL; 21459 } else if (!IS_CPU_PORT(unit, port) & (!(flags & BCM_PORT_LEARN_ARL))) { 21460 /* When the PENDING flag is set, the ARL must also be set */ 21461 return BCM_E_PARAM; 21462 } 21463 } 21464 21465 PORT_LOCK(unit); 21466 21467 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 21468 21469 pcfg.pc_cpu = ((flags & BCM_PORT_LEARN_CPU) != 0); 21470 21471 /* Use shortened names to handle each flag combination individually */ 21472 21473 #ifdef BCM_TRX_SUPPORT 21474 if (SOC_IS_TRX(unit)) { 21475 pcfg.pc_cml = 0; 21476 rv = _bcm_trx_port_cml_flags2hw(unit, flags, (uint32 *)&pcfg.pc_cml); 21477 if (BCM_FAILURE(rv)) { 21478 PORT_UNLOCK(unit); 21479 return (rv); 21480 } 21481 } else 21482 #endif 21483 { 21484 switch (flags) { 21485 case ((!Arl) | (!Cpu) | (!Fwd)): 21486 pcfg.pc_cml = PVP_CML_DROP; 21487 break; 21488 case ((!Arl) | (!Cpu) | ( Fwd)): 21489 pcfg.pc_cml = PVP_CML_FORWARD; 21490 break; 21491 case ((!Arl) | ( Cpu) | (!Fwd)): 21492 pcfg.pc_cml = PVP_CML_CPU; 21493 break; 21494 case ((!Arl) | ( Cpu) | ( Fwd)): 21495 if (SOC_IS_XGS_SWITCH(unit)) { 21496 pcfg.pc_cml = PVP_CML_CPU_FORWARD; 21497 } else { 21498 rv = BCM_E_UNAVAIL; 21499 } 21500 break; 21501 case (( Arl) | (!Cpu) | (!Fwd)): 21502 rv = BCM_E_UNAVAIL; 21503 break; 21504 case (( Arl) | (!Cpu) | ( Fwd)): 21505 pcfg.pc_cml = PVP_CML_SWITCH; 21506 break; 21507 case (( Arl) | ( Cpu) | (!Fwd)): 21508 rv = BCM_E_UNAVAIL; 21509 break; 21510 case (( Arl) | ( Cpu) | ( Fwd)): 21511 if (SOC_IS_XGS_SWITCH(unit)) { 21512 pcfg.pc_cml = PVP_CML_CPU_SWITCH; 21513 } else { 21514 pcfg.pc_cml = PVP_CML_SWITCH; /* pc_cpu also being set */ 21515 } 21516 break; 21517 } 21518 } 21519 21520 if (BCM_SUCCESS(rv)) { 21521 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg); 21522 } 21523 21524 PORT_UNLOCK(unit); 21525 21526 return rv; 21527 } 21528 21529 #undef Arl 21530 #undef Cpu 21531 #undef Fwd 21532 21533 /* 21534 * Function: 21535 * bcm_port_ifilter_get 21536 * Description: 21537 * Return input filter mode for a port. 21538 * Parameters: 21539 * unit - StrataSwitch PCI device unit number (driver internal). 21540 * port - Port number to operate on 21541 * mode - (OUT) Filter mode, 1 is enable; 0 is disable. 21542 * Returns: 21543 * BCM_E_NONE Success. 21544 * BCM_E_INTERNAL Chip access failure. 21545 * Notes: 21546 * This API is superseded by bcm_port_vlan_member_get. 21547 */ 21548 21549 int 21550 bcm_esw_port_ifilter_get(int unit, bcm_port_t port, int *mode) 21551 { 21552 int rv; 21553 uint32 flags; 21554 21555 /* Make sure port module is initialized. */ 21556 PORT_INIT(unit); 21557 21558 rv = bcm_esw_port_vlan_member_get(unit, port, &flags); 21559 21560 if (BCM_SUCCESS(rv)) { 21561 *mode = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? 1 : 0; 21562 } 21563 21564 return rv; 21565 } 21566 21567 /* 21568 * Function: 21569 * bcm_port_ifilter_set 21570 * Description: 21571 * Set input filter mode for a port. 21572 * Parameters: 21573 * unit - StrataSwitch PCI device unit number (driver internal). 21574 * port - Port number to operate on 21575 * mode - 1 to enable, 0 to disable. 21576 * Returns: 21577 * BCM_E_NONE Success. 21578 * BCM_E_INTERNAL Chip access failure. 21579 * Notes: 21580 * This API is superseded by bcm_port_vlan_member_set. 21581 * 21582 * When input filtering is turned on for a port, packets received 21583 * on the port that do not match the port's VLAN classifications 21584 * are discarded. 21585 */ 21586 21587 int 21588 bcm_esw_port_ifilter_set(int unit, bcm_port_t port, int mode) 21589 { 21590 uint32 flags; 21591 21592 /* Make sure port module is initialized. */ 21593 PORT_INIT(unit); 21594 21595 BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, port, &flags)); 21596 21597 if (mode) { 21598 flags |= BCM_PORT_VLAN_MEMBER_INGRESS; 21599 } else { 21600 flags &= (~BCM_PORT_VLAN_MEMBER_INGRESS); 21601 } 21602 21603 return bcm_esw_port_vlan_member_set(unit, port, flags); 21604 } 21605 21606 /* 21607 * Function: 21608 * bcm_esw_port_vlan_member_get 21609 * Description: 21610 * Return filter mode for a port. 21611 * Parameters: 21612 * unit - StrataSwitch PCI device unit number (driver internal). 21613 * port - Port number to operate on 21614 * flags - (OUT) Filter mode, one of BCM_PORT_VLAN_MEMBER_xxx. 21615 * Returns: 21616 * BCM_E_NONE Success. 21617 * BCM_E_INTERNAL Chip access failure. 21618 */ 21619 21620 int 21621 bcm_esw_port_vlan_member_get(int unit, bcm_port_t port, uint32 *flags) 21622 { 21623 int rv = BCM_E_UNAVAIL; 21624 21625 *flags = 0; 21626 21627 /* Make sure port module is initialized. */ 21628 PORT_INIT(unit); 21629 21630 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 21631 if (BCMI_GPORT_TYPE_VALID(port)) { 21632 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 21633 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 21634 return bcm_td2p_vp_vlan_member_get(unit, port, -1, flags); 21635 } else 21636 #endif 21637 { 21638 return bcm_td_vp_vlan_member_get(unit, port, flags); 21639 } 21640 } else 21641 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 21642 if (BCM_GPORT_IS_WLAN_PORT(port)) { 21643 rv = BCM_E_NONE; 21644 } else { 21645 rv = _bcm_esw_port_gport_validate(unit, port, &port); 21646 } 21647 BCM_IF_ERROR_RETURN(rv); 21648 rv = BCM_E_UNAVAIL; 21649 21650 switch (BCM_CHIP_FAMILY(unit)) { 21651 21652 case BCM_FAMILY_HERCULES: 21653 rv = BCM_E_NONE; 21654 break; 21655 21656 case BCM_FAMILY_FIREBOLT: 21657 case BCM_FAMILY_BRADLEY: 21658 case BCM_FAMILY_HUMV: 21659 case BCM_FAMILY_TRIUMPH: 21660 case BCM_FAMILY_SCORPION: 21661 case BCM_FAMILY_CONQUEROR: 21662 case BCM_FAMILY_TRIUMPH2: 21663 case BCM_FAMILY_TRIDENT: 21664 case BCM_FAMILY_TITAN: 21665 case BCM_FAMILY_KATANA: 21666 if (SOC_IS_XGS12_SWITCH(unit) && IS_HG_PORT(unit, port)) { 21667 rv = BCM_E_NONE; 21668 } else { 21669 uint32 ent[SOC_MAX_MEM_FIELD_WORDS]; 21670 soc_mem_t mem; 21671 soc_field_t field = EN_EFILTERf; 21672 21673 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 21674 && defined(INCLUDE_L3)) 21675 if (BCM_GPORT_IS_WLAN_PORT(port)) { 21676 int value; 21677 if (!soc_feature(unit, soc_feature_wlan)) { 21678 return BCM_E_PORT; 21679 } 21680 #if defined(BCM_TRIUMPH3_SUPPORT) 21681 if (SOC_IS_TRIUMPH3(unit)) { 21682 rv = bcm_tr3_wlan_lport_field_get(unit, port, 21683 EN_IFILTERf, &value); 21684 } else 21685 #endif /* BCM_TRIUMPH3_SUPPORT */ 21686 { 21687 rv = bcm_tr2_wlan_lport_field_get(unit, port, 21688 EN_IFILTERf, &value); 21689 } 21690 if (value) { 21691 *flags |= BCM_PORT_VLAN_MEMBER_INGRESS; 21692 } 21693 return rv; 21694 } 21695 #endif 21696 21697 mem = SOC_PORT_MEM_TAB(unit, port); 21698 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 21699 #ifdef BCM_TRIDENT3_SUPPORT 21700 int value; 21701 rv = _bcm_esw_port_tab_get(unit, port, EN_IFILTERf, &value); 21702 if (rv == BCM_E_NONE) { 21703 if(value) { 21704 *flags |= BCM_PORT_VLAN_MEMBER_INGRESS; 21705 if (value == 2) { 21706 *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP; 21707 } 21708 } 21709 } 21710 #endif 21711 } else { 21712 uint32 value = 0; 21713 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 21714 SOC_PORT_MOD_OFFSET(unit, port), &ent); 21715 21716 if (BCM_SUCCESS(rv)) { 21717 value = soc_PORT_TABm_field32_get(unit, &ent, EN_IFILTERf); 21718 if (value) { 21719 *flags |= BCM_PORT_VLAN_MEMBER_INGRESS; 21720 if (value == 2) { 21721 *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP; 21722 } 21723 } 21724 } 21725 } 21726 21727 #ifdef BCM_TRIDENT_SUPPORT 21728 mem = EGR_PORTm; 21729 field = EN_EFILTERf; 21730 #ifdef BCM_TRIDENT3_SUPPORT 21731 if (SOC_IS_TRIDENT3X(unit)) { 21732 int val = 0; 21733 rv = _bcm_esw_egr_port_tab_get(unit, port, field, &val); 21734 if (BCM_SUCCESS(rv) && val != 0) { 21735 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS; 21736 if(val == 2) { 21737 *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP; 21738 } 21739 } 21740 } else 21741 #endif 21742 if (SOC_MEM_IS_VALID(unit, mem)) { 21743 int val = 0; 21744 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, &ent); 21745 val = soc_mem_field32_get(unit, mem, &ent, field); 21746 if (BCM_SUCCESS(rv) && val) { 21747 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS; 21748 if(val == 2) { 21749 *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP; 21750 } 21751 } 21752 } else 21753 #endif /* BCM_TRIDENT_SUPPORT */ 21754 if (SOC_IS_XGS3_SWITCH(unit)) { 21755 uint32 egr_val; 21756 uint64 egr_val64; 21757 if (SOC_REG_IS_VALID(unit, EGR_PORTr)) { 21758 rv = READ_EGR_PORTr(unit, port, &egr_val); 21759 } else { 21760 rv = READ_EGR_PORT_64r(unit, port, &egr_val64); 21761 } 21762 if (BCM_SUCCESS(rv)) { 21763 if (SOC_REG_IS_VALID(unit, EGR_PORTr)) { 21764 if (soc_reg_field_valid(unit, EGR_PORTr, field)) { 21765 if (soc_reg_field_get(unit, EGR_PORTr, 21766 egr_val, field)) { 21767 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS; 21768 } 21769 } 21770 } else if (soc_reg64_field32_get(unit, 21771 EGR_PORT_64r, egr_val64, field)) { 21772 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS; 21773 } 21774 } 21775 } 21776 } 21777 break; 21778 21779 default: 21780 break; 21781 } 21782 21783 return rv; 21784 } 21785 21786 /* 21787 * Function: 21788 * bcm_esw_port_vlan_member_set 21789 * Description: 21790 * Set ingress and egress filter mode for a port. 21791 * Parameters: 21792 * unit - StrataSwitch PCI device unit number (driver internal). 21793 * port - Port number to operate on 21794 * flags - BCM_PORT_VLAN_MEMBER_xxx. 21795 * Returns: 21796 * BCM_E_NONE Success. 21797 * BCM_E_INTERNAL Chip access failure. 21798 */ 21799 21800 int 21801 bcm_esw_port_vlan_member_set(int unit, bcm_port_t port, uint32 flags) 21802 { 21803 int rv = BCM_E_UNAVAIL; 21804 int fieldLen = 0; 21805 21806 /* Make sure port module is initialized. */ 21807 PORT_INIT(unit); 21808 21809 if(bcm_common_oamp_port_enable_get(unit, port)) { 21810 LOG_ERROR(BSL_LS_BCM_PORT, 21811 (BSL_META("Error: Not permitted on OAMP Port %d.\n"), 21812 port)); 21813 return BCM_E_PARAM; 21814 } 21815 21816 if (BCMI_GPORT_TYPE_VALID(port)) { 21817 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 21818 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 21819 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 21820 rv = bcm_td2p_vp_vlan_member_set(unit, port, flags); 21821 } else 21822 #endif 21823 { 21824 rv = bcm_td_vp_vlan_member_set(unit, port, flags); 21825 } 21826 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 21827 return rv; 21828 } else if (BCM_GPORT_IS_WLAN_PORT(port)) { 21829 rv = BCM_E_NONE; 21830 } else { 21831 rv = _bcm_esw_port_gport_validate(unit, port, &port); 21832 } 21833 BCM_IF_ERROR_RETURN(rv); 21834 rv = BCM_E_UNAVAIL; 21835 21836 PORT_LOCK(unit); 21837 21838 switch (BCM_CHIP_FAMILY(unit)) { 21839 21840 case BCM_FAMILY_HERCULES: 21841 rv = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? BCM_E_UNAVAIL : 21842 ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) ? BCM_E_UNAVAIL : BCM_E_NONE); 21843 break; 21844 21845 case BCM_FAMILY_FIREBOLT: 21846 case BCM_FAMILY_BRADLEY: 21847 case BCM_FAMILY_HUMV: 21848 case BCM_FAMILY_TRIUMPH: 21849 case BCM_FAMILY_SCORPION: 21850 case BCM_FAMILY_CONQUEROR: 21851 case BCM_FAMILY_TRIUMPH2: 21852 case BCM_FAMILY_TRIDENT: 21853 case BCM_FAMILY_TITAN: 21854 case BCM_FAMILY_KATANA: 21855 if (SOC_IS_XGS12_SWITCH(unit) && IS_HG_PORT(unit, port)) { 21856 rv = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? BCM_E_UNAVAIL : 21857 ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) ? BCM_E_UNAVAIL : 21858 BCM_E_NONE); 21859 } else { 21860 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 21861 && defined(INCLUDE_L3)) 21862 21863 if (BCM_GPORT_IS_WLAN_PORT(port)) { 21864 if (!soc_feature(unit, soc_feature_wlan)) { 21865 PORT_UNLOCK(unit); 21866 return BCM_E_PORT; 21867 } 21868 if (flags & BCM_PORT_VLAN_MEMBER_INGRESS) { 21869 #if defined(BCM_TRIUMPH3_SUPPORT) 21870 if (SOC_IS_TRIUMPH3(unit)) { 21871 rv = _bcm_tr3_wlan_port_set(unit, port, EN_IFILTERf, 1); 21872 } else 21873 #endif /* BCM_TRIUMPH3_SUPPORT */ 21874 { 21875 rv = _bcm_tr2_wlan_port_set(unit, port, EN_IFILTERf, 1); 21876 } 21877 } else { 21878 #if defined(BCM_TRIUMPH3_SUPPORT) 21879 if (SOC_IS_TRIUMPH3(unit)) { 21880 rv = _bcm_tr3_wlan_port_set(unit, port, EN_IFILTERf, 0); 21881 } else 21882 #endif /* BCM_TRIUMPH3_SUPPORT */ 21883 { 21884 rv = _bcm_tr2_wlan_port_set(unit, port, EN_IFILTERf, 0); 21885 } 21886 } 21887 PORT_UNLOCK(unit); 21888 return rv; 21889 } 21890 #endif 21891 if (SOC_MEM_IS_VALID(unit, PORT_TABm) && 21892 SOC_MEM_FIELD_VALID(unit, PORT_TABm, EN_IFILTERf)) { 21893 fieldLen = soc_mem_field_length(unit, PORT_TABm, EN_IFILTERf); 21894 } else if (SOC_MEM_IS_VALID(unit, LPORT_TABm) && 21895 SOC_MEM_FIELD_VALID(unit, LPORT_TABm, EN_IFILTERf)) { 21896 fieldLen = soc_mem_field_length(unit, LPORT_TABm, EN_IFILTERf); 21897 } 21898 if (fieldLen > 0) { 21899 /* value = 2 requires EN_IFILTERf to have 2 bits. In some 21900 * chips the field only has 1 bit */ 21901 if ((flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) && 21902 fieldLen == 1) { 21903 PORT_UNLOCK(unit); 21904 return BCM_E_PARAM; 21905 } 21906 } 21907 21908 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 21909 int value = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? 1 : 0; 21910 if (soc_feature(unit, soc_feature_vlan_vfi_membership) && 21911 (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 21912 if (value == 1) { 21913 value = 2; 21914 } 21915 } 21916 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 21917 EN_IFILTERf, value); 21918 } else { 21919 int value = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? 1 : 0; 21920 if (soc_feature(unit, soc_feature_vlan_vfi_membership) && 21921 (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 21922 if (value == 1) { 21923 value = 2; 21924 } 21925 } 21926 rv = _bcm_esw_port_tab_set(unit, port, 0, EN_IFILTERf, value); 21927 } 21928 21929 #ifdef BCM_TRIDENT_SUPPORT 21930 if (SOC_MEM_IS_VALID(unit, ING_EN_EFILTER_BITMAPm)) { 21931 uint32 efilter; 21932 ing_en_efilter_bitmap_entry_t entry; 21933 pbmp_t pbmp; 21934 21935 if (SOC_MEM_IS_VALID(unit, EGR_PORTm) && 21936 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EN_EFILTERf)) { 21937 fieldLen = soc_mem_field_length(unit, EGR_PORTm, EN_EFILTERf); 21938 } else if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm) && 21939 SOC_MEM_FIELD_VALID(unit, EGR_LPORT_PROFILEm, EN_EFILTERf)) { 21940 fieldLen = soc_mem_field_length(unit, EGR_LPORT_PROFILEm, EN_EFILTERf); 21941 } 21942 if (fieldLen > 0) { 21943 /* value = 2 requires EN_EFILTERf to have 2 bits. In some 21944 * chips the field only has 1 bit */ 21945 if ((flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) && 21946 fieldLen == 1) { 21947 PORT_UNLOCK(unit); 21948 return BCM_E_PARAM; 21949 } 21950 } 21951 21952 efilter = flags & BCM_PORT_VLAN_MEMBER_EGRESS ? 1 : 0; 21953 if((efilter == 1) && (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 21954 efilter = 2; 21955 } 21956 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EGR_LPORT_PROFILE_IDXf)) { 21957 rv = _bcm_esw_egr_port_tab_set(unit, port, EN_EFILTERf, 21958 efilter); 21959 } else { 21960 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, EN_EFILTERf, 21961 efilter); 21962 } 21963 if (BCM_SUCCESS(rv)) { 21964 rv = soc_mem_read(unit, ING_EN_EFILTER_BITMAPm, 21965 MEM_BLOCK_ANY, 0, &entry); 21966 } 21967 if (BCM_SUCCESS(rv)) { 21968 soc_mem_pbmp_field_get(unit, ING_EN_EFILTER_BITMAPm, 21969 &entry, BITMAPf, &pbmp); 21970 if (efilter && PORT(unit, port).vp_count == 0) { 21971 SOC_PBMP_PORT_ADD(pbmp, port); 21972 } else { 21973 SOC_PBMP_PORT_REMOVE(pbmp, port); 21974 } 21975 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, 21976 &entry, BITMAPf, &pbmp); 21977 rv = soc_mem_write(unit, ING_EN_EFILTER_BITMAPm, 21978 MEM_BLOCK_ANY, 0, &entry); 21979 } 21980 } else 21981 #endif /* BCM_TRIDENT_SUPPORT */ 21982 if (SOC_IS_XGS3_SWITCH(unit)) { 21983 soc_reg_t egr_port_reg; 21984 egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 21985 SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) || 21986 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ? 21987 EGR_PORT_64r : EGR_PORTr; 21988 rv = soc_reg_field32_modify(unit, egr_port_reg, port, EN_EFILTERf, 21989 (flags & BCM_PORT_VLAN_MEMBER_EGRESS) ? 1 : 0); 21990 if (BCM_SUCCESS(rv)) { 21991 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 21992 defined(BCM_SCORPION_SUPPORT) 21993 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || 21994 SOC_IS_SC_CQ(unit) || SOC_IS_HAWKEYE(unit)) { 21995 uint32 egr_val; 21996 pbmp_t pbmp; 21997 uint32 bitmap, pbmp32; 21998 21999 rv = READ_ING_EN_EFILTER_BITMAPr(unit, &egr_val); 22000 if (BCM_SUCCESS(rv)) { 22001 SOC_PBMP_PORT_SET(pbmp, port); 22002 pbmp32 = SOC_PBMP_WORD_GET(pbmp, 0); 22003 bitmap = 22004 soc_reg_field_get(unit, 22005 ING_EN_EFILTER_BITMAPr, 22006 egr_val, BITMAPf); 22007 if (flags & BCM_PORT_VLAN_MEMBER_EGRESS) { 22008 bitmap |= pbmp32; 22009 } else { 22010 bitmap &= ~pbmp32; 22011 } 22012 soc_reg_field_set(unit, ING_EN_EFILTER_BITMAPr, 22013 &egr_val, BITMAPf, bitmap); 22014 rv = WRITE_ING_EN_EFILTER_BITMAPr(unit, egr_val); 22015 } 22016 } 22017 #endif /* BCM_FIREBOLT_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 22018 #if defined(BCM_TRIUMPH_SUPPORT) 22019 /* Do this only if there is no VP on this port */ 22020 if (soc_feature (unit, soc_feature_high_portcount_register)) { 22021 /* 22022 * pbmp reg split to multiple reg due to high port count 22023 * Note : 22024 * - ING_EN_EFILTER_BITMAP_64r here is split to 22025 * {ING_EN_EFILTER_BITMAP_LOr + ING_EN_EFILTER_BITMAP_HIr} 22026 */ 22027 uint64 fval64, rval64; 22028 uint32 t_port; 22029 soc_reg_t reg; 22030 pbmp_t curr_pbmp; 22031 22032 BCM_PBMP_CLEAR(curr_pbmp); 22033 COMPILER_64_ZERO(fval64); 22034 COMPILER_64_ZERO(rval64); 22035 22036 if (port < 64) { 22037 reg = ING_EN_EFILTER_BITMAP_LOr; 22038 t_port = port; 22039 } else { 22040 reg = ING_EN_EFILTER_BITMAP_HIr; 22041 t_port = port - 64; 22042 } 22043 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64); 22044 if (BCM_SUCCESS(rv)) { 22045 fval64 = soc_reg64_field_get(unit, reg, 22046 rval64, BITMAPf); 22047 SOC_PBMP_WORD_SET(curr_pbmp, 0, 22048 COMPILER_64_LO(fval64)); 22049 SOC_PBMP_WORD_SET(curr_pbmp, 1, 22050 COMPILER_64_HI(fval64)); 22051 22052 if ((flags & BCM_PORT_VLAN_MEMBER_EGRESS)){ 22053 SOC_PBMP_PORT_ADD(curr_pbmp, t_port); 22054 } else { 22055 SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port); 22056 } 22057 22058 COMPILER_64_SET(fval64, 22059 SOC_PBMP_WORD_GET(curr_pbmp, 1), 22060 SOC_PBMP_WORD_GET(curr_pbmp, 0)); 22061 soc_reg64_field_set(unit, reg, &rval64, 22062 BITMAPf, fval64); 22063 rv = soc_reg_set(unit, reg, 22064 REG_PORT_ANY, 0, rval64); 22065 } 22066 } else if (SOC_IS_TR_VL(unit)) { 22067 uint64 egr_val_64; 22068 pbmp_t pbmp; 22069 uint32 bitmap, pbmp32; 22070 22071 rv = READ_ING_EN_EFILTER_BITMAP_64r(unit, &egr_val_64); 22072 if (BCM_SUCCESS(rv)) { 22073 SOC_PBMP_PORT_SET(pbmp, port); 22074 /* Low bitmap */ 22075 bitmap = 22076 soc_reg64_field32_get(unit, 22077 ING_EN_EFILTER_BITMAP_64r, 22078 egr_val_64, BITMAP_LOf); 22079 pbmp32 = SOC_PBMP_WORD_GET(pbmp, 0); 22080 if ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) && 22081 (PORT(unit, port).vp_count == 0)) { 22082 bitmap |= pbmp32; 22083 } else { 22084 bitmap &= ~pbmp32; 22085 } 22086 soc_reg64_field32_set(unit, ING_EN_EFILTER_BITMAP_64r, 22087 &egr_val_64, BITMAP_LOf, bitmap); 22088 22089 if(!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 22090 !SOC_IS_GREYHOUND(unit)) { 22091 /* High bitmap */ 22092 bitmap = 22093 soc_reg64_field32_get(unit, 22094 ING_EN_EFILTER_BITMAP_64r, 22095 egr_val_64, BITMAP_HIf); 22096 pbmp32 = SOC_PBMP_WORD_GET(pbmp, 1); 22097 if ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) && 22098 (PORT(unit, port).vp_count == 0)) { 22099 bitmap |= pbmp32; 22100 } else { 22101 bitmap &= ~pbmp32; 22102 } 22103 soc_reg64_field32_set(unit, ING_EN_EFILTER_BITMAP_64r, 22104 &egr_val_64, BITMAP_HIf, bitmap); 22105 } 22106 22107 rv = WRITE_ING_EN_EFILTER_BITMAP_64r(unit, egr_val_64); 22108 } 22109 } 22110 #endif 22111 } 22112 } 22113 } 22114 break; 22115 22116 default: 22117 break; 22118 } 22119 22120 PORT_UNLOCK(unit); 22121 22122 return rv; 22123 } 22124 22125 /* 22126 * Function: 22127 * _bcm_port_link_get 22128 * Purpose: 22129 * Return current PHY up/down status 22130 * Parameters: 22131 * unit - StrataSwitch Unit #. 22132 * port - StrataSwitch port #. 22133 * hw - If TRUE, assume hardware linkscan is active and use it 22134 * to reduce PHY reads. 22135 * If FALSE, do not use information from hardware linkscan. 22136 * up - (OUT) TRUE for link up, FALSE for link down. 22137 * Returns: 22138 * BCM_E_NONE 22139 * BCM_E_XXX 22140 */ 22141 22142 int 22143 _bcm_port_link_get(int unit, bcm_port_t port, int hw, int *up) 22144 { 22145 int rv = 0; 22146 #if defined(BCM_KATANA2_SUPPORT) 22147 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 22148 #endif 22149 22150 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 22151 return bcmi_esw_portctrl_link_get(unit, port, hw, up); 22152 } 22153 22154 #if defined(BCM_KATANA2_SUPPORT) 22155 #if defined(BCM_SABER2_SUPPORT) 22156 if(SOC_IS_SABER2(unit)) { 22157 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 22158 } 22159 #endif 22160 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 22161 (!((port >= 1) && (port <= max_phy_port)))) { 22162 return BCM_E_PORT; 22163 } 22164 #endif 22165 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 22166 22167 PORT_LOCK(unit); 22168 22169 if (hw) { 22170 pbmp_t hw_linkstat; 22171 22172 rv = soc_linkscan_hw_link_get(unit, &hw_linkstat); 22173 22174 *up = PBMP_MEMBER(hw_linkstat, port); 22175 22176 /* 22177 * We need to confirm link down because we may receive false link 22178 * change interrupts when hardware and software linkscan are mixed. 22179 * Processing a false link down event is known to cause packet 22180 * loss, which is obviously unacceptable. 22181 */ 22182 if(!(*up)) { 22183 rv = soc_phyctrl_link_get(unit, port, up); 22184 } 22185 } else { 22186 if (SOC_IS_RCPU_ONLY(unit)) { 22187 rv = MAC_ENABLE_GET(PORT(unit, port).p_mac, unit, port, up); 22188 } else { 22189 rv = soc_phyctrl_link_get(unit, port, up); 22190 } 22191 } 22192 22193 if (BCM_SUCCESS(rv)) { 22194 if (PHY_FLAGS_TST(unit, port, PHY_FLAGS_MEDIUM_CHANGE)) { 22195 soc_port_medium_t medium; 22196 soc_phyctrl_medium_get(unit, port, &medium); 22197 soc_phy_medium_status_notify(unit, port, medium); 22198 } 22199 } 22200 PORT_UNLOCK(unit); 22201 22202 LOG_VERBOSE(BSL_LS_BCM_PORT, 22203 (BSL_META_U(unit, 22204 "_bcm_port_link_get: u=%d p=%d hw=%d up=%d rv=%d\n"), 22205 unit, port, hw, *up, rv)); 22206 22207 return rv; 22208 } 22209 22210 /* 22211 * Function: 22212 * bcm_port_link_status_get 22213 * Purpose: 22214 * Return current Link up/down status, queries linkscan, if unable to 22215 * retrieve status queries the PHY. 22216 * Parameters: 22217 * unit - StrataSwitch Unit #. 22218 * port - StrataSwitch port #. 22219 * up - (OUT) Boolean value, FALSE for link down and TRUE for link up 22220 * Returns: 22221 * BCM_E_NONE 22222 * BCM_E_XXX 22223 */ 22224 22225 int 22226 bcm_esw_port_link_status_get(int unit, bcm_port_t port, int *up) 22227 { 22228 int rv; 22229 #if defined(BCM_KATANA2_SUPPORT) 22230 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 22231 #endif 22232 22233 /* Make sure port module is initialized. */ 22234 PORT_INIT(unit); 22235 22236 if(bcm_common_oamp_port_enable_get(unit, port)) { 22237 LOG_ERROR(BSL_LS_BCM_PORT, 22238 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 22239 port)); 22240 return BCM_E_PARAM; 22241 } 22242 22243 #if defined(BCM_KATANA2_SUPPORT) 22244 #if defined(BCM_SABER2_SUPPORT) 22245 if(SOC_IS_SABER2(unit)) { 22246 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 22247 } 22248 #endif 22249 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 22250 (!((port >= 1) && (port <= max_phy_port)))) { 22251 return BCM_E_PORT; 22252 } 22253 #endif 22254 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 22255 22256 rv = _bcm_esw_link_get(unit, port, up); 22257 22258 if (rv == BCM_E_DISABLED) { 22259 int mode; 22260 mode = BCM_LINKSCAN_MODE_NONE; 22261 22262 rv = bcm_esw_linkscan_mode_get(unit, port, &mode); 22263 22264 #if defined(BCM_KATANA2_SUPPORT) 22265 /* 22266 * Check added for invalid ports where the port number 22267 * lies between the maximum and minimum port values. 22268 */ 22269 if (SOC_IS_KATANA2(unit) && rv == BCM_E_PORT) { 22270 return rv; 22271 } 22272 #endif 22273 if (mode == BCM_LINKSCAN_MODE_HW) { 22274 rv = _bcm_port_link_get(unit, port, 1, up); 22275 } else { 22276 rv = _bcm_port_link_get(unit, port, 0, up); 22277 } 22278 } 22279 22280 22281 return rv; 22282 } 22283 22284 /* 22285 * Function: 22286 * bcm_esw_port_link_failed_clear 22287 * Purpose: 22288 * Clear failed link status from a port which has undergone 22289 * LAG failover. 22290 * Parameters: 22291 * unit - StrataSwitch Unit #. 22292 * port - StrataSwitch port #. 22293 * Notes: 22294 * The port is moved to down status. The application is responsible 22295 * for removing the port from all trunk memberships before calling this 22296 * function. 22297 * Returns: 22298 * BCM_E_NONE 22299 * BCM_E_XXX 22300 */ 22301 22302 int 22303 bcm_esw_port_link_failed_clear(int unit, bcm_port_t port) 22304 { 22305 /* Make sure port module is initialized. */ 22306 PORT_INIT(unit); 22307 22308 return _bcm_esw_link_failed_clear(unit, port); 22309 } 22310 22311 /* 22312 * Function: 22313 * _bcm_port_pfm_set 22314 * Purpose: 22315 * Main part of function bcm_port_pfm_set 22316 */ 22317 22318 STATIC int 22319 _bcm_port_pfm_set(int unit, bcm_port_t port, int mode) 22320 { 22321 int rv = BCM_E_NONE; 22322 22323 /* 22324 * The filter mode for the first 16 ports is in one register 22325 * and for the rest in another 22326 */ 22327 switch (BCM_CHIP_FAMILY(unit)) { 22328 22329 #ifdef BCM_XGS12_FABRIC_SUPPORT 22330 case BCM_FAMILY_HERCULES: 22331 /* See remarks under bcm_port_pfm_get below */ 22332 break; 22333 #endif 22334 22335 #ifdef BCM_XGS3_SWITCH_SUPPORT 22336 case BCM_FAMILY_FIREBOLT: 22337 case BCM_FAMILY_BRADLEY: 22338 case BCM_FAMILY_HUMV: 22339 case BCM_FAMILY_TRIUMPH: 22340 case BCM_FAMILY_SCORPION: 22341 case BCM_FAMILY_CONQUEROR: 22342 case BCM_FAMILY_TRIUMPH2: 22343 case BCM_FAMILY_TRIDENT: 22344 case BCM_FAMILY_TITAN: 22345 case BCM_FAMILY_KATANA: 22346 /* 22347 * PFM is a per VLAN attribute. It is not a per port attribute 22348 * on XGS3 22349 */ 22350 return BCM_E_UNAVAIL; 22351 #endif 22352 22353 default: 22354 return BCM_E_UNAVAIL; 22355 break; 22356 } 22357 22358 return rv; 22359 } 22360 22361 /* 22362 * Function: 22363 * bcm_port_pfm_set 22364 * Purpose: 22365 * Set current port filtering mode (see port.h) 22366 * Parameters: 22367 * unit - StrataSwitch Unit #. 22368 * port - StrataSwitch port #. 22369 * mode - mode for PFM bits (see port.h) 22370 * Returns: 22371 * BCM_E_NONE 22372 * BCM_E_XXX 22373 */ 22374 22375 int 22376 bcm_esw_port_pfm_set(int unit, bcm_port_t port, int mode) 22377 { 22378 int rv; 22379 22380 /* Make sure port module is initialized. */ 22381 PORT_INIT(unit); 22382 22383 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 22384 if (!IS_PORT(unit, port)) { 22385 return BCM_E_PORT; 22386 } 22387 22388 PORT_LOCK(unit); 22389 rv = _bcm_port_pfm_set(unit, port, mode); 22390 PORT_UNLOCK(unit); 22391 22392 return rv; 22393 } 22394 22395 /* 22396 * Function: 22397 * bcm_port_pfm_get 22398 * Purpose: 22399 * Return current port filtering mode (see port.h) 22400 * Parameters: 22401 * unit - StrataSwitch Unit #. 22402 * port - StrataSwitch port #. 22403 * mode - (OUT) mode read from StrataSwitch for PFM bits (see port.h) 22404 * Returns: 22405 * BCM_E_NONE 22406 * BCM_E_XXX 22407 * Notes: 22408 * This function not supported on 5670. 22409 */ 22410 22411 int 22412 bcm_esw_port_pfm_get(int unit, bcm_port_t port, int *mode) 22413 { 22414 /* Make sure port module is initialized. */ 22415 PORT_INIT(unit); 22416 22417 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 22418 if (!IS_PORT(unit, port)) { 22419 return BCM_E_PORT; 22420 } 22421 22422 switch (BCM_CHIP_FAMILY(unit)) { 22423 22424 #ifdef BCM_HERCULES_SUPPORT 22425 case BCM_FAMILY_HERCULES: 22426 /* 22427 * Packets marked as multicast prompt a lookup in the 22428 * MC table in 567x. There is no notion of missing a multicast 22429 * address. 22430 * 22431 * Alternatively, we can mess with the MC/IPMC table 22432 * entries to support the different modes. This is 22433 * probably not worth the trouble when we look at how 22434 * 567x is meant to fit into the system. 22435 */ 22436 *mode = BCM_PORT_PFM_MODEC; 22437 break; 22438 #endif 22439 22440 #ifdef BCM_XGS3_SWITCH_SUPPORT 22441 case BCM_FAMILY_FIREBOLT: 22442 case BCM_FAMILY_BRADLEY: 22443 case BCM_FAMILY_HUMV: 22444 case BCM_FAMILY_TRIUMPH: 22445 case BCM_FAMILY_SCORPION: 22446 case BCM_FAMILY_CONQUEROR: 22447 case BCM_FAMILY_TRIUMPH2: 22448 case BCM_FAMILY_TRIDENT: 22449 case BCM_FAMILY_TITAN: 22450 case BCM_FAMILY_KATANA: 22451 /* 22452 * PFM is a per VLAN attribute. It is not a per port attribute 22453 * on XGS3 22454 */ 22455 *mode = BCM_PORT_PFM_MODEC; 22456 return BCM_E_UNAVAIL; 22457 #endif 22458 22459 default: 22460 return BCM_E_UNAVAIL; 22461 break; 22462 } 22463 22464 return BCM_E_NONE; 22465 } 22466 22467 /* 22468 * Function: 22469 * _bcm_port_untagged_priority_set 22470 * Purpose: 22471 * Main part of bcm_port_untagged_priority_set. 22472 */ 22473 22474 STATIC int 22475 _bcm_port_untagged_priority_set(int unit, bcm_port_t port, int priority) 22476 { 22477 if (priority > 7) { 22478 return BCM_E_PARAM; 22479 } 22480 22481 if(bcm_common_oamp_port_enable_get(unit, port)) { 22482 LOG_ERROR(BSL_LS_BCM_PORT, 22483 (BSL_META("Error: Not permitted on OAMP port %d.n"), 22484 port)); 22485 return BCM_E_PARAM; 22486 } 22487 22488 #if defined(BCM_XGS_SWITCH_SUPPORT) 22489 if (soc_feature(unit, soc_feature_remap_ut_prio) && (priority >= 0)) { 22490 bcm_port_cfg_t pcfg; 22491 SOC_IF_ERROR_RETURN( 22492 mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 22493 pcfg.pc_remap_pri_en = 1; 22494 pcfg.pc_new_opri = priority; 22495 SOC_IF_ERROR_RETURN( 22496 mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 22497 PORT(unit, port).p_ut_prio = pcfg.pc_new_opri; 22498 return SOC_E_NONE; 22499 } 22500 #endif /* BCM_XGS_SWITCH_SUPPORT */ 22501 22502 if (priority < 0) { 22503 return BCM_E_PARAM; 22504 } 22505 22506 return BCM_E_UNAVAIL; 22507 } 22508 22509 /* 22510 * Function: 22511 * bcm_port_untagged_priority_set 22512 * Purpose: 22513 * Set the 802.1P priority for untagged packets coming in on a 22514 * port. This value will be written into the priority field of the 22515 * tag that is added at the ingress. 22516 * Parameters: 22517 * unit - StrataSwitch Unit #. 22518 * port - StrataSwitch port #. 22519 * priority - Priority to be set in 802.1p priority tag, from 0 to 7. 22520 * A negative priority leaves the ingress port priority as 22521 * is, but disables it from overriding ARL-based priorities. 22522 * (on those devices that support ARL-based priority). 22523 * Returns: 22524 * BCM_E_NONE 22525 * BCM_E_XXX 22526 */ 22527 22528 int 22529 bcm_esw_port_untagged_priority_set(int unit, bcm_port_t port, int priority) 22530 { 22531 int rv; 22532 22533 /* Make sure port module is initialized. */ 22534 PORT_INIT(unit); 22535 22536 if(bcm_common_oamp_port_enable_get(unit, port)) { 22537 LOG_ERROR(BSL_LS_BCM_PORT, 22538 (BSL_META("Error: Not permitted on OAMP port %d.n"), 22539 port)); 22540 return BCM_E_PARAM; 22541 } 22542 22543 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 22544 && defined(INCLUDE_L3)) 22545 if (BCM_GPORT_IS_WLAN_PORT(port)) { 22546 #if defined(BCM_TRIUMPH3_SUPPORT) 22547 if (SOC_IS_TRIUMPH3(unit)) { 22548 return bcm_tr3_wlan_port_untagged_prio_set(unit, port, priority); 22549 } else 22550 #endif /* BCM_TRIUMPH3_SUPPORT */ 22551 { 22552 return bcm_tr2_wlan_port_untagged_prio_set(unit, port, priority); 22553 } 22554 } 22555 #endif 22556 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 22557 22558 PORT_LOCK(unit); 22559 rv = _bcm_port_untagged_priority_set(unit, port, priority); 22560 PORT_UNLOCK(unit); 22561 22562 LOG_INFO(BSL_LS_BCM_PORT, 22563 (BSL_META_U(unit, 22564 "bcm_port_ut_priority_set: u=%d p=%d pri=%d rv=%d\n"), 22565 unit, port, priority, rv)); 22566 22567 return rv; 22568 } 22569 22570 /* 22571 * Function: 22572 * bcm_port_untagged_priority_get 22573 * Purpose: 22574 * Returns priority being assigned to untagged receive packets 22575 * Parameters: 22576 * unit - StrataSwitch Unit #. 22577 * port - StrataSwitch port #. 22578 * priority - Pointer to an int in which priority value is returned. 22579 * Returns: 22580 * BCM_E_NONE 22581 * BCM_E_XXX 22582 */ 22583 22584 int 22585 bcm_esw_port_untagged_priority_get(int unit, bcm_port_t port, int *priority) 22586 { 22587 /* Make sure port module is initialized. */ 22588 PORT_INIT(unit); 22589 22590 if(bcm_common_oamp_port_enable_get(unit, port)) { 22591 LOG_ERROR(BSL_LS_BCM_PORT, 22592 (BSL_META("Error: Not permitted on OAMP port %d.n"), 22593 port)); 22594 return BCM_E_PARAM; 22595 } 22596 22597 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 22598 && defined(INCLUDE_L3)) 22599 if (BCM_GPORT_IS_WLAN_PORT(port)) { 22600 #if defined(BCM_TRIUMPH3_SUPPORT) 22601 if (SOC_IS_TRIUMPH3(unit)) { 22602 return bcm_tr3_wlan_port_untagged_prio_get(unit, port, priority); 22603 } else 22604 #endif /* BCM_TRIUMPH3_SUPPORT */ 22605 { 22606 return bcm_tr2_wlan_port_untagged_prio_get(unit, port, priority); 22607 } 22608 } 22609 #endif 22610 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 22611 22612 if (priority != NULL) { 22613 *priority = PORT(unit, port).p_ut_prio; 22614 LOG_INFO(BSL_LS_BCM_PORT, 22615 (BSL_META_U(unit, 22616 "bcm_port_ut_priority_get: u=%d p=%d pri=%d\n"), 22617 unit, port, *priority)); 22618 } 22619 22620 return BCM_E_NONE; 22621 } 22622 22623 /* 22624 * Function: 22625 * bcm_port_selective_get 22626 * Purpose: 22627 * Get requested port parameters 22628 * Parameters: 22629 * unit - switch Unit 22630 * port - switch port 22631 * info - (IN/OUT) port information structure 22632 * Returns: 22633 * BCM_E_XXX 22634 * Notes: 22635 * The action_mask field of the info argument is used as an input 22636 */ 22637 22638 int 22639 bcm_esw_port_selective_get(int unit, bcm_port_t port, bcm_port_info_t *info) 22640 { 22641 int r; 22642 uint32 mask; 22643 bcm_port_if_t intf; 22644 int speed; 22645 22646 /* Make sure port module is initialized. */ 22647 PORT_INIT(unit); 22648 if (!BCM_GPORT_IS_SET(port)) { 22649 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)) { 22650 return BCM_E_PORT; 22651 } 22652 } 22653 22654 if(bcm_common_oamp_port_enable_get(unit, port)) { 22655 LOG_ERROR(BSL_LS_BCM_PORT, 22656 (BSL_META("Error: Not permitted on OAMP port %d.n"), 22657 port)); 22658 return BCM_E_PARAM; 22659 } 22660 22661 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 22662 22663 mask = info->action_mask; 22664 22665 /* PM8x50 does not support these things, so do not try to fetch them */ 22666 if (IS_CD_PORT(unit, port)) { 22667 mask &= ~BCM_PORT_ATTR_ABILITY_MASK; 22668 mask &= ~BCM_PORT_ATTR_LOCAL_ADVERT_MASK; 22669 mask &= ~BCM_PORT_ATTR_INTERFACE_MASK; 22670 } 22671 22672 if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port) || 22673 IS_CE_PORT(unit, port)) { 22674 if (!(IS_CD_PORT(unit, port))) { 22675 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed)); 22676 BCM_IF_ERROR_RETURN(bcm_esw_port_interface_get(unit, port, &intf)); 22677 22678 /* check if the port has no fault status to retrieve */ 22679 if (speed < 5000) { 22680 mask &= ~BCM_PORT_ATTR_FAULT_MASK; 22681 } else if (speed == 5000) { 22682 if (intf != BCM_PORT_IF_KR) { 22683 mask &= ~BCM_PORT_ATTR_FAULT_MASK; 22684 } 22685 } else if (speed < 10000) { 22686 mask &= ~BCM_PORT_ATTR_FAULT_MASK; 22687 } 22688 } 22689 } 22690 22691 if (IS_QSGMII_PORT(unit, port)) { 22692 mask &= ~BCM_PORT_ATTR_FAULT_MASK; 22693 } 22694 22695 if (mask & BCM_PORT_ATTR_ENCAP_MASK) { 22696 r = bcm_esw_port_encap_get(unit, port, &info->encap_mode); 22697 if (BCM_FAILURE(r)) { 22698 LOG_VERBOSE(BSL_LS_BCM_PORT, 22699 (BSL_META_U(unit, 22700 "bcm_port_encap_getfailed:%s\n"), bcm_errmsg(r))); 22701 } 22702 BCM_IF_ERROR_RETURN(r); 22703 } 22704 22705 if (mask & BCM_PORT_ATTR_ENABLE_MASK) { 22706 r = bcm_esw_port_enable_get(unit, port, &info->enable); 22707 if (BCM_FAILURE(r)) { 22708 LOG_VERBOSE(BSL_LS_BCM_PORT, 22709 (BSL_META_U(unit, 22710 "bcm_port_enable_getfailed:%s\n"), bcm_errmsg(r))); 22711 } 22712 BCM_IF_ERROR_RETURN(r); 22713 } 22714 22715 if (mask & BCM_PORT_ATTR_LINKSTAT_MASK) { 22716 r = bcm_esw_port_link_status_get(unit, port, &info->linkstatus); 22717 if (BCM_FAILURE(r)) { 22718 /* LOG_VERBOSE(BSL_LS_BCM_PORT, 22719 (BSL_META_U(unit, 22720 "bcm_port_link_status_getfailed:%s\n"), bcm_errmsg(r))); */ 22721 } 22722 BCM_IF_ERROR_RETURN(r); 22723 } 22724 22725 if (mask & BCM_PORT_ATTR_AUTONEG_MASK) { 22726 r = bcm_esw_port_autoneg_get(unit, port, &info->autoneg); 22727 if (BCM_FAILURE(r)) { 22728 LOG_VERBOSE(BSL_LS_BCM_PORT, 22729 (BSL_META_U(unit, 22730 "bcm_port_autoneg_getfailed:%s\n"), bcm_errmsg(r))); 22731 } 22732 BCM_IF_ERROR_RETURN(r); 22733 } 22734 22735 if (mask & BCM_PORT_ATTR_LOCAL_ADVERT_MASK) { 22736 r = bcm_esw_port_ability_advert_get(unit, port, 22737 &info->local_ability); 22738 if (BCM_FAILURE(r)) { 22739 LOG_VERBOSE(BSL_LS_BCM_PORT, 22740 (BSL_META_U(unit, 22741 "bcm_port_ability_advert_getfailed:%s\n"), 22742 bcm_errmsg(r))); 22743 } 22744 BCM_IF_ERROR_RETURN(r); 22745 r = soc_port_ability_to_mode(&info->local_ability, 22746 &info->local_advert); 22747 BCM_IF_ERROR_RETURN(r); 22748 } 22749 22750 if (mask & BCM_PORT_ATTR_REMOTE_ADVERT_MASK) { 22751 22752 if ((r = bcm_esw_port_ability_remote_get(unit, port, 22753 &info->remote_ability)) < 0) { 22754 info->remote_advert = 0; 22755 info->remote_advert_valid = FALSE; 22756 } else { 22757 r = soc_port_ability_to_mode(&info->remote_ability, 22758 &info->remote_advert); 22759 BCM_IF_ERROR_RETURN(r); 22760 info->remote_advert_valid = TRUE; 22761 } 22762 } 22763 22764 if (mask & BCM_PORT_ATTR_SPEED_MASK) { 22765 if ((r = bcm_esw_port_speed_get(unit, port, &info->speed)) < 0) { 22766 if (r != BCM_E_BUSY) { 22767 LOG_VERBOSE(BSL_LS_BCM_PORT, 22768 (BSL_META_U(unit, 22769 "bcm_port_speed_get failed: %s\n"), bcm_errmsg(r))); 22770 return(r); 22771 } else { 22772 info->speed = 0; 22773 } 22774 } 22775 } 22776 22777 if (mask & BCM_PORT_ATTR_DUPLEX_MASK) { 22778 if ((r = bcm_esw_port_duplex_get(unit, port, &info->duplex)) < 0) { 22779 if (r != BCM_E_BUSY) { 22780 LOG_VERBOSE(BSL_LS_BCM_PORT, 22781 (BSL_META_U(unit, 22782 "bcm_port_duplex_get failed: %s\n"), bcm_errmsg(r))); 22783 return r; 22784 } else { 22785 info->duplex = 0; 22786 } 22787 } 22788 } 22789 22790 /* get both if either mask bit set */ 22791 if (mask & (BCM_PORT_ATTR_PAUSE_TX_MASK | 22792 BCM_PORT_ATTR_PAUSE_RX_MASK)) { 22793 r = bcm_esw_port_pause_get(unit, port, 22794 &info->pause_tx, &info->pause_rx); 22795 if (BCM_FAILURE(r)) { 22796 LOG_VERBOSE(BSL_LS_BCM_PORT, 22797 (BSL_META_U(unit, 22798 "bcm_port_pause_get failed:%s\n"), bcm_errmsg(r))); 22799 } 22800 BCM_IF_ERROR_RETURN(r); 22801 } 22802 22803 if (mask & BCM_PORT_ATTR_PAUSE_MAC_MASK) { 22804 r = bcm_esw_port_pause_addr_get(unit, port, info->pause_mac); 22805 if (BCM_FAILURE(r)) { 22806 LOG_VERBOSE(BSL_LS_BCM_PORT, 22807 (BSL_META_U(unit, 22808 "bcm_port_pause_addr_get failed:%s\n"), bcm_errmsg(r))); 22809 } 22810 BCM_IF_ERROR_RETURN(r); 22811 } 22812 22813 if (mask & BCM_PORT_ATTR_LINKSCAN_MASK) { 22814 r = bcm_esw_port_linkscan_get(unit, port, &info->linkscan); 22815 if (BCM_FAILURE(r)) { 22816 LOG_VERBOSE(BSL_LS_BCM_PORT, 22817 (BSL_META_U(unit, 22818 "bcm_port_linkscan_get failed:%s\n"), bcm_errmsg(r))); 22819 } 22820 BCM_IF_ERROR_RETURN(r); 22821 } 22822 22823 if (mask & BCM_PORT_ATTR_LEARN_MASK) { 22824 r = bcm_esw_port_learn_get(unit, port, &info->learn); 22825 if (BCM_FAILURE(r)) { 22826 LOG_VERBOSE(BSL_LS_BCM_PORT, 22827 (BSL_META_U(unit, 22828 "bcm_port_learn_getfailed:%s\n"), bcm_errmsg(r))); 22829 } 22830 BCM_IF_ERROR_RETURN(r); 22831 } 22832 22833 if (mask & BCM_PORT_ATTR_DISCARD_MASK) { 22834 r = bcm_esw_port_discard_get(unit, port, &info->discard); 22835 if (BCM_FAILURE(r)) { 22836 LOG_VERBOSE(BSL_LS_BCM_PORT, 22837 (BSL_META_U(unit, 22838 "bcm_port_discard_get failed:%s\n"), bcm_errmsg(r))); 22839 } 22840 BCM_IF_ERROR_RETURN(r); 22841 } 22842 22843 if (mask & BCM_PORT_ATTR_VLANFILTER_MASK) { 22844 r = bcm_esw_port_vlan_member_get(unit, port, &info->vlanfilter); 22845 if (BCM_FAILURE(r)) { 22846 LOG_VERBOSE(BSL_LS_BCM_PORT, 22847 (BSL_META_U(unit, 22848 "bcm_esw_port_vlan_member_get failed:%s\n"), 22849 bcm_errmsg(r))); 22850 } 22851 BCM_IF_ERROR_RETURN(r); 22852 } 22853 22854 if (mask & BCM_PORT_ATTR_UNTAG_PRI_MASK) { 22855 r = bcm_esw_port_untagged_priority_get(unit, port, 22856 &info->untagged_priority); 22857 if (BCM_FAILURE(r)) { 22858 LOG_VERBOSE(BSL_LS_BCM_PORT, 22859 (BSL_META_U(unit, 22860 "bcm_port_untagged_priority_get failed:%s\n"), 22861 bcm_errmsg(r))); 22862 } 22863 BCM_IF_ERROR_RETURN(r); 22864 } 22865 22866 if (mask & BCM_PORT_ATTR_UNTAG_VLAN_MASK) { 22867 r = bcm_esw_port_untagged_vlan_get(unit, port, 22868 &info->untagged_vlan); 22869 if (BCM_FAILURE(r)) { 22870 LOG_VERBOSE(BSL_LS_BCM_PORT, 22871 (BSL_META_U(unit, 22872 "bcm_port_untagged_vlan_get failed:%s\n"), 22873 bcm_errmsg(r))); 22874 } 22875 BCM_IF_ERROR_RETURN(r); 22876 } 22877 22878 if (mask & BCM_PORT_ATTR_STP_STATE_MASK) { 22879 r = bcm_esw_port_stp_get(unit, port, &info->stp_state); 22880 if (BCM_FAILURE(r)) { 22881 LOG_VERBOSE(BSL_LS_BCM_PORT, 22882 (BSL_META_U(unit, 22883 "bcm_port_stp_get failed:%s\n"), bcm_errmsg(r))); 22884 } 22885 BCM_IF_ERROR_RETURN(r); 22886 } 22887 22888 if (mask & BCM_PORT_ATTR_PFM_MASK) { 22889 r = bcm_esw_port_pfm_get(unit, port, &info->pfm); 22890 if (r != BCM_E_UNAVAIL) { 22891 if (BCM_FAILURE(r)) { 22892 LOG_VERBOSE(BSL_LS_BCM_PORT, 22893 (BSL_META_U(unit, 22894 "bcm_port_pfm_get failed:%s\n"), bcm_errmsg(r))); 22895 } 22896 } 22897 BCM_IF_ERROR_NOT_UNAVAIL_RETURN(r); 22898 } 22899 22900 if (mask & BCM_PORT_ATTR_LOOPBACK_MASK) { 22901 r = bcm_esw_port_loopback_get(unit, port, &info->loopback); 22902 if (BCM_FAILURE(r)) { 22903 LOG_VERBOSE(BSL_LS_BCM_PORT, 22904 (BSL_META_U(unit, 22905 "bcm_port_loopback_get failed:%s\n"), bcm_errmsg(r))); 22906 } 22907 BCM_IF_ERROR_RETURN(r); 22908 } 22909 22910 if (mask & BCM_PORT_ATTR_PHY_MASTER_MASK) { 22911 r = bcm_esw_port_master_get(unit, port, &info->phy_master); 22912 if (BCM_FAILURE(r)) { 22913 LOG_VERBOSE(BSL_LS_BCM_PORT, 22914 (BSL_META_U(unit, 22915 "bcm_port_master_get failed:%s\n"), bcm_errmsg(r))); 22916 } 22917 BCM_IF_ERROR_RETURN(r); 22918 } 22919 22920 if (mask & BCM_PORT_ATTR_INTERFACE_MASK) { 22921 r = bcm_esw_port_interface_get(unit, port, &info->interface); 22922 if (BCM_FAILURE(r)) { 22923 LOG_VERBOSE(BSL_LS_BCM_PORT, 22924 (BSL_META_U(unit, 22925 "bcm_port_interface_get failed:%s\n"), bcm_errmsg(r))); 22926 } 22927 BCM_IF_ERROR_RETURN(r); 22928 } 22929 22930 if (mask & BCM_PORT_ATTR_RATE_MCAST_MASK) { 22931 r = bcm_esw_rate_mcast_get(unit, &info->mcast_limit, 22932 &info->mcast_limit_enable, port); 22933 if (r == BCM_E_UNAVAIL) { 22934 r = BCM_E_NONE; /* Ignore if not supported on chip */ 22935 } 22936 if (BCM_FAILURE(r)) { 22937 LOG_VERBOSE(BSL_LS_BCM_PORT, 22938 (BSL_META_U(unit, 22939 "bcm_rate_mcast_get failed:%s\n"), bcm_errmsg(r))); 22940 } 22941 BCM_IF_ERROR_RETURN(r); 22942 } 22943 22944 if (mask & BCM_PORT_ATTR_RATE_BCAST_MASK) { 22945 r = bcm_esw_rate_bcast_get(unit, &info->bcast_limit, 22946 &info->bcast_limit_enable, port); 22947 if (r == BCM_E_UNAVAIL) { 22948 r = BCM_E_NONE; /* Ignore if not supported on chip */ 22949 } 22950 if (BCM_FAILURE(r)) { 22951 LOG_VERBOSE(BSL_LS_BCM_PORT, 22952 (BSL_META_U(unit, 22953 "bcm_rate_bcast_get failed:%s\n"), bcm_errmsg(r))); 22954 } 22955 BCM_IF_ERROR_RETURN(r); 22956 } 22957 22958 if (mask & BCM_PORT_ATTR_RATE_DLFBC_MASK) { 22959 r = bcm_esw_rate_dlfbc_get(unit, &info->dlfbc_limit, 22960 &info->dlfbc_limit_enable, port); 22961 if (r == BCM_E_UNAVAIL) { 22962 r = BCM_E_NONE; /* Ignore if not supported on chip */ 22963 } 22964 if (BCM_FAILURE(r)) { 22965 LOG_VERBOSE(BSL_LS_BCM_PORT, 22966 (BSL_META_U(unit, 22967 "bcm_rate_dlfbc_get failed:%s\n"), bcm_errmsg(r))); 22968 } 22969 BCM_IF_ERROR_RETURN(r); 22970 } 22971 22972 if (mask & BCM_PORT_ATTR_SPEED_MAX_MASK) { 22973 r = bcm_esw_port_speed_max(unit, port, &info->speed_max); 22974 if (BCM_FAILURE(r)) { 22975 LOG_VERBOSE(BSL_LS_BCM_PORT, 22976 (BSL_META_U(unit, 22977 "bcm_port_speed_max failed:%s\n"), bcm_errmsg(r))); 22978 } 22979 BCM_IF_ERROR_RETURN(r); 22980 } 22981 22982 if (mask & BCM_PORT_ATTR_ABILITY_MASK) { 22983 r = bcm_esw_port_ability_local_get(unit, port, &info->port_ability); 22984 if (BCM_FAILURE(r)) { 22985 LOG_VERBOSE(BSL_LS_BCM_PORT, 22986 (BSL_META_U(unit, 22987 "bcm_port_ability_get failed:%s\n"), bcm_errmsg(r))); 22988 } 22989 BCM_IF_ERROR_RETURN(r); 22990 r = soc_port_ability_to_mode(&info->port_ability, 22991 &info->ability); 22992 BCM_IF_ERROR_RETURN(r); 22993 } 22994 22995 if (mask & BCM_PORT_ATTR_FRAME_MAX_MASK) { 22996 r = bcm_esw_port_frame_max_get(unit, port, &info->frame_max); 22997 if (BCM_FAILURE(r)) { 22998 LOG_VERBOSE(BSL_LS_BCM_PORT, 22999 (BSL_META_U(unit, 23000 "bcm_port_frame_max_get failed:%s\n"), bcm_errmsg(r))); 23001 } 23002 BCM_IF_ERROR_RETURN(r); 23003 } 23004 23005 if (mask & BCM_PORT_ATTR_MDIX_MASK) { 23006 r = bcm_esw_port_mdix_get(unit, port, &info->mdix); 23007 if (BCM_FAILURE(r)) { 23008 LOG_VERBOSE(BSL_LS_BCM_PORT, 23009 (BSL_META_U(unit, 23010 "bcm_port_mdix_get failed:%s\n"), bcm_errmsg(r))); 23011 } 23012 BCM_IF_ERROR_RETURN(r); 23013 } 23014 23015 if (mask & BCM_PORT_ATTR_MDIX_STATUS_MASK) { 23016 r = bcm_esw_port_mdix_status_get(unit, port, &info->mdix_status); 23017 if (BCM_FAILURE(r)) { 23018 LOG_VERBOSE(BSL_LS_BCM_PORT, 23019 (BSL_META_U(unit, 23020 "bcm_port_mdix_status_get failed:%s\n"), bcm_errmsg(r))); 23021 } 23022 BCM_IF_ERROR_RETURN(r); 23023 } 23024 23025 if (mask & BCM_PORT_ATTR_MEDIUM_MASK) { 23026 r = bcm_esw_port_medium_get(unit, port, &info->medium); 23027 if (BCM_FAILURE(r)) { 23028 LOG_VERBOSE(BSL_LS_BCM_PORT, 23029 (BSL_META_U(unit, 23030 "bcm_port_medium_get failed:%s\n"), bcm_errmsg(r))); 23031 } 23032 BCM_IF_ERROR_RETURN(r); 23033 } 23034 23035 if (mask & BCM_PORT_ATTR_FAULT_MASK) { 23036 r = bcm_esw_port_fault_get(unit, port, &info->fault); 23037 if (r == BCM_E_PORT) { 23038 r = BCM_E_NONE; /* Ignore if not supported on chip/port */ 23039 } 23040 if (BCM_FAILURE(r)) { 23041 LOG_VERBOSE(BSL_LS_BCM_PORT, 23042 (BSL_META_U(unit, 23043 "bcm_port_fault_get failed:%s\n"), bcm_errmsg(r))); 23044 } 23045 BCM_IF_ERROR_RETURN(r); 23046 } 23047 23048 return BCM_E_NONE; 23049 } 23050 23051 /* 23052 * Function: 23053 * bcm_port_selective_set 23054 * Purpose: 23055 * Set requested port parameters 23056 * Parameters: 23057 * unit - switch unit 23058 * port - switch port 23059 * info - port information structure 23060 * Returns: 23061 * BCM_E_NONE 23062 * BCM_E_XXX 23063 * Notes: 23064 * Does not set spanning tree state. 23065 */ 23066 23067 int 23068 bcm_esw_port_selective_set(int unit, bcm_port_t port, bcm_port_info_t *info) 23069 { 23070 int r; 23071 uint32 mask; 23072 int flags = 0; 23073 soc_info_t *si; 23074 23075 if (!(si = &SOC_INFO(unit))) { 23076 return SOC_E_INTERNAL; 23077 } 23078 23079 LOG_INFO(BSL_LS_BCM_PORT, 23080 (BSL_META_U(unit, 23081 "bcm_port_selective_set: u=%d p=%d\n"), unit, port)); 23082 23083 /* Make sure port module is initialized. */ 23084 PORT_INIT(unit); 23085 if (!BCM_GPORT_IS_SET(port)) { 23086 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)) { 23087 return BCM_E_PORT; 23088 } 23089 } 23090 23091 if(bcm_common_oamp_port_enable_get(unit, port)) { 23092 LOG_ERROR(BSL_LS_BCM_PORT, 23093 (BSL_META("Error: Not permitted on OAMP port %d.n"), 23094 port)); 23095 return BCM_E_PARAM; 23096 } 23097 23098 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 23099 23100 mask = info->action_mask; 23101 23102 /* PM8x50 does not support these things, so do not try to fetch them */ 23103 if (IS_CD_PORT(unit, port)) { 23104 mask &= ~BCM_PORT_ATTR_ABILITY_MASK; 23105 mask &= ~BCM_PORT_ATTR_LOCAL_ADVERT_MASK; 23106 mask &= ~BCM_PORT_ATTR_INTERFACE_MASK; 23107 } 23108 23109 if (mask & BCM_PORT_ATTR_ENCAP_MASK) { 23110 if (info->encap_mode == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) { 23111 /* HGOE mode valid only for TD3 fabric */ 23112 #ifdef BCM_TRIDENT3_SUPPORT 23113 if (SOC_IS_TRIDENT3X(unit) && 23114 soc_feature(unit, soc_feature_higig_over_ethernet)) { 23115 bcm_port_encap_config_t config; 23116 config.encap = info->encap_mode; 23117 BCM_IF_ERROR_RETURN( 23118 bcm_esw_port_encap_config_set(unit, port, &config)); 23119 } else 23120 #endif 23121 { 23122 return BCM_E_PARAM; 23123 } 23124 } else { 23125 23126 BCM_IF_ERROR_RETURN 23127 (bcmi_esw_port_encap_validate(unit, port, info->encap_mode, 23128 ((mask & BCM_PORT_ATTR_SPEED_MASK) ? info->speed : 0))); 23129 r = _bcm_esw_port_encap_set(unit, port, info->encap_mode); 23130 if (BCM_FAILURE(r)) { 23131 LOG_ERROR(BSL_LS_BCM_PORT, 23132 (BSL_META_U(unit, 23133 "bcm_port_encap_set failed:%s\n"), bcm_errmsg(r))); 23134 } 23135 BCM_IF_ERROR_RETURN(r); 23136 } 23137 } 23138 23139 if (mask & BCM_PORT_ATTR_ENABLE_MASK) { 23140 r = bcm_esw_port_enable_set(unit, port, info->enable); 23141 if (BCM_FAILURE(r)) { 23142 LOG_ERROR(BSL_LS_BCM_PORT, 23143 (BSL_META_U(unit, 23144 "bcm_port_enable_set failed:%s\n"), bcm_errmsg(r))); 23145 } 23146 BCM_IF_ERROR_RETURN(r); 23147 } 23148 23149 if (mask & BCM_PORT_ATTR_PAUSE_MAC_MASK) { 23150 r = bcm_esw_port_pause_addr_set(unit, port, info->pause_mac); 23151 if (BCM_FAILURE(r)) { 23152 LOG_ERROR(BSL_LS_BCM_PORT, 23153 (BSL_META_U(unit, 23154 "bcm_port_pause_addr_set failed:%s\n"), bcm_errmsg(r))); 23155 } 23156 BCM_IF_ERROR_RETURN(r); 23157 } 23158 23159 if (mask & BCM_PORT_ATTR_INTERFACE_MASK) { 23160 r = bcm_esw_port_interface_set(unit, port, info->interface); 23161 if (BCM_FAILURE(r)) { 23162 LOG_ERROR(BSL_LS_BCM_PORT, 23163 (BSL_META_U(unit, 23164 "bcm_port_interface_set failed:%s\n"), bcm_errmsg(r))); 23165 } 23166 BCM_IF_ERROR_RETURN(r); 23167 } 23168 23169 if (mask & BCM_PORT_ATTR_PHY_MASTER_MASK) { 23170 r = bcm_esw_port_master_set(unit, port, info->phy_master); 23171 if (r != BCM_E_UNAVAIL) { 23172 if (BCM_FAILURE(r)) { 23173 LOG_VERBOSE(BSL_LS_BCM_PORT, 23174 (BSL_META_U(unit, 23175 "bcm_port_master_set failed:%s\n"), bcm_errmsg(r))); 23176 } 23177 } 23178 BCM_IF_ERROR_NOT_UNAVAIL_RETURN(r); 23179 } 23180 23181 if (mask & BCM_PORT_ATTR_LINKSCAN_MASK) { 23182 r = bcm_esw_port_linkscan_set(unit, port, info->linkscan); 23183 if (BCM_FAILURE(r)) { 23184 LOG_ERROR(BSL_LS_BCM_PORT, 23185 (BSL_META_U(unit, 23186 "bcm_port_linkscan_set failed:%s\n"), bcm_errmsg(r))); 23187 } 23188 BCM_IF_ERROR_RETURN(r); 23189 } 23190 23191 if (mask & BCM_PORT_ATTR_LEARN_MASK) { 23192 r = bcm_esw_port_learn_set(unit, port, info->learn); 23193 if (BCM_FAILURE(r)) { 23194 LOG_ERROR(BSL_LS_BCM_PORT, 23195 (BSL_META_U(unit, 23196 "bcm_port_learn_set failed:%s\n"), bcm_errmsg(r))); 23197 } 23198 BCM_IF_ERROR_RETURN(r); 23199 } 23200 23201 if (mask & BCM_PORT_ATTR_DISCARD_MASK) { 23202 r = bcm_esw_port_discard_set(unit, port, info->discard); 23203 if (BCM_FAILURE(r)) { 23204 LOG_ERROR(BSL_LS_BCM_PORT, 23205 (BSL_META_U(unit, 23206 "bcm_port_discard_set failed:%s\n"), bcm_errmsg(r))); 23207 } 23208 BCM_IF_ERROR_RETURN(r); 23209 } 23210 23211 if (mask & BCM_PORT_ATTR_VLANFILTER_MASK) { 23212 r = bcm_esw_port_vlan_member_set(unit, port, info->vlanfilter); 23213 if (BCM_FAILURE(r)) { 23214 LOG_ERROR(BSL_LS_BCM_PORT, 23215 (BSL_META_U(unit, 23216 "bcm_esw_port_vlan_member_set failed:%s\n"), 23217 bcm_errmsg(r))); 23218 } 23219 BCM_IF_ERROR_RETURN(r); 23220 } 23221 23222 if (mask & BCM_PORT_ATTR_UNTAG_PRI_MASK) { 23223 r = bcm_esw_port_untagged_priority_set(unit, port, 23224 info->untagged_priority); 23225 if (BCM_FAILURE(r)) { 23226 LOG_ERROR(BSL_LS_BCM_PORT, 23227 (BSL_META_U(unit, 23228 "bcm_port_untagged_priority_set failed:%s\n"), 23229 bcm_errmsg(r))); 23230 } 23231 BCM_IF_ERROR_RETURN(r); 23232 } 23233 23234 if (mask & BCM_PORT_ATTR_UNTAG_VLAN_MASK) { 23235 r = bcm_esw_port_untagged_vlan_set(unit, port, info->untagged_vlan); 23236 if (BCM_FAILURE(r)) { 23237 LOG_ERROR(BSL_LS_BCM_PORT, 23238 (BSL_META_U(unit, 23239 "bcm_port_untagged_vlan_set (%d) failed: %s\n"), 23240 info->untagged_vlan, bcm_errmsg(r))); 23241 } 23242 BCM_IF_ERROR_RETURN(r); 23243 } 23244 23245 if (mask & BCM_PORT_ATTR_PFM_MASK) { 23246 r = bcm_esw_port_pfm_set(unit, port, info->pfm); 23247 if (r != BCM_E_UNAVAIL) { 23248 if (BCM_FAILURE(r)) { 23249 LOG_ERROR(BSL_LS_BCM_PORT, 23250 (BSL_META_U(unit, 23251 "bcm_port_pfm_set failed:%s\n"), bcm_errmsg(r))); 23252 } 23253 } 23254 BCM_IF_ERROR_NOT_UNAVAIL_RETURN(r); 23255 } 23256 23257 /* 23258 * Set loopback mode before setting the speed/duplex, since it may 23259 * affect the allowable values for speed/duplex. 23260 */ 23261 23262 if (mask & BCM_PORT_ATTR_LOOPBACK_MASK) { 23263 r = bcm_esw_port_loopback_set(unit, port, info->loopback); 23264 if (BCM_FAILURE(r)) { 23265 LOG_ERROR(BSL_LS_BCM_PORT, 23266 (BSL_META_U(unit, 23267 "bcm_port_loopback_set failed:%s\n"), bcm_errmsg(r))); 23268 } 23269 BCM_IF_ERROR_RETURN(r); 23270 } 23271 23272 if (mask & BCM_PORT_ATTR_LOCAL_ADVERT_MASK) { 23273 if (info->action_mask2 & BCM_PORT_ATTR2_PORT_ABILITY) { 23274 r = bcm_esw_port_ability_advert_set(unit, port, 23275 &(info->local_ability)); 23276 if (BCM_FAILURE(r)) { 23277 LOG_ERROR(BSL_LS_BCM_PORT, 23278 (BSL_META_U(unit, 23279 "bcm_port_ability_advert_set failed: %s\n"), 23280 bcm_errmsg(r))); 23281 } 23282 BCM_IF_ERROR_RETURN(r); 23283 } else { 23284 r = bcm_esw_port_advert_set(unit, port, info->local_advert); 23285 if (BCM_FAILURE(r)) { 23286 LOG_ERROR(BSL_LS_BCM_PORT, 23287 (BSL_META_U(unit, 23288 "bcm_port_advert_set failed: (0x%x): %s\n"), 23289 info->local_advert, bcm_errmsg(r))); 23290 } 23291 BCM_IF_ERROR_RETURN(r); 23292 } 23293 } 23294 23295 if (mask & BCM_PORT_ATTR_AUTONEG_MASK) { 23296 #if defined(BCM_TOMAHAWK_SUPPORT) 23297 if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit)) && IS_CL_PORT(unit, port)) { 23298 int speed = si->port_init_speed[port]; 23299 if (1000 == speed) { /* 1G ports do not support autoneg, force off */ 23300 info->autoneg = 0; 23301 } 23302 } 23303 #endif 23304 r = bcm_esw_port_autoneg_set(unit, port, info->autoneg); 23305 if (BCM_FAILURE(r)) { 23306 LOG_ERROR(BSL_LS_BCM_PORT, 23307 (BSL_META_U(unit, 23308 "bcm_port_autoneg_set failed:%s\n"), bcm_errmsg(r))); 23309 } 23310 BCM_IF_ERROR_RETURN(r); 23311 } 23312 23313 if (mask & BCM_PORT_ATTR_SPEED_MASK) { 23314 /*When AN=on, speed will be auto-detected. Hence don't set*/ 23315 if ((mask & BCM_PORT_ATTR_AUTONEG_MASK) && info->autoneg) { 23316 r = BCM_E_PARAM; 23317 if (BCM_FAILURE(r)) { 23318 LOG_ERROR(BSL_LS_BCM_PORT, 23319 (BSL_META_U(unit, 23320 "Autoneg:On. SPEED will be " 23321 "auto-detected :%s\n"), bcm_errmsg(r))); 23322 } 23323 BCM_IF_ERROR_RETURN(r); 23324 } 23325 #ifdef BCM_TOMAHAWK3_SUPPORT 23326 if (SOC_IS_TOMAHAWK3(unit) && IS_CD_PORT(unit, port)) { 23327 bcm_port_resource_t pr; 23328 r = bcm_esw_port_resource_get(unit, port, &pr); 23329 BCM_IF_ERROR_RETURN(r); 23330 if (pr.speed != info->speed) { 23331 LOG_INFO(BSL_LS_BCM_PORT, 23332 (BSL_META_U(unit, 23333 "Warning: bcm_port_info speed (%d) does NOT match " 23334 " current speed (%d). May have fec/link training/" 23335 "phy lane config mismatches!\n"), 23336 pr.speed, info->speed)); 23337 } 23338 pr.speed = info->speed; 23339 r = bcm_esw_port_resource_speed_set(unit, port, &pr); 23340 BCM_IF_ERROR_RETURN(r); 23341 } else 23342 #endif 23343 { 23344 r = bcm_esw_port_speed_set(unit, port, info->speed); 23345 } 23346 if (BCM_FAILURE(r)) { 23347 LOG_ERROR(BSL_LS_BCM_PORT, 23348 (BSL_META_U(unit, 23349 "bcm_port_speed_set failed:%s\n"), bcm_errmsg(r))); 23350 } 23351 BCM_IF_ERROR_RETURN(r); 23352 } 23353 23354 if (mask & BCM_PORT_ATTR_DUPLEX_MASK) { 23355 /*When AN=on, then duplex method will be auto-detected, hence don't set*/ 23356 if ((mask & BCM_PORT_ATTR_AUTONEG_MASK) && info->autoneg) { 23357 r = BCM_E_PARAM; 23358 if (BCM_FAILURE(r)) { 23359 LOG_ERROR(BSL_LS_BCM_PORT, 23360 (BSL_META_U(unit, 23361 "Autoneg:On. DUPLEX should be " 23362 "auto-detected :%s\n"), bcm_errmsg(r))); 23363 } 23364 BCM_IF_ERROR_RETURN(r); 23365 } 23366 r = bcm_esw_port_duplex_set(unit, port, info->duplex); 23367 if (BCM_FAILURE(r)) { 23368 LOG_ERROR(BSL_LS_BCM_PORT, 23369 (BSL_META_U(unit, 23370 "bcm_port_duplex_set failed:%s\n"), bcm_errmsg(r))); 23371 } 23372 BCM_IF_ERROR_RETURN(r); 23373 } 23374 23375 if (mask & (BCM_PORT_ATTR_PAUSE_TX_MASK | 23376 BCM_PORT_ATTR_PAUSE_RX_MASK)) { 23377 int tpause, rpause; 23378 23379 tpause = rpause = -1; 23380 if (mask & BCM_PORT_ATTR_PAUSE_TX_MASK) { 23381 tpause = info->pause_tx; 23382 } 23383 if (mask & BCM_PORT_ATTR_PAUSE_RX_MASK) { 23384 rpause = info->pause_rx; 23385 } 23386 r = bcm_esw_port_pause_set(unit, port, tpause, rpause); 23387 if (BCM_FAILURE(r)) { 23388 LOG_ERROR(BSL_LS_BCM_PORT, 23389 (BSL_META_U(unit, 23390 "bcm_port_pause_set failed:%s\n"), bcm_errmsg(r))); 23391 } 23392 BCM_IF_ERROR_RETURN(r); 23393 } 23394 23395 if (mask & BCM_PORT_ATTR_RATE_MCAST_MASK) { 23396 flags = (info->mcast_limit_enable) ? BCM_RATE_MCAST : 0; 23397 r = bcm_esw_rate_mcast_set(unit, info->mcast_limit, flags, port); 23398 if (r == BCM_E_UNAVAIL) { 23399 r = BCM_E_NONE; /* Ignore if not supported on chip */ 23400 } 23401 if (BCM_FAILURE(r)) { 23402 LOG_ERROR(BSL_LS_BCM_PORT, 23403 (BSL_META_U(unit, 23404 "bcm_rate_mcast_port_set failed:%s\n"), bcm_errmsg(r))); 23405 } 23406 BCM_IF_ERROR_RETURN(r); 23407 } 23408 23409 if (mask & BCM_PORT_ATTR_RATE_BCAST_MASK) { 23410 flags = (info->bcast_limit_enable) ? BCM_RATE_BCAST : 0; 23411 r = bcm_esw_rate_bcast_set(unit, info->bcast_limit, flags, port); 23412 if (r == BCM_E_UNAVAIL) { 23413 r = BCM_E_NONE; /* Ignore if not supported on chip */ 23414 } 23415 if (BCM_FAILURE(r)) { 23416 LOG_ERROR(BSL_LS_BCM_PORT, 23417 (BSL_META_U(unit, 23418 "bcm_rate_bcast_port_set failed:%s\n"), bcm_errmsg(r))); 23419 } 23420 BCM_IF_ERROR_RETURN(r); 23421 } 23422 23423 if (mask & BCM_PORT_ATTR_RATE_DLFBC_MASK) { 23424 flags = (info->dlfbc_limit_enable) ? BCM_RATE_DLF : 0; 23425 r = bcm_esw_rate_dlfbc_set(unit, info->dlfbc_limit, flags, port); 23426 if (r == BCM_E_UNAVAIL) { 23427 r = BCM_E_NONE; /* Ignore if not supported on chip */ 23428 } 23429 if (BCM_FAILURE(r)) { 23430 LOG_ERROR(BSL_LS_BCM_PORT, 23431 (BSL_META_U(unit, 23432 "bcm_rate_dlfbcast_port_set failed:%s\n"), 23433 bcm_errmsg(r))); 23434 } 23435 BCM_IF_ERROR_RETURN(r); 23436 } 23437 23438 if (mask & BCM_PORT_ATTR_STP_STATE_MASK) { 23439 r = bcm_esw_port_stp_set(unit, port, info->stp_state); 23440 if (BCM_FAILURE(r)) { 23441 LOG_ERROR(BSL_LS_BCM_PORT, 23442 (BSL_META_U(unit, 23443 "bcm_port_stp_set failed:%s\n"), bcm_errmsg(r))); 23444 } 23445 BCM_IF_ERROR_RETURN(r); 23446 } 23447 23448 if (mask & BCM_PORT_ATTR_FRAME_MAX_MASK) { 23449 r = bcm_esw_port_frame_max_set(unit, port, info->frame_max); 23450 if (BCM_FAILURE(r)) { 23451 LOG_ERROR(BSL_LS_BCM_PORT, 23452 (BSL_META_U(unit, 23453 "bcm_port_frame_max_set failed:%s\n"), bcm_errmsg(r))); 23454 } 23455 BCM_IF_ERROR_RETURN(r); 23456 } 23457 23458 if (mask & BCM_PORT_ATTR_MDIX_MASK) { 23459 r = bcm_esw_port_mdix_set(unit, port, info->mdix); 23460 if (BCM_FAILURE(r)) { 23461 LOG_ERROR(BSL_LS_BCM_PORT, 23462 (BSL_META_U(unit, 23463 "bcm_port_mdix_set failed:%s\n"), bcm_errmsg(r))); 23464 } 23465 BCM_IF_ERROR_RETURN(r); 23466 } 23467 23468 return BCM_E_NONE; 23469 } 23470 23471 /* 23472 * Function: 23473 * bcm_port_info_get 23474 * Purpose: 23475 * Get all information on the port 23476 * Parameters: 23477 * unit - StrataSwitch unit # 23478 * port - StrataSwitch port # 23479 * info - Pointer to structure in which to save values 23480 * Returns: 23481 * BCM_E_XXX 23482 */ 23483 23484 int 23485 bcm_esw_port_info_get(int unit, bcm_port_t port, bcm_port_info_t *info) 23486 { 23487 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 23488 23489 /* Make sure port module is initialized. */ 23490 PORT_INIT(unit); 23491 23492 bcm_port_info_t_init(info); 23493 23494 if (IS_ST_PORT(unit, port)) { 23495 info->action_mask = BCM_PORT_HERC_ATTRS; 23496 if (SOC_IS_XGS_SWITCH(unit)) { 23497 info->action_mask |= BCM_PORT_ATTR_STP_STATE_MASK | 23498 BCM_PORT_ATTR_DISCARD_MASK | 23499 BCM_PORT_ATTR_LEARN_MASK; 23500 } 23501 } else { 23502 info->action_mask = BCM_PORT_ATTR_ALL_MASK; 23503 } 23504 23505 return bcm_esw_port_selective_get(unit, port, info); 23506 } 23507 23508 /* 23509 * Function: 23510 * bcm_port_info_set 23511 * Purpose: 23512 * Set all information on the port 23513 * Parameters: 23514 * unit - StrataSwitch unit # 23515 * port - StrataSwitch port # 23516 * info - Pointer to structure in which to save values 23517 * Returns: 23518 * BCM_E_XXX 23519 * Notes: 23520 * Checks if AN is on, and if so, clears the 23521 * proper bits in the action mask. 23522 */ 23523 23524 int 23525 bcm_esw_port_info_set(int unit, bcm_port_t port, bcm_port_info_t *info) 23526 { 23527 /* Make sure port module is initialized. */ 23528 PORT_INIT(unit); 23529 23530 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 23531 23532 if (IS_ST_PORT(unit, port)) { 23533 info->action_mask = BCM_PORT_HERC_ATTRS; 23534 if (SOC_IS_XGS_SWITCH(unit)) { 23535 info->action_mask |= BCM_PORT_ATTR_STP_STATE_MASK | 23536 BCM_PORT_ATTR_DISCARD_MASK | 23537 BCM_PORT_ATTR_LEARN_MASK; 23538 } 23539 } else { 23540 info->action_mask = BCM_PORT_ATTR_ALL_MASK; 23541 } 23542 23543 /* If autoneg is set, remove those attributes controlled by it */ 23544 if (info->autoneg) { 23545 info->action_mask &= ~BCM_PORT_AN_ATTRS; 23546 } 23547 23548 return bcm_esw_port_selective_set(unit, port, info); 23549 } 23550 23551 /* 23552 * Function: 23553 * bcm_port_info_save 23554 * Purpose: 23555 * Save the current settings of a port 23556 * Parameters: 23557 * unit - StrataSwitch unit # 23558 * port - StrataSwitch port # 23559 * info - Pointer to structure in which to save values 23560 * Returns: 23561 * BCM_E_XXX 23562 * Notes: 23563 * The action_mask will be adjusted so that the 23564 * proper values will be set when a restore is made. 23565 * This mask should not be altered between these calls. 23566 */ 23567 23568 int 23569 bcm_esw_port_info_save(int unit, bcm_port_t port, bcm_port_info_t *info) 23570 { 23571 /* Make sure port module is initialized. */ 23572 PORT_INIT(unit); 23573 23574 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 23575 23576 if (IS_ST_PORT(unit, port)) { 23577 info->action_mask = BCM_PORT_HERC_ATTRS; 23578 if (SOC_IS_XGS_SWITCH(unit)) { 23579 info->action_mask |= BCM_PORT_ATTR_STP_STATE_MASK; 23580 } 23581 #ifdef BCM_GXPORT_SUPPORT 23582 if (IS_GX_PORT(unit, port)) { 23583 info->action_mask |= BCM_PORT_ATTR_AUTONEG_MASK; 23584 } 23585 #endif 23586 } else { 23587 info->action_mask = BCM_PORT_ATTR_ALL_MASK; 23588 } 23589 info->action_mask2 = BCM_PORT_ATTR2_PORT_ABILITY; 23590 23591 BCM_IF_ERROR_RETURN(bcm_esw_port_selective_get(unit, port, info)); 23592 23593 if (info->autoneg) { 23594 info->action_mask &= ~BCM_PORT_AN_ATTRS; 23595 } 23596 23597 return BCM_E_NONE; 23598 } 23599 23600 /* 23601 * Function: 23602 * bcm_port_info_restore 23603 * Purpose: 23604 * Restore port settings saved by info_save 23605 * Parameters: 23606 * unit - StrataSwitch unit # 23607 * port - StrataSwitch port # 23608 * info - Pointer to structure with info from port_info_save 23609 * Returns: 23610 * BCM_E_XXX 23611 * Notes: 23612 * bcm_port_info_save has done all the work. 23613 * We just call port_selective_set. 23614 */ 23615 23616 int 23617 bcm_esw_port_info_restore(int unit, bcm_port_t port, bcm_port_info_t *info) 23618 { 23619 /* Make sure port module is initialized. */ 23620 PORT_INIT(unit); 23621 23622 return bcm_esw_port_selective_set(unit, port, info); 23623 } 23624 23625 /* 23626 * Function: 23627 * bcm_port_phy_drv_name_get 23628 * Purpose: 23629 * Return the name of the PHY driver being used on a port. 23630 * Parameters: 23631 * unit - StrataSwitch unit # 23632 * port - StrataSwitch port # 23633 * Returns: 23634 * Pointer to static string 23635 */ 23636 int 23637 bcm_esw_port_phy_drv_name_get(int unit, bcm_port_t port, char *name, int len) 23638 { 23639 int str_len; 23640 23641 /* Make sure port module is initialized. */ 23642 PORT_INIT(unit); 23643 23644 if(bcm_common_oamp_port_enable_get(unit, port)) { 23645 LOG_ERROR(BSL_LS_BCM_PORT, 23646 (BSL_META("Error: Not permitted on OAMP port %d.n"), 23647 port)); 23648 return BCM_E_PARAM; 23649 } 23650 23651 /* Call Port Control module */ 23652 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 23653 return bcmi_esw_portctrl_phy_drv_name_get(unit, port, name, len); 23654 } 23655 23656 if (bcm_port_info[unit] == NULL) { 23657 str_len = sal_strlen("driver not initialized"); 23658 if (str_len <= len) { 23659 sal_strlcpy(name, "driver not initialized", len); 23660 } 23661 return BCM_E_INIT; 23662 } 23663 if (!SOC_PORT_VALID(unit, port)) { 23664 str_len = sal_strlen("invalid port"); 23665 if (str_len <= len) { 23666 sal_strlcpy(name, "invalid port", len); 23667 } 23668 return BCM_E_PORT; 23669 } 23670 return (soc_phyctrl_drv_name_get(unit, port, name, len)); 23671 } 23672 23673 /* 23674 * Function: 23675 * _bcm_port_encap_xport_set 23676 * Purpose: 23677 * Convert 10G Ether port to Higig port, or reverse 23678 * Notes; 23679 * Must be called with PORT_LOCK held. 23680 */ 23681 23682 int 23683 _bcm_port_encap_xport_set(int unit, bcm_port_t port, int mode, 23684 int update_port_mode) 23685 { 23686 #ifdef BCM_FIREBOLT_SUPPORT 23687 bcm_stg_t stg; 23688 int to_higig; 23689 soc_field_t port_type_field; 23690 soc_reg_t egr_port_reg; 23691 soc_port_ability_t ability; 23692 soc_port_mode_t non_ieee_speed; 23693 int an, an_done, force_speed, port_type; 23694 uint32 entry[SOC_MAX_MEM_WORDS]; 23695 #ifdef BCM_TRIDENT2_SUPPORT 23696 int config_speed = 0; 23697 #endif 23698 #if defined(BCM_KATANA2_SUPPORT) 23699 int speed = 0; 23700 bcmMxqPhyPortMode_t phy_mode; 23701 #endif 23702 int enable = 0; 23703 #if defined(BCM_XGS3_SWITCH_SUPPORT) 23704 uint32 rval = 0; 23705 uint32 mtu = 0; 23706 soc_info_t *si = &SOC_INFO(unit); 23707 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 23708 23709 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 23710 return bcmi_esw_portctrl_encap_xport_set(unit, port, mode); 23711 } 23712 23713 to_higig = (mode != BCM_PORT_ENCAP_IEEE); 23714 port_type_field = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 23715 SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) || 23716 SOC_IS_HURRICANEX(unit) || SOC_IS_TD_TT(unit) || 23717 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)|| 23718 SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit)) ? 23719 PORT_TYPEf : HIGIG_PACKETf; 23720 egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 23721 SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) || 23722 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ? 23723 EGR_PORT_64r : EGR_PORTr; 23724 23725 #if defined(BCM_KATANA2_SUPPORT) 23726 if (to_higig && SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit) && 23727 update_port_mode) { 23728 /* 23729 * Updating the phy_mode according to the port encap type. 23730 * Using 13G as default speed for higig since the underlying routine 23731 * do not differentiate on higig speeds. 23732 */ 23733 SOC_IF_ERROR_RETURN 23734 (soc_katana2_get_phy_port_mode(unit, port, 13000, &phy_mode)); 23735 } 23736 #endif 23737 SOC_IF_ERROR_RETURN 23738 (MAC_ENCAP_SET(PORT(unit, port).p_mac, unit, port, mode)); 23739 23740 if ((SOC_IS_SABER2(unit) || SOC_IS_HURRICANE2(unit)) && IS_XL_PORT(unit, port)) { 23741 if (mode == BCM_PORT_ENCAP_HIGIG2_LITE) { 23742 SOC_PBMP_PORT_ADD(SOC_INFO(unit).hl.bitmap, port); 23743 } else { 23744 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port); 23745 } 23746 } 23747 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 23748 if ((mode == BCM_PORT_ENCAP_HIGIG2_LITE) && IS_ST_PORT(unit, port)) { 23749 /*KT2: HL port is treated as GE port too*/ 23750 SOC_PBMP_PORT_ADD(SOC_INFO(unit).hl.bitmap, port); 23751 SOC_PBMP_PORT_ADD(SOC_INFO(unit).ge.bitmap, port); 23752 } else if ((mode == BCM_PORT_ENCAP_IEEE) && IS_XE_PORT(unit,port)) { 23753 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port); 23754 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).ge.bitmap, port); 23755 } 23756 soc_dport_map_update(unit); 23757 } 23758 /* 23759 * MAC_ENCAP_SET() would change the ING_MTU to defalut value. 23760 * So also change EGR_MTU to default value manually. 23761 */ 23762 #ifdef BCM_SHADOW_SUPPORT 23763 if (SOC_IS_SHADOW(unit)) { 23764 mtu = (1 << soc_reg_field_length(unit, EGR_L2_MTUr, VALUEf)) - 1; 23765 soc_reg_field_set(unit, EGR_L2_MTUr, &rval, 23766 VALUEf, mtu); 23767 SOC_IF_ERROR_RETURN(WRITE_EGR_L2_MTUr(unit, port, rval)); 23768 } else 23769 #endif /* BCM_SHADOW_SUPPORT */ 23770 23771 #ifdef BCM_XGS3_SWITCH_SUPPORT 23772 if (SOC_IS_XGS3_SWITCH(unit)) { 23773 soc_reg_t reg; 23774 soc_mem_t mem; 23775 uint32 field_val_clear = 0; 23776 23777 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 23778 mem = EGR_MTUm; 23779 mtu = si->max_mtu; 23780 if (soc_feature(unit, soc_feature_egr_all_profile)) { 23781 BCM_IF_ERROR_RETURN( 23782 bcm_esw_port_egr_lport_field_set(unit, port, mem, 23783 MTU_SIZEf, mtu)); 23784 } else { 23785 SOC_IF_ERROR_RETURN( 23786 soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, entry)); 23787 soc_mem_field_set(unit, mem, entry, MTU_SIZEf, &mtu); 23788 if (soc_mem_field_valid(unit, mem, MTU_ENABLEf)) { 23789 soc_mem_field_set(unit, mem, entry, MTU_ENABLEf, 23790 &field_val_clear); 23791 } 23792 SOC_IF_ERROR_RETURN( 23793 soc_mem_write(unit, mem, MEM_BLOCK_ANY, port, entry)); 23794 } 23795 } else { 23796 reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr; 23797 mtu = si->max_mtu; 23798 soc_reg_field_set(unit, reg, &rval, MTU_SIZEf, mtu); 23799 if (soc_reg_field_valid(unit, reg, MTU_ENABLEf)) { 23800 soc_reg_field_set(unit, reg, &rval, MTU_ENABLEf, 0); 23801 } 23802 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 23803 } 23804 } 23805 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 23806 23807 if (!to_higig) { 23808 SOC_IF_ERROR_RETURN 23809 (MAC_INTERFACE_SET(PORT(unit, port).p_mac, 23810 unit, port, SOC_PORT_IF_XGMII)); 23811 } 23812 23813 /* Sepcific for GH on avoiding port speed change */ 23814 if (!soc_feature(unit, soc_feature_hg_no_speed_change)) { 23815 BCM_IF_ERROR_RETURN 23816 (bcm_esw_port_ability_local_get(unit, port, &ability)); 23817 23818 non_ieee_speed = ability.speed_full_duplex & 23819 ~(SOC_PA_SPEED_100GB | SOC_PA_SPEED_40GB | SOC_PA_SPEED_10GB | 23820 SOC_PA_SPEED_2500MB | SOC_PA_SPEED_1000MB | SOC_PA_SPEED_100MB | 23821 SOC_PA_SPEED_10MB); 23822 23823 BCM_IF_ERROR_RETURN 23824 (bcm_esw_port_ability_advert_get(unit, port, &ability)); 23825 if (to_higig) { 23826 ability.speed_full_duplex |= non_ieee_speed; 23827 ability.pause &= ~(SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM); 23828 /* Retrieving the max speed */ 23829 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_max(unit, port, &force_speed)); 23830 force_speed = force_speed == 0 ? 23831 SOC_CONTROL(unit)->info.port_speed_max[port] : force_speed; 23832 23833 #ifdef BCM_TRIDENT2_SUPPORT 23834 if (SOC_IS_TRIDENT2(unit) && 23835 soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, 0) && 23836 (si->port_num_lanes[port] != 4)) { 23837 config_speed = soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, force_speed); 23838 force_speed = (force_speed > config_speed) ? config_speed : force_speed; 23839 } 23840 #endif 23841 23842 ability.speed_full_duplex |= SOC_PA_SPEED(force_speed); 23843 } else { 23844 ability.speed_full_duplex &= ~non_ieee_speed; 23845 force_speed = IS_GE_PORT(unit , port) ? 1000 : IS_CE_PORT(unit , port) ? 23846 100000 : SOC_CONTROL(unit)->info.port_speed_max[port] >= 40000 ? 23847 40000 : SOC_CONTROL(unit)->info.port_speed_max[port] >= 10000 ? 23848 10000 : 1000; 23849 #if defined(BCM_KATANA2_SUPPORT) 23850 /* For Katana2 Warpcore the xlport_mode_reg. The phy_port_mode value 23851 * differs when speed is 1000 vs 2500. 23852 * GE port does not necessarily have 1000 speed always. 23853 * The VCO frequency can change ased on phy_port_mode, 23854 * core_port_mode and number of lanes on Warpcore. 23855 * The lower layer Warpcore driver relies on these values. 23856 * So we need to set the correct forced speed for the port */ 23857 if ((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && force_speed == 1000) { 23858 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed)); 23859 force_speed = (speed == 2500) ? speed : force_speed; 23860 } 23861 #endif 23862 } 23863 23864 BCM_IF_ERROR_RETURN 23865 (bcm_esw_port_ability_advert_set(unit, port, &ability)); 23866 23867 #ifdef BCM_KATANA2_SUPPORT 23868 #ifdef BCM_METROLITE_SUPPORT 23869 if (SOC_IS_METROLITE(unit)) { 23870 BCM_IF_ERROR_RETURN 23871 (_bcm_ml_update_port_mode(unit, port, force_speed)); 23872 23873 if (IS_XL_PORT(unit,port) && 23874 ((mode == BCM_PORT_ENCAP_HIGIG2) || (mode == BCM_PORT_ENCAP_HIGIG))) { 23875 SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, force_speed)); 23876 SOC_IF_ERROR_RETURN(MAC_SPEED_SET(PORT(unit, port).p_mac, 23877 unit, port, force_speed)); 23878 } 23879 } else 23880 #endif 23881 23882 #ifdef BCM_SABER2_SUPPORT 23883 if (SOC_IS_SABER2(unit)) { 23884 BCM_IF_ERROR_RETURN 23885 (_bcm_sb2_update_port_mode(unit, port, force_speed)); 23886 23887 if (IS_XL_PORT(unit,port) && 23888 ((mode == BCM_PORT_ENCAP_HIGIG2) || (mode == BCM_PORT_ENCAP_HIGIG))) { 23889 SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, force_speed)); 23890 SOC_IF_ERROR_RETURN(MAC_SPEED_SET(PORT(unit, port).p_mac, 23891 unit, port, force_speed)); 23892 } 23893 } else 23894 #endif 23895 if(SOC_IS_KATANA2(unit) && update_port_mode) { 23896 BCM_IF_ERROR_RETURN 23897 (_bcm_kt2_update_port_mode(unit, port, force_speed)); 23898 } 23899 #endif 23900 SOC_IF_ERROR_RETURN 23901 (soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done)); 23902 /* some phy driver will enable the port no matter previous port 23903 * state while executing speed_set or autoneg_set. So we need to 23904 * get the port state before speed_set or autoneg_set, and set it 23905 * back after speed_set or autoneg_set. So that it can keep the 23906 * same port state before after speed_set or autoneg_set*/ 23907 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable)); 23908 23909 /* Some mac driver re-init phy while executing MAC_ENCAP_SET, in that case 23910 * autoneg is probably always true here */ 23911 if (an) { 23912 SOC_IF_ERROR_RETURN(bcm_esw_port_autoneg_set(unit, port, TRUE)); 23913 } else { 23914 SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, force_speed)); 23915 } 23916 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, enable)); 23917 } 23918 23919 /* Now we propagate the changes */ 23920 port_type = to_higig ? 1 : 0; 23921 if (soc_mem_field_valid(unit, PORT_TABm, port_type_field)) { 23922 SOC_IF_ERROR_RETURN(soc_mem_field32_modify( 23923 unit, PORT_TABm, port, port_type_field, port_type)); 23924 } 23925 if (SOC_MEM_IS_VALID(unit, EGR_PORTm)) { 23926 if (soc_mem_field_valid(unit, EGR_PORTm, port_type_field)) { 23927 SOC_IF_ERROR_RETURN 23928 (soc_mem_field32_modify(unit, EGR_PORTm, port, port_type_field, 23929 port_type)); 23930 } 23931 } else { 23932 SOC_IF_ERROR_RETURN 23933 (soc_reg_field32_modify(unit, egr_port_reg, port, port_type_field, 23934 port_type)); 23935 } 23936 23937 if (SOC_MEM_IS_VALID(unit, EGR_ING_PORTm)) { 23938 if (!IS_CPU_PORT(unit, port) && !IS_LB_PORT(unit, port)) { 23939 SOC_IF_ERROR_RETURN 23940 (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, PORT_TYPEf, 23941 mode == BCM_PORT_ENCAP_IEEE ? 0 : 1)); 23942 } 23943 } 23944 23945 23946 if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) { 23947 icontrol_opcode_bitmap_entry_t entry; 23948 soc_pbmp_t pbmp; 23949 23950 SOC_IF_ERROR_RETURN 23951 (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 23952 SOC_PBMP_CLEAR(pbmp); 23953 if (to_higig) { 23954 SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit)); 23955 } 23956 soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry, 23957 BITMAPf, &pbmp); 23958 SOC_IF_ERROR_RETURN 23959 (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 23960 } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 23961 SOC_IS_VALKYRIE2(unit)) { 23962 uint64 cpu_pbm64; 23963 uint64 rval64; /* Current 64 bit register data. */ 23964 COMPILER_64_ZERO(cpu_pbm64); 23965 COMPILER_64_SET(cpu_pbm64, 0, to_higig ? 1 : 0); 23966 SOC_IF_ERROR_RETURN(READ_ICONTROL_OPCODE_BITMAP_64r(unit, port, 23967 &rval64)); 23968 soc_reg64_field_set(unit, ICONTROL_OPCODE_BITMAP_64r, &rval64, 23969 BITMAPf, cpu_pbm64); 23970 SOC_IF_ERROR_RETURN(WRITE_ICONTROL_OPCODE_BITMAP_64r(unit, port, 23971 rval64)); 23972 } else if (SOC_REG_IS_VALID(unit,ICONTROL_OPCODE_BITMAP_LOr) && 23973 SOC_REG_IS_VALID(unit,ICONTROL_OPCODE_BITMAP_HIr)) { 23974 uint64 fval64, rval64; 23975 uint32 t_port; 23976 pbmp_t curr_pbmp; 23977 soc_reg_t reg; 23978 23979 BCM_PBMP_CLEAR(curr_pbmp); 23980 COMPILER_64_ZERO(fval64); 23981 23982 /* Set HG ingress CPU Opcode map to the CPU */ 23983 if (CMIC_PORT(unit) < 64) { 23984 reg = ICONTROL_OPCODE_BITMAP_LOr; 23985 t_port = CMIC_PORT(unit); 23986 } else { 23987 reg = ICONTROL_OPCODE_BITMAP_HIr; 23988 t_port = CMIC_PORT(unit) - 64; 23989 } 23990 23991 23992 if (to_higig) { 23993 SOC_PBMP_PORT_ADD(curr_pbmp, t_port); 23994 } 23995 23996 BCM_IF_ERROR_RETURN(soc_reg_get(unit, 23997 reg, port, 0, &rval64)); 23998 COMPILER_64_SET(fval64, 23999 SOC_PBMP_WORD_GET(curr_pbmp, 1), 24000 SOC_PBMP_WORD_GET(curr_pbmp, 0)); 24001 24002 soc_reg64_field_set(unit, 24003 reg, &rval64, BITMAPf, fval64); 24004 BCM_IF_ERROR_RETURN(soc_reg_set(unit, 24005 reg, port, 0, rval64)); 24006 24007 } else if (SOC_REG_IS_VALID(unit,ICONTROL_OPCODE_BITMAPr)) { 24008 24009 /* Set HG ingress CPU Opcode map to the CPU */ 24010 int pbm_len; 24011 uint32 cpu_pbm = 0; 24012 24013 if (to_higig) { 24014 if (SOC_IS_TR_VL(unit)) { 24015 soc_xgs3_port_to_higig_bitmap(unit, CMIC_PORT(unit), 24016 &cpu_pbm); 24017 } else if (CMIC_PORT(unit)) { 24018 pbm_len = soc_reg_field_length(unit, ICONTROL_OPCODE_BITMAPr, 24019 BITMAPf); 24020 cpu_pbm = 1 << (pbm_len - 1); 24021 } else { 24022 cpu_pbm = 1; 24023 } 24024 } /* else, cpu_pbm = 0 */ 24025 24026 SOC_IF_ERROR_RETURN 24027 (soc_reg_field32_modify(unit, ICONTROL_OPCODE_BITMAPr, 24028 port, BITMAPf, cpu_pbm)); 24029 } 24030 24031 if (to_higig) { 24032 /* HG ports to forwarding */ 24033 BCM_IF_ERROR_RETURN(bcm_esw_port_stp_set(unit, port, 24034 BCM_STG_STP_FORWARD)); 24035 } 24036 24037 #if defined(BCM_XGS3_SWITCH_SUPPORT) 24038 /* 24039 * Higig ports need the MIRROR_CONTROL.M_ENABLE=1 in order to respond to 24040 * the mirror bit in the Higig headers. 24041 */ 24042 if (to_higig) { 24043 BCM_IF_ERROR_RETURN(_bcm_esw_mirror_enable_set(unit, port, TRUE)); 24044 } 24045 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 24046 24047 /* Clear mirror enable settings */ 24048 /* coverity[stack_use_callee] */ 24049 /* coverity[stack_use_overflow] */ 24050 BCM_IF_ERROR_RETURN(bcm_esw_mirror_port_set(unit, port, -1, -1, 0)); 24051 24052 /* Set untagged state in default VLAN properly */ 24053 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_untag_update(unit, port, to_higig)); 24054 24055 /* Resolve STG 0 */ 24056 BCM_IF_ERROR_RETURN(bcm_esw_stg_default_get(unit, &stg)); 24057 BCM_IF_ERROR_RETURN 24058 (bcm_esw_stg_stp_set(unit, 0, port, 24059 to_higig ? BCM_STG_STP_FORWARD : BCM_STG_STP_DISABLE)); 24060 24061 #ifdef BCM_TRX_SUPPORT 24062 /* Reset the vlan default action */ 24063 if (SOC_IS_TRX(unit) && 24064 (soc_feature(unit, soc_feature_vlan_action) || 24065 soc_feature(unit, soc_feature_egr_vlan_action))) { 24066 bcm_vlan_action_set_t action; 24067 24068 BCM_IF_ERROR_RETURN 24069 (_bcm_trx_vlan_port_egress_default_action_get(unit, 24070 port, &action)); 24071 /* Backward compatible defaults */ 24072 if (to_higig && (!SOC_IS_TRIDENT3X(unit))) { 24073 action.ot_outer = bcmVlanActionDelete; 24074 action.dt_outer = bcmVlanActionDelete; 24075 } else { 24076 action.ot_outer = bcmVlanActionNone; 24077 action.dt_outer = bcmVlanActionNone; 24078 } 24079 BCM_IF_ERROR_RETURN 24080 (_bcm_trx_vlan_port_egress_default_action_set(unit, 24081 port, &action)); 24082 } 24083 #endif 24084 24085 #ifdef INCLUDE_L3 24086 if (soc_feature(unit, soc_feature_ip_mcast)) { 24087 BCM_IF_ERROR_RETURN(bcm_esw_ipmc_egress_port_set(unit, port, 24088 to_higig ? _soc_mac_all_ones :_soc_mac_all_zeroes, 24089 0, 0, 0)); 24090 } 24091 #endif /* INCLUDE_L3 */ 24092 24093 return BCM_E_NONE; 24094 #else 24095 return BCM_E_PARAM; 24096 #endif 24097 } 24098 24099 /* 24100 * Function: 24101 * _bcm_port_encap_stport_set 24102 * Purpose: 24103 * Convert 2.5G Higig 2 port to Ether port, or reverse 24104 */ 24105 int 24106 _bcm_port_encap_stport_set(int unit, bcm_port_t port, int mode) 24107 { 24108 #if defined(BCM_RAVEN_SUPPORT) || defined (BCM_TRIUMPH2_SUPPORT) || \ 24109 defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 24110 uint32 rval; 24111 bcm_stg_t stg; 24112 int to_higig = 0, max_mtu = 0; 24113 uint32 tab_higig_type; 24114 soc_info_t *si = &SOC_INFO(unit); 24115 soc_field_t hg_en[6] = {-1, HGIG2_EN_S0f, HGIG2_EN_S1f, -1, 24116 HGIG2_EN_S3f, HGIG2_EN_S4f}; 24117 soc_field_t port_type; 24118 soc_reg_t egr_port; 24119 24120 if (mode == BCM_PORT_ENCAP_HIGIG2 || mode == BCM_PORT_ENCAP_HIGIG2_LITE 24121 || mode == BCM_PORT_ENCAP_HIGIG || mode == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) { 24122 to_higig = TRUE; 24123 } 24124 24125 #ifdef BCM_FIRELIGHT_SUPPORT 24126 if (SOC_IS_FIRELIGHT(unit)) { 24127 /* FL goes through */ 24128 } else 24129 #endif 24130 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 24131 SOC_IS_GREYHOUND2(unit)) { 24132 if (!soc_feature(unit, soc_feature_wh2)) { 24133 return BCM_E_INTERNAL; 24134 } 24135 } 24136 24137 /* This check is not correct for devices supporting embedded higig */ 24138 if (!soc_feature(unit, soc_feature_embedded_higig) && 24139 !soc_feature(unit, soc_feature_higig_over_ethernet)) { 24140 if (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit)) { 24141 if ((port != 26) && (port != 27) && (port != 28) && (port != 29)) { 24142 return BCM_E_PORT; 24143 } 24144 SOC_IF_ERROR_RETURN 24145 (soc_reg_field32_modify(unit, EHG_RX_CONTROLr, port, MODEf, 24146 to_higig ? 2 : 0)); 24147 } else if (SOC_IS_HURRICANE2(unit)) { 24148 if ((port < 26) || (port > 29)) { 24149 return BCM_E_PORT; 24150 } 24151 } else if (SOC_IS_KATANA(unit)) { 24152 /* Only ports 25..34 are HGL capable */ 24153 if ((port < 25) || (port > 34)) { 24154 return BCM_E_PORT; 24155 } 24156 } else if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 24157 /* Only ports 25..40 are HGL capable */ 24158 if ((port < 25) || (port > 40)) { 24159 return BCM_E_PORT; 24160 } 24161 } else if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TOMAHAWKX(unit) || 24162 SOC_IS_TRIDENT3X(unit)) { 24163 /* Need to check what is the right condition for Embedded Higig */ 24164 } else if (soc_feature(unit, soc_feature_wh2)) { 24165 /* All ports are HGL capable */ 24166 #ifdef BCM_FIRELIGHT_SUPPORT 24167 } else if (SOC_IS_FIRELIGHT(unit)) { 24168 /* All ports are HGL capable */ 24169 #endif 24170 } else { 24171 if ((port != 1) && (port != 2) && (port != 4) && (port != 5)) { 24172 return BCM_E_PORT; 24173 } 24174 } 24175 } 24176 24177 #if defined(BCM_KATANA2_SUPPORT) 24178 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 24179 SOC_IF_ERROR_RETURN(MAC_ENCAP_SET(PORT(unit, port).p_mac, 24180 unit, port, mode)); 24181 } else 24182 #endif 24183 { 24184 port_type = SOC_MEM_FIELD_VALID(unit, 24185 SOC_PORT_MEM_TAB(unit, port), 24186 HIGIG_PACKETf) ? 24187 HIGIG_PACKETf : PORT_TYPEf; 24188 24189 BCM_IF_ERROR_RETURN 24190 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 24191 port_type, to_higig)); 24192 24193 if (to_higig == 1) { 24194 if (mode == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) { 24195 tab_higig_type = BCM_PORT_HG_TYPE_HGOE_TRANSPORT; 24196 } else if (mode == BCM_PORT_ENCAP_HIGIG) { 24197 tab_higig_type = BCM_PORT_HG_TYPE_HIGIGPLUS; 24198 } else { 24199 tab_higig_type = BCM_PORT_HG_TYPE_HIGIG2_NORMAL; 24200 } 24201 } else { 24202 tab_higig_type = 0; 24203 } 24204 24205 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, HG_TYPEf)) { 24206 SOC_IF_ERROR_RETURN 24207 (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, 24208 HG_TYPEf, tab_higig_type)); 24209 } 24210 24211 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, HG_TYPEf)) { 24212 SOC_IF_ERROR_RETURN 24213 (soc_mem_field32_modify(unit, EGR_PORTm, port, 24214 HG_TYPEf, tab_higig_type)); 24215 } 24216 24217 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, PORT_TYPEf)) { 24218 SOC_IF_ERROR_RETURN 24219 (soc_mem_field32_modify(unit, EGR_PORTm, port, 24220 PORT_TYPEf, to_higig)); 24221 } else { 24222 if (SOC_REG_IS_VALID(unit, EGR_PORT_64r)) { 24223 egr_port = EGR_PORT_64r; 24224 } else { 24225 egr_port = EGR_PORTr; 24226 } 24227 SOC_IF_ERROR_RETURN 24228 (soc_reg_field32_modify(unit, egr_port, port, 24229 port_type, to_higig)); 24230 } 24231 24232 /* The port number check is for Coverity. No port > 6 will 24233 * reach this logic on Raven. */ 24234 if (SOC_IS_RAVEN(unit) && (port < 6)) { 24235 SOC_IF_ERROR_RETURN 24236 (soc_reg_field32_modify(unit, GPORT_CONFIGr, port, 24237 hg_en[port], to_higig)); 24238 } 24239 } 24240 24241 if (to_higig) { 24242 BCM_IF_ERROR_RETURN(bcm_esw_port_pause_set(unit, port, 0, 0)); 24243 /* For encap to hg/st port, SOC_PORT_MIN need to update or 24244 cannot do SOC_PBMP_PORT_ADD if the port is lower than 24245 SOC_PORT_MIN 24246 */ 24247 if ((port < SOC_PORT_MIN(unit,st)) || (SOC_PORT_MIN(unit,st) == -1)) { 24248 SOC_PORT_MIN(unit,st) = port; 24249 } 24250 if (port > SOC_PORT_MAX(unit,st)) { 24251 SOC_PORT_MAX(unit,st) = port; 24252 } 24253 24254 SOC_PBMP_PORT_ADD(si->st.bitmap, port); 24255 SOC_PBMP_PORT_ADD(si->hl.bitmap, port); 24256 SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port); 24257 SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port); 24258 24259 SOC_PBMP_PORT_INFO_UPDATE(si->xe); 24260 24261 max_mtu = SOC_INFO(unit).max_mtu; 24262 BCM_IF_ERROR_RETURN(bcm_esw_port_frame_max_set(unit, port, max_mtu)); 24263 } else { 24264 SOC_PBMP_PORT_REMOVE(si->st.bitmap, port); 24265 SOC_PBMP_PORT_REMOVE(si->hl.bitmap, port); 24266 SOC_PBMP_PORT_ADD(si->ether.bitmap, port); 24267 24268 /* Set pause and frame - other abilities depend on the board and 24269 * the application needs to call other APIs appropriately */ 24270 BCM_IF_ERROR_RETURN(bcm_esw_port_pause_set(unit, port, 1, 1)); 24271 max_mtu = SOC_INFO(unit).max_mtu - 4; 24272 BCM_IF_ERROR_RETURN(bcm_esw_port_frame_max_set(unit, port, max_mtu)); 24273 } 24274 SOC_PBMP_PORT_INFO_UPDATE(si->ether); 24275 SOC_PBMP_PORT_INFO_UPDATE(si->st); 24276 SOC_PBMP_PORT_INFO_UPDATE(si->hl); 24277 24278 /* Set HG ingress CPU Opcode map to the CPU */ 24279 if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) { 24280 icontrol_opcode_bitmap_entry_t entry; 24281 soc_pbmp_t pbmp; 24282 24283 SOC_IF_ERROR_RETURN 24284 (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 24285 SOC_PBMP_CLEAR(pbmp); 24286 if (to_higig) { 24287 SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit)); 24288 } 24289 soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry, 24290 BITMAPf, &pbmp); 24291 SOC_IF_ERROR_RETURN 24292 (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 24293 } else if (SOC_REG_IS_VALID(unit, ICONTROL_OPCODE_BITMAP_64r)) { 24294 uint64 cpu_pbm64; 24295 uint64 rval64; /* Current 64 bit register data. */ 24296 COMPILER_64_ZERO(cpu_pbm64); 24297 COMPILER_64_SET(cpu_pbm64, 0, to_higig ? 1 : 0); 24298 SOC_IF_ERROR_RETURN( 24299 READ_ICONTROL_OPCODE_BITMAP_64r(unit, port,&rval64)); 24300 24301 soc_reg64_field_set(unit, ICONTROL_OPCODE_BITMAP_64r, &rval64, 24302 BITMAPf, cpu_pbm64); 24303 24304 SOC_IF_ERROR_RETURN( 24305 WRITE_ICONTROL_OPCODE_BITMAP_64r(unit, port, rval64)); 24306 } else { 24307 uint32 cpu_pbm; 24308 24309 if(SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit)) { 24310 if(to_higig) { 24311 SOC_IF_ERROR_RETURN 24312 (soc_xgs3_port_to_higig_bitmap(unit, CMIC_PORT(unit), 24313 &cpu_pbm)); 24314 } else { 24315 cpu_pbm = 0; 24316 } 24317 } else { 24318 cpu_pbm = to_higig ? 1 : 0; 24319 } 24320 #ifdef BCM_FIRELIGHT_SUPPORT 24321 if (SOC_IS_FIRELIGHT(unit)) { 24322 uint64 fval64, rval64; 24323 uint32 t_port; 24324 pbmp_t curr_pbmp; 24325 soc_reg_t reg; 24326 24327 BCM_PBMP_CLEAR(curr_pbmp); 24328 COMPILER_64_ZERO(fval64); 24329 24330 /* Set HG ingress CPU Opcode map to the CPU */ 24331 if (CMIC_PORT(unit) < 64) { 24332 reg = ICONTROL_OPCODE_BITMAP_LOr; 24333 t_port = CMIC_PORT(unit); 24334 } else { 24335 reg = ICONTROL_OPCODE_BITMAP_HIr; 24336 t_port = CMIC_PORT(unit) - 64; 24337 } 24338 24339 if (to_higig) { 24340 SOC_PBMP_PORT_ADD(curr_pbmp, t_port); 24341 } 24342 24343 BCM_IF_ERROR_RETURN(soc_reg_get(unit, 24344 reg, port, 0, &rval64)); 24345 COMPILER_64_SET(fval64, 24346 SOC_PBMP_WORD_GET(curr_pbmp, 1), 24347 SOC_PBMP_WORD_GET(curr_pbmp, 0)); 24348 24349 soc_reg64_field_set(unit, 24350 reg, &rval64, BITMAPf, fval64); 24351 BCM_IF_ERROR_RETURN(soc_reg_set(unit, 24352 reg, port, 0, rval64)); 24353 } else 24354 #endif 24355 { 24356 SOC_IF_ERROR_RETURN( 24357 READ_ICONTROL_OPCODE_BITMAPr(unit, port,&rval)); 24358 24359 soc_reg_field_set(unit, ICONTROL_OPCODE_BITMAPr, 24360 &rval, BITMAPf, cpu_pbm); 24361 24362 SOC_IF_ERROR_RETURN( 24363 WRITE_ICONTROL_OPCODE_BITMAPr(unit, port, rval)); 24364 } 24365 } 24366 24367 /* HG ports to forwarding */ 24368 BCM_IF_ERROR_RETURN( 24369 bcm_esw_port_stp_set(unit, port, BCM_STG_STP_FORWARD)); 24370 24371 /* Set untagged state in default VLAN properly */ 24372 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_untag_update(unit, port, to_higig)); 24373 24374 /* Resolve STG 0 */ 24375 BCM_IF_ERROR_RETURN(bcm_esw_stg_default_get(unit, &stg)); 24376 BCM_IF_ERROR_RETURN( 24377 bcm_esw_stg_stp_set(unit, stg, port, BCM_STG_STP_FORWARD)); 24378 24379 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 24380 /* Reset the vlan default action */ 24381 if ((SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) || 24382 SOC_IS_KATANA2(unit)) && 24383 soc_feature(unit, soc_feature_vlan_action)) { 24384 bcm_vlan_action_set_t action; 24385 24386 BCM_IF_ERROR_RETURN 24387 (_bcm_trx_vlan_port_egress_default_action_get(unit, 24388 port, &action)); 24389 if (to_higig) { 24390 action.ot_outer = bcmVlanActionDelete; 24391 action.dt_outer = bcmVlanActionDelete; 24392 } else { 24393 action.ot_outer = bcmVlanActionNone; 24394 action.dt_outer = bcmVlanActionNone; 24395 } 24396 BCM_IF_ERROR_RETURN 24397 (_bcm_trx_vlan_port_egress_default_action_set(unit, 24398 port, &action)); 24399 } 24400 #endif /* BCM_ENDURO_SUPPORT */ 24401 24402 return BCM_E_NONE; 24403 #else 24404 return BCM_E_PARAM; 24405 #endif 24406 } 24407 24408 /* 24409 * Function: 24410 * _bcm_port_ehg_header_mem_get 24411 * Purpose: 24412 * Calculates the correct memories for a given port 24413 * Parameters: 24414 * unit - (IN) device id 24415 * port - (IN) Physical port 24416 * tx_mem - (OUT) tx memory for EHG heade 24417 * rx_mem - (OUT) rx memory for EHG heade 24418 * rx_mask_mem - (OUT) rx mask memory for EHG heade 24419 * Returns: 24420 * BCM_E_XXX 24421 */ 24422 STATIC int 24423 _bcm_port_ehg_header_mem_get(int unit, bcm_port_t port, soc_mem_t *tx_mem, 24424 soc_mem_t *rx_mem, soc_mem_t *rx_mask_mem) 24425 { 24426 int phy_port; 24427 24428 if (NULL == tx_mem || NULL == rx_mem || NULL == rx_mask_mem) { 24429 return BCM_E_PARAM; 24430 } 24431 24432 if (soc_feature(unit, soc_feature_logical_port_num)) { 24433 /* coverity[overrun-local : FALSE] */ 24434 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 24435 } else { 24436 phy_port = port; 24437 } 24438 switch (SOC_PORT_BLOCK_TYPE(unit, phy_port)) { 24439 case SOC_BLK_GXPORT: 24440 *tx_mem = XPORT_EHG_TX_TUNNEL_DATAm; 24441 *rx_mem = XPORT_EHG_RX_TUNNEL_DATAm; 24442 *rx_mask_mem = XPORT_EHG_RX_TUNNEL_MASKm; 24443 break; 24444 case SOC_BLK_GPORT: 24445 *tx_mem = GPORT_EHG_TX_TUNNEL_DATAm; 24446 *rx_mem = GPORT_EHG_RX_TUNNEL_DATAm; 24447 *rx_mask_mem = GPORT_EHG_RX_TUNNEL_MASKm; 24448 break; 24449 case SOC_BLK_SPORT: 24450 *tx_mem = SPORT_EHG_TX_TUNNEL_DATAm; 24451 *rx_mem = SPORT_EHG_RX_TUNNEL_DATAm; 24452 *rx_mask_mem = SPORT_EHG_RX_TUNNEL_MASKm; 24453 break; 24454 case SOC_BLK_XQPORT: 24455 *tx_mem = XQPORT_EHG_TX_TUNNEL_DATAm; 24456 *rx_mem = XQPORT_EHG_RX_TUNNEL_DATAm; 24457 *rx_mask_mem = XQPORT_EHG_RX_TUNNEL_MASKm; 24458 break; 24459 case SOC_BLK_CLPORT: 24460 case SOC_BLK_XLPORT: 24461 case SOC_BLK_XTPORT: 24462 case SOC_BLK_XWPORT: 24463 *tx_mem = PORT_EHG_TX_TUNNEL_DATAm; 24464 *rx_mem = PORT_EHG_RX_TUNNEL_DATAm; 24465 *rx_mask_mem = PORT_EHG_RX_TUNNEL_MASKm; 24466 break; 24467 default: 24468 *tx_mem = *rx_mem = *rx_mask_mem = INVALIDm; 24469 } 24470 24471 return BCM_E_NONE; 24472 } 24473 24474 /* 24475 * Function: 24476 * _bcm_port_ehg_header_read 24477 * Purpose: 24478 * Reads EHG header from the HW tables 24479 * Parameters: 24480 * unit - (IN) device id 24481 * port - (IN) Physical port 24482 * buffer - (OUT) Pointer to the buffer to contain header 24483 * Returns: 24484 * BCM_E_XXX 24485 */ 24486 24487 STATIC int 24488 _bcm_port_ehg_header_read(int unit, bcm_port_t port, uint32 *buffer) 24489 { 24490 soc_mem_t tx_mem, rx_mem, rx_mask_mem; 24491 int tbl_idx_start, tbl_idx_end, idx; 24492 xqport_ehg_rx_tunnel_data_entry_t entry; 24493 int phy_port; 24494 24495 BCM_IF_ERROR_RETURN 24496 (_bcm_port_ehg_header_mem_get(unit, port, &tx_mem, &rx_mem, 24497 &rx_mask_mem)); 24498 24499 if (INVALIDm == tx_mem) { 24500 return (BCM_E_PORT); 24501 } 24502 24503 if (soc_feature(unit, soc_feature_logical_port_num)) { 24504 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 24505 } else { 24506 phy_port = port; 24507 } 24508 24509 tbl_idx_start = SOC_PORT_BINDEX(unit, phy_port) * 4; 24510 tbl_idx_end = tbl_idx_start + 3; 24511 24512 for (idx = 0 ; idx <= (tbl_idx_end - tbl_idx_start); idx ++) { 24513 BCM_IF_ERROR_RETURN 24514 (soc_mem_read(unit, tx_mem, SOC_PORT_BLOCK(unit, phy_port), 24515 (idx + tbl_idx_start), (void *)&entry)); 24516 soc_mem_field_get(unit, tx_mem, (void *)&entry, TUNNEL_DATAf, 24517 (buffer + ((tbl_idx_end - tbl_idx_start - idx) * 4))); 24518 } 24519 24520 return (BCM_E_NONE); 24521 } 24522 24523 /* 24524 * Function: 24525 * _bcm_port_ehg_header_write 24526 * Purpose: 24527 * Writes EHG header into the HW tables 24528 * Parameters: 24529 * unit - (IN) device id 24530 * port - (IN) Physical port 24531 * tx_buff - (IN) Pointer to the tx header 24532 * rx_buff - (IN) Pointer to the rx header 24533 * mask - (IN) Pointer to the mask header 24534 * len - (IN) Header length 24535 * Returns: 24536 * BCM_E_XXX 24537 */ 24538 int 24539 _bcm_port_ehg_header_write(int unit, bcm_port_t port, uint32 *tx_buf, 24540 uint32 *rx_buf, uint32 *mask, int len) 24541 { 24542 soc_mem_t tx_mem, rx_mem, rx_mask_mem; 24543 int tbl_idx_start, tbl_idx_end, idx; 24544 xqport_ehg_rx_tunnel_data_entry_t data_entry; 24545 xqport_ehg_rx_tunnel_mask_entry_t mask_entry; 24546 int phy_port; 24547 24548 BCM_IF_ERROR_RETURN 24549 (_bcm_port_ehg_header_mem_get(unit, port, &tx_mem, &rx_mem, 24550 &rx_mask_mem)); 24551 24552 if (INVALIDm == tx_mem) { 24553 return (BCM_E_PORT); 24554 } 24555 24556 if (soc_feature(unit, soc_feature_logical_port_num)) { 24557 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 24558 } else { 24559 phy_port = port; 24560 } 24561 24562 tbl_idx_start = SOC_PORT_BINDEX(unit, phy_port) * 4; 24563 tbl_idx_end = tbl_idx_start + (len / 4) - 1; 24564 24565 for (idx = 0; idx <= (tbl_idx_end - tbl_idx_start); idx ++) { 24566 /* Reset hw buffer. */ 24567 sal_memset(&data_entry, 0, sizeof(xqport_ehg_rx_tunnel_data_entry_t)); 24568 soc_mem_field_set(unit, tx_mem, (uint32 *)&data_entry, TUNNEL_DATAf, 24569 (tx_buf + ((tbl_idx_end - tbl_idx_start - idx) * 4))); 24570 BCM_IF_ERROR_RETURN 24571 (soc_mem_write(unit, tx_mem, SOC_PORT_BLOCK(unit, phy_port), 24572 (idx + tbl_idx_start), &data_entry)); 24573 24574 /* Reset hw buffer. */ 24575 sal_memset(&data_entry, 0, sizeof(xqport_ehg_rx_tunnel_data_entry_t)); 24576 soc_mem_field_set(unit, rx_mem, (uint32 *)&data_entry, TUNNEL_DATAf, 24577 (rx_buf + ((tbl_idx_end - tbl_idx_start - idx) * 4))); 24578 BCM_IF_ERROR_RETURN 24579 (soc_mem_write(unit, rx_mem, SOC_PORT_BLOCK(unit, phy_port), 24580 (idx + tbl_idx_start), &data_entry)); 24581 24582 /* Reset hw buffer. */ 24583 sal_memset(&mask_entry, 0, sizeof(xqport_ehg_rx_tunnel_mask_entry_t)); 24584 soc_mem_field_set(unit, rx_mask_mem, (uint32 *)&mask_entry, TUNNEL_MASKf, 24585 (mask + ((tbl_idx_end - tbl_idx_start - idx)* 4))); 24586 BCM_IF_ERROR_RETURN 24587 (soc_mem_write(unit, rx_mask_mem, SOC_PORT_BLOCK(unit, phy_port), 24588 (idx + tbl_idx_start), &mask_entry)); 24589 } 24590 24591 return (BCM_E_NONE); 24592 } 24593 24594 24595 /* 24596 * Function: 24597 * _bcm_port_ehg_setup_txrx_ethernet_hdr 24598 * Purpose: 24599 * Prepares SRC and DEST MAC addresses into rx and tx buffers on a given index 24600 * Parameters: 24601 * tx_buffer -(IN/OUT) - tx buffer to fill 24602 * rx_buffer -(IN/OUT) - rx buffer to fill 24603 * index -(IN/OUT) - index to the right location in buffer 24604 * encap_config - (IN) structure describes port encapsulation configuration 24605 * Returns: 24606 * BCM_E_XXX 24607 */ 24608 24609 STATIC void 24610 _bcm_port_ehg_setup_txrx_ethernet_hdr(uint32 *tx_buffer, uint32 *rx_buffer, 24611 int *index, 24612 bcm_port_encap_config_t *encap_config) 24613 { 24614 int idx = *index; 24615 24616 /* Destination mac address. */ 24617 tx_buffer[idx] = (((uint32)(encap_config->dst_mac)[0]) << 24 | \ 24618 ((uint32)(encap_config->dst_mac)[1]) << 16 | \ 24619 ((uint32)(encap_config->dst_mac)[2]) << 8 | \ 24620 ((uint32)(encap_config->dst_mac)[3])); 24621 /* TX dest MAC is RX src MAC */ 24622 rx_buffer[idx] = (((uint32)(encap_config->src_mac)[0]) << 24 | \ 24623 ((uint32)(encap_config->src_mac)[1]) << 16 | \ 24624 ((uint32)(encap_config->src_mac)[2]) << 8 | \ 24625 ((uint32)(encap_config->src_mac)[3])); 24626 idx--; 24627 24628 tx_buffer[idx] = (((uint32)(encap_config->dst_mac)[4]) << 24 | \ 24629 ((uint32)(encap_config->dst_mac)[5]) << 16 | \ 24630 ((uint32)(encap_config->src_mac)[0]) << 8 | \ 24631 ((uint32)(encap_config->src_mac)[1])); 24632 /* TX dest MAC is RX src MAC */ 24633 rx_buffer[idx] = (((uint32)(encap_config->src_mac)[4]) << 24 | \ 24634 ((uint32)(encap_config->src_mac)[5]) << 16 | \ 24635 ((uint32)(encap_config->dst_mac)[0]) << 8 | \ 24636 ((uint32)(encap_config->dst_mac)[1])); 24637 idx--; 24638 /* Source mac address. */ 24639 tx_buffer[idx] = (((uint32)(encap_config->src_mac)[2]) << 24 | \ 24640 ((uint32)(encap_config->src_mac)[3]) << 16 | \ 24641 ((uint32)(encap_config->src_mac)[4]) << 8 | \ 24642 ((uint32)(encap_config->src_mac)[5])); 24643 /* TX src MAC is RX dest MAC */ 24644 rx_buffer[idx] = (((uint32)(encap_config->dst_mac)[2]) << 24 | \ 24645 ((uint32)(encap_config->dst_mac)[3]) << 16 | \ 24646 ((uint32)(encap_config->dst_mac)[4]) << 8 | \ 24647 ((uint32)(encap_config->dst_mac)[5])); 24648 idx--; 24649 24650 *index = idx; 24651 return; 24652 } 24653 24654 /* Embedded Higig register access macros */ 24655 #define EHG_TX_REG(unit) \ 24656 (SOC_IS_TRIUMPH3(unit) ? PORT_EHG_TX_CONTROLr : EHG_TX_CONTROLr) 24657 #define EHG_RX_REG(unit) \ 24658 (SOC_IS_TRIUMPH3(unit) ? PORT_EHG_RX_CONTROLr : EHG_RX_CONTROLr) 24659 #define EHG_TPID_REG(unit) \ 24660 (SOC_IS_TRIUMPH3(unit) ? PORT_EHG_TPIDr : EHG_TPIDr) 24661 24662 /* 24663 * Function: 24664 * _bcm_port_ehg_ethernet_header_parse 24665 * Purpose: 24666 * Parses Ethernet header from EHG header 24667 * Parameters: 24668 * unit - (IN) device id 24669 * port - (IN) Physical port 24670 * header - (IN) pointer to the EHG header buffer 24671 * encap_config - (IN/OUT) structure describes port encapsulation configuration 24672 * index - (IN/OUT) index to the right location in buffer 24673 * Returns: 24674 * BCM_E_XXX 24675 */ 24676 STATIC int 24677 _bcm_port_ehg_ethernet_header_parse(int unit, bcm_port_t port, uint32 *header, 24678 bcm_port_encap_config_t *encap_config, int *index) 24679 { 24680 uint32 val; 24681 int idx = *index; 24682 soc_reg_t ehg_tx_reg = EHG_TX_REG(unit); 24683 24684 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val)); 24685 encap_config->dst_mac[0] = (uint8)(header[idx] >> 24); 24686 encap_config->dst_mac[1] = (uint8)(header[idx] >> 16); 24687 encap_config->dst_mac[2] = (uint8)(header[idx] >> 8); 24688 encap_config->dst_mac[3] = (uint8)(header[idx]); 24689 idx--; 24690 encap_config->dst_mac[4] = (uint8)(header[idx] >> 24); 24691 encap_config->dst_mac[5] = (uint8)(header[idx] >> 16); 24692 encap_config->src_mac[0] = (uint8)(header[idx] >> 8); 24693 encap_config->src_mac[1] = (uint8)(header[idx]); 24694 idx--; 24695 encap_config->src_mac[2] = (uint8)(header[idx] >> 24); 24696 encap_config->src_mac[3] = (uint8)(header[idx] >> 16); 24697 encap_config->src_mac[4] = (uint8)(header[idx] >> 8); 24698 encap_config->src_mac[5] = (uint8)(header[idx]); 24699 idx--; 24700 24701 if (soc_reg_field_get(unit, ehg_tx_reg, val, VLAN_TAG_CONTROLf)) { 24702 encap_config->tpid = (uint16)(header[idx] >> 16); 24703 encap_config->vlan = (uint16)(header[idx]); 24704 idx--; 24705 } else { 24706 encap_config->vlan = BCM_VLAN_NONE; 24707 encap_config->tpid = BCM_VLAN_NONE; 24708 } 24709 24710 *index = idx; 24711 return BCM_E_NONE; 24712 } 24713 /* 24714 * Function: 24715 * _bcm_port_ip4_tunnel_header_set 24716 * Purpose: 24717 * Prepares and sets IP GRE tunnel header for Embedded higig 24718 * Parameters: 24719 * unit - (IN) device id 24720 * port - (IN) Physical port 24721 * encap_config - (IN) structure describes port encapsulation configuration 24722 * Returns: 24723 * BCM_E_XXX 24724 */ 24725 STATIC int 24726 _bcm_port_ip4_tunnel_header_set(int unit, bcm_port_t port, 24727 bcm_port_encap_config_t *encap_config) 24728 { 24729 /*SW tunnel tx encap buffer.*/ 24730 uint32 tx_buffer[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ]; 24731 /*SW tunnel rx encap buffer.*/ 24732 uint32 rx_buffer[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ]; 24733 uint32 mask[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ]; 24734 int idx; /* Headers offset iterator.*/ 24735 int adjust_rx_offset = 0; 24736 24737 sal_memset(tx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ)); 24738 sal_memset(rx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ)); 24739 sal_memset(mask, 0, WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ)); 24740 24741 idx = _BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ - 1; 24742 24743 _bcm_port_ehg_setup_txrx_ethernet_hdr(tx_buffer, rx_buffer, &idx, 24744 encap_config); 24745 24746 /* Set tpid & vlan id. */ 24747 if (BCM_VLAN_VALID(encap_config->vlan)) { 24748 /* Tpid. Priority, Cfi, Vlan id. */ 24749 tx_buffer[idx] |= (((uint32)(encap_config->tpid)) << 16 | \ 24750 ((uint32)(encap_config->vlan))); 24751 /*rx_buffer should not have the VLAN and TPID included*/ 24752 idx--; 24753 adjust_rx_offset = 1; 24754 } 24755 24756 /* 24757 * IPv4 header. 24758 */ 24759 /* Set ether type to ip. 0x800 */ 24760 /* Version + 5 word no options length. + Tos */ 24761 /* Length, Id, Flags, Fragmentation offset. */ 24762 tx_buffer[idx] |= (((uint32)(0x0800) << 16) | \ 24763 ((uint32)(0x45) << 8) | \ 24764 ((uint32)(encap_config->tos))); 24765 rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx]; 24766 idx--; 24767 idx--; 24768 24769 /* Ttl */ 24770 /* Protocol (GRE 0x2f) */ 24771 tx_buffer[idx] = (((uint32)(encap_config->ttl) << 8) | \ 24772 ((uint32)(0x2f))); 24773 rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx]; 24774 idx--; 24775 24776 /* TX Src Ip. */ 24777 tx_buffer[idx] |= ((uint32)(encap_config->src_addr) >> 16); 24778 24779 /* RX Dst Ip. */ 24780 rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->dst_addr) >> 16); 24781 idx--; 24782 24783 /* TX Src Ip. */ 24784 tx_buffer[idx] |= ((uint32)(encap_config->src_addr) << 16); 24785 24786 /* RX Dst Ip. */ 24787 rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->dst_addr) << 16); 24788 24789 /* TX Dst Ip. */ 24790 tx_buffer[idx] |= ((uint32)(encap_config->dst_addr) >> 16); 24791 24792 /* RX Src Ip */ 24793 rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->src_addr) >> 16); 24794 idx--; 24795 24796 24797 /* TX Dst Ip. */ 24798 tx_buffer[idx] |= ((uint32)(encap_config->dst_addr) << 16); 24799 24800 /* RX Src Ip */ 24801 rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->src_addr) << 16); 24802 idx--; 24803 24804 /* Gre header */ 24805 /* Set protocol type in GRE header to ether type specified by user */ 24806 tx_buffer[idx] |= (((uint32)(encap_config->higig_ethertype) << 16) | \ 24807 ((uint32)(encap_config->oui)[0]) << 8 | \ 24808 ((uint32)(encap_config->oui)[1])); 24809 rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx]; 24810 mask[idx + adjust_rx_offset]=0x0000FFFF;/*TUNNEL_TYPE=1:The first 38 bytes will be compared against the rx table data*/ 24811 sal_memset(mask, 0xFF, WORDS2BYTES(idx + adjust_rx_offset)); 24812 idx--; 24813 24814 /* Set TX OUI and OUI Ethertype*/ 24815 tx_buffer[idx] |= (((uint32)(encap_config->oui)[2]) << 24 | \ 24816 ((uint32)(encap_config->oui_ethertype)) << 8); 24817 rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx]; 24818 24819 return _bcm_port_ehg_header_write(unit, port, tx_buffer, rx_buffer, mask, 24820 _BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ); 24821 } 24822 24823 /* 24824 * Function: 24825 * _bcm_port_ipv4_tunnel_header_parse 24826 * Purpose: 24827 * Parse IPv4 GRE tunnel header for Embedded higig and updates encap_config 24828 * structure accordingly 24829 * Parameters: 24830 * unit - (IN) device id 24831 * port - (IN) Physical port 24832 * header - (IN) Buffer contains EHG header to parse 24833 * encap_config - (OUT) structure describes port encapsulation configuration 24834 * Returns: 24835 * BCM_E_XXX 24836 */ 24837 STATIC int 24838 _bcm_port_ipv4_tunnel_header_parse(int unit, bcm_port_t port, uint32 *header, 24839 bcm_port_encap_config_t *encap_config) 24840 { 24841 /* Headers offset iterator, begins at end of header */ 24842 int idx = 4 * BYTES2WORDS(sizeof(xport_ehg_tx_tunnel_data_entry_t)) - 1; 24843 24844 BCM_IF_ERROR_RETURN( 24845 _bcm_port_ehg_ethernet_header_parse(unit, port, header, encap_config, 24846 &idx)); 24847 24848 encap_config->tos = (uint8)(header[idx]); 24849 idx--; 24850 idx--; 24851 encap_config->ttl = (uint8)(header[idx] >> 8); 24852 idx--; 24853 encap_config->src_addr = ((uint16)(header[idx])) << 16; 24854 idx--; 24855 encap_config->src_addr |=(uint16)(header[idx] >> 16); 24856 encap_config->dst_addr = ((uint16)(header[idx])) << 16; 24857 idx--; 24858 encap_config->dst_addr |=(uint16)(header[idx] >> 16); 24859 idx--; 24860 encap_config->higig_ethertype = (uint16)(header[idx] >> 16); 24861 encap_config->oui[0] = (uint8)(header[idx] >> 8); 24862 encap_config->oui[1] = (uint8)(header[idx]); 24863 idx--; 24864 encap_config->oui[2] = (uint8)(header[idx] >> 24); 24865 encap_config->oui_ethertype = (uint16)(header[idx] >> 8); 24866 24867 return BCM_E_NONE; 24868 } 24869 24870 /* 24871 * Function: 24872 * _bcm_port_l2_tunnel_header_set 24873 * Purpose: 24874 * Prepares and sets L2 tunnel header for Embedded higig 24875 * Parameters: 24876 * unit - (IN) device id 24877 * port - (IN) Physical port 24878 * encap_config - (IN) structure describes port encapsulation configuration 24879 * Returns: 24880 * BCM_E_XXX 24881 */ 24882 STATIC int 24883 _bcm_port_l2_tunnel_header_set(int unit, bcm_port_t port, 24884 bcm_port_encap_config_t *encap_config) 24885 { 24886 /*SW tunnel tx encap buffer.*/ 24887 uint32 tx_buffer[_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ]; 24888 /*SW tunnel rx encap buffer.*/ 24889 uint32 rx_buffer[_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ]; 24890 uint32 mask[_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ]; 24891 int idx; /* Headers offset iterator.*/ 24892 int adjust_rx_offset = 0; 24893 24894 sal_memset(tx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ)); 24895 sal_memset(rx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ)); 24896 sal_memset(mask, 0, WORDS2BYTES(_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ)); 24897 24898 idx = _BCM_PORT_EHG_L2_HEADER_BUFFER_SZ - 1; 24899 24900 _bcm_port_ehg_setup_txrx_ethernet_hdr(tx_buffer, rx_buffer, &idx, 24901 encap_config); 24902 24903 /* Set tpid & vlan id. */ 24904 if (BCM_VLAN_VALID(encap_config->vlan)) { 24905 /* Tpid. Priority, Cfi, Vlan id. */ 24906 tx_buffer[idx] |= (((uint32)(encap_config->tpid)) << 16 | \ 24907 ((uint32)(encap_config->vlan))); 24908 /*rx_buffer should not have the VLAN and TPID included*/ 24909 idx--; 24910 adjust_rx_offset = 1; 24911 } 24912 24913 /* Set ether type to OUI and TX OUI */ 24914 tx_buffer[idx] |= (((uint32)(encap_config->higig_ethertype)) << 16 | \ 24915 ((uint32)(encap_config->oui)[0]) << 8 | \ 24916 ((uint32)(encap_config->oui)[1])); 24917 rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx]; 24918 mask[idx + adjust_rx_offset] = 0x0000FFFF; /*TUNNEL_TYPE=0:The first 14 bytes will be compared against the rx table data*/ 24919 sal_memset(mask, 0xFF, WORDS2BYTES(idx + adjust_rx_offset)); 24920 idx--; 24921 /* Set TX OUI and HG ether type */ 24922 tx_buffer[idx] |= (((uint32)(encap_config->oui)[2]) << 24 | \ 24923 ((uint32)(encap_config->oui_ethertype)) << 8); 24924 rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx]; 24925 24926 return _bcm_port_ehg_header_write(unit, port, tx_buffer, rx_buffer, mask, 24927 _BCM_PORT_EHG_L2_HEADER_BUFFER_SZ); 24928 } 24929 24930 24931 /* 24932 * Function: 24933 * _bcm_port_l2_tunnel_header_parse 24934 * Purpose: 24935 * Parse L2 tunnel header for Embedded higig and updates encap_config 24936 * structure accordingly 24937 * Parameters: 24938 * unit - (IN) device id 24939 * port - (IN) Physical port 24940 * header - (IN) Buffer contains EHG header to parse 24941 * encap_config - (OUT) structure describes port encapsulation configuration 24942 * Returns: 24943 * BCM_E_XXX 24944 */ 24945 STATIC int 24946 _bcm_port_l2_tunnel_header_parse(int unit, bcm_port_t port, uint32 *header, 24947 bcm_port_encap_config_t *encap_config) 24948 { 24949 /* Headers offset iterator, begins at end of header */ 24950 int idx = 4 * BYTES2WORDS(sizeof(xport_ehg_tx_tunnel_data_entry_t)) - 1; 24951 24952 BCM_IF_ERROR_RETURN 24953 (_bcm_port_ehg_ethernet_header_parse(unit, port, header, 24954 encap_config, &idx)); 24955 24956 encap_config->higig_ethertype = (uint16)(header[idx] >> 16); 24957 encap_config->oui[0] = (uint8)(header[idx] >> 8); 24958 encap_config->oui[1] = (uint8)(header[idx]); 24959 idx--; 24960 encap_config->oui[2] = (uint8)(header[idx] >> 24); 24961 encap_config->oui_ethertype = (uint16)(header[idx] >> 8); 24962 24963 return BCM_E_NONE; 24964 } 24965 24966 /* 24967 * Function: 24968 * _bcm_port_encap_ehg_xport_update 24969 * Purpose: 24970 * Updates XPORT higig config for EHG 24971 * Parameters: 24972 * unit - (IN) device id 24973 * port - (IN) Physical port 24974 * Returns: 24975 */ 24976 STATIC int 24977 _bcm_port_encap_ehg_xport_update(int unit, bcm_port_t port) 24978 { 24979 #if defined(BCM_TRIUMPH3_SUPPORT) 24980 if (SOC_IS_TRIUMPH3(unit)) { 24981 24982 soc_field_t ept_fields[2] = { HIGIG2f, PORT_TYPEf }; 24983 uint32 ept_vals[2] = { BCM_EGR_PORT_HIGIG2, BCM_EGR_PORT_TYPE_EHG }; 24984 24985 /* Ingress port table */ 24986 BCM_IF_ERROR_RETURN 24987 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 24988 HIGIG2f, 1)); 24989 BCM_IF_ERROR_RETURN 24990 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 24991 PORT_TYPEf, BCM_EGR_PORT_TYPE_EHG)); 24992 24993 /* Egress port table */ 24994 BCM_IF_ERROR_RETURN 24995 (soc_mem_fields32_modify(unit, EGR_PORTm, port, 2, 24996 ept_fields, ept_vals)); 24997 24998 /* Egress ingress port table */ 24999 BCM_IF_ERROR_RETURN 25000 (soc_mem_fields32_modify(unit, EGR_ING_PORTm, port, 2, 25001 ept_fields, ept_vals)); 25002 25003 BCM_IF_ERROR_RETURN 25004 (soc_reg_field32_modify(unit, PORT_CONFIGr, port, 25005 HIGIG2_MODEf, 1)); 25006 25007 if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) { 25008 icontrol_opcode_bitmap_entry_t entry; 25009 soc_pbmp_t pbmp; 25010 25011 BCM_IF_ERROR_RETURN 25012 (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 25013 25014 SOC_PBMP_CLEAR(pbmp); 25015 25016 SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit)); 25017 25018 soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry, 25019 BITMAPf, &pbmp); 25020 25021 BCM_IF_ERROR_RETURN 25022 (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 25023 } 25024 25025 return (BCM_E_NONE); 25026 } 25027 #endif /* BCM_TRIUMPH3_SUPPORT */ 25028 25029 #ifdef BCM_GXPORT_SUPPORT 25030 { 25031 soc_reg_t egr_port_reg; 25032 25033 if (IS_GX_PORT(unit, port) || IS_XQ_PORT(unit,port)) { 25034 25035 egr_port_reg = 25036 (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 25037 SOC_IS_VALKYRIE2(unit)|| SOC_IS_GREYHOUND(unit) || 25038 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ? 25039 EGR_PORT_64r : EGR_PORTr; 25040 25041 BCM_IF_ERROR_RETURN 25042 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 25043 HIGIG2f, 1)); 25044 25045 BCM_IF_ERROR_RETURN 25046 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 25047 PORT_TYPEf, BCM_EGR_PORT_TYPE_EHG)); 25048 BCM_IF_ERROR_RETURN 25049 (soc_reg_field32_modify(unit, egr_port_reg, port, HIGIG2f, 25050 BCM_EGR_PORT_HIGIG2)); 25051 BCM_IF_ERROR_RETURN 25052 (soc_reg_field32_modify(unit, egr_port_reg, port, 25053 PORT_TYPEf, BCM_EGR_PORT_TYPE_EHG)); 25054 25055 if(SOC_REG_IS_VALID(unit, XPORT_CONFIGr)) { 25056 BCM_IF_ERROR_RETURN 25057 (soc_reg_field32_modify(unit, XPORT_CONFIGr, port, 25058 HIGIG2_MODEf, 1)); 25059 } 25060 } 25061 } 25062 #endif /* BCM_GXPORT_SUPPORT */ 25063 return (BCM_E_NONE); 25064 } 25065 25066 /* 25067 * Function: 25068 * _bcm_port_ehg_transport_mode_set 25069 * Purpose: 25070 * Set the port into embedded higig transport mode 25071 * Parameters: 25072 * unit - (IN) device id 25073 * port - (IN) Physical port 25074 * encap_config - (IN) structure describes port encapsulation configuration 25075 * Returns: 25076 * BCM_E_XXX 25077 */ 25078 STATIC int 25079 _bcm_port_ehg_transport_mode_set(int unit, bcm_port_t port, 25080 bcm_port_encap_config_t *encap_config) 25081 { 25082 int vlan_valid; 25083 uint32 val; 25084 soc_reg_t ehg_tx_reg = EHG_TX_REG(unit); 25085 soc_reg_t ehg_rx_reg = EHG_RX_REG(unit); 25086 soc_reg_t ehg_tpid_reg = EHG_TPID_REG(unit); 25087 25088 if (IS_HG_PORT(unit, port)) { 25089 return BCM_E_CONFIG; 25090 } 25091 25092 BCM_IF_ERROR_RETURN 25093 (_bcm_port_encap_ehg_xport_update(unit, port)); 25094 25095 vlan_valid = BCM_VLAN_VALID(encap_config->vlan); 25096 25097 /* Configure TX control */ 25098 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val)); 25099 soc_reg_field_set(unit, ehg_tx_reg, &val, ENABLEf, 1); 25100 soc_reg_field_set(unit, ehg_tx_reg, &val, TUNNEL_TYPEf, 0); 25101 soc_reg_field_set(unit, ehg_tx_reg, &val, VLAN_TAG_CONTROLf, 25102 vlan_valid); 25103 soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_VLAN_PRI_CFIf, 25104 vlan_valid); 25105 soc_reg_field_set(unit, ehg_tx_reg, &val, PAYLOAD_LENGTH_ADJUSTMENTf, 25106 0); 25107 soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_DSCPf, 0); 25108 soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_IPf, 0); 25109 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tx_reg, port, 0, val)); 25110 25111 /* Configure RX control */ 25112 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_rx_reg, port, 0, &val)); 25113 soc_reg_field_set(unit, ehg_rx_reg, &val, TUNNEL_TYPEf, 0); 25114 soc_reg_field_set(unit, ehg_rx_reg, &val, MODEf, 1); 25115 soc_reg_field_set(unit, ehg_rx_reg, &val, VLAN_TAG_CONTROLf, 25116 vlan_valid); 25117 soc_reg_field_set(unit, ehg_rx_reg, &val, COMPARE_VLANf, 25118 vlan_valid); 25119 soc_reg_field_set(unit, ehg_rx_reg, &val, VLANf, 25120 (vlan_valid) ? encap_config->vlan : 0); 25121 soc_reg_field_set(unit, ehg_rx_reg, &val, IPV4_CHKSUM_ENABLEf, 0); 25122 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_rx_reg, port, 0, val)); 25123 25124 /* Configure EHG-tpid */ 25125 if (vlan_valid) { 25126 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tpid_reg, port, 0, &val)); 25127 soc_reg_field_set(unit, ehg_tpid_reg, &val, TPIDf, 25128 encap_config->tpid); 25129 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tpid_reg, port, 0, val)); 25130 } 25131 25132 return _bcm_port_l2_tunnel_header_set(unit, port, encap_config); 25133 } 25134 25135 /* 25136 * Function: 25137 * _bcm_port_ehg_tunnel_mode_set 25138 * Purpose: 25139 * Set the port into embedded higig tunnel mode 25140 * Parameters: 25141 * unit - (IN) device id 25142 * port - (IN) Physical port 25143 * encap_config - (IN) structure describes port encapsulation configuration 25144 * Returns: 25145 * BCM_E_XXX 25146 */ 25147 STATIC int 25148 _bcm_port_ehg_tunnel_mode_set(int unit, bcm_port_t port, 25149 bcm_port_encap_config_t *encap_config) 25150 { 25151 int vlan_valid; 25152 uint32 val; 25153 soc_reg_t ehg_tx_reg = EHG_TX_REG(unit); 25154 soc_reg_t ehg_rx_reg = EHG_RX_REG(unit); 25155 soc_reg_t ehg_tpid_reg = EHG_TPID_REG(unit); 25156 25157 if (IS_HG_PORT(unit, port)) { 25158 return BCM_E_CONFIG; 25159 } 25160 25161 BCM_IF_ERROR_RETURN 25162 (_bcm_port_encap_ehg_xport_update(unit, port)); 25163 25164 vlan_valid = BCM_VLAN_VALID(encap_config->vlan); 25165 25166 /* Configure TX control */ 25167 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val)); 25168 soc_reg_field_set(unit, ehg_tx_reg, &val, ENABLEf, 1); 25169 soc_reg_field_set(unit, ehg_tx_reg, &val, TUNNEL_TYPEf, 1); 25170 soc_reg_field_set(unit, ehg_tx_reg, &val, VLAN_TAG_CONTROLf, 25171 vlan_valid); 25172 soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_VLAN_PRI_CFIf, 25173 vlan_valid); 25174 soc_reg_field_set(unit, ehg_tx_reg, &val, PAYLOAD_LENGTH_ADJUSTMENTf, 25175 vlan_valid ? (WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ) - 1): 25176 (WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ - 1) - 1)); 25177 soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_DSCPf, 1); 25178 soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_IPf, 1); 25179 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tx_reg, port, 0, val)); 25180 25181 /* Configure RX control */ 25182 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_rx_reg, port, 0, &val)); 25183 soc_reg_field_set(unit, ehg_rx_reg, &val, MODEf, 1); 25184 soc_reg_field_set(unit, ehg_rx_reg, &val, TUNNEL_TYPEf, 1); 25185 soc_reg_field_set(unit, ehg_rx_reg, &val, VLAN_TAG_CONTROLf, 25186 vlan_valid); 25187 soc_reg_field_set(unit, ehg_rx_reg, &val, COMPARE_VLANf, 25188 vlan_valid); 25189 soc_reg_field_set(unit, ehg_rx_reg, &val, VLANf, 25190 (vlan_valid) ? encap_config->vlan : 0); 25191 soc_reg_field_set(unit, ehg_rx_reg, &val, IPV4_CHKSUM_ENABLEf, 1); 25192 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_rx_reg, port, 0, val)); 25193 25194 /* Configure EHG-tpid */ 25195 if (vlan_valid) { 25196 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tpid_reg, port, 0, &val)); 25197 soc_reg_field_set(unit, ehg_tpid_reg, &val, TPIDf, 25198 encap_config->tpid); 25199 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tpid_reg, port, 0, val)); 25200 } 25201 25202 return _bcm_port_ip4_tunnel_header_set(unit, port, encap_config); 25203 } 25204 25205 /* 25206 * Function: 25207 * _bcm_port_hgoe_transport_mode_set 25208 * Purpose: 25209 * Set the port into Higig over Ethernet transport mode 25210 * Parameters: 25211 * unit - (IN) device id 25212 * port - (IN) Physical port 25213 * encap_config - (IN) structure describes port encapsulation configuration 25214 * Returns: 25215 * BCM_E_XXX 25216 */ 25217 STATIC int 25218 _bcm_port_hgoe_transport_mode_set(int unit, bcm_port_t port, 25219 bcm_port_encap_config_t *encap_config) 25220 { 25221 uint64 val64; 25222 uint32 val; 25223 25224 25225 if (IS_HG_PORT(unit, port)) { 25226 return BCM_E_CONFIG; 25227 } 25228 #if defined(BCM_TRIDENT3_SUPPORT) 25229 if (SOC_IS_TRIDENT3X(unit)) { 25230 if (BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET == encap_config->encap) { 25231 return bcm_td3_port_hgoe_mode_set(unit, port); 25232 } else { 25233 return BCM_E_UNAVAIL; 25234 } 25235 } 25236 #endif 25237 /* Configure HGoE TX control */ 25238 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, HG_TYPEf)) { 25239 BCM_IF_ERROR_RETURN 25240 (soc_mem_field32_modify(unit, EGR_PORTm, port, PORT_TYPEf, 25241 encap_config->encap == 25242 BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET? 25243 1 : 0)); 25244 BCM_IF_ERROR_RETURN 25245 (soc_mem_field32_modify(unit, EGR_PORTm, port, HG_TYPEf, 25246 BCM_PORT_HG_TYPE_HGOE_TRANSPORT)); 25247 } 25248 25249 if (SOC_REG_IS_VALID(unit, EGR_EHG_ETHERTYPEr)) { 25250 BCM_IF_ERROR_RETURN 25251 (soc_reg32_get(unit, EGR_EHG_ETHERTYPEr, port, 0, &val)); 25252 soc_reg_field_set(unit, EGR_EHG_ETHERTYPEr, 25253 &val, ETHERTYPEf, encap_config->higig_ethertype); 25254 BCM_IF_ERROR_RETURN 25255 (soc_reg32_set(unit, EGR_EHG_ETHERTYPEr, port, 0, val)); 25256 } 25257 25258 if (SOC_REG_IS_VALID(unit, EGR_EHG_HEADER_CONTROLr)) { 25259 BCM_IF_ERROR_RETURN 25260 (soc_reg32_get(unit, EGR_EHG_HEADER_CONTROLr, port, 0, &val)); 25261 soc_reg_field_set(unit, EGR_EHG_HEADER_CONTROLr, 25262 &val, EHG_RESERVEDf, encap_config->hgoe_reserved); 25263 BCM_IF_ERROR_RETURN 25264 (soc_reg32_set(unit, EGR_EHG_HEADER_CONTROLr, port, 0, val)); 25265 } 25266 25267 /* Configure HGoE RX control */ 25268 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, HG_TYPEf)) { 25269 BCM_IF_ERROR_RETURN 25270 (_bcm_esw_port_tab_set(unit, port, 25271 _BCM_CPU_TABS_NONE, PORT_TYPEf, 25272 encap_config->encap == 25273 BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET? 25274 1 : 0)); 25275 25276 BCM_IF_ERROR_RETURN 25277 (_bcm_esw_port_tab_set(unit, port, 25278 _BCM_CPU_TABS_NONE, HG_TYPEf, 25279 BCM_PORT_HG_TYPE_HGOE_TRANSPORT)); 25280 } 25281 25282 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, HG_TYPEf)) { 25283 BCM_IF_ERROR_RETURN 25284 (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, PORT_TYPEf, 25285 encap_config->encap == 25286 BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET? 25287 1 : 0)); 25288 BCM_IF_ERROR_RETURN 25289 (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, HG_TYPEf, 25290 BCM_PORT_HG_TYPE_HGOE_TRANSPORT)); 25291 } 25292 25293 if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr)) { 25294 uint64 v64; 25295 COMPILER_64_SET(v64, 0, encap_config->higig_ethertype); 25296 BCM_IF_ERROR_RETURN 25297 (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, port, 0, 25298 &val64)); 25299 soc_reg64_field_set(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, 25300 &val64, ETHERTYPEf, v64); 25301 BCM_IF_ERROR_RETURN 25302 (soc_reg_set(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, port, 0, 25303 val64)); 25304 } 25305 25306 /* Enable HGoE */ 25307 if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r)) { 25308 uint64 one = COMPILER_64_INIT(0, 1); 25309 BCM_IF_ERROR_RETURN 25310 (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, port, 0, 25311 &val64)); 25312 soc_reg64_field_set(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, 25313 &val64, TRANSPORT_ENf, one); 25314 BCM_IF_ERROR_RETURN 25315 (soc_reg_set(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, port, 0, 25316 val64)); 25317 } 25318 #ifdef BCM_TRX_SUPPORT 25319 /* Set the vlan default action */ 25320 if (soc_feature(unit, soc_feature_vlan_action) && 25321 (!SOC_IS_TRIDENT3X(unit))) { 25322 bcm_vlan_action_set_t action; 25323 25324 BCM_IF_ERROR_RETURN 25325 (_bcm_trx_vlan_port_egress_default_action_get(unit, 25326 port, &action)); 25327 /* Backward compatible defaults */ 25328 action.ot_outer = bcmVlanActionDelete; 25329 action.dt_outer = bcmVlanActionDelete; 25330 BCM_IF_ERROR_RETURN 25331 (_bcm_trx_vlan_port_egress_default_action_set(unit, 25332 port, &action)); 25333 } 25334 #endif 25335 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(BCM_TX_HGOE_LIMITED_SOLUTION) 25336 if (SOC_IS_TRIDENT2PLUS(unit) 25337 && SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) { 25338 icontrol_opcode_bitmap_entry_t entry; 25339 soc_pbmp_t pbmp; 25340 25341 SOC_IF_ERROR_RETURN 25342 (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 25343 SOC_PBMP_CLEAR(pbmp); 25344 SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit)); 25345 soc_mem_pbmp_field_set(unit, 25346 ICONTROL_OPCODE_BITMAPm, &entry, BITMAPf, &pbmp); 25347 SOC_IF_ERROR_RETURN 25348 (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 25349 } 25350 #endif /* BCM_TRIDENT2PLUS_SUPPORT && BCM_TX_HGOE_LIMITED_SOLUTION */ 25351 25352 return BCM_E_NONE; 25353 } 25354 25355 25356 /* 25357 * Function: 25358 * _bcm_esw_port_encap_higig_lite_set 25359 * Purpose: 25360 * Helper function to force a port into HIGIG2_LITE mode 25361 * Parameters: 25362 * unit - (IN) device id 25363 * port - (IN) port number 25364 * Returns: 25365 * BCM_E_XXX 25366 */ 25367 STATIC int 25368 _bcm_esw_port_encap_higig_lite_set(int unit, bcm_port_t port) 25369 { 25370 soc_port_ability_t ability; 25371 int an, an_done; 25372 int rv = BCM_E_CONFIG; 25373 25374 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 25375 return bcmi_esw_portctrl_encap_higig_lite_set(unit, port); 25376 } 25377 25378 sal_memset(&ability, 0, sizeof(soc_port_ability_t)); 25379 25380 if (soc_feature(unit, soc_feature_hg_no_speed_change)) { 25381 /* HG-Lite process without 2.5G speed setting can calls to 25382 * _bcm_port_encap_xport_set() directly. 25383 */ 25384 return _bcm_port_encap_xport_set(unit, port, 25385 BCM_PORT_ENCAP_HIGIG2_LITE, TRUE); 25386 } else { 25387 if (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port) || 25388 (SOC_IS_METROLITE(unit) && IS_XL_PORT(unit, port))) { 25389 /* Restrict the speed to <= 2.5G and set the encap to HG2 */ 25390 if ((SOC_IS_SABER2(unit) || SOC_IS_HURRICANE2(unit)) && IS_XL_PORT(unit, port)) { 25391 rv = _bcm_port_encap_xport_set(unit, port, 25392 BCM_PORT_ENCAP_HIGIG2_LITE, 25393 TRUE); 25394 if (rv != BCM_E_NONE) { 25395 return rv; 25396 } 25397 SOC_IF_ERROR_RETURN 25398 (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, 2500)); 25399 } 25400 if((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && IS_XE_PORT(unit, port)) { 25401 /*Restrict the speed to <= 2.5G and set the encap to HG_LITE*/ 25402 rv = _bcm_port_encap_xport_set(unit, port, 25403 BCM_PORT_ENCAP_HIGIG2_LITE, 25404 TRUE); 25405 if (rv != BCM_E_NONE) { 25406 return rv; 25407 } 25408 SOC_IF_ERROR_RETURN 25409 (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, 2500)); 25410 } 25411 BCM_IF_ERROR_RETURN( 25412 soc_phyctrl_ability_local_get(unit, port, &ability)); 25413 25414 ability.speed_full_duplex &= ~(SOC_PA_SPEED_10GB | 25415 SOC_PA_SPEED_12GB | SOC_PA_SPEED_13GB | SOC_PA_SPEED_15GB | 25416 SOC_PA_SPEED_16GB | SOC_PA_SPEED_20GB | SOC_PA_SPEED_21GB | 25417 SOC_PA_SPEED_25GB | SOC_PA_SPEED_30GB | SOC_PA_SPEED_40GB); 25418 25419 BCM_IF_ERROR_RETURN( 25420 soc_phyctrl_ability_advert_set(unit, port, &ability)); 25421 BCM_IF_ERROR_RETURN( 25422 soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done)); 25423 if (!an) { 25424 BCM_IF_ERROR_RETURN( 25425 soc_phyctrl_speed_set(unit, port, 2500)); 25426 } 25427 if (!SOC_IS_SABER2(unit) && !SOC_IS_KATANA2(unit) && !SOC_IS_HURRICANE2(unit)) { 25428 return _bcm_port_encap_xport_set(unit, port, 25429 BCM_PORT_ENCAP_HIGIG2, TRUE); 25430 } 25431 } else if (IS_ST_PORT(unit, port) || IS_E_PORT(unit, port)) { 25432 return _bcm_port_encap_stport_set(unit, port, BCM_PORT_ENCAP_HIGIG2); 25433 } 25434 } /* if soc_feature(soc_feature_hg_no_speed_change) */ 25435 25436 return rv; 25437 } 25438 25439 25440 /* 25441 * Function: 25442 * bcm_esw_port_encap_config_set 25443 * Purpose: 25444 * Set the port encapsulation 25445 * Parameters: 25446 * unit - (IN) device id 25447 * gport - (IN) Generic port 25448 * encap_config - (IN) structure describes port encapsulation configuration 25449 * Returns: 25450 * BCM_E_XXX 25451 */ 25452 int 25453 bcm_esw_port_encap_config_set(int unit, bcm_gport_t gport, 25454 bcm_port_encap_config_t *encap_config) 25455 { 25456 bcm_port_t port; 25457 int rv = BCM_E_UNAVAIL, curr_mode=0; 25458 soc_info_t *si = &SOC_INFO(unit); 25459 bcm_stg_t stg = 0; 25460 25461 if (NULL == encap_config) { 25462 return BCM_E_PARAM; 25463 } 25464 /* Make sure port module is initialized. */ 25465 PORT_INIT(unit); 25466 25467 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, gport, &port)); 25468 if(bcm_common_oamp_port_enable_get(unit, port)) { 25469 LOG_ERROR(BSL_LS_BCM_PORT, 25470 (BSL_META("Error: Not permitted on OAMP port %d.n"), 25471 port)); 25472 return BCM_E_PARAM; 25473 } 25474 25475 25476 if (encap_config->encap != BCM_PORT_ENCAP_HIGIG2_L2 && 25477 encap_config->encap != BCM_PORT_ENCAP_HIGIG2_LITE && 25478 encap_config->encap != BCM_PORT_ENCAP_HIGIG2_IP_GRE && 25479 encap_config->encap != BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) { 25480 return bcm_esw_port_encap_set(unit, port, encap_config->encap); 25481 } 25482 25483 if (encap_config->encap == BCM_PORT_ENCAP_HIGIG2_LITE && 25484 (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) || SOC_IS_RAVEN(unit) 25485 || SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit))) { 25486 return bcm_esw_port_encap_set(unit, port, encap_config->encap); 25487 } 25488 25489 if (!soc_feature(unit, soc_feature_embedded_higig) && 25490 !soc_feature(unit, soc_feature_higig_over_ethernet)) { 25491 return (BCM_E_UNAVAIL); 25492 } 25493 25494 #if defined(BCM_SABER2_SUPPORT) 25495 if (SOC_IS_SABER2(unit) && (!BCM_GPORT_IS_SET(port))) { 25496 if(!IS_XL_PORT(unit, port)) { 25497 /* On saber2 non XL port, shouldn't have reached till here */ 25498 return BCM_E_UNAVAIL; 25499 } 25500 } 25501 #endif 25502 #if defined(BCM_TRIDENT3_SUPPORT) 25503 if (SOC_IS_TRIDENT3X(unit) 25504 && encap_config->encap == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) { 25505 25506 if (!soc_feature(unit, soc_feature_higig_over_ethernet)) { 25507 return BCM_E_UNAVAIL; 25508 } 25509 } 25510 #endif 25511 PORT_LOCK(unit); 25512 25513 if (encap_config->encap == BCM_PORT_ENCAP_HIGIG2_LITE) { 25514 rv = _bcm_esw_port_encap_higig_lite_set(unit, port); 25515 } else { 25516 if ((IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port))) { 25517 if (BCM_PORT_ENCAP_HIGIG2_L2 == encap_config->encap) { 25518 rv = BCM_E_NONE; 25519 rv = bcm_esw_port_encap_get(unit, port, &curr_mode); 25520 if ((BCM_SUCCESS(rv)) && (curr_mode != BCM_PORT_ENCAP_IEEE)) { 25521 rv = _bcm_port_encap_xport_set(unit, port, 25522 BCM_PORT_ENCAP_IEEE, TRUE); 25523 } 25524 } else { 25525 rv = _bcm_port_encap_xport_set(unit, port, 25526 BCM_PORT_ENCAP_IEEE, TRUE); 25527 } 25528 /* Update soc_info_t after changing port to ethernet */ 25529 soc_xport_type_update(unit, port, 0); 25530 } else if (IS_ST_PORT(unit, port) || IS_E_PORT(unit, port)) { 25531 rv = _bcm_port_encap_stport_set(unit, port, BCM_PORT_ENCAP_IEEE); 25532 } 25533 } 25534 25535 if (BCM_SUCCESS(rv)) { 25536 if (BCM_PORT_ENCAP_HIGIG2_L2 == encap_config->encap) { 25537 rv = _bcm_port_ehg_transport_mode_set(unit, port, encap_config); 25538 } else if (BCM_PORT_ENCAP_HIGIG2_IP_GRE == encap_config->encap){ 25539 rv = _bcm_port_ehg_tunnel_mode_set(unit, port, encap_config); 25540 } else if (BCM_PORT_ENCAP_HIGIG2_LITE == encap_config->encap){ 25541 rv = soc_reg_field32_modify(unit, EHG_RX_REG(unit), 25542 port, MODEf, 2); 25543 } else if (BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET == encap_config->encap){ 25544 rv = _bcm_port_hgoe_transport_mode_set(unit, port, encap_config); 25545 } 25546 } 25547 25548 /* Embedded Higig ports should be configured and marked as ST ports */ 25549 if (BCM_SUCCESS(rv)) { 25550 rv = bcm_esw_port_pause_set(unit, port, 0, 0); 25551 } 25552 if (BCM_SUCCESS(rv)) { 25553 /* Stack ports to forwarding */ 25554 rv = bcm_esw_port_stp_set(unit, port, BCM_STG_STP_FORWARD); 25555 } 25556 if (BCM_SUCCESS(rv)) { 25557 /* Set untagged state in default VLAN properly */ 25558 rv = _bcm_esw_vlan_untag_update(unit, port, TRUE); 25559 } 25560 if (BCM_SUCCESS(rv)) { 25561 /* Resolve STG 0 */ 25562 rv = bcm_esw_stg_default_get(unit, &stg); 25563 } 25564 if (BCM_SUCCESS(rv)) { 25565 rv = bcm_esw_stg_stp_set(unit, stg, port, BCM_STG_STP_FORWARD); 25566 } 25567 if (BCM_SUCCESS(rv)) { 25568 SOC_PBMP_PORT_ADD(si->st.bitmap, port); 25569 SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port); 25570 SOC_PBMP_PORT_REMOVE(si->hg2_pbm, port); 25571 } 25572 25573 PORT_UNLOCK(unit); 25574 25575 return (rv); 25576 } 25577 25578 /* 25579 * Function: 25580 * bcm_esw_port_encap_config_get 25581 * Purpose: 25582 * Get the port encapsulation 25583 * Parameters: 25584 * unit - (IN) device id 25585 * gport - (IN) Generic port 25586 * encap_config - (OUT) structure describes port encapsulation configuration 25587 * Returns: 25588 * BCM_E_XXX 25589 */ 25590 int 25591 bcm_esw_port_encap_config_get(int unit, bcm_gport_t gport, 25592 bcm_port_encap_config_t *encap_config) 25593 { 25594 bcm_port_t port; 25595 uint32 val, buffer[16]; /* 64 bytes max EHG header size */ 25596 uint64 val64; 25597 int rv = BCM_E_NONE, mode = 0; 25598 soc_reg_t ehg_tx_reg = EHG_TX_REG(unit); 25599 soc_reg_t ehg_rx_reg = EHG_RX_REG(unit); 25600 25601 if (NULL == encap_config) { 25602 return (BCM_E_PARAM); 25603 } 25604 /* Make sure port module is initialized. */ 25605 PORT_INIT(unit); 25606 25607 sal_memset(encap_config, 0, sizeof(bcm_port_encap_config_t)); 25608 25609 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, gport, &port)); 25610 if(bcm_common_oamp_port_enable_get(unit, port)) { 25611 LOG_ERROR(BSL_LS_BCM_PORT, 25612 (BSL_META("Error: Not permitted on OAMP port %d.n"), 25613 port)); 25614 return BCM_E_PARAM; 25615 } 25616 25617 if (!soc_feature(unit, soc_feature_embedded_higig) && 25618 !soc_feature(unit, soc_feature_higig_over_ethernet)) { 25619 25620 rv = bcm_esw_port_encap_get(unit, port, &mode); 25621 if (BCM_SUCCESS(rv)) { 25622 encap_config->encap = (bcm_port_encap_t)mode; 25623 } 25624 return rv; 25625 } 25626 25627 if (soc_feature(unit, soc_feature_embedded_higig)) { 25628 /* Check for Raptor-style stacking */ 25629 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_rx_reg, port, 0, &val)); 25630 if (soc_reg_field_get(unit, ehg_rx_reg, val, MODEf) == 2) { 25631 encap_config->encap = BCM_PORT_ENCAP_HIGIG2_LITE; 25632 return rv; 25633 } 25634 25635 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val)); 25636 /* If no EHG was programmed the just read port encapsulation */ 25637 if (!soc_reg_field_get(unit, ehg_tx_reg, val, ENABLEf)) { 25638 rv = bcm_esw_port_encap_get(unit, port, &mode); 25639 if (BCM_SUCCESS(rv)) { 25640 encap_config->encap = (bcm_port_encap_t)mode; 25641 } 25642 return rv; 25643 } 25644 25645 /* EHG is enabled. */ 25646 if (!IS_ST_PORT(unit, port)) { 25647 return (BCM_E_CONFIG); 25648 } 25649 25650 BCM_IF_ERROR_RETURN(_bcm_port_ehg_header_read(unit, port, buffer)); 25651 25652 if (!soc_reg_field_get(unit, ehg_tx_reg, val, TUNNEL_TYPEf)) { 25653 encap_config->encap = BCM_PORT_ENCAP_HIGIG2_L2; 25654 rv = _bcm_port_l2_tunnel_header_parse(unit, port, buffer, 25655 encap_config); 25656 } else { 25657 encap_config->encap = BCM_PORT_ENCAP_HIGIG2_IP_GRE; 25658 rv = _bcm_port_ipv4_tunnel_header_parse(unit, port, buffer, 25659 encap_config); 25660 } 25661 } else if(soc_feature(unit, soc_feature_higig_over_ethernet)) { 25662 uint64 v64 = COMPILER_64_INIT(0, 0); 25663 uint32 v32=0; 25664 25665 /* If HGoE disabled and then just read port encapsulation */ 25666 if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r)) { 25667 BCM_IF_ERROR_RETURN 25668 (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, port, 0, 25669 &val64)); 25670 v64 = soc_reg64_field_get(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, 25671 val64, TRANSPORT_ENf); 25672 } 25673 #ifdef BCM_TRIDENT3_SUPPORT 25674 if (SOC_IS_TRIDENT3X(unit)) { 25675 uint8 is_hgoe = 0; 25676 BCM_IF_ERROR_RETURN(bcm_td3_port_hgoe_mode_get( 25677 unit, port, &is_hgoe)); 25678 if (is_hgoe) { 25679 encap_config->encap = BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET; 25680 encap_config->higig_ethertype = BCM_TD3_HGOE_HDR_TYPE; 25681 return BCM_E_NONE; 25682 } else { 25683 rv = bcm_esw_port_encap_get(unit, port, &mode); 25684 if (BCM_SUCCESS(rv)) { 25685 encap_config->encap = (bcm_port_encap_t)mode; 25686 } 25687 return rv; 25688 } 25689 } else 25690 #endif 25691 if (COMPILER_64_IS_ZERO(v64)) { 25692 rv = bcm_esw_port_encap_get(unit, port, &mode); 25693 if (BCM_SUCCESS(rv)) { 25694 encap_config->encap = (bcm_port_encap_t)mode; 25695 } 25696 return rv; 25697 } 25698 25699 if (!IS_ST_PORT(unit, port)) { 25700 return (BCM_E_CONFIG); 25701 } 25702 25703 sal_memset(encap_config, 0, sizeof(bcm_port_encap_config_t)); 25704 encap_config->encap = BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET; 25705 25706 if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr)) { 25707 BCM_IF_ERROR_RETURN 25708 (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, port, 25709 0, &val64)); 25710 v64 = soc_reg64_field_get(unit, 25711 PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, val64, ETHERTYPEf); 25712 encap_config->higig_ethertype = (uint16) COMPILER_64_LO(v64); 25713 } 25714 25715 if (SOC_REG_IS_VALID(unit, EGR_EHG_HEADER_CONTROLr)) { 25716 BCM_IF_ERROR_RETURN 25717 (soc_reg_get(unit, EGR_EHG_HEADER_CONTROLr, port, 0, &val64)); 25718 v32 = COMPILER_64_LO(val64); 25719 encap_config->hgoe_reserved = soc_reg_field_get(unit, 25720 EGR_EHG_HEADER_CONTROLr, v32, EHG_RESERVEDf); 25721 } 25722 } 25723 25724 return (rv); 25725 } 25726 25727 /* 25728 * Function: 25729 * _bcm_esw_port_mirror_lock 25730 * Purpose: 25731 * Take the mirror and port mutexes 25732 * Parameters: 25733 * unit - unit # 25734 * Returns: 25735 * None 25736 */ 25737 void 25738 _bcm_esw_port_mirror_lock(int unit) { 25739 bcm_esw_mirror_lock(unit); 25740 PORT_LOCK(unit); 25741 } 25742 25743 /* 25744 * Function: 25745 * _bcm_esw_port_mirror_unlock 25746 * Purpose: 25747 * Give up the mirror and port mutexes 25748 * Parameters: 25749 * unit - unit # 25750 * Returns: 25751 * None 25752 */ 25753 void 25754 _bcm_esw_port_mirror_unlock(int unit) { 25755 PORT_UNLOCK(unit); 25756 bcm_esw_mirror_unlock(unit); 25757 } 25758 25759 /* 25760 * Function: 25761 * bcmi_esw_port_encap_set 25762 * Purpose: 25763 * Set the port encapsulation mode 25764 * Parameters: 25765 * unit - StrataSwitch unit # 25766 * port - StrataSwitch port # 25767 * mode - One of BCM_PORT_ENCAP_xxx (see port.h) 25768 * Returns: 25769 * BCM_E_XXX 25770 */ 25771 int 25772 bcmi_esw_port_encap_set(int unit, bcm_port_t port, int mode) 25773 { 25774 int rv=BCM_E_NONE, xport_swap = FALSE; 25775 int stport_swap = FALSE; 25776 #if defined(BCM_KATANA2_SUPPORT) 25777 uint64 rval64; 25778 ing_physical_port_table_entry_t ing_entry={{0}}; 25779 ing_physical_port_table_entry_t ing_entry_dup={{0}}; 25780 egr_physical_port_entry_t egr_entry={{0}}; 25781 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 25782 #endif 25783 #ifdef BCM_HELIX4_SUPPORT 25784 uint16 dev_id = 0; 25785 uint8 rev_id = 0; 25786 #endif 25787 /* Make sure port module is initialized. */ 25788 PORT_INIT(unit); 25789 25790 if(bcm_common_oamp_port_enable_get(unit, port)) { 25791 LOG_ERROR(BSL_LS_BCM_PORT, 25792 (BSL_META("Error: Not permitted on OAMP port %d.n"), 25793 port)); 25794 return BCM_E_PARAM; 25795 } 25796 25797 #ifdef BCM_HELIX4_SUPPORT 25798 soc_cm_get_id(unit, &dev_id, &rev_id); 25799 if ((BCM56548H_DEVICE_ID == dev_id) && 25800 (mode == BCM_PORT_ENCAP_IEEE) && ((port >= 46) && (port <= 53))) { 25801 /* IEEE encap mode shouldn't be supported on WC1 and WC2 for BCM56548H*/ 25802 return BCM_E_UNAVAIL; 25803 } 25804 #endif 25805 25806 #if defined(BCM_KATANA2_SUPPORT) 25807 #if defined(BCM_SABER2_SUPPORT) 25808 if(SOC_IS_SABER2(unit)) { 25809 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 25810 } 25811 #endif 25812 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 25813 (!((port >= 1) && (port <= max_phy_port)))) { 25814 return BCM_E_PORT; 25815 } 25816 #endif 25817 25818 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 25819 LOG_INFO(BSL_LS_BCM_PORT, 25820 (BSL_META_U(unit, 25821 "bcm_esw_port_encap_set: u=%d p=%d mode=%d\n"), 25822 unit, port, mode)); 25823 #if defined(BCM_METROLITE_SUPPORT) 25824 if (SOC_IS_METROLITE(unit)){ 25825 if (!BCM_GPORT_IS_SET(port)) { 25826 if(!IS_XL_PORT(unit, port) && (mode != BCM_PORT_ENCAP_IEEE)) { 25827 return BCM_E_UNAVAIL; 25828 } 25829 if((0 == SOC_PORT_BLOCK_NUMBER(unit, port)) && 25830 (mode != BCM_PORT_ENCAP_IEEE)) { 25831 return BCM_E_UNAVAIL; 25832 } 25833 } 25834 }else 25835 #endif 25836 #if defined(BCM_SABER2_SUPPORT) 25837 if (SOC_IS_SABER2(unit) && (!BCM_GPORT_IS_SET(port))) { 25838 if(!IS_XL_PORT(unit, port) && (mode != BCM_PORT_ENCAP_IEEE)) { 25839 return BCM_E_UNAVAIL; 25840 } 25841 } 25842 #endif 25843 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||\ 25844 defined (BCM_SABER2_SUPPORT) 25845 if (SOC_IS_GREYHOUND(unit) || SOC_IS_TOMAHAWKX(unit) || 25846 SOC_IS_HURRICANE3(unit) || SOC_IS_SABER2(unit) || 25847 SOC_IS_TRIDENT3X(unit) || SOC_IS_GREYHOUND2(unit)) { 25848 int encap_mode; 25849 BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, port, &encap_mode)); 25850 if (encap_mode == mode) { 25851 /* no encap set is required */ 25852 return BCM_E_NONE; 25853 } 25854 } 25855 #endif /* BCM_GREYHOUND_SUPPORT || BCM_TOMAHAWK_SUPPORT || BCM_SABER2_SUPPORT */ 25856 25857 #if defined(BCM_HURRICANE3_SUPPORT) 25858 if (soc_feature(unit, soc_feature_wh2)){ 25859 return bcmi_wh2_port_encap_set(unit, port, mode); 25860 } 25861 #endif /* BCM_HURRICANE3_SUPPORT */ 25862 _bcm_esw_port_mirror_lock(unit); 25863 25864 if ((IS_HG_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) || 25865 ((IS_XE_PORT(unit,port) || IS_CE_PORT(unit,port)) && 25866 (mode != BCM_PORT_ENCAP_IEEE))) { 25867 if (soc_feature(unit, soc_feature_xport_convertible)) { 25868 xport_swap = TRUE; 25869 } else { 25870 /* Ether <=> Higig not allowed on all systems */ 25871 _bcm_esw_port_mirror_unlock(unit); 25872 return BCM_E_UNAVAIL; 25873 } 25874 } 25875 #if defined(BCM_GREYHOUND_SUPPORT) 25876 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 25877 SOC_IS_GREYHOUND2(unit)) { 25878 if ((IS_HG_PORT(unit, port) && (mode != BCM_PORT_ENCAP_IEEE)) || 25879 (IS_HL_PORT(unit, port) && (mode == BCM_PORT_ENCAP_IEEE))) { 25880 /* HG port encap swap between HG/HG2/HG-Lite and 25881 * HG-Lite encap swap to IEEE. 25882 */ 25883 xport_swap = TRUE; 25884 } else if (IS_GE_PORT(unit, port)) { 25885 if ((IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) && 25886 (mode == BCM_PORT_ENCAP_IEEE || 25887 mode == BCM_PORT_ENCAP_HIGIG2_LITE)){ 25888 /* GE+XL/CL port encap set between IEEE/HG-Lite */ 25889 xport_swap = TRUE; 25890 } else { 25891 /* unavail encap configuration : 25892 * 1. QSGMII port for HG/HG2/HG2-Lite related encap 25893 * 2. GE(+XL) port for HG/HG2 25894 */ 25895 _bcm_esw_port_mirror_unlock(unit); 25896 return BCM_E_UNAVAIL; 25897 } 25898 } 25899 } 25900 #endif /* BCM_GREYHOUND_SUPPORT */ 25901 #if defined(BCM_KATANA_SUPPORT) 25902 if (SOC_IS_KATANA(unit) && IS_MXQ_PORT(unit,port) && 25903 IS_GE_PORT(unit,port)) { 25904 if ((IS_ST_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) || 25905 (IS_E_PORT(unit,port) && (mode == BCM_PORT_ENCAP_HIGIG2 || 25906 mode == BCM_PORT_ENCAP_HIGIG2_LITE))) { 25907 stport_swap = TRUE; 25908 } 25909 } 25910 #endif 25911 #if defined(BCM_KATANA2_SUPPORT) 25912 if ((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && 25913 (port >= 25 && port <= 40)) { 25914 if ((IS_ST_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) || 25915 (IS_E_PORT(unit,port) && (mode == BCM_PORT_ENCAP_HIGIG2 || 25916 mode == BCM_PORT_ENCAP_HIGIG2_LITE))) { 25917 stport_swap = TRUE; 25918 } 25919 } 25920 #endif 25921 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 25922 /* There could be hg to hg (hg2 -> hg2 lite) which require special processing */ 25923 if ((SOC_IS_SABER2(unit) || SOC_IS_HURRICANE2(unit)) && IS_XL_PORT(unit, port)) { 25924 xport_swap = TRUE; 25925 } 25926 #endif 25927 if (SOC_IS_RAVEN(unit) || SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit)) { 25928 if ((IS_ST_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) || 25929 (IS_E_PORT(unit,port) && (mode == BCM_PORT_ENCAP_HIGIG2 || 25930 mode == BCM_PORT_ENCAP_HIGIG2_LITE))) { 25931 stport_swap = TRUE; 25932 } 25933 } 25934 #ifdef BCM_TRIUMPH3_SUPPORT 25935 if (SOC_IS_TRIUMPH3(unit) && IS_XT_PORT(unit,port) && 25936 !((mode == BCM_PORT_ENCAP_IEEE) || (mode == BCM_PORT_ENCAP_HIGIG2_L2))) { 25937 /* Ether => Higig not allowed on XT ports */ 25938 _bcm_esw_port_mirror_unlock(unit); 25939 return BCM_E_UNAVAIL; 25940 } 25941 if (SOC_IS_TRIUMPH3(unit) && (mode != BCM_PORT_ENCAP_IEEE) && 25942 !IS_HG_PORT(unit, port)) { 25943 int hp, hgc = 0; 25944 25945 PBMP_HG_ITER(unit, hp) { 25946 if (!SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit, port), hp)) { 25947 hgc++; 25948 } 25949 } 25950 if (hgc+1 > _SOC_TR3_MAX_HG_PORT_COUNT) { 25951 LOG_ERROR(BSL_LS_BCM_PORT, \ 25952 (BSL_META_U(unit, \ 25953 "Error: Port %d config error "\ 25954 "(Higig port count(%d) exceeded) !!\n"), 25955 port, hgc)); 25956 _bcm_esw_port_mirror_unlock(unit); 25957 return BCM_E_RESOURCE; 25958 } 25959 } 25960 #endif /* BCM_TRIUMPH3_SUPPORT */ 25961 25962 if (xport_swap) { 25963 COUNTER_LOCK(unit); 25964 if ((BCM_PORT_ENCAP_HIGIG2_LITE == mode)) { 25965 rv = _bcm_esw_port_encap_higig_lite_set(unit, port); 25966 } else { 25967 rv = _bcm_port_encap_xport_set(unit, port, mode, TRUE); 25968 } 25969 25970 COUNTER_UNLOCK(unit); 25971 } else if (stport_swap) { 25972 rv = _bcm_port_encap_stport_set(unit, port, mode); 25973 } else if (IS_HG_PORT(unit, port)) { 25974 rv = MAC_ENCAP_SET(PORT(unit, port).p_mac, unit, port, mode); 25975 } else if (IS_GE_PORT(unit, port) && IS_ST_PORT(unit, port)) { 25976 if (mode == BCM_PORT_ENCAP_IEEE) { 25977 bcm_port_encap_config_t encap_config; 25978 25979 rv = bcm_esw_port_encap_config_get(unit, port, 25980 &encap_config); 25981 if (BCM_SUCCESS(rv)) { 25982 if ((BCM_PORT_ENCAP_HIGIG2_L2 == encap_config.encap) || 25983 (BCM_PORT_ENCAP_HIGIG2_IP_GRE == encap_config.encap) || 25984 (BCM_PORT_ENCAP_HIGIG2_LITE == encap_config.encap) || 25985 (BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET == encap_config.encap)) { 25986 rv = _bcm_port_encap_stport_set(unit, port, 25987 BCM_PORT_ENCAP_IEEE); 25988 } else { 25989 rv = BCM_E_UNAVAIL; 25990 } 25991 } 25992 } else { 25993 if ((mode == BCM_PORT_ENCAP_HIGIG2) || 25994 (mode == BCM_PORT_ENCAP_HIGIG2_LITE && 25995 (SOC_IS_RAVEN(unit) || SOC_IS_ENDURO(unit) || 25996 SOC_IS_HURRICANEX( unit) || SOC_IS_GREYHOUND(unit) || 25997 SOC_IS_GREYHOUND2(unit)))) { 25998 rv = BCM_E_NONE; 25999 } else { 26000 rv = BCM_E_UNAVAIL; 26001 } 26002 } 26003 #if defined(BCM_TRIUMPH3_SUPPORT) 26004 } else if (IS_CE_PORT(unit, port)) { 26005 if ((mode == BCM_PORT_ENCAP_HIGIG2) || (mode == BCM_PORT_ENCAP_HIGIG) 26006 || (mode == BCM_PORT_ENCAP_IEEE)) { 26007 rv = _bcm_port_encap_stport_set(unit, port, mode); 26008 } else { 26009 rv = BCM_E_UNAVAIL; 26010 } 26011 #endif 26012 } else if (mode == BCM_PORT_ENCAP_IEEE) { 26013 rv = BCM_E_NONE; 26014 } else { 26015 rv = BCM_E_UNAVAIL; 26016 } 26017 26018 #ifdef BCM_GXPORT_SUPPORT 26019 if ( IS_GX_PORT(unit, port) 26020 || IS_XG_PORT(unit,port) 26021 || (IS_XQ_PORT(unit, port) && 26022 (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit))) 26023 || (IS_XL_PORT(unit, port) && 26024 (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || 26025 (SOC_IS_SABER2(unit) || SOC_IS_HURRICANE3(unit)) || 26026 SOC_IS_GREYHOUND2(unit))) 26027 || (IS_CL_PORT(unit, port) && (SOC_IS_GREYHOUND2(unit))) 26028 || (IS_MXQ_PORT(unit, port) && (SOC_IS_KATANAX(unit) && !SOC_IS_SABER2(unit))) 26029 || ((IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port) || 26030 IS_CE_PORT(unit, port)) && 26031 (SOC_IS_TRIUMPH3(unit) 26032 || (SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2PLUS(unit)) || 26033 SOC_IS_TOMAHAWKX(unit))) ) { 26034 int hg2 = FALSE; 26035 soc_reg_t port_config_reg; 26036 uint32 regval, new_hg_pbm; 26037 int blk, blk_num, bindex; 26038 26039 if (mode == BCM_PORT_ENCAP_HIGIG2 || mode == BCM_PORT_ENCAP_HIGIG2_LITE) { 26040 hg2 = TRUE; 26041 } 26042 if (BCM_SUCCESS(rv)) { 26043 rv = _bcm_esw_port_higig2_mode_set(unit, port, hg2); 26044 } 26045 26046 if (IS_CL_PORT(unit, port) && 26047 SOC_REG_IS_VALID(unit, CLPORT_CONFIGr)) { 26048 port_config_reg = CLPORT_CONFIGr; 26049 } else if (IS_C_PORT(unit, port) && 26050 SOC_REG_IS_VALID(unit, CPORT_CONFIGr)) { 26051 port_config_reg = CPORT_CONFIGr; 26052 } else if (SOC_REG_IS_VALID(unit, XLPORT_CONFIGr)) { 26053 port_config_reg = XLPORT_CONFIGr; 26054 } else if (SOC_REG_IS_VALID(unit, PORT_CONFIGr)) { 26055 port_config_reg = PORT_CONFIGr; 26056 } else { 26057 port_config_reg = XPORT_CONFIGr; 26058 } 26059 if (BCM_SUCCESS(rv)) { 26060 #if defined(BCM_GREYHOUND_SUPPORT)||defined(BCM_GREYHOUND2_SUPPORT) 26061 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 26062 SOC_IS_GREYHOUND2(unit)){ 26063 uint32 port_hg_mode; 26064 26065 /* XLPORT/CLPORT and PGW register for HIGIG_MODEf is confirmed 26066 * will be '1' for HG/HG+ setting only and '0' for other 26067 * encap mode{IEEE/HG2/HG2-LITE} 26068 */ 26069 port_hg_mode = (mode == BCM_PORT_ENCAP_HIGIG) ? 1 : 0; 26070 rv = soc_reg_field32_modify(unit, port_config_reg, port, 26071 HIGIG_MODEf, port_hg_mode); 26072 if (BCM_FAILURE(rv)) { 26073 _bcm_esw_port_mirror_unlock(unit); 26074 return rv; 26075 } 26076 26077 /* only port available for HG2 configuration allows PGW encap 26078 * setting below 26079 */ 26080 #if defined(BCM_GREYHOUND2_SUPPORT) 26081 if (SOC_IS_GREYHOUND2(unit)) { 26082 #ifdef BCM_FIRELIGHT_SUPPORT 26083 if (soc_feature(unit, soc_feature_fl)) { 26084 rv = soc_firelight_pgw_encap_field_modify(unit, 26085 port, HIGIG_MODEf, port_hg_mode); 26086 } else 26087 #endif /* BCM_FIRELIGHT_SUPPORT */ 26088 { 26089 rv = soc_greyhound2_pgw_encap_field_modify(unit, 26090 port, HIGIG_MODEf, port_hg_mode); 26091 } 26092 } else 26093 #endif /* BCM_GREYHOUND2_SUPPORT */ 26094 { 26095 rv = soc_greyhound_pgw_encap_field_modify(unit, 26096 port, HIGIG_MODEf, port_hg_mode); 26097 } 26098 if (BCM_FAILURE(rv)) { 26099 _bcm_esw_port_mirror_unlock(unit); 26100 return rv; 26101 } 26102 } else 26103 #endif /* BCM_GREYHOUND_SUPPORT||BCM_GREYHOUND2_SUPPORT */ 26104 { 26105 #if defined(BCM_SABER2_SUPPORT) 26106 if(SOC_IS_SABER2(unit)) { 26107 /* For Saber2, configure IECELL along with XLPORT */ 26108 if (SOC_REG_PORT_VALID(unit, IECELL_CONFIGr, port)) { 26109 if ((mode == BCM_PORT_ENCAP_HIGIG2) || 26110 (mode == BCM_PORT_ENCAP_HIGIG2_LITE) || 26111 (mode == BCM_PORT_ENCAP_HIGIG)) { 26112 rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port, 26113 HIGIG_MODEf, mode == BCM_PORT_ENCAP_HIGIG ? 26114 1 : 0); 26115 rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port, 26116 HIGIG2_MODEf, mode == BCM_PORT_ENCAP_HIGIG ? 26117 0 : 1); 26118 } else { 26119 rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port, 26120 HIGIG2_MODEf, 0); 26121 rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port, 26122 HIGIG_MODEf, 0); 26123 } 26124 } 26125 } 26126 #endif 26127 #ifdef BCM_KATANA2_SUPPORT 26128 if (SOC_IS_KATANA2(unit)) { 26129 if (SOC_REG_FIELD_VALID(unit, port_config_reg, HIGIG_MODEf)) { 26130 if ((mode == BCM_PORT_ENCAP_HIGIG2) || 26131 (mode == BCM_PORT_ENCAP_HIGIG2_LITE) || 26132 (mode == BCM_PORT_ENCAP_HIGIG)) { 26133 26134 rv = soc_reg_field32_modify(unit, port_config_reg, port, 26135 HIGIG_MODEf, mode == BCM_PORT_ENCAP_HIGIG ? 26136 1 : 0); 26137 rv = soc_reg_field32_modify(unit, port_config_reg, port, 26138 HIGIG2_MODEf, mode == BCM_PORT_ENCAP_HIGIG ? 26139 0 : 1); 26140 } else { 26141 rv = soc_reg_field32_modify(unit, port_config_reg, port, 26142 HIGIG2_MODEf, 0); 26143 rv = soc_reg_field32_modify(unit, port_config_reg, port, 26144 HIGIG_MODEf, 0); 26145 } 26146 } 26147 } else 26148 #endif 26149 { 26150 if (SOC_REG_FIELD_VALID(unit, port_config_reg, HIGIG_MODEf)) { 26151 rv = soc_reg_field32_modify(unit, port_config_reg, port, 26152 HIGIG_MODEf, mode == BCM_PORT_ENCAP_IEEE ? 26153 0 : 1); 26154 } 26155 if (SOC_IS_TOMAHAWKX(unit)) { 26156 if (IS_CL_PORT(unit, port) && 26157 (mode == BCM_PORT_ENCAP_HIGIG)) { 26158 if (SOC_REG_FIELD_VALID(unit, port_config_reg, 26159 HIGIG2_MODEf)) { 26160 rv = soc_reg_field32_modify(unit, 26161 port_config_reg, port, HIGIG2_MODEf, 1); 26162 } 26163 } 26164 } 26165 } 26166 } 26167 } 26168 if (BCM_SUCCESS(rv)) { 26169 if (SOC_MEM_IS_VALID(unit, EGR_PORTm) && 26170 soc_mem_field_valid(unit, EGR_PORTm, PORT_TYPEf)) { 26171 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 26172 PORT_TYPEf, mode == BCM_PORT_ENCAP_IEEE ? 26173 0 : 1); 26174 } 26175 } 26176 if (SOC_IS_TRIUMPH3(unit) && (mode == BCM_PORT_ENCAP_IEEE)) { 26177 /* Disable E2ECC */ 26178 if (soc_feature(unit, soc_feature_logical_port_num)) { 26179 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[port]); 26180 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[port]); 26181 } else{ 26182 blk = SOC_PORT_BLOCK(unit, port); 26183 bindex = SOC_PORT_BINDEX(unit, port); 26184 } 26185 blk_num = SOC_BLOCK_INFO(unit, blk).number; 26186 /* In TR3 E2ECC is implemented only in blocks CL, XL1 */ 26187 if (IS_CL_PORT(unit, port) || (blk == 13)) { 26188 if (IS_CL_PORT(unit, port)) { 26189 blk_num = (blk_num ? 4 + bindex/4 : bindex/4); 26190 bindex = bindex%4; 26191 } else { 26192 blk_num = 3; 26193 } 26194 #if defined(BCM_KATANA2_SUPPORT) 26195 if (SOC_IS_KATANA2(unit)) { 26196 /* In KT2 E2ECC is implemented only in blocks 6..9 */ 26197 blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ; 26198 } 26199 #endif 26200 rv = READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num, ®val); 26201 if (BCM_FAILURE(rv)) { 26202 _bcm_esw_port_mirror_unlock(unit); 26203 return rv; 26204 } 26205 if (regval & (1 << bindex)) { 26206 new_hg_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval, 26207 TX_ENABLE_BMPf); 26208 new_hg_pbm &= ~(1 << bindex); 26209 soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, ®val, 26210 TX_ENABLE_BMPf, new_hg_pbm); 26211 rv = WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, regval); 26212 } 26213 } 26214 } 26215 } 26216 #endif /* BCM_GXPORT_SUPPORT */ 26217 26218 if (soc_feature(unit, soc_feature_embedded_higig)) { 26219 /* Clear embedded Higig regs, if present */ 26220 soc_reg_t ehg_tx_reg = EHG_TX_REG(unit); 26221 soc_reg_t ehg_rx_reg = EHG_RX_REG(unit); 26222 26223 if (BCM_SUCCESS(rv) && SOC_REG_IS_VALID(unit, ehg_tx_reg)) { 26224 rv = soc_reg32_set(unit, ehg_tx_reg, port, 0, 0); 26225 } 26226 if (BCM_SUCCESS(rv) && SOC_REG_IS_VALID(unit, ehg_rx_reg)) { 26227 rv = soc_reg32_set(unit, ehg_rx_reg, port, 0, 0); 26228 } 26229 } 26230 26231 #ifdef BCM_HIGIG2_SUPPORT 26232 /* Update cached version of HiGig2 encapsulation */ 26233 if (BCM_SUCCESS(rv)) { 26234 if (mode == BCM_PORT_ENCAP_HIGIG2 || mode == BCM_PORT_ENCAP_HIGIG2_LITE) { 26235 SOC_HG2_ENABLED_PORT_ADD(unit, port); 26236 26237 if(SOC_IS_SABER2(unit)){ 26238 if(mode == BCM_PORT_ENCAP_HIGIG2_LITE) { 26239 SOC_PBMP_PORT_ADD(SOC_INFO(unit).hl.bitmap, port); 26240 } else { 26241 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port); 26242 } 26243 } 26244 } else { 26245 SOC_HG2_ENABLED_PORT_REMOVE(unit, port); 26246 if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) { 26247 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port); 26248 } 26249 } 26250 } 26251 #endif /* BCM_HIGIG2_SUPPORT */ 26252 26253 #ifdef BCM_KATANA2_SUPPORT 26254 if (BCM_SUCCESS(rv)) { 26255 if (SOC_IS_KATANA2(unit)) { 26256 int hdr_mode = 0; 26257 26258 do { 26259 rv = soc_mem_read(unit, ING_PHYSICAL_PORT_TABLEm, 26260 MEM_BLOCK_ANY, port, &ing_entry); 26261 sal_memcpy(&ing_entry_dup,&ing_entry, 26262 sizeof(ing_physical_port_table_entry_t)); 26263 if (BCM_FAILURE(rv)) { 26264 LOG_ERROR(BSL_LS_BCM_PORT, 26265 (BSL_META_U(unit, 26266 "Error: Encap Set: " 26267 "ING_PHYSICAL_PORT_TABLEm read failure"))); 26268 break; 26269 } 26270 rv = soc_mem_read(unit, EGR_PHYSICAL_PORTm, 26271 MEM_BLOCK_ANY, port, &egr_entry); 26272 if (BCM_FAILURE(rv)) { 26273 LOG_ERROR(BSL_LS_BCM_PORT, 26274 (BSL_META_U(unit, 26275 "Error: Encap Set: " 26276 "EGR_PHYSICAL_PORTm read failure"))); 26277 break; 26278 } 26279 /* Initialize */ 26280 soc_mem_field32_set(unit, ING_PHYSICAL_PORT_TABLEm, 26281 &ing_entry, PORT_TYPEf, 0); 26282 soc_mem_field32_set(unit, ING_PHYSICAL_PORT_TABLEm, 26283 &ing_entry, HIGIG2f, 0); 26284 soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm, 26285 &egr_entry, PORT_TYPEf, 0); 26286 soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm, 26287 &egr_entry, HIGIG2f, 0); 26288 if ((mode == BCM_PORT_ENCAP_HIGIG) || 26289 (mode == BCM_PORT_ENCAP_HIGIG2) || 26290 (mode == BCM_PORT_ENCAP_HIGIG2_LITE)) { 26291 if (((mode == BCM_PORT_ENCAP_HIGIG2) || 26292 (mode == BCM_PORT_ENCAP_HIGIG2_LITE)) && 26293 soc_feature(unit, soc_feature_higig2)) { 26294 if (mode == BCM_PORT_ENCAP_HIGIG2_LITE) { 26295 hdr_mode = 0; /* Ieee mode */ 26296 } else { 26297 hdr_mode = 2; /* Higig2 */ 26298 } 26299 soc_mem_field32_set(unit, 26300 ING_PHYSICAL_PORT_TABLEm, 26301 &ing_entry, HIGIG2f, 1); 26302 soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm, 26303 &egr_entry, HIGIG2f, 1); 26304 } else { 26305 hdr_mode = 1; /* HG, hg+ */ 26306 } 26307 soc_mem_field32_set(unit, ING_PHYSICAL_PORT_TABLEm, 26308 &ing_entry, PORT_TYPEf, 1); 26309 soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm, 26310 &egr_entry, PORT_TYPEf, 1); 26311 } else { 26312 hdr_mode = 0; /* Ieee mode */ 26313 } 26314 if (SOC_REG_IS_VALID(unit, XMAC_MODEr)) { 26315 rv = READ_XMAC_MODEr(unit,port, &rval64); 26316 if (BCM_FAILURE(rv)) { 26317 _bcm_esw_port_mirror_unlock(unit); 26318 return rv; 26319 } 26320 soc_reg64_field32_set(unit, XMAC_MODEr, &rval64,HDR_MODEf, hdr_mode); 26321 rv = WRITE_XMAC_MODEr(unit, port, rval64); 26322 if (BCM_FAILURE(rv)) { 26323 _bcm_esw_port_mirror_unlock(unit); 26324 return rv; 26325 } 26326 } 26327 if (SOC_REG_IS_VALID(unit, XLMAC_MODEr)) { 26328 rv = READ_XLMAC_MODEr(unit,port, &rval64); 26329 if (BCM_FAILURE(rv)) { 26330 _bcm_esw_port_mirror_unlock(unit); 26331 return rv; 26332 } 26333 soc_reg64_field32_set(unit, XLMAC_MODEr, &rval64,HDR_MODEf, hdr_mode); 26334 rv = WRITE_XLMAC_MODEr(unit, port, rval64); 26335 if (BCM_FAILURE(rv)) { 26336 _bcm_esw_port_mirror_unlock(unit); 26337 return rv; 26338 } 26339 } 26340 26341 if (sal_memcmp(&ing_entry_dup,&ing_entry, 26342 sizeof(ing_physical_port_table_entry_t)) == 0) { 26343 LOG_VERBOSE(BSL_LS_BCM_PORT, 26344 (BSL_META_U(unit, 26345 "##No Change in entry so skipping write##\n"))); 26346 rv = BCM_E_NONE; 26347 } else { 26348 LOG_ERROR(BSL_LS_BCM_PORT, 26349 (BSL_META_U(unit, 26350 "##Change in entry so Need to update##\n"))); 26351 rv = soc_mem_write(unit, ING_PHYSICAL_PORT_TABLEm, 26352 MEM_BLOCK_ALL, port, &ing_entry); 26353 } 26354 if (BCM_FAILURE(rv)) { 26355 LOG_ERROR(BSL_LS_BCM_PORT, 26356 (BSL_META_U(unit, 26357 "Error: Encap Set: " 26358 "ING_PHYSICAL_PORT_TABLEm write failure"))); 26359 break; 26360 } 26361 rv = soc_mem_write(unit, EGR_PHYSICAL_PORTm, 26362 MEM_BLOCK_ALL, port, &egr_entry); 26363 if (BCM_FAILURE(rv)) { 26364 LOG_ERROR(BSL_LS_BCM_PORT, 26365 (BSL_META_U(unit, 26366 "Error: Encap Set: " 26367 "EGR_PHYSICAL_PORTm write failure"))); 26368 break; 26369 } 26370 26371 #ifdef BCM_KATANA2_SUPPORT 26372 if (SOC_IS_KATANA2(unit )) { 26373 rv = _bcm_kt2_cosq_dynamic_port_encap_change(unit,port); 26374 if (BCM_FAILURE(rv)) { 26375 LOG_ERROR(BSL_LS_BCM_PORT, 26376 (BSL_META_U(unit, 26377 "Error: Encap Set: " 26378 "MMU config failure"))); 26379 break; 26380 } 26381 } 26382 #endif 26383 26384 }while (0); 26385 } 26386 } 26387 #endif 26388 26389 #if defined(BCM_XMAC_SUPPORT) 26390 if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) || 26391 SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 26392 uint32 vco_disturbed = 0; 26393 phy_ctrl_t *int_pc; 26394 if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) || 26395 IS_XE_PORT(unit, port))) { 26396 26397 int_pc = INT_PHY_SW_STATE(unit, port); 26398 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed); 26399 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) { 26400 _bcm_esw_port_mirror_unlock(unit); 26401 return rv; 26402 } 26403 if (vco_disturbed) { 26404 rv = _mac_x_reinit(unit, port); 26405 if (BCM_FAILURE(rv)) { 26406 _bcm_esw_port_mirror_unlock(unit); 26407 return rv; 26408 } 26409 } 26410 } 26411 } 26412 #endif 26413 _bcm_esw_port_mirror_unlock(unit); 26414 26415 return rv; 26416 } 26417 26418 26419 /* 26420 * Function: 26421 * bcmi_esw_port_encap_validate 26422 * Purpose: 26423 * Check if the encap change for this port can be acceptable or not. 26424 * Parameters: 26425 * unit - (IN) Unit number 26426 * port - (IN) Logical port number 26427 * encap - (IN) encap mode 26428 * speed - (IN) speed 26429 * Returns: 26430 * BCM_E_NONE 26431 * BCM_E_XXX 26432 * Notes: 26433 */ 26434 STATIC int 26435 bcmi_esw_port_encap_validate(int unit, bcm_port_t port, int mode, int speed) 26436 { 26437 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT 26438 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 26439 26440 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 26441 if (BCM_ESW_PORT_DRV(unit)->encap_speed_check != NULL) { 26442 BCM_IF_ERROR_RETURN 26443 (BCM_ESW_PORT_DRV(unit)->encap_speed_check(unit, port, 26444 mode, speed)); 26445 } 26446 } 26447 return BCM_E_NONE; 26448 #else 26449 return BCM_E_NONE; 26450 #endif 26451 } 26452 26453 STATIC int 26454 _bcm_esw_port_encap_set(int unit, bcm_port_t port, int mode) 26455 { 26456 int rv; 26457 #if defined(BCM_TOMAHAWK2_SUPPORT) 26458 int asf_mode; 26459 #endif /* BCM_TOMAHAWK2_SUPPORT */ 26460 26461 26462 #if defined(BCM_TOMAHAWK3_SUPPORT) 26463 if (SOC_IS_TOMAHAWK3(unit)) { 26464 return BCM_E_NONE; 26465 } 26466 #endif /* BCM_TOMAHAWK3_SUPPORT */ 26467 26468 #if defined(BCM_TOMAHAWK2_SUPPORT) 26469 if (SOC_IS_TOMAHAWK2(unit)) { 26470 BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_get(unit, port, &asf_mode)); 26471 if (asf_mode != _SOC_TH_ASF_MODE_SAF) { 26472 BCM_IF_ERROR_RETURN 26473 (bcm_esw_port_asf_mode_set(unit, port, _SOC_TH_ASF_MODE_SAF)); 26474 } 26475 } 26476 #endif /* BCM_TOMAHAWK2_SUPPORT */ 26477 26478 /* Call Port Control module */ 26479 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 26480 rv = bcmi_esw_portctrl_encap_set(unit, port, mode, FALSE); 26481 } else { 26482 rv = bcmi_esw_port_encap_set(unit, port, mode); 26483 } 26484 26485 #if defined(BCM_TOMAHAWK2_SUPPORT) 26486 if (SOC_IS_TOMAHAWK2(unit)) { 26487 if (asf_mode != _SOC_TH_ASF_MODE_SAF) { 26488 BCM_IF_ERROR_RETURN 26489 (bcm_esw_port_asf_mode_set(unit, port, asf_mode)); 26490 } 26491 } 26492 #endif /* BCM_TOMAHAWK2_SUPPORT */ 26493 26494 return rv; 26495 } 26496 26497 /* 26498 * Function: 26499 * bcm_port_encap_set 26500 * Purpose: 26501 * Set the port encapsulation mode 26502 * Parameters: 26503 * unit - StrataSwitch unit # 26504 * port - StrataSwitch port # 26505 * mode - One of BCM_PORT_ENCAP_xxx (see port.h) 26506 * Returns: 26507 * BCM_E_XXX 26508 */ 26509 int 26510 bcm_esw_port_encap_set(int unit, bcm_port_t port, int mode) 26511 { 26512 /* Make sure port module is initialized. */ 26513 PORT_INIT(unit); 26514 26515 BCM_IF_ERROR_RETURN(bcmi_esw_port_encap_validate(unit, port, mode, 0)); 26516 BCM_IF_ERROR_RETURN(_bcm_esw_port_encap_set(unit, port, mode)); 26517 26518 return BCM_E_NONE; 26519 } 26520 26521 /* 26522 * Function: 26523 * bcm_port_encap_get 26524 * Purpose: 26525 * Get the port encapsulation mode 26526 * Parameters: 26527 * unit - StrataSwitch unit # 26528 * port - StrataSwitch port # 26529 * mode (OUT) - One of BCM_PORT_ENCAP_xxx (see port.h) 26530 * Returns: 26531 * BCM_E_XXX 26532 */ 26533 26534 int 26535 bcm_esw_port_encap_get(int unit, bcm_port_t port, int *mode) 26536 { 26537 26538 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_KATANA_SUPPORT) 26539 int speed_mode = 0; 26540 uint64 rval64; 26541 #endif 26542 26543 #if defined(BCM_KATANA2_SUPPORT) 26544 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 26545 #endif 26546 26547 *mode = -1; 26548 26549 /* Make sure port module is initialized. */ 26550 PORT_INIT(unit); 26551 26552 /* Call Port Control module */ 26553 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 26554 return (bcmi_esw_portctrl_encap_get(unit, port, mode)); 26555 } 26556 if(bcm_common_oamp_port_enable_get(unit, port)) { 26557 LOG_ERROR(BSL_LS_BCM_PORT, 26558 (BSL_META("Error: Not permitted on OAMP port %d.n"), 26559 port)); 26560 return BCM_E_PARAM; 26561 } 26562 26563 26564 #if defined(BCM_KATANA2_SUPPORT) 26565 #if defined(BCM_SABER2_SUPPORT) 26566 if(SOC_IS_SABER2(unit)) { 26567 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 26568 } 26569 #endif 26570 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 26571 (!((port >= 1) && (port <= max_phy_port)))) { 26572 return BCM_E_PORT; 26573 } 26574 #endif 26575 26576 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 26577 26578 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA_SUPPORT) 26579 if (SOC_IS_ENDURO(unit) || SOC_IS_KATANAX(unit) || 26580 SOC_IS_HURRICANE(unit) || SOC_IS_HURRICANE2(unit)) { 26581 if (IS_HL_PORT(unit, port)) { 26582 *mode = BCM_PORT_ENCAP_HIGIG2; 26583 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 26584 if (SOC_IS_KATANAX(unit)) { 26585 if (SOC_REG_PORT_VALID(unit, XMAC_MODEr, port)) { 26586 SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit, port, &rval64)); 26587 speed_mode = soc_reg64_field32_get(unit, XMAC_MODEr, rval64, 26588 SPEED_MODEf); 26589 26590 } else if (SOC_REG_PORT_VALID(unit, XLMAC_MODEr, port)) { 26591 26592 SOC_IF_ERROR_RETURN(READ_XLMAC_MODEr(unit, port, &rval64)); 26593 speed_mode = soc_reg64_field32_get(unit, XLMAC_MODEr, rval64, 26594 SPEED_MODEf); 26595 } 26596 #if defined(BCM_METROLITE_SUPPORT) 26597 if (SOC_IS_METROLITE(unit)) { 26598 /* 2.5G and 1G speed in HIGIG2_LITE */ 26599 if ((speed_mode == 3)||(speed_mode == 2)) { 26600 *mode = BCM_PORT_ENCAP_HIGIG2_LITE; 26601 } 26602 } else 26603 #endif 26604 if (speed_mode == 3) { 26605 *mode = BCM_PORT_ENCAP_HIGIG2_LITE; 26606 } 26607 } 26608 #endif 26609 } else { 26610 SOC_IF_ERROR_RETURN 26611 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode)); 26612 } 26613 } else 26614 #endif /* BCM_ENDURO_SUPPORT */ 26615 #ifdef BCM_GREYHOUND_SUPPORT 26616 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 26617 SOC_IS_GREYHOUND2(unit)) { 26618 int rv; 26619 uint32 hg2_mode = 0; 26620 26621 #if defined(BCM_HURRICANE3_SUPPORT) 26622 if (soc_feature(unit, soc_feature_wh2)) { 26623 return bcmi_wh2_port_encap_get(unit, port, mode); 26624 } 26625 #endif /* BCM_HURRICANE3_SUPPORT */ 26626 /* MAC encap can report the proper encap type but special setting 26627 * in port marcro for HG2-Lite case. 26628 * 26629 * For HG2-Lite condition : 26630 * - in Port Macro(MAC is included in PM), the encap will be IEEE. 26631 * - Out of Port Macro, the encap will be HG2 26632 */ 26633 BCM_IF_ERROR_RETURN 26634 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode)); 26635 if (*mode == BCM_PORT_ENCAP_IEEE) { 26636 #ifdef BCM_GREYHOUND2_SUPPORT 26637 if (SOC_IS_GREYHOUND2(unit)) { 26638 #ifdef BCM_FIRELIGHT_SUPPORT 26639 if (soc_feature(unit, soc_feature_fl)) { 26640 rv = soc_firelight_pgw_encap_field_get(unit, 26641 port, HIGIG2_MODEf, &hg2_mode); 26642 } else 26643 #endif /* BCM_FIRELIGHT_SUPPORT */ 26644 { 26645 rv = soc_greyhound2_pgw_encap_field_get(unit, 26646 port, HIGIG2_MODEf, &hg2_mode); 26647 } 26648 } else 26649 #endif /* GREYHOUDN2 */ 26650 { 26651 /* only port in XLMAC allows PGW encap setting below */ 26652 rv = soc_greyhound_pgw_encap_field_get(unit, 26653 port, HIGIG2_MODEf, &hg2_mode); 26654 } 26655 26656 if (BCM_SUCCESS(rv)){ 26657 *mode = (hg2_mode) ? BCM_PORT_ENCAP_HIGIG2_LITE : *mode; 26658 } else if (rv != BCM_E_UNAVAIL) { 26659 /* BCM_E_UNAVAIL can be occurred on the port at QSGMII */ 26660 return rv; 26661 } 26662 } 26663 } else 26664 #endif /* BCM_GREYHOUND_SUPPORT */ 26665 if (IS_GE_PORT(unit, port) && IS_ST_PORT(unit, port)) { 26666 if (soc_feature(unit, soc_feature_embedded_higig)) { 26667 *mode = BCM_PORT_ENCAP_IEEE; 26668 } else { 26669 uint32 rval; 26670 soc_field_t hg_en[6] = {-1, HGIG2_EN_S0f, HGIG2_EN_S1f, -1, 26671 HGIG2_EN_S3f, HGIG2_EN_S4f}; 26672 /* The port number check is for Coverity. No port > 6 will 26673 * reach this logic on Raven. */ 26674 if (SOC_IS_RAVEN(unit) && (port < 6)) { 26675 BCM_IF_ERROR_RETURN(READ_GPORT_CONFIGr(unit, port, &rval)); 26676 26677 if (SOC_REG_FIELD_VALID(unit, GPORT_CONFIGr, hg_en[port])) { 26678 *mode = soc_reg_field_get(unit, GPORT_CONFIGr, rval, 26679 hg_en[port]) ? 26680 BCM_PORT_ENCAP_HIGIG2 : BCM_PORT_ENCAP_IEEE; 26681 } else { 26682 return (BCM_E_CONFIG); 26683 } 26684 } 26685 } 26686 #if defined(BCM_TRIUMPH3_SUPPORT) 26687 } else if (SOC_IS_TRIUMPH3(unit) && IS_CE_PORT(unit, port)) { 26688 uint32 regval; 26689 BCM_IF_ERROR_RETURN(READ_PORT_CONFIGr(unit, port, ®val)); 26690 if (soc_reg_field_get(unit, PORT_CONFIGr, regval, HIGIG2_MODEf)) { 26691 *mode = BCM_PORT_ENCAP_HIGIG2; 26692 } else if (soc_reg_field_get(unit, PORT_CONFIGr, regval, HIGIG_MODEf)) { 26693 *mode = BCM_PORT_ENCAP_HIGIG; 26694 } else { 26695 SOC_IF_ERROR_RETURN 26696 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode)); 26697 } 26698 #endif 26699 } else { 26700 SOC_IF_ERROR_RETURN 26701 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode)); 26702 } 26703 26704 if(*mode == -1) { 26705 /* Default : Return MAC encap mode */ 26706 SOC_IF_ERROR_RETURN 26707 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode)); 26708 } 26709 26710 LOG_INFO(BSL_LS_BCM_PORT, 26711 (BSL_META_U(unit, 26712 "bcm_esw_port_encap_get: u=%d p=%d mode=%d\n"), 26713 unit, port, *mode)); 26714 return BCM_E_NONE; 26715 } 26716 26717 /* 26718 * Function: 26719 * bcm_port_queued_count_get 26720 * Purpose: 26721 * Returns the count of packets (or cells) currently buffered 26722 * for a port. Useful to know when a port has drained all 26723 * data and can then be re-configured. 26724 * Parameters: 26725 * unit - StrataSwitch unit # 26726 * port - StrataSwitch port # 26727 * count (OUT) - count of packets currently buffered 26728 * Returns: 26729 * BCM_E_XXX 26730 * Notes: 26731 * "packets" may actually be cells on most chips, 26732 * If no packets are buffered, the cell count is 0, 26733 * If some packets are buffered the cell count will be 26734 * greater than or equal to the packet count. 26735 */ 26736 26737 int 26738 bcm_esw_port_queued_count_get(int unit, bcm_port_t port, uint32 *count) 26739 { 26740 uint32 regval; 26741 int cos; 26742 26743 *count = 0; 26744 26745 /* Make sure port module is initialized. */ 26746 PORT_INIT(unit); 26747 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 26748 26749 if (SOC_IS_FB_FX_HX(unit) || SOC_IS_HURRICANE2(unit) || 26750 SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 26751 SOC_IS_GREYHOUND2(unit)) { 26752 for (cos = 0; cos < NUM_COS(unit); cos++) { 26753 regval = 0; 26754 SOC_IF_ERROR_RETURN(READ_COSLCCOUNTr(unit, port, cos, ®val)); 26755 *count += soc_reg_field_get(unit, COSLCCOUNTr, regval, LCCOUNTf); 26756 } 26757 return BCM_E_NONE; 26758 } 26759 26760 #if defined(BCM_XGS12_FABRIC_SUPPORT) 26761 if (SOC_IS_XGS12_FABRIC(unit)) { 26762 regval = 0; 26763 SOC_IF_ERROR_RETURN(READ_MMU_CELLCNTTOTALr(unit, port, ®val)); 26764 *count += soc_reg_field_get(unit, MMU_CELLCNTTOTALr, regval, COUNTf); 26765 return BCM_E_NONE; 26766 } 26767 #endif /* BCM_XGS12_FABRIC_SUPPORT */ 26768 26769 #if defined(BCM_BRADLEY_SUPPORT) 26770 if (SOC_IS_HBX(unit)) { 26771 regval = 0; 26772 SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNTr(unit, port, ®val)); 26773 *count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNTr, 26774 regval, OP_PORT_TOTAL_COUNTf); 26775 return BCM_E_NONE; 26776 } 26777 #endif /* BCM_BRADLEY_SUPPORT */ 26778 26779 #if defined(BCM_TRIDENT_SUPPORT) 26780 if (SOC_IS_TD_TT(unit)) { 26781 return soc_egress_cell_count(unit, port, count); 26782 } 26783 #endif /* BCM_TRIDENT_SUPPORT */ 26784 26785 #if defined(BCM_TRIUMPH3_SUPPORT) 26786 if (SOC_IS_TRIUMPH3(unit)) { 26787 regval = 0; 26788 SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, ®val)); 26789 *count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr, 26790 regval, TOTAL_COUNTf); 26791 return BCM_E_NONE; 26792 } 26793 #endif /* BCM_TRIUMPH3_SUPPORT */ 26794 26795 return BCM_E_UNAVAIL; 26796 } 26797 26798 /* 26799 * Function: 26800 * bcm_port_protocol_vlan_add 26801 * Purpose: 26802 * Adds a protocol based vlan to a port. The protocol 26803 * is matched by frame type and ether type. Returns an 26804 * error if hardware does not support protocol vlans 26805 * (Strata and Hercules). 26806 * Parameters: 26807 * unit - StrataSwitch unit # 26808 * port - StrataSwitch port # 26809 * frame - one of BCM_PORT_FRAMETYPE_{ETHER2,8023,LLC} 26810 * ether - 16 bit Ethernet type field 26811 * vid - VLAN ID 26812 * Returns: 26813 * BCM_E_XXX 26814 */ 26815 26816 int 26817 bcm_esw_port_protocol_vlan_add(int unit, 26818 bcm_port_t port, 26819 bcm_port_frametype_t frame, 26820 bcm_port_ethertype_t ether, 26821 bcm_vlan_t vid) 26822 { 26823 int rv = BCM_E_UNAVAIL; 26824 26825 /* Make sure port module is initialized. */ 26826 PORT_INIT(unit); 26827 #ifdef BCM_XGS_SWITCH_SUPPORT 26828 26829 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 26830 PORT_SWITCHED_CHECK(unit, port); 26831 26832 PORT_LOCK(unit); 26833 #ifdef BCM_TRX_SUPPORT 26834 if (SOC_IS_TRX(unit)) { 26835 bcm_vlan_action_set_t action; 26836 26837 if (!soc_feature(unit, soc_feature_vlan_action)) { 26838 PORT_UNLOCK(unit); 26839 return BCM_E_UNAVAIL; 26840 } 26841 26842 bcm_vlan_action_set_t_init(&action); 26843 action.new_outer_vlan = vid; 26844 action.new_inner_vlan = 0; 26845 action.priority = PORT(unit, port).p_ut_prio; 26846 action.ut_outer = bcmVlanActionAdd; 26847 action.it_outer = bcmVlanActionAdd; 26848 action.it_inner = bcmVlanActionDelete; 26849 action.it_inner_prio = bcmVlanActionNone; 26850 action.ot_outer_prio = bcmVlanActionReplace; 26851 action.dt_outer_prio = bcmVlanActionReplace; 26852 26853 rv = _bcm_trx_vlan_port_protocol_action_add(unit, port, frame, 26854 ether, &action); 26855 PORT_UNLOCK(unit); 26856 return rv; 26857 } 26858 #endif /* BCM_TRX_SUPPORT */ 26859 26860 #if defined(BCM_FIREBOLT_SUPPORT) 26861 if (SOC_IS_FBX(unit)) { 26862 rv = _bcm_fb_port_protocol_vlan_add(unit, port, frame, ether, vid); 26863 PORT_UNLOCK(unit); 26864 return rv; 26865 } 26866 #endif /* BCM_FIREBOLT_SUPPORT */ 26867 PORT_UNLOCK(unit); 26868 #endif /* BCM_XGS_SWITCH_SUPPORT */ 26869 /* not supported on STRATA and HERCULES */ 26870 return rv; 26871 } 26872 26873 /* 26874 * Function: 26875 * bcm_port_protocol_vlan_delete 26876 * Purpose: 26877 * Remove an already created proto protocol based vlan 26878 * on a port. 26879 * Parameters: 26880 * unit - StrataSwitch unit # 26881 * port - StrataSwitch port # 26882 * frame - one of BCM_PORT_FRAMETYPE_{ETHER2,8023,LLC} 26883 * ether - 16 bit Ethernet type field 26884 * Returns: 26885 * BCM_E_XXX 26886 */ 26887 26888 int 26889 bcm_esw_port_protocol_vlan_delete(int unit, 26890 bcm_port_t port, 26891 bcm_port_frametype_t frame, 26892 bcm_port_ethertype_t ether) 26893 { 26894 int rv = BCM_E_UNAVAIL; 26895 /* Make sure port module is initialized. */ 26896 PORT_INIT(unit); 26897 #ifdef BCM_XGS_SWITCH_SUPPORT 26898 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 26899 PORT_SWITCHED_CHECK(unit, port); 26900 26901 PORT_LOCK(unit); 26902 26903 #ifdef BCM_TRX_SUPPORT 26904 if (SOC_IS_TRX(unit)) { 26905 if (!soc_feature(unit, soc_feature_vlan_action)) { 26906 PORT_UNLOCK(unit); 26907 return BCM_E_UNAVAIL; 26908 } 26909 rv = _bcm_trx_vlan_port_protocol_delete(unit, port, frame, ether); 26910 PORT_UNLOCK(unit); 26911 return rv; 26912 } 26913 #endif /* BCM_TRX_SUPPORT */ 26914 26915 #if defined(BCM_FIREBOLT_SUPPORT) 26916 if (SOC_IS_FBX(unit)) { 26917 rv = _bcm_fb_port_protocol_vlan_delete(unit, port, frame, ether); 26918 PORT_UNLOCK(unit); 26919 return rv; 26920 26921 } 26922 #endif /* BCM_FIREBOLT_SUPPORT */ 26923 26924 PORT_UNLOCK(unit); 26925 #endif /* BCM_XGS_SWITCH_SUPPORT */ 26926 /* not supported on STRATA and HERCULES */ 26927 return rv; 26928 } 26929 26930 /* 26931 * Function: 26932 * bcm_port_protocol_vlan_delete_all 26933 * Purpose: 26934 * Remove all protocol based vlans on a port. 26935 * Parameters: 26936 * unit - StrataSwitch unit # 26937 * port - StrataSwitch port # 26938 * Returns: 26939 * BCM_E_XXX 26940 */ 26941 26942 int 26943 bcm_esw_port_protocol_vlan_delete_all(int unit, bcm_port_t port) 26944 { 26945 #ifdef BCM_XGS_SWITCH_SUPPORT 26946 int i; 26947 26948 /* Make sure port module is initialized. */ 26949 PORT_INIT(unit); 26950 26951 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 26952 PORT_SWITCHED_CHECK(unit, port); 26953 26954 #ifdef BCM_TRX_SUPPORT 26955 if (SOC_IS_TRX(unit)) { 26956 int rv; 26957 if (!soc_feature(unit, soc_feature_vlan_action)) { 26958 return BCM_E_UNAVAIL; 26959 } 26960 PORT_LOCK(unit); 26961 rv = _bcm_trx_vlan_port_protocol_delete_all(unit, port); 26962 PORT_UNLOCK(unit); 26963 return rv; 26964 } 26965 #endif /* BCM_TRX_SUPPORT */ 26966 26967 #if defined(BCM_FIREBOLT_SUPPORT) 26968 if (SOC_IS_FBX(unit)) { 26969 vlan_protocol_entry_t vpe; 26970 vlan_protocol_data_entry_t vde; 26971 bcm_vlan_t cvid, defvid; 26972 int idxmin, idxmax; 26973 int vlan_prot_entries; 26974 int vdentry, p, valid; 26975 _bcm_port_info_t *pinfo; 26976 bcm_pbmp_t switched_pbm; 26977 26978 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm); 26979 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm); 26980 vlan_prot_entries = idxmax + 1; 26981 26982 for (i = idxmin; i <= idxmax; i++) { 26983 vdentry = (port * vlan_prot_entries) + i; 26984 SOC_IF_ERROR_RETURN 26985 (READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, 26986 vdentry, &vde)); 26987 cvid = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, VLAN_IDf); 26988 BCM_IF_ERROR_RETURN 26989 (bcm_esw_port_untagged_vlan_get(unit, port, &defvid)); 26990 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 26991 if (cvid == 0 || 26992 (cvid == defvid && (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)))) { 26993 continue; 26994 } 26995 sal_memset(&vde, 0, sizeof(vde)); 26996 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde, VLAN_IDf, defvid); 26997 SOC_IF_ERROR_RETURN 26998 (WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL, vdentry, &vde)); 26999 _BCM_PORT_VD_PBVL_CLEAR(pinfo, i); 27000 /* 27001 * see if any vlan_protocol_data entries are still valid 27002 * for the current protocol. 27003 */ 27004 valid = 0; 27005 switched_pbm = PBMP_E_ALL(unit); 27006 if (soc_feature(unit, soc_feature_cpuport_switched)) { 27007 BCM_PBMP_OR(switched_pbm, PBMP_CMIC(unit)); 27008 } 27009 27010 BCM_PBMP_ITER(switched_pbm, p) { 27011 if (p == port) { /* skip the entry we just "defaulted" */ 27012 continue; 27013 } 27014 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo)); 27015 /* entry valid if programmed VLAN ID for port */ 27016 if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) { 27017 valid = 1; 27018 break; 27019 } 27020 } 27021 if (!valid) { 27022 /* 27023 * Clear all VLAN_PROTOCOL_DATA entries associated 27024 * with this protocol. 27025 */ 27026 BCM_PBMP_ITER(switched_pbm, p) { 27027 vdentry = (p * vlan_prot_entries) + i; 27028 sal_memset(&vde, 0, sizeof(vde)); 27029 SOC_IF_ERROR_RETURN 27030 (WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL, 27031 vdentry, &vde)); 27032 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo)); 27033 _BCM_PORT_VD_PBVL_CLEAR(pinfo, i); 27034 } 27035 /* clear VLAN_PROTOCOL entry */ 27036 sal_memset(&vpe, 0, sizeof(vpe)); 27037 SOC_IF_ERROR_RETURN 27038 (WRITE_VLAN_PROTOCOLm(unit, MEM_BLOCK_ALL, i, &vpe)); 27039 } 27040 } 27041 return BCM_E_NONE; 27042 } 27043 #endif /* BCM_FIREBOLT_SUPPORT */ 27044 27045 #endif /* BCM_XGS_SWITCH_SUPPORT */ 27046 27047 /* not supported on STRATA and HERCULES */ 27048 27049 return BCM_E_UNAVAIL; 27050 } 27051 27052 /* 27053 * Differentiated Services Code Point Mapping 27054 */ 27055 27056 /* 27057 * Function: 27058 * bcm_esw_port_dscp_map_mode_set 27059 * Purpose: 27060 * Set DSCP mapping for the port. 27061 * Parameters: 27062 * unit - switch device 27063 * port - switch port or -1 to apply on all the ports. 27064 * mode - BCM_PORT_DSCP_MAP_NONE 27065 * - BCM_PORT_DSCP_MAP_ZERO Map if incomming DSCP = 0 27066 * - BCM_PORT_DSCP_MAP_ALL DSCP -> DSCP mapping. 27067 * Returns: 27068 * BCM_E_XXX 27069 */ 27070 static int 27071 _bcm_esw_port_dscp_map_mode_set(int unit, bcm_port_t port, int mode) 27072 { 27073 bcm_port_cfg_t pcfg; 27074 27075 BCM_IF_ERROR_RETURN 27076 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 27077 if (pcfg.pc_dse_mode == -1) { /* STRATA1 for example */ 27078 return BCM_E_UNAVAIL; 27079 } 27080 switch (mode) { 27081 case BCM_PORT_DSCP_MAP_NONE: 27082 pcfg.pc_dse_mode = 0; 27083 pcfg.pc_dse_mode_ipv6 = 0; 27084 #if defined(BCM_XGS_SWITCH_SUPPORT) 27085 pcfg.pc_dscp_prio = 0; 27086 #endif /* BCM_XGS_SWITCH_SUPPORT */ 27087 break; 27088 case BCM_PORT_DSCP_MAP_ZERO: 27089 if (soc_feature(unit, soc_feature_dscp_map_mode_all)) { 27090 return BCM_E_UNAVAIL; 27091 } 27092 pcfg.pc_dse_mode = 1; 27093 #if defined(BCM_XGS_SWITCH_SUPPORT) 27094 pcfg.pc_dscp_prio = 1; 27095 #endif /* BCM_XGS_SWITCH_SUPPORT */ 27096 break; 27097 case BCM_PORT_DSCP_MAP_ALL: 27098 if (soc_feature(unit, soc_feature_dscp_map_mode_all)) { 27099 pcfg.pc_dse_mode = 1; 27100 pcfg.pc_dse_mode_ipv6 = 1; 27101 } else { 27102 pcfg.pc_dse_mode = 2; 27103 } 27104 #if defined(BCM_XGS_SWITCH_SUPPORT) 27105 pcfg.pc_dscp_prio = 1; 27106 #endif /* BCM_XGS_SWITCH_SUPPORT */ 27107 break; 27108 case BCM_PORT_DSCP_MAP_IPV4_ONLY: 27109 if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) { 27110 return BCM_E_UNAVAIL; 27111 } 27112 pcfg.pc_dse_mode = 1; 27113 #if defined(BCM_XGS_SWITCH_SUPPORT) 27114 pcfg.pc_dscp_prio = 1; 27115 #endif /* BCM_XGS_SWITCH_SUPPORT */ 27116 break; 27117 case BCM_PORT_DSCP_MAP_IPV6_ONLY: 27118 if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) { 27119 return BCM_E_UNAVAIL; 27120 } 27121 pcfg.pc_dse_mode_ipv6 = 1; 27122 #if defined(BCM_XGS_SWITCH_SUPPORT) 27123 pcfg.pc_dscp_prio = 1; 27124 #endif /* BCM_XGS_SWITCH_SUPPORT */ 27125 break; 27126 case BCM_PORT_DSCP_MAP_IPV4_NONE: 27127 if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) { 27128 return BCM_E_UNAVAIL; 27129 } 27130 pcfg.pc_dse_mode = 0; 27131 #if defined(BCM_XGS_SWITCH_SUPPORT) 27132 if (!pcfg.pc_dse_mode_ipv6) { 27133 pcfg.pc_dscp_prio = 0; 27134 } 27135 #endif /* BCM_XGS_SWITCH_SUPPORT */ 27136 break; 27137 case BCM_PORT_DSCP_MAP_IPV6_NONE: 27138 if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) { 27139 return BCM_E_UNAVAIL; 27140 } 27141 pcfg.pc_dse_mode_ipv6 = 0; 27142 #if defined(BCM_XGS_SWITCH_SUPPORT) 27143 if (!pcfg.pc_dse_mode) { 27144 pcfg.pc_dscp_prio = 0; 27145 } 27146 #endif /* BCM_XGS_SWITCH_SUPPORT */ 27147 break; 27148 default: 27149 return BCM_E_PARAM; 27150 } 27151 BCM_IF_ERROR_RETURN 27152 (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 27153 27154 return BCM_E_NONE; 27155 } 27156 27157 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 27158 static int 27159 _bcm_esw_vp_dscp_map_mode_set(int unit, bcm_gport_t port, int mode) { 27160 if (SOC_IS_KATANAX(unit) || 27161 SOC_IS_TD_TT(unit)|| 27162 soc_feature(unit, soc_feature_vp_dscp_map)) { 27163 return _bcm_tr2_vp_dscp_map_mode_set(unit, port, mode); 27164 } 27165 return BCM_E_UNAVAIL; 27166 } 27167 27168 STATIC int 27169 _bcm_esw_vp_dscp_map_set(int unit, bcm_gport_t port, int srccp, int mapcp, 27170 int prio) 27171 { 27172 if (SOC_IS_TD_TT(unit) || soc_feature(unit, soc_feature_vp_dscp_map)) { 27173 return _bcm_tr2_vp_dscp_map_set(unit, port, srccp, mapcp, prio); 27174 } 27175 return BCM_E_UNAVAIL; 27176 } 27177 #endif 27178 27179 int 27180 bcm_esw_port_dscp_map_mode_set(int unit, bcm_port_t port, int mode) 27181 { 27182 int rv; 27183 bcm_port_config_t port_conf; 27184 bcm_pbmp_t pbmp; 27185 27186 /* Make sure port module is initialized. */ 27187 PORT_INIT(unit); 27188 27189 if (!soc_feature(unit, soc_feature_dscp)) { 27190 return BCM_E_UNAVAIL; 27191 } 27192 27193 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 27194 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 27195 !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) { 27196 return _bcm_esw_vp_dscp_map_mode_set(unit, port, mode); 27197 } 27198 #endif 27199 27200 if (port != -1) { 27201 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 27202 } 27203 27204 PORT_LOCK(unit); 27205 27206 /* Get device port configuration. */ 27207 rv = bcm_esw_port_config_get(unit, &port_conf); 27208 if (BCM_FAILURE(rv)) { 27209 PORT_UNLOCK(unit); 27210 return rv; 27211 } 27212 BCM_PBMP_ASSIGN(pbmp, port_conf.e); 27213 if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) { 27214 BCM_PBMP_OR(pbmp, port_conf.cpu); 27215 } 27216 #ifdef BCM_KATANA2_SUPPORT 27217 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 27218 rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp); 27219 if (BCM_FAILURE(rv)) { 27220 PORT_UNLOCK(unit); 27221 return (rv); 27222 } 27223 } 27224 if (soc_feature(unit, soc_feature_linkphy_coe) || 27225 soc_feature(unit, soc_feature_subtag_coe)) { 27226 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 27227 } 27228 #endif 27229 27230 if (port == -1) { 27231 PBMP_ITER(pbmp, port) { 27232 rv = _bcm_esw_port_dscp_map_mode_set(unit, port, mode); 27233 if (BCM_FAILURE(rv)) { 27234 PORT_UNLOCK(unit); 27235 return rv; 27236 } 27237 } 27238 } else { 27239 if (BCM_PBMP_MEMBER(pbmp, port)) { 27240 rv = _bcm_esw_port_dscp_map_mode_set(unit, port, mode); 27241 } else { 27242 rv = BCM_E_PORT; 27243 } 27244 } 27245 PORT_UNLOCK(unit); 27246 return rv; 27247 } 27248 27249 /* 27250 * Function: 27251 * bcm_esw_port_dscp_map_mode_get 27252 * Purpose: 27253 * DSCP mapping status for the port. 27254 * Parameters: 27255 * unit - switch device 27256 * port - switch port or -1 to get mode from first available port 27257 * mode - (OUT) 27258 * - BCM_PORT_DSCP_MAP_NONE 27259 * - BCM_PORT_DSCP_MAP_ZERO Map if incomming DSCP = 0 27260 * - BCM_PORT_DSCP_MAP_ALL DSCP -> DSCP mapping. 27261 * Returns: 27262 * BCM_E_XXX 27263 */ 27264 27265 static int 27266 _bcm_esw_port_dscp_map_mode_get(int unit, bcm_port_t port, int *mode) 27267 { 27268 bcm_port_cfg_t pcfg; 27269 27270 BCM_IF_ERROR_RETURN 27271 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 27272 if (pcfg.pc_dse_mode == -1) { /* STRATA1 for example */ 27273 return BCM_E_UNAVAIL; 27274 } 27275 switch (pcfg.pc_dse_mode) { 27276 case 1: 27277 if (soc_feature(unit, soc_feature_dscp_map_mode_all)) { 27278 if (pcfg.pc_dse_mode_ipv6) { 27279 *mode = BCM_PORT_DSCP_MAP_ALL; 27280 } else { 27281 *mode = BCM_PORT_DSCP_MAP_IPV4_ONLY; 27282 } 27283 } else { 27284 *mode = BCM_PORT_DSCP_MAP_ZERO; 27285 } 27286 break; 27287 case 2: 27288 if (soc_feature(unit, soc_feature_dscp_map_mode_all)) { 27289 if (pcfg.pc_dse_mode_ipv6) { 27290 *mode = BCM_PORT_DSCP_MAP_ALL; 27291 } else { 27292 *mode = BCM_PORT_DSCP_MAP_IPV4_ONLY; 27293 } 27294 } else { 27295 *mode = BCM_PORT_DSCP_MAP_ALL; 27296 } 27297 break; 27298 case 0: 27299 if (pcfg.pc_dse_mode_ipv6) { 27300 *mode = BCM_PORT_DSCP_MAP_IPV6_ONLY; 27301 } else { 27302 *mode = BCM_PORT_DSCP_MAP_NONE; 27303 } 27304 break; 27305 27306 default: 27307 *mode = BCM_PORT_DSCP_MAP_NONE; 27308 break; 27309 } 27310 27311 return BCM_E_NONE; 27312 } 27313 27314 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 27315 static int 27316 _bcm_esw_vp_dscp_map_mode_get(int unit, bcm_gport_t port, int *mode) { 27317 if (SOC_IS_KATANAX(unit) || 27318 SOC_IS_TD_TT(unit) || 27319 soc_feature(unit, soc_feature_vp_dscp_map)) { 27320 return _bcm_tr2_vp_dscp_map_mode_get(unit, port, mode); 27321 } 27322 return BCM_E_UNAVAIL; 27323 } 27324 27325 STATIC int 27326 _bcm_esw_vp_dscp_map_get(int unit, bcm_gport_t port, int srccp, int *mapcp, 27327 int *prio) 27328 { 27329 if (SOC_IS_TD_TT(unit) || soc_feature(unit, soc_feature_vp_dscp_map)) { 27330 return _bcm_tr2_vp_dscp_map_get(unit, port, srccp, mapcp, prio); 27331 } 27332 return BCM_E_UNAVAIL; 27333 } 27334 #endif 27335 27336 int 27337 bcm_esw_port_dscp_map_mode_get(int unit, bcm_port_t port, int *mode) 27338 { 27339 int rv; 27340 bcm_port_config_t port_conf; 27341 bcm_pbmp_t pbmp; 27342 27343 /* Make sure port module is initialized. */ 27344 PORT_INIT(unit); 27345 27346 if (!soc_feature(unit, soc_feature_dscp)) { 27347 return BCM_E_UNAVAIL; 27348 } 27349 27350 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 27351 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 27352 !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) { 27353 return _bcm_esw_vp_dscp_map_mode_get(unit, port, mode); 27354 } 27355 #endif 27356 27357 if (port != -1) { 27358 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 27359 } 27360 27361 PORT_LOCK(unit); 27362 27363 /* Get device port configuration. */ 27364 rv = bcm_esw_port_config_get(unit, &port_conf); 27365 if (BCM_FAILURE(rv)) { 27366 PORT_UNLOCK(unit); 27367 return rv; 27368 } 27369 BCM_PBMP_ASSIGN(pbmp, port_conf.e); 27370 if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) { 27371 BCM_PBMP_OR(pbmp, port_conf.cpu); 27372 } 27373 #ifdef BCM_KATANA2_SUPPORT 27374 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 27375 rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp); 27376 if (BCM_FAILURE(rv)) { 27377 PORT_UNLOCK(unit); 27378 return (rv); 27379 } 27380 } 27381 if (soc_feature(unit, soc_feature_linkphy_coe) || 27382 soc_feature(unit, soc_feature_subtag_coe)) { 27383 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 27384 } 27385 #endif 27386 27387 if (port == -1) { 27388 PBMP_ITER(pbmp, port) { 27389 break; 27390 } 27391 } 27392 27393 /* coverity[overrun-local : FALSE] */ 27394 if (BCM_PBMP_MEMBER(pbmp, port)) { 27395 rv = _bcm_esw_port_dscp_map_mode_get(unit, port, mode); 27396 } else { 27397 rv = BCM_E_PORT; 27398 } 27399 PORT_UNLOCK(unit); 27400 return rv; 27401 } 27402 27403 /* 27404 * Function: 27405 * _bcm_port_dscp_map_set 27406 * Purpose: 27407 * Internal implementation for bcm_port_dscp_map_set 27408 * Parameters: 27409 * unit - switch device 27410 * port - switch port or -1 for global table 27411 * srccp - src code point or -1 27412 * mapcp - mapped code point or -1 27413 * prio - priority value for mapped code point 27414 * -1 to use port default untagged priority 27415 * BCM_PRIO_RED can be or'ed into the priority 27416 * BCM_PRIO_YELLOW can be or'ed into the priority 27417 * Returns: 27418 * BCM_E_XXX 27419 */ 27420 27421 STATIC int 27422 _bcm_port_dscp_map_set(int unit, bcm_port_t port, 27423 int srccp, int mapcp, int prio) 27424 { 27425 #define DSCP_CODE_POINT_CNT 64 27426 #define DSCP_CODE_POINT_MAX (DSCP_CODE_POINT_CNT - 1) 27427 bcm_port_cfg_t pcfg; 27428 27429 if (mapcp < -1 || mapcp > DSCP_CODE_POINT_MAX) { 27430 return BCM_E_PARAM; 27431 } 27432 27433 #if defined(BCM_XGS3_SWITCH_SUPPORT) 27434 if (SOC_IS_XGS3_SWITCH(unit)) { 27435 int i, cng; 27436 dscp_table_entry_t de; 27437 phb_mapping_tbl_2_entry_t phb_tbl_2; 27438 int max_index; 27439 int min_index; 27440 int field_len; 27441 27442 if (SOC_IS_TRIDENT3X(unit)) { 27443 field_len = soc_mem_field_length(unit, PHB_MAPPING_TBL_2m, INT_PRIf); 27444 } else { 27445 field_len = soc_mem_field_length(unit, DSCP_TABLEm, PRIf); 27446 } 27447 27448 if (srccp < -1 || srccp > DSCP_CODE_POINT_MAX) { 27449 return BCM_E_PARAM; 27450 } 27451 /* Extract cng bits and check for valid priority. */ 27452 27453 cng = 0; /* Green */ 27454 if (prio < BCM_PRIO_MIN) { 27455 return BCM_E_PARAM; 27456 } 27457 if (prio & BCM_PRIO_RED) { 27458 cng = 0x01; /* Red */ 27459 prio &= ~BCM_PRIO_RED; 27460 } else if (prio & BCM_PRIO_YELLOW) { 27461 cng = 0x03; /* Yellow */ 27462 prio &= ~BCM_PRIO_YELLOW; 27463 } 27464 if ((prio & ~BCM_PRIO_MASK) != 0) { 27465 return BCM_E_PARAM; 27466 } 27467 if (prio >= (1 << field_len)) { 27468 return BCM_E_PARAM; 27469 } 27470 if (srccp < 0 && mapcp < 0) { 27471 /* No mapping */ 27472 return BCM_E_NONE; 27473 } else if (srccp < 0) { 27474 /* Map all DSCPs to a new DSCP */ 27475 /* fill all entries in DSCP_TABLEm with mapcp */ 27476 27477 #ifdef BCM_TRIDENT2_SUPPORT 27478 if (SOC_IS_TD2_TT2(unit)) { 27479 return (bcm_td2_port_dscp_map_set(unit, 27480 port, srccp, mapcp, prio, cng)); 27481 } 27482 #endif 27483 #ifdef BCM_KATANA2_SUPPORT 27484 if (SOC_IS_KATANA2(unit)) { 27485 return (bcm_kt2_port_dscp_map_set(unit, port, 27486 srccp, mapcp, prio, cng)); 27487 } 27488 #endif 27489 27490 if (SOC_IS_TRIDENT3X(unit)) { 27491 sal_memset(&phb_tbl_2, 0, sizeof(phb_tbl_2)); 27492 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, DSCPf, mapcp); 27493 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, INT_PRIf, prio); 27494 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, CNGf, cng); 27495 } else { 27496 sal_memset(&de, 0, sizeof(de)); 27497 soc_DSCP_TABLEm_field32_set(unit, &de, DSCPf, mapcp); 27498 soc_DSCP_TABLEm_field32_set(unit, &de, PRIf, prio); 27499 soc_DSCP_TABLEm_field32_set(unit, &de, CNGf, cng); 27500 } 27501 if (soc_feature(unit, soc_feature_dscp_map_per_port)) { 27502 min_index = port * DSCP_CODE_POINT_CNT; 27503 max_index = min_index + DSCP_CODE_POINT_MAX; 27504 } else { 27505 if (SOC_IS_TRIDENT3X(unit)) { 27506 max_index = soc_mem_index_max(unit, PHB_MAPPING_TBL_2m); 27507 } else { 27508 max_index = soc_mem_index_max(unit, DSCP_TABLEm); 27509 } 27510 min_index = 0; 27511 } 27512 27513 for (i = min_index; i <= max_index; i++) { 27514 if (SOC_IS_TRIDENT3X(unit)) { 27515 SOC_IF_ERROR_RETURN 27516 (WRITE_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ALL, i, &phb_tbl_2)); 27517 } else { 27518 SOC_IF_ERROR_RETURN 27519 (WRITE_DSCP_TABLEm(unit, MEM_BLOCK_ALL, i, &de)); 27520 } 27521 } 27522 } else { 27523 int num_cosq; 27524 27525 #ifdef BCM_TRIDENT2_SUPPORT 27526 if (SOC_IS_TD2_TT2(unit)) { 27527 return (bcm_td2_port_dscp_map_set(unit, port, 27528 srccp, mapcp, prio, cng)); 27529 } 27530 #endif 27531 #ifdef BCM_KATANA2_SUPPORT 27532 if (SOC_IS_KATANA2(unit)) { 27533 return (bcm_kt2_port_dscp_map_set(unit, port, 27534 srccp, mapcp, prio, cng)); 27535 } 27536 #endif 27537 27538 num_cosq = 1; /* For all cosqs */ 27539 /* Map a specific DSCP to a new DSCP */ 27540 sal_memset(&de, 0, sizeof(de)); 27541 /* fill specific srccp entry/entries in DSCP_TABLEm with mapcp */ 27542 if (SOC_IS_TRIDENT3X(unit)) { 27543 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, DSCPf, mapcp); 27544 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, INT_PRIf, prio); 27545 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, CNGf, cng); 27546 } else { 27547 soc_DSCP_TABLEm_field32_set(unit, &de, DSCPf, mapcp); 27548 soc_DSCP_TABLEm_field32_set(unit, &de, PRIf, prio); 27549 soc_DSCP_TABLEm_field32_set(unit, &de, CNGf, cng); 27550 } 27551 27552 if (soc_feature(unit, soc_feature_dscp_map_per_port)) { 27553 if (SOC_IS_TRIDENT3X(unit)) { 27554 SOC_IF_ERROR_RETURN 27555 (WRITE_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ALL, 27556 (port * DSCP_CODE_POINT_CNT) + srccp, &phb_tbl_2)); 27557 } else { 27558 SOC_IF_ERROR_RETURN 27559 (WRITE_DSCP_TABLEm(unit, MEM_BLOCK_ALL, 27560 (port * DSCP_CODE_POINT_CNT) + srccp, &de)); 27561 } 27562 27563 } else { 27564 for (i = 0; i < num_cosq ; i++) { 27565 if (SOC_IS_TRIDENT3X(unit)) { 27566 SOC_IF_ERROR_RETURN 27567 (WRITE_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ALL, 27568 (i * DSCP_CODE_POINT_CNT) + srccp, &phb_tbl_2)); 27569 } else { 27570 SOC_IF_ERROR_RETURN 27571 (WRITE_DSCP_TABLEm(unit, MEM_BLOCK_ALL, 27572 (i * DSCP_CODE_POINT_CNT) + srccp, &de)); 27573 } 27574 } 27575 } 27576 } 27577 return BCM_E_NONE; 27578 } 27579 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 27580 27581 /* all other switches */ 27582 if (srccp < -1 || srccp > 0) { 27583 return BCM_E_PARAM; 27584 } 27585 27586 pcfg.pc_dse_mode = -1; 27587 BCM_IF_ERROR_RETURN 27588 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 27589 if (pcfg.pc_dse_mode == -1) { /* STRATA1 for example */ 27590 return BCM_E_UNAVAIL; 27591 } 27592 27593 if (mapcp >= 0) { 27594 pcfg.pc_dscp = mapcp; 27595 27596 BCM_IF_ERROR_RETURN 27597 (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 27598 } 27599 27600 return BCM_E_NONE; 27601 } 27602 27603 /* 27604 * Function: 27605 * bcm_port_dscp_map_set 27606 * Purpose: 27607 * Define a mapping for diffserv code points 27608 * The mapping enable/disable is controlled by a seperate API 27609 * bcm_port_dscp_map_enable_set/get 27610 * Also Enable/Disable control for DSCP mapping for tunnels 27611 * are available in the respective tunnel create APIs. 27612 * Parameters: 27613 * unit - switch device 27614 * port - switch port or -1 to setup global mapping table. 27615 * srccp - src code point or -1 27616 * mapcp - mapped code point or -1 27617 * prio - priority value for mapped code point 27618 * -1 to use port default untagged priority 27619 * BCM_PRIO_DROP_FIRST can be or'ed into the priority 27620 * Returns: 27621 * BCM_E_XXX 27622 * Notes: 27623 * On most xgs switches there are a limited set 27624 * of mappings that are possible: 27625 * srccp -1, mapcp -1: no mapping 27626 * srccp -1, mapcp 0..63: map all packets 27627 * srccp 0, mapcp 0..63: map packets with cp 0 27628 * On Firebolt/Helix/Felix, there is no per port mapping table. 27629 * Only a global mapping table is available. 27630 */ 27631 27632 int 27633 bcm_esw_port_dscp_map_set(int unit, bcm_port_t port, int srccp, int mapcp, 27634 int prio) 27635 { 27636 int rv; 27637 bcm_port_config_t port_conf; 27638 bcm_pbmp_t pbmp; 27639 27640 /* Make sure port module is initialized. */ 27641 PORT_INIT(unit); 27642 27643 if (!soc_feature(unit, soc_feature_dscp)) { 27644 return BCM_E_UNAVAIL; 27645 } 27646 27647 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 27648 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 27649 !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) { 27650 return _bcm_esw_vp_dscp_map_set(unit, port, srccp, mapcp, prio); 27651 } 27652 #endif 27653 27654 if (port != -1) { 27655 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 27656 if (!soc_feature(unit, soc_feature_dscp_map_per_port)) { 27657 return BCM_E_PORT; 27658 } 27659 } 27660 27661 PORT_LOCK(unit); 27662 27663 /* Get device port configuration. */ 27664 rv = bcm_esw_port_config_get(unit, &port_conf); 27665 if (BCM_FAILURE(rv)) { 27666 PORT_UNLOCK(unit); 27667 return rv; 27668 } 27669 BCM_PBMP_ASSIGN(pbmp, port_conf.e); 27670 if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) { 27671 BCM_PBMP_OR(pbmp, port_conf.cpu); 27672 } 27673 #ifdef BCM_KATANA2_SUPPORT 27674 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 27675 rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp); 27676 if (BCM_FAILURE(rv)) { 27677 PORT_UNLOCK(unit); 27678 return (rv); 27679 } 27680 } 27681 if (soc_feature(unit, soc_feature_linkphy_coe) || 27682 soc_feature(unit, soc_feature_subtag_coe)) { 27683 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 27684 } 27685 #endif 27686 27687 if ((port == -1) && (soc_feature(unit, soc_feature_dscp_map_per_port))) { 27688 PBMP_ITER(pbmp, port) { 27689 /* coverity[stack_use_callee] */ 27690 /* coverity[stack_use_overflow] */ 27691 rv = _bcm_port_dscp_map_set(unit, port, srccp, mapcp, prio); 27692 if (BCM_FAILURE(rv)) { 27693 PORT_UNLOCK(unit); 27694 return rv; 27695 } 27696 } 27697 } else { 27698 if (BCM_PBMP_MEMBER(pbmp, port) || (port == -1)) { 27699 rv = _bcm_port_dscp_map_set(unit, port, srccp, mapcp, prio); 27700 } else { 27701 rv = BCM_E_PORT; 27702 } 27703 } 27704 PORT_UNLOCK(unit); 27705 27706 return rv; 27707 } 27708 27709 /* 27710 * Function: 27711 * _bcm_port_dscp_map_get 27712 * Purpose: 27713 * Get a mapping for diffserv code points 27714 * Parameters: 27715 * unit - switch device 27716 * port - switch port 27717 * srccp - src code point or -1 27718 * mapcp - (OUT) pointer to returned mapped code point 27719 * prio - (OUT) Priority value for mapped code point or -1 27720 * May have BCM_PRIO_DROP_FIRST or'ed into it 27721 * Returns: 27722 * BCM_E_XXX 27723 */ 27724 27725 STATIC int 27726 _bcm_esw_port_dscp_map_get(int unit, bcm_port_t port, int srccp, int *mapcp, 27727 int *prio) 27728 { 27729 bcm_port_cfg_t pcfg; 27730 port_tab_entry_t pent; 27731 #if defined(BCM_XGS3_SWITCH_SUPPORT) 27732 int index = 0; 27733 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 27734 int rv = BCM_E_NONE; 27735 27736 if (SOC_IS_TRIDENT3X(unit)) { 27737 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, port, 27738 TRUST_DSCP_PTRf, &index)); 27739 } else if (SOC_IS_TD2_TT2(unit) || SOC_IS_KATANA2(unit)) { 27740 /* Get profile index from port table. */ 27741 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, 27742 port, &pent); 27743 if (BCM_FAILURE(rv)) { 27744 return rv; 27745 } 27746 27747 #if defined(BCM_XGS3_SWITCH_SUPPORT) 27748 index = soc_mem_field32_get(unit, PORT_TABm, &pent, TRUST_DSCP_PTRf); 27749 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 27750 } 27751 27752 if (srccp < -1 || srccp > DSCP_CODE_POINT_MAX || 27753 mapcp == NULL || prio == NULL) { 27754 return BCM_E_PARAM; 27755 } 27756 27757 #if defined(BCM_XGS3_SWITCH_SUPPORT) 27758 if (SOC_IS_XGS3_SWITCH(unit)) { 27759 int base; 27760 int cng; 27761 dscp_table_entry_t de; 27762 phb_mapping_tbl_2_entry_t phb_tbl_2; 27763 27764 /* look up in DSCP_TABLEm */ 27765 if (srccp < 0) { 27766 srccp = 0; 27767 } 27768 if (soc_feature(unit, soc_feature_dscp_map_per_port)) { 27769 base = (port * DSCP_CODE_POINT_CNT); 27770 27771 if (SOC_IS_TD2_TT2(unit) || SOC_IS_KATANA2(unit)) { 27772 base = (index * DSCP_CODE_POINT_CNT); 27773 } 27774 } else { 27775 base = 0; 27776 } 27777 27778 if (SOC_IS_TRIDENT3X(unit)) { 27779 SOC_IF_ERROR_RETURN 27780 (READ_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ANY, base + srccp, &phb_tbl_2)); 27781 *mapcp = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &phb_tbl_2, DSCPf); 27782 *prio = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &phb_tbl_2, INT_PRIf); 27783 27784 cng = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &phb_tbl_2, CNGf); 27785 } else { 27786 SOC_IF_ERROR_RETURN 27787 (READ_DSCP_TABLEm(unit, MEM_BLOCK_ANY, base + srccp, &de)); 27788 *mapcp = soc_DSCP_TABLEm_field32_get(unit, &de, DSCPf); 27789 *prio = soc_DSCP_TABLEm_field32_get(unit, &de, PRIf); 27790 27791 cng = soc_DSCP_TABLEm_field32_get(unit, &de, CNGf); 27792 } 27793 if (cng == 1) { 27794 *prio |= BCM_PRIO_RED; 27795 } else if (cng == 3) { 27796 *prio |= BCM_PRIO_YELLOW; 27797 } else if (cng != 0) { 27798 *prio |= BCM_PRIO_DROP_FIRST; 27799 } 27800 27801 return BCM_E_NONE; 27802 } 27803 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 27804 27805 /* all other switches */ 27806 27807 pcfg.pc_dse_mode = -1; 27808 BCM_IF_ERROR_RETURN 27809 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 27810 if (pcfg.pc_dse_mode == -1) { /* STRATA1 for example */ 27811 return BCM_E_UNAVAIL; 27812 } 27813 27814 /* 27815 * The mapping table is set independently of the mapping mode. 27816 * So the _get API will return the mapping table setup and not 27817 * necessarily the actual mapping that will be applied to the packet. 27818 * The mapping applied to the packet is determined by mapping mode 27819 * set using bcm_port_dscp_map_mode_set 27820 */ 27821 *mapcp = pcfg.pc_dscp; 27822 27823 *prio = -1; 27824 27825 return BCM_E_NONE; 27826 } 27827 27828 /* 27829 * Function: 27830 * bcm_port_dscp_map_get 27831 * Purpose: 27832 * Get a mapping for diffserv code points 27833 * Parameters: 27834 * unit - switch device 27835 * port - switch port 27836 * srccp - src code point or -1 27837 * mapcp - (OUT) pointer to returned mapped code point 27838 * prio - (OUT) Priority value for mapped code point or -1 27839 * May have BCM_PRIO_DROP_FIRST or'ed into it 27840 * Returns: 27841 * BCM_E_XXX 27842 */ 27843 27844 int 27845 bcm_esw_port_dscp_map_get(int unit, bcm_port_t port, int srccp, int *mapcp, 27846 int *prio) 27847 { 27848 int rv; 27849 bcm_port_config_t port_conf; 27850 bcm_pbmp_t pbmp; 27851 27852 /* Make sure port module is initialized. */ 27853 PORT_INIT(unit); 27854 27855 if (!soc_feature(unit, soc_feature_dscp)) { 27856 return BCM_E_UNAVAIL; 27857 } 27858 27859 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 27860 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 27861 !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) { 27862 return _bcm_esw_vp_dscp_map_get(unit, port, srccp, mapcp, prio); 27863 } 27864 #endif 27865 27866 if (port != -1) { 27867 if (0 == soc_feature(unit, soc_feature_dscp_map_per_port)) { 27868 return BCM_E_PORT; 27869 } 27870 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 27871 } 27872 27873 PORT_LOCK(unit); 27874 27875 /* Get device port configuration. */ 27876 rv = bcm_esw_port_config_get(unit, &port_conf); 27877 if (BCM_FAILURE(rv)) { 27878 PORT_UNLOCK(unit); 27879 return rv; 27880 } 27881 BCM_PBMP_ASSIGN(pbmp, port_conf.e); 27882 if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) { 27883 BCM_PBMP_OR(pbmp, port_conf.cpu); 27884 } 27885 #ifdef BCM_KATANA2_SUPPORT 27886 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 27887 rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp); 27888 if (BCM_FAILURE(rv)) { 27889 PORT_UNLOCK(unit); 27890 return (rv); 27891 } 27892 } 27893 if (soc_feature(unit, soc_feature_linkphy_coe) || 27894 soc_feature(unit, soc_feature_subtag_coe)) { 27895 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 27896 } 27897 #endif 27898 27899 if (port == -1) { 27900 PBMP_ITER(pbmp, port) { 27901 break; 27902 } 27903 } 27904 27905 if (SOC_PORT_VALID(unit, port) && BCM_PBMP_MEMBER(pbmp, port)) { 27906 rv = _bcm_esw_port_dscp_map_get(unit, port, srccp, mapcp, prio); 27907 } else { 27908 rv = BCM_E_PORT; 27909 } 27910 27911 PORT_UNLOCK(unit); 27912 return rv; 27913 } 27914 27915 #ifdef BCM_TRIDENT_SUPPORT 27916 STATIC int 27917 _bcm_td_egr_l3_intf_dscp_map_update(int unit, uint32 dscp_map_id, uint32 new_dscp_map_id) 27918 { 27919 char *egr_intf_tbl_ptr = NULL; /* EGR_L3_INTF dma table pointer. */ 27920 int rv; 27921 uint32 *egr_intf_entry_ptr; /* EGR_L3_INTF entry pointer. */ 27922 int ifindex; 27923 uint32 dscp_map_ptr; 27924 int tbl_size; 27925 int alloc_size; 27926 27927 if (dscp_map_id == new_dscp_map_id) { 27928 return BCM_E_NONE; 27929 } 27930 27931 /* Calculate table size. */ 27932 tbl_size = soc_mem_index_count(unit, EGR_L3_INTFm); 27933 if (!tbl_size) { 27934 return (BCM_E_NOT_FOUND); 27935 } 27936 alloc_size = sizeof(egr_l3_intf_entry_t) * tbl_size; 27937 27938 /* Allocate memory buffer. */ 27939 egr_intf_tbl_ptr = soc_cm_salloc(unit, alloc_size, "egr_l3_intf_tbl"); 27940 if (egr_intf_tbl_ptr == NULL) { 27941 return (BCM_E_MEMORY); 27942 } 27943 27944 /* Reset allocated buffer. */ 27945 sal_memset(egr_intf_tbl_ptr, 0, alloc_size); 27946 27947 /* Read table to the buffer. */ 27948 rv = soc_mem_read_range(unit, EGR_L3_INTFm, MEM_BLOCK_ANY, 27949 soc_mem_index_min(unit, EGR_L3_INTFm), 27950 soc_mem_index_max(unit, EGR_L3_INTFm), egr_intf_tbl_ptr); 27951 if (BCM_FAILURE(rv)) { 27952 goto cleanup; 27953 } 27954 for (ifindex = 0; ifindex < tbl_size; ifindex++) { 27955 egr_intf_entry_ptr = 27956 soc_mem_table_idx_to_pointer(unit, EGR_L3_INTFm, 27957 uint32 *, egr_intf_tbl_ptr, 27958 ifindex); 27959 dscp_map_ptr = soc_mem_field32_get(unit, EGR_L3_INTFm, 27960 egr_intf_entry_ptr, DSCP_MAPPING_PTRf); 27961 if (dscp_map_ptr == dscp_map_id) { 27962 27963 soc_mem_field32_set(unit, EGR_L3_INTFm, 27964 egr_intf_entry_ptr, DSCP_MAPPING_PTRf, 27965 new_dscp_map_id); 27966 } 27967 } 27968 rv = soc_mem_write_range(unit, EGR_L3_INTFm, MEM_BLOCK_ALL, 27969 soc_mem_index_min(unit, EGR_L3_INTFm), 27970 soc_mem_index_max(unit, EGR_L3_INTFm), 27971 egr_intf_tbl_ptr); 27972 if (SOC_FAILURE(rv)) { 27973 goto cleanup; 27974 } 27975 27976 _bcm_tr2_qos_id_update(unit, dscp_map_id, new_dscp_map_id); 27977 27978 cleanup: 27979 27980 if (egr_intf_tbl_ptr) { 27981 soc_cm_sfree(unit, egr_intf_tbl_ptr); 27982 } 27983 return rv; 27984 27985 } 27986 #endif 27987 27988 /* 27989 * Function: 27990 * _bcm_port_dscp_unmap_set 27991 * Purpose: 27992 * Internal implementation for bcm_port_dscp_unmap_set 27993 * Returns: 27994 * BCM_E_XXX 27995 */ 27996 STATIC int 27997 _bcm_port_dscp_unmap_set(int unit, bcm_port_t port, int internal_pri, 27998 bcm_color_t color, int pkt_dscp) 27999 { 28000 int index, port_shift = 6; 28001 egr_dscp_table_entry_t dscp_unmap; 28002 egr_zone_4_qos_mapping_table_entry_t z4_qos_unmap; 28003 #if defined(BCM_TRIDENT_SUPPORT) 28004 egr_dscp_table_entry_t egr_dscp_map_entries[64]; 28005 void *entries[1]; 28006 uint32 dscp_index = 0; 28007 uint32 new_dscp_index; 28008 int ref_count; 28009 void *entry; 28010 int port_dscp_map_set; 28011 int old_pkt_dscp; 28012 #endif 28013 if (pkt_dscp < 0 || pkt_dscp > DSCP_CODE_POINT_MAX) { 28014 return BCM_E_PARAM; 28015 } 28016 if ((internal_pri < 0) || (internal_pri > 15) || 28017 ((color != bcmColorGreen) && (color != bcmColorYellow) && 28018 (color != bcmColorRed))) { 28019 return BCM_E_PARAM; 28020 } 28021 28022 /* EGR_DSCP_TABLE table is indexed with 28023 * port[5:0] priority[3:0] CNG [1:0] 28024 */ 28025 28026 index = (port << port_shift) | (internal_pri << 2) | 28027 _BCM_COLOR_ENCODING(unit, color); 28028 28029 if (SOC_IS_TRIDENT3X(unit)) { 28030 /* This function is obselete - put in the right register for readability*/ 28031 sal_memset(&z4_qos_unmap, 0, sizeof(z4_qos_unmap)); 28032 soc_mem_field32_set(unit, EGR_ZONE_4_QOS_MAPPING_TABLEm, &z4_qos_unmap, QOSf, pkt_dscp); 28033 SOC_IF_ERROR_RETURN 28034 (WRITE_EGR_ZONE_4_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ALL, index, &z4_qos_unmap)); 28035 28036 soc_mem_field32_set(unit, EGR_ZONE_2_QOS_MAPPING_TABLEm, &z4_qos_unmap, QOSf, pkt_dscp); 28037 SOC_IF_ERROR_RETURN 28038 (WRITE_EGR_ZONE_2_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ALL, index, &z4_qos_unmap)); 28039 } else 28040 #ifdef BCM_TRIDENT_SUPPORT 28041 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_SELf)) { 28042 dscp_index = port << port_shift; 28043 index = (internal_pri << 2) | _BCM_COLOR_ENCODING(unit, color); 28044 28045 sal_memset(egr_dscp_map_entries, 0, sizeof(egr_dscp_map_entries)); 28046 entries[0] = &egr_dscp_map_entries; 28047 28048 entry = &egr_dscp_map_entries[index]; 28049 BCM_IF_ERROR_RETURN( 28050 _bcm_egr_dscp_table_entry_ref_count_get(unit, dscp_index, &ref_count)); 28051 port_dscp_map_set = PORT(unit, port).port_dscp_map_set; 28052 if (ref_count > 0) { 28053 BCM_IF_ERROR_RETURN( 28054 _bcm_egr_dscp_table_entry_get(unit, dscp_index, 28055 _BCM_QOS_MAP_CHUNK_EGR_DSCP, entries)); 28056 old_pkt_dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm, entry, DSCPf); 28057 if (pkt_dscp != old_pkt_dscp) { 28058 int i; 28059 int port_dscp_map_count = port_dscp_map_set; 28060 /* If this profile is only used by port */ 28061 if ((ref_count == 1) && (port_dscp_map_set == 1)) { 28062 soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, pkt_dscp); 28063 BCM_IF_ERROR_RETURN( 28064 _bcm_egr_dscp_table_entry_set(unit, entries, dscp_index)); 28065 BCM_IF_ERROR_RETURN( 28066 _bcm_egr_dscp_table_entry_delete(unit, dscp_index)); 28067 } else { /* If this profile is used not only by port */ 28068 soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, 28069 old_pkt_dscp); 28070 BCM_IF_ERROR_RETURN( 28071 _bcm_egr_dscp_table_entry_add(unit, entries, 28072 _BCM_QOS_MAP_CHUNK_EGR_DSCP, 28073 &new_dscp_index, 28074 SOC_PROFILE_MEM_F_NO_SHARE)); 28075 for (i = 0; i < (ref_count - port_dscp_map_count - 1); i++) { 28076 BCM_IF_ERROR_RETURN( 28077 _bcm_egr_dscp_table_entry_reference(unit, new_dscp_index, 28078 _BCM_QOS_MAP_CHUNK_EGR_DSCP)); 28079 } 28080 BCM_IF_ERROR_RETURN( 28081 _bcm_td_egr_l3_intf_dscp_map_update(unit, port, 28082 (new_dscp_index >> port_shift))); 28083 soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, pkt_dscp); 28084 BCM_IF_ERROR_RETURN( 28085 _bcm_egr_dscp_table_entry_set(unit, entries, dscp_index)); 28086 for (i = 0; i < ref_count; i++) { 28087 BCM_IF_ERROR_RETURN( 28088 _bcm_egr_dscp_table_entry_delete(unit, dscp_index)); 28089 } 28090 } 28091 } 28092 } else { 28093 soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, pkt_dscp); 28094 _bcm_common_profile_mem_ref_cnt_update(unit, EGR_DSCP_TABLEm, port, 1); 28095 BCM_IF_ERROR_RETURN( 28096 _bcm_egr_dscp_table_entry_set(unit, entries, dscp_index)); 28097 BCM_IF_ERROR_RETURN( 28098 _bcm_egr_dscp_table_entry_delete(unit, dscp_index)); 28099 } 28100 PORT(unit, port).port_dscp_map_set = 1; 28101 28102 } else 28103 #endif 28104 { 28105 sal_memset(&dscp_unmap, 0, sizeof(dscp_unmap)); 28106 soc_mem_field32_set(unit, EGR_DSCP_TABLEm, &dscp_unmap, DSCPf, pkt_dscp); 28107 SOC_IF_ERROR_RETURN 28108 (WRITE_EGR_DSCP_TABLEm(unit, MEM_BLOCK_ALL, index, &dscp_unmap)); 28109 } 28110 return BCM_E_NONE; 28111 } 28112 28113 /* 28114 * Function: 28115 * bcm_port_dscp_unmap_set 28116 * Purpose: 28117 * Define a mapping for diffserv code points 28118 * The mapping enable/disable is controlled by a seperate API 28119 * bcm_port_dscp_map_enable_set/get 28120 * Also Enable/Disable control for DSCP mapping for tunnels 28121 * are available in the respective tunnel create APIs. 28122 * Parameters: 28123 * unit - switch device 28124 * port - switch port or -1 to setup global mapping table. 28125 * internal_pri - internal priority 28126 * color - Red/Yellow/Green 28127 * pkt_dscp - DSCP marking on outgoing packet 28128 * Returns: 28129 * BCM_E_XXX 28130 */ 28131 int 28132 bcm_esw_port_dscp_unmap_set(int unit, bcm_port_t port, int internal_pri, 28133 bcm_color_t color, int pkt_dscp) 28134 { 28135 int rv; 28136 bcm_port_config_t port_conf; 28137 bcm_pbmp_t pbmp; 28138 28139 /* Make sure port module is initialized. */ 28140 PORT_INIT(unit); 28141 if (!soc_feature(unit, soc_feature_dscp) || 28142 !soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 28143 return BCM_E_UNAVAIL; 28144 } 28145 28146 if (port != -1) { 28147 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 28148 if (IS_HG_PORT(unit, port) || IS_ST_PORT(unit, port)) { 28149 return BCM_E_PORT; 28150 } 28151 } 28152 28153 PORT_LOCK(unit); 28154 28155 /* Get device port configuration. */ 28156 rv = bcm_esw_port_config_get(unit, &port_conf); 28157 if (BCM_FAILURE(rv)) { 28158 PORT_UNLOCK(unit); 28159 return rv; 28160 } 28161 BCM_PBMP_ASSIGN(pbmp, port_conf.e); 28162 BCM_PBMP_OR(pbmp, port_conf.cpu); 28163 #ifdef BCM_KATANA2_SUPPORT 28164 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 28165 rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp); 28166 if (BCM_FAILURE(rv)) { 28167 PORT_UNLOCK(unit); 28168 return (rv); 28169 } 28170 } 28171 if (soc_feature(unit, soc_feature_linkphy_coe) || 28172 soc_feature(unit, soc_feature_subtag_coe)) { 28173 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 28174 } 28175 #endif 28176 28177 if (port == -1) { 28178 PBMP_ITER(pbmp, port) { 28179 rv = _bcm_port_dscp_unmap_set(unit, port, internal_pri, color, 28180 pkt_dscp); 28181 if (BCM_FAILURE(rv)) { 28182 PORT_UNLOCK(unit); 28183 return rv; 28184 } 28185 } 28186 } else if (SOC_PORT_VALID(unit, port) && BCM_PBMP_MEMBER(pbmp, port)) { 28187 rv = _bcm_port_dscp_unmap_set(unit, port, internal_pri, color, 28188 pkt_dscp); 28189 } else { 28190 rv = BCM_E_PORT; 28191 } 28192 PORT_UNLOCK(unit); 28193 28194 return rv; 28195 } 28196 28197 /* 28198 * Function: 28199 * _bcm_port_dscp_unmap_get 28200 * Purpose: 28201 * Internal implementation for bcm_port_dscp_unmap_get 28202 * Returns: 28203 * BCM_E_XXX 28204 */ 28205 STATIC int 28206 _bcm_port_dscp_unmap_get(int unit, bcm_port_t port, int internal_pri, 28207 bcm_color_t color, int *pkt_dscp) 28208 { 28209 int index, port_shift = 6; 28210 egr_dscp_table_entry_t dscp_unmap; 28211 #if defined(BCM_TRIDENT_SUPPORT) 28212 egr_dscp_table_entry_t egr_dscp_map_entries[64]; 28213 void *entries[1]; 28214 uint32 dscp_index = 0; 28215 void *entry; 28216 #endif 28217 if ((internal_pri < 0) || (internal_pri > 15) || 28218 ((color != bcmColorGreen) && (color != bcmColorYellow) && 28219 (color != bcmColorRed))) { 28220 return BCM_E_PARAM; 28221 } 28222 28223 /* EGR_DSCP_TABLE table is indexed with 28224 * port[5:0] priority[3:0] CNG [1:0] 28225 */ 28226 index = (port << port_shift) | (internal_pri << 2) | 28227 _BCM_COLOR_ENCODING(unit, color); 28228 28229 if (SOC_IS_TRIDENT3X(unit)) { 28230 SOC_IF_ERROR_RETURN 28231 (READ_EGR_ZONE_4_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ANY, index, &dscp_unmap)); 28232 *pkt_dscp = soc_mem_field32_get(unit, EGR_ZONE_4_QOS_MAPPING_TABLEm, 28233 &dscp_unmap, QOSf); 28234 28235 SOC_IF_ERROR_RETURN 28236 (READ_EGR_ZONE_2_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ANY, index, &dscp_unmap)); 28237 *pkt_dscp = soc_mem_field32_get(unit, EGR_ZONE_2_QOS_MAPPING_TABLEm, 28238 &dscp_unmap, QOSf); 28239 } else 28240 #if defined(BCM_TRIDENT_SUPPORT) 28241 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_SELf)) { 28242 dscp_index = port << port_shift; 28243 index = (internal_pri << 2) | _BCM_COLOR_ENCODING(unit, color); 28244 28245 sal_memset(egr_dscp_map_entries, 0, sizeof(egr_dscp_map_entries)); 28246 entries[0] = &egr_dscp_map_entries; 28247 28248 BCM_IF_ERROR_RETURN( 28249 _bcm_egr_dscp_table_entry_get(unit, dscp_index, 28250 _BCM_QOS_MAP_CHUNK_EGR_DSCP, entries)); 28251 entry = &egr_dscp_map_entries[index]; 28252 *pkt_dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm, 28253 entry, DSCPf); 28254 } else 28255 #endif 28256 { 28257 SOC_IF_ERROR_RETURN 28258 (READ_EGR_DSCP_TABLEm(unit, MEM_BLOCK_ANY, index, &dscp_unmap)); 28259 *pkt_dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm, 28260 &dscp_unmap, DSCPf); 28261 } 28262 return BCM_E_NONE; 28263 } 28264 28265 /* 28266 * Function: 28267 * bcm_port_dscp_unmap_get 28268 * Purpose: 28269 * Retrieve a mapping for diffserv code points 28270 * The mapping enable/disable is controlled by a seperate API 28271 * bcm_port_dscp_map_enable_set/get 28272 * Also Enable/Disable control for DSCP mapping for tunnels 28273 * are available in the respective tunnel create APIs. 28274 * Parameters: 28275 * unit - switch device 28276 * port - switch port. 28277 * internal_pri - internal priority 28278 * color - Red/Yellow/Green 28279 * pkt_dscp - DSCP marking on outgoing packet 28280 * Returns: 28281 * BCM_E_XXX 28282 */ 28283 int 28284 bcm_esw_port_dscp_unmap_get(int unit, bcm_port_t port, int internal_pri, 28285 bcm_color_t color, int *pkt_dscp) 28286 { 28287 int rv; 28288 bcm_port_config_t port_conf; 28289 bcm_pbmp_t pbmp; 28290 28291 /* Make sure port module is initialized. */ 28292 PORT_INIT(unit); 28293 if (!soc_feature(unit, soc_feature_dscp) || 28294 !soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 28295 return BCM_E_UNAVAIL; 28296 } 28297 28298 if (port != -1) { 28299 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 28300 if (IS_HG_PORT(unit, port) || IS_ST_PORT(unit, port)) { 28301 return BCM_E_PORT; 28302 } 28303 } 28304 28305 PORT_LOCK(unit); 28306 28307 /* Get device port configuration. */ 28308 rv = bcm_esw_port_config_get(unit, &port_conf); 28309 if (BCM_FAILURE(rv)) { 28310 PORT_UNLOCK(unit); 28311 return rv; 28312 } 28313 BCM_PBMP_ASSIGN(pbmp, port_conf.e); 28314 BCM_PBMP_OR(pbmp, port_conf.cpu); 28315 #ifdef BCM_KATANA2_SUPPORT 28316 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 28317 rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp); 28318 if (BCM_FAILURE(rv)) { 28319 PORT_UNLOCK(unit); 28320 return (rv); 28321 } 28322 } 28323 if (soc_feature(unit, soc_feature_linkphy_coe) || 28324 soc_feature(unit, soc_feature_subtag_coe)) { 28325 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 28326 } 28327 #endif 28328 28329 if (port == -1) { 28330 PBMP_ITER(pbmp, port) { 28331 break; 28332 } 28333 } 28334 28335 if (SOC_PORT_VALID(unit, port) && BCM_PBMP_MEMBER(pbmp, port)) { 28336 rv = _bcm_port_dscp_unmap_get(unit, port, internal_pri, color, 28337 pkt_dscp); 28338 } else { 28339 rv = BCM_E_PORT; 28340 } 28341 28342 PORT_UNLOCK(unit); 28343 return rv; 28344 } 28345 28346 #undef DSCP_CODE_POINT_MAX 28347 #undef DSCP_CODE_POINT_CNT 28348 28349 STATIC int 28350 _bcm_esw_port_modid_egress_resolve(int unit, _bcm_port_egr_dest_t *egr_dst) 28351 { 28352 int port_adjst = 0, mod_adjust = 0; 28353 int isLocal = 0; 28354 bcm_module_t my_mod, modid; 28355 28356 if (BCM_GPORT_IS_SET(egr_dst->in_port)) { 28357 bcm_trunk_t tid; 28358 int id; 28359 bcm_port_t port; 28360 28361 BCM_IF_ERROR_RETURN( 28362 _bcm_esw_gport_resolve(unit, egr_dst->in_port, &modid, &port, 28363 &tid, &id)); 28364 if ((-1 != id) || (-1 != tid)) { 28365 return BCM_E_PORT; 28366 } 28367 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_mod)); 28368 BCM_IF_ERROR_RETURN( 28369 _bcm_esw_modid_is_local(unit, modid, &isLocal)); 28370 28371 if ((TRUE == isLocal) && (modid != my_mod)){ 28372 port_adjst = 32; 28373 mod_adjust = 1; 28374 } 28375 egr_dst->out_min_port = egr_dst->out_max_port = port + port_adjst; 28376 egr_dst->out_min_modid = egr_dst->out_max_modid = modid - mod_adjust; 28377 } else { 28378 if (egr_dst->in_modid < 0) { 28379 egr_dst->out_min_modid = 0; 28380 egr_dst->out_max_modid = SOC_MODID_MAX(unit); 28381 } else if (!SOC_MODID_ADDRESSABLE(unit, egr_dst->in_modid)) { 28382 return BCM_E_PARAM; 28383 } else { 28384 egr_dst->out_min_modid = egr_dst->out_max_modid = egr_dst->in_modid; 28385 } 28386 28387 if (egr_dst->in_port < 0) { 28388 egr_dst->out_min_port = 0; 28389 egr_dst->out_max_port = SOC_PORT_MAX(unit, all); 28390 } else if (!SOC_PORT_ADDRESSABLE(unit, egr_dst->in_port)) { 28391 return BCM_E_PORT; 28392 } else { 28393 egr_dst->out_min_port = egr_dst->out_max_port = egr_dst->in_port; 28394 } 28395 } 28396 28397 return BCM_E_NONE; 28398 } 28399 28400 28401 /* 28402 * Function: 28403 * bcm_port_egress_set 28404 * Description: 28405 * Set switching only to indicated ports from given (modid, port). 28406 * Parameters: 28407 * unit - StrataSwitch PCI device unit number (driver internal). 28408 * port - ingress port number. 28409 * modid - source module ID index (in HiGig mod header). 28410 * pbmp - bitmap of ports to allow egress. 28411 * Returns: 28412 * BCM_E_xxxx 28413 * Note: 28414 * if port < 0, means all/any port 28415 * if modid < 0, means all/any modid 28416 */ 28417 int 28418 bcm_esw_port_egress_set(int unit, bcm_port_t port, int modid, bcm_pbmp_t pbmp) 28419 { 28420 egr_mask_entry_t em_entry; 28421 int em_index; 28422 bcm_module_t cur_mod, hw_mod; 28423 bcm_pbmp_t em_pbmp; 28424 bcm_port_t cur_port, hw_port; 28425 int rv = BCM_E_NONE; 28426 _bcm_port_egr_dest_t egr_dst; 28427 int mod_is_local = 0; 28428 int mod_port_map_done = 0; 28429 28430 /* Make sure port module is initialized. */ 28431 PORT_INIT(unit); 28432 28433 if(bcm_common_oamp_port_enable_get(unit, port)) { 28434 LOG_ERROR(BSL_LS_BCM_PORT, 28435 (BSL_META("Error: Not permitted on OAMP port %d.n"), 28436 port)); 28437 return BCM_E_PARAM; 28438 } 28439 28440 #ifdef BCM_TRIDENT_SUPPORT 28441 if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 28442 return bcm_td_port_egress_set(unit, port, modid, pbmp); 28443 } 28444 #endif /* BCM_TRIDENT_SUPPORT */ 28445 28446 #ifdef BCM_HURRICANE3_SUPPORT 28447 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 28448 return bcm_hr3_port_egress_set(unit, port, modid, pbmp); 28449 } 28450 #endif /* BCM_HURRICANE3_SUPPORT */ 28451 28452 if (!SOC_IS_XGS_SWITCH(unit)) { 28453 if (BCM_PBMP_EQ(pbmp, PBMP_ALL(unit))) { 28454 return BCM_E_NONE; 28455 } else { 28456 return BCM_E_UNAVAIL; 28457 } 28458 } 28459 28460 sal_memset(&em_entry, 0, sizeof(egr_mask_entry_t)); 28461 28462 BCM_PBMP_NEGATE(em_pbmp, pbmp); 28463 BCM_PBMP_AND(em_pbmp, PBMP_ALL(unit)); 28464 BCM_PBMP_REMOVE(em_pbmp, PBMP_LB(unit)); 28465 soc_mem_pbmp_field_set(unit, EGR_MASKm, &em_entry, EGRESS_MASKf, 28466 &em_pbmp); 28467 28468 egr_dst.in_modid = modid; 28469 egr_dst.in_port = port; 28470 BCM_IF_ERROR_RETURN(_bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28471 /* If the given port is a gport, _bcm_esw_port_modid_egress_resolve had 28472 * already performed module and port mapping for devices with 28473 * multiple module IDs. 28474 */ 28475 mod_port_map_done = BCM_GPORT_IS_SET(port) ? 1 : 0; 28476 28477 soc_mem_lock(unit, EGR_MASKm); 28478 for (cur_mod = egr_dst.out_min_modid; cur_mod <= egr_dst.out_max_modid; cur_mod++) { 28479 rv = _bcm_esw_modid_is_local(unit, cur_mod, &mod_is_local); 28480 if (BCM_FAILURE(rv)) { 28481 break; 28482 } 28483 for (cur_port = egr_dst.out_min_port; cur_port <= egr_dst.out_max_port; cur_port++) { 28484 if (mod_is_local && (NUM_MODID(unit) > 1) && !mod_port_map_done) { 28485 if (cur_port <= SOC_MODPORT_MAX(unit)) { 28486 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET, 28487 cur_mod, cur_port, &hw_mod, &hw_port); 28488 if (BCM_FAILURE(rv)) { 28489 break; 28490 } 28491 } else { 28492 break; 28493 } 28494 } else { 28495 hw_mod = cur_mod; 28496 hw_port = cur_port; 28497 } 28498 28499 em_index = (hw_mod & SOC_MODID_MAX(unit)) * 28500 (SOC_PORT_ADDR_MAX(unit) + 1) | 28501 (hw_port & SOC_PORT_ADDR_MAX(unit)); 28502 rv = soc_mem_write(unit, EGR_MASKm, MEM_BLOCK_ALL, 28503 em_index, &em_entry); 28504 if (!BCM_SUCCESS(rv)) { 28505 break; 28506 } 28507 } 28508 if (!BCM_SUCCESS(rv)) { 28509 break; 28510 } 28511 } 28512 soc_mem_unlock(unit, EGR_MASKm); 28513 28514 return rv; 28515 } 28516 28517 /* 28518 * Function: 28519 * bcm_port_egress_get 28520 * Description: 28521 * Retrieve bitmap of ports for which switching is enabled 28522 * for (modid, port). 28523 * Parameters: 28524 * unit - StrataSwitch PCI device unit number (driver internal). 28525 * port - ingress port number. 28526 * modid - source module ID index (in HiGig mod header). 28527 * pbmp - (OUT) bitmap of ports where egress allowed. 28528 * Returns: 28529 * BCM_E_xxxx 28530 */ 28531 int 28532 bcm_esw_port_egress_get(int unit, bcm_port_t port, int modid, bcm_pbmp_t *pbmp) 28533 { 28534 egr_mask_entry_t em_entry; 28535 int em_index; 28536 bcm_pbmp_t em_pbmp, temp_pbmp; 28537 _bcm_port_egr_dest_t egr_dst; 28538 int mod_port_map_done = 0; 28539 bcm_module_t hw_mod; 28540 bcm_port_t hw_port; 28541 28542 /* Make sure port module is initialized. */ 28543 PORT_INIT(unit); 28544 28545 if(bcm_common_oamp_port_enable_get(unit, port)) { 28546 LOG_ERROR(BSL_LS_BCM_PORT, 28547 (BSL_META("Error: Not permitted on OAMP port %d.n"), 28548 port)); 28549 return BCM_E_PARAM; 28550 } 28551 28552 #ifdef BCM_TRIDENT_SUPPORT 28553 if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 28554 return bcm_td_port_egress_get(unit, port, modid, pbmp); 28555 } 28556 #endif /* BCM_TRIDENT_SUPPORT */ 28557 28558 #ifdef BCM_HURRICANE3_SUPPORT 28559 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 28560 return bcm_hr3_port_egress_get(unit, port, modid, pbmp); 28561 } 28562 #endif /* BCM_HURRICANE3_SUPPORT */ 28563 28564 if (!SOC_IS_XGS_SWITCH(unit)) { 28565 BCM_PBMP_ASSIGN(*pbmp, PBMP_ALL(unit)); 28566 return BCM_E_NONE; 28567 } 28568 28569 if ((modid < 0) || (port < 0) ){ 28570 return BCM_E_PARAM; 28571 } 28572 28573 egr_dst.in_modid = modid; 28574 egr_dst.in_port = port; 28575 BCM_IF_ERROR_RETURN(_bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28576 /* If the given port is a gport, _bcm_esw_port_modid_egress_resolve had 28577 * already performed module and port mapping for devices with 28578 * multiple module IDs. 28579 */ 28580 mod_port_map_done = BCM_GPORT_IS_SET(port) ? 1 : 0; 28581 28582 if (!mod_port_map_done) { 28583 PORT_DUALMODID_VALID(unit, egr_dst.out_min_port); 28584 BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET, 28585 egr_dst.out_min_modid, egr_dst.out_min_port, 28586 &hw_mod, &hw_port)); 28587 } else { 28588 hw_mod = egr_dst.out_min_modid; 28589 hw_port = egr_dst.out_min_port; 28590 } 28591 em_index = (hw_mod & SOC_MODID_MAX(unit)) * 28592 (SOC_PORT_ADDR_MAX(unit) + 1) | (hw_port & SOC_PORT_ADDR_MAX(unit)); 28593 28594 BCM_IF_ERROR_RETURN 28595 (READ_EGR_MASKm(unit, MEM_BLOCK_ALL, em_index, &em_entry)); 28596 28597 BCM_PBMP_CLEAR(em_pbmp); 28598 soc_mem_pbmp_field_get(unit, EGR_MASKm, &em_entry, EGRESS_MASKf, 28599 &em_pbmp); 28600 BCM_PBMP_NEGATE(temp_pbmp, em_pbmp); 28601 BCM_PBMP_AND(temp_pbmp, PBMP_ALL(unit)); 28602 BCM_PBMP_REMOVE(temp_pbmp, PBMP_LB(unit)); 28603 BCM_PBMP_ASSIGN(*pbmp, temp_pbmp); 28604 28605 return BCM_E_NONE; 28606 } 28607 28608 #ifdef BCM_TRIUMPH2_SUPPORT 28609 STATIC int 28610 _bcm_port_src_mod_egress_profile_add(int unit, bcm_port_t port, 28611 int min_mod, int max_mod, pbmp_t pbmp) 28612 { 28613 int i, region, modid_cnt, new_region, empty_profile, alloc_size; 28614 int rv = BCM_E_NONE; 28615 uint32 val, add_index; 28616 src_modid_egress_entry_t *srcmodegr_p, *sme_buf; 28617 pbmp_t test_pbmp; 28618 void *entries[1]; /* for profile memories */ 28619 28620 modid_cnt = SOC_MODID_MAX(unit) + 1; 28621 region = PORT_SRC_MOD_EGR_PROF_PTR(unit, port); 28622 empty_profile = TRUE; 28623 new_region = -1; 28624 28625 alloc_size = modid_cnt * sizeof(*srcmodegr_p); 28626 sme_buf = sal_alloc(alloc_size, "SRC_MODID_EGRESS update buffer"); 28627 if (NULL == sme_buf) { 28628 return BCM_E_MEMORY; 28629 } 28630 sal_memset(sme_buf, 0, alloc_size); 28631 entries[0] = sme_buf; 28632 28633 if (0 <= region) { 28634 rv = soc_profile_mem_get(unit, PORT_SRC_MOD_EGR_PROFILE(unit), 28635 region * modid_cnt, modid_cnt, entries); 28636 } /* Else cleared by memset above. Null entry is all 0's */ 28637 28638 if (BCM_SUCCESS(rv)) { 28639 for (i = min_mod; i <= max_mod; i++) { 28640 /* Profile memory is an array of entries, not a DMA buffer */ 28641 srcmodegr_p = sme_buf + i; /* Both same pointer type */ 28642 soc_mem_pbmp_field_set(unit, SRC_MODID_EGRESSm, srcmodegr_p, 28643 PORT_BLOCK_MASK_BITMAPf, &pbmp); 28644 } 28645 28646 if (BCM_PBMP_IS_NULL(pbmp)) { 28647 /* Check for empty bitmap */ 28648 for (i = 0; i < modid_cnt; i++) { 28649 srcmodegr_p = sme_buf + i; /* Both same pointer type */ 28650 soc_mem_pbmp_field_get(unit, SRC_MODID_EGRESSm, srcmodegr_p, 28651 PORT_BLOCK_MASK_BITMAPf, &test_pbmp); 28652 if (BCM_PBMP_NOT_NULL(test_pbmp)) { 28653 empty_profile = FALSE; 28654 break; 28655 } 28656 } 28657 } else { 28658 empty_profile = FALSE; 28659 } 28660 28661 if (!empty_profile) { 28662 rv = soc_profile_mem_add(unit, PORT_SRC_MOD_EGR_PROFILE(unit), 28663 entries, modid_cnt, &add_index); 28664 if (BCM_SUCCESS(rv)) { 28665 new_region = add_index / modid_cnt; 28666 } 28667 } 28668 } 28669 28670 sal_free(sme_buf); 28671 BCM_IF_ERROR_RETURN(rv); 28672 28673 BCM_IF_ERROR_RETURN(READ_SRC_MODID_EGRESS_SELr(unit, port, &val)); 28674 if (empty_profile) { 28675 soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val, ENABLEf, 0); 28676 soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val, 28677 SRCMOD_INDEXf, 0); 28678 } else { 28679 soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val, ENABLEf, 1); 28680 soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val, 28681 SRCMOD_INDEXf, new_region); 28682 } 28683 BCM_IF_ERROR_RETURN(WRITE_SRC_MODID_EGRESS_SELr(unit, port, val)); 28684 28685 if (-1 != region) { 28686 BCM_IF_ERROR_RETURN 28687 (soc_profile_mem_delete(unit, PORT_SRC_MOD_EGR_PROFILE(unit), 28688 region * modid_cnt)); 28689 } 28690 28691 PORT_SRC_MOD_EGR_PROF_PTR(unit, port) = new_region; 28692 return BCM_E_NONE; 28693 } 28694 #endif 28695 28696 /* 28697 * Function: 28698 * bcm_port_modid_egress_set 28699 * Description: 28700 * Set port bitmap of egress ports on which the incoming packets 28701 * will be forwarded. 28702 * Parameters: 28703 * unit - StrataSwitch PCI device unit number (driver internal). 28704 * port - ingress port number. 28705 * modid - source module ID index (in HiGig mod header). 28706 * pbmp - bitmap of ports to allow egress. 28707 * Returns: 28708 * BCM_E_xxxx 28709 * Note: 28710 * if port < 0, means all/any port 28711 * if modid < 0, means all/any modid 28712 */ 28713 int 28714 bcm_esw_port_modid_egress_set(int unit, bcm_port_t port, 28715 bcm_module_t modid, bcm_pbmp_t pbmp) 28716 { 28717 #if defined(BCM_HERCULES15_SUPPORT) || defined(BCM_FIREBOLT_SUPPORT) 28718 int rv=BCM_E_UNAVAIL; 28719 28720 /* Make sure port module is initialized. */ 28721 PORT_INIT(unit); 28722 28723 #ifdef BCM_HERCULES15_SUPPORT 28724 if (SOC_IS_HERCULES15(unit)) { 28725 mem_ing_srcmodblk_entry_t srcmod; 28726 uint32 smf; 28727 bcm_module_t mod_idx, min_mod, max_mod; 28728 bcm_pbmp_t mod_pbmp; 28729 int bk=-1, blk; 28730 28731 if (port >= 0) { 28732 if (!SOC_PORT_VALID(unit, port) || !IS_HG_PORT(unit, port)) { 28733 return BCM_E_PORT; 28734 } 28735 bk = SOC_PORT_BLOCK(unit, port); 28736 } 28737 28738 if (modid < 0) { 28739 min_mod = soc_mem_index_min(unit, MEM_ING_SRCMODBLKm); 28740 max_mod = soc_mem_index_max(unit, MEM_ING_SRCMODBLKm); 28741 } else if (modid > soc_mem_index_max(unit, MEM_ING_SRCMODBLKm)) { 28742 return BCM_E_PARAM; 28743 } else { 28744 min_mod = max_mod = modid; 28745 } 28746 28747 BCM_PBMP_ASSIGN(mod_pbmp, pbmp); 28748 BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit)); 28749 if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) { 28750 return BCM_E_PARAM; 28751 } 28752 28753 soc_mem_lock(unit, MEM_ING_SRCMODBLKm); 28754 SOC_MEM_BLOCK_ITER(unit, MEM_ING_SRCMODBLKm, blk) { 28755 if ((port >= 0) && (bk !=blk)) { 28756 continue; 28757 } 28758 for (mod_idx = min_mod; mod_idx <= max_mod; mod_idx++) { 28759 sal_memset(&srcmod, 0, sizeof(srcmod)); 28760 rv = READ_MEM_ING_SRCMODBLKm(unit, blk, mod_idx, &srcmod); 28761 if (rv >= 0) { 28762 SOC_PBMP_WORD_SET(mod_pbmp, 0, 28763 soc_MEM_ING_SRCMODBLKm_field32_get(unit, &srcmod, BITMAPf)); 28764 if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) { 28765 smf = SOC_PBMP_WORD_GET(pbmp, 0); 28766 soc_MEM_ING_SRCMODBLKm_field_set(unit, &srcmod, BITMAPf, &smf); 28767 rv = WRITE_MEM_ING_SRCMODBLKm(unit, blk, mod_idx, &srcmod); 28768 } 28769 } 28770 } 28771 } 28772 soc_mem_unlock(unit, MEM_ING_SRCMODBLKm); 28773 } 28774 #endif /* BCM_HERCULES15_SUPPORT */ 28775 28776 #ifdef BCM_TRIUMPH2_SUPPORT 28777 if (soc_feature(unit, soc_feature_src_modid_blk_profile)) { 28778 src_modid_ingress_block_entry_t srcmoding; 28779 _bcm_port_egr_dest_t egr_dst; 28780 int all_st_ports; 28781 int i; 28782 bcm_port_t p; 28783 pbmp_t mod_pbmp, all_pbmp; 28784 28785 if ((port != -1) && (!SOC_PORT_VALID(unit, port))) { 28786 return BCM_E_PORT; 28787 } 28788 egr_dst.in_port = port; 28789 egr_dst.in_modid = modid; 28790 BCM_IF_ERROR_RETURN( 28791 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28792 28793 if (egr_dst.out_min_port == egr_dst.out_max_port) { 28794 all_st_ports = 0; 28795 } else { 28796 all_st_ports = 1; 28797 } 28798 28799 SOC_PBMP_CLEAR(all_pbmp); 28800 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 28801 28802 #ifdef BCM_KATANA2_SUPPORT 28803 if (soc_feature(unit, soc_feature_linkphy_coe) || 28804 soc_feature(unit, soc_feature_subtag_coe)) { 28805 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 28806 } 28807 #endif 28808 /* First program the ingress blocking */ 28809 soc_mem_lock(unit, SRC_MODID_INGRESS_BLOCKm); 28810 for (i = egr_dst.out_min_modid; i <= egr_dst.out_max_modid; i++) { 28811 rv = READ_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ANY, i, 28812 &srcmoding); 28813 if (BCM_FAILURE(rv)) { 28814 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm); 28815 return rv; 28816 } 28817 if (!all_st_ports) { 28818 soc_mem_pbmp_field_get(unit, SRC_MODID_INGRESS_BLOCKm, 28819 &srcmoding, PORT_BITMAPf, &mod_pbmp); 28820 BCM_PBMP_PORT_REMOVE(mod_pbmp, egr_dst.out_min_port); 28821 } else { 28822 BCM_PBMP_ASSIGN(mod_pbmp, all_pbmp); 28823 BCM_PBMP_OR(mod_pbmp, PBMP_LB(unit)); 28824 PBMP_ST_ITER(unit, p) { 28825 BCM_PBMP_PORT_REMOVE(mod_pbmp, p); 28826 } 28827 } 28828 soc_mem_pbmp_field_set(unit, SRC_MODID_INGRESS_BLOCKm, 28829 &srcmoding, PORT_BITMAPf, &mod_pbmp); 28830 rv = WRITE_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ALL, i, 28831 &srcmoding); 28832 if (BCM_FAILURE(rv)) { 28833 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm); 28834 return rv; 28835 } 28836 } 28837 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm); 28838 28839 /* Deal with the egress blocking - use one of 8 profiles */ 28840 BCM_PBMP_ASSIGN(mod_pbmp, pbmp); 28841 BCM_PBMP_AND(mod_pbmp, all_pbmp); 28842 BCM_PBMP_REMOVE(mod_pbmp, PBMP_LB(unit)); 28843 if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) { 28844 return BCM_E_PARAM; 28845 } 28846 28847 BCM_PBMP_NEGATE(mod_pbmp, pbmp); 28848 BCM_PBMP_AND(mod_pbmp, all_pbmp); 28849 BCM_PBMP_REMOVE(mod_pbmp, PBMP_LB(unit)); 28850 28851 soc_mem_lock(unit, SRC_MODID_EGRESSm); 28852 if (!all_st_ports) { 28853 /* Deal with a single stack port and its profile */ 28854 /* coverity[overrun-call : FALSE] */ 28855 rv = _bcm_port_src_mod_egress_profile_add(unit, 28856 egr_dst.out_min_port, 28857 egr_dst.out_min_modid, 28858 egr_dst.out_max_modid, 28859 mod_pbmp); 28860 if (BCM_FAILURE(rv)) { 28861 soc_mem_unlock(unit, SRC_MODID_EGRESSm); 28862 return rv; 28863 } 28864 } else { 28865 /* Deal with all stack ports and their profiles */ 28866 PBMP_ST_ITER(unit, p) { 28867 /* coverity[overrun-local : FALSE] */ 28868 rv = _bcm_port_src_mod_egress_profile_add(unit, p, 28869 egr_dst.out_min_modid, 28870 egr_dst.out_max_modid, 28871 mod_pbmp); 28872 if (BCM_FAILURE(rv)) { 28873 soc_mem_unlock(unit, SRC_MODID_EGRESSm); 28874 return rv; 28875 } 28876 } 28877 } 28878 soc_mem_unlock(unit, SRC_MODID_EGRESSm); 28879 28880 return rv; 28881 } 28882 #endif 28883 28884 #ifdef BCM_TRX_SUPPORT 28885 if (SOC_IS_TRX(unit)) { 28886 src_modid_block_entry_t srcmod; 28887 int modid_cnt, idx, i, j; 28888 bcm_pbmp_t mod_pbmp; 28889 _bcm_port_egr_dest_t egr_dst; 28890 28891 /* Number of supported MODIDs for this unit */ 28892 modid_cnt = SOC_MODID_MAX(unit) + 1; 28893 28894 egr_dst.in_port = port; 28895 egr_dst.in_modid = modid; 28896 BCM_IF_ERROR_RETURN( 28897 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28898 28899 if (egr_dst.out_min_port == egr_dst.out_max_port) { 28900 /* process to retrieve hg_port index from port */ 28901 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 28902 SOC_IS_GREYHOUND2(unit)) { 28903 egr_dst.out_min_port = egr_dst.out_max_port; 28904 } else { 28905 SOC_IF_ERROR_RETURN( 28906 soc_xgs3_port_num_to_higig_port_num(unit, 28907 egr_dst.out_max_port, &egr_dst.out_min_port)); 28908 } 28909 28910 egr_dst.out_max_port = egr_dst.out_min_port; 28911 } else { 28912 egr_dst.out_min_port = soc_mem_index_min(unit, SRC_MODID_BLOCKm) / modid_cnt; 28913 egr_dst.out_max_port = soc_mem_index_max(unit, SRC_MODID_BLOCKm) / modid_cnt; 28914 } 28915 28916 BCM_PBMP_ASSIGN(mod_pbmp, pbmp); 28917 BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit)); 28918 if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) { 28919 return BCM_E_PARAM; 28920 } 28921 28922 BCM_PBMP_NEGATE(mod_pbmp, pbmp); 28923 BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit)); 28924 28925 soc_mem_lock(unit, SRC_MODID_BLOCKm); 28926 for (i = egr_dst.out_min_port; i <= egr_dst.out_max_port; i++) { 28927 for (j = egr_dst.out_min_modid; j <= egr_dst.out_max_modid; j++) { 28928 idx = i * modid_cnt + j; 28929 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod); 28930 if (rv >= 0) { 28931 soc_SRC_MODID_BLOCKm_field_set(unit, &srcmod, 28932 PORT_BLOCK_MASK_BITMAPf, 28933 (uint32 *)&mod_pbmp); 28934 rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL, idx, 28935 &srcmod); 28936 } 28937 if (rv < 0) { 28938 soc_mem_unlock(unit, SRC_MODID_BLOCKm); 28939 return rv; 28940 } 28941 } 28942 } 28943 soc_mem_unlock(unit, SRC_MODID_BLOCKm); 28944 return rv; 28945 } 28946 #endif /* BCM_TRX_SUPPORT */ 28947 28948 #ifdef BCM_FIREBOLT_SUPPORT 28949 if (soc_feature(unit, soc_feature_src_modid_blk)) { 28950 src_modid_block_entry_t srcmod; 28951 bcm_module_t mod_idx; 28952 int p_idx, min_p, max_p; 28953 int tbl_size, modid_cnt, idx; 28954 bcm_pbmp_t mod_pbmp, tst_pbmp, hg_pbmp; 28955 int cpu=0, ether=0; 28956 uint32 xge_val; 28957 _bcm_port_egr_dest_t egr_dst; 28958 #if defined(BCM_RAPTOR_SUPPORT) 28959 uint32 rp_val; 28960 #endif /* BCM_RAPTOR_SUPPORT */ 28961 /* Number of supported MODIDs for this unit */ 28962 modid_cnt = SOC_MODID_MAX(unit) + 1; 28963 28964 28965 egr_dst.in_port = port; 28966 egr_dst.in_modid = modid; 28967 BCM_IF_ERROR_RETURN( 28968 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28969 28970 if (egr_dst.out_min_port == egr_dst.out_max_port) { 28971 min_p = max_p = egr_dst.out_min_port - SOC_HG_OFFSET(unit); 28972 } else { 28973 min_p = 0; 28974 tbl_size = soc_mem_index_count(unit, SRC_MODID_BLOCKm); 28975 max_p = (tbl_size / modid_cnt) - 1; 28976 assert(max_p >= 0); 28977 } 28978 28979 BCM_PBMP_ASSIGN(mod_pbmp, pbmp); 28980 BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit)); 28981 if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) { 28982 return BCM_E_PARAM; 28983 } 28984 28985 BCM_PBMP_NEGATE(mod_pbmp, pbmp); 28986 BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit)); 28987 28988 BCM_PBMP_ASSIGN(tst_pbmp, mod_pbmp); 28989 BCM_PBMP_AND(tst_pbmp, PBMP_CMIC(unit)); 28990 if (BCM_PBMP_NOT_NULL(tst_pbmp)) { 28991 cpu = 1; 28992 } 28993 28994 BCM_PBMP_ASSIGN(tst_pbmp, mod_pbmp); 28995 BCM_PBMP_AND(tst_pbmp, PBMP_E_ALL(unit)); 28996 if (BCM_PBMP_NOT_NULL(tst_pbmp)) { 28997 ether = 1; 28998 BCM_PBMP_ASSIGN(tst_pbmp, PBMP_XE_ALL(unit)); 28999 } 29000 29001 BCM_PBMP_ASSIGN(hg_pbmp, mod_pbmp); 29002 BCM_PBMP_AND(hg_pbmp, PBMP_ST_ALL(unit)); 29003 29004 if (ether && BCM_PBMP_NOT_NULL(tst_pbmp)) { 29005 BCM_PBMP_OR(hg_pbmp, tst_pbmp); 29006 } 29007 xge_val = SOC_PBMP_WORD_GET(hg_pbmp, 0) >> SOC_HG_OFFSET(unit); 29008 29009 /* In Raven, port #3 is the GMII port and it introduces a hole in the ST pbmp */ 29010 soc_mem_lock(unit, SRC_MODID_BLOCKm); 29011 for (p_idx = min_p; p_idx <= max_p; p_idx++) { 29012 if (SOC_IS_RAVEN(unit) && p_idx == 3) { 29013 continue; 29014 } 29015 for (mod_idx = egr_dst.out_min_modid; mod_idx <= egr_dst.out_max_modid; mod_idx++) { 29016 sal_memset(&srcmod, 0, sizeof(srcmod)); 29017 /* Table is 2-dimensional array */ 29018 if (SOC_IS_RAVEN(unit) && p_idx >= 4) { 29019 idx = (p_idx - 1) * modid_cnt + mod_idx; 29020 } else { 29021 idx = (p_idx * modid_cnt) + mod_idx; 29022 } 29023 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod); 29024 if (rv >= 0) { 29025 soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod, 29026 CPU_PORT_BLOCK_MASKf, 29027 (cpu) ? 1 : 0); 29028 if (SOC_IS_FB_FX_HX(unit)) { 29029 soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod, 29030 GE_PORT_BLOCK_MASKf, 29031 (ether) ? 1 : 0); 29032 } 29033 soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod, 29034 HIGIG_XGE_PORT_BLOCK_MASKf, 29035 xge_val); 29036 #if defined(BCM_RAPTOR_SUPPORT) 29037 if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm, 29038 PORT_0_5_BLOCK_MASKf)) { 29039 rp_val = (SOC_PBMP_WORD_GET(mod_pbmp, 0)) & 29040 ((1 << soc_reg_field_length(unit, SRC_MODID_BLOCKm, 29041 PORT_0_5_BLOCK_MASKf )) - 1); 29042 soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod, 29043 PORT_0_5_BLOCK_MASKf, 29044 rp_val); 29045 } 29046 #endif /* BCM_RAPTOR_SUPPORT */ 29047 rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL, 29048 idx, &srcmod); 29049 } 29050 } 29051 } 29052 soc_mem_unlock(unit, SRC_MODID_BLOCKm); 29053 } 29054 #endif /* BCM_FIREBOLT_SUPPORT */ 29055 29056 return rv; 29057 #else 29058 return BCM_E_UNAVAIL; 29059 #endif /* BCM_HERCULES15_SUPPORT || BCM_FIREBOLT_SUPPORT */ 29060 } 29061 29062 /* 29063 * Function: 29064 * bcm_port_modid_egress_get 29065 * Description: 29066 * Retrieve port bitmap of egress ports on which the incoming packets 29067 * will be forwarded. 29068 * Parameters: 29069 * unit - StrataSwitch PCI device unit number (driver internal). 29070 * port - ingress port number. 29071 * modid - source module ID index (in HiGig mod header). 29072 * pbmp - (OUT) bitmap of ports where egress allowed. 29073 * Returns: 29074 * BCM_E_xxxx 29075 */ 29076 int 29077 bcm_esw_port_modid_egress_get(int unit, bcm_port_t port, 29078 bcm_module_t modid, bcm_pbmp_t *pbmp) 29079 { 29080 #if defined(BCM_HERCULES15_SUPPORT) || defined(BCM_FIREBOLT_SUPPORT) 29081 int rv=BCM_E_UNAVAIL; 29082 29083 /* Make sure port module is initialized. */ 29084 PORT_INIT(unit); 29085 29086 #ifdef BCM_HERCULES15_SUPPORT 29087 if (SOC_IS_HERCULES15(unit)) { 29088 mem_ing_srcmodblk_entry_t srcmod; 29089 bcm_module_t min_mod, max_mod; 29090 int blk, rv=BCM_E_NONE; 29091 29092 if (!SOC_PORT_VALID(unit, port) || !IS_HG_PORT(unit, port)) { 29093 return BCM_E_PORT; 29094 } 29095 29096 min_mod = soc_mem_index_min(unit, MEM_ING_SRCMODBLKm); 29097 max_mod = soc_mem_index_max(unit, MEM_ING_SRCMODBLKm); 29098 if ((modid < min_mod) || (modid > max_mod)) { 29099 return BCM_E_PARAM; 29100 } 29101 29102 blk = SOC_PORT_BLOCK(unit, port); 29103 SOC_PBMP_CLEAR(*pbmp); 29104 rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod); 29105 if (rv >= 0) { 29106 SOC_PBMP_WORD_SET(*pbmp, 0, 29107 soc_MEM_ING_SRCMODBLKm_field32_get(unit, &srcmod, BITMAPf)); 29108 } 29109 } 29110 #endif /* BCM_HERCULES15_SUPPORT */ 29111 29112 #ifdef BCM_TRIUMPH2_SUPPORT 29113 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 29114 SOC_IS_VALKYRIE2(unit) || SOC_IS_TD_TT(unit) || 29115 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 29116 src_modid_egress_entry_t srcmodegr; 29117 int idx; 29118 _bcm_port_egr_dest_t egr_dst; 29119 bcm_pbmp_t all_pbmp; 29120 29121 SOC_PBMP_CLEAR(all_pbmp); 29122 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 29123 29124 #ifdef BCM_KATANA2_SUPPORT 29125 if (soc_feature(unit, soc_feature_linkphy_coe) || 29126 soc_feature(unit, soc_feature_subtag_coe)) { 29127 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 29128 } 29129 #endif 29130 29131 egr_dst.in_port = port; 29132 egr_dst.in_modid = modid; 29133 BCM_IF_ERROR_RETURN( 29134 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 29135 29136 if (egr_dst.out_min_modid != egr_dst.out_max_modid) { 29137 return BCM_E_PARAM; 29138 } 29139 if (egr_dst.out_max_port != egr_dst.out_min_port) { 29140 return BCM_E_PORT; 29141 } 29142 29143 idx = PORT_SRC_MOD_EGR_PROF_PTR(unit, egr_dst.out_min_port) * 29144 (SOC_MODID_MAX(unit) + 1) + egr_dst.out_min_modid; 29145 SOC_IF_ERROR_RETURN(READ_SRC_MODID_EGRESSm(unit, MEM_BLOCK_ANY, idx, 29146 &srcmodegr)); 29147 soc_mem_pbmp_field_get(unit, SRC_MODID_EGRESSm, &srcmodegr, 29148 PORT_BLOCK_MASK_BITMAPf, pbmp); 29149 BCM_PBMP_NEGATE(*pbmp, *pbmp); 29150 BCM_PBMP_AND(*pbmp, all_pbmp); 29151 BCM_PBMP_REMOVE(*pbmp, PBMP_LB(unit)); 29152 return SOC_E_NONE; 29153 } 29154 #endif 29155 29156 #ifdef BCM_TRX_SUPPORT 29157 if (SOC_IS_TRX(unit)) { 29158 src_modid_block_entry_t srcmod; 29159 int hg_port, idx; 29160 _bcm_port_egr_dest_t egr_dst; 29161 29162 egr_dst.in_port = port; 29163 egr_dst.in_modid = modid; 29164 BCM_IF_ERROR_RETURN( 29165 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 29166 29167 if (egr_dst.out_min_modid != egr_dst.out_max_modid) { 29168 return BCM_E_PARAM; 29169 } 29170 if (egr_dst.out_max_port != egr_dst.out_min_port) { 29171 return BCM_E_PORT; 29172 } 29173 29174 /* process to retrieve hg_port index from port */ 29175 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 29176 SOC_IS_GREYHOUND2(unit)) { 29177 hg_port = egr_dst.out_min_port; 29178 } else { 29179 SOC_IF_ERROR_RETURN( 29180 soc_xgs3_port_num_to_higig_port_num(unit, 29181 egr_dst.out_min_port, &hg_port)); 29182 } 29183 29184 idx = hg_port * (SOC_MODID_MAX(unit) + 1) + egr_dst.out_min_modid; 29185 SOC_IF_ERROR_RETURN(READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, 29186 &srcmod)); 29187 soc_SRC_MODID_BLOCKm_field_get(unit, &srcmod, PORT_BLOCK_MASK_BITMAPf, 29188 (uint32 *)pbmp); 29189 BCM_PBMP_NEGATE(*pbmp, *pbmp); 29190 BCM_PBMP_AND(*pbmp, PBMP_ALL(unit)); 29191 29192 return SOC_E_NONE; 29193 } 29194 #endif 29195 29196 #ifdef BCM_FIREBOLT_SUPPORT 29197 if (soc_feature(unit, soc_feature_src_modid_blk)) { 29198 src_modid_block_entry_t srcmod; 29199 int modid_cnt, p_idx, idx; 29200 _bcm_port_egr_dest_t egr_dst; 29201 29202 egr_dst.in_port = port; 29203 egr_dst.in_modid = modid; 29204 BCM_IF_ERROR_RETURN( 29205 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 29206 29207 if (egr_dst.out_min_modid != egr_dst.out_max_modid) { 29208 return BCM_E_PARAM; 29209 } 29210 if (egr_dst.out_max_port != egr_dst.out_min_port) { 29211 return BCM_E_PORT; 29212 } 29213 29214 modid_cnt = SOC_MODID_MAX(unit) + 1; 29215 p_idx = egr_dst.out_min_port - SOC_HG_OFFSET(unit); 29216 if (SOC_IS_RAVEN(unit) && p_idx >= 4) { 29217 idx = (p_idx - 1) * modid_cnt + egr_dst.out_min_modid; 29218 } else { 29219 idx = (p_idx * modid_cnt) + egr_dst.out_min_modid; 29220 } 29221 29222 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod); 29223 BCM_PBMP_CLEAR(*pbmp); 29224 if (rv >= 0) { 29225 int cpu, ether; 29226 pbmp_t hg_pbmp; 29227 uint32 xge_val; 29228 #if defined(BCM_RAPTOR_SUPPORT) 29229 uint32 rp_val; 29230 #endif /* BCM_RAPTOR_SUPPORT */ 29231 cpu = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod, 29232 CPU_PORT_BLOCK_MASKf); 29233 if (SOC_IS_FB_FX_HX(unit)) { 29234 ether = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod, 29235 GE_PORT_BLOCK_MASKf); 29236 } else { 29237 ether = 0; 29238 } 29239 xge_val = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod, 29240 HIGIG_XGE_PORT_BLOCK_MASKf); 29241 SOC_PBMP_CLEAR(hg_pbmp); 29242 SOC_PBMP_WORD_SET(hg_pbmp, 0, xge_val << SOC_HG_OFFSET(unit)); 29243 29244 #if defined(BCM_RAPTOR_SUPPORT) 29245 if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm, 29246 PORT_0_5_BLOCK_MASKf)) { 29247 rp_val = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod, 29248 PORT_0_5_BLOCK_MASKf); 29249 SOC_PBMP_WORD_SET(hg_pbmp, 0, rp_val); 29250 } 29251 #endif /* BCM_RAPTOR_SUPPORT */ 29252 BCM_PBMP_ASSIGN(*pbmp, PBMP_ALL(unit)); 29253 if (cpu) { 29254 BCM_PBMP_REMOVE(*pbmp, PBMP_CMIC(unit)); 29255 } 29256 if (ether) { 29257 BCM_PBMP_REMOVE(*pbmp, PBMP_E_ALL(unit)); 29258 } 29259 if (BCM_PBMP_NOT_NULL(hg_pbmp)) { 29260 BCM_PBMP_REMOVE(*pbmp, hg_pbmp); 29261 } 29262 } 29263 } 29264 #endif /* BCM_FIREBOLT_SUPPORT */ 29265 29266 return rv; 29267 #else 29268 return BCM_E_UNAVAIL; 29269 #endif /* BCM_HERCULES15_SUPPORT || BCM_FIREBOLT_SUPPORT */ 29270 } 29271 29272 /* 29273 * Function: 29274 * bcm_port_modid_enable_set 29275 * Purpose: 29276 * Enable/block packets from a specific module on a port. 29277 * Parameters: 29278 * unit - StrataSwitch PCI device unit number (driver internal). 29279 * port - StrataSwitch port number. 29280 * modid - Which source module id to enable/disable 29281 * enable - TRUE/FALSE Enable/disable forwarding packets from 29282 * source module arriving on port. 29283 * Returns: 29284 * BCM_E_XXX 29285 */ 29286 int 29287 bcm_esw_port_modid_enable_set(int unit, bcm_port_t port, int modid, int enable) 29288 { 29289 int max_mod; 29290 #ifdef BCM_HERCULES_SUPPORT 29291 uint32 smf, osmf; 29292 #endif /* BCM_HERCULES_SUPPORT */ 29293 #ifdef BCM_HERCULES1_SUPPORT 29294 uint32 mask; 29295 #endif /* BCM_HERCULES1_SUPPORT */ 29296 #ifdef BCM_HERCULES15_SUPPORT 29297 mem_ing_srcmodblk_entry_t srcmod; 29298 int blk; 29299 #endif /* BCM_HERCULES15_SUPPORT */ 29300 #if defined(BCM_HERCULES15_SUPPORT) || defined(BCM_FIREBOLT_SUPPORT) 29301 int rv=BCM_E_NONE; 29302 #endif /* BCM_HERCULES15_SUPPORT || BCM_FIREBOLT_SUPPORT */ 29303 29304 /* Make sure port module is initialized. */ 29305 PORT_INIT(unit); 29306 29307 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 29308 29309 #ifdef BCM_TRX_SUPPORT 29310 if (SOC_IS_TRX(unit)) { 29311 src_modid_ingress_block_entry_t srcmoding; 29312 src_modid_block_entry_t srcmod; 29313 int modid_cnt, hg_port, idx, i; 29314 bcm_pbmp_t pbmp; 29315 _bcm_port_egr_dest_t egr_dst; 29316 29317 egr_dst.in_port = port; 29318 egr_dst.in_modid = modid; 29319 BCM_IF_ERROR_RETURN( 29320 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 29321 29322 if (egr_dst.out_max_port != egr_dst.out_min_port) { 29323 return BCM_E_PORT; 29324 } 29325 29326 if (!IS_E_PORT(unit, egr_dst.out_max_port) && 29327 !IS_ST_PORT(unit, egr_dst.out_max_port)) { 29328 return BCM_E_PORT; 29329 } 29330 29331 29332 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 29333 SOC_IS_VALKYRIE2(unit) || SOC_IS_TD_TT(unit) || 29334 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 29335 soc_mem_lock(unit, SRC_MODID_INGRESS_BLOCKm); 29336 for (i = egr_dst.out_min_modid; i <= egr_dst.out_max_modid; i++) { 29337 rv = READ_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ANY, i, 29338 &srcmoding); 29339 if (rv >= 0) { 29340 soc_mem_pbmp_field_get(unit, SRC_MODID_INGRESS_BLOCKm, 29341 &srcmoding, PORT_BITMAPf, &pbmp); 29342 if (enable) { 29343 BCM_PBMP_PORT_REMOVE(pbmp, egr_dst.out_max_port); 29344 } else { 29345 BCM_PBMP_PORT_ADD(pbmp, egr_dst.out_max_port); 29346 } 29347 soc_mem_pbmp_field_set(unit, SRC_MODID_INGRESS_BLOCKm, 29348 &srcmoding, PORT_BITMAPf, &pbmp); 29349 rv = WRITE_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ALL, i, 29350 &srcmoding); 29351 } 29352 if (rv < 0) { 29353 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm); 29354 return rv; 29355 } 29356 } 29357 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm); 29358 } else { 29359 modid_cnt = SOC_MODID_MAX(unit) + 1; 29360 29361 /* process to retrieve hg_port index from port */ 29362 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 29363 SOC_IS_GREYHOUND2(unit)) { 29364 hg_port = port; 29365 } else { 29366 SOC_IF_ERROR_RETURN( 29367 soc_xgs3_port_num_to_higig_port_num(unit, port, &hg_port)); 29368 } 29369 29370 soc_mem_lock(unit, SRC_MODID_BLOCKm); 29371 for (i = egr_dst.out_min_modid; i <= egr_dst.out_max_modid; i++) { 29372 idx = hg_port * modid_cnt + i; 29373 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod); 29374 if (rv >= 0) { 29375 if (!enable) { 29376 SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 29377 } else { 29378 SOC_PBMP_CLEAR(pbmp); 29379 } 29380 soc_mem_pbmp_field_set(unit, SRC_MODID_BLOCKm, &srcmod, 29381 PORT_BLOCK_MASK_BITMAPf,&pbmp); 29382 rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL, idx, &srcmod); 29383 } 29384 if (rv < 0) { 29385 soc_mem_unlock(unit, SRC_MODID_BLOCKm); 29386 return rv; 29387 } 29388 } 29389 soc_mem_unlock(unit, SRC_MODID_BLOCKm); 29390 } 29391 return rv; 29392 } 29393 #endif /* BCM_TRX_SUPPORT */ 29394 29395 #ifdef BCM_FIREBOLT_SUPPORT 29396 if (soc_feature(unit, soc_feature_src_modid_blk)) { 29397 src_modid_block_entry_t src_mod; 29398 int modid_cnt, mod_idx, p_idx, idx, val; 29399 _bcm_port_egr_dest_t egr_dst; 29400 29401 egr_dst.in_port = port; 29402 egr_dst.in_modid = modid; 29403 BCM_IF_ERROR_RETURN( 29404 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 29405 29406 if (egr_dst.out_max_port != egr_dst.out_min_port) { 29407 return BCM_E_PORT; 29408 } 29409 29410 modid_cnt = SOC_MODID_MAX(unit) + 1; 29411 p_idx = egr_dst.out_min_port - SOC_HG_OFFSET(unit); 29412 soc_mem_lock(unit, SRC_MODID_BLOCKm); 29413 for (mod_idx = egr_dst.out_min_modid; mod_idx <= egr_dst.out_max_modid; mod_idx++) { 29414 sal_memset(&src_mod, 0, sizeof(src_mod)); 29415 if (SOC_IS_RAVEN(unit) && p_idx >= 4) { 29416 idx = (p_idx - 1) * modid_cnt + mod_idx; 29417 } else { 29418 idx = (p_idx * modid_cnt) + mod_idx; 29419 } 29420 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &src_mod); 29421 if (rv >= 0) { 29422 soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod, 29423 CPU_PORT_BLOCK_MASKf, 29424 (enable) ? 0 : 1); 29425 if (SOC_IS_FB_FX_HX(unit)) { 29426 soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod, 29427 GE_PORT_BLOCK_MASKf, 29428 (enable) ? 0 : 1); 29429 } 29430 29431 val = (1 << soc_mem_field_length(unit, SRC_MODID_BLOCKm, 29432 HIGIG_XGE_PORT_BLOCK_MASKf)) - 1; 29433 29434 soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod, 29435 HIGIG_XGE_PORT_BLOCK_MASKf, 29436 (enable) ? 0 : val); 29437 #if defined(BCM_RAPTOR_SUPPORT) 29438 if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm, 29439 PORT_0_5_BLOCK_MASKf)) { 29440 29441 val = (1 << soc_mem_field_length(unit, SRC_MODID_BLOCKm, 29442 PORT_0_5_BLOCK_MASKf)) - 1; 29443 29444 soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod, 29445 PORT_0_5_BLOCK_MASKf, 29446 (enable) ? 0 : val); 29447 29448 } 29449 #endif /* BCM_RAPTOR_SUPPORT */ 29450 rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL, 29451 idx, &src_mod); 29452 } 29453 } 29454 soc_mem_unlock(unit, SRC_MODID_BLOCKm); 29455 29456 return rv; 29457 } 29458 #endif /* BCM_FIREBOLT_SUPPORT */ 29459 29460 if (!IS_PORT(unit, port)) { 29461 return BCM_E_PORT; 29462 } 29463 29464 if (!soc_feature(unit, soc_feature_srcmod_filter)) { 29465 if (enable) { 29466 return BCM_E_NONE; 29467 } else { 29468 return BCM_E_UNAVAIL; 29469 } 29470 } 29471 29472 max_mod = 128; 29473 if (modid >= max_mod) { 29474 return BCM_E_PARAM; 29475 } 29476 29477 #ifdef BCM_HERCULES15_SUPPORT 29478 if (SOC_IS_HERCULES15(unit)) { 29479 blk = SOC_PORT_BLOCK(unit, port); 29480 soc_mem_lock(unit, MEM_ING_SRCMODBLKm); 29481 if (modid < 0) { 29482 for (modid = 0; modid < max_mod; modid++) { 29483 rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod); 29484 if (rv < 0) { 29485 break; 29486 } 29487 soc_MEM_ING_SRCMODBLKm_field_get(unit, &srcmod, BITMAPf, 29488 &osmf); 29489 smf = (enable) ? SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0) : 0; 29490 if (osmf != smf) { 29491 soc_MEM_ING_SRCMODBLKm_field_set(unit, &srcmod, BITMAPf, 29492 &smf); 29493 rv = WRITE_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod); 29494 if (rv < 0) { 29495 break; 29496 } 29497 } 29498 } 29499 } else { 29500 rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod); 29501 if (rv >= 0) { 29502 soc_MEM_ING_SRCMODBLKm_field_get(unit, &srcmod, BITMAPf, 29503 &osmf); 29504 smf = (enable) ? SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0) : 0; 29505 if (osmf != smf) { 29506 soc_MEM_ING_SRCMODBLKm_field_set(unit, &srcmod, BITMAPf, 29507 &smf); 29508 rv = WRITE_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod); 29509 } 29510 } 29511 } 29512 soc_mem_unlock(unit, MEM_ING_SRCMODBLKm); 29513 } 29514 #endif /* BCM_HERCULES15_SUPPORT */ 29515 29516 return BCM_E_NONE; 29517 } 29518 29519 /* 29520 * Function: 29521 * bcm_port_modid_enable_get 29522 * Purpose: 29523 * Return enable/block state for a specific module on a port. 29524 * Parameters: 29525 * unit - StrataSwitch PCI device unit number (driver internal). 29526 * port - StrataSwitch port number. 29527 * modid - Which source module id to enable/disable 29528 * enable - (OUT) TRUE/FALSE Enable/disable forwarding packets from 29529 * source module arriving on port. 29530 * Returns: 29531 * BCM_E_XXX 29532 */ 29533 int 29534 bcm_esw_port_modid_enable_get(int unit, bcm_port_t port, int modid, int *enable) 29535 { 29536 int max_mod; 29537 #ifdef BCM_HERCULES_SUPPORT 29538 uint32 smf; 29539 #endif /* BCM_HERCULES_SUPPORT */ 29540 #ifdef BCM_HERCULES1_SUPPORT 29541 uint32 mask; 29542 #endif /* BCM_HERCULES1_SUPPORT */ 29543 #ifdef BCM_HERCULES15_SUPPORT 29544 mem_ing_srcmodblk_entry_t srcmod; 29545 int blk, rv; 29546 #endif /* BCM_HERCULES15_SUPPORT */ 29547 29548 /* Make sure port module is initialized. */ 29549 PORT_INIT(unit); 29550 29551 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 29552 29553 #ifdef BCM_TRX_SUPPORT 29554 if (SOC_IS_TRX(unit)) { 29555 src_modid_ingress_block_entry_t srcmoding; 29556 src_modid_block_entry_t srcmod; 29557 int hg_port, idx; 29558 bcm_pbmp_t pbmp; 29559 _bcm_port_egr_dest_t egr_dst; 29560 29561 egr_dst.in_port = port; 29562 egr_dst.in_modid = modid; 29563 BCM_IF_ERROR_RETURN( 29564 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 29565 29566 if (egr_dst.out_max_port != egr_dst.out_min_port) { 29567 return BCM_E_PORT; 29568 } 29569 if (egr_dst.out_max_modid != egr_dst.out_min_modid) { 29570 return BCM_E_PARAM; 29571 } 29572 29573 if (!IS_E_PORT(unit, egr_dst.out_max_port) && 29574 !IS_ST_PORT(unit, egr_dst.out_max_port)) { 29575 return BCM_E_PORT; 29576 } 29577 29578 SOC_PBMP_CLEAR(pbmp); 29579 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 29580 SOC_IS_VALKYRIE2(unit) || SOC_IS_TD_TT(unit) || 29581 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 29582 SOC_IF_ERROR_RETURN( 29583 READ_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ANY, 29584 egr_dst.out_min_modid, &srcmoding)); 29585 soc_mem_pbmp_field_get(unit, SRC_MODID_INGRESS_BLOCKm, 29586 &srcmoding, PORT_BITMAPf, &pbmp); 29587 } else { 29588 /* process to retrieve hg_port index from port */ 29589 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 29590 SOC_IS_GREYHOUND2(unit)) { 29591 hg_port = egr_dst.out_min_port; 29592 } else { 29593 SOC_IF_ERROR_RETURN(soc_xgs3_port_num_to_higig_port_num(unit, 29594 egr_dst.out_min_port, &hg_port)); 29595 } 29596 29597 idx = hg_port * (SOC_MODID_MAX(unit) + 1) + egr_dst.out_min_modid; 29598 SOC_IF_ERROR_RETURN(READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, 29599 &srcmod)); 29600 soc_mem_pbmp_field_get(unit, SRC_MODID_BLOCKm, &srcmod, 29601 PORT_BLOCK_MASK_BITMAPf, &pbmp); 29602 } 29603 29604 *enable = !SOC_PBMP_MEMBER(pbmp, egr_dst.out_max_port); 29605 29606 return BCM_E_NONE; 29607 } 29608 #endif /* BCM_TRIUMPH_SUPPORT */ 29609 29610 #ifdef BCM_FIREBOLT_SUPPORT 29611 if (soc_feature(unit, soc_feature_src_modid_blk)) { 29612 uint32 config; 29613 src_modid_block_entry_t src_mod; 29614 int gable, modid_cnt, p_idx, idx; 29615 _bcm_port_egr_dest_t egr_dst; 29616 29617 egr_dst.in_port = port; 29618 egr_dst.in_modid = modid; 29619 BCM_IF_ERROR_RETURN( 29620 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 29621 29622 if (egr_dst.out_max_port != egr_dst.out_min_port) { 29623 return BCM_E_PORT; 29624 } 29625 if (egr_dst.out_max_modid != egr_dst.out_min_modid) { 29626 return BCM_E_PARAM; 29627 } 29628 29629 SOC_IF_ERROR_RETURN(READ_ING_CONFIGr(unit, &config)); 29630 gable = !soc_reg_field_get(unit, ING_CONFIGr, config, 29631 FB_A0_COMPATIBLEf); 29632 if (gable) { 29633 modid_cnt = SOC_MODID_MAX(unit) + 1; 29634 p_idx = egr_dst.out_min_port - SOC_HG_OFFSET(unit); 29635 if (SOC_IS_RAVEN(unit) && p_idx >= 4) { 29636 idx = (p_idx - 1) * modid_cnt + egr_dst.out_min_modid; 29637 } else { 29638 idx = (p_idx * modid_cnt) + egr_dst.out_min_modid; 29639 } 29640 SOC_IF_ERROR_RETURN 29641 (READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, 29642 idx, &src_mod)); 29643 *enable = (soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod, 29644 CPU_PORT_BLOCK_MASKf) | 29645 soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod, 29646 HIGIG_XGE_PORT_BLOCK_MASKf) 29647 ) ? 0 : 1; 29648 if (SOC_IS_FB_FX_HX(unit)) { 29649 *enable = (soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod, 29650 GE_PORT_BLOCK_MASKf) 29651 ) ? 0 : 1; 29652 } 29653 29654 #if defined(BCM_RAPTOR_SUPPORT) 29655 if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm, 29656 PORT_0_5_BLOCK_MASKf)) { 29657 *enable = (soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod, 29658 PORT_0_5_BLOCK_MASKf) 29659 ) ? 0 : 1; 29660 } 29661 #endif /* BCM_RAPTOR_SUPPORT */ 29662 29663 } else { 29664 *enable = gable; 29665 } 29666 29667 return BCM_E_NONE; 29668 } 29669 #endif /* BCM_FIREBOLT_SUPPORT */ 29670 29671 if (!IS_PORT(unit, port)) { 29672 return BCM_E_PORT; 29673 } 29674 29675 if (!soc_feature(unit, soc_feature_srcmod_filter)) { 29676 *enable = TRUE; 29677 return BCM_E_NONE; 29678 } 29679 29680 max_mod = 128; 29681 if (!((modid >= 0) && (modid < max_mod))) { 29682 return BCM_E_PARAM; 29683 } 29684 29685 #ifdef BCM_HERCULES15_SUPPORT 29686 if (SOC_IS_HERCULES15(unit)) { 29687 blk = SOC_PORT_BLOCK(unit, port); 29688 rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod); 29689 if (rv >= 0) { 29690 soc_MEM_ING_SRCMODBLKm_field_get(unit, &srcmod, BITMAPf, &smf); 29691 *enable = (smf & SOC_PBMP_WORD_GET(PBMP_ALL(unit),0)) ? 1 : 0; 29692 } 29693 } 29694 #endif /* BCM_HERCULES15_SUPPORT */ 29695 29696 return BCM_E_NONE; 29697 } 29698 29699 29700 /* 29701 * Function: 29702 * _bcm_port_flood_block_op 29703 * Purpose: 29704 * Set or get port membership in one of the egress block registers 29705 * Parameters: 29706 * unit 29707 * set_op - TRUE for set, FALSE for get 29708 * ingress_port - ingress port on which the egress blocking 29709 * will be enabled 29710 * egress_port - port for which egress will be blocked 29711 * mode - BCM_PORT_FLOOD_BLOCK_XXX 29712 * enable - Whether blocking should be enabled or disabled 29713 * This is also BCM_PORT_FLOOD_BLOCK_XXX 29714 * Returns: 29715 * BCM_E_UNAVAIL - This chip does not support this feature 29716 * BCM_E_NONE 29717 */ 29718 STATIC int 29719 _bcm_port_flood_block_op(int unit, int set_op, 29720 bcm_port_t ingress_port, bcm_port_t egress_port, 29721 uint32 mode, uint32 *enable) 29722 { 29723 soc_reg_t reg, mask_reg[2], mask_hi_reg[2]; 29724 soc_mem_t mem; 29725 soc_field_t field; 29726 uint64 rval; 29727 uint32 fval; 29728 uint32 entry[SOC_MAX_MEM_WORDS]; 29729 pbmp_t pbmp; 29730 int index; 29731 int cpu_hg_index = 0; 29732 29733 mask_reg[0] = mask_reg[1] = INVALIDr; 29734 mask_hi_reg[0] = mask_hi_reg[1] = INVALIDr; 29735 mem = INVALIDm; 29736 field = INVALIDf; 29737 29738 switch (mode) { 29739 case BCM_PORT_FLOOD_BLOCK_BCAST: 29740 if (SOC_MEM_IS_VALID(unit, BCAST_BLOCK_MASKm)) { 29741 mem = BCAST_BLOCK_MASKm; 29742 field = BLK_BITMAPf; 29743 /* coverity[result_independent_of_operands] */ 29744 } else if (SOC_REG_IS_VALID(unit, BCAST_BLOCK_MASK_64r)) { 29745 mask_reg[0] = BCAST_BLOCK_MASK_64r; 29746 mask_reg[1] = IBCAST_BLOCK_MASK_64r; 29747 } else if (SOC_REG_IS_VALID(unit, BCAST_BLOCK_MASK_LO_64r)) { 29748 mask_reg[0] = BCAST_BLOCK_MASK_LO_64r; 29749 mask_reg[1] = IBCAST_BLOCK_MASK_LO_64r; 29750 mask_hi_reg[0] = BCAST_BLOCK_MASK_HI_64r; 29751 mask_hi_reg[1] = IBCAST_BLOCK_MASK_HI_64r; 29752 } else if (SOC_REG_IS_VALID(unit, BCAST_BLOCK_MASKr)) { 29753 mask_reg[0] = BCAST_BLOCK_MASKr; 29754 mask_reg[1] = IBCAST_BLOCK_MASKr; 29755 } else { 29756 return BCM_E_UNAVAIL; 29757 } 29758 break; 29759 case BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST: 29760 if (SOC_MEM_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASKm)) { 29761 mem = UNKNOWN_UCAST_BLOCK_MASKm; 29762 field = BLK_BITMAPf; 29763 } else if (SOC_REG_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASK_64r)) { 29764 mask_reg[0] = UNKNOWN_UCAST_BLOCK_MASK_64r; 29765 mask_reg[1] = IUNKNOWN_UCAST_BLOCK_MASK_64r; 29766 } else if (SOC_REG_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASK_LO_64r)) { 29767 mask_reg[0] = UNKNOWN_UCAST_BLOCK_MASK_LO_64r; 29768 mask_reg[1] = IUNKNOWN_UCAST_BLOCK_MASK_LO_64r; 29769 mask_hi_reg[0] = UNKNOWN_UCAST_BLOCK_MASK_HI_64r; 29770 mask_hi_reg[1] = IUNKNOWN_UCAST_BLOCK_MASK_HI_64r; 29771 } else if (SOC_REG_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASKr)) { 29772 mask_reg[0] = UNKNOWN_UCAST_BLOCK_MASKr; 29773 mask_reg[1] = IUNKNOWN_UCAST_BLOCK_MASKr; 29774 } else { 29775 return BCM_E_UNAVAIL; 29776 } 29777 break; 29778 case BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST: 29779 if (SOC_MEM_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASKm)) { 29780 mem = UNKNOWN_MCAST_BLOCK_MASKm; 29781 field = BLK_BITMAPf; 29782 } else if (SOC_REG_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASK_64r)) { 29783 mask_reg[0] = UNKNOWN_MCAST_BLOCK_MASK_64r; 29784 mask_reg[1] = IUNKNOWN_MCAST_BLOCK_MASK_64r; 29785 } else if (SOC_REG_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASK_LO_64r)) { 29786 mask_reg[0] = UNKNOWN_MCAST_BLOCK_MASK_LO_64r; 29787 mask_reg[1] = IUNKNOWN_MCAST_BLOCK_MASK_LO_64r; 29788 mask_hi_reg[0] = UNKNOWN_MCAST_BLOCK_MASK_HI_64r; 29789 mask_hi_reg[1] = IUNKNOWN_MCAST_BLOCK_MASK_HI_64r; 29790 } else if (SOC_REG_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASKr)) { 29791 mask_reg[0] = UNKNOWN_MCAST_BLOCK_MASKr; 29792 mask_reg[1] = IUNKNOWN_MCAST_BLOCK_MASKr; 29793 } else { 29794 return BCM_E_UNAVAIL; 29795 } 29796 break; 29797 case BCM_PORT_FLOOD_BLOCK_KNOWN_MCAST: 29798 if (SOC_MEM_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASKm)) { 29799 mem = KNOWN_MCAST_BLOCK_MASKm; 29800 field = BLK_BITMAPf; 29801 } else if (SOC_REG_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASK_64r)) { 29802 mask_reg[0] = KNOWN_MCAST_BLOCK_MASK_64r; 29803 mask_reg[1] = IKNOWN_MCAST_BLOCK_MASK_64r; 29804 } else if (SOC_REG_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASK_LOr)) { 29805 mask_reg[0] = KNOWN_MCAST_BLOCK_MASK_LOr; 29806 mask_reg[1] = IKNOWN_MCAST_BLOCK_MASK_LOr; 29807 mask_hi_reg[0] = KNOWN_MCAST_BLOCK_MASK_HIr; 29808 mask_hi_reg[1] = IKNOWN_MCAST_BLOCK_MASK_HIr; 29809 } else if (SOC_REG_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASKr)) { 29810 mask_reg[0] = KNOWN_MCAST_BLOCK_MASKr; 29811 mask_reg[1] = IKNOWN_MCAST_BLOCK_MASKr; 29812 } else { 29813 return BCM_E_UNAVAIL; 29814 } 29815 break; 29816 case BCM_PORT_FLOOD_BLOCK_ALL: 29817 if (SOC_MEM_IS_VALID(unit, ING_EGRMSKBMAPm)) { 29818 mem = ING_EGRMSKBMAPm; 29819 field = BITMAPf; 29820 } else if (SOC_REG_IS_VALID(unit, ING_EGRMSKBMAP_64r)) { 29821 mask_reg[0] = ING_EGRMSKBMAP_64r; 29822 mask_reg[1] = IING_EGRMSKBMAP_64r; 29823 } else if (SOC_REG_IS_VALID(unit, ING_EGRMSKBMAP_LOr)) { 29824 mask_reg[0] = ING_EGRMSKBMAP_LOr; 29825 mask_reg[1] = IING_EGRMSKBMAP_LOr; 29826 mask_hi_reg[0] = ING_EGRMSKBMAP_HIr; 29827 mask_hi_reg[1] = IING_EGRMSKBMAP_HIr; 29828 } else if (SOC_REG_IS_VALID(unit, ING_EGRMSKBMAPr)) { 29829 mask_reg[0] = ING_EGRMSKBMAPr; 29830 mask_reg[1] = IING_EGRMSKBMAPr; 29831 } else { 29832 return BCM_E_UNAVAIL; 29833 } 29834 break; 29835 default: 29836 return BCM_E_INTERNAL; 29837 } 29838 29839 if (mem != INVALIDm) { 29840 BCM_IF_ERROR_RETURN 29841 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, ingress_port, entry)); 29842 soc_mem_pbmp_field_get(unit, mem, entry, field, &pbmp); 29843 if (!set_op) { 29844 *enable = SOC_PBMP_WORD_GET(pbmp, egress_port / 32) & 29845 (1 << (egress_port & 0x1f)) ? mode : 0; 29846 return BCM_E_NONE; 29847 } 29848 if (*enable & mode) { 29849 SOC_PBMP_PORT_ADD(pbmp, egress_port); 29850 } else { 29851 SOC_PBMP_PORT_REMOVE(pbmp, egress_port); 29852 } 29853 soc_mem_pbmp_field_set(unit, mem, entry, field, &pbmp); 29854 BCM_IF_ERROR_RETURN 29855 (soc_mem_write(unit, mem, MEM_BLOCK_ANY, ingress_port, entry)); 29856 29857 cpu_hg_index = SOC_IS_KATANA2(unit) ? 29858 SOC_INFO(unit).cpu_hg_pp_port_index : 29859 SOC_INFO(unit).cpu_hg_index; 29860 if (IS_CPU_PORT(unit, ingress_port) && cpu_hg_index != -1) { 29861 BCM_IF_ERROR_RETURN 29862 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, cpu_hg_index, entry)); 29863 soc_mem_pbmp_field_get(unit, mem, entry, field, &pbmp); 29864 if (*enable & mode) { 29865 SOC_PBMP_PORT_ADD(pbmp, egress_port); 29866 } else { 29867 SOC_PBMP_PORT_REMOVE(pbmp, egress_port); 29868 } 29869 soc_mem_pbmp_field_set(unit, mem, entry, field, &pbmp); 29870 BCM_IF_ERROR_RETURN 29871 (soc_mem_write(unit, mem, MEM_BLOCK_ANY, cpu_hg_index, entry)); 29872 } 29873 } else { 29874 if (!IS_CPU_PORT(unit, ingress_port)) { 29875 if (IS_ST_PORT(unit, ingress_port)) { 29876 mask_reg[0] = INVALIDr; 29877 mask_hi_reg[0] = INVALIDr; 29878 } else { 29879 mask_reg[1] = INVALIDr; 29880 mask_hi_reg[1] = INVALIDr; 29881 } 29882 } 29883 29884 for (index = 0; index < 2; index++) { 29885 if (soc_feature (unit, soc_feature_high_portcount_register)) { 29886 uint64 fval64, rval64; 29887 uint32 t_port; 29888 pbmp_t curr_pbmp; 29889 29890 /* 29891 * pbmp reg split to multiple reg due to high port count 29892 * example : 29893 * - BCAST_BLOCK_MASK_64r was split to 29894 * {BCAST_BLOCK_MASK_LO_64r + BCAST_BLOCK_MASK_HI_64r} 29895 * - ING_EGRMSKBMAP_64r was split to 29896 * {ING_EGRMSKBMAP_LOr + ING_EGRMSKBMAP_HIr} 29897 */ 29898 BCM_PBMP_CLEAR(curr_pbmp); 29899 COMPILER_64_ZERO(fval64); 29900 COMPILER_64_ZERO(rval64); 29901 29902 if (egress_port < 64) { 29903 reg = mask_reg[index]; 29904 t_port = egress_port; 29905 } else { 29906 reg = mask_hi_reg[index]; 29907 t_port = egress_port - 64; 29908 } 29909 field = BLK_BITMAPf; 29910 29911 if (SOC_REG_IS_VALID(unit, reg)) { 29912 BCM_IF_ERROR_RETURN(soc_reg_get(unit, 29913 reg, ingress_port, 0, &rval64)); 29914 29915 fval64 = soc_reg64_field_get(unit, reg, rval64, field); 29916 SOC_PBMP_WORD_SET(curr_pbmp, 0, COMPILER_64_LO(fval64)); 29917 SOC_PBMP_WORD_SET(curr_pbmp, 1, COMPILER_64_HI(fval64)); 29918 29919 if (!set_op) { 29920 /* for GET */ 29921 *enable = SOC_PBMP_MEMBER(curr_pbmp, t_port) ? mode : 0; 29922 } else { 29923 /* for SET */ 29924 if (*enable & mode) { 29925 SOC_PBMP_PORT_ADD(curr_pbmp, t_port); 29926 } else { 29927 SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port); 29928 } 29929 COMPILER_64_SET(fval64, 29930 SOC_PBMP_WORD_GET(curr_pbmp, 1), 29931 SOC_PBMP_WORD_GET(curr_pbmp, 0)); 29932 soc_reg64_field_set(unit, reg, 29933 &rval64, field, fval64); 29934 BCM_IF_ERROR_RETURN(soc_reg_set(unit, 29935 reg, ingress_port, 0, rval64)); 29936 } 29937 } 29938 } else { 29939 reg = mask_reg[index]; 29940 if (reg == INVALIDr) { 29941 continue; 29942 } 29943 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, ingress_port, 0, &rval)); 29944 if (SOC_REG_IS_64(unit, reg)) { 29945 if (egress_port < 32) { 29946 if (soc_reg_field_valid(unit, reg, BLK_BITMAP_LOf)) { 29947 field = BLK_BITMAP_LOf; 29948 } else { 29949 field = BLK_BITMAP_0f; 29950 } 29951 } else { 29952 if (soc_reg_field_valid(unit, reg, BLK_BITMAP_HIf)) { 29953 field = BLK_BITMAP_HIf; 29954 } else { 29955 field = BLK_BITMAP_1f; 29956 } 29957 } 29958 } else { 29959 field = BLK_BITMAPf; 29960 } 29961 fval = soc_reg64_field32_get(unit, reg, rval, field); 29962 if (!set_op) { 29963 *enable = fval & (1 << (egress_port & 0x1f)) ? mode : 0; 29964 return BCM_E_NONE; 29965 } 29966 if (*enable & mode) { 29967 fval |= 1 << (egress_port & 0x1f); 29968 } else { 29969 fval &= ~(1 << (egress_port & 0x1f)); 29970 } 29971 soc_reg64_field32_set(unit, reg, &rval, field, fval); 29972 BCM_IF_ERROR_RETURN(soc_reg_set(unit, reg, ingress_port, 0, rval)); 29973 } 29974 } 29975 } 29976 29977 return BCM_E_NONE; 29978 } 29979 29980 #if defined(BCM_RAPTOR_SUPPORT) 29981 /* 29982 * Function: 29983 * _bcm_port_flood_block_hi_set 29984 * Purpose: 29985 * Enable/disable port membership in one of the egress block registers 29986 * Parameters: 29987 * unit 29988 * ingress_port - ingress port on which the egress blocking 29989 * will be enabled 29990 * egress_port - port for which egress will be blocked 29991 * reg - egress block register. 29992 * enable - Whether blocking should be enabled or disabled 29993 * Returns: 29994 * BCM_E_UNAVAIL - This chip does not support this feature 29995 * BCM_E_NONE 29996 * Notes: 29997 * 'reg' must be one of BCAST_BLOCK_MASKr, 29998 * UNKNOWN_UCAST_BLOCK_MASKr, UNKNOWN_MCAST_BLOCK_MASKr, or 29999 * their Stack port variants. 30000 * 30001 * This function is a helper for bcm_port_flood_block_set() 30002 */ 30003 30004 STATIC int 30005 _bcm_port_flood_block_hi_set(int unit, 30006 bcm_port_t ingress_port, bcm_port_t egress_port, 30007 soc_reg_t reg, uint32 enable) 30008 { 30009 uint32 rval; 30010 pbmp_t pbmp; 30011 uint32 pbmp32; 30012 uint32 bitmap32, obitmap32; 30013 30014 if (!soc_feature(unit, soc_feature_register_hi)) { 30015 return BCM_E_UNAVAIL; 30016 } 30017 30018 SOC_PBMP_PORT_SET(pbmp, egress_port); 30019 pbmp32 = SOC_PBMP_WORD_GET(pbmp, 1); 30020 30021 if (!pbmp32) { 30022 return BCM_E_NONE; 30023 } 30024 30025 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, ingress_port, 0, &rval)); 30026 30027 obitmap32 = bitmap32 = soc_reg_field_get(unit, reg, rval, BLK_BITMAPf); 30028 if (enable) { 30029 bitmap32 |= pbmp32; 30030 } else { 30031 bitmap32 &= ~pbmp32; 30032 } 30033 30034 if (obitmap32 != bitmap32) { 30035 soc_reg_field_set(unit, reg, &rval, BLK_BITMAPf, bitmap32); 30036 return soc_reg32_set(unit, reg, ingress_port, 0, rval); 30037 } 30038 30039 return BCM_E_NONE; 30040 } 30041 30042 /* 30043 * Function: 30044 * _bcm_port_flood_block_hi_get 30045 * Purpose: 30046 * Retrieve the current state egress block state on a port 30047 * Parameters: 30048 * unit 30049 * ingress_port - ingress_port for which the state will be retreived 30050 * egress_port - port for which the egress blocking state 30051 * on ingress_port is requested 30052 * reg - block mask register 30053 * enable - (OUT) receives the block state 30054 * Returns: 30055 * BCM_E_UNAVAIL - Feature unavailable on this chip 30056 * BCM_E_NONE 30057 * Notes: 30058 * See _bcm_port_flood_block_hi_set() 30059 * This is a helper function for bcm_port_flood_block_get() 30060 */ 30061 30062 STATIC int 30063 _bcm_port_flood_block_hi_get(int unit, 30064 bcm_port_t ingress_port, bcm_port_t egress_port, 30065 soc_reg_t reg, uint32 *enable) 30066 { 30067 uint32 rval; 30068 pbmp_t pbmp; 30069 uint32 pbmp32; 30070 uint32 bitmap32; 30071 30072 if (!soc_feature(unit, soc_feature_register_hi)) { 30073 return BCM_E_UNAVAIL; 30074 } 30075 30076 SOC_PBMP_PORT_SET(pbmp, egress_port); 30077 pbmp32 = SOC_PBMP_WORD_GET(pbmp, 1); 30078 if (!pbmp32) { 30079 *enable = 0; 30080 return BCM_E_NONE; 30081 } 30082 30083 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, ingress_port, 0, &rval)); 30084 30085 bitmap32 = soc_reg_field_get(unit, reg, rval, BLK_BITMAPf); 30086 *enable = (pbmp32 & bitmap32) ? 1 : 0; 30087 30088 return BCM_E_NONE; 30089 } 30090 #endif /* BCM_RAPTOR_SUPPORT */ 30091 30092 /* 30093 * Function: 30094 * bcm_port_flood_block_set 30095 * Purpose: 30096 * Set selective per-port blocking of flooded VLAN traffic 30097 * Parameters: 30098 * unit - unit number 30099 * ingress_port - Port traffic is ingressing 30100 * egress_port - Port for which the traffic should be blocked. 30101 * flags - Specifies the type of traffic to block 30102 * Returns: 30103 * BCM_E_UNAVAIL - Functionality not available 30104 * BCM_E_NONE 30105 * 30106 * NOTE: For fabrics, this changes egrmskbmap; as a result, all traffic 30107 * will be blocked (or enabled) to the given egress port, including 30108 * unicast traffic. 30109 */ 30110 30111 int 30112 bcm_esw_port_flood_block_set(int unit, 30113 bcm_port_t ingress_port, bcm_port_t egress_port, 30114 uint32 flags) 30115 { 30116 /* Make sure port module is initialized. */ 30117 PORT_INIT(unit); 30118 30119 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, ingress_port, 30120 &ingress_port)); 30121 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, egress_port, 30122 &egress_port)); 30123 30124 #if defined(BCM_XGS12_FABRIC_SUPPORT) 30125 /* See note above */ 30126 if (SOC_IS_XGS12_FABRIC(unit)) { 30127 uint32 ports, oports; 30128 pbmp_t pbmp; 30129 30130 if (!IS_HG_PORT(unit, ingress_port)) { 30131 return BCM_E_PORT; 30132 } 30133 30134 SOC_IF_ERROR_RETURN 30135 (READ_ING_EGRMSKBMAPr(unit, ingress_port, &ports)); 30136 oports = ports; 30137 SOC_PBMP_CLEAR(pbmp); 30138 SOC_PBMP_WORD_SET(pbmp, 0, ports); 30139 if (flags) { 30140 SOC_PBMP_PORT_REMOVE(pbmp, egress_port); 30141 } else { 30142 SOC_PBMP_PORT_ADD(pbmp, egress_port); 30143 } 30144 ports = SOC_PBMP_WORD_GET(pbmp, 0); 30145 if (ports != oports) { 30146 SOC_IF_ERROR_RETURN 30147 (WRITE_ING_EGRMSKBMAPr(unit, ingress_port, ports)); 30148 } 30149 return BCM_E_NONE; 30150 } 30151 #endif /* BCM_XGS12_FABRIC_SUPPORT */ 30152 30153 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 30154 || defined(BCM_BRADLEY_SUPPORT) 30155 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit)|| 30156 SOC_IS_HBX(unit) || SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) { 30157 BCM_IF_ERROR_RETURN 30158 (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port, 30159 BCM_PORT_FLOOD_BLOCK_ALL, &flags)); 30160 } 30161 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || \ 30162 BCM_BRADLEY_SUPPORT */ 30163 30164 BCM_IF_ERROR_RETURN 30165 (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port, 30166 BCM_PORT_FLOOD_BLOCK_BCAST, &flags)); 30167 30168 BCM_IF_ERROR_RETURN 30169 (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port, 30170 BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST, &flags)); 30171 30172 /* 30173 * For some devices like RAVEN , which do not have support for 30174 * blocking KNOWN_MCAST , continue processing. 30175 */ 30176 BCM_IF_ERROR_NOT_UNAVAIL_RETURN 30177 (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port, 30178 BCM_PORT_FLOOD_BLOCK_KNOWN_MCAST, &flags)); 30179 30180 BCM_IF_ERROR_RETURN 30181 (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port, 30182 BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST, &flags)); 30183 30184 /* 30185 * Handle the devices with > 32 ports that use _HI convention 30186 */ 30187 #if defined(BCM_RAPTOR_SUPPORT) 30188 if (soc_feature(unit, soc_feature_register_hi)){ 30189 soc_reg_t reg; 30190 uint32 enable; 30191 reg = IS_ST_PORT(unit, ingress_port) ? 30192 IUNKNOWN_UCAST_BLOCK_MASK_HIr : UNKNOWN_UCAST_BLOCK_MASK_HIr; 30193 enable = flags & BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST; 30194 BCM_IF_ERROR_RETURN 30195 (_bcm_port_flood_block_hi_set(unit, ingress_port, egress_port, 30196 reg, enable)); 30197 30198 reg = IS_ST_PORT(unit, ingress_port) ? 30199 IUNKNOWN_MCAST_BLOCK_MASK_HIr : UNKNOWN_MCAST_BLOCK_MASK_HIr; 30200 enable = flags & BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST; 30201 BCM_IF_ERROR_RETURN 30202 (_bcm_port_flood_block_hi_set(unit, ingress_port, egress_port, 30203 reg, enable)); 30204 30205 reg = IS_ST_PORT(unit, ingress_port) ? 30206 IBCAST_BLOCK_MASK_HIr : BCAST_BLOCK_MASK_HIr; 30207 enable = flags & BCM_PORT_FLOOD_BLOCK_BCAST; 30208 BCM_IF_ERROR_RETURN 30209 (_bcm_port_flood_block_hi_set(unit, ingress_port, egress_port, 30210 reg, enable)); 30211 } 30212 #endif /* BCM_RAPTOR_SUPPORT */ 30213 30214 return BCM_E_NONE; 30215 } 30216 30217 /* 30218 * Function: 30219 * bcm_port_flood_block_get 30220 * Purpose: 30221 * Get the current per-port flood block settings 30222 * Parameters: 30223 * unit - unit number 30224 * ingress_port - Port traffic is ingressing 30225 * egress_port - Port for which the traffic would be blocked 30226 * flags - (OUT) Returns the current settings 30227 * Returns: 30228 * BCM_E_UNAVAIL - Functionality not available 30229 * BCM_E_NONE 30230 */ 30231 30232 int 30233 bcm_esw_port_flood_block_get(int unit, 30234 bcm_port_t ingress_port, bcm_port_t egress_port, 30235 uint32 *flags) 30236 { 30237 uint32 enable; 30238 30239 /* Make sure port module is initialized. */ 30240 PORT_INIT(unit); 30241 30242 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, ingress_port, 30243 &ingress_port)); 30244 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, egress_port, 30245 &egress_port)); 30246 30247 *flags = 0; 30248 30249 #if defined(BCM_XGS12_FABRIC_SUPPORT) 30250 if (SOC_IS_XGS12_FABRIC(unit)) { 30251 uint32 ports; 30252 pbmp_t pbmp; 30253 30254 if (!IS_HG_PORT(unit, ingress_port)) { 30255 return BCM_E_PORT; 30256 } 30257 30258 SOC_IF_ERROR_RETURN 30259 (READ_ING_EGRMSKBMAPr(unit, ingress_port, &ports)); 30260 SOC_PBMP_CLEAR(pbmp); 30261 SOC_PBMP_WORD_SET(pbmp, 0, ports); 30262 if (!SOC_PBMP_MEMBER(pbmp, egress_port)) { 30263 *flags = -1; 30264 } 30265 return BCM_E_NONE; 30266 } 30267 #endif 30268 30269 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 30270 || defined(BCM_BRADLEY_SUPPORT) 30271 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit)|| 30272 SOC_IS_HBX(unit) || SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) { 30273 BCM_IF_ERROR_RETURN 30274 (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port, 30275 BCM_PORT_FLOOD_BLOCK_ALL, &enable)); 30276 *flags |= enable; 30277 } 30278 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_BRADLEY_SUPPORT */ 30279 30280 BCM_IF_ERROR_RETURN 30281 (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port, 30282 BCM_PORT_FLOOD_BLOCK_BCAST, &enable)); 30283 *flags |= enable; 30284 30285 BCM_IF_ERROR_RETURN 30286 (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port, 30287 BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST, 30288 &enable)); 30289 *flags |= enable; 30290 30291 /* 30292 * For some devices like RAVEN , which do not have support for 30293 * blocking KNOWN_MCAST , continue processing. 30294 */ 30295 BCM_IF_ERROR_NOT_UNAVAIL_RETURN 30296 (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port, 30297 BCM_PORT_FLOOD_BLOCK_KNOWN_MCAST, 30298 &enable)); 30299 *flags |= enable; 30300 30301 BCM_IF_ERROR_RETURN 30302 (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port, 30303 BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST, 30304 &enable)); 30305 *flags |= enable; 30306 30307 #if defined(BCM_RAPTOR_SUPPORT) 30308 if (soc_feature(unit, soc_feature_register_hi)){ 30309 soc_reg_t reg; 30310 reg = IS_ST_PORT(unit, ingress_port) ? 30311 IBCAST_BLOCK_MASK_HIr : BCAST_BLOCK_MASK_HIr; 30312 BCM_IF_ERROR_RETURN 30313 (_bcm_port_flood_block_hi_get(unit, ingress_port, egress_port, 30314 reg, &enable)); 30315 *flags |= (enable) ? BCM_PORT_FLOOD_BLOCK_BCAST : 0; 30316 30317 reg = IS_ST_PORT(unit, ingress_port) ? 30318 IUNKNOWN_MCAST_BLOCK_MASK_HIr : UNKNOWN_MCAST_BLOCK_MASK_HIr; 30319 BCM_IF_ERROR_RETURN 30320 (_bcm_port_flood_block_hi_get(unit, ingress_port, egress_port, 30321 reg, &enable)); 30322 *flags |= (enable) ? BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST : 0; 30323 30324 reg = IS_ST_PORT(unit, ingress_port) ? 30325 IUNKNOWN_UCAST_BLOCK_MASK_HIr : UNKNOWN_UCAST_BLOCK_MASK_HIr; 30326 BCM_IF_ERROR_RETURN 30327 (_bcm_port_flood_block_hi_get(unit, ingress_port, egress_port, 30328 reg, &enable)); 30329 *flags |= (enable) ? BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST : 0; 30330 } 30331 #endif /* BCM_RAPTOR_SUPPORT */ 30332 30333 return BCM_E_NONE; 30334 } 30335 30336 /* 30337 * Per-port leaky bucket ingress and egress rate limiting 30338 * 30339 * Granularity is in kbits/sec and a rate of 0 disables rate limiting. 30340 * The max burst size is set in kbits. 30341 */ 30342 30343 /* 30344 * Function: 30345 * bcm_port_rate_egress_set 30346 * Purpose: 30347 * Set egress rate limiting parameters 30348 * Parameters: 30349 * unit - Device number 30350 * port - Port number 30351 * kbits_sec - Rate in kilobits (1000 bits) per second. 30352 * Rate of 0 disables rate limiting. 30353 * kbits_burst - Maximum burst size in kilobits (1000 bits). 30354 * Returns: 30355 * BCM_E_XXX 30356 */ 30357 30358 int 30359 bcm_esw_port_rate_egress_set(int unit, 30360 bcm_port_t port, 30361 uint32 kbits_sec, 30362 uint32 kbits_burst) 30363 { 30364 /* Make sure port module is initialized. */ 30365 PORT_INIT(unit); 30366 30367 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30368 30369 if (!soc_feature(unit, soc_feature_egress_metering)) { 30370 return BCM_E_UNAVAIL; 30371 } else { 30372 return mbcm_driver[unit]->mbcm_port_rate_egress_set(unit, port, 30373 kbits_sec, 30374 kbits_burst, 30375 _BCM_PORT_RATE_BYTE_MODE); 30376 } 30377 30378 return BCM_E_NONE; 30379 } 30380 30381 /* 30382 * Function: 30383 * bcm_port_rate_egress_pps_set 30384 * Purpose: 30385 * Set egress rate limiting parameter in packet mode. 30386 * Parameters: 30387 * unit - Device number 30388 * port - Port number 30389 * pps - Rate in pps 30390 * Rate of 0 disables rate limiting. 30391 * burst - Maximum burst size 30392 * Returns: 30393 * BCM_E_XXX 30394 */ 30395 30396 int 30397 bcm_esw_port_rate_egress_pps_set(int unit, 30398 bcm_port_t port, 30399 uint32 pps, 30400 uint32 burst) 30401 { 30402 /* Make sure port module is initialized. */ 30403 PORT_INIT(unit); 30404 30405 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30406 30407 if (!soc_feature(unit, soc_feature_egress_metering)) { 30408 return BCM_E_UNAVAIL; 30409 } else { 30410 return mbcm_driver[unit]->mbcm_port_rate_egress_set(unit, port, 30411 pps, 30412 burst, 30413 _BCM_PORT_RATE_PPS_MODE); 30414 } 30415 30416 return BCM_E_NONE; 30417 } 30418 30419 30420 /* 30421 * Function: 30422 * bcm_port_rate_egress_get 30423 * Purpose: 30424 * Get egress rate limiting parameters 30425 * Parameters: 30426 * unit - Device number 30427 * port - Port number 30428 * kbits_sec - (OUT) Rate in kilobits (1000 bits) per second, or 30429 * zero if rate limiting is disabled. 30430 * kbits_burst - (OUT) Maximum burst size in kilobits (1000 bits). 30431 * Returns: 30432 * BCM_E_XXX 30433 */ 30434 30435 int 30436 bcm_esw_port_rate_egress_get(int unit, 30437 bcm_port_t port, 30438 uint32 *kbits_sec, 30439 uint32 *kbits_burst) 30440 { 30441 uint32 flags = 0; 30442 int rv = BCM_E_NONE; 30443 30444 /* Make sure port module is initialized. */ 30445 PORT_INIT(unit); 30446 30447 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30448 30449 if (!soc_feature(unit, soc_feature_egress_metering)) { 30450 return BCM_E_UNAVAIL; 30451 } else { 30452 rv = mbcm_driver[unit]->mbcm_port_rate_egress_get(unit, port, 30453 kbits_sec, 30454 kbits_burst, 30455 &flags); 30456 } 30457 30458 if (BCM_SUCCESS(rv)) { 30459 if (flags == _BCM_PORT_RATE_BYTE_MODE) { 30460 return BCM_E_NONE; 30461 } else { 30462 /* Set as pps; kbits cannot be returned */ 30463 return BCM_E_CONFIG; 30464 } 30465 } 30466 30467 return rv; 30468 } 30469 30470 /* 30471 * Function: 30472 * bcm_port_rate_egress_pps_get 30473 * Purpose: 30474 * Get egress rate limiting parameter in packet mode. 30475 * Parameters: 30476 * unit - Device number 30477 * port - Port number 30478 * pps - (OUT) Rate in pps 30479 * 0 if rate limiting is disabled 30480 * burst -(OUT) burst size 30481 * Returns: 30482 * BCM_E_XXX 30483 */ 30484 30485 int 30486 bcm_esw_port_rate_egress_pps_get(int unit, 30487 bcm_port_t port, 30488 uint32 *pps, 30489 uint32 *burst) 30490 { 30491 uint32 flags = 0; 30492 int rv = BCM_E_NONE; 30493 30494 /* Make sure port module is initialized. */ 30495 PORT_INIT(unit); 30496 30497 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30498 30499 if (!soc_feature(unit, soc_feature_egress_metering)) { 30500 return BCM_E_UNAVAIL; 30501 } else { 30502 rv = mbcm_driver[unit]->mbcm_port_rate_egress_get(unit, port, 30503 pps, 30504 burst, 30505 &flags); 30506 } 30507 30508 if (BCM_SUCCESS(rv)) { 30509 if (flags == _BCM_PORT_RATE_PPS_MODE) { 30510 return BCM_E_NONE; 30511 } else { 30512 /* Set as kbits; pps cannot be returned */ 30513 return BCM_E_CONFIG; 30514 } 30515 } 30516 return rv; 30517 } 30518 30519 /* 30520 * Function: 30521 * bcm_port_rate_ingress_set 30522 * Purpose: 30523 * Set ingress rate limiting parameters 30524 * Parameters: 30525 * unit - Device number 30526 * port - Port number 30527 * kbits_sec - Rate in kilobits (1000 bits) per second. 30528 * Rate of 0 disables rate limiting. 30529 * kbits_burst - Maximum burst size in kilobits (1000 bits). 30530 * Returns: 30531 * BCM_E_XXX 30532 */ 30533 30534 int 30535 bcm_esw_port_rate_ingress_set(int unit, 30536 bcm_port_t port, 30537 uint32 kbits_sec, 30538 uint32 kbits_burst) 30539 { 30540 /* Make sure port module is initialized. */ 30541 PORT_INIT(unit); 30542 30543 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30544 30545 #ifdef BCM_XGS3_SWITCH_SUPPORT 30546 if (SOC_IS_XGS3_SWITCH(unit)) { 30547 /* 30548 * Use port-based ingress metering function. 30549 * Enabling rate-based ingress metering on the Firebolt 30550 * will also enable rate-based pause frames on this port. 30551 */ 30552 return bcm_xgs3_port_rate_ingress_set(unit, port, kbits_sec, 30553 kbits_burst); 30554 } 30555 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 30556 30557 return BCM_E_UNAVAIL; 30558 } 30559 30560 /* 30561 * Function: 30562 * bcm_port_rate_ingress_get 30563 * Purpose: 30564 * Get ingress rate limiting parameters 30565 * Parameters: 30566 * unit - Device number 30567 * port - Port number 30568 * kbits_sec - (OUT) Rate in kilobits (1000 bits) per second, or 30569 * zero if rate limiting is disabled. 30570 * kbits_burst - (OUT) Maximum burst size in kilobits (1000 bits). 30571 * Returns: 30572 * BCM_E_XXX 30573 */ 30574 30575 int 30576 bcm_esw_port_rate_ingress_get(int unit, 30577 bcm_port_t port, 30578 uint32 *kbits_sec, 30579 uint32 *kbits_burst) 30580 { 30581 /* Make sure port module is initialized. */ 30582 PORT_INIT(unit); 30583 30584 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30585 30586 if (!kbits_sec || !kbits_burst) { 30587 return BCM_E_PARAM; 30588 } 30589 30590 #ifdef BCM_XGS3_SWITCH_SUPPORT 30591 if (SOC_IS_XGS3_SWITCH(unit)) { 30592 /* Use port-based ingress metering function */ 30593 return bcm_xgs3_port_rate_ingress_get(unit, port, kbits_sec, 30594 kbits_burst); 30595 } 30596 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 30597 30598 *kbits_sec = 0; 30599 *kbits_burst = 0; 30600 30601 return BCM_E_UNAVAIL; 30602 } 30603 30604 /* 30605 * Function: 30606 * bcm_port_rate_pause_set 30607 * Purpose: 30608 * Set ingress rate limiting pause frame control parameters 30609 * Parameters: 30610 * unit - Device number 30611 * port - Port number 30612 * kbits_pause - Pause threshold in kbits (1000 bits). 30613 * A value of zero disables the pause/resume mechanism. 30614 * kbits_resume - Resume threshold in kbits (1000 bits). 30615 * Returns: 30616 * BCM_E_XXX 30617 * Notes: 30618 * This interface applies only when port ingress rate limiting 30619 * is active. Currently, only the 566x supports this feature. 30620 * 30621 * If the maximum of bits that could be received before dropping a 30622 * frame falls below the kbits_pause, a pause frame is sent. 30623 * A resume frame will be sent once it becomes possible to receive 30624 * kbits_resume bits of data without dropping. 30625 */ 30626 30627 int 30628 bcm_esw_port_rate_pause_set(int unit, 30629 bcm_port_t port, 30630 uint32 kbits_pause, 30631 uint32 kbits_resume) 30632 { 30633 /* Make sure port module is initialized. */ 30634 PORT_INIT(unit); 30635 30636 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30637 30638 #ifdef BCM_FIREBOLT_SUPPORT 30639 /* 30640 * For Firebolt, rate-based pause frames are generated as 30641 * a result of rate-based metering. As such, their behavior 30642 * is not directly controllable, but may be read. 30643 * see bcm_port_rate_pause_get(). 30644 */ 30645 #endif /* BCM_FIREBOLT_SUPPORT */ 30646 /* Otherwise, not supported */ 30647 return (kbits_pause == 0) ? BCM_E_NONE : BCM_E_UNAVAIL; 30648 } 30649 30650 /* 30651 * Function: 30652 * bcm_port_rate_pause_get 30653 * Purpose: 30654 * Get ingress rate limiting pause frame control parameters 30655 * Parameters: 30656 * unit - Device number 30657 * port - Port number 30658 * kbits_pause - (OUT) Pause threshold in kbits (1000 bits). 30659 * Zero indicates the pause/resume mechanism is disabled. 30660 * kbits_resume - (OUT) Resume threshold in kbits (1000 bits). 30661 * Returns: 30662 * BCM_E_XXX 30663 */ 30664 30665 int 30666 bcm_esw_port_rate_pause_get(int unit, 30667 bcm_port_t port, 30668 uint32 *kbits_pause, 30669 uint32 *kbits_resume) 30670 { 30671 /* Make sure port module is initialized. */ 30672 PORT_INIT(unit); 30673 30674 #if defined(BCM_HGPROXY_COE_SUPPORT) 30675 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 30676 (soc_feature(unit, soc_feature_channelized_switching))) && 30677 BCM_GPORT_IS_SET(port) && 30678 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 30679 return BCM_E_PORT; 30680 } else 30681 #endif /* BCM_HGPROXY_COE_SUPPORT */ 30682 30683 #if defined(BCM_KATANA2_SUPPORT) 30684 if (BCM_GPORT_IS_SET(port) && 30685 _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)) { 30686 return BCM_E_PORT; 30687 } 30688 #endif 30689 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30690 30691 #ifdef BCM_MONTEREY_SUPPORT 30692 if (SOC_IS_MONTEREY(unit)) { 30693 *kbits_pause = 0; 30694 *kbits_resume = 0; 30695 return BCM_E_UNAVAIL; 30696 } else 30697 #endif 30698 #ifdef BCM_TOMAHAWK_SUPPORT 30699 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 30700 *kbits_pause = 0; 30701 *kbits_resume = 0; 30702 return BCM_E_UNAVAIL; 30703 } else 30704 #endif /* BCM_TOMAHAWK_SUPPORT */ 30705 #ifdef BCM_TRIDENT2_SUPPORT 30706 if (SOC_IS_TD2_TT2(unit)) { 30707 return bcm_td2_port_rate_pause_get(unit, port, kbits_pause, 30708 kbits_resume); 30709 } else 30710 #endif /* BCM_TRIDENT2_SUPPORT */ 30711 #ifdef BCM_TRIUMPH_SUPPORT 30712 if (SOC_IS_TR_VL(unit) && !SOC_IS_HURRICANEX(unit) && 30713 !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) { 30714 return bcm_tr_port_rate_pause_get(unit, port, kbits_pause, 30715 kbits_resume); 30716 } 30717 #endif /* BCM_TRIUMPH_SUPPORT */ 30718 #ifdef BCM_FIREBOLT_SUPPORT 30719 if (SOC_IS_FBX(unit)) { 30720 return bcm_fb_port_rate_pause_get(unit, port, kbits_pause, 30721 kbits_resume); 30722 } 30723 #endif /* BCM_FIREBOLT_SUPPORT */ 30724 /* Otherwise, not supported */ 30725 *kbits_pause = 0; 30726 *kbits_resume = 0; 30727 return BCM_E_UNAVAIL; 30728 } 30729 30730 /* 30731 * Function: 30732 * bcm_port_sample_rate_set 30733 * Purpose: 30734 * Control the sampling of packets ingressing or egressing a port 30735 * Parameters: 30736 * unit - Device number 30737 * port - Port number 30738 * ingress_rate - Every 1/ingress_rate packets will be sampled 30739 * 0 indicates no sampling 30740 * 1 indicates sampling all packets 30741 * egress_rate - Every 1/egress_rate packets will be sampled 30742 * 0 indicates no sampling 30743 * 1 indicates sampling all packets 30744 * Returns: 30745 * BCM_E_XXX 30746 * Notes: 30747 * This API is a building block for supporting sFlow (RFC 3176) 30748 */ 30749 30750 int 30751 bcm_esw_port_sample_rate_set(int unit, bcm_port_t port, 30752 int ingress_rate, int egress_rate) 30753 { 30754 /* Make sure port module is initialized. */ 30755 PORT_INIT(unit); 30756 30757 /* 30758 * IMPLEMENTATION NOTES 30759 * 30760 * ingress_rate maps into the per port SFLOW_ING_THRESHOLD reg: 30761 * if (ingress_rate <= 0) { 30762 * SFLOW_ING_THRESHOLD.ENABLE=0 30763 * SFLOW_ING_THRESHOLD.THRESHOLD=0 30764 * } else { 30765 * SFLOW_ING_THRESHOLD.ENABLE=1 30766 * SFLOW_ING_THRESHOLD.THRESHOLD=0xffff/ingress_rate 30767 * } 30768 * egress_rate maps into the per port SFLOW_EGR_THRESHOLD reg: 30769 * if (egress_rate <= 0) { 30770 * SFLOW_EGR_THRESHOLD.ENABLE=0 30771 * SFLOW_EGR_THRESHOLD.THRESHOLD=0 30772 * } else { 30773 * SFLOW_EGR_THRESHOLD.ENABLE=1 30774 * SFLOW_EGR_THRESHOLD.THRESHOLD=0xffff/egress_rate 30775 * } 30776 * 30777 * bcmSwitchCpuSamplePrio maps to CPU_CONTROL_2.CPU_SFLOW_PRIORITY 30778 * bcmSwitchSampleIngressRandomSeed maps to SFLOW_ING_RAND_SEED.SEED 30779 * bcmSwitchSampleEgressRandomSeed maps to SFLOW_EGR_RAND_SEED.SEED 30780 * 30781 * There are two related RX reason codes defined in <bcm/rx.h> 30782 * BCM_RX_PR_SAMPLE_SRC 30783 * BCM_RX_PR_SAMPLE_DST 30784 */ 30785 30786 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30787 if (ingress_rate < 0 || egress_rate < 0) { 30788 return BCM_E_PARAM; 30789 } 30790 30791 #ifdef BCM_XGS3_SWITCH_SUPPORT 30792 if (SOC_IS_XGS3_SWITCH(unit)) { 30793 return bcm_xgs3_port_sample_rate_set(unit, port, 30794 ingress_rate, egress_rate); 30795 } 30796 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 30797 30798 return BCM_E_UNAVAIL; 30799 } 30800 30801 /* 30802 * Function: 30803 * bcm_port_sample_rate_get 30804 * Purpose: 30805 * Get the sampling of packets ingressing or egressing a port 30806 * Parameters: 30807 * unit - Device number 30808 * port - Port number 30809 * ingress_rate - Every 1/ingress_rate packets will be sampled 30810 * 0 indicates no sampling 30811 * 1 indicates sampling all packets 30812 * egress_rate - Every 1/egress_rate packets will be sampled 30813 * 0 indicates no sampling 30814 * 1 indicates sampling all packets 30815 * Returns: 30816 * BCM_E_UNIT 30817 * BCM_E_PARAM 30818 * BCM_E_UNAVAIL 30819 * BCM_E_XXX 30820 * Notes: 30821 * This API is a building block for supporting sFlow (RFC 3176) 30822 */ 30823 30824 int 30825 bcm_esw_port_sample_rate_get(int unit, bcm_port_t port, 30826 int *ingress_rate, int *egress_rate) 30827 { 30828 /* Make sure port module is initialized. */ 30829 PORT_INIT(unit); 30830 30831 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30832 30833 if (ingress_rate == NULL || egress_rate == NULL) { 30834 return BCM_E_PARAM; 30835 } 30836 30837 #ifdef BCM_XGS3_SWITCH_SUPPORT 30838 if (SOC_IS_XGS3_SWITCH(unit)) { 30839 return bcm_xgs3_port_sample_rate_get(unit, port, 30840 ingress_rate, egress_rate); 30841 } 30842 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 30843 30844 30845 return BCM_E_UNAVAIL; 30846 } 30847 30848 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 30849 #ifdef BCM_WARM_BOOT_SUPPORT 30850 STATIC int 30851 _bcm_esw_sflow_counter_wb_recover(int unit, soc_mem_t mem) 30852 { 30853 int idx_min, idx_max, i, id, rv = 0; 30854 soc_counter_non_dma_t *non_dma = NULL; 30855 soc_control_t *soc; 30856 uint32 count = 0, subset_ct = 0, sflow_enable = 0; 30857 uint8 *sflow_tbl_chunk = NULL; 30858 void *sflow_entry; 30859 30860 soc = SOC_CONTROL(unit); 30861 30862 idx_min = soc_mem_index_min(unit, mem); 30863 idx_max = soc_mem_index_max(unit, mem); 30864 sflow_tbl_chunk = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem), 30865 "sFlow Ingress Data Source table buffer"); 30866 if (sflow_tbl_chunk == NULL) { 30867 return BCM_E_MEMORY; 30868 } 30869 30870 /* Read Ingress rate data table entries */ 30871 sal_memset(sflow_tbl_chunk, 0, SOC_MEM_TABLE_BYTES(unit, mem)); 30872 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max, 30873 sflow_tbl_chunk); 30874 if (SOC_FAILURE(rv)) { 30875 soc_cm_sfree(unit, sflow_tbl_chunk); 30876 return rv; 30877 } 30878 30879 if (mem == SFLOW_ING_DATA_SOURCEm) { 30880 id = SOC_COUNTER_NON_DMA_SFLOW_ING_PKT; 30881 } else { 30882 id = SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT; 30883 } 30884 30885 for(i = idx_min; i < idx_max; i++) { 30886 sflow_entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 30887 sflow_tbl_chunk, i); 30888 sflow_enable = soc_mem_field32_get(unit, mem, sflow_entry, ENABLEf); 30889 30890 if (sflow_enable) { 30891 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 30892 /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */ 30893 subset_ct = non_dma->extra_ctr_ct << 1; 30894 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 30895 non_dma = non_dma->extra_ctrs; 30896 30897 do { 30898 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 30899 /* BYTE_CTRf not currently supported */ 30900 count += 2; 30901 non_dma += 2; 30902 } while ((count < subset_ct)); 30903 break; 30904 } 30905 } 30906 30907 soc_cm_sfree(unit, sflow_tbl_chunk); 30908 return BCM_E_NONE; 30909 } 30910 30911 /** 30912 * Function: 30913 * _bcm_esw_sflow_wb_recover 30914 * Purpose: 30915 * sFlow Warmboot Recovery 30916 * Parameters: 30917 * unit - (IN) Unit number 30918 * Returns: 30919 * BCM_E_xxx 30920 */ 30921 STATIC int 30922 _bcm_esw_sflow_wb_recover(int unit) { 30923 int rv = 0; 30924 30925 if (soc_feature(unit, soc_feature_sflow_ing_mem)) { 30926 rv = _bcm_esw_sflow_counter_wb_recover(unit, SFLOW_ING_DATA_SOURCEm); 30927 if (BCM_FAILURE(rv)) { 30928 return rv; 30929 } 30930 } 30931 30932 if (soc_feature(unit, soc_feature_sflow_flex)) { 30933 rv = _bcm_esw_sflow_counter_wb_recover(unit, 30934 SFLOW_ING_FLEX_DATA_SOURCEm); 30935 if (BCM_FAILURE(rv)) { 30936 return rv; 30937 } 30938 } 30939 30940 return BCM_E_NONE; 30941 } 30942 #endif /* BCM_WARM_BOOT_SUPPORT */ 30943 #endif /* BCM_TOMAHAWK_SUPPORT */ 30944 30945 /* 30946 * Double Tagging 30947 */ 30948 30949 /* 30950 * Function: 30951 * bcm_port_dtag_mode_set 30952 * Description: 30953 * Set the double-tagging mode of a port. 30954 * Parameters: 30955 * unit - Device number 30956 * port - Port number 30957 * mode - Double-tagging mode, one of: 30958 * BCM_PORT_DTAG_MODE_NONE No double tagging 30959 * BCM_PORT_DTAG_MODE_INTERNAL Service Provider port 30960 * BCM_PORT_DTAG_MODE_EXTERNAL Customer port 30961 * BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG Remove customer tag 30962 * BCM_PORT_DTAG_ADD_EXTERNAL_TAG Add customer tag 30963 * Return Value: 30964 * BCM_E_XXX 30965 * Notes: 30966 * BCM_PORT_DTAG_MODE_INTERNAL is for service provider ports. 30967 * A tag will be added if the packet does not already 30968 * have the internal TPID (see bcm_port_tpid_set below). 30969 * Internally this sets DT_MODE and clears IGNORE_TAG. 30970 * BCM_PORT_DTAG_MODE_EXTERNAL is for customer ports. 30971 * The service provider TPID will always be added 30972 * (see bcm_port_tpid_set below). 30973 * Internally this sets DT_MODE and sets IGNORE_TAG. 30974 * On some chips, such as BCM5665, double-tag enable is a system-wide 30975 * setting rather than a port setting, so enabling double- 30976 * tagging on one port may enable it on all ports. 30977 */ 30978 30979 int 30980 bcm_esw_port_dtag_mode_set(int unit, bcm_port_t port, int mode) 30981 { 30982 #ifdef BCM_FIREBOLT_SUPPORT 30983 int dt_mode, ignore_tag; 30984 #endif 30985 int dt_mode_mask; 30986 30987 /* Make sure port module is initialized. */ 30988 PORT_INIT(unit); 30989 30990 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30991 /* Skip PORT_SWITCHED_CHECK for Higig lookup (for q-in-q proxy) */ 30992 if (!(IS_ST_PORT(unit, port) && 30993 soc_feature(unit, soc_feature_higig_lookup))) { 30994 PORT_SWITCHED_CHECK(unit, port); 30995 } 30996 30997 dt_mode_mask = BCM_PORT_DTAG_MODE_INTERNAL | 30998 BCM_PORT_DTAG_MODE_EXTERNAL; 30999 31000 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT) 31001 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || \ 31002 SOC_IS_HAWKEYE(unit) || SOC_IS_TRX(unit)) { 31003 if (mode & ~(BCM_PORT_DTAG_MODE_INTERNAL | 31004 BCM_PORT_DTAG_MODE_EXTERNAL | 31005 BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG | 31006 BCM_PORT_DTAG_ADD_EXTERNAL_TAG)) { 31007 return BCM_E_UNAVAIL; 31008 } 31009 31010 if (IS_ST_PORT(unit, port)) { 31011 /* Addition or removal of two tags is not supported on 31012 * Higig / Higig Lite ports. 31013 */ 31014 if (mode & BCM_PORT_DTAG_ADD_EXTERNAL_TAG || 31015 mode & BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG) { 31016 return BCM_E_PARAM; 31017 } 31018 } 31019 31020 /* Removal of two tags should be enable only for UNI egress ports. */ 31021 if (mode == (BCM_PORT_DTAG_MODE_INTERNAL | 31022 BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG)) { 31023 return BCM_E_PARAM; 31024 } 31025 31026 #ifdef BCM_TRX_SUPPORT 31027 if (SOC_IS_TRX(unit)) { 31028 if (!soc_feature(unit, soc_feature_vlan_action)) { 31029 return BCM_E_UNAVAIL; 31030 } 31031 return _bcm_trx_port_dtag_mode_set(unit, port, mode); 31032 } 31033 #endif 31034 } else 31035 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 31036 if (0 != (mode & ~dt_mode_mask)) { 31037 /* Some devices do not support the add/remove tag options */ 31038 return BCM_E_UNAVAIL; 31039 } 31040 31041 #ifdef BCM_FIREBOLT_SUPPORT 31042 switch (mode & dt_mode_mask) { 31043 case BCM_PORT_DTAG_MODE_NONE: 31044 dt_mode = 0; 31045 ignore_tag = 0; 31046 break; 31047 case BCM_PORT_DTAG_MODE_INTERNAL: 31048 dt_mode = 1; 31049 ignore_tag = 0; 31050 break; 31051 case BCM_PORT_DTAG_MODE_EXTERNAL: 31052 dt_mode = 1; 31053 ignore_tag = 1; 31054 break; 31055 default: 31056 return BCM_E_PARAM; 31057 } 31058 31059 if (SOC_IS_FBX(unit)) { 31060 return _bcm_fb_port_dtag_mode_set(unit, port, mode, 31061 dt_mode, ignore_tag); 31062 } 31063 #endif 31064 return BCM_E_UNAVAIL; 31065 } 31066 31067 /* 31068 * Function: 31069 * bcm_port_dtag_mode_get 31070 * Description: 31071 * Return the current double-tagging mode of a port. 31072 * Parameters: 31073 * unit - Device number 31074 * port - Port number 31075 * mode - (OUT) Double-tagging mode 31076 * Return Value: 31077 * BCM_E_XXX 31078 */ 31079 31080 int 31081 bcm_esw_port_dtag_mode_get(int unit, bcm_port_t port, int *mode) 31082 { 31083 /* Make sure port module is initialized. */ 31084 PORT_INIT(unit); 31085 31086 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 31087 /* Skip PORT_SWITCHED_CHECK for Higig lookup (for q-in-q proxy) */ 31088 if (!(IS_ST_PORT(unit, port) && 31089 soc_feature(unit, soc_feature_higig_lookup))) { 31090 PORT_SWITCHED_CHECK(unit, port); 31091 } 31092 31093 if (mode == NULL) { 31094 return BCM_E_PARAM; 31095 } 31096 31097 #ifdef BCM_TRX_SUPPORT 31098 if (SOC_IS_TRX(unit)) { 31099 *mode = PORT(unit, port).dtag_mode; 31100 return BCM_E_NONE; 31101 } 31102 #endif 31103 31104 #ifdef BCM_FIREBOLT_SUPPORT 31105 if (SOC_IS_FBX(unit)) { 31106 return _bcm_fb_port_dtag_mode_get(unit, port, mode); 31107 } 31108 #endif 31109 31110 return BCM_E_UNAVAIL; 31111 } 31112 31113 /* 31114 * Function: 31115 * _bcm_esw_mod_port_tpid_set 31116 * Description: 31117 * Set the Tag Protocol ID for a (module, port). 31118 * Parameters: 31119 * unit - Device number 31120 * mod - Module ID 31121 * port - Port number 31122 * tpid - Tag Protocol ID 31123 * Return Value: 31124 * BCM_E_XXX 31125 */ 31126 STATIC int 31127 _bcm_esw_mod_port_tpid_set(int unit, bcm_module_t mod, bcm_port_t port, 31128 uint16 tpid) 31129 { 31130 #ifdef BCM_HURRICANE3_SUPPORT 31131 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 31132 return _bcm_hr3_mod_port_tpid_set(unit, mod, port, tpid); 31133 } else 31134 #endif /* BCM_HURRICANE3_SUPPORT */ 31135 #ifdef BCM_TRIDENT_SUPPORT 31136 { 31137 return _bcm_td_mod_port_tpid_set(unit, mod, port, tpid); 31138 } 31139 #endif /* BCM_TRIDENT_SUPPORT */ 31140 return BCM_E_UNAVAIL; 31141 } 31142 31143 #if defined(BCM_MONTEREY_SUPPORT) 31144 STATIC 31145 void bcm_port_inner_tpid_obm_set(int unit, bcm_port_t port, uint16 tpid) 31146 { 31147 uint32 rval32 = 0; 31148 int obm, pgw, pgw_inst; 31149 soc_info_t *si; 31150 soc_reg_t reg; 31151 static const soc_reg_t obm_inner_tpid_regs[] = { 31152 IDB_OBM0_INNER_TPIDr, IDB_OBM1_INNER_TPIDr, 31153 IDB_OBM2_INNER_TPIDr, IDB_OBM3_INNER_TPIDr, 31154 IDB_OBM4_INNER_TPIDr, IDB_OBM5_INNER_TPIDr, 31155 IDB_OBM6_INNER_TPIDr, IDB_OBM7_INNER_TPIDr 31156 }; 31157 if ((port < 1) || (port > 64)) { 31158 return; 31159 } 31160 si = &SOC_INFO(unit); 31161 obm = si->port_serdes[port]; 31162 obm %= MONTEREY_TSCS_PER_PGW; 31163 31164 pgw = si->port_group[port]; 31165 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 31166 31167 reg = obm_inner_tpid_regs[obm]; 31168 31169 soc_reg32_get(unit, reg, pgw_inst, 0, &rval32); 31170 soc_reg_field_set(unit, reg, &rval32, TPIDf, tpid); 31171 soc_reg_field_set(unit, reg, &rval32, ENABLEf, tpid ? 1 : 0); 31172 soc_reg32_set(unit, reg, pgw_inst, 0, rval32); 31173 return; 31174 } 31175 STATIC 31176 void bcm_inner_tpid_obm_set(int unit, uint16 tpid) 31177 { 31178 int port; 31179 BCM_PBMP_ITER(PBMP_PORT_ALL(unit), port) { 31180 bcm_port_inner_tpid_obm_set(unit, port, tpid); 31181 } 31182 return; 31183 } 31184 STATIC 31185 void bcm_port_outer_tpid_obm_set(int unit, bcm_port_t port, 31186 uint16 tpid, int tpid_index) 31187 { 31188 uint32 rval32 = 0; 31189 int obm, pgw, pgw_inst; 31190 soc_info_t *si; 31191 soc_reg_t reg; 31192 static const soc_reg_t obm_inner_tpid_regs[][4] = { 31193 {IDB_OBM0_OUTER_TPID_0r, IDB_OBM0_OUTER_TPID_1r, 31194 IDB_OBM0_OUTER_TPID_2r, IDB_OBM0_OUTER_TPID_3r}, 31195 {IDB_OBM1_OUTER_TPID_0r, IDB_OBM1_OUTER_TPID_1r, 31196 IDB_OBM1_OUTER_TPID_2r, IDB_OBM1_OUTER_TPID_3r}, 31197 {IDB_OBM2_OUTER_TPID_0r, IDB_OBM2_OUTER_TPID_1r, 31198 IDB_OBM2_OUTER_TPID_2r, IDB_OBM2_OUTER_TPID_3r}, 31199 {IDB_OBM3_OUTER_TPID_0r, IDB_OBM3_OUTER_TPID_1r, 31200 IDB_OBM3_OUTER_TPID_2r, IDB_OBM3_OUTER_TPID_3r}, 31201 {IDB_OBM4_OUTER_TPID_0r, IDB_OBM4_OUTER_TPID_1r, 31202 IDB_OBM4_OUTER_TPID_2r, IDB_OBM4_OUTER_TPID_3r}, 31203 {IDB_OBM5_OUTER_TPID_0r, IDB_OBM5_OUTER_TPID_1r, 31204 IDB_OBM5_OUTER_TPID_2r, IDB_OBM5_OUTER_TPID_3r}, 31205 {IDB_OBM6_OUTER_TPID_0r, IDB_OBM6_OUTER_TPID_1r, 31206 IDB_OBM6_OUTER_TPID_2r, IDB_OBM6_OUTER_TPID_3r}, 31207 {IDB_OBM7_OUTER_TPID_0r, IDB_OBM7_OUTER_TPID_1r, 31208 IDB_OBM7_OUTER_TPID_2r, IDB_OBM7_OUTER_TPID_3r} 31209 }; 31210 if ((port < 1) || (port > 64) || 31211 (tpid_index < 0) || (tpid_index > 3)) { 31212 return; 31213 } 31214 si = &SOC_INFO(unit); 31215 obm = si->port_serdes[port]; 31216 obm %= MONTEREY_TSCS_PER_PGW; 31217 31218 pgw = si->port_group[port]; 31219 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 31220 31221 reg = obm_inner_tpid_regs[obm][tpid_index]; 31222 31223 soc_reg32_get(unit, reg, pgw_inst, 0, &rval32); 31224 soc_reg_field_set(unit, reg, &rval32, TPIDf, tpid); 31225 soc_reg_field_set(unit, reg, &rval32, ENABLEf, tpid ? 1 : 0); 31226 soc_reg32_set(unit, reg, pgw_inst, 0, rval32); 31227 return; 31228 } 31229 #endif 31230 /* 31231 * Function: 31232 * bcm_port_tpid_set 31233 * Description: 31234 * Set the default Tag Protocol ID for a port. 31235 * Parameters: 31236 * unit - Device number 31237 * port - Port number 31238 * tpid - Tag Protocol ID 31239 * Return Value: 31240 * BCM_E_XXX 31241 * Notes: 31242 * This API is not specifically double-tagging-related, but 31243 * the port TPID becomes the service provider TPID when double-tagging 31244 * is enabled on a port. The default TPID is 0x8100. 31245 * On BCM5665, only 0x8100 is allowed for the inner (customer) tag. 31246 */ 31247 31248 int 31249 bcm_esw_port_tpid_set(int unit, bcm_port_t port, uint16 tpid) 31250 { 31251 int rv = BCM_E_UNAVAIL; 31252 bcm_module_t mod_out; 31253 bcm_port_t port_out; 31254 bcm_trunk_t tgid_out; 31255 int id_out; 31256 int is_local = 0, tpid_index = 0; 31257 #ifdef BCM_FIREBOLT_SUPPORT 31258 bcm_port_t orig_port = -1; 31259 #endif 31260 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 31261 int vp = -1; 31262 #endif 31263 31264 /* Make sure port module is initialized. */ 31265 PORT_INIT(unit); 31266 31267 if(bcm_common_oamp_port_enable_get(unit, port)) { 31268 LOG_ERROR(BSL_LS_BCM_PORT, 31269 (BSL_META("Error: Not permitted on OAMP port %d.n"), 31270 port)); 31271 return BCM_E_PARAM; 31272 } 31273 31274 if (BCM_GPORT_IS_SET(port)) { 31275 /* Handle virtual ports separetly */ 31276 if (BCM_GPORT_IS_MPLS_PORT(port) || 31277 BCM_GPORT_IS_MIM_PORT(port) || 31278 BCM_GPORT_IS_VXLAN_PORT(port) || 31279 BCM_GPORT_IS_FLOW_PORT(port) || 31280 BCM_GPORT_IS_VLAN_PORT(port)) { 31281 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31282 #if defined(BCM_TRX_SUPPORT) 31283 PORT_LOCK(unit); 31284 rv = _bcm_trx_vp_tpid_set(unit, port, tpid); 31285 PORT_UNLOCK(unit); 31286 #endif 31287 } 31288 return rv; 31289 } else if (BCM_GPORT_IS_SUBPORT_GROUP(port)) { 31290 if (soc_feature(unit, soc_feature_subtag_coe)) { 31291 #if defined(BCM_KATANA2_SUPPORT) 31292 PORT_LOCK(unit); 31293 rv = bcm_kt2_subport_subtag_port_tpid_set(unit, port, tpid); 31294 PORT_UNLOCK(unit); 31295 #endif 31296 } 31297 return rv; 31298 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 31299 31300 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 31301 (soc_feature(unit, soc_feature_channelized_switching))) { 31302 #ifdef BCM_HGPROXY_COE_SUPPORT 31303 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 31304 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31305 &mod_out, &port_out, &tgid_out, &id_out)); 31306 orig_port = port; 31307 BCM_IF_ERROR_RETURN( 31308 _bcmi_coe_subport_physical_port_get(unit, 31309 port, &port)); 31310 } else { 31311 return BCM_E_PORT; 31312 } 31313 #endif 31314 } else if (soc_feature(unit, soc_feature_subtag_coe) || 31315 soc_feature(unit, soc_feature_linkphy_coe)) { 31316 #ifdef BCM_KATANA2_SUPPORT 31317 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 31318 port)) { 31319 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31320 &mod_out, &port_out, &tgid_out, &id_out)); 31321 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 31322 mod_out, port_out, &port)); 31323 } else { 31324 return BCM_E_PORT; 31325 } 31326 #endif 31327 } else { 31328 return BCM_E_PORT; 31329 } 31330 } else if (BCM_GPORT_IS_TRUNK(port)) { 31331 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 31332 if (soc_feature(unit, soc_feature_vp_lag)) { 31333 BCM_IF_ERROR_RETURN( 31334 _bcm_esw_trunk_tid_to_vp_lag_vp( 31335 unit, BCM_GPORT_TRUNK_GET(port), &vp)); 31336 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 31337 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31338 PORT_LOCK(unit); 31339 rv = _bcm_trx_vp_tpid_set(unit, port, tpid); 31340 PORT_UNLOCK(unit); 31341 return rv; 31342 } 31343 } else { 31344 return BCM_E_PARAM; 31345 } 31346 } 31347 #endif 31348 return BCM_E_PARAM; 31349 } else { 31350 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31351 &mod_out, &port_out, &tgid_out, &id_out)); 31352 if ((-1 != tgid_out) || (-1 != id_out)) { 31353 return BCM_E_PARAM; 31354 } 31355 31356 BCM_IF_ERROR_RETURN 31357 (_bcm_esw_modid_is_local(unit, mod_out, &is_local)); 31358 #if defined(BCM_HURRICANE3_SUPPORT) 31359 /* Here only take care non-local port, the local port will 31360 * be handled later (by _bcm_fb2_port_tpid_set) */ 31361 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 31362 if (!is_local) { 31363 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31364 return _bcm_esw_mod_port_tpid_set(unit, mod_out, 31365 port_out, tpid); 31366 } else { 31367 return BCM_E_PARAM; 31368 } 31369 } else { 31370 BCM_IF_ERROR_RETURN( 31371 bcm_esw_port_local_get(unit, port, &port)); 31372 } 31373 } else 31374 #endif 31375 { 31376 if (!is_local) { 31377 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm) || 31378 soc_feature(unit,soc_feature_stm_tpid_support)) { 31379 return _bcm_esw_mod_port_tpid_set(unit, mod_out, 31380 port_out, tpid); 31381 } else { 31382 return BCM_E_PARAM; 31383 } 31384 } else { 31385 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31386 BCM_IF_ERROR_RETURN 31387 (_bcm_esw_mod_port_tpid_set(unit, mod_out, 31388 port_out, tpid)); 31389 } 31390 BCM_IF_ERROR_RETURN( 31391 bcm_esw_port_local_get(unit, port, &port)); 31392 } 31393 } 31394 } 31395 } else if (!SOC_PORT_VALID(unit, port)) { 31396 return BCM_E_PORT; 31397 } 31398 31399 #if defined (BCM_TRX_SUPPORT) 31400 if (SOC_IS_TRX(unit) && 31401 (PORT(unit, port).dtag_mode == BCM_PORT_DTAG_MODE_EXTERNAL)) { 31402 /* For DT mode external ports, don't enable any outer TPIDs */ 31403 return BCM_E_NONE; 31404 } 31405 #endif 31406 31407 #ifdef BCM_FIREBOLT_SUPPORT 31408 if (SOC_IS_FBX(unit)) { 31409 PORT_LOCK(unit); 31410 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) || \ 31411 defined(BCM_RAVEN_SUPPORT) 31412 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31413 if (orig_port != -1) { 31414 rv = _bcm_fb2_port_tpid_set(unit, orig_port, tpid, &tpid_index); 31415 } else { 31416 rv = _bcm_fb2_port_tpid_set(unit, port, tpid, &tpid_index); 31417 } 31418 #if defined(BCM_TOMAHAWK_SUPPORT) 31419 /* For Tomahawk low latency mode, use outer_tpid field */ 31420 /* of EGR_VLAN_TAG_ACTION_FOR_BYPASSr on egress side */ 31421 if (soc_feature(unit, soc_feature_fast_egr_vlan_action)) { 31422 uint32 rval; 31423 bcm_port_t local_port; 31424 31425 if (orig_port != -1) 31426 local_port = orig_port; 31427 else { 31428 local_port = port; 31429 } 31430 31431 rv = READ_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, local_port, 31432 &rval); 31433 if (SOC_FAILURE(rv)) { 31434 PORT_UNLOCK(unit); 31435 return (rv); 31436 } 31437 31438 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, &rval, 31439 OUTER_TPIDf, tpid); 31440 31441 rv = WRITE_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, local_port, 31442 rval); 31443 if (SOC_FAILURE(rv)) { 31444 PORT_UNLOCK(unit); 31445 return (rv); 31446 } 31447 } 31448 #endif 31449 #if defined(BCM_MONTEREY_SUPPORT) 31450 if (soc_feature(unit, soc_feature_obm_tpid_sync)) { 31451 bcm_port_outer_tpid_obm_set(unit, port, tpid, tpid_index); 31452 } 31453 #endif 31454 } else 31455 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 31456 { 31457 rv = _bcm_fb_port_tpid_set(unit, port, tpid); 31458 } 31459 /* coverity[negative_shift] */ 31460 if (BCM_SUCCESS(rv) && SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) { 31461 31462 31463 if(!SOC_IS_TOMAHAWK3(unit)) { 31464 /* 31465 * At now, this mac drvier is only supported by XMAC & XLMAC 31466 * If function return BCM_E_UNAVAIL, it should be correct. 31467 */ 31468 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 31469 rv = bcmi_esw_portctrl_vlan_tpid_set(unit, port, tpid); 31470 } else { 31471 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 31472 SOC_MAC_CONTROL_RX_VLAN_TAG_OUTER_TPID, tpid); 31473 if (rv == BCM_E_UNAVAIL) { 31474 rv = BCM_E_NONE; 31475 } 31476 } 31477 } 31478 } 31479 PORT_UNLOCK(unit); 31480 return rv; 31481 } 31482 #endif 31483 31484 if (tpid == 0x8100) { 31485 return BCM_E_NONE; 31486 } 31487 return BCM_E_UNAVAIL; 31488 } 31489 31490 /* 31491 * Function: 31492 * _bcm_esw_mod_port_tpid_get 31493 * Description: 31494 * Retrieve the Tag Protocol ID for a (module, port). 31495 * Parameters: 31496 * unit - Device number 31497 * mod - Module ID 31498 * port - Port number 31499 * tpid - (OUT) Tag Protocol ID 31500 * Return Value: 31501 * BCM_E_XXX 31502 */ 31503 STATIC int 31504 _bcm_esw_mod_port_tpid_get(int unit, bcm_module_t mod, bcm_port_t port, 31505 uint16 *tpid) 31506 { 31507 #ifdef BCM_HURRICANE3_SUPPORT 31508 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 31509 return _bcm_hr3_mod_port_tpid_get(unit, mod, port, tpid); 31510 } else 31511 #endif /* BCM_HURRICANE3_SUPPORT */ 31512 #ifdef BCM_TRIDENT_SUPPORT 31513 { 31514 return _bcm_td_mod_port_tpid_get(unit, mod, port, tpid); 31515 } 31516 #endif /* BCM_TRIDENT_SUPPORT */ 31517 return BCM_E_UNAVAIL; 31518 } 31519 31520 31521 /* 31522 * Function: 31523 * bcm_port_tpid_get 31524 * Description: 31525 * Retrieve the default Tag Protocol ID for a port. 31526 * Parameters: 31527 * unit - Device number 31528 * port - Port number 31529 * tpid - (OUT) Tag Protocol ID 31530 * Return Value: 31531 * BCM_E_XXX 31532 */ 31533 31534 int 31535 bcm_esw_port_tpid_get(int unit, bcm_port_t port, uint16 *tpid) 31536 { 31537 int rv = BCM_E_UNAVAIL; 31538 bcm_module_t mod_out; 31539 bcm_port_t port_out; 31540 bcm_trunk_t tgid_out; 31541 int id_out; 31542 int is_local = 0; 31543 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 31544 int vp = -1; 31545 #endif 31546 31547 /* Make sure port module is initialized. */ 31548 PORT_INIT(unit); 31549 31550 if(bcm_common_oamp_port_enable_get(unit, port)) { 31551 LOG_ERROR(BSL_LS_BCM_PORT, 31552 (BSL_META("Error: Not permitted on OAMP port %d.n"), 31553 port)); 31554 return BCM_E_PARAM; 31555 } 31556 31557 if (BCM_GPORT_IS_SET(port)) { 31558 /* Handle virtual ports separetly */ 31559 if (BCM_GPORT_IS_MPLS_PORT(port) || 31560 BCM_GPORT_IS_MIM_PORT(port) || 31561 BCM_GPORT_IS_VXLAN_PORT(port) || 31562 BCM_GPORT_IS_FLOW_PORT(port) || 31563 BCM_GPORT_IS_VLAN_PORT(port)) { 31564 31565 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31566 #if defined(BCM_TRX_SUPPORT) 31567 PORT_LOCK(unit); 31568 rv = _bcm_trx_vp_tpid_get(unit, port, tpid); 31569 PORT_UNLOCK(unit); 31570 #endif 31571 } 31572 return rv; 31573 } else if (BCM_GPORT_IS_SUBPORT_GROUP(port)) { 31574 if (soc_feature(unit, soc_feature_subtag_coe)) { 31575 #if defined(BCM_KATANA2_SUPPORT) 31576 PORT_LOCK(unit); 31577 rv = bcm_kt2_subport_subtag_port_tpid_get(unit, port, tpid); 31578 PORT_UNLOCK(unit); 31579 #endif 31580 } 31581 return rv; 31582 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 31583 31584 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 31585 (soc_feature(unit, soc_feature_channelized_switching))) { 31586 #ifdef BCM_HGPROXY_COE_SUPPORT 31587 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 31588 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31589 &mod_out, &port_out, &tgid_out, &id_out)); 31590 } else { 31591 return BCM_E_PORT; 31592 } 31593 #endif 31594 } else if (soc_feature(unit, soc_feature_subtag_coe) || 31595 soc_feature(unit, soc_feature_linkphy_coe)) { 31596 #ifdef BCM_KATANA2_SUPPORT 31597 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 31598 port)) { 31599 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31600 &mod_out, &port_out, &tgid_out, &id_out)); 31601 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 31602 mod_out, port_out, &port)); 31603 } else { 31604 return BCM_E_PORT; 31605 } 31606 #endif 31607 } else { 31608 return BCM_E_PORT; 31609 } 31610 } else if (BCM_GPORT_IS_TRUNK(port)) { 31611 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 31612 if (soc_feature(unit, soc_feature_vp_lag)) { 31613 BCM_IF_ERROR_RETURN( 31614 _bcm_esw_trunk_tid_to_vp_lag_vp( 31615 unit, BCM_GPORT_TRUNK_GET(port), &vp)); 31616 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 31617 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31618 PORT_LOCK(unit); 31619 rv = _bcm_trx_vp_tpid_get(unit, port, tpid); 31620 PORT_UNLOCK(unit); 31621 return rv; 31622 } 31623 } else { 31624 return BCM_E_PARAM; 31625 } 31626 } 31627 #endif 31628 return BCM_E_PARAM; 31629 } else { 31630 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31631 &mod_out, &port_out, &tgid_out, &id_out)); 31632 if ((-1 != tgid_out) || (-1 != id_out)) { 31633 return BCM_E_PARAM; 31634 } 31635 31636 BCM_IF_ERROR_RETURN 31637 (_bcm_esw_modid_is_local(unit, mod_out, &is_local)); 31638 if (!is_local) { 31639 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31640 return _bcm_esw_mod_port_tpid_get(unit, mod_out, port_out, 31641 tpid); 31642 } else { 31643 return BCM_E_PARAM; 31644 } 31645 } else { 31646 BCM_IF_ERROR_RETURN( 31647 bcm_esw_port_local_get(unit, port, &port)); 31648 } 31649 } 31650 31651 } else if (!SOC_PORT_VALID(unit, port)) { 31652 return BCM_E_PORT; 31653 } 31654 31655 if (tpid == NULL) { 31656 return BCM_E_PARAM; 31657 } 31658 31659 #ifdef BCM_FIREBOLT_SUPPORT 31660 if (SOC_IS_FBX(unit)) { 31661 PORT_LOCK(unit); 31662 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 31663 || defined(BCM_RAVEN_SUPPORT) 31664 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31665 rv = _bcm_fb2_port_tpid_get(unit, port, tpid); 31666 } else 31667 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 31668 { 31669 rv = _bcm_fb_port_tpid_get(unit, port, tpid); 31670 } 31671 PORT_UNLOCK(unit); 31672 return rv; 31673 } 31674 #endif /* BCM_FIREBOLT_SUPPORT */ 31675 *tpid = 0x8100; 31676 return (BCM_E_NONE); 31677 } 31678 31679 /* 31680 * Function: 31681 * _bcm_esw_mod_port_tpid_add 31682 * Description: 31683 * Add TPID for a (module, port). 31684 * Parameters: 31685 * unit - (IN) Device number 31686 * mod - (IN) Module ID 31687 * port - (IN) Port number 31688 * tpid - (IN) Tag Protocol ID 31689 * Return Value: 31690 * BCM_E_XXX 31691 */ 31692 STATIC int 31693 _bcm_esw_mod_port_tpid_add(int unit, bcm_module_t mod, bcm_port_t port, 31694 uint16 tpid) 31695 { 31696 #ifdef BCM_HURRICANE3_SUPPORT 31697 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 31698 return _bcm_hr3_mod_port_tpid_add(unit, mod, port, tpid); 31699 } else 31700 #endif /* BCM_HURRICANE3_SUPPORT */ 31701 #ifdef BCM_TRIDENT_SUPPORT 31702 { 31703 return _bcm_td_mod_port_tpid_add(unit, mod, port, tpid); 31704 } 31705 #endif /* BCM_TRIDENT_SUPPORT */ 31706 return BCM_E_UNAVAIL; 31707 } 31708 31709 /* 31710 * Function: 31711 * bcm_esw_port_tpid_add 31712 * Description: 31713 * Add allowed TPID for a port. 31714 * Parameters: 31715 * unit - (IN) Device number 31716 * port - (IN) Port number 31717 * tpid - (IN) Tag Protocol ID 31718 * color_select - (IN) Color mode for TPID 31719 * Return Value: 31720 * BCM_E_XXX 31721 */ 31722 int 31723 bcm_esw_port_tpid_add(int unit, bcm_port_t port, 31724 uint16 tpid, int color_select) 31725 { 31726 int rv = BCM_E_UNAVAIL; 31727 bcm_module_t mod_out; 31728 bcm_port_t port_out; 31729 bcm_trunk_t tgid_out; 31730 int id_out; 31731 int is_local = 0; 31732 #ifdef BCM_FIREBOLT_SUPPORT 31733 bcm_port_t orig_port = -1; 31734 #endif 31735 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 31736 int vp = -1; 31737 #endif 31738 31739 if (color_select != BCM_COLOR_PRIORITY && 31740 color_select != BCM_COLOR_OUTER_CFI && 31741 color_select != BCM_COLOR_INNER_CFI) { 31742 return BCM_E_PARAM; 31743 } 31744 31745 /* Make sure port module is initialized. */ 31746 PORT_INIT(unit); 31747 31748 if(bcm_common_oamp_port_enable_get(unit, port)) { 31749 LOG_ERROR(BSL_LS_BCM_PORT, 31750 (BSL_META("Error: Not permitted on OAMP port %d.n"), 31751 port)); 31752 return BCM_E_PARAM; 31753 } 31754 31755 if (BCM_GPORT_IS_SET(port)) { 31756 /* Handle virtual ports separetly */ 31757 if (BCM_GPORT_IS_MPLS_PORT(port) || 31758 BCM_GPORT_IS_MIM_PORT(port) || 31759 BCM_GPORT_IS_TRILL_PORT(port) || 31760 BCM_GPORT_IS_VXLAN_PORT(port) || 31761 BCM_GPORT_IS_FLOW_PORT(port) || 31762 BCM_GPORT_IS_VLAN_PORT(port)) { 31763 31764 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31765 #if defined(BCM_TRX_SUPPORT) 31766 PORT_LOCK(unit); 31767 rv = _bcm_trx_vp_tpid_add(unit, port, tpid, color_select); 31768 PORT_UNLOCK(unit); 31769 #endif 31770 } 31771 return rv; 31772 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 31773 31774 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 31775 (soc_feature(unit, soc_feature_channelized_switching))) { 31776 #ifdef BCM_HGPROXY_COE_SUPPORT 31777 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 31778 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31779 &mod_out, &port_out, &tgid_out, &id_out)); 31780 orig_port = port; 31781 BCM_IF_ERROR_RETURN( 31782 _bcmi_coe_subport_physical_port_get(unit, 31783 port, &port)); 31784 } else { 31785 return BCM_E_PORT; 31786 } 31787 #endif 31788 } else if (soc_feature(unit, soc_feature_subtag_coe) || 31789 soc_feature(unit, soc_feature_linkphy_coe)) { 31790 #ifdef BCM_KATANA2_SUPPORT 31791 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 31792 port)) { 31793 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31794 &mod_out, &port_out, &tgid_out, &id_out)); 31795 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 31796 mod_out, port_out, &port)); 31797 } else { 31798 return BCM_E_PORT; 31799 } 31800 #endif 31801 } else { 31802 return BCM_E_PORT; 31803 } 31804 } else if (BCM_GPORT_IS_TRUNK(port)) { 31805 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 31806 if (soc_feature(unit, soc_feature_vp_lag)) { 31807 BCM_IF_ERROR_RETURN( 31808 _bcm_esw_trunk_tid_to_vp_lag_vp( 31809 unit, BCM_GPORT_TRUNK_GET(port), &vp)); 31810 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 31811 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31812 PORT_LOCK(unit); 31813 rv = _bcm_trx_vp_tpid_add(unit, port, tpid, 31814 color_select); 31815 PORT_UNLOCK(unit); 31816 return rv; 31817 } 31818 } else { 31819 return BCM_E_PARAM; 31820 } 31821 } 31822 #endif 31823 return BCM_E_PARAM; 31824 } else { 31825 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31826 &mod_out, &port_out, &tgid_out, &id_out)); 31827 if ((-1 != tgid_out) || (-1 != id_out)) { 31828 return BCM_E_PARAM; 31829 } 31830 31831 BCM_IF_ERROR_RETURN 31832 (_bcm_esw_modid_is_local(unit, mod_out, &is_local)); 31833 #if defined(BCM_HURRICANE3_SUPPORT) 31834 /* Here only take care non-local port, the local port will 31835 * be handled later (by _bcm_fb2_port_tpid_add) */ 31836 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 31837 if (!is_local) { 31838 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31839 return _bcm_esw_mod_port_tpid_add(unit, mod_out, 31840 port_out, tpid); 31841 } else { 31842 return BCM_E_PARAM; 31843 } 31844 } else { 31845 BCM_IF_ERROR_RETURN( 31846 bcm_esw_port_local_get(unit, port, &port)); 31847 } 31848 } else 31849 #endif 31850 { 31851 if (!is_local) { 31852 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31853 return _bcm_esw_mod_port_tpid_add(unit, mod_out, 31854 port_out, tpid); 31855 } else { 31856 return BCM_E_PARAM; 31857 } 31858 } else { 31859 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31860 BCM_IF_ERROR_RETURN 31861 (_bcm_esw_mod_port_tpid_add(unit, mod_out, 31862 port_out, tpid)); 31863 } 31864 BCM_IF_ERROR_RETURN( 31865 bcm_esw_port_local_get(unit, port, &port)); 31866 } 31867 } 31868 } 31869 31870 } else if (!SOC_PORT_VALID(unit, port)) { 31871 return BCM_E_PORT; 31872 } 31873 31874 #if defined (BCM_TRX_SUPPORT) 31875 if (SOC_IS_TRX(unit) && 31876 (PORT(unit, port).dtag_mode == BCM_PORT_DTAG_MODE_EXTERNAL)) { 31877 /* For DT mode external ports, don't enable any outer TPIDs */ 31878 return BCM_E_NONE; 31879 } 31880 #endif 31881 31882 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 31883 || defined(BCM_RAVEN_SUPPORT) 31884 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31885 PORT_LOCK(unit); 31886 if (orig_port != -1) { 31887 rv = _bcm_fb2_port_tpid_add(unit, orig_port, tpid, color_select); 31888 } else { 31889 rv = _bcm_fb2_port_tpid_add(unit, port, tpid, color_select); 31890 } 31891 PORT_UNLOCK(unit); 31892 } 31893 #endif 31894 return rv; 31895 } 31896 31897 /* 31898 * Function: 31899 * _bcm_esw_mod_port_tpid_delete 31900 * Description: 31901 * Delete TPID for a (module, port). 31902 * Parameters: 31903 * unit - (IN) Device number 31904 * mod - (IN) Module ID 31905 * port - (IN) Port number 31906 * tpid - (IN) Tag Protocol ID 31907 * Return Value: 31908 * BCM_E_XXX 31909 */ 31910 STATIC int 31911 _bcm_esw_mod_port_tpid_delete(int unit, bcm_module_t mod, bcm_port_t port, 31912 uint16 tpid) 31913 { 31914 #ifdef BCM_HURRICANE3_SUPPORT 31915 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 31916 return _bcm_hr3_mod_port_tpid_delete(unit, mod, port, tpid); 31917 } else 31918 #endif /* BCM_HURRICANE3_SUPPORT */ 31919 #ifdef BCM_TRIDENT_SUPPORT 31920 { 31921 return _bcm_td_mod_port_tpid_delete(unit, mod, port, tpid); 31922 } 31923 #endif /* BCM_TRIDENT_SUPPORT */ 31924 return BCM_E_UNAVAIL; 31925 } 31926 31927 /* 31928 * Function: 31929 * bcm_esw_port_tpid_delete 31930 * Description: 31931 * Delete allowed TPID for a port. 31932 * Parameters: 31933 * unit - (IN) Device number 31934 * port - (IN) Port number 31935 * tpid - (IN) Tag Protocol ID 31936 * Return Value: 31937 * BCM_E_XXX 31938 */ 31939 int 31940 bcm_esw_port_tpid_delete(int unit, bcm_port_t port, uint16 tpid) 31941 { 31942 int rv = BCM_E_UNAVAIL; 31943 bcm_module_t mod_out; 31944 bcm_port_t port_out; 31945 bcm_trunk_t tgid_out; 31946 int id_out; 31947 int is_local = 0; 31948 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 31949 int vp = -1; 31950 #endif 31951 31952 /* Make sure port module is initialized. */ 31953 PORT_INIT(unit); 31954 31955 if(bcm_common_oamp_port_enable_get(unit, port)) { 31956 LOG_ERROR(BSL_LS_BCM_PORT, 31957 (BSL_META("Error: Not permitted on OAMP port %d.n"), 31958 port)); 31959 return BCM_E_PARAM; 31960 } 31961 31962 if (BCM_GPORT_IS_SET(port)) { 31963 /* Handle virtual ports separetly */ 31964 if (BCM_GPORT_IS_MPLS_PORT(port) || 31965 BCM_GPORT_IS_TRILL_PORT(port) || 31966 BCM_GPORT_IS_MIM_PORT(port) || 31967 BCM_GPORT_IS_VXLAN_PORT(port) || 31968 BCM_GPORT_IS_FLOW_PORT(port) || 31969 BCM_GPORT_IS_VLAN_PORT(port)) { 31970 31971 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31972 #if defined(BCM_TRX_SUPPORT) 31973 PORT_LOCK(unit); 31974 rv = _bcm_trx_vp_tpid_delete(unit, port, tpid); 31975 PORT_UNLOCK(unit); 31976 #endif 31977 } 31978 return rv; 31979 } else if (BCM_GPORT_IS_SUBPORT_GROUP(port)) { 31980 if (soc_feature(unit, soc_feature_subtag_coe)) { 31981 #if defined(BCM_KATANA2_SUPPORT) 31982 PORT_LOCK(unit); 31983 rv = bcm_kt2_subport_subtag_port_tpid_delete(unit, port, tpid); 31984 PORT_UNLOCK(unit); 31985 #endif 31986 } 31987 return rv; 31988 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 31989 31990 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 31991 (soc_feature(unit, soc_feature_channelized_switching))) { 31992 #ifdef BCM_HGPROXY_COE_SUPPORT 31993 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 31994 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31995 &mod_out, &port_out, &tgid_out, &id_out)); 31996 } else { 31997 return BCM_E_PORT; 31998 } 31999 #endif 32000 } else if (soc_feature(unit, soc_feature_subtag_coe) || 32001 soc_feature(unit, soc_feature_linkphy_coe)) { 32002 #ifdef BCM_KATANA2_SUPPORT 32003 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 32004 port)) { 32005 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 32006 &mod_out, &port_out, &tgid_out, &id_out)); 32007 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 32008 mod_out, port_out, &port)); 32009 } else { 32010 return BCM_E_PORT; 32011 } 32012 #endif 32013 } else { 32014 return BCM_E_PORT; 32015 } 32016 } else if (BCM_GPORT_IS_TRUNK(port)) { 32017 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 32018 if (soc_feature(unit, soc_feature_vp_lag)) { 32019 BCM_IF_ERROR_RETURN( 32020 _bcm_esw_trunk_tid_to_vp_lag_vp( 32021 unit, BCM_GPORT_TRUNK_GET(port), &vp)); 32022 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 32023 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 32024 PORT_LOCK(unit); 32025 rv = _bcm_trx_vp_tpid_delete(unit, port, tpid); 32026 PORT_UNLOCK(unit); 32027 return rv; 32028 } 32029 } else { 32030 return BCM_E_PARAM; 32031 } 32032 } 32033 #endif 32034 return BCM_E_PARAM; 32035 } else { 32036 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 32037 &mod_out, &port_out, &tgid_out, &id_out)); 32038 if ((-1 != tgid_out) || (-1 != id_out)) { 32039 return BCM_E_PARAM; 32040 } 32041 32042 BCM_IF_ERROR_RETURN 32043 (_bcm_esw_modid_is_local(unit, mod_out, &is_local)); 32044 #if defined(BCM_HURRICANE3_SUPPORT) 32045 /* Here only take care non-local port, the local port will 32046 * be handled later (by _bcm_fb2_port_tpid_delete) */ 32047 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 32048 if (!is_local) { 32049 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 32050 return _bcm_esw_mod_port_tpid_delete(unit, mod_out, 32051 port_out, tpid); 32052 } else { 32053 return BCM_E_PARAM; 32054 } 32055 } else { 32056 BCM_IF_ERROR_RETURN( 32057 bcm_esw_port_local_get(unit, port, &port)); 32058 } 32059 } else 32060 #endif 32061 { 32062 if (!is_local) { 32063 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 32064 return _bcm_esw_mod_port_tpid_delete(unit, mod_out, 32065 port_out, tpid); 32066 } else { 32067 return BCM_E_PARAM; 32068 } 32069 } else { 32070 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 32071 BCM_IF_ERROR_RETURN 32072 (_bcm_esw_mod_port_tpid_delete(unit, mod_out, 32073 port_out, tpid)); 32074 } 32075 BCM_IF_ERROR_RETURN( 32076 bcm_esw_port_local_get(unit, port, &port)); 32077 } 32078 } 32079 } 32080 32081 } else if (!SOC_PORT_VALID(unit, port)) { 32082 return BCM_E_PORT; 32083 } 32084 32085 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 32086 || defined(BCM_RAVEN_SUPPORT) 32087 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 32088 PORT_LOCK(unit); 32089 rv = _bcm_fb2_port_tpid_delete(unit, port, tpid); 32090 PORT_UNLOCK(unit); 32091 } 32092 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 32093 return rv; 32094 } 32095 32096 /* 32097 * Function: 32098 * _bcm_esw_mod_port_tpid_delete_all 32099 * Description: 32100 * Delete all TPID for a (module, port). 32101 * Parameters: 32102 * unit - (IN) Device number 32103 * mod - (IN) Module ID 32104 * port - (IN) Port number 32105 * Return Value: 32106 * BCM_E_XXX 32107 */ 32108 STATIC int 32109 _bcm_esw_mod_port_tpid_delete_all(int unit, bcm_module_t mod, bcm_port_t port) 32110 { 32111 #ifdef BCM_HURRICANE3_SUPPORT 32112 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 32113 return _bcm_hr3_mod_port_tpid_delete_all(unit, mod, port); 32114 } else 32115 #endif /* BCM_HURRICANE3_SUPPORT */ 32116 #ifdef BCM_TRIDENT_SUPPORT 32117 { 32118 return _bcm_td_mod_port_tpid_delete_all(unit, mod, port); 32119 } 32120 #endif /* BCM_TRIDENT_SUPPORT */ 32121 return BCM_E_UNAVAIL; 32122 } 32123 32124 /* 32125 * Function: 32126 * bcm_esw_port_tpid_delete_all 32127 * Description: 32128 * Delete all allowed TPID for a port. 32129 * Parameters: 32130 * unit - (IN) Device number 32131 * port - (IN) Port number 32132 * Return Value: 32133 * BCM_E_XXX 32134 */ 32135 int 32136 bcm_esw_port_tpid_delete_all(int unit, bcm_port_t port) 32137 { 32138 int rv = BCM_E_UNAVAIL; 32139 bcm_module_t mod_out; 32140 bcm_port_t port_out; 32141 bcm_trunk_t tgid_out; 32142 int id_out; 32143 int is_local = 0; 32144 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 32145 int vp = -1; 32146 #endif 32147 32148 /* Make sure port module is initialized. */ 32149 PORT_INIT(unit); 32150 32151 if(bcm_common_oamp_port_enable_get(unit, port)) { 32152 LOG_ERROR(BSL_LS_BCM_PORT, 32153 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32154 port)); 32155 return BCM_E_PARAM; 32156 } 32157 32158 if (BCM_GPORT_IS_SET(port)) { 32159 /* Handle virtual ports separetly */ 32160 if (BCM_GPORT_IS_MPLS_PORT(port) || 32161 BCM_GPORT_IS_MIM_PORT(port) || 32162 BCM_GPORT_IS_VXLAN_PORT(port) || 32163 BCM_GPORT_IS_FLOW_PORT(port) || 32164 BCM_GPORT_IS_VLAN_PORT(port)) { 32165 32166 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 32167 #if defined(BCM_TRX_SUPPORT) 32168 PORT_LOCK(unit); 32169 rv = _bcm_trx_vp_tpid_delete_all(unit, port); 32170 PORT_UNLOCK(unit); 32171 #endif 32172 } 32173 return rv; 32174 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 32175 32176 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 32177 (soc_feature(unit, soc_feature_channelized_switching))) { 32178 #ifdef BCM_HGPROXY_COE_SUPPORT 32179 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 32180 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 32181 &mod_out, &port_out, &tgid_out, &id_out)); 32182 } else { 32183 return BCM_E_PORT; 32184 } 32185 #endif 32186 } else if (soc_feature(unit, soc_feature_subtag_coe) || 32187 soc_feature(unit, soc_feature_linkphy_coe)) { 32188 #ifdef BCM_KATANA2_SUPPORT 32189 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 32190 port)) { 32191 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 32192 &mod_out, &port_out, &tgid_out, &id_out)); 32193 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 32194 mod_out, port_out, &port)); 32195 } else { 32196 return BCM_E_PORT; 32197 } 32198 #endif 32199 } else { 32200 return BCM_E_PORT; 32201 } 32202 } else if (BCM_GPORT_IS_TRUNK(port)) { 32203 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 32204 if (soc_feature(unit, soc_feature_vp_lag)) { 32205 BCM_IF_ERROR_RETURN( 32206 _bcm_esw_trunk_tid_to_vp_lag_vp( 32207 unit, BCM_GPORT_TRUNK_GET(port), &vp)); 32208 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 32209 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 32210 PORT_LOCK(unit); 32211 rv = _bcm_trx_vp_tpid_delete_all(unit, port); 32212 PORT_UNLOCK(unit); 32213 return rv; 32214 } 32215 } else { 32216 return BCM_E_PARAM; 32217 } 32218 } 32219 #endif 32220 return BCM_E_PARAM; 32221 } else { 32222 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 32223 &mod_out, &port_out, &tgid_out, &id_out)); 32224 if ((-1 != tgid_out) || (-1 != id_out)) { 32225 return BCM_E_PARAM; 32226 } 32227 32228 BCM_IF_ERROR_RETURN 32229 (_bcm_esw_modid_is_local(unit, mod_out, &is_local)); 32230 #if defined(BCM_HURRICANE3_SUPPORT) 32231 /* Here only take care non-local port, the local port will 32232 * be handled later (by _bcm_fb2_port_tpid_delete_all) */ 32233 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 32234 if (!is_local) { 32235 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 32236 return _bcm_esw_mod_port_tpid_delete_all(unit, mod_out, 32237 port_out); 32238 } else { 32239 return BCM_E_PARAM; 32240 } 32241 } else { 32242 BCM_IF_ERROR_RETURN( 32243 bcm_esw_port_local_get(unit, port, &port)); 32244 } 32245 } else 32246 #endif 32247 { 32248 if (!is_local) { 32249 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 32250 return _bcm_esw_mod_port_tpid_delete_all(unit, mod_out, 32251 port_out); 32252 } else { 32253 return BCM_E_PARAM; 32254 } 32255 } else { 32256 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 32257 BCM_IF_ERROR_RETURN 32258 (_bcm_esw_mod_port_tpid_delete_all(unit, mod_out, 32259 port_out)); 32260 } 32261 BCM_IF_ERROR_RETURN( 32262 bcm_esw_port_local_get(unit, port, &port)); 32263 } 32264 } 32265 } 32266 32267 } else if (!SOC_PORT_VALID(unit, port)) { 32268 return BCM_E_PORT; 32269 } 32270 32271 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 32272 || defined(BCM_RAVEN_SUPPORT) 32273 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 32274 PORT_LOCK(unit); 32275 rv = _bcm_fb2_port_tpid_delete_all(unit, port); 32276 PORT_UNLOCK(unit); 32277 } 32278 #endif 32279 return rv; 32280 } 32281 32282 /* 32283 * Function: 32284 * _bcm_esw_mod_port_inner_tpid_enable 32285 * Description: 32286 * Enable the Inner Tag Protocol ID for a (module, port). 32287 * Parameters: 32288 * unit - Device number 32289 * mod - Module ID 32290 * port - Port number 32291 * Return Value: 32292 * BCM_E_XXX 32293 */ 32294 STATIC int 32295 _bcm_esw_mod_port_inner_tpid_enable(int unit, bcm_module_t mod, bcm_port_t port) 32296 { 32297 int rv = BCM_E_NONE; 32298 if (!SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 32299 int sys_index = 0; 32300 uint32 enable = 1; 32301 system_config_table_entry_t systab; 32302 sys_index = mod * 64 + port; 32303 rv = READ_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ANY, sys_index, 32304 &systab); 32305 if (BCM_SUCCESS(rv)) { 32306 soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &systab, 32307 INNER_TPID_ENABLEf, enable); 32308 rv = WRITE_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ALL, 32309 sys_index, &systab); 32310 } 32311 } else { 32312 #ifdef BCM_HURRICANE3_SUPPORT 32313 if (SOC_IS_HURRICANE3(unit)) { 32314 rv = _bcm_hr3_mod_port_inner_tpid_enable_write(unit, mod, port, 1); 32315 } 32316 #endif /* BCM_HURRICANE3_SUPPORT */ 32317 } 32318 return rv; 32319 } 32320 32321 /* 32322 * Function: 32323 * bcm_port_inner_tpid_set 32324 * Purpose: 32325 * Set the expected TPID for the inner tag in double-tagging mode. 32326 * Parameters: 32327 * unit - Device number 32328 * port - Port number 32329 * tpid - Tag Protocol ID 32330 * Returns: 32331 * BCM_E_NONE - Success. 32332 * BCM_E_XXX 32333 */ 32334 int 32335 bcm_esw_port_inner_tpid_set(int unit, bcm_port_t port, uint16 tpid) 32336 { 32337 int rv = BCM_E_UNAVAIL; 32338 bcm_module_t mod_out = BCM_MODID_INVALID; 32339 bcm_port_t port_out; 32340 bcm_trunk_t tgid_out; 32341 int is_local = TRUE; 32342 int id_out; 32343 32344 /* Make sure port module is initialized. */ 32345 PORT_INIT(unit); 32346 32347 if(bcm_common_oamp_port_enable_get(unit, port)) { 32348 LOG_ERROR(BSL_LS_BCM_PORT, 32349 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32350 port)); 32351 return BCM_E_PARAM; 32352 } 32353 32354 if (BCM_GPORT_IS_SET(port)) { 32355 /* Handle virtual ports separetly */ 32356 if (BCM_GPORT_IS_MPLS_PORT(port) || 32357 BCM_GPORT_IS_MIM_PORT(port) || 32358 BCM_GPORT_IS_VLAN_PORT(port)) { 32359 32360 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 32361 #if defined(BCM_TRX_SUPPORT) 32362 PORT_LOCK(unit); 32363 rv = _bcm_trx_vp_tpid_set(unit, port,tpid); 32364 PORT_UNLOCK(unit); 32365 #endif 32366 } 32367 return rv; 32368 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 32369 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 32370 (soc_feature(unit, soc_feature_channelized_switching))) { 32371 #ifdef BCM_HGPROXY_COE_SUPPORT 32372 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 32373 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 32374 &mod_out, &port_out, &tgid_out, &id_out)); 32375 BCM_IF_ERROR_RETURN( 32376 _bcmi_coe_subport_physical_port_get(unit, 32377 port, &port)); 32378 } else { 32379 return BCM_E_PORT; 32380 } 32381 #endif 32382 } else if (soc_feature(unit, soc_feature_subtag_coe) || 32383 soc_feature(unit, soc_feature_linkphy_coe)) { 32384 #ifdef BCM_KATANA2_SUPPORT 32385 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 32386 port)) { 32387 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 32388 &mod_out, &port_out, &tgid_out, &id_out)); 32389 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 32390 mod_out, port_out, &port)); 32391 } else { 32392 return BCM_E_PORT; 32393 } 32394 #endif 32395 } else { 32396 return BCM_E_PORT; 32397 } 32398 } else { 32399 BCM_IF_ERROR_RETURN( 32400 _bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, 32401 &tgid_out, &id_out)); 32402 if ((-1 != tgid_out) || (-1 != id_out)) { 32403 return BCM_E_PARAM; 32404 } 32405 port = port_out; 32406 BCM_IF_ERROR_RETURN( 32407 _bcm_esw_modid_is_local(unit, mod_out, &is_local)); 32408 } 32409 } else if (!SOC_PORT_VALID(unit, port)) { 32410 return BCM_E_PORT; 32411 } 32412 32413 if (soc_feature(unit, soc_feature_inner_tpid_enable)) { 32414 if (BCM_MODID_INVALID == mod_out) { 32415 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod_out)); 32416 } 32417 BCM_IF_ERROR_RETURN( 32418 _bcm_esw_mod_port_inner_tpid_enable(unit, mod_out, port)); 32419 32420 if (TRUE == is_local) { 32421 uint32 enable = 1; 32422 BCM_IF_ERROR_RETURN( 32423 soc_mem_field32_modify(unit, PORT_TABm, port, 32424 INNER_TPID_ENABLEf, enable)); 32425 if (soc_reg_field_valid(unit, EGR_VLAN_CONTROL_1r, INNER_TPID_ENABLEf)) { 32426 soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port, 32427 INNER_TPID_ENABLEf, enable); 32428 } 32429 } 32430 } else { 32431 /* INNER_TPID_ENABLEf is also in SYSTEM_CONFIG_TABLE which is for Higig. 32432 * Hence, bypass the switched port check */ 32433 32434 PORT_SWITCHED_CHECK(unit, port); 32435 } 32436 32437 #ifdef BCM_FIREBOLT_SUPPORT 32438 if (SOC_IS_FBX(unit)) { 32439 uint32 rval; 32440 #if 0 32441 int tpid_index; 32442 32443 for (tpid_index = 0; tpid_index < 4; tpid_index++) { 32444 if (SOC_REG_IS_VALID(unit, PARSER1_ING_INNER_TPIDr)) { 32445 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 32446 PARSER1_ING_INNER_TPIDr, tpid_index, TPIDf, tpid)); 32447 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 32448 PARSER2_ING_INNER_TPIDr, tpid_index, TPIDf, tpid)); 32449 } 32450 32451 if (SOC_REG_IS_VALID(unit, EGR_INNER_TPIDr)) { 32452 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 32453 EGR_INNER_TPIDr, tpid_index, TPIDf, tpid)); 32454 } 32455 32456 if (SOC_REG_IS_VALID(unit, EGR_PARSER_INNER_TPIDr)) { 32457 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 32458 EGR_PARSER_INNER_TPIDr, tpid_index, TPIDf, tpid)); 32459 } 32460 } 32461 #endif 32462 32463 BCM_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &rval)); 32464 soc_reg_field_set(unit, VLAN_CTRLr, &rval, INNER_TPIDf, tpid); 32465 BCM_IF_ERROR_RETURN(WRITE_VLAN_CTRLr(unit, rval)); 32466 if (soc_reg_field_valid(unit, EGR_CONFIGr, INNER_TPIDf)) { 32467 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIGr, 32468 REG_PORT_ANY, INNER_TPIDf, tpid)); 32469 } 32470 #ifdef BCM_TRIDENT3_SUPPORT 32471 if (SOC_IS_TRIDENT3X(unit)) { 32472 if (soc_reg_field_valid(unit, EGR_CONFIG_1_64r, INNER_TPIDf)) { 32473 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1_64r, 32474 REG_PORT_ANY, INNER_TPIDf, tpid)); 32475 } 32476 } 32477 #endif 32478 if (SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) { 32479 /* 32480 * At now, this mac drvier is only supported by XMAC & XLMAC 32481 * If function return BCM_E_UNAVAIL, it should be correct. 32482 */ 32483 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 32484 (void)bcmi_esw_portctrl_vlan_inner_tpid_set(unit, port, tpid); 32485 } else { 32486 BCM_IF_ERROR_NOT_UNAVAIL_RETURN( 32487 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 32488 SOC_MAC_CONTROL_RX_VLAN_TAG_INNER_TPID, tpid)); 32489 } 32490 } 32491 rv = BCM_E_NONE; 32492 } 32493 #endif 32494 #if defined(BCM_MONTEREY_SUPPORT) 32495 if (soc_feature(unit, soc_feature_obm_tpid_sync) && (rv == BCM_E_NONE)) { 32496 bcm_inner_tpid_obm_set(unit, tpid); 32497 } 32498 #endif 32499 return rv; 32500 } 32501 32502 /* 32503 * Function: 32504 * bcm_port_inner_tpid_get 32505 * Purpose: 32506 * Get the expected TPID for the inner tag in double-tagging mode. 32507 * Parameters: 32508 * unit - Device number 32509 * port - Port number 32510 * tpid - (OUT) Tag Protocol ID 32511 * Returns: 32512 * BCM_E_NONE - Success. 32513 * BCM_E_XXX 32514 */ 32515 int 32516 bcm_esw_port_inner_tpid_get(int unit, bcm_port_t port, uint16 *tpid) 32517 { 32518 int rv = BCM_E_UNAVAIL; 32519 32520 /* Make sure port module is initialized. */ 32521 PORT_INIT(unit); 32522 32523 if(bcm_common_oamp_port_enable_get(unit, port)) { 32524 LOG_ERROR(BSL_LS_BCM_PORT, 32525 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32526 port)); 32527 return BCM_E_PARAM; 32528 } 32529 32530 if (BCM_GPORT_IS_SET(port)) { 32531 /* Handle virtual ports separetly */ 32532 if (BCM_GPORT_IS_MPLS_PORT(port) || 32533 BCM_GPORT_IS_MIM_PORT(port) || 32534 BCM_GPORT_IS_VLAN_PORT(port)) { 32535 32536 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 32537 #if defined(BCM_TRX_SUPPORT) 32538 PORT_LOCK(unit); 32539 rv = _bcm_trx_vp_tpid_get(unit, port,tpid); 32540 PORT_UNLOCK(unit); 32541 #endif 32542 } 32543 return rv; 32544 } else { 32545 BCM_IF_ERROR_RETURN( 32546 _bcm_esw_port_gport_validate(unit, port, &port)); 32547 } 32548 32549 } else if (!SOC_PORT_VALID(unit, port)) { 32550 return BCM_E_PORT; 32551 } 32552 32553 PORT_SWITCHED_CHECK(unit, port); 32554 32555 if (tpid == NULL) { 32556 return BCM_E_PARAM; 32557 } 32558 32559 #ifdef BCM_FIREBOLT_SUPPORT 32560 if (SOC_IS_FBX(unit)) { 32561 uint32 rval; 32562 BCM_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &rval)); 32563 *tpid = soc_reg_field_get(unit, VLAN_CTRLr, rval, INNER_TPIDf); 32564 return BCM_E_NONE; 32565 } 32566 #endif 32567 32568 return BCM_E_UNAVAIL; 32569 } 32570 32571 /* 32572 * Function: 32573 * bcm_esw_port_frame_max_set 32574 * Description: 32575 * Set the maximum receive frame size for the port 32576 * Parameters: 32577 * unit - Device number 32578 * in_port - Port number 32579 * size - Maximum frame size in bytes 32580 * Return Value: 32581 * BCM_E_XXX 32582 * Notes: 32583 * Depending on chip or port type the actual maximum receive frame size 32584 * might be slightly higher. 32585 * 32586 * It looks like this operation is performed the same way on all the chips 32587 * and the only depends on the port type. 32588 */ 32589 int 32590 bcm_esw_port_frame_max_set(int unit, bcm_port_t in_port, int size) 32591 { 32592 bcm_port_t port; 32593 int max_size = BCM_PORT_JUMBO_MAXSZ; 32594 #if defined(BCM_XGS3_SWITCH_SUPPORT) 32595 uint32 rval; 32596 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 32597 #if defined(BCM_KATANA2_SUPPORT) 32598 int min_pp_port = SOC_INFO(unit).pp_port_index_min; 32599 #endif /* BCM_KATANA2_SUPPORT */ 32600 32601 /* Make sure port module is initialized. */ 32602 PORT_INIT(unit); 32603 32604 if(bcm_common_oamp_port_enable_get(unit, in_port)) { 32605 LOG_ERROR(BSL_LS_BCM_PORT, 32606 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32607 in_port)); 32608 return BCM_E_PARAM; 32609 } 32610 32611 /* Call Port Control module */ 32612 if (SOC_PORT_USE_PORTCTRL(unit, in_port)) { 32613 return bcmi_esw_portctrl_frame_max_set(unit, in_port, size); 32614 } 32615 32616 /* Set jumbo max size to 12k for Katana2 as per Arch team recommendation */ 32617 max_size = SOC_INFO(unit).max_mtu; 32618 #ifdef BCM_TRIDENT2_SUPPORT 32619 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TOMAHAWKX(unit) || 32620 SOC_IS_HURRICANE4(unit)) { 32621 if (IS_XE_PORT(unit, in_port) || IS_GE_PORT(unit, in_port) 32622 || IS_CE_PORT(unit, in_port) 32623 || (IS_C_PORT(unit, in_port) && IS_E_PORT(unit, in_port))) { 32624 max_size -= 4; 32625 } 32626 } 32627 #endif 32628 if (size < 0 || size > max_size) { 32629 return BCM_E_PARAM; 32630 } 32631 32632 if (!BCM_GPORT_IS_SET(in_port)) { 32633 if (!SOC_PBMP_MEMBER((PBMP_PORT_ALL(unit)), in_port)) { 32634 return BCM_E_PORT; 32635 } 32636 } 32637 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, in_port, &port)); 32638 32639 #if defined(BCM_KATANA2_SUPPORT) 32640 /* LinkPHY/SubportTag CoE subport does not have MAC */ 32641 #if defined(BCM_METROLITE_SUPPORT) 32642 if ((soc_feature(unit, soc_feature_linkphy_coe) || 32643 soc_feature(unit, soc_feature_subtag_coe)) && 32644 soc_feature(unit, soc_feature_discontinuous_pp_port) && 32645 (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, port) && 32646 !_SOC_IS_PORT_LINKPHY_SUBTAG(unit, port))) { 32647 } else 32648 #endif 32649 if ((soc_feature(unit, soc_feature_linkphy_coe) || 32650 soc_feature(unit, soc_feature_subtag_coe)) && 32651 !soc_feature(unit, soc_feature_discontinuous_pp_port) && 32652 (port >= min_pp_port)) { 32653 } else 32654 #endif 32655 { 32656 #ifdef BCM_HURRICANE4_SUPPORT 32657 if (SOC_IS_HURRICANE4(unit) && 32658 (IS_XE_PORT(unit, port) || IS_GE_PORT(unit, port) 32659 || IS_CE_PORT(unit, port) 32660 || (IS_C_PORT(unit, port) && IS_E_PORT(unit, port)))) { 32661 SOC_IF_ERROR_RETURN 32662 (MAC_FRAME_MAX_SET(PORT(unit, port).p_mac, unit, port, (size + 4))); 32663 } else 32664 #endif 32665 { 32666 SOC_IF_ERROR_RETURN 32667 (MAC_FRAME_MAX_SET(PORT(unit, port).p_mac, unit, port, size)); 32668 } 32669 } 32670 32671 #ifdef BCM_SHADOW_SUPPORT 32672 if (SOC_IS_SHADOW(unit)) { 32673 SOC_IF_ERROR_RETURN(READ_EGR_L2_MTUr(unit, port, &rval)); 32674 soc_reg_field_set(unit, EGR_L2_MTUr, &rval, 32675 VALUEf, size + 4); 32676 SOC_IF_ERROR_RETURN(WRITE_EGR_L2_MTUr(unit, port, rval)); 32677 } else 32678 #endif /* BCM_SHADOW_SUPPORT */ 32679 32680 #ifdef BCM_XGS3_SWITCH_SUPPORT 32681 if (SOC_IS_XGS3_SWITCH(unit)) { 32682 soc_reg_t reg; 32683 egr_mtu_entry_t mtu; 32684 uint32 mtu_size = size; 32685 uint32 field_val_set = 1; 32686 32687 if (IS_XE_PORT(unit, port) || IS_GE_PORT(unit, port) 32688 || IS_CE_PORT(unit, port) 32689 || (IS_C_PORT(unit, port) && IS_E_PORT(unit, port))) { 32690 mtu_size += 4; 32691 } 32692 32693 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 32694 soc_mem_t mem = EGR_MTUm; 32695 if (soc_feature(unit, soc_feature_egr_all_profile)) { 32696 BCM_IF_ERROR_RETURN( 32697 bcm_esw_port_egr_lport_field_set(unit, port, mem, 32698 MTU_SIZEf, mtu_size)); 32699 32700 } else { 32701 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 32702 port, &mtu)); 32703 soc_mem_field_set (unit, mem, (uint32 *)&mtu, MTU_SIZEf, 32704 &mtu_size); 32705 if (soc_mem_field_valid(unit, EGR_MTUm, MTU_ENABLEf)) { 32706 soc_mem_field_set(unit, EGR_MTUm, (uint32 *)&mtu, 32707 MTU_ENABLEf, &field_val_set); 32708 } 32709 32710 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ANY, 32711 port, &mtu)); 32712 } 32713 } else { 32714 reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr; 32715 32716 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 32717 soc_reg_field_set(unit, reg, &rval, MTU_SIZEf, mtu_size); 32718 if (soc_reg_field_valid(unit, reg, MTU_ENABLEf)) { 32719 soc_reg_field_set(unit, reg, &rval, MTU_ENABLEf, 1); 32720 } 32721 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 32722 } 32723 } 32724 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 32725 32726 return BCM_E_NONE; 32727 } 32728 32729 /* 32730 * Function: 32731 * bcm_esw_port_frame_max_get 32732 * Description: 32733 * Get the maximum receive frame size for the port 32734 * Parameters: 32735 * unit - Device number 32736 * in_port - Port number 32737 * size - Maximum frame size in bytes 32738 * Return Value: 32739 * BCM_E_XXX 32740 * Notes: 32741 * Depending on chip or port type the actual maximum receive frame size 32742 * might be slightly higher. 32743 * 32744 * For GE ports that use 2 separate MACs (one for GE and another one for 32745 * 10/100 modes) the function returns the maximum rx frame size set for 32746 * the current mode. 32747 */ 32748 int 32749 bcm_esw_port_frame_max_get(int unit, bcm_port_t in_port, int *size) 32750 { 32751 int rv = BCM_E_UNAVAIL; 32752 bcm_port_t port; 32753 #if defined(BCM_KATANA2_SUPPORT) 32754 uint32 rval; 32755 int min_pp_port = SOC_INFO(unit).pp_port_index_min; 32756 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 32757 32758 #if defined(BCM_SABER2_SUPPORT) 32759 if(SOC_IS_SABER2(unit)) { 32760 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 32761 } 32762 #endif 32763 #endif 32764 32765 /* Make sure port module is initialized. */ 32766 PORT_INIT(unit); 32767 32768 /* Call Port Control module */ 32769 if (SOC_PORT_USE_PORTCTRL(unit, in_port)) { 32770 return bcmi_esw_portctrl_frame_max_get(unit, in_port, size); 32771 } 32772 32773 #if defined(BCM_KATANA2_SUPPORT) 32774 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(in_port)) && 32775 (!((in_port >= 1) && (in_port <= max_phy_port) && 32776 SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),in_port)))) { 32777 return BCM_E_PORT; 32778 } 32779 #endif 32780 32781 if(bcm_common_oamp_port_enable_get(unit, in_port)) { 32782 LOG_ERROR(BSL_LS_BCM_PORT, 32783 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32784 in_port)); 32785 return BCM_E_PARAM; 32786 } 32787 32788 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, in_port, &port)); 32789 32790 #if defined(BCM_KATANA2_SUPPORT) 32791 /* LinkPHY/SubportTag CoE subport does not have MAC */ 32792 #if defined(BCM_METROLITE_SUPPORT) 32793 if ((soc_feature(unit, soc_feature_linkphy_coe) || 32794 soc_feature(unit, soc_feature_subtag_coe)) && 32795 soc_feature(unit, soc_feature_discontinuous_pp_port) && 32796 (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, port) && 32797 !_SOC_IS_PORT_LINKPHY_SUBTAG(unit, port))) { 32798 *size = 0; 32799 if (SOC_REG_IS_VALID(unit, EGR_MTUr)) { 32800 SOC_IF_ERROR_RETURN(READ_EGR_MTUr(unit, port, &rval)); 32801 if (soc_reg_field_get(unit, EGR_MTUr, rval, MTU_ENABLEf)) { 32802 *size = soc_reg_field_get(unit, EGR_MTUr, rval, MTU_SIZEf) - 4; 32803 } 32804 } 32805 rv = BCM_E_NONE; 32806 } else 32807 #endif 32808 if ((soc_feature(unit, soc_feature_linkphy_coe) || 32809 soc_feature(unit, soc_feature_subtag_coe)) && 32810 !soc_feature(unit, soc_feature_discontinuous_pp_port) && 32811 (port >= min_pp_port)) { 32812 *size = 0; 32813 if (SOC_REG_IS_VALID(unit, EGR_MTUr)) { 32814 SOC_IF_ERROR_RETURN(READ_EGR_MTUr(unit, port, &rval)); 32815 if (soc_reg_field_get(unit, EGR_MTUr, rval, MTU_ENABLEf)) { 32816 *size = soc_reg_field_get(unit, EGR_MTUr, rval, MTU_SIZEf) - 4; 32817 } 32818 } 32819 rv = BCM_E_NONE; 32820 } else 32821 #endif 32822 { 32823 rv = MAC_FRAME_MAX_GET(PORT(unit, port).p_mac, unit, port, size); 32824 #ifdef BCM_HURRICANE4_SUPPORT 32825 if (SOC_IS_HURRICANE4(unit) && 32826 (IS_XE_PORT(unit, port) || IS_GE_PORT(unit, port) 32827 || IS_CE_PORT(unit, port) 32828 || (IS_C_PORT(unit, port) && IS_E_PORT(unit, port)))) { 32829 *size = *size - 4; 32830 } 32831 #endif 32832 } 32833 32834 return rv; 32835 } 32836 32837 /* 32838 * Function: 32839 * bcm_esw_port_l3_mtu_set 32840 * Description: 32841 * Set the maximum L3 frame size for the port 32842 * Parameters: 32843 * unit - Device number 32844 * port - Port number 32845 * size - Maximum frame size in bytes 32846 * Return Value: 32847 * BCM_E_XXX 32848 */ 32849 int 32850 bcm_esw_port_l3_mtu_set(int unit, bcm_port_t port, int size) 32851 { 32852 int rv = BCM_E_UNAVAIL; 32853 32854 /* Make sure port module is initialized. */ 32855 PORT_INIT(unit); 32856 32857 COMPILER_REFERENCE(rv); 32858 32859 if(bcm_common_oamp_port_enable_get(unit, port)) { 32860 LOG_ERROR(BSL_LS_BCM_PORT, 32861 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32862 port)); 32863 return BCM_E_PARAM; 32864 } 32865 32866 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3) 32867 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 32868 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 32869 32870 int encap_bytes = 0; 32871 soc_info_t *si = &SOC_INFO(unit); 32872 soc_field_t fields[2]; 32873 uint32 values[2]; 32874 32875 if (soc_feature(unit, soc_feature_egr_all_profile) || 32876 (((soc_feature(unit, soc_feature_hgproxy_subtag_coe)) || 32877 (soc_feature(unit, soc_feature_channelized_switching))) && 32878 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))) { 32879 32880 #if defined(BCM_CHANNELIZED_SWITCHING_SUPPORT) 32881 if (soc_feature(unit, soc_feature_channelized_switching)) { 32882 32883 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 32884 encap_bytes = 4; 32885 } else { 32886 if (BCM_PBMP_MEMBER(si->subtag_allowed_pbm, port)) { 32887 encap_bytes = 4; 32888 32889 } 32890 } 32891 } 32892 #endif 32893 32894 if ((size + encap_bytes) > si->max_mtu) { 32895 32896 LOG_ERROR(BSL_LS_BCM_PORT, 32897 (BSL_META("MTU (%d) more than max mtu (%d) .\n"), 32898 (size + encap_bytes), si->max_mtu)); 32899 32900 if (encap_bytes) { 32901 LOG_ERROR( 32902 BSL_LS_BCM_PORT, 32903 (BSL_META_U(unit, 32904 "For CoE port 0x%x, extra 4 bytes are added " 32905 "to user provided MTU to account for SVTAG \n"), 32906 port)); 32907 } 32908 32909 return BCM_E_PARAM; 32910 } 32911 32912 /* Add extra encap bytes on port. */ 32913 size += encap_bytes; 32914 32915 /* Setup the fields and their values */ 32916 fields[0] = MTU_SIZEf; values[0] = size; 32917 fields[1] = MTU_ENABLEf; values[1] = 1; 32918 32919 return bcm_esw_port_egr_lport_fields_set(unit, port, 32920 EGR_MTUm, 2, fields, values); 32921 32922 } else { 32923 egr_mtu_entry_t egr_mtu_entry; 32924 32925 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32926 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_MTUm, 32927 MEM_BLOCK_ANY, port, &egr_mtu_entry)); 32928 /* Set up the fields */ 32929 soc_mem_field32_set(unit, EGR_MTUm, &egr_mtu_entry, MTU_SIZEf, size); 32930 soc_mem_field32_set(unit, EGR_MTUm, &egr_mtu_entry, MTU_ENABLEf, 32931 1); 32932 /* Write data to hardware */ 32933 return soc_mem_write(unit, EGR_MTUm, MEM_BLOCK_ANY, port, &egr_mtu_entry); 32934 } 32935 } else 32936 #endif 32937 { 32938 if (soc_feature(unit, soc_feature_egr_l3_mtu)) { 32939 soc_reg_t reg; 32940 32941 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32942 reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr; 32943 return soc_reg_field32_modify(unit, reg, port, 32944 (SOC_REG_FIELD_VALID(unit, reg, L3_MTU_SIZEf) ? 32945 L3_MTU_SIZEf : MTU_SIZEf), size); 32946 } 32947 } 32948 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */ 32949 32950 return BCM_E_UNAVAIL; 32951 32952 } 32953 32954 /* 32955 * Function: 32956 * bcm_esw_port_l3_mtu_get 32957 * Description: 32958 * Get the maximum L3 frame size for the port 32959 * Parameters: 32960 * unit - Device number 32961 * port - Port number 32962 * size - Maximum frame size in bytes 32963 * Return Value: 32964 * BCM_E_XXX 32965 */ 32966 int 32967 bcm_esw_port_l3_mtu_get(int unit, bcm_port_t port, int *size) 32968 { 32969 /* Make sure port module is initialized. */ 32970 PORT_INIT(unit); 32971 32972 if(bcm_common_oamp_port_enable_get(unit, port)) { 32973 LOG_ERROR(BSL_LS_BCM_PORT, 32974 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32975 port)); 32976 return BCM_E_PARAM; 32977 } 32978 32979 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3) 32980 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 32981 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 32982 if (soc_feature(unit, soc_feature_egr_all_profile) || 32983 ((soc_feature(unit, soc_feature_hgproxy_subtag_coe)) && 32984 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))) { 32985 32986 int rv = BCM_E_NONE; 32987 32988 rv = bcm_esw_port_egr_lport_field_get(unit, port, 32989 EGR_MTUm, MTU_SIZEf, (uint32*)size); 32990 32991 #if defined(BCM_CHANNELIZED_SWITCHING_SUPPORT) 32992 if (BCM_SUCCESS(rv)) { 32993 if (soc_feature(unit, soc_feature_channelized_switching)) { 32994 soc_info_t *si = &SOC_INFO(unit); 32995 32996 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 32997 *size -= 4; 32998 } else { 32999 if (BCM_PBMP_MEMBER(si->subtag_allowed_pbm, port)) { 33000 *size -= 4; 33001 } 33002 } 33003 } 33004 } 33005 #endif 33006 return rv; 33007 33008 } else { 33009 egr_mtu_entry_t entry; 33010 33011 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33012 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_MTUm, MEM_BLOCK_ANY, port, &entry)); 33013 *size = soc_mem_field32_get(unit, EGR_MTUm, &entry, MTU_SIZEf); 33014 return BCM_E_NONE; 33015 } 33016 } else 33017 #endif 33018 { 33019 if (soc_feature(unit, soc_feature_egr_l3_mtu)) { 33020 soc_reg_t reg; 33021 uint32 rval; 33022 33023 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33024 33025 reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr; 33026 33027 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 33028 *size = soc_reg_field_get(unit, reg, rval, 33029 (SOC_REG_FIELD_VALID(unit, reg,L3_MTU_SIZEf) ? 33030 L3_MTU_SIZEf : MTU_SIZEf)); 33031 return BCM_E_NONE; 33032 } 33033 } 33034 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */ 33035 33036 return BCM_E_UNAVAIL; 33037 } 33038 33039 #ifdef BCM_WARM_BOOT_SUPPORT 33040 /* 33041 * Function: 33042 * _bcm_esw_port_ipg_ifg_wb_set 33043 * Purpose: 33044 * Restore the ifg based on the working speed and duplex 33045 */ 33046 STATIC int 33047 _bcm_esw_port_ipg_ifg_wb_set( 33048 int unit, 33049 bcm_port_t port, 33050 soc_ipg_t *ipg, 33051 uint32 ifg) 33052 { 33053 int speed, duplex; 33054 33055 if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) { 33056 /* XLMAC or CLMAC */ 33057 ipg->fd_xe = ifg; 33058 } else { 33059 /* UNIMAC */ 33060 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 33061 BCM_IF_ERROR_RETURN 33062 (bcm_esw_port_speed_get(unit, port, &speed)); 33063 BCM_IF_ERROR_RETURN 33064 (bcm_esw_port_duplex_get(unit, port, &duplex)); 33065 } else { 33066 BCM_IF_ERROR_RETURN( 33067 MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, &speed)); 33068 BCM_IF_ERROR_RETURN( 33069 MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &duplex)); 33070 } 33071 if (duplex == BCM_PORT_DUPLEX_FULL) { 33072 switch (speed) { 33073 case 10: 33074 ipg->fd_10 = ifg; 33075 break; 33076 case 100: 33077 ipg->fd_100 = ifg; 33078 break; 33079 case 1000: 33080 ipg->fd_1000 = ifg; 33081 break; 33082 case 2500: 33083 ipg->fd_2500 = ifg; 33084 break; 33085 default: 33086 return BCM_E_PARAM; 33087 } 33088 } else { 33089 switch (speed) { 33090 case 10: 33091 ipg->hd_10 = ifg; 33092 break; 33093 case 100: 33094 ipg->hd_100 = ifg; 33095 break; 33096 default: 33097 return BCM_E_PARAM; 33098 } 33099 } 33100 } 33101 return BCM_E_NONE; 33102 } 33103 33104 /* 33105 * Function: 33106 * _bcm_esw_port_ipg_ifg_wb_get 33107 * Purpose: 33108 * Get the ifg based on the working speed and duplex 33109 */ 33110 STATIC int 33111 _bcm_esw_port_ipg_ifg_wb_get( 33112 int unit, 33113 bcm_port_t port, 33114 soc_ipg_t *ipg, 33115 uint32 *ifg) 33116 { 33117 int speed, duplex; 33118 33119 if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) { 33120 /* XLMAC or CLMAC */ 33121 *ifg = ipg->fd_xe; 33122 } else { 33123 /* UNIMAC */ 33124 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 33125 BCM_IF_ERROR_RETURN 33126 (bcm_esw_port_speed_get(unit, port, &speed)); 33127 BCM_IF_ERROR_RETURN 33128 (bcm_esw_port_duplex_get(unit, port, &duplex)); 33129 } else { 33130 BCM_IF_ERROR_RETURN( 33131 MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, &speed)); 33132 BCM_IF_ERROR_RETURN( 33133 MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &duplex)); 33134 } 33135 if (duplex == BCM_PORT_DUPLEX_FULL) { 33136 switch (speed) { 33137 case 10: 33138 *ifg = ipg->fd_10; 33139 break; 33140 case 100: 33141 *ifg = ipg->fd_100; 33142 break; 33143 case 1000: 33144 *ifg = ipg->fd_1000; 33145 break; 33146 case 2500: 33147 *ifg = ipg->fd_2500; 33148 break; 33149 default: 33150 return BCM_E_PARAM; 33151 } 33152 } else { 33153 switch (speed) { 33154 case 10: 33155 *ifg = ipg->hd_10; 33156 break; 33157 case 100: 33158 *ifg = ipg->hd_100; 33159 break; 33160 default: 33161 return BCM_E_PARAM; 33162 } 33163 } 33164 } 33165 return BCM_E_NONE; 33166 } 33167 33168 /* 33169 * Function: 33170 * _bcm_esw_port_ifg_wb_sync 33171 * Purpose: 33172 * Sync port_ifg DB to scache. 33173 * Parameters: 33174 * unit - Device unit number 33175 * scache_ptr - Scache pointer. 33176 * Returns: 33177 * BCM_E_XXX 33178 */ 33179 STATIC int 33180 _bcm_esw_port_ifg_wb_sync(int unit, uint8 **scache_ptr) 33181 { 33182 bcm_port_t port; 33183 soc_ipg_t *si = NULL; 33184 uint32 ifg = 0; 33185 int mode = 0; 33186 int rv = BCM_E_NONE; 33187 33188 if ((scache_ptr == NULL) || (*scache_ptr == NULL)) { 33189 return BCM_E_PARAM; 33190 } 33191 33192 PBMP_ALL_ITER(unit, port) { 33193 si = &SOC_PERSIST(unit)->ipg[port]; 33194 if (IS_E_PORT(unit, port)) { 33195 if (soc_feature(unit, soc_feature_ifg_wb_include_unimac) || 33196 IS_EGPHY_PORT(unit, port)) { 33197 BCM_IF_ERROR_RETURN( 33198 _bcm_esw_port_ipg_ifg_wb_get(unit, port, si, &ifg)); 33199 } else { 33200 ifg = si->fd_xe; 33201 } 33202 } else { 33203 if (soc_feature(unit, soc_feature_xmac)) { 33204 rv = bcm_esw_port_encap_get(unit, port, &mode); 33205 if (BCM_E_NONE == rv) { 33206 if (BCM_PORT_ENCAP_HIGIG2 == mode) { 33207 ifg = si->fd_hg2; 33208 } else { 33209 ifg = si->fd_hg; 33210 } 33211 } 33212 } else { 33213 ifg = si->fd_hg; 33214 } 33215 } 33216 sal_memcpy(*scache_ptr, &ifg, sizeof(uint32)); 33217 *scache_ptr += sizeof(uint32); 33218 33219 rv = _scache_port_print_add(unit, port, SPT_IFG, sizeof(uint32), 33220 *scache_ptr - sizeof(uint32)); 33221 if (BCM_FAILURE(rv)) { 33222 return rv; 33223 } 33224 } 33225 33226 return BCM_E_NONE; 33227 } 33228 33229 /* 33230 * Function: 33231 * _bcm_esw_port_ifg_wb_reinit 33232 * Purpose: 33233 * Retrieve port_ifg from scache. 33234 * Parameters: 33235 * unit - Device unit number 33236 * scache_ptr - Scache pointer. 33237 * Returns: 33238 * BCM_E_XXX 33239 */ 33240 STATIC int 33241 _bcm_esw_port_ifg_wb_reinit(int unit, uint8 **scache_ptr) 33242 { 33243 bcm_port_t port; 33244 soc_ipg_t *si = NULL; 33245 uint32 ifg = 0; 33246 int mode = 0; 33247 int rv = BCM_E_NONE; 33248 33249 if ((scache_ptr == NULL) || (*scache_ptr == NULL)) { 33250 return BCM_E_PARAM; 33251 } 33252 33253 PBMP_ALL_ITER(unit, port) { 33254 si = &SOC_PERSIST(unit)->ipg[port]; 33255 sal_memcpy(&ifg, *scache_ptr, sizeof(uint32)); 33256 if (IS_E_PORT(unit, port)) { 33257 if (soc_feature(unit, soc_feature_ifg_wb_include_unimac) || 33258 IS_EGPHY_PORT(unit, port)) { 33259 BCM_IF_ERROR_RETURN( 33260 _bcm_esw_port_ipg_ifg_wb_set(unit, port, si, ifg)); 33261 } else { 33262 si->fd_xe = ifg; 33263 } 33264 } else { 33265 if (soc_feature(unit, soc_feature_xmac)) { 33266 rv = bcm_esw_port_encap_get(unit, port, &mode); 33267 if (BCM_E_NONE == rv) { 33268 if (BCM_PORT_ENCAP_HIGIG2 == mode) { 33269 si->fd_hg2 = ifg; 33270 } else { 33271 si->fd_hg = ifg; 33272 } 33273 } 33274 } else { 33275 si->fd_hg = ifg; 33276 } 33277 } 33278 *scache_ptr += sizeof(uint32); 33279 33280 rv = _scache_port_print_add(unit, port, SPT_IFG, sizeof(uint32), 33281 *scache_ptr - sizeof(uint32)); 33282 if (BCM_FAILURE(rv)) { 33283 return rv; 33284 } 33285 } 33286 33287 return BCM_E_NONE; 33288 } 33289 #endif 33290 33291 /* 33292 * Function: 33293 * bcm_esw_port_ifg_set 33294 * Description: 33295 * Sets the new ifg (Inter-frame gap) value 33296 * Parameters: 33297 * unit - Device number 33298 * port - Port number 33299 * speed - the speed for which the IFG is being set 33300 * duplex - the duplex for which the IFG is being set 33301 * ifg - Inter-frame gap in bit-times 33302 * Return Value: 33303 * BCM_E_XXX 33304 * Notes: 33305 * The function makes sure the IFG value makes sense and updates the 33306 * IPG register in case the speed/duplex match the current settings 33307 */ 33308 int 33309 bcm_esw_port_ifg_set(int unit, bcm_port_t port, 33310 int speed, bcm_port_duplex_t duplex, 33311 int ifg) 33312 { 33313 33314 /* Make sure port module is initialized. */ 33315 PORT_INIT(unit); 33316 33317 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 33318 return bcmi_esw_portctrl_ifg_set(unit, port, speed, duplex, ifg); 33319 } 33320 33321 if(bcm_common_oamp_port_enable_get(unit, port)) { 33322 LOG_ERROR(BSL_LS_BCM_PORT, 33323 (BSL_META("Error: Not permitted on OAMP port %d.n"), 33324 port)); 33325 return BCM_E_PARAM; 33326 } 33327 33328 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33329 33330 return MAC_IFG_SET(PORT(unit, port).p_mac, unit, port, 33331 speed, duplex, ifg); 33332 } 33333 33334 /* 33335 * Function: 33336 * bcm_port_ifg_get 33337 * Description: 33338 * Gets the new ifg (Inter-frame gap) value 33339 * Parameters: 33340 * unit - Device number 33341 * port - Port number 33342 * speed - the speed for which the IFG is being set 33343 * duplex - the duplex for which the IFG is being set 33344 * ifg - Inter-frame gap in bit-times 33345 * Return Value: 33346 * BCM_E_XXX 33347 * Notes: 33348 */ 33349 int 33350 bcm_esw_port_ifg_get(int unit, bcm_port_t port, 33351 int speed, bcm_port_duplex_t duplex, 33352 int *ifg) 33353 { 33354 /* Make sure port module is initialized. */ 33355 PORT_INIT(unit); 33356 33357 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 33358 return bcmi_esw_portctrl_ifg_get(unit, port, speed, duplex, ifg); 33359 } 33360 33361 if(bcm_common_oamp_port_enable_get(unit, port)) { 33362 LOG_ERROR(BSL_LS_BCM_PORT, 33363 (BSL_META("Error: Not permitted on OAMP port %d.n"), 33364 port)); 33365 return BCM_E_PARAM; 33366 } 33367 33368 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33369 33370 return MAC_IFG_GET(PORT(unit, port).p_mac, unit, port, 33371 speed, duplex, ifg); 33372 } 33373 33374 /* 33375 * Function: 33376 * bcm_port_phy_get 33377 * Description: 33378 * General PHY register read 33379 * Parameters: 33380 * unit - Device number 33381 * port - Port number or PHY MDIO address (refer BCM_PORT_PHY_NOMAP) 33382 * flags - Logical OR of one or more of the following flags: 33383 * BCM_PORT_PHY_INTERNAL 33384 * Address internal SERDES PHY for port 33385 * BCM_PORT_PHY_NOMAP 33386 * Instead of mapping port to PHY MDIO address, 33387 * treat port parameter as actual PHY MDIO address. 33388 * BCM_PORT_PHY_CLAUSE45 33389 * Assume Clause 45 device instead of Clause 22 33390 * phy_addr - PHY internal register address 33391 * phy_data - (OUT) Data that was read 33392 * Returns: 33393 * BCM_E_XXX 33394 */ 33395 int 33396 bcm_esw_port_phy_get(int unit, bcm_port_t port, uint32 flags, 33397 uint32 phy_reg_addr, uint32 *phy_data) 33398 { 33399 uint16 phy_id; 33400 uint8 phy_devad; 33401 uint16 phy_reg; 33402 uint16 phy_rd_data; 33403 uint32 reg_flag; 33404 int rv; 33405 int lane = -1; 33406 int phyn = -1, sys_side = 0; 33407 bcm_port_t local_port = -1; 33408 33409 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 33410 return bcmi_esw_portctrl_phy_get(unit, port, flags, phy_reg_addr, 33411 phy_data); 33412 } 33413 33414 /* Make sure port module is initialized. */ 33415 PORT_INIT(unit); 33416 33417 if(bcm_common_oamp_port_enable_get(unit, port)) { 33418 LOG_ERROR(BSL_LS_BCM_PORT, 33419 (BSL_META("Error: Not permitted on OAMP port %d.n"), 33420 port)); 33421 return BCM_E_PARAM; 33422 } 33423 33424 if (!(flags & BCM_PORT_PHY_NOMAP)) { 33425 BCM_IF_ERROR_RETURN 33426 (_bcm_esw_port_gport_phyn_validate(unit, port, 33427 &local_port, &phyn, 33428 &lane, &sys_side)); 33429 if (local_port != -1) { 33430 port = local_port; 33431 } 33432 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33433 33434 if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) { 33435 return BCM_E_PORT; 33436 } 33437 } 33438 33439 if (flags & (SOC_PHY_I2C_DATA8 | SOC_PHY_I2C_DATA16 | SOC_PHY_PVT_DATA)) { 33440 PORT_LOCK(unit); 33441 rv = soc_phyctrl_reg_read(unit, port, flags, phy_reg_addr, phy_data); 33442 PORT_UNLOCK(unit); 33443 return rv; 33444 } 33445 33446 rv = BCM_E_UNAVAIL; 33447 reg_flag = BCM_PORT_PHY_REG_FLAGS(phy_reg_addr); 33448 if ( (reg_flag & SOC_PHY_REG_INDIRECT) || 33449 (flags & (BCM_PORT_PHY_REG_RDB | BCM_PORT_PHY_REG_MACSEC)) ) { 33450 if (flags & BCM_PORT_PHY_NOMAP) { 33451 /* Indirect register access is performed through PHY driver. 33452 * Therefore, indirect register access is not supported if 33453 * BCM_PORT_PHY_NOMAP flag is set. 33454 */ 33455 return BCM_E_PARAM; 33456 } 33457 phy_reg_addr &= ~SOC_PHY_REG_INDIRECT; 33458 33459 if (lane >= 0) { 33460 #if defined(PHYMOD_SUPPORT) 33461 SOC_PHY_PHYMOD_FORCE_LANE_SET(phy_reg_addr, lane); 33462 #endif 33463 } 33464 if (phyn == 1) { 33465 flags |= SOC_PHY_INTERNAL; 33466 } 33467 PORT_LOCK(unit); 33468 rv = soc_phyctrl_reg_read(unit, port, flags, phy_reg_addr, phy_data); 33469 PORT_UNLOCK(unit); 33470 } 33471 33472 if (rv == BCM_E_UNAVAIL) { 33473 if (flags & BCM_PORT_PHY_NOMAP) { 33474 phy_id = port; 33475 } else if (flags & BCM_PORT_PHY_INTERNAL) { 33476 phy_id = PORT_TO_PHY_ADDR_INT(unit, port); 33477 } else { 33478 phy_id = PORT_TO_PHY_ADDR(unit, port); 33479 } 33480 33481 PORT_LOCK(unit); 33482 if (flags & BCM_PORT_PHY_CLAUSE45) { 33483 phy_devad = BCM_PORT_PHY_CLAUSE45_DEVAD(phy_reg_addr); 33484 phy_reg = BCM_PORT_PHY_CLAUSE45_REGAD(phy_reg_addr); 33485 rv = soc_miimc45_read(unit, phy_id, phy_devad, 33486 phy_reg, &phy_rd_data); 33487 33488 } else { 33489 phy_reg = phy_reg_addr; 33490 rv = soc_miim_read(unit, phy_id, phy_reg, &phy_rd_data); 33491 } 33492 PORT_UNLOCK(unit); 33493 33494 if (BCM_SUCCESS(rv)) { 33495 *phy_data = phy_rd_data; 33496 } 33497 } 33498 33499 LOG_INFO(BSL_LS_BCM_PORT, 33500 (BSL_META_U(unit, 33501 "bcm_esw_port_phy_get: u=%d p=%d flags=0x%08x " 33502 "phy_reg=0x%08x, phy_data=0x%08x, rv=%d\n"), 33503 unit, port, flags, phy_reg_addr, *phy_data, rv)); 33504 33505 return rv; 33506 } 33507 33508 /* 33509 * Function: 33510 * bcm_port_phy_set 33511 * Description: 33512 * General PHY register write 33513 * Parameters: 33514 * unit - Device number 33515 * port - Port number or PHY MDIO address (refer BCM_PORT_PHY_NOMAP) 33516 * flags - Logical OR of one or more of the following flags: 33517 * BCM_PORT_PHY_INTERNAL 33518 * Address internal SERDES PHY for port 33519 * BCM_PORT_PHY_NOMAP 33520 * Instead of mapping port to PHY MDIO address, 33521 * treat port parameter as actual PHY MDIO address. 33522 * BCM_PORT_PHY_CLAUSE45 33523 * Assume Clause 45 device instead of Clause 22 33524 * BCM_PORT_PHY_BROADCAST_WRITE 33525 * Broadcast write transactions to all MDIO buses 33526 * within one unit. All the ports that have the same 33527 * phy address as the specified port will receive 33528 * the write command. 33529 * phy_addr - PHY internal register address 33530 * phy_data - Data to write 33531 * Returns: 33532 * BCM_E_XXX 33533 */ 33534 int 33535 bcm_esw_port_phy_set(int unit, bcm_port_t port, uint32 flags, 33536 uint32 phy_reg_addr, uint32 phy_data) 33537 { 33538 uint16 phy_id; 33539 uint8 phy_devad; 33540 uint16 phy_reg; 33541 uint16 phy_wr_data; 33542 uint32 reg_flag; 33543 int rv; 33544 int lane = -1; 33545 int phyn = -1, sys_side = 0; 33546 bcm_port_t local_port = -1; 33547 33548 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 33549 return bcmi_esw_portctrl_phy_set(unit, port, flags, phy_reg_addr, 33550 phy_data); 33551 } 33552 33553 /* Make sure port module is initialized. */ 33554 PORT_INIT(unit); 33555 33556 if(bcm_common_oamp_port_enable_get(unit, port)) { 33557 LOG_ERROR(BSL_LS_BCM_PORT, 33558 (BSL_META("Error: Not permitted on OAMP port %d.n"), 33559 port)); 33560 return BCM_E_PARAM; 33561 } 33562 33563 if (!(flags & BCM_PORT_PHY_NOMAP)) { 33564 BCM_IF_ERROR_RETURN 33565 (_bcm_esw_port_gport_phyn_validate(unit, port, 33566 &local_port, &phyn, 33567 &lane, &sys_side)); 33568 if (local_port != -1) { 33569 port = local_port; 33570 } 33571 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33572 33573 if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) { 33574 return BCM_E_PORT; 33575 } 33576 } 33577 33578 LOG_INFO(BSL_LS_BCM_PORT, 33579 (BSL_META_U(unit, 33580 "bcm_esw_port_phy_set: u=%d p=%d flags=0x%08x " 33581 "phy_reg=0x%08x phy_data=0x%08x\n"), 33582 unit, port, flags, phy_reg_addr, phy_data)); 33583 33584 if (flags & (SOC_PHY_I2C_DATA8 | SOC_PHY_I2C_DATA16 | SOC_PHY_PVT_DATA)) { 33585 PORT_LOCK(unit); 33586 rv = soc_phyctrl_reg_write(unit, port, flags, phy_reg_addr, phy_data); 33587 PORT_UNLOCK(unit); 33588 return rv; 33589 } 33590 33591 rv = BCM_E_UNAVAIL; 33592 reg_flag = BCM_PORT_PHY_REG_FLAGS(phy_reg_addr); 33593 if ( (reg_flag & SOC_PHY_REG_INDIRECT) || 33594 (flags & (BCM_PORT_PHY_REG_RDB | BCM_PORT_PHY_REG_MACSEC)) ) { 33595 if (flags & BCM_PORT_PHY_NOMAP) { 33596 /* Indirect register access is performed through PHY driver. 33597 * Therefore, indirect register access is not supported if 33598 * BCM_PORT_PHY_NOMAP flag is set. 33599 */ 33600 return BCM_E_PARAM; 33601 } 33602 phy_reg_addr &= ~SOC_PHY_REG_INDIRECT; 33603 if (lane >= 0) { 33604 #if defined(PHYMOD_SUPPORT) 33605 SOC_PHY_PHYMOD_FORCE_LANE_SET(phy_reg_addr, lane); 33606 #endif 33607 } 33608 if (phyn == 1) { 33609 flags |= SOC_PHY_INTERNAL; 33610 } 33611 PORT_LOCK(unit); 33612 rv = soc_phyctrl_reg_write(unit, port, flags, phy_reg_addr, phy_data); 33613 PORT_UNLOCK(unit); 33614 } 33615 33616 if (rv == BCM_E_UNAVAIL) { 33617 if (flags & BCM_PORT_PHY_NOMAP) { 33618 phy_id = port; 33619 } else if (flags & BCM_PORT_PHY_INTERNAL) { 33620 phy_id = PORT_TO_PHY_ADDR_INT(unit, port); 33621 } else { 33622 phy_id = PORT_TO_PHY_ADDR(unit, port); 33623 } 33624 33625 if (flags & BCM_PORT_PHY_BROADCAST_WRITE) { 33626 phy_id |= 0x400; 33627 } 33628 33629 phy_wr_data = (uint16) (phy_data & 0xffff); 33630 PORT_LOCK(unit); 33631 if (flags & BCM_PORT_PHY_CLAUSE45) { 33632 phy_devad = BCM_PORT_PHY_CLAUSE45_DEVAD(phy_reg_addr); 33633 phy_reg = BCM_PORT_PHY_CLAUSE45_REGAD(phy_reg_addr); 33634 rv = soc_miimc45_write(unit, phy_id, phy_devad, 33635 phy_reg, phy_wr_data); 33636 } else { 33637 phy_reg = phy_reg_addr; 33638 rv = soc_miim_write(unit, phy_id, phy_reg, phy_wr_data); 33639 } 33640 PORT_UNLOCK(unit); 33641 } 33642 return rv; 33643 } 33644 /* 33645 * Function: 33646 * bcm_port_phy_multi_get 33647 * Description: 33648 * General PHY register read 33649 * Parameters: 33650 * unit - Device number 33651 * port - Port number 33652 * flags - TBD 33653 * dev_addr - Device address on the PHY's bus (ex. I2C addr) 33654 * offset - Offset within device 33655 * max_size - Requested data size 33656 * data - Data buffer 33657 * actual_size - Received data size 33658 * Returns: 33659 * BCM_E_XXX 33660 */ 33661 int 33662 bcm_esw_port_phy_multi_get(int unit, bcm_port_t port, uint32 flags, 33663 uint32 dev_addr, uint32 offset, int max_size, uint8 *data, int *actual_size) 33664 { 33665 int rv; 33666 33667 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 33668 return bcmi_esw_portctrl_phy_multi_get(unit, port, flags, dev_addr, 33669 offset, max_size, data, 33670 actual_size); 33671 } 33672 33673 /* Make sure port module is initialized. */ 33674 PORT_INIT(unit); 33675 33676 if(bcm_common_oamp_port_enable_get(unit, port)) { 33677 LOG_ERROR(BSL_LS_BCM_PORT, 33678 (BSL_META("Error: Not permitted on OAMP port %d.n"), 33679 port)); 33680 return BCM_E_PARAM; 33681 } 33682 33683 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33684 33685 PORT_LOCK(unit); 33686 rv = soc_phyctrl_port_phy_multi_get(unit, port, flags, dev_addr, offset, max_size, data, actual_size); 33687 PORT_UNLOCK(unit); 33688 /* 33689 LOG_INFO(BSL_LS_BCM_PORT, 33690 (BSL_META_U(unit, 33691 "bcm_esw_port_phy_multi_get: u=%d p=%d flags=0x%08x " 33692 "dev_addr=0x%08x, offset=0x%08x, max_size=%d data=%p actual_size=%d rv=%d\n"), 33693 unit, port, flags, dev_addr, offset, max_size, data, *actual_size, rv)); 33694 */ 33695 return rv; 33696 } 33697 33698 /* 33699 * Function: 33700 * bcm_port_phy_modify 33701 * Description: 33702 * General PHY register modify 33703 * Parameters: 33704 * unit - Device number 33705 * port - Port number or PHY MDIO address (refer BCM_PORT_PHY_NOMAP) 33706 * flags - Logical OR of one or more of the following flags: 33707 * BCM_PORT_PHY_INTERNAL 33708 * Address internal SERDES PHY for port 33709 * BCM_PORT_PHY_NOMAP 33710 * Instead of mapping port to PHY MDIO address, 33711 * treat port parameter as actual PHY MDIO address. 33712 * BCM_PORT_PHY_CLAUSE45 33713 * Assume Clause 45 device instead of Clause 22 33714 * phy_addr - PHY internal register address 33715 * phy_data - Data to write 33716 * phy_mask - Bits to modify using phy_data 33717 * Returns: 33718 * BCM_E_XXX 33719 */ 33720 int 33721 bcm_esw_port_phy_modify(int unit, bcm_port_t port, uint32 flags, 33722 uint32 phy_reg_addr, uint32 phy_data, uint32 phy_mask) 33723 { 33724 uint16 phy_id; 33725 uint8 phy_devad; 33726 uint16 phy_reg; 33727 uint16 phy_rd_data; 33728 uint16 phy_wr_data; 33729 uint32 reg_flag; 33730 int rv; 33731 int lane = -1; 33732 int phyn = -1, sys_side = 0; 33733 bcm_port_t local_port = -1; 33734 33735 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 33736 return bcmi_esw_portctrl_phy_modify(unit, port, flags, phy_reg_addr, 33737 phy_data, phy_mask); 33738 } 33739 33740 /* Make sure port module is initialized. */ 33741 PORT_INIT(unit); 33742 33743 if(bcm_common_oamp_port_enable_get(unit, port)) { 33744 LOG_ERROR(BSL_LS_BCM_PORT, 33745 (BSL_META("Error: Not permitted on OAMP port %d.n"), 33746 port)); 33747 return BCM_E_PARAM; 33748 } 33749 33750 if (!(flags & BCM_PORT_PHY_NOMAP)) { 33751 BCM_IF_ERROR_RETURN 33752 (_bcm_esw_port_gport_phyn_validate(unit, port, 33753 &local_port, &phyn, 33754 &lane, &sys_side)); 33755 if (local_port != -1) { 33756 port = local_port; 33757 } 33758 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33759 33760 if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) { 33761 return BCM_E_PORT; 33762 } 33763 } 33764 33765 LOG_INFO(BSL_LS_BCM_PORT, 33766 (BSL_META_U(unit, 33767 "bcm_esw_port_phy_modify: u=%d p=%d flags=0x%08x " 33768 "phy_reg=0x%08x phy_data=0x%08x phy_mask=0x%08x\n"), 33769 unit, port, flags, phy_reg_addr, phy_data, phy_mask)); 33770 33771 rv = BCM_E_UNAVAIL; 33772 reg_flag = BCM_PORT_PHY_REG_FLAGS(phy_reg_addr); 33773 if (reg_flag & SOC_PHY_REG_INDIRECT) { 33774 if (flags & BCM_PORT_PHY_NOMAP) { 33775 /* Indirect register access is performed through PHY driver. 33776 * Therefore, indirect register access is not supported if 33777 * BCM_PORT_PHY_NOMAP flag is set. 33778 */ 33779 return BCM_E_PARAM; 33780 } 33781 phy_reg_addr &= ~SOC_PHY_REG_INDIRECT; 33782 if (lane >= 0) { 33783 #if defined(PHYMOD_SUPPORT) 33784 SOC_PHY_PHYMOD_FORCE_LANE_SET(phy_reg_addr, lane); 33785 #endif 33786 } 33787 if (phyn == 1) { 33788 flags |= SOC_PHY_INTERNAL; 33789 } 33790 PORT_LOCK(unit); 33791 rv = soc_phyctrl_reg_modify(unit, port, flags, phy_reg_addr, 33792 phy_data, phy_mask); 33793 PORT_UNLOCK(unit); 33794 } 33795 33796 if (rv == BCM_E_UNAVAIL) { 33797 if (flags & BCM_PORT_PHY_NOMAP) { 33798 phy_id = port; 33799 } else if (flags & BCM_PORT_PHY_INTERNAL) { 33800 phy_id = PORT_TO_PHY_ADDR_INT(unit, port); 33801 } else { 33802 phy_id = PORT_TO_PHY_ADDR(unit, port); 33803 } 33804 33805 phy_wr_data = (uint16) (phy_data & phy_mask & 0xffff); 33806 PORT_LOCK(unit); 33807 if (flags & BCM_PORT_PHY_CLAUSE45) { 33808 phy_devad = BCM_PORT_PHY_CLAUSE45_DEVAD(phy_reg_addr); 33809 phy_reg = BCM_PORT_PHY_CLAUSE45_REGAD(phy_reg_addr); 33810 rv = soc_miimc45_read(unit, phy_id, phy_devad, 33811 phy_reg, &phy_rd_data); 33812 phy_wr_data |= (phy_rd_data & ~phy_mask); 33813 rv = soc_miimc45_write(unit, phy_id, phy_devad, 33814 phy_reg, phy_wr_data); 33815 } else { 33816 phy_reg = phy_reg_addr; 33817 rv = soc_miim_read(unit, phy_id, phy_reg, &phy_rd_data); 33818 if (BCM_SUCCESS(rv)) { 33819 phy_wr_data |= (phy_rd_data & ~phy_mask); 33820 rv = soc_miim_write(unit, phy_id, phy_reg, phy_wr_data); 33821 } 33822 } 33823 PORT_UNLOCK(unit); 33824 } 33825 return rv; 33826 } 33827 33828 /* 33829 * Function: 33830 * bcm_port_mdix_set 33831 * Description: 33832 * Set the Auto-MDIX mode of a port/PHY 33833 * Parameters: 33834 * unit - Device number 33835 * port - Port number 33836 * mode - One of: 33837 * BCM_PORT_MDIX_AUTO 33838 * Enable auto-MDIX when autonegotiation is enabled 33839 * BCM_PORT_MDIX_FORCE_AUTO 33840 * Enable auto-MDIX always 33841 * BCM_PORT_MDIX_NORMAL 33842 * Disable auto-MDIX 33843 * BCM_PORT_MDIX_XOVER 33844 * Disable auto-MDIX, and swap cable pairs 33845 * Return Value: 33846 * BCM_E_UNAVAIL - feature unsupported by hardware 33847 * BCM_E_XXX - other error 33848 */ 33849 int 33850 bcm_esw_port_mdix_set(int unit, bcm_port_t port, bcm_port_mdix_t mode) 33851 { 33852 int rv; 33853 33854 /* Make sure port module is initialized. */ 33855 PORT_INIT(unit); 33856 33857 /* Call Port Control module */ 33858 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 33859 return bcmi_esw_portctrl_mdix_set(unit, port, mode); 33860 } 33861 33862 if(bcm_common_oamp_port_enable_get(unit, port)) { 33863 LOG_ERROR(BSL_LS_BCM_PORT, 33864 (BSL_META("Error: Not permitted on OAMP port %d.n"), 33865 port)); 33866 return BCM_E_PARAM; 33867 } 33868 33869 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33870 33871 PORT_LOCK(unit); 33872 rv = soc_phyctrl_mdix_set(unit, port, mode); 33873 PORT_UNLOCK(unit); 33874 return rv; 33875 } 33876 33877 /* 33878 * Function: 33879 * bcm_port_mdix_get 33880 * Description: 33881 * Get the Auto-MDIX mode of a port/PHY 33882 * Parameters: 33883 * unit - Device number 33884 * port - Port number 33885 * mode - (Out) One of: 33886 * BCM_PORT_MDIX_AUTO 33887 * Enable auto-MDIX when autonegotiation is enabled 33888 * BCM_PORT_MDIX_FORCE_AUTO 33889 * Enable auto-MDIX always 33890 * BCM_PORT_MDIX_NORMAL 33891 * Disable auto-MDIX 33892 * BCM_PORT_MDIX_XOVER 33893 * Disable auto-MDIX, and swap cable pairs 33894 * Return Value: 33895 * BCM_E_UNAVAIL - feature unsupported by hardware 33896 * BCM_E_XXX - other error 33897 */ 33898 int 33899 bcm_esw_port_mdix_get(int unit, bcm_port_t port, bcm_port_mdix_t *mode) 33900 { 33901 int rv=BCM_E_NONE; 33902 33903 /* Make sure port module is initialized. */ 33904 PORT_INIT(unit); 33905 33906 /* Call Port Control module */ 33907 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 33908 return bcmi_esw_portctrl_mdix_get(unit, port, mode); 33909 } 33910 33911 if(bcm_common_oamp_port_enable_get(unit, port)) { 33912 LOG_ERROR(BSL_LS_BCM_PORT, 33913 (BSL_META("Error: Not permitted on OAMP port %d.n"), 33914 port)); 33915 return BCM_E_PARAM; 33916 } 33917 33918 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33919 PORT_LOCK(unit); 33920 rv = soc_phyctrl_mdix_get(unit, port, mode); 33921 PORT_UNLOCK(unit); 33922 33923 return rv; 33924 } 33925 33926 /* 33927 * Function: 33928 * bcm_port_mdix_status_get 33929 * Description: 33930 * Get the current MDIX status on a port/PHY 33931 * Parameters: 33932 * unit - Device number 33933 * port - Port number 33934 * status - (OUT) One of: 33935 * BCM_PORT_MDIX_STATUS_NORMAL 33936 * Straight connection 33937 * BCM_PORT_MDIX_STATUS_XOVER 33938 * Crossover has been performed 33939 * Return Value: 33940 * BCM_E_UNAVAIL - feature unsupported by hardware 33941 * BCM_E_XXX - other error 33942 */ 33943 int 33944 bcm_esw_port_mdix_status_get(int unit, bcm_port_t port, 33945 bcm_port_mdix_status_t *status) 33946 { 33947 int rv=BCM_E_NONE; 33948 33949 /* Make sure port module is initialized. */ 33950 PORT_INIT(unit); 33951 33952 /* Call Port Control module */ 33953 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 33954 return bcmi_esw_portctrl_mdix_status_get(unit, port, status); 33955 } 33956 33957 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33958 PORT_LOCK(unit); 33959 rv = soc_phyctrl_mdix_status_get(unit, port, status); 33960 PORT_UNLOCK(unit); 33961 return rv; 33962 } 33963 33964 /* 33965 * Function: 33966 * bcm_port_medium_config_set 33967 * Description: 33968 * Set the medium-specific configuration for a combo port 33969 * Parameters: 33970 * unit - Device number 33971 * port - Port number 33972 * medium - The medium (BCM_PORT_MEDIUM_COPPER or BCM_PORT_MEDIUM_FIBER) 33973 * to apply the configuration to 33974 * config - per-medium configuration 33975 * Return Value: 33976 * BCM_E_XXX 33977 */ 33978 int 33979 bcm_esw_port_medium_config_set(int unit, bcm_port_t port, 33980 bcm_port_medium_t medium, 33981 bcm_phy_config_t *config) 33982 { 33983 int rv; 33984 33985 /* Make sure port module is initialized. */ 33986 PORT_INIT(unit); 33987 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33988 33989 #ifdef PORTMOD_SUPPORT 33990 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 33991 rv = bcmi_esw_portctrl_medium_config_set(unit, port, medium, config); 33992 } else 33993 #endif /* PORTMOD_SUPPORT */ 33994 { 33995 PORT_LOCK(unit); 33996 rv = soc_phyctrl_medium_config_set(unit, port, medium, config); 33997 PORT_UNLOCK(unit); 33998 } 33999 34000 return rv; 34001 } 34002 34003 /* 34004 * Function: 34005 * bcm_port_medium_config_get 34006 * Description: 34007 * Get the medium-specific configuration for a combo port 34008 * Parameters: 34009 * unit - Device number 34010 * port - Port number 34011 * medium - The medium (BCM_PORT_MEDIUM_COPPER or BCM_PORT_MEDIUM_FIBER) 34012 * to get the config for 34013 * config - per-medium configuration 34014 * Return Value: 34015 * BCM_E_XXX 34016 */ 34017 int 34018 bcm_esw_port_medium_config_get(int unit, bcm_port_t port, 34019 bcm_port_medium_t medium, 34020 bcm_phy_config_t *config) 34021 { 34022 int rv; 34023 34024 /* Make sure port module is initialized. */ 34025 PORT_INIT(unit); 34026 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34027 34028 #ifdef PORTMOD_SUPPORT 34029 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 34030 rv = bcmi_esw_portctrl_medium_config_get(unit, port, medium, config); 34031 } else 34032 #endif /* PORTMOD_SUPPORT */ 34033 { 34034 PORT_LOCK(unit); 34035 rv = soc_phyctrl_medium_config_get(unit, port, medium, config); 34036 PORT_UNLOCK(unit); 34037 } 34038 return rv; 34039 } 34040 34041 /* 34042 * Function: 34043 * bcm_port_medium_get 34044 * Description: 34045 * Get the current medium used by a combo port 34046 * Parameters: 34047 * unit - Device number 34048 * port - Port number 34049 * medium - The medium (BCM_PORT_MEDIUM_COPPER or BCM_PORT_MEDIUM_FIBER) 34050 * which is currently selected 34051 * Return Value: 34052 * BCM_E_XXX 34053 */ 34054 int 34055 bcm_esw_port_medium_get(int unit, bcm_port_t port, 34056 bcm_port_medium_t *medium) 34057 { 34058 int rv=BCM_E_NONE; 34059 /* Make sure port module is initialized. */ 34060 PORT_INIT(unit); 34061 34062 /* Call Port Control module */ 34063 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 34064 return bcmi_esw_portctrl_medium_get(unit, port, medium); 34065 } 34066 34067 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34068 PORT_LOCK(unit); 34069 rv = soc_phyctrl_medium_get(unit, port, medium); 34070 PORT_UNLOCK(unit); 34071 return rv; 34072 } 34073 34074 /* 34075 * Function: 34076 * bcm_port_medium_status_register 34077 * Description: 34078 * Register a callback function to be called on medium change event 34079 * Parameters: 34080 * unit - Device number 34081 * port - port number 34082 * callback - The callback function to call 34083 * user_data - An opaque cookie to pass to callback function 34084 * whenever it is called 34085 * Returns: 34086 * BCM_E_NONE 34087 * BCM_E_PARAM -- NULL function pointer or bad {unit, port} combination 34088 * BCM_E_FULL -- Cannot register more than 1 callback per {unit, port} 34089 */ 34090 int 34091 bcm_esw_port_medium_status_register(int unit, 34092 bcm_port_t port, 34093 bcm_port_medium_status_cb_t callback, 34094 void *user_data) 34095 { 34096 /* Make sure port module is initialized. */ 34097 PORT_INIT(unit); 34098 34099 return soc_phy_medium_status_register(unit, port, callback, user_data); 34100 } 34101 34102 /* 34103 * Function: 34104 * bcm_port_medium_status_unregister 34105 * Description: 34106 * Unregister a callback function to be called on medium change event 34107 * Parameters: 34108 * unit - Device number 34109 * port - port number 34110 * callback - The callback function to call 34111 * user_data - An opaque cookie to pass to callback function 34112 * whenever it is called 34113 * Returns: 34114 * BCM_E_NONE 34115 * BCM_E_PARAM -- Bad {unit, port} combination 34116 * BCM_E_NOT_FOUND -- The specified {unit, port, callback, user_data} 34117 * combination have not been registered before 34118 */ 34119 int 34120 bcm_esw_port_medium_status_unregister(int unit, 34121 bcm_port_t port, 34122 bcm_port_medium_status_cb_t callback, 34123 void *user_data) 34124 { 34125 /* Make sure port module is initialized. */ 34126 PORT_INIT(unit); 34127 34128 return soc_phy_medium_status_unregister(unit, port, callback, user_data); 34129 } 34130 34131 /* 34132 * Function: 34133 * bcm_port_phy_reset 34134 * Description: 34135 * This function performs the low-level PHY reset and is intended to be 34136 * called ONLY from callback function registered with 34137 * bcm_port_phy_reset_register. Attempting to call it from any other 34138 * place will break lots of things. 34139 * Parameters: 34140 * unit - Device number 34141 * port - Port number 34142 * Returns: 34143 * BCM_E_XXX 34144 */ 34145 int 34146 bcm_esw_port_phy_reset(int unit, bcm_port_t port) 34147 { 34148 int rv; 34149 34150 /* Make sure port module is initialized. */ 34151 PORT_INIT(unit); 34152 34153 /* Call Port Control module */ 34154 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 34155 return (bcmi_esw_portctrl_phy_reset(unit, port)); 34156 } 34157 34158 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34159 34160 if (!(BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) { 34161 return BCM_E_PORT; 34162 } 34163 34164 PORT_LOCK(unit); 34165 rv = soc_phyctrl_reset(unit, port, NULL); 34166 PORT_UNLOCK(unit); 34167 return rv; 34168 } 34169 34170 /* 34171 * Function: 34172 * bcm_port_phy_reset_register 34173 * Description: 34174 * Register a callback function to be called whenever a PHY driver 34175 * needs to perform a PHY reset 34176 * Parameters: 34177 * unit - Device number 34178 * port - port number 34179 * callback - The callback function to call 34180 * user_data - An opaque cookie to pass to callback function 34181 * whenever it is called 34182 * Returns: 34183 * BCM_E_NONE 34184 * BCM_E_PARAM -- Bad {unit, port} combination 34185 * BCM_E_NOT_FOUND -- The specified {unit, port, callback, user_data} 34186 * combination have not been registered before 34187 */ 34188 int 34189 bcm_esw_port_phy_reset_register(int unit, bcm_port_t port, 34190 bcm_port_phy_reset_cb_t callback, 34191 void *user_data) 34192 { 34193 /* Make sure port module is initialized. */ 34194 PORT_INIT(unit); 34195 34196 return soc_phy_reset_register(unit, port, callback, user_data, FALSE); 34197 } 34198 34199 /* 34200 * Function: 34201 * bcm_port_phy_reset_unregister 34202 * Description: 34203 * Unregister a callback function to be called whenever a PHY driver 34204 * needs to perform a PHY reset 34205 * Parameters: 34206 * unit - Device number 34207 * port - port number 34208 * callback - The callback function to call 34209 * user_data - An opaque cookie to pass to callback function 34210 * whenever it is called 34211 * Returns: 34212 * BCM_E_NONE 34213 * BCM_E_PARAM -- Bad {unit, port} combination 34214 * BCM_E_NOT_FOUND -- The specified {unit, port, callback, user_data} 34215 * combination have not been registered before 34216 */ 34217 int 34218 bcm_esw_port_phy_reset_unregister(int unit, bcm_port_t port, 34219 bcm_port_phy_reset_cb_t callback, 34220 void *user_data) 34221 { 34222 /* Make sure port module is initialized. */ 34223 PORT_INIT(unit); 34224 34225 return soc_phy_reset_unregister(unit, port, callback, user_data); 34226 } 34227 34228 /* 34229 * Function: 34230 * bcm_port_jam_set 34231 * Description: 34232 * Enable or disable half duplex jamming on a port 34233 * Parameters: 34234 * unit - Device number 34235 * port - Port number 34236 * enable - non-zero to enable jamming 34237 * Return Value: 34238 * BCM_E_XXX 34239 */ 34240 int 34241 bcm_esw_port_jam_set(int unit, bcm_port_t port, int enable) 34242 { 34243 /* Make sure port module is initialized. */ 34244 PORT_INIT(unit); 34245 34246 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34247 34248 if (!IS_E_PORT(unit, port)) { /* HG, CPU ports */ 34249 return enable ? BCM_E_CONFIG : BCM_E_NONE; 34250 } 34251 34252 #ifdef BCM_XGS3_SWITCH_SUPPORT 34253 if (SOC_IS_XGS3_SWITCH(unit)) { 34254 uint32 rval; 34255 int oenable; 34256 34257 if (!IS_GE_PORT(unit, port) && !IS_FE_PORT(unit, port)) { 34258 return BCM_E_UNAVAIL; 34259 } else if (!soc_reg_field_valid(unit, GE_PORT_CONFIGr, JAM_ENf) && 34260 !soc_feature(unit, soc_feature_unimac)) { 34261 return BCM_E_UNAVAIL; 34262 } 34263 34264 if (soc_feature(unit, soc_feature_unimac)) { 34265 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_HURRICANE_SUPPORT) 34266 if ((SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANEX(unit) || 34267 SOC_IS_GREYHOUND2(unit)) && 34268 (IS_XL_PORT(unit,port) || IS_CL_PORT(unit, port))) { 34269 return BCM_E_UNAVAIL; 34270 } 34271 #endif 34272 #ifdef BCM_KATANA_SUPPORT 34273 /* In KATANA, certain GE ports do not use UNIMAC driver */ 34274 if ((SOC_IS_KATANA(unit)) && (IS_MXQ_PORT(unit, port))) { 34275 return BCM_E_UNAVAIL; 34276 } 34277 #endif 34278 SOC_IF_ERROR_RETURN(READ_IPG_HD_BKP_CNTLr(unit, port, &rval)); 34279 oenable = soc_reg_field_get(unit, IPG_HD_BKP_CNTLr, rval, 34280 HD_FC_ENAf); 34281 #ifdef BCM_HAWKEYE_SUPPORT 34282 if(SOC_IS_HAWKEYE(unit)) { 34283 /* 34284 * In HAWKEYE A0, the back-pressure is disabled 34285 * when the bit HD_FC_ENA is cleared (binary 0). 34286 * In other revision of HAWKEYE, the back-pressure is disabled 34287 * when the bit HD_FC_ENA is set (binary 1). 34288 */ 34289 if(soc_feature(unit, soc_feature_hawkeye_a0_war)) { 34290 enable = enable ? 1 : 0; 34291 } else { 34292 enable = enable ? 0 : 1; 34293 } 34294 } else 34295 #endif /* BCM_HAWKEYE_SUPPORT */ 34296 { 34297 enable = enable ? 1 : 0; 34298 } 34299 if (oenable != enable) { 34300 soc_reg_field_set(unit, IPG_HD_BKP_CNTLr, &rval, HD_FC_ENAf, 34301 enable); 34302 SOC_IF_ERROR_RETURN(WRITE_IPG_HD_BKP_CNTLr(unit, port, rval)); 34303 } 34304 } else { 34305 SOC_IF_ERROR_RETURN(READ_GE_PORT_CONFIGr(unit, port, &rval)); 34306 oenable = soc_reg_field_get(unit, GE_PORT_CONFIGr, rval, JAM_ENf); 34307 enable = enable ? 1 : 0; 34308 if (oenable != enable) { 34309 soc_reg_field_set(unit, GE_PORT_CONFIGr, &rval, JAM_ENf, enable); 34310 SOC_IF_ERROR_RETURN(WRITE_GE_PORT_CONFIGr(unit, port, rval)); 34311 } 34312 } 34313 return BCM_E_NONE; 34314 } 34315 #endif 34316 34317 /* XE ports */ 34318 return enable ? BCM_E_CONFIG : BCM_E_NONE; 34319 } 34320 34321 /* 34322 * Function: 34323 * bcm_port_jam_get 34324 * Description: 34325 * Return half duplex jamming state 34326 * Parameters: 34327 * unit - Device number 34328 * port - Port number 34329 * enable - (OUT) non-zero if jamming enabled 34330 * Return Value: 34331 * BCM_E_XXX 34332 */ 34333 int 34334 bcm_esw_port_jam_get(int unit, bcm_port_t port, int *enable) 34335 { 34336 /* Make sure port module is initialized. */ 34337 PORT_INIT(unit); 34338 34339 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34340 34341 if (!IS_E_PORT(unit, port)) { /* HG, CPU ports */ 34342 *enable = 0; 34343 return BCM_E_NONE; 34344 } 34345 34346 #ifdef BCM_XGS3_SWITCH_SUPPORT 34347 if (SOC_IS_XGS3_SWITCH(unit)) { 34348 uint32 rval; 34349 34350 if (!IS_GE_PORT(unit, port) && !IS_FE_PORT(unit, port)) { 34351 return BCM_E_UNAVAIL; 34352 } else if (!soc_reg_field_valid(unit, GE_PORT_CONFIGr, JAM_ENf) && 34353 !soc_feature(unit, soc_feature_unimac)) { 34354 return BCM_E_UNAVAIL; 34355 } 34356 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_HURRICANE_SUPPORT) 34357 else if ((SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANEX(unit) || 34358 SOC_IS_GREYHOUND2(unit)) && 34359 (IS_XL_PORT(unit,port) || IS_CL_PORT(unit, port))) { 34360 return BCM_E_UNAVAIL; 34361 } 34362 #endif 34363 34364 if (soc_feature(unit, soc_feature_unimac)) { 34365 #ifdef BCM_KATANA_SUPPORT 34366 /* In KATANA, certain GE ports do not use UNIMAC driver */ 34367 if ((SOC_IS_KATANA(unit)) && (IS_MXQ_PORT(unit, port))) { 34368 return BCM_E_UNAVAIL; 34369 } 34370 #endif 34371 SOC_IF_ERROR_RETURN(READ_IPG_HD_BKP_CNTLr(unit, port, &rval)); 34372 *enable = soc_reg_field_get(unit, IPG_HD_BKP_CNTLr, rval, HD_FC_ENAf); 34373 } else { 34374 SOC_IF_ERROR_RETURN(READ_GE_PORT_CONFIGr(unit, port, &rval)); 34375 *enable = soc_reg_field_get(unit, GE_PORT_CONFIGr, rval, JAM_ENf); 34376 } 34377 return BCM_E_NONE; 34378 } 34379 #endif 34380 34381 *enable = 0; 34382 return BCM_E_NONE; 34383 } 34384 34385 /* 34386 * Function: 34387 * bcm_port_cable_diag 34388 * Description: 34389 * Run Cable Diagnostics on port 34390 * Parameters: 34391 * unit - Device number 34392 * port - Port number 34393 * status - (OUT) cable diag status structure 34394 * Return Value: 34395 * BCM_E_XXX 34396 * Notes: 34397 * Cable diagnostics are only supported by some phy types 34398 * (currently 5248 10/100 phy and 546x 10/100/1000 phys) 34399 */ 34400 int 34401 bcm_esw_port_cable_diag(int unit, bcm_port_t port, 34402 bcm_port_cable_diag_t *status) 34403 { 34404 int rv = BCM_E_NONE; 34405 34406 /* Make sure port module is initialized. */ 34407 PORT_INIT(unit); 34408 34409 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34410 34411 #ifdef BCM_RCPU_SUPPORT 34412 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 34413 return BCM_E_PORT; 34414 } 34415 #endif /* BCM_RCPU_SUPPORT */ 34416 34417 #ifdef PORTMOD_SUPPORT 34418 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 34419 return bcmi_esw_portctrl_cable_diag(unit, port, status); 34420 } else 34421 #endif /* PORTMOD_SUPPORT */ 34422 { 34423 PORT_LOCK(unit); 34424 rv = soc_phyctrl_cable_diag(unit, port, status); 34425 PORT_UNLOCK(unit); 34426 } 34427 34428 return rv; 34429 } 34430 34431 /* 34432 * Function: 34433 * bcm_esw_port_fault_get 34434 * Description: 34435 * Get link fault type 34436 * Parameters: 34437 * unit - Device number 34438 * port - Port number 34439 * flags - (OUT) flags to indicate fault type 34440 * Return Value: 34441 * BCM_E_XXX 34442 */ 34443 34444 int 34445 bcm_esw_port_fault_get(int unit, bcm_port_t port, uint32 *flags) 34446 { 34447 int rv, local_fault, remote_fault; 34448 int faults = FALSE; 34449 soc_persist_t *sop = SOC_PERSIST(unit); 34450 34451 /* Make sure port module is initialized. */ 34452 PORT_INIT(unit); 34453 34454 if(bcm_common_oamp_port_enable_get(unit, port)) { 34455 LOG_ERROR(BSL_LS_BCM_PORT, 34456 (BSL_META("Error: Not permitted on OAMP port %d.n"), 34457 port)); 34458 return BCM_E_PARAM; 34459 } 34460 34461 if (SOC_PBMP_MEMBER(sop->lc_pbm_eth_buffer_mode, port)) { 34462 faults = FALSE; 34463 SOC_IF_ERROR_RETURN(soc_phyctrl_linkfault_get(unit, port, &faults)); 34464 } 34465 34466 /* Call Port Control module */ 34467 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 34468 rv = bcmi_esw_portctrl_fault_get(unit, port, flags); 34469 if (SOC_PBMP_MEMBER(sop->lc_pbm_eth_buffer_mode, port)) { 34470 if (faults) { 34471 *flags |= faults; 34472 } 34473 } 34474 return (rv); 34475 } 34476 34477 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34478 34479 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 34480 SOC_MAC_CONTROL_FAULT_LOCAL_STATUS, &local_fault); 34481 if (rv == SOC_E_UNAVAIL) { 34482 return BCM_E_PORT; 34483 } 34484 SOC_IF_ERROR_RETURN 34485 (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 34486 SOC_MAC_CONTROL_FAULT_REMOTE_STATUS, &remote_fault)); 34487 34488 *flags = 0; 34489 if (remote_fault) { 34490 *flags |= BCM_PORT_FAULT_REMOTE; 34491 } 34492 if (local_fault) { 34493 *flags |= BCM_PORT_FAULT_LOCAL; 34494 } 34495 34496 if (SOC_PBMP_MEMBER(sop->lc_pbm_eth_buffer_mode, port)) { 34497 *flags |= faults; 34498 } 34499 34500 return BCM_E_NONE; 34501 } 34502 34503 /* 34504 * Function: 34505 * bcm_port_trunk_index_set 34506 * Description: 34507 * Set port index of a trunk for ingress port that is used to select 34508 * the egress port in the trunk. 34509 * Parameters: 34510 * unit - StrataSwitch PCI device unit number (driver internal). 34511 * port - Ingress port. 34512 * port_index - Port index of a trunk. 34513 * Returns: 34514 * BCM_E_xxxx 34515 * Note: 34516 * The psc (aka rtag) vlaue needs to be 7 (set in bcm_trunk_set()) for 34517 * a trunk in order to utilize this programmable hashing mechanism. 34518 */ 34519 34520 int 34521 bcm_esw_port_trunk_index_set(int unit, bcm_port_t port, int port_index) 34522 { 34523 #if defined(BCM_FIREBOLT_SUPPORT) 34524 uint32 val, mask = 0x7; 34525 34526 /* Make sure port module is initialized. */ 34527 PORT_INIT(unit); 34528 34529 if (soc_feature(unit, soc_feature_port_trunk_index)) { 34530 if (IS_ST_PORT(unit, port)) { 34531 if (!SOC_REG_IS_VALID(unit, IUSER_TRUNK_HASH_SELECTr)) { 34532 return BCM_E_UNAVAIL; 34533 } 34534 34535 val = 0; 34536 if (!SOC_IS_RAVEN(unit)) { 34537 mask = 0x3; 34538 } 34539 soc_reg_field_set(unit, IUSER_TRUNK_HASH_SELECTr, &val, 34540 TRUNK_CFG_VALf, port_index & mask); 34541 SOC_IF_ERROR_RETURN 34542 (WRITE_IUSER_TRUNK_HASH_SELECTr(unit, port, val)); 34543 } else if (IS_E_PORT(unit, port)) { 34544 if (!SOC_REG_IS_VALID(unit, USER_TRUNK_HASH_SELECTr)) { 34545 return BCM_E_UNAVAIL; 34546 } 34547 34548 val = 0; 34549 soc_reg_field_set(unit, USER_TRUNK_HASH_SELECTr, &val, 34550 TRUNK_CFG_VALf, port_index & mask); 34551 SOC_IF_ERROR_RETURN 34552 (WRITE_USER_TRUNK_HASH_SELECTr(unit, port, val)); 34553 } 34554 34555 return BCM_E_NONE; 34556 } 34557 #endif /* BCM_FIREBOLT_SUPPORT */ 34558 34559 return BCM_E_UNAVAIL; 34560 } 34561 34562 /* 34563 * Function: 34564 * bcm_port_trunk_index_get 34565 * Description: 34566 * Get port index of a trunk for ingress port that is used to select 34567 * the egress port in the trunk. 34568 * Parameters: 34569 * unit - StrataSwitch PCI device unit number (driver internal). 34570 * port - Ingress port. 34571 * port_index - (OUT) Port index of a trunk. 34572 * Returns: 34573 * BCM_E_xxxx 34574 */ 34575 34576 int 34577 bcm_esw_port_trunk_index_get(int unit, bcm_port_t port, int *port_index) 34578 { 34579 #if defined(BCM_FIREBOLT_SUPPORT) 34580 uint32 val; 34581 34582 /* Make sure port module is initialized. */ 34583 PORT_INIT(unit); 34584 34585 if (soc_feature(unit, soc_feature_port_trunk_index)) { 34586 if (IS_ST_PORT(unit, port)) { 34587 if (!SOC_REG_IS_VALID(unit, IUSER_TRUNK_HASH_SELECTr)) { 34588 return BCM_E_UNAVAIL; 34589 } 34590 34591 SOC_IF_ERROR_RETURN 34592 (READ_IUSER_TRUNK_HASH_SELECTr(unit, port, &val)); 34593 *port_index = soc_reg_field_get(unit, IUSER_TRUNK_HASH_SELECTr, 34594 val, TRUNK_CFG_VALf); 34595 } else if (IS_E_PORT(unit, port)) { 34596 if (!SOC_REG_IS_VALID(unit, USER_TRUNK_HASH_SELECTr)) { 34597 return BCM_E_UNAVAIL; 34598 } 34599 34600 SOC_IF_ERROR_RETURN 34601 (READ_USER_TRUNK_HASH_SELECTr(unit, port, &val)); 34602 *port_index = soc_reg_field_get(unit, USER_TRUNK_HASH_SELECTr, 34603 val, TRUNK_CFG_VALf); 34604 } 34605 34606 return BCM_E_NONE; 34607 } 34608 #endif /* BCM_FIREBOLT_SUPPORT */ 34609 34610 return BCM_E_UNAVAIL; 34611 } 34612 34613 #ifdef BCM_XGS3_SWITCH_SUPPORT 34614 34615 static soc_field_t _bcm_xgs3_priority_fields[] = { 34616 PRIORITY0_CNGf, 34617 PRIORITY1_CNGf, 34618 PRIORITY2_CNGf, 34619 PRIORITY3_CNGf, 34620 PRIORITY4_CNGf, 34621 PRIORITY5_CNGf, 34622 PRIORITY6_CNGf, 34623 PRIORITY7_CNGf, 34624 }; 34625 34626 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 34627 34628 #ifdef BCM_TRIUMPH2_SUPPORT 34629 STATIC 34630 int _bcm_esw_vp_ing_pri_cng_set(int unit, bcm_gport_t port, int untagged, 34631 int pkt_pri, int cfi, 34632 int internal_pri, bcm_color_t color) 34633 { 34634 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit)) { 34635 return _bcm_tr2_vp_ing_pri_cng_set(unit, port, untagged, 34636 pkt_pri, cfi, 34637 internal_pri, color); 34638 } 34639 return BCM_E_PORT; 34640 } 34641 34642 STATIC 34643 int _bcm_esw_vp_ing_pri_cng_get(int unit, bcm_gport_t port, int untagged, 34644 int pkt_pri, int cfi, 34645 int *internal_pri, bcm_color_t *color) 34646 { 34647 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit)) { 34648 return _bcm_tr2_vp_ing_pri_cng_get(unit, port, untagged, 34649 pkt_pri, cfi, 34650 internal_pri, color); 34651 } 34652 return BCM_E_PORT; 34653 } 34654 #endif 34655 /* 34656 * Function: 34657 * bcm_port_priority_color_set 34658 * Purpose: 34659 * Specify the color selection for the given priority. 34660 * Parameters: 34661 * unit - StrataSwitch PCI device unit number (driver internal). 34662 * port - Port to configure 34663 * prio - priority (aka 802.1p CoS) 34664 * color - color assigned to packets with indicated priority. 34665 * Returns: 34666 * BCM_E_NONE - Success. 34667 * BCM_E_XXX 34668 * Notes: 34669 * Available on XGS3 only. 34670 */ 34671 int 34672 bcm_esw_port_priority_color_set(int unit, bcm_port_t port, 34673 int prio, bcm_color_t color) 34674 { 34675 /* Make sure port module is initialized. */ 34676 PORT_INIT(unit); 34677 34678 #ifdef BCM_XGS3_SWITCH_SUPPORT 34679 if (soc_feature(unit, soc_feature_color)) { 34680 34681 VLAN_CHK_PRIO(unit, prio); 34682 34683 #if defined(BCM_TRIUMPH2_SUPPORT) 34684 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 34685 if (BCM_GPORT_IS_SET(port) && 34686 !BCM_GPORT_IS_MODPORT(port) && 34687 !BCM_GPORT_IS_LOCAL(port) && 34688 !BCM_GPORT_IS_SUBPORT_PORT(port)) { 34689 return _bcm_esw_vp_ing_pri_cng_set(unit, port, FALSE, prio, 34690 -1, -1, color); 34691 } 34692 } 34693 #endif 34694 34695 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34696 34697 #ifdef BCM_TRIUMPH2_SUPPORT 34698 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 34699 #ifdef BCM_TRIDENT3_SUPPORT 34700 if (SOC_IS_TRIDENT3X(unit)) { 34701 return bcm_td3_port_ing_pri_cng_set(unit, port, FALSE, 34702 prio, -1, -1, color); 34703 } else 34704 #endif 34705 #ifdef BCM_TRIDENT_SUPPORT 34706 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 34707 SOC_IS_TRIUMPH3(unit)) { 34708 return bcm_td_port_ing_pri_cng_set(unit, port, FALSE, 34709 prio, -1, -1, color); 34710 } else 34711 #endif /* BCM_TRIDENT_SUPPORT */ 34712 { 34713 return _bcm_tr2_port_priority_color_set(unit, port, 34714 prio, color); 34715 } 34716 } else 34717 #endif 34718 { 34719 uint32 val, oval; 34720 34721 SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, port, &val)); 34722 oval = val; 34723 soc_reg_field_set(unit, CNG_MAPr, &val, 34724 _bcm_xgs3_priority_fields[prio], 34725 _BCM_COLOR_ENCODING(unit, color)); 34726 if (oval != val) { 34727 SOC_IF_ERROR_RETURN(WRITE_CNG_MAPr(unit, port, val)); 34728 } 34729 return BCM_E_NONE; 34730 } 34731 } 34732 #endif 34733 return BCM_E_UNAVAIL; 34734 } 34735 34736 /* 34737 * Function: 34738 * bcm_port_priority_color_get 34739 * Purpose: 34740 * Get the color selection for the given priority. 34741 * Parameters: 34742 * unit - StrataSwitch PCI device unit number (driver internal). 34743 * port - Port to configure 34744 * prio - priority (aka 802.1p CoS) 34745 * color - (OUT) color assigned to packets with indicated priority. 34746 * Returns: 34747 * BCM_E_NONE - Success. 34748 * BCM_E_XXX 34749 * Notes: 34750 * Available on XGS3 only. 34751 */ 34752 int 34753 bcm_esw_port_priority_color_get(int unit, bcm_port_t port, 34754 int prio, bcm_color_t *color) 34755 { 34756 /* Make sure port module is initialized. */ 34757 PORT_INIT(unit); 34758 34759 #ifdef BCM_XGS3_SWITCH_SUPPORT 34760 if (soc_feature(unit, soc_feature_color)) { 34761 uint32 val, hw_color; 34762 cng_map_entry_t cng_map_entry; 34763 int ptr; 34764 34765 /* Input parameters check. */ 34766 if ((NULL == color)) { 34767 return (BCM_E_PARAM); 34768 } 34769 34770 VLAN_CHK_PRIO(unit, prio); 34771 34772 #if defined(BCM_TRIUMPH2_SUPPORT) 34773 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 34774 if (BCM_GPORT_IS_SET(port) && 34775 !BCM_GPORT_IS_MODPORT(port) && 34776 !BCM_GPORT_IS_LOCAL(port) && 34777 !BCM_GPORT_IS_SUBPORT_PORT(port)) { 34778 return _bcm_esw_vp_ing_pri_cng_get(unit, port, FALSE, prio, 34779 0, NULL, color); 34780 } 34781 } 34782 #endif 34783 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34784 ptr = port; 34785 34786 #ifdef BCM_TRIUMPH2_SUPPORT 34787 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 34788 #ifdef BCM_TRIDENT3_SUPPORT 34789 if (SOC_IS_TRIDENT3X(unit)) { 34790 return bcm_td3_port_ing_pri_cng_get(unit, port, FALSE, 34791 prio, 0, NULL, color); 34792 } else 34793 #endif /* BCM_TRIDENT3_SUPPORT */ 34794 #ifdef BCM_TRIDENT_SUPPORT 34795 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 34796 SOC_IS_TRIUMPH3(unit)) { 34797 return bcm_td_port_ing_pri_cng_get(unit, port, FALSE, 34798 prio, 0, NULL, color); 34799 } else 34800 #endif /* BCM_TRIDENT_SUPPORT */ 34801 { 34802 /* Get the pointer from the ING_PRI_CNG_MAP table */ 34803 port_tab_entry_t pent; 34804 BCM_IF_ERROR_RETURN 34805 (soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, 34806 SOC_PORT_MOD_OFFSET(unit, port), &pent)); 34807 ptr = soc_PORT_TABm_field32_get(unit, &pent, 34808 TRUST_DOT1P_PTRf); 34809 } 34810 } 34811 #endif 34812 if (SOC_MEM_IS_VALID(unit, CNG_MAPm)) { 34813 SOC_IF_ERROR_RETURN(READ_CNG_MAPm(unit, MEM_BLOCK_ANY, 34814 ptr, &cng_map_entry)); 34815 hw_color = soc_CNG_MAPm_field32_get(unit, &cng_map_entry, 34816 _bcm_xgs3_priority_fields[prio]); 34817 } else { 34818 SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, ptr, &val)); 34819 hw_color = soc_reg_field_get(unit, CNG_MAPr, val, 34820 _bcm_xgs3_priority_fields[prio]); 34821 } 34822 *color = _BCM_COLOR_DECODING(unit, hw_color); 34823 return BCM_E_NONE; 34824 } 34825 #endif 34826 return BCM_E_UNAVAIL; 34827 } 34828 34829 /* 34830 * Function: 34831 * bcm_port_cfi_color_set 34832 * Purpose: 34833 * Specify the color selection for the given CFI. 34834 * Parameters: 34835 * unit - StrataSwitch PCI device unit number (driver internal). 34836 * port - Port to configure 34837 * cfi - Canonical format indicator (TRUE/FALSE) 34838 * color - color assigned to packets with indicated CFI. 34839 * Returns: 34840 * BCM_E_NONE - Success. 34841 * BCM_E_XXX 34842 * Notes: 34843 * Available on XGS3 only. 34844 */ 34845 int 34846 bcm_esw_port_cfi_color_set(int unit, bcm_port_t port, 34847 int cfi, bcm_color_t color) 34848 { 34849 /* Make sure port module is initialized. */ 34850 PORT_INIT(unit); 34851 34852 #ifdef BCM_XGS3_SWITCH_SUPPORT 34853 if (soc_feature(unit, soc_feature_color)) { 34854 if (cfi < 0 || cfi > 1) { 34855 return BCM_E_PARAM; 34856 } 34857 34858 #if defined(BCM_TRIUMPH2_SUPPORT) 34859 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 34860 if (BCM_GPORT_IS_SET(port) && 34861 !BCM_GPORT_IS_MODPORT(port) && 34862 !BCM_GPORT_IS_LOCAL(port) && 34863 !BCM_GPORT_IS_SUBPORT_PORT(port)) { 34864 return _bcm_esw_vp_ing_pri_cng_set(unit, port, FALSE, -1, 34865 cfi, -1, color); 34866 } 34867 } 34868 #endif 34869 34870 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34871 #ifdef BCM_TRIDENT3_SUPPORT 34872 if (SOC_IS_TRIDENT3X(unit)) { 34873 return bcm_td3_port_ing_pri_cng_set(unit, port, FALSE, 34874 -1, cfi, -1, color); 34875 } else 34876 #endif 34877 #ifdef BCM_TRIDENT_SUPPORT 34878 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 34879 SOC_IS_TRIUMPH3(unit)) { 34880 return bcm_td_port_ing_pri_cng_set(unit, port, FALSE, 34881 -1, cfi, -1, color); 34882 } else 34883 #endif /* BCM_TRIDENT_SUPPORT */ 34884 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 34885 || defined (BCM_TRX_SUPPORT) 34886 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_TRX(unit) || 34887 SOC_IS_HAWKEYE(unit)) { 34888 int index, pkt_pri; 34889 uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS]; 34890 34891 sal_memset(pri_map, 0, sizeof(pri_map)); 34892 34893 #if defined(BCM_TRIUMPH2_SUPPORT) 34894 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 34895 pkt_pri = -1; 34896 return _bcm_tr2_port_vlan_priority_map_set(unit, port, pkt_pri, 34897 cfi, 34898 pkt_pri, color); 34899 } else 34900 #endif /* BCM_TRIUMPH2_SUPPORT */ 34901 { 34902 for (pkt_pri = 0; pkt_pri <= 7; pkt_pri++) { 34903 /* ING_PRI_CNG_MAP table is indexed with 34904 * port[0:4] incoming priority[2:0] incoming CFI[0] 34905 */ 34906 index = (port << 4) | (pkt_pri << 1) | cfi; 34907 if (SOC_IS_TRIDENT3X(unit)) { 34908 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, PRIf, 34909 pkt_pri); 34910 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, CNGf, 34911 _BCM_COLOR_ENCODING(unit, color)); 34912 SOC_IF_ERROR_RETURN(WRITE_PHB_MAPPING_TBL_1m(unit, 34913 MEM_BLOCK_ALL, index, &pri_map)); 34914 } else { 34915 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, PRIf, 34916 pkt_pri); 34917 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, CNGf, 34918 _BCM_COLOR_ENCODING(unit, color)); 34919 SOC_IF_ERROR_RETURN(WRITE_ING_PRI_CNG_MAPm(unit, 34920 MEM_BLOCK_ALL, index, &pri_map)); 34921 } 34922 } 34923 } 34924 } else 34925 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 34926 { 34927 uint32 val, oval; 34928 SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, port, &val)); 34929 oval = val; 34930 soc_reg_field_set(unit, CNG_MAPr, &val, 34931 cfi ? CFI1_CNGf : CFI0_CNGf, 34932 _BCM_COLOR_ENCODING(unit, color)); 34933 if (oval != val) { 34934 SOC_IF_ERROR_RETURN(WRITE_CNG_MAPr(unit, port, val)); 34935 } 34936 } 34937 return BCM_E_NONE; 34938 } 34939 #endif 34940 return BCM_E_UNAVAIL; 34941 } 34942 34943 /* 34944 * Function: 34945 * bcm_port_cfi_color_get 34946 * Purpose: 34947 * Get the color selection for the given CFI. 34948 * Parameters: 34949 * unit - StrataSwitch PCI device unit number (driver internal). 34950 * port - Port to configure 34951 * cfi - Canonical format indicator (TRUE/FALSE) 34952 * color - (OUT) color assigned to packets with indicated CFI. 34953 * Returns: 34954 * BCM_E_NONE - Success. 34955 * BCM_E_XXX 34956 * Notes: 34957 * Available on XGS3 only. 34958 */ 34959 int 34960 bcm_esw_port_cfi_color_get(int unit, bcm_port_t port, 34961 int cfi, bcm_color_t *color) 34962 { 34963 /* Make sure port module is initialized. */ 34964 PORT_INIT(unit); 34965 34966 #ifdef BCM_XGS3_SWITCH_SUPPORT 34967 if (soc_feature(unit, soc_feature_color)) { 34968 uint32 hw_color; 34969 34970 if (cfi < 0 || cfi > 1) { 34971 return BCM_E_PARAM; 34972 } 34973 34974 /* Input parameters check. */ 34975 if ((NULL == color)) { 34976 return (BCM_E_PARAM); 34977 } 34978 34979 #if defined(BCM_TRIUMPH2_SUPPORT) 34980 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 34981 if (BCM_GPORT_IS_SET(port) && 34982 !BCM_GPORT_IS_MODPORT(port) && 34983 !BCM_GPORT_IS_LOCAL(port) && 34984 !BCM_GPORT_IS_SUBPORT_PORT(port)) { 34985 return _bcm_esw_vp_ing_pri_cng_get(unit, port, FALSE, 0, 34986 cfi, NULL, color); 34987 } 34988 } 34989 #endif 34990 34991 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34992 34993 #ifdef BCM_TRIDENT3_SUPPORT 34994 if (SOC_IS_TRIDENT3X(unit)) { 34995 return bcm_td3_port_ing_pri_cng_get(unit, port, FALSE, 0, cfi, NULL, 34996 color); 34997 } else 34998 #endif /* BCM_TRIDENT3_SUPPORT */ 34999 #ifdef BCM_TRIDENT_SUPPORT 35000 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 35001 SOC_IS_TRIUMPH3(unit)) { 35002 return bcm_td_port_ing_pri_cng_get(unit, port, FALSE, 0, cfi, NULL, 35003 color); 35004 } else 35005 #endif /* BCM_TRIDENT_SUPPORT */ 35006 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 35007 || defined(BCM_TRX_SUPPORT) 35008 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) 35009 || SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) { 35010 int index; 35011 uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS]; 35012 35013 sal_memset(pri_map, 0, sizeof(pri_map)); 35014 35015 #if defined(BCM_TRIUMPH2_SUPPORT) 35016 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 35017 int pkt_pri = 0; 35018 return _bcm_tr2_port_vlan_priority_map_get(unit, port, 0, 35019 cfi, &pkt_pri, color); 35020 } else 35021 #endif /* BCM_TRIUMPH2_SUPPORT */ 35022 { 35023 /* ING_PRI_CNG_MAP table is indexed with 35024 * port[0:4] incoming priority[2:0] incoming CFI[0] 35025 */ 35026 index = (port << 4) | cfi; 35027 if (SOC_IS_TRIDENT3X(unit)) { 35028 SOC_IF_ERROR_RETURN(READ_PHB_MAPPING_TBL_1m(unit, MEM_BLOCK_ANY, 35029 index, &pri_map)); 35030 hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, 35031 &pri_map, CNGf); 35032 } else { 35033 SOC_IF_ERROR_RETURN(READ_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ANY, 35034 index, &pri_map)); 35035 hw_color = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, 35036 &pri_map, CNGf); 35037 } 35038 } 35039 } else 35040 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */ 35041 { 35042 uint32 val; 35043 35044 SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, port, &val)); 35045 hw_color = soc_reg_field_get(unit, CNG_MAPr, val, 35046 cfi ? CFI1_CNGf : CFI0_CNGf); 35047 } 35048 *color = _BCM_COLOR_DECODING(unit, hw_color); 35049 return BCM_E_NONE; 35050 } 35051 #endif 35052 return BCM_E_UNAVAIL; 35053 } 35054 35055 /* 35056 * Function: 35057 * bcm_esw_port_vlan_priority_map_set 35058 * Description: 35059 * Define the mapping of incomming port, packet priority, and cfi bit to 35060 * switch internal priority and color. 35061 * Parameters: 35062 * unit - (IN) Device number 35063 * port - (IN) Port number 35064 * pkt_pri - (IN) Packet priority 35065 * cfi - (IN) Packet CFI 35066 * internal_pri - (IN) Internal priority 35067 * color - (IN) color 35068 * Return Value: 35069 * BCM_E_XXX 35070 * Note: 35071 * This API programs only the mapping table. 35072 */ 35073 int 35074 bcm_esw_port_vlan_priority_map_set(int unit, bcm_port_t port, int pkt_pri, 35075 int cfi, int internal_pri, bcm_color_t color) 35076 { 35077 #ifdef BCM_TRIUMPH2_SUPPORT 35078 int untagged = FALSE; 35079 #endif /* BCM_TRIUMPH2_SUPPORT */ 35080 35081 /* Make sure port module is initialized. */ 35082 PORT_INIT(unit); 35083 35084 if (!soc_feature(unit, soc_feature_color_prio_map) || 35085 soc_feature(unit, soc_feature_deprecated_api)) { 35086 return BCM_E_UNAVAIL; 35087 } 35088 35089 if (SOC_MEM_IS_VALID(unit, ING_UNTAGGED_PHBm)) { 35090 if (pkt_pri == -1 && cfi == -1) { 35091 #ifdef BCM_TRIDENT_SUPPORT 35092 untagged = TRUE; 35093 #endif /* BCM_TRIDENT_SUPPORT */ 35094 pkt_pri = 0; 35095 cfi = 0; 35096 } 35097 } 35098 35099 if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1 || internal_pri < 0 ) { 35100 return BCM_E_PARAM; 35101 } 35102 35103 if (SOC_IS_TRIDENT3X(unit)) { 35104 if (internal_pri >= (1 << soc_mem_field_length(unit, PHB_MAPPING_TBL_1m, PRIf))) { 35105 return BCM_E_PARAM; 35106 } 35107 } else { 35108 if (internal_pri >= (1 << soc_mem_field_length(unit, ING_PRI_CNG_MAPm, PRIf))) { 35109 return BCM_E_PARAM; 35110 } 35111 } 35112 35113 #if defined(BCM_TRIUMPH2_SUPPORT) 35114 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 35115 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 35116 !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) { 35117 return _bcm_esw_vp_ing_pri_cng_set(unit, port, untagged, pkt_pri, 35118 cfi, internal_pri, color); 35119 } 35120 } 35121 #endif 35122 35123 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 35124 35125 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 35126 || defined(BCM_TRX_SUPPORT) 35127 #if defined(BCM_TRIUMPH2_SUPPORT) 35128 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 35129 #ifdef BCM_TRIDENT3_SUPPORT 35130 if (SOC_IS_TRIDENT3X(unit)) { 35131 return bcm_td3_port_ing_pri_cng_set(unit, port, untagged, 35132 pkt_pri, cfi, 35133 internal_pri, color); 35134 } else 35135 #endif 35136 #if defined BCM_TRIDENT_SUPPORT 35137 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 35138 SOC_IS_TRIUMPH3(unit)) { 35139 return bcm_td_port_ing_pri_cng_set(unit, port, untagged, 35140 pkt_pri, cfi, 35141 internal_pri, color); 35142 } else 35143 #endif /* BCM_TRIDENT_SUPPORT */ 35144 { 35145 return _bcm_tr2_port_vlan_priority_map_set(unit, port, pkt_pri, 35146 cfi, 35147 internal_pri, color); 35148 } 35149 } else 35150 #endif 35151 if (soc_feature(unit, soc_feature_color_prio_map)) { 35152 int index; 35153 uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS]; 35154 35155 sal_memset(pri_map, 0, sizeof(pri_map)); 35156 35157 /* ING_PRI_CNG_MAP table is indexed with 35158 * port[0:4] incoming priority[2:0] incoming CFI[0] 35159 */ 35160 index = (port << 4) | (pkt_pri << 1) | cfi; 35161 35162 if (SOC_IS_TRIDENT3X(unit)) { 35163 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, PRIf, 35164 internal_pri); 35165 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, CNGf, 35166 _BCM_COLOR_ENCODING(unit, color)); 35167 SOC_IF_ERROR_RETURN 35168 (WRITE_PHB_MAPPING_TBL_1m(unit, MEM_BLOCK_ALL, index, &pri_map)); 35169 } else { 35170 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, PRIf, 35171 internal_pri); 35172 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, CNGf, 35173 _BCM_COLOR_ENCODING(unit, color)); 35174 SOC_IF_ERROR_RETURN 35175 (WRITE_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ALL, index, &pri_map)); 35176 } 35177 35178 return BCM_E_NONE; 35179 } 35180 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 35181 return BCM_E_UNAVAIL; 35182 } 35183 35184 /* 35185 * Function: 35186 * bcm_esw_port_vlan_priority_map_get 35187 * Description: 35188 * Get the mapping of incomming port, packet priority, and cfi bit to 35189 * switch internal priority and color. 35190 * Parameters: 35191 * unit - (IN) Device number 35192 * port - (IN) Port number 35193 * pkt_pri - (IN) Packet priority 35194 * cfi - (IN) Packet CFI 35195 * internal_pri - (OUT) Internal priority 35196 * color - (OUT) color 35197 * Return Value: 35198 * BCM_E_XXX 35199 * Note: 35200 * This API programs only the mapping table. 35201 */ 35202 int 35203 bcm_esw_port_vlan_priority_map_get(int unit, bcm_port_t port, int pkt_pri, 35204 int cfi, int *internal_pri, 35205 bcm_color_t *color) 35206 { 35207 #if defined BCM_TRIUMPH2_SUPPORT 35208 int untagged = FALSE; 35209 #endif /* BCM_TRIUMPH2_SUPPORT */ 35210 35211 /* Make sure port module is initialized. */ 35212 PORT_INIT(unit); 35213 35214 if (!soc_feature(unit, soc_feature_color_prio_map) || 35215 soc_feature(unit, soc_feature_deprecated_api)) { 35216 return BCM_E_UNAVAIL; 35217 } 35218 35219 /* Input parameters check. */ 35220 if ((NULL == internal_pri) || (NULL == color)) { 35221 return (BCM_E_PARAM); 35222 } 35223 35224 if (SOC_MEM_IS_VALID(unit, ING_UNTAGGED_PHBm)) { 35225 if (pkt_pri == -1 && cfi == -1) { 35226 #if defined BCM_TRIDENT_SUPPORT 35227 untagged = TRUE; 35228 #endif /* BCM_TRIDENT_SUPPORT */ 35229 pkt_pri = 0; 35230 cfi = 0; 35231 } 35232 } 35233 35234 if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1) { 35235 return BCM_E_PARAM; 35236 } 35237 35238 #if defined(BCM_TRIUMPH2_SUPPORT) 35239 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 35240 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 35241 !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) { 35242 return _bcm_esw_vp_ing_pri_cng_get(unit, port, untagged, pkt_pri, 35243 cfi, internal_pri, color); 35244 } 35245 } 35246 #endif 35247 35248 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 35249 35250 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 35251 || defined(BCM_TRX_SUPPORT) 35252 #if defined(BCM_TRIUMPH2_SUPPORT) 35253 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 35254 #ifdef BCM_TRIDENT3_SUPPORT 35255 if (SOC_IS_TRIDENT3X(unit)) { 35256 return bcm_td3_port_ing_pri_cng_get(unit, port, untagged, 35257 pkt_pri, cfi, 35258 internal_pri, color); 35259 } else 35260 #endif /* BCM_TRIDENT3_SUPPORT */ 35261 #if defined BCM_TRIDENT_SUPPORT 35262 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 35263 SOC_IS_TRIUMPH3(unit)) { 35264 return bcm_td_port_ing_pri_cng_get(unit, port, untagged, 35265 pkt_pri, cfi, 35266 internal_pri, color); 35267 } else 35268 #endif /* BCM_TRIDENT_SUPPORT */ 35269 { 35270 return _bcm_tr2_port_vlan_priority_map_get(unit, port, pkt_pri, 35271 cfi, internal_pri, 35272 color); 35273 } 35274 } else 35275 #endif 35276 if (soc_feature(unit, soc_feature_color_prio_map)) { 35277 int index, hw_color; 35278 uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS]; 35279 35280 sal_memset(pri_map, 0, sizeof(pri_map)); 35281 35282 /* ING_PRI_CNG_MAP table is indexed with 35283 * port[4:0] incoming priority[2:0] incoming CFI[0] 35284 */ 35285 index = (port << 4) | (pkt_pri << 1) | cfi; 35286 35287 LOG_INFO(BSL_LS_BCM_PORT, 35288 (BSL_META_U(unit, 35289 "bcm_esw_port_vlan_priority_map_get: u=%d p=%d index=%d\n"), 35290 unit, port, index)); 35291 35292 if (SOC_IS_TRIDENT3X(unit)) { 35293 SOC_IF_ERROR_RETURN 35294 (READ_PHB_MAPPING_TBL_1m(unit, MEM_BLOCK_ANY, index, &pri_map)); 35295 *internal_pri = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &pri_map, INT_PRIf); 35296 hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &pri_map, CNGf); 35297 } else { 35298 SOC_IF_ERROR_RETURN 35299 (READ_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ANY, index, &pri_map)); 35300 *internal_pri = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &pri_map, PRIf); 35301 hw_color = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &pri_map, CNGf); 35302 } 35303 35304 *color = _BCM_COLOR_DECODING(unit, hw_color); 35305 return BCM_E_NONE; 35306 } 35307 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 35308 return BCM_E_UNAVAIL; 35309 35310 } 35311 35312 /* 35313 * Function: 35314 * bcm_esw_port_vlan_priority_unmap_set 35315 * Description: 35316 * Define the mapping of outgoing port, internal priority, and color to 35317 * outgoing packet priority and cfi bit. 35318 * Parameters: 35319 * unit - (IN) Device number 35320 * port - (IN) Port number 35321 * internal_pri - (IN) Internal priority 35322 * color - (IN) Color 35323 * pkt_pri - (IN) Packet priority 35324 * cfi - (IN) Packet CFI 35325 * Return Value: 35326 * BCM_E_XXX 35327 * Note: 35328 * This API programs only the mapping table. 35329 */ 35330 int 35331 bcm_esw_port_vlan_priority_unmap_set(int unit, bcm_port_t port, 35332 int internal_pri, bcm_color_t color, 35333 int pkt_pri, int cfi) 35334 { 35335 /* Make sure port module is initialized. */ 35336 PORT_INIT(unit); 35337 35338 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 35339 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 35340 return BCM_E_UNAVAIL; 35341 } 35342 #endif 35343 35344 if (SOC_IS_TRIDENT3X(unit)) { 35345 return BCM_E_UNAVAIL; 35346 } 35347 35348 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 35349 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 35350 || defined(BCM_TRX_SUPPORT) 35351 if (soc_feature(unit, soc_feature_color_prio_map)) { 35352 int index, int_pri_shift; 35353 uint32 pri_unmap[SOC_MAX_MEM_FIELD_WORDS]; 35354 soc_mem_t mem = EGR_PRI_CNG_MAPm; 35355 35356 int_pri_shift = SOC_IS_TRX(unit) ? 4 : 3; 35357 if ((internal_pri < 0 || internal_pri >= (1 << int_pri_shift)) || 35358 ((color != bcmColorGreen) && (color != bcmColorYellow) && 35359 (color != bcmColorRed))) { 35360 return BCM_E_PARAM; 35361 } 35362 if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1) { 35363 return BCM_E_PARAM; 35364 } 35365 35366 /* EGR_PRI_CNG_MAP table is indexed with 35367 * port[4:0] priority[2:0] CNG [1:0] 35368 * port[5:0] priority[3:0] CNG [1:0] (TRX) 35369 */ 35370 index = (port << (int_pri_shift + 2)) | (internal_pri << 2) | 35371 _BCM_COLOR_ENCODING(unit, color); 35372 35373 sal_memset(pri_unmap, 0, sizeof(pri_unmap)); 35374 soc_mem_field32_set(unit, mem, &pri_unmap, PRIf, pkt_pri); 35375 soc_mem_field32_set(unit, mem, &pri_unmap, CFIf, cfi); 35376 SOC_IF_ERROR_RETURN 35377 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &pri_unmap)); 35378 35379 if ((SOC_IS_TD_TT(unit) && !SOC_IS_TOMAHAWK3(unit)) || 35380 SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) { 35381 egr_map_mh_entry_t egr_map; 35382 35383 sal_memset(&egr_map, 0, sizeof(egr_map)); 35384 index = (port << int_pri_shift) | (internal_pri) ; 35385 soc_mem_field32_set(unit, EGR_MAP_MHm, &egr_map, HG_TCf, internal_pri); 35386 SOC_IF_ERROR_RETURN(WRITE_EGR_MAP_MHm(unit, MEM_BLOCK_ALL, index, &egr_map)); 35387 } 35388 35389 return BCM_E_NONE; 35390 } 35391 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 35392 return BCM_E_UNAVAIL; 35393 } 35394 35395 /* 35396 * Function: 35397 * bcm_esw_port_vlan_priority_unmap_get 35398 * Description: 35399 * Get the mapping of outgoing port, internal priority, and color to 35400 * outgoing packet priority and cfi bit. 35401 * Parameters: 35402 * unit - (IN) Device number 35403 * port - (IN) Port number 35404 * internal_pri - (IN) Internal priority 35405 * color - (IN) Color 35406 * pkt_pri - (OUT) Packet priority 35407 * cfi - (OUT) Packet CFI 35408 * Return Value: 35409 * BCM_E_XXX 35410 * Note: 35411 * This API programs only the mapping table. 35412 */ 35413 int 35414 bcm_esw_port_vlan_priority_unmap_get(int unit, bcm_port_t port, 35415 int internal_pri, bcm_color_t color, 35416 int *pkt_pri, int *cfi) 35417 { 35418 /* Make sure port module is initialized. */ 35419 PORT_INIT(unit); 35420 35421 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 35422 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 35423 return BCM_E_UNAVAIL; 35424 } 35425 #endif 35426 35427 if (SOC_IS_TRIDENT3X(unit)) { 35428 return BCM_E_UNAVAIL; 35429 } 35430 35431 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 35432 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 35433 || defined(BCM_TRX_SUPPORT) 35434 if (soc_feature(unit, soc_feature_color_prio_map)) { 35435 int index, int_pri_shift; 35436 uint32 pri_unmap[SOC_MAX_MEM_FIELD_WORDS]; 35437 soc_mem_t mem = EGR_PRI_CNG_MAPm; 35438 35439 int_pri_shift = SOC_IS_TRX(unit) ? 4 : 3; 35440 if ((internal_pri < 0 || internal_pri >= (1 << int_pri_shift)) || 35441 ((color != bcmColorGreen) && (color != bcmColorYellow) && 35442 (color != bcmColorRed))) { 35443 return BCM_E_PARAM; 35444 } 35445 35446 /* EGR_PRI_CNG_MAP table is indexed with 35447 * port[4:0] priority[2:0] CNG [1:0] 35448 * port[5:0] priority[3:0] CNG [1:0] (TRX) 35449 */ 35450 index = (port << (int_pri_shift + 2)) | (internal_pri << 2) | 35451 _BCM_COLOR_ENCODING(unit, color); 35452 35453 SOC_IF_ERROR_RETURN 35454 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, pri_unmap)); 35455 *pkt_pri = soc_mem_field32_get(unit, mem, pri_unmap, PRIf); 35456 *cfi = soc_mem_field32_get(unit, mem, pri_unmap, CFIf); 35457 return BCM_E_NONE; 35458 } 35459 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 35460 return BCM_E_UNAVAIL; 35461 } 35462 35463 /* 35464 * Function: 35465 * bcm_esw_port_l3_modify_set 35466 * Description: 35467 * Enable/Disable ingress port based L3 unicast packet operations. 35468 * Parameters: 35469 * unit - Device number 35470 * port - Port number 35471 * flags - bitmap of the packet operations to be enabled or disabled. 35472 * Return Value: 35473 * BCM_E_XXX 35474 * Notes: 35475 * Available on XGS3 only. 35476 */ 35477 int 35478 bcm_esw_port_l3_modify_set(int unit, bcm_port_t port, uint32 flags) 35479 { 35480 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3) 35481 uint64 r; 35482 soc_reg_t reg; 35483 35484 /* Make sure port module is initialized. */ 35485 PORT_INIT(unit); 35486 35487 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 35488 if (SOC_IS_XGS3_SWITCH(unit)) { 35489 reg = IS_ST_PORT(unit, port) ? 35490 IEGR_PORT_L3UC_MODSr : EGR_PORT_L3UC_MODSr; 35491 } else { 35492 return BCM_E_UNAVAIL; 35493 } 35494 35495 if (!SOC_REG_IS_VALID(unit, reg)) { 35496 return BCM_E_UNAVAIL; 35497 } 35498 35499 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &r)); 35500 35501 soc_reg64_field32_set(unit, reg, &r, L3_UC_SA_DISABLEf, 35502 (flags & BCM_PORT_L3_MODIFY_NO_SRCMAC) ? 1 : 0); 35503 35504 soc_reg64_field32_set(unit, reg, &r, L3_UC_DA_DISABLEf, 35505 (flags & BCM_PORT_L3_MODIFY_NO_DSTMAC) ? 1 : 0); 35506 35507 soc_reg64_field32_set(unit, reg, &r, L3_UC_TTL_DISABLEf, 35508 (flags & BCM_PORT_L3_MODIFY_NO_TTL) ? 1 : 0); 35509 35510 soc_reg64_field32_set(unit, reg, &r, L3_UC_VLAN_DISABLEf, 35511 (flags & BCM_PORT_L3_MODIFY_NO_VLAN) ? 1 : 0); 35512 35513 return soc_reg_set(unit, reg, port, 0, r); 35514 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */ 35515 return BCM_E_UNAVAIL; 35516 } 35517 35518 /* 35519 * Function: 35520 * bcm_esw_port_l3_modify_get 35521 * Description: 35522 * Get ingress port based L3 unicast packet operations status. 35523 * Parameters: 35524 * unit - Device number 35525 * port - Port number 35526 * flags - (OUT) pointer to uint32 where bitmap of the current L3 packet 35527 * operations is returned. 35528 * Return Value: 35529 * BCM_E_NONE 35530 * BCM_E_UNAVAIL - Functionality not available 35531 * Notes: 35532 * Available on XGS3 only. 35533 */ 35534 int 35535 bcm_esw_port_l3_modify_get(int unit, bcm_port_t port, uint32 *flags) 35536 { 35537 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3) 35538 uint64 r; 35539 soc_reg_t reg; 35540 35541 /* Make sure port module is initialized. */ 35542 PORT_INIT(unit); 35543 35544 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 35545 if (SOC_IS_XGS3_SWITCH(unit)) { 35546 reg = IS_ST_PORT(unit, port) ? 35547 IEGR_PORT_L3UC_MODSr : EGR_PORT_L3UC_MODSr; 35548 } else { 35549 return BCM_E_UNAVAIL; 35550 } 35551 35552 if (!SOC_REG_IS_VALID(unit, reg)) { 35553 return BCM_E_UNAVAIL; 35554 } 35555 35556 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &r)); 35557 35558 *flags = 0; 35559 35560 if (soc_reg64_field32_get(unit, reg, r, L3_UC_SA_DISABLEf)) { 35561 *flags |= BCM_PORT_L3_MODIFY_NO_SRCMAC; 35562 } 35563 35564 if (soc_reg64_field32_get(unit, reg, r, L3_UC_DA_DISABLEf)) { 35565 *flags |= BCM_PORT_L3_MODIFY_NO_DSTMAC; 35566 } 35567 35568 if (soc_reg64_field32_get(unit, reg, r, L3_UC_TTL_DISABLEf)) { 35569 *flags |= BCM_PORT_L3_MODIFY_NO_TTL; 35570 } 35571 35572 if (soc_reg64_field32_get(unit, reg, r, L3_UC_VLAN_DISABLEf)) { 35573 *flags |= BCM_PORT_L3_MODIFY_NO_VLAN; 35574 } 35575 35576 return BCM_E_NONE; 35577 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */ 35578 return BCM_E_UNAVAIL; 35579 } 35580 35581 /* 35582 * Function: 35583 * bcm_esw_port_ipmc_modify_set 35584 * Description: 35585 * Enable/Disable ingress port based L3 multicast packet operations. 35586 * If the reg EGR_IPMC_CFG2r does not contain DISABLE_TTL_CHECKf field, 35587 * and if flag is set , then return E_PARAM. 35588 * if flag is not set, then donot validate the field. 35589 * Parameters: 35590 * unit - Device number 35591 * port - Port number 35592 * flags - bitmap of the packet operations to be enabled or disabled. 35593 * Return Value: 35594 * BCM_E_XXX 35595 * Notes: 35596 * Available on XGS3 only. 35597 */ 35598 int 35599 bcm_esw_port_ipmc_modify_set(int unit, bcm_port_t port, uint32 flags) 35600 { 35601 #if defined(INCLUDE_L3) 35602 int field_count; 35603 soc_field_t fields[]={DISABLE_SA_REPLACEf, DISABLE_TTL_DECREMENTf, 35604 DISABLE_TTL_CHECKf}; 35605 uint32 values[]={0, 0, 0}; 35606 35607 /* Make sure port module is initialized. */ 35608 PORT_INIT(unit); 35609 35610 field_count = COUNTOF(fields); 35611 if (!soc_feature(unit, soc_feature_ip_mcast)) { 35612 return BCM_E_UNAVAIL; 35613 } 35614 35615 if (soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) { 35616 return BCM_E_UNAVAIL; 35617 } 35618 35619 if (!SOC_REG_IS_VALID(unit, EGR_IPMC_CFG2r) && 35620 !soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) { 35621 return BCM_E_UNAVAIL; 35622 } 35623 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 35624 35625 #if defined(BCM_RAPTOR1_SUPPORT) 35626 if (SOC_IS_RAPTOR(unit)) { 35627 return BCM_E_UNAVAIL; 35628 } 35629 #endif /* BCM_RAPTOR1_SUPPORT */ 35630 35631 values[0] = (flags & BCM_PORT_IPMC_MODIFY_NO_SRCMAC) ? 1 : 0; 35632 values[1] = (flags & BCM_PORT_IPMC_MODIFY_NO_TTL) ? 1 : 0; 35633 values[2] = (flags & BCM_PORT_IPMC_CHECK_NO_TTL) ? 1 : 0; 35634 35635 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 35636 if (soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) { 35637 return soc_mem_fields32_modify(unit, EGR_IPMC_CFG2m, port, 35638 field_count, fields, values); 35639 } else 35640 #endif 35641 { 35642 if (values[2]) { 35643 if (!SOC_REG_FIELD_VALID(unit, EGR_IPMC_CFG2r, DISABLE_TTL_CHECKf)) { 35644 return BCM_E_PARAM; 35645 } 35646 } else { 35647 /* Donot include DISABLE_TTL_CHECKf for field validation in reg */ 35648 if (!SOC_REG_FIELD_VALID(unit, EGR_IPMC_CFG2r, DISABLE_TTL_CHECKf)) { 35649 field_count -= 1; 35650 } 35651 } 35652 35653 return soc_reg_fields32_modify(unit, EGR_IPMC_CFG2r, port, 35654 field_count, fields, values); 35655 } 35656 #else /* INCLUDE_L3 */ 35657 return (BCM_E_UNAVAIL); 35658 #endif /* INCLUDE_L3 */ 35659 } 35660 35661 /* 35662 * Function: 35663 * bcm_esw_port_ipmc_modify_get 35664 * Description: 35665 * Enable/Disable ingress port based L3 multicast packet operations. 35666 * Parameters: 35667 * unit - Device number 35668 * port - Port number 35669 * flags - (OUT) pointer to uint32 where bitmap of the current L3 packet 35670 * operations is returned. 35671 * Return Value: 35672 * BCM_E_NONE 35673 * BCM_E_UNAVAIL - Functionality not available 35674 * Notes: 35675 * Available on XGS3 only. 35676 */ 35677 int 35678 bcm_esw_port_ipmc_modify_get(int unit, bcm_port_t port, uint32 *flags) 35679 { 35680 #if defined(INCLUDE_L3) 35681 uint32 reg_val; 35682 35683 if (!soc_feature(unit, soc_feature_ip_mcast)) { 35684 return BCM_E_UNAVAIL; 35685 } 35686 35687 if (soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) { 35688 return BCM_E_UNAVAIL; 35689 } 35690 35691 if (!SOC_REG_IS_VALID(unit, EGR_IPMC_CFG2r) && 35692 !soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) { 35693 return BCM_E_UNAVAIL; 35694 } 35695 35696 #if defined(BCM_RAPTOR1_SUPPORT) 35697 if (SOC_IS_RAPTOR(unit)) { 35698 return BCM_E_UNAVAIL; 35699 } 35700 #endif /* BCM_RAPTOR1_SUPPORT */ 35701 35702 /* Make sure port module is initialized. */ 35703 PORT_INIT(unit); 35704 35705 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 35706 if (NULL == flags) { 35707 return (BCM_E_PARAM); 35708 } 35709 35710 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 35711 if (soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) { 35712 BCM_IF_ERROR_RETURN(READ_EGR_IPMC_CFG2m(unit, MEM_BLOCK_ANY, port, ®_val)); 35713 *flags = 0; 35714 if (soc_mem_field32_get(unit, EGR_IPMC_CFG2m, ®_val, DISABLE_SA_REPLACEf)) { 35715 *flags |= BCM_PORT_IPMC_MODIFY_NO_SRCMAC; 35716 } 35717 if (soc_mem_field32_get(unit, EGR_IPMC_CFG2m, ®_val, DISABLE_TTL_DECREMENTf)) { 35718 *flags |= BCM_PORT_IPMC_MODIFY_NO_TTL; 35719 } 35720 if (soc_mem_field32_get(unit, EGR_IPMC_CFG2m, ®_val, DISABLE_TTL_CHECKf)) { 35721 *flags |= BCM_PORT_IPMC_CHECK_NO_TTL; 35722 } 35723 } else 35724 #endif 35725 { 35726 BCM_IF_ERROR_RETURN(READ_EGR_IPMC_CFG2r(unit, port, ®_val)); 35727 35728 *flags = 0; 35729 if (soc_reg_field_get(unit, EGR_IPMC_CFG2r, reg_val, DISABLE_SA_REPLACEf)) { 35730 *flags |= BCM_PORT_IPMC_MODIFY_NO_SRCMAC; 35731 } 35732 if (soc_reg_field_get(unit, EGR_IPMC_CFG2r, reg_val, DISABLE_TTL_DECREMENTf)) { 35733 *flags |= BCM_PORT_IPMC_MODIFY_NO_TTL; 35734 } 35735 if (SOC_REG_FIELD_VALID(unit, EGR_IPMC_CFG2r, DISABLE_TTL_CHECKf)) { 35736 if (soc_reg_field_get(unit, EGR_IPMC_CFG2r, reg_val, 35737 DISABLE_TTL_CHECKf)) { 35738 *flags |= BCM_PORT_IPMC_CHECK_NO_TTL; 35739 } 35740 } 35741 } 35742 return (BCM_E_NONE); 35743 #else /* INCLUDE_L3 */ 35744 return (BCM_E_UNAVAIL); 35745 #endif /* INCLUDE_L3 */ 35746 } 35747 35748 /* 35749 * Function: 35750 * _bcm_port_force_forward_linkscan_handler 35751 * Description: 35752 * Called from linkscan handler when port toggles. 35753 * Adds/removes entry from LOCAL_SW_DISABLE_DEFAULT_PBM 35754 * Parameters: 35755 * unit - Device number 35756 * info - port info 35757 * Return Value: 35758 * BCM_E_XXX 35759 */ 35760 void 35761 _bcm_port_force_forward_linkscan_handler(int unit, 35762 bcm_port_t port, bcm_port_info_t *info) 35763 { 35764 bcm_port_t local_port; 35765 bcm_pbmp_t *sw_disable_pbmp_linkstate = 35766 p_linkstate[unit].sw_disable_pbmp_linkstate; 35767 int rv = BCM_E_NONE; 35768 35769 if (!info) { 35770 return; 35771 } 35772 35773 if (sw_disable_pbmp_linkstate == NULL) { 35774 return; 35775 } 35776 if (p_linkstate[unit].num_pbmp_entry) { 35777 PBMP_ALL_ITER(unit, local_port) { 35778 if (BCM_PBMP_MEMBER(sw_disable_pbmp_linkstate[local_port], 35779 port)) { 35780 if (info->linkstatus == BCM_PORT_LINK_STATUS_DOWN) { 35781 p_linkstate[unit].lock = 1; 35782 rv = bcm_esw_port_force_forward_mode_set(unit, local_port, 35783 port, BCM_PORT_FORCE_FORWARD_DISABLE); 35784 p_linkstate[unit].lock = 0; 35785 } else if (info->linkstatus == BCM_PORT_LINK_STATUS_UP) { 35786 p_linkstate[unit].lock = 1; 35787 rv = bcm_esw_port_force_forward_mode_set(unit, local_port, 35788 port, BCM_PORT_FORCE_FORWARD_ALL); 35789 p_linkstate[unit].lock = 0; 35790 } 35791 if (BCM_FAILURE(rv)) { 35792 LOG_WARN(BSL_LS_BCM_PORT, 35793 (BSL_META_U(unit, 35794 "bcm_esw_port_force_forward_mode_set failed for " 35795 "port %d, dest_port %d, link_state %d. rv = %d\n"), 35796 local_port, port, info->linkstatus, rv)); 35797 } 35798 } 35799 } 35800 } 35801 } 35802 35803 #if defined(BCM_TRIUMPH3_SUPPORT) 35804 /* 35805 * Function: 35806 * _bcm_port_force_forward_init 35807 * Purpose: 35808 * Initialize the port_forward entries 35809 * Parameters: 35810 * unit - SOC unit # 35811 * Returns: 35812 * BCM_E_XXX 35813 */ 35814 int 35815 _bcm_port_force_forward_init(int unit) 35816 { 35817 p_linkstate[unit].num_pbmp_entry = 0; 35818 35819 if (p_linkstate[unit].sw_disable_pbmp_linkstate != NULL) { 35820 sal_free(p_linkstate[unit].sw_disable_pbmp_linkstate); 35821 p_linkstate[unit].sw_disable_pbmp_linkstate = NULL; 35822 } 35823 35824 p_linkstate[unit].sw_disable_pbmp_linkstate = (bcm_pbmp_t*) sal_alloc( 35825 sizeof(bcm_pbmp_t) * SOC_MAX_NUM_PORTS, 35826 "SW disable pbmp linkstate"); 35827 if (p_linkstate[unit].sw_disable_pbmp_linkstate == NULL) { 35828 return BCM_E_MEMORY; 35829 } 35830 sal_memset(p_linkstate[unit].sw_disable_pbmp_linkstate, 0, 35831 sizeof(bcm_pbmp_t) * SOC_MAX_NUM_PORTS); 35832 return BCM_E_NONE; 35833 } 35834 35835 /* 35836 * Function: 35837 * _bcm_port_force_forward_deinit 35838 * Purpose: 35839 * Uninitialize the port_forward entries 35840 * Parameters: 35841 * unit - SOC unit # 35842 * Returns: 35843 * BCM_E_XXX 35844 */ 35845 int 35846 _bcm_port_force_forward_deinit(int unit) 35847 { 35848 if (p_linkstate[unit].sw_disable_pbmp_linkstate != NULL) { 35849 sal_free(p_linkstate[unit].sw_disable_pbmp_linkstate); 35850 p_linkstate[unit].sw_disable_pbmp_linkstate = NULL; 35851 p_linkstate[unit].num_pbmp_entry = 0; 35852 } 35853 return BCM_E_NONE; 35854 } 35855 35856 /* 35857 * Function: 35858 * _bcm_port_force_forward_add 35859 * Purpose: 35860 * Add/Deletes an entry into the port_forward DB. 35861 * Parameters: 35862 * unit - SOC unit # 35863 * local_port - Local port/Ingress port 35864 * egr_port - destination port. Set 0 to delete it. 35865 * Returns: 35866 * BCM_E_XXX 35867 */ 35868 int 35869 _bcm_port_force_forward_add(int unit, bcm_port_t local_port, 35870 bcm_port_t egr_port) 35871 { 35872 bcm_pbmp_t *sw_disable_pbmp_linkstate = 35873 p_linkstate[unit].sw_disable_pbmp_linkstate; 35874 if (!sw_disable_pbmp_linkstate) { 35875 return BCM_E_INTERNAL; 35876 } 35877 /* Lock is taken while calling bcm_esw_port_force_forward_mode_set 35878 * from the linkscan handler. It is not taken when called by user. 35879 * It is to ensure that only HW tables are written to and the 35880 * corresponding SW datastructure remains intact. 35881 */ 35882 if (p_linkstate[unit].lock) { 35883 return BCM_E_NONE; 35884 } 35885 BCM_PBMP_PORT_SET(sw_disable_pbmp_linkstate[local_port], egr_port); 35886 p_linkstate[unit].num_pbmp_entry++; 35887 return BCM_E_NONE; 35888 } 35889 35890 #ifdef BCM_WARM_BOOT_SUPPORT 35891 #define _BCM_PORT_WB_MAX_PBMP_V1_5 256 35892 35893 /* 35894 * Function: 35895 * _bcm_port_force_forward_sync 35896 * Purpose: 35897 * Sync port_forward DB to scache. 35898 * Parameters: 35899 * unit - Device unit number 35900 * scache_ptr - Scache pointer. 35901 * Returns: 35902 * BCM_E_XXX 35903 */ 35904 int 35905 _bcm_port_force_forward_sync(int unit, uint8 **scache_ptr) 35906 { 35907 bcm_port_t local_port, dst_port; 35908 bcm_pbmp_t *sw_disable_pbmp_linkstate = p_linkstate[unit].sw_disable_pbmp_linkstate; 35909 int port_count = 0, iter = 0; 35910 SHR_BITDCLNAME(port_bmp, _BCM_PORT_WB_MAX_PBMP_V1_5); 35911 35912 if ((scache_ptr == NULL) || (*scache_ptr == NULL)) { 35913 return BCM_E_INTERNAL; 35914 } 35915 35916 PBMP_ALL_ITER(unit, local_port) { 35917 port_count = 0; 35918 iter = 0; 35919 sal_memset(&port_bmp, 0, sizeof(port_bmp)); 35920 BCM_PBMP_COUNT(sw_disable_pbmp_linkstate[local_port], port_count); 35921 if (BCM_PBMP_NOT_NULL(sw_disable_pbmp_linkstate[local_port])) { 35922 BCM_PBMP_ITER(sw_disable_pbmp_linkstate[local_port], dst_port) { 35923 if(_SHR_BITDCLSIZE(_BCM_PORT_WB_MAX_PBMP_V1_5) < 35924 _SHR_BITDCLSIZE(dst_port)) { 35925 /* coverity[dead_error_line] */ 35926 continue; 35927 } 35928 /* coverity[overrun-local] */ 35929 SHR_BITSET(port_bmp, dst_port); 35930 iter++; 35931 if (iter >= port_count) { 35932 break; 35933 } 35934 } 35935 } 35936 sal_memcpy(*scache_ptr, port_bmp, sizeof(port_bmp)); 35937 *scache_ptr += sizeof(port_bmp); 35938 } 35939 35940 return BCM_E_NONE; 35941 } 35942 35943 /* 35944 * Function: 35945 * _bcm_port_force_forward_reinit 35946 * Purpose: 35947 * Retrieve port_forward from hardware and scache. 35948 * Parameters: 35949 * unit - Device unit number 35950 * scache_ptr - Scache pointer. 35951 * Returns: 35952 * BCM_E_XXX 35953 */ 35954 int 35955 _bcm_port_force_forward_reinit(int unit, uint8 **scache_ptr) 35956 { 35957 bcm_port_t local_port; 35958 int idx; 35959 bcm_pbmp_t *sw_disable_pbmp_linkstate = 35960 p_linkstate[unit].sw_disable_pbmp_linkstate; 35961 SHR_BITDCLNAME(port_bmp, _BCM_PORT_WB_MAX_PBMP_V1_5); 35962 35963 p_linkstate[unit].num_pbmp_entry = 0; 35964 if ((scache_ptr == NULL) || (*scache_ptr == NULL)) { 35965 return BCM_E_PARAM; 35966 } 35967 35968 sal_memset(&port_bmp, 0, sizeof(port_bmp)); 35969 sal_memset(sw_disable_pbmp_linkstate, 0, sizeof(bcm_pbmp_t)); 35970 PBMP_ALL_ITER(unit, local_port) { 35971 sal_memcpy(&port_bmp, *scache_ptr, sizeof(port_bmp)); 35972 *scache_ptr += sizeof(port_bmp); 35973 if (!SHR_BITNULL_RANGE(port_bmp, 0, _BCM_PORT_WB_MAX_PBMP_V1_5)){ 35974 int bitcount = 0; 35975 SHR_BITCOUNT_RANGE(port_bmp, bitcount, 0, _BCM_PORT_WB_MAX_PBMP_V1_5); 35976 for(idx = 0; (idx < _BCM_PORT_WB_MAX_PBMP_V1_5) && (bitcount); idx++) { 35977 if(SHR_BITGET(port_bmp, idx)) { 35978 BCM_PBMP_PORT_ADD(sw_disable_pbmp_linkstate[local_port], idx); 35979 p_linkstate[unit].num_pbmp_entry++; 35980 bitcount--; 35981 } 35982 } 35983 } 35984 } 35985 35986 return BCM_E_NONE; 35987 } 35988 35989 /* 35990 * Function: 35991 * _bcm_port_force_forward_scache_size 35992 * Purpose: 35993 * Get the size of the port_forward for scache 35994 * Parameters: 35995 * unit - Device unit number 35996 * size - size of scache 35997 * Returns: 35998 * BCM_E_XXX 35999 */ 36000 int 36001 _bcm_port_force_forward_scache_size(int unit, int *size) 36002 { 36003 int port_forward_size; 36004 int port_count = 0; 36005 bcm_port_t local_port; 36006 36007 if (!size) { 36008 return BCM_E_PARAM; 36009 } 36010 36011 /* We prefer to use a predefined size of _BCM_PORT_WB_MAX_PBMP_V1_5 36012 * for warmboot instead of bcm_pbmp_t. This is because of any future 36013 * increase in max port count for new devices which may change the 36014 * size of bcm_bcmp_t. 36015 */ 36016 PBMP_ALL_ITER(unit, local_port) { 36017 port_count++; 36018 } 36019 port_forward_size = SHR_BITALLOCSIZE(_BCM_PORT_WB_MAX_PBMP_V1_5) * port_count; 36020 36021 *size = port_forward_size; 36022 return BCM_E_NONE; 36023 } 36024 #endif /* BCM_WARM_BOOT_SUPPORT */ 36025 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/ 36026 36027 /* 36028 * Function: 36029 * bcm_port_force_forward_mode_set 36030 * Purpose: 36031 * Set egress override port mode. 36032 * Parameters: 36033 * unit - (IN) Unit number. 36034 * port - (IN) Port number 36035 * egr_port - (IN) Egress port number 36036 * flags - (IN) Force forward flags from PORT_FORCE_FORWARD_* 36037 * Returns: 36038 * BCM_E_xxx 36039 * Notes: 36040 */ 36041 int 36042 bcm_esw_port_force_forward_mode_set(int unit, bcm_port_t port, 36043 bcm_port_t egr_port, uint32 flags) 36044 { 36045 /* Make sure port module is initialized. */ 36046 PORT_INIT(unit); 36047 36048 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) \ 36049 || defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 36050 if (soc_feature(unit, soc_feature_force_forward)) { 36051 36052 int enable = FALSE; 36053 36054 if ((0 != (flags & BCM_PORT_FORCE_FORWARD_LOCAL) && 36055 !SOC_IS_TRX(unit))) { 36056 /* We don't support local only mode on pre-TRX devices */ 36057 return BCM_E_PARAM; 36058 } 36059 36060 if (0 != (flags & (BCM_PORT_FORCE_FORWARD_ALL | 36061 BCM_PORT_FORCE_FORWARD_LOCAL))) { 36062 enable = TRUE; 36063 } 36064 36065 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 36066 if (enable) { 36067 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, egr_port, 36068 &egr_port)); 36069 } 36070 36071 #if defined(BCM_TRIUMPH_SUPPORT) 36072 if (SOC_IS_TR_VL(unit)) { 36073 pbmp_t pbmp; 36074 uint64 val; 36075 int cpu_hg_index = 0; 36076 36077 COMPILER_64_SET(val, 0, 0); 36078 SOC_PBMP_CLEAR(pbmp); 36079 if (enable) { 36080 SOC_PBMP_PORT_SET(pbmp, egr_port); 36081 } 36082 if (soc_mem_is_valid(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm)) { 36083 local_sw_disable_default_pbm_entry_t entry; 36084 sal_memset(&entry, 0, sizeof(entry)); 36085 soc_mem_pbmp_field_set(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm, 36086 &entry, PORT_BITMAPf, &pbmp); 36087 BCM_IF_ERROR_RETURN 36088 (soc_mem_write(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm, 36089 MEM_BLOCK_ANY, port, &entry)); 36090 36091 cpu_hg_index = SOC_IS_KATANA2(unit) ? 36092 SOC_INFO(unit).cpu_hg_pp_port_index : 36093 SOC_INFO(unit).cpu_hg_index; 36094 if (IS_CPU_PORT(unit, port)) { 36095 BCM_IF_ERROR_RETURN 36096 (soc_mem_write(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm, 36097 MEM_BLOCK_ANY, cpu_hg_index, &entry)); 36098 } 36099 } else { 36100 #if defined(BCM_GREYHOUND2_SUPPORT) 36101 if (SOC_IS_GREYHOUND2(unit)) { 36102 uint64 val_hi, field_val; 36103 36104 COMPILER_64_SET(val_hi, 0, 0); 36105 COMPILER_64_SET(field_val, 36106 SOC_PBMP_WORD_GET(pbmp, 1), SOC_PBMP_WORD_GET(pbmp, 0)); 36107 soc_reg64_field_set(unit, LOCAL_SW_DISABLE_DEFAULT_PBM_LOr, 36108 &val, PORT_BITMAP_LOf, field_val); 36109 36110 COMPILER_64_SET(field_val, 36111 0, SOC_PBMP_WORD_GET(pbmp, 2)); 36112 soc_reg64_field_set(unit, LOCAL_SW_DISABLE_DEFAULT_PBM_HIr, 36113 &val_hi, PORT_BITMAP_LOf, field_val); 36114 36115 36116 if (IS_ST_PORT(unit, port)) { 36117 BCM_IF_ERROR_RETURN 36118 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, val)); 36119 BCM_IF_ERROR_RETURN 36120 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, val_hi)); 36121 } else { 36122 BCM_IF_ERROR_RETURN 36123 (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, val)); 36124 BCM_IF_ERROR_RETURN 36125 (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, val_hi)); 36126 if (IS_CPU_PORT(unit, port)) { 36127 BCM_IF_ERROR_RETURN 36128 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, val)); 36129 BCM_IF_ERROR_RETURN 36130 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, val_hi)); 36131 } 36132 } 36133 } else 36134 #endif /* BCM_GREYHOUND2_SUPPORT */ 36135 { 36136 soc_reg64_field32_set(unit 36137 , LOCAL_SW_DISABLE_DEFAULT_PBM_64r, 36138 &val, PORT_BITMAP_LOf, 36139 SOC_PBMP_WORD_GET(pbmp, 0)); 36140 if(!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 36141 !SOC_IS_GREYHOUND(unit)) { 36142 soc_reg64_field32_set(unit, 36143 LOCAL_SW_DISABLE_DEFAULT_PBM_64r, 36144 &val, PORT_BITMAP_HIf, 36145 SOC_PBMP_WORD_GET(pbmp, 1)); 36146 } 36147 36148 if (IS_ST_PORT(unit, port)) { 36149 BCM_IF_ERROR_RETURN 36150 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port, 36151 val)); 36152 } else { 36153 BCM_IF_ERROR_RETURN 36154 (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port, 36155 val)); 36156 if (IS_CPU_PORT(unit, port)) { 36157 BCM_IF_ERROR_RETURN 36158 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port, 36159 val)); 36160 } 36161 } 36162 } 36163 } 36164 } else 36165 #endif /* BCM_TRIUMPH_SUPPORT */ 36166 { 36167 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 36168 defined(BCM_SCORPION_SUPPORT) 36169 if ((SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || 36170 SOC_IS_SC_CQ(unit)) && IS_ST_PORT(unit, port)) { 36171 BCM_IF_ERROR_RETURN 36172 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port, 36173 (enable) ? 1 << egr_port : 0)); 36174 } else 36175 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 36176 { 36177 BCM_IF_ERROR_RETURN 36178 (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port, 36179 (enable) ? 1 << egr_port : 0)); 36180 } 36181 } 36182 36183 #if defined(BCM_TRIUMPH3_SUPPORT) 36184 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 36185 int rv; 36186 rv = _bcm_port_force_forward_add(unit, port, 36187 (enable) ? egr_port : 0); 36188 if (BCM_FAILURE(rv)) { 36189 return rv; 36190 } 36191 } 36192 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/ 36193 36194 #if defined(BCM_TRX_SUPPORT) 36195 if (SOC_IS_TRX(unit)) { 36196 uint32 mode; 36197 36198 mode = (flags & BCM_PORT_FORCE_FORWARD_LOCAL) ? 36199 _BCM_TRX_PORT_FORCE_FORWARD_LOCAL : 36200 ((flags & BCM_PORT_FORCE_FORWARD_ALL) ? 36201 _BCM_TRX_PORT_FORCE_FORWARD_ALL : 36202 _BCM_TRX_PORT_FORCE_FORWARD_DISABLE); 36203 36204 return soc_reg_field32_modify(unit, LOCAL_SW_DISABLE_CTRLr, 36205 port, SW_MODEf, mode); 36206 } else 36207 #endif 36208 { 36209 return _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 36210 LOCAL_SW_DISABLEf, 36211 (enable) ? 1 : 0); 36212 } 36213 } 36214 #endif /* BCM_BRADLEY_SUPPORT || BCM_FIREBOLT2_SUPPORT \ 36215 || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 36216 return BCM_E_UNAVAIL; 36217 } 36218 36219 /* 36220 * Function: 36221 * bcm_port_force_forward_mode_get 36222 * Purpose: 36223 * Get egress override port. 36224 * Parameters: 36225 * unit - (IN) Unit number. 36226 * port - (IN) Port number 36227 * egr_port - (OUT) Egress port number 36228 * flags - (OUT) Force forward flags from PORT_FORCE_FORWARD_* 36229 * Returns: 36230 * BCM_E_xxx 36231 * Notes: 36232 */ 36233 int 36234 bcm_esw_port_force_forward_mode_get(int unit, bcm_port_t port, 36235 bcm_port_t *egr_port, uint32 *flags) 36236 { 36237 /* Make sure port module is initialized. */ 36238 PORT_INIT(unit); 36239 36240 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) \ 36241 || defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 36242 if (soc_feature(unit, soc_feature_force_forward)) { 36243 pbmp_t pbmp; 36244 uint32 egr_pbm; 36245 int ep, enabled; 36246 36247 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 36248 36249 #if defined(BCM_TRX_SUPPORT) 36250 if (SOC_IS_TRX(unit)) { 36251 uint32 val_32, mode; 36252 36253 BCM_IF_ERROR_RETURN 36254 (READ_LOCAL_SW_DISABLE_CTRLr(unit, port, &val_32)); 36255 mode = soc_reg_field_get(unit, LOCAL_SW_DISABLE_CTRLr, 36256 val_32, SW_MODEf); 36257 36258 if (_BCM_TRX_PORT_FORCE_FORWARD_LOCAL == mode) { 36259 *flags = BCM_PORT_FORCE_FORWARD_LOCAL; 36260 } else if (_BCM_TRX_PORT_FORCE_FORWARD_ALL == mode) { 36261 *flags = BCM_PORT_FORCE_FORWARD_ALL; 36262 } else { 36263 *flags = BCM_PORT_FORCE_FORWARD_DISABLE; 36264 } 36265 enabled = (BCM_PORT_FORCE_FORWARD_DISABLE != mode); 36266 } else 36267 #endif 36268 { 36269 BCM_IF_ERROR_RETURN 36270 (_bcm_esw_port_tab_get(unit, port, LOCAL_SW_DISABLEf, &enabled)); 36271 *flags = enabled ? BCM_PORT_FORCE_FORWARD_ALL : 36272 BCM_PORT_FORCE_FORWARD_DISABLE; 36273 } 36274 36275 if (enabled) { 36276 _bcm_gport_dest_t dest; 36277 bcm_module_t modid; 36278 int isGport = 0; 36279 36280 _bcm_gport_dest_t_init(&dest); 36281 #if defined(BCM_TRIUMPH_SUPPORT) 36282 if (SOC_IS_TR_VL(unit)) { 36283 uint64 val; 36284 36285 if (soc_mem_is_valid(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm)) { 36286 local_sw_disable_default_pbm_entry_t entry; 36287 BCM_IF_ERROR_RETURN 36288 (soc_mem_read(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm, 36289 MEM_BLOCK_ANY, port, &entry)); 36290 soc_mem_pbmp_field_get(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm, 36291 &entry, PORT_BITMAPf, &pbmp); 36292 } else { 36293 #if defined(BCM_GREYHOUND2_SUPPORT) 36294 if (SOC_IS_GREYHOUND2(unit)) { 36295 BCM_IF_ERROR_RETURN 36296 (READ_LOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, &val)); 36297 36298 egr_pbm = soc_reg64_field32_get(unit, 36299 LOCAL_SW_DISABLE_DEFAULT_PBM_LOr, 36300 val, OVER_LOf); 36301 SOC_PBMP_CLEAR(pbmp); 36302 SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm); 36303 36304 egr_pbm = soc_reg64_field32_get(unit, 36305 LOCAL_SW_DISABLE_DEFAULT_PBM_LOr, 36306 val, OVER_HIf); 36307 SOC_PBMP_WORD_SET(pbmp, 1, egr_pbm); 36308 36309 BCM_IF_ERROR_RETURN 36310 (READ_LOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, &val)); 36311 36312 egr_pbm = soc_reg64_field32_get(unit, 36313 LOCAL_SW_DISABLE_DEFAULT_PBM_HIr, 36314 val, OVER_LOf); 36315 SOC_PBMP_WORD_SET(pbmp, 2, egr_pbm); 36316 } else 36317 #endif /* BCM_GREYHOUND2_SUPPORT */ 36318 { 36319 BCM_IF_ERROR_RETURN 36320 (READ_LOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port, 36321 &val)); 36322 egr_pbm = 36323 soc_reg64_field32_get(unit, 36324 LOCAL_SW_DISABLE_DEFAULT_PBM_64r, 36325 val, PORT_BITMAP_LOf); 36326 SOC_PBMP_CLEAR(pbmp); 36327 SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm); 36328 if ((egr_pbm == 0) && 36329 (!SOC_IS_ENDURO(unit)) && (!SOC_IS_HURRICANEX(unit)) && 36330 (!SOC_IS_GREYHOUND(unit))) { 36331 egr_pbm = soc_reg64_field32_get 36332 (unit, LOCAL_SW_DISABLE_DEFAULT_PBM_64r, 36333 val, PORT_BITMAP_HIf); 36334 SOC_PBMP_WORD_SET(pbmp, 1, egr_pbm); 36335 } 36336 } 36337 } 36338 } else 36339 #endif /* BCM_TRIUMPH_SUPPORT */ 36340 if ((SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || 36341 SOC_IS_SC_CQ(unit)) && IS_ST_PORT(unit, port)) { 36342 BCM_IF_ERROR_RETURN 36343 (READ_ILOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port, &egr_pbm)); 36344 SOC_PBMP_CLEAR(pbmp); 36345 SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm); 36346 } else { 36347 BCM_IF_ERROR_RETURN 36348 (READ_LOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port, &egr_pbm)); 36349 SOC_PBMP_CLEAR(pbmp); 36350 SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm); 36351 } 36352 if (SOC_PBMP_IS_NULL(pbmp)) { 36353 return BCM_E_INTERNAL; 36354 } 36355 /* Convert port bitmap into port number */ 36356 SOC_PBMP_ITER(pbmp, ep) { 36357 break; 36358 } 36359 BCM_IF_ERROR_RETURN 36360 (bcm_esw_switch_control_get(unit, bcmSwitchUseGport, &isGport)); 36361 if (isGport) { 36362 /* ignore return code to suport devices w/out modid assigned */ 36363 (void)bcm_esw_stk_my_modid_get(unit, &modid); 36364 36365 if (BCM_MODID_INVALID == modid) { 36366 dest.gport_type = _SHR_GPORT_TYPE_DEVPORT; 36367 } else { 36368 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 36369 dest.modid = modid; 36370 } 36371 dest.port = ep; 36372 36373 BCM_IF_ERROR_RETURN 36374 (_bcm_esw_gport_construct(unit, &dest, &ep)); 36375 } 36376 *egr_port = ep; 36377 } 36378 return BCM_E_NONE; 36379 } 36380 #endif /* BCM_BRADLEY_SUPPORT || BCM_FIREBOLT2_SUPPORT \ 36381 || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 36382 return BCM_E_UNAVAIL; 36383 } 36384 36385 /* 36386 * Function: 36387 * bcm_esw_port_force_forward_set 36388 * Purpose: 36389 * This function allows packets to bypass the normal forwarding 36390 * logic and be sent out on a specific port instead. 36391 * Parameters: 36392 * unit - Device number 36393 * port - Port number 36394 * egr_port - Egress port number 36395 * enable - Bypass switching logic and forward to egr_port 36396 * Return Value: 36397 * BCM_E_NONE 36398 * BCM_E_UNAVAIL - Functionality not available 36399 * Notes: 36400 * All normal ingress processing (table lookups etc.) is still 36401 * performed and used for contructing the Higig header if the 36402 * forced egress port is a Higig port. 36403 */ 36404 int 36405 bcm_esw_port_force_forward_set(int unit, bcm_port_t port, 36406 bcm_port_t egr_port, int enable) 36407 { 36408 return bcm_esw_port_force_forward_mode_set(unit, port, egr_port, 36409 enable ? BCM_PORT_FORCE_FORWARD_ALL : 36410 BCM_PORT_FORCE_FORWARD_DISABLE); 36411 } 36412 36413 /* 36414 * Function: 36415 * bcm_esw_port_force_forward_get 36416 * Purpose: 36417 * Determine forced forwarding setting for a port. 36418 * Parameters: 36419 * unit - Device number 36420 * port - Port number 36421 * egr_port - (OUT) Egress port number 36422 * enabled - (OUT) Forced forwarding enabled 36423 * Return Value: 36424 * BCM_E_NONE 36425 * BCM_E_UNAVAIL - Functionality not available 36426 * Notes: 36427 * If the value of enabled is zero, the value of egr_port should 36428 * be ignored. 36429 */ 36430 int 36431 bcm_esw_port_force_forward_get(int unit, bcm_port_t port, 36432 bcm_port_t *egr_port, int *enabled) 36433 { 36434 uint32 flags; 36435 36436 /* Make sure port module is initialized. */ 36437 PORT_INIT(unit); 36438 36439 BCM_IF_ERROR_RETURN 36440 (bcm_esw_port_force_forward_mode_get(unit, port, egr_port, &flags)); 36441 36442 *enabled = (0 != (flags & (BCM_PORT_FORCE_FORWARD_ALL | 36443 BCM_PORT_FORCE_FORWARD_LOCAL))); 36444 return BCM_E_NONE; 36445 } 36446 36447 #if defined(INCLUDE_L3) 36448 /* 36449 * Function: 36450 * _bcm_esw_port_ecmp_dlb_link_status_set 36451 * Purpose: 36452 * Set ECMP DLB port link status. 36453 * Parameters: 36454 * unit - (IN) SOC unit number. 36455 * port - (IN) Port, not Gport. 36456 * status - (IN) ECMP DLB port link status. 36457 * Returns: 36458 * BCM_E_xxx 36459 */ 36460 int 36461 _bcm_esw_port_ecmp_dlb_link_status_set(int unit, bcm_port_t port, 36462 int status) 36463 { 36464 int rv = BCM_E_UNAVAIL; 36465 36466 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 36467 if (soc_feature(unit, soc_feature_ecmp_dlb_optimized)) { 36468 rv = _bcm_th2_l3_egress_ecmp_port_status_set(unit, port, status); 36469 } 36470 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */ 36471 36472 return rv; 36473 } 36474 #endif /* INCLUDE_L3 */ 36475 36476 36477 #if defined(INCLUDE_L3) 36478 /* 36479 * Function: 36480 * _bcm_esw_port_ecmp_dlb_link_status_get 36481 * Purpose: 36482 * Get ECMP DLB port link status. 36483 * Parameters: 36484 * unit - (IN) SOC unit number. 36485 * port - (IN) Port, not Gport. 36486 * status - (OUT) ECMP DLB port link status. 36487 * Returns: 36488 * BCM_E_xxx 36489 */ 36490 int 36491 _bcm_esw_port_ecmp_dlb_link_status_get(int unit, bcm_port_t port, 36492 int *status) 36493 { 36494 int rv = BCM_E_UNAVAIL; 36495 36496 if (status == NULL) { 36497 return BCM_E_PARAM; 36498 } 36499 36500 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 36501 if (soc_feature(unit, soc_feature_ecmp_dlb_optimized)) { 36502 rv = _bcm_th2_l3_egress_ecmp_port_status_get(unit, port, status); 36503 } 36504 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */ 36505 36506 return rv; 36507 } 36508 #endif /* INCLUDE_L3 */ 36509 36510 36511 36512 /* 36513 * Function: 36514 * _bcm_esw_port_err_sym_detect_set 36515 * Description: 36516 * Enable/Disable XAUI error symbol monitoring feature. 36517 * Parameters: 36518 * unit - Device number 36519 * port - Port number 36520 * enable - TRUE, enable |E| monitoring feature on the port. 36521 * FALSE, disable |E| monitoring feature on the port. 36522 * Return Value: 36523 * BCM_E_NONE 36524 * BCM_E_UNAVAIL - Functionality not available 36525 */ 36526 #ifdef BCM_XGS3_SWITCH_SUPPORT 36527 STATIC int 36528 _bcm_esw_port_err_sym_detect_set(int unit, bcm_port_t port, int enable) 36529 { 36530 int rv; 36531 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 36532 36533 LOG_INFO(BSL_LS_BCM_PORT, 36534 (BSL_META_U(unit, 36535 "_bcm_esw_port_err_sym_detect_set: u=%d p=%d enable=%d\n"), 36536 unit, port, enable)); 36537 36538 if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port) 36539 #ifdef BCM_GXPORT_SUPPORT 36540 || IS_GX_PORT(unit, port) 36541 #endif /* BCM_GXPORT_SUPPORT */ 36542 ) { 36543 PORT_LOCK(unit); 36544 rv = soc_xaui_err_sym_detect_set(unit, port, enable); 36545 PORT_UNLOCK(unit); 36546 } else { 36547 rv = BCM_E_UNAVAIL; 36548 } 36549 36550 36551 return rv; 36552 } 36553 #endif 36554 36555 /* 36556 * Function: 36557 * _bcm_esw_port_err_sym_detect_get 36558 * Description: 36559 * Get the status of XAUI error symbol monitoring feature. 36560 * Parameters: 36561 * unit - Device number 36562 * port - Port number 36563 * status - (OUT) TRUE, port is enabled, FALSE port is disabled. 36564 * Return Value: 36565 * BCM_E_NONE 36566 * BCM_E_UNAVAIL - Functionality not available 36567 */ 36568 #ifdef BCM_XGS3_SWITCH_SUPPORT 36569 STATIC int 36570 _bcm_esw_port_err_sym_detect_get(int unit, bcm_port_t port, int *status) 36571 { 36572 int rv; 36573 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 36574 36575 if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port) 36576 #ifdef BCM_GXPORT_SUPPORT 36577 || IS_GX_PORT(unit, port) 36578 #endif /* BCM_GXPORT_SUPPORT */ 36579 ) { 36580 PORT_LOCK(unit); 36581 rv = soc_xaui_err_sym_detect_get(unit, port, status); 36582 PORT_UNLOCK(unit); 36583 } else { 36584 rv = BCM_E_UNAVAIL; 36585 } 36586 36587 LOG_INFO(BSL_LS_BCM_PORT, 36588 (BSL_META_U(unit, 36589 "_bcm_esw_port_err_sym_detect_get: u=%d p=%d status=%d\n"), 36590 unit, port, *status)); 36591 36592 return rv; 36593 } 36594 #endif 36595 36596 /* 36597 * Function: 36598 * _bcm_esw_port_err_sym_count_get 36599 * Description: 36600 * Get the number of |E| symbol in XAUI lanes since last read. 36601 * The |E| symbol count is cleared on read. 36602 * Parameters: 36603 * unit - Device number 36604 * port - Port number 36605 * count - (OUT) Number of |E| error since last read. 36606 * Return Value: 36607 * BCM_E_NONE 36608 * BCM_E_UNAVAIL - Functionality not available 36609 * BCM_E_INIT - Error symbol detect feature is not enabled 36610 */ 36611 STATIC int 36612 _bcm_esw_port_err_sym_count_get(int unit, bcm_port_t port, int *count) 36613 { 36614 int rv; 36615 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 36616 36617 rv = BCM_E_UNAVAIL; 36618 36619 #ifdef BCM_XGS3_SWITCH_SUPPORT 36620 36621 if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port) 36622 #ifdef BCM_GXPORT_SUPPORT 36623 || IS_GX_PORT(unit, port) 36624 #endif /* BCM_GXPORT_SUPPORT */ 36625 ) { 36626 PORT_LOCK(unit); 36627 rv = soc_xaui_err_sym_count(unit, port, count); 36628 PORT_UNLOCK(unit); 36629 } 36630 #endif 36631 36632 LOG_INFO(BSL_LS_BCM_PORT, 36633 (BSL_META_U(unit, 36634 "_bcm_esw_port_err_sym_count_get: u=%d p=%d count=%d\n"), 36635 unit, port, *count)); 36636 36637 return rv; 36638 } 36639 36640 STATIC int 36641 _bcm_esw_port_control_bridge_set(int unit, bcm_port_t port, int value) 36642 { 36643 int rv = BCM_E_UNAVAIL; 36644 36645 #ifdef BCM_TRIUMPH_SUPPORT 36646 if (SOC_IS_TR_VL(unit)) { 36647 bcm_pbmp_t pbmp; /* Port bitmap to update.*/ 36648 36649 if (IS_E_PORT(unit, port) 36650 || IS_CPU_PORT(unit, port) 36651 || IS_HG_PORT(unit, port)) { 36652 if (SOC_MEM_IS_VALID(unit, PORT_BRIDGE_BMAPm)) { 36653 port_bridge_bmap_entry_t entry; 36654 36655 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_BRIDGE_BMAPm, 36656 MEM_BLOCK_ANY, 0, &entry)); 36657 soc_mem_pbmp_field_get(unit, PORT_BRIDGE_BMAPm, &entry, 36658 BITMAPf, &pbmp); 36659 if (value && !SOC_PBMP_MEMBER(pbmp, port)) { 36660 SOC_PBMP_PORT_ADD(pbmp, port); 36661 } else if (!value && SOC_PBMP_MEMBER(pbmp, port)) { 36662 SOC_PBMP_PORT_REMOVE(pbmp, port); 36663 } else { 36664 return BCM_E_NONE; 36665 } 36666 soc_mem_pbmp_field_set(unit, PORT_BRIDGE_BMAPm, &entry, 36667 BITMAPf, &pbmp); 36668 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_BMAPm, 36669 MEM_BLOCK_ANY, 0, &entry)); 36670 } 36671 if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_BMAP_64r)) { 36672 uint64 buf64; /* Buffer for reg64 value. */ 36673 SOC_PBMP_CLEAR(pbmp); 36674 36675 BCM_IF_ERROR_RETURN 36676 (READ_PORT_BRIDGE_BMAP_64r(unit, &buf64)); 36677 36678 /* Set l3 port bitmap. */ 36679 SOC_PBMP_WORD_SET(pbmp, 0, 36680 soc_reg64_field32_get(unit, PORT_BRIDGE_BMAP_64r, 36681 buf64, BITMAP_LOf)); 36682 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 36683 !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) { 36684 SOC_PBMP_WORD_SET(pbmp, 1, 36685 soc_reg64_field32_get(unit, PORT_BRIDGE_BMAP_64r, 36686 buf64, BITMAP_HIf)); 36687 } 36688 36689 if (SOC_PBMP_MEMBER(pbmp, port) && value) { 36690 return BCM_E_NONE; 36691 } 36692 if (!SOC_PBMP_MEMBER(pbmp, port) && !value) { 36693 return BCM_E_NONE; 36694 } 36695 if (!SOC_PBMP_MEMBER(pbmp, port) && value) { 36696 SOC_PBMP_PORT_ADD(pbmp, port); 36697 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) { 36698 SOC_PBMP_PORT_REMOVE(pbmp, port); 36699 } 36700 36701 soc_reg64_field32_set(unit, PORT_BRIDGE_BMAP_64r, 36702 &buf64, BITMAP_LOf, 36703 SOC_PBMP_WORD_GET(pbmp, 0)); 36704 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 36705 !SOC_IS_GREYHOUND(unit)) { 36706 soc_reg64_field32_set(unit, PORT_BRIDGE_BMAP_64r, 36707 &buf64, BITMAP_HIf, 36708 SOC_PBMP_WORD_GET(pbmp, 1)); 36709 } 36710 36711 BCM_IF_ERROR_RETURN 36712 (WRITE_PORT_BRIDGE_BMAP_64r(unit, buf64)); 36713 } else if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_BMAP_LO_64r)) { 36714 /* 36715 * Both PORT_BRIDGE_BMAP_LO_64r and PORT_BRIDGE_BMAP_HI_64r 36716 * are expected been valid here. 36717 */ 36718 36719 uint64 fval64, rval64; 36720 uint32 t_port; 36721 soc_reg_t reg; 36722 pbmp_t curr_pbmp; 36723 36724 BCM_PBMP_CLEAR(curr_pbmp); 36725 COMPILER_64_ZERO(fval64); 36726 COMPILER_64_ZERO(rval64); 36727 36728 36729 if (port < 64) { 36730 reg = PORT_BRIDGE_BMAP_LO_64r; 36731 t_port = port; 36732 } else { 36733 reg = PORT_BRIDGE_BMAP_HI_64r; 36734 t_port = port - 64; 36735 } 36736 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64); 36737 if (BCM_SUCCESS(rv)) { 36738 fval64 = soc_reg64_field_get(unit, reg, 36739 rval64, BITMAPf); 36740 SOC_PBMP_WORD_SET(curr_pbmp, 0, 36741 COMPILER_64_LO(fval64)); 36742 SOC_PBMP_WORD_SET(curr_pbmp, 1, 36743 COMPILER_64_HI(fval64)); 36744 36745 if (value && !SOC_PBMP_MEMBER(curr_pbmp, t_port)) { 36746 SOC_PBMP_PORT_ADD(curr_pbmp, t_port); 36747 } else if (!value && SOC_PBMP_MEMBER(curr_pbmp, t_port)) { 36748 SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port); 36749 } else { 36750 return BCM_E_NONE; 36751 } 36752 36753 COMPILER_64_SET(fval64, 36754 SOC_PBMP_WORD_GET(curr_pbmp, 1), 36755 SOC_PBMP_WORD_GET(curr_pbmp, 0)); 36756 soc_reg64_field_set(unit, reg, &rval64, 36757 BITMAPf, fval64); 36758 rv = soc_reg_set(unit, reg, 36759 REG_PORT_ANY, 0, rval64); 36760 } 36761 } 36762 36763 } 36764 if (IS_HG_PORT(unit, port)) { 36765 36766 if (SOC_MEM_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAPm)) { 36767 port_bridge_mirror_bmap_entry_t entry; 36768 36769 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_BRIDGE_MIRROR_BMAPm, 36770 MEM_BLOCK_ANY, 0, &entry)); 36771 soc_mem_pbmp_field_get(unit, PORT_BRIDGE_MIRROR_BMAPm, &entry, 36772 BITMAPf, &pbmp); 36773 /* it might be different to port_tab, so don't return */ 36774 if (value && !SOC_PBMP_MEMBER(pbmp, port)) { 36775 SOC_PBMP_PORT_ADD(pbmp, port); 36776 } else if (!value && SOC_PBMP_MEMBER(pbmp, port)) { 36777 SOC_PBMP_PORT_REMOVE(pbmp, port); 36778 } 36779 soc_mem_pbmp_field_set(unit, PORT_BRIDGE_MIRROR_BMAPm, &entry, 36780 BITMAPf, &pbmp); 36781 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_MIRROR_BMAPm, 36782 MEM_BLOCK_ANY, 0, &entry)); 36783 } 36784 36785 if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAP_64r)) { 36786 uint64 buf64; /* Buffer for reg64 value. */ 36787 SOC_PBMP_CLEAR(pbmp); 36788 36789 BCM_IF_ERROR_RETURN 36790 (READ_PORT_BRIDGE_MIRROR_BMAP_64r(unit, &buf64)); 36791 36792 /* Set port bitmap. */ 36793 SOC_PBMP_WORD_SET(pbmp, 0, 36794 soc_reg64_field32_get(unit, PORT_BRIDGE_MIRROR_BMAP_64r, 36795 buf64, BITMAP_LOf)); 36796 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 36797 !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) { 36798 SOC_PBMP_WORD_SET(pbmp, 1, 36799 soc_reg64_field32_get(unit, PORT_BRIDGE_MIRROR_BMAP_64r, 36800 buf64, BITMAP_HIf)); 36801 } 36802 36803 if (!SOC_PBMP_MEMBER(pbmp, port) && value) { 36804 SOC_PBMP_PORT_ADD(pbmp, port); 36805 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) { 36806 SOC_PBMP_PORT_REMOVE(pbmp, port); 36807 } else { 36808 return BCM_E_NONE; 36809 } 36810 36811 soc_reg64_field32_set(unit, PORT_BRIDGE_MIRROR_BMAP_64r, 36812 &buf64, BITMAP_LOf, SOC_PBMP_WORD_GET(pbmp, 0)); 36813 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 36814 !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) { 36815 soc_reg64_field32_set(unit, PORT_BRIDGE_MIRROR_BMAP_64r, 36816 &buf64, BITMAP_HIf, SOC_PBMP_WORD_GET(pbmp, 1)); 36817 } 36818 36819 BCM_IF_ERROR_RETURN 36820 (WRITE_PORT_BRIDGE_MIRROR_BMAP_64r(unit, buf64)); 36821 } else if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAP_LOr)) { 36822 /* 36823 * Both PORT_BRIDGE_MIRROR_BMAP_LOr and PORT_BRIDGE_MIRROR_BMAP_HIr 36824 * are expected been valid here. 36825 */ 36826 36827 uint64 fval64, rval64; 36828 uint32 t_port; 36829 soc_reg_t reg; 36830 pbmp_t curr_pbmp; 36831 36832 BCM_PBMP_CLEAR(curr_pbmp); 36833 COMPILER_64_ZERO(fval64); 36834 COMPILER_64_ZERO(rval64); 36835 36836 36837 if (port < 64) { 36838 reg = PORT_BRIDGE_MIRROR_BMAP_LOr; 36839 t_port = port; 36840 } else { 36841 reg = PORT_BRIDGE_MIRROR_BMAP_HIr; 36842 t_port = port - 64; 36843 } 36844 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64); 36845 if (BCM_SUCCESS(rv)) { 36846 fval64 = soc_reg64_field_get(unit, reg, 36847 rval64, BITMAPf); 36848 SOC_PBMP_WORD_SET(curr_pbmp, 0, 36849 COMPILER_64_LO(fval64)); 36850 SOC_PBMP_WORD_SET(curr_pbmp, 1, 36851 COMPILER_64_HI(fval64)); 36852 36853 if (value && !SOC_PBMP_MEMBER(curr_pbmp, t_port)) { 36854 SOC_PBMP_PORT_ADD(curr_pbmp, t_port); 36855 } else if (!value && SOC_PBMP_MEMBER(curr_pbmp, t_port)) { 36856 SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port); 36857 } else { 36858 return BCM_E_NONE; 36859 } 36860 36861 COMPILER_64_SET(fval64, 36862 SOC_PBMP_WORD_GET(curr_pbmp, 1), 36863 SOC_PBMP_WORD_GET(curr_pbmp, 0)); 36864 soc_reg64_field_set(unit, reg, &rval64, 36865 BITMAPf, fval64); 36866 rv = soc_reg_set(unit, reg, 36867 REG_PORT_ANY, 0, rval64); 36868 } 36869 } 36870 } 36871 36872 /* Allow to set bridging on higig ports as well */ 36873 return _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 36874 PORT_BRIDGEf, (value) ? 1 : 0); 36875 } 36876 #endif /* BCM_TRIUMPH_SUPPORT */ 36877 36878 if (SOC_IS_XGS3_SWITCH(unit)) { 36879 /* Allow to set bridging on higig ports as well */ 36880 rv =_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 36881 PORT_BRIDGEf, (value) ? 1 : 0); 36882 BCM_IF_ERROR_RETURN(rv); 36883 36884 if (IS_E_PORT(unit, port) || IS_CPU_PORT(unit, port)) { 36885 36886 #if defined(BCM_RAPTOR_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 36887 defined(BCM_SCORPION_SUPPORT) 36888 if (soc_feature(unit, soc_feature_src_trunk_port_bridge)) { 36889 bcm_pbmp_t pbmp; /* Port bitmap to update.*/ 36890 uint32 port_bridge_map; 36891 #if defined (BCM_RAPTOR_SUPPORT) 36892 uint32 port_bridge_map_hi; 36893 #endif 36894 36895 SOC_PBMP_CLEAR(pbmp); 36896 BCM_IF_ERROR_RETURN 36897 (READ_PORT_BRIDGE_BMAPr(unit, &port_bridge_map)); 36898 36899 SOC_PBMP_WORD_SET(pbmp, 0, 36900 soc_reg_field_get(unit, PORT_BRIDGE_BMAPr, 36901 port_bridge_map, BITMAPf)); 36902 #if defined (BCM_RAPTOR_SUPPORT) 36903 if (soc_feature(unit, soc_feature_register_hi)) { 36904 BCM_IF_ERROR_RETURN 36905 (READ_PORT_BRIDGE_BMAP_HIr(unit, 36906 &port_bridge_map_hi)); 36907 SOC_PBMP_WORD_SET(pbmp, 1, 36908 soc_reg_field_get(unit, PORT_BRIDGE_BMAP_HIr, 36909 port_bridge_map_hi, BITMAPf)); 36910 } 36911 #endif 36912 if (!SOC_PBMP_MEMBER(pbmp, port) && value) { 36913 SOC_PBMP_PORT_ADD(pbmp, port); 36914 soc_reg_field_set(unit, PORT_BRIDGE_BMAPr, 36915 &port_bridge_map, BITMAPf, 36916 SOC_PBMP_WORD_GET(pbmp, 0)); 36917 BCM_IF_ERROR_RETURN 36918 (WRITE_PORT_BRIDGE_BMAPr(unit, port_bridge_map)); 36919 #if defined (BCM_RAPTOR_SUPPORT) 36920 36921 if (soc_feature(unit, soc_feature_register_hi)) { 36922 soc_reg_field_set(unit, PORT_BRIDGE_BMAP_HIr, 36923 &port_bridge_map_hi, BITMAPf, 36924 SOC_PBMP_WORD_GET(pbmp, 1)); 36925 BCM_IF_ERROR_RETURN 36926 (WRITE_PORT_BRIDGE_BMAP_HIr(unit, 36927 port_bridge_map_hi)); 36928 } 36929 #endif 36930 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) { 36931 SOC_PBMP_PORT_REMOVE(pbmp, port); 36932 soc_reg_field_set(unit, PORT_BRIDGE_BMAPr, 36933 &port_bridge_map, BITMAPf, 36934 SOC_PBMP_WORD_GET(pbmp, 0)); 36935 BCM_IF_ERROR_RETURN 36936 (WRITE_PORT_BRIDGE_BMAPr(unit, port_bridge_map)); 36937 #if defined (BCM_RAPTOR_SUPPORT) 36938 if (soc_feature(unit, soc_feature_register_hi)) { 36939 soc_reg_field_set(unit, PORT_BRIDGE_BMAP_HIr, 36940 &port_bridge_map_hi, BITMAPf, 36941 SOC_PBMP_WORD_GET(pbmp, 1)); 36942 BCM_IF_ERROR_RETURN 36943 (WRITE_PORT_BRIDGE_BMAP_HIr(unit, 36944 port_bridge_map_hi)); 36945 } 36946 #endif 36947 } 36948 } 36949 #endif /* BCM_RAPTOR_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 36950 36951 } else if (IS_HG_PORT(unit, port)) { 36952 #ifdef BCM_SCORPION_SUPPORT 36953 if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAPr)) { 36954 bcm_pbmp_t pbmp; /* Port bitmap to update.*/ 36955 uint32 port_bridge_mirror_map; 36956 36957 SOC_PBMP_CLEAR(pbmp); 36958 BCM_IF_ERROR_RETURN(READ_PORT_BRIDGE_MIRROR_BMAPr(unit, 36959 &port_bridge_mirror_map)); 36960 SOC_PBMP_WORD_SET(pbmp, 0, 36961 soc_reg_field_get(unit, PORT_BRIDGE_MIRROR_BMAPr, 36962 port_bridge_mirror_map, BITMAPf)); 36963 36964 if (!SOC_PBMP_MEMBER(pbmp, port) && value) { 36965 SOC_PBMP_PORT_ADD(pbmp, port); 36966 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) { 36967 SOC_PBMP_PORT_REMOVE(pbmp, port); 36968 } else { 36969 return BCM_E_NONE; 36970 } 36971 36972 soc_reg_field_set(unit, PORT_BRIDGE_MIRROR_BMAPr, 36973 &port_bridge_mirror_map, BITMAPf, 36974 SOC_PBMP_WORD_GET(pbmp, 0)); 36975 BCM_IF_ERROR_RETURN(WRITE_PORT_BRIDGE_MIRROR_BMAPr(unit, 36976 port_bridge_mirror_map)); 36977 } 36978 #endif /* BCM_SCORPION_SUPPORT */ 36979 } 36980 } 36981 return rv; 36982 } 36983 36984 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX) 36985 STATIC int 36986 _bcm_esw_port_regex_control_set(int unit, bcm_gport_t gport, 36987 int udp, int tcp, int enable) 36988 { 36989 int vp = -1; 36990 bcm_port_t local_port; 36991 source_vp_entry_t svp_entry; 36992 source_trunk_map_table_entry_t stm_entry; 36993 ft_dst_port_config_entry_t ftdcfg; 36994 bcm_module_t my_modid; 36995 int index; 36996 int rv; 36997 36998 if (!soc_feature(unit, soc_feature_regex)) { 36999 return BCM_E_UNAVAIL; 37000 } 37001 37002 enable = !!enable; 37003 37004 if (BCM_GPORT_IS_MIM_PORT(gport)) { 37005 vp = BCM_GPORT_MIM_PORT_ID_GET(gport); 37006 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 37007 return BCM_E_NOT_FOUND; 37008 } 37009 } else if (BCM_GPORT_IS_MPLS_PORT(gport)) { 37010 vp = BCM_GPORT_MPLS_PORT_ID_GET(gport); 37011 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 37012 return BCM_E_NOT_FOUND; 37013 } 37014 } else if (BCM_GPORT_IS_WLAN_PORT(gport)) { 37015 vp = BCM_GPORT_WLAN_PORT_ID_GET(gport); 37016 } 37017 37018 if (vp >= 0) { 37019 SOC_IF_ERROR_RETURN 37020 (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry)); 37021 if (tcp) { 37022 soc_SOURCE_VPm_field32_set(unit, &svp_entry, 37023 DPI_TCP_CREATE_ENf, enable); 37024 tcp = enable; 37025 } else { 37026 tcp = soc_SOURCE_VPm_field32_get(unit, &svp_entry, 37027 DPI_TCP_CREATE_ENf); 37028 } 37029 if (udp) { 37030 soc_SOURCE_VPm_field32_set(unit, &svp_entry, 37031 DPI_UDP_CREATE_ENf, enable); 37032 udp = enable; 37033 } else { 37034 udp = soc_SOURCE_VPm_field32_get(unit, &svp_entry, 37035 DPI_UDP_CREATE_ENf); 37036 } 37037 if (tcp + udp) { 37038 soc_SOURCE_VPm_field32_set(unit, &svp_entry, DPI_ENABLEf, 1); 37039 } else { 37040 soc_SOURCE_VPm_field32_set(unit, &svp_entry, DPI_ENABLEf, 0); 37041 } 37042 BCM_IF_ERROR_RETURN(WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry)); 37043 } else { 37044 BCM_IF_ERROR_RETURN( 37045 _bcm_esw_port_gport_validate(unit, gport, &local_port)); 37046 /* Port sanity check. */ 37047 if (!SOC_PORT_ADDRESSABLE(unit, local_port)) { 37048 return (BCM_E_PORT); 37049 } 37050 37051 /* Get local module id. */ 37052 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 37053 37054 soc_mem_lock(unit, SOURCE_TRUNK_MAP_TABLEm); 37055 37056 /* Calculate table index. */ 37057 rv = _bcm_esw_src_mod_port_table_index_get(unit, my_modid, 37058 local_port, &index); 37059 37060 if(BCM_FAILURE(rv)) { 37061 soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm); 37062 return rv; 37063 } 37064 37065 rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, 37066 index, &stm_entry); 37067 if(BCM_FAILURE(rv)) { 37068 soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm); 37069 return rv; 37070 } 37071 37072 if (tcp) { 37073 soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, 37074 DPI_TCP_CREATE_ENf, enable); 37075 tcp = enable; 37076 } else { 37077 tcp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry, 37078 DPI_TCP_CREATE_ENf); 37079 } 37080 if (udp) { 37081 soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, 37082 DPI_UDP_CREATE_ENf, enable); 37083 udp = enable; 37084 } else { 37085 udp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry, 37086 DPI_UDP_CREATE_ENf); 37087 } 37088 if (tcp + udp) { 37089 soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, DPI_ENABLEf, 1); 37090 } else { 37091 soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, DPI_ENABLEf, 0); 37092 } 37093 37094 rv = WRITE_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ALL, 37095 index, &stm_entry); 37096 37097 soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm); 37098 if(BCM_FAILURE(rv)) { 37099 return rv; 37100 } 37101 37102 SOC_IF_ERROR_RETURN(READ_FT_DST_PORT_CONFIGm(unit, MEM_BLOCK_ANY, 37103 local_port, &ftdcfg)); 37104 soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg, 37105 DPI_TCP_CREATE_ENf, !!tcp); 37106 soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg, 37107 DPI_UDP_CREATE_ENf, !!udp); 37108 if (tcp + udp) { 37109 soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg, DPI_ENABLEf, 1); 37110 } else { 37111 soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg, DPI_ENABLEf, 0); 37112 } 37113 SOC_IF_ERROR_RETURN(WRITE_FT_DST_PORT_CONFIGm(unit, MEM_BLOCK_ANY, 37114 local_port, &ftdcfg)); 37115 } 37116 return BCM_E_NONE; 37117 } 37118 37119 STATIC int _bcm_esw_port_regex_control_get(int unit, bcm_gport_t gport, 37120 int *udp, int *tcp, int *enable) 37121 { 37122 int vp = -1; 37123 bcm_port_t local_port; 37124 source_vp_entry_t svp_entry; 37125 source_trunk_map_table_entry_t stm_entry; 37126 ft_dst_port_config_entry_t ftdcfg; 37127 bcm_module_t my_modid; 37128 int index; 37129 37130 if (!soc_feature(unit, soc_feature_regex)) { 37131 return BCM_E_UNAVAIL; 37132 } 37133 37134 if (BCM_GPORT_IS_MIM_PORT(gport)) { 37135 vp = BCM_GPORT_MIM_PORT_ID_GET(gport); 37136 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 37137 return BCM_E_NOT_FOUND; 37138 } 37139 } else if (BCM_GPORT_IS_MPLS_PORT(gport)) { 37140 vp = BCM_GPORT_MPLS_PORT_ID_GET(gport); 37141 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 37142 return BCM_E_NOT_FOUND; 37143 } 37144 } else if (BCM_GPORT_IS_WLAN_PORT(gport)) { 37145 vp = BCM_GPORT_WLAN_PORT_ID_GET(gport); 37146 } 37147 37148 if (vp >= 0) { 37149 SOC_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry)); 37150 *tcp = soc_SOURCE_VPm_field32_get(unit, &svp_entry, DPI_TCP_CREATE_ENf); 37151 *udp = soc_SOURCE_VPm_field32_get(unit, &svp_entry, DPI_UDP_CREATE_ENf); 37152 *enable = soc_SOURCE_VPm_field32_get(unit, &svp_entry, DPI_ENABLEf); 37153 } else { 37154 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, gport, &local_port)); 37155 /* Port sanity check. */ 37156 if (!SOC_PORT_ADDRESSABLE(unit, local_port)) { 37157 return (BCM_E_PORT); 37158 } 37159 37160 /* Get local module id. */ 37161 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 37162 37163 /* Calculate table index. */ 37164 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, my_modid, 37165 local_port, &index)); 37166 37167 BCM_IF_ERROR_RETURN(READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, 37168 index, &stm_entry)); 37169 *tcp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry, 37170 DPI_TCP_CREATE_ENf); 37171 *udp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry, 37172 DPI_UDP_CREATE_ENf); 37173 SOC_IF_ERROR_RETURN(READ_FT_DST_PORT_CONFIGm(unit, MEM_BLOCK_ANY, 37174 local_port, &ftdcfg)); 37175 *enable = soc_FT_DST_PORT_CONFIGm_field32_get(unit, &ftdcfg, DPI_ENABLEf); 37176 } 37177 return BCM_E_NONE; 37178 } 37179 #endif 37180 37181 #if defined(BCM_SHADOW_SUPPORT) 37182 STATIC int 37183 _bcm_port_type_shadow_support (int unit, bcm_port_t port, 37184 bcm_port_control_t type) 37185 { 37186 LOG_INFO(BSL_LS_BCM_PORT, 37187 (BSL_META_U(unit, 37188 "_bcm_port_type_shadow_support : u=%d p=%d type=%d\n"), 37189 unit, port, (int)type)); 37190 37191 switch (type) 37192 { 37193 /* Shadoow supported port control types */ 37194 case bcmPortControlManagementPacketIp6Reserved: 37195 case bcmPortControlManagementPacketIp4Reserved: 37196 case bcmPortControlManagementPacketLinkConstrained: 37197 case bcmPortControlManagementPacketGarp: 37198 case bcmPortControlManagementPacketCos: 37199 case bcmPortControlManagementPacketColor: 37200 case bcmPortControlTaggedL3PacketPktPri: 37201 case bcmPortControlTaggedMPLSPacketPktPri: 37202 case bcmPortControlTaggedMPLSL3PacketPktPri: 37203 case bcmPortControlRxEnable: 37204 case bcmPortControlTxEnable: 37205 case bcmPortControlPFCEthertype: 37206 case bcmPortControlPFCOpcode: 37207 case bcmPortControlPFCReceive: 37208 case bcmPortControlPFCTransmit: 37209 case bcmPortControlPFCClasses: 37210 case bcmPortControlPFCPassFrames: 37211 case bcmPortControlPFCDestMacOui: 37212 case bcmPortControlPFCDestMacNonOui: 37213 case bcmPortControlPFCRefreshTime: 37214 case bcmPortControlPFCXOffTime: 37215 case bcmPortControlEEETransmitWakeTime: 37216 case bcmPortControlEEEReceiveWakeTime: 37217 case bcmPortControlEEETransmitSleepTime: 37218 case bcmPortControlEEEReceiveSleepTime: 37219 case bcmPortControlEEETransmitQuietTime: 37220 case bcmPortControlEEEReceiveQuietTime: 37221 case bcmPortControlEEETransmitRefreshTime: 37222 case bcmPortControlEEEEnable: 37223 case bcmPortControlEEETransmitIdleTime: 37224 case bcmPortControlEEETransmitEventCount: 37225 case bcmPortControlEEETransmitDuration: 37226 case bcmPortControlEEEReceiveEventCount: 37227 case bcmPortControlEEEReceiveDuration: 37228 case bcmPortControlEEETransmitIdleTimeHund: 37229 case bcmPortControlEEETransmitWakeTimeHund: 37230 case bcmPortControlEEETransmitMinLPITime: 37231 case bcmPortControlEEETransmitMinLPITimeHund: 37232 if (IS_IL_PORT(unit, port)) { /* No support for IL port type */ 37233 return FALSE; 37234 } 37235 /* Fall through */ 37236 case bcmPortControlPrbsMode: 37237 case bcmPortControlPrbsPolynomial: 37238 case bcmPortControlPrbsTxEnable: 37239 case bcmPortControlPrbsRxEnable: 37240 case bcmPortControlPrbsTxInvertData: 37241 case bcmPortControlPrbsRxStatus: 37242 case bcmPortControlLanes: 37243 return TRUE; 37244 37245 default: 37246 return FALSE; 37247 } 37248 } 37249 #endif /* BCM_SHADOW_SUPPORT */ 37250 37251 static int 37252 _bcm_esw_mac_rx_control(int unit, bcm_port_t port, uint8 optype, int *enable) 37253 { 37254 int rv = BCM_E_NONE; 37255 37256 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 37257 return(bcmi_esw_portctrl_mac_rx_control(unit, port, optype, enable)); 37258 } else { 37259 PORT_LOCK(unit); 37260 if (optype) { /* get */ 37261 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 37262 SOC_MAC_CONTROL_RX_SET, enable); 37263 } else { /* set */ 37264 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 37265 SOC_MAC_CONTROL_RX_SET, *enable); 37266 } 37267 PORT_UNLOCK(unit); 37268 } 37269 return rv; 37270 } 37271 /* 37272 * Function: 37273 * bcm_esw_port_enqueue_set 37274 * Description: 37275 * This function enable and disable the enqueuing 37276 * packets on a port 37277 * Parameters: 37278 * unit - (IN) Device number 37279 * port - (IN) Port to resolve 37280 * enable - (IN) TRUE to enable enqueuing 37281 * FALSE to disable enqueuing 37282 * Return Value: 37283 * BCM_E_XXX 37284 */ 37285 37286 static int 37287 bcm_esw_port_enqueue_set(int unit, bcm_port_t port,int enable) 37288 { 37289 int rv = BCM_E_NONE; 37290 37291 /* Make sure port module is initialized. */ 37292 PORT_INIT(unit); 37293 37294 #ifdef BCM_TRIDENT3_SUPPORT 37295 if (SOC_IS_TRIDENT3X(unit)) { 37296 int link; 37297 rv = bcm_esw_port_link_status_get(unit, port, &link); 37298 if (BCM_FAILURE(rv)) { 37299 return rv; 37300 } 37301 if (link == BCM_PORT_LINK_STATUS_UP) { 37302 /* FALSE to disable enqueuing and MMU cells drain */ 37303 PORT_LOCK(unit); 37304 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 37305 rv = bcmi_esw_portctrl_mac_enable_set(unit, port, enable); 37306 } else { 37307 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, enable); 37308 } 37309 if (BCM_FAILURE(rv)) { 37310 PORT_UNLOCK(unit); 37311 return rv; 37312 } 37313 PORT_UNLOCK(unit); 37314 } 37315 } else 37316 #endif 37317 #ifdef BCM_TOMAHAWK_SUPPORT 37318 if (SOC_IS_TOMAHAWKX(unit)) { 37319 int link; 37320 rv = bcm_esw_port_link_status_get(unit, port, &link); 37321 if (BCM_FAILURE(rv)) { 37322 return rv; 37323 } 37324 if (link == BCM_PORT_LINK_STATUS_UP || SOC_FAST_REBOOT(unit)) { 37325 /* FALSE to disable enqueuing and MMU cells drain */ 37326 PORT_LOCK(unit); 37327 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 37328 rv = bcmi_esw_portctrl_mac_enable_set(unit, port, enable); 37329 } else { 37330 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, enable); 37331 } 37332 if (BCM_FAILURE(rv)) { 37333 PORT_UNLOCK(unit); 37334 return rv; 37335 } 37336 PORT_UNLOCK(unit); 37337 } 37338 } else 37339 #endif 37340 #ifdef BCM_MONTEREY_SUPPORT 37341 if (SOC_IS_MONTEREY(unit)) { 37342 BCM_IF_ERROR_RETURN 37343 (_bcm_mn_port_enqueue_set(unit,port,enable)); 37344 } else 37345 #endif 37346 #ifdef BCM_APACHE_SUPPORT 37347 if (SOC_IS_APACHE(unit)) { 37348 BCM_IF_ERROR_RETURN 37349 (_bcm_ap_port_enqueue_set(unit,port,enable)); 37350 } else 37351 #endif 37352 #ifdef BCM_TRIDENT2_SUPPORT 37353 if (SOC_IS_TD2_TT2(unit)) { 37354 BCM_IF_ERROR_RETURN 37355 (_bcm_td2_port_enqueue_set(unit,port,enable)); 37356 } else 37357 #endif 37358 #ifdef BCM_TRIDENT_SUPPORT 37359 if (SOC_IS_TD_TT(unit)) { 37360 BCM_IF_ERROR_RETURN 37361 (_bcm_td_port_enqueue_set(unit,port,enable)); 37362 } else 37363 #endif 37364 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) 37365 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_HELIX4(unit)) { 37366 BCM_IF_ERROR_RETURN 37367 (_bcm_tr3_port_enqueue_set(unit,port,enable)); 37368 } else 37369 #endif /* BCM_TRIUMPH3_SUPPORT */ 37370 #ifdef BCM_KATANA2_SUPPORT 37371 if (SOC_IS_KATANA2(unit)) { 37372 BCM_IF_ERROR_RETURN 37373 (_bcm_kt2_port_enqueue_set(unit,port,enable)); 37374 } else 37375 #endif 37376 { 37377 return BCM_E_UNAVAIL; 37378 } 37379 return rv; 37380 } 37381 37382 /* 37383 * Function: 37384 * bcm_esw_port_enqueue_get 37385 * Description: 37386 * This function get enqueuing state 37387 * packets on a port 37388 * Parameters: 37389 * unit - (IN) Device number 37390 * port - (IN) Port to resolve 37391 * enable - (OUT) TRUE to when enqueuing is enabled 37392 * FALSE to when enqueuing is disabled 37393 * Return Value: 37394 * BCM_E_XXX 37395 */ 37396 static int 37397 bcm_esw_port_enqueue_get(int unit, bcm_port_t port, int *enable) 37398 { 37399 int rv = BCM_E_NONE; 37400 37401 /* Make sure port module is initialized. */ 37402 PORT_INIT(unit); 37403 37404 #ifdef BCM_TRIDENT3_SUPPORT 37405 if (SOC_IS_TRIDENT3X(unit)) { 37406 BCM_IF_ERROR_RETURN 37407 (_bcm_td3_port_enable_get(unit, port, enable)); 37408 } else 37409 #endif 37410 #ifdef BCM_TOMAHAWK_SUPPORT 37411 if (SOC_IS_TOMAHAWKX(unit)) { 37412 BCM_IF_ERROR_RETURN 37413 (_bcm_th_port_enqueue_get(unit, port, enable)); 37414 } else 37415 #endif 37416 #ifdef BCM_APACHE_SUPPORT 37417 if (SOC_IS_APACHE(unit)) { 37418 BCM_IF_ERROR_RETURN 37419 (_bcm_ap_port_enqueue_get(unit,port,enable)); 37420 } else 37421 #endif 37422 #ifdef BCM_TRIDENT2_SUPPORT 37423 if (SOC_IS_TD2_TT2(unit)) { 37424 BCM_IF_ERROR_RETURN 37425 (_bcm_td2_port_enqueue_get(unit,port,enable)); 37426 } else 37427 #endif 37428 #ifdef BCM_TRIDENT_SUPPORT 37429 if (SOC_IS_TD_TT(unit)) { 37430 BCM_IF_ERROR_RETURN 37431 (_bcm_td_port_enqueue_get(unit,port,enable)); 37432 } else 37433 #endif 37434 { 37435 return BCM_E_UNAVAIL; 37436 } 37437 return rv; 37438 } 37439 37440 /* 37441 * Function: 37442 * bcm_esw_port_drain_cells 37443 * Description:i 37444 * This function will drains the MMU cells which the port 37445 * is holding 37446 * Parameters: 37447 * unit - (IN) Device number 37448 * port - (IN) Port to resolve 37449 * value - (IN) TRUE to drain the cells 37450 * FALSE to just ignore 37451 * Return Value: 37452 * BCM_E_XXX 37453 */ 37454 static int 37455 bcm_esw_port_drain_cells(int unit, bcm_port_t port, int value) 37456 { 37457 int rv = BCM_E_NONE; 37458 37459 /* Make sure port module is initialized. */ 37460 PORT_INIT(unit); 37461 if (value == FALSE ) { 37462 return rv; 37463 } 37464 #ifdef BCM_TRIDENT3_SUPPORT 37465 if (SOC_IS_TRIDENT3X(unit)) { 37466 if (IS_CPU_PORT(unit, port)) { 37467 return BCM_E_PORT; 37468 } 37469 /* MMU cells were drained when enqueuing is disabled */ 37470 return rv; 37471 } else 37472 #endif 37473 #ifdef BCM_TOMAHAWK_SUPPORT 37474 if (SOC_IS_TOMAHAWKX(unit)) { 37475 if (IS_CPU_PORT(unit, port)) { 37476 return BCM_E_PORT; 37477 } 37478 /* MMU cells were drained when enqueuing is disabled */ 37479 return rv; 37480 37481 } else 37482 #endif 37483 #ifdef BCM_MONTEREY_SUPPORT 37484 if (SOC_IS_MONTEREY(unit)) { 37485 BCM_IF_ERROR_RETURN 37486 (bcm_monterey_port_drain_cells(unit, port)); 37487 } else 37488 #endif 37489 #ifdef BCM_APACHE_SUPPORT 37490 if (SOC_IS_APACHE(unit)) { 37491 BCM_IF_ERROR_RETURN 37492 (bcm_apache_port_drain_cells(unit, port)); 37493 } else 37494 #endif 37495 #ifdef BCM_TRIDENT2_SUPPORT 37496 if (SOC_IS_TD2_TT2(unit)) { 37497 BCM_IF_ERROR_RETURN 37498 (bcm_td2_port_drain_cells(unit, port)); 37499 } else 37500 #endif 37501 #ifdef BCM_TRIDENT_SUPPORT 37502 if (SOC_IS_TD_TT(unit)) { 37503 BCM_IF_ERROR_RETURN 37504 (bcm_td_port_drain_cells(unit, port)); 37505 } else 37506 #endif 37507 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) 37508 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_HELIX4(unit)) { 37509 BCM_IF_ERROR_RETURN 37510 (bcm_tr3_port_drain_cells(unit, port)); 37511 } else 37512 #endif /* BCM_TRIUMPH3_SUPPORT */ 37513 #ifdef BCM_KATANA2_SUPPORT 37514 if (SOC_IS_KATANA2(unit)) { 37515 BCM_IF_ERROR_RETURN 37516 (bcm_kt2_port_drain_cells(unit, port)); 37517 } else 37518 #endif 37519 37520 { 37521 return BCM_E_UNAVAIL; 37522 } 37523 return rv; 37524 } 37525 37526 /* 37527 * Function: 37528 * _bcm_esw_port_llfc_set 37529 * Description: 37530 * This function will set the LLFC_RX/TX_ENABLE field, 37531 * and LLFC_EN field can possibly be set accordingly. 37532 * Parameters: 37533 * unit - (IN) Device number 37534 * port - (IN) Port to resolve 37535 * type - (IN) Enum value of the feature 37536 * value - (IN) Value to be set 37537 * Return Value: 37538 * BCM_E_XXX 37539 */ 37540 STATIC int 37541 _bcm_esw_port_llfc_set(int unit, bcm_port_t port, bcm_port_control_t type, int value) 37542 { 37543 int rv = BCM_E_UNAVAIL; 37544 soc_reg_t port_config; 37545 int llfc_enable; 37546 #ifdef BCM_TRIDENT2_SUPPORT 37547 uint32 rval; 37548 #endif 37549 37550 if(SOC_PORT_USE_PORTCTRL(unit, port)) { 37551 return(bcmi_esw_portctrl_llfc_set(unit,port, type, value)); 37552 } 37553 37554 switch(type) { 37555 case bcmPortControlLLFCReceive: 37556 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 37557 case bcmPortControlSAFCReceive: 37558 #endif 37559 #if defined(BCM_XGS3_SWITCH_SUPPORT) 37560 if (SOC_IS_XGS3_SWITCH(unit)) { 37561 37562 if (!SOC_PORT_VALID(unit, port)) { 37563 return BCM_E_PORT; 37564 } 37565 37566 BCM_IF_ERROR_RETURN 37567 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 37568 SOC_MAC_CONTROL_LLFC_RX_ENABLE, value)); 37569 if (value == 0) { 37570 BCM_IF_ERROR_RETURN 37571 (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 37572 SOC_MAC_CONTROL_LLFC_TX_ENABLE, 37573 &llfc_enable)); 37574 } else { 37575 llfc_enable = TRUE; 37576 } 37577 37578 if (SOC_REG_FIELD_VALID(unit, XLPORT_CONFIGr, LLFC_ENf)) { 37579 port_config = XLPORT_CONFIGr; 37580 } else if (SOC_REG_FIELD_VALID(unit, XPORT_CONFIGr, LLFC_ENf)) { 37581 port_config = XPORT_CONFIGr; 37582 } else if (SOC_REG_FIELD_VALID(unit, PORT_CONFIGr, LLFC_ENf)) { 37583 port_config = PORT_CONFIGr; 37584 } else { 37585 port_config = INVALIDr; 37586 } 37587 37588 if (port_config != INVALIDr){ 37589 BCM_IF_ERROR_RETURN 37590 (soc_reg_field32_modify(unit, port_config, port, LLFC_ENf, 37591 llfc_enable ? 1 : 0)); 37592 } 37593 37594 rv = BCM_E_NONE; 37595 } 37596 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 37597 break; 37598 case bcmPortControlLLFCTransmit: 37599 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 37600 case bcmPortControlSAFCTransmit: 37601 #endif 37602 #if defined(BCM_XGS3_SWITCH_SUPPORT) 37603 if (SOC_IS_XGS3_SWITCH(unit)) { 37604 if (!SOC_PORT_VALID(unit, port)) { 37605 return BCM_E_PORT; 37606 } 37607 37608 BCM_IF_ERROR_RETURN 37609 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 37610 SOC_MAC_CONTROL_LLFC_TX_ENABLE, value)); 37611 if (value == 0) { 37612 BCM_IF_ERROR_RETURN 37613 (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 37614 SOC_MAC_CONTROL_LLFC_RX_ENABLE, 37615 &llfc_enable)); 37616 } else { 37617 llfc_enable = TRUE; 37618 } 37619 37620 if (SOC_REG_FIELD_VALID(unit, XLPORT_CONFIGr, LLFC_ENf)) { 37621 port_config = XLPORT_CONFIGr; 37622 } else if (SOC_REG_FIELD_VALID(unit, XPORT_CONFIGr, LLFC_ENf)) { 37623 port_config = XPORT_CONFIGr; 37624 } else if (SOC_REG_FIELD_VALID(unit, PORT_CONFIGr, LLFC_ENf)) { 37625 port_config = PORT_CONFIGr; 37626 } else { 37627 port_config = INVALIDr; 37628 } 37629 37630 if (port_config != INVALIDr){ 37631 BCM_IF_ERROR_RETURN 37632 (soc_reg_field32_modify(unit, port_config, port, LLFC_ENf, 37633 llfc_enable ? 1 : 0)); 37634 } 37635 37636 #ifdef BCM_TRIDENT2_SUPPORT 37637 if (SOC_IS_TD2_TT2(unit)) { 37638 SOC_IF_ERROR_RETURN 37639 (soc_reg32_get(unit, THDI_INPUT_PORT_XON_ENABLESr, 37640 port, 0, &rval)); 37641 37642 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 37643 PORT_PRI_XON_ENABLEf, 37644 value ? 0xffff : 0); 37645 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 37646 PORT_PAUSE_ENABLEf, value ? 0 : 1); 37647 37648 SOC_IF_ERROR_RETURN 37649 (soc_reg32_set(unit, THDI_INPUT_PORT_XON_ENABLESr, 37650 port, 0, rval)); 37651 } 37652 #endif 37653 37654 rv = BCM_E_NONE; 37655 } 37656 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 37657 break; 37658 default: 37659 break; 37660 } 37661 37662 return rv; 37663 } 37664 37665 /* 37666 * Function: 37667 * _bcm_esw_port_llfc_get 37668 * Description: 37669 * This function will get the LLFC_TX/RX_ENABLE field. 37670 * Parameters: 37671 * unit - (IN) Device number 37672 * port - (IN) Port to resolve 37673 * type - (IN) Enum value of the feature 37674 * value - (OUT) Current value of the port feature 37675 * Return Value: 37676 * BCM_E_XXX 37677 */ 37678 STATIC int 37679 _bcm_esw_port_llfc_get(int unit, bcm_port_t port, bcm_port_control_t type, int *value) 37680 { 37681 int rv = BCM_E_UNAVAIL; 37682 37683 if(SOC_PORT_USE_PORTCTRL(unit, port)) { 37684 return(bcmi_esw_portctrl_llfc_get(unit,port, type, value)); 37685 } 37686 37687 switch(type) { 37688 case bcmPortControlLLFCReceive: 37689 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 37690 case bcmPortControlSAFCReceive: 37691 #endif 37692 #if defined(BCM_XGS3_SWITCH_SUPPORT) 37693 if (SOC_IS_XGS3_SWITCH(unit)) { 37694 if (!SOC_PORT_VALID(unit, port)) { 37695 return BCM_E_PORT; 37696 } 37697 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 37698 SOC_MAC_CONTROL_LLFC_RX_ENABLE, value); 37699 } 37700 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 37701 break; 37702 case bcmPortControlLLFCTransmit: 37703 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 37704 case bcmPortControlSAFCTransmit: 37705 #endif 37706 #if defined(BCM_XGS3_SWITCH_SUPPORT) 37707 if (SOC_IS_XGS3_SWITCH(unit)) { 37708 if (!SOC_PORT_VALID(unit, port)) { 37709 return BCM_E_PORT; 37710 } 37711 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 37712 SOC_MAC_CONTROL_LLFC_TX_ENABLE, value); 37713 } 37714 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 37715 break; 37716 default: 37717 break; 37718 } 37719 37720 return rv; 37721 } 37722 37723 #ifdef BCM_TRIUMPH3_SUPPORT 37724 STATIC int 37725 _bcm_tr3_port_lanes_set(int unit, bcm_port_t port, int value) 37726 { 37727 int i, incr = 1, ports = 3, okay; 37728 int rv = BCM_E_NONE, rv1, old_value; 37729 int retry_count = 0, mode_change = -1; 37730 uint16 phy; 37731 uint32 flags; 37732 soc_info_t *si = &SOC_INFO(unit); 37733 int phy_port = -1; 37734 int old_port[4]; 37735 if (!SOC_PORT_VALID(unit, port)) { 37736 return BCM_E_PORT; 37737 } 37738 37739 /* coverity[overrun-local : FALSE] */ 37740 phy_port = si->port_l2p_mapping[port]; 37741 for (i = 0; i < 4; i++) { 37742 old_port[i] = si->flex_port_p2l_mapping[phy_port+i]; 37743 } 37744 37745 _reconfig: 37746 rv = soc_tr3_port_lanes_set(unit, port, value, &old_value, &mode_change); 37747 if (rv != SOC_E_NONE) { 37748 return rv; 37749 } 37750 if (value == 1) { 37751 #ifdef BCM_HELIX4_SUPPORT 37752 /* coverity[overrun-local : FALSE] */ 37753 if (SOC_IS_HELIX4(unit) && ((_tr3_port_config_id[unit] == 410) && 37754 (si->port_l2p_mapping[port] == 57 || si->port_l2p_mapping[port] == 61))){ 37755 ports = 1; 37756 }else if(SOC_IS_HELIX4(unit) && (((_tr3_port_config_id[unit] == 463) || 37757 (_tr3_port_config_id[unit] == 413)) && (si->port_l2p_mapping[port] == 57 || 37758 si->port_l2p_mapping[port] == 61))){ 37759 ports = 2; 37760 } 37761 else 37762 #endif 37763 /* coverity[overrun-local : FALSE] */ 37764 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) && 37765 ((_tr3_port_config_id[unit] == 112 || _tr3_port_config_id[unit] == 12) && 37766 (si->port_l2p_mapping[port] == 73 || si->port_l2p_mapping[port] == 77))) { 37767 ports = 1; 37768 } else { 37769 ports = 4; 37770 } 37771 } else if (value == 2) { 37772 #ifdef BCM_HELIX4_SUPPORT 37773 if(SOC_IS_HELIX4(unit) &&((_tr3_port_config_id[unit] == 463) || 37774 _tr3_port_config_id[unit] == 413) && (si->port_l2p_mapping[port] == 57 || 37775 si->port_l2p_mapping[port] == 61)){ 37776 ports = 1; 37777 incr = 2; 37778 } 37779 else 37780 #endif 37781 { 37782 incr = 2; 37783 } 37784 } else if (value == 4) { 37785 ports = 1; 37786 } 37787 if (value == 2 && old_value == 1) { 37788 #ifdef BCM_HELIX4_SUPPORT 37789 if(SOC_IS_HELIX4(unit) && (((_tr3_port_config_id[unit] == 463) || 37790 (_tr3_port_config_id[unit] == 413)) && (si->port_l2p_mapping[port] == 57 || 37791 si->port_l2p_mapping[port] == 61))){ 37792 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, si->port_p2l_mapping[si->port_l2p_mapping[port] + 1])); 37793 }else 37794 #endif 37795 { 37796 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 1)); 37797 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 3)); 37798 } 37799 } else if (value == 4 && old_value == 1) { 37800 if ((SOC_IS_HELIX4(unit) && (_tr3_port_config_id[unit] == 410)) || 37801 (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) && 37802 (_tr3_port_config_id[unit] == 112 || _tr3_port_config_id[unit] == 12))){ 37803 if (old_port[1] > 0) { 37804 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, old_port[1])); 37805 } 37806 if (old_port[2] > 0) { 37807 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, old_port[2])); 37808 } 37809 if (old_port[3] > 0) { 37810 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, old_port[3])); 37811 } 37812 } else { 37813 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 1)); 37814 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 2)); 37815 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 3)); 37816 } 37817 } else if (value == 4 && old_value == 2) { 37818 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 2)); 37819 } 37820 for (i = 0; i < ports; i+=incr) { 37821 flags = 0; 37822 phy = soc_property_port_get(unit, port + i, spn_FLEX_PORT_PHY_ADDR, 0); 37823 if (!phy) { 37824 SOC_IF_ERROR_RETURN(soc_tr3_phy_addr_get(unit, port + i, &phy)); 37825 flags = _SHR_PORT_PHY_INTERNAL; 37826 } 37827 SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port + i, flags, phy)); 37828 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port + i, &okay)); 37829 LOG_VERBOSE(BSL_LS_BCM_PORT, 37830 (BSL_META_U(unit, 37831 "Port %d probe: %d\n"), port + i, okay)); 37832 if (!okay) { 37833 return BCM_E_INTERNAL; 37834 } 37835 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port + i, TRUE)); 37836 } 37837 #ifdef BCM_WARM_BOOT_SUPPORT 37838 if (SOC_WARM_BOOT(unit)) { 37839 return rv; 37840 } 37841 #endif /* BCM_WARM_BOOT_SUPPORT */ 37842 37843 for (i = 0; i < ports; i+=incr) { 37844 if (SOC_PBMP_MEMBER(si->port.disabled_bitmap, port+i)) { 37845 continue; 37846 } 37847 rv1 = _bcm_tr3_port_ur_chk(unit, ports, port + i); 37848 if (rv1 == BCM_E_PORT) { 37849 /* Error encountered in the newly created flex ports. 37850 Lets revert back to old mode and retry if retry count not exceeded */ 37851 if (++retry_count > _BCM_TR3_PORT_UR_RETRY_MAX) { 37852 return BCM_E_INTERNAL; 37853 } 37854 rv = soc_tr3_port_lanes_set(unit, port, old_value, &old_value, &mode_change); 37855 if (rv != SOC_E_NONE) { 37856 return rv; 37857 } 37858 goto _reconfig; 37859 } 37860 if (rv1 != BCM_E_NONE) { 37861 return rv1; 37862 } 37863 } 37864 37865 /* Note: Following is currently a brute force solution */ 37866 for (i = 0; i < ports; i+=incr) { 37867 if (mode_change == BCM_PORT_ENCAP_HIGIG) { 37868 /* coverity[overrun-call : FALSE] */ 37869 BCM_IF_ERROR_RETURN 37870 (_bcm_port_encap_xport_set(unit, port + i, BCM_PORT_ENCAP_HIGIG, 37871 TRUE)); 37872 } else if (mode_change == BCM_PORT_ENCAP_IEEE) { 37873 /* coverity[overrun-call : FALSE] */ 37874 BCM_IF_ERROR_RETURN 37875 (_bcm_port_encap_xport_set(unit, port + i, BCM_PORT_ENCAP_IEEE, 37876 TRUE)); 37877 } 37878 } 37879 return rv; 37880 } 37881 37882 STATIC int 37883 _bcm_tr3_port_lanes_get(int unit, bcm_port_t port, int *value) 37884 { 37885 int rv = BCM_E_NONE; 37886 if (!SOC_PORT_VALID(unit, port)) { 37887 return BCM_E_PORT; 37888 } 37889 rv = soc_tr3_port_lanes_get(unit, port, value); 37890 return rv; 37891 } 37892 #endif /* BCM_TRIUMPH3_SUPPORT */ 37893 37894 #ifdef BCM_TRIDENT_SUPPORT 37895 STATIC int 37896 _bcm_td_port_lanes_set(int unit, bcm_port_t port, int value) 37897 { 37898 soc_info_t *si; 37899 int rv, okay, i; 37900 uint32 rval, phy_mode, core_mode; 37901 uint32 reset_status; 37902 bcm_port_t phy_port; 37903 37904 rv = READ_XLPORT_MODE_REGr(unit, port, &rval); 37905 if (BCM_SUCCESS(rv)) { 37906 phy_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, 37907 PHY_PORT_MODEf); 37908 core_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, 37909 CORE_PORT_MODEf); 37910 if (phy_mode == 0) { /* single mode */ 37911 /* Case of 40G port --> 10G XFI */ 37912 if (value == 1) { 37913 SOC_INFO(unit).port_speed_max[port]=10000; 37914 } else if (value == 2) { 37915 /* Case of single mode --> dual mode */ 37916 SOC_INFO(unit).port_speed_max[port]=20000; 37917 core_mode = 1; 37918 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, CORE_PORT_MODEf, core_mode); 37919 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval)); 37920 } 37921 } else if (phy_mode == 1) { /* dual mode */ 37922 if (value != 2 && value != 4) { 37923 rv = BCM_E_PARAM; 37924 } else if (value == 4) { 37925 /* Case of dual mode --> single mode */ 37926 core_mode = 0; 37927 SOC_INFO(unit).port_speed_max[port]=40000; 37928 } else { 37929 /* case of 20G single mode --> 20G dual mode */ 37930 core_mode = 1; 37931 } 37932 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, CORE_PORT_MODEf, core_mode); 37933 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval)); 37934 } else { /* phy_mode == 2 */ 37935 if (value == 4) { 37936 /* 10G XFI --> 10G XAUI or 10G XFI --> 40G */ 37937 if (core_mode == 0) { 37938 /* 10GXFI --> 40G */ 37939 SOC_INFO(unit).port_speed_max[port]=40000; 37940 } 37941 } 37942 } 37943 } 37944 if (BCM_SUCCESS(rv)) { 37945 si = &SOC_INFO(unit); 37946 phy_port = si->port_l2p_mapping[port]; 37947 for (i = 0; i < value; i++) { 37948 if ((si->port_p2l_mapping[phy_port + i]) == -1) { 37949 continue; 37950 } 37951 rv = soc_phyctrl_detach 37952 (unit, si->port_p2l_mapping[phy_port + i]); 37953 if (BCM_FAILURE(rv)) { 37954 break; 37955 } 37956 } 37957 } 37958 if (BCM_SUCCESS(rv)) { 37959 si = &SOC_INFO(unit); 37960 si->port_num_lanes[port] = value; 37961 if (BCM_SUCCESS(rv)) { 37962 rv = _bcm_port_phy_probe(unit, port, &okay); 37963 } 37964 } 37965 37966 /* Do XMAC reset when port mode is changed */ 37967 SOC_IF_ERROR_RETURN(READ_XLPORT_XMAC_CONTROLr(unit, port, &rval)); 37968 reset_status = soc_reg_field_get(unit, XLPORT_XMAC_CONTROLr, rval, XMAC_RESETf); 37969 if (reset_status != 1) { 37970 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1); 37971 SOC_IF_ERROR_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval)); 37972 sal_udelay(10); 37973 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0); 37974 SOC_IF_ERROR_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval)); 37975 } 37976 37977 return rv; 37978 } 37979 #endif /* BCM_TRIDENT_SUPPORT */ 37980 37981 #ifdef BCM_TRIDENT2_SUPPORT 37982 STATIC int 37983 _bcm_td2_port_lanes_set(int unit, bcm_port_t port_base, int lanes) 37984 { 37985 soc_info_t *si = &SOC_INFO(unit); 37986 soc_td2_port_lanes_t lanes_ctrl; 37987 int port, i; 37988 int enable, okay; 37989 soc_control_t *soc = SOC_CONTROL(unit); 37990 37991 if(SOC_PORT_USE_PORTCTRL(unit, port_base)) { 37992 return(bcmi_esw_td2_portctrl_lanes_set(unit, port_base, lanes)); 37993 } 37994 37995 sal_memset(&lanes_ctrl, 0, sizeof(lanes_ctrl)); 37996 lanes_ctrl.port_base = port_base; 37997 lanes_ctrl.lanes = lanes; 37998 SOC_IF_ERROR_RETURN 37999 (soc_trident2_port_lanes_validate(unit, &lanes_ctrl)); 38000 38001 if (lanes_ctrl.lanes == lanes_ctrl.cur_lanes) { 38002 return BCM_E_NONE; 38003 } 38004 38005 /* All existing ports are required to be disasbled */ 38006 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port_base, &enable)); 38007 if (enable) { 38008 return BCM_E_BUSY; 38009 } 38010 if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */ 38011 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 38012 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 38013 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable)); 38014 if (enable) { 38015 return BCM_E_BUSY; 38016 } 38017 } 38018 } 38019 38020 SOC_IF_ERROR_RETURN 38021 (soc_trident2_port_lanes_set(unit, &lanes_ctrl)); 38022 38023 /* Detach PHY on all existing port(s) */ 38024 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port_base)); 38025 if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */ 38026 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 38027 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 38028 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port)); 38029 COUNTER_LOCK(unit); 38030 SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, port); 38031 COUNTER_UNLOCK(unit); 38032 } 38033 } 38034 /* Probe PHY on all port(s) after conversion */ 38035 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port_base, &okay)); 38036 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port_base, FALSE)); 38037 if (lanes_ctrl.lanes < lanes_ctrl.cur_lanes) { /* port(s) to be added */ 38038 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 38039 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 38040 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay)); 38041 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, FALSE)); 38042 COUNTER_LOCK(unit); 38043 SOC_PBMP_PORT_ADD(soc->counter_pbmp, port); 38044 COUNTER_UNLOCK(unit); 38045 } 38046 } 38047 38048 return BCM_E_NONE; 38049 } 38050 #endif /* BCM_TRIDENT2_SUPPORT */ 38051 38052 #ifdef BCM_TOMAHAWK_SUPPORT 38053 STATIC int 38054 _bcm_th_port_lanes_set(int unit, bcm_port_t port_base, int lanes) 38055 { 38056 soc_info_t *si = &SOC_INFO(unit); 38057 soc_control_t *soc = SOC_CONTROL(unit); 38058 soc_th_port_lanes_t lanes_ctrl; 38059 int port, i; 38060 int enable, okay; 38061 int speed; 38062 38063 sal_memset(&lanes_ctrl, 0, sizeof(lanes_ctrl)); 38064 lanes_ctrl.port_base = port_base; 38065 lanes_ctrl.lanes = lanes; 38066 38067 /* All existing ports are required to be disabled */ 38068 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port_base, &enable)); 38069 if (enable) { 38070 return BCM_E_PORT; 38071 } 38072 SOC_IF_ERROR_RETURN 38073 (soc_tomahawk_port_lanes_validate(unit, &lanes_ctrl)); 38074 if (lanes_ctrl.lanes == lanes_ctrl.cur_lanes) { 38075 return BCM_E_NONE; 38076 } 38077 38078 if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */ 38079 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 38080 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 38081 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable)); 38082 if (enable) { 38083 return BCM_E_PORT; 38084 } 38085 } 38086 } 38087 38088 SOC_IF_ERROR_RETURN 38089 (soc_tomahawk_port_lanes_set(unit, &lanes_ctrl)); 38090 SOC_IF_ERROR_RETURN 38091 (soc_tomahawk_port_lanes_consolidation(unit, &lanes_ctrl)); 38092 38093 /* Detach PHY on all existing port(s) */ 38094 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port_base)); 38095 if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */ 38096 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 38097 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 38098 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port)); 38099 COUNTER_LOCK(unit); 38100 SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, port); 38101 COUNTER_UNLOCK(unit); 38102 } 38103 } 38104 38105 /* Probe PHY on all port(s) after conversion */ 38106 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port_base, &okay)); 38107 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port_base, FALSE)); 38108 if (lanes_ctrl.lanes < lanes_ctrl.cur_lanes) { /* port(s) to be added */ 38109 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 38110 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 38111 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay)); 38112 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, FALSE)); 38113 COUNTER_LOCK(unit); 38114 SOC_PBMP_PORT_ADD(soc->counter_pbmp, port); 38115 COUNTER_UNLOCK(unit); 38116 } 38117 } 38118 38119 /* Update port ASF setting to SAF */ 38120 /* Base Port */ 38121 speed = si->port_init_speed[port_base]; 38122 BCM_IF_ERROR_RETURN(soc_th_port_asf_mode_set 38123 (unit, port_base, speed, _SOC_TH_ASF_MODE_SAF)); 38124 /* Newly added ports */ 38125 if (lanes_ctrl.lanes < lanes_ctrl.cur_lanes) { /* port(s) to be added */ 38126 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 38127 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 38128 speed = si->port_init_speed[port]; 38129 BCM_IF_ERROR_RETURN(soc_th_port_asf_mode_set 38130 (unit, port, speed, _SOC_TH_ASF_MODE_SAF)); 38131 } 38132 } 38133 38134 return BCM_E_NONE; 38135 } 38136 #endif /* BCM_TOMAHAWK_SUPPORT */ 38137 38138 #ifdef BCM_HURRICANE2_SUPPORT 38139 STATIC int 38140 _bcm_hu2_port_lanes_set(int unit, bcm_port_t port_base, int lanes) 38141 { 38142 soc_info_t *si = &SOC_INFO(unit); 38143 int cur_lanes; 38144 int port, phy_ports[3], phy_ports_len, i; 38145 int okay; 38146 38147 SOC_IF_ERROR_RETURN 38148 (soc_hurricane2_port_lanes_set(unit, port_base, lanes, &cur_lanes, 38149 phy_ports, &phy_ports_len)); 38150 if (lanes == cur_lanes) { 38151 return BCM_E_NONE; 38152 } 38153 38154 if (lanes > cur_lanes) { /* port(s) to be removed */ 38155 for (i = 0; i < phy_ports_len; i++) { 38156 port = si->port_p2l_mapping[phy_ports[i]]; 38157 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port)); 38158 } 38159 } 38160 38161 /* The specified port */ 38162 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port_base, &okay)); 38163 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port_base, TRUE)); 38164 38165 if (lanes < cur_lanes) { /* port(s) to be added */ 38166 for (i = 0; i < phy_ports_len; i++) { 38167 port = si->port_p2l_mapping[phy_ports[i]]; 38168 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay)); 38169 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, TRUE)); 38170 } 38171 } 38172 38173 return BCM_E_NONE; 38174 } 38175 #endif 38176 38177 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 38178 int 38179 _bcm_sc_tr_port_pfc_tx_set(int unit, bcm_port_t port, uint32 pri_bmp) 38180 { 38181 int pfc_enable; 38182 uint32 rval; 38183 int value, val_count = 0; 38184 soc_reg_t reg; 38185 uint32 values[2]; 38186 int chk_gx_port = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 38187 SOC_IS_VALKYRIE2(unit) || SOC_IS_SCORPION(unit)); 38188 soc_field_t fields[] = {PFC_ENABLEf, LLFC_ENf}; 38189 38190 if (!soc_feature(unit, soc_feature_priority_flow_control)) { 38191 return BCM_E_UNAVAIL; 38192 } 38193 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 38194 if (chk_gx_port && !IS_GX_PORT(unit, port)) { /* IS_GX_PORT == IS_XL_PORT */ 38195 return BCM_E_PORT; 38196 } 38197 if (pri_bmp >= (1U << 16)) { 38198 return BCM_E_PARAM; 38199 } 38200 38201 value = (pri_bmp == 0)? 0 : 1; 38202 BCM_IF_ERROR_RETURN 38203 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 38204 SOC_MAC_CONTROL_PFC_TX_ENABLE, value)); 38205 if (value == 0) { 38206 BCM_IF_ERROR_RETURN 38207 (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 38208 SOC_MAC_CONTROL_PFC_RX_ENABLE, 38209 &pfc_enable)); 38210 } else { 38211 pfc_enable = TRUE; 38212 } 38213 38214 if (!soc_feature(unit, soc_feature_mmu_config_property)) { 38215 rval = 0; 38216 if (SOC_REG_IS_VALID(unit,PORT_PRI_XON_ENABLEr)) { 38217 if (value) { 38218 soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval, 38219 PORT_PRI_XON_ENABLEf, 0xff); 38220 if (soc_reg_field_valid(unit, PORT_PRI_XON_ENABLEr, 38221 PORT_PG7PAUSE_DISABLEf)) { 38222 soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval, 38223 PORT_PG7PAUSE_DISABLEf, 1); 38224 } 38225 } 38226 BCM_IF_ERROR_RETURN 38227 (WRITE_PORT_PRI_XON_ENABLEr(unit, port, rval)); 38228 } 38229 } else if (SOC_IS_TRIDENT(unit)) { 38230 rval = 0; 38231 if (SOC_REG_IS_VALID(unit,PORT_PRI_XON_ENABLEr)) { 38232 if(value) { 38233 /* Get flow_control_enable info from mmu config 38234 * property for each priority group, and enable 38235 * generation of XON/XOFF for priority group 38236 * accordingly. */ 38237 int idx = 0, prifc_en = 0, fval = 0; 38238 char suffix; 38239 for(idx = 0; idx < 8; idx ++) { 38240 /* By default, enable generation of XON and XOFF 38241 * LLFC messages for priority 7 */ 38242 prifc_en = (idx == 7) ? 1 : 0; 38243 prifc_en = soc_property_port_obj_attr_get(unit, 38244 port, spn_BUF, spn_PRIGROUP, 38245 idx, spn_FLOW_CONTROL_ENABLE, 38246 0, &suffix, prifc_en); 38247 if(prifc_en != 0) { 38248 fval |= (1 << idx); 38249 } 38250 } 38251 soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval, 38252 PORT_PRI_XON_ENABLEf, fval); 38253 } 38254 /* When disable PFC on port, generation of XON/XOFF 38255 * for all priority groups must be disabled also. */ 38256 BCM_IF_ERROR_RETURN 38257 (WRITE_PORT_PRI_XON_ENABLEr(unit, port, rval)); 38258 } 38259 } 38260 38261 /* Port config settings */ 38262 values[0] = pfc_enable ? 1 : 0; 38263 values[1] = 0; 38264 38265 if (SOC_IS_TD2_TT2(unit)) { 38266 #ifdef BCM_TOMAHAWK3_SUPPORT 38267 if(SOC_IS_TOMAHAWK3(unit)) { 38268 SOC_IF_ERROR_RETURN 38269 (bcm_th3_mmu_pfc_tx_config_set(unit, port, 38270 pfc_enable, pri_bmp)); 38271 } else 38272 #endif 38273 { 38274 SOC_IF_ERROR_RETURN 38275 (soc_reg32_get(unit, THDI_INPUT_PORT_XON_ENABLESr, 38276 port, 0, &rval)); 38277 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 38278 PORT_PRI_XON_ENABLEf, 38279 pfc_enable ? pri_bmp : 0); 38280 38281 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 38282 PORT_PAUSE_ENABLEf, pfc_enable ? 0 : 1); 38283 SOC_IF_ERROR_RETURN 38284 (soc_reg32_set(unit, THDI_INPUT_PORT_XON_ENABLESr, 38285 port, 0, rval)); 38286 } 38287 #ifdef BCM_TOMAHAWK_SUPPORT 38288 if (SOC_IS_TOMAHAWKX(unit) && IS_CL_PORT(unit, port)) { 38289 soc_info_t *si; 38290 uint64 rval64; 38291 int phy_port_base, phy_port, lane, block_idx, pipe, clport, obm; 38292 static const soc_reg_t obm_fc_config_regs[] = { 38293 IDB_OBM0_FLOW_CONTROL_CONFIGr, IDB_OBM1_FLOW_CONTROL_CONFIGr, 38294 IDB_OBM2_FLOW_CONTROL_CONFIGr, IDB_OBM3_FLOW_CONTROL_CONFIGr, 38295 IDB_OBM4_FLOW_CONTROL_CONFIGr, IDB_OBM5_FLOW_CONTROL_CONFIGr, 38296 IDB_OBM6_FLOW_CONTROL_CONFIGr, IDB_OBM7_FLOW_CONTROL_CONFIGr, 38297 #ifdef BCM_TOMAHAWK2_SUPPORT 38298 IDB_OBM8_FLOW_CONTROL_CONFIGr, IDB_OBM9_FLOW_CONTROL_CONFIGr, 38299 IDB_OBM10_FLOW_CONTROL_CONFIGr, IDB_OBM11_FLOW_CONTROL_CONFIGr, 38300 IDB_OBM12_FLOW_CONTROL_CONFIGr, IDB_OBM13_FLOW_CONTROL_CONFIGr, 38301 IDB_OBM14_FLOW_CONTROL_CONFIGr, IDB_OBM15_FLOW_CONTROL_CONFIGr 38302 #endif 38303 }; 38304 38305 COMPILER_64_ZERO(rval64); 38306 si = &SOC_INFO(unit); 38307 phy_port = si->port_l2p_mapping[port]; 38308 phy_port_base = PORT_BLOCK_BASE_PORT(port); 38309 lane = (phy_port - phy_port_base) & 3; 38310 block_idx = SOC_PORT_IDX_BLOCK(unit, phy_port_base, 0); 38311 pipe = si->port_pipe[port]; 38312 clport = SOC_BLOCK_NUMBER(unit, block_idx); 38313 if (SOC_IS_TOMAHAWK(unit)) { 38314 /* obm number is reversed (mirrored) in odd pipe */ 38315 obm = pipe & 1 ? (7- (clport & 7)) : (clport & 7); 38316 } else { 38317 obm = clport & 15; 38318 } 38319 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_config_regs[obm])[pipe]; 38320 SOC_IF_ERROR_RETURN 38321 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 38322 soc_reg64_field32_set(unit, reg, &rval64, FC_TYPEf, pfc_enable); 38323 SOC_IF_ERROR_RETURN 38324 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 38325 } 38326 #endif /* BCM_TOMAHAWK_SUPPORT */ 38327 reg = INVALIDr; 38328 } else if (SOC_IS_TD_TT(unit)) { 38329 int mmu_port; 38330 uint64 r64val; 38331 soc_info_t *si; 38332 38333 /* disable pause if pfc is enabled, vice versa */ 38334 si = &SOC_INFO(unit); 38335 mmu_port = si->port_p2m_mapping[si->port_l2p_mapping[port]]; 38336 reg = (mmu_port < 33) ? PORT_PAUSE_ENABLE0_64r : PORT_PAUSE_ENABLE1_64r; 38337 mmu_port = (mmu_port < 33) ? mmu_port : mmu_port - 33; 38338 SOC_IF_ERROR_RETURN( 38339 soc_reg_get(unit, reg, REG_PORT_ANY, 0, &r64val)); 38340 if (value) { 38341 COMPILER_64_BITCLR(r64val, mmu_port); 38342 } else { 38343 COMPILER_64_BITSET(r64val, mmu_port); 38344 } 38345 SOC_IF_ERROR_RETURN( 38346 soc_reg_set(unit, reg, REG_PORT_ANY, 0, r64val)); 38347 38348 reg = XLPORT_CONFIGr; 38349 val_count=2; 38350 } else if (SOC_IS_SHADOW(unit)) { 38351 reg = XLPORT_CONFIGr; 38352 val_count=2; 38353 } else if (SOC_IS_TRIUMPH3(unit)) { 38354 reg = PORT_CONFIGr; 38355 val_count=2; 38356 } else if (SOC_IS_SABER2(unit)) { 38357 /* No port level config required */ 38358 reg = INVALIDr; 38359 val_count = 0; 38360 } else if (SOC_IS_KATANAX(unit)) { 38361 reg = XPORT_CONFIGr; 38362 val_count=2; 38363 } else { 38364 reg = INVALIDr; 38365 } 38366 38367 if (val_count > 0) { 38368 BCM_IF_ERROR_RETURN 38369 (soc_reg_fields32_modify(unit, reg, port, 38370 COUNTOF(values), fields, values)); 38371 } else if (SOC_IS_SC_CQ(unit) || SOC_IS_TR_VL(unit)) { 38372 if (SOC_REG_IS_VALID(unit, PPFC_ENr)) { 38373 BCM_IF_ERROR_RETURN 38374 (soc_reg_field32_modify(unit, PPFC_ENr, port, 38375 PPFC_FEATURE_ENf, 38376 pfc_enable ? 1 : 0)); 38377 } 38378 if (soc_reg_field_valid(unit, XPORT_CONFIGr, PPP_ENABLEf)) { 38379 BCM_IF_ERROR_RETURN 38380 (soc_reg_field32_modify(unit, XPORT_CONFIGr, port, 38381 PPP_ENABLEf, 38382 pfc_enable ? 1 : 0)); 38383 } 38384 } 38385 38386 /* Stats enable */ 38387 BCM_IF_ERROR_RETURN 38388 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 38389 SOC_MAC_CONTROL_PFC_STATS_ENABLE, 38390 pfc_enable ? 1 : 0)); 38391 38392 return BCM_E_NONE; 38393 } 38394 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 38395 38396 38397 /* 38398 * Function: 38399 * bcm_esw_port_control_wlan_validate 38400 * Description: 38401 * Checks that port control is valid for a WLAN GPORT. 38402 * Resolves port to expected port value for the given port control type. 38403 * Parameters: 38404 * port - (IN) Port to resolve 38405 * type - (IN) Port control type 38406 * port_out - (OUT) Returns port (gport or BCM format) that 38407 * is expected for corresponding port control type. 38408 * Return Value: 38409 * BCM_E_XXX 38410 */ 38411 STATIC int 38412 bcm_esw_port_control_wlan_validate(bcm_port_t port, 38413 bcm_port_control_t type, 38414 bcm_port_t *port_out) 38415 { 38416 int rv = BCM_E_PORT; 38417 int support = FALSE; 38418 38419 switch (type) { 38420 case bcmPortControlBridge: 38421 case bcmPortControlTrunkHashSet: 38422 case bcmPortControlFabricTrunkHashSet: 38423 case bcmPortControlECMPHashSet: 38424 case bcmPortControlLoadBalanceHashSet: 38425 case bcmPortControlLoadBalancingNumber: 38426 case bcmPortControlIP4: 38427 case bcmPortControlIP6: 38428 case bcmPortControlIP4Mcast: 38429 case bcmPortControlIP6Mcast: 38430 case bcmPortControlMpls: 38431 case bcmPortControlMacInMac: 38432 case bcmPortControlSrcBmacMissToCpu: 38433 case bcmPortControlIP4McastL2: 38434 case bcmPortControlIP6McastL2: 38435 case bcmPortControlFilterLookup: 38436 case bcmPortControlFilterIngress: 38437 case bcmPortControlPreservePacketPriority: 38438 case bcmPortControlLearnClassEnable: 38439 case bcmPortControlTrustIncomingVlan: 38440 case bcmPortControlDoNotCheckVlan: 38441 case bcmPortControlIEEE8021ASEnableIngress: 38442 case bcmPortControlIpfixRate: 38443 case bcmPortControlForwardStaticL2MovePkt: 38444 case bcmPortControlTrillHashSelect: 38445 case bcmPortControlFabricSourceKnockout: 38446 case bcmPortControlL2GreEnable: 38447 case bcmPortControlL2GreTunnelbasedVpnId: 38448 case bcmPortControlL2GreDefaultTunnelEnable: 38449 case bcmPortControlVxlanEnable: 38450 case bcmPortControlVxlanTunnelbasedVnId: 38451 case bcmPortControlVxlanDefaultTunnelEnable: 38452 case bcmPortControlRegex: 38453 case bcmPortControlRegexTcp: 38454 case bcmPortControlRegexUdp: 38455 support = TRUE; 38456 break; 38457 default: 38458 support = FALSE; 38459 break; 38460 } 38461 38462 if (support) { 38463 *port_out = port; 38464 rv = BCM_E_NONE; 38465 } 38466 38467 return rv; 38468 } 38469 38470 /* 38471 * Function: 38472 * bcm_esw_port_control_proxy_validate 38473 * Description: 38474 * Checks that port control is valid for a PROXY GPORT. 38475 * Resolves port to expected port value for the given port control type. 38476 * Parameters: 38477 * unit - (IN) Device number 38478 * port - (IN) Port to resolve 38479 * type - (IN) Port control type 38480 * port_out - (OUT) Returns port (gport or BCM format) that 38481 * is expected for corresponding port control type. 38482 * Return Value: 38483 * BCM_E_XXX 38484 */ 38485 STATIC int 38486 bcm_esw_port_control_proxy_validate(int unit, bcm_port_t port, 38487 bcm_port_control_t type, 38488 bcm_port_t *port_out) 38489 { 38490 int rv = BCM_E_PORT; 38491 int support = FALSE; 38492 38493 /* Make sure port module is initialized. */ 38494 PORT_INIT(unit); 38495 38496 if (!soc_feature(unit, soc_feature_proxy_port_property)) { 38497 return BCM_E_PORT; 38498 } 38499 38500 switch(type) { 38501 case bcmPortControlBridge: 38502 case bcmPortControlTrunkHashSet: 38503 case bcmPortControlFabricTrunkHashSet: 38504 case bcmPortControlECMPHashSet: 38505 case bcmPortControlLoadBalanceHashSet: 38506 case bcmPortControlLoadBalancingNumber: 38507 case bcmPortControlIP4: 38508 case bcmPortControlIP6: 38509 case bcmPortControlIP4Mcast: 38510 case bcmPortControlIP6Mcast: 38511 case bcmPortControlMpls: 38512 case bcmPortControlMacInMac: 38513 case bcmPortControlSrcBmacMissToCpu: 38514 case bcmPortControlIP4McastL2: 38515 case bcmPortControlIP6McastL2: 38516 case bcmPortControlFilterLookup: 38517 case bcmPortControlFilterIngress: 38518 case bcmPortControlPreservePacketPriority: 38519 case bcmPortControlLearnClassEnable: 38520 case bcmPortControlTrustIncomingVlan: 38521 case bcmPortControlDoNotCheckVlan: 38522 case bcmPortControlIEEE8021ASEnableIngress: 38523 case bcmPortControlIpfixRate: 38524 case bcmPortControlOAMEnable: 38525 case bcmPortControlForwardStaticL2MovePkt: 38526 case bcmPortControlTrill: 38527 case bcmPortControlTrillAllow: 38528 case bcmPortControlNonTrillAllow: 38529 case bcmPortControlTrillCoreISISToCPU: 38530 case bcmPortControlTrillHashSelect: 38531 case bcmPortControlNivNonVntagDrop: 38532 case bcmPortControlNonEtagDrop: 38533 case bcmPortControlNivVntagDrop: 38534 case bcmPortControlEtagDrop: 38535 case bcmPortControlNivNonVntagAdd: 38536 case bcmPortControlNonEtagAdd: 38537 case bcmPortControlNivVntagIngressReplace: 38538 case bcmPortControlEtagIngressReplace: 38539 case bcmPortControlNivVntagIngressDelete: 38540 case bcmPortControlEtagIngressDelete: 38541 case bcmPortControlNivRpfCheck: 38542 case bcmPortControlExtenderRpfCheck: 38543 case bcmPortControlNivNameSpace: 38544 case bcmPortControlExtenderNameSpace: 38545 case bcmPortControlUseEtagPri: 38546 case bcmPortControlProhibitedDot1p: 38547 case bcmPortControlFabricSourceKnockout: 38548 case bcmPortControlMplsEntropyHashSet: 38549 case bcmPortControlL2GreEnable: 38550 case bcmPortControlL2GreTunnelbasedVpnId: 38551 case bcmPortControlL2GreDefaultTunnelEnable: 38552 case bcmPortControlVxlanEnable: 38553 case bcmPortControlVxlanTunnelbasedVnId: 38554 case bcmPortControlVxlanDefaultTunnelEnable: 38555 support = TRUE; 38556 break; 38557 default: 38558 support = FALSE; 38559 break; 38560 } 38561 38562 if (support) { 38563 *port_out = port; 38564 rv = BCM_E_NONE; 38565 } 38566 38567 return rv; 38568 } 38569 38570 /* 38571 * Function: 38572 * bcm_esw_port_control_scheduler_validate 38573 * Description: 38574 * Checks that port control is valid for a SCHEDULER GPORT. 38575 * Resolves port to expected port value for the given port control type. 38576 * Parameters: 38577 * unit - (IN) Device number 38578 * port - (IN) Port to resolve 38579 * type - (IN) Port control type 38580 * port_out - (OUT) Returns port (gport or BCM format) that 38581 * is expected for corresponding port control type. 38582 * Return Value: 38583 * BCM_E_XXX 38584 */ 38585 STATIC int 38586 bcm_esw_port_control_scheduler_validate(int unit, bcm_port_t port, 38587 bcm_port_control_t type, 38588 bcm_port_t *port_out) 38589 { 38590 int rv = BCM_E_PORT; 38591 int support = FALSE; 38592 38593 switch (type) { 38594 case bcmPortControlWredDropCountUpdateEnableQueueMask: 38595 case bcmPortControlWredDropCountUpdateEnableColorMask: 38596 support = TRUE; 38597 break; 38598 default: 38599 support = FALSE; 38600 break; 38601 } 38602 38603 if (support) { 38604 *port_out = port; 38605 rv = BCM_E_NONE; 38606 } 38607 38608 return rv; 38609 } 38610 38611 /* 38612 * Function: 38613 * bcm_esw_port_control_local_port_validate 38614 * Description: 38615 * Checks that port control is valid for a BCM local physical port. 38616 * Resolves port to expected port value for the given port control type. 38617 * Parameters: 38618 * unit - (IN) Device number 38619 * port - (IN) Port to resolve 38620 * type - (IN) Port control type 38621 * port_out - (OUT) Returns port (gport or BCM format) that 38622 * is expected for corresponding port control type. 38623 * Return Value: 38624 * BCM_E_XXX 38625 * 38626 * Unlike the other similar routines 38627 * (i.e. bcm_esw_port_control_wlan_support), note that the default 38628 * support is VALID and checks for INVALID types, since most 38629 * port controls are valid for this type of port. 38630 */ 38631 STATIC int 38632 bcm_esw_port_control_local_port_validate(int unit, bcm_port_t port, 38633 bcm_port_control_t type, 38634 bcm_port_t *port_out) 38635 { 38636 int rv = BCM_E_PORT; 38637 int support = TRUE; 38638 bcm_port_t local_port; 38639 38640 /* Make sure port module is initialized. */ 38641 PORT_INIT(unit); 38642 38643 /* Check for valid BCM local physical port */ 38644 BCM_IF_ERROR_RETURN 38645 (_bcm_esw_port_gport_validate(unit, port, &local_port)); 38646 38647 if (IS_ST_PORT(unit, local_port)) { 38648 switch(type) { 38649 case bcmPortControlIP4: 38650 case bcmPortControlIP6: 38651 case bcmPortControlIP4Mcast: 38652 case bcmPortControlIP6Mcast: 38653 case bcmPortControlMpls: 38654 case bcmPortControlMacInMac: 38655 case bcmPortControlIP4McastL2: 38656 case bcmPortControlIP6McastL2: 38657 case bcmPortControlIPMC4Ucast: 38658 case bcmPortControlIPMC6Ucast: 38659 support = FALSE; 38660 break; 38661 default: 38662 support = TRUE; 38663 break; 38664 } 38665 } 38666 38667 if (support) { 38668 if (!IS_E_PORT(unit, local_port)) { 38669 switch(type) { 38670 case bcmPortControlEEEEnable: 38671 case bcmPortControlEEETransmitIdleTime: 38672 case bcmPortControlEEEStatisticsClear: 38673 case bcmPortControlEEETransmitRefreshTime: 38674 case bcmPortControlEEETransmitSleepTime: 38675 case bcmPortControlEEETransmitQuietTime: 38676 case bcmPortControlEEETransmitWakeTime: 38677 case bcmPortControlEEEReceiveSleepTime: 38678 case bcmPortControlEEEReceiveQuietTime: 38679 case bcmPortControlEEEReceiveWakeTime: 38680 case bcmPortControlEEEEventCountSymmetric: 38681 case bcmPortControlEEELinkActiveDuration: 38682 case bcmPortControlEEEReceiveDuration: 38683 case bcmPortControlEEETransmitEventCount: 38684 case bcmPortControlEEETransmitDuration: 38685 case bcmPortControlEEEReceiveEventCount: 38686 support = FALSE; 38687 break; 38688 default: 38689 support = TRUE; 38690 break; 38691 } 38692 } 38693 } 38694 38695 if (support) { 38696 *port_out = local_port; 38697 rv = BCM_E_NONE; 38698 } 38699 38700 return rv; 38701 } 38702 38703 /* 38704 * Function: 38705 * bcm_esw_port_control_validate 38706 * Description: 38707 * Checks that port is valid and that control is supported 38708 * for the given port type. Resolves port to expected 38709 * port value for the given port control type. 38710 * Current valid port types are: 38711 * GPORT WLAN 38712 * GPORT PROXY 38713 * GPORT (various types) that resolves to local physical port 38714 * BCM port (non-gport) 38715 * Parameters: 38716 * unit - (IN) Device number 38717 * port - (IN) Port to resolve 38718 * type - (IN) Port control type 38719 * port_out - (OUT) Returns port (gport or BCM format) that 38720 * is expected for corresponding port control type. 38721 * Return Value: 38722 * BCM_E_XXX 38723 */ 38724 STATIC int 38725 bcm_esw_port_control_validate(int unit, bcm_port_t port, 38726 bcm_port_control_t type, 38727 bcm_port_t *port_out) 38728 { 38729 int rv = BCM_E_PORT; 38730 38731 /* Make sure port module is initialized. */ 38732 PORT_INIT(unit); 38733 38734 if (BCM_GPORT_IS_WLAN_PORT(port)) { 38735 rv = bcm_esw_port_control_wlan_validate(port, type, port_out); 38736 } else if (BCM_GPORT_IS_PROXY(port)) { 38737 rv = bcm_esw_port_control_proxy_validate(unit, port, type, port_out); 38738 } else if (BCM_GPORT_IS_SCHEDULER(port)) { 38739 rv = bcm_esw_port_control_scheduler_validate(unit, port, 38740 type, port_out); 38741 } else { 38742 rv = bcm_esw_port_control_local_port_validate(unit, port, type, 38743 port_out); 38744 } 38745 38746 return rv; 38747 } 38748 38749 38750 int 38751 _bcm_esw_port_vrf_set(int unit, bcm_port_t port, int value) 38752 { 38753 int rv = BCM_E_UNAVAIL; 38754 #if defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE_SUPPORT) 38755 if (SOC_IS_HAWKEYE(unit) || SOC_IS_HURRICANEX(unit) || 38756 !soc_feature(unit, soc_feature_l3)) { 38757 return BCM_E_UNAVAIL; 38758 } 38759 #endif /* BCM_HAWKEYE_SUPPORT || BCM_HURRICANE_SUPPORT */ 38760 if (soc_mem_field_valid(unit, PORT_TABm, VRF_IDf)) { 38761 if ((value > 0 ) && (value < SOC_VRF_MAX(unit) )) { 38762 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38763 VRF_IDf, value); 38764 BCM_IF_ERROR_RETURN(rv); 38765 if (soc_mem_field_valid(unit, PORT_TABm, VRF_PORT_ENABLEf)) { 38766 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38767 VRF_PORT_ENABLEf, 0x1); 38768 } 38769 } else { 38770 if (soc_mem_field_valid(unit, PORT_TABm, VRF_PORT_ENABLEf)) { 38771 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38772 VRF_PORT_ENABLEf, 0x0); 38773 BCM_IF_ERROR_RETURN(rv); 38774 } 38775 if (soc_mem_field_valid(unit, PORT_TABm, VRF_IDf)) { 38776 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38777 VRF_IDf, 0x0); 38778 } 38779 } 38780 } 38781 38782 #if defined(BCM_TRIUMPH_SUPPORT) 38783 else { 38784 if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, VRF_IDf)) { 38785 if ((value > 0 ) && (value < SOC_VRF_MAX(unit) )) { 38786 #if defined(BCM_KATANA2_SUPPORT) 38787 if (SOC_IS_KATANA2(unit)) { 38788 rv = _bcm_kt2_source_trunk_map_set(unit, port, 38789 VRF_IDf, value); 38790 } else 38791 #endif 38792 { 38793 rv = _bcm_trx_source_trunk_map_set(unit, port, 38794 VRF_IDf, value); 38795 } 38796 BCM_IF_ERROR_RETURN(rv); 38797 if (soc_mem_field_valid(unit, PORT_TABm, 38798 PORT_OPERATIONf) || 38799 SOC_IS_TRIDENT3X(unit)) { 38800 rv = _bcm_esw_port_tab_set(unit, port, 38801 _BCM_CPU_TABS_BOTH, 38802 PORT_OPERATIONf, 0x3); 38803 } 38804 } else { 38805 if (soc_mem_field_valid(unit, PORT_TABm, 38806 PORT_OPERATIONf) || 38807 SOC_IS_TRIDENT3X(unit)) { 38808 rv = _bcm_esw_port_tab_set(unit, port, 38809 _BCM_CPU_TABS_BOTH, 38810 PORT_OPERATIONf, 0x0); 38811 } 38812 } 38813 } 38814 } 38815 #endif /* BCM_TRIUMPH_SUPPORT */ 38816 return rv; 38817 } 38818 38819 int 38820 _bcm_esw_port_vrf_get(int unit, bcm_port_t port, int *value) 38821 { 38822 int rv = BCM_E_UNAVAIL; 38823 #if defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE_SUPPORT) 38824 if (SOC_IS_HAWKEYE(unit) || SOC_IS_HURRICANEX(unit) || 38825 !soc_feature(unit, soc_feature_l3)) { 38826 return BCM_E_UNAVAIL; 38827 } 38828 #endif /* BCM_HAWKEYE_SUPPORT || BCM_HURRICANE_SUPPORT */ 38829 if (soc_mem_field_valid(unit, PORT_TABm, VRF_PORT_ENABLEf)) { 38830 rv = _bcm_esw_port_tab_get(unit, port, VRF_PORT_ENABLEf, value); 38831 38832 if ((*value == 0x1 ) && (soc_mem_field_valid(unit, PORT_TABm, 38833 VRF_IDf ))) { 38834 rv = _bcm_esw_port_tab_get(unit, port, VRF_IDf, value); 38835 } else { 38836 *value = 0; 38837 } 38838 } else if (soc_mem_field_valid(unit, PORT_TABm, VRF_IDf)) { 38839 rv = _bcm_esw_port_tab_get(unit, port, VRF_IDf, value); 38840 } 38841 38842 #if defined(BCM_TRIUMPH_SUPPORT) 38843 else { 38844 *value = 0; 38845 if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf) || 38846 SOC_IS_TRIDENT3X(unit)) { 38847 rv = _bcm_esw_port_tab_get(unit, port, PORT_OPERATIONf, value); 38848 BCM_IF_ERROR_RETURN(rv); 38849 } 38850 if ((*value == 0x3) && 38851 (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 38852 VRF_IDf))) { 38853 #if defined(BCM_KATANA2_SUPPORT) 38854 if (SOC_IS_KATANA2(unit)) { 38855 rv = _bcm_kt2_source_trunk_map_get(unit, port, VRF_IDf, 38856 (uint32 *)value); 38857 } else 38858 #endif 38859 { 38860 rv = _bcm_trx_source_trunk_map_get(unit, port, VRF_IDf, 38861 (uint32 *)value); 38862 } 38863 } 38864 } 38865 38866 #endif /* BCM_TRIUMPH_SUPPORT */ 38867 return rv; 38868 } 38869 38870 #ifdef BCM_TRIDENT2_SUPPORT 38871 STATIC void 38872 _bcm_flex_port_phy_control_software_rx_los_get(int unit, bcm_port_t control_port) { 38873 int rv = BCM_E_NONE; 38874 bcm_pbmp_t ancillary_pbmp; 38875 bcm_port_t ancillary_port; 38876 uint32 rx_los; 38877 38878 rv = bcm_esw_port_subsidiary_ports_get(unit, control_port, &ancillary_pbmp); 38879 if (BCM_FAILURE(rv)) { 38880 return; 38881 } 38882 PBMP_ITER(ancillary_pbmp, ancillary_port) { 38883 rv = bcm_esw_port_phy_control_get(unit, ancillary_port, BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, &rx_los); 38884 if (BCM_SUCCESS(rv)) { 38885 PORT_INFO_RX_LOS_SET(unit, ancillary_port, BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, rx_los); 38886 } 38887 } 38888 return; 38889 } 38890 #endif 38891 38892 int 38893 bcm_esw_port_phy_fec_error_inject_set(int unit, bcm_port_t port, 38894 uint16 error_control_map, 38895 bcm_port_phy_fec_error_mask_t bit_error_mask) 38896 { 38897 int rv = BCM_E_UNAVAIL; 38898 soc_phy_control_fec_error_mask_t error_mask; 38899 38900 /* Make sure port module is initialized. */ 38901 PORT_INIT(unit); 38902 38903 /* Call Port Control module */ 38904 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 38905 return bcmi_esw_portctrl_phy_fec_error_inject_set(unit, port, error_control_map, bit_error_mask); 38906 } 38907 38908 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 38909 38910 if (!(BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) { 38911 return BCM_E_PORT; 38912 } 38913 error_mask.error_mask_bit_31_0 = bit_error_mask.error_mask_bit_31_0; 38914 error_mask.error_mask_bit_63_32 = bit_error_mask.error_mask_bit_63_32; 38915 error_mask.error_mask_bit_79_64 = bit_error_mask.error_mask_bit_79_64; 38916 38917 PORT_LOCK(unit); 38918 rv = soc_phyctrl_fec_error_inject_set(unit, port, error_control_map, error_mask); 38919 PORT_UNLOCK(unit); 38920 38921 return rv; 38922 } 38923 38924 int 38925 bcm_esw_port_phy_fec_error_inject_get(int unit, bcm_port_t port, 38926 uint16 *error_control_map, 38927 bcm_port_phy_fec_error_mask_t *bit_error_mask) 38928 { 38929 int rv = BCM_E_UNAVAIL; 38930 soc_phy_control_fec_error_mask_t error_mask; 38931 38932 /* Make sure port module is initialized. */ 38933 PORT_INIT(unit); 38934 38935 /* Call Port Control module */ 38936 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 38937 return bcmi_esw_portctrl_phy_fec_error_inject_get(unit, port, error_control_map, bit_error_mask); 38938 } 38939 38940 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 38941 38942 if (!(BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) { 38943 return BCM_E_PORT; 38944 } 38945 38946 PORT_LOCK(unit); 38947 rv = soc_phyctrl_fec_error_inject_get(unit, port, error_control_map, &error_mask); 38948 PORT_UNLOCK(unit); 38949 38950 bit_error_mask->error_mask_bit_31_0 = error_mask.error_mask_bit_31_0; 38951 bit_error_mask->error_mask_bit_63_32 = error_mask.error_mask_bit_63_32; 38952 bit_error_mask->error_mask_bit_79_64 = error_mask.error_mask_bit_79_64; 38953 38954 return rv; 38955 } 38956 38957 /* 38958 * Function: 38959 * _bcm_esw_port_eee_stat_clear 38960 * Description: 38961 * Clear EEE statistics directly by 38962 * writing EEE counter register to 0 38963 * Parameters: 38964 * unit - Device number 38965 * port - Port number 38966 * Return Value: 38967 * BCM_E_XXX 38968 */ 38969 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \ 38970 defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 38971 STATIC int 38972 _bcm_esw_port_eee_stat_clear(int unit, bcm_port_t port) 38973 { 38974 int idx; 38975 uint64 val64; 38976 soc_reg_t def_regs[] = { 38977 RX_EEE_LPI_DURATION_COUNTERr, 38978 RX_EEE_LPI_EVENT_COUNTERr, 38979 TX_EEE_LPI_DURATION_COUNTERr, 38980 TX_EEE_LPI_EVENT_COUNTERr 38981 }; 38982 soc_reg_t ge_regs[] = { 38983 GRX_EEE_LPI_DURATION_COUNTERr, 38984 GRX_EEE_LPI_EVENT_COUNTERr, 38985 GTX_EEE_LPI_DURATION_COUNTERr, 38986 GTX_EEE_LPI_EVENT_COUNTERr 38987 }; 38988 soc_reg_t *regs = def_regs; 38989 38990 COMPILER_64_ZERO(val64); 38991 38992 if (IS_GE_PORT(unit, port) && !IS_XL_PORT(unit, port)) { 38993 regs = ge_regs; 38994 } 38995 38996 for (idx = 0; idx < sizeof(def_regs) / sizeof(def_regs[0]); idx++) { 38997 SOC_IF_ERROR_RETURN(soc_counter_set(unit, port, regs[idx], 0, val64)); 38998 } 38999 39000 return BCM_E_NONE; 39001 } 39002 #endif 39003 39004 /* 39005 * Function: 39006 * bcm_esw_port_control_set 39007 * Description: 39008 * Enable/Disable specified port feature. 39009 * Parameters: 39010 * unit - Device number 39011 * port - Port number 39012 * type - Enum value of the feature 39013 * value - value to be set 39014 * Return Value: 39015 * BCM_E_NONE 39016 * BCM_E_UNAVAIL - Functionality not available 39017 */ 39018 int 39019 bcm_esw_port_control_set(int unit, bcm_port_t port, 39020 bcm_port_control_t type, int value) 39021 { 39022 int rv = BCM_E_UNAVAIL; 39023 int valid = 0; 39024 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 39025 soc_reg_t egr_port_reg; 39026 #endif 39027 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 39028 int chk_gx_port = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 39029 SOC_IS_VALKYRIE2(unit) || SOC_IS_SCORPION(unit)); 39030 #endif 39031 #if defined(BCM_GREYHOUND_SUPPORT) 39032 int cur_val = 0; 39033 #endif 39034 #if defined (BCM_METROLITE_SUPPORT) 39035 bcm_pbmp_t pbm; 39036 #endif 39037 #if defined(BCM_TOMAHAWK3_SUPPORT) 39038 int_turnaround_en_bmap_entry_t int_turnaround_en_bmap_entry; 39039 bcm_pbmp_t pbmp; 39040 #endif 39041 39042 LOG_INFO(BSL_LS_BCM_PORT, 39043 (BSL_META_U(unit, 39044 "bcm_port_control_set: u=%d p=%d rv=%d : %d\n"), 39045 unit, port, value, (int)type)); 39046 39047 /* Make sure port module is initialized. */ 39048 PORT_INIT(unit); 39049 39050 if(bcm_common_oamp_port_enable_get(unit, port) && 39051 (type != bcmPortControlSatEnable)) { 39052 /* Only bcmPortControlSatEnable is permitted on oamp port */ 39053 LOG_ERROR(BSL_LS_BCM_PORT, 39054 (BSL_META("Error: Not permitted on OAMP port %d.n"), 39055 port)); 39056 return BCM_E_PARAM; 39057 } 39058 39059 /* Call Port Control module */ 39060 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 39061 /* 39062 * Check that port control feature is valid in Port Control. 39063 * If valid, call Port Control routine to handle feature; otherwise 39064 * continue with rest of logic. 39065 */ 39066 BCM_IF_ERROR_RETURN 39067 (bcmi_esw_portctrl_control_validate(unit, type, &valid)); 39068 if (valid) { 39069 return bcmi_esw_portctrl_control_set(unit, port, type, value); 39070 } 39071 } 39072 39073 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 39074 egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 39075 SOC_IS_VALKYRIE2(unit)|| SOC_IS_GREYHOUND(unit) || 39076 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ? 39077 EGR_PORT_64r : EGR_PORTr; 39078 #endif 39079 39080 #if defined(BCM_SHADOW_SUPPORT) 39081 if (SOC_IS_SHADOW(unit)) { 39082 /* If unsupported port control type, return unavail */ 39083 if (!_bcm_port_type_shadow_support (unit, port, type)) { 39084 return BCM_E_UNAVAIL; 39085 } 39086 } 39087 #endif /* BCM_SHADOW_SUPPORT */ 39088 39089 if (type == bcmPortControlEsmEligibility) { 39090 #ifdef BCM_TRIUMPH3_SUPPORT 39091 /* For bcmPortControlEsmEligibility, a non-local port 39092 * is accepted. For other port controls, a non-local 39093 * port is not accepted. Hence, bcmPortControlEsmEligibility 39094 * is implemented here, before the _bcm_esw_port_gport_validate 39095 * procedure below. 39096 */ 39097 return bcm_tr3_port_esm_eligible_set(unit, port, value); 39098 #endif /* BCM_TRIUMPH3_SUPPORT */ 39099 } 39100 39101 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 39102 if ( 39103 #ifdef BCM_HGPROXY_COE_SUPPORT 39104 ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 39105 (soc_feature(unit, soc_feature_channelized_switching))) && 39106 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) && 39107 ((type == bcmPortControlVlanVpGroupIngress) || 39108 (type == bcmPortControlVlanVpGroupEgress))) || 39109 #endif 39110 BCM_GPORT_IS_TRUNK(port) || 39111 BCM_GPORT_IS_VLAN_PORT(port) || 39112 BCM_GPORT_IS_NIV_PORT(port) || 39113 BCM_GPORT_IS_VXLAN_PORT(port) || 39114 BCM_GPORT_IS_MIM_PORT(port) || 39115 BCM_GPORT_IS_MPLS_PORT(port) || 39116 BCM_GPORT_IS_L2GRE_PORT(port) || 39117 BCM_GPORT_IS_FLOW_PORT(port) || 39118 BCM_GPORT_IS_EXTENDER_PORT(port)) { 39119 return bcm_td_vp_control_set(unit, port, type, value); 39120 } else 39121 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 39122 #if defined(BCM_KATANA2_SUPPORT) 39123 if ((BCM_GPORT_IS_MIM_PORT(port) || BCM_GPORT_IS_MPLS_PORT(port)) 39124 && SOC_IS_KATANA2(unit)) { 39125 rv = BCM_E_NONE; 39126 } else 39127 #endif /* BCM_KATANA2_SUPPORT */ 39128 if ((BCM_GPORT_IS_LOCAL_CPU_IEEE(port)) || 39129 (BCM_GPORT_IS_LOCAL_CPU_HIGIG(port))) { 39130 rv = BCM_E_NONE; 39131 } else 39132 #ifdef BCM_HGPROXY_COE_SUPPORT 39133 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 39134 (soc_feature(unit, soc_feature_channelized_switching))) && 39135 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 39136 rv = BCM_E_NONE; 39137 } else 39138 #endif 39139 #ifdef BCM_TRIDENT3_SUPPORT 39140 if (soc_feature(unit, soc_feature_pp_port_control) && 39141 (type == bcmPortControlPacketProcssingPort) ) { 39142 rv = BCM_E_NONE; 39143 } else 39144 #endif 39145 { 39146 rv = bcm_esw_port_control_validate(unit, port, type, &port); 39147 } 39148 BCM_IF_ERROR_RETURN(rv); 39149 rv = BCM_E_UNAVAIL; 39150 39151 /* 39152 * At this point, 'port' can be: 39153 * GPORT WLAN 39154 * GPORT PROXY 39155 * BCM valid local port 39156 * 39157 * Some switch cases only handles 'port' in BCM port format 39158 * (non-gport). Corresponding checks must be added in those 39159 * cases to ensure that 'port' is not a gport. 39160 */ 39161 switch (type) { 39162 case bcmPortControlBridge: 39163 if (BCM_GPORT_IS_SET(port)) { 39164 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39165 PORT_BRIDGEf, value); 39166 } else { 39167 PORT_LOCK(unit); 39168 rv = _bcm_esw_port_control_bridge_set(unit, port, value); 39169 PORT_UNLOCK(unit); 39170 } 39171 break; 39172 case bcmPortControlTrunkHashSet: 39173 #if defined(BCM_TRIUMPH3_SUPPORT) 39174 if (SOC_IS_TRIUMPH3(unit)) { 39175 return BCM_E_UNAVAIL; 39176 } else 39177 #endif /* BCM_TRIUMPH3_SUPPORT */ 39178 { 39179 #if defined(BCM_BRADLEY_SUPPORT) 39180 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 39181 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39182 RTAG7_HASH_CFG_SEL_TRUNKf, 39183 (value) ? 1 : 0); 39184 } 39185 #endif /* BCM_BRADLEY_SUPPORT */ 39186 } 39187 break; 39188 case bcmPortControlFabricTrunkHashSet: 39189 #if defined(BCM_TRIUMPH3_SUPPORT) 39190 if (SOC_IS_TRIUMPH3(unit)) { 39191 return BCM_E_UNAVAIL; 39192 } else 39193 #endif /* BCM_TRIUMPH3_SUPPORT */ 39194 { 39195 #if defined(BCM_BRADLEY_SUPPORT) 39196 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 39197 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39198 RTAG7_HASH_CFG_SEL_HIGIG_TRUNKf, 39199 (value) ? 1 : 0); 39200 } 39201 #endif /* BCM_BRADLEY_SUPPORT */ 39202 } 39203 break; 39204 case bcmPortControlECMPHashSet: 39205 #if defined(BCM_TRIUMPH3_SUPPORT) 39206 if (SOC_IS_TRIUMPH3(unit)) { 39207 return BCM_E_UNAVAIL; 39208 } else 39209 #endif /* BCM_TRIUMPH3_SUPPORT */ 39210 { 39211 #if defined(BCM_BRADLEY_SUPPORT) 39212 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 39213 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39214 RTAG7_HASH_CFG_SEL_ECMPf, 39215 (value) ? 1 : 0); 39216 } 39217 #endif /* BCM_BRADLEY_SUPPORT */ 39218 } 39219 break; 39220 case bcmPortControlLoadBalanceHashSet: 39221 #if defined(BCM_TRIUMPH3_SUPPORT) 39222 if (SOC_IS_TRIUMPH3(unit)) { 39223 return BCM_E_UNAVAIL; 39224 } else 39225 #endif /* BCM_TRIUMPH3_SUPPORT */ 39226 { 39227 #if defined(BCM_BRADLEY_SUPPORT) 39228 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 39229 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39230 RTAG7_HASH_CFG_SEL_LBIDf, 39231 (value) ? 1 : 0); 39232 } 39233 #endif /* BCM_BRADLEY_SUPPORT */ 39234 } 39235 break; 39236 case bcmPortControlLoadBalancingNumber: 39237 #if defined(BCM_BRADLEY_SUPPORT) 39238 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 39239 #if defined(BCM_TOMAHAWK3_SUPPORT) 39240 if (SOC_IS_TOMAHAWK3(unit)) { 39241 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39242 RTAG7_PORT_LBNf, 39243 (value) & 0x3f); 39244 } else 39245 #endif /* BCM_TOMAHAWK3_SUPPORT */ 39246 { 39247 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39248 RTAG7_PORT_LBNf, 39249 (value) & 0xf); 39250 } 39251 } 39252 #endif /* BCM_BRADLEY_SUPPORT */ 39253 break; 39254 case bcmPortControlErrorSymbolDetect: 39255 #if defined(BCM_GREYHOUND_SUPPORT) 39256 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 39257 SOC_IS_GREYHOUND2(unit)) { 39258 rv = BCM_E_UNAVAIL; 39259 } else 39260 #endif /* BCM_GREYHOUND_SUPPORT */ 39261 { 39262 #ifdef BCM_XGS3_SWITCH_SUPPORT 39263 if (SOC_IS_XGS3_SWITCH(unit)) { 39264 rv = _bcm_esw_port_err_sym_detect_set(unit, port, value); 39265 } 39266 #endif 39267 } 39268 break; 39269 case bcmPortControlErrorSymbolCount: 39270 #if defined(BCM_GREYHOUND_SUPPORT) 39271 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 39272 SOC_IS_GREYHOUND2(unit)) { 39273 rv = BCM_E_UNAVAIL; 39274 } else 39275 #endif /* BCM_GREYHOUND_SUPPORT */ 39276 { 39277 #ifdef BCM_XGS3_SWITCH_SUPPORT 39278 if (SOC_IS_XGS3_SWITCH(unit)) { 39279 int temp = 0; 39280 /* Error symbol count is read only and cleared on read. */ 39281 rv = _bcm_esw_port_err_sym_count_get(unit, port, &temp); 39282 } 39283 #endif 39284 } 39285 break; 39286 #if defined(INCLUDE_L3) 39287 case bcmPortControlIP4: 39288 if (SOC_IS_XGS3_SWITCH(unit)) { 39289 if (BCM_GPORT_LOCAL_CPU_IEEE == port) { 39290 rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_ETHER, 39291 V4L3_ENABLEf, (value) ? 1 : 0); 39292 } else if (BCM_GPORT_LOCAL_CPU_HIGIG == port) { 39293 rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_HIGIG, 39294 V4L3_ENABLEf, (value) ? 1 : 0); 39295 } else { 39296 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39297 V4L3_ENABLEf, (value) ? 1 : 0); 39298 } 39299 39300 #if defined(BCM_TRIUMPH_SUPPORT) 39301 if (BCM_SUCCESS(rv) && 39302 soc_feature(unit, soc_feature_esm_support)) { 39303 if (SOC_IS_TRIUMPH3(unit)) { 39304 break; 39305 } 39306 if (!BCM_GPORT_IS_SET(port)) { 39307 rv = _bcm_tr_l3_enable(unit, port, 0, (value) ? 1 : 0); 39308 } 39309 } 39310 #endif /* BCM_TRIUMPH_SUPPORT */ 39311 } 39312 break; 39313 case bcmPortControlIP6: 39314 if (SOC_IS_XGS3_SWITCH(unit)) { 39315 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39316 V6L3_ENABLEf, (value) ? 1 : 0); 39317 #if defined(BCM_TRIUMPH_SUPPORT) 39318 if (BCM_SUCCESS(rv) && 39319 soc_feature(unit, soc_feature_esm_support)) { 39320 if (SOC_IS_TRIUMPH3(unit)) { 39321 break; 39322 } 39323 if (!BCM_GPORT_IS_SET(port)) { 39324 rv = _bcm_tr_l3_enable(unit, port, BCM_L3_IP6, 39325 (value) ? 1 : 0); 39326 } 39327 } 39328 #endif /* BCM_TRIUMPH_SUPPORT */ 39329 } 39330 break; 39331 case bcmPortControlIP4Mcast: 39332 if (SOC_IS_XGS3_SWITCH(unit)) { 39333 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39334 V4IPMC_ENABLEf, (value) ? 1 : 0); 39335 } 39336 break; 39337 case bcmPortControlIP6Mcast: 39338 if (SOC_IS_XGS3_SWITCH(unit)) { 39339 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39340 V6IPMC_ENABLEf, (value) ? 1 : 0); 39341 } 39342 break; 39343 case bcmPortControlIPMC4Ucast: 39344 if (soc_feature(unit, soc_feature_ipmc_unicast)) { 39345 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39346 IPMCV4_UNICAST_MACDA_ENABLEf, (value) ? 1 : 0); 39347 } 39348 break; 39349 case bcmPortControlIPMC6Ucast: 39350 if (soc_feature(unit, soc_feature_ipmc_unicast)) { 39351 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39352 IPMCV6_UNICAST_MACDA_ENABLEf, (value) ? 1 : 0); 39353 } 39354 break; 39355 case bcmPortControlMpls: 39356 #if defined(BCM_TRIUMPH_SUPPORT) 39357 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39358 MPLS_ENABLEf, (value) ? 1 : 0); 39359 #endif 39360 break; 39361 case bcmPortControlMacInMac: 39362 if (!soc_feature(unit, soc_feature_mim)) { 39363 break; 39364 } 39365 #if defined(BCM_TRIUMPH2_SUPPORT) 39366 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39367 MIM_TERM_ENABLEf, (value) ? 1 : 0); 39368 if(rv == BCM_E_NONE) { 39369 #if defined(BCM_TRIDENT3_SUPPORT) 39370 if(SOC_IS_TRIDENT3X(unit)) { 39371 int app = 0; 39372 if (0x0 != value) { 39373 app = CANCUN_APP__PORT_TABLE__MIM_MC_TERM_ENABLE; 39374 } else { 39375 app = CANCUN_APP__PORT_TABLE__MIM_MC_TERM_DISABLE; 39376 } 39377 rv = soc_cancun_app_dest_entry_set (unit, 39378 PORT_TABm, port, PORT_TYPEf, app, 0x0); 39379 if (BCM_E_NONE != rv ) { 39380 LOG_ERROR(BSL_LS_BCM_L2, 39381 (BSL_META_U(unit, 39382 "MIM_MC_TERM_ENABLE cfg error\n"))); 39383 } 39384 } else 39385 #endif 39386 { 39387 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39388 MIM_MC_TERM_ENABLEf, (value) ? 1 : 0); 39389 } 39390 } 39391 #endif 39392 break; 39393 39394 case bcmPortControlMimUcastTermEnable: 39395 if (!soc_feature(unit, soc_feature_mim)) { 39396 break; 39397 } 39398 #if defined(BCM_TRIUMPH2_SUPPORT) 39399 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39400 MIM_TERM_ENABLEf, (value) ? 1 : 0); 39401 #endif 39402 break; 39403 39404 case bcmPortControlMimMcastTermEnable: 39405 if (!soc_feature(unit, soc_feature_mim)) { 39406 break; 39407 } 39408 #if defined(BCM_TRIUMPH2_SUPPORT) 39409 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39410 MIM_MC_TERM_ENABLEf, (value) ? 1 : 0); 39411 #endif 39412 break; 39413 39414 case bcmPortControlSrcBmacMissToCpu: 39415 #ifdef BCM_TRIUMPH2_SUPPORT 39416 if (SOC_IS_TRIDENT3X(unit)) { /* see SDK-124007 */ 39417 return BCM_E_UNAVAIL; 39418 } 39419 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 39420 SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) || 39421 SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || 39422 SOC_IS_KATANA(unit)) { 39423 /* 0x2: ToCPU 0x1: Drop(default) */ 39424 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39425 CML_BMAC_NEWf, (value) ? 0x2 : 0x1); 39426 } 39427 #endif /* BCM_TRIUMPH2_SUPPORT */ 39428 break; 39429 39430 case bcmPortControlQosRemarkResolution: 39431 #ifdef BCM_TRIDENT3_SUPPORT 39432 if (SOC_IS_TRIDENT3X(unit)) { 39433 /* Two resolution supported by TD3 hardware: 39434 * 1: Serial resolution. 39435 * 3: Layered resolution. 39436 * Default is Layered resolution 39437 */ 39438 if (value == BCM_PORT_QOS_SERIAL_RESOLUTION) { 39439 value = 1; 39440 } else if (value == BCM_PORT_QOS_LAYERED_RESOLUTION) { 39441 value = 3; 39442 } else { 39443 return BCM_E_PARAM; 39444 } 39445 rv = _bcm_esw_egr_port_tab_set(unit, port, QOS_CTRL_IDf, value); 39446 } 39447 #endif /* BCM_TRIDENT3_SUPPORT */ 39448 break; 39449 39450 case bcmPortControlFabricQueue: 39451 #if defined(BCM_TRIUMPH2_SUPPORT) 39452 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39453 #if defined(BCM_TRIDENT3_SUPPORT) 39454 if (SOC_IS_TRIDENT3X(unit) && 39455 soc_feature(unit, soc_feature_egr_lport_tab_profile)) { 39456 rv = bcm_esw_port_egr_lport_field_set( 39457 unit, port, EGR_LPORT_PROFILEm, EH_EXT_HDR_ENABLEf, 39458 (value) ? 1 : 0); 39459 BCM_IF_ERROR_RETURN(rv); 39460 } 39461 #endif 39462 if (IS_ST_PORT(unit, port)) { 39463 if (SOC_REG_FIELD_VALID(unit, EGR_PORT_64r, EH_EXT_HDR_ENABLEf)) { 39464 rv = soc_reg_field32_modify(unit, EGR_PORT_64r, port, 39465 EH_EXT_HDR_ENABLEf,(value) ? 1 : 0); 39466 } 39467 else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EH_EXT_HDR_ENABLEf)){ 39468 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 39469 EH_EXT_HDR_ENABLEf,(value) ? 1 : 0 ); 39470 } 39471 } else { 39472 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 39473 /* Allow CPU port on TD2+ to add extended header */ 39474 if (SOC_IS_TRIDENT2PLUS(unit) && IS_CPU_PORT(unit, port)) { 39475 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 39476 EH_EXT_HDR_ENABLEf,(value) ? 1 : 0 ); 39477 } 39478 #endif 39479 #if defined(BCM_TOMAHAWK_SUPPORT) 39480 if (SOC_IS_TOMAHAWKX(unit) && IS_CPU_PORT(unit, port)) { 39481 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 39482 EH_EXT_HDR_ENABLEf,(value) ? 1 : 0 ); 39483 } 39484 #endif 39485 } 39486 #endif 39487 break; 39488 #endif /* INCLUDE_L3 */ 39489 case bcmPortControlIP4McastL2: 39490 #if defined(BCM_TRX_SUPPORT) 39491 if (SOC_IS_TD2_TT2(unit) && 39492 soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 39493 IPMCV4_L2_ENABLEf)) { 39494 rv = _bcm_trx_source_trunk_map_set(unit, port, 39495 IPMCV4_L2_ENABLEf, (value) ? 1 : 0); 39496 } else { 39497 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39498 V4IPMC_L2_ENABLEf, (value) ? 1 : 0); 39499 } 39500 #endif /* BCM_TRX_SUPPORT */ 39501 break; 39502 case bcmPortControlIP6McastL2: 39503 #if defined(BCM_TRX_SUPPORT) 39504 if (SOC_IS_TD2_TT2(unit) && 39505 soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 39506 IPMCV6_L2_ENABLEf)) { 39507 rv = _bcm_trx_source_trunk_map_set(unit, port, 39508 IPMCV6_L2_ENABLEf, (value) ? 1 : 0); 39509 } else { 39510 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39511 V6IPMC_L2_ENABLEf, (value) ? 1 : 0); 39512 } 39513 #endif /* BCM_TRX_SUPPORT */ 39514 break; 39515 case bcmPortControlPassControlFrames: 39516 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39517 #ifdef BCM_XGS3_SWITCH_SUPPORT 39518 if (SOC_IS_XGS3_SWITCH(unit) && IS_E_PORT(unit, port)) { 39519 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 39520 PASS_CONTROL_FRAMESf, 39521 (value) ? 1 : 0); 39522 } 39523 #endif 39524 #ifdef BCM_XGS_SWITCH_SUPPORT 39525 if (IS_XE_PORT(unit, port) || IS_CE_PORT(unit, port) || 39526 (IS_GE_PORT(unit, port) 39527 && soc_feature(unit, soc_feature_unified_port)) || 39528 (SOC_IS_KATANAX(unit) && IS_MXQ_PORT(unit, port))) { 39529 /* Enable Control Frames in BigMAC */ 39530 if(soc_feature(unit, soc_feature_pgw_mac_control_frame)) { 39531 uint32 rval32 = 0; 39532 PORT_LOCK(unit); 39533 rv = READ_PGW_MAC_RSV_MASKr(unit, port, &rval32); 39534 if (BCM_SUCCESS(rv)) { 39535 /* PGW_MAC_RSV_MASK: Bit 11 Control Frame recieved 39536 * Enable Control Frame : Set 0. Packet go through 39537 * Disable Control Frame : Set 1. Packet is purged. 39538 */ 39539 if(value) { 39540 rval32 &= ~(1 << 11); 39541 } else { 39542 rval32 |= (1 << 11); 39543 } 39544 rv = WRITE_PGW_MAC_RSV_MASKr(unit, port, rval32); 39545 } 39546 PORT_UNLOCK(unit); 39547 } else { 39548 PORT_LOCK(unit); 39549 39550 if (SOC_IS_SABER2(unit)) { 39551 if (IS_MXQ_PORT(unit, port)) { 39552 rv = soc_reg_field32_modify(unit, XPORT_CONFIGr, port, 39553 PASS_PAUSE_FRAMEf, value ? 1 : 0); 39554 if (rv == SOC_E_NONE) 39555 rv = soc_reg_field32_modify(unit, XPORT_CONFIGr, port, 39556 PASS_CONTROL_FRAMEf, value ? 1 : 0); 39557 } else { 39558 rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port, 39559 PASS_PAUSE_FRAMEf, value ? 1 : 0); 39560 if (rv == SOC_E_NONE) 39561 rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port, 39562 PASS_CONTROL_FRAMEf, value ? 1 : 0); 39563 } 39564 } 39565 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39566 SOC_MAC_PASS_CONTROL_FRAME, value); 39567 PORT_UNLOCK(unit); 39568 } 39569 } 39570 #endif 39571 break; 39572 #ifdef BCM_XGS3_SWITCH_SUPPORT 39573 case bcmPortControlFilterLookup: 39574 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 39575 value = value ? 1 : 0; 39576 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39577 VFP_ENABLEf, value); 39578 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 39579 break; 39580 case bcmPortControlFilterIngress: 39581 value = value ? 1 : 0; 39582 /* Enable/disable ingress filtering. */ 39583 if (BCM_GPORT_LOCAL_CPU_IEEE == port) { 39584 rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_ETHER, 39585 FILTER_ENABLEf, value); 39586 } else if (BCM_GPORT_LOCAL_CPU_HIGIG == port) { 39587 rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_HIGIG, 39588 FILTER_ENABLEf, value); 39589 } else { 39590 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39591 FILTER_ENABLEf, value); 39592 } 39593 39594 break; 39595 case bcmPortControlFilterEgress: 39596 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 39597 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39598 value = value ? 1 : 0; 39599 /* Enable/disable egress filtering. */ 39600 if (SOC_REG_FIELD_VALID(unit, egr_port_reg, EFP_FILTER_ENABLEf)) { 39601 rv = soc_reg_field32_modify(unit, egr_port_reg, port, 39602 EFP_FILTER_ENABLEf, value); 39603 } else { 39604 rv = _bcm_esw_egr_port_tab_set(unit, port, 39605 EFP_FILTER_ENABLEf, value); 39606 } 39607 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 39608 break; 39609 case bcmPortControlFrameSpacingStretch: 39610 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39611 rv = (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39612 SOC_MAC_CONTROL_FRAME_SPACING_STRETCH, 39613 value)); 39614 break; 39615 case bcmPortControlPreservePacketPriority: 39616 #if ((defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)) \ 39617 || defined(BCM_RAVEN_SUPPORT)) 39618 if (SOC_IS_TRIUMPH3(unit)) { 39619 /* Triumph3 has unity mapping to ING_OUTER_DOT1P_MAPPING_TABLE */ 39620 if (value) { 39621 /* Remap pointer to default dot1p profile */ 39622 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39623 DOT1P_REMAP_POINTERf, 0); 39624 } 39625 } else { 39626 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39627 USE_INCOMING_DOT1Pf, (value) ? 1 : 0); 39628 } 39629 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || defined(BCM_RAVEN_SUPPORT) */ 39630 #if defined(BCM_SHADOW_SUPPORT) 39631 if (SOC_IS_SHADOW(unit)) { 39632 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39633 rv = soc_reg_field32_modify(unit, PRIORITY_MAPPING_SELECTr, port, 39634 USE_INPUT_PRIORIYf, 1 ); 39635 } 39636 #endif 39637 break; 39638 case bcmPortControlLearnClassEnable: 39639 #if defined(BCM_TRX_SUPPORT) 39640 if (soc_feature(unit, soc_feature_class_based_learning)) { 39641 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39642 CLASS_BASED_SM_ENABLEf, value ? 1 : 0); 39643 } 39644 #endif /* BCM_TRX_SUPPORT */ 39645 break; 39646 case bcmPortControlTrustIncomingVlan: 39647 #if defined(BCM_TRIDENT3_SUPPORT) 39648 if (SOC_IS_TRIDENT3X(unit)) { 39649 uint32 tpid_enables = value; 39650 if (tpid_enables) { 39651 uint32 tpid_index; 39652 /* recover tpid_index from egress */ 39653 BCM_IF_ERROR_RETURN( 39654 _bcm_fb2_egr_vlan_control_field_get( 39655 unit, port, OUTER_TPID_INDEXf, &tpid_index)); 39656 tpid_enables = 1 << tpid_index; 39657 } 39658 rv = _bcm_fb2_port_tpid_enable_set(unit, port, tpid_enables); 39659 BCM_IF_ERROR_RETURN(rv); 39660 } else 39661 #endif 39662 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT) 39663 { 39664 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39665 TRUST_INCOMING_VIDf, (value) ? 1 : 0); 39666 } 39667 #endif /* BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 39668 break; 39669 case bcmPortControlDoNotCheckVlan: 39670 #if defined(BCM_TRX_SUPPORT) 39671 #if defined(BCM_TRIDENT3_SUPPORT) 39672 if (SOC_IS_TRIDENT3X(unit)) { 39673 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39674 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 39675 BCM_IF_ERROR_RETURN(rv); 39676 } 39677 #endif 39678 if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf)) { 39679 if (CMIC_PORT(unit) == port) { 39680 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_HIGIG, 39681 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 39682 } else { 39683 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39684 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 39685 } 39686 } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 39687 DISABLE_VLAN_CHECKSf)) { 39688 #if defined(BCM_KATANA2_SUPPORT) 39689 if (SOC_IS_KATANA2(unit)) { 39690 rv = _bcm_kt2_source_trunk_map_set(unit, port, 39691 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 39692 } else 39693 #endif 39694 { 39695 rv = _bcm_trx_source_trunk_map_set(unit, port, 39696 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 39697 } 39698 } 39699 #endif /* BCM_TRX_SUPPORT */ 39700 break; 39701 case bcmPortControlDoNotCheckVlanFromCpu: 39702 #if defined(BCM_TRX_SUPPORT) 39703 #if defined(BCM_TRIDENT3_SUPPORT) 39704 if (CMIC_PORT(unit) == port) { 39705 if (SOC_IS_TRIDENT3X(unit)) { 39706 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39707 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 39708 BCM_IF_ERROR_RETURN(rv); 39709 } 39710 } 39711 #endif 39712 if (CMIC_PORT(unit) == port) { 39713 if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf)) { 39714 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 39715 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 39716 } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 39717 DISABLE_VLAN_CHECKSf)) { 39718 rv = _bcm_trx_source_trunk_map_set(unit, port, 39719 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 39720 } 39721 } else { 39722 rv = BCM_E_PORT; 39723 } 39724 #endif /* BCM_TRX_SUPPORT */ 39725 break; 39726 case bcmPortControlIEEE8021ASEnableIngress: 39727 if (soc_feature(unit, soc_feature_rx_timestamp)) { 39728 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39729 IEEE_802_1AS_ENABLEf, (value) ? 1 : 0); 39730 } 39731 break; 39732 case bcmPortControlIEEE8021ASEnableEgress: 39733 #if defined(BCM_HAWKEYE_SUPPORT) 39734 if (SOC_IS_HAWKEYE(unit)) { 39735 rv = soc_reg_field32_modify(unit, EGR_PORTr, port, 39736 IEEE_802_1AS_ENABLEf, (value) ? 1 : 0); 39737 } 39738 #endif /* BCM_HAWKEYE_SUPPORT */ 39739 break; 39740 case bcmPortControlEgressVlanPriUsesPktPri: 39741 #if defined(BCM_TRX_SUPPORT) 39742 if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) { 39743 #if defined (BCM_HGPROXY_COE_SUPPORT) 39744 if (!(soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 39745 BCM_GPORT_IS_SUBPORT_PORT(port))) 39746 #endif 39747 { 39748 BCM_IF_ERROR_RETURN( 39749 _bcm_esw_port_gport_validate(unit, port, &port)); 39750 } 39751 #ifdef BCM_TRIDENT2PLUS_SUPPORT 39752 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 39753 if (soc_feature(unit, soc_feature_egr_all_profile)) { 39754 rv = bcm_esw_port_egr_lport_field_set(unit, 39755 port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DOT1Pf, 39756 value ? 0 : 1); 39757 } else { 39758 #if defined (BCM_HGPROXY_COE_SUPPORT) 39759 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 39760 BCM_GPORT_IS_SUBPORT_PORT(port)) { 39761 rv = bcm_esw_port_egr_lport_field_set( 39762 unit, port, EGR_VLAN_CONTROL_1m, 39763 REMARK_OUTER_DOT1Pf, value ? 0 : 1); 39764 } else 39765 #endif 39766 { 39767 rv = soc_mem_field32_modify( 39768 unit, EGR_VLAN_CONTROL_1m, port, 39769 REMARK_OUTER_DOT1Pf, value ? 0 : 1); 39770 } 39771 } 39772 } else 39773 #endif 39774 { 39775 rv = soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port, 39776 REMARK_OUTER_DOT1Pf, 39777 value ? 0 : 1); 39778 #if defined(BCM_GREYHOUND_SUPPORT) 39779 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 39780 if (BCM_FAILURE(rv)) { 39781 return rv; 39782 } 39783 /* 39784 * Make sure TREAT_PKTPRI_AS_DOT1P bit is set for 39785 * Egress VLAN internal priority mapping. 39786 */ 39787 rv = bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 39788 (unit, (value) ? 1 : -1); 39789 } 39790 #endif /* BCM_GREYHOUND_SUPPORT */ 39791 } 39792 } 39793 #endif /* BCM_TRX_SUPPORT */ 39794 break; 39795 case bcmPortControlEgressModifyDscp: 39796 #if defined(BCM_TRX_SUPPORT) 39797 if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) { 39798 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39799 #ifdef BCM_TRIDENT2PLUS_SUPPORT 39800 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 39801 if (soc_feature(unit, soc_feature_egr_all_profile)) { 39802 rv = bcm_esw_port_egr_lport_field_set(unit, 39803 port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DSCPf, 39804 value ? 1 : 0); 39805 } else { 39806 rv = soc_mem_field32_modify(unit, 39807 EGR_VLAN_CONTROL_1m, port, REMARK_OUTER_DSCPf, 39808 value ? 1 : 0); 39809 } 39810 } else 39811 #endif 39812 { 39813 rv = soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port, 39814 REMARK_OUTER_DSCPf, 39815 value ? 1 : 0); 39816 } 39817 } 39818 #endif /* BCM_TRX_SUPPORT */ 39819 break; 39820 case bcmPortControlIpfixRate: 39821 #ifdef BCM_TRIUMPH2_SUPPORT 39822 if (soc_feature(unit, soc_feature_ipfix_rate)) { 39823 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39824 IPFIX_FLOW_METER_IDf, value); 39825 } 39826 #endif /* BCM_TRIUMPH2_SUPPORT */ 39827 break; 39828 case bcmPortControlCustomerQueuing: 39829 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39830 #ifdef BCM_ENDURO_SUPPORT 39831 if (SOC_IS_ENDURO(unit) && !IS_HG_PORT(unit, port)) { 39832 return BCM_E_UNAVAIL; 39833 } 39834 #endif 39835 #ifdef BCM_HELIX5_SUPPORT 39836 if (SOC_IS_HELIX5(unit) || SOC_IS_HURRICANE4(unit) || 39837 SOC_IS_FIREBOLT6(unit)) { 39838 39839 uint64 rval64, rval64_tmp, rval64_reset_tmp; 39840 soc_reg_t reg; 39841 uint32 phy_port; 39842 uint32 mmu_port; 39843 soc_info_t *si = &SOC_INFO(unit); 39844 39845 if (value < 0 || value > 1) { 39846 return BCM_E_PARAM; 39847 } 39848 39849 COMPILER_64_ZERO(rval64); 39850 COMPILER_64_ZERO(rval64_tmp); 39851 COMPILER_64_ZERO(rval64_reset_tmp); 39852 if (SOC_MEM_IS_VALID(unit, ING_COS_MODEm)) { 39853 rv = soc_mem_field32_modify(unit, ING_COS_MODEm, port, COS_MODEf, value); 39854 BCM_IF_ERROR_RETURN(rv); 39855 } else { 39856 39857 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval64); 39858 BCM_IF_ERROR_RETURN(rv); 39859 soc_reg64_field32_set(unit, ING_COS_MODEr, &rval64, COS_MODEf, 39860 value); 39861 rv = soc_reg_set(unit, ING_COS_MODEr, port, 0, rval64); 39862 BCM_IF_ERROR_RETURN(rv); 39863 39864 phy_port = si->port_l2p_mapping[port]; 39865 mmu_port = si->port_p2m_mapping[phy_port]; 39866 mmu_port &= (SOC_HX5_MMU_PORT_STRIDE - 1); 39867 39868 if (mmu_port < 16) { 39869 reg = COS_MODE_SPLIT0r; /* 2 bits per Port 0-15 */ 39870 COMPILER_64_SET(rval64_tmp, 0, (1 << (mmu_port * 2))); 39871 COMPILER_64_SET(rval64_reset_tmp, 0, (3 << (mmu_port * 2))); 39872 } else { 39873 reg = COS_MODE_64_SPLIT1r; /* 1 bit per Port 16-71 */ 39874 mmu_port -= 16; 39875 if (mmu_port < 32) { 39876 COMPILER_64_SET(rval64_tmp, 0, (1 << mmu_port)); 39877 } else { 39878 COMPILER_64_SET(rval64_tmp, (1 << (mmu_port - 32)), 0); 39879 } 39880 COMPILER_64_COPY(rval64_reset_tmp, rval64_tmp); 39881 } 39882 39883 SOC_IF_ERROR_RETURN 39884 (soc_trident3_xpe_reg_get(unit, reg, -1, si->port_pipe[port], 39885 0, &rval64)); 39886 if (value) { 39887 COMPILER_64_OR(rval64, rval64_tmp); 39888 } else { 39889 COMPILER_64_NOT(rval64_reset_tmp); 39890 COMPILER_64_AND(rval64, rval64_reset_tmp); 39891 } 39892 SOC_IF_ERROR_RETURN 39893 (soc_trident3_xpe_reg_set(unit, reg, -1, si->port_pipe[port], 39894 0, rval64)); 39895 rv = BCM_E_NONE; 39896 } 39897 break; 39898 } 39899 #endif /* BCM_HELIX5_SUPPORT */ 39900 #ifdef BCM_TRIDENT3_SUPPORT 39901 if (SOC_IS_TRIDENT3X(unit)) { 39902 uint64 rval64, rval64_tmp; 39903 soc_reg_t reg; 39904 uint32 pipe_portNum; 39905 soc_info_t *si = &SOC_INFO(unit); 39906 39907 if (value < 0 || value > 1) { 39908 return BCM_E_PARAM; 39909 } 39910 39911 COMPILER_64_ZERO(rval64); 39912 COMPILER_64_ZERO(rval64_tmp); 39913 39914 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval64); 39915 BCM_IF_ERROR_RETURN(rv); 39916 soc_reg64_field32_set(unit, ING_COS_MODEr, &rval64, COS_MODEf, 39917 value); 39918 rv = soc_reg_set(unit, ING_COS_MODEr, port, 0, rval64); 39919 BCM_IF_ERROR_RETURN(rv); 39920 39921 pipe_portNum = port % _TD3_PORTS_PER_PIPE; 39922 if (pipe_portNum < 64) { 39923 reg = COS_MODE_64_SPLIT0r; 39924 } else { 39925 reg = COS_MODE_SPLIT1r; 39926 } 39927 39928 if (pipe_portNum < 32) { 39929 COMPILER_64_SET(rval64_tmp, 0, (1 << pipe_portNum)); 39930 } else { 39931 COMPILER_64_SET(rval64_tmp, (1 << (pipe_portNum - 32)), 0); 39932 } 39933 39934 SOC_IF_ERROR_RETURN 39935 (soc_trident3_xpe_reg_get(unit, reg, -1, si->port_pipe[port], 39936 0, &rval64)); 39937 if (value) { 39938 COMPILER_64_OR(rval64, rval64_tmp); 39939 } else { 39940 COMPILER_64_NOT(rval64_tmp); 39941 COMPILER_64_AND(rval64, rval64_tmp); 39942 } 39943 39944 SOC_IF_ERROR_RETURN 39945 (soc_trident3_xpe_reg_set(unit, reg, -1, si->port_pipe[port], 39946 0, rval64)); 39947 rv = BCM_E_NONE; 39948 break; 39949 } 39950 #endif /* BCM_TRIDENT3_SUPPORT */ 39951 #ifdef BCM_TOMAHAWK_SUPPORT 39952 if (SOC_IS_TOMAHAWKX(unit)) { 39953 uint64 rval64, rval64_tmp; 39954 int pipe, phy_port, mmu_port; 39955 soc_info_t *si; 39956 39957 if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) { 39958 39959 if (value < 0 || value > 1) { 39960 return BCM_E_PARAM; 39961 } 39962 39963 COMPILER_64_ZERO(rval64); 39964 COMPILER_64_ZERO(rval64_tmp); 39965 39966 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval64); 39967 BCM_IF_ERROR_RETURN(rv); 39968 soc_reg64_field32_set(unit, ING_COS_MODEr, &rval64, COS_MODEf, 39969 value); 39970 rv = soc_reg_set(unit, ING_COS_MODEr, port, 0, rval64); 39971 BCM_IF_ERROR_RETURN(rv); 39972 39973 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, port, &pipe)); 39974 si = &SOC_INFO(unit); 39975 phy_port = si->port_l2p_mapping[port]; 39976 mmu_port = si->port_p2m_mapping[phy_port]; 39977 mmu_port &= (SOC_TH_MMU_PORT_STRIDE - 1); 39978 39979 COMPILER_64_SET(rval64_tmp, 0, (1 << mmu_port)); 39980 COMPILER_64_ZERO(rval64); 39981 SOC_IF_ERROR_RETURN 39982 (soc_tomahawk_xpe_reg_get(unit, COS_MODE_64r, -1, pipe, 0, 39983 &rval64)); 39984 if (value) { 39985 COMPILER_64_OR(rval64, rval64_tmp); 39986 } else { 39987 COMPILER_64_NOT(rval64_tmp); 39988 COMPILER_64_AND(rval64, rval64_tmp); 39989 } 39990 39991 SOC_IF_ERROR_RETURN 39992 (soc_tomahawk_xpe_reg_set(unit, COS_MODE_64r, -1, pipe, 0, 39993 rval64)); 39994 rv = BCM_E_NONE; 39995 } 39996 break; 39997 } 39998 #endif /* BCM_TOMAHAWK_SUPPORT */ 39999 40000 #ifdef BCM_TRIDENT2_SUPPORT 40001 if (SOC_IS_TD2_TT2(unit)) { 40002 uint32 fval = 0; 40003 uint64 rval; 40004 40005 if (value <= 4) { 40006 fval = value; 40007 } 40008 40009 if (!SOC_REG_FIELD_VALID(unit, ING_COS_MODE_64r, QUEUE_MODEf)) { 40010 return BCM_E_UNAVAIL; 40011 } 40012 40013 rv = READ_ING_COS_MODE_64r(unit, port, &rval); 40014 BCM_IF_ERROR_RETURN(rv); 40015 40016 soc_reg64_field32_set(unit, ING_COS_MODE_64r, &rval, 40017 QUEUE_MODEf, fval); 40018 rv = WRITE_ING_COS_MODE_64r(unit, port, rval); 40019 break; 40020 } 40021 #endif /* BCM_TRIDENT2_SUPPORT */ 40022 #ifdef BCM_TRIUMPH2_SUPPORT 40023 if (soc_feature(unit, soc_feature_vlan_queue_map)) { 40024 uint32 fval = 0; 40025 if (SOC_IS_TRIUMPH3(unit)) { 40026 if (value <= 4) { 40027 fval = value; 40028 } 40029 } else { 40030 if (value) { 40031 fval = 3; 40032 } else { 40033 fval = 0; 40034 } 40035 } 40036 40037 rv = BCM_E_UNAVAIL; 40038 40039 if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) { 40040 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, SELECTf)) { 40041 rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port, 40042 SELECTf, fval); 40043 } 40044 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, QUEUE_MODEf)) { 40045 rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port, 40046 QUEUE_MODEf, fval); 40047 /* 0 - COS1 port COS, 1 - COS2 vlan COS */ 40048 rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port, 40049 COS_MODEf, 1); 40050 40051 } 40052 } 40053 if (SOC_REG_IS_VALID(unit, COS_MODEr)) { 40054 if (SOC_REG_FIELD_VALID(unit, COS_MODEr, SELECTf)) { 40055 rv = soc_reg_field32_modify(unit, COS_MODEr, REG_PORT_ANY, 40056 SELECTf, fval); 40057 } 40058 } 40059 40060 } 40061 #endif /* BCM_TRIUMPH2_SUPPORT */ 40062 #ifdef BCM_KATANA_SUPPORT 40063 if (SOC_IS_KATANAX(unit)) { 40064 uint32 ing_cos_mode ; 40065 uint32 rqe_cos_mode; 40066 uint32 rval = 0; 40067 /* 40068 * If custom queueing is enabled the ing_cos_mode is set to 1 but 1 is not 40069 * valid for rqe_cos_mode 40070 * setting it to 0 if the ing_cos_mode is 1. 40071 * if value is 4 that means configure service queuing only for unicast 40072 * traffic. i.e if value = 4 then ing_cos_mode = 3 and rqe_cos_mode 0 or 2. 40073 */ if (value == 4) { 40074 ing_cos_mode = 3; 40075 } else { 40076 ing_cos_mode = (value <= 3 ? value : 0); 40077 } 40078 if (IS_HG_PORT(unit, port)) { 40079 rqe_cos_mode = ((ing_cos_mode == 1) || (value == 4)) ? 2 : ing_cos_mode; 40080 } else { 40081 rqe_cos_mode = ((ing_cos_mode == 1) || (value == 4)) ? 0 : ing_cos_mode; 40082 } 40083 40084 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, COS_MODEf)) { 40085 rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port, 40086 COS_MODEf, ing_cos_mode); 40087 } 40088 40089 if (SOC_IS_KATANA(unit)) { 40090 SOC_IF_ERROR_RETURN(READ_RQE_PORT_CONFIGr(unit, port, &rval)); 40091 soc_reg_field_set(unit, RQE_PORT_CONFIGr, &rval, COS_MODEf, 40092 rqe_cos_mode); 40093 SOC_IF_ERROR_RETURN(WRITE_RQE_PORT_CONFIGr(unit, port, rval)); 40094 } else { 40095 #if defined(BCM_KATANA2_SUPPORT) 40096 if (SOC_IS_KATANA2(unit)) { 40097 SOC_IF_ERROR_RETURN(READ_RQE_PP_PORT_CONFIGr(unit, port, &rval)); 40098 soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr, &rval, COS_MODEf, 40099 rqe_cos_mode); 40100 SOC_IF_ERROR_RETURN(WRITE_RQE_PP_PORT_CONFIGr(unit, port, rval)); 40101 } 40102 #endif 40103 } 40104 } 40105 #endif /* BCM_KATANA_SUPPORT */ 40106 break; 40107 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 40108 40109 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT) 40110 case bcmPortControlOAMEnable: 40111 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 40112 OAM_ENABLEf, value ? 1 : 0); 40113 #if defined(BCM_KATANA2_SUPPORT) 40114 if (SOC_IS_KATANA2(unit)) { 40115 rv = _bcm_esw_egr_port_tab_set(unit, port, 40116 OAM_ENABLEf, value ? 1 : 0); 40117 } 40118 #endif 40119 break; 40120 #endif /* defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT) */ 40121 40122 #if defined(BCM_OLP_SUPPORT) 40123 case bcmPortControlOlpEnable: 40124 40125 if (soc_feature(unit, soc_feature_olp)) { 40126 ing_en_efilter_bitmap_entry_t efilter_entry; 40127 bcm_module_t module_id = 0; 40128 bcm_module_t my_modid; 40129 bcm_port_t port_id; 40130 bcm_trunk_t trunk_id = BCM_TRUNK_INVALID; 40131 int local_id; 40132 uint32 olp_enable; 40133 pbmp_t pbmp; 40134 40135 olp_enable = value ? 1 : 0; 40136 40137 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 40138 40139 if (BCM_GPORT_IS_SET(port)) { 40140 SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, &module_id, 40141 &port_id, &trunk_id, &local_id)); 40142 40143 #if defined(BCM_KATANA2_SUPPORT) 40144 if (SOC_IS_KATANA2(unit) && 40145 (BCM_GPORT_IS_SUBPORT_PORT(port)) && 40146 ((_BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) || 40147 (_BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)))) { 40148 40149 LOG_ERROR(BSL_LS_BCM_L2, 40150 (BSL_META_U(unit, 40151 "OLP is not allowed on SUBPORT. \ 40152 \n"))); 40153 return BCM_E_PARAM; 40154 } 40155 #endif 40156 } else { 40157 port_id = port; 40158 } 40159 if ((module_id == 0) || (module_id == my_modid)) { 40160 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 40161 if(SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 40162 iarb_ing_port_table_entry_t entry; 40163 port_tab_entry_t port_entry; 40164 uint64 mac; 40165 int prefix_check = 0; 40166 40167 SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PORT_TABLEm, 40168 MEM_BLOCK_ANY, port_id, &entry)); 40169 soc_IARB_ING_PORT_TABLEm_field32_set(unit, &entry, 40170 OLP_ENABLEf, olp_enable); 40171 SOC_IF_ERROR_RETURN(soc_mem_write(unit, IARB_ING_PORT_TABLEm, 40172 MEM_BLOCK_ALL, port_id, &entry)); 40173 40174 40175 /* Enable/Disable the prefix checking on the OLP port 40176 * If OLP is being enabled - Disable prefix checking 40177 * If OLP is being disabled - Enable prefix checking if it 40178 * is configured. 40179 */ 40180 prefix_check = 0; 40181 if (0 == olp_enable) { 40182 SOC_IF_ERROR_RETURN(READ_ING_OLP_CONFIG_0_64r(unit, &mac)); 40183 if (!COMPILER_64_IS_ZERO(mac)) { 40184 prefix_check = 1; 40185 } 40186 } 40187 SOC_IF_ERROR_RETURN(READ_PORT_TABm(unit, 40188 MEM_BLOCK_ANY, 40189 port_id, 40190 &port_entry)); 40191 soc_PORT_TABm_field32_set(unit, 40192 &port_entry, 40193 OLP_MAC_DA_PREFIX_CHECK_ENABLEf, 40194 prefix_check); 40195 40196 SOC_IF_ERROR_RETURN(WRITE_PORT_TABm(unit, 40197 MEM_BLOCK_ALL, 40198 port_id, 40199 &port_entry)); 40200 } else 40201 #endif 40202 { 40203 iarb_ing_physical_port_entry_t entry; 40204 ing_physical_port_table_entry_t port_entry; 40205 uint64 mac; 40206 int prefix_check = 0; 40207 40208 SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PHYSICAL_PORTm, 40209 MEM_BLOCK_ANY, port_id, &entry)); 40210 soc_IARB_ING_PHYSICAL_PORTm_field32_set(unit, &entry, 40211 OLP_ENABLEf, olp_enable); 40212 SOC_IF_ERROR_RETURN(soc_mem_write(unit, IARB_ING_PHYSICAL_PORTm, 40213 MEM_BLOCK_ALL, port_id, &entry)); 40214 40215 /* Enable/Disable the prefix checking on the OLP port 40216 * If OLP is being enabled - Disable prefix checking 40217 * If OLP is being disabled - Enable prefix checking if it 40218 * is configured. 40219 */ 40220 prefix_check = 0; 40221 if (0 == olp_enable) { 40222 SOC_IF_ERROR_RETURN(READ_ING_OLP_CONFIG_0_64r(unit, &mac)); 40223 if (!COMPILER_64_IS_ZERO(mac)) { 40224 prefix_check = 1; 40225 } 40226 } 40227 SOC_IF_ERROR_RETURN( 40228 READ_ING_PHYSICAL_PORT_TABLEm(unit, 40229 MEM_BLOCK_ANY, 40230 port_id, 40231 &port_entry)); 40232 40233 soc_ING_PHYSICAL_PORT_TABLEm_field32_set(unit, 40234 &port_entry, 40235 OLP_MAC_DA_PREFIX_CHECK_ENABLEf, 40236 prefix_check); 40237 SOC_IF_ERROR_RETURN( 40238 WRITE_ING_PHYSICAL_PORT_TABLEm(unit, 40239 MEM_BLOCK_ALL, 40240 port_id, 40241 &port_entry)); 40242 } 40243 /* Disable EFILTER */ 40244 SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm, 40245 MEM_BLOCK_ANY, 0, &efilter_entry)); 40246 soc_mem_pbmp_field_get(unit, ING_EN_EFILTER_BITMAPm, 40247 &efilter_entry, BITMAPf, &pbmp); 40248 if (olp_enable) { 40249 SOC_PBMP_PORT_REMOVE(pbmp, port_id); 40250 } else { 40251 SOC_PBMP_PORT_ADD(pbmp, port_id); 40252 } 40253 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, 40254 &efilter_entry, BITMAPf, &pbmp); 40255 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm, 40256 MEM_BLOCK_ALL, 0, &efilter_entry)); 40257 } 40258 rv = BCM_E_NONE; 40259 } 40260 break; 40261 #endif /* BCM_OLP_SUPPORT */ 40262 40263 #if defined(BCM_KATANA2_SUPPORT) || defined (BCM_APACHE_SUPPORT) 40264 case bcmPortControlPortMacOui: 40265 case bcmPortControlPortMacNonOui: 40266 40267 /* 40268 * In case of KT2, SB2 and TD2+ NONTCAM STATION related to OAM, OLP, XGS can be programmed 40269 * by either of bcm_l2_station_xxx API or bcm_switch_olp_l2_addr_xxx 40270 * 40271 * Use either of two set of APIs 40272 */ 40273 40274 if (_BCM_SWITCH_OLP_APIV(unit) == _BCM_SWITCH_OLP_L2_STATION_API) { 40275 LOG_VERBOSE(BSL_LS_BCM_L2, 40276 (BSL_META_U(unit, 40277 "use bcm_l2_station_xxx API\n"))); 40278 return BCM_E_UNAVAIL; 40279 } 40280 _BCM_SWITCH_OLP_APIV_SET(unit, _BCM_SWITCH_OLP_TRUE_API); 40281 40282 #if defined(BCM_KATANA2_SUPPORT) 40283 if (SOC_IS_KATANA2(unit) && 40284 (soc_feature(unit, soc_feature_oam) || 40285 soc_feature(unit, soc_feature_sat))) { 40286 uint32 val_lo, val_hi; 40287 uint64 mac_field; 40288 40289 PORT_LOCK(unit); 40290 40291 rv = _bcm_kt2_port_mac_get(unit, port, &mac_field); 40292 40293 if (BCM_FAILURE(rv)) { 40294 PORT_UNLOCK(unit); 40295 return (rv); 40296 } 40297 40298 COMPILER_64_TO_32_LO(val_lo, mac_field); 40299 COMPILER_64_TO_32_HI(val_hi, mac_field); 40300 40301 switch (type) { 40302 case bcmPortControlPortMacOui: 40303 val_lo = (val_lo & 0xffffff) | ((value & 0xff) << 24); 40304 val_hi = (value >> 8) & 0xffff; 40305 COMPILER_64_SET(mac_field, val_hi, val_lo); 40306 break; 40307 40308 case bcmPortControlPortMacNonOui: 40309 val_lo = (val_lo & 0xff000000) | (value & 0xffffff); 40310 COMPILER_64_SET(mac_field, val_hi, val_lo); 40311 break; 40312 40313 default: 40314 break; 40315 } 40316 40317 rv = _bcm_kt2_port_mac_set(unit, port, mac_field); 40318 PORT_UNLOCK(unit); 40319 } 40320 #endif /* BCM_KATANA2_SUPPORT */ 40321 40322 #if defined(BCM_MONTEREY_SUPPORT) 40323 if (SOC_IS_MONTEREY(unit)) { 40324 PORT_LOCK(unit); 40325 rv = _bcm_monterey_port_mac_set(unit, 40326 port, 40327 type == bcmPortControlPortMacOui, 40328 value); 40329 PORT_UNLOCK(unit); 40330 } 40331 #endif /* BCM_MONTEREY_SUPPORT */ 40332 #if defined(BCM_APACHE_SUPPORT) 40333 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 40334 PORT_LOCK(unit); 40335 rv = _bcm_apache_port_mac_set(unit, 40336 port, 40337 type == bcmPortControlPortMacOui, 40338 value); 40339 PORT_UNLOCK(unit); 40340 } 40341 #endif /* BCM_APACHE_SUPPORT */ 40342 break; 40343 #endif /* BCM_KATANA2_SUPPORT || BCM_APACHE_SUPPORT */ 40344 #ifdef BCM_TRX_SUPPORT 40345 case bcmPortControlOamLoopback: 40346 if (SOC_IS_TRX(unit) && !SOC_IS_HURRICANE(unit) 40347 && !SOC_IS_SHADOW(unit)) { 40348 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 40349 40350 if (soc_reg_field_valid(unit,ING_MISC_PORT_CONFIGr, 40351 OAM_DO_NOT_MODIFYf)) { 40352 40353 rv = soc_reg_field32_modify(unit, ING_MISC_PORT_CONFIGr, port, 40354 OAM_DO_NOT_MODIFYf, value ? 1 : 0); 40355 } else { 40356 return BCM_E_UNAVAIL; 40357 } 40358 } 40359 40360 break; 40361 #endif /* BCM_TRX_SUPPORT */ 40362 40363 case bcmPortControlLanes: 40364 if (soc_feature(unit, soc_feature_flexport_no_legacy)) { 40365 return BCM_E_UNAVAIL; 40366 } 40367 #if defined(BCM_TRIUMPH2_SUPPORT) 40368 if (soc_feature(unit, soc_feature_flex_port)) { 40369 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 40370 #ifdef BCM_TRIDENT_SUPPORT 40371 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 40372 bcm_port_t phy_port; 40373 int bindex; 40374 40375 if (!SOC_PORT_VALID(unit, port)) { 40376 return BCM_E_PORT; 40377 } 40378 if (value != 1 && value != 2 && value != 4) { 40379 return BCM_E_PARAM; 40380 } 40381 /* coverity[overrun-local : FALSE] */ 40382 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 40383 bindex = SOC_PORT_BINDEX(unit, phy_port); 40384 if (bindex & (value - 1)) { /* port alignment check */ 40385 return BCM_E_PARAM; 40386 } 40387 } 40388 #endif /* BCM_TRIDENT_SUPPORT */ 40389 _bcm_esw_port_mirror_lock(unit); 40390 40391 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT 40392 if (soc_feature(unit, soc_feature_xgs5_flexport_legacy_mode)) { 40393 rv = bcmi_xgs5_port_lanes_set(unit, port, value); 40394 } 40395 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */ 40396 #if defined(BCM_ENDURO_SUPPORT) 40397 if (SOC_IS_ENDURO(unit)) { 40398 rv = _bcm_en_port_lanes_set(unit, port, value); 40399 } else 40400 #endif 40401 #if defined(BCM_HURRICANE1_SUPPORT) 40402 if (SOC_IS_HURRICANE(unit)) { 40403 rv = _bcm_hu_port_lanes_set(unit, port, value); 40404 } else 40405 #endif 40406 #if defined(BCM_HURRICANE2_SUPPORT) 40407 if (SOC_IS_HURRICANE2(unit)) { 40408 rv = _bcm_hu2_port_lanes_set(unit, port, value); 40409 } else 40410 #endif 40411 #ifdef BCM_TOMAHAWK_SUPPORT 40412 if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TRIDENT3X(unit)) { 40413 /* coverity[overrun-call : FALSE] */ 40414 rv = _bcm_th_port_lanes_set(unit, port, value); 40415 } else 40416 #endif 40417 #if defined(BCM_MONTEREY_SUPPORT) 40418 if (SOC_IS_MONTEREY(unit)) { 40419 rv = bcmi_monterey_port_lanes_set(unit, port, value); 40420 } else 40421 #endif 40422 #if defined(BCM_APACHE_SUPPORT) 40423 if (SOC_IS_APACHE(unit)) { 40424 rv = bcmi_apache_port_lanes_set(unit, port, value); 40425 } else 40426 #endif 40427 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 40428 if (SOC_IS_TD2P_TT2P(unit)) { 40429 rv = bcmi_td2p_port_lanes_set(unit, port, value); 40430 } else 40431 #endif 40432 #ifdef BCM_TRIDENT2_SUPPORT 40433 if (SOC_IS_TD2_TT2(unit)) { 40434 rv = _bcm_td2_port_lanes_set(unit, port, value); 40435 _bcm_flex_port_phy_control_software_rx_los_get(unit, port); 40436 } else 40437 #endif 40438 #ifdef BCM_TRIDENT_SUPPORT 40439 if (SOC_IS_TD_TT(unit)) { 40440 /* coverity[overrun-call : FALSE] */ 40441 rv = _bcm_td_port_lanes_set(unit, port, value); 40442 } else 40443 #endif /* BCM_TRIDENT_SUPPORT */ 40444 #ifdef BCM_SHADOW_SUPPORT 40445 if (SOC_IS_SHADOW(unit)) { 40446 soc_info_t *si = NULL; 40447 int okay; 40448 int i; 40449 40450 rv = _bcm_shadow_port_lanes_set(unit, port, value); 40451 if (BCM_SUCCESS(rv)) { 40452 si = &SOC_INFO(unit); 40453 if (value == 1) { /* Probe other ports */ 40454 for (i = port; i < port+4; i++) { 40455 rv = soc_phyctrl_detach(unit, i); 40456 if (SOC_FAILURE(rv)) { 40457 _bcm_esw_port_mirror_unlock(unit); 40458 return (rv); 40459 } 40460 } 40461 for (i = port; i < port+4; i++) { 40462 /* coverity[overrun-local : FALSE] */ 40463 si->port_num_lanes[i] = value; 40464 rv = _bcm_port_probe(unit, i, &okay); 40465 } 40466 } else if (value == 4) { /* Probe other ports */ 40467 si = &SOC_INFO(unit); 40468 for (i = port; i < port+4; i++) { 40469 rv = soc_phyctrl_detach(unit, i); 40470 if (SOC_FAILURE(rv)) { 40471 _bcm_esw_port_mirror_unlock(unit); 40472 return (rv); 40473 } 40474 } 40475 /* coverity[overrun-local : FALSE] */ 40476 si->port_num_lanes[port] = value; 40477 rv = _bcm_port_probe(unit, port, &okay); 40478 } 40479 } 40480 } else 40481 #endif /* BCM_SHADOW_SUPPORT */ 40482 #ifdef BCM_TRIUMPH3_SUPPORT 40483 if (SOC_IS_TRIUMPH3(unit)) { 40484 if (!SOC_IS_HELIX4(unit) && (_tr3_port_config_id[unit] == 112 || 40485 _tr3_port_config_id[unit] == 12)&& 40486 (port == 54 || port == 55)) { 40487 _bcm_esw_port_mirror_unlock(unit); 40488 return BCM_E_PARAM; 40489 } 40490 COUNTER_LOCK(unit); 40491 rv = _bcm_tr3_port_lanes_set(unit, port, value); 40492 COUNTER_UNLOCK(unit); 40493 } else 40494 #endif /* BCM_TRIUMPH3_SUPPORT */ 40495 #ifdef BCM_METROLITE_SUPPORT 40496 if (SOC_IS_METROLITE(unit)) { 40497 COUNTER_LOCK(unit); 40498 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 40499 rv = _bcm_ml_port_lanes_set(unit, port, value); 40500 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 40501 COUNTER_UNLOCK(unit); 40502 } else 40503 #endif /* BCM_METROLITE_SUPPORT */ 40504 #ifdef BCM_SABER2_SUPPORT 40505 if (SOC_IS_SABER2(unit)) { 40506 COUNTER_LOCK(unit); 40507 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 40508 rv = _bcm_sb2_port_lanes_set(unit, port, value); 40509 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 40510 COUNTER_UNLOCK(unit); 40511 } else 40512 #endif /* BCM_SABER2_SUPPORT */ 40513 #ifdef BCM_KATANA2_SUPPORT 40514 if (SOC_IS_KATANA2(unit)) { 40515 COUNTER_LOCK(unit); 40516 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 40517 rv = _bcm_kt2_port_lanes_set(unit, port, value); 40518 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 40519 COUNTER_UNLOCK(unit); 40520 } else 40521 #endif /* BCM_KATANA2_SUPPORT */ 40522 { 40523 rv = _bcm_tr2_port_lanes_set(unit, port, value); 40524 } 40525 _bcm_esw_port_mirror_unlock(unit); 40526 #ifdef BCM_METROLITE_SUPPORT 40527 if (BCM_SUCCESS(rv) && SOC_IS_METROLITE(unit)) { 40528 COUNTER_LOCK(unit); 40529 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 40530 rv = _bcm_ml_port_lanes_set_post_operation(unit, port); 40531 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 40532 COUNTER_UNLOCK(unit); 40533 } else 40534 #endif /* BCM_METROLITE_SUPPORT */ 40535 #ifdef BCM_SABER2_SUPPORT 40536 if (BCM_SUCCESS(rv) && SOC_IS_SABER2(unit)) { 40537 COUNTER_LOCK(unit); 40538 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 40539 rv = _bcm_sb2_port_lanes_set_post_operation(unit, port); 40540 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 40541 COUNTER_UNLOCK(unit); 40542 } else 40543 #endif 40544 #ifdef BCM_KATANA2_SUPPORT 40545 /* Dead Lock (with port lock) so calling separately */ 40546 if (BCM_SUCCESS(rv) && SOC_IS_KATANA2(unit)) { 40547 COUNTER_LOCK(unit); 40548 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 40549 rv = _bcm_kt2_port_lanes_set_post_operation(unit, port); 40550 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 40551 COUNTER_UNLOCK(unit); 40552 } 40553 #endif 40554 } 40555 #endif 40556 break; 40557 40558 case bcmPortControlPFCEthertype: 40559 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 40560 if (soc_feature(unit, soc_feature_priority_flow_control)) { 40561 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 40562 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 40563 /* IS_GX_PORT == IS_XL_PORT */ 40564 return BCM_E_PORT; 40565 } 40566 if (value < 0 || value > 0xffff) { 40567 return BCM_E_PARAM; 40568 } 40569 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40570 SOC_MAC_CONTROL_PFC_TYPE, value); 40571 } 40572 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 40573 break; 40574 40575 case bcmPortControlPFCOpcode: 40576 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 40577 if (soc_feature(unit, soc_feature_priority_flow_control)) { 40578 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 40579 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 40580 /* IS_GX_PORT == IS_XL_PORT */ 40581 return BCM_E_PORT; 40582 } 40583 if (value < 0 || value > 0xffff) { 40584 return BCM_E_PARAM; 40585 } 40586 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40587 SOC_MAC_CONTROL_PFC_OPCODE, value); 40588 } 40589 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 40590 break; 40591 40592 case bcmPortControlPFCReceive: 40593 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 40594 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 40595 if (soc_feature(unit, soc_feature_priority_flow_control)) { 40596 int pfc_enable; 40597 int val_count = 0; 40598 soc_reg_t reg; 40599 uint32 values[2]; 40600 soc_field_t fields[] = {PFC_ENABLEf, LLFC_ENf}; 40601 40602 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 40603 /* IS_GX_PORT == IS_XL_PORT */ 40604 return BCM_E_PORT; 40605 } 40606 40607 BCM_IF_ERROR_RETURN 40608 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40609 SOC_MAC_CONTROL_PFC_RX_ENABLE, value)); 40610 if (value == 0) { 40611 BCM_IF_ERROR_RETURN 40612 (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 40613 SOC_MAC_CONTROL_PFC_TX_ENABLE, 40614 &pfc_enable)); 40615 } else { 40616 pfc_enable = TRUE; 40617 } 40618 40619 if (SOC_IS_SC_CQ(unit)) { 40620 BCM_IF_ERROR_RETURN 40621 (soc_reg_field32_modify(unit, MMU_LLFC_RX_CONFIGr, 40622 port, RX_ENABLEf, value ? 1 : 0)); 40623 } 40624 40625 if (value == 0) { 40626 /* Disabling RX, flush MMU XOFF state */ 40627 BCM_IF_ERROR_RETURN 40628 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40629 SOC_MAC_CONTROL_PFC_FORCE_XON, 1)); 40630 BCM_IF_ERROR_RETURN 40631 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40632 SOC_MAC_CONTROL_PFC_FORCE_XON, 0)); 40633 } 40634 40635 /* Port config settings */ 40636 values[0] = pfc_enable ? 1 : 0; 40637 values[1] = 0; 40638 40639 if (SOC_IS_TD2_TT2(unit)) { 40640 reg = INVALIDr; 40641 } else if (SOC_IS_TD_TT(unit) || SOC_IS_SHADOW(unit)) { 40642 reg = XLPORT_CONFIGr; 40643 val_count=2; 40644 } else if (SOC_IS_TRIUMPH3(unit)) { 40645 reg = PORT_CONFIGr; 40646 val_count=2; 40647 } else if (SOC_IS_SABER2(unit)) { 40648 /* No port level config required */ 40649 reg = INVALIDr; 40650 val_count = 0; 40651 } else if (SOC_IS_KATANAX(unit)) { 40652 reg = XPORT_CONFIGr; 40653 val_count=2; 40654 } else { 40655 reg = INVALIDr; 40656 } 40657 40658 if (val_count > 0) { 40659 BCM_IF_ERROR_RETURN 40660 (soc_reg_fields32_modify(unit, reg, port, 40661 COUNTOF(values), fields, values)); 40662 } else if (SOC_IS_TD2_TT2(unit)) { 40663 ; 40664 } else if (SOC_IS_SC_CQ(unit) || SOC_IS_TR_VL(unit)) { 40665 if (SOC_REG_IS_VALID(unit, PPFC_ENr)) { 40666 /* Feature enable */ 40667 BCM_IF_ERROR_RETURN 40668 (soc_reg_field32_modify(unit, PPFC_ENr, port, 40669 PPFC_FEATURE_ENf, 40670 pfc_enable ? 1 : 0)); 40671 } 40672 if (soc_reg_field_valid(unit, XPORT_CONFIGr, PPP_ENABLEf)) { 40673 BCM_IF_ERROR_RETURN 40674 (soc_reg_field32_modify(unit, XPORT_CONFIGr, 40675 port, PPP_ENABLEf, 40676 pfc_enable ? 1 : 0)); 40677 } 40678 } 40679 40680 /* Stats enable */ 40681 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40682 SOC_MAC_CONTROL_PFC_STATS_ENABLE, 40683 pfc_enable ? 1 : 0); 40684 40685 if (SOC_REG_IS_VALID(unit, XPORT_TO_MMU_BKPr) && pfc_enable == 0) { 40686 BCM_IF_ERROR_RETURN(WRITE_XPORT_TO_MMU_BKPr(unit, port, 0)); 40687 } 40688 } 40689 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 40690 break; 40691 40692 case bcmPortControlPFCTransmit: 40693 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 40694 if (soc_feature(unit, soc_feature_priority_flow_control)) { 40695 rv = _bcm_sc_tr_port_pfc_tx_set(unit, port, (value)? 0xffff : 0); 40696 } 40697 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 40698 break; 40699 40700 case bcmPortControlPFCClasses: 40701 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 40702 if (soc_feature(unit, soc_feature_priority_flow_control)) { 40703 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 40704 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 40705 /* IS_GX_PORT == IS_XL_PORT */ 40706 return BCM_E_PORT; 40707 } 40708 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40709 SOC_MAC_CONTROL_PFC_CLASSES, value); 40710 } 40711 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 40712 break; 40713 40714 case bcmPortControlPFCPassFrames: 40715 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 40716 if (soc_feature(unit, soc_feature_priority_flow_control)) { 40717 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 40718 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 40719 /* IS_GX_PORT == IS_XL_PORT */ 40720 return BCM_E_PORT; 40721 } 40722 if(soc_feature(unit, soc_feature_pgw_mac_pfc_frame)) { 40723 uint32 rval32 = 0; 40724 soc_reg_t reg = INVALIDr; 40725 if(SOC_REG_IS_VALID(unit, PGW_MAC_RSV_MASKr)) { 40726 reg = PGW_MAC_RSV_MASKr; 40727 } else if(IS_CL_PORT(unit, port) && 40728 SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) { 40729 reg = CLPORT_MAC_RSV_MASKr; 40730 } else if(IS_XL_PORT(unit, port) && 40731 SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) { 40732 reg = XLPORT_MAC_RSV_MASKr; 40733 } else { 40734 reg = INVALIDr; 40735 } 40736 40737 if (reg != INVALIDr) { 40738 PORT_LOCK(unit); 40739 rv = soc_reg32_get(unit, reg, port, 0, &rval32); 40740 if (BCM_SUCCESS(rv)) { 40741 /* xxx_MAC_RSV_MASK: Bit 18 PFC frame detected 40742 * Enable PFC Frame : Set 0. Go through 40743 * Disable PFC Frame : Set 1. Purged. 40744 */ 40745 if(value) { 40746 rval32 &= ~(1 << 18); 40747 } else { 40748 rval32 |= (1 << 18); 40749 } 40750 rv = soc_reg32_set(unit, reg, port, 0, rval32); 40751 } 40752 PORT_UNLOCK(unit); 40753 } else { 40754 rv = BCM_E_UNAVAIL; 40755 } 40756 } else { 40757 PORT_LOCK(unit); 40758 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40759 SOC_MAC_CONTROL_PFC_RX_PASS, value); 40760 PORT_UNLOCK(unit); 40761 } 40762 } 40763 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 40764 break; 40765 40766 case bcmPortControlPFCDestMacOui: 40767 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 40768 if (soc_feature(unit, soc_feature_priority_flow_control)) { 40769 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 40770 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 40771 /* IS_GX_PORT == IS_XL_PORT */ 40772 return BCM_E_PORT; 40773 } 40774 if (value < 0 || value > 0xffffff) { 40775 return BCM_E_PARAM; 40776 } 40777 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40778 SOC_MAC_CONTROL_PFC_MAC_DA_OUI, value); 40779 } 40780 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 40781 break; 40782 40783 case bcmPortControlPFCDestMacNonOui: 40784 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 40785 if (soc_feature(unit, soc_feature_priority_flow_control)) { 40786 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 40787 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 40788 /* IS_GX_PORT == IS_XL_PORT */ 40789 return BCM_E_PORT; 40790 } 40791 if (value < 0 || value > 0xffffff) { 40792 return BCM_E_PARAM; 40793 } 40794 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40795 SOC_MAC_CONTROL_PFC_MAC_DA_NONOUI, value); 40796 } 40797 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 40798 break; 40799 40800 case bcmPortControlPFCRefreshTime: 40801 #if defined(BCM_TRIDENT_SUPPORT)||defined(BCM_GREYHOUND_SUPPORT) 40802 if (soc_feature(unit, soc_feature_priority_flow_control)) { 40803 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 40804 if (value < 0 || value > 0xffff) { 40805 return BCM_E_PARAM; 40806 } 40807 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40808 SOC_MAC_CONTROL_PFC_REFRESH_TIME, value); 40809 } 40810 #endif /* BCM_TRIDENT_SUPPORT */ 40811 break; 40812 40813 case bcmPortControlPFCXOffTime: 40814 #if defined(BCM_TRIDENT_SUPPORT)||defined(BCM_GREYHOUND_SUPPORT) 40815 if (soc_feature(unit, soc_feature_priority_flow_control)) { 40816 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 40817 if (value < 0 || value > 0xffff) { 40818 return BCM_E_PARAM; 40819 } 40820 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40821 SOC_MAC_CONTROL_PFC_XOFF_TIME, value); 40822 } 40823 #endif /* BCM_TRIDENT_SUPPORT */ 40824 break; 40825 40826 case bcmPortControlVrf: 40827 rv = _bcm_esw_port_vrf_set(unit, port, value); 40828 break; 40829 40830 case bcmPortControlL3Ingress: 40831 #if defined(BCM_TRIUMPH_SUPPORT) 40832 if (!soc_feature(unit, soc_feature_l3_ingress_interface)) { 40833 return BCM_E_UNAVAIL; 40834 } 40835 40836 if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, L3_IIFf)) { 40837 if ((value >= 1) && (value < soc_mem_index_count(unit, L3_IIFm))) { 40838 #if defined(BCM_KATANA2_SUPPORT) 40839 if (SOC_IS_KATANA2(unit)) { 40840 rv = _bcm_kt2_source_trunk_map_set(unit, port, L3_IIFf, value); 40841 } else 40842 #endif 40843 { 40844 rv = _bcm_trx_source_trunk_map_set(unit, port, L3_IIFf, value); 40845 } 40846 BCM_IF_ERROR_RETURN(rv); 40847 if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf) || 40848 SOC_IS_TRIDENT3X(unit)) { 40849 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 40850 PORT_OPERATIONf, 0x2); 40851 } 40852 } else { 40853 #if defined(BCM_KATANA2_SUPPORT) 40854 if (SOC_IS_KATANA2(unit)) { 40855 rv = _bcm_kt2_source_trunk_map_set(unit, port, L3_IIFf, 0); 40856 } else 40857 #endif 40858 { 40859 rv = _bcm_trx_source_trunk_map_set(unit, port, L3_IIFf, 0); 40860 } 40861 BCM_IF_ERROR_RETURN(rv); 40862 if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf)) { 40863 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 40864 PORT_OPERATIONf, 0x0); 40865 } 40866 } 40867 } 40868 #endif /* BCM_TRIUMPH_SUPPORT */ 40869 break; 40870 40871 case bcmPortControlL2Learn: 40872 #if defined(BCM_TRX_SUPPORT) 40873 if (SOC_IS_TRX(unit)) { 40874 uint32 hw_val = 0; 40875 bcm_port_cfg_t port_cfg; 40876 40877 BCM_IF_ERROR_RETURN( 40878 _bcm_trx_port_cml_flags2hw(unit, value, &hw_val)); 40879 BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg)); 40880 port_cfg.pc_cml = hw_val; 40881 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &port_cfg); 40882 } 40883 #endif /* BCM_TRX_SUPPORT */ 40884 break; 40885 40886 case bcmPortControlL2Move: 40887 #if defined(BCM_TRX_SUPPORT) 40888 if (SOC_IS_TRX(unit)) { 40889 uint32 hw_val = 0; 40890 bcm_port_cfg_t port_cfg; 40891 40892 BCM_IF_ERROR_RETURN( 40893 _bcm_trx_port_cml_flags2hw(unit, value, &hw_val)); 40894 BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg)); 40895 port_cfg.pc_cml_move = hw_val; 40896 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &port_cfg); 40897 } 40898 #endif /* BCM_TRX_SUPPORT */ 40899 break; 40900 40901 case bcmPortControlForwardStaticL2MovePkt: 40902 #if defined(BCM_TRX_SUPPORT) 40903 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 40904 DISABLE_STATIC_MOVE_DROPf, value ? 1 : 0); 40905 #endif /* BCM_TRX_SUPPORT */ 40906 break; 40907 40908 case bcmPortControlPrbsMode: 40909 if (value != 0) { 40910 return BCM_E_PARAM; 40911 } 40912 rv = BCM_E_NONE; 40913 break; 40914 40915 case bcmPortControlPrbsPolynomial: 40916 /*prbs polynomial value check*/ 40917 if((value < BCM_PORT_PRBS_POLYNOMIAL_X7_X6_1) 40918 || (value > BCM_PORT_PRBS_POLYNOMIAL_PAM4_13Q)) 40919 { 40920 return BCM_E_PARAM; 40921 } 40922 PORT_LOCK(unit); 40923 rv = soc_phyctrl_control_set(unit, port, 40924 SOC_PHY_CONTROL_PRBS_POLYNOMIAL, value); 40925 PORT_UNLOCK(unit); 40926 break; 40927 case bcmPortControlPrbsTxEnable: 40928 PORT_LOCK(unit); 40929 rv = soc_phyctrl_control_set(unit, port, 40930 SOC_PHY_CONTROL_PRBS_TX_ENABLE, value); 40931 PORT_UNLOCK(unit); 40932 break; 40933 40934 case bcmPortControlPrbsRxEnable: 40935 PORT_LOCK(unit); 40936 rv = soc_phyctrl_control_set(unit, port, 40937 SOC_PHY_CONTROL_PRBS_RX_ENABLE, value); 40938 PORT_UNLOCK(unit); 40939 break; 40940 40941 case bcmPortControlPrbsTxInvertData: 40942 PORT_LOCK(unit); 40943 rv = soc_phyctrl_control_set(unit, port, 40944 SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA, 40945 value); 40946 PORT_UNLOCK(unit); 40947 break; 40948 40949 case bcmPortControlLinkFaultLocalEnable: 40950 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40951 SOC_MAC_CONTROL_FAULT_LOCAL_ENABLE, value); 40952 break; 40953 case bcmPortControlLinkFaultRemoteEnable: 40954 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40955 SOC_MAC_CONTROL_FAULT_REMOTE_ENABLE, value); 40956 break; 40957 case bcmPortControlSerdesDriverTune: 40958 PORT_LOCK(unit); 40959 rv = soc_phyctrl_control_set(unit, port, 40960 SOC_PHY_CONTROL_SERDES_DRIVER_TUNE, value); 40961 PORT_UNLOCK(unit); 40962 break; 40963 case bcmPortControlLinkdownTransmit: 40964 PORT_LOCK(unit); 40965 rv = soc_phyctrl_control_set(unit, port, 40966 SOC_PHY_CONTROL_LINKDOWN_TRANSMIT, value); 40967 PORT_UNLOCK(unit); 40968 /* Most of PHYs have nothing to configure and simply return UNAVAIL*/ 40969 if ((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL)) { 40970 BCM_IF_ERROR_RETURN(_bcm_esw_link_down_tx_set(unit, port, value)); 40971 #ifdef BCM_HURRICANE4_SUPPORT 40972 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) { 40973 return rv; 40974 } 40975 #endif 40976 #if defined(BCM_TRIUMPH3_SUPPORT) 40977 if (SOC_REG_PORT_VALID(unit, XMAC_RX_LSS_CTRLr, port)) { 40978 rv = soc_reg_field32_modify(unit, XMAC_RX_LSS_CTRLr, 40979 port, LOCAL_FAULT_DISABLEf, (value ? 1 : 0)); 40980 } else if (SOC_REG_PORT_VALID(unit, XLMAC_RX_LSS_CTRLr, port)) { 40981 rv = soc_reg_field32_modify(unit, XLMAC_RX_LSS_CTRLr, 40982 port, LOCAL_FAULT_DISABLEf, (value ? 1 : 0)); 40983 } 40984 #endif 40985 } 40986 break; 40987 case bcmPortControlSerdesTuneMarginMode: 40988 PORT_LOCK(unit); 40989 rv = soc_phyctrl_control_set(unit, port, 40990 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_MODE, value); 40991 PORT_UNLOCK(unit); 40992 break; 40993 case bcmPortControlSerdesTuneMarginValue: 40994 PORT_LOCK(unit); 40995 rv = soc_phyctrl_control_set(unit, port, 40996 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_VALUE, value); 40997 PORT_UNLOCK(unit); 40998 break; 40999 case bcmPortControlStatOversize: 41000 rv = _bcm_esw_stat_ovr_threshold_set(unit, port, value); 41001 break; 41002 41003 case bcmPortControlStatOversizeIsError: 41004 rv = _bcm_esw_stat_ovr_error_control_set(unit, port, value); 41005 break; 41006 41007 case bcmPortControlTimestampEnable: 41008 #if defined(BCM_HAWKEYE_SUPPORT) 41009 if (SOC_IS_HAWKEYE(unit)) { 41010 uint32 rval; 41011 if (!SOC_PORT_VALID(unit, port)) { 41012 return BCM_E_PORT; 41013 } 41014 SOC_IF_ERROR_RETURN(READ_EAV_ENABLE_BMAPr(unit, &rval)); 41015 if (value) { 41016 /* coverity[BAD_SHIFT: FALSE] */ 41017 rval |= (port >= 32 ? 0 : (1 << port)); 41018 } else { 41019 /* coverity[BAD_SHIFT: FALSE] */ 41020 rval &= ~(port >= 32 ? 0 : (1 << port)); 41021 } 41022 SOC_IF_ERROR_RETURN(WRITE_EAV_ENABLE_BMAPr(unit, rval)); 41023 41024 /* Enable MMU */ 41025 SOC_IF_ERROR_RETURN(WRITE_MMUEAVENABLEr(unit, rval)); 41026 41027 /* Program EGR_PORT register */ 41028 SOC_IF_ERROR_RETURN(READ_EGR_PORTr(unit, port, &rval)); 41029 soc_reg_field_set(unit, EGR_PORTr, &rval, EAV_CAPABLEf, value); 41030 SOC_IF_ERROR_RETURN(WRITE_EGR_PORTr(unit, port, rval)); 41031 41032 rv = BCM_E_NONE; 41033 } else 41034 #endif /* BCM_HAWKEYE_SUPPORT */ 41035 if (soc_feature (unit, soc_feature_xlmac_timestamp_disable)) { 41036 if (IS_XL_PORT(unit, port)) { 41037 /* Enable/disable timesatmp on XLMAC */ 41038 uint32 rval; 41039 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, 41040 port, &rval)); 41041 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, 41042 XLMAC_TS_DISABLEf, (value) ? 0 : 1); 41043 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, 41044 port, rval)); 41045 rv = BCM_E_NONE; 41046 } 41047 } 41048 break; 41049 41050 case bcmPortControlEEEEnable: 41051 if (!SOC_PORT_VALID(unit, port)) { 41052 return BCM_E_PORT; 41053 } 41054 41055 PORT_LOCK(unit); 41056 41057 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 41058 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 41059 || defined(BCM_HURRICANE2_SUPPORT) 41060 if (soc_feature (unit, soc_feature_eee)) { 41061 int mac_val; 41062 uint32 phy_val; 41063 41064 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 41065 SOC_MAC_CONTROL_EEE_ENABLE, 41066 &mac_val) != SOC_E_UNAVAIL) && 41067 (soc_phyctrl_control_get(unit, port, 41068 BCM_PORT_PHY_CONTROL_EEE, 41069 &phy_val) != SOC_E_UNAVAIL)) { 41070 41071 /* If MAC/Switch is EEE aware (Native EEE mode is supported) 41072 * and PHY also supports Native EEE mode 41073 */ 41074 41075 /* a. Disable AutoGrEEEn mode by PHY if applicable */ 41076 rv = (soc_phyctrl_control_get(unit, port, 41077 BCM_PORT_PHY_CONTROL_EEE_AUTO, 41078 &phy_val)); 41079 41080 if ((rv != SOC_E_UNAVAIL) && (phy_val != 0)) { 41081 rv = soc_phyctrl_control_set(unit, port, 41082 BCM_PORT_PHY_CONTROL_EEE_AUTO, 41083 0); 41084 } 41085 41086 /* b. Enable/Disable Native EEE in PHY */ 41087 rv = soc_phyctrl_control_set (unit, port, 41088 BCM_PORT_PHY_CONTROL_EEE, value ? 1 : 0); 41089 41090 if (SOC_SUCCESS(rv)) { 41091 /* EEE standard compliance Work Around: 41092 * Store the software copy of eee value in eee_cfg flag 41093 */ 41094 eee_cfg[unit][port] = value; 41095 /* If (value==1), EEE will be enabled in MAC after 1 sec. 41096 * during linkscan update*/ 41097 if (value == 0) { 41098 /* Disable EEE in MAC immediately*/ 41099 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, 41100 unit, port, 41101 SOC_MAC_CONTROL_EEE_ENABLE, 0); 41102 } 41103 41104 /* Notify Int-PHY to bypass LPI for native EEE mode. 41105 * 41106 * Note : 41107 * 1. Not all internal SerDes support the setting to 41108 * enable/disable bypass LPI signal. 41109 * 2. Int-PHY to bypass LPI will sync with Ext-PHY's EEE 41110 * enabling status for Native EEE mode. 41111 */ 41112 (void)soc_phyctrl_notify(unit, port, 41113 phyEventLpiBypass, value? 1: 0); 41114 } 41115 41116 } else { 41117 /* If native EEE mode is not supported, 41118 * set PHY in AutoGrEEEn mode. 41119 */ 41120 41121 /* a. Disable Native EEE mode in PHY if applicable */ 41122 rv = (soc_phyctrl_control_get(unit, port, 41123 BCM_PORT_PHY_CONTROL_EEE, 41124 &phy_val)); 41125 41126 if ((rv != SOC_E_UNAVAIL) && (phy_val != 0)) { 41127 rv = soc_phyctrl_control_set (unit, port, 41128 BCM_PORT_PHY_CONTROL_EEE, 41129 0); 41130 } 41131 41132 /* b. Enable/Disable AutoGrEEEn in PHY. 41133 * If PHY does not support AutoGrEEEn mode, 41134 * rv will be assigned SOC_E_UNAVAIL. 41135 */ 41136 rv = soc_phyctrl_control_set (unit, port, 41137 BCM_PORT_PHY_CONTROL_EEE_AUTO, 41138 value ? 1 : 0); 41139 if (SOC_SUCCESS(rv)) { 41140 eee_cfg[unit][port] = value; 41141 } 41142 } 41143 } else 41144 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 41145 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 41146 41147 { 41148 /* For legacy devices that don't support native EEE, 41149 * set PHY in AutoGrEEEn mode. 41150 */ 41151 uint32 phy_val; 41152 41153 /* a. Disable Native EEE mode in PHY if applicable */ 41154 rv = (soc_phyctrl_control_get(unit, port, 41155 BCM_PORT_PHY_CONTROL_EEE, 41156 &phy_val)); 41157 41158 if ((rv != SOC_E_UNAVAIL) && (phy_val != 0)) { 41159 rv = soc_phyctrl_control_set (unit, port, 41160 BCM_PORT_PHY_CONTROL_EEE, 0); 41161 } 41162 41163 /* b. Enable/Disable AutoGrEEEn in PHY. 41164 * If PHY does not support AutoGrEEEn mode, 41165 * rv will be assigned BCM_E_UNAVAIL. 41166 */ 41167 rv = soc_phyctrl_control_set (unit, port, 41168 BCM_PORT_PHY_CONTROL_EEE_AUTO, 41169 value ? 1 : 0); 41170 } 41171 41172 PORT_UNLOCK(unit); 41173 41174 break; 41175 41176 case bcmPortControlEEEStatisticsClear: 41177 if (!SOC_PORT_VALID(unit, port)) { 41178 return BCM_E_PORT; 41179 } 41180 if (!IS_E_PORT(unit, port)) { 41181 return BCM_E_UNAVAIL; 41182 } 41183 41184 PORT_LOCK(unit); 41185 41186 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \ 41187 defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 41188 if (soc_feature(unit, soc_feature_eee)) { 41189 uint32 val = 0; 41190 uint64 val64; 41191 int mac_val; 41192 uint32 phy_val; 41193 41194 COMPILER_64_ZERO(val64); 41195 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 41196 SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) 41197 != SOC_E_UNAVAIL) && 41198 (soc_phyctrl_control_get(unit, port, 41199 BCM_PORT_PHY_CONTROL_EEE, &phy_val) 41200 != SOC_E_UNAVAIL)) { 41201 41202 if (soc_feature(unit, soc_feature_eee_stat_clear_directly) || 41203 SOC_IS_TD2_TT2(unit)) { 41204 rv = _bcm_esw_port_eee_stat_clear(unit, port); 41205 41206 PORT_UNLOCK (unit); 41207 break; 41208 } 41209 41210 /* MAC/Switch is EEE aware (Native EEE mode is supported) */ 41211 if (soc_feature(unit, soc_feature_unified_port)) { 41212 if (SOC_REG_IS_VALID(unit,PORT_XGXS_COUNTER_MODEr)) { 41213 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41214 (READ_PORT_XGXS_COUNTER_MODEr(unit, port, &val)); 41215 soc_reg_field_set(unit, PORT_XGXS_COUNTER_MODEr, &val, 41216 CNT_MODEf, 0); 41217 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41218 (WRITE_PORT_XGXS_COUNTER_MODEr(unit, port, val)); 41219 } 41220 } else { 41221 if (SOC_REG_IS_VALID(unit,GE0_EEE_CONFIGr)) { 41222 /*set counter rollover bit to 0*/ 41223 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 41224 READ_GE0_EEE_CONFIGr(unit, port, &val)); 41225 soc_reg_field_set(unit, GE0_EEE_CONFIGr, &val, 41226 COUNTER_ROLLOVERf, 0); 41227 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41228 (WRITE_GE0_EEE_CONFIGr(unit, port, val)); 41229 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41230 (WRITE_GE1_EEE_CONFIGr(unit, port, val)); 41231 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41232 (WRITE_GE2_EEE_CONFIGr(unit, port, val)); 41233 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41234 (WRITE_GE3_EEE_CONFIGr(unit, port, val)); 41235 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41236 (WRITE_GE4_EEE_CONFIGr(unit, port, val)); 41237 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41238 (WRITE_GE5_EEE_CONFIGr(unit, port, val)); 41239 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41240 (WRITE_GE6_EEE_CONFIGr(unit, port, val)); 41241 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41242 (WRITE_GE7_EEE_CONFIGr(unit, port, val)); 41243 } 41244 } 41245 41246 /*Read counters to clear them*/ 41247 if (IS_GE_PORT(unit, port) && !IS_XL_PORT(unit, port) && 41248 (SOC_IS_HURRICANE2(unit) || SOC_IS_HURRICANE3(unit) || 41249 SOC_IS_GREYHOUND(unit))) { 41250 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41251 (READ_GRX_EEE_LPI_DURATION_COUNTERr(unit, port, &val)); 41252 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41253 (READ_GRX_EEE_LPI_EVENT_COUNTERr(unit, port, &val)); 41254 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41255 (READ_GTX_EEE_LPI_DURATION_COUNTERr(unit, port, &val)); 41256 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41257 (READ_GTX_EEE_LPI_EVENT_COUNTERr(unit, port, &val)); 41258 #ifdef BCM_GREYHOUND2_SUPPORT 41259 } else if (SOC_IS_GREYHOUND2(unit)) { 41260 41261 if (IS_CL_PORT(unit, port)) { 41262 /* for port with CLMAC */ 41263 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41264 (READ_CLMIB_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 41265 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41266 (READ_CLMIB_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 41267 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41268 (READ_CLMIB_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 41269 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41270 (READ_CLMIB_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 41271 } else if (IS_XL_PORT(unit, port)) { 41272 /* for port with XLMAC */ 41273 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41274 (READ_XLMIB_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 41275 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41276 (READ_XLMIB_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 41277 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41278 (READ_XLMIB_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 41279 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41280 (READ_XLMIB_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 41281 41282 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41283 (READ_XLPMIB_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 41284 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41285 (READ_XLPMIB_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 41286 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41287 (READ_XLPMIB_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 41288 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41289 (READ_XLPMIB_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 41290 } else { 41291 /* for port with UniMAC */ 41292 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41293 (READ_GRX_EEE_LPI_DURATION_COUNTERr(unit, port, &val)); 41294 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41295 (READ_GRX_EEE_LPI_EVENT_COUNTERr(unit, port, &val)); 41296 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41297 (READ_GTX_EEE_LPI_DURATION_COUNTERr(unit, port, &val)); 41298 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41299 (READ_GTX_EEE_LPI_EVENT_COUNTERr(unit, port, &val)); 41300 } 41301 #endif 41302 } else { 41303 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41304 (READ_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 41305 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41306 (READ_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 41307 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41308 (READ_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 41309 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41310 (READ_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 41311 } 41312 41313 /*set counter rollover bit to 1*/ 41314 if (soc_feature(unit, soc_feature_unified_port)) { 41315 if (SOC_REG_IS_VALID(unit,PORT_XGXS_COUNTER_MODEr)) { 41316 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41317 (READ_PORT_XGXS_COUNTER_MODEr(unit, port, &val)); 41318 soc_reg_field_set(unit, PORT_XGXS_COUNTER_MODEr, &val, 41319 CNT_MODEf, 1); 41320 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41321 (WRITE_PORT_XGXS_COUNTER_MODEr(unit, port, val)); 41322 } 41323 } else { 41324 if (SOC_REG_IS_VALID(unit,GE0_EEE_CONFIGr)) { 41325 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 41326 READ_GE0_EEE_CONFIGr(unit, port, &val)); 41327 soc_reg_field_set(unit, GE0_EEE_CONFIGr, &val, 41328 COUNTER_ROLLOVERf, 1); 41329 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41330 (WRITE_GE0_EEE_CONFIGr(unit, port, val)); 41331 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41332 (WRITE_GE1_EEE_CONFIGr(unit, port, val)); 41333 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41334 (WRITE_GE2_EEE_CONFIGr(unit, port, val)); 41335 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41336 (WRITE_GE3_EEE_CONFIGr(unit, port, val)); 41337 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41338 (WRITE_GE4_EEE_CONFIGr(unit, port, val)); 41339 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41340 (WRITE_GE5_EEE_CONFIGr(unit, port, val)); 41341 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41342 (WRITE_GE6_EEE_CONFIGr(unit, port, val)); 41343 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 41344 (WRITE_GE7_EEE_CONFIGr(unit, port, val)); 41345 } 41346 } 41347 rv = BCM_E_NONE; 41348 } else { 41349 /* native EEE mode is not supported, */ 41350 rv = soc_phyctrl_control_set 41351 (unit, port, 41352 BCM_PORT_PHY_CONTROL_EEE_STATISTICS_CLEAR, value); 41353 } 41354 } else 41355 #endif /* BCM_HURRICANE_SUPPORT || BCM_TRIDENT_SUPPORT 41356 || BCM_HAWKEYE_SUPPORT*/ 41357 { 41358 /* On legacy devices that don't support native EEE, 41359 * get counter value from PHY. If PHY does not support 41360 * EEE counters, rv will be assigned BCM_E_UNAVAIL. 41361 */ 41362 rv = soc_phyctrl_control_set 41363 (unit, port, 41364 BCM_PORT_PHY_CONTROL_EEE_STATISTICS_CLEAR, value); 41365 } 41366 PORT_UNLOCK (unit); 41367 break; 41368 41369 41370 /********************** EEE Mode Overview ************************ 41371 * |DET| | WT | 41372 * Signalling |idles| |------------------------------| | idles | 41373 * from Tx MAC | or | | Low Power Idle (LPI) |idles| or | 41374 * to local PHY |data | |------------------------------| | data | 41375 * * * 41376 * * * 41377 * * -------LPI state------------* 41378 * Local PHY | | | | | | | | | | 41379 * signaling | Active|Ts| Tq |Tr| Tq |Tr| Tq |Tw |Active | 41380 * on MDI | | | | | | | | | | 41381 * *------------------------------* 41382 * * * 41383 * * * 41384 * Signaling | idles |-------------------------------|id| PHY is | 41385 * from LP PHY | or | Low Power Idle (LPI) |le| ready | 41386 * to Rx MAC | data |-------------------------------|s | for data | 41387 * 41388 * where DET = Delay Entry Timer WT = Tx MAC Wake Timer 41389 */ 41390 case bcmPortControlEEETransmitIdleTime: 41391 /* DET = Time (in microsecs) for which condition to move to LPI state 41392 * is satisfied, at the end of which MAC TX transitions to LPI state */ 41393 if (!SOC_PORT_VALID(unit, port)) { 41394 return BCM_E_PORT; 41395 } 41396 41397 PORT_LOCK(unit); 41398 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 41399 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 41400 || defined (BCM_HURRICANE2_SUPPORT) 41401 if (soc_feature (unit, soc_feature_eee)) { 41402 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 41403 SOC_MAC_CONTROL_EEE_TX_IDLE_TIME, value); 41404 } else 41405 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 41406 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 41407 { 41408 rv = BCM_E_UNAVAIL; 41409 } 41410 PORT_UNLOCK(unit); 41411 break; 41412 41413 case bcmPortControlEEETransmitRefreshTime: 41414 if (!SOC_PORT_VALID(unit, port)) { 41415 return BCM_E_PORT; 41416 } 41417 41418 PORT_LOCK(unit); 41419 rv = soc_phyctrl_control_set(unit, port, 41420 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_REFRESH_TIME, value); 41421 PORT_UNLOCK (unit); 41422 break; 41423 41424 case bcmPortControlEEETransmitSleepTime: 41425 if (!SOC_PORT_VALID(unit, port)) { 41426 return BCM_E_PORT; 41427 } 41428 PORT_LOCK (unit); 41429 rv = soc_phyctrl_control_set(unit, port, 41430 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_SLEEP_TIME, value); 41431 PORT_UNLOCK (unit); 41432 break; 41433 41434 case bcmPortControlEEETransmitQuietTime: 41435 if (!SOC_PORT_VALID(unit, port)) { 41436 return BCM_E_PORT; 41437 } 41438 PORT_LOCK(unit); 41439 rv = soc_phyctrl_control_set(unit, port, 41440 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_QUIET_TIME, value); 41441 PORT_UNLOCK (unit); 41442 break; 41443 41444 case bcmPortControlEEETransmitWakeTime: 41445 /* Time(in microsecs) to wait before transmitter can leave LPI State*/ 41446 if (!SOC_PORT_VALID(unit, port)) { 41447 return BCM_E_PORT; 41448 } 41449 41450 PORT_LOCK (unit); 41451 41452 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 41453 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 41454 || defined(BCM_HURRICANE2_SUPPORT) 41455 if (soc_feature (unit, soc_feature_eee)) { 41456 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 41457 SOC_MAC_CONTROL_EEE_TX_WAKE_TIME, value); 41458 } 41459 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || BCM_TRIDENT_SUPPORT || 41460 BCM_SHADOW_SUPPORT */ 41461 41462 PORT_UNLOCK (unit); 41463 break; 41464 41465 case bcmPortControlEEEReceiveSleepTime: 41466 if (!SOC_PORT_VALID(unit, port)) { 41467 return BCM_E_PORT; 41468 } 41469 PORT_LOCK (unit); 41470 rv = soc_phyctrl_control_set(unit, port, 41471 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_SLEEP_TIME, value); 41472 PORT_UNLOCK (unit); 41473 break; 41474 41475 case bcmPortControlEEEReceiveQuietTime: 41476 if (!SOC_PORT_VALID(unit, port)) { 41477 return BCM_E_PORT; 41478 } 41479 PORT_LOCK(unit); 41480 rv = soc_phyctrl_control_set(unit, port, 41481 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_QUIET_TIME, value); 41482 PORT_UNLOCK(unit); 41483 break; 41484 41485 case bcmPortControlEEEReceiveWakeTime: 41486 if (!SOC_PORT_VALID(unit, port)) { 41487 return BCM_E_PORT; 41488 } 41489 if (!IS_E_PORT(unit, port)) { 41490 return BCM_E_UNAVAIL; 41491 } 41492 PORT_LOCK(unit); 41493 41494 rv = soc_phyctrl_control_set (unit, port, 41495 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_WAKE_TIME, value); 41496 PORT_UNLOCK(unit); 41497 break; 41498 41499 case bcmPortControlEEEEventCountSymmetric: 41500 if (!SOC_PORT_VALID(unit, port)) { 41501 return BCM_E_PORT; 41502 } 41503 if (!IS_E_PORT(unit, port)) { 41504 return BCM_E_UNAVAIL; 41505 } 41506 #if defined(BCM_HURRICANE2_SUPPORT) 41507 if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 41508 SOC_IS_GREYHOUND2(unit)) { 41509 soc_reg_t reg; 41510 41511 if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) { 41512 reg = IS_XL_PORT(unit, port) ? XLPORT_EEE_COUNTER_MODEr : 41513 CLPORT_EEE_COUNTER_MODEr; 41514 41515 if (SOC_REG_FIELD_VALID(unit, reg, MODE_BITf)) { 41516 rv = soc_reg_field32_modify(unit, reg, port, 41517 MODE_BITf, (value) ? 1 : 0); 41518 } else { 41519 return BCM_E_INTERNAL; 41520 } 41521 } else { 41522 return BCM_E_PORT; 41523 } 41524 } else 41525 #endif 41526 { 41527 #if defined(BCM_TRIUMPH3_SUPPORT) 41528 if (SOC_REG_FIELD_VALID(unit, PORT_EEE_COUNTER_MODEr, MODE_BITf)) { 41529 rv = soc_reg_field32_modify(unit, PORT_EEE_COUNTER_MODEr, port, 41530 MODE_BITf, (value) ? 1 : 0); 41531 } 41532 #endif 41533 } 41534 break; 41535 41536 case bcmPortControlEEELinkActiveDuration: 41537 if (!SOC_PORT_VALID(unit, port)) { 41538 return BCM_E_PORT; 41539 } 41540 if (!IS_E_PORT(unit, port)) { 41541 return BCM_E_UNAVAIL; 41542 } 41543 #if defined(BCM_HURRICANE2_SUPPORT) 41544 if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || 41545 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 41546 soc_reg_t reg; 41547 41548 if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) { 41549 reg = IS_XL_PORT(unit, port) ? XLMAC_EEE_1_SEC_LINK_STATUS_TIMERr : 41550 CLMAC_EEE_1_SEC_LINK_STATUS_TIMERr; 41551 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) { 41552 if (value >= (1 << soc_reg_field_length(unit, 41553 reg, 41554 ONE_SECOND_TIMERf))) { 41555 return BCM_E_PARAM; 41556 } 41557 rv = soc_reg_field32_modify(unit, 41558 reg, 41559 port, 41560 ONE_SECOND_TIMERf, 41561 value); 41562 } 41563 } else { 41564 return BCM_E_PORT; 41565 } 41566 } else 41567 #endif 41568 { 41569 #if defined(BCM_TRIUMPH3_SUPPORT) 41570 { 41571 soc_reg_t reg; 41572 41573 reg = IS_C_PORT(unit, port) ? 41574 CMAC_EEE_1_SEC_LINK_STATUS_TIMERr : 41575 XMAC_EEE_1_SEC_LINK_STATUS_TIMERr; 41576 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) { 41577 if (value >= (1 << soc_reg_field_length(unit, reg, 41578 ONE_SECOND_TIMERf))) { 41579 return BCM_E_PARAM; 41580 } 41581 rv = soc_reg_field32_modify(unit, reg, port, 41582 ONE_SECOND_TIMERf, value); 41583 } 41584 } 41585 #endif 41586 } 41587 break; 41588 41589 case bcmPortControlRemoteCpuEnable: 41590 if (soc_feature(unit, soc_feature_rcpu_1)) { 41591 bcm_pbmp_t pbmp; 41592 uint32 rval; 41593 41594 rval = 0; 41595 if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTSr)) { 41596 READ_CMIC_PKT_PORTSr(unit, &rval); 41597 SOC_PBMP_WORD_SET(pbmp, 0, rval); 41598 } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_0r)) { 41599 READ_CMIC_PKT_PORTS_0r(unit, &rval); 41600 SOC_PBMP_WORD_SET(pbmp, 0, rval); 41601 } else if (SOC_REG_IS_VALID(unit, CMIC_RPE_PKT_PORTS_0r)) { 41602 READ_CMIC_RPE_PKT_PORTS_0r(unit, &rval); 41603 SOC_PBMP_WORD_SET(pbmp, 0, rval); 41604 } 41605 41606 if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HIr)) { 41607 READ_CMIC_PKT_PORTS_HIr(unit, &rval); 41608 SOC_PBMP_WORD_SET(pbmp, 1, rval); 41609 } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_1r)) { 41610 READ_CMIC_PKT_PORTS_1r(unit, &rval); 41611 SOC_PBMP_WORD_SET(pbmp, 1, rval); 41612 } else if (SOC_REG_IS_VALID(unit, CMIC_RPE_PKT_PORTS_1r)) { 41613 READ_CMIC_RPE_PKT_PORTS_1r(unit, &rval); 41614 SOC_PBMP_WORD_SET(pbmp, 1, rval); 41615 } 41616 41617 if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HI_2r)) { 41618 READ_CMIC_PKT_PORTS_HI_2r(unit, &rval); 41619 SOC_PBMP_WORD_SET(pbmp, 2, rval); 41620 } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_2r)) { 41621 READ_CMIC_PKT_PORTS_2r(unit, &rval); 41622 SOC_PBMP_WORD_SET(pbmp, 2, rval); 41623 } else if (SOC_REG_IS_VALID(unit, CMIC_RPE_PKT_PORTS_2r)) { 41624 READ_CMIC_RPE_PKT_PORTS_2r(unit, &rval); 41625 SOC_PBMP_WORD_SET(pbmp, 2, rval); 41626 } 41627 41628 if (value) { 41629 SOC_PBMP_PORT_ADD(pbmp, port); 41630 } else { 41631 SOC_PBMP_PORT_REMOVE(pbmp, port); 41632 } 41633 rval = 0; 41634 41635 if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTSr)) { 41636 soc_reg_field_set(unit, CMIC_PKT_PORTSr, &rval, PORTSf, 41637 SOC_PBMP_WORD_GET(pbmp, 0)); 41638 (void) WRITE_CMIC_PKT_PORTSr(unit, rval); 41639 } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_0r)) { 41640 soc_reg_field_set(unit, CMIC_PKT_PORTS_0r, &rval, PORTSf, 41641 SOC_PBMP_WORD_GET(pbmp, 0)); 41642 (void) WRITE_CMIC_PKT_PORTS_0r(unit, rval); 41643 } else if (SOC_REG_IS_VALID(unit, CMIC_RPE_PKT_PORTS_0r)) { 41644 soc_reg_field_set(unit, CMIC_RPE_PKT_PORTS_0r, &rval, PORTSf, 41645 SOC_PBMP_WORD_GET(pbmp, 0)); 41646 (void) WRITE_CMIC_RPE_PKT_PORTS_0r(unit, rval); 41647 } 41648 41649 if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HIr)) { 41650 rval = 0; 41651 soc_reg_field_set(unit, CMIC_PKT_PORTS_HIr, &rval, PORTS_HIf, 41652 SOC_PBMP_WORD_GET(pbmp, 1)); 41653 (void) WRITE_CMIC_PKT_PORTS_HIr(unit, rval); 41654 } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_1r)) { 41655 rval = 0; 41656 soc_reg_field_set(unit, CMIC_PKT_PORTS_1r, &rval, PORTS_HIf, 41657 SOC_PBMP_WORD_GET(pbmp, 1)); 41658 (void) WRITE_CMIC_PKT_PORTS_1r(unit, rval); 41659 } else if (SOC_REG_IS_VALID(unit, CMIC_RPE_PKT_PORTS_1r)) { 41660 rval = 0; 41661 soc_reg_field_set(unit, CMIC_RPE_PKT_PORTS_1r, &rval, PORTS_HIf, 41662 SOC_PBMP_WORD_GET(pbmp, 1)); 41663 (void) WRITE_CMIC_RPE_PKT_PORTS_1r(unit, rval); 41664 } 41665 41666 if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HI_2r)) { 41667 rval = 0; 41668 soc_reg_field_set(unit, CMIC_PKT_PORTS_HI_2r, &rval, PORTS_HIf, 41669 SOC_PBMP_WORD_GET(pbmp, 2)); 41670 (void) WRITE_CMIC_PKT_PORTS_HI_2r(unit, rval); 41671 } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_2r)) { 41672 rval = 0; 41673 soc_reg_field_set(unit, CMIC_PKT_PORTS_2r, &rval, PORTS_HIf, 41674 SOC_PBMP_WORD_GET(pbmp, 2)); 41675 (void) WRITE_CMIC_PKT_PORTS_2r(unit, rval); 41676 } else if (SOC_REG_IS_VALID(unit, CMIC_RPE_PKT_PORTS_2r)) { 41677 rval = 0; 41678 soc_reg_field_set(unit, CMIC_RPE_PKT_PORTS_2r, &rval, PORTS_HIf, 41679 SOC_PBMP_WORD_GET(pbmp, 2)); 41680 (void) WRITE_CMIC_RPE_PKT_PORTS_2r(unit, rval); 41681 } 41682 41683 rv = BCM_E_NONE; 41684 } else { 41685 rv = BCM_E_UNAVAIL; 41686 } 41687 break; 41688 41689 case bcmPortControlRemoteCpuTcMapping: 41690 if (soc_feature(unit, soc_feature_rcpu_tc_mapping)) { 41691 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41692 REMOTE_CPU_ENf, (value) ? 1 : 0); 41693 /* If BCM port, then set property in LPORT table too */ 41694 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 41695 rv = bcm_esw_port_lport_field_set(unit, port, 41696 LPORT_PROFILE_LPORT_TAB, 41697 REMOTE_CPU_ENf, 41698 (value) ? 1 : 0); 41699 } 41700 } else { 41701 rv = BCM_E_UNAVAIL; 41702 } 41703 break; 41704 41705 case bcmPortControlTrill: 41706 #if defined(BCM_TRIDENT_SUPPORT) 41707 if (soc_feature(unit, soc_feature_trill)) { 41708 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41709 TRILL_ENABLEf, (value) ? 1 : 0); 41710 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 41711 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, TRILL_ENABLEf)) { 41712 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 41713 TRILL_ENABLEf, 41714 (value) ? 1 : 0); 41715 } 41716 } 41717 } 41718 #endif /* BCM_TRIDENT_SUPPORT */ 41719 break; 41720 41721 case bcmPortControlTrillAllow: 41722 #if defined(BCM_TRIDENT_SUPPORT) 41723 if (soc_feature(unit, soc_feature_trill)) { 41724 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41725 ALLOW_TRILL_FRAMESf, 41726 (value) ? 1 : 0); 41727 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 41728 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 41729 ALLOW_TRILL_FRAMESf)) { 41730 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 41731 ALLOW_TRILL_FRAMESf, 41732 (value) ? 1 : 0); 41733 } 41734 } 41735 } 41736 #endif /* BCM_TRIDENT_SUPPORT */ 41737 break; 41738 41739 case bcmPortControlNonTrillAllow: 41740 #if defined(BCM_TRIDENT_SUPPORT) 41741 if (soc_feature(unit, soc_feature_trill)) { 41742 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41743 ALLOW_NON_TRILL_FRAMESf, 41744 (value) ? 1 : 0); 41745 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 41746 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 41747 ALLOW_NON_TRILL_FRAMESf)) { 41748 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 41749 ALLOW_NON_TRILL_FRAMESf, 41750 (value) ? 1 : 0); 41751 } 41752 } 41753 } 41754 #endif /* BCM_TRIDENT_SUPPORT */ 41755 break; 41756 41757 case bcmPortControlTrillCoreISISToCPU: 41758 #if defined(BCM_TRIDENT_SUPPORT) 41759 if (soc_feature(unit, soc_feature_trill)) { 41760 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41761 COPY_CORE_IS_IS_TO_CPUf, 41762 (value) ? 1 : 0); 41763 } 41764 #endif /* BCM_TRIDENT_SUPPORT */ 41765 break; 41766 41767 case bcmPortControlTrillHashSelect: 41768 #if defined(BCM_TRIUMPH3_SUPPORT) 41769 if (SOC_IS_TRIUMPH3(unit)) { 41770 return BCM_E_UNAVAIL; 41771 } else 41772 #endif /* BCM_TRIUMPH3_SUPPORT */ 41773 { 41774 #if defined(BCM_TRIDENT_SUPPORT) 41775 if (soc_feature(unit, soc_feature_trill)) { 41776 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41777 RTAG7_HASH_CFG_SEL_TRILL_ECMPf, (value) ? 1 : 0); 41778 } 41779 #endif /* BCM_TRIDENT_SUPPORT */ 41780 } 41781 break; 41782 41783 case bcmPortControlNivAccessVirtualInterfaceId: 41784 case bcmPortControlExtendedPortVid: 41785 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 41786 if (soc_feature(unit, soc_feature_niv) || 41787 soc_feature(unit, soc_feature_port_extension)) { 41788 int mod_port_index; 41789 41790 if ((value < 0) || (value > 0xfff)) { 41791 return BCM_E_PARAM; 41792 } 41793 BCM_IF_ERROR_RETURN( 41794 _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41795 NIV_VIF_IDf, value)); 41796 BCM_IF_ERROR_RETURN( 41797 _bcm_esw_src_mod_port_table_index_get_from_port( 41798 unit, port, &mod_port_index)); 41799 SOC_IF_ERROR_RETURN( 41800 soc_mem_field32_modify(unit, EGR_GPP_ATTRIBUTESm, mod_port_index, 41801 SRC_NIV_VIF_IDf, value)); 41802 41803 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 41804 SOC_IS_GREYHOUND2(unit)) { 41805 uint64 val64; 41806 41807 rv = READ_EGR_PORT_64r(unit, port, &val64); 41808 if (BCM_SUCCESS(rv)) { 41809 soc_reg64_field32_set(unit, EGR_PORT_64r, 41810 &val64, 41811 NIV_VIF_IDf, value); 41812 } 41813 rv = WRITE_EGR_PORT_64r(unit, port, val64); 41814 } else { 41815 rv = _bcm_esw_egr_port_tab_set(unit, port, NIV_VIF_IDf, value); 41816 } 41817 } 41818 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 41819 break; 41820 41821 case bcmPortControlNivNonVntagDrop: 41822 case bcmPortControlNonEtagDrop: 41823 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 41824 if (soc_feature(unit, soc_feature_niv) || 41825 soc_feature(unit, soc_feature_port_extension)) { 41826 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41827 DISCARD_IF_VNTAG_NOT_PRESENTf, (value) ? 1 : 0); 41828 } 41829 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT*/ 41830 break; 41831 41832 case bcmPortControlNivVntagDrop: 41833 case bcmPortControlEtagDrop: 41834 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 41835 if (soc_feature(unit, soc_feature_niv) || 41836 soc_feature(unit, soc_feature_port_extension)) { 41837 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41838 DISCARD_IF_VNTAG_PRESENTf, (value) ? 1 : 0); 41839 } 41840 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 41841 break; 41842 41843 case bcmPortControlSubportPktTagDrop: 41844 #if defined(BCM_KATANA2_SUPPORT) 41845 if (soc_feature(unit, soc_feature_lltag)) { 41846 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41847 DISCARD_IF_LLTAG_PRESENTf, (value) ? 1 : 0); 41848 } 41849 #endif /* BCM_KATANA2_SUPPORT */ 41850 break; 41851 41852 case bcmPortControlNoSubportPktTagDrop: 41853 #if defined(BCM_KATANA2_SUPPORT) 41854 if (soc_feature(unit, soc_feature_lltag)) { 41855 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41856 DISCARD_IF_LLTAG_NOT_PRESENTf, (value) ? 1 : 0); 41857 } 41858 #endif /* BCM_KATANA2_SUPPORT */ 41859 break; 41860 41861 case bcmPortControlNivNonVntagAdd: 41862 case bcmPortControlNonEtagAdd: 41863 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 41864 if (soc_feature(unit, soc_feature_niv) || 41865 soc_feature(unit, soc_feature_port_extension)) { 41866 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41867 VNTAG_ACTIONS_IF_NOT_PRESENTf, 41868 (value) ? 41869 ((type == bcmPortControlNonEtagAdd) ? 2 : VNTAG_ADD) : 41870 VNTAG_NOOP); 41871 } 41872 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 41873 break; 41874 41875 case bcmPortControlNivVntagIngressReplace: 41876 case bcmPortControlEtagIngressReplace: 41877 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 41878 if (soc_feature(unit, soc_feature_niv) || 41879 soc_feature(unit, soc_feature_port_extension)) { 41880 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41881 VNTAG_ACTIONS_IF_PRESENTf, 41882 (value) ? VNTAG_REPLACE : VNTAG_NOOP); 41883 } 41884 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 41885 break; 41886 41887 case bcmPortControlNivVntagEgressReplace: 41888 case bcmPortControlEtagEgressReplace: 41889 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 41890 if (soc_feature(unit, soc_feature_niv) || 41891 soc_feature(unit, soc_feature_port_extension)) { 41892 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 41893 SOC_IS_GREYHOUND2(unit)) { 41894 uint64 val64; 41895 41896 if (type == bcmPortControlEtagEgressReplace) { 41897 return BCM_E_UNAVAIL; 41898 } 41899 41900 rv = READ_EGR_PORT_64r(unit, port, &val64); 41901 if (BCM_SUCCESS(rv)) { 41902 soc_reg64_field32_set(unit, EGR_PORT_64r, 41903 &val64, 41904 VNTAG_ACTIONS_IF_PRESENTf, 41905 (value) ? VNTAG_REPLACE : VNTAG_NOOP); 41906 } 41907 rv = WRITE_EGR_PORT_64r(unit, port, val64); 41908 } else { 41909 rv = _bcm_esw_egr_port_tab_set( 41910 unit, port, VNTAG_ACTIONS_IF_PRESENTf, 41911 (value) ? VNTAG_REPLACE : VNTAG_NOOP); 41912 } 41913 } 41914 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 41915 break; 41916 41917 case bcmPortControlNivVntagIngressDelete: 41918 case bcmPortControlEtagIngressDelete: 41919 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 41920 if (soc_feature(unit, soc_feature_niv) || 41921 soc_feature(unit, soc_feature_port_extension)) { 41922 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41923 VNTAG_ACTIONS_IF_PRESENTf, 41924 (value) ? VNTAG_DELETE : VNTAG_NOOP); 41925 } 41926 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 41927 break; 41928 41929 case bcmPortControlNivVntagEgressDelete: 41930 case bcmPortControlEtagEgressDelete: 41931 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 41932 if (soc_feature(unit, soc_feature_niv) || 41933 soc_feature(unit, soc_feature_port_extension)) { 41934 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 41935 SOC_IS_GREYHOUND2(unit)) { 41936 uint64 val64; 41937 rv = READ_EGR_PORT_64r(unit, port, &val64); 41938 if (BCM_SUCCESS(rv)) { 41939 soc_reg64_field32_set(unit, EGR_PORT_64r, 41940 &val64, 41941 VNTAG_ACTIONS_IF_PRESENTf, 41942 (value) ? VNTAG_DELETE : VNTAG_NOOP); 41943 } 41944 rv = WRITE_EGR_PORT_64r(unit, port, val64); 41945 } else { 41946 rv = _bcm_esw_egr_port_tab_set( 41947 unit, port, VNTAG_ACTIONS_IF_PRESENTf, 41948 (value) ? VNTAG_DELETE: VNTAG_NOOP); 41949 } 41950 } 41951 #endif /* BCM_TRIDENT_SUPPORT || BCM_GREYHOUND_SUPPORT */ 41952 break; 41953 41954 case bcmPortControlNivRpfCheck: 41955 case bcmPortControlExtenderRpfCheck: 41956 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 41957 if (soc_feature(unit, soc_feature_niv) || 41958 soc_feature(unit, soc_feature_port_extension)) { 41959 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41960 NIV_RPF_CHECK_ENABLEf, (value) ? 1 : 0); 41961 } 41962 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 41963 break; 41964 41965 case bcmPortControlNivSourceKnockout: 41966 case bcmPortControlExtenderSourceKnockout: 41967 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 41968 if (soc_feature(unit, soc_feature_niv) || 41969 soc_feature(unit, soc_feature_port_extension)) { 41970 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 41971 SOC_IS_GREYHOUND2(unit)) { 41972 uint64 val64; 41973 rv = READ_EGR_PORT_64r(unit, port, &val64); 41974 if (BCM_SUCCESS(rv)) { 41975 soc_reg64_field32_set(unit, EGR_PORT_64r, 41976 &val64, 41977 NIV_PRUNE_ENABLEf, 41978 (value) ? 1 : 0); 41979 } 41980 rv = WRITE_EGR_PORT_64r(unit, port, val64); 41981 } else { 41982 rv = _bcm_esw_egr_port_tab_set(unit, port, NIV_PRUNE_ENABLEf, 41983 (value) ? 1 : 0); 41984 } 41985 } 41986 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 41987 break; 41988 41989 case bcmPortControlNivForwardPort: 41990 case bcmPortControlExtenderForwardPort: 41991 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 41992 if (soc_feature(unit, soc_feature_niv) || 41993 soc_feature(unit, soc_feature_port_extension)) { 41994 int mod_port_index; 41995 bcm_module_t mod_out; 41996 bcm_port_t port_out; 41997 bcm_trunk_t trunk_out; 41998 int id_out; 41999 int tx_dest_port; 42000 42001 if (value == -1) { 42002 BCM_IF_ERROR_RETURN 42003 (_bcm_esw_port_tab_set(unit, port, 42004 _BCM_CPU_TABS_ETHER, 42005 NIV_UPLINK_PORTf, 1)); 42006 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 42007 SOC_IS_GREYHOUND2(unit)) { 42008 uint64 val64; 42009 rv = READ_EGR_PORT_64r(unit, port, &val64); 42010 if (BCM_SUCCESS(rv)) { 42011 soc_reg64_field32_set(unit, EGR_PORT_64r, 42012 &val64, 42013 NIV_UPLINK_PORTf, 1); 42014 } 42015 rv = WRITE_EGR_PORT_64r(unit, port, val64); 42016 } else { 42017 BCM_IF_ERROR_RETURN( 42018 _bcm_esw_egr_port_tab_set(unit, port, 42019 NIV_UPLINK_PORTf, 1)); 42020 BCM_IF_ERROR_RETURN( 42021 _bcm_esw_src_mod_port_table_index_get_from_port( 42022 unit, port, &mod_port_index)); 42023 SOC_IF_ERROR_RETURN( 42024 soc_mem_field32_modify(unit, EGR_GPP_ATTRIBUTESm, 42025 mod_port_index, 42026 SRC_IS_NIV_UPLINK_PORTf, 1)); 42027 } 42028 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42029 NIV_VIF_LOOKUP_ENABLEf, 1); 42030 } else { 42031 BCM_IF_ERROR_RETURN 42032 (_bcm_esw_gport_resolve(unit, value, &mod_out, &port_out, 42033 &trunk_out, &id_out)); 42034 if (id_out != -1) { 42035 return BCM_E_PARAM; 42036 } 42037 42038 if (soc_feature(unit, soc_feature_generic_dest)) { 42039 uint32 dval; 42040 if (trunk_out != -1) { 42041 dval = _soc_mem_dest_value_construct(unit, 42042 SOC_MEM_FIF_DEST_LAG, trunk_out); 42043 } else { 42044 dval = _soc_mem_dest_value_construct(unit, 42045 SOC_MEM_FIF_DEST_DGPP, 42046 mod_out << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS | port_out); 42047 } 42048 BCM_IF_ERROR_RETURN 42049 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42050 DESTINATIONf, dval)); 42051 } else { 42052 if (trunk_out != -1) { 42053 tx_dest_port = (1 << SOC_TRUNK_BIT_POS(unit)) + trunk_out; 42054 } else { 42055 #if defined(BCM_METROLITE_SUPPORT) 42056 /* Metrolite DGLP still uses 7 bits for ports like saber2 */ 42057 if (SOC_IS_METROLITE(unit)) { 42058 tx_dest_port = ((mod_out << 7) | (port_out)); 42059 } else 42060 #endif 42061 tx_dest_port = mod_out * (SOC_PORT_ADDR_MAX(unit) + 1) + 42062 port_out; 42063 } 42064 42065 BCM_IF_ERROR_RETURN 42066 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42067 TX_DEST_PORTf, tx_dest_port)); 42068 } 42069 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42070 TX_DEST_PORT_ENABLEf, 1); 42071 } 42072 } 42073 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 42074 break; 42075 42076 case bcmPortControlNivType: 42077 if (soc_feature(unit, soc_feature_niv)) { 42078 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 42079 SOC_IS_GREYHOUND2(unit)) { 42080 #if defined(BCM_GREYHOUND_SUPPORT) 42081 rv = bcm_gh_port_niv_type_set(unit, port, value); 42082 #endif /* BCM_GREYHOUND_SUPPORT */ 42083 } else { 42084 #if defined(BCM_TRIDENT_SUPPORT) 42085 rv = bcm_td_port_niv_type_set(unit, port, value); 42086 #endif /* BCM_TRIDENT_SUPPORT */ 42087 } 42088 } 42089 break; 42090 42091 case bcmPortControlExtenderType: 42092 if (soc_feature(unit, soc_feature_port_extension)) { 42093 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 42094 SOC_IS_GREYHOUND2(unit)) { 42095 #if defined(BCM_GREYHOUND_SUPPORT) 42096 rv = bcm_gh_port_extender_type_set(unit, port, value); 42097 #endif /* BCM_GREYHOUND_SUPPORT */ 42098 } else { 42099 #if defined(BCM_TRIUMPH3_SUPPORT) 42100 rv = bcm_tr3_port_extender_type_set(unit, port, value); 42101 #endif /* BCM_TRIUMPH3_SUPPORT */ 42102 } 42103 } 42104 break; 42105 42106 case bcmPortControlNivNameSpace: 42107 case bcmPortControlExtenderNameSpace: 42108 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 42109 if (soc_feature(unit, soc_feature_niv) || 42110 soc_feature(unit, soc_feature_port_extension)) { 42111 if ((value < 0) || (value > 0xfff)) { 42112 return BCM_E_PARAM; 42113 } 42114 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42115 NIV_NAMESPACEf, value); 42116 } 42117 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 42118 break; 42119 42120 case bcmPortControlEtagPcpDeSelect: 42121 #if defined(INCLUDE_L3) 42122 if (soc_feature(unit, soc_feature_port_extension)) { 42123 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 42124 SOC_IS_GREYHOUND2(unit)) { 42125 #if defined(BCM_GREYHOUND_SUPPORT) 42126 rv = bcm_gh_port_etag_pcp_de_source_set(unit, port, value); 42127 #endif /* BCM_GREYHOUND_SUPPORT */ 42128 } else { 42129 #if defined(BCM_TRIUMPH3_SUPPORT) 42130 rv = bcm_tr3_port_etag_pcp_de_source_set(unit, port, value); 42131 #endif /* BCM_TRIUMPH3_SUPPORT */ 42132 } 42133 } 42134 #endif /* INCLUDE_L3 */ 42135 break; 42136 42137 case bcmPortControlEtagPcp: 42138 #if defined(BCM_TRIUMPH3_SUPPORT) 42139 if (soc_feature(unit, soc_feature_port_extension)) { 42140 if ((value < 0) || (value > 7)) { 42141 return BCM_E_PARAM; 42142 } 42143 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, ETAG_PCPf)) { 42144 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 42145 EGR_ING_PORTm, port, 42146 ETAG_PCPf, value)); 42147 } 42148 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42149 ETAG_PCPf, value); 42150 } 42151 #endif /* BCM_TRIUMPH3_SUPPORT */ 42152 #if defined(BCM_GREYHOUND_SUPPORT) 42153 if (soc_feature(unit, soc_feature_port_extension)) { 42154 if ((value < 0) || (value > 7)) { 42155 return BCM_E_PARAM; 42156 } 42157 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42158 ETAG_PCPf, value); 42159 } 42160 #endif /* BCM_GREYHOUND_SUPPORT */ 42161 break; 42162 42163 case bcmPortControlEtagDe: 42164 #if defined(BCM_TRIUMPH3_SUPPORT) 42165 if (soc_feature(unit, soc_feature_port_extension)) { 42166 if ((value < 0) || (value > 1)) { 42167 return BCM_E_PARAM; 42168 } 42169 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, ETAG_DEf)) { 42170 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 42171 EGR_ING_PORTm, port, 42172 ETAG_DEf, value)); 42173 } 42174 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42175 ETAG_DEf, value); 42176 } 42177 #endif /* BCM_TRIUMPH3_SUPPORT */ 42178 #if defined(BCM_GREYHOUND_SUPPORT) 42179 if (soc_feature(unit, soc_feature_port_extension)) { 42180 if ((value < 0) || (value > 1)) { 42181 return BCM_E_PARAM; 42182 } 42183 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42184 ETAG_DEf, value); 42185 } 42186 #endif /* BCM_GREYHOUND_SUPPORT */ 42187 break; 42188 42189 case bcmPortControlUseEtagPri: 42190 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 42191 if (soc_feature(unit, soc_feature_port_extension)) { 42192 if ((value < 0) || (value > 1)) { 42193 return BCM_E_PARAM; 42194 } 42195 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42196 PHB_FROM_ETAGf, value); 42197 #if defined(BCM_GREYHOUND_SUPPORT) 42198 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 42199 if (BCM_FAILURE(rv)) { 42200 return rv; 42201 } 42202 /* 42203 * Make sure TREAT_PKTPRI_AS_DOT1P bit is set for 42204 * ETAG internal priority mapping. 42205 */ 42206 rv = bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 42207 (unit, (value) ? 1 : -1); 42208 } 42209 #endif /* BCM_GREYHOUND_SUPPORT */ 42210 } 42211 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */ 42212 break; 42213 42214 case bcmPortControlUseSubportPktTagPri: 42215 #if defined(BCM_KATANA2_SUPPORT) 42216 if (soc_feature(unit, soc_feature_lltag)) { 42217 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42218 PHB_FROM_LLTAGf, value); 42219 } 42220 #endif /* BCM_KATANA2_SUPPORT */ 42221 break; 42222 42223 case bcmPortControlProhibitedDot1p: 42224 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 42225 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42226 PROHIBITED_DOT1Pf, value); 42227 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 42228 break; 42229 42230 case bcmPortControlFabricSourceKnockout: 42231 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, REMOVE_HG_HDR_SRC_PORTf) || 42232 SOC_IS_TRIDENT3X(unit)) { 42233 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42234 REMOVE_HG_HDR_SRC_PORTf, (value) ? 1 : 0); 42235 42236 if (!SOC_IS_TOMAHAWK3(unit)) { 42237 /* If BCM port, then set property in LPORT table too */ 42238 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 42239 rv = bcm_esw_port_lport_field_set(unit, port, 42240 LPORT_PROFILE_LPORT_TAB, 42241 ALLOW_SRC_MODf, value); 42242 } 42243 } 42244 } 42245 break; 42246 case bcmPortControlRxEnable: 42247 rv = _bcm_esw_mac_rx_control(unit, port, 0, &value); 42248 break; 42249 case bcmPortControlTxEnable: 42250 42251 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 42252 /* Use egress scheduling control if available */ 42253 uint32 val; 42254 if (value > 0) { 42255 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) { 42256 /* Port tx was never stopped */ 42257 rv = BCM_E_NONE; 42258 break; 42259 } 42260 /* Restore values */ 42261 val = PORT(unit, port).cosmask; 42262 rv = soc_reg_field32_modify(unit, COSMASKr, port, 42263 COSMASKf, val); 42264 /* clear flag */ 42265 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX; 42266 } else { 42267 uint32 rval; 42268 /* Read and save current values */ 42269 SOC_IF_ERROR_RETURN(READ_COSMASKr(unit, port, &rval)); 42270 PORT(unit, port).cosmask = soc_reg_field_get(unit, COSMASKr, 42271 rval, COSMASKf); 42272 /* set flag */ 42273 PORT(unit, port).flags |= _PORT_INFO_STOP_TX; 42274 /* Disable Tx */ 42275 val = (1 << soc_reg_field_length(unit, COSMASKr, 42276 COSMASKf)) - 1; 42277 rv = soc_reg_field32_modify(unit, COSMASKr, port, 42278 COSMASKf, val); 42279 } 42280 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) 42281 } else if (SOC_IS_HELIX4(unit) || SOC_IS_TRIUMPH3(unit)) { 42282 rv = BCM_E_NONE; 42283 if (value > 0 ) { 42284 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) { 42285 /* Port tx already enabled */ 42286 break; 42287 } 42288 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX; 42289 BCM_IF_ERROR_RETURN(_bcm_tr3_port_tx_set(unit, port, 1)); 42290 } else { 42291 if ((PORT(unit, port).flags & _PORT_INFO_STOP_TX)) { 42292 /* Port tx already disabled */ 42293 break; 42294 } 42295 PORT(unit, port).flags |= _PORT_INFO_STOP_TX; 42296 BCM_IF_ERROR_RETURN(_bcm_tr3_port_tx_set(unit, port, 0)); 42297 } 42298 break; 42299 #endif 42300 } else if ((SOC_REG_IS_VALID(unit, EGRMETERINGCONFIGr)) || 42301 (SOC_REG_IS_VALID(unit, EGRMETERINGBUCKETr))) { /* Use egress metering control if available */ 42302 uint32 rval1 = 0, rval2 = 0; 42303 if (value > 0 ) { 42304 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) { 42305 /* Port tx was never stopped */ 42306 break; 42307 } 42308 /* Restore values */ 42309 BCM_IF_ERROR_RETURN(READ_EGRMETERINGCONFIGr(unit, port, 42310 &rval1)); 42311 BCM_IF_ERROR_RETURN(READ_EGRMETERINGBUCKETr(unit, port, 42312 &rval2)); 42313 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1, 42314 REFRESHf, PORT(unit, port).m_info.refresh); 42315 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1, 42316 THD_SELf, PORT(unit, port).m_info.threshold); 42317 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2, 42318 BUCKETf, PORT(unit, port).m_info.bucket); 42319 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2, 42320 IN_PROFILE_FLAGf, 42321 PORT(unit, port).m_info.in_profile); 42322 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGCONFIGr(unit, port, 42323 rval1)); 42324 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGBUCKETr(unit, port, 42325 rval2)); 42326 /* clear flag */ 42327 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX; 42328 rv = BCM_E_NONE; 42329 42330 } else { 42331 /* Read and save current values */ 42332 BCM_IF_ERROR_RETURN(READ_EGRMETERINGCONFIGr(unit, port, 42333 &rval1)); 42334 PORT(unit, port).m_info.refresh = 42335 soc_reg_field_get(unit, EGRMETERINGCONFIGr, rval1, 42336 REFRESHf); 42337 PORT(unit, port).m_info.threshold = 42338 soc_reg_field_get(unit, EGRMETERINGCONFIGr, rval1, 42339 THD_SELf); 42340 BCM_IF_ERROR_RETURN(READ_EGRMETERINGBUCKETr(unit, port, 42341 &rval2)); 42342 PORT(unit, port).m_info.bucket = 42343 soc_reg_field_get(unit, EGRMETERINGBUCKETr, rval2, 42344 BUCKETf); 42345 PORT(unit, port).m_info.in_profile = 42346 soc_reg_field_get(unit, EGRMETERINGBUCKETr, rval2, 42347 IN_PROFILE_FLAGf); 42348 /* set flag */ 42349 PORT(unit, port).flags |= _PORT_INFO_STOP_TX; 42350 /* Disable Tx */ 42351 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1, 42352 REFRESHf, 0); 42353 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1, 42354 THD_SELf, 1); 42355 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2, 42356 BUCKETf, 0x100000); 42357 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2, 42358 IN_PROFILE_FLAGf, 1); 42359 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGCONFIGr(unit, port, 42360 rval1)); 42361 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGBUCKETr(unit, port, 42362 rval2)); 42363 rv = BCM_E_NONE; 42364 } 42365 } else { 42366 int (*port_tx_enable_set) (int, soc_port_t, int); 42367 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 42368 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TRIDENT2(unit)) { 42369 port_tx_enable_set = soc_td2_port_traffic_egr_enable_set; 42370 } else 42371 #endif 42372 #if defined(BCM_TRIDENT3_SUPPORT) 42373 if (SOC_IS_TRIDENT3X(unit)) { 42374 port_tx_enable_set = soc_td3_port_traffic_egr_enable_set; 42375 } else 42376 #endif 42377 #if defined(BCM_MONTEREY_SUPPORT) 42378 if (SOC_IS_MONTEREY(unit)) { 42379 port_tx_enable_set = soc_monterey_port_traffic_egr_enable_set; 42380 } else 42381 #endif 42382 #if defined(BCM_APACHE_SUPPORT) 42383 if (SOC_IS_APACHE(unit)) { 42384 port_tx_enable_set = soc_apache_port_traffic_egr_enable_set; 42385 } else 42386 #endif 42387 #if defined(BCM_TOMAHAWK_SUPPORT) 42388 if (SOC_IS_TOMAHAWKX(unit)) { 42389 port_tx_enable_set = soc_tomahawk_port_traffic_egr_enable_set; 42390 } else 42391 #endif 42392 { 42393 port_tx_enable_set = NULL; 42394 } 42395 if (port_tx_enable_set != NULL ) { 42396 rv = BCM_E_NONE; 42397 if (value > 0 ) { 42398 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) { 42399 /* Port tx was never stopped */ 42400 break; 42401 } 42402 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX; 42403 BCM_IF_ERROR_RETURN(((*port_tx_enable_set)(unit, port, 1))); 42404 } else { 42405 if ((PORT(unit, port).flags & _PORT_INFO_STOP_TX)) { 42406 /* Port tx alrady enabled */ 42407 break; 42408 } 42409 PORT(unit, port).flags |= _PORT_INFO_STOP_TX; 42410 BCM_IF_ERROR_RETURN(((*port_tx_enable_set)(unit, port, 0))); 42411 } 42412 break; 42413 } else { 42414 rv = BCM_E_UNAVAIL; 42415 } 42416 } 42417 break; 42418 case bcmPortControlMplsEntropyHashSet: 42419 #if defined(BCM_TRIUMPH3_SUPPORT) 42420 if (SOC_IS_TRIUMPH3(unit)) { 42421 return BCM_E_UNAVAIL; 42422 } else 42423 #endif /* BCM_TRIUMPH3_SUPPORT */ 42424 #if defined(BCM_KATANA2_SUPPORT) 42425 if (SOC_IS_KATANA2(unit)) { 42426 return BCM_E_UNAVAIL; 42427 } else 42428 #endif /* BCM_KATANA2_SUPPORT */ 42429 { 42430 #if defined(BCM_KATANA_SUPPORT) 42431 if (soc_feature(unit, soc_feature_mpls)) { 42432 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42433 RTAG7_HASH_CFG_SEL_ENTROPY_LABELf, 42434 (value) ? 1 : 0); 42435 } 42436 #endif /* BCM_KATANA_SUPPORT */ 42437 } 42438 break; 42439 42440 case bcmPortControlL2GreEnable: 42441 #if defined(BCM_TRIUMPH3_SUPPORT) 42442 if (soc_feature(unit, soc_feature_l2gre) 42443 #if defined(BCM_TRIDENT3_SUPPORT) 42444 || soc_feature(unit, soc_feature_flex_flow) 42445 #endif 42446 ) { 42447 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42448 L2GRE_TERMINATION_ALLOWEDf, 42449 (value) ? 1 : 0); 42450 } 42451 #endif /* BCM_TRIUMPH3_SUPPORT */ 42452 break; 42453 42454 case bcmPortControlL2GreTunnelbasedVpnId: 42455 #if defined(BCM_TRIUMPH3_SUPPORT) 42456 if (soc_feature(unit, soc_feature_l2gre) 42457 #if defined(BCM_TRIDENT3_SUPPORT) 42458 || soc_feature(unit, soc_feature_flex_flow) 42459 #endif 42460 ) { 42461 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42462 L2GRE_VPNID_LOOKUP_KEY_TYPEf, 42463 (value) ? 1 : 0); 42464 42465 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 42466 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 42467 L2GRE_VFI_LOOKUP_KEY_TYPEf)) { 42468 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 42469 L2GRE_VFI_LOOKUP_KEY_TYPEf, 42470 (value) ? 1 : 0); 42471 } 42472 } 42473 } 42474 #endif /* BCM_TRIUMPH3_SUPPORT */ 42475 break; 42476 42477 case bcmPortControlL2GreDefaultTunnelEnable: 42478 #if defined(BCM_TRIUMPH3_SUPPORT) 42479 if (soc_feature(unit, soc_feature_l2gre) 42480 #if defined(BCM_TRIDENT3_SUPPORT) 42481 || soc_feature(unit, soc_feature_flex_flow) 42482 #endif 42483 ) { 42484 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42485 L2GRE_DEFAULT_SVP_ENABLEf, 42486 (value) ? 1 : 0); 42487 } 42488 #endif /* BCM_TRIUMPH3_SUPPORT */ 42489 break; 42490 42491 case bcmPortControlVxlanEnable: 42492 #if defined(BCM_TRIDENT2_SUPPORT) 42493 if ((soc_feature(unit, soc_feature_vxlan)) || 42494 (soc_feature(unit, soc_feature_flex_flow))) { 42495 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42496 VXLAN_TERMINATION_ALLOWEDf, 42497 (value) ? 1 : 0); 42498 } 42499 #endif /* BCM_TRIDENT2_SUPPORT */ 42500 break; 42501 42502 case bcmPortControlVxlanTunnelbasedVnId: 42503 #if defined(BCM_TRIDENT2_SUPPORT) 42504 if ((soc_feature(unit, soc_feature_vxlan)) || 42505 (soc_feature(unit, soc_feature_flex_flow))) { 42506 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42507 VXLAN_VN_ID_LOOKUP_KEY_TYPEf, 42508 (value) ? 1 : 0); 42509 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 42510 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 42511 VXLAN_VFI_LOOKUP_KEY_TYPEf)) { 42512 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 42513 VXLAN_VFI_LOOKUP_KEY_TYPEf, 42514 (value) ? 1 : 0); 42515 } 42516 } 42517 #if defined(BCM_TRIDENT3_SUPPORT) && defined(CANCUN_SUPPORT) 42518 if (BCM_SUCCESS(rv) && SOC_IS_TRIDENT3X(unit)) { 42519 rv = _bcm_esw_td3_port_cmh_ctrl_set(unit, port, type, value); 42520 } 42521 #endif 42522 } 42523 #endif /* BCM_TRIDENT2_SUPPORT */ 42524 break; 42525 case bcmPortControlVxlanVpnAssignmentCriteria: 42526 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 42527 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 42528 if ((value < bcmPortVxlanVpnAssignOnVnid) 42529 || (value > bcmPortVxlanVpnAssignOnVnidOuterVlanSrcIp)) { 42530 return BCM_E_PARAM; 42531 } 42532 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42533 VXLAN_VN_ID_LOOKUP_KEY_TYPEf, value); 42534 } 42535 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 42536 break; 42537 case bcmPortControlVxlanTerminationMatchCriteria: 42538 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 42539 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 42540 if ((value < bcmPortVxlanTerminationMatchDstIp) 42541 || (value > bcmPortVxlanTerminationMatchOuterVlanDstIp)) { 42542 return BCM_E_PARAM; 42543 } 42544 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42545 VXLAN_TERMINATION_LOOKUP_TYPEf, value); 42546 } 42547 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 42548 break; 42549 case bcmPortControlVxlanGportAssignmentCriteria: 42550 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 42551 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 42552 if ((value < bcmPortVxlanGportAssignOnSrcIp) 42553 || (value > bcmPortVxlanGportAssignOnOuterVlanSrcIp)) { 42554 return BCM_E_PARAM; 42555 } 42556 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42557 VXLAN_SVP_ASSIGNMENT_KEY_TYPEf, value); 42558 } 42559 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 42560 break; 42561 case bcmPortControlVxlanDefaultTunnelEnable: 42562 #if defined(BCM_TRIDENT2_SUPPORT) 42563 if ((soc_feature(unit, soc_feature_vxlan)) || 42564 (soc_feature(unit, soc_feature_flex_flow))) { 42565 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42566 VXLAN_DEFAULT_SVP_ENABLEf, 42567 (value) ? 1 : 0); 42568 } 42569 #endif /* BCM_TRIDENT2_SUPPORT */ 42570 break; 42571 42572 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX) 42573 case bcmPortControlRegex: 42574 if (!SOC_IS_TRIUMPH3(unit)) { 42575 return BCM_E_UNAVAIL; 42576 } 42577 rv = _bcm_esw_port_regex_control_set(unit, port, 1, 1, !!value); 42578 break; 42579 case bcmPortControlRegexTcp: 42580 if (!SOC_IS_TRIUMPH3(unit)) { 42581 return BCM_E_UNAVAIL; 42582 } 42583 rv = _bcm_esw_port_regex_control_set(unit, port, 0, 1, !!value); 42584 break; 42585 case bcmPortControlRegexUdp: 42586 if (!SOC_IS_TRIUMPH3(unit)) { 42587 return BCM_E_UNAVAIL; 42588 } 42589 rv = _bcm_esw_port_regex_control_set(unit, port, 1, 0, !!value); 42590 break; 42591 #endif 42592 #ifdef BCM_SHADOW_SUPPORT 42593 case bcmPortControlManagementPacketIp6Reserved: 42594 if (!SOC_IS_SHADOW(unit)) { 42595 return BCM_E_UNAVAIL; 42596 } 42597 PORT_LOCK(unit); 42598 if (value == 0) { 42599 /* Clear the MGMT Frame classification */ 42600 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 42601 IPV6_RESVf, 0); 42602 } else { 42603 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 42604 IPV6_RESVf, 1); 42605 } 42606 PORT_UNLOCK(unit); 42607 break; 42608 case bcmPortControlManagementPacketIp4Reserved: 42609 if (!SOC_IS_SHADOW(unit)) { 42610 return BCM_E_UNAVAIL; 42611 } 42612 PORT_LOCK(unit); 42613 if (value == 0) { 42614 /* Clear the MGMT Frame classification */ 42615 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 42616 IPV6_RESVf, 0); 42617 } else { 42618 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 42619 IPV4_RESVf, 1); 42620 } 42621 PORT_UNLOCK(unit); 42622 break; 42623 case bcmPortControlManagementPacketLinkConstrained: 42624 if (!SOC_IS_SHADOW(unit)) { 42625 return BCM_E_UNAVAIL; 42626 } 42627 PORT_LOCK(unit); 42628 if (value == 0) { 42629 /* Clear the MGMT Frame classification */ 42630 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 42631 LINK_CONSTf, 0); 42632 } else { 42633 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 42634 LINK_CONSTf, 1); 42635 } 42636 PORT_UNLOCK(unit); 42637 break; 42638 case bcmPortControlManagementPacketGarp: 42639 if (!SOC_IS_SHADOW(unit)) { 42640 return BCM_E_UNAVAIL; 42641 } 42642 PORT_LOCK(unit); 42643 if (value == 0) { 42644 /* Clear the MGMT Frame classification */ 42645 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 42646 DOT1D_GARPf, 0); 42647 } else { 42648 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 42649 DOT1D_GARPf, 1); 42650 } 42651 PORT_UNLOCK(unit); 42652 break; 42653 case bcmPortControlManagementPacketCos: 42654 if (!SOC_IS_SHADOW(unit)) { 42655 return BCM_E_UNAVAIL; 42656 } 42657 PORT_LOCK(unit); 42658 if ((value >= 0) && (value <= 7)) { 42659 /* Clear the MGMT Frame classification */ 42660 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 42661 MGMT_FRAME_COSf, value); 42662 } else { 42663 rv = BCM_E_PARAM; 42664 } 42665 PORT_UNLOCK(unit); 42666 break; 42667 case bcmPortControlManagementPacketColor: 42668 rv = BCM_E_UNAVAIL; 42669 break; 42670 case bcmPortControlTaggedL3PacketPktPri: 42671 if (!SOC_IS_SHADOW(unit)) { 42672 return BCM_E_UNAVAIL; 42673 } 42674 PORT_LOCK(unit); 42675 switch ((bcm_port_cos_remap_t)value) { 42676 case BCM_PORT_COS_REMAP_VLAN_PRI: 42677 /* Clear the MGMT Frame classification */ 42678 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 42679 SELECT5f, 0); 42680 break; 42681 case BCM_PORT_COS_REMAP_DSCP: 42682 /* Clear the MGMT Frame classification */ 42683 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 42684 SELECT5f, 2); 42685 break; 42686 default: 42687 rv = BCM_E_PARAM; 42688 } 42689 PORT_UNLOCK(unit); 42690 break; 42691 case bcmPortControlTaggedMPLSPacketPktPri: 42692 if (!SOC_IS_SHADOW(unit)) { 42693 return BCM_E_UNAVAIL; 42694 } 42695 PORT_LOCK(unit); 42696 switch ((bcm_port_cos_remap_t)value) { 42697 case BCM_PORT_COS_REMAP_VLAN_PRI: 42698 /* Clear the MGMT Frame classification */ 42699 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 42700 SELECT3f, 0); 42701 break; 42702 case BCM_PORT_COS_REMAP_EXP: 42703 /* Clear the MGMT Frame classification */ 42704 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 42705 SELECT3f, 1); 42706 break; 42707 default: 42708 rv = BCM_E_PARAM; 42709 } 42710 PORT_UNLOCK(unit); 42711 break; 42712 case bcmPortControlTaggedMPLSL3PacketPktPri: 42713 if (!SOC_IS_SHADOW(unit)) { 42714 return BCM_E_UNAVAIL; 42715 } 42716 PORT_LOCK(unit); 42717 switch(value) { 42718 case BCM_PORT_COS_REMAP_VLAN_PRI: 42719 /* Clear the MGMT Frame classification */ 42720 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 42721 SELECT7f, 0); 42722 break; 42723 case BCM_PORT_COS_REMAP_DSCP: 42724 /* Clear the MGMT Frame classification */ 42725 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 42726 SELECT7f, 2); 42727 break; 42728 case BCM_PORT_COS_REMAP_EXP: 42729 /* Clear the MGMT Frame classification */ 42730 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 42731 SELECT7f, 1); 42732 break; 42733 default: 42734 rv = BCM_E_PARAM; 42735 } 42736 PORT_UNLOCK(unit); 42737 break; 42738 42739 #endif 42740 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 42741 case bcmPortControlFieldEgressClassSelect: 42742 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 42743 if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) { 42744 rv = _bcm_td2p_port_control_egress_class_select_set(unit, port, value); 42745 } else 42746 #endif 42747 { 42748 rv = _bcm_trx_port_control_egress_class_select_set(unit, port, value); 42749 } 42750 break; 42751 #endif 42752 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 42753 case bcmPortControlFieldHiGigClassSelect: 42754 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 42755 if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) { 42756 rv = _bcm_td2p_port_control_higig_class_select_set(unit, port, value); 42757 } else 42758 #endif 42759 { 42760 rv = _bcm_trx_port_control_higig_class_select_set(unit, port, value); 42761 } 42762 break; 42763 #endif 42764 case bcmPortControlSubportTagEnable: 42765 42766 #if defined (BCM_HGPROXY_COE_SUPPORT) 42767 if((soc_feature(unit, soc_feature_hgproxy_subtag_coe)) || 42768 (soc_feature(unit, soc_feature_channelized_switching))) { 42769 rv = bcmi_xgs5_port_control_subtag_status_set(unit, port, value); 42770 } 42771 #endif 42772 #if defined (BCM_KATANA2_SUPPORT) 42773 if (soc_feature(unit, soc_feature_subtag_coe)) { 42774 if (SOC_IS_KATANA2(unit)) { 42775 rv = bcm_kt2_port_control_subtag_status_set(unit, port, value); 42776 } 42777 #if defined (BCM_METROLITE_SUPPORT) 42778 /*In Metrolite physical port PP port is [re]used for the subports 42779 * to achieve the MAX number of streams.*/ 42780 if((soc_feature(unit, soc_feature_discontinuous_pp_port)) && (rv == BCM_E_NONE)){ 42781 BCM_PBMP_CLEAR(pbm); 42782 BCM_PBMP_PORT_ADD(pbm, port); 42783 if(value){ 42784 bcm_esw_vlan_port_remove(unit, BCM_VLAN_DEFAULT, pbm); 42785 }else{ 42786 bcm_esw_vlan_port_add(unit, BCM_VLAN_DEFAULT, pbm, pbm); 42787 } 42788 } 42789 #endif 42790 } 42791 #endif 42792 break; 42793 42794 case bcmPortControlLinkPhyEnable: 42795 #if defined (BCM_KATANA2_SUPPORT) 42796 if (soc_feature(unit, soc_feature_linkphy_coe)) { 42797 if (SOC_IS_KATANA2(unit)) { 42798 rv = bcm_kt2_port_control_linkphy_status_set(unit, port, value); 42799 } 42800 #if defined (BCM_METROLITE_SUPPORT) 42801 /*In Metrolite physical port PP port is [re]used for the subports 42802 * to achieve the MAX number of streams.*/ 42803 if((soc_feature(unit, soc_feature_discontinuous_pp_port)) && (rv == BCM_E_NONE)){ 42804 BCM_PBMP_CLEAR(pbm); 42805 BCM_PBMP_PORT_ADD(pbm, port); 42806 if(value){ 42807 bcm_esw_vlan_port_remove(unit, BCM_VLAN_DEFAULT, pbm); 42808 }else{ 42809 bcm_esw_vlan_port_add(unit, BCM_VLAN_DEFAULT, pbm, pbm); 42810 } 42811 } 42812 #endif 42813 } 42814 #endif 42815 break; 42816 42817 #if defined(BCM_TRIDENT2_SUPPORT) 42818 42819 case bcmPortControlFcoeRouteEnable: 42820 if (soc_feature(unit, soc_feature_fcoe)) { 42821 #ifdef BCM_TRIDENT3_SUPPORT 42822 if (SOC_IS_TRIDENT3X(unit)) { 42823 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42824 FCOE_ROUTE_ENABLEf, 42825 (value) ? 1 : 0); 42826 if ((rv == BCM_E_NONE) && 42827 SOC_MEM_IS_VALID(unit, EGR_PORTm) && 42828 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_ROUTE_ENABLEf)) { 42829 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 42830 FCOE_ROUTE_ENABLEf, 42831 (value) ? 1 : 0); 42832 } 42833 } else 42834 #endif 42835 { 42836 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_ROUTE_ENABLEf)) { 42837 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42838 FCOE_ROUTE_ENABLEf, 42839 (value) ? 1 : 0); 42840 } 42841 if ((rv == BCM_E_NONE) && 42842 SOC_MEM_IS_VALID(unit, EGR_PORTm) && 42843 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_ROUTE_ENABLEf)) { 42844 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 42845 FCOE_ROUTE_ENABLEf, 42846 (value) ? 1 : 0); 42847 } 42848 } 42849 } 42850 break; 42851 42852 case bcmPortControlFcoeVftEnable: 42853 if (soc_feature(unit, soc_feature_fcoe)) { 42854 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VFT_ENABLEf)) { 42855 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42856 FCOE_VFT_ENABLEf, (value) ? 1 : 0); 42857 } 42858 } 42859 break; 42860 42861 case bcmPortControlFcoeZoneCheckEnable: 42862 if (soc_feature(unit, soc_feature_fcoe)) { 42863 if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, 42864 FCOE_ZONE_CHECK_ENABLEf))) { 42865 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42866 FCOE_ZONE_CHECK_ENABLEf, 42867 (value) ? 1 : 0); 42868 } 42869 } 42870 break; 42871 42872 case bcmPortControlFcoeSourceBindCheckEnable: 42873 if (soc_feature(unit, soc_feature_fcoe)) { 42874 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, 42875 FCOE_SRC_BIND_CHECK_ENABLEf)) { 42876 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42877 FCOE_SRC_BIND_CHECK_ENABLEf, 42878 (value) ? 1 : 0); 42879 } 42880 } 42881 break; 42882 42883 case bcmPortControlFcoeFpmaPrefixCheckEnable: 42884 if (soc_feature(unit, soc_feature_fcoe)) { 42885 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, 42886 FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf)) { 42887 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42888 FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf, 42889 (value) ? 1 : 0); 42890 } 42891 } 42892 break; 42893 42894 case bcmPortControlFcoeDoNotLearn: 42895 if (soc_feature(unit, soc_feature_fcoe)) { 42896 if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_DO_NOT_LEARNf))) { 42897 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42898 FCOE_DO_NOT_LEARNf, 42899 (value) ? 1 : 0); 42900 } 42901 } 42902 break; 42903 42904 case bcmPortControlFcoeNetworkPort: 42905 if (soc_feature(unit, soc_feature_fcoe)) { 42906 if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_NETWORK_PORTf))) { 42907 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42908 FCOE_NETWORK_PORTf, 42909 (value) ? 1 : 0); 42910 } 42911 } 42912 break; 42913 42914 case bcmPortControlFcoeFabricSel: 42915 if (soc_feature(unit, soc_feature_fcoe)) { 42916 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_SELf)) { 42917 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42918 FCOE_FABRIC_SELf, value); 42919 } 42920 } 42921 break; 42922 42923 case bcmPortControlFcoeFabricId: 42924 if (soc_feature(unit, soc_feature_fcoe)) { 42925 #ifdef BCM_TRIDENT3_SUPPORT 42926 if (SOC_IS_TRIDENT3X(unit)) { 42927 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42928 FCOE_FABRIC_IDf, value); 42929 } else 42930 #endif 42931 { 42932 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_IDf)) { 42933 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42934 FCOE_FABRIC_IDf, value); 42935 } 42936 } 42937 } 42938 break; 42939 42940 case bcmPortControlFcoeFabricPri: 42941 if (soc_feature(unit, soc_feature_fcoe)) { 42942 #ifdef BCM_TRIDENT3_SUPPORT 42943 if (SOC_IS_TRIDENT3X(unit)) { 42944 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42945 FCOE_FABRIC_PRIf, value); 42946 } else 42947 #endif 42948 { 42949 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_PRIf)) { 42950 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42951 FCOE_FABRIC_PRIf, value); 42952 } 42953 } 42954 } 42955 break; 42956 42957 case bcmPortControlFcoeFcCrcAction: 42958 if (soc_feature(unit, soc_feature_fcoe)) { 42959 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, 42960 FCOE_FC_CRC_ACTIONf)) { 42961 /* 2 bits but only 0,1 are valid */ 42962 rv = soc_mem_field32_modify(unit, EGR_ING_PORTm, port, 42963 FCOE_FC_CRC_ACTIONf, value); 42964 } 42965 } 42966 break; 42967 42968 case bcmPortControlFcoeFcCrcRecompute: 42969 if (soc_feature(unit, soc_feature_fcoe)) { 42970 if (SOC_MEM_IS_VALID(unit, EGR_PORTm) && 42971 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 42972 FCOE_FC_CRC_RECOMPUTEf)) { 42973 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 42974 FCOE_FC_CRC_RECOMPUTEf, value); 42975 } 42976 } 42977 break; 42978 42979 case bcmPortControlFcoeFcEofIgnore: 42980 if (soc_feature(unit, soc_feature_fcoe)) { 42981 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, 42982 FCOE_FC_EOF_IGNOREf)) { 42983 rv = soc_mem_field32_modify(unit, EGR_ING_PORTm, port, 42984 FCOE_FC_EOF_IGNOREf, 42985 (value) ? 1 : 0); 42986 } 42987 } 42988 break; 42989 42990 case bcmPortControlFcoeTranslateKeyFirst: 42991 case bcmPortControlFcoeTranslateKeySecond: 42992 if (soc_feature(unit, soc_feature_fcoe)) { 42993 42994 /* first, translate value to HW value */ 42995 int key_type = 0; 42996 int key_type_value; 42997 int use_port = 0; 42998 42999 switch (value) { 43000 case bcmFcoeVsanTranslateKeyPortDouble: 43001 use_port = 1; /* fall thru */ 43002 case bcmFcoeVsanTranslateKeyDouble: 43003 key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID; 43004 break; 43005 case bcmFcoeVsanTranslateKeyPortOuterTag: 43006 use_port = 1; /* fall thru */ 43007 case bcmFcoeVsanTranslateKeyOuterTag: 43008 key_type = VLXLT_HASH_KEY_TYPE_OTAG; 43009 break; 43010 case bcmFcoeVsanTranslateKeyPortInnerTag: 43011 use_port = 1; /* fall thru */ 43012 case bcmFcoeVsanTranslateKeyInnerTag: 43013 key_type = VLXLT_HASH_KEY_TYPE_ITAG; 43014 break; 43015 case bcmFcoeVsanTranslateKeyPortOuter: 43016 use_port = 1; /* fall thru */ 43017 case bcmFcoeVsanTranslateKeyOuter: 43018 key_type = VLXLT_HASH_KEY_TYPE_OVID; 43019 break; 43020 case bcmFcoeVsanTranslateKeyPortInner: 43021 use_port = 1; /* fall thru */ 43022 case bcmFcoeVsanTranslateKeyInner: 43023 key_type = VLXLT_HASH_KEY_TYPE_IVID; 43024 break; 43025 case bcmFcoeVsanTranslateKeyPortOuterPri: 43026 use_port = 1; /* fall thru */ 43027 case bcmFcoeVsanTranslateKeyOuterPri: 43028 key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI; 43029 break; 43030 case bcmFcoeVsanTranslateKeyPortDoubleVsan: 43031 use_port = 1; /* fall thru */ 43032 case bcmFcoeVsanTranslateKeyDoubleVsan: 43033 key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN; 43034 break; 43035 case bcmFcoeVsanTranslateKeyPortInnerVsan: 43036 use_port = 1; /* fall thru */ 43037 case bcmFcoeVsanTranslateKeyInnerVsan: 43038 key_type = VLXLT_HASH_KEY_TYPE_IVID_VSAN; 43039 break; 43040 case bcmFcoeVsanTranslateKeyPortOuterVsan: 43041 use_port = 1; /* fall thru */ 43042 case bcmFcoeVsanTranslateKeyOuterVsan: 43043 key_type = VLXLT_HASH_KEY_TYPE_OVID_VSAN; 43044 break; 43045 default: 43046 return BCM_E_PARAM; 43047 } 43048 43049 BCM_IF_ERROR_RETURN( 43050 _bcm_esw_vlan_xlate_key_type_value_get(unit, key_type, 43051 &key_type_value)); 43052 43053 if (type == bcmPortControlFcoeTranslateKeyFirst) { 43054 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_1f)) { 43055 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 43056 FCOE_VT_KEY_TYPE_1f, 43057 key_type_value); 43058 } 43059 if (BCM_SUCCESS(rv)) { 43060 rv = _bcm_esw_port_config_set(unit, port, 43061 _bcmPortVTKeyPortFirst, 43062 use_port); 43063 } 43064 } else { 43065 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_2f)) { 43066 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 43067 FCOE_VT_KEY_TYPE_2f, 43068 key_type_value); 43069 } 43070 if (BCM_SUCCESS(rv)) { 43071 rv = _bcm_esw_port_config_set(unit, port, 43072 _bcmPortVTKeyPortSecond, 43073 use_port); 43074 } 43075 } 43076 } 43077 break; 43078 43079 case bcmPortControlFcoeTranslateKeyFirstEgress: 43080 case bcmPortControlFcoeTranslateKeySecondEgress: 43081 if (soc_feature(unit, soc_feature_fcoe)) { 43082 43083 /* first, translate value to HW value */ 43084 int key_type_value = 0; 43085 43086 switch (value) { 43087 case bcmFcoeVsanTranslateKeyEgressDoubleVsan: 43088 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN; 43089 break; 43090 case bcmFcoeVsanTranslateKeyEgressVsan: 43091 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_VSAN; 43092 break; 43093 case bcmFcoeVsanTranslateKeyEgressInnerVsan: 43094 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID_VSAN; 43095 break; 43096 case bcmFcoeVsanTranslateKeyEgressOuterVsan: 43097 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_OVID_VSAN; 43098 break; 43099 case bcmFcoeVsanTranslateKeyEgressDouble: 43100 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID; 43101 break; 43102 case bcmFcoeVsanTranslateKeyEgressInner: 43103 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID; 43104 break; 43105 case bcmFcoeVsanTranslateKeyEgressOuter: 43106 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_OVID; 43107 break; 43108 default: 43109 return BCM_E_PARAM; 43110 } 43111 43112 if (type == bcmPortControlFcoeTranslateKeyFirstEgress) { 43113 if (SOC_IS_TRIDENT3X(unit) || 43114 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_1f)) { 43115 rv = _bcm_esw_egr_port_tab_set(unit, port, 43116 FCOE_VT_LOOKUP_1f, 43117 key_type_value); 43118 } 43119 } else { 43120 if (SOC_IS_TRIDENT3X(unit) || 43121 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_2f)) { 43122 rv = _bcm_esw_egr_port_tab_set(unit, port, 43123 FCOE_VT_LOOKUP_2f, 43124 key_type_value); 43125 } 43126 } 43127 } 43128 break; 43129 43130 #endif /* TRIDENT2 */ 43131 case bcmPortControlEEEMode: 43132 if (soc_feature(unit, soc_feature_eee_bb_mode)) { 43133 uint32 rval = 0; 43134 uint32 fval = 0; 43135 uint32 temp = 0; 43136 if (soc_feature (unit, soc_feature_high_portcount_register)) { 43137 soc_reg_t eee_bb_reg; 43138 int phy_port; 43139 int mmu_port; 43140 int offset; 43141 43142 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 43143 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 43144 if (mmu_port < 32) { 43145 eee_bb_reg = EEE_BB_ENABLE_0r; 43146 offset = mmu_port; 43147 } else if ((mmu_port >=32) && (mmu_port < 64)) { 43148 eee_bb_reg = EEE_BB_ENABLE_1r; 43149 offset = mmu_port - 32; 43150 } else { /* mmu_port >= 64 */ 43151 eee_bb_reg = EEE_BB_ENABLE_2r; 43152 offset = mmu_port - 64; 43153 } 43154 temp = (1 << offset); 43155 BCM_IF_ERROR_RETURN( 43156 soc_reg32_get(unit, eee_bb_reg, REG_PORT_ANY, 0, &rval)); 43157 fval = soc_reg_field_get(unit, eee_bb_reg, rval, 43158 EEE_BB_ENABLEf); 43159 if (value == bcmPortEEEBurstAndBatchMode) { 43160 fval |= temp; 43161 } else if (value == bcmPortEEENativeMode) { 43162 fval &= ~temp; 43163 } else { 43164 return BCM_E_PARAM; 43165 } 43166 rv = soc_reg_field32_modify(unit, eee_bb_reg, REG_PORT_ANY, 43167 EEE_BB_ENABLEf, 43168 fval); 43169 } else { 43170 temp = (1 << port); 43171 temp >>= 2; 43172 READ_EEE_BB_ENABLEr(unit, &rval); 43173 fval = soc_reg_field_get(unit, EEE_BB_ENABLEr, rval, 43174 EEE_BB_ENABLEf); 43175 if (value == bcmPortEEEBurstAndBatchMode) { 43176 fval |= temp; 43177 } else if (value == bcmPortEEENativeMode) { 43178 fval &= ~temp; 43179 } else { 43180 return BCM_E_PARAM; 43181 } 43182 rv = soc_reg_field32_modify(unit, EEE_BB_ENABLEr, REG_PORT_ANY, 43183 EEE_BB_ENABLEf, 43184 fval); 43185 } 43186 } 43187 break; 43188 #ifdef BCM_GREYHOUND_SUPPORT 43189 case bcmPortControlWredDropCountUpdateEnableQueueMask: 43190 if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) { 43191 #if defined(BCM_GREYHOUND2_SUPPORT) 43192 if (SOC_IS_GREYHOUND2(unit)) { 43193 rv = bcmi_gh2_cosq_wred_port_control_set(unit, port, type, 43194 value); 43195 } else 43196 #endif /* BCM_GREYHOUND2_SUPPORT */ 43197 { 43198 rv = soc_reg_field32_modify(unit, WRED_DROP_CTR_CONFIGr, 43199 port, QUEUE_MASKf, value); 43200 } 43201 } 43202 break; 43203 case bcmPortControlWredDropCountUpdateEnableColorMask: 43204 if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) { 43205 /* parameter checking */ 43206 if (value & ~((0x1 << bcmColorGreen) | 43207 (0x1 << bcmColorYellow) | 43208 (0x1 << bcmColorRed))) { 43209 return BCM_E_PARAM; 43210 } 43211 #if defined(BCM_GREYHOUND2_SUPPORT) 43212 if (SOC_IS_GREYHOUND2(unit)) { 43213 rv = bcmi_gh2_cosq_wred_port_control_set(unit, port, type, 43214 value); 43215 } else 43216 #endif /* BCM_GREYHOUND2_SUPPORT */ 43217 { 43218 cur_val = 0; 43219 if (value & (0x1 << bcmColorGreen)) { 43220 cur_val |= 0x4; 43221 } 43222 if (value & (0x1 << bcmColorYellow)) { 43223 cur_val |= 0x2; 43224 } 43225 if (value & (0x1 << bcmColorRed)) { 43226 cur_val |= 0x1; 43227 } 43228 rv = soc_reg_field32_modify(unit, WRED_DROP_CTR_CONFIGr, 43229 port, COLOR_MASKf, cur_val); 43230 } 43231 } 43232 break; 43233 #endif /* BCM_GREYHOUND_SUPPORT */ 43234 #ifdef BCM_TRIDENT2_SUPPORT 43235 case bcmPortControlProbeSerdesReset: 43236 if (SOC_IS_TD2_TT2(unit)) { 43237 PORT_LOCK(unit); 43238 if (value) { 43239 PORT(unit, port).flags |= _PORT_INFO_PROBE_RESET_SERDES; 43240 } else { 43241 PORT(unit, port).flags &= ~_PORT_INFO_PROBE_RESET_SERDES; 43242 } 43243 PORT_UNLOCK(unit); 43244 rv = BCM_E_NONE; 43245 } 43246 break; 43247 #endif /* BCM_TRIDENT2_SUPPORT */ 43248 case bcmPortControlMmuDrain: 43249 rv = bcm_esw_port_drain_cells(unit, port, value); 43250 break; 43251 case bcmPortControlMmuTrafficEnable: 43252 rv = bcm_esw_port_enqueue_set(unit, port, value); 43253 break; 43254 case bcmPortControlRxFastLOS: 43255 rv = _bcm_esw_link_fast_set(unit, port, value); 43256 break; 43257 case bcmPortControlStatCollectionEnable: 43258 if (!SOC_PORT_VALID(unit, port)) { 43259 return BCM_E_PORT; 43260 } 43261 rv = soc_counter_port_collect_enable_set(unit, port, value); 43262 break; 43263 case bcmPortControlLLFCReceive: 43264 case bcmPortControlLLFCTransmit: 43265 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 43266 case bcmPortControlSAFCReceive: 43267 case bcmPortControlSAFCTransmit: 43268 #endif 43269 rv = _bcm_esw_port_llfc_set(unit, port, type, value); 43270 break; 43271 case bcmPortControlTrunkLoadBalancingRandomizer: 43272 #ifdef BCM_TOMAHAWK_SUPPORT 43273 if (soc_feature(unit, soc_feature_randomized_load_balance)) { 43274 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 43275 OFFSET_TRUNK_RANDOM_LBf, value); 43276 } 43277 #endif /* BCM_TOMAHAWK_SUPPORT */ 43278 break; 43279 case bcmPortControlECMPLevel1LoadBalancingRandomizer: 43280 #ifdef BCM_TOMAHAWK_SUPPORT 43281 if (soc_feature(unit, soc_feature_ecmp_random)) { 43282 if ((value < 0) || (value > 15)) { 43283 return BCM_E_PARAM; 43284 } 43285 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 43286 OFFSET_ECMP_RANDOM_LBf, value); 43287 } 43288 #endif /* BCM_TOMAHAWK_SUPPORT */ 43289 break; 43290 case bcmPortControlECMPLevel2LoadBalancingRandomizer: 43291 #ifdef BCM_TOMAHAWK_SUPPORT 43292 if (soc_feature(unit, soc_feature_ecmp_random)) { 43293 if ((value < 0) || (value > 15)) { 43294 return BCM_E_PARAM; 43295 } 43296 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 43297 OFFSET_ECMP_LEVEL2_RANDOM_LBf, 43298 value); 43299 } 43300 #endif /* BCM_TOMAHAWK_SUPPORT */ 43301 break; 43302 case bcmPortControlMcastGroupRemap: 43303 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, NETWORK_PORTf)) { 43304 rv = soc_mem_field32_modify(unit, SOURCE_VPm, port, 43305 NETWORK_PORTf, value ? 1 : 0); 43306 } 43307 break; 43308 case bcmPortControlOOBFCTxReportIngEnable: 43309 if (soc_feature(unit, soc_feature_oob_fc)) { 43310 #ifdef BCM_TOMAHAWK_SUPPORT 43311 if (SOC_IS_TOMAHAWKX(unit)) { 43312 rv = _bcm_th_oob_fc_tx_port_control_set(unit, port, value, 0); 43313 } 43314 #endif 43315 #ifdef BCM_KATANA2_SUPPORT 43316 if (SOC_IS_KATANA2(unit)) { 43317 rv = _bcm_kt2_oob_fc_tx_port_control_set(unit, port, value, 0); 43318 } 43319 #endif 43320 #ifdef BCM_TRIDENT3_SUPPORT 43321 if (SOC_IS_TRIDENT3X(unit)) { 43322 rv = _bcm_td3_oob_fc_tx_port_control_set(unit, port, value, 0); 43323 } 43324 #endif 43325 #ifdef BCM_APACHE_SUPPORT 43326 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 43327 rv = _bcm_ap_oob_fc_tx_port_control_set(unit, port, value, 0); 43328 } 43329 #endif 43330 } 43331 break; 43332 case bcmPortControlOOBFCTxReportEgrEnable: 43333 if (soc_feature(unit, soc_feature_oob_fc)) { 43334 #ifdef BCM_TOMAHAWK_SUPPORT 43335 if (SOC_IS_TOMAHAWKX(unit)) { 43336 rv = _bcm_th_oob_fc_tx_port_control_set(unit, port, value, 1); 43337 } 43338 #endif 43339 #ifdef BCM_APACHE_SUPPORT 43340 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 43341 rv = _bcm_ap_oob_fc_tx_port_control_set(unit, port, value, 1); 43342 } 43343 #endif 43344 #ifdef BCM_KATANA2_SUPPORT 43345 if (SOC_IS_KATANA2(unit)) { 43346 rv = _bcm_kt2_oob_fc_tx_port_control_set(unit, port, value, 1); 43347 } 43348 #endif 43349 #ifdef BCM_TRIDENT3_SUPPORT 43350 if (SOC_IS_TRIDENT3X(unit)) { 43351 rv = _bcm_th_oob_fc_tx_port_control_set(unit, port, value, 1); 43352 } 43353 #endif 43354 } 43355 break; 43356 43357 case bcmPortControlSubportTagSize: 43358 #ifdef BCM_HGPROXY_COE_SUPPORT 43359 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 43360 DESTINATION_SUBPORT_TAG_TYPEf)) { 43361 43362 int local_port = 0; 43363 if (BCM_GPORT_IS_SET(port)) { 43364 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 43365 } else { 43366 if(!SOC_PORT_VALID(unit, port)) { 43367 return BCM_E_PORT; 43368 } else { 43369 local_port = port; 43370 } 43371 } 43372 43373 /* Setting of tag_type to 8Byte is not supported currently, 43374 hence return error if 'value' is non-zero */ 43375 if(value) { 43376 return BCM_E_UNAVAIL; 43377 } 43378 43379 rv = soc_mem_field32_modify(unit, EGR_PORTm, local_port, 43380 DESTINATION_SUBPORT_TAG_TYPEf, value ? 1 : 0); 43381 } 43382 if (SOC_IS_TRIDENT3X(unit)) { 43383 if (value) { 43384 return BCM_E_UNAVAIL; 43385 } 43386 else { 43387 return BCM_E_NONE; 43388 } 43389 } 43390 #endif 43391 break; 43392 43393 case bcmPortControlSystemPortOverride: 43394 #ifdef BCM_HGPROXY_COE_SUPPORT 43395 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, VT_SYS_PORT_OVERRIDEf)) { 43396 rv = bcmi_xgs5_subport_subtag_port_override_set(unit, port, value); 43397 } 43398 #endif 43399 break; 43400 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 43401 case bcmPortControlSampleIngressDest: 43402 if(soc_feature(unit, soc_feature_sflow_ing_mem)) { 43403 sflow_ing_data_source_entry_t sflow_entry; 43404 uint32 field_values[2] = {0, 0}; 43405 if ((value < 0) || (value > 3)) { 43406 return BCM_E_PARAM; 43407 } 43408 43409 if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_CPU) == 43410 BCM_PORT_CONTROL_SAMPLE_DEST_CPU) { 43411 field_values[0] = 1; 43412 } 43413 if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) == 43414 BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) { 43415 field_values[1] = 1; 43416 } 43417 43418 BCM_IF_ERROR_RETURN 43419 (READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 43420 &sflow_entry)); 43421 soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry, 43422 CPUf, &field_values[0]); 43423 soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry, 43424 MIRRORf, &field_values[1]); 43425 BCM_IF_ERROR_RETURN 43426 (WRITE_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 43427 &sflow_entry)); 43428 rv = BCM_E_NONE; 43429 } 43430 break; 43431 case bcmPortControlSampleFlexDest: 43432 if(soc_feature(unit, soc_feature_sflow_flex)) { 43433 sflow_ing_flex_data_source_entry_t sflow_entry; 43434 uint32 field_values[2] = {0, 0}; 43435 if ((value < 0) || (value > 3)) { 43436 return BCM_E_PARAM; 43437 } 43438 43439 if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_CPU) == 43440 BCM_PORT_CONTROL_SAMPLE_DEST_CPU) { 43441 field_values[0] = 1; 43442 } 43443 if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) == 43444 BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) { 43445 field_values[1] = 1; 43446 } 43447 43448 BCM_IF_ERROR_RETURN 43449 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 43450 &sflow_entry)); 43451 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry, 43452 CPUf, &field_values[0]); 43453 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry, 43454 MIRRORf, &field_values[1]); 43455 BCM_IF_ERROR_RETURN 43456 (WRITE_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 43457 &sflow_entry)); 43458 rv = BCM_E_NONE; 43459 } 43460 break; 43461 case bcmPortControlSampleFlexRate: 43462 if(soc_feature(unit, soc_feature_sflow_flex)) { 43463 uint32 values[2] = {0, 0}; 43464 sflow_ing_flex_data_source_entry_t sflow_entry; 43465 soc_counter_non_dma_t *non_dma = NULL; 43466 soc_control_t *soc; 43467 uint32 count = 0, subset_ct = 0; 43468 43469 if (value < 0) { 43470 return BCM_E_PARAM; 43471 } 43472 /* Set sampling threshold */ 43473 if (value > 0) { 43474 /* Enable sFlow */ 43475 values[0] = 1; 43476 43477 /* Set sampling threshold */ 43478 if (value == 1) { 43479 /* Needs special handling to avoid register overflow */ 43480 values[1] = (1 << (SFLOW_RANGE_MAX(unit))) - 1; 43481 } else { 43482 /* Calculate threshold based on sampling rate */ 43483 values[1] = (1 << (SFLOW_RANGE_MAX(unit))) / value; 43484 } 43485 } 43486 43487 /* Update Flex rate limiting data table. */ 43488 BCM_IF_ERROR_RETURN 43489 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 43490 &sflow_entry)); 43491 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry, 43492 ENABLEf, &values[0]); 43493 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry, 43494 THRESHOLDf, &values[1]); 43495 BCM_IF_ERROR_RETURN 43496 (WRITE_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 43497 &sflow_entry)); 43498 43499 /* Enable counter thread for Flex sFlow samplers */ 43500 if (values[0] == 1) { 43501 soc = SOC_CONTROL(unit); 43502 non_dma = &soc->counter_non_dma[ 43503 SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT - 43504 SOC_COUNTER_NON_DMA_START]; 43505 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 43506 /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */ 43507 subset_ct = non_dma->extra_ctr_ct << 1; 43508 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 43509 non_dma = non_dma->extra_ctrs; 43510 43511 do { 43512 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 43513 /* BYTE_CTRf not currently supported */ 43514 count += 2; 43515 non_dma += 2; 43516 } while ((count < subset_ct)); 43517 } 43518 } 43519 rv = BCM_E_NONE; 43520 } 43521 break; 43522 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */ 43523 #ifdef BCM_XGS3_SWITCH_SUPPORT 43524 case bcmPortControlSampleIngressEnable: 43525 if (SOC_IS_XGS3_SWITCH(unit)) { 43526 uint32 regval = 0; 43527 uint32 field_enable = 0; 43528 #ifdef BCM_TOMAHAWK_SUPPORT 43529 sflow_ing_data_source_entry_t sflow_entry; 43530 soc_counter_non_dma_t *non_dma = NULL; 43531 soc_control_t *soc; 43532 uint32 count = 0, subset_ct = 0; 43533 #endif /* BCM_TOMAHAWK_SUPPORT */ 43534 43535 field_enable = value ? 1 : 0; 43536 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 43537 /* Update Ingress rate limiting data table. */ 43538 if(soc_feature(unit, soc_feature_sflow_ing_mem)) { 43539 BCM_IF_ERROR_RETURN( 43540 READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 43541 &sflow_entry)); 43542 soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry, ENABLEf, 43543 &field_enable); 43544 43545 BCM_IF_ERROR_RETURN( 43546 WRITE_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 43547 &sflow_entry)); 43548 43549 /* Enable counter thread for Ingress sFlow samplers */ 43550 if (field_enable) { 43551 soc = SOC_CONTROL(unit); 43552 non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_SFLOW_ING_PKT - 43553 SOC_COUNTER_NON_DMA_START]; 43554 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 43555 /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */ 43556 subset_ct = non_dma->extra_ctr_ct << 1; 43557 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 43558 non_dma = non_dma->extra_ctrs; 43559 43560 do { 43561 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 43562 /* BYTE_CTRf not currently supported */ 43563 count += 2; 43564 non_dma += 2; 43565 } while ((count < subset_ct)); 43566 } 43567 } 43568 rv = BCM_E_NONE; 43569 } else 43570 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */ 43571 { 43572 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) { 43573 return BCM_E_UNAVAIL; 43574 } 43575 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, ®val)); 43576 soc_reg_field_set(unit, SFLOW_ING_THRESHOLDr, ®val, 43577 ENABLEf, field_enable); 43578 43579 BCM_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, regval)); 43580 rv = BCM_E_NONE; 43581 } 43582 } else { 43583 rv = BCM_E_UNAVAIL; 43584 } 43585 break; 43586 case bcmPortControlSampleEgressEnable: 43587 if (SOC_IS_XGS3_SWITCH(unit)) { 43588 uint32 regval = 0; 43589 uint32 field_enable = 0; 43590 43591 if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) { 43592 return BCM_E_UNAVAIL; 43593 } 43594 BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, ®val)); 43595 43596 field_enable = value ? 1 : 0; 43597 soc_reg_field_set(unit, SFLOW_EGR_THRESHOLDr, ®val, 43598 ENABLEf, field_enable); 43599 43600 BCM_IF_ERROR_RETURN(WRITE_SFLOW_EGR_THRESHOLDr(unit, port, regval)); 43601 rv = BCM_E_NONE; 43602 } else { 43603 rv = BCM_E_UNAVAIL; 43604 } 43605 break; 43606 case bcmPortControlSampleIngressRate: 43607 if (SOC_IS_XGS3_SWITCH(unit)) { 43608 uint32 field_value = 0; 43609 uint32 regval = 0; 43610 #ifdef BCM_TOMAHAWK_SUPPORT 43611 sflow_ing_data_source_entry_t sflow_entry; 43612 #endif /* BCM_TOMAHAWK_SUPPORT */ 43613 43614 43615 /* rate - (IN)Every 1/rate a packet will be sampled 43616 * 1 indicating sample all. 43617 * 0 indicating sample none.*/ 43618 if (value > 0) { 43619 /* Set sampling threshold */ 43620 if (value == 1) { 43621 /* Needs special handling to avoid register overflow */ 43622 field_value = (1 << (SFLOW_RANGE_MAX(unit))) - 1; 43623 } else if (value <= ((1 << (SFLOW_RANGE_MAX(unit))) - 1)) { 43624 /* Calculate threshold based on sampling rate */ 43625 field_value = (1 << (SFLOW_RANGE_MAX(unit))) / value; 43626 } else { 43627 return BCM_E_PARAM; 43628 } 43629 43630 /* 43631 * For early sFlow implementations the 16-bit threshold value 43632 * is compared to bits [23:8] of the sFlow random number. 43633 */ 43634 if (soc_feature(unit, soc_feature_sample_offset8)) { 43635 field_value >>= 8; 43636 } 43637 43638 /* Cut the value in case 16 bit threshold can not accomodate it. */ 43639 if (soc_feature(unit, soc_feature_sample_thresh16)) { 43640 if (field_value >= (1 << 16)) { 43641 field_value = (1 << 16) - 1; 43642 } 43643 } 43644 } 43645 43646 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 43647 /* Update Ingress rate limiting data table. */ 43648 if(soc_feature(unit, soc_feature_sflow_ing_mem)) { 43649 BCM_IF_ERROR_RETURN( 43650 READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 43651 &sflow_entry)); 43652 soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry, THRESHOLDf, 43653 &field_value); 43654 43655 BCM_IF_ERROR_RETURN( 43656 WRITE_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 43657 &sflow_entry)); 43658 43659 rv = BCM_E_NONE; 43660 } else 43661 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */ 43662 { 43663 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) { 43664 return BCM_E_UNAVAIL; 43665 } 43666 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, ®val)); 43667 soc_reg_field_set(unit, SFLOW_ING_THRESHOLDr, ®val, 43668 THRESHOLDf, field_value); 43669 43670 BCM_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, regval)); 43671 rv = BCM_E_NONE; 43672 } 43673 } else { 43674 rv = BCM_E_UNAVAIL; 43675 } 43676 break; 43677 case bcmPortControlSampleEgressRate: 43678 if (SOC_IS_XGS3_SWITCH(unit)) { 43679 uint32 field_value = 0, regval = 0; 43680 43681 /* rate - (IN)Every 1/rate a packet will be sampled 43682 * 1 indicating sample all. 43683 * 0 indicating sample none.*/ 43684 if (value > 0) { 43685 /* Set sampling threshold */ 43686 if (value == 1) { 43687 /* Needs special handling to avoid register overflow */ 43688 field_value = (1 << (SFLOW_RANGE_MAX(unit))) - 1; 43689 } else if (value <= ((1 << (SFLOW_RANGE_MAX(unit))) - 1)) { 43690 /* Calculate threshold based on sampling rate */ 43691 field_value = (1 << (SFLOW_RANGE_MAX(unit))) / value; 43692 } else { 43693 return BCM_E_PARAM; 43694 } 43695 43696 /* 43697 * For early sFlow implementations the 16-bit threshold value 43698 * is compared to bits [23:8] of the sFlow random number. 43699 */ 43700 if (soc_feature(unit, soc_feature_sample_offset8)) { 43701 field_value >>= 8; 43702 } 43703 43704 /* Cut the value in case 16 bit threshold can not accomodate it. */ 43705 if (soc_feature(unit, soc_feature_sample_thresh16)) { 43706 if (field_value >= (1 << 16)) { 43707 field_value = (1 << 16) - 1; 43708 } 43709 } 43710 } 43711 43712 if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) { 43713 return BCM_E_UNAVAIL; 43714 } 43715 43716 BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, ®val)); 43717 soc_reg_field_set(unit, SFLOW_EGR_THRESHOLDr, ®val, 43718 THRESHOLDf, field_value); 43719 43720 BCM_IF_ERROR_RETURN(WRITE_SFLOW_EGR_THRESHOLDr(unit, port, regval)); 43721 rv = BCM_E_NONE; 43722 } else { 43723 rv = BCM_E_UNAVAIL; 43724 } 43725 break; 43726 #endif 43727 case bcmPortControlExternalBufferEnable: 43728 #if defined(BCM_KATANA2_SUPPORT) 43729 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_ddr3)) { 43730 rv = _bcm_kt2_cosq_port_ext_buf_set(unit, port, value); 43731 } 43732 #endif 43733 break; 43734 #ifdef BCM_HURRICANE3_SUPPORT 43735 case bcmPortControlTrustMimlPri: 43736 if (soc_feature(unit, soc_feature_miml)) { 43737 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 43738 USE_MIML_PCP_FOR_PRIf, value ? 1 : 0); 43739 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 43740 if (BCM_FAILURE(rv)) { 43741 return rv; 43742 } 43743 /* 43744 * Make sure TREAT_PKTPRI_AS_DOT1P bit is set for 43745 * MiML internal priority mapping. 43746 */ 43747 rv = bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 43748 (unit, (value) ? 1 : -1); 43749 } 43750 } 43751 break; 43752 case bcmPortControlTrustCustomHeaderPri: 43753 if (soc_feature(unit, soc_feature_custom_header)) { 43754 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 43755 USE_CUSTOM_HEADER_FOR_PRIf, 43756 value ? 1 : 0); 43757 } 43758 break; 43759 case bcmPortControlCustomHeaderEncapEnable: 43760 if (soc_feature(unit, soc_feature_custom_header)) { 43761 uint64 val64; 43762 43763 rv = READ_EGR_PORT_64r(unit, port, &val64); 43764 if (BCM_SUCCESS(rv)) { 43765 soc_reg64_field32_set(unit, EGR_PORT_64r, 43766 &val64, 43767 CUSTOM_HEADER_ENABLEf, value ? 1 : 0); 43768 } 43769 43770 rv = WRITE_EGR_PORT_64r(unit, port, val64); 43771 } 43772 break; 43773 #endif /* BCM_HURRICANE3_SUPPORT */ 43774 #if defined(BCM_SABER2_SUPPORT) 43775 case bcmPortControlSatEnable: 43776 PORT_LOCK(unit); 43777 if (SOC_IS_SABER2(unit)) { 43778 COUNTER_LOCK(unit); 43779 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 43780 rv = _bcm_sb2_port_oamp_enable(unit, port, value); 43781 COUNTER_UNLOCK(unit); 43782 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 43783 } else { 43784 rv = BCM_E_UNAVAIL; 43785 } 43786 PORT_UNLOCK(unit); 43787 break; 43788 #endif 43789 case bcmPortControl1588P2PDelay: 43790 { 43791 int p_speed=0; 43792 rv = bcm_esw_port_speed_get(unit, port, &p_speed); 43793 if (BCM_FAILURE(rv)) { 43794 rv = BCM_E_FAIL; 43795 } 43796 PORT(unit, port).link_delay_offset = value; 43797 rv = _bcm_esw_port_link_delay_update(unit, port, p_speed); 43798 } 43799 break; 43800 case bcmPortControlPacketTimeStampInsertRx: 43801 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 43802 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 43803 if (soc_feature(unit, soc_feature_timestamp)) { 43804 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43805 BCM_IF_ERROR_RETURN( 43806 _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 43807 INSERT_RX_TIMESTAMPf, value ? 1 : 0)); 43808 rv = BCM_E_NONE; 43809 } 43810 break; 43811 #endif 43812 case bcmPortControlPacketTimeStampInsertTx: 43813 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 43814 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 43815 if (soc_feature(unit, soc_feature_timestamp)) { 43816 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43817 SOC_IF_ERROR_RETURN( 43818 soc_reg_field32_modify(unit, EGR_TS_CONTROLr, port, 43819 INSERT_TX_TIMESTAMPf, value ? 1 : 0)); 43820 rv = BCM_E_NONE; 43821 } 43822 break; 43823 #endif 43824 case bcmPortControlPacketTimeStampSrcPortInsertCancel: 43825 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 43826 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 43827 if (soc_feature(unit, soc_feature_timestamp)) { 43828 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43829 BCM_IF_ERROR_RETURN( 43830 _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 43831 DISABLE_TIMESTAMPINGf, value ? 1 : 0)); 43832 rv = BCM_E_NONE; 43833 } 43834 break; 43835 #endif 43836 case bcmPortControlPacketTimeStampDestPortInsertCancel: 43837 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 43838 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 43839 if (soc_feature(unit, soc_feature_timestamp)) { 43840 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43841 SOC_IF_ERROR_RETURN( 43842 soc_reg_field32_modify(unit, EGR_TS_CONTROLr, port, 43843 DISABLE_TIMESTAMPINGf, value ? 1 : 0)); 43844 rv = BCM_E_NONE; 43845 } 43846 break; 43847 #endif 43848 case bcmPortControlPacketTimeStampRxId: 43849 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 43850 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 43851 if (soc_feature(unit, soc_feature_timestamp)) { 43852 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43853 if ((value < 0) || (value >= 0x7FFFFF)) { 43854 return BCM_E_PARAM; 43855 } 43856 if (SOC_REG_IS_VALID(unit,EGR_TS_ING_PORT_MAPr)) { 43857 SOC_IF_ERROR_RETURN( 43858 soc_reg_field32_modify(unit, EGR_TS_ING_PORT_MAPr, 43859 port, TS_RX_ORIGIN_IDf, value)); 43860 } else { 43861 SOC_IF_ERROR_RETURN( 43862 soc_mem_field32_modify(unit, EGR_TS_ING_PORT_MAPm, 43863 port, TS_RX_ORIGIN_IDf, value)); 43864 } 43865 rv = BCM_E_NONE; 43866 } 43867 #endif 43868 break; 43869 case bcmPortControlPacketTimeStampTxId: 43870 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 43871 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 43872 if (soc_feature(unit, soc_feature_timestamp)) { 43873 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43874 if ((value < 0) || (value >= 0x7FFFFF)) { 43875 return BCM_E_PARAM; 43876 } 43877 if (soc_reg_field_valid(unit, EGR_TS_CONTROL_2r, TS_TX_ORIGIN_IDf)) 43878 { 43879 rv = soc_reg_field32_modify(unit, EGR_TS_CONTROL_2r, 43880 port, TS_TX_ORIGIN_IDf, value); 43881 } else { 43882 rv = soc_reg_field32_modify(unit, EGR_TS_CONTROLr, 43883 port, TS_TX_ORIGIN_IDf, value); 43884 } 43885 } 43886 #endif 43887 break; 43888 case bcmPortControlPacketTimeStampByteMeterAdjust: 43889 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 43890 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 43891 if (soc_feature(unit, soc_feature_timestamp) && !SOC_IS_TOMAHAWK3(unit)) 43892 { 43893 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43894 rv = soc_reg_field32_modify(unit, EGR_TS_CONTROLr, port, 43895 TS_ADJUST_METERSf, (value) ? 1 : 0); 43896 } 43897 #endif 43898 break; 43899 case bcmPortControlE2EFCTransmitEnable: 43900 if (soc_feature(unit, soc_feature_e2efc)) { 43901 uint64 val; 43902 #if defined(BCM_KATANA2_SUPPORT) 43903 uint32 val32; 43904 #endif 43905 if (!IS_HG_PORT(unit, port)) { 43906 LOG_ERROR( 43907 BSL_LS_BCM_PORT, 43908 (BSL_META_U(unit, 43909 "Error: unit %d port %d is not a Higig port. " 43910 "E2EFC messages can only be transmitted to " 43911 "or received from Higig ports.\n"), 43912 unit, port)); 43913 return BCM_E_PARAM; 43914 } 43915 #if defined(BCM_KATANA2_SUPPORT) 43916 if (SOC_IS_KATANA2(unit)) { 43917 val32 = value ? 1: 0; 43918 rv = WRITE_E2EFC_IBP_ENr(unit, val32); 43919 } else 43920 #endif 43921 if (IS_XL_PORT(unit, port)) { 43922 BCM_IF_ERROR_RETURN(READ_XLMAC_E2E_CTRLr(unit, port, &val)); 43923 soc_reg64_field32_set(unit, XLMAC_E2E_CTRLr, 43924 &val, E2E_ENABLEf, value ? 1 : 0); 43925 rv = WRITE_XLMAC_E2E_CTRLr(unit, port, val); 43926 } else if (IS_CL_PORT(unit, port)) { 43927 BCM_IF_ERROR_RETURN(READ_CLMAC_E2E_CTRLr(unit, port, &val)); 43928 soc_reg64_field32_set(unit, CLMAC_E2E_CTRLr, 43929 &val, E2E_ENABLEf, value ? 1 : 0); 43930 rv = WRITE_CLMAC_E2E_CTRLr(unit, port, val); 43931 } else { 43932 return BCM_E_PARAM; 43933 } 43934 } 43935 break; 43936 case bcmPortControlE2EFCReceiveEnable: 43937 if (soc_feature(unit, soc_feature_e2efc)) { 43938 uint32 val; 43939 43940 BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val)); 43941 soc_reg_field_set(unit, IE2E_CONTROLr, 43942 &val, IBP_ENABLEf, value ? 1 : 0); 43943 rv = WRITE_IE2E_CONTROLr(unit, port, val); 43944 } 43945 break; 43946 case bcmPortControlE2EFCCopyToCpuEnable: 43947 if (soc_feature(unit, soc_feature_e2efc)) { 43948 uint32 val; 43949 43950 BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val)); 43951 soc_reg_field_set(unit, IE2E_CONTROLr, 43952 &val, IBP_TOCPUf, value ? 1 : 0); 43953 rv = WRITE_IE2E_CONTROLr(unit, port, val); 43954 } 43955 break; 43956 /* Higher 3 bytes of Destination MAC address */ 43957 case bcmPortControlE2EFCDestMacOui: 43958 if (soc_feature(unit, soc_feature_e2efc)) { 43959 uint32 val_lo, val_hi; 43960 uint64 val_64, data_0; 43961 #if defined(BCM_KATANA2_SUPPORT) 43962 uint32 val; 43963 #endif 43964 soc_reg_t reg; 43965 43966 if (!IS_HG_PORT(unit, port)) { 43967 LOG_ERROR( 43968 BSL_LS_BCM_PORT, 43969 (BSL_META_U(unit, 43970 "Error: unit %d port %d is not a Higig port. " 43971 "E2EFC messages can only be transmitted to " 43972 "or received from Higig ports.\n"), 43973 unit, port)); 43974 return BCM_E_PARAM; 43975 } 43976 #if defined(BCM_KATANA2_SUPPORT) 43977 if (SOC_IS_KATANA2(unit)) { 43978 #if defined(BCM_SABER2_SUPPORT) 43979 if (SOC_IS_SABER2(unit)) { 43980 /* Do nothing */ 43981 } else 43982 #endif /* BCM_SABER2_SUPPORT */ 43983 { 43984 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val)); 43985 val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f); 43986 val_hi = (val_hi & 0xff) | ((value & 0xffffff) << 8); 43987 soc_reg_field_set(unit, XIBP_D0r, &val, DATA_BYTES_0_3f, val_hi); 43988 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D0r, port, 0, val)); 43989 rv = BCM_E_NONE; 43990 break; 43991 } 43992 } 43993 #endif /* BCM_KATANA2_SUPPORT */ 43994 if (IS_XL_PORT(unit, port)) { 43995 reg = XLMAC_E2EFC_DATA_HDR_0r; 43996 } else if (IS_CL_PORT(unit, port)) { 43997 reg = CLMAC_E2EFC_DATA_HDR_0r; 43998 } else { 43999 return BCM_E_PARAM; 44000 } 44001 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 44002 0, &val_64)); 44003 data_0 = soc_reg64_field_get(unit, reg, 44004 val_64, E2EFC_DATA_HDR_0f); 44005 COMPILER_64_TO_32_LO(val_lo, data_0); 44006 COMPILER_64_TO_32_HI(val_hi, data_0); 44007 val_hi = (val_hi & 0xff) | ((value & 0xffffff) << 8); 44008 COMPILER_64_SET(data_0, val_hi, val_lo); 44009 soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_0f, 44010 data_0); 44011 rv = soc_reg64_set(unit, reg, port, 0, val_64); 44012 } 44013 break; 44014 /* Lower 3 bytes of Destination MAC address */ 44015 case bcmPortControlE2EFCDestMacNonOui: 44016 if (soc_feature(unit, soc_feature_e2efc)) { 44017 uint32 val_lo, val_hi; 44018 uint64 val_64, data_0; 44019 soc_reg_t reg; 44020 #if defined(BCM_KATANA2_SUPPORT) 44021 uint32 val; 44022 #endif 44023 44024 if (!IS_HG_PORT(unit, port)) { 44025 LOG_ERROR( 44026 BSL_LS_BCM_PORT, 44027 (BSL_META_U(unit, 44028 "Error: unit %d port %d is not a Higig port. " 44029 "E2EFC messages can only be transmitted to " 44030 "or received from Higig ports.\n"), 44031 unit, port)); 44032 return BCM_E_PARAM; 44033 } 44034 #if defined(BCM_KATANA2_SUPPORT) 44035 if (SOC_IS_KATANA2(unit)) { 44036 #if defined(BCM_SABER2_SUPPORT) 44037 if (SOC_IS_SABER2(unit)) { 44038 /* Do nothing */ 44039 } else 44040 #endif /* BCM_SABER2_SUPPORT */ 44041 { 44042 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val)); 44043 val_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f); 44044 val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16); 44045 soc_reg_field_set(unit, XIBP_D1r, &val, DATA_BYTES_4_7f, val_lo); 44046 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D1r, port, 0, val)); 44047 44048 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val)); 44049 val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f); 44050 val_hi = (val_hi & 0xffffff00) | ((value >> 16) & 0xff); 44051 soc_reg_field_set(unit, XIBP_D0r, &val, DATA_BYTES_0_3f, val_hi); 44052 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D0r, port, 0, val)); 44053 rv = BCM_E_NONE; 44054 break; 44055 } 44056 } 44057 #endif /* BCM_KATANA2_SUPPORT */ 44058 if (IS_XL_PORT(unit, port)) { 44059 reg = XLMAC_E2EFC_DATA_HDR_0r; 44060 } else if (IS_CL_PORT(unit, port)) { 44061 reg = CLMAC_E2EFC_DATA_HDR_0r; 44062 } else { 44063 return BCM_E_PARAM; 44064 } 44065 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 44066 0, &val_64)); 44067 data_0 = soc_reg64_field_get(unit, reg, 44068 val_64, E2EFC_DATA_HDR_0f); 44069 COMPILER_64_TO_32_LO(val_lo, data_0); 44070 COMPILER_64_TO_32_HI(val_hi, data_0); 44071 val_hi = (val_hi & 0xffffff00) | ((value >> 16) & 0xff); 44072 val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16); 44073 COMPILER_64_SET(data_0, val_hi, val_lo); 44074 soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_0f, 44075 data_0); 44076 rv = soc_reg64_set(unit, reg, port, 0, val_64); 44077 } 44078 break; 44079 /* Higher 3 bytes of Source MAC address */ 44080 case bcmPortControlE2EFCSrcMacOui: 44081 if (soc_feature(unit, soc_feature_e2efc)) { 44082 uint32 val_lo, val_hi; 44083 uint64 val_64, data_1, data_0; 44084 soc_reg_t reg_1, reg_0; 44085 #if defined(BCM_KATANA2_SUPPORT) 44086 uint32 val; 44087 #endif 44088 if (!IS_HG_PORT(unit, port)) { 44089 LOG_ERROR( 44090 BSL_LS_BCM_PORT, 44091 (BSL_META_U(unit, 44092 "Error: unit %d port %d is not a Higig port. " 44093 "E2EFC messages can only be transmitted to " 44094 "or received from Higig ports.\n"), 44095 unit, port)); 44096 return BCM_E_PARAM; 44097 } 44098 #if defined(BCM_KATANA2_SUPPORT) 44099 if (SOC_IS_KATANA2(unit)) { 44100 #if defined(BCM_SABER2_SUPPORT) 44101 if (SOC_IS_SABER2(unit)) { 44102 /* Do nothing */ 44103 } else 44104 #endif /* BCM_SABER2_SUPPORT */ 44105 { 44106 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val)); 44107 val_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f); 44108 val_lo = (val_lo & 0xffff0000) | ((value >> 8) & 0xffff); 44109 soc_reg_field_set(unit, XIBP_D1r, &val, DATA_BYTES_4_7f, val_lo); 44110 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D1r, port, 0, val)); 44111 44112 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val)); 44113 val_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f); 44114 val_hi = (val_hi & 0xffffff) | ((value & 0xff) << 24); 44115 soc_reg_field_set(unit, XIBP_D2r, &val, DATA_BYTES_8_11f, val_hi); 44116 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D2r, port, 0, val)); 44117 rv = BCM_E_NONE; 44118 break; 44119 } 44120 } 44121 #endif /* BCM_KATANA2_SUPPORT */ 44122 if (IS_XL_PORT(unit, port)) { 44123 reg_1 = XLMAC_E2EFC_DATA_HDR_1r; 44124 reg_0 = XLMAC_E2EFC_DATA_HDR_0r; 44125 } else if (IS_CL_PORT(unit, port)) { 44126 reg_1 = CLMAC_E2EFC_DATA_HDR_1r; 44127 reg_0 = CLMAC_E2EFC_DATA_HDR_0r; 44128 } else { 44129 return BCM_E_PARAM; 44130 } 44131 44132 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_1, port, 44133 0, &val_64)); 44134 data_1 = soc_reg64_field_get(unit, reg_1, 44135 val_64, E2EFC_DATA_HDR_1f); 44136 COMPILER_64_TO_32_LO(val_lo, data_1); 44137 COMPILER_64_TO_32_HI(val_hi, data_1); 44138 val_hi = (val_hi & 0xffffff) | ((value & 0xff) << 24); 44139 COMPILER_64_SET(data_1, val_hi, val_lo); 44140 soc_reg64_field_set(unit, reg_1, &val_64, E2EFC_DATA_HDR_1f, 44141 data_1); 44142 BCM_IF_ERROR_RETURN(soc_reg64_set(unit, reg_1, port, 0, val_64)); 44143 /* SA MAC setting across 2 registers */ 44144 COMPILER_64_ZERO(val_64); 44145 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_0, port, 44146 0, &val_64)); 44147 data_0 = soc_reg64_field_get(unit, reg_0, 44148 val_64, E2EFC_DATA_HDR_0f); 44149 COMPILER_64_TO_32_LO(val_lo, data_0); 44150 COMPILER_64_TO_32_HI(val_hi, data_0); 44151 val_lo = (val_lo & 0xffff0000) | ((value >> 8) & 0xffff); 44152 COMPILER_64_SET(data_0, val_hi, val_lo); 44153 soc_reg64_field_set(unit, reg_0, &val_64, E2EFC_DATA_HDR_0f, 44154 data_0); 44155 rv = soc_reg64_set(unit, reg_0, port, 0, val_64); 44156 } 44157 break; 44158 /* Lower 3 bytes of Source MAC address */ 44159 case bcmPortControlE2EFCSrcMacNonOui: 44160 if (soc_feature(unit, soc_feature_e2efc)) { 44161 uint32 val_lo, val_hi; 44162 uint64 val_64, data_1; 44163 soc_reg_t reg; 44164 #if defined(BCM_KATANA2_SUPPORT) 44165 uint32 val; 44166 #endif 44167 if (!IS_HG_PORT(unit, port)) { 44168 LOG_ERROR( 44169 BSL_LS_BCM_PORT, 44170 (BSL_META_U(unit, 44171 "Error: unit %d port %d is not a Higig port. " 44172 "E2EFC messages can only be transmitted to " 44173 "or received from Higig ports.\n"), 44174 unit, port)); 44175 return BCM_E_PARAM; 44176 } 44177 #if defined(BCM_KATANA2_SUPPORT) 44178 if (SOC_IS_KATANA2(unit)) { 44179 #if defined(BCM_SABER2_SUPPORT) 44180 if (SOC_IS_SABER2(unit)) { 44181 /* Do nothing */ 44182 } else 44183 #endif /* BCM_SABER2_SUPPORT */ 44184 { 44185 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val)); 44186 val_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f); 44187 val_hi = (val_hi & 0xff000000) | (value & 0xffffff); 44188 soc_reg_field_set(unit, XIBP_D2r, &val, DATA_BYTES_8_11f, val_hi); 44189 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D2r, port, 0, val)); 44190 rv = BCM_E_NONE; 44191 break; 44192 } 44193 } 44194 #endif /* BCM_KATANA2_SUPPORT */ 44195 if (IS_XL_PORT(unit, port)) { 44196 reg = XLMAC_E2EFC_DATA_HDR_1r; 44197 } else if (IS_CL_PORT(unit, port)) { 44198 reg = CLMAC_E2EFC_DATA_HDR_1r; 44199 } else { 44200 return BCM_E_PARAM; 44201 } 44202 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 44203 0, &val_64)); 44204 data_1 = soc_reg64_field_get(unit, reg, 44205 val_64, E2EFC_DATA_HDR_1f); 44206 COMPILER_64_TO_32_LO(val_lo, data_1); 44207 COMPILER_64_TO_32_HI(val_hi, data_1); 44208 val_hi = (val_hi & 0xff000000) | (value & 0xffffff); 44209 COMPILER_64_SET(data_1, val_hi, val_lo); 44210 soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_1f, 44211 data_1); 44212 44213 rv = soc_reg64_set(unit, reg, port, 0, val_64); 44214 } 44215 break; 44216 case bcmPortControlE2EFCEtherType: 44217 if (soc_feature(unit, soc_feature_e2efc)) { 44218 uint32 val_lo, val_hi; 44219 uint64 val_64, data_1; 44220 soc_reg_t reg; 44221 #if defined(BCM_KATANA2_SUPPORT) 44222 uint32 val; 44223 #endif 44224 if (!IS_HG_PORT(unit, port)) { 44225 LOG_ERROR( 44226 BSL_LS_BCM_PORT, 44227 (BSL_META_U(unit, 44228 "Error: unit %d port %d is not a Higig port. " 44229 "E2EFC messages can only be transmitted to " 44230 "or received from Higig ports.\n"), 44231 unit, port)); 44232 return BCM_E_PARAM; 44233 } 44234 #if defined(BCM_KATANA2_SUPPORT) 44235 if (SOC_IS_KATANA2(unit)) { 44236 #if defined(BCM_SABER2_SUPPORT) 44237 if (SOC_IS_SABER2(unit)) { 44238 /* Do nothing */ 44239 } else 44240 #endif /* BCM_SABER2_SUPPORT */ 44241 { 44242 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val)); 44243 val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f); 44244 val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16); 44245 soc_reg_field_set(unit, XIBP_D3r, &val, D_BYTES_12_15f, val_lo); 44246 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D3r, port, 0, val)); 44247 rv = BCM_E_NONE; 44248 break; 44249 } 44250 } 44251 #endif /* BCM_KATANA2_SUPPORT */ 44252 if (IS_XL_PORT(unit, port)) { 44253 reg = XLMAC_E2EFC_DATA_HDR_1r; 44254 } else if (IS_CL_PORT(unit, port)) { 44255 reg = CLMAC_E2EFC_DATA_HDR_1r; 44256 } else { 44257 return BCM_E_PARAM; 44258 } 44259 44260 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 44261 0, &val_64)); 44262 data_1 = soc_reg64_field_get(unit, reg, 44263 val_64, E2EFC_DATA_HDR_1f); 44264 COMPILER_64_TO_32_LO(val_lo, data_1); 44265 COMPILER_64_TO_32_HI(val_hi, data_1); 44266 val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16); 44267 COMPILER_64_SET(data_1, val_hi, val_lo); 44268 soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_1f, 44269 data_1); 44270 rv = soc_reg64_set(unit, reg, port, 0, val_64); 44271 } 44272 break; 44273 case bcmPortControlE2EFCOpcode: 44274 if (soc_feature(unit, soc_feature_e2efc)) { 44275 uint32 val_lo, val_hi; 44276 uint64 val_64, data_1; 44277 soc_reg_t reg; 44278 #if defined(BCM_KATANA2_SUPPORT) 44279 uint32 val; 44280 #endif 44281 44282 if (!IS_HG_PORT(unit, port)) { 44283 LOG_ERROR( 44284 BSL_LS_BCM_PORT, 44285 (BSL_META_U(unit, 44286 "Error: unit %d port %d is not a Higig port. " 44287 "E2EFC messages can only be transmitted to " 44288 "or received from Higig ports.\n"), 44289 unit, port)); 44290 return BCM_E_PARAM; 44291 } 44292 #if defined(BCM_KATANA2_SUPPORT) 44293 if (SOC_IS_KATANA2(unit)) { 44294 #if defined(BCM_SABER2_SUPPORT) 44295 if (SOC_IS_SABER2(unit)) { 44296 /* Do nothing */ 44297 } else 44298 #endif /* BCM_SABER2_SUPPORT */ 44299 { 44300 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val)); 44301 val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f); 44302 val_lo = (val_lo & 0xffff0000) | (value & 0xffff); 44303 soc_reg_field_set(unit, XIBP_D3r, &val, D_BYTES_12_15f, val_lo); 44304 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D3r, port, 0, val)); 44305 rv = BCM_E_NONE; 44306 break; 44307 } 44308 } 44309 #endif /* BCM_KATANA2_SUPPORT */ 44310 if (IS_XL_PORT(unit, port)) { 44311 reg = XLMAC_E2EFC_DATA_HDR_1r; 44312 } else if (IS_CL_PORT(unit, port)) { 44313 reg = CLMAC_E2EFC_DATA_HDR_1r; 44314 } else { 44315 return BCM_E_PARAM; 44316 } 44317 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 44318 0, &val_64)); 44319 data_1 = soc_reg64_field_get(unit, reg, 44320 val_64, E2EFC_DATA_HDR_1f); 44321 COMPILER_64_TO_32_LO(val_lo, data_1); 44322 COMPILER_64_TO_32_HI(val_hi, data_1); 44323 val_lo = (val_lo & 0xffff0000) | (value & 0xffff); 44324 COMPILER_64_SET(data_1, val_hi, val_lo); 44325 soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_1f, 44326 data_1); 44327 rv = soc_reg64_set(unit, reg, port, 0, val_64); 44328 } 44329 break; 44330 case bcmPortControlResetSerdes: 44331 44332 44333 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TOMAHAWKPLUS_SUPPORT) 44334 if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TOMAHAWKPLUS(unit)) { 44335 rv = soc_th_reset_serdes(unit, port, value); 44336 44337 } else 44338 #endif 44339 44340 #if defined(BCM_HURRICANE3_SUPPORT) 44341 if (SOC_IS_HURRICANE3(unit)) { 44342 rv = soc_hurricane3_tsc_core_reset(unit, port, value); 44343 } else 44344 #endif 44345 { 44346 rv = BCM_E_UNAVAIL; 44347 } 44348 break; 44349 case bcmPortControlIntEnable: 44350 #if defined(BCM_TOMAHAWK3_SUPPORT) 44351 if (soc_feature(unit, soc_feature_inband_network_telemetry)) { 44352 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, INT_ENABLEf, value); 44353 } 44354 #endif 44355 break; 44356 case bcmPortControlIntTurnaround: 44357 #if defined(BCM_TOMAHAWK3_SUPPORT) 44358 if (soc_feature(unit, soc_feature_inband_network_telemetry)) { 44359 SOC_IF_ERROR_RETURN 44360 (READ_INT_TURNAROUND_EN_BMAPm(unit, MEM_BLOCK_ANY, 0, 44361 &int_turnaround_en_bmap_entry)); 44362 soc_mem_pbmp_field_get(unit, INT_TURNAROUND_EN_BMAPm, 44363 &int_turnaround_en_bmap_entry, PORT_BITMAPf, &pbmp); 44364 if (value) 44365 SOC_PBMP_PORT_ADD(pbmp, port); 44366 else 44367 SOC_PBMP_PORT_REMOVE(pbmp, port); 44368 44369 soc_mem_pbmp_field_set(unit, INT_TURNAROUND_EN_BMAPm, 44370 &int_turnaround_en_bmap_entry, PORT_BITMAPf, &pbmp); 44371 SOC_IF_ERROR_RETURN 44372 (WRITE_INT_TURNAROUND_EN_BMAPm(unit, MEM_BLOCK_ANY, 0, 44373 &int_turnaround_en_bmap_entry)); 44374 rv = BCM_E_NONE; 44375 } 44376 #endif 44377 break; 44378 case bcmPortControlObmClassifierPriority: 44379 case bcmPortControlObmClassifierEnableDscp: 44380 case bcmPortControlObmClassifierEnableMpls: 44381 case bcmPortControlObmClassifierEnableEtag: 44382 case bcmPortControlObmClassifierEtagEthertype: 44383 case bcmPortControlObmClassifierVntagEthertype: 44384 44385 #if defined(BCM_MONTEREY_SUPPORT) 44386 if (SOC_IS_MONTEREY(unit)) { 44387 rv = bcm_mn_obm_classifier_port_control_set(unit, port, type, value); 44388 } else 44389 #endif 44390 #if defined(BCM_APACHE_SUPPORT) 44391 if (SOC_IS_APACHE(unit)) { 44392 rv = bcm_apache_obm_classifier_port_control_set(unit, port, type, value); 44393 } else 44394 #endif 44395 #if defined(BCM_HELIX5_SUPPORT) 44396 if (SOC_IS_HELIX5(unit)) { 44397 rv = bcm_hx5_obm_classifier_port_control_set(unit, port, type, value); 44398 } else 44399 #endif 44400 #if defined(BCM_TRIDENT3_SUPPORT) 44401 if (soc_feature(unit, soc_feature_td3_style_obm_classifier_map)) { 44402 rv = bcm_td3_obm_classifier_port_control_set(unit, port, type, value); 44403 } else 44404 #endif 44405 { 44406 rv = BCM_E_UNAVAIL; 44407 } 44408 break; 44409 case bcmPortControlObmClassifierInternal: 44410 #if defined(BCM_MONTEREY_SUPPORT) 44411 if (SOC_IS_MONTEREY(unit)) { 44412 rv = bcm_mn_obm_classifier_port_control_set(unit, port, type, value); 44413 } else 44414 #endif 44415 { 44416 rv = BCM_E_UNAVAIL; 44417 } 44418 break; 44419 44420 case bcmPortControlWirelessCosMapSelect: 44421 #if defined(BCM_HELIX5_SUPPORT) 44422 if (SOC_IS_HELIX5(unit) || SOC_IS_HURRICANE4(unit)) { 44423 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 44424 WIRED_WIRELESSf, (value) ? 1 : 0); 44425 } else 44426 #endif 44427 { 44428 rv = BCM_E_UNAVAIL; 44429 } 44430 break; 44431 44432 case bcmPortControlHiGigCosSelect: 44433 #if defined(BCM_HURRICANE4_SUPPORT) 44434 if (SOC_IS_HURRICANE4(unit)) { 44435 rv = bcm_hr4_hgcos_select_port_control_set(unit, port, type, value); 44436 } else 44437 #endif 44438 #if defined(BCM_HELIX5_SUPPORT) 44439 if (SOC_IS_HELIX5(unit)) { 44440 rv = bcm_hx5_hgcos_select_port_control_set(unit, port, type, value); 44441 } else 44442 #endif 44443 { 44444 rv = BCM_E_UNAVAIL; 44445 } 44446 break; 44447 case bcmPortControlInternalLoopback: 44448 #ifdef BCM_TRIDENT3_SUPPORT 44449 if (SOC_IS_TRIDENT3X(unit)) { 44450 rv = bcmi_td3_port_internal_loopback_set(unit,port,value); 44451 44452 } else 44453 #endif 44454 { 44455 rv = BCM_E_UNAVAIL; 44456 } 44457 break; 44458 #ifdef BCM_MONTEREY_SUPPORT 44459 case bcmPortControlObmInterruptTypeDropPreempt : 44460 case bcmPortControlObmInterruptTypeOverflowPreempt : 44461 case bcmPortControlObmInterruptTypeDropExpress : 44462 case bcmPortControlObmInterruptTypeOverflowExpress : 44463 if (SOC_IS_MONTEREY(unit)) { 44464 rv = bcm_mn_obm_interrupt_port_control_set(unit, port, type, value); 44465 44466 } else 44467 #endif 44468 { 44469 rv = BCM_E_UNAVAIL; 44470 } 44471 break; 44472 case bcmPortControlRuntThreshold: 44473 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 44474 SOC_MAC_CONTROL_RX_RUNT_THRESHOLD, value); 44475 break; 44476 case bcmPortControlPacketProcssingPort: 44477 #ifdef BCM_TRIDENT3_SUPPORT 44478 if (soc_feature(unit, soc_feature_pp_port_control)) { 44479 rv = bcmi_td3_port_pp_num_set(unit, port, value); 44480 } else 44481 #endif /* BCM_TRIDENT3_SUPPORT */ 44482 { 44483 rv = BCM_E_UNAVAIL; 44484 } 44485 break; 44486 default: 44487 break; 44488 } 44489 return rv; 44490 } 44491 44492 44493 /* 44494 * Function: 44495 * bcm_esw_port_control_get 44496 * Description: 44497 * Get the status of specified port feature. 44498 * Parameters: 44499 * unit - Device number 44500 * port - Port number 44501 * type - Enum value of the feature 44502 * value - (OUT) Current value of the port feature 44503 * Return Value: 44504 * BCM_E_NONE 44505 * BCM_E_UNAVAIL - Functionality not available 44506 */ 44507 int 44508 bcm_esw_port_control_get(int unit, bcm_port_t port, 44509 bcm_port_control_t type, int *value) 44510 { 44511 int rv = BCM_E_UNAVAIL; 44512 int valid = 0; 44513 #if defined(BCM_SHADOW_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 44514 uint32 val = 0; 44515 #endif /* BCM_SHADOW_SUPPORT || BCM_GREYHOUND_SUPPORT */ 44516 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 44517 int chk_gx_port = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 44518 SOC_IS_VALKYRIE2(unit) || SOC_IS_SCORPION(unit)); 44519 #endif 44520 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX) 44521 int udp; 44522 int tcp; 44523 int enable; 44524 #endif 44525 source_vp_entry_t svp_entry; 44526 #if defined(BCM_TOMAHAWK3_SUPPORT) 44527 int_turnaround_en_bmap_entry_t int_turnaround_en_bmap_entry; 44528 bcm_pbmp_t pbmp; 44529 #endif 44530 if (value == NULL) { 44531 return BCM_E_PARAM; 44532 } 44533 44534 /* Make sure port module is initialized. */ 44535 PORT_INIT(unit); 44536 44537 if(bcm_common_oamp_port_enable_get(unit, port) && 44538 (type != bcmPortControlSatEnable)) { 44539 LOG_ERROR(BSL_LS_BCM_PORT, 44540 (BSL_META("Error: Not permitted on OAMP port %d.n"), 44541 port)); 44542 return BCM_E_PARAM; 44543 } 44544 44545 /* Call Port Control module */ 44546 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 44547 /* 44548 * Check that port control feature is valid in Port Control. 44549 * If valid, call Port Control routine to handle feature; otherwise 44550 * continue with rest of logic. 44551 */ 44552 BCM_IF_ERROR_RETURN 44553 (bcmi_esw_portctrl_control_validate(unit, type, &valid)); 44554 if (valid) { 44555 return bcmi_esw_portctrl_control_get(unit, port, type, value); 44556 } 44557 } 44558 44559 #if defined(BCM_SHADOW_SUPPORT) 44560 if (SOC_IS_SHADOW(unit)) { 44561 /* If unsupported port control type, return unavail */ 44562 if (!_bcm_port_type_shadow_support (unit, port, type)) { 44563 return BCM_E_UNAVAIL; 44564 } 44565 } 44566 #endif /* BCM_SHADOW_SUPPORT */ 44567 44568 if (type == bcmPortControlEsmEligibility) { 44569 #ifdef BCM_TRIUMPH3_SUPPORT 44570 /* For bcmPortControlEsmEligibility, a non-local port 44571 * is accepted. For other port controls, a non-local 44572 * port is not accepted. Hence, bcmPortControlEsmEligibility 44573 * is implemented here, before the _bcm_esw_port_gport_validate 44574 * procedure below. 44575 */ 44576 return bcm_tr3_port_esm_eligible_get(unit, port, value); 44577 #endif /* BCM_TRIUMPH3_SUPPORT */ 44578 } 44579 44580 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 44581 if ( 44582 #ifdef BCM_HGPROXY_COE_SUPPORT 44583 ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 44584 soc_feature(unit, soc_feature_channelized_switching)) && 44585 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) && 44586 ((type == bcmPortControlVlanVpGroupIngress) || 44587 (type == bcmPortControlVlanVpGroupEgress))) || 44588 #endif 44589 BCM_GPORT_IS_TRUNK(port) || 44590 BCM_GPORT_IS_VLAN_PORT(port) || 44591 BCM_GPORT_IS_NIV_PORT(port) || 44592 BCM_GPORT_IS_VXLAN_PORT(port) || 44593 BCM_GPORT_IS_MIM_PORT(port) || 44594 BCM_GPORT_IS_MPLS_PORT(port) || 44595 BCM_GPORT_IS_L2GRE_PORT(port) || 44596 BCM_GPORT_IS_FLOW_PORT(port) || 44597 BCM_GPORT_IS_EXTENDER_PORT(port)) { 44598 return bcm_td_vp_control_get(unit, port, type, value); 44599 } else 44600 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 44601 #if defined(BCM_KATANA2_SUPPORT) 44602 if (((BCM_GPORT_IS_MIM_PORT(port)) || 44603 (BCM_GPORT_IS_MPLS_PORT(port))) && SOC_IS_KATANA2(unit)) { 44604 rv = BCM_E_NONE; 44605 } else 44606 #endif /* BCM_KATANA2_SUPPORT */ 44607 if ((BCM_GPORT_IS_LOCAL_CPU_IEEE(port)) || 44608 (BCM_GPORT_IS_LOCAL_CPU_HIGIG(port))) { 44609 rv = BCM_E_NONE; 44610 } else 44611 #ifdef BCM_HGPROXY_COE_SUPPORT 44612 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 44613 soc_feature(unit, soc_feature_channelized_switching)) && 44614 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 44615 rv = BCM_E_NONE; 44616 } else 44617 #endif 44618 #ifdef BCM_TRIDENT3_SUPPORT 44619 if (soc_feature(unit, soc_feature_pp_port_control) && 44620 (type == bcmPortControlPacketProcssingPort) ) { 44621 rv = BCM_E_NONE; 44622 } else 44623 #endif 44624 { 44625 rv = bcm_esw_port_control_validate(unit, port, type, &port); 44626 } 44627 BCM_IF_ERROR_RETURN(rv); 44628 rv = BCM_E_UNAVAIL; 44629 44630 /* 44631 * At this point, 'port' can be: 44632 * GPORT WLAN 44633 * GPORT PROXY 44634 * BCM valid local port 44635 * 44636 * Some switch cases only handles 'port' in BCM port format 44637 * (non-gport). Corresponding checks must be added in those 44638 * cases to ensure that 'port' is not a gport. 44639 */ 44640 switch (type) { 44641 case bcmPortControlBridge: 44642 if (SOC_IS_XGS3_SWITCH(unit)) { 44643 rv = _bcm_esw_port_tab_get(unit, port, PORT_BRIDGEf, value); 44644 } 44645 break; 44646 case bcmPortControlTrunkHashSet: 44647 #if defined(BCM_TRIUMPH3_SUPPORT) 44648 if (SOC_IS_TRIUMPH3(unit)) { 44649 return BCM_E_UNAVAIL; 44650 } else 44651 #endif /* BCM_TRIUMPH3_SUPPORT */ 44652 { 44653 #if defined(BCM_BRADLEY_SUPPORT) 44654 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 44655 rv = _bcm_esw_port_tab_get(unit, port, 44656 RTAG7_HASH_CFG_SEL_TRUNKf, value); 44657 } 44658 #endif /* BCM_BRADLEY_SUPPORT */ 44659 } 44660 break; 44661 case bcmPortControlFabricTrunkHashSet: 44662 #if defined(BCM_TRIUMPH3_SUPPORT) 44663 if (SOC_IS_TRIUMPH3(unit)) { 44664 return BCM_E_UNAVAIL; 44665 } else 44666 #endif /* BCM_TRIUMPH3_SUPPORT */ 44667 { 44668 #if defined(BCM_BRADLEY_SUPPORT) 44669 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 44670 rv = _bcm_esw_port_tab_get(unit, port, 44671 RTAG7_HASH_CFG_SEL_HIGIG_TRUNKf, 44672 value); 44673 } 44674 #endif /* BCM_BRADLEY_SUPPORT */ 44675 } 44676 break; 44677 case bcmPortControlECMPHashSet: 44678 #if defined(BCM_TRIUMPH3_SUPPORT) 44679 if (SOC_IS_TRIUMPH3(unit)) { 44680 return BCM_E_UNAVAIL; 44681 } else 44682 #endif /* BCM_TRIUMPH3_SUPPORT */ 44683 { 44684 #if defined(BCM_BRADLEY_SUPPORT) 44685 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 44686 rv = _bcm_esw_port_tab_get(unit, port, 44687 RTAG7_HASH_CFG_SEL_ECMPf, value); 44688 } 44689 #endif /* BCM_BRADLEY_SUPPORT */ 44690 } 44691 break; 44692 case bcmPortControlLoadBalanceHashSet: 44693 #if defined(BCM_TRIUMPH3_SUPPORT) 44694 if (SOC_IS_TRIUMPH3(unit)) { 44695 return BCM_E_UNAVAIL; 44696 } else 44697 #endif /* BCM_TRIUMPH3_SUPPORT */ 44698 { 44699 #if defined(BCM_BRADLEY_SUPPORT) 44700 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 44701 rv = _bcm_esw_port_tab_get(unit, port, 44702 RTAG7_HASH_CFG_SEL_LBIDf, value); 44703 } 44704 #endif /* BCM_BRADLEY_SUPPORT */ 44705 } 44706 break; 44707 case bcmPortControlLoadBalancingNumber: 44708 #if defined(BCM_BRADLEY_SUPPORT) 44709 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 44710 rv = _bcm_esw_port_tab_get(unit, port, 44711 RTAG7_PORT_LBNf, value); 44712 } 44713 #endif /* BCM_BRADLEY_SUPPORT */ 44714 break; 44715 case bcmPortControlErrorSymbolDetect: 44716 #if defined(BCM_GREYHOUND_SUPPORT) 44717 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 44718 SOC_IS_GREYHOUND2(unit)) { 44719 rv = BCM_E_UNAVAIL; 44720 } else 44721 #endif /* BCM_GREYHOUND_SUPPORT */ 44722 { 44723 #ifdef BCM_XGS3_SWITCH_SUPPORT 44724 if (SOC_IS_XGS3_SWITCH(unit)) { 44725 rv = _bcm_esw_port_err_sym_detect_get(unit, port, value); 44726 } 44727 #endif 44728 } 44729 break; 44730 case bcmPortControlErrorSymbolCount: 44731 #if defined(BCM_GREYHOUND_SUPPORT) 44732 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 44733 SOC_IS_GREYHOUND2(unit)) { 44734 rv = BCM_E_UNAVAIL; 44735 } else 44736 #endif /* BCM_GREYHOUND_SUPPORT */ 44737 { 44738 #ifdef BCM_XGS3_SWITCH_SUPPORT 44739 if (SOC_IS_XGS3_SWITCH(unit)) { 44740 rv = _bcm_esw_port_err_sym_count_get(unit, port, value); 44741 } 44742 #endif 44743 } 44744 break; 44745 case bcmPortControlIP4: 44746 if (SOC_IS_XGS3_SWITCH(unit)) { 44747 #if defined(BCM_TRX_SUPPORT) 44748 if (BCM_GPORT_LOCAL_CPU_HIGIG == port) { 44749 rv = _bcm_esw_iport_tab_get(unit, CMIC_PORT(unit), V4L3_ENABLEf, value); 44750 } else 44751 #endif 44752 { 44753 rv = _bcm_esw_port_tab_get(unit, port, V4L3_ENABLEf, value); 44754 } 44755 } 44756 break; 44757 case bcmPortControlIP6: 44758 if (SOC_IS_XGS3_SWITCH(unit)) { 44759 rv = _bcm_esw_port_tab_get(unit, port, V6L3_ENABLEf, value); 44760 } 44761 break; 44762 case bcmPortControlIP4Mcast: 44763 if (SOC_IS_XGS3_SWITCH(unit)) { 44764 rv = _bcm_esw_port_tab_get(unit, port, V4IPMC_ENABLEf, value); 44765 } 44766 break; 44767 case bcmPortControlIP6Mcast: 44768 if (SOC_IS_XGS3_SWITCH(unit)) { 44769 rv = _bcm_esw_port_tab_get(unit, port, V6IPMC_ENABLEf, value); 44770 } 44771 break; 44772 case bcmPortControlIPMC4Ucast: 44773 if (soc_feature(unit, soc_feature_ipmc_unicast)) { 44774 rv = _bcm_esw_port_tab_get(unit, port, 44775 IPMCV4_UNICAST_MACDA_ENABLEf, value); 44776 } 44777 break; 44778 case bcmPortControlIPMC6Ucast: 44779 if (soc_feature(unit, soc_feature_ipmc_unicast)) { 44780 rv = _bcm_esw_port_tab_get(unit, port, 44781 IPMCV6_UNICAST_MACDA_ENABLEf, value); 44782 } 44783 break; 44784 case bcmPortControlIP4McastL2: 44785 #if defined(BCM_TRX_SUPPORT) 44786 if (SOC_IS_XGS3_SWITCH(unit)) { 44787 if (SOC_IS_TD2_TT2(unit) && 44788 soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 44789 IPMCV4_L2_ENABLEf)) { 44790 rv = _bcm_trx_source_trunk_map_get(unit, port, 44791 IPMCV4_L2_ENABLEf, (uint32 *)value); 44792 } else { 44793 rv = _bcm_esw_port_tab_get(unit, port, V4IPMC_L2_ENABLEf, value); 44794 } 44795 } 44796 #endif /* BCM_TRX_SUPPORT */ 44797 break; 44798 case bcmPortControlIP6McastL2: 44799 #ifdef BCM_TRX_SUPPORT 44800 if (SOC_IS_XGS3_SWITCH(unit)) { 44801 if (SOC_IS_TD2_TT2(unit) && 44802 soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 44803 IPMCV6_L2_ENABLEf)) { 44804 rv = _bcm_trx_source_trunk_map_get(unit, port, 44805 IPMCV6_L2_ENABLEf, (uint32 *)value); 44806 } else { 44807 rv = _bcm_esw_port_tab_get(unit, port, V6IPMC_L2_ENABLEf, value); 44808 } 44809 } 44810 #endif 44811 break; 44812 44813 case bcmPortControlMpls: 44814 #if defined(BCM_TRIUMPH_SUPPORT) 44815 if (SOC_IS_XGS3_SWITCH(unit)) { 44816 rv = _bcm_esw_port_tab_get(unit, port, MPLS_ENABLEf, value); 44817 } 44818 #endif 44819 break; 44820 44821 case bcmPortControlMacInMac: 44822 #if defined(BCM_TRIUMPH2_SUPPORT) 44823 if (SOC_IS_XGS3_SWITCH(unit) && soc_feature(unit, soc_feature_mim)) { 44824 rv = _bcm_esw_port_tab_get(unit, port, MIM_TERM_ENABLEf, value); 44825 } 44826 #endif 44827 break; 44828 44829 case bcmPortControlMimUcastTermEnable: 44830 #if defined(BCM_TRIUMPH2_SUPPORT) 44831 if (SOC_IS_XGS3_SWITCH(unit) && soc_feature(unit, soc_feature_mim)) { 44832 rv = _bcm_esw_port_tab_get(unit, port, MIM_TERM_ENABLEf, value); 44833 } 44834 #endif 44835 break; 44836 44837 case bcmPortControlMimMcastTermEnable: 44838 #if defined(BCM_TRIUMPH2_SUPPORT) 44839 if (SOC_IS_XGS3_SWITCH(unit) && soc_feature(unit, soc_feature_mim)) { 44840 rv = _bcm_esw_port_tab_get(unit, port, MIM_MC_TERM_ENABLEf, value); 44841 } 44842 #endif 44843 break; 44844 44845 case bcmPortControlSrcBmacMissToCpu: 44846 #ifdef BCM_TRIUMPH2_SUPPORT 44847 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 44848 SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) || 44849 SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA(unit)) { 44850 /* 0x2: ToCPU 0x1: Drop(default) */ 44851 rv = _bcm_esw_port_tab_get(unit, port, CML_BMAC_NEWf, value); 44852 *value = (*value == 0x2) ? TRUE : FALSE; 44853 } 44854 #endif /* BCM_TRIUMPH2_SUPPORT */ 44855 break; 44856 44857 case bcmPortControlQosRemarkResolution: 44858 #ifdef BCM_TRIDENT3_SUPPORT 44859 if (SOC_IS_TRIDENT3X(unit)) { 44860 rv = _bcm_esw_egr_port_tab_get(unit, port, QOS_CTRL_IDf, value); 44861 /* TD3 only supports 2 of the 4 valid hardware configurations for now. 44862 * 1: Serial resolution. 44863 * 3: Layered resolution. 44864 * Other value: Invalid. 44865 */ 44866 if (rv == BCM_E_NONE) { 44867 if (*value == 1) { 44868 *value = BCM_PORT_QOS_SERIAL_RESOLUTION; 44869 } else if (*value == 3) { 44870 *value = BCM_PORT_QOS_LAYERED_RESOLUTION; 44871 } else { 44872 return BCM_E_PARAM; 44873 } 44874 } 44875 } 44876 #endif /* BCM_TRIDENT3_SUPPORT */ 44877 break; 44878 44879 case bcmPortControlFabricQueue: 44880 #if defined(BCM_TRIUMPH2_SUPPORT) 44881 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44882 if (IS_ST_PORT(unit, port)) { 44883 if (SOC_REG_FIELD_VALID(unit, EGR_PORT_64r, EH_EXT_HDR_ENABLEf)) { 44884 uint64 egr_val64; 44885 rv = READ_EGR_PORT_64r(unit, port, &egr_val64); 44886 if (BCM_SUCCESS(rv)) { 44887 *value = soc_reg64_field32_get(unit, EGR_PORT_64r, 44888 egr_val64, EH_EXT_HDR_ENABLEf); 44889 } 44890 } 44891 else if(SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EH_EXT_HDR_ENABLEf)){ 44892 egr_port_entry_t entry; 44893 rv = soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ANY, port, 44894 &entry); 44895 if (BCM_SUCCESS(rv)) { 44896 *value = soc_mem_field32_get(unit, EGR_PORTm, &entry, 44897 EH_EXT_HDR_ENABLEf); 44898 } 44899 } 44900 } else { 44901 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 44902 /* Allow CPU port on TD2+ to add extended header */ 44903 if (SOC_IS_TRIDENT2PLUS(unit) && IS_CPU_PORT(unit, port)) { 44904 egr_port_entry_t entry; 44905 rv = soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ANY, port, 44906 &entry); 44907 if (BCM_SUCCESS(rv)) { 44908 *value = soc_mem_field32_get(unit, EGR_PORTm, &entry, 44909 EH_EXT_HDR_ENABLEf); 44910 } 44911 } 44912 #endif 44913 #if defined(BCM_TOMAHAWK_SUPPORT) 44914 if (SOC_IS_TOMAHAWKX(unit) && IS_CPU_PORT(unit, port)) { 44915 egr_port_entry_t entry; 44916 rv = soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ANY, port, &entry); 44917 if (BCM_SUCCESS(rv)) { 44918 *value = soc_mem_field32_get(unit, EGR_PORTm, &entry, 44919 EH_EXT_HDR_ENABLEf); 44920 } 44921 } 44922 #endif 44923 } 44924 #if defined(BCM_TRIDENT3_SUPPORT) 44925 if (SOC_IS_TRIDENT3X(unit) && 44926 soc_feature(unit, soc_feature_egr_lport_tab_profile)) { 44927 uint32 enable = 0; 44928 rv = bcm_esw_port_egr_lport_field_get( 44929 unit, port, EGR_LPORT_PROFILEm, EH_EXT_HDR_ENABLEf, 44930 &enable); 44931 BCM_IF_ERROR_RETURN(rv); 44932 *value = (enable) ? 1: 0; 44933 } 44934 #endif 44935 #endif 44936 break; 44937 case bcmPortControlPassControlFrames: 44938 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44939 #ifdef BCM_XGS_SWITCH_SUPPORT 44940 if (IS_XE_PORT(unit, port) || IS_CE_PORT(unit, port) || 44941 (IS_GE_PORT(unit, port) 44942 && soc_feature(unit, soc_feature_unified_port)) || 44943 (SOC_IS_KATANAX(unit) && IS_MXQ_PORT(unit, port))) { 44944 if(soc_feature(unit, soc_feature_pgw_mac_control_frame)) { 44945 uint32 rval32 = 0; 44946 rv = READ_PGW_MAC_RSV_MASKr(unit, port, &rval32); 44947 if (BCM_SUCCESS(rv)) { 44948 /* PGW_MAC_RSV_MASK: Bit 11 Control Frame recieved 44949 * the bit value needs to be reversed 44950 */ 44951 *value = ((rval32 & 0x800) >> 11) ? 0 : 1 ; 44952 } 44953 } else { 44954 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44955 SOC_MAC_PASS_CONTROL_FRAME, value); 44956 } 44957 } 44958 #endif 44959 break; 44960 #ifdef BCM_XGS3_SWITCH_SUPPORT 44961 case bcmPortControlFilterLookup: 44962 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 44963 rv = _bcm_esw_port_tab_get(unit, port, VFP_ENABLEf, value); 44964 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 44965 break; 44966 case bcmPortControlFilterIngress: 44967 #if defined(BCM_TRX_SUPPORT) 44968 if (BCM_GPORT_LOCAL_CPU_HIGIG == port) { 44969 rv = _bcm_esw_iport_tab_get(unit, CMIC_PORT(unit), FILTER_ENABLEf, value); 44970 } else 44971 #endif 44972 if (BCM_GPORT_LOCAL_CPU_IEEE == port) { 44973 rv = _bcm_esw_port_tab_get(unit, CMIC_PORT(unit), FILTER_ENABLEf, value); 44974 } else { 44975 rv = _bcm_esw_port_tab_get(unit, port, FILTER_ENABLEf, value); 44976 } 44977 break; 44978 case bcmPortControlFilterEgress: 44979 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 44980 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44981 if (SOC_REG_FIELD_VALID(unit, EGR_PORTr, EFP_FILTER_ENABLEf)) { 44982 uint32 egr_val; 44983 44984 rv = READ_EGR_PORTr(unit, port, &egr_val); 44985 if (BCM_SUCCESS(rv)) { 44986 *value = soc_reg_field_get(unit, EGR_PORTr, egr_val, 44987 EFP_FILTER_ENABLEf); 44988 } 44989 } else if (SOC_REG_FIELD_VALID(unit, EGR_PORT_64r, 44990 EFP_FILTER_ENABLEf)) { 44991 uint64 egr_val64; 44992 44993 rv = READ_EGR_PORT_64r(unit, port, &egr_val64); 44994 if (BCM_SUCCESS(rv)) { 44995 *value = soc_reg64_field32_get(unit, EGR_PORT_64r, 44996 egr_val64, 44997 EFP_FILTER_ENABLEf); 44998 } 44999 } else { 45000 rv = _bcm_esw_egr_port_tab_get(unit, port, EFP_FILTER_ENABLEf, value); 45001 45002 } 45003 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 45004 break; 45005 case bcmPortControlFrameSpacingStretch: 45006 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45007 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45008 SOC_MAC_CONTROL_FRAME_SPACING_STRETCH, value); 45009 break; 45010 case bcmPortControlPreservePacketPriority: 45011 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 45012 if (SOC_IS_TRIUMPH3(unit)) { 45013 /* Triumph3 has unity mapping to ING_OUTER_DOT1P_MAPPING_TABLE */ 45014 rv = _bcm_esw_port_tab_get(unit, port, 45015 DOT1P_REMAP_POINTERf, value); 45016 if (BCM_SUCCESS(rv)) { 45017 /* True if pointed to default dot1p profile */ 45018 *value = (*value) ? 0 : 1; 45019 } 45020 } else { 45021 rv = _bcm_esw_port_tab_get(unit, port, USE_INCOMING_DOT1Pf, value); 45022 } 45023 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 45024 break; 45025 case bcmPortControlLearnClassEnable: 45026 #if defined(BCM_TRX_SUPPORT) 45027 if (soc_feature(unit, soc_feature_class_based_learning)) { 45028 rv = _bcm_esw_port_tab_get(unit, port, CLASS_BASED_SM_ENABLEf, 45029 value); 45030 } 45031 #endif /* BCM_TRX_SUPPORT */ 45032 break; 45033 case bcmPortControlTrustIncomingVlan: 45034 #if defined(BCM_TRIDENT3_SUPPORT) 45035 if (SOC_IS_TRIDENT3X(unit)) { 45036 uint32 tpid_enable; 45037 rv = _bcm_fb2_port_tpid_enable_get(unit, port, &tpid_enable); 45038 *value = tpid_enable ? 1 : 0; 45039 } else 45040 #endif 45041 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT) 45042 { 45043 rv = _bcm_esw_port_tab_get(unit, port, TRUST_INCOMING_VIDf, value); 45044 } 45045 #endif /* BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 45046 break; 45047 case bcmPortControlDoNotCheckVlan: 45048 #if defined(BCM_TRX_SUPPORT) 45049 if (!SOC_IS_SHADOW(unit)) { 45050 #if defined(BCM_TRIDENT3_SUPPORT) 45051 if (SOC_IS_TRIDENT3X(unit)) { 45052 rv = _bcm_esw_port_tab_get(unit, port, 45053 DISABLE_VLAN_CHECKSf, value); 45054 } else 45055 #endif 45056 if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf)) { 45057 if (CMIC_PORT(unit) == port) { 45058 rv = _bcm_esw_iport_tab_get(unit, port, 45059 DISABLE_VLAN_CHECKSf, value); 45060 } else { 45061 rv = _bcm_esw_port_tab_get(unit, port, 45062 DISABLE_VLAN_CHECKSf, value); 45063 } 45064 } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 45065 DISABLE_VLAN_CHECKSf)) { 45066 #if defined(BCM_KATANA2_SUPPORT) 45067 if (SOC_IS_KATANA2(unit)) { 45068 rv = _bcm_kt2_source_trunk_map_get(unit, port, 45069 DISABLE_VLAN_CHECKSf, (uint32 *)value); 45070 } else 45071 #endif 45072 { 45073 rv = _bcm_trx_source_trunk_map_get(unit, port, 45074 DISABLE_VLAN_CHECKSf, (uint32 *)value); 45075 } 45076 } 45077 } 45078 #endif /* BCM_TRX_SUPPORT */ 45079 break; 45080 case bcmPortControlDoNotCheckVlanFromCpu: 45081 #if defined(BCM_TRX_SUPPORT) 45082 if (!SOC_IS_SHADOW(unit)) { 45083 if (CMIC_PORT(unit) == port) { 45084 if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf) || 45085 SOC_IS_TRIDENT3X(unit)) { 45086 rv = _bcm_esw_port_tab_get(unit, port, 45087 DISABLE_VLAN_CHECKSf, value); 45088 } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 45089 DISABLE_VLAN_CHECKSf)) { 45090 rv = _bcm_trx_source_trunk_map_get(unit, port, 45091 DISABLE_VLAN_CHECKSf, (uint32 *)value); 45092 } 45093 } else { 45094 rv = BCM_E_PORT; 45095 } 45096 } 45097 #endif /* BCM_TRX_SUPPORT */ 45098 break; 45099 case bcmPortControlIEEE8021ASEnableIngress: 45100 #if defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_ENDURO_SUPPORT) 45101 if (soc_feature(unit, soc_feature_rx_timestamp)) { 45102 rv = _bcm_esw_port_tab_get(unit, port, 45103 IEEE_802_1AS_ENABLEf, value); 45104 } 45105 #endif /* BCM_HAWKEYE_SUPPORT */ 45106 break; 45107 case bcmPortControlIEEE8021ASEnableEgress: 45108 #if defined(BCM_HAWKEYE_SUPPORT) 45109 if (SOC_IS_HAWKEYE(unit)) { 45110 uint32 egr_val; 45111 45112 rv = READ_EGR_PORTr(unit, port, &egr_val); 45113 if (BCM_SUCCESS(rv)) { 45114 *value = soc_reg_field_get(unit, EGR_PORTr, egr_val, 45115 IEEE_802_1AS_ENABLEf); 45116 } 45117 } 45118 #endif /* BCM_HAWKEYE_SUPPORT */ 45119 break; 45120 case bcmPortControlEgressVlanPriUsesPktPri: 45121 #if defined(BCM_TRX_SUPPORT) 45122 #if defined (BCM_HGPROXY_COE_SUPPORT) 45123 if (!((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 45124 (soc_feature(unit, soc_feature_channelized_switching))) && 45125 BCM_GPORT_IS_SUBPORT_PORT(port))) 45126 #endif 45127 { 45128 BCM_IF_ERROR_RETURN( 45129 _bcm_esw_port_gport_validate(unit, port, &port)); 45130 } 45131 if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) { 45132 uint32 val; 45133 #ifdef BCM_TRIDENT2PLUS_SUPPORT 45134 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 45135 if (soc_feature(unit, soc_feature_egr_all_profile)) { 45136 rv = bcm_esw_port_egr_lport_field_get(unit, 45137 port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DOT1Pf, 45138 (uint32 *)value); 45139 *value = *value ? 0 : 1; 45140 } else { 45141 #if defined (BCM_HGPROXY_COE_SUPPORT) 45142 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 45143 (soc_feature(unit, soc_feature_channelized_switching))) && 45144 BCM_GPORT_IS_SUBPORT_PORT(port)) { 45145 rv = bcm_esw_port_egr_lport_field_get( 45146 unit, port, EGR_VLAN_CONTROL_1m, 45147 REMARK_OUTER_DOT1Pf, (uint32 *)value); 45148 *value = *value ? 0 : 1; 45149 } else 45150 #endif 45151 { 45152 egr_vlan_control_1_entry_t entry; 45153 rv = READ_EGR_VLAN_CONTROL_1m( 45154 unit, MEM_BLOCK_ANY, port, &entry); 45155 if (BCM_SUCCESS(rv)) { 45156 *value = soc_EGR_VLAN_CONTROL_1m_field32_get( 45157 unit, &entry, 45158 REMARK_OUTER_DOT1Pf) ? 0 : 1; 45159 } 45160 } 45161 } 45162 } else 45163 #endif 45164 { 45165 rv = READ_EGR_VLAN_CONTROL_1r(unit, port, &val); 45166 if (BCM_SUCCESS(rv)) { 45167 *value = (soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, val, 45168 REMARK_OUTER_DOT1Pf)) ? 0 : 1; 45169 } 45170 } 45171 } 45172 #endif /* BCM_TRX_SUPPORT */ 45173 break; 45174 case bcmPortControlEgressModifyDscp: 45175 #if defined(BCM_TRX_SUPPORT) 45176 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45177 if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) { 45178 uint32 val; 45179 #ifdef BCM_TRIDENT2PLUS_SUPPORT 45180 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 45181 if (soc_feature(unit, soc_feature_egr_all_profile)) { 45182 rv = bcm_esw_port_egr_lport_field_get(unit, 45183 port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DSCPf, 45184 (uint32 *)value); 45185 *value = *value ? 1 : 0; 45186 } else { 45187 egr_vlan_control_1_entry_t entry; 45188 rv = READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry); 45189 if (BCM_SUCCESS(rv)) { 45190 *value = soc_EGR_VLAN_CONTROL_1m_field32_get(unit, &entry, 45191 REMARK_OUTER_DSCPf) ? 1 : 0; 45192 } 45193 } 45194 } else 45195 #endif 45196 { 45197 rv = READ_EGR_VLAN_CONTROL_1r(unit, port, &val); 45198 if (BCM_SUCCESS(rv)) { 45199 *value = (soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, val, 45200 REMARK_OUTER_DSCPf)) ? 1 : 0; 45201 } 45202 } 45203 } 45204 #endif /* BCM_TRX_SUPPORT */ 45205 break; 45206 case bcmPortControlIpfixRate: 45207 #ifdef BCM_TRIUMPH2_SUPPORT 45208 if (soc_feature(unit, soc_feature_ipfix_rate)) { 45209 rv = _bcm_esw_port_tab_get(unit, port, IPFIX_FLOW_METER_IDf, 45210 value); 45211 } 45212 #endif /* BCM_TRIUMPH2_SUPPORT */ 45213 break; 45214 case bcmPortControlCustomerQueuing: 45215 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45216 #ifdef BCM_ENDURO_SUPPORT 45217 if (SOC_IS_ENDURO(unit) && !IS_HG_PORT(unit, port)) { 45218 return BCM_E_UNAVAIL; 45219 } 45220 #endif 45221 #ifdef BCM_KATANA_SUPPORT 45222 if (SOC_IS_KATANAX(unit)) { 45223 uint32 rval, ing_cos_mode, rqe_cos_mode; 45224 BCM_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &rval)); 45225 ing_cos_mode = soc_reg_field_get(unit, ING_COS_MODEr, rval, COS_MODEf); 45226 if (SOC_IS_KATANA(unit)) { 45227 SOC_IF_ERROR_RETURN(READ_RQE_PORT_CONFIGr(unit, port, &rval)); 45228 rqe_cos_mode = soc_reg_field_get(unit, RQE_PORT_CONFIGr, rval, COS_MODEf); 45229 } else { 45230 SOC_IF_ERROR_RETURN(READ_RQE_PP_PORT_CONFIGr(unit, port, &rval)); 45231 rqe_cos_mode = soc_reg_field_get(unit, RQE_PP_PORT_CONFIGr, rval, COS_MODEf); 45232 } 45233 if ((ing_cos_mode != rqe_cos_mode) && (ing_cos_mode != 1)) { 45234 *value = 4; 45235 } else { 45236 *value = ing_cos_mode; 45237 } 45238 rv = BCM_E_NONE; 45239 break; 45240 } 45241 #endif /* BCM_KATANA_SUPPORT */ 45242 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 45243 if ((SOC_IS_TRIDENT3X(unit)) || (SOC_IS_TOMAHAWKX(unit))) { 45244 uint64 rval1; 45245 if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) { 45246 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval1); 45247 BCM_IF_ERROR_RETURN(rv); 45248 *value = soc_reg64_field32_get(unit, ING_COS_MODEr, rval1, 45249 COS_MODEf); 45250 } 45251 45252 if (SOC_MEM_IS_VALID(unit, ING_COS_MODEm)) { 45253 ing_cos_mode_entry_t entry; 45254 rv = soc_mem_read(unit, ING_COS_MODEm, MEM_BLOCK_ANY, port, &entry); 45255 BCM_IF_ERROR_RETURN(rv); 45256 *value = soc_mem_field32_get(unit, ING_COS_MODEm, &entry, COS_MODEf); 45257 } 45258 45259 break; 45260 } 45261 #endif /* BCM_TRIDENT3_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 45262 #ifdef BCM_TRIDENT2_SUPPORT 45263 if (SOC_IS_TD2_TT2(unit)) { 45264 uint64 rval; 45265 rv = READ_ING_COS_MODE_64r(unit, port, &rval); 45266 BCM_IF_ERROR_RETURN(rv); 45267 45268 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODE_64r, QUEUE_MODEf)) { 45269 *value = soc_reg64_field32_get(unit, ING_COS_MODE_64r, rval, 45270 QUEUE_MODEf); 45271 break; 45272 } 45273 } 45274 #endif /* BCM_TRIDENT2_SUPPORT */ 45275 #ifdef BCM_TRIUMPH2_SUPPORT 45276 if (soc_feature(unit, soc_feature_vlan_queue_map)) { 45277 uint32 rval; 45278 soc_field_t field; 45279 if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) { 45280 rv = READ_ING_COS_MODEr(unit, port, &rval); 45281 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, SELECTf)) { 45282 field = SELECTf; 45283 } else if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, 45284 QUEUE_MODEf)) { 45285 field = QUEUE_MODEf; 45286 } else { 45287 rv = BCM_E_UNAVAIL; 45288 break; 45289 } 45290 if (SOC_IS_TRIUMPH3(unit)) { 45291 *value = soc_reg_field_get(unit, ING_COS_MODEr, rval, field); 45292 } else { 45293 if (soc_reg_field_get(unit, ING_COS_MODEr, rval, field) 45294 == 3) { 45295 *value = 1; 45296 } else { 45297 *value = 0; 45298 } 45299 } 45300 } 45301 } 45302 #endif /* BCM_TRIUMPH2_SUPPORT */ 45303 break; 45304 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 45305 45306 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT) 45307 case bcmPortControlOAMEnable: 45308 rv = _bcm_esw_port_tab_get(unit, port, OAM_ENABLEf, value); 45309 break; 45310 #endif /* defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT) */ 45311 45312 #if defined (BCM_OLP_SUPPORT) 45313 case bcmPortControlOlpEnable: 45314 if (soc_feature(unit, soc_feature_olp)) { 45315 bcm_module_t module_id = 0; 45316 bcm_module_t my_modid; 45317 bcm_port_t port_id; 45318 bcm_trunk_t trunk_id = BCM_TRUNK_INVALID; 45319 int local_id; 45320 45321 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 45322 45323 if (BCM_GPORT_IS_SET(port)) { 45324 SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, &module_id, 45325 &port_id, &trunk_id, &local_id)); 45326 45327 #if defined(BCM_KATANA2_SUPPORT) 45328 if (SOC_IS_KATANA2(unit) && 45329 (BCM_GPORT_IS_SUBPORT_PORT(port)) && 45330 ((_BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) || 45331 (_BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)))) { 45332 45333 LOG_ERROR(BSL_LS_BCM_L2, 45334 (BSL_META_U(unit, 45335 "OLP is not allowed on SUBPORT. \ 45336 \n"))); 45337 return BCM_E_PARAM; 45338 } 45339 #endif 45340 } else { 45341 port_id = port; 45342 } 45343 if ((module_id == 0) || (module_id == my_modid)) { 45344 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 45345 if(SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 45346 iarb_ing_port_table_entry_t entry; 45347 45348 SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PORT_TABLEm, 45349 MEM_BLOCK_ANY, port_id, &entry)); 45350 *value = soc_IARB_ING_PORT_TABLEm_field32_get(unit, 45351 &entry, OLP_ENABLEf); 45352 45353 } else 45354 #endif 45355 { 45356 iarb_ing_physical_port_entry_t entry; 45357 SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PHYSICAL_PORTm, 45358 MEM_BLOCK_ANY, port_id, &entry)); 45359 *value = soc_IARB_ING_PHYSICAL_PORTm_field32_get(unit, 45360 &entry, OLP_ENABLEf); 45361 } 45362 } 45363 rv = BCM_E_NONE; 45364 } 45365 break; 45366 #endif /* BCM_OLP_SUPPORT*/ 45367 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 45368 45369 case bcmPortControlPortMacOui: 45370 case bcmPortControlPortMacNonOui: 45371 45372 /* 45373 * In case of KT2, SB2 and TD2+ NONTCAM STATION related to OAM, OLP, XGS can be programmed 45374 * by either of bcm_l2_station_xxx API or bcm_switch_olp_l2_addr_xxx 45375 * 45376 * Use either of two set of APIs 45377 */ 45378 45379 if (_BCM_SWITCH_OLP_APIV(unit) == _BCM_SWITCH_OLP_L2_STATION_API) { 45380 LOG_VERBOSE(BSL_LS_BCM_L2, 45381 (BSL_META_U(unit, 45382 "use bcm_l2_station_xxx API\n"))); 45383 return BCM_E_UNAVAIL; 45384 } 45385 _BCM_SWITCH_OLP_APIV_SET(unit, _BCM_SWITCH_OLP_TRUE_API); 45386 45387 #if defined(BCM_KATANA2_SUPPORT) 45388 if (SOC_IS_KATANA2(unit) && 45389 (soc_feature(unit, soc_feature_oam) || 45390 soc_feature(unit, soc_feature_sat))) { 45391 45392 uint32 val_lo, val_hi; 45393 uint64 mac_field; 45394 45395 PORT_LOCK(unit); 45396 45397 rv = _bcm_kt2_port_mac_get(unit, port, &mac_field); 45398 if (BCM_FAILURE(rv)) { 45399 PORT_UNLOCK(unit); 45400 return (rv); 45401 } 45402 COMPILER_64_TO_32_LO(val_lo, mac_field); 45403 COMPILER_64_TO_32_HI(val_hi, mac_field); 45404 45405 switch (type) { 45406 case bcmPortControlPortMacOui: 45407 *value = 0xffffff & ((val_hi << 8) | ((val_lo >> 24) & 0xff)); 45408 break; 45409 45410 case bcmPortControlPortMacNonOui: 45411 *value = (val_lo & 0xffffff); 45412 break; 45413 default: 45414 break; 45415 } 45416 PORT_UNLOCK(unit); 45417 45418 rv = BCM_E_NONE; 45419 } 45420 #endif /* BCM_KATANA2_SUPPORT */ 45421 45422 #if defined(BCM_MONTEREY_SUPPORT) 45423 if (SOC_IS_MONTEREY(unit)) { 45424 uint32 mac; 45425 45426 PORT_LOCK(unit); 45427 rv = _bcm_monterey_port_mac_get(unit, 45428 port, 45429 type == bcmPortControlPortMacOui, 45430 &mac); 45431 PORT_UNLOCK(unit); 45432 45433 *value = mac; 45434 } 45435 #endif 45436 #if defined(BCM_APACHE_SUPPORT) 45437 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 45438 uint32 mac; 45439 45440 PORT_LOCK(unit); 45441 rv = _bcm_apache_port_mac_get(unit, 45442 port, 45443 type == bcmPortControlPortMacOui, 45444 &mac); 45445 PORT_UNLOCK(unit); 45446 45447 *value = mac; 45448 } 45449 #endif /* BCM_APACHE_SUPPORT */ 45450 break; 45451 #endif /* BCM_KATANA2_SUPPORT || BCM_APACHE_SUPPORT*/ 45452 45453 #ifdef BCM_TRX_SUPPORT 45454 case bcmPortControlOamLoopback: 45455 if (SOC_IS_TRX(unit) && !SOC_IS_HURRICANE(unit) 45456 && !SOC_IS_SHADOW(unit)) 45457 { 45458 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45459 if (soc_reg_field_valid(unit,ING_MISC_PORT_CONFIGr, 45460 OAM_DO_NOT_MODIFYf)) { 45461 uint32 reg_value; 45462 45463 rv = READ_ING_MISC_PORT_CONFIGr(unit, port, ®_value); 45464 45465 if (SOC_SUCCESS(rv)) { 45466 *value = soc_reg_field_get(unit, ING_MISC_PORT_CONFIGr, 45467 reg_value, OAM_DO_NOT_MODIFYf); 45468 } 45469 } else { 45470 return BCM_E_UNAVAIL; 45471 } 45472 } 45473 45474 break; 45475 #endif /* BCM_TRX_SUPPORT */ 45476 45477 case bcmPortControlLanes: 45478 if (soc_feature(unit, soc_feature_flexport_no_legacy)) { 45479 return BCM_E_UNAVAIL; 45480 } 45481 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45482 #if defined(BCM_TRIUMPH2_SUPPORT) 45483 if (soc_feature(unit, soc_feature_flex_port)) { 45484 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT 45485 if (soc_feature(unit, soc_feature_xgs5_flexport_legacy_mode)) { 45486 rv = bcmi_xgs5_port_lanes_get(unit, port, value); 45487 } else 45488 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */ 45489 #if defined(BCM_ENDURO_SUPPORT) 45490 if (SOC_IS_ENDURO(unit)) { 45491 rv = _bcm_en_port_lanes_get(unit, port, value); 45492 } else 45493 #endif 45494 #if defined(BCM_HURRICANE1_SUPPORT) 45495 if (SOC_IS_HURRICANE(unit)) { 45496 rv = _bcm_hu_port_lanes_get(unit, port, value); 45497 } else 45498 #endif 45499 #if defined(BCM_HURRICANE2_SUPPORT) 45500 if (SOC_IS_HURRICANE2(unit)) { 45501 rv = soc_hurricane2_port_lanes_get(unit, port, value); 45502 } else 45503 #endif 45504 #if defined(BCM_MONTEREY_SUPPORT) 45505 if (SOC_IS_MONTEREY(unit)) { 45506 rv = bcmi_monterey_port_lanes_get(unit, port, value); 45507 } else 45508 #endif 45509 #if defined(BCM_APACHE_SUPPORT) 45510 if (SOC_IS_APACHE(unit)) { 45511 rv = bcmi_apache_port_lanes_get(unit, port, value); 45512 } else 45513 #endif 45514 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 45515 if (SOC_IS_TD2P_TT2P(unit)) { 45516 rv = bcmi_td2p_port_lanes_get(unit, port, value); 45517 } else 45518 #endif 45519 #if defined(BCM_TRIDENT2_SUPPORT) 45520 if (SOC_IS_TD2_TT2(unit)) { 45521 rv = soc_trident2_port_lanes_get(unit, port, value); 45522 } else 45523 #endif /* BCM_TRIDENT2_SUPPORT */ 45524 #ifdef BCM_TRIDENT_SUPPORT 45525 if (SOC_IS_TD_TT(unit)) { 45526 if (!SOC_PORT_VALID(unit, port)) { 45527 return BCM_E_PORT; 45528 } 45529 /* coverity[overrun-local : FALSE] */ 45530 *value = SOC_INFO(unit).port_num_lanes[port]; 45531 rv = BCM_E_NONE; 45532 } else 45533 #endif /* BCM_TRIDENT_SUPPORT */ 45534 #ifdef BCM_SHADOW_SUPPORT 45535 if (SOC_IS_SHADOW(unit)) { 45536 if (!SOC_PORT_VALID(unit, port)) { 45537 return BCM_E_PORT; 45538 } 45539 /* coverity[overrun-local : FALSE] */ 45540 *value = SOC_INFO(unit).port_num_lanes[port]; 45541 rv = BCM_E_NONE; 45542 } else 45543 #endif /* BCM_SHADOW_SUPPORT */ 45544 #ifdef BCM_TRIUMPH3_SUPPORT 45545 if (SOC_IS_TRIUMPH3(unit)) { 45546 rv = _bcm_tr3_port_lanes_get(unit, port, value); 45547 } else 45548 #endif /* BCM_TRIUMPH3_SUPPORT */ 45549 #ifdef BCM_METROLITE_SUPPORT 45550 if (SOC_IS_METROLITE(unit)) { 45551 rv = _bcm_ml_port_lanes_get(unit, port, value); 45552 } else 45553 #endif /* BCM_METROLITE_SUPPORT */ 45554 #ifdef BCM_SABER2_SUPPORT 45555 if (SOC_IS_SABER2(unit)) { 45556 rv = _bcm_sb2_port_lanes_get(unit, port, value); 45557 } else 45558 #endif /* BCM_SABER2_SUPPORT */ 45559 #ifdef BCM_KATANA2_SUPPORT 45560 if (SOC_IS_KATANA2(unit)) { 45561 rv = _bcm_kt2_port_lanes_get(unit, port, value); 45562 } else 45563 #endif /* BCM_KATANA2_SUPPORT */ 45564 { 45565 rv = _bcm_tr2_port_lanes_get(unit, port, value); 45566 } 45567 } 45568 #endif 45569 break; 45570 case bcmPortControlPFCEthertype: 45571 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 45572 if (soc_feature(unit, soc_feature_priority_flow_control)) { 45573 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45574 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 45575 /* IS_GX_PORT == IS_XL_PORT */ 45576 return BCM_E_PORT; 45577 } 45578 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45579 SOC_MAC_CONTROL_PFC_TYPE, value); 45580 } 45581 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 45582 break; 45583 case bcmPortControlPFCOpcode: 45584 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 45585 if (soc_feature(unit, soc_feature_priority_flow_control)) { 45586 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45587 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 45588 /* IS_GX_PORT == IS_XL_PORT */ 45589 return BCM_E_PORT; 45590 } 45591 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45592 SOC_MAC_CONTROL_PFC_OPCODE, value); 45593 } 45594 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 45595 break; 45596 case bcmPortControlPFCReceive: 45597 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 45598 if (soc_feature(unit, soc_feature_priority_flow_control)) { 45599 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45600 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 45601 /* IS_GX_PORT == IS_XL_PORT */ 45602 return BCM_E_PORT; 45603 } 45604 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45605 SOC_MAC_CONTROL_PFC_RX_ENABLE, value); 45606 } 45607 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 45608 break; 45609 case bcmPortControlPFCTransmit: 45610 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 45611 if (soc_feature(unit, soc_feature_priority_flow_control)) { 45612 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45613 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 45614 /* IS_GX_PORT == IS_XL_PORT */ 45615 return BCM_E_PORT; 45616 } 45617 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45618 SOC_MAC_CONTROL_PFC_TX_ENABLE, value); 45619 } 45620 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 45621 break; 45622 case bcmPortControlPFCClasses: 45623 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 45624 if (soc_feature(unit, soc_feature_priority_flow_control)) { 45625 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45626 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 45627 /* IS_GX_PORT == IS_XL_PORT */ 45628 return BCM_E_PORT; 45629 } 45630 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45631 SOC_MAC_CONTROL_PFC_CLASSES, value); 45632 } 45633 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 45634 break; 45635 case bcmPortControlPFCPassFrames: 45636 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 45637 if (soc_feature(unit, soc_feature_priority_flow_control)) { 45638 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45639 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 45640 /* IS_GX_PORT == IS_XL_PORT */ 45641 return BCM_E_PORT; 45642 } 45643 45644 if(soc_feature(unit, soc_feature_pgw_mac_pfc_frame)) { 45645 uint32 rval32 = 0; 45646 soc_reg_t reg = INVALIDr; 45647 if(SOC_REG_IS_VALID(unit, PGW_MAC_RSV_MASKr)) { 45648 reg = PGW_MAC_RSV_MASKr; 45649 } else if(IS_CL_PORT(unit, port) && 45650 SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) { 45651 reg = CLPORT_MAC_RSV_MASKr; 45652 } else if(IS_XL_PORT(unit, port) && 45653 SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) { 45654 reg = XLPORT_MAC_RSV_MASKr; 45655 } else { 45656 reg = INVALIDr; 45657 } 45658 45659 if (reg != INVALIDr) { 45660 rv = soc_reg32_get(unit, reg, port, 0, &rval32); 45661 if (BCM_SUCCESS(rv)) { 45662 /* xxx_MAC_RSV_MASK: Bit 18 PFC frame detected 45663 * the bit value needs to be reversed 45664 */ 45665 *value = ((rval32 & 0x40000) >> 18) ? 0 : 1 ; 45666 } 45667 } else { 45668 rv = BCM_E_UNAVAIL; 45669 } 45670 } else { 45671 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45672 SOC_MAC_CONTROL_PFC_RX_PASS, value); 45673 } 45674 } 45675 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 45676 break; 45677 45678 case bcmPortControlPFCDestMacOui: 45679 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 45680 if (soc_feature(unit, soc_feature_priority_flow_control)) { 45681 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45682 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 45683 /* IS_GX_PORT == IS_XL_PORT */ 45684 return BCM_E_PORT; 45685 } 45686 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45687 SOC_MAC_CONTROL_PFC_MAC_DA_OUI, value); 45688 } 45689 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 45690 break; 45691 45692 case bcmPortControlPFCDestMacNonOui: 45693 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 45694 if (soc_feature(unit, soc_feature_priority_flow_control)) { 45695 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45696 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 45697 /* IS_GX_PORT == IS_XL_PORT */ 45698 return BCM_E_PORT; 45699 } 45700 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45701 SOC_MAC_CONTROL_PFC_MAC_DA_NONOUI, value); 45702 } 45703 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 45704 break; 45705 45706 case bcmPortControlPFCRefreshTime: 45707 #if defined(BCM_TRIDENT_SUPPORT)|defined(BCM_GREYHOUND_SUPPORT) 45708 if (soc_feature(unit, soc_feature_priority_flow_control)) { 45709 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45710 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45711 SOC_MAC_CONTROL_PFC_REFRESH_TIME, value); 45712 } 45713 #endif /* BCM_TRIDENT_SUPPORT */ 45714 break; 45715 45716 case bcmPortControlPFCXOffTime: 45717 #if defined(BCM_TRIDENT_SUPPORT)||defined(BCM_GREYHOUND_SUPPORT) 45718 if (soc_feature(unit, soc_feature_priority_flow_control)) { 45719 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 45720 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45721 SOC_MAC_CONTROL_PFC_XOFF_TIME, value); 45722 } 45723 #endif /* BCM_TRIDENT_SUPPORT */ 45724 break; 45725 45726 case bcmPortControlVrf: 45727 rv = _bcm_esw_port_vrf_get(unit, port, value); 45728 break; 45729 45730 case bcmPortControlL3Ingress: 45731 #if defined(BCM_TRIUMPH_SUPPORT) 45732 { 45733 if (!soc_feature(unit, soc_feature_l3_ingress_interface)) { 45734 return BCM_E_UNAVAIL; 45735 } 45736 45737 *value = 0; 45738 if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf) || 45739 SOC_IS_TRIDENT3X(unit)) { 45740 rv = _bcm_esw_port_tab_get(unit, port, PORT_OPERATIONf, value); 45741 BCM_IF_ERROR_RETURN(rv); 45742 if ((*value == 0x2) && 45743 (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 45744 L3_IIFf)) ) { 45745 #if defined(BCM_KATANA2_SUPPORT) 45746 if (SOC_IS_KATANA2(unit)) { 45747 rv = _bcm_kt2_source_trunk_map_get(unit, port, L3_IIFf, 45748 (uint32 *)value); 45749 } else 45750 #endif 45751 { 45752 rv = _bcm_trx_source_trunk_map_get(unit, port, L3_IIFf, 45753 (uint32 *)value); 45754 } 45755 } 45756 } 45757 } 45758 #endif /* BCM_TRIUMPH_SUPPORT */ 45759 break; 45760 45761 case bcmPortControlL2Learn: 45762 #if defined(BCM_TRX_SUPPORT) 45763 if (SOC_IS_TRX(unit)) { 45764 bcm_port_cfg_t port_cfg; 45765 45766 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg); 45767 if (BCM_SUCCESS(rv)) { 45768 rv = _bcm_trx_port_cml_hw2flags(unit, port_cfg.pc_cml, 45769 (uint32 *)value); 45770 } 45771 } 45772 #endif /* BCM_TRX_SUPPORT */ 45773 break; 45774 45775 case bcmPortControlL2Move: 45776 #if defined(BCM_TRX_SUPPORT) 45777 if (SOC_IS_TRX(unit)) { 45778 bcm_port_cfg_t port_cfg; 45779 45780 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg); 45781 if (BCM_SUCCESS(rv)) { 45782 rv = _bcm_trx_port_cml_hw2flags(unit, port_cfg.pc_cml_move, 45783 (uint32 *)value); 45784 } 45785 } 45786 #endif /* BCM_TRX_SUPPORT */ 45787 break; 45788 45789 case bcmPortControlForwardStaticL2MovePkt: 45790 #if defined(BCM_TRX_SUPPORT) 45791 rv = _bcm_esw_port_tab_get(unit, port, DISABLE_STATIC_MOVE_DROPf, 45792 value); 45793 #endif /* BCM_TRX_SUPPORT */ 45794 break; 45795 45796 case bcmPortControlPrbsRxStatus: 45797 PORT_LOCK(unit); 45798 rv = soc_phyctrl_control_get(unit, port, 45799 SOC_PHY_CONTROL_PRBS_RX_STATUS, 45800 (uint32 *)value); 45801 PORT_UNLOCK(unit); 45802 break; 45803 case bcmPortControlLinkFaultLocalEnable: 45804 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45805 SOC_MAC_CONTROL_FAULT_LOCAL_ENABLE, value); 45806 break; 45807 case bcmPortControlLinkFaultRemoteEnable: 45808 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45809 SOC_MAC_CONTROL_FAULT_REMOTE_ENABLE, value); 45810 break; 45811 case bcmPortControlLinkFaultLocal: 45812 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45813 SOC_MAC_CONTROL_FAULT_LOCAL_STATUS, value); 45814 break; 45815 case bcmPortControlLinkFaultRemote: 45816 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45817 SOC_MAC_CONTROL_FAULT_REMOTE_STATUS, value); 45818 break; 45819 case bcmPortControlTimestampTransmit: 45820 #if defined(BCM_TIMESYNC_SUPPORT) 45821 if (soc_feature(unit, soc_feature_timesync_support)) { 45822 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45823 SOC_MAC_CONTROL_TIMESTAMP_TRANSMIT, value); 45824 } else 45825 #endif /* BCM_TIMESYNC_SUPPORT */ 45826 { 45827 return BCM_E_UNAVAIL; 45828 } 45829 break; 45830 case bcmPortControlTimestampEnable: 45831 #if defined(BCM_HAWKEYE_SUPPORT) 45832 if (SOC_IS_HAWKEYE(unit)) { 45833 uint32 rval; 45834 if (!SOC_PORT_VALID(unit, port)) { 45835 return BCM_E_PORT; 45836 } 45837 SOC_IF_ERROR_RETURN(READ_EAV_ENABLE_BMAPr(unit, &rval)); 45838 if ( port < 32 ) { 45839 *value = (rval & (1 << port)) ? TRUE:FALSE; 45840 } else { 45841 *value = FALSE; 45842 } 45843 rv = BCM_E_NONE; 45844 } else 45845 #endif /* BCM_HAWKEYE_SUPPORT */ 45846 if (soc_feature (unit, soc_feature_xlmac_timestamp_disable)) { 45847 if (IS_XL_PORT(unit, port)) { 45848 int tmp; 45849 uint32 rval; 45850 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, 45851 port, &rval)); 45852 tmp = soc_reg_field_get(unit, XLPORT_MAC_CONTROLr, 45853 rval, XLMAC_TS_DISABLEf); 45854 if (tmp) { 45855 *value = FALSE; 45856 } else { 45857 *value = TRUE; 45858 } 45859 rv = BCM_E_NONE; 45860 } 45861 } 45862 break; 45863 case bcmPortControlSerdesDriverEqualizationTuneStatusFarEnd: 45864 PORT_LOCK(unit); 45865 rv = soc_phyctrl_control_get(unit, port, 45866 SOC_PHY_CONTROL_SERDES_DRIVER_EQUALIZATION_TUNE_STATUS_FAR_END, 45867 (uint32 *)value); 45868 PORT_UNLOCK(unit); 45869 break; 45870 case bcmPortControlLinkdownTransmit: 45871 PORT_LOCK(unit); 45872 rv = soc_phyctrl_control_get(unit, port, 45873 SOC_PHY_CONTROL_LINKDOWN_TRANSMIT, 45874 (uint32 *)value); 45875 PORT_UNLOCK(unit); 45876 /* Most of PHYs have nothing to configure and simply return UNAVAIL*/ 45877 if ((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL)) { 45878 rv = _bcm_esw_link_down_tx_get(unit, port, value); 45879 } 45880 break; 45881 case bcmPortControlSerdesTuneMarginMode: 45882 PORT_LOCK(unit); 45883 rv = soc_phyctrl_control_get(unit, port, 45884 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_MODE, 45885 (uint32 *)value); 45886 PORT_UNLOCK(unit); 45887 break; 45888 case bcmPortControlSerdesTuneMarginValue: 45889 PORT_LOCK(unit); 45890 rv = soc_phyctrl_control_get(unit, port, 45891 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_VALUE, 45892 (uint32 *)value); 45893 PORT_UNLOCK(unit); 45894 break; 45895 case bcmPortControlSerdesTuneMarginMax: 45896 PORT_LOCK(unit); 45897 rv = soc_phyctrl_control_get(unit, port, 45898 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_MAX, 45899 (uint32 *)value); 45900 PORT_UNLOCK(unit); 45901 break; 45902 case bcmPortControlStatOversize: 45903 rv = _bcm_esw_stat_ovr_threshold_get(unit, port, value); 45904 break; 45905 45906 case bcmPortControlStatOversizeIsError: 45907 rv = _bcm_esw_stat_ovr_error_control_get(unit, port, value); 45908 break; 45909 45910 case bcmPortControlEEEEnable: 45911 if (!SOC_PORT_VALID(unit, port)) { 45912 return BCM_E_PORT; 45913 } 45914 45915 PORT_LOCK(unit); 45916 45917 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 45918 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 45919 || defined(BCM_HURRICANE2_SUPPORT) 45920 45921 if (soc_feature(unit, soc_feature_eee)) { 45922 *value = eee_cfg[unit][port]; 45923 rv = BCM_E_NONE; 45924 } else 45925 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPORT || 45926 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 45927 45928 { 45929 uint32 eeenative, eeeauto; 45930 int rv1 = BCM_E_UNAVAIL, rv2 = BCM_E_UNAVAIL; 45931 45932 rv = BCM_E_NONE; 45933 45934 if ((rv1 = soc_phyctrl_control_get(unit, port, 45935 BCM_PORT_PHY_CONTROL_EEE, &eeenative)) != 45936 SOC_E_UNAVAIL) { 45937 *value = eeenative; 45938 } 45939 45940 if ((rv2 = soc_phyctrl_control_get(unit, port, 45941 BCM_PORT_PHY_CONTROL_EEE_AUTO, &eeeauto)) != 45942 SOC_E_UNAVAIL) { 45943 *value = eeeauto; 45944 } 45945 45946 /* If neither Native EEE nor AutoGrEEEn mode is supported */ 45947 if ((rv1 == SOC_E_UNAVAIL) && (rv2 == SOC_E_UNAVAIL)) { 45948 rv = BCM_E_UNAVAIL; 45949 } 45950 45951 /* If both Native EEE and AutoGrEEEn mode are supported */ 45952 if ((rv1 != SOC_E_UNAVAIL) && (rv2 != SOC_E_UNAVAIL)) { 45953 *value = eeenative ? (eeeauto ? 0 : 1) : (eeeauto ? 1 : 0); 45954 } 45955 } 45956 45957 PORT_UNLOCK (unit); 45958 45959 break; 45960 45961 /********************** EEE Mode Overview ************************ 45962 * |DET| | WT | 45963 * Signalling |idles| |------------------------------| | idles | 45964 * from Tx MAC | or | | Low Power Idle (LPI) |idles| or | 45965 * to local PHY |data | |------------------------------| | data | 45966 * * * 45967 * * * 45968 * * -------LPI state------------* 45969 * Local PHY | | | | | | | | | | 45970 * signaling | Active|Ts| Tq |Tr| Tq |Tr| Tq |Tw |Active | 45971 * on MDI | | | | | | | | | | 45972 * *------------------------------* 45973 * * * 45974 * * * 45975 * Signaling | idles |-------------------------------|id| PHY is | 45976 * from LP PHY | or | Low Power Idle (LPI) |le| ready | 45977 * to Rx MAC | data |-------------------------------|s | for data | 45978 * 45979 * where DET = Delay Entry Timer WT = MAC Wake Timer 45980 */ 45981 case bcmPortControlEEETransmitIdleTime: 45982 /* DET = Time (in microsecs) for which condition to move to LPI state 45983 * is satisfied, at the end of which MAC TX transitions to LPI state */ 45984 if (!SOC_PORT_VALID(unit, port)) { 45985 return BCM_E_PORT; 45986 } 45987 45988 PORT_LOCK(unit); 45989 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 45990 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 45991 || defined(BCM_HURRICANE2_SUPPORT) 45992 if (soc_feature (unit, soc_feature_eee)) { 45993 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45994 SOC_MAC_CONTROL_EEE_TX_IDLE_TIME, value); 45995 } else 45996 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 45997 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 45998 { 45999 rv = BCM_E_UNAVAIL; 46000 } 46001 PORT_UNLOCK(unit); 46002 break; 46003 46004 case bcmPortControlEEETransmitEventCount: 46005 /* Number of time MAC TX enters LPI state for 46006 * a given measurement interval*/ 46007 if (!SOC_PORT_VALID(unit, port)) { 46008 return BCM_E_PORT; 46009 } 46010 46011 PORT_LOCK(unit); 46012 46013 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 46014 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 46015 || defined(BCM_HURRICANE2_SUPPORT) 46016 if (soc_feature(unit, soc_feature_eee)) { 46017 int mac_val; 46018 uint32 phy_val; 46019 uint64 rval64, rval64_2nd; 46020 soc_reg_t reg, reg_2nd = INVALIDr; 46021 46022 COMPILER_64_ZERO(rval64); 46023 COMPILER_64_ZERO(rval64_2nd); 46024 46025 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 46026 SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) && 46027 (soc_phyctrl_control_get(unit, port, 46028 BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) { 46029 /* If MAC/Switch is EEE aware (Native EEE mode is supported) 46030 * and PHY also supports Native mode 46031 */ 46032 46033 /* On Katana TX/RX register are swapped */ 46034 reg = (SOC_IS_KATANAX(unit)) ? RX_EEE_LPI_EVENT_COUNTERr : 46035 ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ? 46036 GTX_EEE_LPI_EVENT_COUNTERr : 46037 TX_EEE_LPI_EVENT_COUNTERr); 46038 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) { 46039 if (IS_XL_PORT(unit, port)){ 46040 reg = TX_EEE_LPI_EVENT_COUNTERr; 46041 } else { 46042 reg = GTX_EEE_LPI_EVENT_COUNTERr; 46043 } 46044 } else if (SOC_IS_GREYHOUND2(unit)) { 46045 if (IS_CL_PORT(unit, port)){ 46046 reg = CLMIB_TX_EEE_LPI_EVENT_COUNTERr; 46047 } else if (IS_XL_PORT(unit, port)) { 46048 reg = XLMIB_TX_EEE_LPI_EVENT_COUNTERr; 46049 reg_2nd = XLPMIB_TX_EEE_LPI_EVENT_COUNTERr; 46050 } else { 46051 #if defined(BCM_FIRELIGHT_SUPPORT) 46052 if (soc_feature(unit, soc_feature_fl) && IS_QSGMII_PORT(unit, port)) { 46053 if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) { 46054 reg = GRX_EEE_LPI_EVENT_COUNTERr; 46055 } else { 46056 reg = GTX_EEE_LPI_EVENT_COUNTERr; 46057 } 46058 } else 46059 #endif 46060 { 46061 reg = GTX_EEE_LPI_EVENT_COUNTERr; 46062 } 46063 } 46064 } 46065 46066 #ifdef BCM_HURRICANE4_SUPPORT 46067 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) { 46068 if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) { 46069 reg = GRX_EEE_LPI_EVENT_COUNTERr; 46070 } else { 46071 reg = GTX_EEE_LPI_EVENT_COUNTERr; 46072 } 46073 } 46074 #endif /* BCM_HURRICANE4_SUPPORT */ 46075 46076 rv = soc_reg_get(unit, reg, port, 0, &rval64); 46077 46078 if (BCM_SUCCESS(rv)) { 46079 *value = COMPILER_64_LO(rval64); 46080 } 46081 46082 if (SOC_REG_IS_VALID(unit, reg_2nd)) { 46083 rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd); 46084 46085 if (BCM_SUCCESS(rv)) { 46086 *value += COMPILER_64_LO(rval64_2nd); 46087 } 46088 } 46089 } else { 46090 /* Get counter value from PHY. If PHY does not support 46091 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 46092 */ 46093 rv = soc_phyctrl_control_get(unit, port, 46094 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_EVENTS, &phy_val); 46095 if (SOC_SUCCESS(rv)) { 46096 *value = phy_val; 46097 } 46098 } 46099 } else 46100 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 46101 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 46102 46103 { 46104 /* On legacy devices that don't support native EEE, 46105 * get counter value from PHY. If PHY does not support 46106 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 46107 */ 46108 uint32 phy_val; 46109 rv = soc_phyctrl_control_get(unit, port, 46110 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_EVENTS, &phy_val); 46111 if (SOC_SUCCESS(rv)) { 46112 *value = phy_val; 46113 } 46114 } 46115 46116 PORT_UNLOCK (unit); 46117 46118 break; 46119 46120 case bcmPortControlEEETransmitDuration: 46121 /* Time in (microsecs) for which MAC TX enters LPI state 46122 * during a measurement interval*/ 46123 if (!SOC_PORT_VALID(unit, port)) { 46124 return BCM_E_PORT; 46125 } 46126 46127 PORT_LOCK(unit); 46128 46129 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 46130 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 46131 || defined(BCM_HURRICANE2_SUPPORT) 46132 if (soc_feature(unit, soc_feature_eee)) { 46133 int mac_val; 46134 uint32 phy_val; 46135 uint64 rval64, rval64_2nd; 46136 soc_reg_t reg, reg_2nd = INVALIDr; 46137 46138 COMPILER_64_ZERO(rval64); 46139 COMPILER_64_ZERO(rval64_2nd); 46140 46141 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 46142 SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) && 46143 (soc_phyctrl_control_get(unit, port, 46144 BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) { 46145 /* If MAC/Switch is EEE aware (Native EEE mode is supported) 46146 * and PHY also supports Native mode 46147 */ 46148 /* On Katana TX/RX register are swapped */ 46149 reg = (SOC_IS_KATANAX(unit)) ? RX_EEE_LPI_DURATION_COUNTERr : 46150 ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ? 46151 GTX_EEE_LPI_DURATION_COUNTERr : 46152 TX_EEE_LPI_DURATION_COUNTERr); 46153 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) { 46154 if (IS_XL_PORT(unit, port)) { 46155 reg = TX_EEE_LPI_DURATION_COUNTERr; 46156 } else { 46157 reg = GTX_EEE_LPI_DURATION_COUNTERr; 46158 } 46159 } else if (SOC_IS_GREYHOUND2(unit)) { 46160 if (IS_CL_PORT(unit, port)){ 46161 reg = CLMIB_TX_EEE_LPI_DURATION_COUNTERr; 46162 } else if (IS_XL_PORT(unit, port)) { 46163 reg = XLMIB_TX_EEE_LPI_DURATION_COUNTERr; 46164 reg_2nd = XLPMIB_TX_EEE_LPI_DURATION_COUNTERr; 46165 } else { 46166 #if defined(BCM_FIRELIGHT_SUPPORT) 46167 if (soc_feature(unit, soc_feature_fl) && IS_QSGMII_PORT(unit, port)) { 46168 if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) { 46169 reg = GRX_EEE_LPI_DURATION_COUNTERr; 46170 } else { 46171 reg = GTX_EEE_LPI_DURATION_COUNTERr; 46172 } 46173 } else 46174 #endif 46175 { 46176 reg = GTX_EEE_LPI_DURATION_COUNTERr; 46177 } 46178 } 46179 } 46180 46181 #ifdef BCM_HURRICANE4_SUPPORT 46182 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) { 46183 if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) { 46184 reg = GRX_EEE_LPI_DURATION_COUNTERr; 46185 } else { 46186 reg = GTX_EEE_LPI_DURATION_COUNTERr; 46187 } 46188 } 46189 #endif /* BCM_HURRICANE4_SUPPORT */ 46190 46191 rv = soc_reg_get(unit, reg, port, 0, &rval64); 46192 46193 if (BCM_SUCCESS(rv)) { 46194 *value = COMPILER_64_LO(rval64); 46195 } 46196 46197 if (SOC_REG_IS_VALID(unit, reg_2nd)) { 46198 rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd); 46199 if (BCM_SUCCESS(rv)) { 46200 /* add the 2nd register */ 46201 *value += COMPILER_64_LO(rval64_2nd); 46202 } 46203 } 46204 } else { 46205 /* Get counter value from PHY. If PHY does not support 46206 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 46207 */ 46208 rv = soc_phyctrl_control_get(unit, port, 46209 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_DURATION, &phy_val); 46210 if (SOC_SUCCESS(rv)) { 46211 *value = phy_val; 46212 } 46213 } 46214 } else 46215 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 46216 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 46217 { 46218 /* On legacy devices that don't support native EEE, 46219 * get counter value from PHY. If PHY does not support 46220 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 46221 */ 46222 uint32 phy_val; 46223 rv = soc_phyctrl_control_get(unit, port, 46224 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_DURATION, &phy_val); 46225 if (SOC_SUCCESS(rv)) { 46226 *value = phy_val; 46227 } 46228 } 46229 46230 PORT_UNLOCK (unit); 46231 break; 46232 46233 case bcmPortControlEEEReceiveEventCount: 46234 /* Number of time MAC RX enters LPI state for 46235 * a given measurement interval */ 46236 if (!SOC_PORT_VALID(unit, port)) { 46237 return BCM_E_PORT; 46238 } 46239 46240 PORT_LOCK(unit); 46241 46242 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 46243 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 46244 || defined(BCM_HURRICANE2_SUPPORT) 46245 if (soc_feature(unit, soc_feature_eee)) { 46246 int mac_val; 46247 uint32 phy_val; 46248 uint64 rval64, rval64_2nd; 46249 soc_reg_t reg, reg_2nd = INVALIDr; 46250 46251 COMPILER_64_ZERO(rval64); 46252 COMPILER_64_ZERO(rval64_2nd); 46253 46254 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 46255 SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) && 46256 (soc_phyctrl_control_get(unit, port, 46257 BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) { 46258 /* If MAC/Switch is EEE aware (Native EEE mode is supported) 46259 * and PHY also supports Native mode 46260 */ 46261 /* On Katana TX/RX register are swapped */ 46262 reg = (SOC_IS_KATANAX(unit)) ? TX_EEE_LPI_EVENT_COUNTERr : 46263 ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ? 46264 GRX_EEE_LPI_EVENT_COUNTERr : 46265 RX_EEE_LPI_EVENT_COUNTERr); 46266 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) { 46267 if (IS_XL_PORT(unit, port)) { 46268 reg = RX_EEE_LPI_EVENT_COUNTERr; 46269 } else { 46270 reg = GRX_EEE_LPI_EVENT_COUNTERr; 46271 } 46272 } else if (SOC_IS_GREYHOUND2(unit)) { 46273 if (IS_CL_PORT(unit, port)){ 46274 reg = CLMIB_RX_EEE_LPI_EVENT_COUNTERr; 46275 } else if (IS_XL_PORT(unit, port)) { 46276 reg = XLMIB_RX_EEE_LPI_EVENT_COUNTERr; 46277 reg_2nd = XLPMIB_RX_EEE_LPI_EVENT_COUNTERr; 46278 } else { 46279 #if defined(BCM_FIRELIGHT_SUPPORT) 46280 if (soc_feature(unit, soc_feature_fl) && IS_QSGMII_PORT(unit, port)) { 46281 if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) { 46282 reg = GTX_EEE_LPI_EVENT_COUNTERr; 46283 } else { 46284 reg = GRX_EEE_LPI_EVENT_COUNTERr; 46285 } 46286 } else 46287 #endif 46288 { 46289 reg = GRX_EEE_LPI_EVENT_COUNTERr; 46290 } 46291 } 46292 } 46293 46294 #ifdef BCM_HURRICANE4_SUPPORT 46295 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) { 46296 if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) { 46297 reg = GTX_EEE_LPI_EVENT_COUNTERr; 46298 } else { 46299 reg = GRX_EEE_LPI_EVENT_COUNTERr; 46300 } 46301 } 46302 #endif /* BCM_HURRICANE4_SUPPORT */ 46303 46304 rv = soc_reg_get(unit, reg, port, 0, &rval64); 46305 46306 if (BCM_SUCCESS(rv)) { 46307 *value = COMPILER_64_LO(rval64); 46308 } 46309 46310 if (SOC_REG_IS_VALID(unit, reg_2nd)) { 46311 rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd); 46312 if (BCM_SUCCESS(rv)) { 46313 /* add the 2nd register */ 46314 *value += COMPILER_64_LO(rval64_2nd); 46315 } 46316 } 46317 } else { 46318 /* Get counter value from PHY. If PHY does not support 46319 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 46320 */ 46321 rv = soc_phyctrl_control_get(unit, port, 46322 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_EVENTS, &phy_val); 46323 if (SOC_SUCCESS(rv)) { 46324 *value = phy_val; 46325 } 46326 } 46327 } else 46328 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 46329 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 46330 { 46331 /* On legacy devices that don't support native EEE, 46332 * get counter value from PHY. If PHY does not support 46333 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 46334 */ 46335 uint32 phy_val; 46336 rv = soc_phyctrl_control_get(unit, port, 46337 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_EVENTS, &phy_val); 46338 if (SOC_SUCCESS(rv)) { 46339 *value = phy_val; 46340 } 46341 } 46342 46343 PORT_UNLOCK (unit); 46344 break; 46345 46346 case bcmPortControlEEEReceiveDuration: 46347 /* Time in (microsecs) for which MAC RX enters LPI state 46348 * during a measurement interval*/ 46349 if (!SOC_PORT_VALID(unit, port)) { 46350 return BCM_E_PORT; 46351 } 46352 if (!IS_E_PORT(unit, port)) { 46353 return BCM_E_UNAVAIL; 46354 } 46355 46356 PORT_LOCK(unit); 46357 46358 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 46359 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 46360 if (soc_feature(unit, soc_feature_eee)) { 46361 int mac_val; 46362 uint32 phy_val; 46363 uint64 rval64, rval64_2nd; 46364 soc_reg_t reg, reg_2nd = INVALIDr; 46365 46366 COMPILER_64_ZERO(rval64); 46367 COMPILER_64_ZERO(rval64_2nd); 46368 46369 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 46370 SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) && 46371 (soc_phyctrl_control_get(unit, port, 46372 BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) { 46373 /* If MAC/Switch is EEE aware (Native EEE mode is supported) 46374 * and PHY also supports Native mode 46375 */ 46376 /* On Katana TX/RX register are swapped */ 46377 reg = (SOC_IS_KATANAX(unit)) ? TX_EEE_LPI_DURATION_COUNTERr : 46378 ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ? 46379 GRX_EEE_LPI_DURATION_COUNTERr : 46380 RX_EEE_LPI_DURATION_COUNTERr); 46381 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) { 46382 if (IS_XL_PORT(unit, port)) { 46383 reg = RX_EEE_LPI_DURATION_COUNTERr; 46384 } else { 46385 reg = GRX_EEE_LPI_DURATION_COUNTERr; 46386 } 46387 } else if (SOC_IS_GREYHOUND2(unit)) { 46388 if (IS_CL_PORT(unit, port)){ 46389 reg = CLMIB_RX_EEE_LPI_DURATION_COUNTERr; 46390 } else if (IS_XL_PORT(unit, port)) { 46391 reg = XLMIB_RX_EEE_LPI_DURATION_COUNTERr; 46392 reg_2nd = XLPMIB_RX_EEE_LPI_DURATION_COUNTERr; 46393 } else { 46394 #if defined(BCM_FIRELIGHT_SUPPORT) 46395 if (soc_feature(unit, soc_feature_fl) && IS_QSGMII_PORT(unit, port)) { 46396 if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) { 46397 reg = GTX_EEE_LPI_DURATION_COUNTERr; 46398 } else { 46399 reg = GRX_EEE_LPI_DURATION_COUNTERr; 46400 } 46401 } else 46402 #endif 46403 { 46404 reg = GRX_EEE_LPI_DURATION_COUNTERr; 46405 } 46406 } 46407 } 46408 46409 #ifdef BCM_HURRICANE4_SUPPORT 46410 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) { 46411 if (soc_feature(unit, soc_feature_gport_eee_lpi_tx_rx_swap)) { 46412 reg = GTX_EEE_LPI_DURATION_COUNTERr; 46413 } else { 46414 reg = GRX_EEE_LPI_DURATION_COUNTERr; 46415 } 46416 } 46417 #endif /* BCM_HURRICANE4_SUPPORT */ 46418 46419 rv = soc_reg_get(unit, reg, port, 0, &rval64); 46420 46421 if (BCM_SUCCESS(rv)) { 46422 *value = COMPILER_64_LO(rval64); 46423 } 46424 46425 if (SOC_REG_IS_VALID(unit, reg_2nd)) { 46426 rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd); 46427 if (BCM_SUCCESS(rv)) { 46428 /* add the 2nd register */ 46429 *value += COMPILER_64_LO(rval64_2nd); 46430 } 46431 } 46432 } else { 46433 /* Get counter value from PHY. If PHY does not support 46434 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 46435 */ 46436 rv = soc_phyctrl_control_get(unit, port, 46437 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_DURATION, &phy_val); 46438 if (SOC_SUCCESS(rv)) { 46439 *value = phy_val; 46440 } 46441 } 46442 } else 46443 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 46444 BCM_TRIDENT_SUPPORT */ 46445 { 46446 /* On legacy devices that don't support native EEE, 46447 * get counter value from PHY. If PHY does not support 46448 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 46449 */ 46450 uint32 phy_val; 46451 rv = soc_phyctrl_control_get(unit, port, 46452 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_DURATION, &phy_val); 46453 if (SOC_SUCCESS(rv)) { 46454 *value = phy_val; 46455 } 46456 } 46457 46458 PORT_UNLOCK (unit); 46459 break; 46460 46461 case bcmPortControlEEETransmitRefreshTime: 46462 if (!SOC_PORT_VALID(unit, port)) { 46463 return BCM_E_PORT; 46464 } 46465 if (!IS_E_PORT(unit, port)) { 46466 return BCM_E_UNAVAIL; 46467 } 46468 PORT_LOCK(unit); 46469 rv = soc_phyctrl_control_get(unit, port, 46470 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_REFRESH_TIME, 46471 (uint32 *)value); 46472 PORT_UNLOCK (unit); 46473 break; 46474 46475 case bcmPortControlEEETransmitSleepTime: 46476 if (!SOC_PORT_VALID(unit, port)) { 46477 return BCM_E_PORT; 46478 } 46479 if (!IS_E_PORT(unit, port)) { 46480 return BCM_E_UNAVAIL; 46481 } 46482 PORT_LOCK(unit); 46483 rv = soc_phyctrl_control_get(unit, port, 46484 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_SLEEP_TIME, (uint32 *)value); 46485 PORT_UNLOCK (unit); 46486 break; 46487 46488 case bcmPortControlEEETransmitQuietTime: 46489 if (!SOC_PORT_VALID(unit, port)) { 46490 return BCM_E_PORT; 46491 } 46492 if (!IS_E_PORT(unit, port)) { 46493 return BCM_E_UNAVAIL; 46494 } 46495 PORT_LOCK(unit); 46496 rv = soc_phyctrl_control_get(unit, port, 46497 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_QUIET_TIME, (uint32 *)value); 46498 PORT_UNLOCK (unit); 46499 break; 46500 46501 case bcmPortControlEEETransmitWakeTime: 46502 /* Time(in microsecs) to wait before transmitter can leave LPI State*/ 46503 if (!SOC_PORT_VALID(unit, port)) { 46504 return BCM_E_PORT; 46505 } 46506 if (!IS_E_PORT(unit, port)) { 46507 return BCM_E_UNAVAIL; 46508 } 46509 46510 PORT_LOCK(unit); 46511 46512 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 46513 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 46514 if (soc_feature(unit, soc_feature_eee)) { 46515 int mac_val; 46516 uint32 phy_val; 46517 46518 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 46519 SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) && 46520 (soc_phyctrl_control_get(unit, port, 46521 BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) { 46522 /* If MAC/Switch is EEE aware (Native EEE mode is supported) 46523 * and PHY also supports Native mode 46524 */ 46525 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 46526 SOC_MAC_CONTROL_EEE_TX_WAKE_TIME, value); 46527 46528 } else { 46529 /* Get timer value from PHY. If PHY does not support 46530 * EEE timers, rv will be assigned SOC_E_UNAVAIL. 46531 */ 46532 rv = soc_phyctrl_control_get(unit, port, 46533 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_WAKE_TIME, &phy_val); 46534 if (SOC_SUCCESS(rv)) { 46535 *value = phy_val; 46536 } 46537 } 46538 } else 46539 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 46540 BCM_TRIDENT_SUPPORT */ 46541 { 46542 /* On legacy devices that don't support native EEE, 46543 * get timer value from PHY. If PHY does not support 46544 * EEE timers, rv will be assigned SOC_E_UNAVAIL. 46545 */ 46546 uint32 phy_val; 46547 rv = soc_phyctrl_control_get(unit, port, 46548 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_WAKE_TIME, &phy_val); 46549 if (SOC_SUCCESS(rv)) { 46550 *value = phy_val; 46551 } 46552 } 46553 46554 PORT_UNLOCK (unit); 46555 break; 46556 46557 case bcmPortControlEEEReceiveSleepTime: 46558 if (!SOC_PORT_VALID(unit, port)) { 46559 return BCM_E_PORT; 46560 } 46561 if (!IS_E_PORT(unit, port)) { 46562 return BCM_E_UNAVAIL; 46563 } 46564 PORT_LOCK(unit); 46565 rv = soc_phyctrl_control_get(unit, port, 46566 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_SLEEP_TIME, (uint32 *)value); 46567 PORT_UNLOCK (unit); 46568 break; 46569 46570 case bcmPortControlEEEReceiveQuietTime: 46571 if (!SOC_PORT_VALID(unit, port)) { 46572 return BCM_E_PORT; 46573 } 46574 if (!IS_E_PORT(unit, port)) { 46575 return BCM_E_UNAVAIL; 46576 } 46577 PORT_LOCK(unit); 46578 rv = soc_phyctrl_control_get(unit, port, 46579 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_QUIET_TIME, (uint32 *)value); 46580 PORT_UNLOCK (unit); 46581 break; 46582 46583 case bcmPortControlEEEReceiveWakeTime: 46584 if (!SOC_PORT_VALID(unit, port)) { 46585 return BCM_E_PORT; 46586 } 46587 if (!IS_E_PORT(unit, port)) { 46588 return BCM_E_UNAVAIL; 46589 } 46590 PORT_LOCK(unit); 46591 rv = soc_phyctrl_control_get(unit, port, 46592 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_WAKE_TIME, (uint32 *)value); 46593 PORT_UNLOCK (unit); 46594 break; 46595 46596 case bcmPortControlEEEEventCountSymmetric: 46597 if (!SOC_PORT_VALID(unit, port)) { 46598 return BCM_E_PORT; 46599 } 46600 if (!IS_E_PORT(unit, port)) { 46601 return BCM_E_UNAVAIL; 46602 } 46603 #if defined(BCM_HURRICANE2_SUPPORT) 46604 if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || 46605 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 46606 uint32 reg_value; 46607 soc_reg_t reg; 46608 if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) { 46609 reg = IS_XL_PORT(unit, port) ? XLPORT_EEE_COUNTER_MODEr : 46610 CLPORT_EEE_COUNTER_MODEr; 46611 46612 if (SOC_REG_FIELD_VALID(unit, reg, MODE_BITf)) { 46613 rv = soc_reg32_get(unit, reg, port, 0, ®_value); 46614 if (SOC_SUCCESS(rv)) { 46615 *value = soc_reg_field_get(unit, reg, 46616 reg_value, MODE_BITf); 46617 } 46618 } else { 46619 return BCM_E_INTERNAL; 46620 } 46621 } else { 46622 return BCM_E_PORT; 46623 } 46624 } else 46625 #endif 46626 { 46627 #if defined(BCM_TRIUMPH3_SUPPORT) 46628 if (SOC_REG_FIELD_VALID(unit, PORT_EEE_COUNTER_MODEr, MODE_BITf)) { 46629 uint32 reg_value; 46630 46631 rv = READ_PORT_EEE_COUNTER_MODEr(unit, port, ®_value); 46632 46633 if (SOC_SUCCESS(rv)) { 46634 *value = soc_reg_field_get(unit, PORT_EEE_COUNTER_MODEr, 46635 reg_value, MODE_BITf); 46636 } 46637 } 46638 #endif 46639 } 46640 break; 46641 46642 case bcmPortControlEEELinkActiveDuration: 46643 if (!SOC_PORT_VALID(unit, port)) { 46644 return BCM_E_PORT; 46645 } 46646 if (!IS_E_PORT(unit, port)) { 46647 return BCM_E_UNAVAIL; 46648 } 46649 #if defined(BCM_HURRICANE2_SUPPORT) 46650 if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || 46651 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 46652 soc_reg_t reg; 46653 46654 if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) { 46655 46656 reg = IS_XL_PORT(unit, port) ? 46657 XLMAC_EEE_1_SEC_LINK_STATUS_TIMERr : 46658 CLMAC_EEE_1_SEC_LINK_STATUS_TIMERr; 46659 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) { 46660 uint64 reg_value; 46661 46662 rv = soc_reg_get(unit, reg, port, 0, ®_value); 46663 if (SOC_SUCCESS(rv)) { 46664 *value = soc_reg64_field32_get(unit, 46665 reg, reg_value, 46666 ONE_SECOND_TIMERf); 46667 } 46668 } 46669 } else { 46670 return BCM_E_PORT; 46671 } 46672 } else 46673 #endif 46674 { 46675 #if defined(BCM_TRIUMPH3_SUPPORT) 46676 { 46677 soc_reg_t reg; 46678 46679 reg = IS_C_PORT(unit, port) ? 46680 CMAC_EEE_1_SEC_LINK_STATUS_TIMERr : 46681 XMAC_EEE_1_SEC_LINK_STATUS_TIMERr; 46682 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) { 46683 uint64 reg_value; 46684 46685 rv = soc_reg_get(unit, reg, port, 0, ®_value); 46686 if (SOC_SUCCESS(rv)) { 46687 *value = soc_reg64_field32_get(unit, reg, reg_value, 46688 ONE_SECOND_TIMERf); 46689 } 46690 } 46691 } 46692 #endif 46693 } 46694 break; 46695 46696 case bcmPortControlRemoteCpuTcMapping: 46697 if (soc_feature(unit, soc_feature_rcpu_tc_mapping)) { 46698 rv = _bcm_esw_port_tab_get(unit, port, REMOTE_CPU_ENf, value); 46699 } else { 46700 rv = BCM_E_UNAVAIL; 46701 } 46702 break; 46703 46704 case bcmPortControlTrill: 46705 #if defined(BCM_TRIDENT_SUPPORT) 46706 if (soc_feature(unit, soc_feature_trill)) { 46707 rv = _bcm_esw_port_tab_get(unit, port, TRILL_ENABLEf, value); 46708 } 46709 #endif /* BCM_TRIDENT_SUPPORT */ 46710 break; 46711 46712 case bcmPortControlTrillAllow: 46713 #if defined(BCM_TRIDENT_SUPPORT) 46714 if (soc_feature(unit, soc_feature_trill)) { 46715 rv = _bcm_esw_port_tab_get(unit, port, 46716 ALLOW_TRILL_FRAMESf, value); 46717 } 46718 #endif /* BCM_TRIDENT_SUPPORT */ 46719 break; 46720 46721 case bcmPortControlNonTrillAllow: 46722 #if defined(BCM_TRIDENT_SUPPORT) 46723 if (soc_feature(unit, soc_feature_trill)) { 46724 rv = _bcm_esw_port_tab_get(unit, port, 46725 ALLOW_NON_TRILL_FRAMESf, value); 46726 } 46727 #endif /* BCM_TRIDENT_SUPPORT */ 46728 break; 46729 46730 case bcmPortControlTrillCoreISISToCPU: 46731 #if defined(BCM_TRIDENT_SUPPORT) 46732 if (soc_feature(unit, soc_feature_trill)) { 46733 rv = _bcm_esw_port_tab_get(unit, port, 46734 COPY_CORE_IS_IS_TO_CPUf, value); 46735 } 46736 #endif /* BCM_TRIDENT_SUPPORT */ 46737 break; 46738 46739 case bcmPortControlTrillHashSelect: 46740 #if defined(BCM_TRIDENT_SUPPORT) 46741 if (soc_feature(unit, soc_feature_trill)) { 46742 rv = _bcm_esw_port_tab_get(unit, port, 46743 RTAG7_HASH_CFG_SEL_TRILL_ECMPf, value); 46744 } 46745 #endif /* BCM_TRIDENT_SUPPORT */ 46746 break; 46747 46748 case bcmPortControlNivAccessVirtualInterfaceId: 46749 case bcmPortControlExtendedPortVid: 46750 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 46751 if (soc_feature(unit, soc_feature_niv) || 46752 soc_feature(unit, soc_feature_port_extension)) { 46753 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 46754 SOC_IS_GREYHOUND2(unit)) { 46755 uint64 val64; 46756 rv = READ_EGR_PORT_64r(unit, port, &val64); 46757 if (BCM_SUCCESS(rv)) { 46758 *value = soc_reg64_field32_get(unit, EGR_PORT_64r, 46759 val64, NIV_VIF_IDf); 46760 } 46761 } else { 46762 rv = _bcm_esw_port_tab_get(unit, port, NIV_VIF_IDf, value); 46763 } 46764 } 46765 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 46766 break; 46767 46768 case bcmPortControlNivNonVntagDrop: 46769 case bcmPortControlNonEtagDrop: 46770 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 46771 if (soc_feature(unit, soc_feature_niv) || 46772 soc_feature(unit, soc_feature_port_extension)) { 46773 rv = _bcm_esw_port_tab_get(unit, port, 46774 DISCARD_IF_VNTAG_NOT_PRESENTf, value); 46775 } 46776 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 46777 break; 46778 46779 case bcmPortControlNivVntagDrop: 46780 case bcmPortControlEtagDrop: 46781 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 46782 if (soc_feature(unit, soc_feature_niv) || 46783 soc_feature(unit, soc_feature_port_extension)) { 46784 rv = _bcm_esw_port_tab_get(unit, port, 46785 DISCARD_IF_VNTAG_PRESENTf, value); 46786 } 46787 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 46788 break; 46789 46790 case bcmPortControlSubportPktTagDrop: 46791 #if defined(BCM_KATANA2_SUPPORT) 46792 if (soc_feature(unit, soc_feature_lltag)) { 46793 rv = _bcm_esw_port_tab_get(unit, port, 46794 DISCARD_IF_LLTAG_PRESENTf, value); 46795 } 46796 #endif /* BCM_KATANA2_SUPPORT */ 46797 break; 46798 46799 case bcmPortControlNoSubportPktTagDrop: 46800 #if defined(BCM_KATANA2_SUPPORT) 46801 if (soc_feature(unit, soc_feature_lltag)) { 46802 rv = _bcm_esw_port_tab_get(unit, port, 46803 DISCARD_IF_LLTAG_NOT_PRESENTf, value); 46804 } 46805 #endif /* BCM_KATANA2_SUPPORT */ 46806 break; 46807 46808 case bcmPortControlNivNonVntagAdd: 46809 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 46810 if (soc_feature(unit, soc_feature_niv)) { 46811 int vntag_action; 46812 rv = _bcm_esw_port_tab_get(unit, port, 46813 VNTAG_ACTIONS_IF_NOT_PRESENTf, 46814 &vntag_action); 46815 if (BCM_SUCCESS(rv)) { 46816 *value = (vntag_action == VNTAG_ADD) ? TRUE : FALSE; 46817 } 46818 } 46819 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 46820 break; 46821 46822 case bcmPortControlNonEtagAdd: 46823 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 46824 if (soc_feature(unit, soc_feature_port_extension)) { 46825 int etag_action; 46826 rv = _bcm_esw_port_tab_get(unit, port, 46827 VNTAG_ACTIONS_IF_NOT_PRESENTf, 46828 &etag_action); 46829 if (BCM_SUCCESS(rv)) { 46830 *value = (etag_action == 2) ? TRUE : FALSE; 46831 } 46832 } 46833 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */ 46834 break; 46835 46836 case bcmPortControlNivVntagIngressReplace: 46837 case bcmPortControlEtagIngressReplace: 46838 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 46839 if (soc_feature(unit, soc_feature_niv) || 46840 soc_feature(unit, soc_feature_port_extension)) { 46841 int vntag_action; 46842 rv = _bcm_esw_port_tab_get(unit, port, 46843 VNTAG_ACTIONS_IF_PRESENTf, 46844 &vntag_action); 46845 if (BCM_SUCCESS(rv)) { 46846 *value = (vntag_action == VNTAG_REPLACE) ? TRUE : FALSE; 46847 } 46848 } 46849 #endif /* BCM_TRIDENT_SUPPORT ||BCM_GREYHOUND_SUPPORT */ 46850 break; 46851 46852 case bcmPortControlNivVntagEgressReplace: 46853 case bcmPortControlEtagEgressReplace: 46854 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 46855 if (soc_feature(unit, soc_feature_niv) || 46856 soc_feature(unit, soc_feature_port_extension)) { 46857 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 46858 SOC_IS_GREYHOUND2(unit)) { 46859 uint64 val64; 46860 int vntag_action; 46861 46862 if (type == bcmPortControlEtagEgressReplace) { 46863 return BCM_E_UNAVAIL; 46864 } 46865 46866 rv = READ_EGR_PORT_64r(unit, port, &val64); 46867 if (BCM_SUCCESS(rv)) { 46868 vntag_action = soc_reg64_field32_get(unit, EGR_PORT_64r, 46869 val64, VNTAG_ACTIONS_IF_PRESENTf); 46870 *value = (vntag_action == VNTAG_REPLACE) ? TRUE : FALSE; 46871 } 46872 } else { 46873 int vntag_action; 46874 rv = _bcm_esw_egr_port_tab_get(unit, port, 46875 VNTAG_ACTIONS_IF_PRESENTf, 46876 &vntag_action); 46877 if (BCM_SUCCESS(rv)) { 46878 *value = (vntag_action == VNTAG_REPLACE) ? TRUE : FALSE; 46879 } 46880 } 46881 } 46882 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 46883 break; 46884 46885 case bcmPortControlNivVntagIngressDelete: 46886 case bcmPortControlEtagIngressDelete: 46887 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 46888 if (soc_feature(unit, soc_feature_niv) || 46889 soc_feature(unit, soc_feature_port_extension)) { 46890 int vntag_action; 46891 rv = _bcm_esw_port_tab_get(unit, port, 46892 VNTAG_ACTIONS_IF_PRESENTf, 46893 &vntag_action); 46894 if (BCM_SUCCESS(rv)) { 46895 *value = (vntag_action == VNTAG_DELETE) ? TRUE : FALSE; 46896 } 46897 } 46898 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 46899 break; 46900 46901 case bcmPortControlNivVntagEgressDelete: 46902 case bcmPortControlEtagEgressDelete: 46903 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 46904 if (soc_feature(unit, soc_feature_niv) || 46905 soc_feature(unit, soc_feature_port_extension)) { 46906 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 46907 SOC_IS_GREYHOUND2(unit)) { 46908 uint64 val64; 46909 int vntag_action; 46910 rv = READ_EGR_PORT_64r(unit, port, &val64); 46911 if (BCM_SUCCESS(rv)) { 46912 vntag_action = soc_reg64_field32_get(unit, EGR_PORT_64r, 46913 val64, VNTAG_ACTIONS_IF_PRESENTf); 46914 *value = (vntag_action == VNTAG_DELETE) ? TRUE : FALSE; 46915 } 46916 } else { 46917 int vntag_action; 46918 rv = _bcm_esw_egr_port_tab_get(unit, port, 46919 VNTAG_ACTIONS_IF_PRESENTf, 46920 &vntag_action); 46921 if (BCM_SUCCESS(rv)) { 46922 *value = (vntag_action == VNTAG_DELETE) ? TRUE : FALSE; 46923 } 46924 } 46925 } 46926 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 46927 break; 46928 46929 case bcmPortControlNivRpfCheck: 46930 case bcmPortControlExtenderRpfCheck: 46931 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 46932 if (soc_feature(unit, soc_feature_niv) || 46933 soc_feature(unit, soc_feature_port_extension)) { 46934 rv = _bcm_esw_port_tab_get(unit, port, 46935 NIV_RPF_CHECK_ENABLEf, value); 46936 } 46937 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 46938 break; 46939 46940 case bcmPortControlNivSourceKnockout: 46941 case bcmPortControlExtenderSourceKnockout: 46942 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 46943 if (soc_feature(unit, soc_feature_niv) || 46944 soc_feature(unit, soc_feature_port_extension)) { 46945 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 46946 SOC_IS_GREYHOUND2(unit)) { 46947 uint64 val64; 46948 rv = READ_EGR_PORT_64r(unit, port, &val64); 46949 if (BCM_SUCCESS(rv)) { 46950 *value = soc_reg64_field32_get(unit, EGR_PORT_64r, 46951 val64, NIV_PRUNE_ENABLEf); 46952 } 46953 } else { 46954 rv = _bcm_esw_egr_port_tab_get(unit, port, 46955 NIV_PRUNE_ENABLEf, value); 46956 } 46957 } 46958 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 46959 break; 46960 46961 case bcmPortControlNivForwardPort: 46962 case bcmPortControlExtenderForwardPort: 46963 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 46964 if (soc_feature(unit, soc_feature_niv) || 46965 soc_feature(unit, soc_feature_port_extension)) { 46966 int is_niv_uplink; 46967 int tx_dest_port; 46968 _bcm_gport_dest_t dest; 46969 46970 BCM_IF_ERROR_RETURN 46971 (_bcm_esw_port_tab_get(unit, port, 46972 NIV_UPLINK_PORTf, &is_niv_uplink)); 46973 if (is_niv_uplink) { 46974 *value = -1; 46975 } else { 46976 if (soc_feature(unit, soc_feature_generic_dest)) { 46977 uint32 dt, dval; 46978 BCM_IF_ERROR_RETURN 46979 (_bcm_esw_port_tab_get(unit, port, DESTINATIONf, 46980 &tx_dest_port)); 46981 _soc_mem_dest_value_resolve(unit, tx_dest_port, &dt, &dval); 46982 if (dt == SOC_MEM_FIF_DEST_LAG) { 46983 dest.tgid = dval; 46984 dest.gport_type = _SHR_GPORT_TYPE_TRUNK; 46985 } else { 46986 dest.port = dval & SOC_MEM_FIF_DGPP_PORT_MASK; 46987 dest.modid = (dval & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 46988 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 46989 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 46990 } 46991 } else { 46992 BCM_IF_ERROR_RETURN 46993 (_bcm_esw_port_tab_get(unit, port, 46994 TX_DEST_PORTf, &tx_dest_port)); 46995 if ((tx_dest_port >> SOC_TRUNK_BIT_POS(unit)) & 0x1) { 46996 dest.tgid = tx_dest_port - (1 << SOC_TRUNK_BIT_POS(unit)); 46997 dest.gport_type = _SHR_GPORT_TYPE_TRUNK; 46998 } else { 46999 #if defined(BCM_METROLITE_SUPPORT) 47000 /* Metrolite DGLP still uses 7 bits for port like saber 2 */ 47001 if (SOC_IS_METROLITE(unit)) { 47002 dest.port = tx_dest_port & 0x7f; 47003 dest.modid =( tx_dest_port & 0xff10) >> 7; 47004 } else 47005 #endif 47006 { 47007 dest.port = tx_dest_port & SOC_PORT_ADDR_MAX(unit); 47008 dest.modid = (tx_dest_port - dest.port) / 47009 (SOC_PORT_ADDR_MAX(unit) + 1); 47010 } 47011 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 47012 } 47013 } 47014 BCM_IF_ERROR_RETURN 47015 (_bcm_esw_gport_construct(unit, &dest, value)); 47016 } 47017 rv = BCM_E_NONE; 47018 } 47019 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 47020 break; 47021 47022 case bcmPortControlNivType: 47023 if (soc_feature(unit, soc_feature_niv)) { 47024 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 47025 SOC_IS_GREYHOUND2(unit)) { 47026 #if defined(BCM_GREYHOUND_SUPPORT) 47027 rv = bcm_gh_port_niv_type_get(unit, port, value); 47028 #endif /* BCM_GREYHOUND_SUPPORT */ 47029 } else { 47030 #if defined(BCM_TRIDENT_SUPPORT) 47031 rv = bcm_td_port_niv_type_get(unit, port, value); 47032 #endif /* BCM_TRIDENT_SUPPORT */ 47033 } 47034 } 47035 break; 47036 47037 case bcmPortControlExtenderType: 47038 if (soc_feature(unit, soc_feature_port_extension)) { 47039 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 47040 SOC_IS_GREYHOUND2(unit)) { 47041 #if defined(BCM_GREYHOUND_SUPPORT) 47042 rv = bcm_gh_port_extender_type_get(unit, port, value); 47043 #endif /* BCM_GREYHOUND_SUPPORT */ 47044 } else { 47045 #if defined(BCM_TRIUMPH3_SUPPORT) 47046 rv = bcm_tr3_port_extender_type_get(unit, port, value); 47047 #endif /* BCM_TRIUMPH3_SUPPORT */ 47048 } 47049 } 47050 break; 47051 47052 case bcmPortControlNivNameSpace: 47053 case bcmPortControlExtenderNameSpace: 47054 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 47055 if (soc_feature(unit, soc_feature_niv) || 47056 soc_feature(unit, soc_feature_port_extension)) { 47057 rv = _bcm_esw_port_tab_get(unit, port, NIV_NAMESPACEf, value); 47058 } 47059 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 47060 break; 47061 47062 case bcmPortControlEtagPcpDeSelect: 47063 #if defined(INCLUDE_L3) 47064 if (soc_feature(unit, soc_feature_port_extension)) { 47065 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 47066 SOC_IS_GREYHOUND2(unit)) { 47067 #if defined(BCM_GREYHOUND_SUPPORT) 47068 rv = bcm_gh_port_etag_pcp_de_source_get(unit, port, value); 47069 #endif /* BCM_GREYHOUND_SUPPORT */ 47070 } else { 47071 #if defined(BCM_TRIUMPH3_SUPPORT) 47072 rv = bcm_tr3_port_etag_pcp_de_source_get(unit, port, value); 47073 #endif /* BCM_TRIUMPH3_SUPPORT */ 47074 } 47075 } 47076 #endif /* INCLUDE_L3 */ 47077 break; 47078 47079 case bcmPortControlEtagPcp: 47080 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 47081 if (soc_feature(unit, soc_feature_port_extension)) { 47082 rv = _bcm_esw_port_tab_get(unit, port, ETAG_PCPf, value); 47083 } 47084 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */ 47085 break; 47086 47087 case bcmPortControlEtagDe: 47088 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 47089 if (soc_feature(unit, soc_feature_port_extension)) { 47090 rv = _bcm_esw_port_tab_get(unit, port, ETAG_DEf, value); 47091 } 47092 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */ 47093 break; 47094 47095 case bcmPortControlUseEtagPri: 47096 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 47097 if (soc_feature(unit, soc_feature_port_extension)) { 47098 rv = _bcm_esw_port_tab_get(unit, port, PHB_FROM_ETAGf, value); 47099 } 47100 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */ 47101 break; 47102 47103 case bcmPortControlUseSubportPktTagPri: 47104 #if defined(BCM_KATANA2_SUPPORT) 47105 if (soc_feature(unit, soc_feature_lltag)) { 47106 rv = _bcm_esw_port_tab_get(unit, port, PHB_FROM_LLTAGf, value); 47107 } 47108 #endif /* BCM_KATANA2_SUPPORT */ 47109 break; 47110 47111 case bcmPortControlProhibitedDot1p: 47112 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 47113 rv = _bcm_esw_port_tab_get(unit, port, PROHIBITED_DOT1Pf, value); 47114 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 47115 break; 47116 47117 case bcmPortControlFabricSourceKnockout: 47118 rv = _bcm_esw_port_tab_get(unit, port, REMOVE_HG_HDR_SRC_PORTf, 47119 value); 47120 break; 47121 47122 case bcmPortControlPrbsPolynomial: 47123 rv = soc_phyctrl_control_get(unit, port, 47124 SOC_PHY_CONTROL_PRBS_POLYNOMIAL, 47125 (uint32 *)value); 47126 break; 47127 case bcmPortControlPrbsTxEnable: 47128 rv = soc_phyctrl_control_get(unit, port, 47129 SOC_PHY_CONTROL_PRBS_TX_ENABLE, 47130 (uint32 *)value); 47131 break; 47132 47133 case bcmPortControlPrbsRxEnable: 47134 rv = soc_phyctrl_control_get(unit, port, 47135 SOC_PHY_CONTROL_PRBS_RX_ENABLE, 47136 (uint32 *)value); 47137 break; 47138 47139 case bcmPortControlPrbsTxInvertData: 47140 rv = soc_phyctrl_control_get(unit, port, 47141 SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA, 47142 (uint32 *)value); 47143 break; 47144 47145 case bcmPortControlRxEnable: 47146 rv = _bcm_esw_mac_rx_control(unit, port, 1, value); 47147 break; 47148 case bcmPortControlTxEnable: 47149 if (SOC_REG_IS_VALID(unit, COSMASKr) || 47150 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 47151 /* Trident2plus/Trident2 uses soc_td2_port_traffic_egr_enable_set */ 47152 SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TRIDENT2(unit) || 47153 #endif 47154 #ifdef BCM_APACHE_SUPPORT 47155 SOC_IS_APACHE(unit) || 47156 #endif 47157 #ifdef BCM_TRIDENT3_SUPPORT 47158 SOC_IS_TRIDENT3X(unit) || 47159 #endif 47160 #ifdef BCM_TOMAHAWK_SUPPORT 47161 SOC_IS_TOMAHAWKX(unit) || 47162 #endif 47163 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) 47164 (SOC_IS_HELIX4(unit) || SOC_IS_TRIUMPH3(unit)) || 47165 #endif 47166 (SOC_REG_IS_VALID(unit, EGRMETERINGCONFIGr) && 47167 SOC_REG_IS_VALID(unit, EGRMETERINGBUCKETr))) { 47168 *value = 1; 47169 if (PORT(unit, port).flags & _PORT_INFO_STOP_TX) { 47170 *value = 0; 47171 } 47172 rv = SOC_E_NONE; 47173 } 47174 break; 47175 47176 case bcmPortControlL2GreEnable: 47177 #if defined(BCM_TRIUMPH3_SUPPORT) 47178 if (soc_feature(unit, soc_feature_l2gre) 47179 #if defined(BCM_TRIDENT3_SUPPORT) 47180 || soc_feature(unit, soc_feature_flex_flow) 47181 #endif 47182 ) { 47183 rv = _bcm_esw_port_tab_get(unit, port, 47184 L2GRE_TERMINATION_ALLOWEDf, value); 47185 } 47186 #endif /* BCM_TRIUMPH3_SUPPORT */ 47187 break; 47188 47189 case bcmPortControlL2GreTunnelbasedVpnId: 47190 #if defined(BCM_TRIUMPH3_SUPPORT) 47191 if (soc_feature(unit, soc_feature_l2gre) 47192 #if defined(BCM_TRIDENT3_SUPPORT) 47193 || soc_feature(unit, soc_feature_flex_flow) 47194 #endif 47195 ) { 47196 rv = _bcm_esw_port_tab_get(unit, port, 47197 L2GRE_VPNID_LOOKUP_KEY_TYPEf, value); 47198 } 47199 #endif /* BCM_TRIUMPH3_SUPPORT */ 47200 break; 47201 47202 case bcmPortControlL2GreDefaultTunnelEnable: 47203 #if defined(BCM_TRIUMPH3_SUPPORT) 47204 if (soc_feature(unit, soc_feature_l2gre) 47205 #if defined(BCM_TRIDENT3_SUPPORT) 47206 || soc_feature(unit, soc_feature_flex_flow) 47207 #endif 47208 ) { 47209 rv = _bcm_esw_port_tab_get(unit, port, 47210 L2GRE_DEFAULT_SVP_ENABLEf, value); 47211 } 47212 #endif /* BCM_TRIUMPH3_SUPPORT */ 47213 47214 break; 47215 47216 case bcmPortControlVxlanEnable: 47217 #if defined(BCM_TRIDENT2_SUPPORT) 47218 if ((soc_feature(unit, soc_feature_vxlan)) || 47219 (soc_feature(unit, soc_feature_flex_flow))) { 47220 rv = _bcm_esw_port_tab_get(unit, port, 47221 VXLAN_TERMINATION_ALLOWEDf, value); 47222 } 47223 #endif /* BCM_TRIDENT2_SUPPORT */ 47224 break; 47225 47226 case bcmPortControlVxlanTunnelbasedVnId: 47227 #if defined(BCM_TRIDENT2_SUPPORT) 47228 if ((soc_feature(unit, soc_feature_vxlan)) || 47229 (soc_feature(unit, soc_feature_flex_flow))) { 47230 rv = _bcm_esw_port_tab_get(unit, port, 47231 VXLAN_VN_ID_LOOKUP_KEY_TYPEf, value); 47232 } 47233 #endif /* BCM_TRIDENT2_SUPPORT */ 47234 break; 47235 case bcmPortControlVxlanVpnAssignmentCriteria: 47236 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 47237 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 47238 rv = _bcm_esw_port_tab_get(unit, port, 47239 VXLAN_VN_ID_LOOKUP_KEY_TYPEf, value); 47240 } 47241 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 47242 break; 47243 case bcmPortControlVxlanTerminationMatchCriteria: 47244 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 47245 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 47246 rv = _bcm_esw_port_tab_get(unit, port, 47247 VXLAN_TERMINATION_LOOKUP_TYPEf, value); 47248 } 47249 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 47250 break; 47251 case bcmPortControlVxlanGportAssignmentCriteria: 47252 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 47253 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 47254 rv = _bcm_esw_port_tab_get(unit, port, 47255 VXLAN_SVP_ASSIGNMENT_KEY_TYPEf, value); 47256 } 47257 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 47258 break; 47259 case bcmPortControlVxlanDefaultTunnelEnable: 47260 #if defined(BCM_TRIDENT2_SUPPORT) 47261 if ((soc_feature(unit, soc_feature_vxlan)) || 47262 (soc_feature(unit, soc_feature_flex_flow))) { 47263 rv = _bcm_esw_port_tab_get(unit, port, 47264 VXLAN_DEFAULT_SVP_ENABLEf, value); 47265 } 47266 #endif /* BCM_TRIDENT2_SUPPORT */ 47267 break; 47268 47269 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX) 47270 case bcmPortControlRegex: 47271 rv = _bcm_esw_port_regex_control_get(unit, port, &udp, &tcp, &enable); 47272 if (enable != 0) { 47273 *value = 1; 47274 } else { 47275 *value = 0; 47276 } 47277 break; 47278 case bcmPortControlRegexTcp: 47279 rv = _bcm_esw_port_regex_control_get(unit, port, &udp, &tcp, &enable); 47280 if (tcp != 0) { 47281 *value = 1; 47282 } else { 47283 *value = 0; 47284 } 47285 break; 47286 case bcmPortControlRegexUdp: 47287 rv = _bcm_esw_port_regex_control_get(unit, port, &udp, &tcp, &enable); 47288 if (udp != 0) { 47289 *value = 1; 47290 } else { 47291 *value = 0; 47292 } 47293 break; 47294 #endif 47295 47296 case bcmPortControlMplsEntropyHashSet: 47297 #if defined(BCM_KATANA2_SUPPORT) 47298 if (SOC_IS_KATANA2(unit)) { 47299 return BCM_E_UNAVAIL; 47300 } else 47301 #endif /* BCM_KATANA2_SUPPORT */ 47302 { 47303 #if defined(BCM_KATANA_SUPPORT) 47304 if (soc_feature(unit, soc_feature_mpls)) { 47305 rv = _bcm_esw_port_tab_get(unit, port, 47306 RTAG7_HASH_CFG_SEL_ENTROPY_LABELf, 47307 value); 47308 } 47309 #endif /* BCM_KATANA_SUPPORT */ 47310 } 47311 break; 47312 47313 #ifdef BCM_SHADOW_SUPPORT 47314 case bcmPortControlManagementPacketIp6Reserved: 47315 if (!SOC_IS_SHADOW(unit)) { 47316 return BCM_E_UNAVAIL; 47317 } 47318 PORT_LOCK(unit); 47319 rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val); 47320 if (BCM_SUCCESS(rv)) { 47321 *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr, 47322 val, IPV6_RESVf); 47323 } 47324 PORT_UNLOCK(unit); 47325 break; 47326 case bcmPortControlManagementPacketIp4Reserved: 47327 if (!SOC_IS_SHADOW(unit)) { 47328 return BCM_E_UNAVAIL; 47329 } 47330 PORT_LOCK(unit); 47331 rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val); 47332 if (BCM_SUCCESS(rv)) { 47333 *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr, 47334 val, IPV4_RESVf); 47335 } 47336 PORT_UNLOCK(unit); 47337 break; 47338 case bcmPortControlManagementPacketLinkConstrained: 47339 if (!SOC_IS_SHADOW(unit)) { 47340 return BCM_E_UNAVAIL; 47341 } 47342 PORT_LOCK(unit); 47343 rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val); 47344 if (BCM_SUCCESS(rv)) { 47345 *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr, 47346 val, LINK_CONSTf); 47347 } 47348 PORT_UNLOCK(unit); 47349 break; 47350 case bcmPortControlManagementPacketGarp: 47351 if (!SOC_IS_SHADOW(unit)) { 47352 return BCM_E_UNAVAIL; 47353 } 47354 PORT_LOCK(unit); 47355 rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val); 47356 if (BCM_SUCCESS(rv)) { 47357 *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr, 47358 val, DOT1D_GARPf); 47359 } 47360 PORT_UNLOCK(unit); 47361 break; 47362 case bcmPortControlManagementPacketCos: 47363 if (!SOC_IS_SHADOW(unit)) { 47364 return BCM_E_UNAVAIL; 47365 } 47366 PORT_LOCK(unit); 47367 rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val); 47368 if (BCM_SUCCESS(rv)) { 47369 *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr, 47370 val, MGMT_FRAME_COSf); 47371 } 47372 PORT_UNLOCK(unit); 47373 break; 47374 case bcmPortControlManagementPacketColor: 47375 rv = BCM_E_UNAVAIL; 47376 break; 47377 case bcmPortControlTaggedL3PacketPktPri: 47378 if (!SOC_IS_SHADOW(unit)) { 47379 return BCM_E_UNAVAIL; 47380 } 47381 PORT_LOCK(unit); 47382 rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val); 47383 if (BCM_SUCCESS(rv)) { 47384 *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr, 47385 val, SELECT5f); 47386 switch (*value) { 47387 case 0: 47388 *value = BCM_PORT_COS_REMAP_DSCP; 47389 break; 47390 case 1: 47391 *value = BCM_PORT_COS_REMAP_EXP; 47392 break; 47393 case 2: 47394 *value = BCM_PORT_COS_REMAP_VLAN_PRI; 47395 break; 47396 default: 47397 *value = BCM_PORT_COS_REMAP_VLAN_PRI; 47398 } 47399 } 47400 PORT_UNLOCK(unit); 47401 break; 47402 case bcmPortControlTaggedMPLSPacketPktPri: 47403 if (!SOC_IS_SHADOW(unit)) { 47404 return BCM_E_UNAVAIL; 47405 } 47406 PORT_LOCK(unit); 47407 rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val); 47408 if (BCM_SUCCESS(rv)) { 47409 *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr, 47410 val, SELECT3f); 47411 switch (*value) { 47412 case 0: 47413 *value = BCM_PORT_COS_REMAP_DSCP; 47414 break; 47415 case 1: 47416 *value = BCM_PORT_COS_REMAP_EXP; 47417 break; 47418 case 2: 47419 *value = BCM_PORT_COS_REMAP_VLAN_PRI; 47420 break; 47421 default: 47422 *value = BCM_PORT_COS_REMAP_VLAN_PRI; 47423 } 47424 } 47425 PORT_UNLOCK(unit); 47426 break; 47427 case bcmPortControlTaggedMPLSL3PacketPktPri: 47428 if (!SOC_IS_SHADOW(unit)) { 47429 return BCM_E_UNAVAIL; 47430 } 47431 PORT_LOCK(unit); 47432 rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val); 47433 if (BCM_SUCCESS(rv)) { 47434 *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr, 47435 val, SELECT7f); 47436 switch (*value) { 47437 case 0: 47438 *value = BCM_PORT_COS_REMAP_DSCP; 47439 break; 47440 case 1: 47441 *value = BCM_PORT_COS_REMAP_EXP; 47442 break; 47443 case 2: 47444 *value = BCM_PORT_COS_REMAP_VLAN_PRI; 47445 break; 47446 default: 47447 *value = BCM_PORT_COS_REMAP_VLAN_PRI; 47448 } 47449 } 47450 PORT_UNLOCK(unit); 47451 break; 47452 #endif 47453 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 47454 case bcmPortControlFieldEgressClassSelect: 47455 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 47456 if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) { 47457 rv = _bcm_td2p_port_control_egress_class_select_get(unit, port, 47458 (uint32 *)value); 47459 } else 47460 #endif 47461 { 47462 rv = _bcm_trx_port_control_egress_class_select_get(unit, port, 47463 (uint32 *)value); 47464 } 47465 break; 47466 #endif 47467 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 47468 case bcmPortControlFieldHiGigClassSelect: 47469 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 47470 if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) { 47471 rv = _bcm_td2p_port_control_higig_class_select_get(unit, port, 47472 (uint32 *)value); 47473 } else 47474 #endif 47475 { 47476 rv = _bcm_trx_port_control_higig_class_select_get(unit, port, 47477 (uint32 *)value); 47478 } 47479 break; 47480 #endif 47481 case bcmPortControlSubportTagEnable: 47482 #if defined (BCM_HGPROXY_COE_SUPPORT) 47483 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 47484 soc_feature(unit, soc_feature_channelized_switching)) { 47485 rv = bcmi_xgs5_port_control_subtag_status_get(unit, port, value); 47486 } 47487 #endif 47488 #if defined (BCM_KATANA2_SUPPORT) 47489 if (soc_feature(unit, soc_feature_subtag_coe)) { 47490 if (SOC_IS_KATANA2(unit)) { 47491 rv = bcm_kt2_port_control_subtag_status_get(unit, port, value); 47492 } 47493 } 47494 #endif 47495 break; 47496 47497 47498 case bcmPortControlLinkPhyEnable: 47499 #if defined (BCM_KATANA2_SUPPORT) 47500 if (soc_feature(unit, soc_feature_linkphy_coe)) { 47501 if (SOC_IS_KATANA2(unit)) { 47502 rv = bcm_kt2_port_control_linkphy_status_get(unit, port, value); 47503 } 47504 } 47505 #endif 47506 break; 47507 47508 #if defined(BCM_TRIDENT2_SUPPORT) 47509 47510 case bcmPortControlFcoeRouteEnable: 47511 if (soc_feature(unit, soc_feature_fcoe)) { 47512 #ifdef BCM_TRIDENT3_SUPPORT 47513 if (SOC_IS_TRIDENT3X(unit)) { 47514 rv = _bcm_esw_port_tab_get(unit, port, 47515 FCOE_ROUTE_ENABLEf, value); 47516 } else 47517 #endif 47518 { 47519 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_ROUTE_ENABLEf)) { 47520 rv = _bcm_esw_port_tab_get(unit, port, 47521 FCOE_ROUTE_ENABLEf, value); 47522 } 47523 } 47524 } 47525 break; 47526 47527 case bcmPortControlFcoeVftEnable: 47528 if (soc_feature(unit, soc_feature_fcoe)) { 47529 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VFT_ENABLEf)) { 47530 rv = _bcm_esw_port_tab_get(unit, port, 47531 FCOE_VFT_ENABLEf, value); 47532 } 47533 } 47534 break; 47535 47536 case bcmPortControlFcoeZoneCheckEnable: 47537 if (soc_feature(unit, soc_feature_fcoe)) { 47538 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, 47539 FCOE_ZONE_CHECK_ENABLEf)) { 47540 rv = _bcm_esw_port_tab_get(unit, port, 47541 FCOE_ZONE_CHECK_ENABLEf, value); 47542 } 47543 } 47544 break; 47545 47546 case bcmPortControlFcoeSourceBindCheckEnable: 47547 if (soc_feature(unit, soc_feature_fcoe)) { 47548 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, 47549 FCOE_SRC_BIND_CHECK_ENABLEf)) { 47550 rv = _bcm_esw_port_tab_get(unit, port, 47551 FCOE_SRC_BIND_CHECK_ENABLEf, 47552 value); 47553 } 47554 } 47555 break; 47556 47557 case bcmPortControlFcoeFpmaPrefixCheckEnable: 47558 if (soc_feature(unit, soc_feature_fcoe)) { 47559 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, 47560 FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf)) { 47561 rv = _bcm_esw_port_tab_get(unit, port, 47562 FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf, 47563 value); 47564 } 47565 } 47566 break; 47567 47568 case bcmPortControlFcoeDoNotLearn: 47569 if (soc_feature(unit, soc_feature_fcoe)) { 47570 if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_DO_NOT_LEARNf))) { 47571 rv = _bcm_esw_port_tab_get(unit, port, 47572 FCOE_DO_NOT_LEARNf, value); 47573 } 47574 } 47575 break; 47576 47577 case bcmPortControlFcoeNetworkPort: 47578 if (soc_feature(unit, soc_feature_fcoe)) { 47579 if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_NETWORK_PORTf))) { 47580 rv = _bcm_esw_port_tab_get(unit, port, 47581 FCOE_NETWORK_PORTf, value); 47582 } 47583 } 47584 break; 47585 47586 case bcmPortControlFcoeFabricSel: 47587 if (soc_feature(unit, soc_feature_fcoe)) { 47588 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_SELf)) { 47589 rv = _bcm_esw_port_tab_get(unit, port, 47590 FCOE_FABRIC_SELf, value); 47591 } 47592 } 47593 break; 47594 47595 case bcmPortControlFcoeFabricId: 47596 if (soc_feature(unit, soc_feature_fcoe)) { 47597 #ifdef BCM_TRIDENT3_SUPPORT 47598 if (SOC_IS_TRIDENT3X(unit)) { 47599 rv = _bcm_esw_port_tab_get(unit, port, 47600 FCOE_FABRIC_IDf, value); 47601 } else 47602 #endif 47603 { 47604 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_IDf)) { 47605 rv = _bcm_esw_port_tab_get(unit, port, 47606 FCOE_FABRIC_IDf, value); 47607 } 47608 } 47609 } 47610 break; 47611 47612 case bcmPortControlFcoeFabricPri: 47613 if (soc_feature(unit, soc_feature_fcoe)) { 47614 #ifdef BCM_TRIDENT3_SUPPORT 47615 if (SOC_IS_TRIDENT3X(unit)) { 47616 rv = _bcm_esw_port_tab_get(unit, port, 47617 FCOE_FABRIC_PRIf, value); 47618 } else 47619 #endif 47620 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_PRIf)) { 47621 rv = _bcm_esw_port_tab_get(unit, port, 47622 FCOE_FABRIC_PRIf, value); 47623 } 47624 } 47625 break; 47626 47627 case bcmPortControlFcoeFcCrcAction: 47628 if (soc_feature(unit, soc_feature_fcoe)) { 47629 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, 47630 FCOE_FC_CRC_ACTIONf)) { 47631 egr_ing_port_entry_t egr_ing_port_entry; 47632 47633 rv = READ_EGR_ING_PORTm(unit, MEM_BLOCK_ANY, port, 47634 &egr_ing_port_entry); 47635 if (BCM_SUCCESS(rv)) { 47636 *value = soc_mem_field32_get(unit, EGR_ING_PORTm, 47637 &egr_ing_port_entry, 47638 FCOE_FC_CRC_ACTIONf); 47639 } 47640 } 47641 } 47642 break; 47643 47644 case bcmPortControlFcoeFcCrcRecompute: 47645 if (soc_feature(unit, soc_feature_fcoe)) { 47646 if (SOC_MEM_IS_VALID(unit, EGR_PORTm) && 47647 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 47648 FCOE_FC_CRC_RECOMPUTEf)) { 47649 egr_port_entry_t egr_port_entry; 47650 47651 rv = READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, 47652 &egr_port_entry); 47653 if (BCM_SUCCESS(rv)) { 47654 *value = soc_mem_field32_get(unit, EGR_PORTm, 47655 &egr_port_entry, 47656 FCOE_FC_CRC_RECOMPUTEf); 47657 } 47658 } 47659 } 47660 break; 47661 47662 case bcmPortControlFcoeFcEofIgnore: 47663 if (soc_feature(unit, soc_feature_fcoe)) { 47664 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, 47665 FCOE_FC_EOF_IGNOREf)) { 47666 egr_ing_port_entry_t egr_ing_port_entry; 47667 47668 rv = READ_EGR_ING_PORTm(unit, MEM_BLOCK_ANY, port, 47669 &egr_ing_port_entry); 47670 if (BCM_SUCCESS(rv)) { 47671 *value = soc_mem_field32_get(unit, EGR_ING_PORTm, 47672 &egr_ing_port_entry, 47673 FCOE_FC_EOF_IGNOREf); 47674 } 47675 } 47676 } 47677 break; 47678 47679 case bcmPortControlFcoeTranslateKeyFirst: 47680 case bcmPortControlFcoeTranslateKeySecond: 47681 if (soc_feature(unit, soc_feature_fcoe)) { 47682 int reg_val; 47683 int key_type; 47684 int use_port = 0; 47685 int vt_port_type; 47686 47687 if (type == bcmPortControlFcoeTranslateKeyFirst) { 47688 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_1f)) { 47689 rv = _bcm_esw_port_tab_get(unit, port, 47690 FCOE_VT_KEY_TYPE_1f, ®_val); 47691 } 47692 47693 if (BCM_SUCCESS(rv)) { 47694 rv = _bcm_esw_port_config_get(unit, port, 47695 _bcmPortVTKeyPortFirst, 47696 &vt_port_type); 47697 if (BCM_SUCCESS(rv)) { 47698 if (vt_port_type != 0) { 47699 use_port = 1; 47700 } 47701 } 47702 } 47703 } else { 47704 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_2f)) { 47705 rv = _bcm_esw_port_tab_get(unit, port, 47706 FCOE_VT_KEY_TYPE_2f, ®_val); 47707 } 47708 if (BCM_SUCCESS(rv)) { 47709 rv = _bcm_esw_port_config_get(unit, port, 47710 _bcmPortVTKeyPortSecond, 47711 &vt_port_type); 47712 if (BCM_SUCCESS(rv)) { 47713 if (vt_port_type != 0) { 47714 use_port = 1; 47715 } 47716 } 47717 } 47718 } 47719 47720 if (BCM_SUCCESS(rv)) { 47721 /* convert register value to common key type */ 47722 rv = _bcm_esw_vlan_xlate_key_type_get(unit, reg_val, &key_type); 47723 if (!BCM_SUCCESS(rv)) { 47724 break; 47725 } 47726 47727 /* convert common key type value to 47728 bcm_fcoe_vsan_translate_key_t */ 47729 switch (key_type) { 47730 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 47731 if (use_port) { 47732 *value = bcmFcoeVsanTranslateKeyPortDouble; 47733 } else { 47734 *value = bcmFcoeVsanTranslateKeyDouble; 47735 } 47736 break; 47737 case VLXLT_HASH_KEY_TYPE_OTAG: 47738 if (use_port) { 47739 *value = bcmFcoeVsanTranslateKeyPortOuterTag; 47740 } else { 47741 *value = bcmFcoeVsanTranslateKeyOuterTag; 47742 } 47743 break; 47744 case VLXLT_HASH_KEY_TYPE_ITAG: 47745 if (use_port) { 47746 *value = bcmFcoeVsanTranslateKeyPortInnerTag; 47747 } else { 47748 *value = bcmFcoeVsanTranslateKeyInnerTag; 47749 } 47750 break; 47751 case VLXLT_HASH_KEY_TYPE_OVID: 47752 if (use_port) { 47753 *value = bcmFcoeVsanTranslateKeyPortOuter; 47754 } else { 47755 *value = bcmFcoeVsanTranslateKeyOuter; 47756 } 47757 break; 47758 case VLXLT_HASH_KEY_TYPE_IVID: 47759 if (use_port) { 47760 *value = bcmFcoeVsanTranslateKeyPortInner; 47761 } else { 47762 *value = bcmFcoeVsanTranslateKeyInner; 47763 } 47764 break; 47765 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 47766 if (use_port) { 47767 *value = bcmFcoeVsanTranslateKeyPortOuterPri; 47768 } else { 47769 *value = bcmFcoeVsanTranslateKeyOuterPri; 47770 } 47771 break; 47772 case VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN: 47773 if (use_port) { 47774 *value = bcmFcoeVsanTranslateKeyPortDoubleVsan; 47775 } else { 47776 *value = bcmFcoeVsanTranslateKeyDoubleVsan; 47777 } 47778 break; 47779 case VLXLT_HASH_KEY_TYPE_IVID_VSAN: 47780 if (use_port) { 47781 *value = bcmFcoeVsanTranslateKeyPortInnerVsan; 47782 } else { 47783 *value = bcmFcoeVsanTranslateKeyInnerVsan; 47784 } 47785 break; 47786 case VLXLT_HASH_KEY_TYPE_OVID_VSAN: 47787 if (use_port) { 47788 *value = bcmFcoeVsanTranslateKeyPortOuterVsan; 47789 } else { 47790 *value = bcmFcoeVsanTranslateKeyOuterVsan; 47791 } 47792 break; 47793 default: 47794 *value = bcmFcoeVsanTranslateKeyInvalid; 47795 break; 47796 } 47797 } 47798 } else { 47799 rv = BCM_E_UNAVAIL; 47800 } 47801 break; 47802 47803 case bcmPortControlFcoeTranslateKeyFirstEgress: 47804 case bcmPortControlFcoeTranslateKeySecondEgress: 47805 if (soc_feature(unit, soc_feature_fcoe)) { 47806 int key_type = -1; 47807 47808 if (type == bcmPortControlFcoeTranslateKeyFirstEgress) { 47809 if (SOC_IS_TRIDENT3X(unit) || 47810 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_1f)) { 47811 rv = _bcm_esw_egr_port_tab_get(unit, port, 47812 FCOE_VT_LOOKUP_1f, 47813 &key_type); 47814 } 47815 } else { 47816 if (SOC_IS_TRIDENT3X(unit) || 47817 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_2f)) { 47818 rv = _bcm_esw_egr_port_tab_get(unit, port, 47819 FCOE_VT_LOOKUP_2f, 47820 &key_type); 47821 } 47822 } 47823 47824 if (BCM_SUCCESS(rv)) { 47825 /* convert common key type value to 47826 bcm_fcoe_vsan_translate_key_egress_t */ 47827 switch (key_type) { 47828 case EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN: 47829 *value = bcmFcoeVsanTranslateKeyEgressDoubleVsan; 47830 break; 47831 case EGR_VLXLT_HASH_KEY_TYPE_VSAN: 47832 *value = bcmFcoeVsanTranslateKeyEgressVsan; 47833 break; 47834 case EGR_VLXLT_HASH_KEY_TYPE_IVID_VSAN: 47835 *value = bcmFcoeVsanTranslateKeyEgressInnerVsan; 47836 break; 47837 case EGR_VLXLT_HASH_KEY_TYPE_OVID_VSAN: 47838 *value = bcmFcoeVsanTranslateKeyEgressOuterVsan; 47839 break; 47840 case EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID: 47841 *value = bcmFcoeVsanTranslateKeyEgressDouble; 47842 break; 47843 case EGR_VLXLT_HASH_KEY_TYPE_IVID: 47844 *value = bcmFcoeVsanTranslateKeyEgressInner; 47845 break; 47846 case EGR_VLXLT_HASH_KEY_TYPE_OVID: 47847 *value = bcmFcoeVsanTranslateKeyEgressOuter; 47848 break; 47849 default: 47850 *value = bcmFcoeVsanTranslateKeyEgressInvalid; 47851 break; 47852 } 47853 } 47854 } else { 47855 rv = BCM_E_UNAVAIL; 47856 } 47857 break; 47858 47859 #endif /* BCM_TRIDENT2_SUPPORT */ 47860 case bcmPortControlEEEMode: 47861 if (soc_feature(unit, soc_feature_eee_bb_mode)) { 47862 uint32 fval = 0; 47863 uint32 rval = 0; 47864 uint32 temp = 0; 47865 if (soc_feature (unit, soc_feature_high_portcount_register)) { 47866 soc_reg_t eee_bb_reg; 47867 int phy_port; 47868 int mmu_port; 47869 int offset; 47870 47871 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 47872 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 47873 if (mmu_port < 32) { 47874 eee_bb_reg = EEE_BB_ENABLE_0r; 47875 offset = mmu_port; 47876 } else if ((mmu_port >=32) && (mmu_port < 64)) { 47877 eee_bb_reg = EEE_BB_ENABLE_1r; 47878 offset = mmu_port - 32; 47879 } else { /* mmu_port >= 64 */ 47880 eee_bb_reg = EEE_BB_ENABLE_2r; 47881 offset = mmu_port - 64; 47882 } 47883 temp = (1 << offset); 47884 BCM_IF_ERROR_RETURN( 47885 soc_reg32_get(unit, eee_bb_reg, REG_PORT_ANY, 0, &rval)); 47886 fval = soc_reg_field_get(unit, eee_bb_reg, rval, 47887 EEE_BB_ENABLEf); 47888 *value = (fval & temp) ? \ 47889 bcmPortEEEBurstAndBatchMode:bcmPortEEENativeMode; 47890 } else { 47891 temp = (1 << port); 47892 temp >>= 2; 47893 rv = READ_EEE_BB_ENABLEr(unit, &rval); 47894 if (BCM_SUCCESS(rv)) { 47895 fval = soc_reg_field_get(unit, EEE_BB_ENABLEr, rval, 47896 EEE_BB_ENABLEf); 47897 *value = (fval & temp) ? \ 47898 bcmPortEEEBurstAndBatchMode:bcmPortEEENativeMode; 47899 } 47900 } 47901 } 47902 break; 47903 #ifdef BCM_GREYHOUND_SUPPORT 47904 case bcmPortControlWredDropCountUpdateEnableQueueMask: 47905 if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) { 47906 #if defined(BCM_GREYHOUND2_SUPPORT) 47907 if (SOC_IS_GREYHOUND2(unit)) { 47908 rv = bcmi_gh2_cosq_wred_port_control_get(unit, port, type, 47909 value); 47910 } else 47911 #endif /* BCM_GREYHOUND2_SUPPORT */ 47912 { 47913 rv = READ_WRED_DROP_CTR_CONFIGr(unit, port, &val); 47914 *value = soc_reg_field_get(unit, WRED_DROP_CTR_CONFIGr, 47915 val, QUEUE_MASKf); 47916 } 47917 } 47918 break; 47919 case bcmPortControlWredDropCountUpdateEnableColorMask: 47920 if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) { 47921 #if defined(BCM_GREYHOUND2_SUPPORT) 47922 if (SOC_IS_GREYHOUND2(unit)) { 47923 rv = bcmi_gh2_cosq_wred_port_control_get(unit, port, type, 47924 value); 47925 } else 47926 #endif /* BCM_GREYHOUND2_SUPPORT */ 47927 { 47928 uint32 fld_val; 47929 rv = READ_WRED_DROP_CTR_CONFIGr(unit, port, &val); 47930 if (BCM_SUCCESS(rv)) { 47931 fld_val = soc_reg_field_get(unit, WRED_DROP_CTR_CONFIGr, 47932 val, COLOR_MASKf); 47933 *value = 0; 47934 if (fld_val & 0x4) { 47935 *value |= (0x1 << bcmColorGreen); 47936 } 47937 if (fld_val & 0x2) { 47938 *value |= (0x1 << bcmColorYellow); 47939 } 47940 if (fld_val & 0x1) { 47941 *value |= (0x1 << bcmColorRed); 47942 } 47943 } 47944 } 47945 } 47946 break; 47947 #endif /* BCM_GREYHOUND_SUPPORT */ 47948 #ifdef BCM_TRIDENT2_SUPPORT 47949 case bcmPortControlProbeSerdesReset: 47950 if (SOC_IS_TD2_TT2(unit)) { 47951 *value = 47952 PORT(unit, port).flags & _PORT_INFO_PROBE_RESET_SERDES ? 47953 1 : 0; 47954 rv = BCM_E_NONE; 47955 } 47956 break; 47957 #endif /* BCM_TRIDENT2_SUPPORT */ 47958 case bcmPortControlMmuTrafficEnable: 47959 rv = bcm_esw_port_enqueue_get(unit, port, value); 47960 break; 47961 case bcmPortControlRxFastLOS: 47962 rv = _bcm_esw_link_fast_get(unit, port, value); 47963 break; 47964 case bcmPortControlLLFCReceive: 47965 case bcmPortControlLLFCTransmit: 47966 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 47967 case bcmPortControlSAFCReceive: 47968 case bcmPortControlSAFCTransmit: 47969 #endif 47970 rv = _bcm_esw_port_llfc_get(unit, port, type, value); 47971 break; 47972 case bcmPortControlTrunkLoadBalancingRandomizer: 47973 #ifdef BCM_TOMAHAWK_SUPPORT 47974 if (soc_feature(unit, soc_feature_randomized_load_balance)) { 47975 rv = _bcm_esw_port_tab_get(unit, port, 47976 OFFSET_TRUNK_RANDOM_LBf, value); 47977 } 47978 #endif /* BCM_TOMAHAWK_SUPPORT */ 47979 break; 47980 case bcmPortControlECMPLevel1LoadBalancingRandomizer: 47981 #ifdef BCM_TOMAHAWK_SUPPORT 47982 if (soc_feature(unit, soc_feature_ecmp_random)) { 47983 rv = _bcm_esw_port_tab_get(unit, port, 47984 OFFSET_ECMP_RANDOM_LBf , value); 47985 } 47986 #endif /* BCM_TOMAHAWK_SUPPORT */ 47987 break; 47988 case bcmPortControlECMPLevel2LoadBalancingRandomizer: 47989 #ifdef BCM_TOMAHAWK_SUPPORT 47990 if (soc_feature(unit, soc_feature_ecmp_random)) { 47991 rv = _bcm_esw_port_tab_get(unit, port, 47992 OFFSET_ECMP_LEVEL2_RANDOM_LBf, 47993 value); 47994 } 47995 #endif /* BCM_TOMAHAWK_SUPPORT */ 47996 break; 47997 case bcmPortControlMcastGroupRemap: 47998 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, NETWORK_PORTf)) { 47999 SOC_IF_ERROR_RETURN 48000 (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, port, &svp_entry)); 48001 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry, 48002 NETWORK_PORTf); 48003 rv = BCM_E_NONE; 48004 } 48005 break; 48006 case bcmPortControlOOBFCTxReportIngEnable: 48007 if (soc_feature(unit, soc_feature_oob_fc)) { 48008 #ifdef BCM_TOMAHAWK_SUPPORT 48009 if (SOC_IS_TOMAHAWKX(unit)) { 48010 rv = _bcm_th_oob_fc_tx_port_control_get(unit, port, value, 0); 48011 } 48012 #endif 48013 #ifdef BCM_KATANA2_SUPPORT 48014 if (SOC_IS_KATANA2(unit)) { 48015 rv = _bcm_kt2_oob_fc_tx_port_control_get(unit, port, value, 0); 48016 } 48017 #endif 48018 #ifdef BCM_TRIDENT3_SUPPORT 48019 if (SOC_IS_TRIDENT3X(unit)) { 48020 rv = _bcm_td3_oob_fc_tx_port_control_get(unit, port, value, 0); 48021 } 48022 #endif 48023 #ifdef BCM_APACHE_SUPPORT 48024 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 48025 rv = _bcm_ap_oob_fc_tx_port_control_get(unit, port, value, 0); 48026 } 48027 #endif 48028 } 48029 break; 48030 case bcmPortControlOOBFCTxReportEgrEnable: 48031 if (soc_feature(unit, soc_feature_oob_fc)) { 48032 #ifdef BCM_TOMAHAWK_SUPPORT 48033 if (SOC_IS_TOMAHAWKX(unit)) { 48034 rv = _bcm_th_oob_fc_tx_port_control_get(unit, port, value, 1); 48035 } 48036 #endif 48037 #ifdef BCM_APACHE_SUPPORT 48038 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 48039 rv = _bcm_ap_oob_fc_tx_port_control_get(unit, port, value, 1); 48040 } 48041 #endif 48042 #ifdef BCM_KATANA2_SUPPORT 48043 if (SOC_IS_KATANA2(unit)) { 48044 rv = _bcm_kt2_oob_fc_tx_port_control_get(unit, port, value, 1); 48045 } 48046 #endif 48047 #ifdef BCM_TRIDENT3_SUPPORT 48048 if (SOC_IS_TRIDENT3X(unit)) { 48049 rv = _bcm_td3_oob_fc_tx_port_control_get(unit, port, value, 1); 48050 } 48051 #endif 48052 } 48053 break; 48054 48055 case bcmPortControlSubportTagSize: 48056 #ifdef BCM_HGPROXY_COE_SUPPORT 48057 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 48058 DESTINATION_SUBPORT_TAG_TYPEf)) { 48059 48060 int local_port = 0; 48061 egr_port_entry_t egr_port_entry; 48062 if (BCM_GPORT_IS_SET(port)) { 48063 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 48064 } else { 48065 if(!SOC_PORT_VALID(unit, port)) { 48066 return BCM_E_PORT; 48067 } else { 48068 local_port = port; 48069 } 48070 } 48071 48072 SOC_IF_ERROR_RETURN 48073 (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, local_port, &egr_port_entry)); 48074 *value = soc_EGR_PORTm_field32_get(unit, &egr_port_entry, 48075 DESTINATION_SUBPORT_TAG_TYPEf); 48076 rv = BCM_E_NONE; 48077 } 48078 if (SOC_IS_TRIDENT3X(unit)) { 48079 *value = 0; 48080 rv = BCM_E_NONE; 48081 } 48082 #endif 48083 break; 48084 48085 case bcmPortControlSystemPortOverride: 48086 #ifdef BCM_HGPROXY_COE_SUPPORT 48087 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 48088 VT_SYS_PORT_OVERRIDEf)) { 48089 48090 rv = bcmi_xgs5_subport_subtag_port_override_get(unit, port, 48091 value); 48092 } 48093 #endif 48094 break; 48095 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 48096 case bcmPortControlSampleIngressDest: 48097 if(soc_feature(unit, soc_feature_sflow_ing_mem)) { 48098 sflow_ing_data_source_entry_t sflow_entry; 48099 uint32 field_values[2] = {0, 0}; 48100 BCM_IF_ERROR_RETURN 48101 (READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 48102 &sflow_entry)); 48103 soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry, 48104 CPUf, &field_values[0]); 48105 soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry, 48106 MIRRORf, &field_values[1]); 48107 *value = field_values[0] | (field_values[1] << 1); 48108 rv = BCM_E_NONE; 48109 } 48110 break; 48111 case bcmPortControlSampleFlexDest: 48112 if(soc_feature(unit, soc_feature_sflow_flex)) { 48113 sflow_ing_flex_data_source_entry_t sflow_entry; 48114 uint32 field_values[2] = {0, 0}; 48115 BCM_IF_ERROR_RETURN 48116 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 48117 &sflow_entry)); 48118 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry, 48119 CPUf, &field_values[0]); 48120 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry, 48121 MIRRORf, &field_values[1]); 48122 *value = field_values[0] | (field_values[1] << 1); 48123 rv = BCM_E_NONE; 48124 } 48125 break; 48126 case bcmPortControlSampleFlexRate: 48127 if(soc_feature(unit, soc_feature_sflow_flex)) { 48128 sflow_ing_flex_data_source_entry_t sflow_entry; 48129 uint32 field_enable, field_thresh; 48130 48131 /* Read ENABLE and THRESHOLD fields from flex rate data table */ 48132 BCM_IF_ERROR_RETURN 48133 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 48134 &sflow_entry)); 48135 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry, 48136 ENABLEf, &field_enable); 48137 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry, 48138 THRESHOLDf, 48139 &field_thresh); 48140 48141 if (field_enable) { 48142 if (field_thresh) { 48143 *value = (1 << (SFLOW_RANGE_MAX(unit))) / field_thresh; 48144 } else { 48145 *value = 1 << (SFLOW_RANGE_MAX(unit)); 48146 } 48147 } else { 48148 *value = 0; 48149 if (field_thresh) { 48150 return BCM_E_INTERNAL; 48151 } 48152 } 48153 rv = BCM_E_NONE; 48154 } 48155 break; 48156 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */ 48157 #ifdef BCM_XGS3_SWITCH_SUPPORT 48158 case bcmPortControlSampleIngressEnable: 48159 if (SOC_IS_XGS3_SWITCH(unit)) { 48160 uint32 regval = 0; 48161 uint32 field_enable = 0; 48162 #ifdef BCM_TOMAHAWK_SUPPORT 48163 sflow_ing_data_source_entry_t sflow_entry; 48164 #endif /* BCM_TOMAHAWK_SUPPORT */ 48165 48166 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 48167 if (soc_feature(unit, soc_feature_sflow_ing_mem)) { 48168 BCM_IF_ERROR_RETURN( 48169 READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 48170 &sflow_entry)); 48171 48172 soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry, ENABLEf, 48173 &field_enable); 48174 } else 48175 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */ 48176 { 48177 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) { 48178 return BCM_E_UNAVAIL; 48179 } 48180 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, ®val)); 48181 field_enable = soc_reg_field_get(unit, SFLOW_ING_THRESHOLDr, regval, 48182 ENABLEf); 48183 } 48184 48185 *value = field_enable ? 1 : 0; 48186 rv = BCM_E_NONE; 48187 } else { 48188 rv = BCM_E_UNAVAIL; 48189 } 48190 break; 48191 case bcmPortControlSampleEgressEnable: 48192 if (SOC_IS_XGS3_SWITCH(unit)) { 48193 uint32 regval = 0; 48194 uint32 field_enable = 0; 48195 48196 if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) { 48197 return BCM_E_UNAVAIL; 48198 } 48199 BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, ®val)); 48200 field_enable = soc_reg_field_get(unit, SFLOW_EGR_THRESHOLDr, regval, 48201 ENABLEf); 48202 48203 *value = field_enable ? 1 : 0; 48204 rv = BCM_E_NONE; 48205 } else { 48206 rv = BCM_E_UNAVAIL; 48207 } 48208 break; 48209 case bcmPortControlSampleIngressRate: 48210 if (SOC_IS_XGS3_SWITCH(unit)) { 48211 uint32 regval = 0; 48212 uint32 field_value; 48213 #ifdef BCM_TOMAHAWK_SUPPORT 48214 sflow_ing_data_source_entry_t sflow_entry; 48215 #endif /* BCM_TOMAHAWK_SUPPORT */ 48216 48217 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 48218 if (soc_feature(unit, soc_feature_sflow_ing_mem)) { 48219 BCM_IF_ERROR_RETURN( 48220 READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 48221 &sflow_entry)); 48222 48223 soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry, THRESHOLDf, 48224 &field_value); 48225 } else 48226 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */ 48227 { 48228 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) { 48229 return BCM_E_UNAVAIL; 48230 } 48231 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, ®val)); 48232 48233 field_value = soc_reg_field_get(unit, SFLOW_ING_THRESHOLDr, 48234 regval, THRESHOLDf); 48235 } 48236 48237 /* 48238 * For early sFlow implementations the 16-bit threshold value 48239 * is compared to bits [23:8] of the sFlow random number. 48240 */ 48241 if (soc_feature(unit, soc_feature_sample_offset8)) { 48242 field_value <<= 8; 48243 } 48244 48245 if (field_value) { 48246 *value = (1 << (SFLOW_RANGE_MAX(unit))) / field_value; 48247 } else { 48248 *value = 0; 48249 } 48250 rv = BCM_E_NONE; 48251 } else { 48252 rv = BCM_E_UNAVAIL; 48253 } 48254 break; 48255 case bcmPortControlSampleEgressRate: 48256 if (SOC_IS_XGS3_SWITCH(unit)) { 48257 uint32 regval; 48258 uint32 field_value; 48259 48260 if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) { 48261 return BCM_E_UNAVAIL; 48262 } 48263 BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, ®val)); 48264 48265 field_value = soc_reg_field_get(unit, SFLOW_EGR_THRESHOLDr, 48266 regval, THRESHOLDf); 48267 48268 /* 48269 * For early sFlow implementations the 16-bit threshold value 48270 * is compared to bits [23:8] of the sFlow random number. 48271 */ 48272 if (soc_feature(unit, soc_feature_sample_offset8)) { 48273 field_value <<= 8; 48274 } 48275 48276 if (field_value) { 48277 *value = (1 << (SFLOW_RANGE_MAX(unit))) / field_value; 48278 } else { 48279 *value = 0; 48280 } 48281 rv = BCM_E_NONE; 48282 } else { 48283 rv = BCM_E_UNAVAIL; 48284 } 48285 break; 48286 #endif 48287 case bcmPortControlExternalBufferEnable: 48288 #if defined(BCM_KATANA2_SUPPORT) 48289 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_ddr3)) { 48290 rv = _bcm_kt2_cosq_port_ext_buf_get(unit, port, value); 48291 } 48292 #endif 48293 break; 48294 #ifdef BCM_HURRICANE3_SUPPORT 48295 case bcmPortControlTrustMimlPri: 48296 if (soc_feature(unit, soc_feature_miml)) { 48297 rv = _bcm_esw_port_tab_get(unit, port, 48298 USE_MIML_PCP_FOR_PRIf, value); 48299 } 48300 break; 48301 case bcmPortControlTrustCustomHeaderPri: 48302 if (soc_feature(unit, soc_feature_custom_header)) { 48303 rv = _bcm_esw_port_tab_get(unit, port, 48304 USE_CUSTOM_HEADER_FOR_PRIf, value); 48305 } 48306 break; 48307 case bcmPortControlCustomHeaderEncapEnable: 48308 if (soc_feature(unit, soc_feature_custom_header)) { 48309 uint64 val64; 48310 48311 rv = READ_EGR_PORT_64r(unit, port, &val64); 48312 if (BCM_SUCCESS(rv)) { 48313 *value = soc_reg64_field32_get(unit, EGR_PORT_64r, 48314 val64, CUSTOM_HEADER_ENABLEf); 48315 } 48316 } 48317 break; 48318 #endif /* BCM_HURRICANE3_SUPPORT */ 48319 case bcmPortControl1588P2PDelay: 48320 { 48321 uint32 link_delay; 48322 int mac_rx_latency = 0; 48323 int speed; 48324 rv = bcm_esw_port_speed_get(unit, port, &speed); 48325 soc_property_port_get(unit, port, 48326 spn_LINK_DELAY(speed), mac_rx_latency); 48327 48328 if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) { 48329 soc_reg32_get(unit, EGR_1588_LINK_DELAYr, 48330 port, LINK_DELAYf, &link_delay); 48331 *value = link_delay - mac_rx_latency; 48332 rv = BCM_E_NONE; 48333 } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) { 48334 soc_reg_above_64_field32_read(unit, EGR_1588_LINK_DELAY_64r, 48335 port, 0, LINK_DELAYf, &link_delay); 48336 *value = link_delay - mac_rx_latency; 48337 rv = BCM_E_NONE; 48338 } else { 48339 rv = BCM_E_UNAVAIL; 48340 /* No LINK_DELAY register, so no-op */ 48341 } 48342 } 48343 break; 48344 case bcmPortControlPacketTimeStampInsertRx: 48345 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 48346 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 48347 if (soc_feature(unit, soc_feature_timestamp)) { 48348 int ing_insert; 48349 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 48350 48351 BCM_IF_ERROR_RETURN( 48352 _bcm_esw_port_tab_get(unit, port, INSERT_RX_TIMESTAMPf, 48353 &ing_insert)); 48354 *value = ing_insert; 48355 rv = BCM_E_NONE; 48356 } 48357 #endif 48358 break; 48359 case bcmPortControlPacketTimeStampInsertTx: 48360 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 48361 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 48362 if (soc_feature(unit, soc_feature_timestamp)) { 48363 uint32 regval; 48364 uint32 egr_insert; 48365 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 48366 48367 BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, ®val)); 48368 egr_insert = soc_reg_field_get(unit, EGR_TS_CONTROLr, regval, 48369 INSERT_TX_TIMESTAMPf); 48370 *value = (int)egr_insert; 48371 rv = BCM_E_NONE; 48372 } 48373 #endif 48374 break; 48375 case bcmPortControlPacketTimeStampSrcPortInsertCancel: 48376 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 48377 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 48378 if (soc_feature(unit, soc_feature_timestamp)) { 48379 int ing_disable; 48380 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 48381 48382 BCM_IF_ERROR_RETURN( 48383 _bcm_esw_port_tab_get(unit, port, DISABLE_TIMESTAMPINGf, 48384 &ing_disable)); 48385 *value = ing_disable; 48386 rv = BCM_E_NONE; 48387 } 48388 #endif 48389 break; 48390 case bcmPortControlPacketTimeStampDestPortInsertCancel: 48391 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 48392 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 48393 if (soc_feature(unit, soc_feature_timestamp)) { 48394 uint32 regval; 48395 uint32 egr_disable; 48396 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 48397 48398 BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, ®val)); 48399 egr_disable = soc_reg_field_get(unit, EGR_TS_CONTROLr, regval, 48400 DISABLE_TIMESTAMPINGf); 48401 *value = (int)egr_disable; 48402 rv = BCM_E_NONE; 48403 } 48404 #endif 48405 break; 48406 case bcmPortControlPacketTimeStampRxId: 48407 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 48408 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 48409 if (soc_feature(unit, soc_feature_timestamp)) { 48410 uint32 regval; 48411 egr_ts_ing_port_map_entry_t egr_ts_entry; 48412 uint32 id; 48413 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 48414 if (SOC_REG_IS_VALID(unit, EGR_TS_ING_PORT_MAPr)) { 48415 BCM_IF_ERROR_RETURN(READ_EGR_TS_ING_PORT_MAPr(unit, port, ®val)); 48416 id = soc_reg_field_get(unit, EGR_TS_ING_PORT_MAPr, regval, 48417 TS_RX_ORIGIN_IDf); 48418 *value = (int)id; 48419 } else { 48420 48421 BCM_IF_ERROR_RETURN( 48422 READ_EGR_TS_ING_PORT_MAPm(unit, MEM_BLOCK_ANY, port, &egr_ts_entry)); 48423 soc_EGR_TS_ING_PORT_MAPm_field_get(unit, &egr_ts_entry, TS_RX_ORIGIN_IDf, 48424 ®val); 48425 *value = (int)regval; 48426 48427 } 48428 rv = BCM_E_NONE; 48429 } 48430 #endif 48431 break; 48432 case bcmPortControlPacketTimeStampTxId: 48433 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 48434 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 48435 if (soc_feature(unit, soc_feature_timestamp)) { 48436 uint32 regval; 48437 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 48438 48439 if (soc_reg_field_valid(unit, EGR_TS_CONTROL_2r, TS_TX_ORIGIN_IDf)) 48440 { 48441 BCM_IF_ERROR_RETURN( 48442 READ_EGR_TS_CONTROL_2r(unit, port, ®val)); 48443 *value = soc_reg_field_get( 48444 unit, EGR_TS_CONTROL_2r, regval, TS_TX_ORIGIN_IDf); 48445 } else { 48446 BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, ®val)); 48447 *value = soc_reg_field_get( 48448 unit, EGR_TS_CONTROLr, regval, TS_TX_ORIGIN_IDf); 48449 } 48450 rv = BCM_E_NONE; 48451 } 48452 #endif 48453 break; 48454 case bcmPortControlPacketTimeStampByteMeterAdjust: 48455 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 48456 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 48457 if (soc_feature(unit, soc_feature_timestamp) && !SOC_IS_TOMAHAWK3(unit)) 48458 { 48459 uint32 regval; 48460 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 48461 48462 BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, ®val)); 48463 *value = soc_reg_field_get(unit, EGR_TS_CONTROLr, regval, 48464 TS_ADJUST_METERSf); 48465 rv = BCM_E_NONE; 48466 } 48467 #endif 48468 break; 48469 case bcmPortControlE2EFCTransmitEnable: 48470 if (soc_feature(unit, soc_feature_e2efc)) { 48471 uint32 fval; 48472 uint64 val; 48473 48474 if (!IS_HG_PORT(unit, port)) { 48475 LOG_ERROR( 48476 BSL_LS_BCM_PORT, 48477 (BSL_META_U(unit, 48478 "Error: unit %d port %d is not a Higig port. " 48479 "E2EFC messages can only be transmitted to " 48480 "or received from Higig ports.\n"), 48481 unit, port)); 48482 return BCM_E_PARAM; 48483 } 48484 #if defined(BCM_KATANA2_SUPPORT) 48485 if (SOC_IS_KATANA2(unit)) { 48486 BCM_IF_ERROR_RETURN(READ_E2EFC_IBP_ENr(unit, &fval)); 48487 *value = fval; 48488 } else 48489 #endif 48490 if (IS_XL_PORT(unit, port)) { 48491 BCM_IF_ERROR_RETURN(READ_XLMAC_E2E_CTRLr(unit, port, &val)); 48492 fval = soc_reg64_field32_get(unit, XLMAC_E2E_CTRLr, 48493 val, E2E_ENABLEf); 48494 *value = fval; 48495 } else if (IS_CL_PORT(unit, port)) { 48496 BCM_IF_ERROR_RETURN(READ_CLMAC_E2E_CTRLr(unit, port, &val)); 48497 fval = soc_reg64_field32_get(unit, CLMAC_E2E_CTRLr, 48498 val, E2E_ENABLEf); 48499 *value = fval; 48500 } else { 48501 return BCM_E_PARAM; 48502 } 48503 48504 rv = BCM_E_NONE; 48505 } 48506 break; 48507 case bcmPortControlE2EFCReceiveEnable: 48508 if (soc_feature(unit, soc_feature_e2efc)) { 48509 uint32 val, fval; 48510 48511 BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val)); 48512 fval = soc_reg_field_get(unit, IE2E_CONTROLr, 48513 val, IBP_ENABLEf); 48514 *value = fval; 48515 rv = BCM_E_NONE; 48516 } 48517 break; 48518 case bcmPortControlE2EFCCopyToCpuEnable: 48519 if (soc_feature(unit, soc_feature_e2efc)) { 48520 uint32 val, fval; 48521 48522 BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val)); 48523 fval = soc_reg_field_get(unit, IE2E_CONTROLr, 48524 val, IBP_TOCPUf); 48525 *value = fval; 48526 rv = BCM_E_NONE; 48527 } 48528 break; 48529 /* Higher 3 bytes of Destination MAC address */ 48530 case bcmPortControlE2EFCDestMacOui: 48531 if (soc_feature(unit, soc_feature_e2efc)) { 48532 uint32 val_hi; 48533 uint64 val_64, data_0; 48534 soc_reg_t reg; 48535 #if defined(BCM_KATANA2_SUPPORT) 48536 uint32 val; 48537 #endif 48538 if (!IS_HG_PORT(unit, port)) { 48539 LOG_ERROR( 48540 BSL_LS_BCM_PORT, 48541 (BSL_META_U(unit, 48542 "Error: unit %d port %d is not a Higig port. " 48543 "E2EFC messages can only be transmitted to " 48544 "or received from Higig ports.\n"), 48545 unit, port)); 48546 return BCM_E_PARAM; 48547 } 48548 #if defined(BCM_KATANA2_SUPPORT) 48549 if (SOC_IS_KATANA2(unit)) { 48550 #if defined(BCM_SABER2_SUPPORT) 48551 if (SOC_IS_SABER2(unit)) { 48552 /* Do nothing */ 48553 } else 48554 #endif /* BCM_SABER2_SUPPORT */ 48555 { 48556 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val)); 48557 val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f); 48558 *value = (val_hi >> 8) & 0xffffff; 48559 rv = BCM_E_NONE; 48560 break; 48561 } 48562 } 48563 #endif /* BCM_KATANA2_SUPPORT */ 48564 if (IS_XL_PORT(unit, port)) { 48565 reg = XLMAC_E2EFC_DATA_HDR_0r; 48566 } else if (IS_CL_PORT(unit, port)) { 48567 reg = CLMAC_E2EFC_DATA_HDR_0r; 48568 } else { 48569 return BCM_E_PARAM; 48570 } 48571 48572 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, 48573 port, 0, &val_64)); 48574 data_0 = soc_reg64_field_get(unit, reg, 48575 val_64, E2EFC_DATA_HDR_0f); 48576 COMPILER_64_TO_32_HI(val_hi, data_0); 48577 *value = (val_hi >> 8) & 0xffffff; 48578 rv = BCM_E_NONE; 48579 } 48580 break; 48581 /* Lower 3 bytes of Destination MAC address */ 48582 case bcmPortControlE2EFCDestMacNonOui: 48583 if (soc_feature(unit, soc_feature_e2efc)) { 48584 uint32 val_lo, val_hi; 48585 uint64 val_64, data_0; 48586 soc_reg_t reg; 48587 #if defined(BCM_KATANA2_SUPPORT) 48588 uint32 val; 48589 #endif 48590 if (!IS_HG_PORT(unit, port)) { 48591 LOG_ERROR( 48592 BSL_LS_BCM_PORT, 48593 (BSL_META_U(unit, 48594 "Error: unit %d port %d is not a Higig port. " 48595 "E2EFC messages can only be transmitted to " 48596 "or received from Higig ports.\n"), 48597 unit, port)); 48598 return BCM_E_PARAM; 48599 } 48600 #if defined(BCM_KATANA2_SUPPORT) 48601 if (SOC_IS_KATANA2(unit)) { 48602 #if defined(BCM_SABER2_SUPPORT) 48603 if (SOC_IS_SABER2(unit)) { 48604 /* Do nothing */ 48605 } else 48606 #endif /* BCM_SABER2_SUPPORT */ 48607 { 48608 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val)); 48609 val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f); 48610 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val)); 48611 val_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f); 48612 *value = ((val_hi & 0xff) << 16) | ((val_lo >> 16) & 0xffff); 48613 rv = BCM_E_NONE; 48614 break; 48615 } 48616 } 48617 #endif /* BCM_KATANA2_SUPPORT */ 48618 if (IS_XL_PORT(unit, port)) { 48619 reg = XLMAC_E2EFC_DATA_HDR_0r; 48620 } else if (IS_CL_PORT(unit, port)) { 48621 reg = CLMAC_E2EFC_DATA_HDR_0r; 48622 } else { 48623 return BCM_E_PARAM; 48624 } 48625 48626 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, 48627 port, 0, &val_64)); 48628 data_0 = soc_reg64_field_get(unit, reg, 48629 val_64, E2EFC_DATA_HDR_0f); 48630 COMPILER_64_TO_32_LO(val_lo, data_0); 48631 COMPILER_64_TO_32_HI(val_hi, data_0); 48632 *value = ((val_hi & 0xff) << 16) | ((val_lo >> 16) & 0xffff); 48633 rv = BCM_E_NONE; 48634 } 48635 break; 48636 /* Higher 3 bytes of Source MAC address */ 48637 case bcmPortControlE2EFCSrcMacOui: 48638 if (soc_feature(unit, soc_feature_e2efc)) { 48639 uint32 val_0_lo, val_1_hi; 48640 uint64 val_64, data_1, data_0; 48641 soc_reg_t reg_0, reg_1; 48642 #if defined(BCM_KATANA2_SUPPORT) 48643 uint32 val; 48644 #endif 48645 if (!IS_HG_PORT(unit, port)) { 48646 LOG_ERROR( 48647 BSL_LS_BCM_PORT, 48648 (BSL_META_U(unit, 48649 "Error: unit %d port %d is not a Higig port. " 48650 "E2EFC messages can only be transmitted to " 48651 "or received from Higig ports.\n"), 48652 unit, port)); 48653 return BCM_E_PARAM; 48654 } 48655 #if defined(BCM_KATANA2_SUPPORT) 48656 if (SOC_IS_KATANA2(unit)) { 48657 #if defined(BCM_SABER2_SUPPORT) 48658 if (SOC_IS_SABER2(unit)) { 48659 /* Do nothing */ 48660 } else 48661 #endif /* BCM_SABER2_SUPPORT */ 48662 { 48663 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val)); 48664 val_0_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f); 48665 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val)); 48666 val_1_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f); 48667 *value = ((val_1_hi >> 24) & 0xff) | ((val_0_lo & 0xffff) << 8); 48668 rv = BCM_E_NONE; 48669 break; 48670 } 48671 } 48672 #endif /* BCM_KATANA2_SUPPORT */ 48673 if (IS_XL_PORT(unit, port)) { 48674 reg_0 = XLMAC_E2EFC_DATA_HDR_0r; 48675 reg_1 = XLMAC_E2EFC_DATA_HDR_1r; 48676 } else if (IS_CL_PORT(unit, port)) { 48677 reg_0 = CLMAC_E2EFC_DATA_HDR_0r; 48678 reg_1 = CLMAC_E2EFC_DATA_HDR_1r; 48679 } else { 48680 return BCM_E_PARAM; 48681 } 48682 48683 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_1, 48684 port, 0, &val_64)); 48685 data_1 = soc_reg64_field_get(unit, reg_1, 48686 val_64, E2EFC_DATA_HDR_1f); 48687 COMPILER_64_TO_32_HI(val_1_hi, data_1); 48688 /* SA MAC setting across 2 registers */ 48689 COMPILER_64_ZERO(val_64); 48690 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_0, 48691 port, 0, &val_64)); 48692 data_0 = soc_reg64_field_get(unit, reg_0, 48693 val_64, E2EFC_DATA_HDR_0f); 48694 COMPILER_64_TO_32_LO(val_0_lo, data_0); 48695 *value = ((val_1_hi >> 24) & 0xff) | ((val_0_lo & 0xffff) << 8); 48696 rv = BCM_E_NONE; 48697 } 48698 break; 48699 /* Lower 3 bytes of Source MAC address */ 48700 case bcmPortControlE2EFCSrcMacNonOui: 48701 if (soc_feature(unit, soc_feature_e2efc)) { 48702 uint32 val_hi; 48703 uint64 val_64, data_1; 48704 soc_reg_t reg; 48705 #if defined(BCM_KATANA2_SUPPORT) 48706 uint32 val; 48707 #endif 48708 if (!IS_HG_PORT(unit, port)) { 48709 LOG_ERROR( 48710 BSL_LS_BCM_PORT, 48711 (BSL_META_U(unit, 48712 "Error: unit %d port %d is not a Higig port. " 48713 "E2EFC messages can only be transmitted to " 48714 "or received from Higig ports.\n"), 48715 unit, port)); 48716 return BCM_E_PARAM; 48717 } 48718 #if defined(BCM_KATANA2_SUPPORT) 48719 if (SOC_IS_KATANA2(unit)) { 48720 #if defined(BCM_SABER2_SUPPORT) 48721 if (SOC_IS_SABER2(unit)) { 48722 /* Do nothing */ 48723 } else 48724 #endif /* BCM_SABER2_SUPPORT */ 48725 { 48726 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val)); 48727 val_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f); 48728 *value = val_hi & 0xffffff; 48729 rv = BCM_E_NONE; 48730 break; 48731 } 48732 } 48733 #endif /* BCM_KATANA2_SUPPORT */ 48734 48735 if (IS_XL_PORT(unit, port)) { 48736 reg = XLMAC_E2EFC_DATA_HDR_1r; 48737 } else if (IS_CL_PORT(unit, port)) { 48738 reg = CLMAC_E2EFC_DATA_HDR_1r; 48739 } else { 48740 return BCM_E_PARAM; 48741 } 48742 48743 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, 48744 port, 0, &val_64)); 48745 data_1 = soc_reg64_field_get(unit, reg, 48746 val_64, E2EFC_DATA_HDR_1f); 48747 COMPILER_64_TO_32_HI(val_hi, data_1); 48748 *value = val_hi & 0xffffff; 48749 rv = BCM_E_NONE; 48750 } 48751 break; 48752 case bcmPortControlE2EFCEtherType: 48753 if (soc_feature(unit, soc_feature_e2efc)) { 48754 uint32 val_lo; 48755 uint64 val_64, data_1; 48756 soc_reg_t reg; 48757 #if defined(BCM_KATANA2_SUPPORT) 48758 uint32 val; 48759 #endif 48760 if (!IS_HG_PORT(unit, port)) { 48761 LOG_ERROR( 48762 BSL_LS_BCM_PORT, 48763 (BSL_META_U(unit, 48764 "Error: unit %d port %d is not a Higig port. " 48765 "E2EFC messages can only be transmitted to " 48766 "or received from Higig ports.\n"), 48767 unit, port)); 48768 return BCM_E_PARAM; 48769 } 48770 #if defined(BCM_KATANA2_SUPPORT) 48771 if (SOC_IS_KATANA2(unit)) { 48772 #if defined(BCM_SABER2_SUPPORT) 48773 if (SOC_IS_SABER2(unit)) { 48774 /* Do nothing */ 48775 } else 48776 #endif /* BCM_SABER2_SUPPORT */ 48777 { 48778 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val)); 48779 val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f); 48780 *value = (val_lo >> 16) & 0xffff; 48781 rv = BCM_E_NONE; 48782 break; 48783 } 48784 } 48785 #endif /* BCM_KATANA2_SUPPORT */ 48786 if (IS_XL_PORT(unit, port)) { 48787 reg = XLMAC_E2EFC_DATA_HDR_1r; 48788 } else if (IS_CL_PORT(unit, port)) { 48789 reg = CLMAC_E2EFC_DATA_HDR_1r; 48790 } else { 48791 return BCM_E_PARAM; 48792 } 48793 48794 BCM_IF_ERROR_RETURN( 48795 soc_reg_get(unit, reg, port, 0, &val_64)); 48796 data_1 = soc_reg64_field_get(unit, reg, 48797 val_64, E2EFC_DATA_HDR_1f); 48798 COMPILER_64_TO_32_LO(val_lo, data_1); 48799 *value = (val_lo >> 16) & 0xffff; 48800 rv = BCM_E_NONE; 48801 } 48802 break; 48803 case bcmPortControlE2EFCOpcode: 48804 if (soc_feature(unit, soc_feature_e2efc)) { 48805 uint32 val_lo; 48806 uint64 val_64, data_1; 48807 soc_reg_t reg; 48808 #if defined(BCM_KATANA2_SUPPORT) 48809 uint32 val; 48810 #endif 48811 if (!IS_HG_PORT(unit, port)) { 48812 LOG_ERROR( 48813 BSL_LS_BCM_PORT, 48814 (BSL_META_U(unit, 48815 "Error: unit %d port %d is not a Higig port. " 48816 "E2EFC messages can only be transmitted to " 48817 "or received from Higig ports.\n"), 48818 unit, port)); 48819 return BCM_E_PARAM; 48820 } 48821 #if defined(BCM_KATANA2_SUPPORT) 48822 if (SOC_IS_KATANA2(unit)) { 48823 #if defined(BCM_SABER2_SUPPORT) 48824 if (SOC_IS_SABER2(unit)) { 48825 /* Do nothing */ 48826 } else 48827 #endif /* BCM_SABER2_SUPPORT */ 48828 { 48829 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val)); 48830 val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f); 48831 *value = val_lo & 0xffff; 48832 rv = BCM_E_NONE; 48833 break; 48834 } 48835 } 48836 #endif /* BCM_KATANA2_SUPPORT */ 48837 if (IS_XL_PORT(unit, port)) { 48838 reg = XLMAC_E2EFC_DATA_HDR_1r; 48839 } else if (IS_CL_PORT(unit, port)) { 48840 reg = CLMAC_E2EFC_DATA_HDR_1r; 48841 } else { 48842 return BCM_E_PARAM; 48843 } 48844 48845 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, 48846 port, 0, &val_64)); 48847 data_1 = soc_reg64_field_get(unit, reg, 48848 val_64, E2EFC_DATA_HDR_1f); 48849 COMPILER_64_TO_32_LO(val_lo, data_1); 48850 *value = val_lo & 0xffff; 48851 rv = BCM_E_NONE; 48852 } 48853 break; 48854 case bcmPortControlIntEnable: 48855 #if defined(BCM_TOMAHAWK3_SUPPORT) 48856 if (soc_feature(unit, soc_feature_inband_network_telemetry)) { 48857 rv = _bcm_esw_port_tab_get(unit, port, INT_ENABLEf, value); 48858 } 48859 #endif 48860 break; 48861 case bcmPortControlIntTurnaround: 48862 #if defined(BCM_TOMAHAWK3_SUPPORT) 48863 if (soc_feature(unit, soc_feature_inband_network_telemetry)) { 48864 SOC_IF_ERROR_RETURN 48865 (READ_INT_TURNAROUND_EN_BMAPm(unit, MEM_BLOCK_ANY, 0, 48866 &int_turnaround_en_bmap_entry)); 48867 soc_mem_pbmp_field_get(unit, INT_TURNAROUND_EN_BMAPm, 48868 &int_turnaround_en_bmap_entry, PORT_BITMAPf, &pbmp); 48869 *value = 0; 48870 if (SOC_PBMP_MEMBER(pbmp, port)) { 48871 *value = 1; 48872 } 48873 48874 rv = BCM_E_NONE; 48875 } 48876 #endif 48877 break; 48878 case bcmPortControlObmClassifierPriority: 48879 case bcmPortControlObmClassifierEnableDscp: 48880 case bcmPortControlObmClassifierEnableMpls: 48881 case bcmPortControlObmClassifierEnableEtag: 48882 case bcmPortControlObmClassifierEtagEthertype: 48883 case bcmPortControlObmClassifierVntagEthertype: 48884 48885 #if defined(BCM_MONTEREY_SUPPORT) 48886 if (SOC_IS_MONTEREY(unit)) { 48887 rv = bcm_mn_obm_classifier_port_control_get(unit, port, type, value); 48888 } else 48889 #endif 48890 #if defined(BCM_APACHE_SUPPORT) 48891 if (SOC_IS_APACHE(unit)) { 48892 rv = bcm_apache_obm_classifier_port_control_get(unit, port, type, value); 48893 } else 48894 #endif 48895 #if defined(BCM_HELIX5_SUPPORT) 48896 if (SOC_IS_HELIX5(unit)) { 48897 rv = bcm_hx5_obm_classifier_port_control_get(unit, port, type, value); 48898 } else 48899 #endif 48900 #if defined(BCM_TRIDENT3_SUPPORT) 48901 if (soc_feature(unit, soc_feature_td3_style_obm_classifier_map)) { 48902 rv = bcm_td3_obm_classifier_port_control_get(unit, port, type, value); 48903 } else 48904 #endif 48905 { 48906 rv = BCM_E_UNAVAIL; 48907 } 48908 break; 48909 case bcmPortControlObmClassifierInternal: 48910 #if defined(BCM_MONTEREY_SUPPORT) 48911 if (SOC_IS_MONTEREY(unit)) { 48912 rv = bcm_mn_obm_classifier_port_control_get(unit, port, type, value); 48913 } else 48914 #endif 48915 { 48916 rv = BCM_E_UNAVAIL; 48917 } 48918 break; 48919 48920 case bcmPortControlWirelessCosMapSelect: 48921 #if defined(BCM_HELIX5_SUPPORT) 48922 if (SOC_IS_HELIX5(unit) || SOC_IS_HURRICANE4(unit)) { 48923 rv = _bcm_esw_port_tab_get(unit, port, WIRED_WIRELESSf, value); 48924 } else 48925 #endif 48926 { 48927 rv = BCM_E_UNAVAIL; 48928 } 48929 break; 48930 48931 case bcmPortControlHiGigCosSelect: 48932 #if defined(BCM_HURRICANE4_SUPPORT) 48933 if (SOC_IS_HURRICANE4(unit)) { 48934 rv = bcm_hr4_hgcos_select_port_control_get(unit, port, type, value); 48935 } else 48936 #endif 48937 #if defined(BCM_HELIX5_SUPPORT) 48938 if (SOC_IS_HELIX5(unit)) { 48939 rv = bcm_hx5_hgcos_select_port_control_get(unit, port, type, value); 48940 } else 48941 #endif 48942 { 48943 rv = BCM_E_UNAVAIL; 48944 } 48945 break; 48946 case bcmPortControlInternalLoopback: 48947 #ifdef BCM_TRIDENT3_SUPPORT 48948 if (SOC_IS_TRIDENT3X(unit)) { 48949 int port_type; 48950 rv = _bcm_esw_port_tab_get(unit, port, PORT_TYPEf, &port_type); 48951 (port_type == 2) ? (*value = 1) : (*value = 0); 48952 } else 48953 #endif 48954 { 48955 rv = BCM_E_UNAVAIL; 48956 } 48957 break; 48958 #ifdef BCM_MONTEREY_SUPPORT 48959 case bcmPortControlObmInterruptTypeDropPreempt : 48960 case bcmPortControlObmInterruptTypeOverflowPreempt : 48961 case bcmPortControlObmInterruptTypeDropExpress : 48962 case bcmPortControlObmInterruptTypeOverflowExpress : 48963 if (SOC_IS_MONTEREY(unit)) { 48964 rv = bcm_mn_obm_interrupt_port_control_get(unit, port, type, value); 48965 48966 }else 48967 #endif 48968 { 48969 rv = BCM_E_UNAVAIL; 48970 } 48971 break; 48972 case bcmPortControlRuntThreshold: 48973 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 48974 SOC_MAC_CONTROL_RX_RUNT_THRESHOLD, value); 48975 break; 48976 case bcmPortControlPacketProcssingPort: 48977 #ifdef BCM_TRIDENT3_SUPPORT 48978 if (soc_feature(unit, soc_feature_pp_port_control)) { 48979 rv = bcmi_td3_port_pp_num_get(unit, port, value); 48980 } else 48981 #endif /* BCM_TRIDENT3_SUPPORT */ 48982 { 48983 rv = BCM_E_UNAVAIL; 48984 } 48985 break; 48986 default: 48987 break; 48988 } 48989 48990 if (BCM_SUCCESS(rv)) { 48991 LOG_INFO(BSL_LS_BCM_PORT, 48992 (BSL_META_U(unit, 48993 "bcm_port_control_get: u=%d p=%d v=%d\n"), 48994 unit, port, *value)); 48995 } else { 48996 /* On error, the value is not guaranteed valid */ 48997 LOG_INFO(BSL_LS_BCM_PORT, 48998 (BSL_META_U(unit, 48999 "bcm_port_control_get failure: u=%d p=%d: %s\n"), 49000 unit, port, bcm_errmsg(rv))); 49001 } 49002 49003 return rv; 49004 } 49005 49006 /* 49007 * Function: 49008 * bcm_esw_port_mac_failover_notify 49009 * Description: 49010 * disable RX routine on MAC 49011 * note: omitting XLMAC since it should not be disabled during failover 49012 * Parameters: 49013 * unit - Device number 49014 * port - Port number 49015 * Return Value: 49016 * BCM_E_NONE 49017 * BCM_E_UNAVAIL - Functionality not available 49018 */ 49019 int 49020 _bcm_esw_port_mac_failover_notify(int unit, bcm_port_t port) 49021 { 49022 int rv = BCM_E_NONE; 49023 49024 if (!SOC_PORT_USE_PORTCTRL(unit, port)) { 49025 /* disable RX for MAC and XMAC controller. 49026 for TD2, lag failover has been implemented within XLMAC; 49027 thus, XLMAC rx should not be disabled during failover */ 49028 PORT_LOCK(unit); 49029 rv = (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 49030 SOC_MAC_CONTROL_FAILOVER_RX_SET, FALSE)); 49031 PORT_UNLOCK(unit); 49032 } 49033 return rv; 49034 } 49035 49036 49037 /* 49038 * Function: 49039 * _bcm_esw_port_policer_get 49040 * Purpose: 49041 * Internal function to Retrieve the Policer ID accociated 49042 * with specified physical port. 49043 * Parameters: 49044 * Unit - (IN) unit number 49045 * port - (IN) Port Number 49046 * policer_id - (OUT) policer Id 49047 * Returns: 49048 * BCM_E_XXX 49049 */ 49050 int _bcm_esw_port_policer_get( 49051 int unit, 49052 bcm_port_t port, 49053 bcm_policer_t *policer_id) 49054 { 49055 int rv = BCM_E_NONE; 49056 49057 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 49058 defined(BCM_GREYHOUND2_SUPPORT) 49059 int index = 0; 49060 int offset_mode = 0; 49061 49062 BCM_IF_ERROR_RETURN 49063 (_bcm_esw_port_config_get(unit, port, 49064 _bcmPortSvcMeterIndex, &index)); 49065 BCM_IF_ERROR_RETURN 49066 (_bcm_esw_port_config_get(unit, port, 49067 _bcmPortSvcMeterOffsetMode, &offset_mode)); 49068 _bcm_esw_get_policer_id_from_index_offset(unit, index, 49069 offset_mode, policer_id); 49070 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 49071 BCM_GREYHOUND2_SUPPORT */ 49072 return rv; 49073 } 49074 49075 /* 49076 * Function: 49077 * bcm_esw_port_policer_get 49078 * Purpose: 49079 * Retrieve the Policer ID accociated for the specified physical port. 49080 * Parameters: 49081 * Unit - (IN) unit number 49082 * port - (IN) Port Number 49083 * policer_id - (OUT) policer Id 49084 * Returns: 49085 * BCM_E_XXX 49086 */ 49087 int bcm_esw_port_policer_get( 49088 int unit, 49089 bcm_port_t port, 49090 bcm_policer_t *policer_id) 49091 { 49092 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 49093 defined(BCM_GREYHOUND2_SUPPORT) 49094 int rv = BCM_E_NONE; 49095 49096 /* Make sure port module is initialized. */ 49097 PORT_INIT(unit); 49098 if (!soc_feature(unit, soc_feature_global_meter)) { 49099 return BCM_E_UNAVAIL; 49100 } 49101 BCM_IF_ERROR_RETURN(_check_global_meter_init(unit)); 49102 rv = _bcm_esw_port_gport_validate(unit, port, &port); 49103 BCM_IF_ERROR_RETURN(rv); 49104 rv = _bcm_esw_port_policer_get(unit, port, policer_id); 49105 return rv; 49106 #else /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 49107 BCM_GREYHOUND2_SUPPORT */ 49108 return BCM_E_UNAVAIL; 49109 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 49110 BCM_GREYHOUND2_SUPPORT */ 49111 } 49112 49113 #if defined(BCM_GLOBAL_METER_V2_SUPPORT) 49114 /* 49115 * Function: 49116 * bcmi_esw_port_policer_set 49117 * Purpose: 49118 * Set the Policer ID accociated for the specified physical port. 49119 * Parameters: 49120 * Unit - (IN) unit number 49121 * port - (IN) Port Number 49122 * policer_id - (IN) policer Id 49123 * Returns: 49124 * BCM_E_XXX 49125 */ 49126 STATIC int 49127 bcmi_esw_port_policer_set( 49128 int unit, 49129 bcm_port_t port, 49130 bcm_policer_t policer_id) 49131 { 49132 int rv = BCM_E_UNAVAIL; 49133 #if defined(BCM_GREYHOUND2_SUPPORT) 49134 int index = 0; 49135 int offset_mode = 0; 49136 bcm_policer_t current_policer_id = 0; 49137 49138 if (SOC_IS_GREYHOUND2(unit)) { 49139 /* Make sure port module is initialized. */ 49140 PORT_INIT(unit); 49141 if (!soc_feature(unit, soc_feature_global_meter)) { 49142 return BCM_E_UNAVAIL; 49143 } 49144 BCM_IF_ERROR_RETURN(_check_global_meter_init(unit)); 49145 rv = _bcm_esw_port_gport_validate(unit, port, &port); 49146 BCM_IF_ERROR_RETURN(rv); 49147 /* validate policer id */ 49148 rv = _bcm_esw_policer_validate(unit, &policer_id); 49149 if (BCM_FAILURE(rv)) { 49150 LOG_VERBOSE(BSL_LS_BCM_PORT, 49151 (BSL_META_U(unit, 49152 "Invalid policer id passed: %x \n"), 49153 policer_id)); 49154 return (rv); 49155 } 49156 /* get the policer id that is currently configured */ 49157 rv = _bcm_esw_port_policer_get(unit, port, ¤t_policer_id); 49158 if (BCM_FAILURE(rv)) { 49159 LOG_VERBOSE(BSL_LS_BCM_PORT, 49160 (BSL_META_U(unit, 49161 "Unabel to get the current policer configured \n"))); 49162 return (rv); 49163 } 49164 49165 /* Set policer id */ 49166 BCM_IF_ERROR_RETURN( 49167 _bcm_esw_get_policer_table_index(unit, policer_id, &index)); 49168 BCM_IF_ERROR_RETURN( 49169 _bcm_esw_policer_offset_mode_get(unit, policer_id, &offset_mode)); 49170 49171 BCM_IF_ERROR_RETURN( 49172 _bcm_esw_port_config_set( 49173 unit, port, _bcmPortSvcMeterIndex, index)); 49174 BCM_IF_ERROR_RETURN( 49175 _bcm_esw_port_config_set( 49176 unit, port, _bcmPortSvcMeterOffsetMode, offset_mode)); 49177 49178 /* increment new set policer ref_cnt */ 49179 rv = _bcm_esw_policer_increment_ref_count(unit, policer_id); 49180 BCM_IF_ERROR_RETURN(rv); 49181 49182 /* decrement current hw policer ref_cnt */ 49183 rv = _bcm_esw_policer_validate(unit, ¤t_policer_id); 49184 49185 /* Don't need to handle fail case since existed index could be 0 */ 49186 if (BCM_SUCCESS(rv)) { 49187 rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer_id); 49188 BCM_IF_ERROR_RETURN(rv); 49189 } 49190 49191 rv = BCM_E_NONE; 49192 } 49193 #endif /* BCM_GREYHOUND2_SUPPORT */ 49194 return rv; 49195 } 49196 49197 #endif /* BCM_GLOBAL_METER_V2_SUPPORT */ 49198 49199 /* 49200 * Function: 49201 * bcm_esw_port_policer_set 49202 * Purpose: 49203 * Set the Policer ID accociated for the specified physical port. 49204 * Parameters: 49205 * Unit - (IN) unit number 49206 * port - (IN) Port Number 49207 * policer_id - (IN) policer Id 49208 * Returns: 49209 * BCM_E_XXX 49210 */ 49211 int bcm_esw_port_policer_set( 49212 int unit, 49213 bcm_port_t port, 49214 bcm_policer_t policer) 49215 { 49216 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 49217 defined(BCM_APACHE_SUPPORT)) 49218 int rv = BCM_E_NONE; 49219 int index=0; 49220 int offset_mode=0; 49221 bcm_policer_t current_policer = 0; 49222 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 49223 BCM_APACHE_SUPPORT */ 49224 49225 #if defined(BCM_GLOBAL_METER_V2_SUPPORT) 49226 if (soc_feature(unit, soc_feature_global_meter_v2)) { 49227 return bcmi_esw_port_policer_set(unit, port, policer); 49228 } 49229 #endif /* BCM_GLOBAL_METER_V2_SUPPORT */ 49230 49231 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 49232 defined(BCM_APACHE_SUPPORT)) 49233 49234 /* Make sure port module is initialized. */ 49235 PORT_INIT(unit); 49236 if (!soc_feature(unit, soc_feature_global_meter)) { 49237 return BCM_E_UNAVAIL; 49238 } 49239 BCM_IF_ERROR_RETURN(_check_global_meter_init(unit)); 49240 rv = _bcm_esw_port_gport_validate(unit, port, &port); 49241 BCM_IF_ERROR_RETURN(rv); 49242 /* validate policer id */ 49243 rv = _bcm_esw_policer_validate(unit, &policer); 49244 if (BCM_FAILURE(rv)) { 49245 LOG_VERBOSE(BSL_LS_BCM_PORT, 49246 (BSL_META_U(unit, 49247 "Invalid policer id passed: %x \n"), 49248 policer)); 49249 return (rv); 49250 } 49251 /* get the policer id that is currently configured */ 49252 rv = _bcm_esw_port_policer_get(unit, port, ¤t_policer); 49253 if (BCM_FAILURE(rv)) { 49254 LOG_VERBOSE(BSL_LS_BCM_PORT, 49255 (BSL_META_U(unit, 49256 "Unabel to get the current policer configured \n"))); 49257 return (rv); 49258 } 49259 rv = BCM_E_UNAVAIL; 49260 /* Set policer id */ 49261 _bcm_esw_get_policer_table_index(unit, policer, &index); 49262 offset_mode = (((policer) & BCM_POLICER_GLOBAL_METER_MODE_MASK) >> 49263 BCM_POLICER_GLOBAL_METER_MODE_SHIFT); 49264 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) { 49265 if ((offset_mode == 0) && (policer != 0)) { 49266 /* 49267 * Not a Global meter policer, 49268 * policer zero is used to detach already configured policer 49269 */ 49270 return (BCM_E_PARAM); 49271 } 49272 } 49273 if (offset_mode >= 1) { 49274 offset_mode = offset_mode - 1; 49275 } 49276 if (index >= soc_mem_index_count(unit,SVM_METER_TABLEm)) { 49277 LOG_VERBOSE(BSL_LS_BCM_PORT, 49278 (BSL_META_U(unit, 49279 "Invalid table index\n"))); 49280 return BCM_E_PARAM; 49281 } 49282 if (offset_mode >= (soc_mem_index_count(unit,SVM_OFFSET_TABLEm) >> 49283 BCM_POLICER_SVC_METER_OFFSET_TABLE_KEY_SIZE)) { 49284 LOG_VERBOSE(BSL_LS_BCM_PORT, 49285 (BSL_META_U(unit, 49286 "Invalid offset mode\n"))); 49287 return BCM_E_PARAM; 49288 } 49289 BCM_IF_ERROR_RETURN( 49290 _bcm_esw_port_config_set(unit, port, 49291 _bcmPortSvcMeterIndex, index)); 49292 BCM_IF_ERROR_RETURN( 49293 _bcm_esw_port_config_set(unit, port, 49294 _bcmPortSvcMeterOffsetMode, offset_mode)); 49295 /* decrement current policer if any */ 49296 if ((current_policer & BCM_POLICER_GLOBAL_METER_INDEX_MASK) > 0) { 49297 rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer); 49298 BCM_IF_ERROR_RETURN(rv); 49299 } 49300 /* increment policer reference count */ 49301 if ((policer & BCM_POLICER_GLOBAL_METER_INDEX_MASK) > 0 ) { 49302 rv = _bcm_esw_policer_increment_ref_count(unit, policer); 49303 BCM_IF_ERROR_RETURN(rv); 49304 } 49305 return rv; 49306 #else /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 49307 BCM_APACHE_SUPPORT */ 49308 return BCM_E_UNAVAIL; 49309 #endif 49310 } 49311 49312 /* 49313 * Function: 49314 * bcm_port_vlan_inner_tag_set 49315 * Purpose: 49316 * Set the inner tag to be added to the packet. 49317 * Parameters: 49318 * unit - (IN) BCM unit. 49319 * port - (IN) Port number. 49320 * inner_tag - (IN) Inner tag. 49321 * Priority[15:13] CFI[12] VLAN ID [11:0] 49322 * Returns: 49323 * BCM_E_XXX 49324 */ 49325 int 49326 bcm_esw_port_vlan_inner_tag_set(int unit, bcm_port_t port, uint16 inner_tag) 49327 { 49328 int rv; 49329 49330 /* Make sure port module is initialized. */ 49331 PORT_INIT(unit); 49332 49333 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 49334 49335 rv = BCM_E_UNAVAIL; 49336 49337 #ifdef BCM_TRX_SUPPORT 49338 if (SOC_IS_TRX(unit)) { 49339 bcm_vlan_action_set_t action; 49340 49341 if (!soc_feature(unit, soc_feature_vlan_action)) { 49342 return BCM_E_UNAVAIL; 49343 } 49344 49345 PORT_LOCK(unit); 49346 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 49347 (_bcm_trx_vlan_port_default_action_get(unit, port, &action)); 49348 action.new_inner_vlan = BCM_VLAN_CTRL_ID(inner_tag); 49349 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 49350 if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 49351 rv =_bcm_trx_vlan_port_default_action_profile_set(unit, port, &action); 49352 } else 49353 #endif 49354 { 49355 rv = _bcm_trx_vlan_port_default_action_set(unit, port, &action); 49356 } 49357 PORT_UNLOCK(unit); 49358 return rv; 49359 } 49360 #endif 49361 49362 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 49363 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 49364 PORT_LOCK(unit); 49365 49366 rv = soc_reg_field32_modify(unit, EGR_SRC_PORTr, port, 49367 INNER_TAGf, inner_tag); 49368 PORT_UNLOCK(unit); 49369 } 49370 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */ 49371 49372 return rv; 49373 } 49374 49375 /* 49376 * Function: 49377 * bcm_port_vlan_inner_tag_get 49378 * Purpose: 49379 * Get the inner tag to be added to the packet. 49380 * Parameters: 49381 * unit - (IN) BCM unit. 49382 * port - (IN) Port number. 49383 * inner_tag - (OUT) Inner tag. 49384 * Priority[15:13] CFI[12] VLAN ID [11:0] 49385 * Returns: 49386 * BCM_E_XXX 49387 */ 49388 int 49389 bcm_esw_port_vlan_inner_tag_get(int unit, bcm_port_t port, uint16 *inner_tag) 49390 { 49391 int rv; 49392 49393 /* Make sure port module is initialized. */ 49394 PORT_INIT(unit); 49395 49396 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 49397 49398 rv = BCM_E_UNAVAIL; 49399 49400 #ifdef BCM_TRX_SUPPORT 49401 if (SOC_IS_TRX(unit)) { 49402 bcm_vlan_action_set_t action; 49403 49404 if (!soc_feature(unit, soc_feature_vlan_action)) { 49405 return BCM_E_UNAVAIL; 49406 } 49407 49408 PORT_LOCK(unit); 49409 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 49410 (_bcm_trx_vlan_port_default_action_get(unit, port, &action)); 49411 *inner_tag = action.new_inner_vlan; 49412 PORT_UNLOCK(unit); 49413 return BCM_E_NONE; 49414 } 49415 #endif 49416 49417 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 49418 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 49419 uint32 value; 49420 49421 rv = READ_EGR_SRC_PORTr(unit, port, &value); 49422 *inner_tag = soc_reg_field_get(unit, EGR_SRC_PORTr, value, 49423 INNER_TAGf); 49424 } 49425 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */ 49426 return rv; 49427 } 49428 49429 #if defined(INCLUDE_L3) && defined(BCM_TRIDENT_SUPPORT) 49430 STATIC int 49431 _bcm_esw_port_vp_type_id_get(int unit, bcm_port_t port, 49432 _bcm_vp_type_e *vp_type, int *vp) 49433 { 49434 *vp = -1; 49435 *vp_type = _bcmVpTypeAny; 49436 49437 if (BCM_GPORT_IS_MIM_PORT(port) && soc_feature(unit, soc_feature_mim)) { 49438 *vp_type = _bcmVpTypeMim; 49439 *vp = BCM_GPORT_MIM_PORT_ID_GET(port); 49440 } else if (BCM_GPORT_IS_TRILL_PORT(port) && soc_feature(unit, soc_feature_trill)) { 49441 *vp_type = _bcmVpTypeTrill; 49442 *vp = BCM_GPORT_TRILL_PORT_ID_GET(port); 49443 } else if (BCM_GPORT_IS_VXLAN_PORT(port) && soc_feature(unit, soc_feature_vxlan)) { 49444 *vp_type = _bcmVpTypeVxlan; 49445 *vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 49446 } else if (BCM_GPORT_IS_MPLS_PORT(port) && soc_feature(unit, soc_feature_mpls)) { 49447 *vp_type = _bcmVpTypeMpls; 49448 *vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 49449 } else if (BCM_GPORT_IS_EXTENDER_PORT(port) && soc_feature(unit, soc_feature_port_extension)) { 49450 *vp_type = _bcmVpTypeExtender; 49451 *vp = BCM_GPORT_EXTENDER_PORT_ID_GET(port); 49452 } else if (BCM_GPORT_IS_WLAN_PORT(port) && soc_feature(unit, soc_feature_wlan)) { 49453 *vp_type = _bcmVpTypeWlan; 49454 *vp = BCM_GPORT_WLAN_PORT_ID_GET(port); 49455 } else if (BCM_GPORT_IS_NIV_PORT(port) && soc_feature(unit, soc_feature_niv)) { 49456 *vp_type = _bcmVpTypeNiv; 49457 *vp = BCM_GPORT_NIV_PORT_ID_GET(port); 49458 } else if (BCM_GPORT_IS_VLAN_PORT(port) && soc_feature(unit, soc_feature_vlan_vp)) { 49459 *vp_type = _bcmVpTypeVlan; 49460 *vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 49461 } else if (BCM_GPORT_IS_L2GRE_PORT(port) && soc_feature(unit, soc_feature_l2gre)) { 49462 *vp_type = _bcmVpTypeL2Gre; 49463 *vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 49464 } else if (BCM_GPORT_IS_FLOW_PORT(port) && soc_feature(unit, soc_feature_flex_flow)) { 49465 *vp_type = _bcmVpTypeFlow; 49466 *vp = BCM_GPORT_FLOW_PORT_ID_GET(port); 49467 } else if (BCM_GPORT_IS_TRUNK(port) && soc_feature(unit, soc_feature_vp_lag)) { 49468 *vp_type = _bcmVpTypeVpLag; 49469 BCM_IF_ERROR_RETURN( 49470 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port), 49471 vp)); 49472 } 49473 return BCM_E_NONE; 49474 } 49475 #endif 49476 49477 /* 49478 * Function : 49479 * bcm_port_class_set 49480 * Description : 49481 * Set the ports class ID. Ports with the 49482 * same class ID can be treated as a group in 49483 * field processing and VLAN translation. 49484 * Parameters : 49485 * (IN) unit - BCM device number 49486 * (IN) port - Device or logical port number 49487 * (IN) pclass - Classification type 49488 * (IN) pclass_id - New class ID of the port. 49489 * Returns : 49490 * BCM_E_NONE - Success 49491 * BCM_E_XXX - Failed 49492 */ 49493 int 49494 bcm_esw_port_class_set(int unit, bcm_port_t port, 49495 bcm_port_class_t pclass, uint32 pclass_id) 49496 { 49497 int rv = BCM_E_UNAVAIL; 49498 bcm_port_t port_out = port; 49499 #if defined(BCM_TOMAHAWK_SUPPORT) 49500 soc_mem_t port_mem = PORT_TABm; 49501 #endif 49502 49503 /* Make sure port module is initialized. */ 49504 PORT_INIT(unit); 49505 49506 #if defined(INCLUDE_L3) 49507 #if defined(BCM_TRIDENT_SUPPORT) 49508 if (BCM_GPORT_IS_SET(port)) { 49509 int vp; 49510 _bcm_vp_type_e vp_type; 49511 BCM_IF_ERROR_RETURN(_bcm_esw_port_vp_type_id_get(unit, port, 49512 &vp_type, &vp)); 49513 switch (pclass) { 49514 case bcmPortClassFieldIngress: 49515 if (vp_type == _bcmVpTypeMim || vp_type == _bcmVpTypeTrill || 49516 vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeMpls || 49517 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeWlan || 49518 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeVlan || 49519 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeVpLag || 49520 vp_type == _bcmVpTypeFlow){ 49521 49522 if (!_bcm_vp_used_get(unit, vp, vp_type)) { 49523 return BCM_E_PORT; 49524 } 49525 rv = soc_mem_field32_modify(unit, SOURCE_VPm, vp, CLASS_IDf, pclass_id); 49526 return rv; 49527 } 49528 break; 49529 case bcmPortClassVlanTranslateEgress: 49530 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 49531 /* class_id of DVP used in egress VLAN translation */ 49532 /* class_id of DVP used in egress VLAN translation */ 49533 if ((vp_type == _bcmVpTypeVxlan) || (vp_type == _bcmVpTypeMim) || 49534 (vp_type == _bcmVpTypeMpls) || (vp_type == _bcmVpTypeL2Gre) || 49535 (vp_type == _bcmVpTypeFlow) ) { 49536 int network_port; 49537 source_vp_entry_t svp; 49538 _bcm_vp_info_t vp_info; 49539 49540 if (!_bcm_vp_used_get(unit, vp, vp_type)) { 49541 return BCM_E_PORT; 49542 } 49543 BCM_IF_ERROR_RETURN (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 49544 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 49545 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 49546 network_port = TRUE; 49547 } else { 49548 network_port = FALSE; 49549 } 49550 49551 if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, 49552 VT_DVP_GROUP_IDf) 49553 #if defined(BCM_TRIDENT3_SUPPORT) 49554 || (SOC_IS_TRIDENT3X(unit) && SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, 49555 COMMON__VT_DVP_GROUP_IDf)) 49556 #endif 49557 ) { 49558 if ((network_port) && (vp_type == _bcmVpTypeVxlan)) { 49559 rv = soc_mem_field32_modify(unit, EGR_DVP_ATTRIBUTEm, vp, 49560 VXLAN__VT_DVP_GROUP_IDf, pclass_id); 49561 } else if ((network_port) && (vp_type == _bcmVpTypeL2Gre)) { 49562 rv = soc_mem_field32_modify(unit, EGR_DVP_ATTRIBUTEm, vp, 49563 L2GRE__VT_DVP_GROUP_IDf, pclass_id); 49564 } else { 49565 rv = soc_mem_field32_modify(unit, EGR_DVP_ATTRIBUTEm, vp, 49566 COMMON__VT_DVP_GROUP_IDf, pclass_id); 49567 } 49568 } else { 49569 return BCM_E_UNAVAIL; 49570 } 49571 return rv; 49572 } 49573 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 49574 break; 49575 #if defined(BCM_TOMAHAWK_SUPPORT) 49576 case bcmPortClassFieldIngressSourceGport: 49577 if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 49578 return BCM_E_UNAVAIL; 49579 } 49580 if (pclass_id > 33) { 49581 return BCM_E_PARAM; 49582 } 49583 if (vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeVlan || 49584 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeVpLag || 49585 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeMpls || 49586 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeMim || 49587 vp_type == _bcmVpTypeFlow) { 49588 if (!_bcm_vp_used_get(unit, vp, vp_type)) { 49589 return BCM_E_PORT; 49590 } 49591 rv = soc_mem_field32_modify(unit, SOURCE_VPm, vp, 49592 IPBM_INDEXf, pclass_id); 49593 return rv; 49594 } 49595 break; 49596 #endif /* BCM_TOMAHAWK_SUPPORT */ 49597 49598 default: 49599 break; 49600 } 49601 } 49602 #endif /* BCM_TRIDENT_SUPPORT*/ 49603 #endif /* INCLUDE_L3 */ 49604 49605 #ifdef BCM_XGS3_SWITCH_SUPPORT 49606 if (SOC_IS_XGS3_SWITCH(unit)) { 49607 #if defined(BCM_TOMAHAWK_SUPPORT) 49608 bcm_module_t mod; 49609 bcm_trunk_t tid_out; 49610 int id_out; 49611 int index; 49612 #endif /* BCM_TOMAHAWK_SUPPORT */ 49613 switch (pclass) { 49614 case bcmPortClassFieldIngressSystemPort: 49615 #if defined(BCM_TOMAHAWK_SUPPORT) 49616 if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 49617 return BCM_E_UNAVAIL; 49618 } 49619 if (pclass_id > 33) { 49620 #if defined(BCM_TRIDENT3_SUPPORT) 49621 if (!SOC_IS_TRIDENT3X(unit) || 49622 soc_feature(unit, soc_feature_ifp_no_inports_support)) 49623 #endif 49624 return BCM_E_PARAM; 49625 } 49626 if (BCM_GPORT_IS_SET(port)) { 49627 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 49628 &mod, &port_out, &tid_out, &id_out)); 49629 if (-1 != tid_out || -1 != id_out) { 49630 return BCM_E_PORT; 49631 } 49632 } else { 49633 if (!SOC_PORT_VALID(unit, port)) { 49634 return BCM_E_PORT; 49635 } 49636 port_out = port; 49637 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod)); 49638 } 49639 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, 49640 mod, port_out, &index)); 49641 #if defined(BCM_TRIDENT3_SUPPORT) 49642 if (SOC_IS_TRIDENT3X(unit) && 49643 !soc_feature(unit, soc_feature_ifp_no_inports_support)) { 49644 rv = bcm_td3_port_ipbm_opaque_set(unit, index, pclass_id); 49645 return rv; 49646 } 49647 #endif 49648 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, index, 49649 IPBM_INDEXf, pclass_id); 49650 return rv; 49651 #endif /* BCM_TOMAHAWK_SUPPORT */ 49652 break; 49653 default: 49654 break; 49655 } 49656 } 49657 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 49658 /* 49659 * Skip port validation if soc_feature_shg_support_remote_port 49660 * is true and ptype is bcmPortClassFieldIngress. 49661 */ 49662 if (!(soc_feature(unit, soc_feature_shg_support_remote_port) && 49663 (pclass == bcmPortClassFieldIngress))) { 49664 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port_out)); 49665 } 49666 49667 49668 #ifdef BCM_XGS3_SWITCH_SUPPORT 49669 if (SOC_IS_XGS3_SWITCH(unit)) { 49670 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 49671 int port_class_id; 49672 soc_reg_t egr_port_reg; 49673 egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 49674 SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) || 49675 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ? 49676 EGR_PORT_64r : EGR_PORTr; 49677 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */ 49678 49679 switch (pclass) { 49680 case bcmPortClassFieldIngressGroupSel: 49681 #if defined(BCM_TOMAHAWK_SUPPORT) 49682 if (SOC_IS_TRIDENT3X(unit)) { 49683 port_mem = LPORT_TABm; 49684 } 49685 if (soc_mem_field_valid(unit, port_mem, IFP_KEY_SEL_CLASS_IDf)) { 49686 rv = soc_mem_field_pbmp_fit(unit, port_mem, 49687 IFP_KEY_SEL_CLASS_IDf, &pclass_id); 49688 if (rv == BCM_E_NONE) { 49689 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 49690 IFP_KEY_SEL_CLASS_IDf, pclass_id); 49691 } 49692 } 49693 #endif 49694 break; 49695 case bcmPortClassFieldLookup: 49696 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 49697 if (soc_mem_field_valid(unit, PORT_TABm, VFP_PORT_GROUP_IDf) || 49698 SOC_IS_TRIDENT3X(unit)) { 49699 /* Intentional use of var pclass_id, to be filled here */ 49700 if (soc_mem_field_valid(unit, PORT_TABm, VFP_PORT_GROUP_IDf)) { 49701 /* coverity [callee_ptr_arith] */ 49702 rv = soc_mem_field_pbmp_fit(unit, PORT_TABm, 49703 VFP_PORT_GROUP_IDf, &pclass_id); 49704 } else if (SOC_IS_TRIDENT3X(unit)) { 49705 rv = soc_mem_field_pbmp_fit(unit, LPORT_TABm, 49706 VFP_PORT_GROUP_IDf, &pclass_id); 49707 } 49708 if (rv == BCM_E_NONE) { 49709 port_class_id = (int) pclass_id; 49710 rv = _bcm_esw_port_tab_set(unit, port, 49711 _BCM_CPU_TABS_BOTH, 49712 VFP_PORT_GROUP_IDf, 49713 port_class_id); 49714 } 49715 } 49716 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */ 49717 #if defined(BCM_TRX_SUPPORT) 49718 if ((SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 49719 VFP_PORT_GROUP_IDf)) && 49720 (BCM_SUCCESS(rv))) { 49721 #if defined(BCM_KATANA2_SUPPORT) 49722 if (SOC_IS_KATANA2(unit)) { 49723 rv = _bcm_kt2_source_trunk_map_set(unit, port_out, 49724 VFP_PORT_GROUP_IDf, 49725 pclass_id); 49726 } else 49727 #endif 49728 { 49729 rv = _bcm_trx_source_trunk_map_set(unit, port, 49730 VFP_PORT_GROUP_IDf, 49731 pclass_id); 49732 } 49733 } 49734 #endif /* BCM_TRX_SUPPORT */ 49735 break; 49736 case bcmPortClassVlanTranslateIngress: 49737 #if defined(BCM_TRIDENT2_SUPPORT) 49738 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, PORT_GROUPf)) { 49739 rv = _bcm_trx_source_trunk_map_set(unit, port, 49740 PORT_GROUPf, pclass_id); 49741 } 49742 #endif /* BCM_TRIDENT2_SUPPORT */ 49743 break; 49744 case bcmPortClassFieldIngress: 49745 #if defined(BCM_TRX_SUPPORT) 49746 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, CLASS_IDf)) { 49747 #if defined(BCM_KATANA2_SUPPORT) 49748 if (SOC_IS_KATANA2(unit)) { 49749 rv = _bcm_kt2_source_trunk_map_set(unit, port_out, 49750 CLASS_IDf, pclass_id); 49751 } else 49752 #endif 49753 { 49754 rv = _bcm_trx_source_trunk_map_set(unit, port, 49755 CLASS_IDf, pclass_id); 49756 } 49757 } 49758 #endif /* BCM_TRX_SUPPORT */ 49759 break; 49760 case bcmPortClassFieldEgress: 49761 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 49762 if (soc_reg_field_valid(unit, egr_port_reg, EGR_PORT_GROUP_IDf)) { 49763 rv = soc_reg_field32_modify(unit, egr_port_reg, port_out, 49764 EGR_PORT_GROUP_IDf, pclass_id); 49765 } 49766 #ifdef BCM_TRIDENT_SUPPORT 49767 else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EGR_PORT_GROUP_IDf) || 49768 SOC_IS_TRIDENT3X(unit)) { 49769 rv = _bcm_esw_egr_port_tab_set(unit, port, 49770 EGR_PORT_GROUP_IDf, pclass_id); 49771 } 49772 #endif /* BCM_TRIDENT_SUPPORT */ 49773 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */ 49774 break; 49775 case bcmPortClassVlanTranslateEgress: 49776 #if defined(BCM_TRX_SUPPORT) 49777 if (soc_reg_field_valid(unit, egr_port_reg, VT_PORT_GROUP_IDf)) { 49778 soc_control_t *sc = SOC_CONTROL(unit); 49779 49780 if (sc->soc_flags & SOC_F_PORT_CLASS_BLOCKED) { 49781 return BCM_E_CONFIG; 49782 } 49783 rv = soc_reg_field32_modify(unit, egr_port_reg, port_out, 49784 VT_PORT_GROUP_IDf, pclass_id); 49785 if (BCM_SUCCESS(rv)) { 49786 /* Once port class is changed system will not allow */ 49787 /* To use bcm_vlan_translate_egress */ 49788 sc->soc_flags |= SOC_F_XLATE_EGR_BLOCKED; 49789 } 49790 } 49791 #ifdef BCM_TRIDENT_SUPPORT 49792 else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, VT_PORT_GROUP_IDf) || 49793 SOC_IS_TRIDENT3X(unit)) { 49794 rv = _bcm_esw_egr_port_tab_set(unit, port, 49795 VT_PORT_GROUP_IDf, pclass_id); 49796 } 49797 #endif /* BCM_TRIDENT_SUPPORT */ 49798 #endif /* BCM_TRX_SUPPORT */ 49799 break; 49800 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 49801 case bcmPortClassEgress: 49802 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, CLASS_IDf) || 49803 SOC_IS_TRIDENT3X(unit)) { 49804 rv = _bcm_esw_egr_port_tab_set(unit, port, 49805 CLASS_IDf, pclass_id); 49806 } 49807 break; 49808 #endif 49809 #if defined(BCM_TOMAHAWK_SUPPORT) 49810 case bcmPortClassFieldIngressDevicePort: 49811 if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 49812 return BCM_E_UNAVAIL; 49813 } 49814 if (pclass_id > 33) { 49815 return BCM_E_PARAM; 49816 } 49817 #if defined (BCM_TOMAHAWK3_SUPPORT) 49818 if (SOC_IS_TOMAHAWK3(unit)) { 49819 if (pclass_id > 19) { 49820 return BCM_E_PARAM; 49821 } 49822 } 49823 #endif 49824 49825 if (BCM_GPORT_IS_SET(port)) { 49826 bcm_module_t mod; 49827 bcm_trunk_t tid_out; 49828 int id_out; 49829 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 49830 &mod, &port_out, &tid_out, &id_out)); 49831 if (-1 != tid_out || -1 != id_out) { 49832 return BCM_E_PORT; 49833 } 49834 } else { 49835 if (!SOC_PORT_VALID(unit, port)) { 49836 return BCM_E_PORT; 49837 } 49838 } 49839 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 49840 PORT_IPBM_INDEXf, pclass_id); 49841 break; 49842 #endif /* BCM_TOMAHAWK_SUPPORT */ 49843 default: 49844 rv = BCM_E_PARAM; 49845 } 49846 } 49847 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 49848 49849 return rv; 49850 } 49851 49852 /* 49853 * Function : 49854 * bcm_port_class_get 49855 * Description : 49856 * Get the ports class ID. Ports with the 49857 * same class ID can be treated as a group in 49858 * field processing and VLAN translation. 49859 * Parameters : 49860 * (IN) unit - BCM device number 49861 * (IN) port - Device or logical port number 49862 * (IN) pclass - Classification type 49863 * (OUT) pclass_id - New class ID of the port. 49864 * Returns : 49865 * BCM_E_NONE - Success 49866 * BCM_E_XXX - Failed 49867 */ 49868 int 49869 bcm_esw_port_class_get(int unit, bcm_port_t port, 49870 bcm_port_class_t pclass, uint32 *pclass_id) 49871 { 49872 int rv = BCM_E_UNAVAIL; 49873 bcm_port_t port_out = port; 49874 49875 /* Make sure port module is initialized. */ 49876 PORT_INIT(unit); 49877 49878 #if defined(INCLUDE_L3) 49879 #if defined(BCM_TRIDENT_SUPPORT) 49880 if (BCM_GPORT_IS_SET(port)) { 49881 int vp; 49882 _bcm_vp_type_e vp_type; 49883 source_vp_entry_t entry; 49884 BCM_IF_ERROR_RETURN(_bcm_esw_port_vp_type_id_get(unit, port, 49885 &vp_type, &vp)); 49886 switch (pclass) { 49887 case bcmPortClassFieldIngress: 49888 if (vp_type == _bcmVpTypeMim || vp_type == _bcmVpTypeTrill || 49889 vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeMpls || 49890 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeWlan || 49891 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeVlan || 49892 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeVpLag || 49893 vp_type == _bcmVpTypeFlow){ 49894 49895 if (!_bcm_vp_used_get(unit, vp, vp_type)) { 49896 return BCM_E_PORT; 49897 } 49898 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &entry); 49899 if (BCM_SUCCESS(rv)) { 49900 *pclass_id = soc_mem_field32_get(unit, SOURCE_VPm, 49901 &entry, CLASS_IDf); 49902 } 49903 return rv; 49904 } 49905 break; 49906 case bcmPortClassVlanTranslateEgress: 49907 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 49908 /* class_id of DVP used in egress VLAN translation */ 49909 if ((vp_type == _bcmVpTypeVxlan) || (vp_type == _bcmVpTypeMim) || 49910 (vp_type == _bcmVpTypeMpls) || (vp_type == _bcmVpTypeL2Gre)) { 49911 int network_port; 49912 egr_dvp_attribute_entry_t dvp_entry; 49913 _bcm_vp_info_t vp_info; 49914 49915 if (!_bcm_vp_used_get(unit, vp, vp_type)) { 49916 return BCM_E_PORT; 49917 } 49918 49919 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 49920 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 49921 network_port = TRUE; 49922 } else { 49923 network_port = FALSE; 49924 } 49925 49926 if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, 49927 VT_DVP_GROUP_IDf) 49928 #if defined(BCM_TRIDENT3_SUPPORT) 49929 || (SOC_IS_TRIDENT3X(unit) && SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, 49930 COMMON__VT_DVP_GROUP_IDf)) 49931 #endif 49932 ) { 49933 rv = READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY, 49934 vp, &dvp_entry); 49935 if (BCM_SUCCESS(rv)) { 49936 if ((network_port) && (vp_type == _bcmVpTypeVxlan)) { 49937 *pclass_id = soc_mem_field32_get 49938 (unit, EGR_DVP_ATTRIBUTEm, &dvp_entry, 49939 VXLAN__VT_DVP_GROUP_IDf); 49940 } else if ((network_port) && (vp_type == _bcmVpTypeL2Gre)) { 49941 *pclass_id = soc_mem_field32_get 49942 (unit, EGR_DVP_ATTRIBUTEm, &dvp_entry, 49943 L2GRE__VT_DVP_GROUP_IDf); 49944 } else { 49945 *pclass_id = soc_mem_field32_get 49946 (unit, EGR_DVP_ATTRIBUTEm, &dvp_entry, 49947 COMMON__VT_DVP_GROUP_IDf); 49948 } 49949 } 49950 } else { 49951 return BCM_E_UNAVAIL; 49952 } 49953 return rv; 49954 } 49955 49956 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 49957 break; 49958 #if defined(BCM_TOMAHAWK_SUPPORT) 49959 case bcmPortClassFieldIngressSourceGport: 49960 if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 49961 return BCM_E_UNAVAIL; 49962 } 49963 if (vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeVlan || 49964 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeVpLag || 49965 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeMpls || 49966 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeMim || 49967 vp_type == _bcmVpTypeFlow) { 49968 if (!_bcm_vp_used_get(unit, vp, vp_type)) { 49969 return BCM_E_PORT; 49970 } 49971 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &entry); 49972 if (BCM_SUCCESS(rv)) { 49973 *pclass_id = soc_mem_field32_get(unit, SOURCE_VPm, 49974 &entry, IPBM_INDEXf); 49975 } 49976 return rv; 49977 } 49978 break; 49979 #endif /* BCM_TOMAHAWK_SUPPORT */ 49980 default: 49981 break; 49982 } 49983 } 49984 #endif /* BCM_TRIDENT_SUPPORT */ 49985 #endif /* INCLUDE_L3 */ 49986 #ifdef BCM_XGS3_SWITCH_SUPPORT 49987 if (SOC_IS_XGS3_SWITCH(unit)) { 49988 #if defined(BCM_TOMAHAWK_SUPPORT) 49989 source_trunk_map_table_entry_t entry; 49990 bcm_module_t mod; 49991 bcm_trunk_t tid_out; 49992 int id_out; 49993 int index; 49994 #endif /* BCM_TOMAHAWK_SUPPORT */ 49995 49996 switch (pclass) { 49997 case bcmPortClassFieldIngressSystemPort: 49998 #if defined(BCM_TOMAHAWK_SUPPORT) 49999 if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 50000 return BCM_E_UNAVAIL; 50001 } 50002 if (BCM_GPORT_IS_SET(port)) { 50003 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 50004 &mod, &port_out, &tid_out, &id_out)); 50005 if (-1 != tid_out || -1 != id_out) { 50006 return BCM_E_PORT; 50007 } 50008 } else { 50009 if (!SOC_PORT_VALID(unit, port)) { 50010 return BCM_E_PORT; 50011 } 50012 port_out = port; 50013 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod)); 50014 } 50015 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, 50016 mod, port_out, &index)); 50017 #if defined(BCM_TRIDENT3_SUPPORT) 50018 if (SOC_IS_TRIDENT3X(unit) && 50019 !soc_feature(unit, soc_feature_ifp_no_inports_support)){ 50020 rv = bcm_td3_port_ipbm_opaque_get(unit, index, pclass_id); 50021 return rv; 50022 } 50023 #endif 50024 SOC_IF_ERROR_RETURN(soc_mem_read(unit, SOURCE_TRUNK_MAP_TABLEm, 50025 MEM_BLOCK_ANY, index, &entry)); 50026 *pclass_id = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, 50027 &entry, IPBM_INDEXf); 50028 return BCM_E_NONE; 50029 #endif /* BCM_TOMAHAWK_SUPPORT */ 50030 break; 50031 default: 50032 break; 50033 } 50034 } 50035 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 50036 /* 50037 * Skip port validation if soc_feature_shg_support_remote_port 50038 * is true and ptype is bcmPortClassFieldIngress. 50039 */ 50040 if (!(soc_feature(unit, soc_feature_shg_support_remote_port) && 50041 (pclass == bcmPortClassFieldIngress))) { 50042 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port_out)); 50043 } 50044 50045 if (NULL == pclass_id) { 50046 return BCM_E_PARAM; 50047 } 50048 50049 #ifdef BCM_XGS3_SWITCH_SUPPORT 50050 if (SOC_IS_XGS3_SWITCH(unit)) { 50051 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 50052 uint32 reg_val; 50053 uint64 reg_val64; 50054 int port_class_id; 50055 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 50056 switch (pclass) { 50057 case bcmPortClassFieldIngressGroupSel: 50058 #if defined(BCM_TOMAHAWK_SUPPORT) 50059 rv = _bcm_esw_port_tab_get(unit, port, IFP_KEY_SEL_CLASS_IDf, 50060 (int32*) pclass_id); 50061 #endif 50062 break; 50063 50064 case bcmPortClassFieldLookup: 50065 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 50066 if (soc_mem_field_valid(unit, PORT_TABm, VFP_PORT_GROUP_IDf) || 50067 SOC_IS_TRIDENT3X(unit)) { 50068 rv = _bcm_esw_port_tab_get(unit, port, VFP_PORT_GROUP_IDf, 50069 &port_class_id); 50070 *pclass_id = (uint32) port_class_id; 50071 } 50072 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */ 50073 break; 50074 case bcmPortClassVlanTranslateIngress: 50075 #if defined(BCM_TRIDENT2_SUPPORT) 50076 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, PORT_GROUPf)) { 50077 rv = _bcm_trx_source_trunk_map_get(unit, port, 50078 PORT_GROUPf, pclass_id); 50079 } 50080 #endif /* BCM_TRIDENT2_SUPPORT */ 50081 break; 50082 case bcmPortClassFieldIngress: 50083 #if defined(BCM_TRX_SUPPORT) 50084 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, CLASS_IDf)) { 50085 #if defined(BCM_KATANA2_SUPPORT) 50086 if (SOC_IS_KATANA2(unit)) { 50087 rv = _bcm_kt2_source_trunk_map_get(unit, port_out, 50088 CLASS_IDf, pclass_id); 50089 } else 50090 #endif 50091 { 50092 rv = _bcm_trx_source_trunk_map_get(unit, port, 50093 CLASS_IDf, pclass_id); 50094 } 50095 } 50096 #endif /* BCM_TRX_SUPPORT */ 50097 break; 50098 case bcmPortClassFieldEgress: 50099 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 50100 if (soc_reg_field_valid(unit, EGR_PORT_64r, EGR_PORT_GROUP_IDf)) { 50101 rv = READ_EGR_PORT_64r(unit, port_out, ®_val64); 50102 if (BCM_SUCCESS(rv)) { 50103 *pclass_id = soc_reg64_field32_get(unit, EGR_PORT_64r, 50104 reg_val64, EGR_PORT_GROUP_IDf); 50105 } 50106 } else if (soc_reg_field_valid(unit, EGR_PORTr, EGR_PORT_GROUP_IDf)) { 50107 rv = READ_EGR_PORTr(unit, port_out, ®_val); 50108 if (BCM_SUCCESS(rv)) { 50109 *pclass_id = soc_reg_field_get(unit, EGR_PORTr, 50110 reg_val, EGR_PORT_GROUP_IDf); 50111 } 50112 } 50113 #ifdef BCM_TRIDENT_SUPPORT 50114 else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EGR_PORT_GROUP_IDf) || 50115 SOC_IS_TRIDENT3X(unit)) { 50116 rv = _bcm_esw_egr_port_tab_get(unit, port, EGR_PORT_GROUP_IDf, 50117 (int *)pclass_id); 50118 50119 } 50120 #endif /* BCM_TRIDENT_SUPPORT */ 50121 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */ 50122 break; 50123 case bcmPortClassVlanTranslateEgress: 50124 #if defined(BCM_TRX_SUPPORT) 50125 if (soc_reg_field_valid(unit, EGR_PORT_64r, VT_PORT_GROUP_IDf)) { 50126 if (SOC_REG_IS_VALID(unit, EGR_PORT_64r)) { 50127 rv = READ_EGR_PORT_64r(unit, port_out, ®_val64); 50128 if (BCM_SUCCESS(rv)) { 50129 *pclass_id = soc_reg64_field32_get(unit, EGR_PORT_64r, 50130 reg_val64, VT_PORT_GROUP_IDf); 50131 } 50132 } 50133 } else if (soc_reg_field_valid(unit, EGR_PORTr, VT_PORT_GROUP_IDf)) { 50134 rv = READ_EGR_PORTr(unit, port_out, ®_val); 50135 if (BCM_SUCCESS(rv)) { 50136 *pclass_id = soc_reg_field_get(unit, EGR_PORTr, 50137 reg_val, VT_PORT_GROUP_IDf); 50138 } 50139 } 50140 #ifdef BCM_TRIDENT_SUPPORT 50141 else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, VT_PORT_GROUP_IDf) || 50142 SOC_IS_TRIDENT3X(unit)) { 50143 rv = _bcm_esw_egr_port_tab_get(unit, port, VT_PORT_GROUP_IDf, 50144 (int *)pclass_id); 50145 } 50146 #endif /* BCM_TRIDENT_SUPPORT */ 50147 #endif /* BCM_TRX_SUPPORT */ 50148 break; 50149 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 50150 case bcmPortClassEgress: 50151 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, CLASS_IDf) || 50152 SOC_IS_TRIDENT3X(unit)) { 50153 rv = _bcm_esw_egr_port_tab_get(unit, port, CLASS_IDf, 50154 (int *)pclass_id); 50155 } 50156 break; 50157 #endif 50158 #if defined(BCM_TOMAHAWK_SUPPORT) 50159 case bcmPortClassFieldIngressDevicePort: 50160 if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 50161 return BCM_E_UNAVAIL; 50162 } 50163 rv = _bcm_esw_port_tab_get(unit, port, PORT_IPBM_INDEXf, 50164 &port_class_id); 50165 if (BCM_SUCCESS(rv)) { 50166 *pclass_id = (uint32) port_class_id; 50167 } 50168 break; 50169 #endif /* BCM_TOMAHAWK_SUPPORT */ 50170 50171 default: 50172 rv = BCM_E_PARAM; 50173 } 50174 } 50175 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 50176 50177 return rv; 50178 } 50179 50180 50181 /* 50182 * Function : _bcm_esw_port_config_set 50183 * Description : Internal function to set port configuration. 50184 * Parameters : (IN)unit - BCM device number. 50185 * (IN)port - Port number (see Notes for valid port formats). 50186 * (IN)type - Port property. 50187 * (IN)value - New property value. 50188 * Returns : BCM_E_XXX 50189 * Notes: 50190 * Current valid port types are: 50191 * GPORT PROXY 50192 * GPORT SUBPORT 50193 * GPORT (various types) that resolves to local physical port 50194 * BCM port (non-gport), local physical port 50195 */ 50196 int 50197 _bcm_esw_port_config_set(int unit, bcm_port_t port, 50198 _bcm_port_config_t type, int value) 50199 { 50200 int rv = BCM_E_UNAVAIL; /* Operation return status. */ 50201 50202 #ifdef BCM_HGPROXY_COE_SUPPORT 50203 if (BCM_GPORT_IS_SET(port) && 50204 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) && 50205 (soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 50206 soc_feature(unit, soc_feature_channelized_switching))) { 50207 /* Don't resolve port */ 50208 } else 50209 #endif 50210 if (BCM_GPORT_IS_PROXY(port)) { 50211 /* Don't resolve port */ 50212 } else { 50213 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 50214 } 50215 50216 50217 PORT_LOCK(unit); 50218 50219 switch (type) { 50220 case _bcmPortL3UrpfMode: 50221 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 50222 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50223 URPF_MODEf, value); 50224 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 50225 break; 50226 case _bcmPortL3UrpfDefaultRoute: 50227 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 50228 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50229 URPF_DEFAULTROUTECHECKf, 50230 (value) ? 0 : 1); 50231 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 50232 break; 50233 case _bcmPortVlanTranslate: 50234 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50235 VT_ENABLEf, value); 50236 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 50237 defined(BCM_KATANA2_SUPPORT) 50238 if ((SOC_IS_TRIUMPH3(unit) || 50239 SOC_IS_TD2_TT2(unit) || 50240 SOC_IS_KATANA2(unit)) && (rv == SOC_E_NONE)) { 50241 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50242 VT_PORT_TYPE_SELECTf, value); 50243 if (rv == SOC_E_NONE) { 50244 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50245 VT_PORT_TYPE_SELECT_2f, value); 50246 } 50247 } else 50248 #endif 50249 { 50250 #if defined(BCM_TRX_SUPPORT) 50251 if (SOC_IS_TRX(unit) && (rv == SOC_E_NONE)) { 50252 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50253 VT_KEY_TYPE_USE_GLPf, value); 50254 if (rv == SOC_E_NONE) { 50255 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50256 VT_KEY_TYPE_2_USE_GLPf, value); 50257 } 50258 } 50259 #endif 50260 } 50261 break; 50262 case _bcmPortVlanPrecedence: 50263 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50264 VLAN_PRECEDENCEf, value); 50265 break; 50266 case _bcmPortVTMissDrop: 50267 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50268 VT_MISS_DROPf, value); 50269 break; 50270 case _bcmPortLookupMACEnable: 50271 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50272 MAC_BASED_VID_ENABLEf, value); 50273 break; 50274 case _bcmPortLookupIPEnable: 50275 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50276 SUBNET_BASED_VID_ENABLEf, 50277 value); 50278 break; 50279 case _bcmPortUseInnerPri: 50280 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 50281 defined(BCM_TRX_SUPPORT) 50282 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50283 USE_INNER_PRIf, value); 50284 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 50285 break; 50286 case _bcmPortUseOuterPri: 50287 #if defined(BCM_TRX_SUPPORT) 50288 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50289 TRUST_OUTER_DOT1Pf, value); 50290 #endif /* BCM_TRX_SUPPORT */ 50291 break; 50292 case _bcmPortVerifyOuterTpid: 50293 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 50294 defined(BCM_TRX_SUPPORT) 50295 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50296 OUTER_TPID_VERIFYf, value); 50297 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 50298 break; 50299 case _bcmPortVTKeyTypeFirst: 50300 #if defined(BCM_TRX_SUPPORT) 50301 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50302 VT_KEY_TYPEf, value); 50303 #endif /* BCM_TRX_SUPPORT */ 50304 break; 50305 case _bcmPortVTKeyPortFirst: 50306 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 50307 defined(BCM_KATANA2_SUPPORT) 50308 if (SOC_IS_TRIUMPH3(unit) || 50309 SOC_IS_TD2_TT2(unit) || 50310 SOC_IS_KATANA2(unit)) { 50311 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50312 VT_PORT_TYPE_SELECTf, value); 50313 } else 50314 #endif 50315 { 50316 #if defined(BCM_TRX_SUPPORT) 50317 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50318 VT_KEY_TYPE_USE_GLPf, value); 50319 #endif /* BCM_TRX_SUPPORT */ 50320 } 50321 break; 50322 case _bcmPortVTKeyTypeSecond: 50323 #if defined(BCM_TRX_SUPPORT) 50324 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50325 VT_KEY_TYPE_2f, value); 50326 #endif /* BCM_TRX_SUPPORT */ 50327 break; 50328 case _bcmPortVTKeyPortSecond: 50329 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 50330 defined(BCM_KATANA2_SUPPORT) 50331 if (SOC_IS_TRIUMPH3(unit) || 50332 SOC_IS_TD2_TT2(unit) || 50333 SOC_IS_KATANA2(unit)) { 50334 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50335 VT_PORT_TYPE_SELECT_2f, value); 50336 } else 50337 #endif 50338 { 50339 #if defined(BCM_TRX_SUPPORT) 50340 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50341 VT_KEY_TYPE_2_USE_GLPf, value); 50342 #endif /* BCM_TRX_SUPPORT */ 50343 } 50344 break; 50345 case _bcmPortIpmcV4Enable: 50346 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50347 V4IPMC_ENABLEf, value); 50348 break; 50349 case _bcmPortIpmcV6Enable: 50350 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50351 V6IPMC_ENABLEf, value); 50352 break; 50353 case _bcmPortIpmcVlanKey: 50354 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50355 IPMC_DO_VLANf, value); 50356 break; 50357 case _bcmPortCfiAsCng: 50358 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50359 CFI_AS_CNGf, value); 50360 break; 50361 case _bcmPortNni: 50362 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50363 NNI_PORTf, value); 50364 break; 50365 case _bcmPortHigigTrunkId: 50366 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT) 50367 if (value < 0) { 50368 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50369 HIGIG_TRUNKf, 0); 50370 if (BCM_SUCCESS(rv)) { 50371 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50372 HIGIG_TRUNK_IDf, 0); 50373 } 50374 } else { 50375 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50376 HIGIG_TRUNK_IDf, value); 50377 if (BCM_SUCCESS(rv)) { 50378 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50379 HIGIG_TRUNKf, 1); 50380 } 50381 } 50382 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */ 50383 break; 50384 case _bcmPortModuleLoopback: 50385 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50386 ALLOW_SRC_MODf, value); 50387 break; 50388 case _bcmPortOuterTpidEnables: 50389 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 50390 defined(BCM_TRX_SUPPORT) 50391 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 50392 OUTER_TPID_ENABLEf)) { 50393 #ifdef BCM_TRX_SUPPORT 50394 rv = _bcm_trx_source_trunk_map_set(unit, port, OUTER_TPID_ENABLEf, 50395 (uint32)value); 50396 #endif 50397 } else { 50398 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50399 OUTER_TPID_ENABLEf, value); 50400 } 50401 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 50402 break; 50403 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 50404 defined(BCM_GREYHOUND2_SUPPORT) 50405 case _bcmPortSvcMeterIndex: 50406 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || \ 50407 SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) { 50408 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50409 SVC_METER_INDEXf, value); 50410 } 50411 break; 50412 case _bcmPortSvcMeterOffsetMode: 50413 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || \ 50414 SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) { 50415 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50416 SVC_METER_OFFSET_MODEf, value); 50417 } 50418 break; 50419 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 50420 BCM_GREYHOUND2_SUPPORT */ 50421 #if defined(BCM_KATANA2_SUPPORT) 50422 case _bcmPortOamUseXlatedInnerVlan: 50423 if (SOC_IS_KATANA2(unit)) { 50424 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 50425 OAM_CVLAN_MEP_AFTER_VXLTf, value); 50426 rv = _bcm_esw_egr_port_tab_set(unit, port, 50427 OAM_CVLAN_MEP_AFTER_VXLTf, value); 50428 } 50429 break; 50430 #endif /* BCM_KATANA2_SUPPORT */ 50431 default: 50432 rv = BCM_E_INTERNAL; 50433 } 50434 50435 PORT_UNLOCK(unit); 50436 return (rv); 50437 } 50438 50439 /* 50440 * Function : _bcm_esw_port_config_get 50441 * Description : Internal function to get port configuration. 50442 * Parameters : (IN)unit - BCM device number. 50443 * (IN)port - Port number. 50444 * (IN)type - Port property. 50445 * (OUT)value -Port property value. 50446 * Returns : BCM_E_XXX 50447 * Notes: 50448 * Current valid port types are: 50449 * GPORT PROXY 50450 * GPORT SUBPORT 50451 * GPORT (various types) that resolves to local physical port 50452 * BCM port (non-gport), local physical port 50453 */ 50454 int 50455 _bcm_esw_port_config_get(int unit, bcm_port_t port, 50456 _bcm_port_config_t type, int *value) 50457 { 50458 int rv = BCM_E_UNAVAIL; /* Operation return status. */ 50459 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 50460 int tmp_value; /* Temporary value. */ 50461 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 50462 50463 #ifdef BCM_HGPROXY_COE_SUPPORT 50464 if (BCM_GPORT_IS_SET(port) && 50465 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) && 50466 (soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 50467 soc_feature(unit, soc_feature_channelized_switching))) { 50468 /* Don't resolve port */ 50469 } else 50470 #endif 50471 if (BCM_GPORT_IS_PROXY(port)) { 50472 /* Don't resolve port */ 50473 } else { 50474 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 50475 } 50476 50477 PORT_LOCK(unit); 50478 50479 switch (type) { 50480 case _bcmPortL3UrpfMode: 50481 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 50482 rv = _bcm_esw_port_tab_get(unit, port, URPF_MODEf, value); 50483 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 50484 break; 50485 case _bcmPortL3UrpfDefaultRoute: 50486 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 50487 rv = _bcm_esw_port_tab_get(unit, port, URPF_DEFAULTROUTECHECKf, 50488 &tmp_value); 50489 *value = (tmp_value) ? FALSE : TRUE; 50490 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 50491 break; 50492 case _bcmPortVlanTranslate: 50493 rv = _bcm_esw_port_tab_get(unit, port, VT_ENABLEf, value); 50494 break; 50495 case _bcmPortVlanPrecedence: 50496 rv = _bcm_esw_port_tab_get(unit, port, VLAN_PRECEDENCEf, value); 50497 break; 50498 case _bcmPortVTMissDrop: 50499 rv = _bcm_esw_port_tab_get(unit, port, VT_MISS_DROPf, value); 50500 break; 50501 case _bcmPortLookupMACEnable: 50502 rv = _bcm_esw_port_tab_get(unit, port, MAC_BASED_VID_ENABLEf, value); 50503 break; 50504 case _bcmPortLookupIPEnable: 50505 rv = _bcm_esw_port_tab_get(unit, port, SUBNET_BASED_VID_ENABLEf, 50506 value); 50507 break; 50508 case _bcmPortUseInnerPri: 50509 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 50510 defined(BCM_TRX_SUPPORT) 50511 rv = _bcm_esw_port_tab_get(unit, port, USE_INNER_PRIf, value); 50512 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 50513 break; 50514 case _bcmPortUseOuterPri: 50515 #if defined(BCM_TRX_SUPPORT) 50516 rv = _bcm_esw_port_tab_get(unit, port, TRUST_OUTER_DOT1Pf, value); 50517 #endif /* BCM_TRX_SUPPORT */ 50518 break; 50519 case _bcmPortVerifyOuterTpid: 50520 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 50521 defined(BCM_TRX_SUPPORT) 50522 rv = _bcm_esw_port_tab_get(unit, port, OUTER_TPID_VERIFYf, value); 50523 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 50524 break; 50525 case _bcmPortVTKeyTypeFirst: 50526 #if defined(BCM_TRX_SUPPORT) 50527 rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPEf, value); 50528 #endif /* BCM_TRX_SUPPORT */ 50529 break; 50530 case _bcmPortVTKeyPortFirst: 50531 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 50532 defined(BCM_KATANA2_SUPPORT) 50533 if (SOC_IS_TRIUMPH3(unit) || 50534 SOC_IS_TD2_TT2(unit) || 50535 SOC_IS_KATANA2(unit)) { 50536 rv = _bcm_esw_port_tab_get(unit, port, 50537 VT_PORT_TYPE_SELECTf, value); 50538 } else 50539 #endif 50540 { 50541 #if defined(BCM_TRX_SUPPORT) 50542 rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPE_USE_GLPf, value); 50543 #endif /* BCM_TRX_SUPPORT */ 50544 } 50545 break; 50546 case _bcmPortVTKeyTypeSecond: 50547 #if defined(BCM_TRX_SUPPORT) 50548 rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPE_2f, value); 50549 #endif /* BCM_TRX_SUPPORT */ 50550 break; 50551 case _bcmPortVTKeyPortSecond: 50552 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 50553 defined(BCM_KATANA2_SUPPORT) 50554 if (SOC_IS_TRIUMPH3(unit) || 50555 SOC_IS_TD2_TT2(unit) || 50556 SOC_IS_KATANA2(unit)) { 50557 rv = _bcm_esw_port_tab_get(unit, port, 50558 VT_PORT_TYPE_SELECT_2f, value); 50559 } else 50560 #endif 50561 { 50562 #if defined(BCM_TRX_SUPPORT) 50563 rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPE_2_USE_GLPf, value); 50564 #endif /* BCM_TRX_SUPPORT */ 50565 } 50566 break; 50567 case _bcmPortIpmcV4Enable: 50568 rv = _bcm_esw_port_tab_get(unit, port, V4IPMC_ENABLEf, value); 50569 break; 50570 case _bcmPortIpmcV6Enable: 50571 rv = _bcm_esw_port_tab_get(unit, port, V6IPMC_ENABLEf, value); 50572 break; 50573 case _bcmPortIpmcVlanKey: 50574 rv = _bcm_esw_port_tab_get(unit, port, IPMC_DO_VLANf, value); 50575 break; 50576 case _bcmPortCfiAsCng: 50577 rv = _bcm_esw_port_tab_get(unit, port, CFI_AS_CNGf, value); 50578 break; 50579 case _bcmPortNni: 50580 rv = _bcm_esw_port_tab_get(unit, port, NNI_PORTf, value); 50581 break; 50582 case _bcmPortHigigTrunkId: 50583 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT) 50584 rv = _bcm_esw_port_tab_get(unit, port, HIGIG_TRUNKf, value); 50585 if (BCM_SUCCESS(rv)) { 50586 if (*value == 0) { 50587 *value = -1; 50588 } else { 50589 rv = _bcm_esw_port_tab_get(unit, port, 50590 HIGIG_TRUNK_IDf, value); 50591 } 50592 } 50593 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */ 50594 break; 50595 case _bcmPortModuleLoopback: 50596 rv = _bcm_esw_port_tab_get(unit, port, ALLOW_SRC_MODf, value); 50597 break; 50598 case _bcmPortOuterTpidEnables: 50599 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 50600 defined(BCM_TRX_SUPPORT) 50601 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 50602 OUTER_TPID_ENABLEf)) { 50603 #ifdef BCM_TRX_SUPPORT 50604 rv = _bcm_trx_source_trunk_map_get(unit, port, OUTER_TPID_ENABLEf, 50605 (uint32 *)value); 50606 #endif 50607 } else { 50608 rv = _bcm_esw_port_tab_get(unit, port, OUTER_TPID_ENABLEf, value); 50609 } 50610 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 50611 break; 50612 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 50613 defined(BCM_GREYHOUND2_SUPPORT) 50614 case _bcmPortSvcMeterIndex: 50615 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) \ 50616 || SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) { 50617 rv = _bcm_esw_port_tab_get(unit, port, SVC_METER_INDEXf, value); 50618 } 50619 break; 50620 case _bcmPortSvcMeterOffsetMode: 50621 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) \ 50622 || SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) { 50623 rv = _bcm_esw_port_tab_get(unit, port, SVC_METER_OFFSET_MODEf, value); 50624 } 50625 break; 50626 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 50627 BCM_GREYHOUND2_SUPPORT */ 50628 #if defined(BCM_KATANA2_SUPPORT) 50629 case _bcmPortOamUseXlatedInnerVlan: 50630 if (SOC_IS_KATANA2(unit)) { 50631 rv = _bcm_esw_port_tab_get(unit, port, OAM_CVLAN_MEP_AFTER_VXLTf, 50632 value); 50633 } 50634 break; 50635 #endif /* BCM_KATANA2_SUPPORT */ 50636 default: 50637 rv = BCM_E_INTERNAL; 50638 } 50639 PORT_UNLOCK(unit); 50640 return (rv); 50641 } 50642 50643 /* 50644 * Function: 50645 * bcm_port_force_vlan_set 50646 * Description: 50647 * To set the force vlan attribute of a port 50648 * Parameters: 50649 * unit device number 50650 * port port number 50651 * vlan vlan identifier 50652 * (0 - 4095) - use this VLAN id if egress packet is tagged 50653 * pkt_prio egress packet priority (-1, 0..7) 50654 * any negative priority value disable the priority 50655 * override if the egress packet is tagged 50656 * flags bit fields 50657 * BCM_PORT_FORCE_VLAN_ENABLE - enable force vlan on this 50658 * port 50659 * BCM_PORT_FORCE_VLAN_UNTAG - egress untagged when force 50660 * vlan is enabled on this port 50661 * 50662 * Return: 50663 * BCM_E_NONE 50664 * BCM_E_UNIT 50665 * BCM_E_PORT 50666 * BCM_E_PARAM 50667 * BCM_E_UNAVAIL 50668 * BCM_E_XXX 50669 */ 50670 int 50671 bcm_esw_port_force_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vlan, 50672 int pkt_prio, uint32 flags) 50673 { 50674 int rv = BCM_E_UNAVAIL; 50675 50676 /* Make sure port module is initialized. */ 50677 PORT_INIT(unit); 50678 50679 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 50680 if (BCM_GPORT_IS_VLAN_PORT(port) || 50681 BCM_GPORT_IS_NIV_PORT(port) || 50682 BCM_GPORT_IS_EXTENDER_PORT(port)) { 50683 return bcm_td_vp_force_vlan_set(unit, port, vlan, flags); 50684 } 50685 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 50686 50687 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 50688 #if defined(BCM_TRX_SUPPORT) 50689 if ((!soc_feature(unit, soc_feature_egr_pvlan_eport_control_is_mem) && 50690 SOC_REG_FIELD_VALID(unit, EGR_PVLAN_EPORT_CONTROLr, PVLAN_UNTAGf)) || 50691 (soc_feature(unit, soc_feature_egr_pvlan_eport_control_is_mem) && 50692 SOC_MEM_FIELD_VALID(unit, EGR_PVLAN_EPORT_CONTROLm, PVLAN_UNTAGf))) { 50693 rv = _bcm_trx_port_force_vlan_set(unit, port, vlan, pkt_prio, flags); 50694 } 50695 50696 #endif /* defined(BCM_TRX_SUPPORT) */ 50697 50698 return rv; 50699 } 50700 50701 /* 50702 * Function: 50703 * bcm_port_force_vlan_get 50704 * Description: 50705 * To get the force vlan attribute of a port 50706 * Parameters: 50707 * unit device number 50708 N_UNTAGf* port port number 50709 * vlan pointer to vlan identifier 50710 * (0 - 4095) - use this VLAN id if egress packet is tagged 50711 * valid only when BCM_PORT_FORCE_VLAN_ENABLE is set and 50712 * BCM_PORT_FORCE_VLAN_UNTAG is clear 50713 * pkt_prio egress packet priority (-1, 0 - 7) 50714 * valid only when BCM_PORT_FORCE_VLAN_ENABLE is set and 50715 * BCM_PORT_FORCE_VLAN_UNTAG is clear 50716 * flags bit fields 50717 * BCM_PORT_FORCE_VLAN_ENABLE - enable force vlan on this 50718 * port 50719 * BCM_PORT_FORCE_VLAN_UNTAG - egress untagged when force 50720 * vlan is enabled on this port 50721 * 50722 * Return: 50723 * BCM_E_XXX 50724 */ 50725 int 50726 bcm_esw_port_force_vlan_get(int unit, bcm_port_t port, bcm_vlan_t *vlan, 50727 int *pkt_prio, uint32 *flags) 50728 { 50729 int rv = BCM_E_UNAVAIL; 50730 50731 /* Make sure port module is initialized. */ 50732 PORT_INIT(unit); 50733 50734 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 50735 if (BCM_GPORT_IS_VLAN_PORT(port) || 50736 BCM_GPORT_IS_NIV_PORT(port) || 50737 BCM_GPORT_IS_EXTENDER_PORT(port)) { 50738 return bcm_td_vp_force_vlan_get(unit, port, vlan, flags); 50739 } 50740 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 50741 50742 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 50743 50744 #if defined(BCM_TRX_SUPPORT) 50745 if (SOC_REG_FIELD_VALID(unit, EGR_PVLAN_EPORT_CONTROLr, PVLAN_UNTAGf)) { 50746 rv = _bcm_trx_port_force_vlan_get(unit, port, vlan, pkt_prio, flags); 50747 } 50748 #endif /* defined(BCM_TRX_SUPPORT) */ 50749 50750 return rv; 50751 } 50752 50753 /* 50754 * Function: 50755 * bcm_port_phy_control_set 50756 * Description: 50757 * Set PHY specific properties 50758 * Parameters: 50759 * unit device number 50760 * port port number 50761 * type configuration type 50762 * value new value for the configuration 50763 * Return: 50764 * BCM_E_XXX 50765 */ 50766 int 50767 bcm_esw_port_phy_control_set(int unit, bcm_port_t port, 50768 bcm_port_phy_control_t type, uint32 value) 50769 { 50770 int rv; 50771 bcm_port_t local_port = 0; 50772 int phy_lane = -1; 50773 int phyn = 0, sys_side = 0; 50774 50775 /* Make sure port module is initialized. */ 50776 PORT_INIT(unit); 50777 50778 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 50779 BCM_IF_ERROR_RETURN 50780 (bcmi_esw_portctrl_phy_control_set(unit, port, type, value)); 50781 #ifdef BCM_TOMAHAWK_SUPPORT 50782 /* If FEC/CL91/CL108 is enabled/disabled on the 25/27/50/53G ports, we will need to update ASF parameters */ 50783 if (SOC_IS_TOMAHAWKX(unit)) { 50784 if ((type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL91) 50785 || (type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL108)) { 50786 bcm_port_info_t port_info; 50787 50788 bcm_port_info_t_init(&port_info); 50789 BCM_IF_ERROR_RETURN(bcm_esw_port_info_get(unit, port, &port_info)); 50790 50791 if ((port_info.speed == 25000) || (port_info.speed == 27000) || 50792 (port_info.speed == 50000) || (port_info.speed == 53000) || 50793 (port_info.speed == 100000) || (port_info.speed == 106000)){ 50794 int mode; 50795 50796 BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_get(unit, port, &mode)); 50797 BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_set(unit, port, mode)); 50798 } 50799 } 50800 } 50801 #endif 50802 return BCM_E_NONE; 50803 } 50804 50805 if(BCM_PHY_GPORT_IS_PHYN(port)) { 50806 local_port = BCM_PHY_GPORT_PHYN_PORT_PORT_GET(port); 50807 phyn = BCM_PHY_GPORT_PHYN_PORT_PHYN_GET(port); 50808 phy_lane = -1; 50809 } else if(BCM_PHY_GPORT_IS_PHYN_LANE(port)) { 50810 local_port = BCM_PHY_GPORT_PHYN_LANE_PORT_PORT_GET(port); 50811 phyn = BCM_PHY_GPORT_PHYN_LANE_PORT_PHYN_GET(port); 50812 phy_lane = BCM_PHY_GPORT_PHYN_LANE_PORT_LANE_GET(port); 50813 } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE(port)) { 50814 local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PORT_GET(port); 50815 phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PHYN_GET(port); 50816 sys_side = TRUE; 50817 phy_lane = -1; 50818 } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE_LANE(port)) { 50819 local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PORT_GET(port); 50820 phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PHYN_GET(port); 50821 phy_lane = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_LANE_GET(port); 50822 sys_side = TRUE; 50823 } else if (BCM_PHY_GPORT_IS_LANE(port)) { 50824 local_port = BCM_PHY_GPORT_LANE_PORT_PORT_GET(port); 50825 phy_lane = BCM_PHY_GPORT_LANE_PORT_LANE_GET(port); 50826 } else { 50827 BCM_IF_ERROR_RETURN 50828 (_bcm_esw_port_gport_validate(unit, port, &local_port)); 50829 50830 PORT_LOCK(unit); 50831 rv = soc_phyctrl_control_set(unit, local_port, (soc_phy_control_t) type, value); 50832 if (BCM_SUCCESS(rv)) { 50833 PORT_INFO_RX_LOS_SET(unit, local_port, type, value); 50834 } 50835 PORT_UNLOCK(unit); 50836 50837 #ifdef BCM_TOMAHAWK_SUPPORT 50838 /* If FEC/CL91/CL108 is enabled/disabled on the 25/27/50/53G ports, we will need to update ASF parameters */ 50839 if (SOC_IS_TOMAHAWKX(unit)) { 50840 if ((type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL91) 50841 || (type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL108)) { 50842 bcm_port_info_t port_info; 50843 50844 bcm_port_info_t_init(&port_info); 50845 BCM_IF_ERROR_RETURN(bcm_esw_port_info_get(unit, port, &port_info)); 50846 50847 if ((port_info.speed == 25000) || (port_info.speed == 27000) || 50848 (port_info.speed == 50000) || (port_info.speed == 53000) || 50849 (port_info.speed == 100000) || (port_info.speed == 106000)){ 50850 int mode; 50851 50852 BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_get(unit, port, &mode)); 50853 BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_set(unit, port, mode)); 50854 } 50855 } 50856 } 50857 #endif 50858 return rv; 50859 } 50860 50861 if (!SOC_PORT_VALID(unit, local_port)) { 50862 return BCM_E_PORT; 50863 } 50864 50865 PORT_LOCK(unit); 50866 rv = soc_phyctrl_redirect_control_set(unit, local_port, phyn, phy_lane, 50867 sys_side, (soc_phy_control_t) type, value); 50868 if (BCM_SUCCESS(rv)) { 50869 PORT_INFO_RX_LOS_SET(unit, local_port, type, value); 50870 } 50871 PORT_UNLOCK(unit); 50872 50873 return rv; 50874 } 50875 50876 /* 50877 * Function: 50878 * bcm_esw_port_phy_control_get 50879 * Description: 50880 * Set PHY specific properties 50881 * Parameters: 50882 * unit device number 50883 * port port number 50884 * type configuration type 50885 * value value for the configuration 50886 * Return: 50887 * BCM_E_XXX 50888 */ 50889 int 50890 bcm_esw_port_phy_control_get(int unit, bcm_port_t port, 50891 bcm_port_phy_control_t type, uint32 *value) 50892 { 50893 int rv; 50894 bcm_port_t local_port; 50895 int phy_lane = -1; 50896 int phyn = 0, sys_side = 0; 50897 50898 if (NULL == value) { 50899 return BCM_E_PARAM; 50900 } 50901 50902 /* Make sure port module is initialized. */ 50903 PORT_INIT(unit); 50904 50905 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 50906 return bcmi_esw_portctrl_phy_control_get(unit, port, type, value); 50907 } 50908 50909 if(BCM_PHY_GPORT_IS_PHYN(port)) { 50910 local_port = BCM_PHY_GPORT_PHYN_PORT_PORT_GET(port); 50911 phyn = BCM_PHY_GPORT_PHYN_PORT_PHYN_GET(port); 50912 phy_lane = -1; 50913 } else if(BCM_PHY_GPORT_IS_PHYN_LANE(port)) { 50914 local_port = BCM_PHY_GPORT_PHYN_LANE_PORT_PORT_GET(port); 50915 phyn = BCM_PHY_GPORT_PHYN_LANE_PORT_PHYN_GET(port); 50916 phy_lane = BCM_PHY_GPORT_PHYN_LANE_PORT_LANE_GET(port); 50917 } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE(port)) { 50918 local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PORT_GET(port); 50919 phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PHYN_GET(port); 50920 sys_side = TRUE; 50921 phy_lane = -1; 50922 } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE_LANE(port)) { 50923 local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PORT_GET(port); 50924 phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PHYN_GET(port); 50925 phy_lane = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_LANE_GET(port); 50926 sys_side = TRUE; 50927 } else if (BCM_PHY_GPORT_IS_LANE(port)) { 50928 local_port = BCM_PHY_GPORT_LANE_PORT_PORT_GET(port); 50929 phy_lane = BCM_PHY_GPORT_LANE_PORT_LANE_GET(port); 50930 } else { 50931 BCM_IF_ERROR_RETURN 50932 (_bcm_esw_port_gport_validate(unit, port, &port)); 50933 50934 PORT_LOCK(unit); 50935 rv = soc_phyctrl_control_get(unit, port, (soc_phy_control_t) type, value); 50936 PORT_UNLOCK(unit); 50937 return rv; 50938 } 50939 50940 if (!SOC_PORT_VALID(unit, local_port)) { 50941 return BCM_E_PORT; 50942 } 50943 50944 PORT_LOCK(unit); 50945 rv = soc_phyctrl_redirect_control_get(unit, local_port, phyn, phy_lane, 50946 sys_side, (soc_phy_control_t) type, value); 50947 PORT_UNLOCK(unit); 50948 50949 return rv; 50950 } 50951 50952 /* 50953 * Function: 50954 * bcm_esw_port_phy_firmware_set 50955 * Purpose: 50956 * Write the firmware to the PHY device's non-volatile storage. 50957 * Parameters: 50958 * unit - (IN) Unit number. 50959 * port - (IN) Port number 50960 * flags - (IN) PHY spcific flags, such as BCM_PORT_PHY_INTERNAL 50961 * offset - (IN) Offset to the firmware data array 50962 * array - (IN) The firmware data array 50963 * length - (IN) The length of the firmware data array 50964 * Returns: 50965 * BCM_E_XXX 50966 * Notes: 50967 */ 50968 int 50969 bcm_esw_port_phy_firmware_set(int unit, bcm_port_t port, uint32 flags, 50970 int offset, uint8 *array, int length) 50971 { 50972 int rv; 50973 50974 /* Make sure port module is initialized. */ 50975 PORT_INIT(unit); 50976 50977 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 50978 50979 PORT_LOCK(unit); 50980 rv = soc_phyctrl_firmware_set(unit, port, flags,offset,array,length); 50981 PORT_UNLOCK(unit); 50982 50983 return rv; 50984 } 50985 50986 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 50987 /* 50988 * Function : _bcm_esw_port_subport_index_get 50989 * Description : Get the subport index for the specified mod port. 50990 * 50991 * Parameters : (IN) unit - BCM device number 50992 * (IN) modport - GPORT ID 50993 * (OUT) subport_index - subport index 50994 * Returns : BCM_E_XXX 50995 */ 50996 int 50997 _bcm_esw_port_subport_index_get(int unit, bcm_gport_t modport, 50998 int *subport_index) 50999 { 51000 int id_out = 0; 51001 bcm_module_t mod_out = 0; 51002 bcm_port_t port_out = 0; 51003 bcm_trunk_t tgid_out = 0; 51004 int base_index = 0; 51005 int result = FALSE; 51006 modid_base_ptr_entry_t modid_base_entry; 51007 soc_info_t *si = &SOC_INFO(unit); 51008 int i = 0, valid = 0, modid = 0; 51009 51010 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, modport, 51011 &mod_out, &port_out, &tgid_out, &id_out)); 51012 if ((-1 != tgid_out) || (-1 != id_out)) { 51013 return BCM_E_PARAM; 51014 } 51015 51016 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 51017 for (i = 0; i < si->num_modules; i++) { 51018 if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] 51019 == mod_out) { 51020 BCM_IF_ERROR_RETURN( 51021 _bcm_esw_stk_get_mod_config_by_type(unit, 51022 BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid, 51023 &base_index)); 51024 if ((valid == 1) && (modid == mod_out)) { 51025 if (port_out > 51026 src_modid_base_index_bk[unit]->num_ports[modid]) { 51027 return BCM_E_PARAM; 51028 } 51029 *subport_index = base_index + port_out; 51030 return BCM_E_NONE; 51031 } 51032 } 51033 } 51034 } 51035 51036 /* Check modport in one of additional module */ 51037 BCM_IF_ERROR_RETURN ( 51038 _bcm_esw_my_modid_additional_check(unit, mod_out, &result)); 51039 if(result == FALSE) { 51040 return BCM_E_PORT; 51041 } 51042 MODULE_ID_LOWER_6_BITS(mod_out); /* lower 6 bit */ 51043 SOC_IF_ERROR_RETURN( 51044 READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_out, 51045 &modid_base_entry)); 51046 base_index = soc_MODID_BASE_PTRm_field32_get( 51047 unit, &modid_base_entry, MODID_BASEf); 51048 *subport_index = base_index; /* the index is indicated by module base ptr */ 51049 51050 return BCM_E_NONE; 51051 } 51052 51053 /* 51054 * Function : _bcm_esw_modport_local_get 51055 * Description : Get the physical port for the specified mod port. 51056 * 51057 * Parameters : (IN) unit - BCM device number 51058 * (IN) modport - Gport number 51059 * (OUT) local_port - port number 51060 * 51061 * Returns : BCM_E_XXX 51062 */ 51063 int _bcm_esw_modport_local_get(int unit, bcm_gport_t modport, bcm_port_t *local_port) 51064 { 51065 int subport_index = 0; 51066 modport_map_subport_entry_t modport_map_subport_entry; 51067 51068 /* Make sure port module is initialized. */ 51069 PORT_INIT(unit); 51070 51071 /* Parameter check */ 51072 if (!BCM_GPORT_IS_MODPORT(modport)) { 51073 return BCM_E_PARAM; 51074 } 51075 51076 if(local_port == NULL) { 51077 return BCM_E_PARAM; 51078 } 51079 51080 SOC_IF_ERROR_RETURN( 51081 _bcm_esw_port_subport_index_get(unit, modport, &subport_index)); 51082 51083 SOC_IF_ERROR_RETURN( 51084 READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index, 51085 &modport_map_subport_entry)); 51086 *local_port = soc_MODPORT_MAP_SUBPORTm_field32_get( 51087 unit, &modport_map_subport_entry, DESTf); 51088 51089 return BCM_E_NONE; 51090 } 51091 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 51092 51093 /* 51094 * Function : bcm_esw_port_local_get 51095 * Description : Get the local port from the given GPORT ID. 51096 * 51097 * Parameters : (IN) unit - BCM device number 51098 * (IN) gport - global port identifier 51099 * (OUT) local_port - local port encoded in gport 51100 * Returns : BCM_E_XXX 51101 */ 51102 int 51103 bcm_esw_port_local_get(int unit, bcm_gport_t gport, bcm_port_t *local_port) 51104 { 51105 bcm_module_t my_mod, encap_mod; 51106 bcm_port_t encap_port; 51107 int num_modid, isLocal = 0; 51108 soc_info_t *si = &SOC_INFO(unit); 51109 51110 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 51111 int rv = BCM_E_NONE; 51112 #endif 51113 51114 #if defined(BCM_KATANA2_SUPPORT) 51115 bcm_trunk_t trunk_id = BCM_TRUNK_INVALID; 51116 int id = -1; 51117 int pp_port = 0; 51118 int min_pp_port = SOC_INFO(unit).pp_port_index_min; 51119 int max_pp_port = SOC_INFO(unit).pp_port_index_max; 51120 #endif /* BCM_KATANA2_SUPPORT */ 51121 51122 /* Make sure port module is initialized. */ 51123 PORT_INIT(unit); 51124 51125 BCM_IF_ERROR_RETURN(bcm_esw_stk_modid_count(unit, &num_modid)); 51126 if ((!num_modid) && !BCM_GPORT_IS_DEVPORT(gport) ){ 51127 /* Only devport gport can be supported on device with no modid */ 51128 return BCM_E_UNAVAIL; 51129 } 51130 51131 if (BCM_GPORT_IS_LOCAL(gport)) { 51132 *local_port = BCM_GPORT_LOCAL_GET(gport); 51133 } else if (BCM_GPORT_IS_LOCAL_CPU(gport)) { 51134 *local_port = CMIC_PORT(unit); 51135 } else if (BCM_GPORT_IS_DEVPORT(gport)) { 51136 *local_port = BCM_GPORT_DEVPORT_PORT_GET(gport); 51137 if (unit != BCM_GPORT_DEVPORT_DEVID_GET(gport)) { 51138 return BCM_E_PORT; 51139 } 51140 } else if (BCM_GPORT_IS_MODPORT(gport) || BCM_GPORT_IS_PROXY(gport)) { 51141 BCM_IF_ERROR_RETURN( 51142 bcm_esw_stk_my_modid_get(unit, &my_mod)); 51143 51144 if (BCM_GPORT_IS_MODPORT(gport)) { 51145 encap_mod = BCM_GPORT_MODPORT_MODID_GET(gport); 51146 encap_port = BCM_GPORT_MODPORT_PORT_GET(gport); 51147 } else { 51148 encap_mod = BCM_GPORT_PROXY_MODID_GET(gport); 51149 encap_port = BCM_GPORT_PROXY_PORT_GET(gport); 51150 } 51151 51152 if (encap_mod == my_mod){ 51153 *local_port = encap_port; 51154 } else if ((num_modid > 1) && 51155 !si->coe_stacking_mode) { 51156 BCM_IF_ERROR_RETURN( 51157 _bcm_esw_modid_is_local(unit, encap_mod, &isLocal)); 51158 if (isLocal) { 51159 #if defined(BCM_TOMAHAWK_SUPPORT) 51160 /* Call asymmetric dual modid unmapping function */ 51161 if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) { 51162 BCM_IF_ERROR_RETURN ( 51163 _bcm_esw_stk_asymmetric_dual_modmap_map(unit, 51164 BCM_STK_MODMAP_SET, &encap_mod, &encap_port)); 51165 *local_port = encap_port; 51166 } else 51167 #endif /* BCM_TOMAHAWK_SUPPORT */ 51168 { 51169 *local_port = encap_port + 51170 (encap_mod - my_mod) * (SOC_MODPORT_MAX(unit) + 1); 51171 } 51172 } else { 51173 return BCM_E_PORT; 51174 } 51175 } else { 51176 51177 #if defined(BCM_KATANA2_SUPPORT) 51178 if (soc_feature(unit, soc_feature_linkphy_coe) || 51179 soc_feature(unit, soc_feature_subtag_coe)) { 51180 if (_bcm_kt2_mod_is_coe_mod_check(unit, encap_mod) == BCM_E_NONE) { 51181 BCM_IF_ERROR_RETURN( 51182 _bcm_kt2_modport_to_pp_port_get(unit, 51183 encap_mod, encap_port, &pp_port)); 51184 #if defined BCM_METROLITE_SUPPORT 51185 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 51186 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 51187 *local_port = pp_port; 51188 return BCM_E_NONE; 51189 } 51190 } else 51191 #endif 51192 { 51193 if ((pp_port >= min_pp_port) && (pp_port <= max_pp_port)) { 51194 *local_port = pp_port; 51195 return BCM_E_NONE; 51196 } 51197 } 51198 } 51199 } else 51200 #endif 51201 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 51202 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 51203 soc_feature(unit, soc_feature_channelized_switching)) && 51204 _bcm_xgs5_subport_coe_mod_port_local(unit, encap_mod, encap_port)) { 51205 BCM_IF_ERROR_RETURN( 51206 _bcmi_coe_subport_mod_port_physical_port_get(unit, encap_mod, 51207 encap_port, local_port)); 51208 } 51209 /* Call modport to local function */ 51210 else if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 51211 BCM_IF_ERROR_RETURN ( 51212 _bcm_esw_modport_local_get(unit, gport, &encap_port)); 51213 *local_port = encap_port; 51214 } else 51215 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 51216 { 51217 return BCM_E_PORT; 51218 } 51219 } 51220 if (soc_feature(unit, soc_feature_sysport_remap)) { 51221 BCM_XLATE_SYSPORT_S2P(unit, local_port); 51222 } 51223 if (!SOC_PORT_VALID(unit, *local_port)) { 51224 return BCM_E_PORT; 51225 } 51226 } else if (BCM_GPORT_IS_SUBPORT_PORT(gport)) { 51227 51228 #if defined(BCM_HGPROXY_COE_SUPPORT) 51229 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 51230 soc_feature(unit, soc_feature_channelized_switching)) && 51231 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) { 51232 return _bcmi_coe_subport_physical_port_get(unit, gport, local_port); 51233 } else 51234 #endif /* BCM_HGPROXY_COE_SUPPORT */ 51235 #if defined(BCM_KATANA2_SUPPORT) 51236 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, gport)) { 51237 pp_port = BCM_GPORT_SUBPORT_PORT_GET(gport); 51238 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_mod)); 51239 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, gport, &encap_mod, 51240 &encap_port, &trunk_id, &id)); 51241 if (_bcm_kt2_mod_is_coe_mod_check(unit, encap_mod) == BCM_E_NONE) { 51242 #if defined BCM_METROLITE_SUPPORT 51243 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 51244 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 51245 *local_port = pp_port; 51246 return BCM_E_NONE; 51247 } 51248 } else 51249 #endif 51250 { 51251 if ((pp_port >= min_pp_port) && (pp_port <= max_pp_port)) { 51252 *local_port = pp_port; 51253 return BCM_E_NONE; 51254 } 51255 } 51256 } 51257 } 51258 #endif 51259 return BCM_E_PORT; 51260 } else if (BCM_GPORT_IS_VLAN_PORT(gport)) { 51261 *local_port = BCM_GPORT_VLAN_PORT_ID_GET(gport); 51262 } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 51263 *local_port = BCM_GPORT_EXTENDER_PORT_ID_GET(gport); 51264 } else if (BCM_GPORT_IS_NIV_PORT(gport)) { 51265 *local_port = BCM_GPORT_NIV_PORT_ID_GET(gport); 51266 } else if (BCM_GPORT_IS_VXLAN_PORT(gport)) { 51267 *local_port = BCM_GPORT_VXLAN_PORT_ID_GET(gport); 51268 } else if (BCM_GPORT_IS_FLOW_PORT(gport)) { 51269 *local_port = BCM_GPORT_FLOW_PORT_ID_GET(gport); 51270 } else if (BCM_GPORT_IS_L2GRE_PORT(gport)) { 51271 *local_port = BCM_GPORT_L2GRE_PORT_ID_GET(gport); 51272 } else if (BCM_GPORT_IS_MIM_PORT(gport)) { 51273 *local_port = BCM_GPORT_MIM_PORT_ID_GET(gport); 51274 } else if (BCM_GPORT_IS_MPLS_PORT(gport)) { 51275 *local_port = BCM_GPORT_MPLS_PORT_ID_GET(gport); 51276 } else if (BCM_GPORT_IS_TRUNK(gport)) { 51277 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 51278 if (soc_feature(unit, soc_feature_vp_lag)) { 51279 rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit, 51280 BCM_GPORT_TRUNK_GET(gport),local_port); 51281 return (rv != BCM_E_NONE) ? BCM_E_PORT : BCM_E_NONE; 51282 } 51283 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 51284 return BCM_E_PORT; 51285 } else if (BCM_GPORT_IS_VP_GROUP(gport)) { 51286 *local_port = BCM_GPORT_VP_GROUP_GET(gport); 51287 } else { 51288 return BCM_E_PORT; 51289 } 51290 51291 return BCM_E_NONE; 51292 } 51293 51294 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 51295 51296 /* 51297 * Function : _bcm_esw_modid_is_coe_mod 51298 * Description : Identifies if given modid is a CoE module 51299 * 51300 * Parameters : (IN) unit - BCM device number 51301 * (IN) modnd - Module ID 51302 * Returns : BCM_E_NONE, if it is a CoE Module 51303 * BCM_E_NOT_FOUND, if it is not a CoE Module 51304 */ 51305 51306 int 51307 _bcm_esw_modid_is_coe_mod(int unit, bcm_module_t modid) 51308 { 51309 bcm_stk_modid_config_t mod_cfg; 51310 mod_cfg.modid = modid; 51311 51312 mod_cfg.modid_type = bcmStkModidTypeCoe; 51313 51314 /* Also check if this is one of the CoE modules */ 51315 return bcm_esw_stk_modid_config_get(unit, &mod_cfg); 51316 } 51317 #endif 51318 51319 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 51320 /* 51321 * Function : _bcm_esw_modid_is_multi_nexthop_mod 51322 * Description : Identifies if given modid is a Multi Next Hop module 51323 * 51324 * Parameters : (IN) unit - BCM device number 51325 * (IN) modnd - Module ID 51326 * Returns : BCM_E_NONE, if it is a Multi Next Hop Module 51327 * BCM_E_NOT_FOUND, if it is not a Multi Next Hop Module 51328 */ 51329 51330 int 51331 _bcm_esw_modid_is_multi_nexthop_mod(int unit, bcm_module_t modid) 51332 { 51333 bcm_stk_modid_config_t mod_cfg; 51334 51335 if ((modid < 0) || (modid > SOC_MODID_MAX(unit))) { 51336 return BCM_E_PARAM; 51337 } 51338 mod_cfg.modid = modid; 51339 mod_cfg.modid_type = bcmStkModidTypeMultiNextHops; 51340 51341 /* Also check if this is one of the Multi Next Hop modules */ 51342 return bcm_esw_stk_modid_config_get(unit, &mod_cfg); 51343 } 51344 51345 /* 51346 * Function : _bcm_esw_is_multi_nexthop_mod_port 51347 * Description : Identifies if given modid is a Multi Next Hop module port 51348 * 51349 * Parameters : (IN) unit - BCM device number 51350 * (IN) modid - Mod Id value 51351 * (IN) port - Port Id value 51352 * Returns : TRUE if is Multi Next Hop module port, FALSE otherwise 51353 */ 51354 int 51355 _bcm_esw_is_multi_nexthop_mod_port(int unit, bcm_module_t modid, 51356 bcm_port_t port) 51357 { 51358 int rv = BCM_E_NONE; 51359 int result = FALSE; 51360 51361 if(_bcm_esw_modid_is_multi_nexthop_mod(unit, modid) == BCM_E_NONE) { 51362 if (port <= src_modid_base_index_bk[unit]->num_ports[modid]) { 51363 return TRUE; 51364 } 51365 } else { 51366 rv = _bcm_esw_my_modid_additional_check(unit, modid, &result); 51367 if (BCM_FAILURE(rv)) { 51368 return FALSE; 51369 } 51370 return result; 51371 } 51372 return FALSE; 51373 } 51374 #endif 51375 51376 /* 51377 * Function : _bcm_esw_modid_is_local 51378 * Description : Identifies if given modid is local on a given unit 51379 * 51380 * Parameters : (IN) unit - BCM device number 51381 * (IN) modnd - Module ID 51382 * (OUT) result - TRUE if modid is local, FALSE otherwise 51383 * Returns : BCM_E_XXX 51384 */ 51385 int 51386 _bcm_esw_modid_is_local(int unit, bcm_module_t modid, int *result) 51387 { 51388 bcm_module_t mymodid; 51389 int rv; 51390 soc_info_t *si=&SOC_INFO(unit); 51391 51392 /* Input parameters check. */ 51393 if (NULL == result) { 51394 return (BCM_E_PARAM); 51395 } 51396 51397 COMPILER_REFERENCE(si); 51398 51399 /* Get local module id. */ 51400 rv = bcm_esw_stk_my_modid_get(unit, &mymodid); 51401 if (BCM_E_UNAVAIL == rv) { 51402 if (BCM_MODID_INVALID == modid) { 51403 *result = TRUE; 51404 } else { 51405 #if defined(BCM_HGPROXY_COE_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 51406 /* If hg_proxy or if (subtag/linkPhy-Coe && stacking-mode) 51407 check the local modid */ 51408 if (((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 51409 soc_feature(unit, soc_feature_channelized_switching)) || 51410 ((soc_feature(unit, soc_feature_subtag_coe) || 51411 (soc_feature(unit, soc_feature_linkphy_coe))) && 51412 si->coe_stacking_mode)) && 51413 (_bcm_esw_modid_is_coe_mod(unit, modid) == BCM_E_NONE)) { 51414 *result = TRUE; 51415 } else 51416 #endif 51417 { 51418 *result = FALSE; 51419 } 51420 } 51421 return (BCM_E_NONE); 51422 } 51423 51424 if (mymodid == modid) { 51425 *result = TRUE; 51426 } else if ((modid > mymodid) && (modid < mymodid + NUM_MODID(unit))) { 51427 *result = TRUE; 51428 } 51429 #if defined(BCM_HGPROXY_COE_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 51430 /* If hg_proxy or if (subtag/linkPhy-Coe && stacking-mode) 51431 check the local modid */ 51432 else if (((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 51433 soc_feature(unit, soc_feature_channelized_switching)) || 51434 ((soc_feature(unit, soc_feature_subtag_coe) || 51435 (soc_feature(unit, soc_feature_linkphy_coe))) && 51436 si->coe_stacking_mode)) && 51437 (_bcm_esw_modid_is_coe_mod(unit, modid) == BCM_E_NONE)) { 51438 *result = TRUE; 51439 } 51440 #endif /* BCM_HGPROXY_COE_SUPPORT || BCM_KATANA2_SUPPORT */ 51441 else { 51442 *result = FALSE; 51443 } 51444 51445 return (BCM_E_NONE); 51446 } 51447 51448 51449 /* 51450 * Function : _bcm_gport_modport_hw2api_map 51451 * Description : Remaps module and port from HW space to API space 51452 * 51453 * Parameters : (IN) unit - BCM device number 51454 * (IN) mod_in - Module ID to map 51455 * (IN) port_in - Physical port to map 51456 * (OUT) mod_out - Module ID after mapping 51457 * (OUT) port_out - Port number after mapping 51458 * Returns : BCM_E_XXX 51459 * Notes : If mod_out == NULL then port_out will be local physical port. 51460 */ 51461 int 51462 _bcm_gport_modport_hw2api_map(int unit, bcm_module_t mod_in, bcm_port_t port_in, 51463 bcm_module_t *mod_out, bcm_port_t *port_out) 51464 { 51465 if (port_out == NULL) { 51466 return (BCM_E_PARAM); 51467 } 51468 51469 if (NUM_MODID(unit) == 1) { /* HW device has single modid */ 51470 if (mod_out != NULL) { 51471 *mod_out = mod_in; 51472 } 51473 *port_out = port_in; 51474 51475 return (BCM_E_NONE); 51476 } 51477 /* Here only for devices with multiple modid NUM_MODID(unit) > 1 */ 51478 if (mod_out == NULL) { /* physical port requested */ 51479 int isLocal = 0; 51480 bcm_module_t mymodid; 51481 BCM_IF_ERROR_RETURN( 51482 _bcm_esw_modid_is_local(unit, mod_in, &isLocal)); 51483 if (isLocal != TRUE) { 51484 return (BCM_E_PARAM); 51485 } 51486 BCM_IF_ERROR_RETURN (bcm_esw_stk_my_modid_get(unit, &mymodid)); 51487 51488 #if defined(BCM_TOMAHAWK_SUPPORT) 51489 /* Call asymmetric dual modid unmapping function */ 51490 if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) { 51491 BCM_IF_ERROR_RETURN ( 51492 _bcm_esw_stk_asymmetric_dual_modmap_map(unit, 51493 BCM_STK_MODMAP_SET, &mod_in, &port_in)); 51494 *port_out = port_in; 51495 } else 51496 #endif /* BCM_TOMAHAWK_SUPPORT */ 51497 { 51498 *port_out = port_in + 51499 (mod_in - mymodid) * (SOC_MODPORT_MAX(unit) + 1); 51500 } 51501 } else { /* NUM_MODID(unit) > 1 and not local physical port */ 51502 #if defined(BCM_TOMAHAWK_SUPPORT) 51503 /* Call asymmetric dual modid mapping function */ 51504 if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) { 51505 BCM_IF_ERROR_RETURN ( 51506 _bcm_esw_stk_asymmetric_dual_modmap_map(unit, 51507 BCM_STK_MODMAP_GET, &mod_in, &port_in)); 51508 *mod_out = mod_in; 51509 *port_out = port_in; 51510 } else 51511 #endif /* BCM_TOMAHAWK_SUPPORT */ 51512 { 51513 *port_out = port_in % (SOC_MODPORT_MAX(unit) + 1); 51514 *mod_out = mod_in + port_in / (SOC_MODPORT_MAX(unit) + 1); 51515 } 51516 } 51517 51518 return (BCM_E_NONE); 51519 } 51520 51521 /* 51522 * Function : bcm_port_gport_get 51523 * Description : Get the GPORT ID for the specified physical port. 51524 * 51525 * Parameters : (IN) unit - BCM device number 51526 * (IN) port - Port number 51527 * (OUT) gport - GPORT ID 51528 * Returns : BCM_E_XXX 51529 * Notes: 51530 * Always returns a MODPORT gport or an error. 51531 */ 51532 int 51533 bcm_esw_port_gport_get(int unit, bcm_port_t port, bcm_gport_t *gport) 51534 { 51535 int rv; 51536 _bcm_gport_dest_t dest; 51537 51538 /* Make sure port module is initialized. */ 51539 PORT_INIT(unit); 51540 51541 _bcm_gport_dest_t_init(&dest); 51542 51543 #if defined(BCM_FIREBOLT6_SUPPORT) 51544 if (SOC_IS_FIREBOLT6(unit)) { 51545 BCM_IF_ERROR_RETURN 51546 (bcm_fb6_port_param_check(unit, port)); 51547 } else 51548 #endif 51549 { 51550 PORT_PARAM_CHECK(unit, port); 51551 } 51552 51553 rv = bcm_esw_stk_my_modid_get(unit, &dest.modid); 51554 51555 if (BCM_FAILURE(rv)) { 51556 return BCM_E_UNAVAIL; 51557 } 51558 51559 if (soc_feature(unit, soc_feature_sysport_remap)) { 51560 BCM_XLATE_SYSPORT_P2S(unit, &port); 51561 } 51562 51563 dest.port = port; 51564 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 51565 51566 /* In this case we can safely assume that a port is in hw format */ 51567 /* since it is a physical port number */ 51568 BCM_IF_ERROR_RETURN 51569 (_bcm_gport_modport_hw2api_map(unit, dest.modid, dest.port, 51570 &(dest.modid), &(dest.port))); 51571 51572 return _bcm_esw_gport_construct(unit, &dest, gport); 51573 } 51574 51575 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 51576 /* 51577 * Function : bcm_port_gport_add 51578 * Description : Add the GPORT ID for the specified physical port. 51579 * 51580 * Parameters : (IN) unit - BCM device number 51581 * (IN) local_port - Port number 51582 * (IN) modport - GPORT ID 51583 * Returns : BCM_E_XXX 51584 */ 51585 int 51586 _bcm_esw_port_gport_add(int unit, bcm_port_t local_port, 51587 bcm_gport_t modport) 51588 { 51589 int subport_index = 0; 51590 bcm_port_t old_local_port = 0; 51591 modport_map_subport_entry_t modport_map_subport_entry; 51592 51593 /* Make sure port module is initialized. */ 51594 PORT_INIT(unit); 51595 51596 /* Parameter check */ 51597 PORT_PARAM_CHECK(unit, local_port); 51598 if (!BCM_GPORT_IS_MODPORT(modport)) { 51599 return BCM_E_PARAM; 51600 } 51601 51602 SOC_IF_ERROR_RETURN( 51603 _bcm_esw_port_subport_index_get(unit, modport, &subport_index)); 51604 51605 SOC_IF_ERROR_RETURN 51606 (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index, 51607 &modport_map_subport_entry)); 51608 old_local_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 51609 &modport_map_subport_entry, DESTf); 51610 if(old_local_port == local_port) { 51611 return BCM_E_NONE; 51612 } 51613 if(old_local_port) { 51614 return BCM_E_RESOURCE; 51615 } 51616 51617 soc_MODPORT_MAP_SUBPORTm_field32_set (unit, 51618 &modport_map_subport_entry, DESTf, local_port); 51619 soc_MODPORT_MAP_SUBPORTm_field32_set (unit, 51620 &modport_map_subport_entry, ISTRUNKf, 0); 51621 soc_MODPORT_MAP_SUBPORTm_field32_set (unit, 51622 &modport_map_subport_entry, ENABLEf, 1); 51623 SOC_IF_ERROR_RETURN 51624 (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index, 51625 &modport_map_subport_entry)); 51626 51627 return BCM_E_NONE; 51628 } 51629 51630 /* 51631 * Function : bcm_port_gport_get_all 51632 * Description : Get all the extra GPORT ID for the specified physical port. 51633 * 51634 * Parameters : (IN) unit - BCM device number 51635 * (IN) local_port - Port number 51636 * (IN) modport_max - size of gport array 51637 * (OUT) gport_array - Gport number 51638 * (OUT) count - GPORT count 51639 * Returns : BCM_E_XXX 51640 * Notes: 51641 * Always returns MODPORT gports or an error. 51642 */ 51643 int _bcm_esw_port_gport_get_all(int unit, bcm_port_t local_port, int size, 51644 bcm_gport_t *gport_array, int *count) 51645 { 51646 int rv = BCM_E_NONE; 51647 int mod_idx = 0; 51648 int port_idx = 0; 51649 int base_index = 0; 51650 bcm_gport_t modport = 0; 51651 _bcm_gport_dest_t dest; 51652 bcm_port_t egress_port = 0; 51653 bcm_stk_modid_config_t mod_cfg; 51654 modid_base_ptr_entry_t modid_base_entry; 51655 modport_map_subport_entry_t modport_map_subport_entry; 51656 soc_info_t *si = &SOC_INFO(unit); 51657 int i = 0, valid = 0, modid = 0, n_ports = 0; 51658 51659 /* Make sure port module is initialized. */ 51660 PORT_INIT(unit); 51661 51662 /* Parameter check */ 51663 PORT_PARAM_CHECK(unit, local_port); 51664 if (size < 0 || count == NULL) { 51665 return BCM_E_PARAM; 51666 } 51667 51668 if ((size > 0) && gport_array == NULL) { 51669 return BCM_E_PARAM; 51670 } 51671 51672 mod_cfg.modid_type = bcmStkModidTypeMultiNextHops; 51673 mod_cfg.modid = BCM_MODID_INVALID; 51674 BCM_IF_ERROR_RETURN(bcm_esw_stk_modid_config_get(unit, &mod_cfg)); 51675 51676 *count = 0; 51677 if (size == 0) { 51678 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 51679 for (i = 0; i < si->num_modules; i++) { 51680 if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] == 51681 BCM_MODID_INVALID) { 51682 continue; 51683 } 51684 BCM_IF_ERROR_RETURN( 51685 _bcm_esw_stk_get_mod_config_by_type(unit, 51686 BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid, 51687 &base_index)); 51688 if (valid == 0) { 51689 continue; 51690 } 51691 n_ports = src_modid_base_index_bk[unit]->num_ports[modid]; 51692 for (port_idx = base_index; port_idx < base_index + n_ports; 51693 port_idx++) { 51694 SOC_IF_ERROR_RETURN 51695 (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx, 51696 &modport_map_subport_entry)); 51697 /* Check if index is used. */ 51698 egress_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 51699 &modport_map_subport_entry, DESTf); 51700 if(egress_port == local_port) {/* Entry found. */ 51701 (*count)++; 51702 } 51703 } 51704 } 51705 } 51706 51707 for (mod_idx = mod_cfg.modid; mod_idx < mod_cfg.modid + mod_cfg.num_mods; 51708 mod_idx ++) { 51709 MODULE_ID_LOWER_6_BITS(mod_idx); /* lower 6 bit */ 51710 SOC_IF_ERROR_RETURN( 51711 READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_idx, 51712 &modid_base_entry)); 51713 base_index = 51714 soc_MODID_BASE_PTRm_field32_get(unit, &modid_base_entry, 51715 MODID_BASEf); 51716 SOC_IF_ERROR_RETURN( 51717 READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, base_index, 51718 &modport_map_subport_entry)); 51719 /* Check if index is used. */ 51720 egress_port = 51721 soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 51722 &modport_map_subport_entry, DESTf); 51723 if (egress_port == local_port) {/* Entry found. */ 51724 (*count)++; 51725 } 51726 } 51727 return BCM_E_NONE; 51728 } 51729 51730 _bcm_gport_dest_t_init(&dest); 51731 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 51732 for (i = 0; i < si->num_modules; i++) { 51733 if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] == 51734 BCM_MODID_INVALID) { 51735 continue; 51736 } 51737 BCM_IF_ERROR_RETURN( 51738 _bcm_esw_stk_get_mod_config_by_type(unit, 51739 BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid, 51740 &base_index)); 51741 if (valid == 0) { 51742 continue; 51743 } 51744 n_ports = src_modid_base_index_bk[unit]->num_ports[modid]; 51745 for (port_idx = base_index; port_idx < base_index + n_ports; 51746 port_idx++) { 51747 if ((*count) < size) { 51748 SOC_IF_ERROR_RETURN 51749 (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx, 51750 &modport_map_subport_entry)); 51751 /* Check if index is used. */ 51752 egress_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 51753 &modport_map_subport_entry, DESTf); 51754 if (egress_port == local_port) { 51755 /* Entry found. */ 51756 dest.port = port_idx - base_index; 51757 dest.modid = modid; 51758 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 51759 rv = _bcm_esw_gport_construct(unit, &dest, &modport); 51760 gport_array[(*count)++] = modport; 51761 } 51762 } 51763 } 51764 } 51765 } 51766 51767 for (mod_idx = mod_cfg.modid; mod_idx < mod_cfg.modid + mod_cfg.num_mods; 51768 mod_idx ++) { 51769 MODULE_ID_LOWER_6_BITS(mod_idx); /* lower 6 bit */ 51770 SOC_IF_ERROR_RETURN 51771 (READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_idx, &modid_base_entry)); 51772 base_index = soc_MODID_BASE_PTRm_field32_get(unit, 51773 &modid_base_entry, MODID_BASEf); 51774 if ((*count) < size) { 51775 SOC_IF_ERROR_RETURN( 51776 READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, base_index, 51777 &modport_map_subport_entry)); 51778 /* Check if index is used. */ 51779 egress_port = 51780 soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 51781 &modport_map_subport_entry, DESTf); 51782 if (egress_port == local_port) { 51783 /* Entry found. */ 51784 dest.port = BCM_PORT_INVALID; 51785 dest.modid = mod_idx; 51786 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 51787 rv = _bcm_esw_gport_construct(unit, &dest, &modport); 51788 gport_array[(*count)++] = modport; 51789 } 51790 } 51791 } 51792 51793 return rv; 51794 } 51795 51796 /* 51797 * Function : bcm_port_gport_delete 51798 * Description : Delete the mapping of the specified GPORT. 51799 * 51800 * Parameters : (IN) unit - BCM device number 51801 * (IN) modport - GPORT ID 51802 * Returns : BCM_E_XXX 51803 */ 51804 int 51805 _bcm_esw_port_gport_delete(int unit, bcm_port_t local_port, bcm_gport_t modport) 51806 { 51807 int subport_index = 0; 51808 modport_map_subport_entry_t modport_map_subport_entry; 51809 51810 /* Make sure port module is initialized. */ 51811 PORT_INIT(unit); 51812 51813 /* Parameter check */ 51814 PORT_PARAM_CHECK(unit, local_port); 51815 if (!BCM_GPORT_IS_MODPORT(modport)) { 51816 return BCM_E_PARAM; 51817 } 51818 51819 SOC_IF_ERROR_RETURN( 51820 _bcm_esw_port_subport_index_get(unit, modport, &subport_index)); 51821 51822 SOC_IF_ERROR_RETURN 51823 (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index, 51824 &modport_map_subport_entry)); 51825 soc_MODPORT_MAP_SUBPORTm_field32_set(unit, 51826 &modport_map_subport_entry, DESTf, 0); 51827 soc_MODPORT_MAP_SUBPORTm_field32_set (unit, 51828 &modport_map_subport_entry, ISTRUNKf, 0); 51829 soc_MODPORT_MAP_SUBPORTm_field32_set (unit, 51830 &modport_map_subport_entry, ENABLEf, 0); 51831 SOC_IF_ERROR_RETURN 51832 (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index, 51833 &modport_map_subport_entry)); 51834 51835 return BCM_E_NONE; 51836 } 51837 51838 /* 51839 * Function : bcm_port_gport_delete_all 51840 * Description : Delete all the extra mapping of the specified physical port. 51841 * 51842 * Parameters : (IN) unit - BCM device number 51843 * (IN) local_port - PORT ID 51844 * Returns : BCM_E_XXX 51845 */ 51846 int 51847 _bcm_esw_port_gport_delete_all(int unit, bcm_port_t local_port) 51848 { 51849 int mod_idx = 0; 51850 int port_idx = 0; 51851 int base_index = 0; 51852 bcm_port_t egress_port = 0; 51853 bcm_stk_modid_config_t mod_cfg; 51854 modid_base_ptr_entry_t modid_base_entry; 51855 modport_map_subport_entry_t modport_map_subport_entry; 51856 soc_info_t *si = &SOC_INFO(unit); 51857 int i = 0, valid = 0, modid = 0, n_ports = 0; 51858 51859 /* Make sure port module is initialized. */ 51860 PORT_INIT(unit); 51861 51862 /* Parameter check */ 51863 PORT_PARAM_CHECK(unit, local_port); 51864 51865 mod_cfg.modid_type = bcmStkModidTypeMultiNextHops; 51866 mod_cfg.modid = BCM_MODID_INVALID; 51867 BCM_IF_ERROR_RETURN( 51868 bcm_esw_stk_modid_config_get(unit, &mod_cfg)); 51869 51870 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 51871 for (i = 0; i < si->num_modules; i++) { 51872 if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] == 51873 BCM_MODID_INVALID) { 51874 continue; 51875 } 51876 BCM_IF_ERROR_RETURN( 51877 _bcm_esw_stk_get_mod_config_by_type(unit, 51878 BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid, 51879 &base_index)); 51880 if (valid == 0) { 51881 continue; 51882 } 51883 n_ports = src_modid_base_index_bk[unit]->num_ports[modid]; 51884 for (port_idx = base_index; port_idx < base_index + n_ports; 51885 port_idx++) { 51886 SOC_IF_ERROR_RETURN 51887 (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx, 51888 &modport_map_subport_entry)); 51889 /* Check if index is used. */ 51890 egress_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 51891 &modport_map_subport_entry, DESTf); 51892 if(egress_port == local_port) { 51893 /* Entry found. */ 51894 soc_MODPORT_MAP_SUBPORTm_field32_set( 51895 unit, &modport_map_subport_entry, DESTf, 0); 51896 soc_MODPORT_MAP_SUBPORTm_field32_set( 51897 unit, &modport_map_subport_entry, ENABLEf, 0); 51898 SOC_IF_ERROR_RETURN 51899 (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx, 51900 &modport_map_subport_entry)); 51901 } 51902 } 51903 } 51904 } 51905 51906 for (mod_idx = mod_cfg.modid; mod_idx < mod_cfg.modid + mod_cfg.num_mods; 51907 mod_idx ++) { 51908 MODULE_ID_LOWER_6_BITS(mod_idx); /* lower 6 bit */ 51909 SOC_IF_ERROR_RETURN 51910 (READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_idx, &modid_base_entry)); 51911 base_index = soc_MODID_BASE_PTRm_field32_get(unit, 51912 &modid_base_entry, MODID_BASEf); 51913 SOC_IF_ERROR_RETURN( 51914 READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, base_index, 51915 &modport_map_subport_entry)); 51916 /* Check if index is used. */ 51917 egress_port = 51918 soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 51919 &modport_map_subport_entry, DESTf); 51920 if (egress_port == local_port) { 51921 /* Entry found. */ 51922 soc_MODPORT_MAP_SUBPORTm_field32_set( 51923 unit, &modport_map_subport_entry, DESTf, 0); 51924 soc_MODPORT_MAP_SUBPORTm_field32_set( 51925 unit, &modport_map_subport_entry, ENABLEf, 0); 51926 SOC_IF_ERROR_RETURN( 51927 WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx, 51928 &modport_map_subport_entry)); 51929 } 51930 } 51931 51932 return BCM_E_NONE; 51933 } 51934 51935 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 51936 51937 /* 51938 * Function : bcm_port_gport_add 51939 * Description : Add the GPORT ID for the specified physical port. 51940 * 51941 * Parameters : (IN) unit - BCM device number 51942 * (IN) local_port - Port number 51943 * (IN) modport - GPORT ID 51944 * Returns : BCM_E_XXX 51945 */ 51946 int 51947 bcm_esw_port_gport_add(int unit, bcm_port_t local_port, 51948 bcm_gport_t modport) 51949 { 51950 int rv = BCM_E_UNAVAIL; 51951 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 51952 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 51953 rv = _bcm_esw_port_gport_add(unit, local_port, modport); 51954 } 51955 #endif 51956 return rv; 51957 } 51958 51959 /* 51960 * Function : bcm_port_gport_get_all 51961 * Description : Get all the extra GPORT ID for the specified physical port. 51962 * 51963 * Parameters : (IN) unit - BCM device number 51964 * (IN) local_port - Port number 51965 * (IN) modport_max - size of gport array 51966 * (OUT) gport_array - Gport number 51967 * (OUT) count - GPORT count 51968 * Returns : BCM_E_XXX 51969 * Notes: 51970 */ 51971 int bcm_esw_port_gport_get_all(int unit, bcm_port_t local_port, int size, 51972 bcm_gport_t *gport_array, int *count) 51973 { 51974 int rv = BCM_E_UNAVAIL; 51975 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 51976 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 51977 if (size < 0 || count == NULL) { 51978 return BCM_E_PARAM; 51979 } 51980 51981 if ((size > 0) && gport_array == NULL) { 51982 return BCM_E_PARAM; 51983 } 51984 51985 rv = _bcm_esw_port_gport_get_all(unit, local_port, size, gport_array, count); 51986 } 51987 #endif 51988 return rv; 51989 } 51990 51991 /* 51992 * Function : bcm_port_gport_delete 51993 * Description : Delete the mapping of the specified GPORT. 51994 * 51995 * Parameters : (IN) unit - BCM device number 51996 * (IN) modport - GPORT ID 51997 * Returns : BCM_E_XXX 51998 */ 51999 int 52000 bcm_esw_port_gport_delete(int unit, bcm_port_t local_port, bcm_gport_t modport) 52001 { 52002 int rv = BCM_E_UNAVAIL; 52003 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 52004 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 52005 rv = _bcm_esw_port_gport_delete(unit, local_port, modport); 52006 } 52007 #endif 52008 return rv; 52009 } 52010 52011 /* 52012 * Function : bcm_port_gport_delete_all 52013 * Description : Delete all the extra mapping of the specified physical port. 52014 * 52015 * Parameters : (IN) unit - BCM device number 52016 * (IN) local_port - PORT ID 52017 * Returns : BCM_E_XXX 52018 */ 52019 int 52020 bcm_esw_port_gport_delete_all(int unit, bcm_port_t local_port) 52021 { 52022 int rv = BCM_E_UNAVAIL; 52023 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 52024 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 52025 rv = _bcm_esw_port_gport_delete_all(unit, local_port); 52026 } 52027 #endif 52028 return rv; 52029 } 52030 52031 /* 52032 * Function: 52033 * bcm_esw_port_gport_is_free 52034 * Purpose: 52035 * Request if the given gport value is available on the device 52036 * Parameters: 52037 * unit - (IN) Unit number. 52038 * gport - (IN) GPORT ID. 52039 * Returns: 52040 * BCM_E_NONE - gport is valid and available on the device 52041 * BCM_E_EXISTS - gport is valid but already in use 52042 * on this device 52043 * BCM_E_PARAM - gport is not valid on this device 52044 * BCM_E_UNAVAIL - Feature unavailable 52045 * Notes: 52046 */ 52047 int 52048 bcm_esw_port_gport_is_free(int unit, bcm_gport_t gport) 52049 { 52050 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 52051 int rv = BCM_E_PARAM; 52052 int vp = 0, vp_idx, rv_vp = 0, is_vp = FALSE; 52053 int vp_count = 1; /* Required consecutive VP's */ 52054 52055 /* Make sure port module is initialized. */ 52056 PORT_INIT(unit); 52057 52058 if (!soc_mem_is_valid(unit, SOURCE_VPm)) { 52059 /* No virtual ports at this time. */ 52060 return BCM_E_UNAVAIL; 52061 } 52062 52063 #if defined(BCM_MPLS_SUPPORT) 52064 if (BCM_GPORT_IS_MPLS_PORT(gport) && 52065 soc_feature(unit, soc_feature_mpls)) { 52066 is_vp = TRUE; 52067 vp = BCM_GPORT_MPLS_PORT_ID_GET(gport); 52068 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 52069 rv_vp = -1; 52070 } else { 52071 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeMpls); 52072 } 52073 } else 52074 #endif /* BCM_MPLS_SUPPORT */ 52075 if (BCM_GPORT_IS_MIM_PORT(gport) && 52076 soc_feature(unit, soc_feature_mim)) { 52077 is_vp = TRUE; 52078 vp = BCM_GPORT_MIM_PORT_ID_GET(gport); 52079 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 52080 rv_vp = -1; 52081 } else { 52082 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeMim); 52083 } 52084 } else if (BCM_GPORT_IS_L2GRE_PORT(gport) && 52085 soc_feature(unit, soc_feature_l2gre)) { 52086 is_vp = TRUE; 52087 vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport); 52088 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 52089 rv_vp = -1; 52090 } else { 52091 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre); 52092 } 52093 } else if (BCM_GPORT_IS_VXLAN_PORT(gport) && 52094 soc_feature(unit, soc_feature_vxlan)) { 52095 is_vp = TRUE; 52096 vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport); 52097 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 52098 rv_vp = -1; 52099 } else { 52100 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan); 52101 } 52102 } else if (BCM_GPORT_IS_FLOW_PORT(gport) && 52103 soc_feature(unit, soc_feature_flex_flow)) { 52104 is_vp = TRUE; 52105 vp = BCM_GPORT_FLOW_PORT_ID_GET(gport); 52106 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 52107 rv_vp = -1; 52108 } else { 52109 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeFlow); 52110 } 52111 } else if (BCM_GPORT_IS_WLAN_PORT(gport) && 52112 soc_feature(unit, soc_feature_wlan)) { 52113 is_vp = TRUE; 52114 vp = BCM_GPORT_WLAN_PORT_ID_GET(gport); 52115 if (SOC_MEM_IS_VALID(unit, WLAN_SVP_TABLEm)) { 52116 if (vp > soc_mem_index_count(unit, WLAN_SVP_TABLEm)) { 52117 rv_vp = -1; 52118 } else { 52119 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeWlan); 52120 } 52121 52122 } else if (SOC_MEM_IS_VALID(unit, SOURCE_VP_ATTRIBUTES_2m)) { 52123 if (vp > soc_mem_index_count(unit, SOURCE_VP_ATTRIBUTES_2m)) { 52124 rv_vp = -1; 52125 } else { 52126 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeWlan); 52127 } 52128 } else { 52129 rv_vp = -1; 52130 } 52131 } else if (BCM_GPORT_IS_TRILL_PORT(gport) && 52132 soc_feature(unit, soc_feature_trill)) { 52133 is_vp = TRUE; 52134 vp = BCM_GPORT_TRILL_PORT_ID_GET(gport); 52135 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 52136 rv_vp = -1; 52137 } else { 52138 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeTrill); 52139 } 52140 } else if (BCM_GPORT_IS_VLAN_PORT(gport) && 52141 soc_feature(unit, soc_feature_vlan_vp)) { 52142 is_vp = TRUE; 52143 vp = BCM_GPORT_VLAN_PORT_ID_GET(gport); 52144 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 52145 rv_vp = -1; 52146 } else { 52147 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeVlan); 52148 } 52149 } else if (BCM_GPORT_IS_NIV_PORT(gport) && 52150 soc_feature(unit, soc_feature_niv)) { 52151 is_vp = TRUE; 52152 vp = BCM_GPORT_NIV_PORT_ID_GET(gport); 52153 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 52154 rv_vp = -1; 52155 } else { 52156 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeNiv); 52157 } 52158 } 52159 #if defined(BCM_TRIUMPH2_SUPPORT) 52160 else if ((BCM_GPORT_IS_SUBPORT_GROUP(gport) || 52161 BCM_GPORT_IS_SUBPORT_PORT(gport)) && 52162 soc_feature(unit, soc_feature_subport_enhanced)) { 52163 /* No TR/SC support for now */ 52164 rv_vp = _bcm_tr2_subport_gport_used(unit, gport); 52165 if (BCM_E_NOT_FOUND == rv_vp) { 52166 rv = BCM_E_NONE; 52167 /* Now we need to check if the VP is in use by something else, 52168 * using the logic below. */ 52169 is_vp = TRUE; 52170 rv_vp = 0; 52171 if (BCM_GPORT_IS_SUBPORT_GROUP(gport)) { 52172 vp = BCM_GPORT_SUBPORT_GROUP_GET(gport); 52173 vp = (vp / 8) * 8; 52174 vp_count = 8; 52175 } else { 52176 vp = BCM_GPORT_SUBPORT_PORT_GET(gport); 52177 } 52178 } else if (BCM_E_NONE == rv_vp) { 52179 rv = BCM_E_EXISTS; 52180 } else { 52181 rv = rv_vp; 52182 } 52183 } 52184 #endif /* BCM_TRIUMPH2_SUPPORT */ 52185 52186 if (is_vp) { 52187 if (0 == rv_vp) { 52188 /* Double-check no other protocol is using this VP */ 52189 for (vp_idx = 0; vp_idx < vp_count; vp_idx++) { 52190 rv_vp = _bcm_vp_used_get(unit, vp + vp_idx, _bcmVpTypeAny); 52191 if (0 == rv_vp) { 52192 rv = BCM_E_NONE; 52193 } else { 52194 rv = BCM_E_EXISTS; 52195 break; 52196 } 52197 } 52198 } else if (-1 != rv_vp) { 52199 rv = BCM_E_EXISTS; 52200 } /* else parameter error */ 52201 } 52202 /* subport */ 52203 52204 return rv; 52205 #else 52206 return BCM_E_UNAVAIL; 52207 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 52208 } 52209 52210 /* 52211 * Function: 52212 * bcm_esw_port_gport_free_range_get 52213 * Purpose: 52214 * Retrieve the minimum and maximum unallocated gport values for 52215 * a given gport type. 52216 * Parameters: 52217 * unit - (IN) Unit number. 52218 * gport_type - (IN) One of BCM_GPORT_TYPE_* or BCM_GPORT_*_PORT values. 52219 * gport_min - (OUT) Minimum available gport value of type gport_type 52220 * gport_max - (OUT) Maximum available gport value of type gport_type 52221 * Returns: 52222 * BCM_E_NONE - Valid gports range of requested type returned 52223 * BCM_E_NOT_FOUND - No available gports of this type 52224 * BCM_E_PARAM - Gport type is not valid on this device 52225 * BCM_E_UNAVAIL - Feature unavailable 52226 * Notes: 52227 */ 52228 int 52229 bcm_esw_port_gport_free_range_get(int unit, uint32 gport_type, 52230 bcm_gport_t *gport_min, 52231 bcm_gport_t *gport_max) 52232 { 52233 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 52234 bcm_gport_t dev_min, dev_max, gport, free_min, free_max; 52235 int rv = BCM_E_PARAM; 52236 int svp_max; 52237 52238 /* Make sure port module is initialized. */ 52239 PORT_INIT(unit); 52240 52241 if (soc_mem_is_valid(unit, SOURCE_VPm)) { 52242 svp_max = soc_mem_index_max(unit, SOURCE_VPm); 52243 } else { 52244 /* No virtual ports at this time. */ 52245 return BCM_E_UNAVAIL; 52246 } 52247 52248 switch (gport_type) { 52249 case BCM_GPORT_MPLS_PORT: 52250 BCM_GPORT_MPLS_PORT_ID_SET(dev_min, 0); 52251 BCM_GPORT_MPLS_PORT_ID_SET(dev_max, svp_max); 52252 break; 52253 case BCM_GPORT_MIM_PORT: 52254 BCM_GPORT_MIM_PORT_ID_SET(dev_min, 0); 52255 BCM_GPORT_MIM_PORT_ID_SET(dev_max, svp_max); 52256 break; 52257 case BCM_GPORT_L2GRE_PORT: 52258 BCM_GPORT_L2GRE_PORT_ID_SET(dev_min, 0); 52259 BCM_GPORT_L2GRE_PORT_ID_SET(dev_max, svp_max); 52260 break; 52261 case BCM_GPORT_VXLAN_PORT: 52262 BCM_GPORT_VXLAN_PORT_ID_SET(dev_min, 0); 52263 BCM_GPORT_VXLAN_PORT_ID_SET(dev_max, svp_max); 52264 break; 52265 case BCM_GPORT_WLAN_PORT: 52266 BCM_GPORT_WLAN_PORT_ID_SET(dev_min, 0); 52267 BCM_GPORT_WLAN_PORT_ID_SET(dev_max, svp_max); 52268 break; 52269 case BCM_GPORT_TRILL_PORT: 52270 BCM_GPORT_TRILL_PORT_ID_SET(dev_min, 0); 52271 BCM_GPORT_TRILL_PORT_ID_SET(dev_max, svp_max); 52272 break; 52273 case BCM_GPORT_VLAN_PORT: 52274 BCM_GPORT_VLAN_PORT_ID_SET(dev_min, 0); 52275 BCM_GPORT_VLAN_PORT_ID_SET(dev_max, svp_max); 52276 break; 52277 case BCM_GPORT_NIV_PORT: 52278 BCM_GPORT_NIV_PORT_ID_SET(dev_min, 0); 52279 BCM_GPORT_NIV_PORT_ID_SET(dev_max, svp_max); 52280 break; 52281 case BCM_GPORT_SUBPORT_GROUP: 52282 BCM_GPORT_SUBPORT_GROUP_SET(dev_min, 0); 52283 BCM_GPORT_SUBPORT_GROUP_SET(dev_max, svp_max); 52284 break; 52285 case BCM_GPORT_SUBPORT_PORT: 52286 BCM_GPORT_SUBPORT_PORT_SET(dev_min, 0); 52287 BCM_GPORT_SUBPORT_PORT_SET(dev_max, svp_max); 52288 break; 52289 default: 52290 /* Not a supported gport type at this time */ 52291 return rv; 52292 } 52293 52294 free_min = free_max = 0; /* Invalid multicast group */ 52295 for (gport = dev_min; gport <= dev_max; gport++) { 52296 rv = bcm_esw_port_gport_is_free(unit, gport); 52297 if (BCM_SUCCESS(rv)) { 52298 if (0 == free_min) { 52299 free_min = gport; 52300 } 52301 free_max = gport; 52302 } else if (BCM_E_EXISTS == rv) { 52303 /* Nothing to do but clear the error */ 52304 rv = BCM_E_NONE; 52305 } else if (BCM_E_PARAM == rv) { 52306 /* Range is less than expected, stop iterating */ 52307 rv = BCM_E_NONE; 52308 break; 52309 } else { 52310 /* Real error, return */ 52311 break; 52312 } 52313 } 52314 52315 if (BCM_SUCCESS(rv)) { 52316 if (0 == free_min) { 52317 /* No available groups of this type */ 52318 return BCM_E_NOT_FOUND; 52319 } else { 52320 /* Copy the results */ 52321 *gport_min = free_min; 52322 *gport_max = free_max; 52323 } 52324 } 52325 52326 return rv; 52327 52328 #else 52329 return BCM_E_UNAVAIL; 52330 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 52331 } 52332 52333 #if defined(BCM_TRIUMPH2_SUPPORT) 52334 int 52335 _bcm_esw_port_flex_stat_index_set(int unit, bcm_gport_t port, int fs_idx, 52336 uint32 flags) 52337 { 52338 bcm_port_t loc_port; 52339 int rv; 52340 52341 rv = bcm_esw_port_local_get(unit, port, &loc_port); 52342 if (BCM_FAILURE(rv)) { 52343 return BCM_E_NOT_FOUND; /* Local port disabled */ 52344 } 52345 52346 PORT_LOCK(unit); /* Keep port tables in sync */ 52347 rv = BCM_E_NONE; 52348 if (flags & _BCM_FLEX_STAT_HW_INGRESS) { 52349 rv = soc_mem_field32_modify(unit, PORT_TABm, loc_port, VINTF_CTR_IDXf, 52350 fs_idx); 52351 } 52352 52353 if (flags & _BCM_FLEX_STAT_HW_EGRESS) { 52354 if (BCM_SUCCESS(rv)) { 52355 #ifdef BCM_TRIDENT_SUPPORT 52356 if (SOC_IS_TD_TT(unit)) { 52357 rv = soc_mem_field32_modify(unit, EGR_PORTm, loc_port, 52358 VINTF_CTR_IDXf, fs_idx); 52359 } else 52360 #endif /* BCM_TRIDENT_SUPPORT */ 52361 { 52362 rv = soc_reg_field32_modify(unit, EGR_PORT_64r, loc_port, 52363 VINTF_CTR_IDXf, fs_idx); 52364 } 52365 } 52366 } 52367 PORT_UNLOCK(unit); 52368 return rv; 52369 } 52370 52371 STATIC int 52372 _bcm_esw_port_stat_param_verify(int unit, bcm_gport_t port) 52373 { 52374 int vp; 52375 52376 if (BCM_GPORT_IS_MPLS_PORT(port)) { 52377 #if defined(BCM_MPLS_SUPPORT) && defined(INCLUDE_L3) 52378 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 52379 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 52380 return BCM_E_PARAM; 52381 } 52382 #endif 52383 } else if (BCM_GPORT_IS_NIV_PORT(port)) { 52384 #if defined(BCM_MPLS_SUPPORT) && defined(INCLUDE_L3) 52385 vp = BCM_GPORT_NIV_PORT_ID_GET(port); 52386 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) { 52387 return BCM_E_PARAM; 52388 } 52389 #endif 52390 } else if (BCM_GPORT_IS_SUBPORT_GROUP(port) || 52391 BCM_GPORT_IS_SUBPORT_PORT(port)) { 52392 52393 #if defined(BCM_HGPROXY_COE_SUPPORT) 52394 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 52395 soc_feature(unit, soc_feature_channelized_switching)) && 52396 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 52397 return bcm_esw_port_local_get(unit, port, &vp); 52398 } 52399 #endif 52400 #if defined(BCM_KATANA2_SUPPORT) 52401 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)){ 52402 return bcm_esw_port_local_get(unit, port, &vp); 52403 } 52404 #endif 52405 #if defined(INCLUDE_L3) 52406 if (BCM_FAILURE(_bcm_tr2_subport_gport_used(unit, port))) { 52407 return BCM_E_PARAM; 52408 } 52409 } else if (BCM_GPORT_IS_MIM_PORT(port)) { 52410 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 52411 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 52412 return BCM_E_PARAM; 52413 } 52414 } else if (BCM_GPORT_IS_WLAN_PORT(port)) { 52415 vp = BCM_GPORT_WLAN_PORT_ID_GET(port); 52416 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) { 52417 return BCM_E_PARAM; 52418 } 52419 #endif 52420 } else { 52421 BCM_IF_ERROR_RETURN( 52422 bcm_esw_port_local_get(unit, port, &vp)); 52423 } 52424 52425 return BCM_E_NONE; 52426 } 52427 STATIC int 52428 _bcm_esw_port_stat_param_valid(int unit, bcm_gport_t port) 52429 { 52430 PORT_INIT(unit); 52431 52432 if (!soc_feature(unit, soc_feature_gport_service_counters)) { 52433 return BCM_E_UNAVAIL; 52434 } 52435 return _bcm_esw_port_stat_param_verify(unit, port); 52436 } 52437 52438 STATIC _bcm_flex_stat_t 52439 _bcm_esw_port_stat_to_flex_stat(bcm_port_stat_t stat) 52440 { 52441 _bcm_flex_stat_t flex_stat; 52442 52443 switch (stat) { 52444 case bcmPortStatIngressPackets: 52445 flex_stat = _bcmFlexStatIngressPackets; 52446 break; 52447 case bcmPortStatIngressBytes: 52448 flex_stat = _bcmFlexStatIngressBytes; 52449 break; 52450 case bcmPortStatEgressPackets: 52451 flex_stat = _bcmFlexStatEgressPackets; 52452 break; 52453 case bcmPortStatEgressBytes: 52454 flex_stat = _bcmFlexStatEgressBytes; 52455 break; 52456 default: 52457 flex_stat = _bcmFlexStatNum; 52458 } 52459 52460 return flex_stat; 52461 } 52462 52463 /* Requires "idx" variable */ 52464 #define BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr) \ 52465 for (idx = 0; idx < nstat; idx++) { \ 52466 if (NULL == value_arr + idx) { \ 52467 return (BCM_E_PARAM); \ 52468 } \ 52469 } 52470 52471 STATIC int 52472 _bcm_port_stat_array_convert(int unit, int nstat, bcm_port_stat_t *stat_arr, 52473 _bcm_flex_stat_t *fs_arr) 52474 { 52475 int idx; 52476 52477 if ((nstat <= 0) || (nstat > _bcmFlexStatNum)) { 52478 return BCM_E_PARAM; 52479 } 52480 if ((NULL == stat_arr) || (NULL == fs_arr)) { 52481 return (BCM_E_PARAM); 52482 } 52483 52484 for (idx = 0; idx < nstat; idx++) { 52485 fs_arr[idx] = _bcm_esw_port_stat_to_flex_stat(stat_arr[idx]); 52486 } 52487 return BCM_E_NONE; 52488 } 52489 #endif /* BCM_TRIUMPH2_SUPPORT */ 52490 52491 /* 52492 * Function: 52493 * bcm_esw_port_stat_enable_set 52494 * Purpose: 52495 * Enable/disable packet and byte counters for the selected 52496 * gport. 52497 * Parameters: 52498 * unit - (IN) Unit number. 52499 * port - (IN) GPORT ID 52500 * enable - (IN) Non-zero to enable counter collection, zero to disable. 52501 * Returns: 52502 * BCM_E_XXX 52503 * Notes: 52504 */ 52505 int 52506 bcm_esw_port_stat_enable_set(int unit, bcm_gport_t port, int enable) 52507 { 52508 #if defined(BCM_TRIUMPH2_SUPPORT) 52509 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52510 uint32 num_of_tables=0; 52511 uint32 num_stat_counter_ids=0; 52512 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 52513 bcm_stat_object_t object=bcmStatObjectIngPort; 52514 uint32 stat_counter_id[ 52515 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]={0}; 52516 uint32 num_entries=0; 52517 int index=0; 52518 int rv; 52519 52520 #endif 52521 52522 /* Make sure port module is initialized. */ 52523 PORT_INIT(unit); 52524 52525 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 52526 BCM_IF_ERROR_RETURN 52527 (_bcm_esw_port_stat_param_valid(unit, port)); 52528 return _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeGport, 52529 _bcm_esw_port_flex_stat_hw_index_set, 52530 NULL, port, enable,0); 52531 } 52532 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52533 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 52534 unit,port,&num_of_tables,&table_info[0])); 52535 if (enable) { 52536 rv = _bcm_esw_stat_flex_get_counter_id(unit, num_of_tables, 52537 &table_info[0], &num_stat_counter_ids, &stat_counter_id[0]); 52538 if (BCM_SUCCESS(rv)) { 52539 return BCM_E_EXISTS; 52540 } else if (rv != BCM_E_NOT_FOUND) { 52541 return rv; 52542 } 52543 52544 for(index=0;index < num_of_tables ;index++) { 52545 if(table_info[index].direction == bcmStatFlexDirectionIngress) { 52546 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object( 52547 unit,table_info[index].table, 52548 table_info[index].index,NULL,&object)); 52549 } else { 52550 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object( 52551 unit,table_info[index].table, 52552 table_info[index].index,NULL,&object)); 52553 } 52554 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_create( 52555 unit,object,bcmStatGroupModeSingle, 52556 &stat_counter_id[table_info[index].direction], 52557 &num_entries)); 52558 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_attach( 52559 unit,port, 52560 stat_counter_id[table_info[index].direction])); 52561 } 52562 return BCM_E_NONE; 52563 } else { 52564 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_counter_id( 52565 unit, num_of_tables,&table_info[0], 52566 &num_stat_counter_ids,&stat_counter_id[0])); 52567 if ((stat_counter_id[bcmStatFlexDirectionIngress] == 0) && 52568 (stat_counter_id[bcmStatFlexDirectionEgress] == 0)) { 52569 return BCM_E_PARAM; 52570 } 52571 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_detach(unit,port)); 52572 if (stat_counter_id[bcmStatFlexDirectionIngress] != 0) { 52573 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 52574 unit, 52575 stat_counter_id[bcmStatFlexDirectionIngress])); 52576 } 52577 if (stat_counter_id[bcmStatFlexDirectionEgress] != 0) { 52578 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 52579 unit, 52580 stat_counter_id[bcmStatFlexDirectionEgress])); 52581 } 52582 return BCM_E_NONE; 52583 } 52584 #else 52585 return BCM_E_UNAVAIL; 52586 #endif 52587 #else 52588 return BCM_E_UNAVAIL; 52589 #endif 52590 } 52591 52592 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52593 /* 52594 * Function: 52595 * _bcm_esw_port_stat_get_table_info 52596 * Description: 52597 * Provides relevant flex table information(table-name,index with 52598 * direction) for given gport. 52599 * 52600 * Parameters: 52601 * unit - (IN) unit number 52602 * port - (IN) GPORT ID 52603 * num_of_tables - (OUT) Number of flex counter tables 52604 * table_info - (OUT) Flex counter tables information 52605 * 52606 * Return Value: 52607 * BCM_E_XXX 52608 * Notes: 52609 */ 52610 STATIC 52611 bcm_error_t _bcm_esw_port_stat_get_table_info( 52612 int unit, 52613 bcm_gport_t port, 52614 uint32 *num_of_tables, 52615 bcm_stat_flex_table_info_t *table_info) 52616 { 52617 #if defined(INCLUDE_L3) 52618 int vp=0; 52619 int rv=0; 52620 int nh_index=0; 52621 int vp_base=0; 52622 int vt_index =-1; 52623 bcm_vlan_t ovid = 0; 52624 uint32 port_class = 0; 52625 bcm_port_t egress_port = 0; 52626 ing_l3_next_hop_entry_t ing_nh={{0}}; 52627 egr_vlan_xlate_entry_t egr_vent={{0}}; 52628 ing_dvp_table_entry_t dvp={{0}}; 52629 egr_l3_next_hop_entry_t egr_nh={{0}}; 52630 source_vp_entry_t svp; 52631 int l3_idx=0; 52632 egr_l3_intf_entry_t l3_intf; 52633 52634 #endif 52635 bcm_port_t loc_port=0; 52636 52637 (*num_of_tables) = 0; 52638 52639 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 52640 return BCM_E_UNAVAIL; 52641 } 52642 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_param_verify(unit, port)); 52643 if (BCM_GPORT_IS_MPLS_PORT(port) || 52644 BCM_GPORT_IS_NIV_PORT(port)) { 52645 #if defined(BCM_MPLS_SUPPORT) && defined(INCLUDE_L3) 52646 if (BCM_GPORT_IS_MPLS_PORT(port)) { 52647 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 52648 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 52649 return BCM_E_NOT_FOUND; 52650 } 52651 } 52652 if (BCM_GPORT_IS_NIV_PORT(port)) { 52653 vp = BCM_GPORT_NIV_PORT_ID_GET(port); 52654 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) { 52655 return BCM_E_NOT_FOUND; 52656 } 52657 } 52658 52659 /* Ingress Side */ 52660 table_info[*num_of_tables].table=SOURCE_VPm; 52661 table_info[*num_of_tables].index=vp; 52662 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 52663 (*num_of_tables)++; 52664 /* Egress Side */ 52665 if (BCM_SUCCESS(READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp))) { 52666 nh_index = soc_mem_field32_get(unit, ING_DVP_TABLEm, &dvp, 52667 NEXT_HOP_INDEXf); 52668 if (BCM_SUCCESS(soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 52669 nh_index,&egr_nh))) { 52670 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm; 52671 table_info[*num_of_tables].index=nh_index; 52672 table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress; 52673 (*num_of_tables)++; 52674 } 52675 } 52676 return BCM_E_NONE; 52677 #endif/* BCM_MPLS_SUPPORT && INCLUDE_L3*/ 52678 } else if (BCM_GPORT_IS_SUBPORT_GROUP(port) || 52679 BCM_GPORT_IS_SUBPORT_PORT(port)) { 52680 52681 52682 #if defined(BCM_HGPROXY_COE_SUPPORT) 52683 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 52684 soc_feature(unit, soc_feature_channelized_switching)) && 52685 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 52686 52687 #if defined(BCM_CHANNELIZED_SWITCHING_SUPPORT) 52688 if (soc_feature(unit, soc_feature_channelized_switching)) { 52689 int subport_num=0; 52690 BCM_IF_ERROR_RETURN( 52691 _bcm_coe_subtag_subport_port_subport_num_get(unit, 52692 port, NULL, &subport_num)); 52693 52694 table_info[*num_of_tables].table = LPORT_TABm; 52695 table_info[*num_of_tables].index = subport_num; 52696 table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress; 52697 (*num_of_tables)++; 52698 table_info[*num_of_tables].table = EGR_LPORT_PROFILEm; 52699 table_info[*num_of_tables].index = subport_num; 52700 table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress; 52701 (*num_of_tables)++; 52702 return BCM_E_NONE; 52703 } 52704 #endif 52705 52706 if(BCM_FAILURE(bcm_esw_port_local_get(unit, port, &loc_port))) { 52707 return BCM_E_NOT_FOUND; /* Local port disabled */ 52708 } 52709 table_info[*num_of_tables].table = PORT_TABm; 52710 table_info[*num_of_tables].index =loc_port; 52711 table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress; 52712 (*num_of_tables)++; 52713 table_info[*num_of_tables].table = EGR_PORTm; 52714 table_info[*num_of_tables].index = loc_port; 52715 table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress; 52716 (*num_of_tables)++; 52717 return BCM_E_NONE; 52718 } 52719 #endif 52720 #if defined(BCM_KATANA2_SUPPORT) 52721 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)){ 52722 if(BCM_FAILURE(bcm_esw_port_local_get(unit, port, &loc_port))) { 52723 return BCM_E_NOT_FOUND; /* Local port disabled */ 52724 } 52725 table_info[*num_of_tables].table = PORT_TABm; 52726 table_info[*num_of_tables].index =loc_port; 52727 table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress; 52728 (*num_of_tables)++; 52729 table_info[*num_of_tables].table = EGR_PORTm; 52730 table_info[*num_of_tables].index = loc_port; 52731 table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress; 52732 (*num_of_tables)++; 52733 return BCM_E_NONE; 52734 } 52735 #endif /* BCM_KATANA2_SUPPORT */ 52736 #if defined(INCLUDE_L3) 52737 if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 52738 l3_idx = BCM_GPORT_SUBPORT_PORT_GET(port) & 0xfff; 52739 BCM_IF_ERROR_RETURN(soc_mem_read( 52740 unit, EGR_L3_INTFm, MEM_BLOCK_ALL, 52741 l3_idx, &l3_intf)); 52742 vp = soc_mem_field32_get(unit,EGR_L3_INTFm, &l3_intf, IVIDf); 52743 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm( 52744 unit,MEM_BLOCK_ALL,vp,&svp)); 52745 vp_base = soc_SOURCE_VPm_field32_get(unit, &svp, DVPf); 52746 /* vp = BCM_GPORT_SUBPORT_PORT_GET(port); */ 52747 /* Get the base group VP */ 52748 /* vp_base = vp & ~(0x7); */ 52749 /* Get the group's next-hop index */ 52750 BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm( 52751 unit, MEM_BLOCK_ALL, vp_base, &dvp)); 52752 nh_index = soc_ING_DVP_TABLEm_field32_get( 52753 unit, &dvp, NEXT_HOP_INDEXf); 52754 /*Get the group's OVID from the group's egress NextHopEntry*/ 52755 BCM_IF_ERROR_RETURN(soc_mem_read( 52756 unit, EGR_L3_NEXT_HOPm, 52757 MEM_BLOCK_ALL, nh_index, &egr_nh)); 52758 ovid = soc_mem_field32_get( 52759 unit, EGR_L3_NEXT_HOPm, &egr_nh, OVIDf); 52760 /* Get the egress port class */ 52761 BCM_IF_ERROR_RETURN (soc_mem_read( 52762 unit, ING_L3_NEXT_HOPm, 52763 MEM_BLOCK_ANY,nh_index, &ing_nh)); 52764 if (!soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, Tf)) { 52765 egress_port = soc_ING_L3_NEXT_HOPm_field32_get( 52766 unit, &ing_nh, PORT_NUMf); 52767 BCM_IF_ERROR_RETURN(bcm_esw_port_class_get( 52768 unit, egress_port, 52769 bcmPortClassVlanTranslateEgress, 52770 &port_class)); 52771 } 52772 sal_memset(&egr_vent, 0, sizeof(egr_vent)); 52773 soc_EGR_VLAN_XLATEm_field32_set(unit, &egr_vent, VALIDf, 1); 52774 soc_EGR_VLAN_XLATEm_field32_set(unit, &egr_vent, OVIDf,ovid); 52775 if (soc_feature(unit, soc_feature_subport_enhanced)) { 52776 soc_EGR_VLAN_XLATEm_field32_set(unit,&egr_vent,IVIDf,vp); 52777 } 52778 soc_EGR_VLAN_XLATEm_field32_set( 52779 unit,&egr_vent,ENTRY_TYPEf, 0x01); 52780 soc_EGR_VLAN_XLATEm_field32_set( 52781 unit,&egr_vent,PORT_GROUP_IDf,port_class); 52782 MEM_LOCK(unit, EGR_VLAN_XLATEm); 52783 rv = soc_mem_search(unit,EGR_VLAN_XLATEm,MEM_BLOCK_ALL, 52784 &vt_index, &egr_vent, &egr_vent, 0); 52785 if (rv < 0) { 52786 MEM_UNLOCK(unit, EGR_VLAN_XLATEm); 52787 return rv; 52788 } 52789 rv = soc_mem_write(unit, EGR_VLAN_XLATEm, 52790 MEM_BLOCK_ALL, vt_index,&egr_vent); 52791 if (BCM_FAILURE(rv)) { 52792 MEM_UNLOCK(unit, EGR_VLAN_XLATEm); 52793 return rv; 52794 } 52795 table_info[*num_of_tables].table= EGR_VLAN_XLATEm; 52796 table_info[*num_of_tables].index=vt_index; 52797 table_info[*num_of_tables].direction= 52798 bcmStatFlexDirectionEgress; 52799 (*num_of_tables)++; 52800 MEM_UNLOCK(unit, EGR_VLAN_XLATEm); 52801 return BCM_E_NONE; 52802 } else { /*BCM_GPORT_IS_SUBPORT_GROUP(port) */ 52803 #if defined(BCM_TRIUMPH2_SUPPORT) 52804 vp_base = BCM_GPORT_SUBPORT_GROUP_GET(port); 52805 BCM_IF_ERROR_RETURN(_bcm_tr2_subport_gport_used(unit,port)); 52806 table_info[*num_of_tables].table= SOURCE_VPm; 52807 table_info[*num_of_tables].index=vp_base; 52808 table_info[*num_of_tables].direction= 52809 bcmStatFlexDirectionIngress; 52810 (*num_of_tables)++; 52811 return BCM_E_NONE; 52812 #endif 52813 } 52814 } else if (BCM_GPORT_IS_MIM_PORT(port)) { 52815 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 52816 /*MIM_LOCK(unit); */ 52817 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 52818 /*MIM_UNLOCK(unit); */ 52819 return BCM_E_NOT_FOUND; 52820 } 52821 /* Ingress side */ 52822 table_info[*num_of_tables].table= SOURCE_VPm; 52823 table_info[*num_of_tables].index=vp; 52824 table_info[*num_of_tables].direction= 52825 bcmStatFlexDirectionIngress; 52826 (*num_of_tables)++; 52827 /* Egress side */ 52828 if (BCM_SUCCESS(READ_ING_DVP_TABLEm( 52829 unit, MEM_BLOCK_ANY, vp, &dvp))) { 52830 nh_index = soc_mem_field32_get(unit, ING_DVP_TABLEm, &dvp, 52831 NEXT_HOP_INDEXf); 52832 if (BCM_SUCCESS(soc_mem_read( 52833 unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 52834 nh_index,&egr_nh))) { 52835 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm; 52836 table_info[*num_of_tables].index=nh_index; 52837 table_info[*num_of_tables].direction= 52838 bcmStatFlexDirectionEgress; 52839 (*num_of_tables)++; 52840 } 52841 } 52842 return BCM_E_NONE; 52843 } else if (BCM_GPORT_IS_WLAN_PORT(port)) { 52844 vp = BCM_GPORT_WLAN_PORT_ID_GET(port); 52845 /*WLAN_LOCK(unit); */ 52846 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) { 52847 /*WLAN_UNLOCK(unit); */ 52848 return BCM_E_NOT_FOUND; 52849 } 52850 /*Ingress Side */ 52851 table_info[*num_of_tables].table= SOURCE_VPm; 52852 table_info[*num_of_tables].index=vp; 52853 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 52854 (*num_of_tables)++; 52855 BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm( 52856 unit, MEM_BLOCK_ANY, vp, &dvp)); 52857 nh_index = soc_ING_DVP_TABLEm_field32_get( 52858 unit, &dvp, NEXT_HOP_INDEXf); 52859 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm; 52860 table_info[*num_of_tables].index=nh_index; 52861 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress; 52862 (*num_of_tables)++; 52863 return BCM_E_NONE; 52864 } else if (BCM_GPORT_IS_VLAN_PORT(port)) { 52865 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 52866 52867 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan))) { 52868 return BCM_E_NOT_FOUND; 52869 } 52870 52871 /*Ingress Side */ 52872 table_info[*num_of_tables].table= SOURCE_VPm; 52873 table_info[*num_of_tables].index=vp; 52874 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 52875 (*num_of_tables)++; 52876 BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm( 52877 unit, MEM_BLOCK_ANY, vp, &dvp)); 52878 nh_index = soc_ING_DVP_TABLEm_field32_get( 52879 unit, &dvp, NEXT_HOP_INDEXf); 52880 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm; 52881 table_info[*num_of_tables].index=nh_index; 52882 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress; 52883 (*num_of_tables)++; 52884 return BCM_E_NONE; 52885 #endif 52886 } 52887 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 52888 else if (BCM_GPORT_IS_TRUNK(port)) { 52889 if (!soc_feature(unit, soc_feature_vp_lag)) { 52890 return BCM_E_UNAVAIL; 52891 } 52892 BCM_IF_ERROR_RETURN( 52893 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port), 52894 &vp)); 52895 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 52896 return BCM_E_NOT_FOUND; 52897 } 52898 /* Ingress Side */ 52899 table_info[*num_of_tables].table = SOURCE_VPm; 52900 table_info[*num_of_tables].index = vp; 52901 table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress; 52902 (*num_of_tables)++; 52903 return BCM_E_NONE; 52904 } 52905 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3*/ 52906 else { 52907 if(BCM_FAILURE(bcm_esw_port_local_get(unit, port, &loc_port))) { 52908 return BCM_E_NOT_FOUND; /* Local port disabled */ 52909 } 52910 /*PORT_LOCK(unit); */ 52911 #if defined(BCM_TRIDENT3_SUPPORT) 52912 if (SOC_IS_TRIDENT3X(unit)) { 52913 table_info[*num_of_tables].table = LPORT_TABm; 52914 table_info[*num_of_tables].index = loc_port; 52915 table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress; 52916 (*num_of_tables)++; 52917 if (soc_mem_field_valid(unit, EGR_PORTm, EGR_LPORT_PROFILE_IDXf) && 52918 soc_mem_is_valid(unit, EGR_LPORT_PROFILEm)) { 52919 table_info[*num_of_tables].table = EGR_LPORT_PROFILEm; 52920 table_info[*num_of_tables].index = loc_port; 52921 table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress; 52922 (*num_of_tables)++; 52923 } else { 52924 return BCM_E_NOT_FOUND; 52925 } 52926 } else 52927 #endif 52928 { 52929 table_info[*num_of_tables].table= PORT_TABm; 52930 table_info[*num_of_tables].index=loc_port; 52931 table_info[*num_of_tables].direction= bcmStatFlexDirectionIngress; 52932 (*num_of_tables)++; 52933 table_info[*num_of_tables].table= EGR_PORTm; 52934 table_info[*num_of_tables].index=loc_port; 52935 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress; 52936 (*num_of_tables)++; 52937 } 52938 return BCM_E_NONE; 52939 } 52940 return BCM_E_NOT_FOUND; 52941 } 52942 #endif 52943 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52944 /* 52945 * Function: 52946 * _bcm_esw_port_stat_attach 52947 * Description: 52948 * Attach counter entries to the given GPORT 52949 * 52950 * Parameters: 52951 * unit - (IN) unit number 52952 * port - (IN) GPORT ID 52953 * stat_counter_id - (IN) Stat Counter ID. 52954 * 52955 * Return Value: 52956 * BCM_E_XXX 52957 * Notes: 52958 */ 52959 int _bcm_esw_port_stat_attach( 52960 int unit, 52961 bcm_gport_t port, 52962 uint32 stat_counter_id) 52963 { 52964 soc_mem_t table=0; 52965 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 52966 uint32 pool_number=0; 52967 uint32 base_index=0; 52968 bcm_stat_flex_mode_t offset_mode=0; 52969 bcm_stat_object_t object=bcmStatObjectIngPort; 52970 bcm_stat_group_mode_t group_mode= bcmStatGroupModeSingle; 52971 uint32 count=0; 52972 uint32 actual_num_tables=0; 52973 uint32 num_of_tables=0; 52974 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 52975 uint8 skip_table_check = 0; 52976 52977 _bcm_esw_stat_get_counter_id_info( 52978 unit, stat_counter_id, 52979 &group_mode,&object,&offset_mode,&pool_number,&base_index); 52980 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction)); 52981 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode)); 52982 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info( 52983 unit,object,1,&actual_num_tables,&table,&direction)); 52984 52985 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 52986 unit, port,&num_of_tables,&table_info[0])); 52987 skip_table_check = soc_property_get(unit, spn_FLEX_STAT_SHARE_ENABLE, 0); 52988 for (count=0; count < num_of_tables ; count++) { 52989 if ( (table_info[count].direction == direction) && 52990 ((table_info[count].table == table) || (skip_table_check)) ) { 52991 if(direction == bcmStatFlexDirectionIngress) { 52992 return _bcm_esw_stat_flex_attach_ingress_table_counters( 52993 unit, 52994 table_info[count].table, 52995 table_info[count].index, 52996 offset_mode, 52997 base_index, 52998 pool_number); 52999 } else { 53000 return _bcm_esw_stat_flex_attach_egress_table_counters( 53001 unit, 53002 table_info[count].table, 53003 table_info[count].index, 53004 0, 53005 offset_mode, 53006 base_index, 53007 pool_number); 53008 } 53009 } 53010 } 53011 return BCM_E_NOT_FOUND; 53012 } 53013 #endif 53014 53015 /* 53016 * Function: 53017 * bcm_esw_port_stat_attach 53018 * Description: 53019 * Attach counter entries to the given GPORT 53020 * 53021 * Parameters: 53022 * unit - (IN) unit number 53023 * port - (IN) GPORT ID 53024 * stat_counter_id - (IN) Stat Counter ID. 53025 * 53026 * Return Value: 53027 * BCM_E_XXX 53028 * Notes: 53029 */ 53030 int bcm_esw_port_stat_attach( 53031 int unit, 53032 bcm_gport_t port, 53033 uint32 stat_counter_id) 53034 { 53035 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53036 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 53037 return _bcm_esw_port_stat_attach(unit,port,stat_counter_id); 53038 } else 53039 #endif 53040 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 53041 if (soc_feature(unit,soc_feature_gport_service_counters)) { 53042 _bcm_flex_stat_type_t fs_type; 53043 uint32 fs_inx; 53044 uint32 flag; 53045 int rv; 53046 53047 fs_type = _BCM_FLEX_STAT_TYPE(stat_counter_id); 53048 fs_inx = _BCM_FLEX_STAT_COUNT_INX(stat_counter_id); 53049 53050 if (!((fs_type == _bcmFlexStatTypeGport || 53051 fs_type == _bcmFlexStatTypeEgressGport) && fs_inx)) { 53052 return BCM_E_PARAM; 53053 } 53054 BCM_IF_ERROR_RETURN 53055 (_bcm_esw_port_stat_param_valid(unit, port)); 53056 53057 flag = fs_type==_bcmFlexStatTypeGport? _BCM_FLEX_STAT_HW_INGRESS: 53058 _BCM_FLEX_STAT_HW_EGRESS; 53059 53060 rv = _bcm_esw_flex_stat_enable_set(unit, fs_type, 53061 _bcm_esw_port_flex_stat_hw_index_set, 53062 INT_TO_PTR(flag), 53063 port, TRUE,fs_inx); 53064 return rv; 53065 } else 53066 #endif 53067 { 53068 return BCM_E_UNAVAIL; 53069 } 53070 } 53071 53072 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53073 /* 53074 * Function: 53075 * _bcm_esw_port_stat_detach 53076 * Description: 53077 * Detach counter entries to the given GPORT 53078 * 53079 * Parameters: 53080 * unit - (IN) unit number 53081 * port - (IN) GPORT ID 53082 * 53083 * Return Value: 53084 * BCM_E_XXX 53085 * Notes: 53086 */ 53087 int _bcm_esw_port_stat_detach( 53088 int unit, 53089 bcm_gport_t port) 53090 { 53091 uint32 count=0; 53092 uint32 num_of_tables=0; 53093 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 53094 bcm_error_t rv = BCM_E_NONE; 53095 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 53096 53097 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 53098 unit, port,&num_of_tables,&table_info[0])); 53099 53100 for (count=0; count < num_of_tables ; count++) { 53101 if (table_info[count].direction == bcmStatFlexDirectionIngress) { 53102 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 53103 unit, 53104 table_info[count].table, 53105 table_info[count].index); 53106 if (BCM_E_NONE != rv && 53107 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 53108 err_code[bcmStatFlexDirectionIngress] = rv; 53109 } 53110 } else { 53111 rv = _bcm_esw_stat_flex_detach_egress_table_counters( 53112 unit, 53113 0, 53114 table_info[count].table, 53115 table_info[count].index); 53116 if (BCM_E_NONE != rv && 53117 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) { 53118 err_code[bcmStatFlexDirectionEgress] = rv; 53119 } 53120 } 53121 } 53122 53123 BCM_STAT_FLEX_DETACH_RETURN(err_code) 53124 } 53125 53126 /* 53127 * Function: 53128 * _bcm_esw_port_stat_detach_with_id 53129 * Description: 53130 * Detach counter entries to the given GPORT with a given stat counter id 53131 * 53132 * Parameters: 53133 * unit - (IN) unit number 53134 * port - (IN) GPORT ID 53135 * stat_counter_id - (IN) Stat Counter ID 53136 * 53137 * Return Value: 53138 * BCM_E_XXX 53139 * Notes: 53140 */ 53141 bcm_error_t _bcm_esw_port_stat_detach_with_id( 53142 int unit, 53143 bcm_gport_t port, 53144 uint32 stat_counter_id) 53145 { 53146 uint32 count=0; 53147 uint32 num_of_tables=0; 53148 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 53149 bcm_error_t rv = BCM_E_NONE; 53150 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 53151 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 53152 uint32 pool_number=0; 53153 uint32 base_index=0; 53154 bcm_stat_flex_mode_t offset_mode=0; 53155 bcm_stat_object_t object=bcmStatObjectIngPort; 53156 bcm_stat_group_mode_t group_mode= bcmStatGroupModeSingle; 53157 uint32 actual_num_tables=0; 53158 soc_mem_t table=0; 53159 53160 _bcm_esw_stat_get_counter_id_info(unit, stat_counter_id, &group_mode, &object, 53161 &offset_mode, &pool_number, &base_index); 53162 BCM_IF_ERROR_RETURN 53163 (_bcm_esw_stat_validate_object(unit, object, &direction)); 53164 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit, group_mode)); 53165 BCM_IF_ERROR_RETURN 53166 (_bcm_esw_stat_flex_get_table_info(unit, object, 1, &actual_num_tables, 53167 &table, &direction)); 53168 53169 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 53170 unit, port,&num_of_tables,&table_info[0])); 53171 53172 for (count=0; count < num_of_tables ; count++) { 53173 if((table_info[count].direction == direction) && 53174 (table_info[count].table == table)) { 53175 if(direction == bcmStatFlexDirectionIngress) { 53176 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 53177 unit, 53178 table_info[count].table, 53179 table_info[count].index); 53180 if (BCM_E_NONE != rv && 53181 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 53182 err_code[bcmStatFlexDirectionIngress] = rv; 53183 } 53184 } else { 53185 rv = _bcm_esw_stat_flex_detach_egress_table_counters( 53186 unit, 53187 0, 53188 table_info[count].table, 53189 table_info[count].index); 53190 if (BCM_E_NONE != rv && 53191 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) { 53192 err_code[bcmStatFlexDirectionEgress] = rv; 53193 } 53194 } 53195 } 53196 } 53197 53198 BCM_STAT_FLEX_DETACH_RETURN(err_code) 53199 } 53200 #endif 53201 53202 /* 53203 * Function: 53204 * bcm_esw_port_stat_detach 53205 * Description: 53206 * Detach counter entries to the given GPORT 53207 * 53208 * Parameters: 53209 * unit - (IN) unit number 53210 * port - (IN) GPORT ID 53211 * 53212 * Return Value: 53213 * BCM_E_XXX 53214 * Notes: 53215 */ 53216 int bcm_esw_port_stat_detach( 53217 int unit, 53218 bcm_gport_t port) 53219 { 53220 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53221 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 53222 return _bcm_esw_port_stat_detach(unit,port); 53223 } else 53224 #endif 53225 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 53226 if (soc_feature(unit,soc_feature_gport_service_counters)) { 53227 uint32 flag; 53228 int rv; 53229 int rv1; 53230 53231 BCM_IF_ERROR_RETURN 53232 (_bcm_esw_port_stat_param_valid(unit, port)); 53233 53234 /* no count_id, detach all counters associated with this port.*/ 53235 flag= _BCM_FLEX_STAT_HW_INGRESS; 53236 rv = _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeGport, 53237 _bcm_esw_port_flex_stat_hw_index_set, 53238 INT_TO_PTR(flag), 53239 port, FALSE,1); 53240 flag= _BCM_FLEX_STAT_HW_EGRESS; 53241 rv1 = _bcm_esw_flex_stat_enable_set(unit, 53242 _bcmFlexStatTypeEgressGport, 53243 _bcm_esw_port_flex_stat_hw_index_set, 53244 INT_TO_PTR(flag), 53245 port, FALSE,1); 53246 if (BCM_SUCCESS(rv) && BCM_SUCCESS(rv1)) { 53247 return BCM_E_NONE; 53248 } else { 53249 return BCM_E_NOT_FOUND; 53250 } 53251 } else 53252 #endif 53253 { 53254 return BCM_E_UNAVAIL; 53255 } 53256 } 53257 53258 /* 53259 * Function: 53260 * bcm_esw_port_stat_detach_with_id 53261 * Description: 53262 * Detach counter entries to the given GPORT with a given stat counter id 53263 * 53264 * Parameters: 53265 * unit - (IN) unit number 53266 * port - (IN) GPORT ID 53267 * stat_counter_id - (IN) Stat Counter ID 53268 * 53269 * Return Value: 53270 * BCM_E_XXX 53271 * Notes: 53272 */ 53273 bcm_error_t bcm_esw_port_stat_detach_with_id( 53274 int unit, 53275 bcm_gport_t port, 53276 uint32 stat_counter_id) 53277 { 53278 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53279 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 53280 return _bcm_esw_port_stat_detach_with_id(unit, port, stat_counter_id); 53281 } else 53282 #endif 53283 { 53284 return BCM_E_UNAVAIL; 53285 } 53286 } 53287 53288 53289 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53290 /* 53291 * Function: 53292 * _bcm_esw_port_stat_counter_get 53293 * Description: 53294 * retrieve set of counter statistic values for the given GPORT 53295 * if sync_mode is set, sync the sw accumulated count 53296 * with hw count value first, else return sw count. 53297 * 53298 * Parameters: 53299 * unit - (IN) unit number 53300 * port - (IN) GPORT ID 53301 * stat - (IN) Type of the counter to retrieve 53302 * I.e. ingress/egress byte/packet) 53303 * num_entries - (IN) Number of counter Entries 53304 * counter_indexes - (IN) Pointer to Counter indexes entries 53305 * counter_values - (OUT) Pointer to counter values 53306 * 53307 * Return Value: 53308 * BCM_E_XXX 53309 * Notes: 53310 */ 53311 int _bcm_esw_port_stat_counter_get( 53312 int unit, 53313 int sync_mode, 53314 bcm_gport_t port, 53315 bcm_port_stat_t stat, 53316 uint32 num_entries, 53317 uint32 *counter_indexes, 53318 bcm_stat_value_t *counter_values) 53319 { 53320 uint32 table_count=0; 53321 uint32 index_count=0; 53322 uint32 num_of_tables=0; 53323 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 53324 uint32 byte_flag=0; 53325 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 53326 53327 if ((stat == bcmPortStatIngressPackets) || 53328 (stat == bcmPortStatIngressBytes)) { 53329 direction = bcmStatFlexDirectionIngress; 53330 } else { 53331 direction = bcmStatFlexDirectionEgress; 53332 } 53333 if ((stat == bcmPortStatIngressPackets) || 53334 (stat == bcmPortStatEgressPackets)) { 53335 byte_flag=0; 53336 } else { 53337 byte_flag=1; 53338 } 53339 53340 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 53341 unit, port,&num_of_tables,&table_info[0])); 53342 53343 for (table_count=0; table_count < num_of_tables ; table_count++) { 53344 if (table_info[table_count].direction == direction) { 53345 for (index_count=0; index_count < num_entries ; index_count++) { 53346 /*ctr_offset_info.offset_index = counter_indexes[index_count];*/ 53347 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get( 53348 unit, sync_mode, 53349 table_info[table_count].index, 53350 table_info[table_count].table, 53351 0, 53352 byte_flag, 53353 counter_indexes[index_count], 53354 &counter_values[index_count])); 53355 } 53356 } 53357 } 53358 return BCM_E_NONE; 53359 } 53360 #endif 53361 53362 /* 53363 * Function: 53364 * _bcm_esw_port_flex_stat_counter_get 53365 * Description: 53366 * retrieve set of counter statistic values for the given GPORT 53367 * if sync_mode is set, sync the sw accumulated count 53368 * with hw count value first, else return sw count. 53369 * Parameters: 53370 * unit - (IN) unit number 53371 * sync_mode - (IN) hwcount is to be synced to sw count 53372 * port - (IN) GPORT ID 53373 * stat - (IN) Type of the counter to retrieve 53374 * I.e. ingress/egress byte/packet) 53375 * num_entries - (IN) Number of counter Entries 53376 * counter_indexes - (IN) Pointer to Counter indexes entries 53377 * counter_values - (OUT) Pointer to counter values 53378 * 53379 * Return Value: 53380 * BCM_E_XXX 53381 * Notes: 53382 */ 53383 int _bcm_esw_port_flex_stat_counter_get(int unit, 53384 int sync_mode, 53385 bcm_gport_t port, 53386 bcm_port_stat_t stat, 53387 uint32 num_entries, 53388 uint32 *counter_indexes, 53389 bcm_stat_value_t *counter_values) 53390 { 53391 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53392 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 53393 return _bcm_esw_port_stat_counter_get(unit, sync_mode, port, stat, 53394 num_entries, counter_indexes, 53395 counter_values); 53396 } else 53397 #endif 53398 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 53399 if (soc_feature(unit,soc_feature_gport_service_counters)) { 53400 uint64 val; 53401 int rv = BCM_E_NONE; 53402 53403 rv = _bcm_esw_flex_stat_get(unit, sync_mode, 53404 ((stat == bcmPortStatIngressPackets) || 53405 (stat == bcmPortStatIngressBytes)) ? 53406 _bcmFlexStatTypeGport:_bcmFlexStatTypeEgressGport, 53407 port, 53408 _bcm_esw_port_stat_to_flex_stat(stat), &val); 53409 53410 if ((stat == bcmPortStatIngressPackets) || 53411 (stat == bcmPortStatEgressPackets)) { 53412 counter_values->packets = COMPILER_64_LO(val); 53413 } else { 53414 COMPILER_64_SET(counter_values->bytes, 53415 COMPILER_64_HI(val), 53416 COMPILER_64_LO(val)); 53417 } 53418 return rv; 53419 53420 } else 53421 #endif 53422 { 53423 return BCM_E_UNAVAIL; 53424 } 53425 53426 } 53427 53428 53429 /* 53430 * Function: 53431 * bcm_esw_port_stat_counter_get 53432 * Description: 53433 * retrieve set of counter statistic values for the given GPORT 53434 * Parameters: 53435 * unit - (IN) unit number 53436 * port - (IN) GPORT ID 53437 * stat - (IN) Type of the counter to retrieve 53438 * I.e. ingress/egress byte/packet) 53439 * num_entries - (IN) Number of counter Entries 53440 * counter_indexes - (IN) Pointer to Counter indexes entries 53441 * counter_values - (OUT) Pointer to counter values 53442 * 53443 * Return Value: 53444 * BCM_E_XXX 53445 * Notes: 53446 */ 53447 53448 int bcm_esw_port_stat_counter_get(int unit, 53449 bcm_gport_t port, 53450 bcm_port_stat_t stat, 53451 uint32 num_entries, 53452 uint32 *counter_indexes, 53453 bcm_stat_value_t *counter_values) 53454 { 53455 int rv = BCM_E_UNAVAIL; 53456 53457 rv = _bcm_esw_port_flex_stat_counter_get(unit, 0, port, stat, num_entries, 53458 counter_indexes, counter_values); 53459 53460 return rv; 53461 } 53462 53463 53464 /* 53465 * Function: 53466 * bcm_esw_port_stat_counter_sync_get 53467 * Description: 53468 * retrieve set of counter statistic values for the given GPORT 53469 * sw accumulated counters synced with hw count. 53470 * Parameters: 53471 * unit - (IN) unit number 53472 * port - (IN) GPORT ID 53473 * stat - (IN) Type of the counter to retrieve 53474 * I.e. ingress/egress byte/packet) 53475 * num_entries - (IN) Number of counter Entries 53476 * counter_indexes - (IN) Pointer to Counter indexes entries 53477 * counter_values - (OUT) Pointer to counter values 53478 * 53479 * Return Value: 53480 * BCM_E_XXX 53481 * Notes: 53482 */ 53483 53484 int bcm_esw_port_stat_counter_sync_get(int unit, 53485 bcm_gport_t port, 53486 bcm_port_stat_t stat, 53487 uint32 num_entries, 53488 uint32 *counter_indexes, 53489 bcm_stat_value_t *counter_values) 53490 { 53491 int rv = BCM_E_UNAVAIL; 53492 53493 rv = _bcm_esw_port_flex_stat_counter_get(unit, 1, port, stat, num_entries, 53494 counter_indexes, counter_values); 53495 53496 return rv; 53497 } 53498 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53499 /* 53500 * Function: 53501 * _bcm_esw_port_stat_counter_set 53502 * Description: 53503 * set counter statistic values for the given GPORT 53504 * 53505 * Parameters: 53506 * unit - (IN) unit number 53507 * port - (IN) GPORT ID 53508 * stat - (IN) Type of the counter to retrieve 53509 * I.e. ingress/egress byte/packet) 53510 * num_entries - (IN) Number of counter Entries 53511 * counter_indexes - (IN) Pointer to Counter indexes entries 53512 * counter_values - (IN) Pointer to counter values 53513 * 53514 * Return Value: 53515 * BCM_E_XXX 53516 * Notes: 53517 */ 53518 int _bcm_esw_port_stat_counter_set( 53519 int unit, 53520 bcm_gport_t port, 53521 bcm_port_stat_t stat, 53522 uint32 num_entries, 53523 uint32 *counter_indexes, 53524 bcm_stat_value_t *counter_values) 53525 { 53526 uint32 table_count=0; 53527 uint32 index_count=0; 53528 uint32 num_of_tables=0; 53529 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 53530 uint32 byte_flag=0; 53531 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 53532 53533 if ((stat == bcmPortStatIngressPackets) || 53534 (stat == bcmPortStatIngressBytes)) { 53535 direction = bcmStatFlexDirectionIngress; 53536 } else { 53537 direction = bcmStatFlexDirectionEgress; 53538 } 53539 if ((stat == bcmPortStatIngressPackets) || 53540 (stat == bcmPortStatEgressPackets)) { 53541 byte_flag=0; 53542 } else { 53543 byte_flag=1; 53544 } 53545 53546 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 53547 unit, port,&num_of_tables,&table_info[0])); 53548 53549 for (table_count=0; table_count < num_of_tables ; table_count++) { 53550 if (table_info[table_count].direction == direction) { 53551 for (index_count=0; index_count < num_entries ; index_count++) { 53552 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set( 53553 unit, 53554 table_info[table_count].index, 53555 table_info[table_count].table, 53556 0, 53557 byte_flag, 53558 counter_indexes[index_count], 53559 &counter_values[index_count])); 53560 } 53561 } 53562 } 53563 return BCM_E_NONE; 53564 } 53565 #endif 53566 /* 53567 * Function: 53568 * bcm_esw_port_stat_counter_set 53569 * Description: 53570 * set counter statistic values for the given GPORT 53571 * 53572 * Parameters: 53573 * unit - (IN) unit number 53574 * port - (IN) GPORT ID 53575 * stat - (IN) Type of the counter to retrieve 53576 * I.e. ingress/egress byte/packet) 53577 * num_entries - (IN) Number of counter Entries 53578 * counter_indexes - (IN) Pointer to Counter indexes entries 53579 * counter_values - (IN) Pointer to counter values 53580 * 53581 * Return Value: 53582 * BCM_E_XXX 53583 * Notes: 53584 */ 53585 int bcm_esw_port_stat_counter_set( 53586 int unit, 53587 bcm_gport_t port, 53588 bcm_port_stat_t stat, 53589 uint32 num_entries, 53590 uint32 *counter_indexes, 53591 bcm_stat_value_t *counter_values) 53592 { 53593 /* Make sure port module is initialized. */ 53594 PORT_INIT(unit); 53595 53596 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53597 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 53598 return _bcm_esw_port_stat_counter_set(unit,port,stat, 53599 num_entries,counter_indexes,counter_values); 53600 } else 53601 #endif 53602 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 53603 if (soc_feature(unit,soc_feature_gport_service_counters)) { 53604 uint64 val; 53605 int rv = BCM_E_NONE; 53606 53607 if ((stat == bcmPortStatIngressPackets) || 53608 (stat == bcmPortStatEgressPackets)) { 53609 COMPILER_64_SET(val,0,counter_values->packets); 53610 } else { 53611 COMPILER_64_SET(val, 53612 COMPILER_64_HI(counter_values->bytes), 53613 COMPILER_64_LO(counter_values->bytes)); 53614 } 53615 rv = _bcm_esw_flex_stat_set(unit, 53616 ((stat == bcmPortStatIngressPackets) || 53617 (stat == bcmPortStatIngressBytes)) ? 53618 _bcmFlexStatTypeGport:_bcmFlexStatTypeEgressGport, 53619 port, 53620 _bcm_esw_port_stat_to_flex_stat(stat), val); 53621 53622 return rv; 53623 53624 } else 53625 #endif 53626 { 53627 return BCM_E_UNAVAIL; 53628 } 53629 } 53630 /* 53631 * Function: 53632 * bcm_esw_port_stat_id_get 53633 * Description: 53634 * Get stat counter id associated with given gport 53635 * 53636 * Parameters: 53637 * unit - (IN) unit number 53638 * port - (IN) GPORT ID 53639 * stat - (IN) Type of the counter to retrieve 53640 * I.e. ingress/egress byte/packet) 53641 * Stat_counter_id - (OUT) Stat Counter ID 53642 * Return Value: 53643 * BCM_E_XXX 53644 * Notes: 53645 */ 53646 int bcm_esw_port_stat_id_get( 53647 int unit, 53648 bcm_gport_t port, 53649 bcm_port_stat_t stat, 53650 uint32 *stat_counter_id) 53651 { 53652 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53653 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 53654 uint32 num_of_tables=0; 53655 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 53656 uint32 index=0; 53657 uint32 num_stat_counter_ids=0; 53658 53659 /* Make sure port module is initialized. */ 53660 PORT_INIT(unit); 53661 53662 if ((stat == bcmPortStatIngressPackets) || 53663 (stat == bcmPortStatIngressBytes)) { 53664 direction = bcmStatFlexDirectionIngress; 53665 } else { 53666 direction = bcmStatFlexDirectionEgress; 53667 } 53668 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 53669 unit,port,&num_of_tables,&table_info[0])); 53670 for (index=0; index < num_of_tables ; index++) { 53671 if (table_info[index].direction == direction) 53672 return _bcm_esw_stat_flex_get_counter_id( 53673 unit, 1, &table_info[index], 53674 &num_stat_counter_ids,stat_counter_id); 53675 } 53676 return BCM_E_NOT_FOUND; 53677 #else 53678 return BCM_E_UNAVAIL; 53679 #endif 53680 } 53681 53682 53683 /* 53684 * Function: 53685 * _bcm_esw_port_stat_get 53686 * Purpose: 53687 * Get 64-bit counter value for specified port statistic type. 53688 * if sync_mode is set, sync the sw accumulated count 53689 * with hw count value first, else return sw count. 53690 * Parameters: 53691 * unit - (IN) Unit number. 53692 * sync_mode - (IN) hwcount is to be synced to sw count 53693 * port - (IN) GPORT ID 53694 * stat - (IN) Type of the counter to retrieve. 53695 * val - (OUT) Pointer to a counter value. 53696 * Returns: 53697 * BCM_E_XXX 53698 * Notes: 53699 */ 53700 int 53701 _bcm_esw_port_stat_get(int unit, int sync_mode, bcm_gport_t port, 53702 bcm_port_stat_t stat, uint64 *val) 53703 { 53704 #if defined(BCM_TRIUMPH2_SUPPORT) 53705 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53706 uint32 counter_indexes=0; 53707 bcm_stat_value_t counter_values={0}; 53708 #endif 53709 53710 /* Make sure port module is initialized. */ 53711 PORT_INIT(unit); 53712 53713 #if defined(BCM_PREEMPTION_SUPPORT) 53714 if (soc_feature(unit, soc_feature_preemption_cnt)) { 53715 bcm_port_t local_port; 53716 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 53717 return bcmi_esw_preemption_counter_get(unit, sync_mode, local_port, 53718 stat, val); 53719 } 53720 #endif /* BCM_PREEMPTION_SUPPORT */ 53721 53722 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 53723 BCM_IF_ERROR_RETURN 53724 (_bcm_esw_port_stat_param_valid(unit, port)); 53725 return _bcm_esw_flex_stat_get(unit, sync_mode, _bcmFlexStatTypeGport, port, 53726 _bcm_esw_port_stat_to_flex_stat(stat), val); 53727 } 53728 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53729 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_counter_get(unit, sync_mode, port, 53730 stat, 1, &counter_indexes, 53731 &counter_values)); 53732 if ((stat == bcmPortStatIngressPackets) || 53733 (stat == bcmPortStatEgressPackets)) { 53734 COMPILER_64_SET(*val, 53735 COMPILER_64_HI(counter_values.packets64), 53736 COMPILER_64_LO(counter_values.packets64)); 53737 } else { 53738 COMPILER_64_SET(*val, 53739 COMPILER_64_HI(counter_values.bytes), 53740 COMPILER_64_LO(counter_values.bytes)); 53741 } 53742 return BCM_E_NONE; 53743 #else 53744 return BCM_E_UNAVAIL; 53745 #endif 53746 #else 53747 return BCM_E_UNAVAIL; 53748 #endif 53749 } 53750 53751 53752 /* 53753 * Function: 53754 * bcm_esw_port_stat_get 53755 * Purpose: 53756 * Get 64-bit counter value for specified port statistic type. 53757 * Parameters: 53758 * unit - (IN) Unit number. 53759 * port - (IN) GPORT ID 53760 * stat - (IN) Type of the counter to retrieve. 53761 * val - (OUT) Pointer to a counter value. 53762 * Returns: 53763 * BCM_E_XXX 53764 * Notes: 53765 */ 53766 int 53767 bcm_esw_port_stat_get(int unit, bcm_gport_t port, bcm_port_stat_t stat, 53768 uint64 *val) 53769 { 53770 int rv = BCM_E_UNAVAIL; 53771 53772 rv = _bcm_esw_port_stat_get(unit, 0, port, stat, val); 53773 53774 return rv; 53775 } 53776 53777 53778 /* 53779 * Function: 53780 * bcm_esw_port_stat_sync_get 53781 * Purpose: 53782 * Get 64-bit counter value for specified port statistic type. 53783 * sw accumulated counters synced with hw count. 53784 * Parameters: 53785 * unit - (IN) Unit number. 53786 * port - (IN) GPORT ID 53787 * stat - (IN) Type of the counter to retrieve. 53788 * val - (OUT) Pointer to a counter value. 53789 * Returns: 53790 * BCM_E_XXX 53791 * Notes: 53792 */ 53793 int 53794 bcm_esw_port_stat_sync_get(int unit, bcm_gport_t port, bcm_port_stat_t stat, 53795 uint64 *val) 53796 { 53797 int rv = BCM_E_UNAVAIL; 53798 53799 rv = _bcm_esw_port_stat_get(unit, 1, port, stat, val); 53800 53801 return rv; 53802 } 53803 53804 /* 53805 * Function: 53806 * _bcm_esw_port_stat_get32 53807 * Purpose: 53808 * Get lower 32-bit counter value for specified port statistic 53809 * type. 53810 * if sync_mode is set, sync the sw accumulated count 53811 * with hw count value first, else return sw count. 53812 * Parameters: 53813 * unit - (IN) Unit number. 53814 * sync_mode - (IN) hwcount is to be synced to sw count 53815 * port - (IN) GPORT ID 53816 * stat - (IN) Type of the counter to retrieve. 53817 * val - (OUT) Pointer to a counter value. 53818 * Returns: 53819 * BCM_E_XXX 53820 * Notes: 53821 */ 53822 int 53823 _bcm_esw_port_stat_get32(int unit, int sync_mode, bcm_gport_t port, 53824 bcm_port_stat_t stat, uint32 *val) 53825 { 53826 #if defined(BCM_TRIUMPH2_SUPPORT) 53827 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53828 uint32 counter_indexes=0; 53829 bcm_stat_value_t counter_values={0}; 53830 #endif 53831 53832 /* Make sure port module is initialized. */ 53833 PORT_INIT(unit); 53834 53835 #if defined(BCM_PREEMPTION_SUPPORT) 53836 if (soc_feature(unit, soc_feature_preemption_cnt)) { 53837 bcm_port_t local_port; 53838 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 53839 return bcmi_esw_preemption_counter_get32(unit, sync_mode, local_port, 53840 stat, val); 53841 } 53842 #endif /* BCM_PREEMPTION_SUPPORT */ 53843 53844 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 53845 BCM_IF_ERROR_RETURN 53846 (_bcm_esw_port_stat_param_valid(unit, port)); 53847 return _bcm_esw_flex_stat_get32(unit, sync_mode, 53848 _bcmFlexStatTypeGport, port, 53849 _bcm_esw_port_stat_to_flex_stat(stat), val); 53850 } 53851 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53852 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_counter_get(unit, sync_mode, 53853 port, stat, 1, 53854 &counter_indexes, 53855 &counter_values)); 53856 if ((stat == bcmPortStatIngressPackets) || 53857 (stat == bcmPortStatEgressPackets)) { 53858 *val = counter_values.packets; 53859 } else { 53860 /* Ignoring Hi bytes value */ 53861 *val = COMPILER_64_LO(counter_values.bytes); 53862 } 53863 return BCM_E_NONE; 53864 #else 53865 return BCM_E_UNAVAIL; 53866 #endif 53867 #else 53868 return BCM_E_UNAVAIL; 53869 #endif 53870 } 53871 53872 53873 /* 53874 * Function: 53875 * bcm_esw_port_stat_get32 53876 * Purpose: 53877 * Get lower 32-bit counter value for specified port statistic 53878 * type. 53879 * Parameters: 53880 * unit - (IN) Unit number. 53881 * port - (IN) GPORT ID 53882 * stat - (IN) Type of the counter to retrieve. 53883 * val - (OUT) Pointer to a counter value. 53884 * Returns: 53885 * BCM_E_XXX 53886 * Notes: 53887 */ 53888 int 53889 bcm_esw_port_stat_get32(int unit, bcm_gport_t port, 53890 bcm_port_stat_t stat, uint32 *val) 53891 { 53892 int rv = BCM_E_UNAVAIL; 53893 53894 rv = _bcm_esw_port_stat_get32(unit, 0, port, stat, val); 53895 53896 return rv; 53897 53898 } 53899 53900 53901 /* 53902 * Function: 53903 * bcm_esw_port_stat_sync_get32 53904 * Purpose: 53905 * Get lower 32-bit counter value for specified port statistic 53906 * type. sw accumulated counters synced with hw count. 53907 * Parameters: 53908 * unit - (IN) Unit number. 53909 * port - (IN) GPORT ID 53910 * stat - (IN) Type of the counter to retrieve. 53911 * val - (OUT) Pointer to a counter value. 53912 * Returns: 53913 * BCM_E_XXX 53914 * Notes: 53915 */ 53916 int 53917 bcm_esw_port_stat_sync_get32(int unit, bcm_gport_t port, 53918 bcm_port_stat_t stat, uint32 *val) 53919 { 53920 int rv = BCM_E_UNAVAIL; 53921 53922 rv = _bcm_esw_port_stat_get32(unit, 1, port, stat, val); 53923 53924 return rv; 53925 } 53926 53927 /* 53928 * Function: 53929 * bcm_esw_port_stat_set 53930 * Purpose: 53931 * Set 64-bit counter value for specified port statistic type. 53932 * Parameters: 53933 * unit - (IN) Unit number. 53934 * port - (IN) GPORT ID 53935 * stat - (IN) Type of the counter to retrieve. 53936 * val - (IN) New counter value. 53937 * Returns: 53938 * BCM_E_XXX 53939 * Notes: 53940 */ 53941 int 53942 bcm_esw_port_stat_set(int unit, bcm_gport_t port, bcm_port_stat_t stat, 53943 uint64 val) 53944 { 53945 #if defined(BCM_TRIUMPH2_SUPPORT) 53946 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53947 uint32 counter_indexes=0; 53948 bcm_stat_value_t counter_values={0}; 53949 #endif 53950 53951 /* Make sure port module is initialized. */ 53952 PORT_INIT(unit); 53953 53954 #if defined(BCM_PREEMPTION_SUPPORT) 53955 if (soc_feature(unit, soc_feature_preemption_cnt)) { 53956 bcm_port_t local_port; 53957 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 53958 return bcmi_esw_preemption_counter_set(unit, local_port, 53959 stat, val); 53960 } 53961 #endif /* BCM_PREEMPTION_SUPPORT */ 53962 53963 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 53964 BCM_IF_ERROR_RETURN 53965 (_bcm_esw_port_stat_param_valid(unit, port)); 53966 return _bcm_esw_flex_stat_set(unit, _bcmFlexStatTypeGport, port, 53967 _bcm_esw_port_stat_to_flex_stat(stat), val); 53968 } 53969 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 53970 if ((stat == bcmPortStatIngressPackets) || 53971 (stat == bcmPortStatEgressPackets)) { 53972 counter_values.packets = COMPILER_64_LO(val); 53973 } else { 53974 COMPILER_64_SET(counter_values.bytes, 53975 COMPILER_64_HI(val), 53976 COMPILER_64_LO(val)); 53977 } 53978 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set( 53979 unit,port,stat, 1, &counter_indexes, &counter_values)); 53980 return BCM_E_NONE; 53981 #else 53982 return BCM_E_UNAVAIL; 53983 #endif 53984 #else 53985 return BCM_E_UNAVAIL; 53986 #endif 53987 } 53988 53989 /* 53990 * Function: 53991 * bcm_esw_port_stat_set32 53992 * Purpose: 53993 * Set lower 32-bit counter value for specified port statistic 53994 * type. 53995 * Parameters: 53996 * unit - (IN) Unit number. 53997 * port - (IN) GPORT ID 53998 * stat - (IN) Type of the counter to retrieve. 53999 * val - (IN) New counter value. 54000 * Returns: 54001 * BCM_E_XXX 54002 * Notes: 54003 */ 54004 int 54005 bcm_esw_port_stat_set32(int unit, bcm_gport_t port, 54006 bcm_port_stat_t stat, uint32 val) 54007 { 54008 #if defined(BCM_TRIUMPH2_SUPPORT) 54009 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 54010 uint32 counter_indexes=0; 54011 bcm_stat_value_t counter_values={0}; 54012 #endif 54013 54014 /* Make sure port module is initialized. */ 54015 PORT_INIT(unit); 54016 54017 #if defined(BCM_PREEMPTION_SUPPORT) 54018 if (soc_feature(unit, soc_feature_preemption_cnt)) { 54019 bcm_port_t local_port; 54020 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 54021 return bcmi_esw_preemption_counter_set32(unit, local_port, 54022 stat, val); 54023 } 54024 #endif /* BCM_PREEMPTION_SUPPORT */ 54025 54026 54027 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 54028 BCM_IF_ERROR_RETURN 54029 (_bcm_esw_port_stat_param_valid(unit, port)); 54030 return _bcm_esw_flex_stat_set32(unit, _bcmFlexStatTypeGport, port, 54031 _bcm_esw_port_stat_to_flex_stat(stat), val); 54032 } 54033 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 54034 if ((stat == bcmPortStatIngressPackets) || 54035 (stat == bcmPortStatEgressPackets)) { 54036 counter_values.packets = val; 54037 } else { 54038 /* Ignoring high value */ 54039 COMPILER_64_SET(counter_values.bytes,0,val); 54040 } 54041 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set( 54042 unit,port,stat, 1, &counter_indexes, &counter_values)); 54043 return BCM_E_NONE; 54044 #else 54045 return BCM_E_UNAVAIL; 54046 #endif 54047 #else 54048 return BCM_E_UNAVAIL; 54049 #endif 54050 } 54051 54052 /* 54053 * Function: 54054 * bcm_esw_port_stat_multi_get 54055 * Purpose: 54056 * Get 64-bit counter value for multiple port statistic types. 54057 * Parameters: 54058 * unit - (IN) Unit number. 54059 * port - (IN) GPORT ID 54060 * nstat - (IN) Number of elements in stat array 54061 * stat_arr - (IN) Collected statistics descriptors array 54062 * value_arr - (OUT) Collected counters values 54063 * Returns: 54064 * BCM_E_XXX 54065 * Notes: 54066 */ 54067 int 54068 bcm_esw_port_stat_multi_get(int unit, bcm_gport_t port, int nstat, 54069 bcm_port_stat_t *stat_arr, 54070 uint64 *value_arr) 54071 { 54072 #if defined(BCM_TRIUMPH2_SUPPORT) 54073 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 54074 int idx; 54075 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 54076 uint32 counter_indexes=0; 54077 bcm_stat_value_t counter_values={0}; 54078 #endif 54079 54080 /* Make sure port module is initialized. */ 54081 PORT_INIT(unit); 54082 54083 #if defined(BCM_PREEMPTION_SUPPORT) 54084 if (soc_feature(unit, soc_feature_preemption_cnt)) { 54085 bcm_port_t local_port; 54086 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 54087 return bcmi_esw_preemption_counter_multi_get(unit, 0, local_port, nstat, 54088 stat_arr, value_arr); 54089 } 54090 #endif /* BCM_PREEMPTION_SUPPORT */ 54091 54092 if (!soc_feature(unit, soc_feature_advanced_flex_counter)) { 54093 BCM_IF_ERROR_RETURN 54094 (_bcm_esw_port_stat_param_valid(unit, port)); 54095 BCM_IF_ERROR_RETURN 54096 (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr)); 54097 BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr); 54098 54099 return _bcm_esw_flex_stat_multi_get(unit, _bcmFlexStatTypeGport, port, 54100 nstat, fs_arr, value_arr); 54101 } 54102 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 54103 for (idx=0;idx < nstat ; idx ++) { 54104 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_get( 54105 unit, port, stat_arr[idx], 54106 1, &counter_indexes, &counter_values)); 54107 if ((stat_arr[idx] == bcmPortStatIngressPackets) || 54108 (stat_arr[idx] == bcmPortStatEgressPackets)) { 54109 COMPILER_64_SET(value_arr[idx], 54110 COMPILER_64_HI(counter_values.packets64), 54111 COMPILER_64_LO(counter_values.packets64)); 54112 } else { 54113 COMPILER_64_SET(value_arr[idx], 54114 COMPILER_64_HI(counter_values.bytes), 54115 COMPILER_64_LO(counter_values.bytes)); 54116 } 54117 } 54118 return BCM_E_NONE; 54119 #else 54120 return BCM_E_UNAVAIL; 54121 #endif 54122 #else 54123 return BCM_E_UNAVAIL; 54124 #endif 54125 } 54126 54127 /* 54128 * Function: 54129 * bcm_esw_port_stat_multi_get32 54130 * Purpose: 54131 * Get lower 32-bit counter value for multiple port statistic 54132 * types. 54133 * Parameters: 54134 * unit - (IN) Unit number. 54135 * port - (IN) GPORT ID 54136 * nstat - (IN) Number of elements in stat array 54137 * stat_arr - (IN) Collected statistics descriptors array 54138 * value_arr - (OUT) Collected counters values 54139 * Returns: 54140 * BCM_E_XXX 54141 * Notes: 54142 */ 54143 int 54144 bcm_esw_port_stat_multi_get32(int unit, bcm_gport_t port, int nstat, 54145 bcm_port_stat_t *stat_arr, 54146 uint32 *value_arr) 54147 { 54148 #if defined(BCM_TRIUMPH2_SUPPORT) 54149 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 54150 int idx; 54151 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 54152 uint32 counter_indexes=0; 54153 bcm_stat_value_t counter_values={0}; 54154 #endif 54155 54156 /* Make sure port module is initialized. */ 54157 PORT_INIT(unit); 54158 54159 #if defined(BCM_PREEMPTION_SUPPORT) 54160 if (soc_feature(unit, soc_feature_preemption_cnt)) { 54161 bcm_port_t local_port; 54162 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 54163 return bcmi_esw_preemption_counter_multi_get32(unit, 0, local_port, nstat, 54164 stat_arr, value_arr); 54165 } 54166 #endif /* BCM_PREEMPTION_SUPPORT */ 54167 54168 54169 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 54170 BCM_IF_ERROR_RETURN 54171 (_bcm_esw_port_stat_param_valid(unit, port)); 54172 BCM_IF_ERROR_RETURN 54173 (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr)); 54174 BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr); 54175 54176 return _bcm_esw_flex_stat_multi_get32(unit, _bcmFlexStatTypeGport, port, 54177 nstat, fs_arr, value_arr); 54178 } 54179 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 54180 for (idx=0;idx < nstat ; idx ++) { 54181 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_get( 54182 unit, port, stat_arr[idx], 54183 1, &counter_indexes, &counter_values)); 54184 if ((stat_arr[idx] == bcmPortStatIngressPackets) || 54185 (stat_arr[idx] == bcmPortStatEgressPackets)) { 54186 value_arr[idx] = counter_values.packets; 54187 } else { 54188 value_arr[idx] = COMPILER_64_LO(counter_values.bytes); 54189 } 54190 } 54191 return BCM_E_NONE; 54192 #else 54193 return BCM_E_UNAVAIL; 54194 #endif 54195 #else 54196 return BCM_E_UNAVAIL; 54197 #endif 54198 } 54199 54200 /* 54201 * Function: 54202 * bcm_esw_port_stat_multi_set 54203 * Purpose: 54204 * Set 64-bit counter value for multiple port statistic types. 54205 * Parameters: 54206 * unit - (IN) Unit number. 54207 * port - (IN) GPORT ID 54208 * nstat - (IN) Number of elements in stat array 54209 * stat_arr - (IN) New statistics descriptors array 54210 * value_arr - (IN) New counters values 54211 * Returns: 54212 * BCM_E_XXX 54213 * Notes: 54214 */ 54215 int 54216 bcm_esw_port_stat_multi_set(int unit, bcm_gport_t port, int nstat, 54217 bcm_port_stat_t *stat_arr, 54218 uint64 *value_arr) 54219 { 54220 #if defined(BCM_TRIUMPH2_SUPPORT) 54221 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 54222 int idx; 54223 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 54224 uint32 counter_indexes=0; 54225 bcm_stat_value_t counter_values={0}; 54226 #endif 54227 54228 /* Make sure port module is initialized. */ 54229 PORT_INIT(unit); 54230 54231 #if defined(BCM_PREEMPTION_SUPPORT) 54232 if (soc_feature(unit, soc_feature_preemption_cnt)) { 54233 bcm_port_t local_port; 54234 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 54235 return bcmi_esw_preemption_counter_multi_set(unit, local_port, nstat, 54236 stat_arr, value_arr); 54237 } 54238 #endif /* BCM_PREEMPTION_SUPPORT */ 54239 54240 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 54241 BCM_IF_ERROR_RETURN 54242 (_bcm_esw_port_stat_param_valid(unit, port)); 54243 BCM_IF_ERROR_RETURN 54244 (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr)); 54245 BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr); 54246 54247 return _bcm_esw_flex_stat_multi_set(unit, _bcmFlexStatTypeGport, port, 54248 nstat, fs_arr, value_arr); 54249 } 54250 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 54251 for (idx=0;idx < nstat ; idx ++) { 54252 if ((stat_arr[idx] == bcmPortStatIngressPackets) || 54253 (stat_arr[idx] == bcmPortStatEgressPackets)) { 54254 counter_values.packets = COMPILER_64_LO(value_arr[idx]); 54255 } else { 54256 COMPILER_64_SET(counter_values.bytes, 54257 COMPILER_64_HI(value_arr[idx]), 54258 COMPILER_64_LO(value_arr[idx])); 54259 } 54260 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set( 54261 unit, port, stat_arr[idx], 54262 1, &counter_indexes, &counter_values)); 54263 } 54264 return BCM_E_NONE; 54265 #else 54266 return BCM_E_UNAVAIL; 54267 #endif 54268 #else 54269 return BCM_E_UNAVAIL; 54270 #endif 54271 } 54272 54273 /* 54274 * Function: 54275 * bcm_esw_port_stat_multi_set32 54276 * Purpose: 54277 * Set lower 32-bit counter value for multiple port statistic 54278 * types. 54279 * Parameters: 54280 * unit - (IN) Unit number. 54281 * port - (IN) GPORT ID 54282 * nstat - (IN) Number of elements in stat array 54283 * stat_arr - (IN) New statistics descriptors array 54284 * value_arr - (IN) New counters values 54285 * Returns: 54286 * BCM_E_XXX 54287 * Notes: 54288 */ 54289 int 54290 bcm_esw_port_stat_multi_set32(int unit, bcm_gport_t port, int nstat, 54291 bcm_port_stat_t *stat_arr, 54292 uint32 *value_arr) 54293 { 54294 #if defined(BCM_TRIUMPH2_SUPPORT) 54295 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 54296 int idx; 54297 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 54298 uint32 counter_indexes=0; 54299 bcm_stat_value_t counter_values={0}; 54300 #endif 54301 54302 /* Make sure port module is initialized. */ 54303 PORT_INIT(unit); 54304 54305 #if defined(BCM_PREEMPTION_SUPPORT) 54306 if (soc_feature(unit, soc_feature_preemption_cnt)) { 54307 bcm_port_t local_port; 54308 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 54309 return bcmi_esw_preemption_counter_multi_set32(unit, local_port, nstat, 54310 stat_arr, value_arr); 54311 } 54312 #endif /* BCM_PREEMPTION_SUPPORT */ 54313 54314 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 54315 BCM_IF_ERROR_RETURN 54316 (_bcm_esw_port_stat_param_valid(unit, port)); 54317 BCM_IF_ERROR_RETURN 54318 (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr)); 54319 BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr); 54320 54321 return _bcm_esw_flex_stat_multi_set32(unit, _bcmFlexStatTypeGport, port, 54322 nstat, fs_arr, value_arr); 54323 } 54324 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 54325 for (idx=0;idx < nstat ; idx ++) { 54326 if ((stat_arr[idx] == bcmPortStatIngressPackets) || 54327 (stat_arr[idx] == bcmPortStatEgressPackets)) { 54328 counter_values.packets = value_arr[idx]; 54329 } else { 54330 COMPILER_64_SET(counter_values.bytes,0,value_arr[idx]); 54331 } 54332 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set( 54333 unit, port, stat_arr[idx], 54334 1, &counter_indexes, &counter_values)); 54335 } 54336 return BCM_E_NONE; 54337 #else 54338 return BCM_E_UNAVAIL; 54339 #endif 54340 #else 54341 return BCM_E_UNAVAIL; 54342 #endif 54343 } 54344 54345 /* 54346 * Function : _bcm_gport_dest_t_init 54347 * Description : Initialize gport_dest structure 54348 * Parameters : (IN/OUT) gport_dest - Structure to initialize 54349 * Returns : None 54350 */ 54351 54352 void 54353 _bcm_gport_dest_t_init(_bcm_gport_dest_t *gport_dest) 54354 { 54355 sal_memset(gport_dest, 0, sizeof (_bcm_gport_dest_t)); 54356 } 54357 54358 54359 /* 54360 * Function : _bcm_esw_gport_construct 54361 * Description : Internal function to construct a gport from 54362 * given parameters 54363 * Parameters : (IN) unit - BCM device number 54364 * (IN) gport_dest - Structure that contains destination 54365 * to encode into a gport 54366 * (OUT) gport - Global port identifier 54367 * Returns : BCM_E_XXX 54368 * Notes : The modid and port are translated from the 54369 * local modid/port space to application space 54370 */ 54371 int 54372 _bcm_esw_gport_construct(int unit, _bcm_gport_dest_t *gport_dest, bcm_gport_t *gport) 54373 { 54374 54375 bcm_gport_t l_gport = 0; 54376 bcm_module_t mod_out; 54377 bcm_port_t port_out; 54378 54379 if ((NULL == gport_dest) || (NULL == gport) ){ 54380 return BCM_E_PARAM; 54381 } 54382 54383 switch (gport_dest->gport_type) { 54384 case _SHR_GPORT_TYPE_TRUNK: 54385 SOC_GPORT_TRUNK_SET(l_gport, gport_dest->tgid); 54386 break; 54387 case _SHR_GPORT_TYPE_LOCAL_CPU: 54388 l_gport = BCM_GPORT_LOCAL_CPU; 54389 break; 54390 case _SHR_GPORT_TYPE_BLACK_HOLE: 54391 l_gport = BCM_GPORT_BLACK_HOLE; 54392 break; 54393 case _SHR_GPORT_TYPE_LOCAL: 54394 SOC_GPORT_LOCAL_SET(l_gport, gport_dest->port); 54395 break; 54396 case _SHR_GPORT_TYPE_SUBPORT_GROUP: 54397 SOC_GPORT_SUBPORT_GROUP_SET(l_gport, gport_dest->subport_id); 54398 break; 54399 case _SHR_GPORT_TYPE_MPLS_PORT: 54400 BCM_GPORT_MPLS_PORT_ID_SET(l_gport, gport_dest->mpls_id); 54401 break; 54402 case _SHR_GPORT_TYPE_MIM_PORT: 54403 BCM_GPORT_MIM_PORT_ID_SET(l_gport, gport_dest->mim_id); 54404 break; 54405 case _SHR_GPORT_TYPE_WLAN_PORT: 54406 BCM_GPORT_WLAN_PORT_ID_SET(l_gport, gport_dest->wlan_id); 54407 break; 54408 case _SHR_GPORT_TYPE_TRILL_PORT: 54409 BCM_GPORT_TRILL_PORT_ID_SET(l_gport, gport_dest->trill_id); 54410 break; 54411 case _SHR_GPORT_TYPE_NIV_PORT: 54412 BCM_GPORT_NIV_PORT_ID_SET(l_gport, gport_dest->niv_id); 54413 break; 54414 case _SHR_GPORT_TYPE_L2GRE_PORT: 54415 BCM_GPORT_L2GRE_PORT_ID_SET(l_gport, gport_dest->l2gre_id); 54416 break; 54417 case _SHR_GPORT_TYPE_VXLAN_PORT: 54418 BCM_GPORT_VXLAN_PORT_ID_SET(l_gport, gport_dest->vxlan_id); 54419 break; 54420 case _SHR_GPORT_TYPE_FLOW_PORT: 54421 BCM_GPORT_FLOW_PORT_ID_SET(l_gport, gport_dest->flow_id); 54422 break; 54423 case _SHR_GPORT_TYPE_VLAN_PORT: 54424 BCM_GPORT_VLAN_PORT_ID_SET(l_gport, gport_dest->vlan_vp_id); 54425 break; 54426 case _SHR_GPORT_TYPE_EXTENDER_PORT: 54427 BCM_GPORT_EXTENDER_PORT_ID_SET(l_gport, gport_dest->extender_id); 54428 break; 54429 case _SHR_GPORT_TYPE_DEVPORT: 54430 BCM_GPORT_DEVPORT_SET(l_gport, unit, gport_dest->port); 54431 break; 54432 case _SHR_GPORT_TYPE_MODPORT: 54433 BCM_IF_ERROR_RETURN ( 54434 _bcm_gport_modport_hw2api_map(unit, gport_dest->modid, 54435 gport_dest->port, &mod_out, 54436 &port_out)); 54437 SOC_GPORT_MODPORT_SET(l_gport, mod_out, port_out); 54438 break; 54439 default: 54440 return BCM_E_PARAM; 54441 } 54442 54443 *gport = l_gport; 54444 return BCM_E_NONE; 54445 } 54446 54447 /* 54448 * Function : _bcm_esw_gport_resolve 54449 * Description : Internal function to get modid, port, and trunk_id 54450 * from a bcm_gport_t (global port) 54451 * Parameters : (IN) unit - BCM device number 54452 * (IN) gport - Global port identifier 54453 * (OUT) modid - Module ID 54454 * (OUT) port - Port number 54455 * (OUT) trunk_id - Trunk ID 54456 * (OUT) id - HW ID 54457 * Returns : BCM_E_XXX 54458 * Notes : The modid and port are translated from the 54459 * application space to local modid/port space if applicable, 54460 * on units without modid (Fabric) modid will be -1 and port 54461 * will be a local physical port. 54462 */ 54463 int 54464 _bcm_esw_gport_resolve(int unit, bcm_gport_t gport, 54465 bcm_module_t *modid, bcm_port_t *port, 54466 bcm_trunk_t *trunk_id, int *id) 54467 { 54468 int local_id, rv = BCM_E_NONE; 54469 bcm_module_t mod_in, local_modid; 54470 bcm_port_t port_in, local_port; 54471 bcm_trunk_t local_tgid; 54472 #ifdef BCM_KATANA_SUPPORT 54473 int extended_queue_id = 0; 54474 #endif 54475 54476 local_modid = -1; 54477 local_port = -1; 54478 local_id = -1; 54479 local_tgid = BCM_TRUNK_INVALID; 54480 54481 if (BCM_GPORT_IS_TRUNK(gport)) { 54482 local_tgid = SOC_GPORT_TRUNK_GET(gport); 54483 } else if (BCM_GPORT_IS_LOCAL_CPU(gport)) { 54484 rv = bcm_esw_stk_my_modid_get(unit, &local_modid); 54485 if (BCM_FAILURE(rv) && !SOC_IS_XGS_FABRIC(unit)) { 54486 return rv; 54487 } 54488 local_port = CMIC_PORT(unit); 54489 } else if (BCM_GPORT_IS_LOCAL(gport)) { 54490 BCM_IF_ERROR_RETURN 54491 (bcm_esw_stk_my_modid_get(unit, &local_modid)); 54492 local_port = SOC_GPORT_LOCAL_GET(gport); 54493 if (soc_feature(unit, soc_feature_sysport_remap)) { 54494 BCM_XLATE_SYSPORT_P2S(unit, &local_port); 54495 } 54496 if (!SOC_PORT_ADDRESSABLE(unit, local_port)) { 54497 return BCM_E_PORT; 54498 } 54499 } else if (BCM_GPORT_IS_DEVPORT(gport)) { 54500 rv = bcm_esw_stk_my_modid_get(unit, &local_modid); 54501 if (BCM_FAILURE(rv)) { 54502 if (!SOC_IS_XGS_FABRIC(unit)) { 54503 return rv; 54504 } 54505 } 54506 if (unit != SOC_GPORT_DEVPORT_DEVID_GET(gport)) { 54507 return BCM_E_PORT; 54508 } 54509 local_port = SOC_GPORT_DEVPORT_PORT_GET(gport); 54510 54511 if (!SOC_PORT_ADDRESSABLE(unit, local_port)) { 54512 return BCM_E_PORT; 54513 } 54514 } else if (BCM_GPORT_IS_MODPORT(gport)) { 54515 mod_in = SOC_GPORT_MODPORT_MODID_GET(gport); 54516 port_in = SOC_GPORT_MODPORT_PORT_GET(gport); 54517 54518 if (NUM_MODID(unit) > 1) { 54519 #if defined(BCM_TOMAHAWK_SUPPORT) 54520 /* Call asymmetric dual modid unmapping function */ 54521 if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) { 54522 BCM_IF_ERROR_RETURN ( 54523 _bcm_esw_stk_asymmetric_dual_modmap_map(unit, 54524 BCM_STK_MODMAP_GET, &mod_in, &port_in)); 54525 } else 54526 #endif /* BCM_TOMAHAWK_SUPPORT */ 54527 if ((NUM_MODID(unit) > 1) && (port_in > SOC_INFO(unit).modport_max)) { 54528 mod_in = mod_in + 1; 54529 port_in = port_in - (SOC_INFO(unit).modport_max + 1); 54530 } 54531 } 54532 PORT_DUALMODID_VALID(unit, port_in); 54533 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET, 54534 mod_in, port_in, &local_modid, &local_port); 54535 54536 if (!SOC_MODID_ADDRESSABLE(unit, local_modid)) { 54537 return BCM_E_BADID; 54538 } 54539 if (!SOC_PORT_ADDRESSABLE(unit, local_port)) { 54540 return BCM_E_PORT; 54541 } 54542 } else if (BCM_GPORT_IS_PROXY(gport)) { 54543 mod_in = BCM_GPORT_PROXY_MODID_GET(gport); 54544 port_in = BCM_GPORT_PROXY_PORT_GET(gport); 54545 PORT_DUALMODID_VALID(unit, port_in); 54546 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET, 54547 mod_in, port_in, &local_modid, &local_port); 54548 54549 if (!SOC_MODID_ADDRESSABLE(unit, local_modid)) { 54550 return BCM_E_BADID; 54551 } 54552 if (!SOC_PORT_ADDRESSABLE(unit, local_port)) { 54553 return BCM_E_PORT; 54554 } 54555 } 54556 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \ 54557 defined(INCLUDE_L3) 54558 else if (BCM_GPORT_IS_MPLS_PORT(gport)) { 54559 if (SOC_IS_TR_VL(unit)) { 54560 rv = _bcm_tr_mpls_port_resolve(unit, gport, &local_modid, 54561 &local_port, &local_tgid, 54562 &local_id); 54563 } 54564 } 54565 #endif 54566 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 54567 && defined(INCLUDE_L3)) 54568 else if (BCM_GPORT_IS_MIM_PORT(gport)) { 54569 if (soc_feature(unit, soc_feature_mim)) { 54570 rv = _bcm_tr2_mim_port_resolve(unit, gport, &local_modid, 54571 &local_port, &local_tgid, 54572 &local_id); 54573 } 54574 } else if (BCM_GPORT_IS_WLAN_PORT(gport)) { 54575 if (soc_feature(unit, soc_feature_wlan)) { 54576 #if defined(BCM_TRIUMPH3_SUPPORT) 54577 if (SOC_IS_TRIUMPH3(unit)) { 54578 rv = _bcm_tr3_wlan_port_resolve(unit, gport, &local_modid, 54579 &local_port, &local_tgid, 54580 &local_id); 54581 } else 54582 #endif /* BCM_TRIUMPH3_SUPPORT */ 54583 { 54584 rv = _bcm_tr2_wlan_port_resolve(unit, gport, &local_modid, 54585 &local_port, &local_tgid, 54586 &local_id); 54587 } 54588 } 54589 } 54590 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 54591 #if defined (BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 54592 else if (BCM_GPORT_IS_L2GRE_PORT(gport)) { 54593 if (soc_feature(unit, soc_feature_l2gre)) { 54594 rv = _bcm_tr3_l2gre_port_resolve(unit, gport, -1, &local_modid, 54595 &local_port, &local_tgid, 54596 &local_id); 54597 } 54598 } 54599 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 54600 #if defined (BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 54601 else if (BCM_GPORT_IS_VXLAN_PORT(gport)) { 54602 if (soc_feature(unit, soc_feature_vxlan)) { 54603 rv = _bcm_td2_vxlan_port_resolve(unit, gport, -1, &local_modid, 54604 &local_port, &local_tgid, 54605 &local_id); 54606 } 54607 } 54608 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 54609 #if defined (BCM_GREYHOUND2_SUPPORT) && defined(INCLUDE_L3) 54610 else if (BCM_GPORT_IS_VXLAN_PORT(gport)) { 54611 if (soc_feature(unit, soc_feature_vxlan_lite)) { 54612 rv = bcmi_gh2_vxlan_port_resolve(unit, gport, -1, &local_modid, 54613 &local_port, &local_tgid, 54614 &local_id); 54615 } 54616 } 54617 #endif /* BCM_GREYHOUND2_SUPPORT && INCLUDE_L3 */ 54618 #if defined (BCM_TRIDENT3_SUPPORT) && defined(INCLUDE_L3) 54619 else if (BCM_GPORT_IS_FLOW_PORT(gport)) { 54620 if (soc_feature(unit, soc_feature_flex_flow)) { 54621 rv = _bcm_td3_flow_port_resolve(unit, gport, -1, &local_modid, 54622 &local_port, &local_tgid, 54623 &local_id); 54624 } 54625 } 54626 #endif /* BCM_TRIDENT3_SUPPORT && INCLUDE_L3 */ 54627 #if defined (BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 54628 else if (BCM_GPORT_IS_TRILL_PORT(gport)) { 54629 if (soc_feature(unit, soc_feature_trill)) { 54630 rv = _bcm_td_trill_port_resolve(unit, gport, -1, &local_modid, 54631 &local_port, &local_tgid, 54632 &local_id); 54633 } 54634 } 54635 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 54636 #if defined (BCM_TRX_SUPPORT) && defined(INCLUDE_L3) 54637 else if (BCM_GPORT_IS_SUBPORT_GROUP(gport)) { 54638 if (SOC_IS_TRX(unit)) { 54639 54640 #if defined (BCM_HGPROXY_COE_SUPPORT) 54641 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 54642 soc_feature(unit, soc_feature_channelized_switching)) { 54643 rv = _bcmi_xgs5_subport_group_resolve(unit, gport, &local_modid, 54644 &local_port, &local_tgid, 54645 &local_id); 54646 } else 54647 #endif /* defined (BCM_HGPROXY_COE_SUPPORT) */ 54648 54649 #if defined (BCM_KATANA2_SUPPORT) 54650 if (SOC_IS_KATANA2(unit)) { 54651 rv = bcm_kt2_subport_group_resolve(unit, gport, &local_modid, 54652 &local_port, &local_tgid, 54653 &local_id); 54654 } else 54655 #endif /* defined (BCM_KATANA2_SUPPORT) */ 54656 if (soc_feature(unit, soc_feature_subport_enhanced)) { 54657 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 54658 rv = _bcm_tr2_subport_group_resolve(unit, gport, &local_modid, 54659 &local_port, &local_tgid, 54660 &local_id); 54661 #endif /* defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) */ 54662 } else if (soc_feature(unit, soc_feature_subport)) { 54663 rv = _bcm_tr_subport_group_resolve(unit, gport, &local_modid, 54664 &local_port, &local_tgid, 54665 &local_id); 54666 } 54667 } 54668 } else if (BCM_GPORT_IS_SUBPORT_PORT(gport)) { 54669 if (SOC_IS_TRX(unit)) { 54670 54671 #if defined (BCM_HGPROXY_COE_SUPPORT) 54672 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 54673 soc_feature(unit, soc_feature_channelized_switching)) { 54674 rv = _bcm_xgs5_subport_port_resolve(unit, gport, &local_modid, 54675 &local_port, &local_tgid, 54676 &local_id); 54677 } else 54678 #endif /* defined (BCM_HGPROXY_COE_SUPPORT) */ 54679 54680 #if defined (BCM_KATANA2_SUPPORT) 54681 if (SOC_IS_KATANA2(unit)) { 54682 54683 rv = bcm_kt2_subport_port_resolve(unit, gport, &local_modid, 54684 &local_port, &local_tgid, 54685 &local_id); 54686 } else 54687 #endif /* defined (BCM_KATANA2_SUPPORT) */ 54688 if (soc_feature(unit, soc_feature_subport_enhanced)) { 54689 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 54690 rv = _bcm_tr2_subport_port_resolve(unit, gport, &local_modid, 54691 &local_port, &local_tgid, 54692 &local_id); 54693 #endif /* defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) */ 54694 } else if (soc_feature(unit, soc_feature_subport)) { 54695 rv = _bcm_tr_subport_port_resolve(unit, gport, &local_modid, 54696 &local_port, &local_tgid, 54697 &local_id); 54698 } 54699 } 54700 } 54701 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */ 54702 #ifdef BCM_TRIUMPH_SUPPORT 54703 else if (BCM_GPORT_IS_SCHEDULER(gport)) { 54704 #if defined (BCM_TOMAHAWK3_SUPPORT) 54705 if (SOC_IS_TOMAHAWK3(unit)) { 54706 rv = _bcm_th3_cosq_port_resolve(unit, gport, &local_modid, 54707 &local_port, &local_tgid, 54708 &local_id, NULL); 54709 } else 54710 #endif /* BCM_TOMAHAWK3_SUPPORT */ 54711 #if defined (BCM_TOMAHAWK_SUPPORT) 54712 if (SOC_IS_TOMAHAWKX(unit)) { 54713 rv = _bcm_th_cosq_port_resolve(unit, gport, &local_modid, 54714 &local_port, &local_tgid, 54715 &local_id, NULL); 54716 } else 54717 #endif /* BCM_TOMAHAWK_SUPPORT */ 54718 #ifdef BCM_HURRICANE4_SUPPORT 54719 if (SOC_IS_HURRICANE4(unit)) { 54720 rv = _bcm_hr4_cosq_port_resolve(unit, gport, &local_modid, 54721 &local_port, &local_tgid, 54722 &local_id, NULL); 54723 } else 54724 #endif /* BCM_HURRICANE4_SUPPORT */ 54725 #ifdef BCM_HELIX5_SUPPORT 54726 if (SOC_IS_HELIX5(unit)) { 54727 rv = _bcm_hx5_cosq_port_resolve(unit, gport, &local_modid, 54728 &local_port, &local_tgid, 54729 &local_id, NULL); 54730 } else 54731 #endif /* BCM_HELIX5_SUPPORT */ 54732 #if defined (BCM_MONTEREY_SUPPORT) 54733 if (SOC_IS_MONTEREY(unit)) { 54734 rv = _bcm_mn_cosq_port_resolve(unit, gport, &local_modid, 54735 &local_port, &local_tgid, 54736 &local_id, NULL); 54737 } else 54738 #endif 54739 #ifdef BCM_FIREBOLT6_SUPPORT 54740 if (SOC_IS_FIREBOLT6(unit)) { 54741 rv = _bcm_fb6_cosq_port_resolve(unit, gport, &local_modid, 54742 &local_port, &local_tgid, 54743 &local_id, NULL); 54744 } else 54745 #endif /* BCM_FIREBOLT6_SUPPORT */ 54746 #ifdef BCM_TRIDENT3_SUPPORT 54747 if (SOC_IS_TRIDENT3X(unit)) { 54748 rv = _bcm_td3_cosq_port_resolve(unit, gport, &local_modid, 54749 &local_port, &local_tgid, 54750 &local_id, NULL); 54751 } else 54752 #endif /* BCM_TRIDENT3_SUPPORT */ 54753 #if defined (BCM_APACHE_SUPPORT) 54754 if (SOC_IS_APACHE(unit)) { 54755 rv = _bcm_ap_cosq_port_resolve(unit, gport, &local_modid, 54756 &local_port, &local_tgid, 54757 &local_id, NULL); 54758 } else 54759 #endif 54760 #if defined (BCM_TRIDENT2_SUPPORT) 54761 if (SOC_IS_TD2_TT2(unit)) { 54762 rv = _bcm_td2_cosq_port_resolve(unit, gport, &local_modid, 54763 &local_port, &local_tgid, 54764 &local_id, NULL); 54765 } else 54766 #endif /* BCM_TRIDENT2_SUPPORT */ 54767 #if defined (BCM_TRIDENT_SUPPORT) 54768 if (SOC_IS_TD_TT(unit)) { 54769 rv = _bcm_td_cosq_port_resolve(unit, gport, &local_modid, 54770 &local_port, &local_tgid, 54771 &local_id); 54772 } else 54773 #endif /* BCM_TRIDENT_SUPPORT */ 54774 #if defined (BCM_TRIUMPH3_SUPPORT) 54775 if (SOC_IS_TRIUMPH3(unit)) { 54776 rv = _bcm_tr3_cosq_port_resolve(unit, gport, &local_modid, 54777 &local_port, &local_tgid, 54778 &local_id, NULL); 54779 } else 54780 #endif /* BCM_TRIUMPH3_SUPPORT */ 54781 #if defined (BCM_TRIUMPH2_SUPPORT) 54782 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 54783 SOC_IS_VALKYRIE2(unit)) { 54784 rv = _bcm_tr2_cosq_port_resolve(unit, gport, &local_modid, 54785 &local_port, &local_tgid, 54786 &local_id); 54787 } else 54788 #endif /* BCM_TRIUMPH2_SUPPORT */ 54789 #if defined (BCM_GREYHOUND2_SUPPORT) 54790 if (SOC_IS_GREYHOUND2(unit)) { 54791 rv = bcmi_gh2_cosq_port_resolve(unit, gport, &local_modid, 54792 &local_port, &local_tgid, 54793 &local_id); 54794 } else 54795 #endif /* BCM_GREYHOUND2_SUPPORT */ 54796 if (SOC_IS_TR_VL(unit)) { 54797 rv = _bcm_tr_cosq_port_resolve(unit, gport, &local_modid, 54798 &local_port, &local_tgid, 54799 &local_id); 54800 } 54801 } 54802 #endif /* BCM_TRIUMPH_SUPPORT */ 54803 #ifdef BCM_KATANA_SUPPORT 54804 else if ((SOC_IS_KATANAX(unit)) && 54805 ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) || 54806 (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) || 54807 (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)))) { 54808 if (soc_feature(unit, soc_feature_extended_queueing)) { 54809 #if defined(BCM_KATANA2_SUPPORT) 54810 if (SOC_IS_KATANA2(unit)) { 54811 rv = _bcm_kt2_cosq_port_resolve(unit, gport, &local_modid, 54812 &local_port, &local_tgid, 54813 &local_id, &extended_queue_id); 54814 } else 54815 #endif 54816 if (SOC_IS_KATANA(unit)){ 54817 rv = _bcm_kt_cosq_port_resolve(unit, gport, &local_modid, 54818 &local_port, &local_tgid, 54819 &local_id, &extended_queue_id); 54820 } 54821 local_tgid = extended_queue_id; 54822 } 54823 } 54824 #endif /* BCM_KATANA_SUPPORT */ 54825 54826 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 54827 defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 54828 else if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) || 54829 BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 54830 #if defined (BCM_TOMAHAWK3_SUPPORT) 54831 if (SOC_IS_TOMAHAWK3(unit)) { 54832 rv = _bcm_th3_cosq_port_resolve(unit, gport, &local_modid, 54833 &local_port, &local_tgid, 54834 &local_id, NULL); 54835 } else 54836 #endif /* BCM_TOMAHAWK3_SUPPORT */ 54837 #if defined (BCM_TOMAHAWK_SUPPORT) 54838 if (SOC_IS_TOMAHAWKX(unit)) { 54839 rv = _bcm_th_cosq_port_resolve(unit, gport, &local_modid, 54840 &local_port, &local_tgid, 54841 &local_id, NULL); 54842 } else 54843 #endif /* BCM_TOMAHAWK_SUPPORT */ 54844 #ifdef BCM_HURRICANE4_SUPPORT 54845 if (SOC_IS_HURRICANE4(unit)) { 54846 rv = _bcm_hr4_cosq_port_resolve(unit, gport, &local_modid, 54847 &local_port, &local_tgid, 54848 &local_id, NULL); 54849 } else 54850 #endif /* BCM_HURRICANE4_SUPPORT */ 54851 #ifdef BCM_HELIX5_SUPPORT 54852 if (SOC_IS_HELIX5(unit)) { 54853 rv = _bcm_hx5_cosq_port_resolve(unit, gport, &local_modid, 54854 &local_port, &local_tgid, 54855 &local_id, NULL); 54856 } else 54857 #endif /* BCM_HELIX5_SUPPORT */ 54858 #if defined (BCM_MONTEREY_SUPPORT) 54859 if (SOC_IS_MONTEREY(unit)) { 54860 rv = _bcm_mn_cosq_port_resolve(unit, gport, &local_modid, 54861 &local_port, &local_tgid, 54862 &local_id, NULL); 54863 } else 54864 #endif 54865 54866 #ifdef BCM_FIREBOLT6_SUPPORT 54867 if (SOC_IS_FIREBOLT6(unit)) { 54868 rv = _bcm_fb6_cosq_port_resolve(unit, gport, &local_modid, 54869 &local_port, &local_tgid, 54870 &local_id, NULL); 54871 } else 54872 #endif /* BCM_FIREBOLT6_SUPPORT */ 54873 #ifdef BCM_TRIDENT3_SUPPORT 54874 if (SOC_IS_TRIDENT3X(unit)) { 54875 rv = _bcm_td3_cosq_port_resolve(unit, gport, &local_modid, 54876 &local_port, &local_tgid, 54877 &local_id, NULL); 54878 } else 54879 #endif /* BCM_TRIDENT3_SUPPORT */ 54880 #if defined(BCM_APACHE_SUPPORT) 54881 if (SOC_IS_APACHE(unit)) { 54882 rv = _bcm_ap_cosq_port_resolve(unit, gport, &local_modid, 54883 &local_port, &local_tgid, 54884 &local_id, NULL); 54885 } else 54886 #endif /* BCM_APACHE_SUPPORT */ 54887 #if defined(BCM_TRIDENT2_SUPPORT) 54888 if (SOC_IS_TD2_TT2(unit)) { 54889 rv = _bcm_td2_cosq_port_resolve(unit, gport, &local_modid, 54890 &local_port, &local_tgid, 54891 &local_id, NULL); 54892 } else 54893 #endif /* BCM_TRIDENT2_SUPPORT */ 54894 #if defined(BCM_TRIDENT_SUPPORT) 54895 if (SOC_IS_TD_TT(unit)) { 54896 rv = _bcm_td_cosq_port_resolve(unit, gport, &local_modid, 54897 &local_port, &local_tgid, 54898 &local_id); 54899 } else 54900 #endif /* BCM_TRIDENT_SUPPORT */ 54901 #if defined(BCM_TRIUMPH3_SUPPORT) 54902 if (SOC_IS_TRIUMPH3(unit)) { 54903 rv = _bcm_tr3_cosq_port_resolve(unit, gport, &local_modid, 54904 &local_port, &local_tgid, 54905 &local_id, NULL); 54906 } else 54907 #endif 54908 #if defined (BCM_GREYHOUND2_SUPPORT) 54909 if (SOC_IS_GREYHOUND2(unit)) { 54910 rv = bcmi_gh2_cosq_port_resolve(unit, gport, &local_modid, 54911 &local_port, &local_tgid, 54912 &local_id); 54913 } else 54914 #endif /* BCM_GREYHOUND2_SUPPORT */ 54915 { 54916 return BCM_E_UNAVAIL; 54917 } 54918 } 54919 #endif /* BCM_TRIDENT_SUPPORT || BCM_TRIUMPH3_SUPPORT */ 54920 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 54921 else if (BCM_GPORT_IS_VLAN_PORT(gport)) { 54922 if (soc_feature(unit, soc_feature_vlan_vp)) { 54923 #if defined(BCM_ENDURO_SUPPORT) 54924 if (SOC_IS_ENDURO(unit)) { 54925 rv = _bcm_enduro_vlan_port_resolve(unit, gport, &local_modid, 54926 &local_port, &local_tgid, 54927 &local_id); 54928 } else 54929 #endif /* BCM_ENDURO_SUPPORT */ 54930 { 54931 rv = _bcm_tr2_vlan_port_resolve(unit, gport, &local_modid, 54932 &local_port, &local_tgid, 54933 &local_id); 54934 } 54935 } 54936 } 54937 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 54938 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 54939 else if (BCM_GPORT_IS_NIV_PORT(gport)) { 54940 if (soc_feature(unit, soc_feature_niv)) { 54941 rv = _bcm_trident_niv_port_resolve(unit, gport, &local_modid, 54942 &local_port, &local_tgid, 54943 &local_id); 54944 } 54945 } 54946 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 54947 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 54948 else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 54949 if (soc_feature(unit, soc_feature_port_extension)) { 54950 rv = _bcm_tr3_extender_port_resolve(unit, gport, &local_modid, 54951 &local_port, &local_tgid, 54952 &local_id); 54953 } 54954 } 54955 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 54956 else if (BCM_GPORT_IS_BLACK_HOLE(gport)) { 54957 local_modid = BCM_MODID_INVALID; 54958 local_tgid = BCM_TRUNK_INVALID; 54959 local_port = BCM_GPORT_INVALID; 54960 local_id = -1; 54961 rv = BCM_E_NONE; 54962 } 54963 else { 54964 /* BCM_GPORT_INVALID should return an error */ 54965 return BCM_E_PORT; 54966 } 54967 *modid = local_modid; 54968 *port = local_port; 54969 *trunk_id = local_tgid; 54970 *id = local_id; 54971 return (rv); 54972 } 54973 54974 /* 54975 * Function : _bcm_esw_port_is_local_subport 54976 * Description : Internal function to check whehter a gport or (mod,port) 54977 * is local subport. 54978 * Parameters : (IN) unit - BCM device number 54979 * (IN) gport - Global port identifier 54980 * (IN) modid - Module ID 54981 * (IN) port - Port number 54982 * (OUT) is_local_subport - True/False 54983 * (OUT) phy_port - physical port of subport 54984 * Returns : BCM_E_XXX 54985 * Note: all gport, modid, port parameters are required. 54986 */ 54987 int 54988 _bcm_esw_port_is_local_subport(int unit, bcm_gport_t gport, 54989 bcm_module_t modid, bcm_port_t port, 54990 int *is_local_subport, bcm_port_t *phy_port) 54991 { 54992 #if defined(BCM_KATANA2_SUPPORT) 54993 int pp_port; 54994 int min_subport = SOC_INFO(unit).pp_port_index_min; 54995 int max_subport = SOC_INFO(unit).pp_port_index_max; 54996 #endif 54997 54998 if ((is_local_subport == NULL) || (phy_port == NULL)) { 54999 return BCM_E_PARAM; 55000 } 55001 55002 *is_local_subport = FALSE; 55003 55004 #if defined(BCM_HGPROXY_COE_SUPPORT) 55005 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 55006 soc_feature(unit, soc_feature_channelized_switching)) && 55007 BCM_GPORT_IS_SET(gport) && 55008 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) { 55009 55010 if(_bcm_xgs5_subport_coe_gport_local(unit, gport)) { 55011 *is_local_subport = TRUE; 55012 } 55013 55014 if (*is_local_subport == FALSE) { 55015 return BCM_E_PORT; 55016 } 55017 55018 BCM_IF_ERROR_RETURN( 55019 _bcmi_coe_subport_physical_port_get(unit, gport, phy_port)); 55020 } else if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 55021 soc_feature(unit, soc_feature_channelized_switching)) && 55022 _bcm_xgs5_subport_coe_mod_port_local(unit, modid, port)) { 55023 *is_local_subport = TRUE; 55024 BCM_IF_ERROR_RETURN( 55025 _bcmi_coe_subport_mod_port_physical_port_get( 55026 unit, modid, port, phy_port)); 55027 } else 55028 #endif 55029 55030 #if defined(BCM_KATANA2_SUPPORT) 55031 if (soc_feature(unit, soc_feature_linkphy_coe) || 55032 soc_feature(unit, soc_feature_subtag_coe)) { 55033 if (BCM_GPORT_IS_SET(gport) && 55034 _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, gport)) { 55035 pp_port = BCM_GPORT_SUBPORT_PORT_GET(gport); 55036 if ((_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE) || 55037 (soc_feature(unit, soc_feature_general_cascade) && 55038 SOC_PBMP_MEMBER(SOC_INFO(unit).general_pp_port_pbm, pp_port))) { 55039 #if defined BCM_METROLITE_SUPPORT 55040 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 55041 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 55042 *is_local_subport = TRUE; 55043 *phy_port = pp_port; 55044 } 55045 } else 55046 #endif 55047 { 55048 if ((pp_port >= min_subport) && 55049 (pp_port <= max_subport)) { 55050 *is_local_subport = TRUE; 55051 *phy_port = pp_port; 55052 } 55053 } 55054 } 55055 if (*is_local_subport == FALSE) { 55056 return BCM_E_PORT; 55057 } 55058 } 55059 } else 55060 #endif 55061 { 55062 return BCM_E_NONE; 55063 } 55064 55065 return BCM_E_NONE; 55066 } 55067 55068 /* 55069 * Function: 55070 * _bcm_esw_port_gport_get_from_modport 55071 * Purpose: 55072 * Get a gport for all port. 55073 * For non-COE port, it returns modport gport. 55074 * For COE subport, it returns Coe subport gport. 55075 * Parameters: 55076 * unit - (IN) Unit number. 55077 * modid - (IN) Module id. 55078 * port - (IN) Port id. 55079 * Returns: 55080 * gport 55081 * Notes: 55082 */ 55083 bcm_gport_t 55084 _bcm_esw_port_gport_get_from_modport(int unit, bcm_module_t modid, bcm_port_t port) 55085 { 55086 bcm_gport_t gport; 55087 55088 #if defined(BCM_HGPROXY_COE_SUPPORT) 55089 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 55090 soc_feature(unit, soc_feature_channelized_switching)) && 55091 _bcm_xgs5_subport_coe_mod_port_local(unit, modid, port)) { 55092 _BCM_SUBPORT_COE_PORT_ID_SET(gport, modid, port); 55093 _BCM_SUBPORT_COE_PORT_TYPE_SET(gport,_BCM_SUBPORT_COE_TYPE_SUBTAG); 55094 } else 55095 #endif 55096 { 55097 BCM_GPORT_MODPORT_SET(gport, modid, port); 55098 } 55099 55100 return gport; 55101 } 55102 55103 /* Check if a given port is a valid controlling port for the Flex-port 55104 feature. 55105 */ 55106 55107 unsigned 55108 _bcm_esw_valid_flex_port_controlling_port(int unit, bcm_port_t port) 55109 { 55110 uint16 dev_id; 55111 uint8 rev_id; 55112 55113 if (!SOC_PORT_VALID(unit, port)) return (FALSE); 55114 55115 soc_cm_get_id(unit, &dev_id, &rev_id); 55116 55117 if (dev_id == BCM56636_DEVICE_ID) { 55118 /* Device is a BCM56636 */ 55119 55120 /* Only valid controlling ports are 42 and 50 55121 (ports 30, 34 and 38 come up in gigE, and 55122 therefore are not valid Flex-port controlling ports). 55123 */ 55124 55125 if (port != 42 && port != 50) return (FALSE); 55126 } else 55127 #if defined(BCM_METROLITE_SUPPORT) 55128 if (SOC_IS_METROLITE(unit)) { 55129 if ((port != 1) && (port != 5) && (port != 9)) { 55130 return (FALSE); 55131 } 55132 } else 55133 #endif 55134 #if defined(BCM_SABER2_SUPPORT) 55135 if (SOC_IS_SABER2(unit)) { 55136 if ((port != 1) && (port != 5) && (port != 9) 55137 && (port != 13) && (port != 17) && (port != 21) 55138 && (port != 25)) { 55139 return (FALSE); 55140 } 55141 } else 55142 #endif 55143 #if defined(BCM_KATANA2_SUPPORT) 55144 if (SOC_IS_KATANA2(unit)) { 55145 if ((port != 1) && (port != 5) && (port != 9) 55146 && (port != 13) && (port != 17) && (port != 21) 55147 && (port != 25) && (port != 26) && (port != 27) 55148 && (port != 28)) { 55149 return (FALSE); 55150 } 55151 } else 55152 #endif 55153 { 55154 if ((port != 30) && (port != 34) && (port != 38) 55155 && (port != 42) && (port != 46) && (port != 50)) { 55156 return (FALSE); 55157 } 55158 } 55159 return (TRUE); 55160 } 55161 55162 55163 /* 55164 * Function: 55165 * bcm_port_subsidiary_ports_get 55166 * Purpose: 55167 * Given a controlling port, this API returns the set of ancillary ports 55168 * belonging to the group (port block) that can be configured to operate 55169 * either as a single high-speed port or multiple GE ports. If the input 55170 * port is not a controlling port, BCM_E_PORT error will be returned. 55171 * Parameters: 55172 * unit - (IN) Unit number. 55173 * port - (IN) Port 55174 * pbmp - (OUT) Ports associated with the hot-swap group 55175 * Returns: 55176 * BCM_E_XXX 55177 * Notes: 55178 */ 55179 int 55180 bcm_esw_port_subsidiary_ports_get(int unit, bcm_port_t port, bcm_pbmp_t *pbmp) 55181 { 55182 int rv = BCM_E_UNAVAIL; 55183 55184 /* Make sure port module is initialized. */ 55185 PORT_INIT(unit); 55186 55187 if (!soc_feature(unit, soc_feature_flex_port)) { 55188 return BCM_E_UNAVAIL; 55189 } 55190 55191 #if defined(BCM_TRIDENT3_SUPPORT) 55192 if (SOC_IS_TRIDENT3X(unit)) { 55193 return (soc_td3_subsidiary_ports_get(unit, port, pbmp)); 55194 } 55195 #endif 55196 #if defined(BCM_TOMAHAWK_SUPPORT) 55197 if (SOC_IS_TOMAHAWKX(unit)) { 55198 return (soc_th_subsidiary_ports_get(unit, port, pbmp)); 55199 } 55200 #endif 55201 #if defined(BCM_MONTEREY_SUPPORT) 55202 if (SOC_IS_MONTEREY(unit)) { 55203 return (soc_monterey_subsidiary_ports_get(unit, port, pbmp)); 55204 } 55205 #endif 55206 #if defined(BCM_APACHE_SUPPORT) 55207 if (SOC_IS_APACHE(unit)) { 55208 return (soc_apache_subsidiary_ports_get(unit, port, pbmp)); 55209 } 55210 #endif 55211 #ifdef BCM_TRIDENT2PLUS_SUPPORT 55212 if (SOC_IS_TRIDENT2PLUS(unit)) { 55213 return(soc_td2p_subsidiary_ports_get(unit, port, pbmp)); 55214 } 55215 #endif 55216 55217 #if defined(BCM_TRIDENT2_SUPPORT) 55218 if (SOC_IS_TD2_TT2(unit)) { 55219 soc_info_t *si = &SOC_INFO(unit); 55220 int i, port_num_lanes_max; 55221 int phy_port, phy_port_base, port_base, lp; 55222 bcm_pbmp_t pbm; 55223 55224 if (!SOC_PORT_VALID(unit, port)) { 55225 return BCM_E_PORT; 55226 } 55227 /* coverity[overrun-local : FALSE] */ 55228 phy_port = si->port_l2p_mapping[port]; 55229 if (phy_port == -1) { 55230 return BCM_E_PORT; 55231 } 55232 55233 phy_port_base = (phy_port & ~0x3) + 1; 55234 if (phy_port != phy_port_base) { 55235 return BCM_E_PORT; 55236 } 55237 55238 port_base = si->port_p2l_mapping[phy_port_base]; 55239 55240 if (si->port_speed_max[port_base] > 20000) { 55241 port_num_lanes_max = 4; 55242 } else if (si->port_speed_max[port_base] > 10000) { 55243 port_num_lanes_max = 2; 55244 } else { 55245 port_num_lanes_max = 1; 55246 } 55247 55248 BCM_PBMP_CLEAR(pbm); 55249 /* Get the subsidiary ports bitmap */ 55250 for (i = 1; i < port_num_lanes_max; i++) { 55251 lp = si->port_p2l_mapping[phy_port_base + i]; 55252 if (lp != -1 55253 && BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), lp)) { 55254 BCM_PBMP_PORT_ADD(pbm, lp); 55255 } 55256 } 55257 55258 if (BCM_PBMP_IS_NULL(pbm)) { /* No Subsidiary ports */ 55259 return BCM_E_PORT; 55260 } 55261 55262 /* Add base port to subsidiary ports bitmap */ 55263 BCM_PBMP_PORT_ADD(pbm, port_base); 55264 BCM_PBMP_ASSIGN(*pbmp, pbm); 55265 55266 rv = BCM_E_NONE; 55267 } 55268 #endif /* BCM_TRIDENT2_SUPPORT */ 55269 55270 #if defined(BCM_TRIUMPH3_SUPPORT) 55271 if (SOC_IS_TRIUMPH3(unit)) { 55272 soc_info_t *si = &SOC_INFO(unit); 55273 int i, phy_port, phy_port_base, lp; 55274 bcm_pbmp_t pbm; 55275 55276 BCM_PBMP_CLEAR(pbm); 55277 55278 if ( !(IS_XW_PORT(unit,port) || IS_CL_PORT(unit, port) || IS_XT_PORT(unit,port)) || 55279 !_bcm_tr3_port_is_control_port(unit, port) || !soc_tr3_port_is_flex_port(unit, port)) { 55280 return BCM_E_PORT; 55281 } 55282 /* coverity[overrun-local : FALSE] */ 55283 phy_port = si->port_l2p_mapping[port]; 55284 if (phy_port == -1) { 55285 return BCM_E_PORT; 55286 } 55287 phy_port_base = (phy_port & ~0x3) + 1; 55288 if (phy_port != phy_port_base) { 55289 return BCM_E_PORT; 55290 } 55291 BCM_PBMP_CLEAR(pbm); 55292 for (i = 0; i < _SOC_TR3_LANES_PER_PHY; i++) { 55293 /* coverity[overrun-local : FALSE] */ 55294 lp = si->port_p2l_mapping[phy_port_base + i]; 55295 if (lp != -1 && 55296 (si->port_speed_max[lp] != 0) && 55297 BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), lp)) { 55298 BCM_PBMP_PORT_ADD(pbm, lp); 55299 } 55300 } 55301 55302 55303 BCM_PBMP_ASSIGN(*pbmp, pbm); 55304 return BCM_E_NONE; 55305 } 55306 #endif /* BCM_TRIUMPH3_SUPPORT */ 55307 55308 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 55309 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 55310 !SOC_IS_TD_TT(unit)) { 55311 int i; 55312 55313 if (!_bcm_esw_valid_flex_port_controlling_port(unit, port)) { 55314 return (BCM_E_PORT); 55315 } 55316 55317 BCM_PBMP_CLEAR(*pbmp); 55318 if ((SOC_IS_KATANA2(unit)) && (!SOC_IS_SABER2(unit))) { 55319 if (port == 25) { 55320 BCM_PBMP_PORT_ADD(*pbmp, 25); 55321 for (i = 0; i < 3; i++) { 55322 if(SOC_PORT_VALID(unit, 35 + i)) { 55323 BCM_PBMP_PORT_ADD(*pbmp, 35 + i); 55324 } 55325 } 55326 return (BCM_E_NONE); 55327 } else if (port == 26) { 55328 BCM_PBMP_PORT_ADD(*pbmp, 26); 55329 for (i = 0; i < 3; i++) { 55330 if(SOC_PORT_VALID(unit, 38 + i)) { 55331 BCM_PBMP_PORT_ADD(*pbmp, 38 + i); 55332 } 55333 } 55334 return (BCM_E_NONE); 55335 } else if (port == 27) { 55336 BCM_PBMP_PORT_ADD(*pbmp, 27); 55337 for (i = 0; i < 3; i++) { 55338 if(SOC_PORT_VALID(unit, 32 + i)) { 55339 BCM_PBMP_PORT_ADD(*pbmp, 32 + i); 55340 } 55341 } 55342 return (BCM_E_NONE); 55343 } 55344 } 55345 55346 for (i = 0; i < 4; i++) { 55347 /* coverity[overrun-local : FALSE] */ 55348 if (SOC_PORT_VALID(unit, port + i)) { 55349 BCM_PBMP_PORT_ADD(*pbmp, port + i); 55350 } 55351 } 55352 rv = BCM_E_NONE; 55353 } 55354 #endif 55355 55356 return rv; 55357 } 55358 55359 /* 55360 * Function: 55361 * _bcm_esw_port_e2ecc_hg_pbm_convert 55362 * Purpose: 55363 * Convert Higig port to E2ECC Higig port bitmap. 55364 * Parameters: 55365 * port - (IN) Higig port number. 55366 * converted_hg_pbm - (OUT) Converted Higig port bitmap. 55367 * Returns: 55368 * BCM_E_xxx 55369 */ 55370 STATIC int 55371 _bcm_esw_port_e2ecc_hg_pbm_convert(bcm_port_t port, uint32 *converted_hg_pbm) 55372 { 55373 int hg_pbm_index; 55374 55375 /* In Triumph2, the mapping between HG_PBM[9:0] and physical port number is: 55376 * 55377 * HG_PBM index: | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 55378 * Physical Port: | 50 | 46 | 42 | 38 | 34 | 30 | 29 | 28 | 27 | 26 | 55379 */ 55380 switch (port) 55381 { 55382 case 26: 55383 case 27: 55384 case 28: 55385 case 29: 55386 case 30: 55387 hg_pbm_index = port - 26; 55388 break; 55389 case 34: 55390 case 38: 55391 case 42: 55392 case 46: 55393 case 50: 55394 hg_pbm_index = 5 + (port - 34) / 4; 55395 break; 55396 default: 55397 LOG_ERROR(BSL_LS_BCM_PORT, 55398 (BSL_META("Error: Port %d is an invalid Higig port"), port)); 55399 return BCM_E_PARAM; 55400 } 55401 55402 *converted_hg_pbm = (1 << hg_pbm_index); 55403 55404 return BCM_E_NONE; 55405 } 55406 55407 STATIC int 55408 _bcm_esw_port_drop_status_enable_set(int unit, bcm_port_t port, int enable) 55409 { 55410 uint32 rval; 55411 int idx; 55412 55413 #if defined(BCM_MONTEREY_SUPPORT) 55414 if (SOC_IS_MONTEREY(unit)) { 55415 return bcm_mn_cosq_drop_status_enable_set(unit, port, enable); 55416 } 55417 #endif /* BCM_TRIDENT2_SUPPORT */ 55418 #if defined(BCM_APACHE_SUPPORT) 55419 if (SOC_IS_APACHE(unit)) { 55420 return bcm_ap_cosq_drop_status_enable_set(unit, port, enable); 55421 } 55422 #endif /* BCM_TRIDENT2_SUPPORT */ 55423 #if defined(BCM_TRIDENT2_SUPPORT) 55424 if (SOC_IS_TD2_TT2(unit)) { 55425 return bcm_td2_cosq_drop_status_enable_set(unit, port, enable); 55426 } 55427 #endif /* BCM_TRIDENT2_SUPPORT */ 55428 55429 #if defined(BCM_TRIDENT_SUPPORT) 55430 if (SOC_IS_TD_TT(unit)) { 55431 return bcm_td_cosq_drop_status_enable_set(unit, port, enable); 55432 } 55433 #endif /* BCM_TRIDENT_SUPPORT */ 55434 55435 #if defined(BCM_TRIUMPH3_SUPPORT) 55436 if (SOC_IS_TRIUMPH3(unit)) { 55437 return bcm_tr3_cosq_drop_status_enable_set(unit, port, enable); 55438 } 55439 #endif /* BCM_TRIUMPH3_SUPPORT */ 55440 55441 #if defined(BCM_KATANA_SUPPORT) 55442 if (SOC_IS_KATANA(unit)) { 55443 return bcm_kt_cosq_drop_status_enable_set(unit, port, enable); 55444 } 55445 #endif /* BCM_KATANA_SUPPORT */ 55446 #if defined(BCM_KATANA2_SUPPORT) 55447 if (SOC_IS_KATANA2(unit)) { 55448 return bcm_kt2_cosq_drop_status_enable_set(unit, port, enable); 55449 } 55450 #endif /* BCM_KATANA2_SUPPORT */ 55451 #if defined(BCM_HURRICANE3_SUPPORT) 55452 if (SOC_IS_HURRICANE3(unit)) { 55453 return bcm_hr3_cosq_drop_status_enable_set(unit, port, enable); 55454 } 55455 #endif /* BCM_HURRICANE3_SUPPORT */ 55456 #if defined(BCM_GREYHOUND2_SUPPORT) 55457 if (SOC_IS_GREYHOUND2(unit)) { 55458 return bcmi_gh2_cosq_drop_status_enable_set(unit, port, enable); 55459 } 55460 #endif /* BCM_GREYHOUND2_SUPPORT */ 55461 55462 for (idx = 0; idx < 8; idx++) { 55463 if (SOC_IS_SC_CQ(unit)) { 55464 SOC_IF_ERROR_RETURN(READ_OP_QUEUE_CONFIGr(unit, port, idx, &rval)); 55465 soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &rval, 55466 Q_E2E_DS_ENABLEf, enable ? 1 : 0); 55467 SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_CONFIGr(unit, port, idx, rval)); 55468 } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 55469 SOC_IS_VALKYRIE2(unit)) { 55470 SOC_IF_ERROR_RETURN 55471 (READ_OP_QUEUE_CONFIG1_CELLr(unit, port, idx, &rval)); 55472 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval, 55473 Q_E2E_DS_EN_CELLf, enable ? 1 : 0); 55474 SOC_IF_ERROR_RETURN 55475 (WRITE_OP_QUEUE_CONFIG1_CELLr(unit, port, idx, rval)); 55476 55477 SOC_IF_ERROR_RETURN 55478 (READ_OP_QUEUE_CONFIG1_PACKETr(unit, port, idx, &rval)); 55479 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_PACKETr, &rval, 55480 Q_E2E_DS_EN_PACKETf, enable ? 1 : 0); 55481 SOC_IF_ERROR_RETURN 55482 (WRITE_OP_QUEUE_CONFIG1_PACKETr(unit, port, idx, rval)); 55483 } 55484 } 55485 55486 SOC_IF_ERROR_RETURN(READ_OP_THR_CONFIGr(unit, &rval)); 55487 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval, EARLY_E2E_SELECTf, 55488 enable ? 1 : 0); 55489 SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, rval)); 55490 55491 return BCM_E_NONE; 55492 } 55493 55494 /* 55495 * Function: 55496 * _bcm_esw_port_e2e_tx_enable_set 55497 * Purpose: 55498 * Set E2E Tx Enable 55499 * Parameters: 55500 * unit - (IN) SOC unit number. 55501 * port - (IN) Port number. 55502 * enable - (IN) Whether to enable or disable 55503 * Returns: 55504 * BCM_E_xxx 55505 */ 55506 STATIC int 55507 _bcm_esw_port_e2e_tx_enable_set(int unit, bcm_port_t port, int enable) 55508 { 55509 uint64 rval64; 55510 55511 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 55512 return bcmi_esw_portctrl_e2e_tx_enable_set(unit, port, enable); 55513 } 55514 55515 if (IS_CL_PORT(unit, port)) { 55516 SOC_IF_ERROR_RETURN(READ_CLMAC_E2E_CTRLr(unit, port, &rval64)); 55517 soc_reg64_field32_set(unit, CLMAC_E2E_CTRLr, &rval64, 55518 E2E_ENABLEf, enable); 55519 SOC_IF_ERROR_RETURN(WRITE_CLMAC_E2E_CTRLr(unit, port, rval64)); 55520 } else { 55521 SOC_IF_ERROR_RETURN(READ_XLMAC_E2E_CTRLr(unit, port, &rval64)); 55522 soc_reg64_field32_set(unit, XLMAC_E2E_CTRLr, &rval64, 55523 E2E_ENABLEf, enable); 55524 SOC_IF_ERROR_RETURN(WRITE_XLMAC_E2E_CTRLr(unit, port, rval64)); 55525 } 55526 return BCM_E_NONE; 55527 } 55528 55529 /* 55530 * Function: 55531 * _bcm_esw_port_e2ecc_tx 55532 * Purpose: 55533 * Configure E2ECC message transmission. 55534 * Parameters: 55535 * unit - (IN) Unit number. 55536 * port - (IN) Local port number. 55537 * config - (IN) Congestion configuration. 55538 * Returns: 55539 * BCM_E_xxx 55540 */ 55541 STATIC int 55542 _bcm_esw_port_e2ecc_tx(int unit, bcm_port_t port, 55543 bcm_port_congestion_config_t *config) 55544 { 55545 uint32 regval; 55546 uint32 hg_pbm, converted_hg_pbm, new_hg_pbm; 55547 int value_a, value_b; 55548 int time_unit_sel, time_units; 55549 int src_modid, src_pid; 55550 soc_higig_e2ecc_hdr_t e2ecc_hdr; 55551 int blk, blk_num = -1, bindex = 0; 55552 if (config->flags & BCM_PORT_CONGESTION_CONFIG_TX) { 55553 /* If BCM_PORT_CONGESTION_CONFIG_TX flag is set, enable E2ECC transmission. */ 55554 55555 /* Set chip-wide E2ECC enable bit */ 55556 if (SOC_IS_SC_CQ(unit)) { 55557 SOC_IF_ERROR_RETURN(READ_E2E_HOL_ENr(unit, ®val)); 55558 if (soc_reg_field_get(unit, E2E_HOL_ENr, regval, ENf) == 0) { 55559 soc_reg_field_set(unit, E2E_HOL_ENr, ®val, ENf, 1); 55560 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_ENr(unit, regval)); 55561 } 55562 } else { 55563 SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_ENr(unit, ®val)); 55564 if (soc_reg_field_get(unit, E2ECC_HOL_ENr, regval, ENf) == 0) { 55565 soc_reg_field_set(unit, E2ECC_HOL_ENr, ®val, ENf, 1); 55566 SOC_IF_ERROR_RETURN(WRITE_E2ECC_HOL_ENr(unit, regval)); 55567 } 55568 } 55569 55570 55571 /* In Trident E2E_HOL_ENf is not present. MMY E2ECC_HOL_EN is used */ 55572 /* (Checked with Architecture) */ 55573 if (soc_reg_field_valid(unit, XPORT_CONFIGr, E2E_HOL_ENf)) { 55574 /* Set per-port E2ECC TX enable bit */ 55575 SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, ®val)); 55576 if (soc_reg_field_get(unit, XPORT_CONFIGr, 55577 regval, E2E_HOL_ENf) == 0) { 55578 soc_reg_field_set(unit, XPORT_CONFIGr, ®val, 55579 E2E_HOL_ENf, 1); 55580 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, regval)); 55581 } 55582 } 55583 55584 if (soc_reg_field_valid(unit, XPORT_MODE_REGr, E2E_HOL_ENf)) { 55585 /* Set per-port E2ECC TX enable bit */ 55586 SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, ®val)); 55587 if (soc_reg_field_get(unit, XPORT_MODE_REGr, 55588 regval, E2E_HOL_ENf) == 0) { 55589 soc_reg_field_set(unit, XPORT_MODE_REGr, ®val, 55590 E2E_HOL_ENf, 1); 55591 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, regval)); 55592 } 55593 } 55594 55595 /* Set per-queue E2ECC enable bits */ 55596 BCM_IF_ERROR_RETURN 55597 (_bcm_esw_port_drop_status_enable_set(unit, port, TRUE)); 55598 55599 /* Set the Higig port bitmap used to transmit E2ECC messages */ 55600 if (SOC_IS_SC_CQ(unit)) { 55601 SOC_IF_ERROR_RETURN(READ_E2E_HOL_PBMr(unit, ®val)); 55602 hg_pbm = soc_reg_field_get(unit, E2E_HOL_PBMr, regval, PORT_BITMAPf); 55603 55604 converted_hg_pbm = 1 << port; 55605 55606 if (!(hg_pbm & converted_hg_pbm)) { 55607 new_hg_pbm = hg_pbm | converted_hg_pbm; 55608 soc_reg_field_set(unit, E2E_HOL_PBMr, ®val, PORT_BITMAPf, new_hg_pbm); 55609 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_PBMr(unit, regval)); 55610 } 55611 } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 55612 SOC_IS_VALKYRIE2(unit)) { 55613 SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_PBMr(unit, ®val)); 55614 hg_pbm = soc_reg_field_get(unit, E2ECC_HOL_PBMr, regval, HG_PBMf); 55615 55616 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hg_pbm_convert(port, &converted_hg_pbm)); 55617 55618 if (!(hg_pbm & converted_hg_pbm)) { 55619 new_hg_pbm = hg_pbm | converted_hg_pbm; 55620 soc_reg_field_set(unit, E2ECC_HOL_PBMr, ®val, HG_PBMf, new_hg_pbm); 55621 SOC_IF_ERROR_RETURN(WRITE_E2ECC_HOL_PBMr(unit, regval)); 55622 } 55623 } else { /* TD_TT, KATANAX, TR3 */ 55624 if (soc_feature(unit, soc_feature_logical_port_num)) { 55625 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[port]); 55626 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[port]); 55627 } else{ 55628 blk = SOC_PORT_BLOCK(unit, port); 55629 bindex = SOC_PORT_BINDEX(unit, port); 55630 } 55631 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 55632 if (SOC_IS_TRIDENT2X(unit)) { 55633 blk_num = SOC_INFO(unit).port_serdes[port]; 55634 } else 55635 #endif 55636 { 55637 blk_num = SOC_BLOCK_INFO(unit, blk).number; 55638 } 55639 /* In TR3 E2ECC is implemented only in blocks CL, XL1 */ 55640 if (!SOC_IS_TRIUMPH3(unit) || (IS_CL_PORT(unit, port) || (blk == 13))) { 55641 if (SOC_IS_TRIUMPH3(unit)) { 55642 if (IS_CL_PORT(unit, port)) { 55643 blk_num = (blk_num ? 4 + bindex/4 : bindex/4); 55644 bindex = bindex%4; 55645 } else { 55646 blk_num = 3; 55647 } 55648 } 55649 #if defined(BCM_KATANA2_SUPPORT) 55650 if (SOC_IS_KATANA2(unit)) { 55651 /* In KT2 E2ECC is implemented only in blocks 6..9 */ 55652 blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ; 55653 } 55654 #endif 55655 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num, 55656 ®val)); 55657 if (!(regval & (1 << bindex))) { 55658 new_hg_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval, 55659 TX_ENABLE_BMPf); 55660 /* new_hg_pbm &= ~(1 << bindex); */ 55661 new_hg_pbm |= (1 << bindex); 55662 soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, ®val, 55663 TX_ENABLE_BMPf, new_hg_pbm); 55664 SOC_IF_ERROR_RETURN 55665 (WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, regval)); 55666 } 55667 } 55668 55669 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 55670 if (SOC_IS_TD2_TT2(unit)) { 55671 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1)); 55672 55673 /* DMVOQ congestion bytes max length is 64 bytes, 55674 As a result 55675 DMVOQ feature can support upto 64 ports*/ 55676 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_PORTS_NUMr(unit, ®val)); 55677 soc_reg_field_set(unit, E2ECC_TX_PORTS_NUMr, ®val, 55678 TX_PORTS_NUMf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ); 55679 SOC_IF_ERROR_RETURN(WRITE_E2ECC_TX_PORTS_NUMr(unit, regval)); 55680 55681 /* By default congestion states of 4 cos values are transmitted 55682 inorder to transmit the congestion state for all the 55683 8 cos values 55684 if num_coq > 8 following configuration is done */ 55685 if (!SOC_IS_TRIUMPH3(unit) && !SOC_IS_MONTEREY(unit) && NUM_COS(unit) >= 8) { 55686 uint64 rval64 ; 55687 uint64 fval64; 55688 COMPILER_64_ZERO(fval64); 55689 COMPILER_64_SET(fval64, 0xffffffff, 0xffffffff); 55690 soc_reg64_field_set(unit, OOBFC_ENG_PORT_QSEL0_64r , 55691 &rval64, 55692 ENG_PORT_QSELf, fval64); 55693 SOC_IF_ERROR_RETURN(WRITE_OOBFC_ENG_PORT_QSEL0_64r(unit, 55694 rval64)); 55695 } 55696 } 55697 #endif 55698 #if defined(BCM_HURRICANE3_SUPPORT) 55699 if (SOC_IS_FIRELIGHT(unit)) { 55700 /* When in Chassis mode, _soc_firelight_mmu_init_helper_chassis() 55701 * would set E2ECC_TX_PORTS_NUM the correct value. Leave it alone 55702 * for firelight. 55703 */ 55704 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1)); 55705 } else if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 55706 uint32 max_bitmap; 55707 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_PORTS_NUMr(unit, ®val)); 55708 /* max Congestion bitmap number of E2ECC message */ 55709 if (SOC_IS_HURRICANE3(unit)) { 55710 max_bitmap = 36; 55711 } else { /* GREYHOUND2 */ 55712 max_bitmap = 64; 55713 } 55714 soc_reg_field_set(unit, E2ECC_TX_PORTS_NUMr, ®val, 55715 TX_PORTS_NUMf, max_bitmap); 55716 SOC_IF_ERROR_RETURN(WRITE_E2ECC_TX_PORTS_NUMr(unit, regval)); 55717 55718 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1)); 55719 } 55720 #endif 55721 55722 if (SOC_IS_KATANAX(unit)) { 55723 SOC_IF_ERROR_RETURN(READ_OP_THR_CONFIGr(unit, ®val)); 55724 soc_reg_field_set(unit, OP_THR_CONFIGr, ®val, E2ECC_HOL_ENf, 1); 55725 SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, regval)); 55726 if (SOC_IS_SABER2(unit)) { 55727 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1)); 55728 } 55729 } 55730 } 55731 55732 /* Configuring the E2ECC min timer so that during congestion, back-to-back 55733 * E2ECC messages are generated as fast as hardware allows. 55734 */ 55735 if (SOC_IS_SC_CQ(unit)) { 55736 55737 SOC_IF_ERROR_RETURN(READ_E2E_MIN_TX_TIMERr(unit, ®val)); 55738 if (soc_reg_field_get(unit, E2E_MIN_TX_TIMERr, regval, TIMERf) != 0) { 55739 soc_reg_field_set(unit, E2E_MIN_TX_TIMERr, ®val, TIMERf, 0); 55740 soc_reg_field_set(unit, E2E_MIN_TX_TIMERr, ®val, LGf, 0); 55741 SOC_IF_ERROR_RETURN(WRITE_E2E_MIN_TX_TIMERr(unit, regval)); 55742 } 55743 } else { 55744 SOC_IF_ERROR_RETURN(READ_E2ECC_MIN_TX_TIMERr(unit, ®val)); 55745 if (soc_reg_field_get(unit, E2ECC_MIN_TX_TIMERr, regval, TIMERf) != 0) { 55746 soc_reg_field_set(unit, E2ECC_MIN_TX_TIMERr, ®val, TIMERf, 0); 55747 soc_reg_field_set(unit, E2ECC_MIN_TX_TIMERr, ®val, LGf, 0); 55748 SOC_IF_ERROR_RETURN(WRITE_E2ECC_MIN_TX_TIMERr(unit, regval)); 55749 } 55750 } 55751 55752 /* In the absence of congestion, an E2ECC message is still generated to refresh 55753 * congestion status when the E2ECC max timer expires. This timer is specified 55754 * in units of 250ns or 25us, and up to 1023 time units can be specified. 55755 * The selection of time unit and the number of time units is computed as follows: 55756 * 55757 * Let E2ECC message refresh rate = N messages/sec, and N != 0, 55758 * then A = # of 250ns time units = 1 sec / N / 250ns = 4000000 / N, 55759 * and B = # of 25us time units = 1 sec / N / 25us = 40000 / N = A / 100. 55760 * 55761 * If A < 1, configure the minimum allowed timer value: time unit = 250ns, 55762 * # of time units = 1. 55763 * 55764 * If A is between 1 and 1023, configure the timer as: time unit = 250ns, 55765 * # of time units = A. 55766 * 55767 * If A > 1023 and B <= 1023, configure the timer as: time unit = 25us, 55768 * # of time units = B. 55769 * 55770 * If B > 1023, configure the maximum allowed timer value: time unit = 25us, 55771 * # of time units = 1023. 55772 * 55773 * Note: If N = 0, # of time units will be set to 0, and E2ECC message refresh 55774 * is effectively disabled. E2ECC message will be generated only when 55775 * there is a change in congestion status. 55776 */ 55777 55778 if (config->packets_per_sec == 0) { 55779 time_unit_sel = 0; 55780 time_units = 0; 55781 } else { 55782 value_a = 4000000 / config->packets_per_sec; 55783 value_b = value_a / 100; 55784 if (value_a < 1) { 55785 time_unit_sel = 0; 55786 time_units = 1; 55787 } else if (value_a <= 1023) { 55788 time_unit_sel = 0; 55789 time_units = value_a; 55790 } else if ((value_a > 1023) && (value_b <= 1023)) { 55791 time_unit_sel = 1; 55792 time_units = value_b; 55793 } else { /* value_b > 1023 */ 55794 time_unit_sel = 1; 55795 time_units = 1023; 55796 } 55797 } 55798 55799 if (SOC_IS_SC_CQ(unit)) { 55800 SOC_IF_ERROR_RETURN(READ_E2E_MAX_TX_TIMERr(unit, ®val)); 55801 soc_reg_field_set(unit, E2E_MAX_TX_TIMERr, ®val, LGf, 55802 time_unit_sel); 55803 soc_reg_field_set(unit, E2E_MAX_TX_TIMERr, ®val, TIMERf, 55804 time_units); 55805 SOC_IF_ERROR_RETURN(WRITE_E2E_MAX_TX_TIMERr(unit, regval)); 55806 } else { 55807 SOC_IF_ERROR_RETURN(READ_E2ECC_MAX_TX_TIMERr(unit, ®val)); 55808 soc_reg_field_set(unit, E2ECC_MAX_TX_TIMERr, ®val, LGf, 55809 time_unit_sel); 55810 soc_reg_field_set(unit, E2ECC_MAX_TX_TIMERr, ®val, TIMERf, 55811 time_units); 55812 SOC_IF_ERROR_RETURN(WRITE_E2ECC_MAX_TX_TIMERr(unit, regval)); 55813 } 55814 55815 /* Configure per-port E2ECC message header */ 55816 #ifdef BCM_FIRELIGHT_SUPPORT 55817 if (SOC_IS_FIRELIGHT(unit) && (!IS_HG_PORT(unit, port))) { 55818 uint64 rval; 55819 55820 if (!IS_CL_PORT(unit, port) && !IS_XL_PORT(unit, port)) { 55821 return BCM_E_UNAVAIL; 55822 } 55823 55824 if (IS_CL_PORT(unit, port)) { 55825 SOC_IF_ERROR_RETURN(READ_CLMAC_MODEr(unit, port, &rval)); 55826 } else { 55827 SOC_IF_ERROR_RETURN(READ_XLMAC_MODEr(unit, port, &rval)); 55828 } 55829 if (soc_reg64_field32_get(unit, CLMAC_MODEr, rval, HDR_MODEf) 55830 !=SOC_ENCAP_IEEE) { 55831 LOG_ERROR(BSL_LS_BCM_PORT, 55832 (BSL_META_U(unit, 55833 "Error: unit %d port %d is not a Higig port. " 55834 "HDR_MODE of XL or CL port should be configured " 55835 "with IEEE Ethernet format.\n"), 55836 unit, port)); 55837 return BCM_E_UNAVAIL; 55838 } 55839 55840 sal_memset(&e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t)); 55841 55842 e2ecc_hdr.overlay1.words[0] = 55843 (config->dest_mac[0] << 24) | /* MAC-DA[47:40] */ 55844 (config->dest_mac[1] << 16) | /* MAC-DA[39:32] */ 55845 (config->dest_mac[2] << 8) | /* MAC-DA[31:24] */ 55846 (config->dest_mac[3]); /* MAC-DA[23:16] */ 55847 55848 e2ecc_hdr.overlay1.words[1] = 55849 (config->dest_mac[4] << 24) | /* MAC-DA[15:8] */ 55850 (config->dest_mac[5] << 16) | /* MAC-DA[7:0] */ 55851 (config->src_mac[0] << 8) | /* MAC-SA[47:40] */ 55852 (config->src_mac[1]); /* MAC-SA[39:32] */ 55853 55854 e2ecc_hdr.overlay1.words[2] = 55855 (config->src_mac[2] << 24) | /* MAC-SA[31:24] */ 55856 (config->src_mac[3] << 16) | /* MAC-SA[23:16] */ 55857 (config->src_mac[4] << 8) | /* MAC-SA[15:8] */ 55858 (config->src_mac[5]); /* MAC-SA[7:0] */ 55859 55860 /* SVTAG for E2ECC on ethernet port is fixed to be 0xff0008ff 55861 * SVTAG Signature = 0xFF 55862 * MACSEC Error Code = 0x00 55863 * PRI = 0 55864 * CPU = 0 ,CPU = 0 should be set for all control packets 55865 * PKT_TYPE = 2b10 ,control packet 55866 * RSVD = 0 55867 * Channel # = 0xFF 55868 */ 55869 e2ecc_hdr.overlay1.words[3] = 0xff0008ff; 55870 e2ecc_hdr.overlay1.words[4] = 55871 ((config->ethertype & 0xFFFF) << 16) | /* Ethertype[15:0] */ 55872 (config->opcode & 0xFFFF); /* Opcode[7:0] */ 55873 e2ecc_hdr.overlay1.words[5] = 0; 55874 e2ecc_hdr.overlay1.words[6] = 0; 55875 e2ecc_hdr.overlay1.words[7] = 0; 55876 } else 55877 #endif /* BCM_FIRELIGHT_SUPPORT */ 55878 { 55879 if (BCM_GPORT_IS_MODPORT(config->src_port)) { 55880 src_modid = BCM_GPORT_MODPORT_MODID_GET(config->src_port); 55881 src_pid = BCM_GPORT_MODPORT_PORT_GET(config->src_port); 55882 } else { 55883 LOG_ERROR(BSL_LS_BCM_PORT, 55884 (BSL_META_U(unit, 55885 "Error: src_port %d is not of type modid:port.\n"), config->src_port)); 55886 return BCM_E_PARAM; 55887 } 55888 55889 sal_memset(&e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t)); 55890 55891 e2ecc_hdr.overlay1.words[0] = 55892 (SOC_HIGIG_START << 24) | /* K.SOP[7:0] */ 55893 (((1 << 4) | (config->traffic_class & 0x0F)) << 16) | /* MC and TC[3:0] */ 55894 (config->multicast_id & 0xFFFF); /* MGID[15:0] */ 55895 55896 e2ecc_hdr.overlay1.words[1] = 55897 ((src_modid & 0xFF) << 24) | /* SRC_MODID[7:0] */ 55898 ((src_pid & 0xFF) << 16) | /* SRC_PID[7:0] */ 55899 ((config->color & 0x03) << 6); /* DP[1:0] */ 55900 55901 /* e2ecc_hdr.overlay1.words[2] is all zeroes. */ 55902 55903 if (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL) { 55904 /* In case of DMVOQ, we are sending opcode as Multicast 55905 so that packet is accepted at different modules */ 55906 e2ecc_hdr.overlay1.words[3] = 55907 ((config->pri & 0x07) << 29) | /* VID_HIGH[7:5] */ 55908 ((config->cfi & 0x01) << 28) | /* VID_HIGH[4] */ 55909 ((config->vlan & 0xfff) << 16) | /* VID_HIGH[3:0], VID_LOW[7:0] */ 55910 ((SOC_HIGIG_OP_MC & 0x07) << 8); /* OPCODE[2:0] */ 55911 } else { 55912 e2ecc_hdr.overlay1.words[3] = 55913 ((config->pri & 0x07) << 29) | /* VID_HIGH[7:5] */ 55914 ((config->cfi & 0x01) << 28) | /* VID_HIGH[4] */ 55915 ((config->vlan & 0xfff) << 16) | /* VID_HIGH[3:0], VID_LOW[7:0] */ 55916 ((SOC_HIGIG_OP_BC & 0x07) << 8); /* OPCODE[2:0] */ 55917 } 55918 55919 e2ecc_hdr.overlay1.words[4] = 55920 (config->dest_mac[0] << 24) | /* MAC-DA[47:40] */ 55921 (config->dest_mac[1] << 16) | /* MAC-DA[39:32] */ 55922 (config->dest_mac[2] << 8) | /* MAC-DA[31:24] */ 55923 (config->dest_mac[3]); /* MAC-DA[23:16] */ 55924 55925 e2ecc_hdr.overlay1.words[5] = 55926 (config->dest_mac[4] << 24) | /* MAC-DA[15:8] */ 55927 (config->dest_mac[5] << 16) | /* MAC-DA[7:0] */ 55928 (config->src_mac[0] << 8) | /* MAC-SA[47:40] */ 55929 (config->src_mac[1]); /* MAC-SA[39:32] */ 55930 55931 e2ecc_hdr.overlay1.words[6] = 55932 (config->src_mac[2] << 24) | /* MAC-SA[31:24] */ 55933 (config->src_mac[3] << 16) | /* MAC-SA[23:16] */ 55934 (config->src_mac[4] << 8) | /* MAC-SA[15:8] */ 55935 (config->src_mac[5]); /* MAC-SA[7:0] */ 55936 55937 e2ecc_hdr.overlay1.words[7] = 55938 ((config->ethertype & 0xFFFF) << 16) | /* Ethertype[15:0] */ 55939 (config->opcode & 0xFFFF); /* Opcode[7:0] */ 55940 } 55941 55942 BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hdr_set(unit, port, &e2ecc_hdr)); 55943 55944 /* Enable QE interop mode */ 55945 if (SOC_IS_SC_CQ(unit)) { 55946 SOC_IF_ERROR_RETURN(READ_GLOBAL_SHARED_FILL_STATE_CONFIGr(unit, ®val)); 55947 if (soc_reg_field_get(unit, GLOBAL_SHARED_FILL_STATE_CONFIGr, regval, 55948 GLOBAL_SHARED_FILL_STATE_ENf) == 0) { 55949 soc_reg_field_set(unit, GLOBAL_SHARED_FILL_STATE_CONFIGr, ®val, 55950 GLOBAL_SHARED_FILL_STATE_ENf, 1); 55951 SOC_IF_ERROR_RETURN(WRITE_GLOBAL_SHARED_FILL_STATE_CONFIGr(unit, regval)); 55952 } 55953 } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit)) { 55954 SOC_IF_ERROR_RETURN(READ_QE_INTEROP_CONFIGr(unit, ®val)); 55955 if (soc_reg_field_get(unit, QE_INTEROP_CONFIGr, regval, QE_INTEROP_ENf) == 0) { 55956 soc_reg_field_set(unit, QE_INTEROP_CONFIGr, ®val, QE_INTEROP_ENf, 1); 55957 SOC_IF_ERROR_RETURN(WRITE_QE_INTEROP_CONFIGr(unit, regval)); 55958 } 55959 } else if (SOC_IS_TD2_TT2(unit)) { 55960 SOC_IF_ERROR_RETURN 55961 (soc_reg_field32_modify(unit, 55962 INTFO_E2ECC_POOL_STATE_REPORT_ENABLEr, 55963 REG_PORT_ANY, ENf, 1)); 55964 } else if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) { 55965 SOC_IF_ERROR_RETURN(READ_THDO_INTEROP_CONFIGr(unit, ®val)); 55966 if (soc_reg_field_get(unit, THDO_INTEROP_CONFIGr, regval, 55967 GLOBAL_CNG_STATE_REPORT_ENABLEf) == 0) { 55968 soc_reg_field_set(unit, THDO_INTEROP_CONFIGr, ®val, 55969 GLOBAL_CNG_STATE_REPORT_ENABLEf, 1); 55970 SOC_IF_ERROR_RETURN(WRITE_THDO_INTEROP_CONFIGr(unit, regval)); 55971 } 55972 } 55973 55974 } else { 55975 /* If BCM_PORT_CONGESTION_CONFIG_TX flag is not set, disable E2ECC transmission. */ 55976 55977 if (soc_reg_field_valid(unit, XPORT_CONFIGr, E2E_HOL_ENf)) { 55978 /* Clear per-port E2ECC TX enable bit */ 55979 SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, ®val)); 55980 if (soc_reg_field_get(unit, XPORT_CONFIGr, regval, E2E_HOL_ENf) == 1) { 55981 soc_reg_field_set(unit, XPORT_CONFIGr, ®val, E2E_HOL_ENf, 0); 55982 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, regval)); 55983 } 55984 } 55985 55986 if (soc_reg_field_valid(unit, XPORT_MODE_REGr, E2E_HOL_ENf)) { 55987 /* Clear per-port E2ECC TX enable bit */ 55988 SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, ®val)); 55989 if (soc_reg_field_get(unit, XPORT_MODE_REGr, regval, E2E_HOL_ENf) == 1) { 55990 soc_reg_field_set(unit, XPORT_MODE_REGr, ®val, E2E_HOL_ENf, 0); 55991 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, regval)); 55992 } 55993 } 55994 55995 /* Clear per-queue E2ECC enable bits */ 55996 BCM_IF_ERROR_RETURN 55997 (_bcm_esw_port_drop_status_enable_set(unit, port, FALSE)); 55998 55999 /* Clear the bit corresponding to the given Higig port in the Higig port bitmap 56000 * used to transmit E2ECC messages 56001 */ 56002 if (SOC_IS_SC_CQ(unit)) { 56003 SOC_IF_ERROR_RETURN(READ_E2E_HOL_PBMr(unit, ®val)); 56004 hg_pbm = soc_reg_field_get(unit, E2E_HOL_PBMr, regval, PORT_BITMAPf); 56005 56006 converted_hg_pbm = 1 << port; 56007 56008 if (hg_pbm & converted_hg_pbm) { 56009 new_hg_pbm = hg_pbm & ~converted_hg_pbm; 56010 soc_reg_field_set(unit, E2E_HOL_PBMr, ®val, PORT_BITMAPf, new_hg_pbm); 56011 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_PBMr(unit, regval)); 56012 } 56013 } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit)) { 56014 SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_PBMr(unit, ®val)); 56015 hg_pbm = soc_reg_field_get(unit, E2ECC_HOL_PBMr, regval, HG_PBMf); 56016 56017 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hg_pbm_convert(port, &converted_hg_pbm)); 56018 56019 if (hg_pbm & converted_hg_pbm) { 56020 new_hg_pbm = hg_pbm & ~converted_hg_pbm; 56021 soc_reg_field_set(unit, E2ECC_HOL_PBMr, ®val, HG_PBMf, new_hg_pbm); 56022 SOC_IF_ERROR_RETURN(WRITE_E2ECC_HOL_PBMr(unit, regval)); 56023 } 56024 } else if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 56025 SOC_IS_TRIUMPH3(unit) || SOC_IS_HURRICANE3(unit) || 56026 SOC_IS_GREYHOUND2(unit)) { 56027 if (soc_feature(unit, soc_feature_logical_port_num)) { 56028 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[port]); 56029 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[port]); 56030 } else{ 56031 blk = SOC_PORT_BLOCK(unit, port); 56032 bindex = SOC_PORT_BINDEX(unit, port); 56033 } 56034 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 56035 if (SOC_IS_TRIDENT2X(unit)) { 56036 blk_num = SOC_INFO(unit).port_serdes[port]; 56037 } else 56038 #endif 56039 { 56040 blk_num = SOC_BLOCK_INFO(unit, blk).number; 56041 } 56042 /* In TR3 E2ECC is implemented only in blocks CL, XL1 */ 56043 if (!SOC_IS_TRIUMPH3(unit) || (IS_CL_PORT(unit, port) || (blk == 13))) { 56044 if (SOC_IS_TRIUMPH3(unit)) { 56045 if (IS_CL_PORT(unit, port)) { 56046 blk_num = (blk_num ? 4 + bindex/4 : bindex/4); 56047 bindex = bindex%4; 56048 } else { 56049 blk_num = 3; 56050 } 56051 } 56052 #if defined(BCM_KATANA2_SUPPORT) 56053 if (SOC_IS_KATANA2(unit)) { 56054 /* In KT2 E2ECC is implemented only in blocks 6..9 */ 56055 blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ; 56056 if (SOC_IS_SABER2(unit)) { 56057 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 0)); 56058 } 56059 } 56060 #endif 56061 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num, 56062 ®val)); 56063 if (regval & (1 << bindex)) { 56064 new_hg_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval, 56065 TX_ENABLE_BMPf); 56066 new_hg_pbm &= ~(1 << bindex); 56067 soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, ®val, 56068 TX_ENABLE_BMPf, new_hg_pbm); 56069 SOC_IF_ERROR_RETURN 56070 (WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, regval)); 56071 } 56072 } 56073 56074 if (SOC_IS_TD2_TT2(unit) || SOC_IS_HURRICANE3(unit) || 56075 SOC_IS_GREYHOUND2(unit)) { 56076 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 0)); 56077 } 56078 } 56079 56080 /* Clear per-port registers holding the E2ECC message header */ 56081 sal_memset(&e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t)); 56082 BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hdr_set(unit, port, &e2ecc_hdr)); 56083 } 56084 56085 return BCM_E_NONE; 56086 } 56087 56088 /* 56089 * Function: 56090 * _bcm_esw_port_e2ecc_rx 56091 * Purpose: 56092 * Configure E2ECC message reception. 56093 * Parameters: 56094 * unit - (IN) Unit number. 56095 * port - (IN) Local port number. 56096 * config - (IN) Congestion configuration. 56097 * Returns: 56098 * BCM_E_xxx 56099 */ 56100 STATIC int 56101 _bcm_esw_port_e2ecc_rx(int unit, bcm_port_t port, 56102 bcm_port_congestion_config_t *config) 56103 { 56104 uint32 regval; 56105 uint64 regval64; 56106 uint32 field_val; 56107 56108 if (config->flags & BCM_PORT_CONGESTION_CONFIG_RX) { 56109 /* If BCM_PORT_CONGESTION_CONFIG_RX flag is set, enable E2ECC reception. */ 56110 56111 /* Make sure chip-wide E2ECC reception disable bit is cleared */ 56112 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, ®val64)); 56113 if (soc_reg64_field32_get(unit, ING_CONFIG_64r, regval64, 56114 DISABLE_E2E_HOL_CHECKf) == 1) { 56115 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®val64, 56116 DISABLE_E2E_HOL_CHECKf, 0); 56117 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, regval64)); 56118 } 56119 56120 /* Set per-port E2ECC RX enable bit */ 56121 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 56122 if (soc_reg_field_get(unit, IE2E_CONTROLr, regval, 56123 HOL_ENABLEf) == 0) { 56124 soc_reg_field_set(unit, IE2E_CONTROLr, ®val, HOL_ENABLEf, 1); 56125 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval)); 56126 } 56127 56128 /* Configure E2ECC receive MAC-DA, Length/Type, and Opcode */ 56129 56130 field_val = (config->dest_mac[0] << 8) | /* MAC-DA[47:40] */ 56131 (config->dest_mac[1]); /* MAC-DA[39:32] */ 56132 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_MSr(unit, ®val)); 56133 soc_reg_field_set(unit, E2E_HOL_RX_DA_MSr, ®val, DAf, field_val); 56134 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_DA_MSr(unit, regval)); 56135 56136 field_val = (config->dest_mac[2] << 24) | /* MAC-DA[31:24] */ 56137 (config->dest_mac[3] << 16) | /* MAC-DA[23:16] */ 56138 (config->dest_mac[4] << 8) | /* MAC-DA[15:8] */ 56139 (config->dest_mac[5]); /* MAC-DA[7:0] */ 56140 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_LSr(unit, ®val)); 56141 soc_reg_field_set(unit, E2E_HOL_RX_DA_LSr, ®val, DAf, field_val); 56142 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_DA_LSr(unit, regval)); 56143 56144 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_LENGTH_TYPEr(unit, ®val)); 56145 soc_reg_field_set(unit, E2E_HOL_RX_LENGTH_TYPEr, ®val, LENGTH_TYPEf, config->ethertype); 56146 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_LENGTH_TYPEr(unit, regval)); 56147 56148 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_OPCODEr(unit, ®val)); 56149 soc_reg_field_set(unit, E2E_HOL_RX_OPCODEr, ®val, OPCODEf, config->opcode); 56150 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_OPCODEr(unit, regval)); 56151 56152 } else { 56153 /* If BCM_PORT_CONGESTION_CONFIG_RX flag is not set, disable E2ECC reception. */ 56154 56155 /* Clear per-port E2ECC RX enable bit */ 56156 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 56157 if (soc_reg_field_get(unit, IE2E_CONTROLr, regval, HOL_ENABLEf) == 1) { 56158 soc_reg_field_set(unit, IE2E_CONTROLr, ®val, HOL_ENABLEf, 0); 56159 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval)); 56160 } 56161 } 56162 56163 return BCM_E_NONE; 56164 } 56165 56166 STATIC int 56167 _bcm_tr3_port_hcfc(int unit, bcm_port_t port, 56168 bcm_port_congestion_config_t *config) 56169 { 56170 #if defined(BCM_TRIUMPH3_SUPPORT) 56171 soc_reg_t reg; 56172 int enable; 56173 uint32 rval; 56174 uint64 rval64, fval64, tmp; 56175 56176 enable = config->flags & BCM_PORT_CONGESTION_CONFIG_TX ? 1 : 0; 56177 BCM_IF_ERROR_RETURN 56178 (_bcm_esw_port_drop_status_enable_set(unit, port, enable)); 56179 56180 /* Configure egress status reporting */ 56181 reg = OOBFC_ENG_PORT_EN_64r; 56182 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 56183 fval64 = soc_reg64_field_get(unit, reg, rval64, ENG_PORT_ENf); 56184 COMPILER_64_SET(tmp, 0, 1); 56185 COMPILER_64_SHL(tmp, port); 56186 COMPILER_64_AND(fval64, tmp); 56187 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 56188 56189 SOC_IF_ERROR_RETURN(READ_OOBFC_GCSr(unit, &rval)); 56190 soc_reg_field_set(unit, OOBFC_GCSr, &rval, GCS_ENf, 0); 56191 SOC_IF_ERROR_RETURN(WRITE_OOBFC_GCSr(unit, rval)); 56192 56193 return BCM_E_NONE; 56194 #else 56195 return BCM_E_UNAVAIL; 56196 #endif 56197 } 56198 56199 56200 /* 56201 * Function: 56202 * _bcm_esw_port_hcfc_tx 56203 * Purpose: 56204 * configure the port hcfc egress status to enable 56205 * Parameters: 56206 * unit - (IN) Unit number. 56207 * port - (IN) Port number 56208 * config - (IN) Configuration 56209 * Returns: 56210 * BCM_E_xxx 56211 * Notes: 56212 */ 56213 STATIC int 56214 _bcm_esw_port_hcfc_tx(int unit, bcm_port_t port, 56215 bcm_port_congestion_config_t *config) 56216 { 56217 soc_reg_t reg, reg0, reg1; 56218 int enable, len; 56219 uint64 rval64, fval64; 56220 uint32 fval_hi, fval_lo; 56221 56222 if (!SOC_PORT_VALID(unit, port)) { 56223 return BCM_E_PORT; 56224 } 56225 56226 if (SOC_REG_IS_VALID(unit, OOBFC_ENG_PORT_EN0_64r)) { 56227 reg0 = OOBFC_ENG_PORT_EN0_64r; 56228 reg1 = OOBFC_ENG_PORT_EN1_64r; 56229 } else { 56230 reg0 = OOBFC_ENG_PORT_EN_0_64r; 56231 reg1 = OOBFC_ENG_PORT_EN_1_64r; 56232 } 56233 if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) { 56234 return BCM_E_PORT; 56235 } 56236 56237 /* Configure egress status reporting */ 56238 len = soc_reg_field_length(unit, reg0, ENG_PORT_ENf); 56239 if (len < 1) { 56240 return BCM_E_PORT; 56241 } 56242 if (port < len) { /* First half of logical ports (not mmu port) */ 56243 reg = reg0; 56244 } else { /* Second half of logical ports (not mmu port) */ 56245 reg = reg1; 56246 } 56247 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 56248 fval64 = soc_reg64_field_get(unit, reg, rval64, ENG_PORT_ENf); 56249 fval_hi = COMPILER_64_HI(fval64); 56250 fval_lo = COMPILER_64_LO(fval64); 56251 enable = config->flags & BCM_PORT_CONGESTION_CONFIG_TX ? 1 : 0; 56252 if (enable) { 56253 if (port < len) { 56254 if (port < 32) { 56255 fval_lo |= (1 << port); 56256 } else { 56257 /* coverity[large_shift : FALSE] */ 56258 fval_hi |= (1 << (port - 32)); 56259 } 56260 } else { 56261 int port_offset = port - len; 56262 if ( port_offset < 32 ) { 56263 fval_lo |= (1 << port_offset); 56264 } else { 56265 fval_hi |= (1 << (port_offset - 32)); 56266 } 56267 } 56268 } else { 56269 if (port < len) { 56270 if (port < 32) { 56271 fval_lo &= ~(1 << port); 56272 } else { 56273 /* coverity[large_shift : FALSE] */ 56274 fval_hi &= ~(1 << (port - 32)); 56275 } 56276 } else { 56277 int port_offset = port - len; 56278 if ( port_offset < 32 ) { 56279 fval_lo &= ~(1 << port_offset); 56280 } else { 56281 fval_hi &= ~(1 << (port_offset - 32)); 56282 } 56283 } 56284 } 56285 COMPILER_64_SET(fval64, fval_hi, fval_lo); 56286 soc_reg64_field_set(unit, reg, &rval64, ENG_PORT_ENf, fval64); 56287 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 56288 56289 return BCM_E_NONE; 56290 } 56291 56292 /* 56293 * Function: 56294 * _bcm_esw_port_hcfc_rx 56295 * Purpose: 56296 * configure the port hcfc ingress status to enable 56297 * Parameters: 56298 * unit - (IN) Unit number. 56299 * port - (IN) Port number 56300 * config - (IN) Configuration 56301 * Returns: 56302 * BCM_E_xxx 56303 * Notes: 56304 */ 56305 STATIC int 56306 _bcm_esw_port_hcfc_rx(int unit, bcm_port_t port, 56307 bcm_port_congestion_config_t *config) 56308 { 56309 soc_reg_t reg, reg0, reg1; 56310 int enable, len; 56311 uint64 rval64, fval64; 56312 uint32 fval_hi, fval_lo; 56313 56314 if (!SOC_PORT_VALID(unit, port)) { 56315 return BCM_E_PORT; 56316 } 56317 56318 if (SOC_REG_IS_VALID(unit, OOBFC_ING_PORT_EN0_64r)) { 56319 reg0 = OOBFC_ING_PORT_EN0_64r; 56320 reg1 = OOBFC_ING_PORT_EN1_64r; 56321 } else { 56322 reg0 = OOBFC_ING_PORT_EN_0_64r; 56323 reg1 = OOBFC_ING_PORT_EN_1_64r; 56324 } 56325 if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) { 56326 return BCM_E_PORT; 56327 } 56328 56329 /* Configure ingress status reporting */ 56330 len = soc_reg_field_length(unit, reg0, ING_PORT_ENf); 56331 if (len < 1) { 56332 return BCM_E_PORT; 56333 } 56334 if (port < len) { /* First half of logical ports (not mmu port) */ 56335 reg = reg0; 56336 } else { /* Second half of logical ports (not mmu port) */ 56337 reg = reg1; 56338 } 56339 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 56340 fval64 = soc_reg64_field_get(unit, reg, rval64, ING_PORT_ENf); 56341 fval_hi = COMPILER_64_HI(fval64); 56342 fval_lo = COMPILER_64_LO(fval64); 56343 56344 enable = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0; 56345 if (enable) { 56346 if (port < len) { 56347 if (port < 32) { 56348 fval_lo |= (1 << port); 56349 } else { 56350 /* coverity[large_shift : FALSE] */ 56351 fval_hi |= (1 << (port - 32)); 56352 } 56353 } else { 56354 int port_offset = port - len; 56355 if ( port_offset < 32 ) { 56356 fval_lo |= (1 << port_offset); 56357 } else { 56358 fval_hi |= (1 << (port_offset - 32)); 56359 } 56360 } 56361 } else { 56362 if (port < len) { 56363 if (port < 32) { 56364 fval_lo &= ~(1 << port); 56365 } else { 56366 /* coverity[large_shift : FALSE] */ 56367 fval_hi &= ~(1 << (port - 32)); 56368 } 56369 } else { 56370 int port_offset = port - len; 56371 if ( port_offset < 32 ) { 56372 fval_lo &= ~(1 << port_offset); 56373 } else { 56374 fval_hi &= ~(1 << (port_offset - 32)); 56375 } 56376 } 56377 } 56378 COMPILER_64_SET(fval64, fval_hi, fval_lo); 56379 soc_reg64_field_set(unit, reg, &rval64, ING_PORT_ENf, fval64); 56380 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 56381 56382 return BCM_E_NONE; 56383 } 56384 56385 56386 STATIC int 56387 _bcm_esw_port_hcfc(int unit, bcm_port_t port, 56388 bcm_port_congestion_config_t *config) 56389 { 56390 int enable; 56391 uint32 rval; 56392 56393 enable = config->flags & BCM_PORT_CONGESTION_CONFIG_TX ? 1 : 0; 56394 BCM_IF_ERROR_RETURN 56395 (_bcm_esw_port_drop_status_enable_set(unit, port, enable)); 56396 56397 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_tx(unit, port, config)); 56398 56399 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_rx(unit, port, config)); 56400 56401 SOC_IF_ERROR_RETURN(READ_OOBFC_GCSr(unit, &rval)); 56402 soc_reg_field_set(unit, OOBFC_GCSr, &rval, GCS_ENf, 0); 56403 SOC_IF_ERROR_RETURN(WRITE_OOBFC_GCSr(unit, rval)); 56404 56405 return BCM_E_NONE; 56406 } 56407 56408 #ifdef BCM_KATANA2_SUPPORT 56409 STATIC int 56410 _bcm_esw_port_coe_e2ecc(int unit, bcm_port_t port, 56411 bcm_port_congestion_config_t *config) 56412 { 56413 56414 uint32 regval = 0; 56415 int en; 56416 int e2ecc_strict = -1; 56417 uint32 field_val; 56418 int index; 56419 mmu_intfi_st_trans_tbl_entry_t st_trans_entry; 56420 uint16 dev_id; 56421 uint8 rev_id; 56422 56423 soc_cm_get_id(unit, &dev_id, &rev_id); 56424 56425 en = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0; 56426 56427 if ((config->flags & 56428 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE)) { 56429 e2ecc_strict = 0; 56430 } else if (config->flags & 56431 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) { 56432 e2ecc_strict = 1; 56433 } else { 56434 return BCM_E_PARAM; 56435 } 56436 if ((rev_id == BCM56450_A0_REV_ID) && (!SOC_IS_SABER2(unit))) { 56437 if (e2ecc_strict) { 56438 /* E2ECC STRICT mode only valid for BCM56450_B0 onwards 56439 */ 56440 return BCM_E_UNAVAIL; 56441 } 56442 } else if ((rev_id >= BCM56450_B0_REV_ID) || SOC_IS_SABER2(unit)) { 56443 /* setting of strict/flex mode is valid only when flow control is 56444 * enabled 56445 */ 56446 e2ecc_strict = (en ? e2ecc_strict : 0); 56447 SOC_IF_ERROR_RETURN( 56448 READ_COE_FLOW_CONTROL_CONFIGr (unit, port, ®val)); 56449 /* Enable the Flow control and E2ECC mode 56450 * 1. When there is enable request 56451 * 2. When flow control is already enabled 56452 * and there is change in E2ECC_mode from 56453 * strict to flex or vice versa 56454 */ 56455 if ((en != soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr, 56456 regval, FLOW_CONTROL_FORMATf)) || 56457 (en && (soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr, 56458 regval, FLOW_CONTROL_FORMATf) == 1) && 56459 (e2ecc_strict != soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr, 56460 regval, E2ECC_MODEf)))) { 56461 soc_reg_field_set(unit, COE_FLOW_CONTROL_CONFIGr, ®val, 56462 FLOW_CONTROL_FORMATf, en); 56463 soc_reg_field_set(unit, COE_FLOW_CONTROL_CONFIGr, ®val, 56464 E2ECC_MODEf, e2ecc_strict); 56465 SOC_IF_ERROR_RETURN( 56466 WRITE_COE_FLOW_CONTROL_CONFIGr (unit, port, regval)); 56467 } 56468 } 56469 56470 if (en) { 56471 /* Configure E2ECC-FC receive MAC-DA, Length/Type, and Opcode */ 56472 field_val = (config->dest_mac[0] << 8) | /* MAC-DA[47:40] */ 56473 (config->dest_mac[1]); /* MAC-DA[39:32] */ 56474 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_MSr(unit, ®val)); 56475 soc_reg_field_set(unit, ING_VOQFC_MACDA_MSr, ®val, DAf, field_val); 56476 SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_MSr(unit, regval)); 56477 56478 field_val = (config->dest_mac[2] << 24) | /* MAC-DA[31:24] */ 56479 (config->dest_mac[3] << 16) | /* MAC-DA[23:16] */ 56480 (config->dest_mac[4] << 8) | /* MAC-DA[15:8] */ 56481 (config->dest_mac[5]); /* MAC-DA[7:0] */ 56482 56483 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_LSr(unit, ®val)); 56484 soc_reg_field_set(unit, ING_VOQFC_MACDA_LSr, ®val, DAf, field_val); 56485 SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_LSr(unit, regval)); 56486 56487 56488 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, ®val)); 56489 soc_reg_field_set(unit, ING_VOQFC_IDr, ®val, 56490 LENGTH_TYPEf, config->ethertype); 56491 56492 soc_reg_field_set(unit, ING_VOQFC_IDr, ®val, 56493 OPCODEf, config->opcode); 56494 SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_IDr(unit, regval)); 56495 56496 /* 56497 * Hardcoding the MMU_INTFI_ST_TRANS_TBL so the 56498 * congestion data is written as it is 56499 * in FC_ST_TABLE 56500 */ 56501 56502 for (index=0 ; index < soc_mem_index_count(unit, 56503 MMU_INTFI_ST_TRANS_TBLm); index++) { 56504 SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm( 56505 unit, MEM_BLOCK_ALL,index, 56506 &st_trans_entry)); 56507 soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm, 56508 &st_trans_entry, FC_ST_XLATEf,index%256); 56509 SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm( 56510 unit, MEM_BLOCK_ALL, index, 56511 &st_trans_entry)); 56512 } 56513 56514 /* 56515 * Hardcoding FC_WIDTH to 3 so that 8 bits are read at time 56516 */ 56517 SOC_IF_ERROR_RETURN 56518 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 56519 FC_WIDTHf, 3)); 56520 /* 56521 * In case of COE E2ECC merger block should be disabled 56522 */ 56523 56524 SOC_IF_ERROR_RETURN 56525 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 56526 MERGE_ENf, 0)); 56527 /* 56528 * Hardcode the INTFI_MAP_L0/L1/L2_TBL_ADDR, 56529 * so that state machine reads 56530 * all the L1,L2,L3 Nodes in a cycle 56531 */ 56532 56533 56534 SOC_IF_ERROR_RETURN 56535 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 56536 FC_MAP_TBL_ADDR_ENf, 0)); 56537 SOC_IF_ERROR_RETURN 56538 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 56539 FC_MAP_TBL_START_ADDRf, 0)); 56540 if (SOC_IS_SABER2(unit)) { 56541 #ifdef BCM_METROLITE_SUPPORT 56542 if (SOC_IS_METROLITE(unit)) { 56543 SOC_IF_ERROR_RETURN 56544 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 56545 FC_MAP_TBL_END_ADDRf, 0x1f)); 56546 } else 56547 #endif 56548 SOC_IF_ERROR_RETURN 56549 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 56550 FC_MAP_TBL_END_ADDRf, 0x3f)); 56551 } else { 56552 SOC_IF_ERROR_RETURN 56553 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 56554 FC_MAP_TBL_END_ADDRf, 0xff)); 56555 } 56556 SOC_IF_ERROR_RETURN 56557 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 56558 FC_MAP_TBL_ADDR_ENf, 0)); 56559 SOC_IF_ERROR_RETURN 56560 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 56561 FC_MAP_TBL_START_ADDRf, 0)); 56562 if (SOC_IS_SABER2(unit)) { 56563 #ifdef BCM_METROLITE_SUPPORT 56564 if (SOC_IS_METROLITE(unit)) { 56565 SOC_IF_ERROR_RETURN 56566 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 56567 FC_MAP_TBL_END_ADDRf, 0x7)); 56568 } else 56569 #endif 56570 SOC_IF_ERROR_RETURN 56571 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 56572 FC_MAP_TBL_END_ADDRf, 0xf)); 56573 } else { 56574 SOC_IF_ERROR_RETURN 56575 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 56576 FC_MAP_TBL_END_ADDRf, 0x3f)); 56577 } 56578 SOC_IF_ERROR_RETURN 56579 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 56580 FC_MAP_TBL_ADDR_ENf, 0)); 56581 SOC_IF_ERROR_RETURN 56582 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 56583 FC_MAP_TBL_START_ADDRf, 0)); 56584 if (SOC_IS_SABER2(unit)) { 56585 #ifdef BCM_METROLITE_SUPPORT 56586 if (SOC_IS_METROLITE(unit)) { 56587 SOC_IF_ERROR_RETURN 56588 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 56589 FC_MAP_TBL_END_ADDRf, 0x3)); 56590 } else 56591 #endif 56592 SOC_IF_ERROR_RETURN 56593 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 56594 FC_MAP_TBL_END_ADDRf, 0x7)); 56595 } else { 56596 SOC_IF_ERROR_RETURN 56597 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 56598 FC_MAP_TBL_END_ADDRf, 0x1f)); 56599 } 56600 56601 if (e2ecc_strict == 0) { 56602 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 56603 if (en != soc_reg_field_get(unit, IE2E_CONTROLr, regval, 56604 VOQFC_ENABLEf)) { 56605 soc_reg_field_set(unit, IE2E_CONTROLr, ®val, 56606 VOQFC_ENABLEf, en); 56607 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval)); 56608 } 56609 } else { 56610 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 56611 if (soc_reg_field_get(unit, IE2E_CONTROLr, regval, 56612 VOQFC_ENABLEf)) { 56613 soc_reg_field_set(unit, IE2E_CONTROLr, ®val, 56614 VOQFC_ENABLEf, 0); 56615 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval)); 56616 } 56617 } 56618 } else { 56619 if (e2ecc_strict == 0) { 56620 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 56621 if (soc_reg_field_get(unit, IE2E_CONTROLr, regval, 56622 VOQFC_ENABLEf)) { 56623 soc_reg_field_set(unit, IE2E_CONTROLr, ®val, 56624 VOQFC_ENABLEf, 0); 56625 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval)); 56626 } 56627 } 56628 } 56629 56630 return BCM_E_NONE; 56631 } 56632 #endif 56633 56634 /* 56635 * Function: 56636 * _bcm_esw_port_dmvoqfc_rx 56637 * Purpose: 56638 * Configure VOQFC message reception. 56639 * Parameters: 56640 * unit - (IN) Unit number. 56641 * port - (IN) Local port number. 56642 * config - (IN) Congestion configuration. 56643 * Returns: 56644 * BCM_E_xxx 56645 */ 56646 STATIC int 56647 _bcm_esw_port_dmvoqfc_rx(int unit, bcm_port_t port, 56648 bcm_port_congestion_config_t *config) 56649 { 56650 uint32 regval; 56651 uint32 field_val; 56652 int en, cos_mode; 56653 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \ 56654 defined(BCM_TRIUMPH3_SUPPORT) 56655 int index; 56656 #endif 56657 #if defined(BCM_TRIDENT2_SUPPORT) 56658 uint64 rval; 56659 #endif 56660 #if defined(BCM_TRIUMPH3_SUPPORT) 56661 uint32 rval1; 56662 mmu_intfi_st_trans_tbl_entry_t st_trans_entry; 56663 #endif 56664 56665 en = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0; 56666 cos_mode = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0; 56667 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 56668 if (en != soc_reg_field_get(unit, IE2E_CONTROLr, regval, 56669 VOQFC_ENABLEf)) { 56670 soc_reg_field_set(unit, IE2E_CONTROLr, ®val, VOQFC_ENABLEf, en); 56671 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval)); 56672 } 56673 #ifdef BCM_TRIDENT2_SUPPORT 56674 if (SOC_IS_TD2_TT2(unit)) { 56675 SOC_IF_ERROR_RETURN(READ_ING_COS_MODE_64r(unit, port, &rval)); 56676 if (cos_mode != soc_reg64_field32_get(unit, ING_COS_MODE_64r, rval, 56677 QUEUE_MODEf)) { 56678 soc_reg64_field32_set(unit, ING_COS_MODE_64r, &rval, QUEUE_MODEf, cos_mode); 56679 SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODE_64r(unit, port, rval)); 56680 } 56681 /* 56682 * FC_WIDTH is set to 2 so that 4 bits of i 56683 * congestion data is read on each cycle 56684 */ 56685 SOC_IF_ERROR_RETURN 56686 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 56687 FC_WIDTHf, 2)); 56688 /* 56689 * MERGE_EN is set to 1, to merge the congestion state 56690 * received from different ports of the same module 56691 */ 56692 56693 SOC_IF_ERROR_RETURN 56694 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 56695 MERGE_ENf, 1)); 56696 /* MODE_SEL is set to 1 to specify the message is of type 56697 * DMVOQ 56698 */ 56699 SOC_IF_ERROR_RETURN 56700 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 56701 MODE_SELf, 1)); 56702 #ifdef BCM_APACHE_SUPPORT 56703 if (SOC_IS_APACHE(unit)) { 56704 if (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL) { 56705 /* 56706 * MERGE_EN is set to 0, in case of DPVOQ. 56707 */ 56708 56709 SOC_IF_ERROR_RETURN 56710 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 56711 MERGE_ENf, 0)); 56712 /* MODE_SEL is set to 0 to specify the message is of type 56713 * DPVOQ 56714 */ 56715 SOC_IF_ERROR_RETURN 56716 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 56717 MODE_SELf, 0)); 56718 } 56719 } 56720 #endif 56721 /* DMVOQ congestion bytes max length is 64 bytes, 56722 * as a result 56723 * DMVOQ feature can support upto 64 ports 56724 */ 56725 56726 for (index = 0 ; index < SOC_REG_NUMELS(unit, CONGESTION_STATE_BYTESr) 56727 ; index++) { 56728 soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, ®val, 56729 DATAf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ); 56730 SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit, 56731 index, regval)); 56732 } 56733 56734 } else 56735 #endif 56736 #ifdef BCM_KATANA2_SUPPORT 56737 if (SOC_IS_KATANA2(unit)) { 56738 SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, ®val)); 56739 if (cos_mode != soc_reg_field_get(unit, ING_COS_MODEr, regval, 56740 COS_MODEf)) { 56741 soc_reg_field_set(unit, ING_COS_MODEr, ®val, COS_MODEf, cos_mode); 56742 SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, regval)); 56743 } 56744 56745 /* 56746 * Hardcoding FC_WIDTH to 3 so that 8 bits are read at time 56747 */ 56748 SOC_IF_ERROR_RETURN 56749 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 56750 FC_WIDTHf, 3)); 56751 if (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL) { 56752 /* 56753 * In case of DMVOQ we need to merge all the congestion bytes 56754 * of the ports so enabling MERGE_EN 56755 */ 56756 56757 SOC_IF_ERROR_RETURN 56758 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 56759 MERGE_ENf, 1)); 56760 } 56761 /* 56762 * Hardcode the INTFI_MAP_L0/L1/L2_TBL_ADDR, 56763 * so that state machine reads 56764 * all the L1,L2,L3 Nodes in a cycle 56765 */ 56766 56767 SOC_IF_ERROR_RETURN 56768 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 56769 FC_MAP_TBL_ADDR_ENf, 0)); 56770 SOC_IF_ERROR_RETURN 56771 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 56772 FC_MAP_TBL_START_ADDRf, 0)); 56773 SOC_IF_ERROR_RETURN 56774 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 56775 FC_MAP_TBL_END_ADDRf, 56776 ((soc_mem_index_count(unit, LLS_L2_PARENTm)) / 16) - 1)); 56777 SOC_IF_ERROR_RETURN 56778 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 56779 FC_MAP_TBL_ADDR_ENf, 0)); 56780 SOC_IF_ERROR_RETURN 56781 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 56782 FC_MAP_TBL_START_ADDRf, 0)); 56783 SOC_IF_ERROR_RETURN 56784 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 56785 FC_MAP_TBL_END_ADDRf, 56786 ((soc_mem_index_count(unit, LLS_L1_PARENTm)) / 16) - 1 )); 56787 SOC_IF_ERROR_RETURN 56788 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 56789 FC_MAP_TBL_ADDR_ENf, 0)); 56790 SOC_IF_ERROR_RETURN 56791 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 56792 FC_MAP_TBL_START_ADDRf, 0)); 56793 SOC_IF_ERROR_RETURN 56794 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 56795 FC_MAP_TBL_END_ADDRf, 56796 ((soc_mem_index_count(unit, LLS_L0_PARENTm)) / 56797 (SOC_IS_METROLITE(unit) ? 32: 16)) - 1)); 56798 56799 /* Though the number of ports supported in KT2 is 41, we're setting the 56800 max to 64 to support stacked systems. */ 56801 for (index = 0 ; index < SOC_REG_NUMELS(unit, CONGESTION_STATE_BYTESr) 56802 ; index++) { 56803 soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, ®val, 56804 DATAf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ); 56805 SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit, 56806 index, regval)); 56807 } 56808 56809 } else 56810 #endif 56811 #ifdef BCM_TRIUMPH3_SUPPORT 56812 if (SOC_IS_TRIUMPH3(unit)) { 56813 SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &rval1)); 56814 if (cos_mode != soc_reg_field_get(unit, ING_COS_MODEr, rval1, 56815 QUEUE_MODEf)) { 56816 soc_reg_field_set(unit, ING_COS_MODEr, &rval1, QUEUE_MODEf, cos_mode); 56817 SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, rval1)); 56818 } 56819 /* 56820 * Hardcoding the MMU_INTFI_ST_TRANS_TBL so the 56821 * congestion data is written as it is 56822 * in FC_ST_TABLE, This we are doing so that 56823 * congestion data is updated as it is how 56824 * it recevied 56825 */ 56826 56827 for (index=0 ; index < soc_mem_index_count(unit, 56828 MMU_INTFI_ST_TRANS_TBLm); index++) { 56829 SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm( 56830 unit, MEM_BLOCK_ALL,index, 56831 &st_trans_entry)); 56832 soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm, 56833 &st_trans_entry, FC_ST_XLATEf,index%16); 56834 SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm( 56835 unit, MEM_BLOCK_ALL, index, 56836 &st_trans_entry)); 56837 } 56838 /* 56839 * FC_WIDTH is set to 2 so that 4 bits of i 56840 * congestion data is read on each cycle 56841 */ 56842 SOC_IF_ERROR_RETURN 56843 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 56844 FC_WIDTHf, 2)); 56845 /* 56846 * MERGE_EN is set to 1, to merge the congestion state 56847 * received from different ports of the same module 56848 */ 56849 56850 SOC_IF_ERROR_RETURN 56851 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 56852 MERGE_ENf, 1)); 56853 /* DMVOQ congestion bytes max length is 64 bytes, 56854 * as a result 56855 * DMVOQ feature can support upto 64 ports 56856 */ 56857 56858 for (index = 0; index < SOC_REG_NUMELS(unit, CONGESTION_STATE_BYTESr) 56859 ; index++) { 56860 soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, ®val, 56861 DATAf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ); 56862 SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit, 56863 index, regval)); 56864 } 56865 56866 } else 56867 #endif 56868 { 56869 SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, ®val)); 56870 if (cos_mode != soc_reg_field_get(unit, ING_COS_MODEr, regval, 56871 QUEUE_MODEf)) { 56872 soc_reg_field_set(unit, ING_COS_MODEr, ®val, QUEUE_MODEf, cos_mode); 56873 SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, regval)); 56874 } 56875 } 56876 56877 if (en) { 56878 /* Configure DMVOQFC receive MAC-DA, Length/Type, and Opcode */ 56879 field_val = (config->dest_mac[0] << 8) | /* MAC-DA[47:40] */ 56880 (config->dest_mac[1]); /* MAC-DA[39:32] */ 56881 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_MSr(unit, ®val)); 56882 soc_reg_field_set(unit, ING_VOQFC_MACDA_MSr, ®val, DAf, field_val); 56883 SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_MSr(unit, regval)); 56884 56885 field_val = (config->dest_mac[2] << 24) | /* MAC-DA[31:24] */ 56886 (config->dest_mac[3] << 16) | /* MAC-DA[23:16] */ 56887 (config->dest_mac[4] << 8) | /* MAC-DA[15:8] */ 56888 (config->dest_mac[5]); /* MAC-DA[7:0] */ 56889 56890 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_LSr(unit, ®val)); 56891 soc_reg_field_set(unit, ING_VOQFC_MACDA_LSr, ®val, DAf, field_val); 56892 SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_LSr(unit, regval)); 56893 56894 56895 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, ®val)); 56896 soc_reg_field_set(unit, ING_VOQFC_IDr, ®val, 56897 LENGTH_TYPEf, config->ethertype); 56898 56899 soc_reg_field_set(unit, ING_VOQFC_IDr, ®val, OPCODEf, config->opcode); 56900 SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_IDr(unit, regval)); 56901 } 56902 56903 return BCM_E_NONE; 56904 } 56905 /* 56906 * Function: 56907 * _bcm_esw_port_dmvoqfc_tx 56908 * Purpose: 56909 * Configure VOQFC message reception. 56910 * Parameters: 56911 * unit - (IN) Unit number. 56912 * port - (IN) Local port number. 56913 * config - (IN) Congestion configuration. 56914 * Returns: 56915 * BCM_E_xxx 56916 */ 56917 STATIC int 56918 _bcm_esw_port_dmvoqfc_tx(int unit, bcm_port_t port, 56919 bcm_port_congestion_config_t *config) 56920 { 56921 /* 56922 * Trident/Titan VOQFC message generation is same as E2ECC, except for 56923 * ethertype and opcode. 56924 */ 56925 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANA2(unit) 56926 || SOC_IS_TD2_TT2(unit) || SOC_IS_TRIUMPH3(unit)) { 56927 BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_tx(unit, port, config)); 56928 return BCM_E_NONE; 56929 } 56930 56931 return BCM_E_UNAVAIL; 56932 } 56933 56934 /* 56935 * Function: 56936 * bcm_port_congestion_config_set 56937 * Purpose: 56938 * Set end-to-end congestion control. 56939 * Parameters: 56940 * unit - (IN) Unit number. 56941 * port - (IN) Gport number. 56942 * config - (IN) Structure containing the congestion configuration. 56943 * Returns: 56944 * BCM_E_xxx 56945 */ 56946 int 56947 bcm_esw_port_congestion_config_set(int unit, bcm_gport_t port, 56948 bcm_port_congestion_config_t *config) 56949 { 56950 bcm_port_t local_port; 56951 56952 /* Make sure port module is initialized. */ 56953 PORT_INIT(unit); 56954 56955 if (soc_feature(unit, soc_feature_e2ecc)) { 56956 /* Check for parameters */ 56957 56958 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &local_port)); 56959 56960 if (!IS_HG_PORT(unit, local_port)) { 56961 if(SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 56962 SOC_IS_APACHE(unit) ) { 56963 if ((config->flags & 56964 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) || 56965 (config->flags & 56966 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) || 56967 (config->flags & 56968 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) 56969 { 56970 if (!IS_SUBTAG_PORT(unit, local_port)) { 56971 LOG_ERROR(BSL_LS_BCM_PORT, 56972 (BSL_META_U(unit, 56973 "E2ECC COE is applicable on subports only." 56974 "Port %d is not a subport.\n"), 56975 local_port)); 56976 return BCM_E_PORT; 56977 } 56978 } else if ((config->flags & 56979 BCM_PORT_CONGESTION_CONFIG_TX) && 56980 (config->flags & 56981 BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL)) { 56982 if ((IS_GE_PORT(unit, local_port)) || 56983 (IS_XE_PORT(unit, local_port))) { 56984 /* Set per-queue E2ECC enable bits */ 56985 BCM_IF_ERROR_RETURN 56986 (_bcm_esw_port_drop_status_enable_set(unit, 56987 port, TRUE)); 56988 /* Make sure port module is initialized. */ 56989 PORT_INIT(unit); 56990 56991 /* Lock is needed to modify bcm_port_info */ 56992 PORT_LOCK(unit); 56993 56994 /* Allocate per-port congestion configuration state on demand */ 56995 if (PORT(unit, local_port).e2ecc_config == NULL) { 56996 PORT(unit, local_port).e2ecc_config = sal_alloc(sizeof(bcm_port_congestion_config_t), 56997 "bcm_port_congestion_config"); 56998 if (PORT(unit, local_port).e2ecc_config == NULL) { 56999 LOG_ERROR(BSL_LS_BCM_PORT, 57000 (BSL_META_U(unit, 57001 "Error: unable to allocate memory for bcm_port_congestion_config.\n"))); 57002 PORT_UNLOCK(unit); 57003 return BCM_E_MEMORY; 57004 } 57005 } 57006 57007 /* Store E2ECC configuration */ 57008 *(PORT(unit, local_port).e2ecc_config) = *(config); 57009 57010 PORT_UNLOCK(unit); 57011 return BCM_E_NONE; 57012 } 57013 LOG_ERROR(BSL_LS_BCM_PORT, 57014 (BSL_META_U(unit, 57015 "Applicable on Ge/Xe only " 57016 "for enabling dmvoq transmitting only.\n "))); 57017 return BCM_E_PARAM; 57018 } else { 57019 if (((SOC_IS_TRIDENT2PLUS(unit)) || SOC_IS_APACHE(unit)) && 57020 (config->flags & BCM_PORT_CONGESTION_CONFIG_HCFC)) { 57021 LOG_ERROR(BSL_LS_BCM_PORT, 57022 (BSL_META_U(unit, 57023 "Error: unit %d port %d is not a Higig port. " 57024 "E2ECC messages can only be transmitted to " 57025 "or received from Higig ports.\n"), 57026 unit, local_port)); 57027 return BCM_E_PARAM; 57028 } 57029 } 57030 } else { 57031 #ifdef BCM_FIRELIGHT_SUPPORT 57032 if (SOC_IS_FIRELIGHT(unit) && 57033 (IS_XL_PORT(unit, local_port) || IS_CL_PORT(unit, local_port)) ) { 57034 LOG_DEBUG(BSL_LS_BCM_PORT, 57035 (BSL_META_U(unit, 57036 "unit %d port %d is not a Higig port. " 57037 "E2ECC messages can be transmitted to " 57038 "Higig/ethernet(XL/CL) ports.\n"), unit, local_port)); 57039 } else 57040 #endif /* BCM_FIRELIGHT_SUPPORT */ 57041 { 57042 LOG_ERROR(BSL_LS_BCM_PORT, 57043 (BSL_META_U(unit, 57044 "Error: unit %d port %d is not a Higig port. " 57045 "E2ECC messages can only be transmitted to or received from " 57046 "Higig ports.\n"), unit, local_port)); 57047 return BCM_E_PARAM; 57048 } 57049 } 57050 } 57051 57052 if (config == NULL) { 57053 return BCM_E_PARAM; 57054 } 57055 57056 if (!((config->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC) || 57057 (config->flags & BCM_PORT_CONGESTION_CONFIG_HCFC) || 57058 (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL) || 57059 (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL) || 57060 (config->flags & BCM_PORT_CONGESTION_CONFIG_MAX_SPLIT4) || 57061 (config->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) || 57062 (config->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) || 57063 (config->flags & BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE))) { 57064 return BCM_E_PARAM; 57065 } 57066 57067 if (config->packets_per_sec < 0) { 57068 return BCM_E_PARAM; 57069 } 57070 57071 switch (config->flags & 57072 (BCM_PORT_CONGESTION_CONFIG_E2ECC | 57073 BCM_PORT_CONGESTION_CONFIG_HCFC | 57074 BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL | 57075 BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL | 57076 BCM_PORT_CONGESTION_CONFIG_MAX_SPLIT4 | 57077 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE | 57078 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE | 57079 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) { 57080 case BCM_PORT_CONGESTION_CONFIG_E2ECC: 57081 case BCM_PORT_CONGESTION_CONFIG_MAX_SPLIT4: 57082 /* Handle E2ECC message transmission */ 57083 BCM_IF_ERROR_RETURN 57084 (_bcm_esw_port_e2ecc_tx(unit, local_port, config)); 57085 57086 /* Handle E2ECC message reception */ 57087 BCM_IF_ERROR_RETURN 57088 (_bcm_esw_port_e2ecc_rx(unit, local_port, config)); 57089 break; 57090 57091 case BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE: 57092 case BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE: 57093 case BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE: 57094 /* COE flow control using E2ECC messages 57095 * KT2 supports E2E-CC message reception on 57096 * COE ports. 57097 */ 57098 #ifdef BCM_KATANA2_SUPPORT 57099 if (SOC_IS_KATANA2(unit)) { 57100 BCM_IF_ERROR_RETURN 57101 (_bcm_esw_port_coe_e2ecc(unit, local_port, config)); 57102 57103 } 57104 #endif 57105 57106 57107 57108 /* COE flow control using E2ECC messages 57109 * TD2+ supports E2E-CC message reception on 57110 * COE ports, only in STRICT mode. 57111 */ 57112 #ifdef BCM_TRIDENT2PLUS_SUPPORT 57113 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 57114 if (((config->flags & 57115 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) || 57116 (config->flags & 57117 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) && 57118 (config->flags & 57119 BCM_PORT_CONGESTION_CONFIG_RX)) 57120 { 57121 BCM_IF_ERROR_RETURN 57122 (bcm_td2p_port_coe_e2ecc(unit, local_port, config)); 57123 } else { 57124 return BCM_E_PARAM; 57125 } 57126 57127 } 57128 #endif 57129 break; 57130 57131 case BCM_PORT_CONGESTION_CONFIG_HCFC: 57132 if (SOC_IS_TRIUMPH3(unit)) { 57133 BCM_IF_ERROR_RETURN(_bcm_tr3_port_hcfc(unit, local_port, config)); 57134 } else { 57135 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc(unit, local_port, config)); 57136 } 57137 break; 57138 57139 case BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL: 57140 if ((!SOC_IS_TD_TT(unit)) && (!SOC_IS_KATANA2(unit)) && 57141 (!SOC_IS_TD2_TT2(unit)) && (!SOC_IS_TRIUMPH3(unit))) { 57142 return BCM_E_PARAM; 57143 } 57144 57145 /* Handle VOQFC message reception */ 57146 BCM_IF_ERROR_RETURN 57147 (_bcm_esw_port_dmvoqfc_rx(unit, local_port, config)); 57148 57149 /* Handle E2ECC message transmission */ 57150 BCM_IF_ERROR_RETURN 57151 (_bcm_esw_port_dmvoqfc_tx(unit, local_port, config)); 57152 break; 57153 case BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL: 57154 if (!SOC_IS_KATANA2(unit) && !(SOC_IS_APACHE(unit))) { 57155 return BCM_E_PARAM; 57156 } 57157 57158 /* Handle VOQFC message reception */ 57159 BCM_IF_ERROR_RETURN 57160 (_bcm_esw_port_dmvoqfc_rx(unit, local_port, config)); 57161 57162 /* Handle E2ECC message transmission */ 57163 BCM_IF_ERROR_RETURN 57164 (_bcm_esw_port_dmvoqfc_tx(unit, local_port, config)); 57165 break; 57166 default: 57167 return BCM_E_PARAM; 57168 } 57169 /* Make sure port module is initialized. */ 57170 PORT_INIT(unit); 57171 57172 /* Lock is needed to modify bcm_port_info */ 57173 PORT_LOCK(unit); 57174 57175 /* Allocate per-port congestion configuration state on demand */ 57176 if (PORT(unit, local_port).e2ecc_config == NULL) { 57177 PORT(unit, local_port).e2ecc_config = sal_alloc(sizeof(bcm_port_congestion_config_t), 57178 "bcm_port_congestion_config"); 57179 if (PORT(unit, local_port).e2ecc_config == NULL) { 57180 LOG_ERROR(BSL_LS_BCM_PORT, 57181 (BSL_META_U(unit, 57182 "Error: unable to allocate memory for bcm_port_congestion_config.\n"))); 57183 PORT_UNLOCK(unit); 57184 return BCM_E_MEMORY; 57185 } 57186 } 57187 57188 /* Store E2ECC configuration */ 57189 *(PORT(unit, local_port).e2ecc_config) = *(config); 57190 57191 PORT_UNLOCK(unit); 57192 57193 57194 return BCM_E_NONE; 57195 } else { 57196 return BCM_E_UNAVAIL; 57197 } 57198 57199 } 57200 57201 /* 57202 * Function: 57203 * bcm_port_congestion_config_get 57204 * Purpose: 57205 * Get end-to-end congestion control configuration. 57206 * Parameters: 57207 * unit - (IN) Unit number. 57208 * port - (IN) Gport number. 57209 * config - (OUT) Structure containing the congestion configuration. 57210 * Returns: 57211 * BCM_E_xxx 57212 */ 57213 57214 int 57215 bcm_esw_port_congestion_config_get(int unit, bcm_gport_t port, 57216 bcm_port_congestion_config_t *config) 57217 { 57218 bcm_port_t local_port; 57219 57220 /* Make sure port module is initialized. */ 57221 PORT_INIT(unit); 57222 57223 if (soc_feature(unit, soc_feature_e2ecc)) { 57224 /* Check for parameters */ 57225 57226 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &local_port)); 57227 if (!IS_HG_PORT(unit, local_port)) { 57228 if (SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 57229 SOC_IS_APACHE(unit)) { 57230 if ((config->flags & 57231 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) || 57232 (config->flags & 57233 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) || 57234 (config->flags & 57235 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) { 57236 if (!IS_SUBTAG_PORT(unit, local_port)) { 57237 LOG_ERROR( 57238 BSL_LS_BCM_PORT, 57239 (BSL_META_U(unit, 57240 "Error: unit %d port %d is not a Higig " 57241 "port or Subtag port. E2ECC messages " 57242 "can be transmitted to or received from " 57243 "Higig ports or can be received on " 57244 "Subtag port.\n"), 57245 unit, local_port)); 57246 return BCM_E_PORT; 57247 } 57248 if ((SOC_IS_TRIDENT2PLUS(unit)|| SOC_IS_APACHE(unit)) && 57249 ((config->flags & 57250 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE))) { 57251 return BCM_E_PARAM; 57252 57253 } else if ((SOC_IS_TRIDENT2PLUS(unit)|| SOC_IS_APACHE(unit)) && 57254 ((config->flags & 57255 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) || 57256 (config->flags & 57257 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) && 57258 (config->flags & 57259 BCM_PORT_CONGESTION_CONFIG_TX)) { 57260 return BCM_E_PARAM; 57261 } 57262 } else if ((config->flags & 57263 BCM_PORT_CONGESTION_CONFIG_TX) && 57264 (config->flags & 57265 BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL)) { 57266 if (!(IS_GE_PORT(unit, local_port)) && 57267 !(IS_XE_PORT(unit, local_port))) { 57268 LOG_ERROR( 57269 BSL_LS_BCM_PORT, 57270 (BSL_META_U(unit, 57271 "Applicable on Ge/Xe only for enabling " 57272 "dmvoq transmitting only.\n "))); 57273 return BCM_E_PARAM; 57274 } 57275 } else if ((SOC_IS_TRIDENT2PLUS(unit)|| SOC_IS_APACHE(unit)) && 57276 (config->flags & BCM_PORT_CONGESTION_CONFIG_HCFC)) { 57277 LOG_ERROR( 57278 BSL_LS_BCM_PORT, 57279 (BSL_META_U(unit, 57280 "Error: unit %d port %d is not a Higig port. " 57281 "E2ECC messages can only be transmitted to " 57282 "or received from Higig ports.\n"), 57283 unit, local_port)); 57284 return BCM_E_PARAM; 57285 } 57286 } else { 57287 #ifdef BCM_FIRELIGHT_SUPPORT 57288 if (SOC_IS_FIRELIGHT(unit) && 57289 (IS_XL_PORT(unit, local_port) || IS_CL_PORT(unit, local_port)) ) { 57290 LOG_DEBUG(BSL_LS_BCM_PORT, 57291 (BSL_META_U(unit, 57292 "unit %d port %d is not a Higig port. " 57293 "E2ECC messages can be transmitted to " 57294 "Higig/ethernet(XL/CL) ports.\n"), unit, local_port)); 57295 } else 57296 #endif /* BCM_FIRELIGHT_SUPPORT */ 57297 { 57298 LOG_ERROR( 57299 BSL_LS_BCM_PORT, 57300 (BSL_META_U(unit, 57301 "Error: unit %d port %d is not a Higig port. " 57302 "E2ECC messages can only be transmitted to " 57303 "or received from Higig ports.\n"), 57304 unit, local_port)); 57305 return BCM_E_PARAM; 57306 } 57307 } 57308 } 57309 if (config == NULL) { 57310 return BCM_E_PARAM; 57311 } 57312 57313 /* Make sure port module is initialized. */ 57314 PORT_INIT(unit); 57315 57316 if (PORT(unit, local_port).e2ecc_config == NULL) { 57317 LOG_ERROR(BSL_LS_BCM_PORT, 57318 (BSL_META_U(unit, 57319 "Error: Port %d bcm_port_congestion_config was not set.\n"), 57320 local_port)); 57321 return BCM_E_NOT_FOUND; 57322 } 57323 57324 /* Retrieve E2ECC configuration */ 57325 *config = *(PORT(unit, local_port).e2ecc_config); 57326 57327 return BCM_E_NONE; 57328 57329 } else { 57330 return BCM_E_UNAVAIL; 57331 } 57332 } 57333 57334 /* 57335 * Function: 57336 * bcm_port_match_add 57337 * Purpose: 57338 * Add a match to an existing port 57339 * Parameters: 57340 * unit - (IN) Unit number. 57341 * port - (IN) Port or gport 57342 * match - (IN) Match criteria 57343 * Returns: 57344 * BCM_E_xxx 57345 * Notes: 57346 */ 57347 int 57348 bcm_esw_port_match_add( 57349 int unit, 57350 bcm_gport_t port, 57351 bcm_port_match_info_t *match) 57352 { 57353 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 57354 int vp=0, rv = BCM_E_NONE; 57355 bcm_gport_t gp = 0; 57356 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_MPLS_SUPPORT) 57357 _bcm_vp_info_t vp_info; 57358 #endif 57359 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 57360 bcm_vxlan_port_t vxlan_port; 57361 bcm_l2gre_port_t l2gre_port; 57362 #endif 57363 int existing_updated = 0; 57364 #if defined(BCM_TRIDENT3_SUPPORT) 57365 bcm_mirror_destination_t mirror_dest; 57366 uint32 cancun_ver; 57367 #endif /* BCM_TRIDENT3_SUPPORT */ 57368 #if defined(BCM_TRX_SUPPORT) 57369 bcm_vlan_match_info_t vlan_match_info; 57370 #endif 57371 if (match == NULL) { 57372 return BCM_E_PARAM; 57373 } 57374 57375 /* Make sure port module is initialized. */ 57376 PORT_INIT(unit); 57377 57378 if (BCM_GPORT_IS_MIM_PORT(port)) { 57379 #if defined(BCM_TRIUMPH2_SUPPORT) 57380 if (!soc_feature(unit, soc_feature_mim)) { 57381 return BCM_E_UNAVAIL; 57382 } 57383 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 57384 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 57385 return BCM_E_NOT_FOUND; 57386 } 57387 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 57388 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57389 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_port_phys_gport_get(unit, vp, &gp)); 57390 } 57391 #endif 57392 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 57393 if (!soc_feature(unit, soc_feature_mpls)) { 57394 return BCM_E_UNAVAIL; 57395 } 57396 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 57397 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 57398 return BCM_E_NOT_FOUND; 57399 } 57400 #if defined(BCM_MPLS_SUPPORT) 57401 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 57402 if ((vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57403 if (!soc_feature(unit, soc_feature_vp_sharing)) { 57404 return BCM_E_UNAVAIL; 57405 } 57406 } else { 57407 BCM_IF_ERROR_RETURN(bcm_tr_mpls_port_phys_gport_get(unit, vp, &gp)); 57408 } 57409 #endif 57410 } else 57411 #if defined(BCM_TRIDENT2_SUPPORT) 57412 if (BCM_GPORT_IS_TRUNK(port)) { 57413 if (!soc_feature(unit, soc_feature_vp_lag)) { 57414 return BCM_E_UNAVAIL; 57415 } 57416 BCM_IF_ERROR_RETURN( 57417 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port), 57418 &vp)); 57419 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 57420 return BCM_E_NOT_FOUND; 57421 } 57422 if (match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID && 57423 match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN) { 57424 return BCM_E_PARAM; 57425 } 57426 } else 57427 #endif /* BCM_TRIDENT2_SUPPORT */ 57428 #if defined(BCM_TRIDENT2_SUPPORT) 57429 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 57430 if (!soc_feature(unit, soc_feature_vxlan)) { 57431 return BCM_E_UNAVAIL; 57432 } 57433 if (match->match == BCM_PORT_MATCH_PORT 57434 || match->match == BCM_PORT_MATCH_MAC_PORT 57435 || match->match == BCM_PORT_MATCH_PORT_VLAN_RANGE 57436 || match->match == BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE 57437 || match->match == BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE 57438 ) { 57439 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 57440 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) { 57441 return BCM_E_NOT_FOUND; 57442 } 57443 } else { 57444 if (!soc_feature(unit, soc_feature_vp_sharing)) { 57445 return BCM_E_UNAVAIL; 57446 } 57447 57448 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 57449 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 57450 57451 if (vp_info.vp_type != _bcmVpTypeVxlan) { 57452 return BCM_E_PARAM; 57453 } 57454 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57455 return BCM_E_PARAM; 57456 } 57457 57458 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, match->vpn)); 57459 } 57460 } else 57461 #endif 57462 #if defined(BCM_TRIDENT2_SUPPORT) 57463 if (BCM_GPORT_IS_L2GRE_PORT(port)) { 57464 if (!soc_feature(unit, soc_feature_l2gre)) { 57465 return BCM_E_UNAVAIL; 57466 } 57467 if (match->match == BCM_PORT_MATCH_PORT) { 57468 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 57469 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre))) { 57470 return BCM_E_NOT_FOUND; 57471 } 57472 } else { 57473 if (!soc_feature(unit, soc_feature_vp_sharing)) { 57474 return BCM_E_UNAVAIL; 57475 } 57476 57477 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 57478 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 57479 57480 if (vp_info.vp_type != _bcmVpTypeL2Gre) { 57481 return BCM_E_PARAM; 57482 } 57483 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57484 return BCM_E_PARAM; 57485 } 57486 57487 BCM_IF_ERROR_RETURN(_bcm_tr3_l2gre_vpn_is_valid(unit, match->vpn)); 57488 } 57489 } else 57490 #endif 57491 57492 57493 #if defined(BCM_TRIUMPH2_SUPPORT) 57494 if (BCM_GPORT_IS_VLAN_PORT(port)) { 57495 if ((!soc_feature(unit, soc_feature_lltag)) && 57496 (!soc_feature(unit, soc_feature_vlan_vp))) { 57497 return BCM_E_UNAVAIL; 57498 } 57499 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 57500 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan))) { 57501 return BCM_E_NOT_FOUND; 57502 } 57503 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_port_phys_gport_get(unit, vp, &gp)); 57504 } else 57505 #endif 57506 #if defined(BCM_TRIDENT_SUPPORT) 57507 if (BCM_GPORT_IS_NIV_PORT(port)) { 57508 if (!soc_feature(unit, soc_feature_niv)) { 57509 return BCM_E_UNAVAIL; 57510 } 57511 vp = BCM_GPORT_NIV_PORT_ID_GET(port); 57512 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv))) { 57513 return BCM_E_PARAM; 57514 } 57515 } else 57516 #endif /* BCM_TRIDENT_SUPPORT */ 57517 #if defined(BCM_TRIDENT3_SUPPORT) 57518 if (BCM_GPORT_IS_MIRROR(port)) { 57519 if (!soc_feature(unit, soc_feature_mirror_encap_profile)) { 57520 return BCM_E_UNAVAIL; 57521 } 57522 if ((match->match == BCM_PORT_MATCH_PORT_VLAN) || 57523 (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) || 57524 (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) { 57525 57526 SOC_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver)); 57527 if (SOC_IS_TRIDENT3(unit) && 57528 SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) { 57529 if ((match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) || 57530 (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) { 57531 LOG_ERROR(BSL_LS_BCM_PORT, 57532 (BSL_META_U(unit, 57533 "BCM_PORT_MATCH_PORT_I2E_CLASS match criteria \ 57534 not supported in Cancun 5.1.8 release\n"))); 57535 return BCM_E_UNAVAIL; 57536 } 57537 } else { 57538 if (match->match == BCM_PORT_MATCH_PORT_VLAN) { 57539 LOG_ERROR(BSL_LS_BCM_PORT, 57540 (BSL_META_U(unit, 57541 "BCM_PORT_MATCH_PORT_VLAN match criteria \ 57542 not supported after Cancun 5.1.8 release\n"))); 57543 return BCM_E_UNAVAIL; 57544 } 57545 57546 /* check if max I2E class_id */ 57547 if (match->match_vlan > _BCM_I2E_CLASS_ID_MAX) { 57548 LOG_ERROR(BSL_LS_BCM_PORT, 57549 (BSL_META_U(unit, " %d exceeds I2E class_id max %d\n"), 57550 match->match_vlan,_BCM_I2E_CLASS_ID_MAX)); 57551 return BCM_E_PARAM; 57552 } 57553 } 57554 57555 bcm_mirror_destination_t_init(&mirror_dest); 57556 BCM_IF_ERROR_RETURN(bcm_esw_mirror_destination_get(unit, port, 57557 &mirror_dest)); 57558 if (mirror_dest.flags & BCM_MIRROR_DEST_FIELD) { 57559 return BCM_E_PARAM; 57560 } 57561 } else { 57562 return BCM_E_PARAM; 57563 } 57564 } else 57565 #endif /* BCM_TRIDENT3_SUPPORT */ 57566 { 57567 return BCM_E_PORT; 57568 } 57569 57570 switch (match->match) { 57571 case BCM_PORT_MATCH_NONE: 57572 rv = BCM_E_NONE; 57573 break; 57574 #if defined(BCM_TRIDENT2_SUPPORT) 57575 case BCM_PORT_MATCH_PORT: 57576 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 57577 bcm_vxlan_port_t_init(&vxlan_port); 57578 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT; 57579 vxlan_port.vxlan_port_id = port; 57580 vxlan_port.match_port = match->port; 57581 BCM_IF_ERROR_RETURN( 57582 _bcm_td2_vxlan_match_add(unit, &vxlan_port, vp, 0)); 57583 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 57584 bcm_l2gre_port_t_init(&l2gre_port); 57585 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT; 57586 l2gre_port.l2gre_port_id = port; 57587 l2gre_port.match_port = match->port; 57588 BCM_IF_ERROR_RETURN( 57589 bcm_td2_l2gre_match_add(unit, &l2gre_port, vp, 0)); 57590 } else if (BCM_GPORT_IS_MIM_PORT(port) && 57591 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57592 bcm_mim_port_t mim_port; 57593 bcm_mim_port_t_init(&mim_port); 57594 mim_port.criteria = BCM_MIM_PORT_MATCH_PORT; 57595 mim_port.mim_port_id = port; 57596 mim_port.port = match->port; 57597 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_add(unit, 57598 &mim_port, vp, match->vpn)); 57599 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 57600 #if defined(BCM_MPLS_SUPPORT) 57601 bcm_mpls_port_t mpls_port; 57602 bcm_mpls_port_t_init(&mpls_port); 57603 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT; 57604 mpls_port.mpls_port_id = port; 57605 mpls_port.port = match->port; 57606 BCM_IF_ERROR_RETURN( 57607 _bcm_tr_mpls_match_add(unit, &mpls_port, vp, 0, TRUE)); 57608 #endif 57609 } else if (BCM_GPORT_IS_VLAN_PORT(port)) { 57610 bcm_vlan_port_t vlan_port; 57611 bcm_vlan_port_t_init(&vlan_port); 57612 vlan_port.criteria = BCM_VLAN_PORT_MATCH_PORT; 57613 vlan_port.port = match->port; 57614 BCM_IF_ERROR_RETURN( 57615 bcm_tr2_vlan_vp_match_add(unit, &vlan_port, vp)); 57616 57617 } else { 57618 rv = BCM_E_PARAM; 57619 } 57620 break; 57621 #endif 57622 57623 case BCM_PORT_MATCH_PORT_I2E_CLASS: 57624 case BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE: 57625 #if defined(BCM_TRIDENT3_SUPPORT) 57626 if (BCM_GPORT_IS_MIRROR(port)) { 57627 rv = _bcm_mirror_port_match_add(unit, &mirror_dest, match->port, 57628 match->match_vlan, match->match); 57629 } else 57630 #endif 57631 { 57632 rv = BCM_E_UNAVAIL; 57633 } 57634 break; 57635 57636 case BCM_PORT_MATCH_PORT_VLAN: 57637 #if defined(BCM_TRIDENT3_SUPPORT) 57638 if (BCM_GPORT_IS_MIRROR(port)) { 57639 rv = _bcm_mirror_port_match_add(unit, &mirror_dest, match->port, 57640 match->match_vlan, match->match); 57641 break; 57642 } else 57643 #endif /* BCM_TRIDENT3_SUPPORT */ 57644 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 57645 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 57646 /* match_info translation to vxlan_port */ 57647 bcm_vxlan_port_t_init(&vxlan_port); 57648 VLAN_CHK_ID(unit, match->match_vlan); 57649 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN; 57650 vxlan_port.match_vlan = match->match_vlan; 57651 vxlan_port.vxlan_port_id = port; 57652 vxlan_port.match_port = match->port; 57653 57654 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit, 57655 &vxlan_port, vp, match->vpn)); 57656 break; 57657 } else if (BCM_GPORT_IS_MIM_PORT(port) && 57658 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57659 bcm_mim_port_t mim_port; 57660 bcm_mim_port_t_init(&mim_port); 57661 VLAN_CHK_ID(unit, match->match_vlan); 57662 mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN; 57663 mim_port.match_vlan = match->match_vlan; 57664 mim_port.mim_port_id = port; 57665 mim_port.port = match->port; 57666 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_add(unit, 57667 &mim_port, vp, match->vpn)); 57668 break; 57669 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 57670 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57671 bcm_mpls_port_t mpls_port; 57672 bcm_mpls_port_t_init(&mpls_port); 57673 VLAN_CHK_ID(unit, match->match_vlan); 57674 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN; 57675 mpls_port.match_vlan = match->match_vlan; 57676 mpls_port.mpls_port_id = port; 57677 mpls_port.port = match->port; 57678 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit, 57679 &mpls_port, vp, match->vpn, TRUE)); 57680 break; 57681 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 57682 /* match_info translation to L2GRE_port */ 57683 bcm_l2gre_port_t_init(&l2gre_port); 57684 VLAN_CHK_ID(unit, match->match_vlan); 57685 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN; 57686 l2gre_port.match_vlan = match->match_vlan; 57687 l2gre_port.l2gre_port_id = port; 57688 l2gre_port.match_port = match->port; 57689 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit, 57690 &l2gre_port, vp, match->vpn)); 57691 break; 57692 } 57693 #endif 57694 57695 /* Add an entry in the VLAN_XLATE table */ 57696 /* Tag actions need to be adjusted by calling the 57697 bcm_vlan_translate_action_add API for the entry we are creating */ 57698 VLAN_CHK_ID(unit, match->match_vlan); 57699 if (BCM_GPORT_IS_MODPORT(match->port) || 57700 BCM_GPORT_IS_TRUNK(match->port)) { 57701 /* Use the port from bcm_port_match_info_t instead of the physical 57702 port from the VP */ 57703 gp = match->port; 57704 } 57705 57706 rv = _bcm_tr_vlan_translate_vp_add(unit, gp, 57707 bcmVlanTranslateKeyPortOuter, 57708 match->match_vlan, 57709 BCM_VLAN_INVALID, 57710 vp, match->action, 57711 &existing_updated); 57712 if (BCM_GPORT_IS_MIM_PORT(port)) { 57713 #if defined(BCM_TRIUMPH2_SUPPORT) 57714 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 57715 #endif 57716 } else if (BCM_GPORT_IS_MPLS_PORT(port) && !existing_updated) { 57717 #if defined(BCM_MPLS_SUPPORT) 57718 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1); 57719 #endif 57720 } 57721 break; 57722 57723 case BCM_PORT_MATCH_PORT_INNER_VLAN: 57724 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 57725 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 57726 bcm_vxlan_port_t_init(&vxlan_port); 57727 VLAN_CHK_ID(unit, match->match_inner_vlan); 57728 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_INNER_VLAN; 57729 vxlan_port.match_inner_vlan = match->match_inner_vlan; 57730 vxlan_port.vxlan_port_id = port; 57731 vxlan_port.match_port = match->port; 57732 57733 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit, 57734 &vxlan_port, vp, match->vpn)); 57735 break; 57736 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 57737 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57738 bcm_mpls_port_t mpls_port; 57739 bcm_mpls_port_t_init(&mpls_port); 57740 VLAN_CHK_ID(unit, match->match_inner_vlan); 57741 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_INNER_VLAN; 57742 mpls_port.match_inner_vlan = match->match_inner_vlan; 57743 mpls_port.mpls_port_id = port; 57744 mpls_port.port = match->port; 57745 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit, 57746 &mpls_port, vp, match->vpn, TRUE)); 57747 break; 57748 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 57749 /* match_info translation to L2GRE_port */ 57750 bcm_l2gre_port_t_init(&l2gre_port); 57751 VLAN_CHK_ID(unit, match->match_vlan); 57752 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN; 57753 l2gre_port.match_inner_vlan = match->match_inner_vlan; 57754 l2gre_port.l2gre_port_id = port; 57755 l2gre_port.match_port = match->port; 57756 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit, 57757 &l2gre_port, vp, match->vpn)); 57758 break; 57759 } 57760 #endif 57761 /* Add an entry in the VLAN_XLATE table */ 57762 /* Tag actions need to be adjusted by calling the 57763 * bcm_vlan_translate_action_add API for the entry we are creating */ 57764 VLAN_CHK_ID(unit, match->match_inner_vlan); 57765 if (BCM_GPORT_IS_MODPORT(match->port) || 57766 BCM_GPORT_IS_TRUNK(match->port)) { 57767 /* Use the port from bcm_port_match_info_t instead of the physical 57768 port from the VP */ 57769 gp = match->port; 57770 } 57771 57772 rv = _bcm_tr_vlan_translate_vp_add(unit, gp, 57773 bcmVlanTranslateKeyPortInner, 57774 BCM_VLAN_INVALID, 57775 match->match_inner_vlan, 57776 vp, match->action, 57777 &existing_updated); 57778 break; 57779 57780 case BCM_PORT_MATCH_PORT_VLAN16: 57781 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 57782 if (BCM_GPORT_IS_VXLAN_PORT(port) && 57783 ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) { 57784 bcm_vxlan_port_t_init(&vxlan_port); 57785 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI; 57786 vxlan_port.match_vlan = match->match_vlan; 57787 vxlan_port.vxlan_port_id = port; 57788 vxlan_port.match_port = match->port; 57789 57790 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit, 57791 &vxlan_port, vp, match->vpn)); 57792 break; 57793 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 57794 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) && 57795 ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) { 57796 bcm_mpls_port_t mpls_port; 57797 bcm_mpls_port_t_init(&mpls_port); 57798 mpls_port.criteria = BCM_MPLS_PORT_MATCH_VLAN_PRI; 57799 mpls_port.match_vlan = match->match_vlan; 57800 mpls_port.mpls_port_id = port; 57801 mpls_port.port = match->port; 57802 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit, 57803 &mpls_port, vp, match->vpn, TRUE)); 57804 break; 57805 } else if (BCM_GPORT_IS_L2GRE_PORT(port) && 57806 ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) { 57807 /* match_info translation to L2GRE_port */ 57808 bcm_l2gre_port_t_init(&l2gre_port); 57809 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_VLAN_PRI; 57810 l2gre_port.match_vlan = match->match_vlan; 57811 l2gre_port.l2gre_port_id = port; 57812 l2gre_port.match_port = match->port; 57813 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit, 57814 &l2gre_port, vp, match->vpn)); 57815 break; 57816 } 57817 #endif 57818 /* Add an entry in the VLAN_XLATE table */ 57819 /* Tag actions need to be adjusted by calling the 57820 bcm_vlan_translate_action_add API for the entry we are creating */ 57821 if (BCM_GPORT_IS_MODPORT(match->port) || 57822 BCM_GPORT_IS_TRUNK(match->port)) { 57823 /* Use the port from bcm_port_match_info_t instead of the physical 57824 port from the VP */ 57825 gp = match->port; 57826 } 57827 57828 /* allow 16 bit VLAN id */ 57829 rv = _bcm_tr_vlan_translate_vp_add(unit, gp, 57830 bcmVlanTranslateKeyPortOuterTag, 57831 match->match_vlan, 57832 BCM_VLAN_INVALID, 57833 vp, match->action, 57834 &existing_updated); 57835 if (BCM_GPORT_IS_MIM_PORT(port)) { 57836 #if defined(BCM_TRIUMPH2_SUPPORT) 57837 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 57838 #endif 57839 } else if (BCM_GPORT_IS_MPLS_PORT(port) && !existing_updated) { 57840 #if defined(BCM_MPLS_SUPPORT) 57841 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1); 57842 #endif 57843 } 57844 break; 57845 57846 57847 case BCM_PORT_MATCH_PORT_VLAN_STACKED: 57848 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 57849 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 57850 /* match_info translation to vxlan_port */ 57851 bcm_vxlan_port_t_init(&vxlan_port); 57852 VLAN_CHK_ID(unit, match->match_vlan); 57853 VLAN_CHK_ID(unit, match->match_inner_vlan); 57854 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN_STACKED; 57855 vxlan_port.match_vlan = match->match_vlan; 57856 vxlan_port.match_inner_vlan = match->match_inner_vlan; 57857 vxlan_port.vxlan_port_id = port; 57858 vxlan_port.match_port = match->port; 57859 57860 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit, 57861 &vxlan_port, vp, match->vpn)); 57862 break; 57863 } else if (BCM_GPORT_IS_MIM_PORT(port) && 57864 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57865 bcm_mim_port_t mim_port; 57866 bcm_mim_port_t_init(&mim_port); 57867 VLAN_CHK_ID(unit, match->match_vlan); 57868 VLAN_CHK_ID(unit, match->match_inner_vlan); 57869 mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN_STACKED; 57870 mim_port.match_vlan = match->match_vlan; 57871 mim_port.match_inner_vlan = match->match_inner_vlan; 57872 mim_port.mim_port_id = port; 57873 mim_port.port = match->port; 57874 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_add(unit, 57875 &mim_port, vp, match->vpn)); 57876 break; 57877 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 57878 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57879 bcm_mpls_port_t mpls_port; 57880 bcm_mpls_port_t_init(&mpls_port); 57881 VLAN_CHK_ID(unit, match->match_vlan); 57882 VLAN_CHK_ID(unit, match->match_inner_vlan); 57883 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN_STACKED; 57884 mpls_port.match_vlan = match->match_vlan; 57885 mpls_port.match_inner_vlan = match->match_inner_vlan; 57886 mpls_port.mpls_port_id = port; 57887 mpls_port.port = match->port; 57888 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit, 57889 &mpls_port, vp, match->vpn, TRUE)); 57890 break; 57891 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 57892 /* match_info translation to L2GRE_port */ 57893 bcm_l2gre_port_t_init(&l2gre_port); 57894 VLAN_CHK_ID(unit, match->match_vlan); 57895 VLAN_CHK_ID(unit, match->match_inner_vlan); 57896 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED; 57897 l2gre_port.match_vlan = match->match_vlan; 57898 l2gre_port.match_inner_vlan = match->match_inner_vlan; 57899 l2gre_port.l2gre_port_id = port; 57900 l2gre_port.match_port = match->port; 57901 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit, 57902 &l2gre_port, vp, match->vpn)); 57903 break; 57904 } 57905 #endif 57906 57907 /* Add an entry in the VLAN_XLATE table */ 57908 /* Tag actions need to be adjusted by calling the 57909 bcm_vlan_translate_action_add API for the entry we are creating */ 57910 VLAN_CHK_ID(unit, match->match_vlan); 57911 VLAN_CHK_ID(unit, match->match_inner_vlan); 57912 if (BCM_GPORT_IS_MODPORT(match->port) || 57913 BCM_GPORT_IS_TRUNK(match->port)) { 57914 /* Use the port from bcm_port_match_info_t instead of the physical 57915 port from the VP */ 57916 gp = match->port; 57917 } 57918 rv = _bcm_tr_vlan_translate_vp_add(unit, gp, 57919 bcmVlanTranslateKeyPortDouble, 57920 match->match_vlan, 57921 match->match_inner_vlan, 57922 vp, match->action, 57923 &existing_updated); 57924 if (BCM_GPORT_IS_MIM_PORT(port)) { 57925 #if defined(BCM_TRIUMPH2_SUPPORT) 57926 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 57927 #endif 57928 } else if (BCM_GPORT_IS_MPLS_PORT(port) && !existing_updated) { 57929 #if defined(BCM_MPLS_SUPPORT) 57930 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1); 57931 #endif 57932 } 57933 break; 57934 case BCM_PORT_MATCH_PORT_VLAN_RANGE: 57935 #if defined(BCM_TRIUMPH2_SUPPORT) 57936 /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */ 57937 /* Tag actions need to be adjusted by calling the 57938 bcm_vlan_translate_action_add API for the entry we are creating */ 57939 VLAN_CHK_ID(unit, match->match_vlan); 57940 VLAN_CHK_ID(unit, match->match_vlan_max); 57941 if (BCM_GPORT_IS_MODPORT(match->port) || 57942 BCM_GPORT_IS_TRUNK(match->port)) { 57943 /* Use the port from bcm_port_match_info_t instead of the physical 57944 port from the VP */ 57945 gp = match->port; 57946 } 57947 57948 rv = _bcm_tr2_vlan_translate_range_vp_add(unit, gp, 57949 match->match_vlan, 57950 match->match_vlan_max, 57951 BCM_VLAN_INVALID, 57952 BCM_VLAN_INVALID, 57953 vp, match->action); 57954 if (BCM_SUCCESS(rv)) { 57955 if (BCM_GPORT_IS_MIM_PORT(port)) { 57956 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 57957 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 57958 #if defined(BCM_MPLS_SUPPORT) 57959 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1); 57960 #endif 57961 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 57962 #if defined(BCM_TRIDENT2_SUPPORT) 57963 bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1); 57964 #endif 57965 } 57966 } 57967 #endif 57968 break; 57969 case BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE: 57970 #if defined(BCM_TRIUMPH2_SUPPORT) 57971 if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) { 57972 return BCM_E_UNAVAIL; 57973 } 57974 /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */ 57975 /* Tag actions need to be adjusted by calling the 57976 bcm_vlan_translate_action_add API for the entry we are creating */ 57977 VLAN_CHK_ID(unit, match->match_inner_vlan); 57978 VLAN_CHK_ID(unit, match->match_inner_vlan_max); 57979 if (BCM_GPORT_IS_MODPORT(match->port) || 57980 BCM_GPORT_IS_TRUNK(match->port)) { 57981 /* Use the port from bcm_port_match_info_t instead of the physical 57982 port from the VP */ 57983 gp = match->port; 57984 } 57985 57986 rv = _bcm_tr2_vlan_translate_range_vp_add(unit, gp, 57987 BCM_VLAN_INVALID, 57988 BCM_VLAN_INVALID, 57989 match->match_inner_vlan, 57990 match->match_inner_vlan_max, 57991 vp, match->action); 57992 if (BCM_SUCCESS(rv)) { 57993 if (BCM_GPORT_IS_MIM_PORT(port)) { 57994 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 57995 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 57996 #if defined(BCM_MPLS_SUPPORT) 57997 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1); 57998 #endif 57999 } 58000 } 58001 #endif 58002 break; 58003 case BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE: 58004 #if defined(BCM_TRIUMPH2_SUPPORT) 58005 if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) { 58006 return BCM_E_UNAVAIL; 58007 } 58008 /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */ 58009 /* Tag actions need to be adjusted by calling the 58010 bcm_vlan_translate_action_add API for the entry we are creating */ 58011 VLAN_CHK_ID(unit, match->match_vlan); 58012 VLAN_CHK_ID(unit, match->match_vlan_max); 58013 VLAN_CHK_ID(unit, match->match_inner_vlan); 58014 VLAN_CHK_ID(unit, match->match_inner_vlan_max); 58015 if (BCM_GPORT_IS_MODPORT(match->port) || 58016 BCM_GPORT_IS_TRUNK(match->port)) { 58017 /* Use the port from bcm_port_match_info_t instead of the physical 58018 port from the VP */ 58019 gp = match->port; 58020 } 58021 58022 rv = _bcm_tr2_vlan_translate_range_vp_add(unit, gp, 58023 match->match_vlan, 58024 match->match_vlan_max, 58025 match->match_inner_vlan, 58026 match->match_inner_vlan_max, 58027 vp, match->action); 58028 if (BCM_SUCCESS(rv)) { 58029 if (BCM_GPORT_IS_MIM_PORT(port)) { 58030 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 58031 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 58032 #if defined(BCM_MPLS_SUPPORT) 58033 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1); 58034 #endif 58035 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 58036 #if defined(BCM_TRIDENT2_SUPPORT) 58037 bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1); 58038 #endif 58039 } 58040 } 58041 #endif 58042 break; 58043 58044 #if defined(BCM_TRIUMPH3_SUPPORT) 58045 case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID: 58046 case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN: 58047 rv = _bcm_esw_extender_port_match_add(unit, match->port, 58048 match->extended_port_vid, 58049 match->match_vlan, vp); 58050 break; 58051 #endif 58052 58053 #ifdef BCM_TRIUMPH2_SUPPORT 58054 case BCM_PORT_MATCH_PORT_PON_TUNNEL: 58055 case BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN: 58056 case BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN: 58057 if (!BCM_GPORT_IS_VLAN_PORT(port)) { 58058 return BCM_E_UNAVAIL; 58059 } 58060 if (BCM_GPORT_IS_MODPORT(match->port) || 58061 BCM_GPORT_IS_TRUNK(match->port)) { 58062 if (match->port != gp) { 58063 return BCM_E_PORT; 58064 } 58065 } else if (BCM_GPORT_IS_LOCAL(match->port)) { 58066 bcm_module_t modid; 58067 bcm_trunk_t trunk_id; 58068 bcm_port_t port_num; 58069 bcm_gport_t modport; 58070 int id; 58071 58072 BCM_IF_ERROR_RETURN (_bcm_esw_gport_resolve(unit, 58073 match->port, &modid, &port_num, &trunk_id, &id)); 58074 if (trunk_id != BCM_TRUNK_INVALID) { 58075 BCM_GPORT_TRUNK_SET(modport, trunk_id); 58076 } else { 58077 BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, 58078 BCM_STK_MODMAP_GET, modid, port_num, &modid, &port_num)); 58079 BCM_GPORT_MODPORT_SET(modport, modid, port_num); 58080 } 58081 58082 if (modport != gp) { 58083 return BCM_E_PORT; 58084 } 58085 }else { 58086 return BCM_E_PORT; 58087 } 58088 58089 VLAN_CHK_ID(unit, match->match_pon_tunnel); 58090 if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL) { 58091 rv = _bcm_tr_lltag_vlan_translate_vp_add(unit, gp, bcmVlanTranslateKeyPortPonTunnel, 58092 match->match_pon_tunnel, 58093 BCM_VLAN_INVALID, 58094 vp, 58095 match->action); 58096 } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN) { 58097 VLAN_CHK_ID(unit, match->match_vlan); 58098 rv = _bcm_tr_lltag_vlan_translate_vp_add(unit, gp, bcmVlanTranslateKeyPortPonTunnelOuter, 58099 match->match_pon_tunnel, 58100 match->match_vlan, 58101 vp, 58102 match->action); 58103 } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN) { 58104 VLAN_CHK_ID(unit, match->match_inner_vlan); 58105 rv = _bcm_tr_lltag_vlan_translate_vp_add(unit, gp, bcmVlanTranslateKeyPortPonTunnelInner, 58106 match->match_pon_tunnel, 58107 match->match_inner_vlan, 58108 vp, 58109 match->action); 58110 } 58111 58112 if (BCM_FAILURE(rv)) { 58113 return rv; 58114 } 58115 58116 bcm_tr2_vlan_port_match_count_adjust(unit, vp, 1); 58117 break; 58118 #endif 58119 #if defined(BCM_TRIDENT_SUPPORT) 58120 case BCM_PORT_MATCH_PORT_NIV_PORT_VIF: 58121 case BCM_PORT_MATCH_PORT_NIV_PORT_VIF_VLAN: 58122 rv = _bcm_trident_niv_match_add(unit, match->port, 58123 match->niv_port_vif, 58124 match->match_vlan, vp); 58125 break; 58126 #endif /* BCM_TRIDENT_SUPPORT */ 58127 #if defined(BCM_TRX_SUPPORT) 58128 case BCM_PORT_MATCH_MAC_PORT: 58129 case BCM_PORT_MATCH_MAC_PORT_CLASS: 58130 bcm_vlan_match_info_t_init(&vlan_match_info); 58131 if (match->match == BCM_PORT_MATCH_MAC_PORT) { 58132 vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT; 58133 vlan_match_info.port = match->port; 58134 } else if (match->match == BCM_PORT_MATCH_MAC_PORT_CLASS) { 58135 vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT_CLASS; 58136 vlan_match_info.port_class = match->port_class; 58137 } 58138 sal_memcpy(vlan_match_info.src_mac, 58139 match->src_mac, sizeof (bcm_mac_t)); 58140 rv = _bcm_trx_vlan_match_action_add(unit, 0, 58141 port, &vlan_match_info, match->action); 58142 break; 58143 #endif 58144 default: 58145 rv = BCM_E_PARAM; 58146 break; 58147 } 58148 return rv; 58149 #else 58150 return BCM_E_UNAVAIL; 58151 #endif 58152 } 58153 58154 /* 58155 * Function: 58156 * bcm_port_match_delete 58157 * Purpose: 58158 * Remove a match from an existing port 58159 * Parameters: 58160 * unit - (IN) Unit number. 58161 * port - (IN) Port or gport 58162 * match - (IN) Match criteria 58163 * Returns: 58164 * BCM_E_xxx 58165 * Notes: 58166 */ 58167 int 58168 bcm_esw_port_match_delete( 58169 int unit, 58170 bcm_gport_t port, 58171 bcm_port_match_info_t *match) 58172 { 58173 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 58174 int vp=0, rv = BCM_E_NONE; 58175 bcm_gport_t gp = 0; 58176 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_MPLS_SUPPORT) 58177 _bcm_vp_info_t vp_info; 58178 #endif 58179 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 58180 bcm_vxlan_port_t vxlan_port; 58181 bcm_l2gre_port_t l2gre_port; 58182 #endif 58183 #if defined(BCM_TRIDENT3_SUPPORT) 58184 bcm_mirror_destination_t mirror_dest; 58185 uint32 cancun_ver; 58186 #endif /* BCM_TRIDENT3_SUPPORT */ 58187 #if defined(BCM_TRX_SUPPORT) 58188 bcm_vlan_match_info_t vlan_match_info; 58189 #endif 58190 58191 if (match == NULL) { 58192 return BCM_E_PARAM; 58193 } 58194 /* Make sure port module is initialized. */ 58195 PORT_INIT(unit); 58196 58197 if (BCM_GPORT_IS_MIM_PORT(port)) { 58198 #if defined(BCM_TRIUMPH2_SUPPORT) 58199 if (!soc_feature(unit, soc_feature_mim)) { 58200 return BCM_E_UNAVAIL; 58201 } 58202 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 58203 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 58204 return BCM_E_NOT_FOUND; 58205 } 58206 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 58207 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 58208 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_port_phys_gport_get(unit, vp, &gp)); 58209 } 58210 #endif 58211 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 58212 if (!soc_feature(unit, soc_feature_mpls)) { 58213 return BCM_E_UNAVAIL; 58214 } 58215 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 58216 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 58217 return BCM_E_NOT_FOUND; 58218 } 58219 #if defined(BCM_MPLS_SUPPORT) 58220 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 58221 if ((vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 58222 if (!soc_feature(unit, soc_feature_vp_sharing)) { 58223 return BCM_E_UNAVAIL; 58224 } 58225 } else { 58226 BCM_IF_ERROR_RETURN(bcm_tr_mpls_port_phys_gport_get(unit, vp, &gp)); 58227 } 58228 #endif 58229 } else 58230 #if defined(BCM_TRIDENT2_SUPPORT) 58231 if (BCM_GPORT_IS_TRUNK(port)) { 58232 if (!soc_feature(unit, soc_feature_vp_lag)) { 58233 return BCM_E_UNAVAIL; 58234 } 58235 BCM_IF_ERROR_RETURN( 58236 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port), 58237 &vp)); 58238 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 58239 return BCM_E_NOT_FOUND; 58240 } 58241 if (match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID && 58242 match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN) { 58243 return BCM_E_PARAM; 58244 } 58245 } else 58246 #endif /* BCM_TRIDENT2_SUPPORT */ 58247 #if defined(BCM_TRIDENT2_SUPPORT) 58248 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 58249 if (!soc_feature(unit, soc_feature_vxlan)) { 58250 return BCM_E_UNAVAIL; 58251 } 58252 if (match->match == BCM_PORT_MATCH_PORT 58253 || match->match == BCM_PORT_MATCH_MAC_PORT 58254 || match->match == BCM_PORT_MATCH_PORT_VLAN_RANGE 58255 || match->match == BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE 58256 || match->match == BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE 58257 ) { 58258 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 58259 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) { 58260 return BCM_E_NOT_FOUND; 58261 } 58262 } else { 58263 if (!soc_feature(unit, soc_feature_vp_sharing)) { 58264 return BCM_E_UNAVAIL; 58265 } 58266 58267 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 58268 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 58269 if (vp_info.vp_type != _bcmVpTypeVxlan) { 58270 return BCM_E_PARAM; 58271 } 58272 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 58273 return BCM_E_PARAM; 58274 } 58275 } 58276 } else 58277 #endif 58278 #if defined(BCM_TRIDENT2_SUPPORT) 58279 if (BCM_GPORT_IS_L2GRE_PORT(port)) { 58280 if (!soc_feature(unit, soc_feature_l2gre)) { 58281 return BCM_E_UNAVAIL; 58282 } 58283 if (match->match == BCM_PORT_MATCH_PORT) { 58284 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 58285 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre))) { 58286 return BCM_E_NOT_FOUND; 58287 } 58288 } else { 58289 if (!soc_feature(unit, soc_feature_vp_sharing)) { 58290 return BCM_E_UNAVAIL; 58291 } 58292 58293 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 58294 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 58295 58296 if (vp_info.vp_type != _bcmVpTypeL2Gre) { 58297 return BCM_E_PARAM; 58298 } 58299 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 58300 return BCM_E_PARAM; 58301 } 58302 } 58303 } else 58304 #endif 58305 58306 #if defined(BCM_TRIUMPH2_SUPPORT) 58307 if (BCM_GPORT_IS_VLAN_PORT(port)) { 58308 if ((!soc_feature(unit, soc_feature_lltag)) && 58309 (!soc_feature(unit, soc_feature_vlan_vp))) { 58310 return BCM_E_UNAVAIL; 58311 } 58312 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 58313 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan))) { 58314 return BCM_E_NOT_FOUND; 58315 } 58316 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_port_phys_gport_get(unit, vp, &gp)); 58317 } else 58318 #endif 58319 #if defined(BCM_TRIDENT_SUPPORT) 58320 if (BCM_GPORT_IS_NIV_PORT(port)) { 58321 if (!soc_feature(unit, soc_feature_niv)) { 58322 return BCM_E_UNAVAIL; 58323 } 58324 vp = BCM_GPORT_NIV_PORT_ID_GET(port); 58325 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv))) { 58326 return BCM_E_PARAM; 58327 } 58328 } else 58329 #endif /* BCM_TRIDENT_SUPPORT */ 58330 #if defined(BCM_TRIDENT3_SUPPORT) 58331 if (BCM_GPORT_IS_MIRROR(port)) { 58332 if (!soc_feature(unit, soc_feature_mirror_encap_profile)) { 58333 return BCM_E_UNAVAIL; 58334 } 58335 if ((match->match == BCM_PORT_MATCH_PORT_VLAN) || 58336 (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) || 58337 (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) { 58338 58339 SOC_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver)); 58340 if (SOC_IS_TRIDENT3(unit) && 58341 SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) { 58342 if ((match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) || 58343 (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) { 58344 LOG_ERROR(BSL_LS_BCM_PORT, 58345 (BSL_META_U(unit, 58346 "BCM_PORT_MATCH_PORT_I2E_CLASS match criteria \ 58347 not supported in Cancun 5.1.8 release\n"))); 58348 return BCM_E_UNAVAIL; 58349 } 58350 } else { 58351 if (match->match == BCM_PORT_MATCH_PORT_VLAN) { 58352 LOG_ERROR(BSL_LS_BCM_PORT, 58353 (BSL_META_U(unit, 58354 "BCM_PORT_MATCH_PORT_VLAN match criteria \ 58355 not supported after Cancun 5.1.8 release\n"))); 58356 return BCM_E_UNAVAIL; 58357 } 58358 } 58359 58360 bcm_mirror_destination_t_init(&mirror_dest); 58361 BCM_IF_ERROR_RETURN(bcm_esw_mirror_destination_get(unit, port, 58362 &mirror_dest)); 58363 if (mirror_dest.flags & BCM_MIRROR_DEST_FIELD) { 58364 return BCM_E_PARAM; 58365 } 58366 } else { 58367 return BCM_E_PARAM; 58368 } 58369 } else 58370 #endif /* BCM_TRIDENT3_SUPPORT */ 58371 { 58372 return BCM_E_PORT; 58373 } 58374 58375 switch (match->match) { 58376 case BCM_PORT_MATCH_NONE: 58377 rv = BCM_E_NONE; 58378 break; 58379 #if defined(BCM_TRIDENT2_SUPPORT) 58380 case BCM_PORT_MATCH_PORT: 58381 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 58382 bcm_vxlan_port_t_init(&vxlan_port); 58383 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT; 58384 vxlan_port.vxlan_port_id = port; 58385 vxlan_port.match_port = match->port; 58386 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0)); 58387 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 58388 #if defined(BCM_MPLS_SUPPORT) 58389 bcm_mpls_port_t mpls_port; 58390 bcm_mpls_port_t_init(&mpls_port); 58391 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT; 58392 mpls_port.mpls_port_id = port; 58393 mpls_port.port = match->port; 58394 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit, vp, &mpls_port, TRUE)); 58395 #endif 58396 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 58397 bcm_l2gre_port_t_init(&l2gre_port); 58398 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT; 58399 l2gre_port.l2gre_port_id = port; 58400 l2gre_port.match_port = match->port; 58401 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp, &l2gre_port)); 58402 } else if (BCM_GPORT_IS_VLAN_PORT(port)) { 58403 bcm_vlan_port_t vlan_port; 58404 bcm_vlan_port_t_init(&vlan_port); 58405 vlan_port.criteria = BCM_VLAN_PORT_MATCH_PORT; 58406 vlan_port.port = match->port; 58407 BCM_IF_ERROR_RETURN( 58408 bcm_tr2_vlan_vp_match_delete(unit, &vlan_port, vp)); 58409 } else { 58410 rv = BCM_E_PARAM; 58411 } 58412 break; 58413 #endif 58414 58415 case BCM_PORT_MATCH_PORT_I2E_CLASS: 58416 case BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE: 58417 #if defined(BCM_TRIDENT3_SUPPORT) 58418 if (BCM_GPORT_IS_MIRROR(port)) { 58419 rv = _bcm_mirror_port_match_delete(unit, &mirror_dest, match->port, 58420 match->match_vlan, match->match); 58421 } else 58422 #endif 58423 { 58424 rv = BCM_E_UNAVAIL; 58425 } 58426 break; 58427 58428 case BCM_PORT_MATCH_PORT_VLAN: 58429 #if defined(BCM_TRIDENT3_SUPPORT) 58430 if (BCM_GPORT_IS_MIRROR(port)) { 58431 rv = _bcm_mirror_port_match_delete(unit, &mirror_dest, match->port, 58432 match->match_vlan, match->match); 58433 break; 58434 } else 58435 #endif /* BCM_TRIDENT3_SUPPORT */ 58436 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 58437 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 58438 /* match_info translation to vxlan_port */ 58439 bcm_vxlan_port_t_init(&vxlan_port); 58440 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN; 58441 vxlan_port.match_vlan = match->match_vlan; 58442 vxlan_port.vxlan_port_id = port; 58443 vxlan_port.match_port = match->port; 58444 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0)); 58445 break; 58446 } else if (BCM_GPORT_IS_MIM_PORT(port) && 58447 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 58448 bcm_mim_port_t mim_port; 58449 bcm_mim_port_t_init(&mim_port); 58450 VLAN_CHK_ID(unit, match->match_vlan); 58451 mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN; 58452 mim_port.match_vlan = match->match_vlan; 58453 mim_port.mim_port_id = port; 58454 mim_port.port = match->port; 58455 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_delete(unit, 58456 vp, mim_port)); 58457 break; 58458 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 58459 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 58460 bcm_mpls_port_t mpls_port; 58461 bcm_mpls_port_t_init(&mpls_port); 58462 VLAN_CHK_ID(unit, match->match_vlan); 58463 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN; 58464 mpls_port.match_vlan = match->match_vlan; 58465 mpls_port.mpls_port_id = port; 58466 mpls_port.port = match->port; 58467 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit, 58468 vp, &mpls_port, 0)); 58469 break; 58470 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 58471 /* match_info translation to L2GRE_port */ 58472 bcm_l2gre_port_t_init(&l2gre_port); 58473 VLAN_CHK_ID(unit, match->match_vlan); 58474 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN; 58475 l2gre_port.match_vlan = match->match_vlan; 58476 l2gre_port.l2gre_port_id = port; 58477 l2gre_port.match_port = match->port; 58478 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit,vp, 58479 &l2gre_port)); 58480 break; 58481 } 58482 #endif 58483 58484 /* Add an entry in the VLAN_XLATE table */ 58485 /* Tag actions need to be adjusted by calling the 58486 bcm_vlan_translate_action_add API for the entry we are creating */ 58487 VLAN_CHK_ID(unit, match->match_vlan); 58488 if (BCM_GPORT_IS_MODPORT(match->port) || 58489 BCM_GPORT_IS_TRUNK(match->port)) { 58490 /* Use the port from bcm_port_match_info_t instead of the physical 58491 port from the VP */ 58492 gp = match->port; 58493 } 58494 rv = _bcm_tr_vlan_translate_vp_delete(unit, gp, 58495 bcmVlanTranslateKeyPortOuter, 58496 match->match_vlan, 58497 BCM_VLAN_INVALID, 58498 vp); 58499 58500 if (BCM_GPORT_IS_MIM_PORT(port)) { 58501 #if defined(BCM_TRIUMPH2_SUPPORT) 58502 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 58503 #endif 58504 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 58505 #if defined(BCM_MPLS_SUPPORT) 58506 bcm_tr_mpls_port_match_count_adjust(unit, vp, -1); 58507 #endif 58508 } 58509 break; 58510 58511 case BCM_PORT_MATCH_PORT_INNER_VLAN: 58512 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 58513 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 58514 bcm_vxlan_port_t_init(&vxlan_port); 58515 VLAN_CHK_ID(unit, match->match_inner_vlan); 58516 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_INNER_VLAN; 58517 vxlan_port.match_inner_vlan = match->match_inner_vlan; 58518 vxlan_port.vxlan_port_id = port; 58519 vxlan_port.match_port = match->port; 58520 58521 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0)); 58522 break; 58523 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 58524 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 58525 bcm_mpls_port_t mpls_port; 58526 bcm_mpls_port_t_init(&mpls_port); 58527 VLAN_CHK_ID(unit, match->match_inner_vlan); 58528 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_INNER_VLAN; 58529 mpls_port.match_inner_vlan = match->match_inner_vlan; 58530 mpls_port.mpls_port_id = port; 58531 mpls_port.port = match->port; 58532 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit, 58533 vp, &mpls_port, 0)); 58534 break; 58535 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 58536 /* match_info translation to L2GRE_port */ 58537 bcm_l2gre_port_t_init(&l2gre_port); 58538 VLAN_CHK_ID(unit, match->match_inner_vlan); 58539 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN; 58540 l2gre_port.match_inner_vlan = match->match_inner_vlan; 58541 l2gre_port.l2gre_port_id = port; 58542 l2gre_port.match_port = match->port; 58543 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp, 58544 &l2gre_port)); 58545 break; 58546 } 58547 #endif 58548 /* Add an entry in the VLAN_XLATE table */ 58549 /* Tag actions need to be adjusted by calling the 58550 * bcm_vlan_translate_action_add API for the entry we are creating */ 58551 VLAN_CHK_ID(unit, match->match_inner_vlan); 58552 if (BCM_GPORT_IS_MODPORT(match->port) || 58553 BCM_GPORT_IS_TRUNK(match->port)) { 58554 /* Use the port from bcm_port_match_info_t instead of the physical 58555 port from the VP */ 58556 gp = match->port; 58557 } 58558 58559 rv = _bcm_tr_vlan_translate_vp_delete(unit, gp, 58560 bcmVlanTranslateKeyPortInner, 58561 BCM_VLAN_INVALID, 58562 match->match_inner_vlan, 58563 vp); 58564 break; 58565 58566 case BCM_PORT_MATCH_PORT_VLAN16: 58567 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 58568 if (BCM_GPORT_IS_VXLAN_PORT(port) && 58569 ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) { 58570 bcm_vxlan_port_t_init(&vxlan_port); 58571 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI; 58572 vxlan_port.match_vlan = match->match_vlan; 58573 vxlan_port.vxlan_port_id = port; 58574 vxlan_port.match_port = match->port; 58575 58576 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0)); 58577 break; 58578 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 58579 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 58580 bcm_mpls_port_t mpls_port; 58581 bcm_mpls_port_t_init(&mpls_port); 58582 mpls_port.criteria = BCM_MPLS_PORT_MATCH_VLAN_PRI; 58583 mpls_port.match_vlan = match->match_vlan; 58584 mpls_port.mpls_port_id = port; 58585 mpls_port.port = match->port; 58586 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit, 58587 vp, &mpls_port, 0)); 58588 break; 58589 } else if (BCM_GPORT_IS_L2GRE_PORT(port) && 58590 ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) { 58591 /* match_info translation to L2GRE_port */ 58592 bcm_l2gre_port_t_init(&l2gre_port); 58593 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_VLAN_PRI; 58594 l2gre_port.match_vlan = match->match_vlan; 58595 l2gre_port.l2gre_port_id = port; 58596 l2gre_port.match_port = match->port; 58597 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp, 58598 &l2gre_port)); 58599 break; 58600 } 58601 #endif 58602 /* Add an entry in the VLAN_XLATE table */ 58603 /* Tag actions need to be adjusted by calling the 58604 bcm_vlan_translate_action_add API for the entry we are creating */ 58605 if (BCM_GPORT_IS_MODPORT(match->port) || 58606 BCM_GPORT_IS_TRUNK(match->port)) { 58607 /* Use the port from bcm_port_match_info_t instead of the physical 58608 port from the VP */ 58609 gp = match->port; 58610 } 58611 /* allow 16 bit VLAN id */ 58612 rv = _bcm_tr_vlan_translate_vp_delete(unit, gp, 58613 bcmVlanTranslateKeyPortOuterTag, 58614 match->match_vlan, 58615 BCM_VLAN_INVALID, 58616 vp); 58617 58618 if (BCM_GPORT_IS_MIM_PORT(port)) { 58619 #if defined(BCM_TRIUMPH2_SUPPORT) 58620 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 58621 #endif 58622 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 58623 #if defined(BCM_MPLS_SUPPORT) 58624 bcm_tr_mpls_port_match_count_adjust(unit, vp, -1); 58625 #endif 58626 } 58627 break; 58628 case BCM_PORT_MATCH_PORT_VLAN_STACKED: 58629 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 58630 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 58631 /* match_info translation to vxlan_port */ 58632 bcm_vxlan_port_t_init(&vxlan_port); 58633 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN_STACKED; 58634 vxlan_port.match_vlan = match->match_vlan; 58635 vxlan_port.match_inner_vlan = match->match_inner_vlan; 58636 vxlan_port.vxlan_port_id = port; 58637 vxlan_port.match_port = match->port; 58638 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0)); 58639 break; 58640 } else if (BCM_GPORT_IS_MIM_PORT(port) && 58641 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 58642 bcm_mim_port_t mim_port; 58643 bcm_mim_port_t_init(&mim_port); 58644 VLAN_CHK_ID(unit, match->match_vlan); 58645 VLAN_CHK_ID(unit, match->match_inner_vlan); 58646 mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN_STACKED; 58647 mim_port.match_vlan = match->match_vlan; 58648 mim_port.match_inner_vlan = match->match_inner_vlan; 58649 mim_port.mim_port_id = port; 58650 mim_port.port = match->port; 58651 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_delete(unit, 58652 vp, mim_port)); 58653 break; 58654 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 58655 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 58656 bcm_mpls_port_t mpls_port; 58657 bcm_mpls_port_t_init(&mpls_port); 58658 VLAN_CHK_ID(unit, match->match_vlan); 58659 VLAN_CHK_ID(unit, match->match_inner_vlan); 58660 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN_STACKED; 58661 mpls_port.match_vlan = match->match_vlan; 58662 mpls_port.match_inner_vlan = match->match_inner_vlan; 58663 mpls_port.mpls_port_id = port; 58664 mpls_port.port = match->port; 58665 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit, 58666 vp, &mpls_port, 0)); 58667 break; 58668 }else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 58669 /* match_info translation to L2GRE_port */ 58670 bcm_l2gre_port_t_init(&l2gre_port); 58671 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED; 58672 l2gre_port.match_vlan = match->match_vlan; 58673 l2gre_port.match_inner_vlan = match->match_inner_vlan; 58674 l2gre_port.l2gre_port_id = port; 58675 l2gre_port.match_port = match->port; 58676 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp, 58677 &l2gre_port)); 58678 break; 58679 } 58680 #endif 58681 /* Add an entry in the VLAN_XLATE table */ 58682 /* Tag actions need to be adjusted by calling the 58683 bcm_vlan_translate_action_add API for the entry we are creating */ 58684 VLAN_CHK_ID(unit, match->match_vlan); 58685 VLAN_CHK_ID(unit, match->match_inner_vlan); 58686 if (BCM_GPORT_IS_MODPORT(match->port) || 58687 BCM_GPORT_IS_TRUNK(match->port)) { 58688 /* Use the port from bcm_port_match_info_t instead of the physical 58689 port from the VP */ 58690 gp = match->port; 58691 } 58692 rv = _bcm_tr_vlan_translate_vp_delete(unit, gp, 58693 bcmVlanTranslateKeyPortDouble, 58694 match->match_vlan, 58695 match->match_inner_vlan, 58696 vp); 58697 58698 if (BCM_GPORT_IS_MIM_PORT(port)) { 58699 #if defined(BCM_TRIUMPH2_SUPPORT) 58700 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 58701 #endif 58702 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 58703 #if defined(BCM_MPLS_SUPPORT) 58704 bcm_tr_mpls_port_match_count_adjust(unit, vp, -1); 58705 #endif 58706 } 58707 break; 58708 case BCM_PORT_MATCH_PORT_VLAN_RANGE: 58709 #if defined(BCM_TRIUMPH2_SUPPORT) 58710 /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */ 58711 /* Tag actions need to be adjusted by calling the 58712 bcm_vlan_translate_action_add API for the entry we are creating */ 58713 VLAN_CHK_ID(unit, match->match_vlan); 58714 VLAN_CHK_ID(unit, match->match_vlan_max); 58715 if (BCM_GPORT_IS_MODPORT(match->port) || 58716 BCM_GPORT_IS_TRUNK(match->port)) { 58717 /* Use the port from bcm_port_match_info_t instead of the physical 58718 port from the VP */ 58719 gp = match->port; 58720 } 58721 rv = _bcm_tr2_vlan_translate_range_vp_delete(unit, gp, 58722 match->match_vlan, 58723 match->match_vlan_max, 58724 BCM_VLAN_INVALID, 58725 BCM_VLAN_INVALID, 58726 vp); 58727 if (BCM_GPORT_IS_MIM_PORT(port)) { 58728 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 58729 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 58730 #if defined(BCM_MPLS_SUPPORT) 58731 bcm_tr_mpls_port_match_count_adjust(unit, vp, -1); 58732 #endif 58733 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 58734 #if defined(BCM_TRIDENT2_SUPPORT) 58735 bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1); 58736 #endif 58737 } 58738 #endif 58739 break; 58740 case BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE: 58741 #if defined(BCM_TRIUMPH2_SUPPORT) 58742 if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) { 58743 return BCM_E_UNAVAIL; 58744 } 58745 /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */ 58746 /* Tag actions need to be adjusted by calling the 58747 bcm_vlan_translate_action_add API for the entry we are creating */ 58748 VLAN_CHK_ID(unit, match->match_inner_vlan); 58749 VLAN_CHK_ID(unit, match->match_inner_vlan_max); 58750 if (BCM_GPORT_IS_MODPORT(match->port) || 58751 BCM_GPORT_IS_TRUNK(match->port)) { 58752 /* Use the port from bcm_port_match_info_t instead of the physical 58753 port from the VP */ 58754 gp = match->port; 58755 } 58756 rv = _bcm_tr2_vlan_translate_range_vp_delete(unit, gp, 58757 BCM_VLAN_INVALID, 58758 BCM_VLAN_INVALID, 58759 match->match_inner_vlan, 58760 match->match_inner_vlan_max, 58761 vp); 58762 if (BCM_GPORT_IS_MIM_PORT(port)) { 58763 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 58764 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 58765 #if defined(BCM_MPLS_SUPPORT) 58766 bcm_tr_mpls_port_match_count_adjust(unit, vp, -1); 58767 #endif 58768 } 58769 #endif 58770 break; 58771 case BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE: 58772 #if defined(BCM_TRIUMPH2_SUPPORT) 58773 if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) { 58774 return BCM_E_UNAVAIL; 58775 } 58776 /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */ 58777 /* Tag actions need to be adjusted by calling the 58778 bcm_vlan_translate_action_add API for the entry we are creating */ 58779 VLAN_CHK_ID(unit, match->match_vlan); 58780 VLAN_CHK_ID(unit, match->match_vlan_max); 58781 VLAN_CHK_ID(unit, match->match_inner_vlan); 58782 VLAN_CHK_ID(unit, match->match_inner_vlan_max); 58783 if (BCM_GPORT_IS_MODPORT(match->port) || 58784 BCM_GPORT_IS_TRUNK(match->port)) { 58785 /* Use the port from bcm_port_match_info_t instead of the physical 58786 port from the VP */ 58787 gp = match->port; 58788 } 58789 rv = _bcm_tr2_vlan_translate_range_vp_delete(unit, gp, 58790 match->match_vlan, 58791 match->match_vlan_max, 58792 match->match_inner_vlan, 58793 match->match_inner_vlan_max, 58794 vp); 58795 if (BCM_GPORT_IS_MIM_PORT(port)) { 58796 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 58797 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 58798 #if defined(BCM_MPLS_SUPPORT) 58799 bcm_tr_mpls_port_match_count_adjust(unit, vp, -1); 58800 #endif 58801 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 58802 #if defined(BCM_TRIDENT2_SUPPORT) 58803 bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1); 58804 #endif 58805 } 58806 #endif 58807 break; 58808 58809 #if defined(BCM_TRIUMPH3_SUPPORT) 58810 case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID: 58811 case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN: 58812 rv = _bcm_esw_extender_port_match_delete(unit, match->port, 58813 match->extended_port_vid, 58814 match->match_vlan, vp); 58815 break; 58816 #endif 58817 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 58818 case BCM_PORT_MATCH_PORT_PCP_VLAN: 58819 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 58820 /* match_info translation to vxlan_port */ 58821 bcm_vxlan_port_t_init(&vxlan_port); 58822 VLAN_CHK_ID(unit, match->match_vlan); 58823 if ((match->match_vlan & 0x0fff) != 0) { 58824 return BCM_E_UNAVAIL; 58825 } 58826 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI; 58827 vxlan_port.match_vlan = (match->match_vlan & 0xf000); 58828 vxlan_port.vxlan_port_id = port; 58829 vxlan_port.match_port = match->port; 58830 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0)); 58831 break; 58832 } else { 58833 rv = BCM_E_PARAM; 58834 } 58835 break; 58836 #endif 58837 #ifdef BCM_TRIUMPH2_SUPPORT 58838 case BCM_PORT_MATCH_PORT_PON_TUNNEL: 58839 case BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN: 58840 case BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN: 58841 if (!BCM_GPORT_IS_VLAN_PORT(port)) { 58842 return BCM_E_UNAVAIL; 58843 } 58844 if (match->port != gp) { 58845 return BCM_E_PORT; 58846 } 58847 58848 VLAN_CHK_ID(unit, match->match_pon_tunnel); 58849 if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL) { 58850 rv = _bcm_tr_lltag_vlan_translate_vp_delete(unit, gp, bcmVlanTranslateKeyPortPonTunnel, 58851 match->match_pon_tunnel, 58852 BCM_VLAN_INVALID, 58853 vp); 58854 } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN) { 58855 VLAN_CHK_ID(unit, match->match_vlan); 58856 rv = _bcm_tr_lltag_vlan_translate_vp_delete(unit, gp, bcmVlanTranslateKeyPortPonTunnelOuter, 58857 match->match_pon_tunnel, 58858 match->match_vlan, 58859 vp); 58860 } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN) { 58861 VLAN_CHK_ID(unit, match->match_pon_tunnel); 58862 rv = _bcm_tr_lltag_vlan_translate_vp_delete(unit, gp, bcmVlanTranslateKeyPortPonTunnelInner, 58863 match->match_pon_tunnel, 58864 match->match_inner_vlan, 58865 vp); 58866 } 58867 58868 if (BCM_FAILURE(rv)) { 58869 return rv; 58870 } 58871 58872 bcm_tr2_vlan_port_match_count_adjust(unit, vp, -1); 58873 break; 58874 #endif 58875 #if defined(BCM_TRIDENT_SUPPORT) 58876 case BCM_PORT_MATCH_PORT_NIV_PORT_VIF: 58877 case BCM_PORT_MATCH_PORT_NIV_PORT_VIF_VLAN: 58878 rv = _bcm_trident_niv_match_delete(unit, match->port, 58879 match->niv_port_vif, 58880 match->match_vlan, NULL); 58881 break; 58882 #endif /* BCM_TRIDENT_SUPPORT */ 58883 #if defined(BCM_TRX_SUPPORT) 58884 case BCM_PORT_MATCH_MAC_PORT: 58885 case BCM_PORT_MATCH_MAC_PORT_CLASS: 58886 bcm_vlan_match_info_t_init(&vlan_match_info); 58887 if (match->match == BCM_PORT_MATCH_MAC_PORT) { 58888 vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT; 58889 vlan_match_info.port = match->port; 58890 } else if (match->match == BCM_PORT_MATCH_MAC_PORT_CLASS) { 58891 vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT_CLASS; 58892 vlan_match_info.port_class = match->port_class; 58893 } 58894 sal_memcpy(vlan_match_info.src_mac, 58895 match->src_mac, sizeof (bcm_mac_t)); 58896 rv = _bcm_trx_vlan_match_action_delete(unit, 58897 port, &vlan_match_info); 58898 break; 58899 #endif 58900 default: 58901 rv = BCM_E_PARAM; 58902 break; 58903 } 58904 return rv; 58905 #else 58906 return BCM_E_UNAVAIL; 58907 #endif 58908 } 58909 58910 /* 58911 * Function: 58912 * bcm_port_match_replace 58913 * Purpose: 58914 * Replace an old match with a new one for an existing port 58915 * Parameters: 58916 * unit - (IN) Unit number. 58917 * port - (IN) Port or gport 58918 * old_match - (IN) Old match criteria 58919 * new_match - (IN) New match criteria 58920 * Returns: 58921 * BCM_E_xxx 58922 * Notes: 58923 */ 58924 int 58925 bcm_esw_port_match_replace( 58926 int unit, 58927 bcm_gport_t port, 58928 bcm_port_match_info_t *old_match, 58929 bcm_port_match_info_t *new_match) 58930 { 58931 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 58932 int rv = BCM_E_NONE; 58933 /* Make sure port module is initialized. */ 58934 PORT_INIT(unit); 58935 rv = bcm_esw_port_match_delete(unit, port, old_match); 58936 if (BCM_SUCCESS(rv)) { 58937 rv = bcm_esw_port_match_add(unit, port, new_match); 58938 } 58939 return rv; 58940 #else 58941 return BCM_E_UNAVAIL; 58942 #endif 58943 } 58944 58945 extern void 58946 _bcm_trx_vlan_range_profile_entry_get(int unit, bcm_vlan_t *min_vlan, 58947 bcm_vlan_t *max_vlan, uint32 index); 58948 58949 int _bcm_esw_port_vp_gport_check(bcm_gport_t port, 58950 int vp) 58951 { 58952 int matched = 0; 58953 if (BCM_GPORT_IS_MIM_PORT(port)) { 58954 if (vp == BCM_GPORT_MIM_PORT_ID_GET(port)) { 58955 matched = 1; 58956 } 58957 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 58958 if (vp == BCM_GPORT_MPLS_PORT_ID_GET(port)) { 58959 matched = 1; 58960 } 58961 } 58962 #if defined(BCM_TRIDENT2_SUPPORT) 58963 else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 58964 if (vp == BCM_GPORT_VXLAN_PORT_ID_GET(port)) { 58965 matched = 1; 58966 } 58967 } 58968 #endif 58969 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 58970 else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 58971 if (vp == BCM_GPORT_L2GRE_PORT_ID_GET(port)) { 58972 matched = 1; 58973 } 58974 } 58975 #endif 58976 #if defined(BCM_TRIUMPH2_SUPPORT) 58977 else if(BCM_GPORT_IS_VLAN_PORT(port)) { 58978 if (vp == BCM_GPORT_VLAN_PORT_ID_GET(port)) { 58979 matched = 1; 58980 } 58981 } 58982 #endif 58983 return matched; 58984 } 58985 /* 58986 * Function: 58987 * bcm_port_match_multi_get 58988 * Purpose: 58989 * Get all the matches for an existing port 58990 * Parameters: 58991 * unit - (IN) Unit number. 58992 * port - (IN) Port or gport 58993 * size - (IN) Number of elements in match array 58994 * match_array - (OUT) Match array 58995 * count - (OUT) Match count 58996 * Returns: 58997 * BCM_E_xxx 58998 * Notes: 58999 */ 59000 int 59001 bcm_esw_port_match_multi_get( 59002 int unit, 59003 bcm_gport_t port, 59004 int size, 59005 bcm_port_match_info_t *match_array, 59006 int *count) 59007 { 59008 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 59009 int id, vp, prof_idx, i, j, index_min, index_max, ctr, rv = BCM_E_NONE; 59010 int stm_idx = 0; 59011 int key_type_value = 0, key_type = 0; 59012 uint32 matched; 59013 uint8 *vlan_xlate_buf = NULL; /* VLAN_XLATE DMA buffer */ 59014 uint8 *source_trunk_map_buf = NULL; /* SOURCE_TRUNK_MAP DMA buffer */ 59015 source_trunk_map_table_entry_t *source_trunk_map; 59016 bcm_gport_t gp; 59017 bcm_vlan_t min_vlan[8], max_vlan[8]; 59018 bcm_module_t mod_out, mod_in; 59019 bcm_port_t port_out, port_in; 59020 bcm_trunk_t trunk_id; 59021 int mpls_action; 59022 soc_mem_t mem; 59023 #if defined(BCM_TRIUMPH3_SUPPORT) 59024 vlan_xlate_entry_t vent; 59025 #endif 59026 bcm_vlan_action_set_t *action; 59027 int profile_idx; 59028 void *entry; 59029 59030 bcm_trunk_member_t *member_array = NULL; 59031 59032 /* Parameter checks */ 59033 if ((size < 0) || (count == NULL)) { 59034 return BCM_E_PARAM; 59035 } 59036 if ((size > 0) && (match_array == NULL)) { 59037 return BCM_E_PARAM; 59038 } 59039 59040 /* Make sure port module is initialized. */ 59041 PORT_INIT(unit); 59042 59043 if (BCM_GPORT_IS_MIM_PORT(port)) { 59044 if (!soc_feature(unit, soc_feature_mim)) { 59045 return BCM_E_UNAVAIL; 59046 } 59047 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 59048 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 59049 return BCM_E_NOT_FOUND; 59050 } 59051 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_port_phys_gport_get(unit, vp, &gp)); 59052 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 59053 if (!soc_feature(unit, soc_feature_mpls)) { 59054 return BCM_E_UNAVAIL; 59055 } 59056 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 59057 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 59058 return BCM_E_NOT_FOUND; 59059 } 59060 #if defined(BCM_MPLS_SUPPORT) 59061 BCM_IF_ERROR_RETURN(bcm_tr_mpls_port_phys_gport_get(unit, vp, &gp)); 59062 #endif 59063 59064 } else 59065 #if defined(BCM_TRIDENT2_SUPPORT) 59066 if (BCM_GPORT_IS_TRUNK(port)) { 59067 if (!soc_feature(unit, soc_feature_vp_lag)) { 59068 return BCM_E_UNAVAIL; 59069 } 59070 return _bcm_esw_trunk_match_multi_get(unit, BCM_GPORT_TRUNK_GET(port), 59071 size, match_array, count); 59072 } else 59073 #endif /* BCM_TRIDENT2_SUPPORT */ 59074 #if defined(BCM_TRIDENT2_SUPPORT) 59075 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 59076 59077 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 59078 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) { 59079 return BCM_E_NOT_FOUND; 59080 } 59081 59082 BCM_GPORT_VXLAN_PORT_ID_SET(gp,vp); 59083 } else 59084 #endif 59085 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 59086 if (BCM_GPORT_IS_L2GRE_PORT(port)) { 59087 _bcm_vp_info_t vp_info; 59088 59089 if (!soc_feature(unit, soc_feature_vp_sharing)) { 59090 return BCM_E_UNAVAIL; 59091 } 59092 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 59093 59094 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 59095 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 59096 return BCM_E_NOT_FOUND; 59097 } 59098 59099 BCM_GPORT_L2GRE_PORT_ID_SET(gp,vp); 59100 } else 59101 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 59102 #if defined(BCM_TRIUMPH2_SUPPORT) 59103 if (BCM_GPORT_IS_VLAN_PORT(port)) { 59104 if (!soc_feature(unit, soc_feature_lltag)) { 59105 return BCM_E_UNAVAIL; 59106 } 59107 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 59108 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 59109 return BCM_E_NOT_FOUND; 59110 } 59111 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_port_phys_gport_get(unit, vp, &gp)); 59112 } else 59113 #endif 59114 #if defined(BCM_TRIDENT_SUPPORT) 59115 if (BCM_GPORT_IS_NIV_PORT(port)) { 59116 if (!soc_feature(unit, soc_feature_niv)) { 59117 return BCM_E_UNAVAIL; 59118 } 59119 return _bcm_td_port_vif_match_multi_get(unit, port, 59120 size, match_array, count); 59121 } else 59122 #endif /* BCM_TRIDENT_SUPPORT */ 59123 #if defined(BCM_TRIDENT3_SUPPORT) 59124 if (BCM_GPORT_IS_MIRROR(port)) { 59125 if (!soc_feature(unit, soc_feature_mirror_encap_profile)) { 59126 return BCM_E_UNAVAIL; 59127 } 59128 return _bcm_mirror_port_match_multi_get(unit, port, size, match_array, 59129 count); 59130 } else 59131 #endif /* BCM_TRIDENT3_SUPPORT */ 59132 { 59133 return BCM_E_PORT; 59134 } 59135 59136 rv = _bcm_esw_gport_resolve(unit, gp, &mod_out, &port_out, &trunk_id, &id); 59137 if (BCM_FAILURE(rv)) { 59138 goto cleanup; 59139 } 59140 #if defined(BCM_TRIUMPH3_SUPPORT) 59141 if (SOC_IS_TRIUMPH3(unit)) { 59142 mem = VLAN_XLATE_EXTDm; 59143 } else 59144 #endif 59145 #if defined(BCM_TRIDENT3_SUPPORT) 59146 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 59147 mem = VLAN_XLATE_1_DOUBLEm; 59148 } else 59149 #endif 59150 { 59151 mem = VLAN_XLATEm; 59152 } 59153 59154 /* DMA the relevant tables for traversal */ 59155 vlan_xlate_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem), 59156 "VLAN_XLATE buffer"); 59157 if (NULL == vlan_xlate_buf) { 59158 rv = BCM_E_MEMORY; 59159 goto cleanup; 59160 } 59161 59162 index_min = soc_mem_index_min(unit, mem); 59163 index_max = soc_mem_index_max(unit, mem); 59164 if ((rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 59165 index_min, index_max, 59166 vlan_xlate_buf)) < 0 ) { 59167 goto cleanup; 59168 } 59169 source_trunk_map_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES 59170 (unit, SOURCE_TRUNK_MAP_TABLEm), 59171 "SOURCE_TRUNK_MAP_TABLE buffer"); 59172 if (NULL == source_trunk_map_buf) { 59173 rv = BCM_E_MEMORY; 59174 goto cleanup; 59175 } 59176 index_min = soc_mem_index_min(unit, SOURCE_TRUNK_MAP_TABLEm); 59177 index_max = soc_mem_index_max(unit, SOURCE_TRUNK_MAP_TABLEm); 59178 if ((rv = soc_mem_read_range(unit, SOURCE_TRUNK_MAP_TABLEm, MEM_BLOCK_ANY, 59179 index_min, index_max, 59180 source_trunk_map_buf)) < 0 ) { 59181 goto cleanup; 59182 } 59183 59184 ctr = 0; 59185 /* Get all VLAN_XLATE matches */ 59186 index_min = soc_mem_index_min(unit, mem); 59187 index_max = soc_mem_index_max(unit, mem); 59188 for (i = index_min; i <= index_max; i++) { 59189 if ((size != 0) && (size <= ctr)) { 59190 break; 59191 } 59192 if (SOC_IS_TRIUMPH3(unit)) { 59193 mem = VLAN_XLATE_EXTDm; 59194 } 59195 entry = soc_mem_table_idx_to_pointer 59196 (unit, mem, void *, vlan_xlate_buf, i); 59197 #if defined(BCM_TRIUMPH3_SUPPORT) 59198 if (SOC_IS_TRIUMPH3(unit)) { 59199 int key_type; 59200 59201 /* double wide entry should always start at double wide boundary */ 59202 key_type = soc_mem_field32_get(unit, mem, entry, KEY_TYPE_0f); 59203 59204 /* if key type is odd number, then it is double wide entry */ 59205 if (!(key_type & 1)) { 59206 continue; 59207 } 59208 mpls_action = soc_mem_field32_get(unit, mem, entry, MPLS_ACTIONf); 59209 vp = soc_mem_field32_get(unit, mem, entry, SOURCE_VPf); 59210 sal_memset(&vent, 0, sizeof(vent)); 59211 rv = _bcm_tr3_vxlate_extd2vxlate(unit, (vlan_xlate_extd_entry_t *)entry, &vent, 0); 59212 if (rv != BCM_E_NONE) { 59213 goto cleanup; 59214 } 59215 entry = &vent; 59216 mem = VLAN_XLATEm; 59217 } else 59218 #endif /* BCM_TRIUMPH3_SUPPORT */ 59219 { 59220 mpls_action = soc_mem_field32_get(unit, mem, entry, MPLS_ACTIONf); 59221 vp = soc_mem_field32_get(unit, mem, entry, SOURCE_VPf); 59222 } 59223 59224 #if defined(BCM_TRIDENT3_SUPPORT) 59225 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 59226 if (soc_mem_field32_get(unit, mem, entry, BASE_VALID_0f) != 3) { 59227 continue; 59228 } 59229 if (soc_mem_field32_get(unit, mem, entry, BASE_VALID_1f) != 7) { 59230 continue; 59231 } 59232 } 59233 #endif 59234 59235 if (SOC_MEM_FIELD_VALID(unit, mem, VALIDf)) { 59236 if (soc_mem_field32_get(unit, mem, entry, VALIDf) == 0) { 59237 continue; 59238 } 59239 } 59240 59241 if (!(mpls_action & 0x1)) { 59242 continue; /* Entry is not for an SVP */ 59243 } 59244 59245 key_type_value = (int)soc_mem_field32_get(unit, mem, entry, KEY_TYPEf); 59246 59247 rv = _bcm_esw_vlan_xlate_key_type_get(unit,key_type_value,&key_type); 59248 if (rv != BCM_E_NONE) { 59249 goto cleanup; 59250 } 59251 59252 matched = _bcm_esw_port_vp_gport_check(port, vp); 59253 59254 if (matched) { 59255 soc_field_t field; 59256 int port_count; 59257 int tid; 59258 int gport_id; 59259 int outer_vlan_range_found = 0, inner_vlan_range_found = 0; 59260 ctr++; 59261 if (size >= ctr) { 59262 switch (key_type) { 59263 case VLXLT_HASH_KEY_TYPE_OVID: 59264 match_array->match = BCM_PORT_MATCH_PORT_VLAN; 59265 match_array->match_vlan = 59266 soc_mem_field32_get(unit, mem, entry, XLATE__OVIDf); 59267 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 59268 if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) { 59269 if (soc_feature(unit, soc_feature_vfi_zero_invalid) && 59270 (soc_mem_field32_get(unit, mem, entry, XLATE__VFIf)) == 0) { 59271 match_array->vpn = 0; 59272 } else { 59273 _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI, 59274 soc_mem_field32_get(unit, mem, entry, XLATE__VFIf)); 59275 } 59276 } else { 59277 match_array->vpn = 0; 59278 } 59279 #endif 59280 /* Check if this match is a VLAN range match */ 59281 if (BCM_TRUNK_INVALID != trunk_id) { 59282 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, 59283 &port_count); 59284 if (BCM_FAILURE(rv)) { 59285 goto cleanup; 59286 } 59287 59288 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count, 59289 "trunk member array"); 59290 if (member_array == NULL) { 59291 rv = BCM_E_MEMORY; 59292 goto cleanup; 59293 } 59294 sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count); 59295 59296 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count, 59297 member_array, &port_count); 59298 if (BCM_FAILURE(rv)) { 59299 goto cleanup; 59300 } 59301 59302 rv = _bcm_esw_gport_resolve(unit, member_array[0].gport, 59303 &mod_out, &port_out, &tid, &gport_id); 59304 if (BCM_FAILURE(rv)) { 59305 goto cleanup; 59306 } 59307 59308 } 59309 rv = _bcm_esw_src_mod_port_table_index_get( 59310 unit, mod_out, port_out, &stm_idx); 59311 if (BCM_FAILURE(rv)) { 59312 goto cleanup; 59313 } 59314 59315 source_trunk_map = soc_mem_table_idx_to_pointer 59316 (unit, SOURCE_TRUNK_MAP_TABLEm, 59317 source_trunk_map_table_entry_t *, 59318 source_trunk_map_buf, stm_idx); 59319 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 59320 OUTER_VLAN_RANGE_IDXf)) { 59321 field = OUTER_VLAN_RANGE_IDXf; 59322 } else { 59323 field = VLAN_RANGE_IDXf; 59324 } 59325 prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, 59326 source_trunk_map, field); 59327 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, 59328 max_vlan, prof_idx); 59329 for (j = 0; j < 8; j++) { 59330 if (min_vlan[j] == match_array->match_vlan) { 59331 match_array->match_vlan_max = max_vlan[j]; 59332 match_array->match = 59333 BCM_PORT_MATCH_PORT_VLAN_RANGE; 59334 break; /* Found a VLAN range match */ 59335 } 59336 } 59337 if (j == 8) { 59338 match_array->match = BCM_PORT_MATCH_PORT_VLAN; 59339 } 59340 if (soc_mem_field32_get(unit, mem, entry, XLATE__Tf)) { 59341 trunk_id = soc_mem_field32_get(unit, mem, entry, XLATE__TGIDf); 59342 BCM_GPORT_TRUNK_SET(gp, trunk_id); 59343 } else { 59344 mod_in = soc_mem_field32_get(unit, mem, entry, XLATE__MODULE_IDf); 59345 port_in = soc_mem_field32_get(unit, mem, entry, XLATE__PORT_NUMf); 59346 59347 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 59348 mod_in, port_in, &mod_out, &port_out); 59349 BCM_GPORT_MODPORT_SET(gp, mod_out, port_out); 59350 } 59351 match_array->port = gp; 59352 match_array++; 59353 break; 59354 case VLXLT_HASH_KEY_TYPE_IVID: 59355 match_array->match = BCM_PORT_MATCH_PORT_INNER_VLAN; 59356 match_array->match_inner_vlan = 59357 soc_mem_field32_get(unit, mem, entry, XLATE__IVIDf); 59358 59359 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 59360 if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) { 59361 if (soc_feature(unit, soc_feature_vfi_zero_invalid) && 59362 (soc_mem_field32_get(unit, mem, entry, XLATE__VFIf) == 0)) { 59363 59364 match_array->vpn = 0; 59365 } else { 59366 _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI, 59367 soc_mem_field32_get(unit, mem, entry, XLATE__VFIf)); 59368 59369 } 59370 } else { 59371 match_array->vpn = 0; 59372 } 59373 #endif 59374 /* Check if this match is a VLAN range match */ 59375 if (BCM_TRUNK_INVALID != trunk_id) { 59376 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, 59377 &port_count); 59378 if (BCM_FAILURE(rv)) { 59379 goto cleanup; 59380 } 59381 59382 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count, 59383 "trunk member array"); 59384 if (member_array == NULL) { 59385 rv = BCM_E_MEMORY; 59386 goto cleanup; 59387 } 59388 sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count); 59389 59390 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count, 59391 member_array, &port_count); 59392 if (BCM_FAILURE(rv)) { 59393 goto cleanup; 59394 } 59395 59396 rv = _bcm_esw_gport_resolve(unit, member_array[0].gport, 59397 &mod_out, &port_out, &tid, &gport_id); 59398 if (BCM_FAILURE(rv)) { 59399 goto cleanup; 59400 } 59401 59402 } 59403 59404 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 59405 INNER_VLAN_RANGE_IDXf)) { 59406 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 59407 if (soc_feature(unit, soc_feature_src_modid_base_index)) { 59408 int is_local; 59409 bcm_module_t modid = mod_out; 59410 59411 rv = _bcm_esw_stk_modmap_map( 59412 unit, BCM_STK_MODMAP_SET, modid, -1, 59413 &mod_out, NULL); 59414 if (BCM_SUCCESS(rv)) { 59415 rv = _bcm_esw_modid_is_local(unit, mod_out, 59416 &is_local); 59417 } 59418 if (BCM_SUCCESS(rv)) { 59419 rv = _bcm_esw_src_modid_base_index_get( 59420 unit, modid, is_local, &stm_idx); 59421 } 59422 if (BCM_FAILURE(rv)) { 59423 goto cleanup; 59424 } 59425 stm_idx += port_out; 59426 } else 59427 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */ 59428 { 59429 stm_idx = (mod_out * (SOC_PORT_ADDR_MAX(unit) + 1)) 59430 + port_out; 59431 } 59432 source_trunk_map = 59433 soc_mem_table_idx_to_pointer(unit, SOURCE_TRUNK_MAP_TABLEm, 59434 source_trunk_map_table_entry_t *, 59435 source_trunk_map_buf, 59436 stm_idx); 59437 field = INNER_VLAN_RANGE_IDXf; 59438 prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, 59439 source_trunk_map, field); 59440 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, 59441 max_vlan, prof_idx); 59442 for (j = 0; j < 8; j++) { 59443 if (min_vlan[j] == match_array->match_inner_vlan) { 59444 match_array->match_inner_vlan_max = max_vlan[j]; 59445 match_array->match = 59446 BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE; 59447 break; /* Found a VLAN range match */ 59448 } 59449 } 59450 } 59451 if (soc_mem_field32_get(unit, mem, entry, XLATE__Tf)) { 59452 trunk_id = soc_mem_field32_get(unit, mem, entry, XLATE__TGIDf); 59453 BCM_GPORT_TRUNK_SET(gp, trunk_id); 59454 } else { 59455 mod_in = soc_mem_field32_get(unit, mem, entry, XLATE__MODULE_IDf); 59456 port_in = soc_mem_field32_get(unit, mem, entry, XLATE__PORT_NUMf); 59457 59458 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 59459 mod_in, port_in, &mod_out, &port_out); 59460 BCM_GPORT_MODPORT_SET(gp, mod_out, port_out); 59461 } 59462 match_array->port = gp; 59463 match_array++; 59464 break; 59465 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 59466 match_array->match = BCM_PORT_MATCH_PORT_VLAN16; 59467 match_array->match_vlan = 59468 soc_mem_field32_get(unit, mem, entry, OTAGf); 59469 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 59470 if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) { 59471 if (soc_feature(unit, soc_feature_vfi_zero_invalid) && 59472 (soc_mem_field32_get(unit, mem, entry, VFIf) == 0)) { 59473 match_array->vpn = 0; 59474 } else { 59475 _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI, 59476 soc_mem_field32_get(unit, mem, entry, VFIf)); 59477 } 59478 } else { 59479 match_array->vpn = 0; 59480 } 59481 #endif 59482 if (soc_mem_field32_get(unit, mem, entry, Tf)) { 59483 trunk_id = soc_mem_field32_get(unit, mem, entry, TGIDf); 59484 BCM_GPORT_TRUNK_SET(gp, trunk_id); 59485 } else { 59486 mod_in = soc_mem_field32_get(unit, mem, entry, MODULE_IDf); 59487 port_in = soc_mem_field32_get(unit, mem, entry, PORT_NUMf); 59488 59489 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 59490 mod_in, port_in, &mod_out, &port_out); 59491 BCM_GPORT_MODPORT_SET(gp, mod_out, port_out); 59492 } 59493 match_array->port = gp; 59494 match_array++; 59495 break; 59496 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 59497 match_array->match = BCM_PORT_MATCH_PORT_VLAN_STACKED; 59498 match_array->match_vlan = 59499 soc_mem_field32_get(unit, mem, entry, OVIDf); 59500 match_array->match_inner_vlan = 59501 soc_mem_field32_get(unit, mem, entry, IVIDf); 59502 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 59503 if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) { 59504 if (soc_feature(unit, soc_feature_vfi_zero_invalid) && 59505 (soc_mem_field32_get(unit, mem, entry, VFIf) == 0)) { 59506 match_array->vpn = 0; 59507 } else { 59508 _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI, 59509 soc_mem_field32_get(unit, mem, entry, VFIf)); 59510 } 59511 } else { 59512 match_array->vpn = 0; 59513 } 59514 #endif 59515 59516 /* Check if this match is a VLAN range match */ 59517 if (BCM_TRUNK_INVALID != trunk_id) { 59518 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, 59519 &port_count); 59520 if (BCM_FAILURE(rv)) { 59521 goto cleanup; 59522 } 59523 59524 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count, 59525 "trunk member array"); 59526 if (member_array == NULL) { 59527 rv = BCM_E_MEMORY; 59528 goto cleanup; 59529 } 59530 sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count); 59531 59532 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count, 59533 member_array, &port_count); 59534 if (BCM_FAILURE(rv)) { 59535 goto cleanup; 59536 } 59537 59538 rv = _bcm_esw_gport_resolve(unit, member_array[0].gport, 59539 &mod_out, &port_out, &tid, &gport_id); 59540 if (BCM_FAILURE(rv)) { 59541 goto cleanup; 59542 } 59543 59544 } 59545 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 59546 OUTER_VLAN_RANGE_IDXf)) { 59547 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 59548 if (soc_feature(unit, soc_feature_src_modid_base_index)) { 59549 int is_local; 59550 bcm_module_t modid = mod_out; 59551 59552 rv = _bcm_esw_stk_modmap_map( 59553 unit, BCM_STK_MODMAP_SET, modid, -1, 59554 &mod_out, NULL); 59555 if (BCM_SUCCESS(rv)) { 59556 rv = _bcm_esw_modid_is_local(unit, mod_out, 59557 &is_local); 59558 } 59559 if (BCM_SUCCESS(rv)) { 59560 rv = _bcm_esw_src_modid_base_index_get( 59561 unit, modid, is_local, &stm_idx); 59562 } 59563 if (BCM_FAILURE(rv)) { 59564 goto cleanup; 59565 } 59566 stm_idx += port_out; 59567 } else 59568 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */ 59569 { 59570 stm_idx = (mod_out * (SOC_PORT_ADDR_MAX(unit) + 1)) 59571 + port_out; 59572 } 59573 source_trunk_map = 59574 soc_mem_table_idx_to_pointer(unit, SOURCE_TRUNK_MAP_TABLEm, 59575 source_trunk_map_table_entry_t *, 59576 source_trunk_map_buf, 59577 stm_idx); 59578 field = OUTER_VLAN_RANGE_IDXf; 59579 prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, 59580 source_trunk_map, field); 59581 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, 59582 max_vlan, prof_idx); 59583 for (j = 0; j < 8; j++) { 59584 if (min_vlan[j] == match_array->match_vlan) { 59585 match_array->match_vlan_max = max_vlan[j]; 59586 outer_vlan_range_found = 1; 59587 break; /* Found a VLAN range match */ 59588 } 59589 } 59590 } 59591 59592 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 59593 INNER_VLAN_RANGE_IDXf)) { 59594 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 59595 if (soc_feature(unit, soc_feature_src_modid_base_index)) { 59596 int is_local; 59597 bcm_module_t modid = mod_out; 59598 59599 rv = _bcm_esw_stk_modmap_map( 59600 unit, BCM_STK_MODMAP_SET, modid, -1, 59601 &mod_out, NULL); 59602 if (BCM_SUCCESS(rv)) { 59603 rv = _bcm_esw_modid_is_local(unit, mod_out, 59604 &is_local); 59605 } 59606 if (BCM_SUCCESS(rv)) { 59607 rv = _bcm_esw_src_modid_base_index_get( 59608 unit, modid, is_local, &stm_idx); 59609 } 59610 if (BCM_FAILURE(rv)) { 59611 goto cleanup; 59612 } 59613 stm_idx += port_out; 59614 } else 59615 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */ 59616 { 59617 stm_idx = (mod_out * (SOC_PORT_ADDR_MAX(unit) + 1)) 59618 + port_out; 59619 } 59620 source_trunk_map = 59621 soc_mem_table_idx_to_pointer(unit, SOURCE_TRUNK_MAP_TABLEm, 59622 source_trunk_map_table_entry_t *, 59623 source_trunk_map_buf, 59624 stm_idx); 59625 field = INNER_VLAN_RANGE_IDXf; 59626 prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, 59627 source_trunk_map, field); 59628 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, 59629 max_vlan, prof_idx); 59630 for (j = 0; j < 8; j++) { 59631 if (min_vlan[j] == match_array->match_inner_vlan) { 59632 match_array->match_inner_vlan_max = max_vlan[j]; 59633 inner_vlan_range_found = 1; 59634 break; /* Found a VLAN range match */ 59635 } 59636 } 59637 } 59638 if (inner_vlan_range_found && outer_vlan_range_found) { 59639 match_array->match = BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE; 59640 } 59641 59642 if (soc_mem_field32_get(unit, mem, entry, Tf)) { 59643 trunk_id = soc_mem_field32_get(unit, mem, entry, TGIDf); 59644 BCM_GPORT_TRUNK_SET(gp, trunk_id); 59645 } else { 59646 mod_in = soc_mem_field32_get(unit, mem, entry, MODULE_IDf); 59647 port_in = soc_mem_field32_get(unit, mem, entry, PORT_NUMf); 59648 59649 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 59650 mod_in, port_in, &mod_out, &port_out); 59651 BCM_GPORT_MODPORT_SET(gp, mod_out, port_out); 59652 } 59653 match_array->port = gp; 59654 match_array++; 59655 break; 59656 #if defined (BCM_TRIUMPH2_SUPPORT) 59657 case VLXLT_HASH_KEY_TYPE_LLVID: 59658 case VLXLT_HASH_KEY_TYPE_LLVID_OVID: 59659 case VLXLT_HASK_KEY_TYPE_LLVID_IVID: 59660 if (key_type == VLXLT_HASH_KEY_TYPE_LLVID) { 59661 match_array->match = BCM_PORT_MATCH_PORT_PON_TUNNEL; 59662 } else if (key_type == VLXLT_HASH_KEY_TYPE_LLVID_OVID) { 59663 match_array->match = BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN; 59664 } else { 59665 match_array->match = BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN; 59666 } 59667 59668 match_array->match_pon_tunnel = 59669 soc_mem_field32_get(unit, mem, entry, LLTAG__LLVIDf); 59670 match_array->match_inner_vlan = 59671 soc_mem_field32_get(unit, mem, entry, LLTAG__IVIDf); 59672 match_array->match_vlan = 59673 soc_mem_field32_get(unit, mem, entry, LLTAG__OVIDf); 59674 59675 if (soc_mem_field32_get(unit, mem, entry, Tf)) { 59676 trunk_id = soc_mem_field32_get(unit, mem, entry, TGIDf); 59677 BCM_GPORT_TRUNK_SET(gp, trunk_id); 59678 } else { 59679 mod_in = soc_mem_field32_get(unit, mem, entry, MODULE_IDf); 59680 port_in = soc_mem_field32_get(unit, mem, entry, PORT_NUMf); 59681 59682 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 59683 mod_in, port_in, &mod_out, &port_out); 59684 BCM_GPORT_MODPORT_SET(gp, mod_out, port_out); 59685 } 59686 59687 if (match_array->action != NULL) { 59688 action = match_array->action; 59689 action->new_outer_vlan = 59690 soc_mem_field32_get(unit, mem, entry, NEW_OVIDf); 59691 action->new_inner_vlan = 59692 soc_mem_field32_get(unit, mem, entry, NEW_IVIDf); 59693 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 59694 action->priority = 59695 soc_mem_field32_get(unit, mem, entry, NEW_OPRIf); 59696 action->new_outer_cfi = 59697 soc_mem_field32_get(unit, mem, entry, NEW_OCFIf); 59698 action->new_inner_pkt_prio = 59699 soc_mem_field32_get(unit, mem, entry, NEW_IPRIf); 59700 action->new_inner_cfi = 59701 soc_mem_field32_get(unit, mem, entry, NEW_ICFIf); 59702 } 59703 profile_idx = soc_mem_field32_get(unit, mem, entry, TAG_ACTION_PROFILE_PTRf); 59704 _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx); 59705 } 59706 match_array->port = gp; 59707 match_array++; 59708 break; 59709 #endif 59710 default: 59711 break; 59712 } 59713 } 59714 } 59715 } 59716 59717 #if defined(BCM_TRX_SUPPORT) 59718 /* Get the list from VLAN_MACm */ 59719 if (BCM_SUCCESS(rv)) { 59720 rv = _bcm_vlan_match_action_multi_get(unit, 59721 port, size, match_array, ctr, &ctr); 59722 } 59723 #endif 59724 59725 *count = ctr; 59726 59727 cleanup: 59728 if (vlan_xlate_buf) { 59729 soc_cm_sfree(unit, vlan_xlate_buf); 59730 } 59731 if (source_trunk_map_buf) { 59732 soc_cm_sfree(unit, source_trunk_map_buf); 59733 } 59734 if (member_array) { 59735 sal_free(member_array); 59736 } 59737 return rv; 59738 #else 59739 return BCM_E_UNAVAIL; 59740 #endif 59741 } 59742 59743 /* 59744 * Function: 59745 * bcm_port_match_set 59746 * Purpose: 59747 * Assign a set of matches to an existing port 59748 * Parameters: 59749 * unit - (IN) Unit number. 59750 * port - (IN) Port or gport 59751 * size - (IN) Number of elements in match array 59752 * match_array - (IN) Match array 59753 * Returns: 59754 * BCM_E_xxx 59755 * Notes: 59756 */ 59757 int 59758 bcm_esw_port_match_set( 59759 int unit, 59760 bcm_gport_t port, 59761 int size, 59762 bcm_port_match_info_t *match_array) 59763 { 59764 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 59765 int i, rv = BCM_E_NONE; 59766 if ((size <= 0) || (match_array == NULL)) { 59767 return BCM_E_PARAM; 59768 } 59769 59770 /* Make sure port module is initialized. */ 59771 PORT_INIT(unit); 59772 59773 /* Add every single match */ 59774 for (i = 0; i < size; i++) { 59775 rv = bcm_esw_port_match_add(unit, port, match_array + i); 59776 if (BCM_FAILURE(rv)) { 59777 return rv; 59778 } 59779 } 59780 return rv; 59781 #else 59782 return BCM_E_UNAVAIL; 59783 #endif 59784 } 59785 59786 /* 59787 * Function: 59788 * bcm_port_match_delete_all 59789 * Purpose: 59790 * Delete all matches for an existing port 59791 * Parameters: 59792 * unit - (IN) Unit number. 59793 * port - (IN) Port or gport 59794 * Returns: 59795 * BCM_E_xxx 59796 * Notes: 59797 */ 59798 int 59799 bcm_esw_port_match_delete_all( 59800 int unit, 59801 bcm_gport_t port) 59802 { 59803 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 59804 int i, size, count, rv = BCM_E_NONE; 59805 bcm_port_match_info_t *match_array = NULL; 59806 59807 /* Make sure port module is initialized. */ 59808 PORT_INIT(unit); 59809 59810 /* First get number of entries */ 59811 rv = bcm_esw_port_match_multi_get(unit, port, 0, match_array, &count); 59812 if (BCM_FAILURE(rv) || (count == 0)) { 59813 return rv; 59814 } 59815 match_array = sal_alloc(sizeof(bcm_port_match_info_t) * count, 59816 "match_array"); 59817 if (match_array == NULL) { 59818 return BCM_E_MEMORY; 59819 } 59820 sal_memset(match_array, 0, sizeof(bcm_port_match_info_t) * count); 59821 59822 /* Get all matches */ 59823 size = count; 59824 rv = bcm_esw_port_match_multi_get(unit, port, size, match_array, &count); 59825 if (BCM_FAILURE(rv)) { 59826 sal_free(match_array); 59827 return rv; 59828 } 59829 59830 /* Delete every single match */ 59831 for (i = 0; i < count; i++) { 59832 rv = bcm_esw_port_match_delete(unit, port, match_array + i); 59833 if (BCM_FAILURE(rv)) { 59834 sal_free(match_array); 59835 return rv; 59836 } 59837 } 59838 sal_free(match_array); 59839 return rv; 59840 #else 59841 return BCM_E_UNAVAIL; 59842 #endif 59843 } 59844 59845 int 59846 bcmi_esw_port_eee_cfg_get(int unit, bcm_port_t port, int *value) 59847 { 59848 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \ 59849 defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) || \ 59850 defined(BCM_HURRICANE2_SUPPORT) 59851 if ((port < 0) || (port >= SOC_MAX_NUM_PORTS)) { 59852 return BCM_E_PORT; 59853 } 59854 59855 *value = eee_cfg[unit][port]; 59856 59857 return BCM_E_NONE; 59858 #else 59859 return BCM_E_UNAVAIL; 59860 #endif 59861 } 59862 59863 59864 59865 /* 59866 * Function: 59867 * bcm_esw_port_timesync_config_get 59868 * Purpose: 59869 * Delete all matches for an existing port 59870 * Parameters: 59871 * unit - (IN) Unit number. 59872 * port - (IN) Port 59873 * conf - (IN) Configuration 59874 * Returns: 59875 * BCM_E_xxx 59876 * Notes: 59877 */ 59878 59879 int 59880 bcm_esw_port_timesync_config_get(int unit, bcm_port_t port, int array_size, 59881 bcm_port_timesync_config_t *config_array, 59882 int *array_count) 59883 { 59884 int rv; 59885 int is_remote_port = FALSE; 59886 59887 /* Make sure port module is initialized. */ 59888 PORT_INIT(unit); 59889 59890 if (SOC_IS_TRIDENT3X(unit) && BCM_GPORT_IS_PROXY(port)) { 59891 if (bcm_esw_port_local_get(unit, port, &port) != BCM_E_NONE) { 59892 /* the port is remote mod port */ 59893 is_remote_port = TRUE; 59894 } 59895 } 59896 59897 if (!is_remote_port) { 59898 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 59899 } 59900 59901 COMPILER_REFERENCE(array_size); 59902 COMPILER_REFERENCE(config_array); 59903 COMPILER_REFERENCE(array_count); 59904 59905 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \ 59906 defined(BCM_TIMESYNC_V3_SUPPORT)|| defined(BCM_SABER2_SUPPORT) || \ 59907 defined(BCM_APACHE_SUPPORT) 59908 /* 59909 * Internal timesync function handles port lock and retrieves 59910 * timesync config profiles 59911 */ 59912 if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) || 59913 SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 59914 SOC_IS_APACHE(unit)) && 59915 (soc_feature(unit,soc_feature_timesync_support))) { 59916 rv = _bcm_esw_port_timesync_config_get(unit, port, array_size, 59917 config_array, array_count, is_remote_port); 59918 } else 59919 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || 59920 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */ 59921 { 59922 rv = BCM_E_UNAVAIL; 59923 } 59924 59925 return rv; 59926 } 59927 59928 /* 59929 * Function: 59930 * bcm_esw_port_timesync_config_set 59931 * Purpose: 59932 * Set Timesync Configuration profiles for the port 59933 * Parameters: 59934 * unit - (IN) bcm device 59935 * port - (IN) port 59936 * config_count - (IN)Count of timesync profile 59937 * *config_array - (IN/OUT) Pointer to array of timesync profiles 59938 * Returns: 59939 * BCM_E_xxx 59940 * Notes: 59941 */ 59942 int 59943 bcm_esw_port_timesync_config_set(int unit, bcm_port_t port, int config_count, 59944 bcm_port_timesync_config_t *config_array) 59945 { 59946 int rv; 59947 int is_remote_port = FALSE; 59948 59949 /* Make sure port module is initialized. */ 59950 PORT_INIT(unit); 59951 59952 if (SOC_IS_TRIDENT3X(unit) && BCM_GPORT_IS_PROXY(port)) { 59953 if (bcm_esw_port_local_get(unit, port, &port) != BCM_E_NONE) { 59954 int cnt; 59955 bcm_port_timesync_config_t *ts_config; 59956 is_remote_port = TRUE; 59957 for (cnt = 0; cnt < config_count; cnt++) 59958 { 59959 ts_config = (bcm_port_timesync_config_t*) (config_array + cnt); 59960 /* the params can't be configured on remote logical port */ 59961 if (ts_config->flags & BCM_PORT_TIMESYNC_ONE_STEP_TIMESTAMP || 59962 ts_config->flags & BCM_PORT_TIMESYNC_TWO_STEP_TIMESTAMP || 59963 ts_config->flags & BCM_PORT_TIMESYNC_TIMESTAMP_CFUPDATE_ALL || 59964 ts_config->pkt_drop & BCM_PORT_TIMESYNC_PKT_INVALID) { 59965 return BCM_E_PORT; 59966 } 59967 } 59968 } 59969 } 59970 59971 if (!is_remote_port) { 59972 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 59973 } 59974 59975 COMPILER_REFERENCE(config_count); 59976 COMPILER_REFERENCE(config_array); 59977 59978 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \ 59979 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) || \ 59980 defined(BCM_APACHE_SUPPORT) 59981 /* 59982 * Internal timesync function handles port lock and adds 59983 * timesync config profiles 59984 */ 59985 if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) || 59986 SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 59987 SOC_IS_APACHE(unit)) && 59988 (soc_feature(unit,soc_feature_timesync_support))) { 59989 rv = _bcm_esw_port_timesync_config_set(unit, port, config_count, 59990 config_array, is_remote_port); 59991 } else 59992 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || 59993 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */ 59994 { 59995 rv = BCM_E_UNAVAIL; 59996 } 59997 59998 return rv; 59999 } 60000 60001 /* 60002 * Function: 60003 * bcm_esw_port_timesync_tx_timestamp_and_seqid_get 60004 * Purpose: 60005 * Retrives two-step PTP timestamp and seqid from MAC FIFO after packet TX 60006 * Parameters: 60007 * unit - (IN) Unit number. 60008 * port - (IN) Port 60009 * conf - (IN) Configuration 60010 * Returns: 60011 * BCM_E_xxx 60012 * Notes: 60013 */ 60014 60015 int 60016 bcm_esw_port_timesync_tx_info_get(int unit, bcm_port_t port, 60017 bcm_port_timesync_tx_info_t *tx_info) 60018 { 60019 int rv; 60020 60021 /* Make sure port module is initialized. */ 60022 PORT_INIT(unit); 60023 60024 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 60025 60026 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) \ 60027 || defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) \ 60028 || defined(BCM_SABER2_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) \ 60029 || defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_FIRELIGHT_SUPPORT) \ 60030 || defined(BCM_GREYHOUND_SUPPORT) 60031 /* 60032 * Internal timesync function handles port lock and retrieves 60033 * timesync config profiles 60034 */ 60035 if (((SOC_IS_TD2_TT2(unit)) || SOC_IS_HURRICANE3(unit) || SOC_IS_SABER2(unit) || SOC_IS_TRIDENT2(unit) || 60036 SOC_IS_TRIUMPH3(unit) || SOC_IS_FIRELIGHT(unit) || SOC_IS_GREYHOUND(unit)) && 60037 (soc_feature(unit,soc_feature_timesync_support))) { 60038 if (SOC_USE_PORTCTRL(unit)) { 60039 rv = _bcm_esw_port_timesync_tx_info_get(unit, port, tx_info); 60040 } else { 60041 soc_port_timesync_tx_info_t info; 60042 sal_memset(&info, 0, sizeof(soc_port_timesync_tx_info_t)); 60043 60044 PORT_LOCK(unit) 60045 rv = MAC_TIMESYNC_TX_INFO_GET(PORT(unit, port).p_mac, unit, port, &info); 60046 PORT_UNLOCK(unit); 60047 COMPILER_64_SET(tx_info->timestamp, info.timestamps_in_fifo_hi, info.timestamps_in_fifo); 60048 tx_info->sequence_id = info.sequence_id; 60049 } 60050 } else 60051 #endif /* defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 60052 || defined(BCM_TOMAHAWK2_SUPPORT) */ 60053 { 60054 rv = BCM_E_UNAVAIL; 60055 } 60056 60057 return rv; 60058 } 60059 60060 /* 60061 * Function: 60062 * bcm_esw_port_timestamp_adjust_get 60063 * Purpose: 60064 * get OSTS,TSTS timestamp adjust based on current speed 60065 * Parameters: 60066 * unit - (IN) Unit number. 60067 * port - (IN) Port 60068 * ts_adjust - (OUT) configuration for tsts,osts timestamp adjustment. 60069 * Returns: 60070 * BCM_E_xxx 60071 * Notes: 60072 */ 60073 int 60074 bcm_esw_port_timestamp_adjust_get(int unit, bcm_port_t port, 60075 bcm_port_timestamp_adjust_t *ts_adjust) 60076 { 60077 int rv; 60078 60079 /* Make sure port module is initialized. */ 60080 PORT_INIT(unit); 60081 60082 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 60083 60084 #ifdef PORTMOD_SUPPORT 60085 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 60086 PORT_LOCK(unit); 60087 rv = bcmi_esw_portctrl_timestamp_adjust_get(unit, port, ts_adjust); 60088 PORT_UNLOCK(unit); 60089 } else 60090 #endif /* PORTMOD_SUPPORT */ 60091 { 60092 rv = BCM_E_UNAVAIL; 60093 } 60094 60095 return rv; 60096 60097 } 60098 60099 /* 60100 * Function: 60101 * bcm_esw_port_timestamp_adjust_set 60102 * Purpose: 60103 * set OSTS,TSTS timestamp adjust based on speed 60104 * Parameters: 60105 * unit - (IN) Unit number. 60106 * port - (IN) Port. 60107 * ts_adjust - (IN) configuration for tsts,osts timestamp adjust. 60108 * Returns: 60109 * BCM_E_xxx 60110 * Notes: 60111 */ 60112 int 60113 bcm_esw_port_timestamp_adjust_set(int unit, bcm_port_t port, 60114 bcm_port_timestamp_adjust_t *ts_adjust) 60115 { 60116 int rv; 60117 /* Make sure port module is initialized. */ 60118 PORT_INIT(unit); 60119 60120 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 60121 60122 #ifdef PORTMOD_SUPPORT 60123 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 60124 PORT_LOCK(unit); 60125 rv = bcmi_esw_portctrl_timestamp_adjust_set(unit, port, ts_adjust); 60126 PORT_UNLOCK(unit); 60127 } else 60128 #endif /* PORTMOD_SUPPORT */ 60129 { 60130 rv = BCM_E_UNAVAIL; 60131 } 60132 60133 return rv; 60134 60135 } 60136 60137 /* 60138 * Function: 60139 * bcm_esw_port_phy_timesync_config_set 60140 * Purpose: 60141 * Delete all matches for an existing port 60142 * Parameters: 60143 * unit - (IN) Unit number. 60144 * port - (IN) Port 60145 * conf - (IN) Configuration 60146 * Returns: 60147 * BCM_E_xxx 60148 * Notes: 60149 */ 60150 int 60151 bcm_esw_port_phy_timesync_config_set(int unit, bcm_port_t port, 60152 bcm_port_phy_timesync_config_t *conf) 60153 { 60154 int rv; 60155 /* Make sure port module is initialized. */ 60156 PORT_INIT(unit); 60157 60158 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 60159 60160 #ifdef PORTMOD_SUPPORT 60161 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 60162 PORT_LOCK(unit); 60163 rv = soc_portctrl_phy_timesync_config_set(unit, port, 60164 (soc_port_phy_timesync_config_t *)conf); 60165 PORT_UNLOCK(unit); 60166 } else 60167 #endif /* PORTMOD_SUPPORT */ 60168 { 60169 PORT_LOCK(unit); 60170 rv = soc_port_phy_timesync_config_set(unit, port, 60171 (soc_port_phy_timesync_config_t *)conf); 60172 PORT_UNLOCK(unit); 60173 } 60174 60175 return rv; 60176 } 60177 60178 /* 60179 * Function: 60180 * bcm_esw_port_phy_timesync_config_get 60181 * Purpose: 60182 * Delete all matches for an existing port 60183 * Parameters: 60184 * unit - (IN) Unit number. 60185 * port - (IN) Port 60186 * conf - (OUT) Configuration 60187 * Returns: 60188 * BCM_E_xxx 60189 * Notes: 60190 */ 60191 int 60192 bcm_esw_port_phy_timesync_config_get(int unit, bcm_port_t port, 60193 bcm_port_phy_timesync_config_t *conf) 60194 { 60195 int rv; 60196 60197 /* Make sure port module is initialized. */ 60198 PORT_INIT(unit); 60199 60200 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 60201 60202 #ifdef PORTMOD_SUPPORT 60203 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 60204 PORT_LOCK(unit); 60205 rv = soc_portctrl_phy_timesync_config_get(unit, port, 60206 (soc_port_phy_timesync_config_t *)conf); 60207 PORT_UNLOCK(unit); 60208 } else 60209 #endif /* PORTMOD_SUPPORT */ 60210 { 60211 PORT_LOCK(unit); 60212 rv = soc_port_phy_timesync_config_get(unit, port, 60213 (soc_port_phy_timesync_config_t *)conf); 60214 PORT_UNLOCK(unit); 60215 } 60216 60217 return rv; 60218 } 60219 60220 /* 60221 * Function: 60222 * bcm_esw_port_control_phy_timesync_set 60223 * Purpose: 60224 * Delete all matches for an existing port 60225 * Parameters: 60226 * unit - (IN) Unit number. 60227 * port - (IN) Port 60228 * type - (IN) Operation 60229 * value- (IN) Arg to operation 60230 * Returns: 60231 * BCM_E_xxx 60232 * Notes: 60233 */ 60234 int 60235 bcm_esw_port_control_phy_timesync_set(int unit, bcm_port_t port, 60236 bcm_port_control_phy_timesync_t type, 60237 uint64 value) 60238 { 60239 int rv; 60240 60241 /* Make sure port module is initialized. */ 60242 PORT_INIT(unit); 60243 60244 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 60245 60246 #ifdef PORTMOD_SUPPORT 60247 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 60248 PORT_LOCK(unit); 60249 rv = soc_portctrl_control_phy_timesync_set(unit, port, type, value); 60250 PORT_UNLOCK(unit); 60251 } else 60252 #endif /* PORTMOD_SUPPORT */ 60253 { 60254 PORT_LOCK(unit); 60255 rv = soc_port_control_phy_timesync_set(unit, port, type, value); 60256 PORT_UNLOCK(unit); 60257 } 60258 60259 return rv; 60260 } 60261 60262 /* 60263 * Function: 60264 * bcm_esw_port_control_phy_timesync_get 60265 * Purpose: 60266 * Delete all matches for an existing port 60267 * Parameters: 60268 * unit - (IN) Unit number. 60269 * port - (IN) Port 60270 * type - (IN) Operation 60271 * value- (OUT) Pointer to arg for operation 60272 * Returns: 60273 * BCM_E_xxx 60274 * Notes: 60275 */ 60276 int 60277 bcm_esw_port_control_phy_timesync_get(int unit, bcm_port_t port, 60278 bcm_port_control_phy_timesync_t type, 60279 uint64 *value) 60280 { 60281 int rv; 60282 60283 /* Make sure port module is initialized. */ 60284 PORT_INIT(unit); 60285 60286 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 60287 60288 #ifdef PORTMOD_SUPPORT 60289 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 60290 PORT_LOCK(unit); 60291 rv = soc_portctrl_control_phy_timesync_get(unit, port, type, value); 60292 PORT_UNLOCK(unit); 60293 } else 60294 #endif /* PORTMOD_SUPPORT */ 60295 { 60296 PORT_LOCK(unit); 60297 rv = soc_port_control_phy_timesync_get(unit, port, type, value); 60298 PORT_UNLOCK(unit); 60299 } 60300 60301 return rv; 60302 } 60303 60304 /* 60305 * Function: 60306 * bcm_esw_port_phy_timesync_enhanced_capture_get 60307 * Purpose: 60308 * Delete all matches for an existing port 60309 * Parameters: 60310 * unit - (IN) Unit number. 60311 * port - (IN) Port 60312 * value - (OUT) Configuration 60313 * Returns: 60314 * BCM_E_xxx 60315 * Notes: 60316 */ 60317 int 60318 bcm_esw_port_phy_timesync_enhanced_capture_get(int unit, bcm_port_t port, 60319 bcm_port_phy_timesync_enhanced_capture_t *value) 60320 { 60321 int rv; 60322 /* Make sure port module is initialized. */ 60323 PORT_INIT(unit); 60324 60325 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 60326 60327 PORT_LOCK(unit); 60328 rv = soc_port_phy_timesync_enhanced_capture_get(unit, port, 60329 (soc_port_phy_timesync_enhanced_capture_t *)value); 60330 PORT_UNLOCK(unit); 60331 60332 return rv; 60333 } 60334 60335 /* bcm_port_config_phy_oam_set */ 60336 int bcm_esw_port_config_phy_oam_set(int unit, bcm_port_t port, 60337 bcm_port_config_phy_oam_t *conf){ 60338 int rv; 60339 60340 /* Make sure port module is initialized. */ 60341 PORT_INIT(unit); 60342 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 60343 60344 #ifdef PORTMOD_SUPPORT 60345 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 60346 rv = BCM_E_UNAVAIL; 60347 } else 60348 #endif /* PORTMOD_SUPPORT */ 60349 { 60350 60351 PORT_LOCK(unit); 60352 rv = soc_port_config_phy_oam_set(unit, port, 60353 (soc_port_config_phy_oam_t *)conf); 60354 PORT_UNLOCK(unit); 60355 } 60356 60357 return rv; 60358 } 60359 60360 /* bcm_port_config_phy_oam_get */ 60361 int bcm_esw_port_config_phy_oam_get(int unit, bcm_port_t port, 60362 bcm_port_config_phy_oam_t *conf){ 60363 int rv; 60364 60365 /* Make sure port module is initialized. */ 60366 PORT_INIT(unit); 60367 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 60368 60369 #ifdef PORTMOD_SUPPORT 60370 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 60371 rv = BCM_E_UNAVAIL; 60372 } else 60373 #endif /* PORTMOD_SUPPORT */ 60374 { 60375 PORT_LOCK(unit); 60376 rv = soc_port_config_phy_oam_get(unit, port, 60377 (soc_port_config_phy_oam_t *)conf); 60378 PORT_UNLOCK(unit); 60379 } 60380 60381 return rv; 60382 } 60383 60384 /* bcm_port_control_phy_oam_set */ 60385 int bcm_esw_port_control_phy_oam_set(int unit, bcm_port_t port, 60386 bcm_port_control_phy_oam_t type, 60387 uint64 value){ 60388 int rv; 60389 60390 /* Make sure port module is initialized. */ 60391 PORT_INIT(unit); 60392 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 60393 60394 #ifdef PORTMOD_SUPPORT 60395 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 60396 rv = BCM_E_UNAVAIL; 60397 } else 60398 #endif /* PORTMOD_SUPPORT */ 60399 { 60400 PORT_LOCK(unit); 60401 rv = soc_port_control_phy_oam_set(unit, port,type, value); 60402 PORT_UNLOCK(unit); 60403 } 60404 60405 return rv; 60406 } 60407 60408 /* bcm_port_control_phy_oam_get */ 60409 int bcm_esw_port_control_phy_oam_get(int unit, bcm_port_t port, 60410 bcm_port_control_phy_oam_t type, 60411 uint64 *value){ 60412 int rv; 60413 60414 /* Make sure port module is initialized. */ 60415 PORT_INIT(unit); 60416 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 60417 60418 #ifdef PORTMOD_SUPPORT 60419 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 60420 rv = BCM_E_UNAVAIL; 60421 } else 60422 #endif /* PORTMOD_SUPPORT */ 60423 { 60424 PORT_LOCK(unit); 60425 rv = soc_port_control_phy_oam_get(unit, port,type, value); 60426 PORT_UNLOCK(unit); 60427 } 60428 60429 return rv; 60430 } 60431 60432 /* 60433 * Function: 60434 * bcm_esw_port_tpid_get_all 60435 * Purpose: 60436 * Get a list of tpids and associated color selections for a given port 60437 * Parameters: 60438 * unit - (IN) Unit number. 60439 * port - (IN) Port 60440 * size - (IN) number of elements of the next two array parameters 60441 *tpid_array - (OUT) buffer array to hold a list of retrieved tpids 60442 *color_array - (OUT) buffer array to hold a list of retrieved color selections 60443 * count - (OUT) actual number of tpids retrieved. 60444 * Returns: 60445 * BCM_E_xxx 60446 */ 60447 int 60448 bcm_esw_port_tpid_get_all(int unit, bcm_port_t port, 60449 int size, /* number of elements of the arrays */ 60450 uint16 *tpid_array, /* buffer array to hold a list of retrieved tpids */ 60451 int *color_array, /* buffer array to hold a list of retrieved colors */ 60452 int *count) /* actual number of tpids retrieved. */ 60453 { 60454 int rv = BCM_E_UNAVAIL; 60455 bcm_module_t mod_out; 60456 bcm_port_t port_out; 60457 bcm_trunk_t tgid_out; 60458 int id_out; 60459 int is_local = 0; 60460 60461 /* safety check */ 60462 if (size < 0 || count == NULL) { 60463 return BCM_E_PARAM; 60464 } 60465 if ((size > 0) && (tpid_array == NULL || color_array == NULL)) { 60466 return BCM_E_PARAM; 60467 } 60468 60469 *count = 0; 60470 60471 /* Make sure port module is initialized. */ 60472 PORT_INIT(unit); 60473 if (BCM_GPORT_IS_SET(port)) { 60474 /* Handle virtual ports separetly */ 60475 if (BCM_GPORT_IS_MPLS_PORT(port) || 60476 BCM_GPORT_IS_MIM_PORT(port) || 60477 BCM_GPORT_IS_TRILL_PORT(port) || 60478 BCM_GPORT_IS_VXLAN_PORT(port) || 60479 BCM_GPORT_IS_FLOW_PORT(port) || 60480 BCM_GPORT_IS_VLAN_PORT(port)) { 60481 60482 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 60483 #if defined(BCM_TRX_SUPPORT) 60484 PORT_LOCK(unit); 60485 rv = _bcm_trx_vp_tpid_get_all(unit, port, size, 60486 tpid_array, color_array,count); 60487 PORT_UNLOCK(unit); 60488 #endif 60489 } 60490 return rv; 60491 } else { 60492 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 60493 &mod_out, &port_out, &tgid_out, &id_out)); 60494 if ((-1 != tgid_out) || (-1 != id_out)) { 60495 return BCM_E_PARAM; 60496 } 60497 60498 BCM_IF_ERROR_RETURN 60499 (_bcm_esw_modid_is_local(unit, mod_out, &is_local)); 60500 if (!is_local) { 60501 return BCM_E_PORT; 60502 } else { 60503 BCM_IF_ERROR_RETURN( 60504 bcm_esw_port_local_get(unit, port, &port)); 60505 } 60506 } 60507 60508 } else if (!SOC_PORT_VALID(unit, port)) { 60509 return BCM_E_PORT; 60510 } 60511 60512 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 60513 || defined(BCM_RAVEN_SUPPORT) 60514 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 60515 PORT_LOCK(unit); 60516 rv = _bcm_fb2_port_tpid_get_all(unit, port, size,tpid_array, 60517 color_array, count); 60518 PORT_UNLOCK(unit); 60519 } 60520 #endif 60521 return (rv); 60522 } 60523 void bcm_esw_kt2_port_lock(int unit) 60524 { 60525 PORT_LOCK(unit); 60526 } 60527 void bcm_esw_kt2_port_unlock(int unit) 60528 { 60529 PORT_UNLOCK(unit); 60530 } 60531 60532 #ifdef BCM_WARM_BOOT_SUPPORT 60533 int 60534 _bcm_port_cleanup(int unit) 60535 { 60536 #if defined(BCM_FIREBOLT_SUPPORT) 60537 if (SOC_IS_FB_FX_HX(unit)) { 60538 bcm_port_t port; 60539 60540 for (port = 0; port < SOC_MAX_NUM_PORTS; port++) { 60541 if (PORT(unit, port).p_vd_pbvl != NULL) { 60542 sal_free(PORT(unit, port).p_vd_pbvl); 60543 PORT(unit, port).p_vd_pbvl = NULL; 60544 } 60545 60546 if (PORT(unit, port).e2ecc_config != NULL) { 60547 sal_free(PORT(unit, port).e2ecc_config); 60548 PORT(unit, port).e2ecc_config = NULL; 60549 } 60550 } 60551 60552 if (bcm_port_info[unit] != NULL) { 60553 sal_free(bcm_port_info[unit]); 60554 bcm_port_info[unit] = NULL; 60555 } 60556 } 60557 #endif /* BCM_FIREBOLT_SUPPORT */ 60558 60559 return BCM_E_NONE; 60560 } 60561 #endif /* BCM_WARM_BOOT_SUPPORT */ 60562 60563 #ifndef BCM_SW_STATE_DUMP_DISABLE 60564 /* 60565 * Function: 60566 * _bcm_port_sw_dump 60567 * Purpose: 60568 * Displays port information maintained by software. 60569 * Parameters: 60570 * unit - Device unit number 60571 * Returns: 60572 * None 60573 * Note: 60574 * Skip following structure fields: p_phy, p_mac 60575 */ 60576 void 60577 _bcm_port_sw_dump(int unit) 60578 { 60579 _bcm_port_info_t *info; 60580 int i, j; 60581 int idxmax, entries, max_num_ports = 0; 60582 bcm_port_t port; 60583 bcm_pbmp_t all_pbmp; 60584 60585 info = bcm_port_info[unit]; 60586 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm) + 1; 60587 entries = (idxmax + (_BCM_PORT_VD_PBVL_ESIZE - 1)) / _BCM_PORT_VD_PBVL_ESIZE; 60588 60589 max_num_ports = SOC_MAX_NUM_PORTS; 60590 60591 SOC_PBMP_CLEAR(all_pbmp); 60592 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 60593 60594 #ifdef BCM_KATANA2_SUPPORT 60595 if (soc_feature(unit, soc_feature_linkphy_coe) || 60596 soc_feature(unit, soc_feature_subtag_coe)) { 60597 _bcm_kt2_subport_pbmp_update (unit, &all_pbmp); 60598 if (SOC_INFO(unit).linkphy_enabled || 60599 SOC_INFO(unit).subtag_enabled) { 60600 max_num_ports = SOC_MAX_NUM_PP_PORTS; 60601 } 60602 } 60603 #endif 60604 60605 60606 LOG_CLI((BSL_META_U(unit, 60607 "\nSW Information Port - Unit %d\n"), unit)); 60608 60609 if (info != NULL) { 60610 for (i = 0; i < max_num_ports; i++) { 60611 LOG_CLI((BSL_META_U(unit, 60612 " Port %2d : "), i)); 60613 LOG_CLI((BSL_META_U(unit, 60614 " MAC driver - %s\n"), 60615 ((SOC_PORT_VALID(unit, i)) && (info[i].p_mac != NULL)) ? 60616 (info[i].p_mac)->drv_name : "none")); 60617 LOG_CLI((BSL_META_U(unit, 60618 " Untagged priority - %d\n"), 60619 info[i].p_ut_prio)); 60620 LOG_CLI((BSL_META_U(unit, 60621 " Double-tag mode - "))); 60622 if (0 != info[i].dtag_mode) { 60623 if (0 != (info[i].dtag_mode & 60624 BCM_PORT_DTAG_MODE_INTERNAL)) { 60625 LOG_CLI((BSL_META_U(unit, 60626 " Internal"))); 60627 } 60628 if (0 != (info[i].dtag_mode & 60629 BCM_PORT_DTAG_MODE_EXTERNAL)) { 60630 LOG_CLI((BSL_META_U(unit, 60631 " External"))); 60632 } 60633 if (0 != (info[i].dtag_mode & 60634 BCM_PORT_DTAG_ADD_EXTERNAL_TAG)) { 60635 LOG_CLI((BSL_META_U(unit, 60636 " AddTag"))); 60637 } 60638 if (0 != (info[i].dtag_mode & 60639 BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG)) { 60640 LOG_CLI((BSL_META_U(unit, 60641 " RemoveTag"))); 60642 } 60643 } else { 60644 LOG_CLI((BSL_META_U(unit, 60645 " None"))); 60646 } 60647 LOG_CLI((BSL_META_U(unit, 60648 "\n"))); 60649 LOG_CLI((BSL_META_U(unit, 60650 " VLAN_PROTOCOL_DATA index - %d\n"), 60651 info[i].vlan_prot_ptr)); 60652 LOG_CLI((BSL_META_U(unit, 60653 " Number of VPs - %d\n"), 60654 info[i].vp_count)); 60655 } 60656 60657 LOG_CLI((BSL_META_U(unit, 60658 "\n"))); 60659 60660 LOG_CLI((BSL_META_U(unit, 60661 " Protocol based VLAN - \n"))); 60662 LOG_CLI((BSL_META_U(unit, 60663 " Total Entries : %d\n"), entries)); 60664 60665 PBMP_ITER(all_pbmp, port) { 60666 LOG_CLI((BSL_META_U(unit, 60667 " Port %2d : "), port)); 60668 if (info[port].p_vd_pbvl == NULL) { 60669 LOG_CLI((BSL_META_U(unit, 60670 "\n"))); 60671 continue; 60672 } 60673 60674 for (j = 0; j < entries; j++) { 60675 if ((j > 0) && !(j % 10)) { 60676 LOG_CLI((BSL_META_U(unit, 60677 "\n "))); 60678 } 60679 LOG_CLI((BSL_META_U(unit, 60680 " 0x%2.2x"), info[port].p_vd_pbvl[j])); 60681 } 60682 LOG_CLI((BSL_META_U(unit, 60683 "\n"))); 60684 } 60685 60686 if (soc_feature(unit, soc_feature_e2ecc)) { 60687 bcm_port_congestion_config_t *e2ep; 60688 60689 LOG_CLI((BSL_META_U(unit, 60690 "\n"))); 60691 LOG_CLI((BSL_META_U(unit, 60692 " E2E Congestion Control - \n"))); 60693 PBMP_ALL_ITER(unit, port) { 60694 e2ep = info[port].e2ecc_config; 60695 if (NULL == e2ep) { 60696 continue; 60697 } 60698 60699 if ((0 == (e2ep->flags & (BCM_PORT_CONGESTION_CONFIG_E2ECC | 60700 BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL | 60701 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE | 60702 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE)))) { 60703 continue; 60704 } 60705 60706 LOG_CLI((BSL_META_U(unit, 60707 "\n Port : %d\n"), port)); 60708 if ((e2ep->flags & 60709 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) || 60710 (e2ep->flags & 60711 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE)) { 60712 LOG_CLI((BSL_META_U(unit, 60713 " E2ECC COE Flags: %s %s \n"), 60714 (e2ep->flags & 60715 BCM_PORT_CONGESTION_CONFIG_RX) ? 60716 "RX" : "", 60717 ((e2ep->flags & 60718 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) ? 60719 "FLEX mode": 60720 (e2ep->flags & 60721 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ? 60722 "STRICT mode" : ""))) ; 60723 } else { 60724 LOG_CLI((BSL_META_U(unit, 60725 " Flags : %s %s %s\n"), 60726 (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC) ? 60727 "E2ECC" : "DestMod Flow control", 60728 (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_TX) ? 60729 "TX" : "", 60730 (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_RX) ? 60731 "RX" : "")); 60732 } 60733 60734 if (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_TX) { 60735 LOG_CLI((BSL_META_U(unit, 60736 " Port bits : 0x%02x\n"), 60737 e2ep->port_bits)); 60738 LOG_CLI((BSL_META_U(unit, 60739 " Packets/sec : %d\n"), 60740 e2ep->packets_per_sec)); 60741 LOG_CLI((BSL_META_U(unit, 60742 " Source gport : 0x%08x\n"), 60743 e2ep->src_port)); 60744 LOG_CLI((BSL_META_U(unit, 60745 " Multicast ID : 0x%04x\n"), 60746 e2ep->multicast_id)); 60747 LOG_CLI((BSL_META_U(unit, 60748 " Traffic class : %d\n"), 60749 e2ep->traffic_class)); 60750 LOG_CLI((BSL_META_U(unit, 60751 " Color : %d\n"), 60752 e2ep->color)); 60753 LOG_CLI((BSL_META_U(unit, 60754 " Source MAC : 0x%02x%02x%02x%02x%02x%02x\n"), 60755 e2ep->src_mac[0], e2ep->src_mac[1], 60756 e2ep->src_mac[2], e2ep->src_mac[3], 60757 e2ep->src_mac[4], e2ep->src_mac[5])); 60758 } 60759 60760 LOG_CLI((BSL_META_U(unit, 60761 " Destination MAC : " 60762 "0x%02x%02x%02x%02x%02x%02x\n"), 60763 e2ep->dest_mac[0], e2ep->dest_mac[1], 60764 e2ep->dest_mac[2], e2ep->dest_mac[3], 60765 e2ep->dest_mac[4], e2ep->dest_mac[5])); 60766 LOG_CLI((BSL_META_U(unit, 60767 " Ethertype : 0x%04x\n"), 60768 e2ep->ethertype)); 60769 LOG_CLI((BSL_META_U(unit, 60770 " Opcode : 0x%04x\n"), 60771 e2ep->opcode)); 60772 } 60773 } 60774 60775 #ifdef BCM_TRIUMPH2_SUPPORT 60776 if (soc_feature(unit, soc_feature_src_modid_blk_profile)) { 60777 60778 LOG_CLI((BSL_META_U(unit, 60779 "\n"))); 60780 LOG_CLI((BSL_META_U(unit, 60781 " Source Modid Egress Blocking Profiles - \n"))); 60782 PBMP_ITER(all_pbmp, port) { 60783 if (-1 == PORT_SRC_MOD_EGR_PROF_PTR(unit, port)) { 60784 continue; 60785 } 60786 LOG_CLI((BSL_META_U(unit, 60787 " Port %2d : "), port)); 60788 LOG_CLI((BSL_META_U(unit, 60789 "Profile index %d\n"), 60790 PORT_SRC_MOD_EGR_PROF_PTR(unit, port))); 60791 } 60792 /* Display those entries with reference count > 0 */ 60793 if (PORT_SRC_MOD_EGR_PROFILE(unit) != NULL) { 60794 int i; 60795 int num_entries; 60796 int ref_count; 60797 int entries_per_set; 60798 int modid_count; 60799 uint32 index; 60800 pbmp_t sme_pbmp; 60801 src_modid_egress_entry_t *entry_p; 60802 char sme_pfm[SOC_PBMP_FMT_LEN]; 60803 60804 num_entries = soc_mem_index_count(unit, 60805 PORT_SRC_MOD_EGR_PROFILE(unit)->tables[0].mem); 60806 LOG_CLI((BSL_META_U(unit, 60807 " Source Modid Egress Profile\n"))); 60808 LOG_CLI((BSL_META_U(unit, 60809 " Number of entries: %d\n"), num_entries)); 60810 LOG_CLI((BSL_META_U(unit, 60811 " Index RefCount EntriesPerSet - " 60812 "PortBlockMaskBitmap\n"))); 60813 60814 modid_count = SOC_MODID_MAX(unit) + 1; 60815 for (index = 0; index < num_entries; index += modid_count) { 60816 if (SOC_FAILURE(soc_profile_mem_ref_count_get(unit, 60817 PORT_SRC_MOD_EGR_PROFILE(unit), 60818 index, &ref_count))) { 60819 break; 60820 } 60821 60822 if (ref_count <= 0) { 60823 continue; 60824 } 60825 60826 for (i = 0; i < modid_count; i++) { 60827 entries_per_set = 60828 PORT_SRC_MOD_EGR_PROFILE(unit)->tables[0].\ 60829 entries[index+i].entries_per_set; 60830 entry_p = SOC_PROFILE_MEM_ENTRY(unit, 60831 PORT_SRC_MOD_EGR_PROFILE(unit), 60832 src_modid_egress_entry_t *, 60833 index + i); 60834 soc_mem_pbmp_field_get(unit, SRC_MODID_EGRESSm, 60835 entry_p, 60836 PORT_BLOCK_MASK_BITMAPf, 60837 &sme_pbmp); 60838 60839 if (BCM_PBMP_NOT_NULL(sme_pbmp)) { 60840 LOG_CLI((BSL_META_U(unit, 60841 " %5d %8d %13d "), 60842 index + i, ref_count, 60843 entries_per_set)); 60844 LOG_CLI((BSL_META_U(unit, 60845 "%s\n"), 60846 SOC_PBMP_FMT(sme_pbmp, sme_pfm))); 60847 } 60848 } 60849 } 60850 } 60851 } 60852 #endif /* BCM_TRIUMPH2_SUPPORT */ 60853 } 60854 60855 LOG_CLI((BSL_META_U(unit, 60856 "\n"))); 60857 60858 return; 60859 } 60860 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 60861 60862 60863 /* 60864 * Function: 60865 * _bcm_esw_port_gport_phyn_validate 60866 * Purpose: 60867 * Validate PHY specific gport 60868 * Parameters: 60869 * unit - (IN) Unit number. 60870 * port - (IN) Port number. 60871 * local_port - (OUT) Local Port number. 60872 * phyn - (OUT) Phy number 60873 * phy_lane - (OUT) Lane number 60874 * sys_side - (OUT) System side(1)or line side(0). 60875 * Returns: 60876 * BCM_E_XXX 60877 */ 60878 60879 int 60880 _bcm_esw_port_gport_phyn_validate(int unit, bcm_port_t port, 60881 bcm_port_t *local_port, int *phyn, 60882 int *phy_lane, int *sys_side) 60883 { 60884 /* Validate input arguments */ 60885 if (local_port == NULL || phy_lane == NULL || 60886 phyn == NULL || sys_side == NULL) { 60887 return BCM_E_PARAM; 60888 } 60889 60890 if (BCM_PHY_GPORT_IS_PHYN(port)) { 60891 *local_port = BCM_PHY_GPORT_PHYN_PORT_PORT_GET(port); 60892 *phyn = BCM_PHY_GPORT_PHYN_PORT_PHYN_GET(port); 60893 *phy_lane = -1; 60894 } else if(BCM_PHY_GPORT_IS_PHYN_LANE(port)) { 60895 *local_port = BCM_PHY_GPORT_PHYN_LANE_PORT_PORT_GET(port); 60896 *phyn = BCM_PHY_GPORT_PHYN_LANE_PORT_PHYN_GET(port); 60897 *phy_lane = BCM_PHY_GPORT_PHYN_LANE_PORT_LANE_GET(port); 60898 } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE(port)) { 60899 *local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PORT_GET(port); 60900 *phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PHYN_GET(port); 60901 *sys_side = TRUE; 60902 *phy_lane = -1; 60903 } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE_LANE(port)) { 60904 *local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PORT_GET(port); 60905 *phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PHYN_GET(port); 60906 *phy_lane = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_LANE_GET(port); 60907 *sys_side = TRUE; 60908 } else if (BCM_PHY_GPORT_IS_LANE(port)) { 60909 *local_port = BCM_PHY_GPORT_LANE_PORT_PORT_GET(port); 60910 *phy_lane = BCM_PHY_GPORT_LANE_PORT_LANE_GET(port); 60911 } else { 60912 *local_port = -1; 60913 return BCM_E_NONE; 60914 } 60915 60916 if (!SOC_PORT_VALID(unit, *local_port)) { 60917 return BCM_E_PORT; 60918 } 60919 60920 return BCM_E_NONE; 60921 } 60922 60923 /** 60924 * Function: 60925 * _bcm_esw_link_force_for_disabled_loopback_port 60926 * Purpose: 60927 * Force linkscan's current link status on for a disabled port 60928 * which is configured to MAC loopback. 60929 * Parameters: 60930 * unit - (IN) Unit number. 60931 * Returns: 60932 * BCM_E_xxx 60933 * Notes: 60934 */ 60935 int 60936 _bcm_esw_link_force_for_disabled_loopback_port(int unit) 60937 { 60938 bcm_port_t port; 60939 int loopback; 60940 int enable; 60941 bcm_pbmp_t pbmp; 60942 60943 SOC_PBMP_ASSIGN(pbmp, PBMP_E_ALL(unit)); 60944 #if defined(BCM_SABER2_SUPPORT) 60945 if(SOC_IS_SABER2(unit)){ 60946 /* 60947 * During warmboot init, the oamp port is not removed 60948 * from ethernet bitmaps till sat is initialized. 60949 * So manually removing it here. 60950 */ 60951 int oamp_enable; 60952 (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable); 60953 /* Skip OAMP port for saber2 device */ 60954 if(oamp_enable) { 60955 SOC_PBMP_PORT_REMOVE(pbmp, 60956 _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER); 60957 } 60958 } 60959 #endif 60960 60961 PBMP_ITER(pbmp,port) { 60962 BCM_IF_ERROR_RETURN( 60963 bcm_esw_port_loopback_get(unit, port, &loopback)); 60964 BCM_IF_ERROR_RETURN( 60965 bcm_esw_port_enable_get(unit, port, &enable)); 60966 if ((loopback == BCM_PORT_LOOPBACK_MAC) && (enable == FALSE)) { 60967 BCM_IF_ERROR_RETURN 60968 (_bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, TRUE)); 60969 } 60970 } 60971 60972 return BCM_E_NONE; 60973 } 60974 60975 #ifdef BCM_MAVERICK2_SUPPORT 60976 /** 60977 * Function: 60978 * _bcm_esw_mv2_asf_init 60979 * Purpose: 60980 * Initialize ASF subsystem and configure all the applicable ports 60981 * to the specified forwarding mode 60982 * Parameters: 60983 * unit - (IN) Unit number. 60984 * mode - (IN) forwarding mode 60985 * Returns: 60986 * BCM_E_xxx 60987 */ 60988 STATIC int 60989 _bcm_esw_mv2_asf_init( 60990 int unit, 60991 soc_mv2_asf_mode_e asf_mode) 60992 { 60993 bcm_port_t port; 60994 int speed; 60995 soc_info_t *si; 60996 60997 if (!(si = &SOC_INFO(unit))) { 60998 return BCM_E_INTERNAL; 60999 } 61000 61001 BCM_IF_ERROR_RETURN(soc_mv2_asf_init_start(unit)); 61002 61003 PBMP_ALL_ITER(unit, port) { 61004 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 61005 continue; 61006 } 61007 speed = si->port_init_speed[port]; 61008 if (speed == 0) { 61009 BCM_IF_ERROR_RETURN( 61010 bcm_esw_port_speed_get(unit, port, &speed)); 61011 } 61012 BCM_IF_ERROR_RETURN( 61013 soc_mv2_port_asf_init(unit, port, speed, asf_mode)); 61014 } 61015 BCM_IF_ERROR_RETURN(soc_mv2_asf_init_done(unit)); 61016 61017 return BCM_E_NONE; 61018 } 61019 61020 STATIC int 61021 _bcm_esw_mv2_port_asf_mode_set( 61022 int unit, 61023 bcm_port_t port, 61024 int mode) 61025 { 61026 int rv = BCM_E_NONE, speed; 61027 soc_info_t *si; 61028 int txp = 0, rxp = 0; 61029 pbmp_t *pause_bmp; 61030 61031 if (!(si = &SOC_INFO(unit))) { 61032 return SOC_E_INTERNAL; 61033 } 61034 61035 pause_bmp = soc_mv2_port_asf_pause_bpmp_get(unit); 61036 if (pause_bmp == NULL) { 61037 return BCM_E_INTERNAL; 61038 } 61039 61040 /* Update Pause for ASF mode */ 61041 if (_SOC_MV2_ASF_MODE_SAF != mode) { 61042 /* Disable rx pause for cut through */ 61043 BCM_IF_ERROR_RETURN 61044 (bcm_esw_port_pause_get(unit, port, &txp, &rxp)); 61045 61046 if (rxp) { 61047 SOC_PBMP_PORT_ADD((*pause_bmp), port); 61048 } 61049 BCM_IF_ERROR_RETURN 61050 (bcm_esw_port_pause_set(unit, port, txp, 0)); 61051 61052 } 61053 61054 speed = si->port_init_speed[port]; 61055 if (speed == 0) { 61056 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed)); 61057 } 61058 PORT_LOCK(unit); 61059 rv = soc_mv2_port_asf_mode_set(unit, port, speed, mode); 61060 PORT_UNLOCK(unit); 61061 61062 /* Update Pause for ASF mode */ 61063 if (((rv != SOC_E_NONE) && (_SOC_MV2_ASF_MODE_SAF != mode)) || 61064 ((rv == SOC_E_NONE) && (_SOC_MV2_ASF_MODE_SAF == mode))) { 61065 /* restore pause */ 61066 if (SOC_PBMP_MEMBER((*pause_bmp), port)) { 61067 BCM_IF_ERROR_RETURN 61068 (bcm_esw_port_pause_get(unit, port, &txp, &rxp)); 61069 BCM_IF_ERROR_RETURN 61070 (bcm_esw_port_pause_set(unit, port, txp, 1)); 61071 SOC_PBMP_PORT_REMOVE((*pause_bmp), port); 61072 } 61073 } 61074 61075 return rv; 61076 } 61077 #endif 61078 61079 #ifdef BCM_TRIDENT3_SUPPORT 61080 /** 61081 * Function: 61082 * _bcm_esw_td3_asf_init 61083 * Purpose: 61084 * Initialize ASF subsystem and configure all the applicable ports 61085 * to the specified forwarding mode 61086 * Parameters: 61087 * unit - (IN) Unit number. 61088 * mode - (IN) forwarding mode 61089 * Returns: 61090 * BCM_E_xxx 61091 */ 61092 STATIC int 61093 _bcm_esw_td3_asf_init( 61094 int unit, 61095 soc_td3_asf_mode_e asf_mode) 61096 { 61097 bcm_port_t port; 61098 int speed; 61099 soc_info_t *si; 61100 61101 if (!(si = &SOC_INFO(unit))) { 61102 return BCM_E_INTERNAL; 61103 } 61104 61105 BCM_IF_ERROR_RETURN(soc_td3_asf_init_start(unit)); 61106 61107 PBMP_ALL_ITER(unit, port) { 61108 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 61109 continue; 61110 } 61111 speed = si->port_init_speed[port]; 61112 if (speed == 0) { 61113 BCM_IF_ERROR_RETURN( 61114 bcm_esw_port_speed_get(unit, port, &speed)); 61115 } 61116 BCM_IF_ERROR_RETURN( 61117 soc_td3_port_asf_init(unit, port, speed, asf_mode)); 61118 } 61119 BCM_IF_ERROR_RETURN(soc_td3_asf_init_done(unit)); 61120 61121 return BCM_E_NONE; 61122 } 61123 61124 STATIC int 61125 _bcm_esw_td3_port_asf_mode_set( 61126 int unit, 61127 bcm_port_t port, 61128 int mode) 61129 { 61130 int rv = BCM_E_NONE, speed; 61131 soc_info_t *si; 61132 int txp = 0, rxp = 0; 61133 pbmp_t *pause_bmp; 61134 61135 if (!(si = &SOC_INFO(unit))) { 61136 return SOC_E_INTERNAL; 61137 } 61138 61139 pause_bmp = soc_td3_port_asf_pause_bpmp_get(unit); 61140 if (pause_bmp == NULL) { 61141 return BCM_E_INTERNAL; 61142 } 61143 61144 /* Update Pause for ASF mode */ 61145 if (_SOC_TD3_ASF_MODE_SAF != mode) { 61146 /* Disable rx pause for cut through */ 61147 BCM_IF_ERROR_RETURN 61148 (bcm_esw_port_pause_get(unit, port, &txp, &rxp)); 61149 61150 if (rxp) { 61151 SOC_PBMP_PORT_ADD((*pause_bmp), port); 61152 } 61153 BCM_IF_ERROR_RETURN 61154 (bcm_esw_port_pause_set(unit, port, txp, 0)); 61155 61156 } 61157 61158 speed = si->port_init_speed[port]; 61159 if (speed == 0) { 61160 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed)); 61161 } 61162 PORT_LOCK(unit); 61163 rv = soc_td3_port_asf_mode_set(unit, port, speed, mode); 61164 PORT_UNLOCK(unit); 61165 61166 /* Update Pause for ASF mode */ 61167 if (((rv != SOC_E_NONE) && (_SOC_TD3_ASF_MODE_SAF != mode)) || 61168 ((rv == SOC_E_NONE) && (_SOC_TD3_ASF_MODE_SAF == mode))) { 61169 /* restore pause */ 61170 if (SOC_PBMP_MEMBER((*pause_bmp), port)) { 61171 BCM_IF_ERROR_RETURN 61172 (bcm_esw_port_pause_get(unit, port, &txp, &rxp)); 61173 BCM_IF_ERROR_RETURN 61174 (bcm_esw_port_pause_set(unit, port, txp, 1)); 61175 SOC_PBMP_PORT_REMOVE((*pause_bmp), port); 61176 } 61177 } 61178 61179 return rv; 61180 } 61181 #endif 61182 61183 #if defined(BCM_TOMAHAWK_SUPPORT) 61184 /* ASF (Cut-thru Forwarding) */ 61185 61186 /** 61187 * Function: 61188 * _bcm_esw_asf_init 61189 * Purpose: 61190 * Initialize ASF subsystem and configure all the applicable ports 61191 * to the specified forwarding mode 61192 * Parameters: 61193 * unit - (IN) Unit number. 61194 * mode - (IN) forwarding mode 61195 * Returns: 61196 * BCM_E_xxx 61197 */ 61198 STATIC int 61199 _bcm_esw_asf_init( 61200 int unit, 61201 soc_th_asf_mode_e asf_mode) 61202 { 61203 bcm_port_t port; 61204 int speed; 61205 soc_info_t *si; 61206 61207 if (!(si = &SOC_INFO(unit))) { 61208 return SOC_E_INTERNAL; 61209 } 61210 61211 if (!soc_feature(unit, soc_feature_asf_multimode)) { 61212 return BCM_E_UNAVAIL; 61213 } 61214 61215 #ifdef BCM_WARM_BOOT_SUPPORT 61216 if (SOC_WARM_BOOT(unit)) { 61217 /* WB recovery happens in _bcm_esw_port_wb_recover context */ 61218 return BCM_E_NONE; 61219 } 61220 #endif /* BCM_WARM_BOOT_SUPPORT */ 61221 61222 #ifdef BCM_TOMAHAWK3_SUPPORT 61223 if (SOC_IS_TOMAHAWK3(unit)) { 61224 return soc_th3_asf_init(unit); 61225 } else 61226 #endif 61227 { 61228 BCM_IF_ERROR_RETURN(soc_th_asf_init_start(unit)); 61229 61230 PBMP_ALL_ITER(unit, port) { 61231 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 61232 continue; 61233 } 61234 speed = si->port_init_speed[port]; 61235 BCM_IF_ERROR_RETURN( 61236 soc_th_port_asf_init(unit, port, speed, asf_mode)); 61237 } 61238 BCM_IF_ERROR_RETURN(soc_th_asf_init_done(unit)); 61239 } 61240 61241 return BCM_E_NONE; 61242 } 61243 61244 /** 61245 * Function: 61246 * _bcm_esw_asf_deinit 61247 * Purpose: 61248 * Deinitialize ASF subsystem and release ASF internal structures 61249 * Parameters: 61250 * unit - (IN) Unit number. 61251 * Returns: 61252 * BCM_E_xxx 61253 */ 61254 STATIC int 61255 _bcm_esw_asf_deinit(int unit) 61256 { 61257 #ifdef BCM_TRIDENT3_SUPPORT 61258 if (SOC_IS_TRIDENT3X(unit)) { 61259 return soc_td3_asf_deinit(unit); 61260 } else 61261 #endif 61262 #ifdef BCM_TOMAHAWK3_SUPPORT 61263 if (SOC_IS_TOMAHAWK3(unit)) { 61264 return soc_th3_asf_deinit(unit); 61265 } else 61266 #endif 61267 { 61268 if (SOC_IS_TOMAHAWKX(unit)) { 61269 return soc_th_asf_deinit(unit); 61270 } 61271 } 61272 61273 return BCM_E_NONE; 61274 } 61275 61276 #ifdef BCM_WARM_BOOT_SUPPORT 61277 /** 61278 * Function: 61279 * bcm_esw_asf_wb_memsz_get 61280 * Purpose: 61281 * Returns the WB Memory requirement from ASF subsystem 61282 * Parameters: 61283 * unit - (IN) Unit number 61284 * mem_sz - (OUT) WB Memory required in bytes 61285 * Returns: 61286 * BCM_E_xxx 61287 */ 61288 STATIC int 61289 _bcm_esw_asf_wb_memsz_get( 61290 int unit, 61291 OUT uint32* const mem_sz, 61292 uint16 scache_ver) 61293 { 61294 int rv; 61295 61296 if (soc_feature(unit, soc_feature_asf_multimode)) { 61297 #ifdef BCM_MAVERICK2_SUPPORT 61298 if (SOC_IS_MAVERICK2(unit)) { 61299 rv = soc_mv2_asf_wb_memsz_get(unit, mem_sz, scache_ver); 61300 } else 61301 #endif 61302 #ifdef BCM_TRIDENT3_SUPPORT 61303 if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_MAVERICK2(unit)) { 61304 rv = soc_td3_asf_wb_memsz_get(unit, mem_sz, scache_ver); 61305 } else 61306 #endif 61307 #ifdef BCM_TOMAHAWK3_SUPPORT 61308 if (SOC_IS_TOMAHAWK3(unit)) { 61309 rv = soc_th3_asf_wb_memsz_get(unit, mem_sz, scache_ver); 61310 } else 61311 #endif 61312 if (SOC_IS_TOMAHAWKX(unit)) { 61313 rv = soc_th_asf_wb_memsz_get(unit, mem_sz, scache_ver); 61314 } else { 61315 *mem_sz = 0; 61316 rv = BCM_E_NONE; 61317 } 61318 } else { 61319 *mem_sz = 0; 61320 rv = BCM_E_NONE; 61321 } 61322 61323 return rv; 61324 } 61325 61326 /** 61327 * Function: 61328 * _bcm_esw_asf_wb_sync 61329 * Purpose: 61330 * ASF Warmboot Sync 61331 * Parameters: 61332 * unit - (IN) Unit number 61333 * wb_data - (IN/OUT) ptr to ASF WB data area 61334 * Returns: 61335 * BCM_E_xxx 61336 */ 61337 STATIC int 61338 _bcm_esw_asf_wb_sync( 61339 int unit, 61340 IN_OUT uint8* wb_data) 61341 { 61342 int rv; 61343 61344 if (soc_feature(unit, soc_feature_asf_multimode)) { 61345 #ifdef BCM_MAVERICK2_SUPPORT 61346 if (SOC_IS_MAVERICK2(unit)) { 61347 rv = soc_mv2_asf_wb_sync(unit, wb_data); 61348 } else 61349 #endif 61350 #ifdef BCM_TRIDENT3_SUPPORT 61351 if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_MAVERICK2(unit)) { 61352 rv = soc_td3_asf_wb_sync(unit, wb_data); 61353 } else 61354 #endif 61355 #ifdef BCM_TOMAHAWK3_SUPPORT 61356 if (SOC_IS_TOMAHAWK3(unit)) { 61357 rv = soc_th3_asf_wb_sync(unit, wb_data); 61358 } else 61359 #endif 61360 61361 if (SOC_IS_TOMAHAWKX(unit)) { 61362 rv = soc_th_asf_wb_sync(unit, wb_data); 61363 } else { 61364 rv = BCM_E_NONE; 61365 } 61366 } else { 61367 rv = BCM_E_NONE; 61368 } 61369 61370 return rv; 61371 } 61372 61373 /** 61374 * Function: 61375 * _bcm_esw_asf_wb_recover 61376 * Purpose: 61377 * ASF Warmboot Recovery 61378 * Parameters: 61379 * unit - (IN) Unit number 61380 * wb_data - (IN) pointer to ASF WB data area 61381 * Returns: 61382 * BCM_E_xxx 61383 */ 61384 STATIC int 61385 _bcm_esw_asf_wb_recover( 61386 int unit, 61387 uint8* const wb_data, 61388 uint16 scache_ver) 61389 { 61390 int rv; 61391 61392 if (soc_feature(unit, soc_feature_asf_multimode)) { 61393 #ifdef BCM_MAVERICK2_SUPPORT 61394 if (SOC_IS_MAVERICK2(unit)) { 61395 rv = soc_mv2_asf_wb_recover(unit, wb_data, scache_ver); 61396 } else 61397 #endif 61398 #ifdef BCM_TRIDENT3_SUPPORT 61399 if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_MAVERICK2(unit)) { 61400 rv = soc_td3_asf_wb_recover(unit, wb_data, scache_ver); 61401 } else 61402 #endif 61403 #ifdef BCM_TOMAHAWK3_SUPPORT 61404 if (SOC_IS_TOMAHAWK3(unit)) { 61405 rv = soc_th3_asf_wb_recover(unit, wb_data, scache_ver); 61406 } else 61407 #endif 61408 61409 if (SOC_IS_TOMAHAWKX(unit)) { 61410 rv = soc_th_asf_wb_recover(unit, wb_data, scache_ver); 61411 } else { 61412 rv = BCM_E_NONE; 61413 } 61414 } else { 61415 rv = BCM_E_NONE; 61416 } 61417 61418 return rv; 61419 } 61420 #endif /* BCM_WARMBOOT_SUPPORT */ 61421 61422 /** 61423 * Function: 61424 * bcm_esw_port_asf_mode_get 61425 * Purpose: 61426 * Returns the forwarding mode configured on the specified port 61427 * Parameters: 61428 * unit - (IN) Unit number 61429 * port - (IN) Logical port 61430 * mode - (OUT) SAF/ASF mode configured on the port 61431 * 0=SAF, 1=ASF(Same Speed), 2=ASF(Slow to Fast) 61432 * 3=ASF (Fast to Slow) 61433 * Returns: 61434 * BCM_E_xxx 61435 */ 61436 int 61437 bcm_esw_port_asf_mode_get( 61438 int unit, 61439 bcm_port_t port, 61440 OUT int* const mode) 61441 { 61442 int rv = BCM_E_UNAVAIL, speed; 61443 soc_info_t *si; 61444 61445 if (!(si = &SOC_INFO(unit))) { 61446 return SOC_E_INTERNAL; 61447 } 61448 61449 /* Make sure port module is initialized. */ 61450 PORT_INIT(unit); 61451 if (!soc_feature(unit, soc_feature_asf_multimode)) { 61452 return BCM_E_UNAVAIL; 61453 } 61454 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 61455 speed = si->port_init_speed[port]; 61456 61457 PORT_LOCK(unit); 61458 #ifdef BCM_MAVERICK2_SUPPORT 61459 if (SOC_IS_MAVERICK2(unit)) { 61460 rv = soc_mv2_port_asf_mode_get(unit, port, speed, 61461 (soc_mv2_asf_mode_e *) mode ); 61462 } else 61463 #endif 61464 #ifdef BCM_TRIDENT3_SUPPORT 61465 if (SOC_IS_TRIDENT3X(unit)) { 61466 rv = soc_td3_port_asf_mode_get(unit, port, speed, 61467 (soc_td3_asf_mode_e *) mode); 61468 } else 61469 #endif 61470 61471 #ifdef BCM_TOMAHAWK3_SUPPORT 61472 if (SOC_IS_TOMAHAWK3(unit)) { 61473 rv = soc_th3_port_asf_mode_get(unit, port, speed, 61474 (soc_th3_asf_mode_t *) mode); 61475 } else 61476 #endif 61477 if (SOC_IS_TOMAHAWKX(unit)) { 61478 rv = soc_th_port_asf_mode_get(unit, port, speed, 61479 (soc_th_asf_mode_e *) mode); 61480 } 61481 PORT_UNLOCK(unit); 61482 61483 return rv; 61484 } 61485 61486 /** 61487 * Function: 61488 * bcm_esw_port_asf_mode_set 61489 * Purpose: 61490 * Configure specified SAF/ASF mode on the given port 61491 * Parameters: 61492 * unit - (IN) Unit number 61493 * port - (IN) Logical port 61494 * mode - (IN) Forwarding mode to be configured on the port 61495 * 0=SAF, 1=ASF(Same Speed), 2=ASF(Slow to Fast) 61496 * 3=ASF (Fast to Slow) 61497 * Returns: 61498 * BCM_E_xxx 61499 */ 61500 int 61501 bcm_esw_port_asf_mode_set( 61502 int unit, 61503 bcm_port_t port, 61504 int mode) 61505 { 61506 int rv = BCM_E_UNAVAIL, speed = 0; 61507 soc_info_t *si; 61508 #if defined(BCM_TOMAHAWK2_SUPPORT) 61509 int txp = 0, rxp = 0; 61510 pbmp_t *pause_bmp = NULL; 61511 #endif /* BCM_TOMAHAWK2_SUPPORT */ 61512 61513 if (!(si = &SOC_INFO(unit))) { 61514 return SOC_E_INTERNAL; 61515 } 61516 61517 /* Make sure port module is initialized. */ 61518 PORT_INIT(unit); 61519 if (!soc_feature(unit, soc_feature_asf_multimode)) { 61520 return BCM_E_UNAVAIL; 61521 } 61522 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 61523 61524 #if defined(BCM_TOMAHAWK2_SUPPORT) 61525 /* Update Pause for ASF mode */ 61526 if (SOC_IS_TOMAHAWK2(unit)) { 61527 pause_bmp = soc_th_port_asf_pause_bpmp_get(unit); 61528 if (pause_bmp == NULL) { 61529 return BCM_E_INTERNAL; 61530 } 61531 61532 if (_SOC_TH_ASF_MODE_SAF != mode) { 61533 /* Disable rx pause for cut through */ 61534 BCM_IF_ERROR_RETURN 61535 (bcm_esw_port_pause_get(unit, port, &txp, &rxp)); 61536 61537 if (rxp) { 61538 SOC_PBMP_PORT_ADD((*pause_bmp), port); 61539 } 61540 BCM_IF_ERROR_RETURN 61541 (bcm_esw_port_pause_set(unit, port, txp, 0)); 61542 } 61543 } 61544 #endif /* BCM_TOMAHAWK2_SUPPORT */ 61545 61546 #ifdef BCM_MAVERICK2_SUPPORT 61547 if (SOC_IS_MAVERICK2(unit)) { 61548 rv = _bcm_esw_mv2_port_asf_mode_set(unit, port, mode); 61549 } else 61550 #endif 61551 #ifdef BCM_TRIDENT3_SUPPORT 61552 if (SOC_IS_TRIDENT3X(unit)) { 61553 rv = _bcm_esw_td3_port_asf_mode_set(unit, port, mode); 61554 } else 61555 #endif 61556 #ifdef BCM_TOMAHAWK3_SUPPORT 61557 if(SOC_IS_TOMAHAWK3(unit)) { 61558 if (mode >= 2) { 61559 return BCM_E_PARAM; 61560 } 61561 speed = si->port_init_speed[port]; 61562 PORT_LOCK(unit); 61563 rv = soc_th3_port_asf_mode_set(unit, port, speed, mode); 61564 PORT_UNLOCK(unit); 61565 } else 61566 #endif 61567 { 61568 speed = si->port_init_speed[port]; 61569 PORT_LOCK(unit); 61570 rv = soc_th_port_asf_mode_set(unit, port, speed, mode); 61571 PORT_UNLOCK(unit); 61572 } 61573 61574 #if defined(BCM_TOMAHAWK2_SUPPORT) 61575 /* Update Pause for ASF mode */ 61576 if (SOC_IS_TOMAHAWK2(unit)) { 61577 if (_SOC_TH_ASF_MODE_SAF == mode) { /* SAF */ 61578 /* restore pause */ 61579 if (SOC_PBMP_MEMBER((*pause_bmp), port)) { 61580 BCM_IF_ERROR_RETURN 61581 (bcm_esw_port_pause_get(unit, port, &txp, &rxp)); 61582 BCM_IF_ERROR_RETURN 61583 (bcm_esw_port_pause_set(unit, port, txp, 1)); 61584 SOC_PBMP_PORT_REMOVE((*pause_bmp), port); 61585 } 61586 } 61587 } 61588 #endif /* BCM_TOMAHAWK2_SUPPORT */ 61589 61590 return rv; 61591 } 61592 61593 /** 61594 * Function: 61595 * bcm_esw_asf_diag 61596 * Purpose: 61597 * Dump all ASF configurations specific to the unit 61598 * Parameters: 61599 * unit - (IN) Unit number 61600 * Returns: 61601 * BCM_E_xxx 61602 */ 61603 int 61604 bcm_esw_asf_diag(int unit) 61605 { 61606 /* Make sure port module is initialized. */ 61607 PORT_INIT(unit); 61608 if (!soc_feature(unit, soc_feature_asf_multimode)) { 61609 return BCM_E_UNAVAIL; 61610 } 61611 61612 #ifdef BCM_MAVERICK2_SUPPORT 61613 if (SOC_IS_MAVERICK2(unit)) { 61614 return soc_mv2_asf_config_dump(unit); 61615 } else 61616 #endif 61617 #ifdef BCM_TRIDENT3_SUPPORT 61618 if (SOC_IS_TRIDENT3X(unit)) { 61619 return soc_td3_asf_config_dump(unit); 61620 } else 61621 #endif 61622 #ifdef BCM_TOMAHAWK3_SUPPORT 61623 if(SOC_IS_TOMAHAWK3(unit)) { 61624 return soc_th3_asf_config_dump(unit); 61625 } else 61626 #endif 61627 if (SOC_IS_TOMAHAWKX(unit)) { 61628 return soc_th_asf_config_dump(unit); 61629 } 61630 61631 return BCM_E_UNAVAIL; 61632 } 61633 61634 /** 61635 * Function: 61636 * bcm_esw_port_asf_show 61637 * Purpose: 61638 * Display formatted ASF information for a port 61639 * Parameters: 61640 * unit - (IN) Unit number 61641 * port - (IN) Logical port 61642 * Returns: 61643 * BCM_E_xxx 61644 */ 61645 int 61646 bcm_esw_port_asf_show( 61647 int unit, 61648 bcm_port_t port) 61649 { 61650 int speed; 61651 soc_info_t *si; 61652 61653 if (!(si = &SOC_INFO(unit))) { 61654 return SOC_E_INTERNAL; 61655 } 61656 61657 /* Make sure port module is initialized. */ 61658 PORT_INIT(unit); 61659 if (!soc_feature(unit, soc_feature_asf_multimode)) { 61660 return BCM_E_UNAVAIL; 61661 } 61662 if(!SOC_IS_TOMAHAWK3(unit)) { 61663 61664 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed)); 61665 } else { 61666 speed = si->port_init_speed[port]; 61667 } 61668 #ifdef BCM_MAVERICK2_SUPPORT 61669 if (SOC_IS_MAVERICK2(unit)) { 61670 return soc_mv2_port_asf_show(unit, port, speed); 61671 } else 61672 #endif 61673 #ifdef BCM_TRIDENT3_SUPPORT 61674 if (SOC_IS_TRIDENT3X(unit)) { 61675 return soc_td3_port_asf_show(unit, port, speed); 61676 } else 61677 #endif 61678 #ifdef BCM_TOMAHAWK3_SUPPORT 61679 if(SOC_IS_TOMAHAWK3(unit)) { 61680 return soc_th3_port_asf_show(unit, port, speed); 61681 } else 61682 #endif 61683 if (SOC_IS_TOMAHAWKX(unit)) { 61684 return soc_th_port_asf_show(unit, port, speed); 61685 } 61686 61687 return BCM_E_UNAVAIL; 61688 } 61689 61690 /** 61691 * Function: 61692 * bcm_esw_port_asf_diag 61693 * Purpose: 61694 * Dump all related ASF configurations for the given port 61695 * Parameters: 61696 * unit - (IN) Unit number 61697 * port - (IN) Logical port 61698 * Returns: 61699 * BCM_E_xxx 61700 */ 61701 int 61702 bcm_esw_port_asf_diag( 61703 int unit, 61704 bcm_port_t port) 61705 { 61706 int speed; 61707 soc_info_t *si; 61708 61709 if (!(si = &SOC_INFO(unit))) { 61710 return SOC_E_INTERNAL; 61711 } 61712 61713 /* Make sure port module is initialized. */ 61714 PORT_INIT(unit); 61715 if (!soc_feature(unit, soc_feature_asf_multimode)) { 61716 return BCM_E_UNAVAIL; 61717 } 61718 if(!SOC_IS_TOMAHAWK3(unit)) { 61719 61720 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed)); 61721 } else { 61722 speed = si->port_init_speed[port]; 61723 } 61724 #ifdef BCM_MAVERICK2_SUPPORT 61725 if (SOC_IS_MAVERICK2(unit)) { 61726 return soc_mv2_port_asf_config_dump(unit, port, speed); 61727 } else 61728 #endif 61729 #ifdef BCM_TRIDENT3_SUPPORT 61730 if (SOC_IS_TRIDENT3X(unit)) { 61731 return soc_td3_port_asf_config_dump(unit, port, speed); 61732 } else 61733 #endif 61734 #ifdef BCM_TOMAHAWK3_SUPPORT 61735 if (SOC_IS_TOMAHAWK3(unit)) { 61736 return soc_th3_port_asf_config_dump(unit, port, speed); 61737 } else 61738 #endif 61739 if (SOC_IS_TOMAHAWKX(unit)) { 61740 return soc_th_port_asf_config_dump(unit, port, speed); 61741 } 61742 61743 return BCM_E_UNAVAIL; 61744 } 61745 #endif /* BCM_TOMAHAWK_SUPPORT */ 61746 61747 /** 61748 * Function : 61749 * _bcm_esw_port_sw_info_display 61750 * Purpose: 61751 * To display status of port related software structures 61752 * Parameters: 61753 * unit - (IN) Unit number 61754 * port - (IN) Port number 61755 * Returns : 61756 * BCM_E_xxxx 61757 * Note: 61758 * Implementation currently limited to KATANA2 and SABER2 ONLY 61759 */ 61760 int 61761 _bcm_esw_port_sw_info_display(int unit, bcm_port_t port) 61762 { 61763 #ifdef BCM_METROLITE_SUPPORT 61764 if (SOC_IS_METROLITE(unit)) { 61765 BCM_IF_ERROR_RETURN(_bcm_ml_port_sw_info_display(unit, port)); 61766 } else 61767 #endif 61768 #ifdef BCM_SABER2_SUPPORT 61769 if (SOC_IS_SABER2(unit)) { 61770 BCM_IF_ERROR_RETURN(_bcm_sb2_port_sw_info_display(unit, port)); 61771 } else 61772 #endif 61773 #ifdef BCM_KATANA2_SUPPORT 61774 if (SOC_IS_KATANA2(unit)) { 61775 BCM_IF_ERROR_RETURN(_bcm_kt2_port_sw_info_display(unit, port)); 61776 } else 61777 #endif 61778 { 61779 LOG_ERROR(BSL_LS_BCM_PORT, 61780 (BSL_META_U(unit, 61781 "_bcm_esw_port_sw_info_display \ 61782 implementation not implemented\n"))); 61783 return SOC_E_UNIT; 61784 } 61785 61786 return BCM_E_NONE; 61787 } 61788 61789 /** 61790 * Function : 61791 * _bcm_esw_port_hw_info_display 61792 * Purpose: 61793 * To display status of port related harware registers. 61794 * Parameters: 61795 * unit - (IN) Unit number. 61796 * port - (IN) Port number 61797 * Returns: 61798 * BCM_E_xxxx 61799 * Notes: 61800 * Implementation currently limited to KATANA2 and SABER2 ONLY 61801 */ 61802 int 61803 _bcm_esw_port_hw_info_display(int unit, bcm_port_t port) 61804 { 61805 #ifdef BCM_METROLITE_SUPPORT 61806 if (SOC_IS_METROLITE(unit)) { 61807 BCM_IF_ERROR_RETURN(_bcm_ml_port_hw_info_display(unit, port)); 61808 } else 61809 #endif 61810 #ifdef BCM_SABER2_SUPPORT 61811 if (SOC_IS_SABER2(unit)) { 61812 BCM_IF_ERROR_RETURN(_bcm_sb2_port_hw_info_display(unit, port)); 61813 } else 61814 #endif 61815 #ifdef BCM_KATANA2_SUPPORT 61816 if (SOC_IS_KATANA2(unit)) { 61817 BCM_IF_ERROR_RETURN(_bcm_kt2_port_hw_info_display(unit, port)); 61818 } else 61819 #endif 61820 { 61821 LOG_ERROR(BSL_LS_BCM_PORT, 61822 (BSL_META_U(unit, 61823 "_bcm_esw_port_hw_info_display \ 61824 implementation not implemented\n"))); 61825 return SOC_E_UNIT; 61826 } 61827 61828 return BCM_E_NONE; 61829 } 61830 61831 /* 61832 * Function: 61833 * bcmi_esw_port_resource_portmod_support_check 61834 * Purpose: 61835 * - Validates if all ports in resource array are supported by portmod 61836 * Parameters: 61837 * unit - (IN) Unit number. 61838 * nport - (IN) Number of logical port. 61839 * resource - (IN) Port resource configuration. 61840 * Returns: 61841 * BCM_E_XXX 61842 */ 61843 int 61844 bcmi_esw_port_resource_portmod_support_check(int unit, 61845 int nport, 61846 bcm_port_resource_t *res) 61847 { 61848 #if defined(BCM_XGS5_SWITCH_PORT_SUPPORT) && \ 61849 defined(BCM_MIXED_LEGACY_AND_PORTMOD_SUPPORT) 61850 int idx, port; 61851 int rv = BCM_E_NONE; 61852 61853 if (soc_feature(unit, soc_feature_mixed_legacy_and_portmod)) { 61854 if ((nport < 0) || (nport > SOC_MAX_NUM_PORTS)) { 61855 return BCM_E_PARAM; 61856 } 61857 61858 if (res == NULL) { 61859 return BCM_E_PARAM; 61860 } 61861 61862 for (idx = 0; idx < nport; idx++) { 61863 rv = bcmi_xgs5_port_addressable_local_get(unit, res[idx].port, 61864 &port); 61865 if (BCM_SUCCESS(rv)) { 61866 if (SOC_IS_HURRICANE4(unit) && IS_EGPHY_PORT(unit, port)) { 61867 return BCM_E_PARAM; 61868 } 61869 } 61870 } 61871 } 61872 #endif 61873 return BCM_E_NONE; 61874 } 61875 61876 /* 61877 * Function: 61878 * bcm_esw_port_resource_set 61879 * Purpose: 61880 * Modify the following port resources: 61881 * - Logical to physical port mapping 61882 * - Speed 61883 * - Number of PHY lanes 61884 * - Encapsulation mode 61885 * Parameters: 61886 * unit - (IN) Unit number. 61887 * port - (IN) Logical port. 61888 * resource - (IN) Port resource configuration. 61889 * Returns: 61890 * BCM_E_XXX 61891 */ 61892 int 61893 bcm_esw_port_resource_set(int unit, 61894 bcm_gport_t port, bcm_port_resource_t *resource) 61895 { 61896 int rv = BCM_E_UNAVAIL; 61897 61898 PORT_INIT(unit); 61899 61900 PORT_LOCK(unit); 61901 61902 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 61903 if (BCM_ESW_PORT_DRV(unit)->resource_set != NULL) { 61904 rv = bcmi_esw_port_resource_portmod_support_check(unit, 61905 1, resource); 61906 if (BCM_SUCCESS(rv)) { 61907 rv = BCM_ESW_PORT_DRV(unit)->resource_set(unit, port, resource); 61908 } 61909 } 61910 } 61911 61912 if (BCM_SUCCESS(rv) && (BCM_ESW_PORT_DRV(unit)->resource_status_update != NULL)) { 61913 BCM_ESW_PORT_DRV(unit)->resource_status_update(unit, 1, resource); 61914 } 61915 61916 PORT_UNLOCK(unit); 61917 61918 return rv; 61919 } 61920 61921 61922 /* 61923 * Function: 61924 * bcm_esw_port_resource_get 61925 * Purpose: 61926 * Get the port resource configuration for the specified logical port. 61927 * Parameters: 61928 * unit - (IN) Unit number. 61929 * port - (IN) Logical port. 61930 * resource - (OUT) Returns port resource information. 61931 * Returns: 61932 * BCM_E_XXX 61933 */ 61934 int 61935 bcm_esw_port_resource_get(int unit, 61936 bcm_gport_t port, bcm_port_resource_t *resource) 61937 { 61938 int rv = BCM_E_UNAVAIL; 61939 61940 PORT_INIT(unit); 61941 61942 PORT_LOCK(unit); 61943 61944 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 61945 if (BCM_ESW_PORT_DRV(unit)->resource_get != NULL) { 61946 rv = BCM_ESW_PORT_DRV(unit)->resource_get(unit, port, resource); 61947 } 61948 } 61949 61950 PORT_UNLOCK(unit); 61951 61952 return rv; 61953 } 61954 61955 /* 61956 * Function: 61957 * bcm_esw_port_resource_multi_set 61958 * Purpose: 61959 * Modify the following port resources: 61960 * - Logical to physical port mapping 61961 * - Speedu 61962 * - Number of PHY lanes 61963 * - Encapsulation mode 61964 * Parameters: 61965 * unit - (IN) Unit number. 61966 * nport - (IN) Number of elements in array resource. 61967 * resource - (IN) Port resource configuration array. 61968 * Returns: 61969 * BCM_E_XXX 61970 */ 61971 int 61972 bcm_esw_port_resource_multi_set(int unit, 61973 int nport, bcm_port_resource_t *resource) 61974 { 61975 int rv = BCM_E_UNAVAIL; 61976 61977 PORT_INIT(unit); 61978 61979 PORT_LOCK(unit); 61980 61981 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 61982 if (BCM_ESW_PORT_DRV(unit)->resource_multi_set != NULL) { 61983 rv = bcmi_esw_port_resource_portmod_support_check(unit, 61984 nport, resource); 61985 if (BCM_SUCCESS(rv)) { 61986 rv = BCM_ESW_PORT_DRV(unit)->resource_multi_set(unit, nport, 61987 resource); 61988 } 61989 } 61990 } 61991 61992 if (BCM_SUCCESS(rv) && (BCM_ESW_PORT_DRV(unit)->resource_status_update != NULL)) { 61993 BCM_ESW_PORT_DRV(unit)->resource_status_update(unit, nport, resource); 61994 } 61995 61996 PORT_UNLOCK(unit); 61997 61998 return rv; 61999 } 62000 /* 62001 * Function: 62002 * bcm_esw_port_resource_speed_config_validate 62003 * Purpose: 62004 * Validate the resource configuration 62005 * Parameters: 62006 * unit - (IN) Unit number. 62007 * resource - (IN) Port resource information. 62008 * pbmp - (OUT) Returns the affected sister ports 62009 * Returns: 62010 * BCM_E_NONE - Config is honred without affecting sister ports 62011 * BCM_E_PARAM - Config will affect sister ports in pbmp 62012 */ 62013 int 62014 bcm_esw_port_resource_speed_config_validate(int unit, 62015 bcm_port_resource_t *resource, bcm_pbmp_t *pbmp) 62016 { 62017 int rv = BCM_E_UNAVAIL; 62018 62019 /* Make sure port module is initialized. */ 62020 PORT_INIT(unit); 62021 62022 /* Call Port Control module */ 62023 if (SOC_USE_PORTCTRL(unit)) { 62024 BCM_IF_ERROR_RETURN 62025 (bcmi_esw_port_resource_portmod_support_check(unit, 62026 1, resource)); 62027 rv = bcmi_esw_portctrl_resource_speed_config_validate(unit, 62028 resource, pbmp); 62029 } 62030 62031 return rv; 62032 } 62033 62034 /* 62035 * Function: 62036 * bcm_esw_port_resource_speed_get 62037 * Purpose: 62038 * Get the speed port resource configuration for the specified logical 62039 * port. 62040 * Parameters: 62041 * unit - (IN) Unit number. 62042 * port - (IN) Logical port. 62043 * resource - (OUT) Returns port resource information. 62044 * Returns: 62045 * BCM_E_XXX 62046 */ 62047 int 62048 bcm_esw_port_resource_speed_get(int unit, 62049 bcm_gport_t port, bcm_port_resource_t *resource) 62050 { 62051 int rv = BCM_E_UNAVAIL; 62052 62053 rv = bcm_esw_port_resource_get(unit, port, resource); 62054 62055 return rv; 62056 } 62057 62058 /* 62059 * Function: 62060 * bcm_esw_port_resource_speed_set 62061 * Purpose: 62062 * Modify the following port resources: 62063 * - Speed 62064 * Note: The parameter for this function will be used to derive the 62065 * associated physical port 62066 * Parameters: 62067 * unit - (IN) Unit number. 62068 * gport - (IN) Logical Port. 62069 * resource - (IN) Port resource configuration array. 62070 * Returns: 62071 * BCM_E_XXX 62072 */ 62073 int 62074 bcm_esw_port_resource_speed_set(int unit, 62075 bcm_gport_t port, bcm_port_resource_t *resource) 62076 { 62077 int rv = BCM_E_UNAVAIL; 62078 int lport; 62079 62080 if (NULL == resource) { 62081 return BCM_E_PARAM; 62082 } 62083 62084 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &lport)); 62085 62086 /* Use the passed in logical port to be consistent with port_speed_set */ 62087 resource->port = lport; 62088 62089 rv = bcm_esw_port_resource_speed_multi_set(unit, 1, resource); 62090 62091 return rv; 62092 } 62093 62094 /* 62095 * Function: 62096 * bcm_esw_port_resource_speed_multi_set 62097 * Purpose: 62098 * Modify the following port resources: 62099 * - Speed 62100 * Parameters: 62101 * unit - (IN) Unit number. 62102 * nport - (IN) Number of elements in array resource. 62103 * resource - (IN) Port resource configuration array. 62104 * Returns: 62105 * BCM_E_XXX 62106 */ 62107 int 62108 bcm_esw_port_resource_speed_multi_set(int unit, 62109 int nport, bcm_port_resource_t *resource) 62110 { 62111 int i, max_speed; 62112 pbmp_t pbm; 62113 int *enable; 62114 int rv = BCM_E_UNAVAIL; 62115 62116 62117 PORT_INIT(unit); 62118 62119 /* Do this check because we don't want to allocate 4 billion ints 62120 * if there's bad input 62121 */ 62122 if ((nport < 0) || (nport > SOC_MAX_NUM_PORTS)) { 62123 return BCM_E_PARAM; 62124 } 62125 62126 if (resource == NULL) { 62127 return BCM_E_PARAM; 62128 } 62129 62130 BCM_IF_ERROR_RETURN 62131 (bcmi_esw_port_resource_portmod_support_check(unit, 62132 nport, resource)); 62133 62134 enable = sal_alloc(nport * sizeof(int), "port enable array"); 62135 if (NULL == enable) { 62136 return BCM_E_MEMORY; 62137 } 62138 62139 /* Iterate through each entry and do some sanity checks */ 62140 for (i = 0; i < nport; i++) { 62141 rv = (_bcm_esw_port_gport_validate(unit, 62142 resource[i].port, &resource[i].port)); 62143 if(!BCM_SUCCESS(rv)) { 62144 goto speed_multi_cleanup; 62145 } 62146 62147 rv = (bcm_esw_port_speed_max(unit,resource[i].port, &max_speed)); 62148 if(!BCM_SUCCESS(rv)) { 62149 goto speed_multi_cleanup; 62150 } 62151 62152 62153 if ((resource[i].speed < 0) || (resource[i].speed > max_speed)) { 62154 if ((resource[i].speed > max_speed) && 62155 !soc_feature(unit, soc_feature_flexport_based_speed_set)) 62156 rv = BCM_E_PARAM; 62157 if(!BCM_SUCCESS(rv)) { 62158 goto speed_multi_cleanup; 62159 } 62160 } 62161 62162 /* 62163 * When performing flexport based speed changes, disable port 62164 * first prior to affecting speed change, but keep track of whether 62165 * the port was enabled 62166 */ 62167 if (soc_feature(unit, soc_feature_flexport_based_speed_set) && 62168 !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), resource[i].port) && 62169 !SOC_PORT_USE_PORTCTRL(unit, resource[i].port)) { 62170 rv = (bcm_esw_port_enable_get(unit, 62171 resource[i].port, &enable[i])); 62172 if(!BCM_SUCCESS(rv)) { 62173 goto speed_multi_cleanup; 62174 } 62175 62176 if (TRUE == enable[i]) { 62177 rv = (bcm_esw_port_enable_set(unit, resource[i].port, FALSE)); 62178 if(!BCM_SUCCESS(rv)) { 62179 goto speed_multi_cleanup; 62180 } 62181 62182 } 62183 } 62184 62185 } 62186 PORT_LOCK(unit); 62187 rv = bcmi_esw_portctrl_speed_multi_set(unit, nport, resource); 62188 PORT_UNLOCK(unit); 62189 if(!BCM_SUCCESS(rv)) { 62190 goto speed_multi_cleanup; 62191 } 62192 62193 for (i = 0; i < nport; i++) { 62194 /* 62195 * Restore port's enable state based on what was read prior 62196 * to setting speed 62197 */ 62198 if (soc_feature(unit, soc_feature_flexport_based_speed_set) && 62199 !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), resource[i].port) && 62200 !SOC_PORT_USE_PORTCTRL(unit, resource[i].port)) { 62201 if (TRUE == enable[i]) { 62202 rv = bcm_esw_port_enable_set(unit, resource[i].port, TRUE); 62203 if(!BCM_SUCCESS(rv)) { 62204 goto speed_multi_cleanup; 62205 } 62206 } 62207 } 62208 62209 if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) { 62210 SOC_PBMP_CLEAR(pbm); 62211 SOC_PBMP_PORT_ADD(pbm, resource[i].port); 62212 (void)bcm_esw_link_change(unit, pbm); 62213 } 62214 62215 rv = _bcm_esw_port_link_delay_update(unit, resource[i].port, 62216 resource[i].speed); 62217 if(!BCM_SUCCESS(rv)) { 62218 goto speed_multi_cleanup; 62219 } 62220 } 62221 62222 62223 speed_multi_cleanup: 62224 if (NULL != enable) { 62225 sal_free(enable); 62226 } 62227 62228 return rv; 62229 } 62230 /* 62231 * Function: 62232 * bcm_esw_port_resource_traverse 62233 * Purpose: 62234 * Iterates over the port resource configurations on a given 62235 * unit and calls user-provided callback for every entry. 62236 * Parameters: 62237 * unit - (IN) Unit number. 62238 * trav_fn - (IN) Callback function to execute. 62239 * user_data - (IN) Pointer to any user data. 62240 * Returns: 62241 * BCM_E_XXX 62242 */ 62243 int 62244 bcm_esw_port_resource_traverse(int unit, 62245 bcm_port_resource_traverse_cb trav_fn, 62246 void *user_data) 62247 { 62248 int rv = BCM_E_UNAVAIL; 62249 62250 PORT_INIT(unit); 62251 62252 PORT_LOCK(unit); 62253 62254 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 62255 if (BCM_ESW_PORT_DRV(unit)->resource_traverse != NULL) { 62256 rv = BCM_ESW_PORT_DRV(unit)->resource_traverse(unit, trav_fn, 62257 user_data); 62258 } 62259 } 62260 62261 PORT_UNLOCK(unit); 62262 62263 return rv; 62264 } 62265 62266 /* 62267 * Function: 62268 * bcm_esw_port_priority_group_mapping_set 62269 * Purpose: 62270 * Assign a Priority Group for the input priority. 62271 * Parameters: 62272 * unit - (IN) device id. 62273 * gport - (IN) generic port. 62274 * prio - (IN) input priority. 62275 * priority_group - (IN) priority group ID that the input priority mapped to. 62276 * Returns: 62277 * BCM_E_XXX 62278 */ 62279 int 62280 bcm_esw_port_priority_group_mapping_set(int unit, bcm_gport_t gport, int prio, int priority_group) 62281 { 62282 int rv = BCM_E_UNAVAIL; 62283 62284 PORT_INIT(unit); 62285 if (soc_feature(unit, soc_feature_priority_flow_control)) { 62286 #ifdef BCM_SABER2_SUPPORT 62287 if (SOC_IS_SABER2(unit)) { 62288 return (bcm_kt2_port_priority_group_mapping_set(unit, gport, prio, priority_group)); 62289 } 62290 #endif 62291 #if defined(BCM_GREYHOUND_SUPPORT) 62292 if (soc_feature(unit, soc_feature_gh_style_pfc_config)) { 62293 return (bcm_gh_port_priority_group_mapping_set(unit, gport, prio, priority_group)); 62294 } 62295 #endif /* BCM_GREYHOUND_SUPPORT */ 62296 #if defined(BCM_TRIDENT3_SUPPORT) 62297 if (SOC_IS_TRIDENT3X(unit)) { 62298 return (bcm_td3_port_priority_group_mapping_set(unit, gport, prio, 62299 priority_group)); 62300 } 62301 #endif /* BCM_TRIDENT3_SUPPORT */ 62302 #if defined(BCM_TRIDENT2_SUPPORT) 62303 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 62304 SOC_IS_TITAN2X(unit)) { 62305 return (bcm_td2_port_priority_group_mapping_set(unit, gport, prio, 62306 priority_group)); 62307 } 62308 #endif /* BCM_TRIDENT2_SUPPORT */ 62309 #if defined(BCM_TOMAHAWK3_SUPPORT) 62310 if (SOC_IS_TOMAHAWK3(unit)) { 62311 return BCM_E_UNAVAIL; 62312 } 62313 #endif /* BCM_TOMAHAWK3_SUPPORT */ 62314 #if defined(BCM_TOMAHAWK_SUPPORT) 62315 if (SOC_IS_TOMAHAWKX(unit)) { 62316 return (bcm_th_port_priority_group_mapping_set(unit, gport, prio, 62317 priority_group)); 62318 } 62319 #endif /* BCM_TOMAHAWK_SUPPORT */ 62320 #if defined(BCM_APACHE_SUPPORT) 62321 if (SOC_IS_APACHE(unit)){ 62322 return (bcm_ap_port_priority_group_mapping_set(unit, gport, prio, 62323 priority_group)); 62324 } 62325 #endif 62326 } 62327 return rv; 62328 } 62329 62330 /* 62331 * Function: 62332 * bcm_esw_port_priority_group_mapping_get 62333 * Purpose: 62334 * Get the assigned Priority Group ID of the input priority. 62335 * Parameters: 62336 * unit - (IN) device id. 62337 * gport - (IN) generic port. 62338 * prio - (IN) input priority. 62339 * priority_group - (OUT) priority group ID that the input priority mapped to. 62340 * Returns: 62341 * BCM_E_XXX 62342 */ 62343 int 62344 bcm_esw_port_priority_group_mapping_get(int unit, bcm_gport_t gport, int prio, int *priority_group) 62345 { 62346 int rv = BCM_E_UNAVAIL; 62347 62348 PORT_INIT(unit); 62349 if (soc_feature(unit, soc_feature_priority_flow_control)) { 62350 #ifdef BCM_SABER2_SUPPORT 62351 if (SOC_IS_SABER2(unit)) { 62352 return (bcm_kt2_port_priority_group_mapping_get(unit, gport, prio, priority_group)); 62353 } 62354 #endif 62355 62356 #if defined(BCM_GREYHOUND_SUPPORT) 62357 if (soc_feature(unit, soc_feature_gh_style_pfc_config)) { 62358 return (bcm_gh_port_priority_group_mapping_get(unit, gport, prio, priority_group)); 62359 } 62360 #endif /* BCM_GREYHOUND_SUPPORT */ 62361 #if defined(BCM_TRIDENT3_SUPPORT) 62362 if (SOC_IS_TRIDENT3X(unit)) { 62363 return (bcm_td3_port_priority_group_mapping_get(unit, gport, prio, 62364 priority_group)); 62365 } 62366 #endif /* BCM_TRIDENT3_SUPPORT */ 62367 #if defined(BCM_TRIDENT2_SUPPORT) 62368 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 62369 SOC_IS_TITAN2X(unit)) { 62370 return (bcm_td2_port_priority_group_mapping_get(unit, gport, prio, 62371 priority_group)); 62372 } 62373 #endif /* BCM_TRIDENT2_SUPPORT */ 62374 #if defined(BCM_TOMAHAWK3_SUPPORT) 62375 if (SOC_IS_TOMAHAWK3(unit)) { 62376 return BCM_E_UNAVAIL; 62377 } 62378 #endif /* BCM_TOMAHAWK3_SUPPORT */ 62379 #if defined(BCM_TOMAHAWK_SUPPORT) 62380 if (SOC_IS_TOMAHAWKX(unit)) { 62381 return (bcm_th_port_priority_group_mapping_get(unit, gport, prio, 62382 priority_group)); 62383 } 62384 #endif /* BCM_TOMAHAWK_SUPPORT */ 62385 #if defined(BCM_APACHE_SUPPORT) 62386 if (SOC_IS_APACHE(unit)) { 62387 return (bcm_ap_port_priority_group_mapping_get(unit, gport, prio, 62388 priority_group)); 62389 } 62390 #endif 62391 } 62392 return rv; 62393 } 62394 62395 /* 62396 * Function: 62397 * bcm_esw_port_priority_group_config_set 62398 * Purpose: 62399 * Set the port priority group configuration. 62400 * Parameters: 62401 * unit - (IN) device id. 62402 * gport - (IN) generic port. 62403 * priority_group - (IN) priority group id. 62404 * prigrp_config - (IN) structure describes port priority group configuration. 62405 * Returns: 62406 * BCM_E_XXX 62407 */ 62408 int 62409 bcm_esw_port_priority_group_config_set(int unit, bcm_gport_t gport, int priority_group, bcm_port_priority_group_config_t *prigrp_config) 62410 { 62411 int rv = BCM_E_UNAVAIL; 62412 62413 PORT_INIT(unit); 62414 if (soc_feature(unit, soc_feature_priority_flow_control)) { 62415 #if defined(BCM_GREYHOUND_SUPPORT) 62416 if (soc_feature(unit, soc_feature_gh_style_pfc_config)) { 62417 return (bcm_gh_port_priority_group_config_set(unit, gport, priority_group, prigrp_config)); 62418 } 62419 #endif /* BCM_GREYHOUND_SUPPORT */ 62420 #if defined(BCM_TRIDENT3_SUPPORT) 62421 if (SOC_IS_TRIDENT3X(unit)) { 62422 return (bcm_td3_port_priority_group_config_set(unit, gport, 62423 priority_group, prigrp_config)); 62424 } 62425 #endif /* BCM_TRIDENT3_SUPPORT */ 62426 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 62427 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 62428 SOC_IS_TITAN2X(unit) || SOC_IS_MONTEREY(unit) || 62429 SOC_IS_APACHE(unit)) { 62430 if (SOC_PORT_USE_PORTCTRL(unit, gport)) { 62431 return bcmi_esw_portctrl_priority_group_config_set(unit, gport, 62432 priority_group, prigrp_config); 62433 } 62434 return (bcm_td2_port_priority_group_config_set(unit, gport, 62435 priority_group, prigrp_config)); 62436 } 62437 #endif /* BCM_TRIDENT2_SUPPORT */ 62438 #if defined(BCM_TOMAHAWK_SUPPORT) 62439 if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) { 62440 return (bcm_th_port_priority_group_config_set(unit, gport, 62441 priority_group, prigrp_config)); 62442 } 62443 #endif /* BCM_TOMAHAWK_SUPPORT */ 62444 62445 #if defined(BCM_TOMAHAWK3_SUPPORT) 62446 if(SOC_IS_TOMAHAWK3(unit)) { 62447 return (bcm_th3_port_priority_group_config_set(unit, gport, 62448 priority_group, prigrp_config)); 62449 } 62450 #endif 62451 62452 } 62453 return rv; 62454 } 62455 62456 /* 62457 * Function: 62458 * bcm_esw_port_priority_group_config_get 62459 * Purpose: 62460 * Get the port priority group configuration. 62461 * Parameters: 62462 * unit - (IN) device id. 62463 * gport - (IN) generic port. 62464 * priority_group - (IN) priority group id. 62465 * prigrp_config - (OUT) structure describes port priority group configuration. 62466 * Returns: 62467 * BCM_E_XXX 62468 */ 62469 int 62470 bcm_esw_port_priority_group_config_get(int unit, bcm_gport_t gport, int priority_group, bcm_port_priority_group_config_t *prigrp_config) 62471 { 62472 int rv = BCM_E_UNAVAIL; 62473 62474 PORT_INIT(unit); 62475 if (soc_feature(unit, soc_feature_priority_flow_control)) { 62476 #if defined(BCM_GREYHOUND_SUPPORT) 62477 if (soc_feature(unit, soc_feature_gh_style_pfc_config)) { 62478 return (bcm_gh_port_priority_group_config_get(unit, gport, priority_group, prigrp_config)); 62479 } 62480 #endif /* BCM_GREYHOUND_SUPPORT */ 62481 #if defined(BCM_TRIDENT3_SUPPORT) 62482 if (SOC_IS_TRIDENT3X(unit)) { 62483 return (bcm_td3_port_priority_group_config_get(unit, gport, 62484 priority_group, prigrp_config)); 62485 } 62486 #endif /* BCM_TRIDENT3_SUPPORT */ 62487 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 62488 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 62489 SOC_IS_TITAN2X(unit) || SOC_IS_MONTEREY(unit) || 62490 SOC_IS_APACHE(unit)) { 62491 return (bcm_td2_port_priority_group_config_get(unit, gport, 62492 priority_group, prigrp_config)); 62493 } 62494 #endif /* BCM_TRIDENT2_SUPPORT */ 62495 62496 #if defined(BCM_TOMAHAWK3_SUPPORT) 62497 if (SOC_IS_TOMAHAWK3(unit)) { 62498 return (bcm_th3_port_priority_group_config_get(unit, gport, 62499 priority_group, prigrp_config)); 62500 } 62501 #endif /* BCM_TOMAHAWK3_SUPPORT */ 62502 62503 #if defined(BCM_TOMAHAWK_SUPPORT) 62504 if (SOC_IS_TOMAHAWKX(unit)) { 62505 return (bcm_th_port_priority_group_config_get(unit, gport, 62506 priority_group, prigrp_config)); 62507 } 62508 #endif /* BCM_TOMAHAWK_SUPPORT */ 62509 62510 } 62511 return rv; 62512 } 62513 62514 /* 62515 * Function: 62516 * bcm_esw_port_redirect_config_t_init 62517 * Purpose: 62518 * Initialize the redirection config structure 62519 * Parameters: 62520 * redirect_config - (IN) Pointer to the redirection config structure 62521 * Returns: 62522 * None 62523 */ 62524 void bcm_esw_port_redirect_config_t_init( 62525 bcm_port_redirect_config_t *redirect_config) 62526 { 62527 return; 62528 } 62529 62530 /* 62531 * Function: 62532 * bcm_esw_port_redirect_set 62533 * Purpose: 62534 * Configure the redirection data 62535 * Parameters: 62536 * unit - (IN) device id. 62537 * port - (IN) Port number. 62538 * redirect_config - (IN) Pointer to the redirection config structure 62539 * Returns: 62540 * None 62541 */ 62542 int 62543 bcm_esw_port_redirect_config_set(int unit, int port, 62544 bcm_port_redirect_config_t *redirect_config) 62545 { 62546 int rv = BCM_E_UNAVAIL; 62547 62548 PORT_INIT(unit); 62549 62550 PORT_LOCK(unit); 62551 62552 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 62553 if (BCM_ESW_PORT_DRV(unit)->port_redirect_set != NULL) { 62554 rv = BCM_ESW_PORT_DRV(unit)->port_redirect_set(unit, port, 62555 redirect_config); 62556 } 62557 } 62558 62559 PORT_UNLOCK(unit); 62560 62561 return rv; 62562 } 62563 62564 62565 /* 62566 * Function: 62567 * bcm_esw_port_redirect_get 62568 * Purpose: 62569 * Configure the redirection data 62570 * Parameters: 62571 * unit - (IN) device id. 62572 * port - (IN) Port number. 62573 * redirect_config - (IN) Pointer to the redirection config structure 62574 * Returns: 62575 * None 62576 */ 62577 int 62578 bcm_esw_port_redirect_config_get(int unit, int port, 62579 bcm_port_redirect_config_t *redirect_config) 62580 { 62581 int rv = BCM_E_UNAVAIL; 62582 62583 PORT_INIT(unit); 62584 62585 PORT_LOCK(unit); 62586 62587 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 62588 if (BCM_ESW_PORT_DRV(unit)->port_redirect_get != NULL) { 62589 rv = BCM_ESW_PORT_DRV(unit)->port_redirect_get(unit, port, 62590 redirect_config); 62591 } 62592 } 62593 62594 PORT_UNLOCK(unit); 62595 62596 return rv; 62597 } 62598 62599 /* 62600 * Function : _bcm_esw_glp_bits_pos 62601 * Description : Internal function to get modid, port, and trunk_id 62602 * from a glp 62603 * Parameters : (IN) unit - BCM device number 62604 * (OUT) trunk_pos - Trunk ID position 62605 * (OUT) max_modid - Max module ID bits 62606 * (OUT) modid_pos - Module ID position 62607 * (OUT) max_port - Max port addr bits 62608 * Returns : BCM_E_XXX 62609 * Notes : The trunkid, modid and port are used for 16 bits {T, MODID[7:0], PORT[7:0]}, 62610 * get qualifiers for GLP related fields in FP_TCAM 62611 */ 62612 static int 62613 _bcm_esw_glp_bits_pos(int unit, 62614 uint8 *trunk_pos, uint8 *max_modid, 62615 uint8 *modid_pos, uint8 *max_port) 62616 { 62617 if ((NULL == trunk_pos) || (NULL == max_modid) || (NULL == modid_pos) || 62618 (NULL == max_port)) { 62619 return BCM_E_PARAM; 62620 } 62621 62622 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \ 62623 defined(BCM_TITAN_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \ 62624 defined(BCM_TITAN2_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 62625 defined(BCM_HELIX4_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 62626 defined(BCM_SABER2_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) || \ 62627 defined(BCM_APACHE_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 62628 if(SOC_IS_KATANA(unit) || SOC_IS_KATANA2(unit) || 62629 SOC_IS_TITAN(unit) || SOC_IS_TRIDENT(unit) || 62630 SOC_IS_TITAN2(unit) || SOC_IS_TRIDENT2(unit) || 62631 SOC_IS_HELIX4(unit) || SOC_IS_TRIUMPH3(unit) || 62632 SOC_IS_SABER2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 62633 SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) { 62634 *trunk_pos = 15; 62635 *max_modid = 0xff; 62636 *modid_pos = 7; 62637 *max_port = 0x7f; 62638 } else 62639 #endif 62640 #if defined(BCM_TOMAHAWK_SUPPORT) 62641 if (SOC_IS_TOMAHAWKX(unit)) { 62642 *trunk_pos = 16; 62643 *max_modid = 0xff; 62644 *modid_pos = 8; 62645 *max_port = 0xff; 62646 } else 62647 #endif 62648 #if defined(BCM_CONQUEROR_SUPPORT) || defined(BCM_SCORPION_SUPPORT) || \ 62649 defined(BCM_SHADOW_SUPPORT) 62650 if (SOC_IS_CONQUEROR(unit) || SOC_IS_SCORPION(unit) || 62651 SOC_IS_SHADOW(unit)) { 62652 *trunk_pos = 14; 62653 *max_modid = 0xff; 62654 *modid_pos = 6; 62655 *max_port = 0x3f; 62656 } else 62657 #endif 62658 #if defined(BCM_RAPTOR_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 62659 defined(BCM_HAWKEYE_SUPPORT) 62660 if (SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 62661 *trunk_pos = 0; 62662 *max_modid = 0x0; 62663 *modid_pos = 6; 62664 *max_port = 0x3f; 62665 } else 62666 #endif 62667 { 62668 *trunk_pos = 13; 62669 *max_modid = 0x7f; 62670 *modid_pos = 6; 62671 *max_port = 0x3f; 62672 } 62673 62674 return BCM_E_NONE; 62675 } 62676 62677 /* 62678 * Function : _bcm_esw_glp_construct 62679 * Description : Internal function to set GLP port 62680 * from modid, port, and trunk_id 62681 * Parameters : (IN) unit - BCM device number 62682 * (IN) modid - Module ID 62683 * (IN) port - Port number 62684 * (IN) trunk_id - Trunk ID 62685 * (OUT) glp - is trunk + modid + port num 62686 * Returns : BCM_E_XXX 62687 * Notes : The trunkid, modid and port are used for 16 bits {T, MODID[7:0], PORT[7:0]}, 62688 * set qualifiers for GLP related fields in FP_TCAM 62689 */ 62690 int 62691 _bcm_esw_glp_construct(int unit, bcm_trunk_t trunk_id, 62692 bcm_module_t modid, bcm_port_t port, 62693 bcm_gport_t *glp) 62694 { 62695 uint8 trunk_pos = 0; 62696 uint8 max_modid = 0; 62697 uint8 modid_pos = 0; 62698 uint8 max_port = 0; 62699 62700 if (NULL == glp) { 62701 return BCM_E_PARAM; 62702 } 62703 62704 BCM_IF_ERROR_RETURN 62705 (_bcm_esw_glp_bits_pos(unit, 62706 &trunk_pos, &max_modid, 62707 &modid_pos, &max_port)); 62708 62709 if (trunk_id != BCM_TRUNK_INVALID) { 62710 *glp = ((1 << trunk_pos) | trunk_id); 62711 } else { 62712 *glp = (((modid & max_modid) << modid_pos) | 62713 (port & max_port)); 62714 } 62715 62716 return BCM_E_NONE; 62717 } 62718 62719 /* 62720 * Function : _bcm_esw_glp_resolve 62721 * Description : Internal function to get modid, port, and trunk_id 62722 * from a glp 62723 * Parameters : (IN) unit - BCM device number 62724 * (IN) glp - trunk + modid + port num 62725 * (OUT) modid - Module ID 62726 * (OUT) port - Port number 62727 * (OUT) trunk_id - Trunk ID 62728 * Returns : BCM_E_XXX 62729 * Notes : The trunkid, modid and port are used for 16 bits {T, MODID[7:0], PORT[7:0]}, 62730 * get qualifiers for GLP related fields in FP_TCAM 62731 */ 62732 int 62733 _bcm_esw_glp_resolve(int unit, bcm_trunk_t *trunk_id, 62734 bcm_module_t *modid, bcm_port_t *port, 62735 bcm_gport_t glp) 62736 { 62737 uint8 trunk_pos = 0; 62738 uint8 max_modid = 0; 62739 uint8 modid_pos = 0; 62740 uint8 max_port = 0; 62741 62742 if ((NULL == trunk_id) || (NULL == modid) || (NULL == port)){ 62743 return BCM_E_PARAM; 62744 } 62745 62746 BCM_IF_ERROR_RETURN 62747 (_bcm_esw_glp_bits_pos(unit, 62748 &trunk_pos, &max_modid, 62749 &modid_pos, &max_port)); 62750 62751 if (glp & (1 << trunk_pos)) { 62752 *trunk_id = (glp & ~(1 << trunk_pos)); 62753 } else { 62754 *port = (glp & max_port); 62755 *modid = ((glp >> modid_pos) & max_modid); 62756 } 62757 62758 return BCM_E_NONE; 62759 } 62760 62761 /* 62762 * Function : _bcm_esw_gport_to_glp 62763 * Description : Internal function to set GLP port from gport 62764 * Parameters : (IN) unit - BCM device number 62765 * (IN) gport - trunk + modid + port num 62766 * (OUT) glp - trunk + modid + port num 62767 * Returns : BCM_E_XXX 62768 * Notes : The glport as Eg: 16 bits {T, MODID[7:0], PORT[7:0]}, 62769 * get qualifiers for GLP related fields in FP_TCAM 62770 */ 62771 int 62772 _bcm_esw_gport_to_glp(int unit, bcm_gport_t gport, bcm_gport_t *glp) 62773 { 62774 bcm_trunk_t trunk_id; 62775 bcm_module_t mod_id; 62776 bcm_port_t port; 62777 int local_id; 62778 62779 if (BCM_GPORT_IS_SET(gport)) { 62780 SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, gport, &mod_id, 62781 &port, &trunk_id, &local_id)); 62782 62783 BCM_IF_ERROR_RETURN 62784 (_bcm_esw_glp_construct(unit, 62785 trunk_id, mod_id, 62786 port, glp)); 62787 return BCM_E_NONE; 62788 } 62789 62790 return BCM_E_PARAM; 62791 } 62792 62793 /* 62794 * Function: 62795 * bcmi_esw_port_eee_cfg_get 62796 * Purpose: 62797 * Set the eee_cfg value for given port. 62798 * Parameters: 62799 * unit - (IN) Unit number. 62800 * port - (IN) Logical port, BCM format. 62801 * value - (IN) Value to set. 62802 * Returns: 62803 * BCM_E_XXX 62804 * Notes: 62805 */ 62806 int 62807 bcmi_esw_port_eee_cfg_set(int unit, bcm_port_t port, int value) 62808 { 62809 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \ 62810 defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) || \ 62811 defined(BCM_HURRICANE2_SUPPORT) 62812 if ((port < 0) || (port >= SOC_MAX_NUM_PORTS)) { 62813 return BCM_E_PORT; 62814 } 62815 62816 eee_cfg[unit][port] = value; 62817 62818 return BCM_E_NONE; 62819 #else 62820 return BCM_E_UNAVAIL; 62821 #endif 62822 } 62823 62824 62825 /* 62826 * Function: 62827 * bcmi_esw_port_egr_prof_ptr_set 62828 * Purpose: 62829 * Set the port_src_mod_egr_prof_ptr value for given port. 62830 * Parameters: 62831 * unit - (IN) Unit number. 62832 * port - (IN) Logical port, BCM format. 62833 * egr_prof_ptr - (IN) Value to set. 62834 * Returns: 62835 * BCM_E_XXX 62836 * Notes: 62837 */ 62838 int 62839 bcmi_esw_port_egr_prof_ptr_set(int unit, bcm_port_t port, int value) 62840 { 62841 #ifdef BCM_TRIUMPH2_SUPPORT 62842 if ((port < 0) || (port >= SOC_MAX_NUM_PORTS)) { 62843 return BCM_E_PORT; 62844 } 62845 62846 PORT_SRC_MOD_EGR_PROF_PTR(unit, port) = value; 62847 62848 return BCM_E_NONE; 62849 #else 62850 return BCM_E_UNAVAIL; 62851 #endif /* BCM_TRIUMPH2_SUPPORT */ 62852 } 62853 62854 62855 /* 62856 * Function: 62857 * bcmi_port_force_lb_set 62858 * Purpose: 62859 * Force port into internal loopback accroding to bond options. 62860 * Parameters: 62861 * unit - (IN) Unit number. 62862 * port - (IN) Logical port, BCM format. 62863 * egr_prof_ptr - (IN) Value to set. 62864 * Returns: 62865 * BCM_E_XXX 62866 * Notes: 62867 */ 62868 int 62869 bcmi_port_force_lb_set(int unit) 62870 { 62871 int rv = BCM_E_UNAVAIL; 62872 62873 PORT_INIT(unit); 62874 62875 PORT_LOCK(unit); 62876 62877 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 62878 if (BCM_ESW_PORT_DRV(unit)->force_lb_set != NULL) { 62879 rv = BCM_ESW_PORT_DRV(unit)->force_lb_set(unit); 62880 } 62881 } 62882 62883 PORT_UNLOCK(unit); 62884 62885 return rv; 62886 } 62887 62888 /* 62889 * Function: 62890 * bcm_esw_port_preemption_control_set 62891 * Purpose: 62892 * Set various configurations for Preemption. 62893 * Parameters: 62894 * unit - (IN) Unit number. 62895 * gport - (IN) gport id 62896 * type - (IN) preemption control type defined in bcm_port_preempt_control_t 62897 * arg - (IN) the preemption control value 62898 * Returns: 62899 * BCM_E_XXX 62900 * Notes: 62901 */ 62902 int 62903 bcm_esw_port_preemption_control_set(int unit, bcm_gport_t gport, 62904 bcm_port_preempt_control_t type, 62905 uint32 arg) 62906 { 62907 PORT_INIT(unit); 62908 62909 #if defined(BCM_PREEMPTION_SUPPORT) 62910 if (soc_feature(unit, soc_feature_preemption)) { 62911 bcm_port_t local_port; 62912 uint32 preempt_support; 62913 #ifdef BCM_MONTEREY_SUPPORT 62914 int link = BCM_PORT_LINK_STATUS_DOWN; 62915 #endif 62916 62917 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port)); 62918 if(!SOC_PBMP_MEMBER(PBMP_E_ALL(unit), local_port)) { 62919 /* hg port does not support preemption */ 62920 BCM_IF_ERROR_RETURN(BCM_E_UNAVAIL); 62921 } 62922 #ifdef BCM_MONTEREY_SUPPORT 62923 if (SOC_IS_MONTEREY(unit)) { 62924 if ((type == bcmPortPreemptControlVerifyTime) || 62925 (type == bcmPortPreemptControlVerifyAttempts) || 62926 (type == bcmPortPreemptControlVerifyEnable)) { 62927 return BCM_E_UNAVAIL; 62928 } 62929 if (type == bcmPortPreemptControlPreemptionSupport) { 62930 /* Intentionally supreesing return type to avoid unrelated error */ 62931 (void)_bcm_esw_link_get(unit, local_port, &link); 62932 if (!arg && (link == BCM_PORT_LINK_STATUS_UP)) { 62933 return BCM_E_CONFIG; 62934 } 62935 } 62936 } 62937 #endif /* BCM_MONTEREY_SUPPORT */ 62938 PORT_LOCK(unit); 62939 switch (type) { 62940 /* only need set mac-related */ 62941 case bcmPortPreemptControlEnableTx: 62942 case bcmPortPreemptControlVerifyEnable: 62943 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 62944 bcmi_esw_preemption_capability_get(unit, 62945 local_port, 62946 &preempt_support)); 62947 if (0 == preempt_support) { 62948 /* need to enable preempt ability on this port first */ 62949 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM); 62950 } 62951 /* fall-through */ 62952 case bcmPortPreemptControlVerifyTime: 62953 case bcmPortPreemptControlVerifyAttempts: 62954 case bcmPortPreemptControlNonFinalFragSizeRx: 62955 case bcmPortPreemptControlFinalFragSizeRx: 62956 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 62957 bcmi_esw_preemption_mac_config_set(unit, 62958 local_port, 62959 type, arg)); 62960 break; 62961 /* only need setup chip-related */ 62962 case bcmPortPreemptControlNonFinalFragSizeTx: 62963 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 62964 bcmi_esw_preemption_frag_config_tx_set(unit, 62965 local_port, 0, 62966 arg)); 62967 break; 62968 case bcmPortPreemptControlFinalFragSizeTx: 62969 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 62970 bcmi_esw_preemption_frag_config_tx_set(unit, 62971 local_port, 1, 62972 arg)); 62973 break; 62974 case bcmPortPreemptControlHoldReqCntMode: 62975 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 62976 bcmi_esw_preemption_hold_request_mode_set(unit, 62977 local_port, 62978 arg)); 62979 break; 62980 case bcmPortPreemptControlQueueBitmap: 62981 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 62982 bcmi_esw_preemption_queue_bitmap_set(unit, 62983 local_port, 62984 arg)); 62985 break; 62986 case bcmPortPreemptControlPreemptionSupport: 62987 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 62988 bcmi_esw_preemption_capability_set(unit, 62989 local_port, 62990 arg)); 62991 break; 62992 default: 62993 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM); 62994 62995 } 62996 PORT_UNLOCK(unit); 62997 return BCM_E_NONE; 62998 } else 62999 #endif /* BCM_PREEMPTION_SUPPORT */ 63000 { 63001 return BCM_E_UNAVAIL; 63002 } 63003 } 63004 63005 63006 /* 63007 * Function: 63008 * bcmi_esw_port_mac_type_get 63009 * Purpose: 63010 * Get mactype for a given logical port 63011 * Parameters: 63012 * unit - (IN) Unit number. 63013 * lport - (IN) logical port 63014 * type - (OUT) mac type defined in bcmi_port_mac_type_t 63015 * Returns: 63016 * BCM_E_XXX 63017 * Notes: 63018 */ 63019 int bcmi_esw_port_mac_type_get(int unit, bcm_port_t lport, 63020 bcmi_port_mac_type_t *type) { 63021 #if defined(BCM_GREYHOUND2_SUPPORT) 63022 if(SOC_IS_GREYHOUND2(unit)) { 63023 return bcmi_gh2_port_mac_type_get(unit, lport, type); 63024 } else 63025 #endif /* BCM_GREYHOUND2_SUPPORT */ 63026 { 63027 if (NULL == type) { 63028 return SOC_E_PARAM; 63029 } 63030 *type = bcmiPortMacTypePortmode; 63031 } 63032 return BCM_E_NONE; 63033 } 63034 63035 /* 63036 * Function: 63037 * bcm_esw_port_preemption_control_get 63038 * Purpose: 63039 * Get various configurations for Preemption. 63040 * Parameters: 63041 * unit - (IN) Unit number. 63042 * gport - (IN) gport id 63043 * type - (IN) preemption control type defined in bcm_port_preempt_control_t 63044 * arg - (OUT) the preemption control value 63045 * Returns: 63046 * BCM_E_XXX 63047 * Notes: 63048 */ 63049 int 63050 bcm_esw_port_preemption_control_get(int unit, bcm_gport_t gport, 63051 bcm_port_preempt_control_t type, 63052 uint32 *arg) 63053 { 63054 PORT_INIT(unit); 63055 63056 #if defined(BCM_PREEMPTION_SUPPORT) 63057 if (soc_feature(unit, soc_feature_preemption)) { 63058 bcm_port_t local_port; 63059 63060 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port)); 63061 if(!SOC_PBMP_MEMBER(PBMP_E_ALL(unit), local_port)) { 63062 /* hg port does not support preemption */ 63063 BCM_IF_ERROR_RETURN(BCM_E_UNAVAIL); 63064 } 63065 #ifdef BCM_MONTEREY_SUPPORT 63066 if (SOC_IS_MONTEREY(unit)) { 63067 if ((type == bcmPortPreemptControlVerifyTime) || 63068 (type == bcmPortPreemptControlVerifyAttempts) || 63069 (type == bcmPortPreemptControlVerifyEnable)) { 63070 return BCM_E_UNAVAIL; 63071 } 63072 } 63073 #endif /* BCM_MONTEREY_SUPPORT */ 63074 PORT_LOCK(unit); 63075 switch (type) { 63076 /* mac-related */ 63077 case bcmPortPreemptControlEnableTx: 63078 case bcmPortPreemptControlVerifyEnable: 63079 case bcmPortPreemptControlVerifyTime: 63080 case bcmPortPreemptControlVerifyAttempts: 63081 case bcmPortPreemptControlNonFinalFragSizeRx: 63082 case bcmPortPreemptControlFinalFragSizeRx: 63083 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 63084 bcmi_esw_preemption_mac_config_get(unit, 63085 local_port, 63086 type, arg)); 63087 break; 63088 /* chip-related */ 63089 case bcmPortPreemptControlNonFinalFragSizeTx: 63090 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 63091 bcmi_esw_preemption_frag_config_tx_get(unit, 63092 local_port, 0, 63093 arg)); 63094 break; 63095 case bcmPortPreemptControlFinalFragSizeTx: 63096 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 63097 bcmi_esw_preemption_frag_config_tx_get(unit, 63098 local_port, 1, 63099 arg)); 63100 break; 63101 case bcmPortPreemptControlHoldReqCntMode: 63102 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 63103 bcmi_esw_preemption_hold_request_mode_get(unit, 63104 local_port, 63105 arg)); 63106 break; 63107 case bcmPortPreemptControlQueueBitmap: 63108 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 63109 bcmi_esw_preemption_queue_bitmap_get(unit, 63110 local_port, 63111 arg)); 63112 break; 63113 case bcmPortPreemptControlPreemptionSupport: 63114 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 63115 bcmi_esw_preemption_capability_get(unit, 63116 local_port, 63117 arg)); 63118 break; 63119 default: 63120 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM); 63121 63122 } 63123 PORT_UNLOCK(unit); 63124 return BCM_E_NONE; 63125 } else 63126 #endif /* BCM_PREEMPTION_SUPPORT */ 63127 { 63128 return BCM_E_UNAVAIL; 63129 } 63130 } 63131 63132 63133 /* 63134 * Function: 63135 * bcm_esw_port_preemption_status_get 63136 * Purpose: 63137 * Get the specified preemption status. 63138 * Parameters: 63139 * unit - (IN) Unit number. 63140 * gport - (IN) gport id 63141 * type - (IN) preemption status type defined in bcm_port_preempt_status_t 63142 * status - (OUT) the preemption status 63143 * For bcmPortPreemptStatusTx type, the status value 63144 * defined in bcm_port_preempt_status_tx_t. 63145 * For bcmPortPreemptStatusVerify type, the status value 63146 * defined in bcm_port_preempt_status_verify_t. 63147 * Returns: 63148 * BCM_E_XXX 63149 * Notes: 63150 */ 63151 int bcm_esw_port_preemption_status_get(int unit, bcm_gport_t gport, 63152 bcm_port_preempt_status_t type, 63153 uint32 *status) 63154 { 63155 PORT_INIT(unit); 63156 63157 #if defined(BCM_PREEMPTION_SUPPORT) 63158 if (soc_feature(unit, soc_feature_preemption)) { 63159 bcm_port_t local_port; 63160 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port)); 63161 PORT_LOCK(unit); 63162 switch (type) { 63163 case bcmPortPreemptStatusTx: 63164 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 63165 bcmi_esw_preemption_status_tx_get(unit, local_port, 63166 status)); 63167 break; 63168 case bcmPortPreemptStatusVerify: 63169 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 63170 bcmi_esw_preemption_status_verify_get(unit, local_port, 63171 status)); 63172 break; 63173 default: 63174 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM); 63175 } 63176 PORT_UNLOCK(unit); 63177 return BCM_E_NONE; 63178 } else 63179 #endif /* BCM_PREEMPTION_SUPPORT */ 63180 { 63181 return BCM_E_UNAVAIL; 63182 } 63183 } 63184 63185 /* 63186 * Description: 63187 * Enable and configure the remote module to apply E2EFC mechanism. 63188 * Or disable it. 63189 * Parameter: 63190 * unit - (IN) unit number 63191 * remote_module - (IN) remote module id 63192 * mode - (IN) selected mode 63193 * enable - (IN) enable or disable selection 63194 * e2efc_rmod_cfg - (IN) structure containing the configuration. 63195 * Ignored when enable = 0. 63196 */ 63197 int 63198 bcm_esw_port_e2efc_remote_module_enable_set( 63199 int unit, 63200 bcm_module_t remote_module, 63201 bcm_port_e2efc_mode_t mode, 63202 int enable, 63203 bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg) 63204 { 63205 if (e2efc_rmod_cfg == NULL) { 63206 return BCM_E_UNAVAIL; 63207 } 63208 63209 if (soc_feature(unit, soc_feature_e2efc)) { 63210 #if defined(BCM_GREYHOUND2_SUPPORT) 63211 if (SOC_IS_GREYHOUND2(unit)) { 63212 return bcmi_gh2_port_e2efc_remote_module_enable_set(unit, 63213 remote_module, mode, enable, e2efc_rmod_cfg); 63214 } 63215 #endif /* BCM_GREYHOUND2_SUPPORT */ 63216 63217 #if defined(BCM_KATANA2_SUPPORT) 63218 if (SOC_IS_KATANA2(unit)) { 63219 return bcmi_kt2_port_e2efc_remote_module_enable_set(unit, 63220 remote_module, mode, enable, e2efc_rmod_cfg); 63221 } 63222 #endif /* BCM_KATANA2_SUPPORT */ 63223 } 63224 63225 return BCM_E_UNAVAIL; 63226 } 63227 63228 /* 63229 * Description: 63230 * Get the enable mode and configuration of the remote module that 63231 * applies E2EFC mechanism. 63232 * Parameter: 63233 * unit - (IN) unit number 63234 * remote_module - (IN) remote module id 63235 * mode - (IN) selected mode 63236 * enable - (OUT) enable or disable selection 63237 * e2efc_rmod_cfg - (OUT) structure containing the configuration. 63238 * Only valid if the remote module is enabled. 63239 */ 63240 int 63241 bcm_esw_port_e2efc_remote_module_enable_get( 63242 int unit, 63243 bcm_module_t remote_module, 63244 bcm_port_e2efc_mode_t mode, 63245 int *enable, 63246 bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg) 63247 { 63248 63249 if (e2efc_rmod_cfg == NULL || enable == NULL) { 63250 return BCM_E_UNAVAIL; 63251 } 63252 63253 if (soc_feature(unit, soc_feature_e2efc)) { 63254 #if defined(BCM_GREYHOUND2_SUPPORT) 63255 if (SOC_IS_GREYHOUND2(unit)) { 63256 return bcmi_gh2_port_e2efc_remote_module_enable_get(unit, 63257 remote_module, mode, enable, e2efc_rmod_cfg); 63258 } 63259 #endif /* BCM_GREYHOUND2_SUPPORT */ 63260 63261 #if defined(BCM_KATANA2_SUPPORT) 63262 if (SOC_IS_KATANA2(unit)) { 63263 return bcmi_kt2_port_e2efc_remote_module_enable_get(unit, 63264 remote_module, mode, enable, e2efc_rmod_cfg); 63265 } 63266 #endif /* BCM_KATANA2_SUPPORT */ 63267 } 63268 63269 return BCM_E_UNAVAIL; 63270 } 63271 63272 /* 63273 * Description: 63274 * Traverse enabled remote modules that apply E2EFC mechanism. 63275 * Parameter: 63276 * unit - (IN) unit number 63277 * cb - (IN) call back function to execute 63278 * user_data - (IN) pointer to user data 63279 */ 63280 int 63281 bcm_esw_port_e2efc_remote_module_traverse( 63282 int unit, 63283 bcm_port_e2efc_remote_module_traverse_cb cb, 63284 void *user_data) 63285 { 63286 if ( user_data == NULL || cb == NULL) { 63287 return BCM_E_PARAM; 63288 } 63289 63290 if (soc_feature(unit, soc_feature_e2efc)) { 63291 #if defined(BCM_GREYHOUND2_SUPPORT) 63292 if (SOC_IS_GREYHOUND2(unit)) { 63293 return bcmi_gh2_port_e2efc_remote_module_traverse(unit, cb, 63294 user_data); 63295 } 63296 #endif /* BCM_GREYHOUND2_SUPPORT */ 63297 63298 #if defined(BCM_KATANA2_SUPPORT) 63299 if (SOC_IS_KATANA2(unit)) { 63300 return bcmi_kt2_port_e2efc_remote_module_traverse(unit, cb, 63301 user_data); 63302 } 63303 #endif /* BCM_KATANA2_SUPPORT */ 63304 } 63305 return BCM_E_UNAVAIL; 63306 } 63307 63308 /* 63309 * Description: 63310 * Add remote module-port and set configuration. 63311 * Return a handle id for the bcm_port_e2efc_remote_port_xxx APIs. 63312 * The API of remote module-port configuration is only for E2EFC 63313 * transmission. 63314 * Parameter: 63315 * unit - (IN) unit number 63316 * e2efc_rport_cfg - (IN) structure containing the configuration 63317 * rport_handle_id - (OUT) remote port handle id, to be used for the rest 63318 * of bcm_port_e2efc_remote_port_xxx APIs 63319 */ 63320 int 63321 bcm_esw_port_e2efc_remote_port_add( 63322 int unit, 63323 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg, 63324 int *rport_handle_id) 63325 { 63326 if (e2efc_rport_cfg == NULL || rport_handle_id == NULL) { 63327 return BCM_E_UNAVAIL; 63328 } 63329 if (soc_feature(unit, soc_feature_e2efc)) { 63330 #if defined(BCM_GREYHOUND2_SUPPORT) 63331 if (SOC_IS_GREYHOUND2(unit)) { 63332 return bcmi_gh2_port_e2efc_remote_port_add(unit, e2efc_rport_cfg, 63333 rport_handle_id); 63334 } 63335 #endif /* BCM_GREYHOUND2_SUPPORT */ 63336 63337 #if defined(BCM_KATANA2_SUPPORT) 63338 if (SOC_IS_KATANA2(unit)) { 63339 return bcmi_kt2_port_e2efc_remote_port_add(unit, e2efc_rport_cfg, 63340 rport_handle_id); 63341 } 63342 #endif /* BCM_KATANA2_SUPPORT */ 63343 } 63344 return BCM_E_UNAVAIL; 63345 } 63346 63347 /* 63348 * Description: 63349 * Set (modify) configuration of the remote port. 63350 * Parameter: 63351 * unit - (IN) unit number 63352 * rport_handle_id - (IN) remote port handle id 63353 * e2efc_rport_cfg - (IN) structure containing the configuration 63354 */ 63355 int 63356 bcm_esw_port_e2efc_remote_port_set( 63357 int unit, 63358 int rport_handle_id, 63359 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg) 63360 { 63361 if (e2efc_rport_cfg == NULL) { 63362 return BCM_E_UNAVAIL; 63363 } 63364 if (soc_feature(unit, soc_feature_e2efc)) { 63365 #if defined(BCM_GREYHOUND2_SUPPORT) 63366 if (SOC_IS_GREYHOUND2(unit)) { 63367 return bcmi_gh2_port_e2efc_remote_port_set(unit, rport_handle_id, 63368 e2efc_rport_cfg); 63369 } 63370 #endif /* BCM_GREYHOUND2_SUPPORT */ 63371 63372 #if defined(BCM_KATANA2_SUPPORT) 63373 if (SOC_IS_KATANA2(unit)) { 63374 return bcmi_kt2_port_e2efc_remote_port_set(unit, rport_handle_id, 63375 e2efc_rport_cfg); 63376 } 63377 #endif /* BCM_KATANA2_SUPPORT */ 63378 } 63379 return BCM_E_UNAVAIL; 63380 } 63381 63382 /* 63383 * Description: 63384 * Get configuration of the remote port. 63385 * Return the remote module, remote port and configuration of the 63386 * handle id. 63387 * Parameter: 63388 * unit - (IN) unit number 63389 * rport_handle_id - (IN) remote port handle id 63390 * e2efc_rport_cfg - (OUT) structure containing the configuration 63391 */ 63392 int 63393 bcm_esw_port_e2efc_remote_port_get( 63394 int unit, 63395 int rport_handle_id, 63396 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg) 63397 { 63398 if (e2efc_rport_cfg == NULL) { 63399 return BCM_E_UNAVAIL; 63400 } 63401 if (soc_feature(unit, soc_feature_e2efc)) { 63402 #if defined(BCM_GREYHOUND2_SUPPORT) 63403 if (SOC_IS_GREYHOUND2(unit)) { 63404 return bcmi_gh2_port_e2efc_remote_port_get(unit, rport_handle_id, 63405 e2efc_rport_cfg); 63406 } 63407 #endif /* BCM_GREYHOUND2_SUPPORT */ 63408 63409 #if defined(BCM_KATANA2_SUPPORT) 63410 if (SOC_IS_KATANA2(unit)) { 63411 return bcmi_kt2_port_e2efc_remote_port_get(unit, rport_handle_id, 63412 e2efc_rport_cfg); 63413 } 63414 #endif /* BCM_KATANA2_SUPPORT */ 63415 } 63416 return BCM_E_UNAVAIL; 63417 } 63418 63419 /* 63420 * Description: 63421 * Delete remote port. 63422 * Parameter: 63423 * unit - (IN) unit number 63424 * rport_handle_id - (IN) remote port handle id 63425 */ 63426 int 63427 bcm_esw_port_e2efc_remote_port_delete( 63428 int unit, 63429 int rport_handle_id) 63430 { 63431 63432 if (soc_feature(unit, soc_feature_e2efc)) { 63433 #if defined(BCM_GREYHOUND2_SUPPORT) 63434 if (SOC_IS_GREYHOUND2(unit)) { 63435 return bcmi_gh2_port_e2efc_remote_port_delete(unit, 63436 rport_handle_id); 63437 } 63438 #endif /* BCM_GREYHOUND2_SUPPORT */ 63439 63440 #if defined(BCM_KATANA2_SUPPORT) 63441 if (SOC_IS_KATANA2(unit)) { 63442 return bcmi_kt2_port_e2efc_remote_port_delete(unit, 63443 rport_handle_id); 63444 } 63445 #endif /* BCM_KATANA2_SUPPORT */ 63446 } 63447 return BCM_E_UNAVAIL; 63448 } 63449 63450 /* 63451 * Description: 63452 * Traverse remote ports. 63453 * Parameter: 63454 * unit - (IN) unit number 63455 * cb - (IN) call back function to execute 63456 * user_data - (IN) pointer to user data 63457 */ 63458 int 63459 bcm_esw_port_e2efc_remote_port_traverse( 63460 int unit, 63461 bcm_port_e2efc_remote_port_traverse_cb cb, 63462 void *user_data) 63463 { 63464 if ( user_data == NULL || cb == NULL) { 63465 return BCM_E_PARAM; 63466 } 63467 63468 if (soc_feature(unit, soc_feature_e2efc)) { 63469 #if defined(BCM_GREYHOUND2_SUPPORT) 63470 if (SOC_IS_GREYHOUND2(unit)) { 63471 return bcmi_gh2_port_e2efc_remote_port_traverse(unit, cb, 63472 user_data); 63473 } 63474 #endif /* BCM_GREYHOUND2_SUPPORT */ 63475 63476 #if defined(BCM_KATANA2_SUPPORT) 63477 if (SOC_IS_KATANA2(unit)) { 63478 return bcmi_kt2_port_e2efc_remote_port_traverse(unit, cb, 63479 user_data); 63480 } 63481 #endif /* BCM_KATANA2_SUPPORT */ 63482 } 63483 return BCM_E_UNAVAIL; 63484 } 63485 63486 #ifdef SW_AUTONEG_SUPPORT 63487 /* 63488 * Function : _bcm_esw_port_notify_link_down_evt 63489 * Description : Notify Link_Down event to SW AN SM. 63490 * Parameters : (IN) unit - BCM device number 63491 * (IN) port - Port number 63492 * Returns : BCM_E_XXX 63493 */ 63494 int 63495 _bcm_esw_port_notify_link_down_evt(int unit, bcm_port_t port) 63496 { 63497 int an_mode = 0; 63498 int an_enabled = 0; 63499 int rv = BCM_E_NONE; 63500 63501 if (soc_feature(unit, soc_feature_sw_autoneg)) { 63502 /* if the link is down notify the SW AN thread 63503 * to restart AN if AN is enabled for the port 63504 */ 63505 an_mode = soc_property_port_get(unit, port, 63506 spn_PHY_AN_C73, an_mode); 63507 63508 /* phy_an_c73 value of 3 indicated MSA AN mode */ 63509 if ((an_mode == SW_AN_MODE_CL73_MSA) || 63510 (an_mode == SW_AN_MODE_MSA_ONLY)) { 63511 63512 63513 rv = bcm_esw_port_autoneg_get(unit, port , &an_enabled); 63514 if (BCM_FAILURE(rv)) { 63515 LOG_WARN(BSL_LS_BCM_PORT, 63516 (BSL_META_U(unit, 63517 "u=%d p=%d AUTONEG GET FALSE rv=%d\n"), 63518 unit, port, rv)); 63519 return rv; 63520 } 63521 63522 if (an_enabled) { 63523 /* notify the SW AN thread of link down event */ 63524 rv = bcm_sw_an_post_event(unit, port, BCM_PORT_SW_AN_EVENT_AN_LINK_DOWN); 63525 } 63526 63527 if (BCM_FAILURE(rv)) { 63528 LOG_WARN(BSL_LS_BCM_PORT, 63529 (BSL_META_U(unit, 63530 "u=%d p=%d SW AN POST EVENT FAILED rv=%d\n"), 63531 unit, port, rv)); 63532 } 63533 } 63534 } 63535 return BCM_E_NONE; 63536 } 63537 #endif 63538 63539 63540 /* 63541 * Function: 63542 * bcm_esw_port_phy_tx_set 63543 * Purpose: 63544 * Set port phy tx properties 63545 * Parameters: 63546 * unit - StrataSwitch Unit #. 63547 * port - StrataSwitch port #. 63548 * tx - tx properties 63549 * Returns: 63550 * BCM_E_NONE 63551 * BCM_E_XXX 63552 */ 63553 int 63554 bcm_esw_port_phy_tx_set(int unit, bcm_port_t port, bcm_port_phy_tx_t *tx) { 63555 int rv = BCM_E_UNAVAIL; 63556 63557 if (NULL == tx) { 63558 return BCM_E_PARAM; 63559 } 63560 63561 /* Make sure port module is initialized. */ 63562 PORT_INIT(unit); 63563 63564 if (SOC_IS_TOMAHAWK3(unit)) { 63565 /* Call Port Control module */ 63566 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 63567 rv = bcmi_esw_portctrl_phy_tx_set(unit, port, tx); 63568 } 63569 } 63570 63571 return rv; 63572 } 63573 63574 /* 63575 * Function: 63576 * bcm_esw_port_phy_tx_get 63577 * Purpose: 63578 * Get port phy tx properties 63579 * Parameters: 63580 * unit - StrataSwitch Unit #. 63581 * port - StrataSwitch port #. 63582 * tx - tx properties 63583 * Returns: 63584 * BCM_E_NONE 63585 * BCM_E_XXX 63586 */ 63587 int 63588 bcm_esw_port_phy_tx_get(int unit, bcm_port_t port, bcm_port_phy_tx_t *tx) { 63589 int rv = BCM_E_UNAVAIL; 63590 63591 if (NULL == tx) { 63592 return BCM_E_PARAM; 63593 } 63594 63595 /* Make sure port module is initialized. */ 63596 PORT_INIT(unit); 63597 63598 if (SOC_IS_TOMAHAWK3(unit)) { 63599 /* Call Port Control module */ 63600 if (SOC_PORT_USE_PORTCTRL(unit, port)) { 63601 rv = bcmi_esw_portctrl_phy_tx_get(unit, port, tx); 63602 } 63603 } 63604 63605 return rv; 63606 } 63607 63608 /* 63609 * Function: 63610 * bcm_esw_port_rlm_config_set 63611 * Purpose: 63612 * Set port rlm config properties 63613 * Parameters: 63614 * unit - (IN) StrataSwitch Unit #. 63615 * port - (IN) StrataSwitch port #. 63616 * rlm_config - (IN) rlm properties 63617 * enable - (IN) enable or disable rlm 63618 * Returns: 63619 * BCM_E_NONE 63620 * BCM_E_XXX 63621 */ 63622 int 63623 bcm_esw_port_rlm_config_set(int unit, bcm_port_t port, 63624 bcm_port_rlm_config_t *rlm_config, int enable) { 63625 int rv = BCM_E_UNAVAIL; 63626 int port_enabled = 0; 63627 int link; 63628 63629 if (NULL == rlm_config) { 63630 return BCM_E_PARAM; 63631 } 63632 63633 /* Make sure port module is initialized. */ 63634 PORT_INIT(unit); 63635 63636 /* Check for valid port */ 63637 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 63638 63639 if (!enable) { 63640 /* need to disable the port first if disable RLM */ 63641 rv = bcm_esw_port_enable_set(unit, port, 0); 63642 } else { 63643 /*next check if the port is enabled */ 63644 rv = bcm_esw_port_enable_get(unit, port, &port_enabled); 63645 if (!port_enabled) { 63646 LOG_ERROR(BSL_LS_BCM_PORT, 63647 (BSL_META_U(unit, 63648 "port %d is not enabled \n"), port)); 63649 return BCM_E_CONFIG; 63650 } 63651 63652 /* check link status */ 63653 SOC_IF_ERROR_RETURN 63654 (bcm_esw_port_link_status_get(unit, port, &link)); 63655 if (FALSE == link) { 63656 LOG_ERROR(BSL_LS_BCM_PORT, 63657 (BSL_META_U(unit, 63658 "port %d link is not up \n"), port)); 63659 return BCM_E_CONFIG; 63660 } 63661 } 63662 63663 if (SOC_IS_TOMAHAWK3(unit)) { 63664 /* Call Port Control module */ 63665 if (SOC_USE_PORTCTRL(unit)) { 63666 rv = bcmi_esw_portctrl_rlm_config_set(unit, 63667 port, 63668 rlm_config, 63669 enable); 63670 } 63671 } 63672 63673 if (!enable) { 63674 /* need to re-enable the port after RLM is disabled */ 63675 rv = bcm_esw_port_enable_set(unit, port, 1); 63676 } 63677 63678 return rv; 63679 } 63680 63681 /* 63682 * Function: 63683 * bcm_esw_port_rlm_config_get 63684 * Purpose: 63685 * Get port phy tx properties 63686 * Parameters: 63687 * unit - (IN) StrataSwitch Unit #. 63688 * port - (IN) StrataSwitch port #. 63689 * rlm_config - (OUT) rlm config properties 63690 * enable - (OUT) enable/disable 63691 * Returns: 63692 * BCM_E_NONE 63693 * BCM_E_XXX 63694 */ 63695 int 63696 bcm_esw_port_rlm_config_get(int unit, bcm_port_t port, 63697 bcm_port_rlm_config_t *rlm_config, int *enable) { 63698 int rv = BCM_E_UNAVAIL; 63699 63700 if (NULL == rlm_config) { 63701 return BCM_E_PARAM; 63702 } 63703 63704 /* Make sure port module is initialized. */ 63705 PORT_INIT(unit); 63706 63707 /* Check for valid port */ 63708 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 63709 63710 if (SOC_IS_TOMAHAWK3(unit)) { 63711 /* Call Port Control module */ 63712 if (SOC_USE_PORTCTRL(unit)) { 63713 rv = bcmi_esw_portctrl_rlm_config_get(unit, 63714 port, 63715 rlm_config, 63716 enable); 63717 } 63718 } 63719 63720 return rv; 63721 } 63722 /* 63723 * Function: 63724 * bcm_esw_port_rlm_status_get 63725 * Purpose: 63726 * Get port rlm status 63727 * Parameters: 63728 * unit - (IN) StrataSwitch Unit #. 63729 * port - (IN) StrataSwitch port #. 63730 * rlm_status - (OUT) rlm config properties 63731 * Returns: 63732 * BCM_E_NONE 63733 * BCM_E_XXX 63734 */ 63735 int 63736 bcm_esw_port_rlm_status_get(int unit, bcm_port_t port, 63737 bcm_port_rlm_status_t *rlm_status) { 63738 int rv = BCM_E_UNAVAIL; 63739 63740 if (NULL == rlm_status) { 63741 return BCM_E_PARAM; 63742 } 63743 63744 /* Make sure port module is initialized. */ 63745 PORT_INIT(unit); 63746 63747 /* Check for valid port */ 63748 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 63749 63750 if (SOC_IS_TOMAHAWK3(unit)) { 63751 /* Call Port Control module */ 63752 if (SOC_USE_PORTCTRL(unit)) { 63753 rv = bcmi_esw_portctrl_rlm_status_get(unit, 63754 port, 63755 rlm_status); 63756 } 63757 } 63758 63759 return rv; 63760 } 63761 63762 /* 63763 * bcm_port_txpi_rxcdr_clk_get 63764 * 63765 * @brief get both tx/rx clocks in Hz. 63766 * 63767 * @param [in] unit - unit id 63768 * @param [in] port - logical port 63769 * @param [out] txpi_clk - tx pi clk in Hz 63770 * @param [out] rxcdr_clk - rx cdr clk in Hz 63771 */ 63772 int bcm_esw_port_txpi_rxcdr_clk_get(int unit, bcm_port_t port, 63773 uint32* txpi_clk, uint32* rxcdr_clk) 63774 { 63775 int rv = BCM_E_UNAVAIL; 63776 #if (defined(BCM_MONTEREY_SUPPORT) & defined(INCLUDE_GDPLL)) ||\ 63777 defined(BCM_FIRELIGHT_SUPPORT) || defined(BCM_FIREBOLT6_SUPPORT) 63778 if (SOC_IS_MONTEREY(unit) || SOC_IS_FIRELIGHT(unit) || SOC_IS_FIREBOLT6(unit)) { 63779 if (SOC_USE_PORTCTRL(unit)) { 63780 rv = portmod_port_txpi_rxcdr_clk_get(unit, port, txpi_clk, rxcdr_clk); 63781 } 63782 } 63783 #endif 63784 return rv; 63785 } 63786 63787 /* 63788 * Function: 63789 * bcm_esw_port_post_ber_proj_get 63790 * Purpose: 63791 * Get the BER histogram and post-FEC estimation values 63792 * Parameters: 63793 * unit - (IN) StrataSwitch Unit #. 63794 * port - (IN) StrataSwitch port #. 63795 * ber_proj - (IN) BER Projection parameters 63796 * max_errnct - (IN) size of errcnt_array[] 63797 * errcnt_array - (OUT) errcnt_array[] for storing post-FEC estimation values 63798 * actual_errcnt - (OUT) actual number of errcnt in errcnt_array[] 63799 * Returns: 63800 * BCM_E_NONE 63801 * BCM_E_XXX 63802 */ 63803 int 63804 bcm_esw_port_post_ber_proj_get(int unit, bcm_port_t port, 63805 bcm_port_ber_proj_params_t *ber_proj, 63806 int max_errcnt, 63807 bcm_port_ber_proj_analyzer_errcnt_t *errcnt_array, 63808 int *actual_errcnt) { 63809 int rv = BCM_E_UNAVAIL; 63810 63811 if ((ber_proj == NULL) || (errcnt_array == NULL)) { 63812 return BCM_E_PARAM; 63813 } 63814 63815 /* Make sure port module is initialized. */ 63816 PORT_INIT(unit); 63817 63818 if (SOC_IS_TOMAHAWK3(unit)) { 63819 /* Call Port Control module */ 63820 if (SOC_USE_PORTCTRL(unit)) { 63821 rv = bcmi_esw_portctrl_post_ber_proj_get(unit, port, 63822 ber_proj, max_errcnt, errcnt_array, actual_errcnt); 63823 } 63824 } 63825 63826 return rv; 63827 } 63828 63829 int 63830 bcm_esw_port_get(int unit, bcm_port_t port, uint32 *flags, 63831 bcm_port_interface_info_t *interface_info, 63832 bcm_port_mapping_info_t *mapping_info) 63833 { 63834 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 63835 int mcq, ucq; 63836 pbmp_t pbmp = PBMP_ALL(unit); 63837 63838 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TOMAHAWK(unit)) { 63839 if (!_SHR_PBMP_MEMBER((pbmp), (port))) { 63840 return BCM_E_PARAM; 63841 } 63842 if (interface_info == NULL || mapping_info == NULL) { 63843 return BCM_E_PARAM; 63844 } 63845 sal_memset(interface_info, 0, sizeof(bcm_port_interface_info_t)); 63846 sal_memset(mapping_info, 0, sizeof(bcm_port_mapping_info_t)); 63847 63848 /* phy_pbmp, interface_id, channel, core, base_q_pair, num_priorities, 63849 * pp_port, base_hr and num_sch_priorities, are used for Dune switch. 63850 */ 63851 interface_info->phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 63852 BCM_IF_ERROR_RETURN(bcm_esw_port_interface_get(unit, port, 63853 &interface_info->interface)); 63854 interface_info->num_lanes = SOC_INFO(unit).port_num_lanes[port]; 63855 mapping_info->tm_port = SOC_INFO(unit).port_p2m_mapping[interface_info->phy_port]; 63856 interface_info->max_speed = SOC_INFO(unit).port_speed_max[port]; 63857 mcq = SOC_INFO(unit).port_cosq_base[port]; 63858 ucq = SOC_INFO(unit).port_uc_cosq_base[port]; 63859 #ifdef BCM_TRIDENT2_SUPPORT 63860 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TITAN2(unit)) { 63861 mapping_info->base_mc_queue = soc_td2_logical_qnum_hw_qnum(unit, port, mcq, 0); 63862 mapping_info->base_uc_queue = soc_td2_logical_qnum_hw_qnum(unit, port, ucq, 1); 63863 } else 63864 #endif 63865 if (SOC_IS_TOMAHAWK(unit)) { 63866 mapping_info->base_mc_queue = mcq; 63867 mapping_info->base_uc_queue = ucq; 63868 } 63869 mapping_info->num_mc_queue = SOC_INFO(unit).port_num_cosq[port]; 63870 mapping_info->num_uc_queue = SOC_INFO(unit).port_num_uc_cosq[port]; 63871 63872 return BCM_E_NONE; 63873 } 63874 return BCM_E_UNAVAIL; 63875 #else 63876 return BCM_E_UNAVAIL; 63877 #endif 63878 }