port.c (2232212B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: 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 139 #if defined (BCM_HGPROXY_COE_SUPPORT) 140 #include <bcm_int/esw/xgs5.h> 141 #include <bcm_int/esw/subport.h> 142 #endif /* BCM_HGPROXY_COE_SUPPORT */ 143 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 144 #include <bcm_int/esw/tomahawk2.h> 145 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */ 146 #if defined(BCM_TOMAHAWK2_SUPPORT) 147 #include <bcm_int/esw/xgs5.h> 148 #include <soc/tomahawk2.h> 149 #endif /* BCM_TOMAHAWK2_SUPPORT */ 150 #include <bcm_int/esw/xgs3.h> 151 152 #include <bcm_int/esw/flex_ctr.h> 153 #include <bcm_int/esw/policer.h> 154 #if defined(BCM_KATANA2_SUPPORT) 155 #include <bcm_int/esw/subport.h> 156 #include <bcm_int/esw/katana2.h> 157 #include <soc/katana2.h> 158 #include <bcm/subport.h> 159 #endif /* BCM_KATANA2_SUPPORT */ 160 #if defined(BCM_SABER2_SUPPORT) 161 #include <bcm_int/esw/saber2.h> 162 #include <soc/saber2.h> 163 #endif /* BCM_SABER2_SUPPORT */ 164 #if defined(BCM_METROLITE_SUPPORT) 165 #include <bcm_int/esw/metrolite.h> 166 #include <soc/metrolite.h> 167 #endif /* BCM_METROLITE_SUPPORT */ 168 #if defined(BCM_GREYHOUND_SUPPORT) 169 #include <bcm_int/esw/greyhound.h> 170 #endif /* BCM_GREYHOUND_SUPPORT */ 171 #if defined(BCM_HURRICANE3_SUPPORT) 172 #include <bcm_int/esw/hurricane3.h> 173 #include <soc/hurricane3.h> 174 #endif /* BCM_HURRICANE3_SUPPORT */ 175 #if defined(BCM_GREYHOUND2_SUPPORT) 176 #include <bcm_int/esw/greyhound2.h> 177 #endif /* BCM_GREYHOUND2_SUPPORT */ 178 #if defined (BCM_EP_REDIRECT_VERSION_2) 179 #include <bcm_int/esw/xgs5.h> 180 #endif 181 #if defined(BCM_HGPROXY_COE_SUPPORT) 182 #include <bcm_int/esw/subport.h> 183 #include <bcm_int/esw/xgs5.h> 184 #endif /* BCM_HGPROXY_COE_SUPPORT */ 185 #if defined(BCM_PREEMPTION_SUPPORT) 186 #include <bcm_int/esw/preemption.h> 187 #include <bcm_int/esw/preemption_cnt.h> 188 #endif /* BCM_PREEMPTION_SUPPORT */ 189 #include <bcm_int/esw_dispatch.h> 190 191 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_WARM_BOOT_SUPPORT) 192 #include <bcm_int/esw/switch.h> 193 #endif /* BCM_WARM_BOOT_SUPPORT */ 194 195 #if defined(BCM_TRIUMPH2_SUPPORT) 196 #include <bcm_int/esw/qos.h> 197 #endif /* BCM_TRIUMPH2_SUPPORT */ 198 199 #ifdef PORTMOD_SUPPORT 200 #include <soc/portmod/portmod.h> 201 #endif /* PORTMOD_SUPPORT */ 202 203 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT 204 #include <bcm_int/esw/xgs5.h> 205 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */ 206 207 #ifdef INCLUDE_FCMAP 208 #include <../../phyident.h> 209 #endif 210 211 #define BCMI_GPORT_TYPE_VALID(port) \ 212 (BCM_GPORT_IS_VLAN_PORT(port) || \ 213 BCM_GPORT_IS_NIV_PORT(port) || \ 214 BCM_GPORT_IS_EXTENDER_PORT(port) || \ 215 BCM_GPORT_IS_SUBPORT_PORT(port) || \ 216 BCM_GPORT_IS_VXLAN_PORT(port) || \ 217 BCM_GPORT_IS_L2GRE_PORT(port) || \ 218 BCM_GPORT_IS_MIM_PORT(port) || \ 219 BCM_GPORT_IS_MPLS_PORT(port) || \ 220 BCM_GPORT_IS_FLOW_PORT(port) || \ 221 BCM_GPORT_IS_TRUNK(port)) 222 223 224 #if defined (BCM_EP_REDIRECT_VERSION_2) 225 #define BCMI_EP_REDIRECT_PORT (74) 226 #endif 227 228 #define _BCM_QOS_MAP_CHUNK_EGR_DSCP 64 229 #define _BCM_I2E_CLASS_ID_MAX 0x1ff 230 231 /* 232 * Define the macro for measuring the benchmark of speed change. 233 */ 234 #define BCM_PORT_SPEED_CHANGE_BENCHMARK 235 236 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 237 #define MODULE_ID_LOWER_6_BITS(a) ((a) = ((a) & 0x3f)) 238 #endif 239 240 /* 241 * Port Function Vector Driver 242 */ 243 bcm_esw_port_drv_t *bcm_esw_port_drv[BCM_MAX_NUM_UNITS] = {0}; 244 245 /* 246 * Variable: 247 * bcm_port_info 248 * Purpose: 249 * One entry for each SOC device containing port information 250 * for that device. Use the PORT macro to access it. 251 */ 252 static _bcm_port_info_t *bcm_port_info[BCM_MAX_NUM_UNITS]; 253 254 STATIC _bcm_port_force_forward_linkstate_t p_linkstate[BCM_MAX_NUM_UNITS]; 255 256 #define PORT(unit, port) bcm_port_info[unit][port] 257 258 extern int inside_bcm_shutdown[BCM_MAX_NUM_UNITS]; 259 260 #if defined(BCM_XMAC_SUPPORT) 261 extern int _mac_x_reinit(int unit, soc_port_t port); 262 #endif 263 264 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 265 extern src_modid_base_index_bookkeeping_t *src_modid_base_index_bk[BCM_MAX_NUM_UNITS]; 266 #endif 267 268 /* Accessor to bcm_port_info used by other modules */ 269 void _bcm_port_info_access(int unit, bcm_port_t port, _bcm_port_info_t **info) 270 { 271 (bcm_port_info[unit] != NULL) ? (*info = &PORT(unit, port)):(*info = NULL); 272 return; 273 } 274 275 /* Return On error with port mutex unlocked */ 276 #define _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(op) \ 277 do { \ 278 int __rv__; \ 279 if (((__rv__ = (op)) < 0)) { \ 280 PORT_UNLOCK(unit); \ 281 _SHR_ERROR_TRACE(__rv__); \ 282 return(__rv__); \ 283 } \ 284 } while(0) 285 286 int 287 _bcm_esw_port_gport_phyn_validate(int unit, bcm_port_t port, 288 bcm_port_t *local_port, int *phyn, 289 int *phy_lane, int *sys_side); 290 291 #if defined(BCM_KATANA2_SUPPORT) 292 int _bcm_kt2_update_port_mode(int unit, uint8 port, int speed); 293 int _bcm_kt2_cosq_dynamic_port_encap_change(int unit, bcm_port_t port); 294 #endif 295 296 #if defined(BCM_METROLITE_SUPPORT) 297 int _bcm_ml_update_port_mode(int unit, uint8 port, int speed); 298 #endif 299 #if defined(BCM_SABER2_SUPPORT) 300 int _bcm_sb2_update_port_mode(int unit, uint8 port, int speed); 301 #ifdef BCM_WARM_BOOT_SUPPORT 302 int bcm_sb2_wb_v2_flexio_update = 0; 303 #endif 304 #endif 305 #if defined(BCM_TRIUMPH3_SUPPORT) 306 STATIC int 307 _bcm_port_force_forward_add(int unit, bcm_port_t local_port, 308 bcm_port_t egr_port); 309 310 STATIC int 311 _bcm_port_force_forward_init(int unit); 312 313 STATIC int 314 _bcm_port_force_forward_deinit(int unit); 315 316 #ifdef BCM_WARM_BOOT_SUPPORT 317 STATIC int 318 _bcm_port_force_forward_sync(int unit, uint8 **scache_ptr); 319 320 STATIC int 321 _bcm_port_force_forward_reinit(int unit, uint8 **scache_ptr); 322 323 STATIC int 324 _bcm_port_force_forward_scache_size(int unit, int *size); 325 #endif /* BCM_WARM_BOOT_SUPPORT */ 326 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */ 327 328 /* 329 * Define: 330 * PORT_INIT 331 * Purpose: 332 * Causes a routine to return BCM_E_INIT if port is not yet initialized. 333 */ 334 335 #define PORT_INIT(unit) \ 336 if (bcm_port_info[unit] == NULL) { return BCM_E_INIT; } 337 338 /* 339 * Define: 340 * PORT_PARAM_CHECK 341 * Purpose: 342 * Check unit and port parameters for most bcm_port api calls 343 */ 344 #define PORT_PARAM_CHECK(unit, port) do { \ 345 PORT_INIT(unit); \ 346 if (!SOC_PORT_VALID(unit, port)) { return BCM_E_PORT; } \ 347 } while (0); 348 349 /* 350 * Define: 351 * PORT_SWITCHED_CHECK 352 * Purpose: 353 * Check unit and port for switching feature support 354 */ 355 #define PORT_SWITCHED_CHECK(unit, port) do { \ 356 if (IS_ST_PORT(unit, port)) { \ 357 return BCM_E_PORT; \ 358 } else { \ 359 if (IS_CPU_PORT(unit, port)) { \ 360 if (!soc_feature(unit, soc_feature_cpuport_switched)) { \ 361 return BCM_E_PORT; \ 362 } \ 363 } \ 364 } \ 365 } while (0); 366 367 368 /* 369 * Define: 370 * PORT_INFO_RX_LOS_SET 371 * Purpose: 372 * Records the SW RX LOS configuration used for warmboot recovery 373 */ 374 #define PORT_INFO_RX_LOS_SET(_u, _p, _type, _val) do { \ 375 if (_type == BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS) { \ 376 PORT(_u, _p).rx_los = _val; \ 377 } \ 378 } while (0); 379 380 381 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) \ 382 || defined(BCM_TRIUMPH3_SUPPORT) 383 #define BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ 64 384 #endif 385 #ifdef BCM_TRIUMPH2_SUPPORT 386 typedef int _port_src_mod_egr_prof_ptr_t; 387 STATIC _port_src_mod_egr_prof_ptr_t 388 port_src_mod_egr_prof_ptr[BCM_MAX_NUM_UNITS][SOC_MAX_NUM_PORTS]; 389 #define PORT_SRC_MOD_EGR_PROF_PTR(_u, _p) port_src_mod_egr_prof_ptr[_u][_p] 390 391 STATIC soc_profile_mem_t *_bcm_src_mod_egr_profile[BCM_MAX_NUM_UNITS]; 392 #define PORT_SRC_MOD_EGR_PROFILE(_u) _bcm_src_mod_egr_profile[_u] 393 394 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 395 STATIC 396 bcm_error_t _bcm_esw_port_stat_get_table_info( 397 int unit, 398 bcm_gport_t port, 399 uint32 *num_of_tables, 400 bcm_stat_flex_table_info_t *table_info); 401 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT */ 402 #endif /* BCM_TRIUMPH2_SUPPORT */ 403 404 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) ||\ 405 defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 406 /* EEE standard compliance Work Around: 407 * To Maintain software state of native eee in MAC*/ 408 STATIC int eee_cfg[BCM_MAX_NUM_UNITS][SOC_MAX_NUM_PORTS]; 409 #endif 410 411 #ifdef BCM_TRIUMPH3_SUPPORT 412 STATIC int _bcm_tr3_port_lanes_set(int unit, bcm_port_t port, int value); 413 STATIC int _bcm_tr3_port_lanes_get(int unit, bcm_port_t port, int *value); 414 #endif /* BCM_TRIUMPH3_SUPPORT */ 415 416 /* 417 * The Port Monitor Thread is intended for handling work-arounds 418 * that are unneeded in most cases. In order to avoid unnecessary 419 * processing overhead the thread is not started by default, but 420 * only if so requested through configuration parameters. 421 */ 422 423 typedef struct _port_mon_ctrl_s 424 { 425 char taskname[16]; 426 sal_sem_t sema; 427 int interval; 428 int running; 429 int stop; 430 int unit; 431 uint32 gtuc; 432 uint32 gtmca; 433 uint32 gtbca; 434 uint32 gtlcl; 435 uint32 gtpok; 436 } _port_mon_ctrl_t; 437 438 STATIC _port_mon_ctrl_t _bcm_esw_port_mon_ctrl[BCM_MAX_NUM_UNITS]; 439 440 #define PORT_MON_CTRL(_u) (&_bcm_esw_port_mon_ctrl[_u]) 441 442 #define PORT_MON_INTERVAL_MIN 100000 443 444 int 445 _bcm_port_mac_init(int unit, bcm_port_t port, int *okay); 446 447 #if defined(BCM_TRIDENT3_SUPPORT) 448 STATIC int 449 _bcm_esw_td3_asf_init(int unit, soc_td3_asf_mode_e asf_mode); 450 STATIC int 451 _bcm_esw_td3_port_asf_mode_set(int unit, bcm_port_t port, int mode); 452 #endif 453 454 #if defined(BCM_MAVERICK2_SUPPORT) 455 STATIC int 456 _bcm_esw_mv2_asf_init(int unit, soc_mv2_asf_mode_e asf_mode); 457 STATIC int 458 _bcm_esw_mv2_port_asf_mode_set(int unit, bcm_port_t port, int mode); 459 #endif 460 461 #if defined(BCM_TOMAHAWK_SUPPORT) 462 STATIC int 463 _bcm_esw_asf_init(int unit, soc_th_asf_mode_e asf_mode); 464 465 STATIC int 466 _bcm_esw_asf_deinit(int unit); 467 468 #ifdef BCM_WARM_BOOT_SUPPORT 469 STATIC int 470 _bcm_esw_asf_wb_memsz_get(int unit, uint32* const mem_sz, uint16 scache_ver); 471 472 STATIC int 473 _bcm_esw_asf_wb_sync(int unit, uint8* wb_data); 474 475 STATIC int 476 _bcm_esw_asf_wb_recover(int unit, uint8* const wb_data, uint16 scache_ver); 477 478 STATIC int 479 _bcm_esw_sflow_wb_recover(int unit); 480 481 STATIC int 482 _bcm_esw_sflow_counter_wb_recover(int unit, soc_mem_t mem); 483 #endif /* BCM_WARM_BOOT_SUPPORT */ 484 #endif /* BCM_TOMAHAWK_SUPPORT */ 485 486 #ifdef BCM_WARM_BOOT_SUPPORT 487 STATIC int 488 _bcm_esw_port_ifg_wb_sync(int unit, uint8 **scache_ptr); 489 490 STATIC int 491 _bcm_esw_port_ifg_wb_reinit(int unit, uint8 **scache_ptr); 492 #endif 493 494 STATIC int 495 bcmi_esw_port_encap_validate(int unit, bcm_port_t port, int mode, int speed); 496 STATIC int 497 _bcm_esw_port_encap_set(int unit, bcm_port_t port, int mode); 498 499 500 #if defined(BCM_GREYHOUND_SUPPORT) 501 /* Treat Packet Priority as dot1p ref_cnt structure */ 502 typedef struct bcmi_esw_treat_pktpri_as_dot1p_s { 503 sal_mutex_t ref_cnt_mutex; 504 int ref_cnt; 505 } bcmi_esw_treat_pktpri_as_dot1p_t; 506 507 STATIC bcmi_esw_treat_pktpri_as_dot1p_t 508 bcmi_treat_pktpri_as_dot1p[BCM_MAX_NUM_UNITS]; 509 510 /* Treat Packet Priority as dot1p ref_cnt lock/unlock */ 511 #define TREAT_PKTPRI_AS_DOT1P_LOCK(_unit_) \ 512 sal_mutex_take(bcmi_treat_pktpri_as_dot1p[_unit_].ref_cnt_mutex, \ 513 sal_mutex_FOREVER) 514 #define TREAT_PKTPRI_AS_DOT1P_UNLOCK(_unit_) \ 515 sal_mutex_give(bcmi_treat_pktpri_as_dot1p[_unit_].ref_cnt_mutex) 516 517 /* 518 * Function: 519 * bcmi_esw_port_treat_pktpri_as_dot1p_cleanup 520 * Purpose: 521 * cleanup resource after detach 522 * Parameters: 523 * unit - (IN) Device Number 524 * Return Value: 525 * BCM_E_XXX 526 * Notes: 527 */ 528 STATIC int 529 bcmi_esw_port_treat_pktpri_as_dot1p_cleanup(int unit) 530 { 531 if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex != NULL) { 532 sal_mutex_destroy(bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex); 533 bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex = NULL; 534 } 535 536 return BCM_E_NONE; 537 } 538 539 /* 540 * Function: 541 * bcmi_esw_port_treat_pktpri_as_dot1p_init 542 * Purpose: 543 * Initialize the ref_cnt of enabling treat packet priority 544 * as dot1p priority for different packet types or port controls. 545 * Parameters: 546 * unit - (IN) Device Number 547 * Return Value: 548 * BCM_E_XXX 549 * Notes: 550 * The ref_cnt of treat packet priority as dot1p priority is system-wise. 551 */ 552 STATIC int 553 bcmi_esw_port_treat_pktpri_as_dot1p_init(int unit) 554 { 555 if (!soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 556 return BCM_E_UNAVAIL; 557 } 558 559 /* Create protection mutex. */ 560 if (NULL == bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex) { 561 bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex = 562 sal_mutex_create("treat_pktpri_as_dot1p.lock"); 563 if (NULL == bcmi_treat_pktpri_as_dot1p[unit].ref_cnt_mutex) { 564 return BCM_E_RESOURCE; 565 } 566 } 567 568 bcmi_treat_pktpri_as_dot1p[unit].ref_cnt = 0; 569 570 return BCM_E_NONE; 571 } 572 573 /* 574 * Function: 575 * bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 576 * Purpose: 577 * Update the ref_cnt of enabling treat packet priority 578 * as dot1p priority for various packet types or port controls. 579 * Parameters: 580 * unit - (IN) Device Number 581 * incr_decr_flag - (IN) If TRUE, increment ref_cnt, else decrease ref_cnt 582 * Return Value: 583 * BCM_E_XXX 584 * Notes: 585 * The ref_cnt of treat packet priority as dot1p priority is system-wise. 586 */ 587 STATIC int 588 bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update( 589 int unit, int incr_decr_flag) 590 { 591 int rv = BCM_E_NONE; 592 uint64 regval64; 593 594 if (!soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 595 return BCM_E_UNAVAIL; 596 } 597 598 /* Input parameter check */ 599 if ((incr_decr_flag != 1) && (incr_decr_flag != -1)) { 600 return BCM_E_PARAM; 601 } 602 603 TREAT_PKTPRI_AS_DOT1P_LOCK(unit); 604 if (incr_decr_flag == 1) { 605 /* Increment */ 606 /* Need to set TREAT_PKTPRI_AS_DOT1Pf for the first ref_cnt */ 607 if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt == 0) { 608 COMPILER_64_ZERO(regval64); 609 rv = READ_ING_CONFIG_64r(unit, ®val64); 610 if (BCM_FAILURE(rv)) { 611 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit); 612 return rv; 613 } 614 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®val64, 615 TREAT_PKTPRI_AS_DOT1Pf, 1); 616 rv = WRITE_ING_CONFIG_64r(unit, regval64); 617 if (BCM_FAILURE(rv)) { 618 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit); 619 return rv; 620 } 621 } 622 bcmi_treat_pktpri_as_dot1p[unit].ref_cnt++; 623 } else { 624 /* Decrement */ 625 if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt >= 1) { 626 bcmi_treat_pktpri_as_dot1p[unit].ref_cnt--; 627 /* Need to unset TREAT_PKTPRI_AS_DOT1Pf when ref_cnt = 0 */ 628 if (bcmi_treat_pktpri_as_dot1p[unit].ref_cnt == 0) { 629 COMPILER_64_ZERO(regval64); 630 rv = READ_ING_CONFIG_64r(unit, ®val64); 631 if (BCM_FAILURE(rv)) { 632 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit); 633 return rv; 634 } 635 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®val64, 636 TREAT_PKTPRI_AS_DOT1Pf, 0); 637 rv = WRITE_ING_CONFIG_64r(unit, regval64); 638 if (BCM_FAILURE(rv)) { 639 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit); 640 return rv; 641 } 642 } 643 } 644 } 645 TREAT_PKTPRI_AS_DOT1P_UNLOCK(unit); 646 647 return rv; 648 } 649 650 #ifdef BCM_WARM_BOOT_SUPPORT 651 /* 652 * Function: 653 * bcmi_esw_port_treat_pktpri_as_dot1p_reinit 654 * Purpose: 655 * Recovery the ref_cnt of enabling treat packet priority 656 * as dot1p priority for different packet types or port contols. 657 * Parameters: 658 * unit - (IN) Device Number 659 * Return Value: 660 * BCM_E_XXX 661 */ 662 STATIC int 663 bcmi_esw_port_treat_pktpri_as_dot1p_reinit(int unit) 664 { 665 int rv = BCM_E_NONE; 666 bcm_port_t port_idx; 667 int pri_en = 0; 668 uint64 regval64; 669 670 if (!soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 671 return BCM_E_UNAVAIL; 672 } 673 674 bcmi_treat_pktpri_as_dot1p[unit].ref_cnt = 0; 675 676 COMPILER_64_ZERO(regval64); 677 BCM_IF_ERROR_RETURN( 678 READ_ING_CONFIG_64r(unit, ®val64)); 679 if (soc_reg64_field32_get(unit, ING_CONFIG_64r, regval64, 680 TREAT_PKTPRI_AS_DOT1Pf) == 0x1) { 681 BCM_PBMP_ITER(PBMP_PORT_ALL(unit), port_idx) { 682 /* Recover ref_cnt for Egress VLAN internal priority mapping */ 683 rv = bcm_esw_port_control_get 684 (unit, port_idx, 685 bcmPortControlEgressVlanPriUsesPktPri, &pri_en); 686 if (BCM_FAILURE(rv)) { 687 return rv; 688 } 689 if (pri_en) { 690 BCM_IF_ERROR_RETURN( 691 bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 692 (unit, 1)); 693 } 694 695 /* Recover ref_cnt for ETAG internal priority mapping */ 696 if (soc_feature(unit, soc_feature_port_extension)) { 697 rv = bcm_esw_port_control_get(unit, port_idx, 698 bcmPortControlUseEtagPri, &pri_en); 699 if (BCM_FAILURE(rv)) { 700 return rv; 701 } 702 if (pri_en) { 703 BCM_IF_ERROR_RETURN( 704 bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 705 (unit, 1)); 706 } 707 } 708 #ifdef BCM_HURRICANE3_SUPPORT 709 /* Recover ref_cnt for MiML internal priority mapping */ 710 if (soc_feature(unit, soc_feature_miml)) { 711 rv = bcm_esw_port_control_get(unit, port_idx, 712 bcmPortControlTrustMimlPri, &pri_en); 713 if (BCM_FAILURE(rv)) { 714 return rv; 715 } 716 if (pri_en) { 717 BCM_IF_ERROR_RETURN( 718 bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 719 (unit, 1)); 720 } 721 } 722 #endif /* BCM_HURRICANE3_SUPPORT */ 723 } 724 } 725 726 return rv; 727 } 728 #endif /* BCM_WARM_BOOT_SUPPORT */ 729 #endif /* BCM_GREYHOUND_SUPPORT */ 730 731 /* 732 * Function: 733 * _bcm_esw_port_mon_unimac_lock_up 734 * Description: 735 * Check for UniMAC half duplex collision lock-up issue 736 * Parameters: 737 * pmc - (IN) port monitor control data 738 * Return Value: 739 * None 740 * Notes: 741 * See errata 56020-ES105-R for additional details. 742 */ 743 STATIC void 744 _bcm_esw_port_mon_unimac_lock_up(_port_mon_ctrl_t *pmc) 745 { 746 int unit = pmc->unit; 747 int port, rv, link_up, fulld, lock_up; 748 uint32 gtuc, gtmca, gtbca, gtlcl, gtpok; 749 uint32 ccnt, rcnt, txfifo; 750 751 if (!soc_feature(unit, soc_feature_unimac)) { 752 return; 753 } 754 755 PBMP_E_ITER(unit, port) { 756 /* Check only half duplex ports */ 757 rv = _bcm_esw_link_get(unit, port, &link_up); 758 if (BCM_FAILURE(rv) || !link_up) { 759 continue; 760 } 761 rv = MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &fulld); 762 if (BCM_FAILURE(rv) || fulld) { 763 continue; 764 } 765 766 lock_up = 0; 767 rv = 0; 768 769 /* Collect test counters */ 770 rv += soc_counter_get32(unit, port, GTUCr, 0, >uc); 771 rv += soc_counter_get32(unit, port, GTMCAr, 0, >mca); 772 rv += soc_counter_get32(unit, port, GTBCAr, 0, >bca); 773 rv += soc_counter_get32(unit, port, GTLCLr, 0, >lcl); 774 rv += soc_counter_get32(unit, port, GTPOKr, 0, >pok); 775 776 /* Test lock-up conditions */ 777 if (gtuc == pmc->gtuc && 778 gtmca == pmc->gtmca && 779 gtbca == pmc->gtbca) { 780 if (gtlcl != pmc->gtlcl && 781 gtpok != pmc->gtpok) { 782 lock_up = 2; 783 } else { 784 rcnt = ccnt = 0; 785 if (SOC_REG_IS_VALID(unit, GE0_GBODE_CELL_CNTr)) { 786 uint32 reg, addr, idx; 787 idx = (port < 6) ? (port - 1) : ((port - 6) % 12); 788 reg = GE0_GBODE_CELL_CNTr; 789 addr = soc_reg_addr(unit, reg, port, 0); 790 addr += idx; 791 rv += soc_reg32_read(unit, addr, &ccnt); 792 reg = GE0_GBODE_CELL_REQ_CNTr; 793 addr = soc_reg_addr(unit, reg, port, 0); 794 addr += idx; 795 rv += soc_reg32_read(unit, addr, &rcnt); 796 } else if (SOC_REG_IS_VALID(unit, GE_GBODE_CELL_CNTr)) { 797 rv += READ_GE_GBODE_CELL_CNTr(unit, port, &ccnt); 798 rv += READ_GE_GBODE_CELL_REQ_CNTr(unit, port, &rcnt); 799 } 800 if (gtlcl && rcnt == 0 && ccnt == 4) { 801 lock_up = 1; 802 } 803 } 804 } 805 if (lock_up == 0) { 806 rv += READ_TXFIFO_STATr(unit, port, &txfifo); 807 if (soc_reg_field_get(unit, TXFIFO_STATr, 808 txfifo, TXFIFO_UNDERRUNf)) { 809 lock_up = 2; 810 } 811 } 812 813 /* Reset MAC if lock-up is detected */ 814 if (rv == 0 && lock_up) { 815 LOG_VERBOSE(BSL_LS_BCM_PORT, 816 (BSL_META_U(unit, 817 "Port %s: UniMAC lock up (%d) detected\n"), 818 SOC_PORT_NAME(unit, port), lock_up)); 819 PORT_LOCK(unit); 820 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 821 SOC_MAC_CONTROL_SW_RESET, TRUE); 822 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 823 SOC_MAC_CONTROL_SW_RESET, FALSE); 824 PORT_UNLOCK(unit); 825 } 826 827 /* Sync test counters */ 828 pmc->gtuc = gtuc; 829 pmc->gtmca = gtmca; 830 pmc->gtbca = gtbca; 831 pmc->gtlcl = gtlcl; 832 pmc->gtpok = gtpok; 833 } 834 } 835 836 /* 837 * Function: 838 * _bcm_esw_port_mon_ctrl_thread 839 * Description: 840 * Port monitor thread 841 * Parameters: 842 * context - (IN) Port monitor control data 843 * Return Value: 844 * None 845 */ 846 STATIC void 847 _bcm_esw_port_mon_ctrl_thread(void *context) 848 { 849 _port_mon_ctrl_t *pmc = (_port_mon_ctrl_t *)context; 850 851 LOG_VERBOSE(BSL_LS_BCM_PORT, 852 (BSL_META("Port monitor started on unit %d\n"), pmc->unit)); 853 854 pmc->running = 1; 855 while (!pmc->stop) { 856 _bcm_esw_port_mon_unimac_lock_up(pmc); 857 (void)sal_sem_take(pmc->sema, pmc->interval); 858 } 859 pmc->running = 0; 860 } 861 862 /* 863 * Function: 864 * _bcm_esw_port_mon_start 865 * Description: 866 * Start port monitor thread 867 * Parameters: 868 * unit - (IN) BCM device number 869 * Return Value: 870 * BCM_E_NONE if thread started successfully 871 */ 872 int 873 _bcm_esw_port_mon_start(int unit) 874 { 875 _port_mon_ctrl_t *pmc = PORT_MON_CTRL(unit); 876 int cnt; 877 878 pmc->interval = soc_property_get(unit, spn_PORTMON_INTERVAL, 0); 879 if (pmc->interval == 0) { 880 return BCM_E_NONE; 881 } 882 883 if (pmc->interval < PORT_MON_INTERVAL_MIN) { 884 pmc->interval = PORT_MON_INTERVAL_MIN; 885 } 886 887 pmc->unit = unit; 888 if (pmc->running) { 889 LOG_VERBOSE(BSL_LS_BCM_PORT, 890 (BSL_META_U(unit, 891 "Port monitor already running on unit %d\n"), 892 pmc->unit)); 893 } else { 894 if (pmc->sema == NULL) { 895 pmc->sema = sal_sem_create("port_mon_SLEEP", sal_sem_BINARY, 0); 896 if (pmc->sema == NULL) { 897 return BCM_E_MEMORY; 898 } 899 } 900 sal_snprintf(pmc->taskname, sizeof (pmc->taskname), 901 "bcmPortMon.%d", unit); 902 pmc->stop = 0; 903 if (sal_thread_create(pmc->taskname, SAL_THREAD_STKSZ, 904 soc_property_get(unit, 905 spn_PORTMON_THREAD_PRI, 906 50), 907 _bcm_esw_port_mon_ctrl_thread, 908 pmc) == SAL_THREAD_ERROR) { 909 return BCM_E_MEMORY; 910 } 911 cnt = 10; 912 while (!pmc->running && cnt--) { 913 sal_usleep(100000); 914 } 915 if (!pmc->running) { 916 LOG_ERROR(BSL_LS_BCM_PORT, 917 (BSL_META_U(unit, 918 "%s: Thread did not start\n"), pmc->taskname)); 919 return BCM_E_TIMEOUT; 920 } 921 } 922 return BCM_E_NONE; 923 } 924 925 /* 926 * Function: 927 * _bcm_esw_port_mon_stop 928 * Description: 929 * Stop port monitor thread 930 * Parameters: 931 * unit - (IN) BCM device number 932 * Return Value: 933 * BCM_E_NONE if thread stopped successfully 934 */ 935 int 936 _bcm_esw_port_mon_stop(int unit) 937 { 938 int cnt; 939 _port_mon_ctrl_t *pmc = PORT_MON_CTRL(unit); 940 941 if (pmc->sema == NULL) { 942 return BCM_E_NONE; 943 } 944 945 pmc->stop = 1; 946 sal_sem_give(pmc->sema); 947 cnt = 10; 948 while (pmc->running && cnt--) { 949 sal_usleep(100000); 950 } 951 if (pmc->running) { 952 LOG_ERROR(BSL_LS_BCM_PORT, 953 (BSL_META_U(unit, 954 "%s: Thread did not start\n"), pmc->taskname)); 955 return BCM_E_TIMEOUT; 956 } 957 sal_sem_destroy(pmc->sema); 958 pmc->sema = NULL; 959 960 return BCM_E_NONE; 961 } 962 963 #ifdef BCM_TRIUMPH3_SUPPORT 964 static _port_ibod_ctrl_t *_port_ibod_ctrl[BCM_MAX_NUM_UNITS]; 965 static int txerr_trigger_flag[SOC_MAX_NUM_PORTS]; 966 967 #define IBOD_RECOVERY_GROUP_MAX ((SOC_MAX_NUM_PORTS + 3) /4) 968 #define IBOD_RECOVERY_GROUP_VALID(grp) ((grp) >= 0 && (grp) < IBOD_RECOVERY_GROUP_MAX) 969 #define IBOD_RECOVERY_GROUP(phy_port) ((phy_port - 1)/4) 970 static sal_mutex_t ibod_port_group_recovery_lock[BCM_MAX_NUM_UNITS][IBOD_RECOVERY_GROUP_MAX]; 971 972 #define TR3_IARB_TDM_TABLE_LENGTH 512 973 974 #define IBOD_IF_ERROR_RETURN_UNLOCK(unit,port,rv) \ 975 if (SOC_FAILURE(rv)) { \ 976 soc_ibod_recovery_in_progress_set(unit, 0); \ 977 _bcm_esw_ibod_recovery_port_unlock(unit, port); \ 978 PORT_UNLOCK(unit); \ 979 return rv; \ 980 } 981 982 #define TXERR_IF_ERROR_RETURN_UNLOCK(unit,port,rv) \ 983 if (SOC_FAILURE(rv)) { \ 984 _bcm_esw_ibod_recovery_port_unlock(unit, port); \ 985 PORT_UNLOCK(unit); \ 986 _bcm_esw_lc_unlock(unit);\ 987 return rv; \ 988 } 989 990 /*#define IBOD_DEBUG 991 #define TXERR_DEBUG */ 992 993 int _ibod_debug_flag = 0; 994 995 void _bcm_esw_ibod_debug_flag_set(int unit, int flag) 996 { 997 _ibod_debug_flag = flag; 998 cli_out("IBOD debug flag:0X%x\n", _ibod_debug_flag); 999 } 1000 1001 static int _bcm_esw_ibod_recovery_lock_init(int unit) 1002 { 1003 int rv = BCM_E_NONE; 1004 int group, rollback_group; 1005 1006 for (group = 0; group < IBOD_RECOVERY_GROUP_MAX; group++) { 1007 ibod_port_group_recovery_lock[unit][group] = sal_mutex_create("IBOD_GROUP_LOCK"); 1008 if (ibod_port_group_recovery_lock[unit][group] == NULL) { 1009 rv = BCM_E_MEMORY; 1010 break; 1011 } 1012 } 1013 /* Recycle the memory */ 1014 if (SOC_FAILURE(rv)) { 1015 for (rollback_group = group - 1; rollback_group >= 0; rollback_group--) { 1016 sal_mutex_destroy(ibod_port_group_recovery_lock[unit][rollback_group]); 1017 } 1018 } 1019 return BCM_E_NONE; 1020 } 1021 1022 static void _bcm_esw_ibod_recovery_lock_deinit(int unit) 1023 { 1024 int group; 1025 1026 for (group = 0; group < IBOD_RECOVERY_GROUP_MAX; group++) { 1027 if (ibod_port_group_recovery_lock[unit][group] != NULL) { 1028 sal_mutex_destroy(ibod_port_group_recovery_lock[unit][group]); 1029 } 1030 } 1031 } 1032 1033 void _bcm_esw_ibod_recovery_port_lock(int unit, bcm_port_t port) 1034 { 1035 int phy_port; 1036 int group; 1037 /* coverity[overrun-local : FALSE] */ 1038 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 1039 group = IBOD_RECOVERY_GROUP(phy_port); 1040 if (IBOD_RECOVERY_GROUP_VALID(group) && 1041 ibod_port_group_recovery_lock[unit][group] != NULL) { 1042 sal_mutex_take(ibod_port_group_recovery_lock[unit][group], sal_mutex_FOREVER); 1043 } 1044 } 1045 1046 void _bcm_esw_ibod_recovery_port_unlock(int unit, bcm_port_t port) 1047 { 1048 int phy_port; 1049 int group; 1050 1051 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 1052 group = IBOD_RECOVERY_GROUP(phy_port); 1053 if (IBOD_RECOVERY_GROUP_VALID(group) && 1054 ibod_port_group_recovery_lock[unit][group] != NULL) { 1055 sal_mutex_give(ibod_port_group_recovery_lock[unit][group]); 1056 } 1057 } 1058 1059 STATIC int _bcm_tr3_port_is_control_port(int unit, soc_port_t port) 1060 { 1061 int phy_port, phy_port_base; 1062 soc_info_t *si = &SOC_INFO(unit); 1063 1064 phy_port = si->port_l2p_mapping[port]; 1065 if (phy_port == -1) { 1066 return FALSE; 1067 } 1068 1069 phy_port_base = ((phy_port - 1) & ~0x3) + 1; 1070 if (phy_port == phy_port_base) { 1071 return TRUE; 1072 } 1073 1074 return FALSE; 1075 } 1076 1077 STATIC int 1078 _bcm_tr3_ibod_mac_x_enable_set(int unit, soc_port_t port, int enable) 1079 { 1080 uint64 ctrl, octrl; 1081 pbmp_t mask; 1082 1083 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port, &ctrl)); 1084 octrl = ctrl; 1085 /* Don't disable TX since it stops egress and hangs if CPU sends */ 1086 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, TX_ENf, 1); 1087 if (enable) { 1088 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 1); 1089 } else { 1090 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, RX_ENf, 0); 1091 } 1092 if (COMPILER_64_NE(ctrl, octrl)) { 1093 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl)); 1094 sal_udelay(10); 1095 } 1096 1097 /* Put the XMAC in a soft reset state when disabled to allow packets to 1098 * drain from the TX FIFO */ 1099 soc_reg64_field32_set(unit, XMAC_CTRLr, &ctrl, SOFT_RESETf, 1100 enable ? 0 : 1); 1101 if (COMPILER_64_NE(ctrl, octrl)) { 1102 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr(unit, port, ctrl)); 1103 } 1104 1105 if (enable) { 1106 SOC_IF_ERROR_RETURN(soc_phyctrl_notify(unit, port, phyEventResume, 1107 PHY_STOP_MAC_DIS)); 1108 } else { 1109 soc_link_mask2_get(unit, &mask); 1110 SOC_PBMP_PORT_REMOVE(mask, port); 1111 SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask)); 1112 SOC_IF_ERROR_RETURN(_mac_x_drain_cells(unit, port, 0)); 1113 SOC_IF_ERROR_RETURN(soc_phyctrl_notify(unit, port, phyEventStop, 1114 PHY_STOP_MAC_DIS)); 1115 } 1116 1117 return SOC_E_NONE; 1118 } 1119 1120 STATIC int 1121 _bcm_tr3_ibod_port_isolate(int unit, int port_enable, bcm_port_t port, 1122 int *port_dis_untag, int *port_dis_tag) 1123 { 1124 port_tab_entry_t ptab_entry; 1125 1126 /* Isolate, drain and remove port from epc link */ 1127 BCM_IF_ERROR_RETURN 1128 (_bcm_tr3_ibod_mac_x_enable_set(unit, port, FALSE)); 1129 1130 if (port_enable) { 1131 LOG_VERBOSE(BSL_LS_BCM_PORT, 1132 (BSL_META_U(unit, 1133 "Port %d enable case..\n"), port)); 1134 /* Enable phy so that packets can loopback */ 1135 SOC_IF_ERROR_RETURN 1136 (soc_phyctrl_enable_set(unit, port, TRUE)); 1137 } else { 1138 LOG_VERBOSE(BSL_LS_BCM_PORT, 1139 (BSL_META_U(unit, 1140 "Port %d Runt received case..\n"), port)); 1141 } 1142 1143 SOC_IF_ERROR_RETURN(MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, TRUE)); 1144 1145 /* Enable MAC so that packets can loopback from phy */ 1146 BCM_IF_ERROR_RETURN 1147 (_bcm_tr3_ibod_mac_x_enable_set(unit, port, TRUE)); 1148 1149 /* Discard tag and untag packet at IP before send packets */ 1150 BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port, &ptab_entry)); 1151 *port_dis_untag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf); 1152 *port_dis_tag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf); 1153 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, 1); 1154 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, 1); 1155 BCM_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port, &ptab_entry)); 1156 1157 return SOC_E_NONE; 1158 } 1159 1160 STATIC int 1161 _bcm_tr3_ibod_port_resume(int unit, bcm_port_t port, int port_dis_untag, int port_dis_tag) 1162 { 1163 pbmp_t epc_pbm; 1164 port_tab_entry_t ptab_entry; 1165 1166 /* Remove MAC loopback */ 1167 SOC_IF_ERROR_RETURN(MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, FALSE)); 1168 1169 /* Restore port discard tag and untag at IP */ 1170 BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port, &ptab_entry)); 1171 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, port_dis_untag); 1172 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, port_dis_tag); 1173 BCM_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port, &ptab_entry)); 1174 1175 /* Restore port in epc link bmap */ 1176 soc_link_mask2_get(unit, &epc_pbm); 1177 SOC_PBMP_PORT_ADD(epc_pbm, port); 1178 SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, epc_pbm)); 1179 1180 return SOC_E_NONE; 1181 } 1182 1183 STATIC int 1184 _bcm_hx4_ibod_sync_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, int port_group_iter, 1185 bcm_port_t port) 1186 { 1187 bcm_pbmp_t pbmp; 1188 bcm_port_t port_iter; 1189 uint32 port_mode; 1190 uint32 rval, rval_1, port_dis_tag=0, port_dis_untag=0, xmac_mode=0; 1191 uint64 rval64,tmp64; 1192 uint64 egress_meter[4]; 1193 int unit=ibod_ctrl->unit; 1194 int rv = BCM_E_NONE; 1195 bcm_pkt_t *pkt = &ibod_ctrl->pkt; 1196 pbmp_t mask, mask1, mask1_restore, mask_restore; 1197 uint64 rrpkt, rrbyt, count64, count64_1; 1198 int count, count_1, i; 1199 soc_timeout_t timeout; 1200 egr_enable_entry_t egr_en; 1201 soc_info_t *si = &SOC_INFO(unit); 1202 port_tab_entry_t ptab_entry; 1203 egr_mmu_requests_entry_t mmu_entry; 1204 int rx_llfc_en[4], rx_pfc_en[4], pause_rx[4], rx_lss[4], rx_lss_1[4], rx_en[4]; 1205 uint32 max_used_entry, ep_level, overflow0, overflow1, total_cell; 1206 static const soc_reg_t lls_port_credit_reg[] = { 1207 LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr, 1208 LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr, 1209 LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr, 1210 LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr, 1211 LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr, 1212 LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr, 1213 LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr, 1214 LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr, 1215 LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr, 1216 LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr, 1217 LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr, 1218 LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr, 1219 LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr, 1220 LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr, 1221 LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr, 1222 LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr, 1223 LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr, 1224 LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr, 1225 LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr, 1226 LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr, 1227 LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr 1228 }; 1229 sal_usecs_t time1, time2; 1230 1231 time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 1232 1233 rv = bcm_esw_port_subsidiary_ports_get(unit, port, &pbmp); 1234 if (BCM_FAILURE(rv)) { 1235 LOG_ERROR(BSL_LS_BCM_PORT, 1236 (BSL_META_U(unit, "\n Error in retreiving the subsidiary ports" 1237 "for port %s"), SOC_PORT_NAME(unit,port))); 1238 return BCM_E_NONE; 1239 } 1240 1241 count=0; 1242 BCM_PBMP_ITER(pbmp, port_iter) { 1243 rv = READ_XMAC_MODEr(unit, port_iter, &rval64); 1244 if (BCM_FAILURE(rv)) { 1245 return BCM_E_NONE; 1246 } 1247 xmac_mode = soc_reg64_field32_get(unit, XMAC_MODEr,rval64, HDR_MODEf); 1248 if ((xmac_mode == 1) || (xmac_mode == 2)) { 1249 count++; 1250 } 1251 } 1252 1253 if (!count) { 1254 return BCM_E_NONE; 1255 } 1256 1257 BCM_PBMP_ITER(pbmp, port_iter) { 1258 SOC_IF_ERROR_RETURN(READ_PORT_CDC_TXFIFO_OVRFLWr(unit, port_iter, &rval)); 1259 if (rval) { 1260 LOG_ERROR(BSL_LS_BCM_PORT, 1261 (BSL_META_U(unit, "ENTER VALIDATE PORT_CDC_TXFIFO_OVRFLW ERR" 1262 " failed on port:%d\n\r"), port_iter )); 1263 } 1264 } 1265 1266 _bcm_esw_lc_lock(unit); 1267 1268 soc_link_fwd_get(unit, &mask1); 1269 SOC_PBMP_ASSIGN(mask1_restore,mask1); 1270 BCM_PBMP_ITER(pbmp, port_iter) { 1271 BCM_PBMP_PORT_REMOVE(mask1,port_iter); 1272 } 1273 rv = soc_link_fwd_set(unit, mask1); 1274 if (BCM_FAILURE(rv)) { 1275 _bcm_esw_lc_unlock(unit); 1276 LOG_ERROR(BSL_LS_BCM_PORT, 1277 (BSL_META_U(unit, "\n Error in setting the mask FWD" 1278 " for WAR on port %s"), SOC_PORT_NAME(unit,port))); 1279 return BCM_E_NONE; 1280 } 1281 1282 /* Hold the ibod recovery port group lock */ 1283 _bcm_esw_ibod_recovery_port_lock(unit, port); 1284 PORT_LOCK(unit); 1285 1286 soc_link_mask2_get(unit, &mask); 1287 SOC_PBMP_ASSIGN(mask_restore, mask); 1288 BCM_PBMP_ITER(pbmp, port_iter) { 1289 BCM_PBMP_PORT_REMOVE(mask,port_iter); 1290 } 1291 rv = soc_link_mask2_set(unit, mask); 1292 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1293 1294 1295 BCM_PBMP_ITER(pbmp, port_iter) { 1296 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, port_iter, 1297 &ptab_entry); 1298 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1299 port_dis_untag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf); 1300 port_dis_tag = soc_mem_field32_get(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf); 1301 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, 1); 1302 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, 1); 1303 rv = soc_mem_write(unit, PORT_TABm, MEM_BLOCK_ALL, port_iter, 1304 &ptab_entry); 1305 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1306 } 1307 1308 count=0; 1309 BCM_PBMP_ITER(pbmp, port_iter) { 1310 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1311 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1312 rx_en[count] = soc_reg64_field32_get(unit, XMAC_CTRLr, rval64, RX_ENf); 1313 count++; 1314 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 0); 1315 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1316 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1317 } 1318 1319 BCM_PBMP_ITER(pbmp, port_iter) { 1320 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1321 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1322 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 0); 1323 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1324 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1325 } 1326 1327 BCM_PBMP_ITER(pbmp, port_iter) { 1328 rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64); 1329 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1330 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 1); 1331 rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64); 1332 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1333 } 1334 1335 BCM_PBMP_ITER(pbmp, port_iter) { 1336 rv = READ_XPORT_TO_MMU_BKPr(unit, port_iter, &rval); 1337 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1338 soc_reg_field_set(unit, XPORT_TO_MMU_BKPr, &rval, PRI15_0_BKPf, 0); 1339 rv = WRITE_XPORT_TO_MMU_BKPr(unit, port_iter, 0); 1340 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1341 } 1342 1343 count=0; 1344 BCM_PBMP_ITER(pbmp, port_iter) { 1345 rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64); 1346 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1347 pause_rx[count] = soc_reg64_field32_get(unit, XMAC_PAUSE_CTRLr, rval64, RX_PAUSE_ENf); 1348 soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, 0); 1349 rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64); 1350 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1351 1352 rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64); 1353 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1354 rx_pfc_en[count] = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval64, RX_PFC_ENf); 1355 soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, 0); 1356 rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64); 1357 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1358 1359 rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64); 1360 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1361 rx_llfc_en[count] = soc_reg64_field32_get(unit, XMAC_LLFC_CTRLr, rval64, RX_LLFC_ENf); 1362 soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, 0); 1363 rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64); 1364 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1365 count++; 1366 } 1367 1368 count=0; 1369 BCM_PBMP_ITER(pbmp, port_iter) { 1370 rv = READ_EGRMETERINGCONFIG_64r(unit, port_iter, &rval64); 1371 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1372 egress_meter[count]=rval64; 1373 COMPILER_64_ZERO(tmp64); 1374 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, tmp64); 1375 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1376 count++; 1377 } 1378 1379 count=0; 1380 BCM_PBMP_ITER(pbmp, port_iter) { 1381 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 1382 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1383 rx_lss[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64, 1384 DROP_TX_DATA_ON_LOCAL_FAULTf); 1385 rx_lss_1[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64, 1386 DROP_TX_DATA_ON_REMOTE_FAULTf); 1387 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1); 1388 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1); 1389 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 1390 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1391 count++; 1392 } 1393 1394 COMPILER_64_SET(tmp64, pbmp.pbits[1], pbmp.pbits[0]); 1395 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 1396 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1397 soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, tmp64); 1398 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 1399 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1400 1401 BCM_PBMP_ITER(pbmp, port_iter) { 1402 rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval); 1403 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1404 soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 1); 1405 rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval); 1406 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1407 } 1408 1409 count_1=0; 1410 soc_timeout_init(&timeout, 30000, 0); 1411 do { 1412 if (soc_timeout_check(&timeout)) { 1413 rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval); 1414 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1415 soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1); 1416 rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval); 1417 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1418 /* coverity[overrun-local : FALSE] */ 1419 rv = READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL, 1420 si->port_l2p_mapping[port], 1421 &max_used_entry); 1422 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1423 ep_level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf); 1424 if(ep_level == 0) { 1425 ibod_ctrl->drain_timeout_flag = 1; 1426 } 1427 else { 1428 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0); 1429 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1430 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1); 1431 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1432 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &total_cell); 1433 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1434 LOG_ERROR(BSL_LS_BCM_PORT, 1435 (BSL_META_U(unit, "\n IBOD recovery Timeout Drain packets %d PORT: %s, " 1436 "ep_level:%d, overflow0:%d, overflow1:%d,total_cell:%d\n"), 1437 ibod_ctrl->unit, SOC_PORT_NAME(unit,port), ep_level, overflow0, overflow1,total_cell)); 1438 } 1439 break; 1440 } else { 1441 BCM_PBMP_ITER(pbmp, port_iter) { 1442 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 1443 REG_PORT_ANY, 0, &rval); 1444 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1445 if (!rval) { 1446 count_1++; 1447 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, 1448 si->port_l2p_mapping[port_iter], 1449 &mmu_entry); 1450 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1451 rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 1452 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 1453 REG_PORT_ANY, 0, rval); 1454 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1455 } 1456 } 1457 count=0; 1458 BCM_PBMP_ITER(pbmp, port_iter) { 1459 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port_iter, &rval); 1460 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1461 count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf); 1462 rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port_iter, &rval); 1463 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1464 count += soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf); 1465 } 1466 } 1467 } while (count); 1468 1469 BCM_PBMP_ITER(pbmp, port_iter) { 1470 /* coverity[overrun-local : FALSE] */ 1471 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, 1472 si->port_l2p_mapping[port_iter], &mmu_entry); 1473 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1474 rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 1475 /* coverity[overrun-local : FALSE] */ 1476 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 1477 REG_PORT_ANY, 0, &rval_1); 1478 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1479 if (rval != rval_1) { 1480 /* coverity[overrun-local : FALSE] */ 1481 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 1482 REG_PORT_ANY, 0, rval); 1483 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1484 } 1485 } 1486 1487 count = 0; 1488 BCM_PBMP_ITER(pbmp, port_iter) { 1489 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, egress_meter[count]); 1490 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1491 count++; 1492 } 1493 1494 rv = READ_PORT_MODE_REGr(unit, port, &rval); 1495 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1496 port_mode = soc_reg_field_get(unit, PORT_MODE_REGr, 1497 rval, XPORT0_CORE_PORT_MODEf); 1498 1499 BCM_PBMP_ITER(pbmp, port_iter) { 1500 rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64); 1501 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1502 soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 1); 1503 rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64); 1504 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1505 } 1506 1507 BCM_PBMP_ITER(pbmp, port_iter) { 1508 rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64); 1509 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1510 soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 0); 1511 rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64); 1512 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1513 } 1514 1515 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 1516 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1517 soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0); 1518 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 1519 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1520 1521 BCM_PBMP_ITER(pbmp, port_iter) { 1522 rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval); 1523 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1524 soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 0); 1525 rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval); 1526 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1527 } 1528 1529 BCM_PBMP_ITER(pbmp, port_iter) { 1530 rv = READ_RRPKTr(unit, port_iter, &rrpkt); 1531 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1532 rv = READ_RRBYTr(unit, port_iter, &rrbyt); 1533 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1534 /* coverity[overrun-local : FALSE] */ 1535 ibod_ctrl->rrpkt[port_iter] = rrpkt; 1536 ibod_ctrl->rrbyt[port_iter] = rrbyt; 1537 } 1538 1539 BCM_PBMP_ITER(pbmp, port_iter) { 1540 /* coverity[overrun-local : FALSE] */ 1541 rv = READ_EGR_ENABLEm( 1542 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1543 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1544 soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 0); 1545 rv = WRITE_EGR_ENABLEm( 1546 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1547 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1548 } 1549 1550 BCM_PBMP_ITER(pbmp, port_iter) { 1551 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1552 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1553 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 1); 1554 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1555 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1556 } 1557 1558 rv = READ_PORT_ENABLE_REGr(unit, port, &rval); 1559 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1560 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 0); 1561 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 0); 1562 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 0); 1563 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 0); 1564 rv = WRITE_PORT_ENABLE_REGr(unit, port, rval); 1565 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1566 1567 rv = READ_PORT_MODE_REGr(unit, port, &rval); 1568 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1569 port_mode=soc_reg_field_get(unit, PORT_MODE_REGr, 1570 rval, XPORT0_CORE_PORT_MODEf); 1571 if(port_mode) { 1572 soc_reg_field_set(unit, PORT_MODE_REGr, 1573 &rval, XPORT0_CORE_PORT_MODEf,0); 1574 } 1575 else { 1576 soc_reg_field_set(unit, PORT_MODE_REGr, 1577 &rval, XPORT0_CORE_PORT_MODEf,1); 1578 } 1579 rv = WRITE_PORT_MODE_REGr(unit, port, rval); 1580 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1581 rv = READ_PORT_MODE_REGr(unit, port, &rval); 1582 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1583 soc_reg_field_set(unit, PORT_MODE_REGr, 1584 &rval, XPORT0_CORE_PORT_MODEf,port_mode); 1585 rv = WRITE_PORT_MODE_REGr(unit, port, rval); 1586 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1587 1588 rv = READ_PORT_ENABLE_REGr(unit, port, &rval); 1589 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1590 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 1); 1591 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 1); 1592 if (port_mode == 2) { 1593 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 1); 1594 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 1); 1595 } 1596 rv = WRITE_PORT_ENABLE_REGr(unit, port, rval); 1597 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1598 1599 BCM_PBMP_ITER(pbmp, port_iter) { 1600 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1601 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1602 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 0); 1603 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1604 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1605 } 1606 1607 BCM_PBMP_ITER(pbmp, port_iter) { 1608 rv = READ_EGR_ENABLEm( 1609 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1610 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1611 soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 1); 1612 rv = WRITE_EGR_ENABLEm( 1613 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1614 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1615 } 1616 1617 BCM_PBMP_ITER(pbmp, port_iter) { 1618 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1619 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1620 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, LINE_LOCAL_LPBKf, 1); 1621 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1622 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1623 } 1624 1625 BCM_PBMP_ITER(pbmp, port_iter) { 1626 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1627 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1628 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 1); 1629 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 1); 1630 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1631 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1632 } 1633 BCM_PBMP_ITER(pbmp, port_iter) { 1634 rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64); 1635 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1636 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 0); 1637 rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64); 1638 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1639 } 1640 sal_udelay(200); 1641 /* Send 80-byte packets to fill IBOD FIFO */ 1642 BCM_PBMP_ITER(pbmp, port_iter) { 1643 rv = READ_RPKTr(unit, port_iter, &rval64); 1644 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1645 count64 = soc_reg64_field_get(unit, RPKTr, rval64, COUNTf); 1646 for (i=0;i<2;i++) 1647 { 1648 BCM_PKT_TX_LEN_SET(pkt, 68); 1649 BCM_PKT_HDR_VTAG_CONTROL_SET(pkt, VLAN_CTRL(0, 0, 1)); 1650 BCM_PKT_PORT_SET(pkt, port_iter, FALSE, FALSE); 1651 rv = bcm_common_tx(unit, pkt, NULL); 1652 if (BCM_FAILURE(rv)) { 1653 LOG_ERROR(BSL_LS_BCM_PORT,(BSL_META_U(unit,"IBOD 80-byte packet transmit" 1654 "failed[%d] on port:%d\n\r"), rv, port_iter)); 1655 ibod_ctrl->port_recovery_failed_flag = 1; 1656 break; 1657 } 1658 sal_udelay(200); 1659 1660 } 1661 if (ibod_ctrl->port_recovery_failed_flag) { 1662 break; 1663 } 1664 1665 rv = READ_RPKTr(unit, port_iter, &rval64); 1666 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1667 count64_1 = soc_reg64_field_get(unit, RPKTr, rval64, COUNTf); 1668 COMPILER_64_SET(tmp64, 0, 2); 1669 COMPILER_64_SUB_64(count64_1, count64); 1670 if (COMPILER_64_LT(count64_1, tmp64)) { 1671 sal_udelay(1000); 1672 rv = READ_RPKTr(unit, port_iter, &rval64); 1673 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1674 count64_1 = soc_reg64_field_get(unit, RPKTr, rval64, COUNTf); 1675 COMPILER_64_SUB_64(count64_1, count64); 1676 if (COMPILER_64_LT(count64_1, tmp64)) { 1677 LOG_WARN(BSL_LS_BCM_PORT, 1678 (BSL_META_U(unit,"\n HELIX4 IBOD loopback packet" 1679 " not received in port %s"),SOC_PORT_NAME(unit,port_iter))); 1680 } 1681 } 1682 } 1683 1684 BCM_PBMP_ITER(pbmp, port_iter) { 1685 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1686 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1687 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 0); 1688 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1689 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1690 } 1691 1692 BCM_PBMP_ITER(pbmp, port_iter) { 1693 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1694 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1695 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 0); 1696 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1697 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1698 } 1699 1700 BCM_PBMP_ITER(pbmp, port_iter) { 1701 rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64); 1702 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1703 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 1); 1704 rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64); 1705 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1706 } 1707 1708 BCM_PBMP_ITER(pbmp, port_iter) { 1709 rv = READ_EGR_ENABLEm( 1710 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1711 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1712 soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 0); 1713 rv = WRITE_EGR_ENABLEm( 1714 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1715 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1716 } 1717 1718 BCM_PBMP_ITER(pbmp, port_iter) { 1719 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1720 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1721 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 1); 1722 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1723 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1724 } 1725 1726 rv = READ_PORT_ENABLE_REGr(unit, port, &rval); 1727 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1728 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 0); 1729 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 0); 1730 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 0); 1731 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 0); 1732 rv = WRITE_PORT_ENABLE_REGr(unit, port, rval); 1733 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1734 1735 rv = READ_PORT_MODE_REGr(unit, port, &rval); 1736 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1737 port_mode=soc_reg_field_get(unit, PORT_MODE_REGr, 1738 rval, XPORT0_CORE_PORT_MODEf); 1739 if(port_mode) { 1740 soc_reg_field_set(unit, PORT_MODE_REGr, 1741 &rval, XPORT0_CORE_PORT_MODEf,0); 1742 } 1743 else { 1744 soc_reg_field_set(unit, PORT_MODE_REGr, 1745 &rval, XPORT0_CORE_PORT_MODEf,1); 1746 } 1747 rv = WRITE_PORT_MODE_REGr(unit, port, rval); 1748 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1749 rv = READ_PORT_MODE_REGr(unit, port, &rval); 1750 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1751 soc_reg_field_set(unit, PORT_MODE_REGr, 1752 &rval, XPORT0_CORE_PORT_MODEf,port_mode); 1753 rv = WRITE_PORT_MODE_REGr(unit, port, rval); 1754 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1755 1756 rv = READ_PORT_ENABLE_REGr(unit, port, &rval); 1757 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1758 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT0f , 1); 1759 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT2f , 1); 1760 if (port_mode == 2) { 1761 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT1f , 1); 1762 soc_reg_field_set(unit, PORT_ENABLE_REGr, &rval, PORT3f , 1); 1763 } 1764 rv = WRITE_PORT_ENABLE_REGr(unit, port, rval); 1765 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1766 1767 BCM_PBMP_ITER(pbmp, port_iter) { 1768 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1769 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1770 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 0); 1771 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1772 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1773 } 1774 1775 BCM_PBMP_ITER(pbmp, port_iter) { 1776 rv = READ_EGR_ENABLEm( 1777 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1778 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1779 soc_EGR_ENABLEm_field32_set(unit, &egr_en, PRT_ENABLEf, 1); 1780 rv = WRITE_EGR_ENABLEm( 1781 unit, SOC_BLOCK_ANY, si->port_l2p_mapping[port_iter], &egr_en); 1782 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1783 } 1784 1785 switch(port_group_iter) { 1786 case 0: 1787 rv = READ_IBOD_INTR_STATUSr(unit, &rval); 1788 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1789 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 1790 &rval, CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf, 1); 1791 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 1792 &rval, CL0_CTRL_FIFO_FULL_ERR_INTR_STATUSf, 1); 1793 rv = WRITE_IBOD_INTR_STATUSr(unit, rval); 1794 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1795 break; 1796 case 1: 1797 rv = READ_IBOD_INTR_STATUSr(unit, &rval); 1798 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1799 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 1800 &rval, CL1_DATA_FIFO_FULL_ERR_INTR_STATUSf, 1); 1801 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 1802 &rval, CL1_CTRL_FIFO_FULL_ERR_INTR_STATUSf, 1); 1803 rv = WRITE_IBOD_INTR_STATUSr(unit, rval); 1804 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1805 break; 1806 case 2: 1807 rv = READ_IBOD_INTR_STATUSr(unit, &rval); 1808 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1809 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 1810 &rval, CL2_DATA_FIFO_FULL_ERR_INTR_STATUSf, 1); 1811 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 1812 &rval, CL2_CTRL_FIFO_FULL_ERR_INTR_STATUSf, 1); 1813 rv = WRITE_IBOD_INTR_STATUSr(unit, rval); 1814 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1815 break; 1816 default: 1817 break; 1818 } 1819 1820 rv = READ_MEM_FAIL_INT_STAT_64r(unit, &rval64); 1821 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1822 soc_reg64_field32_set(unit, MEM_FAIL_INT_STAT_64r, 1823 &rval64, START_BY_START_ERRf, 0); 1824 rv = WRITE_MEM_FAIL_INT_STAT_64r(unit, rval64); 1825 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1826 1827 rv = READ_MEM_FAIL_INT_CTRr(unit, &rval); 1828 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1829 soc_reg_field_set(unit, MEM_FAIL_INT_CTRr, &rval, INT_CTRf, 0); 1830 rv = WRITE_MEM_FAIL_INT_CTRr(unit, rval); 1831 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1832 1833 BCM_PBMP_ITER(pbmp, port_iter) { 1834 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1835 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1836 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, LINE_LOCAL_LPBKf, 0); 1837 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1838 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1839 } 1840 1841 BCM_PBMP_ITER(pbmp, port_iter) { 1842 rv = soc_mem_read( 1843 unit, PORT_TABm, MEM_BLOCK_ANY, port_iter, &ptab_entry); 1844 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1845 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_UNTAGf, port_dis_untag); 1846 soc_mem_field32_set(unit, PORT_TABm, &ptab_entry, PORT_DIS_TAGf, port_dis_tag); 1847 rv = soc_mem_write( 1848 unit, PORT_TABm, MEM_BLOCK_ALL, port_iter, &ptab_entry); 1849 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1850 } 1851 1852 count=0; 1853 BCM_PBMP_ITER(pbmp, port_iter) { 1854 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 1855 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1856 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, rx_lss[count]); 1857 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, rx_lss_1[count]); 1858 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 1859 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1860 count++; 1861 } 1862 1863 count=0; 1864 BCM_PBMP_ITER(pbmp, port_iter) { 1865 rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64); 1866 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1867 soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, pause_rx[count]); 1868 rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64); 1869 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1870 1871 rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64); 1872 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1873 soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, rx_pfc_en[count]); 1874 rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64); 1875 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1876 1877 rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64); 1878 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1879 soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, rx_llfc_en[count]); 1880 rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64); 1881 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1882 count++; 1883 } 1884 1885 BCM_PBMP_ITER(pbmp, port_iter) { 1886 rv = READ_XMAC_TX_CTRLr(unit, port_iter, &rval64); 1887 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1888 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, DISCARDf, 0); 1889 rv = WRITE_XMAC_TX_CTRLr(unit, port_iter, rval64); 1890 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1891 } 1892 1893 count=0; 1894 BCM_PBMP_ITER(pbmp, port_iter) { 1895 rv = READ_XMAC_CTRLr(unit, port_iter, &rval64); 1896 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1897 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf, 1); 1898 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, rx_en[count]); 1899 count++; 1900 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 1901 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1902 } 1903 sal_udelay(200); 1904 rv = soc_link_mask2_set(unit, mask_restore); 1905 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 1906 1907 PORT_UNLOCK(unit); 1908 /* Release the ibod recovery port group lock */ 1909 _bcm_esw_ibod_recovery_port_unlock(unit, port); 1910 1911 rv = soc_link_fwd_set(unit, mask1_restore); 1912 if (BCM_FAILURE(rv)) { 1913 _bcm_esw_lc_unlock(unit); 1914 LOG_ERROR(BSL_LS_BCM_PORT, 1915 (BSL_META_U(unit,"\n Error in re-setting the mask FWD" 1916 " for WAR on port %s"), SOC_PORT_NAME(unit,port))); 1917 return BCM_E_NONE; 1918 } 1919 _bcm_esw_lc_unlock(unit); 1920 1921 BCM_PBMP_ITER(pbmp, port_iter) { 1922 SOC_IF_ERROR_RETURN( 1923 READ_PORT_CDC_TXFIFO_OVRFLWr(unit, port_iter, &rval)); 1924 if (rval) { 1925 LOG_ERROR(BSL_LS_BCM_PORT, 1926 (BSL_META_U(unit," EXIT VALIDATE PORT_CDC_TXFIFO_OVRFLW ERR" 1927 " failed on port:%d\n\r"), port_iter)); 1928 } 1929 } 1930 time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 1931 ibod_ctrl->event_count++; 1932 ibod_ctrl->port_avg_time = (ibod_ctrl->port_avg_time*(ibod_ctrl->event_count - 1) + 1933 time2 - time1) /ibod_ctrl->event_count; 1934 1935 return SOC_E_NONE; 1936 1937 } 1938 1939 STATIC int 1940 _bcm_hx4_txerr_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, 1941 bcm_port_t port) 1942 { 1943 bcm_pbmp_t pbmp; 1944 bcm_port_t port_iter; 1945 uint32 port_mode; 1946 uint32 rval, rval_1; 1947 uint64 rval64, txerr, flush_enable_pbm, tmp64; 1948 uint64 egress_meter[4]; 1949 int unit=ibod_ctrl->unit, okay=0, rv = BCM_E_NONE; 1950 pbmp_t mask, mask1, mask1_restore, mask_restore; 1951 soc_timeout_t timeout; 1952 int count,count_1; 1953 soc_info_t *si = &SOC_INFO(unit); 1954 egr_mmu_requests_entry_t mmu_entry; 1955 int rx_llfc_en[4],rx_pfc_en[4],pause_rx[4], rx_lss[4], rx_lss_1[4]; 1956 uint32 max_used_entry, ep_level, overflow0, overflow1; 1957 static const soc_reg_t lls_port_credit_reg[] = { 1958 LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr, 1959 LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr, 1960 LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr, 1961 LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr, 1962 LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr, 1963 LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr, 1964 LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr, 1965 LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr, 1966 LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr, 1967 LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr, 1968 LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr, 1969 LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr, 1970 LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr, 1971 LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr, 1972 LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr, 1973 LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr, 1974 LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr, 1975 LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr, 1976 LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr, 1977 LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr, 1978 LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr 1979 }; 1980 sal_usecs_t time1, time2; 1981 1982 time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 1983 1984 SOC_IF_ERROR_RETURN(READ_PORT_MODE_REGr(unit, port, &rval)); 1985 port_mode=soc_reg_field_get(unit, PORT_MODE_REGr, 1986 rval, XPORT0_CORE_PORT_MODEf); 1987 sal_memset(&pbmp, 0, sizeof(bcm_pbmp_t)); 1988 if (port_mode) { 1989 rv = bcm_esw_port_subsidiary_ports_get(unit, port, &pbmp); 1990 if (BCM_FAILURE(rv)) { 1991 LOG_ERROR(BSL_LS_BCM_PORT, 1992 (BSL_META_U(unit,"\n Error in retreiving the subsidiary ports" 1993 " for port %s"), SOC_PORT_NAME(unit,port))); 1994 return BCM_E_NONE; 1995 } 1996 } else { 1997 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay)); 1998 if (okay) { 1999 SOC_PBMP_PORT_ADD(pbmp, port); 2000 } else { 2001 return SOC_E_NONE; 2002 } 2003 } 2004 2005 BCM_PBMP_ITER(pbmp, port_iter) { 2006 SOC_IF_ERROR_RETURN(READ_PORT_CDC_TXFIFO_OVRFLWr(unit, port_iter, &rval)); 2007 if (rval) { 2008 LOG_ERROR(BSL_LS_BCM_PORT, 2009 (BSL_META_U(unit,"IBOD PORT_CDC_TXFIFO_OVRFLW ERR" 2010 " failed on port:%d\n\r"), port_iter)); 2011 } 2012 } 2013 2014 count=0; 2015 BCM_PBMP_ITER(pbmp, port_iter) { 2016 SOC_IF_ERROR_RETURN(READ_TERRr(unit, port_iter, &txerr)); 2017 /* coverity[overrun-local : FALSE] */ 2018 if (COMPILER_64_NE(ibod_ctrl->txerrpkt[port_iter], txerr)) { 2019 ibod_ctrl->txerrpkt[port_iter] = txerr; 2020 count++; 2021 } 2022 } 2023 BCM_PBMP_ITER(pbmp, port_iter) { 2024 SOC_IF_ERROR_RETURN(READ_XMAC_FIFO_STATUSr(unit, port_iter, &rval64)); 2025 if (!count) { 2026 count = soc_reg64_field32_get(unit, XMAC_FIFO_STATUSr, rval64, TX_PKT_UNDERFLOWf); 2027 } 2028 } 2029 2030 if (!count) { 2031 return SOC_E_NONE; 2032 } 2033 2034 LOG_VERBOSE(BSL_LS_BCM_PORT, 2035 (BSL_META_U(unit,"\n WAR Trigerred by TXERR in subports %s"),SOC_PORT_NAME(unit,port))); 2036 2037 _bcm_esw_lc_lock(unit); 2038 soc_link_fwd_get(unit, &mask1); 2039 SOC_PBMP_ASSIGN(mask1_restore,mask1); 2040 BCM_PBMP_ITER(pbmp, port_iter) { 2041 BCM_PBMP_PORT_REMOVE(mask1,port_iter); 2042 } 2043 rv = soc_link_fwd_set(unit, mask1); 2044 if (BCM_FAILURE(rv)) { 2045 _bcm_esw_lc_unlock(unit); 2046 LOG_ERROR(BSL_LS_BCM_PORT, 2047 (BSL_META_U(unit,"\n Error in setting the mask FWD" 2048 " for WAR on port %s"), SOC_PORT_NAME(unit,port))); 2049 return BCM_E_NONE; 2050 } 2051 2052 /* Hold the ibod recovery port group lock */ 2053 _bcm_esw_ibod_recovery_port_lock(unit, port); 2054 PORT_LOCK(unit); 2055 2056 soc_link_mask2_get(unit, &mask); 2057 SOC_PBMP_ASSIGN(mask_restore,mask); 2058 BCM_PBMP_ITER(pbmp, port_iter) { 2059 BCM_PBMP_PORT_REMOVE(mask,port_iter); 2060 } 2061 rv = soc_link_mask2_set(unit, mask); 2062 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2063 2064 2065 count=0; 2066 BCM_PBMP_ITER(pbmp, port_iter) { 2067 rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64); 2068 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2069 pause_rx[count] = soc_reg64_field32_get(unit, XMAC_PAUSE_CTRLr, rval64, RX_PAUSE_ENf); 2070 soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, 0); 2071 rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64); 2072 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2073 2074 rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64); 2075 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2076 rx_pfc_en[count] = soc_reg64_field32_get(unit, XMAC_PFC_CTRLr, rval64, RX_PFC_ENf); 2077 soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, 0); 2078 rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64); 2079 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2080 2081 rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64); 2082 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2083 rx_llfc_en[count] = soc_reg64_field32_get(unit, XMAC_LLFC_CTRLr, rval64, RX_LLFC_ENf); 2084 soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, 0); 2085 rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64); 2086 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2087 count++; 2088 } 2089 2090 count=0; 2091 BCM_PBMP_ITER(pbmp, port_iter) { 2092 rv = READ_EGRMETERINGCONFIG_64r(unit, port_iter, &rval64); 2093 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2094 egress_meter[count] = rval64; 2095 COMPILER_64_ZERO(tmp64); 2096 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, tmp64); 2097 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2098 count++; 2099 } 2100 2101 count=0; 2102 BCM_PBMP_ITER(pbmp, port_iter) { 2103 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 2104 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2105 rx_lss[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64, 2106 DROP_TX_DATA_ON_LOCAL_FAULTf); 2107 rx_lss_1[count] = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64, 2108 DROP_TX_DATA_ON_REMOTE_FAULTf); 2109 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1); 2110 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1); 2111 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 2112 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2113 count++; 2114 } 2115 2116 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 2117 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2118 COMPILER_64_SET(flush_enable_pbm, pbmp.pbits[1], pbmp.pbits[0]); 2119 soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, flush_enable_pbm); 2120 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 2121 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2122 2123 BCM_PBMP_ITER(pbmp, port_iter) { 2124 rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval); 2125 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2126 soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 1); 2127 rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval); 2128 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2129 } 2130 rv = READ_PORT_MODE_REGr(unit, port, &rval); 2131 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2132 port_mode = soc_reg_field_get(unit, PORT_MODE_REGr, 2133 rval, XPORT0_CORE_PORT_MODEf); 2134 2135 soc_timeout_init(&timeout, 30000, 0); 2136 count_1=0; 2137 do { 2138 if (soc_timeout_check(&timeout)) { 2139 ep_level = 0; 2140 BCM_PBMP_ITER(pbmp, port_iter) { 2141 rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval); 2142 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2143 soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1); 2144 rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval); 2145 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2146 /* coverity[overrun-local : FALSE] */ 2147 rv = READ_EGR_MAX_USED_ENTRIESm( 2148 unit, MEM_BLOCK_ALL, si->port_l2p_mapping[port_iter], 2149 &max_used_entry); 2150 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2151 ep_level += soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf); 2152 } 2153 if(ep_level == 0) { 2154 ibod_ctrl->drain_timeout_flag = 1; 2155 } 2156 else { 2157 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0); 2158 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2159 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1); 2160 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2161 LOG_ERROR(BSL_LS_BCM_PORT, 2162 (BSL_META_U(unit, "\n IBOD recovery Timeout Drain packets %d PORT: %s, " 2163 "total ep_level:%d, overflow0:%d, overflow1:%d\n"), 2164 ibod_ctrl->unit, SOC_PORT_NAME(unit,port), ep_level, overflow0, overflow1)); 2165 } 2166 break; 2167 } else { 2168 BCM_PBMP_ITER(pbmp, port_iter) { 2169 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 2170 REG_PORT_ANY, 0, &rval); 2171 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2172 if (!rval) { 2173 count_1++; 2174 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, 2175 si->port_l2p_mapping[port_iter], 2176 &mmu_entry); 2177 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2178 rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 2179 rv = soc_reg32_set(unit, 2180 lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 2181 REG_PORT_ANY, 0, rval); 2182 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2183 } 2184 } 2185 count=0; 2186 BCM_PBMP_ITER(pbmp, port_iter) { 2187 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port_iter, &rval); 2188 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2189 count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf); 2190 rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port_iter, &rval); 2191 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2192 count += soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf); 2193 2194 } 2195 } 2196 } while (count); 2197 2198 BCM_PBMP_ITER(pbmp, port_iter) { 2199 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, 2200 si->port_l2p_mapping[port_iter], &mmu_entry); 2201 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2202 rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 2203 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 2204 REG_PORT_ANY, 0, &rval_1); 2205 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2206 if (rval != rval_1) { 2207 rv = soc_reg32_set(unit, 2208 lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 2209 REG_PORT_ANY, 0, rval); 2210 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2211 } 2212 } 2213 2214 BCM_PBMP_ITER(pbmp, port_iter) { 2215 rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64); 2216 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2217 soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 1); 2218 rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64); 2219 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2220 } 2221 2222 BCM_PBMP_ITER(pbmp, port_iter) { 2223 rv = READ_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, &rval64); 2224 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2225 soc_reg64_field32_set(unit, XMAC_CLEAR_FIFO_STATUSr, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 0); 2226 rv = WRITE_XMAC_CLEAR_FIFO_STATUSr(unit, port_iter, rval64); 2227 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2228 } 2229 2230 count=0; 2231 BCM_PBMP_ITER(pbmp, port_iter) { 2232 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, egress_meter[count]); 2233 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2234 count++; 2235 } 2236 2237 BCM_PBMP_ITER(pbmp, port_iter) { 2238 rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, &rval); 2239 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2240 soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 0); 2241 rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port_iter, rval); 2242 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2243 } 2244 2245 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 2246 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2247 soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0); 2248 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 2249 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2250 2251 count=0; 2252 BCM_PBMP_ITER(pbmp, port_iter) { 2253 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 2254 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2255 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, rx_lss[count]); 2256 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, rx_lss_1[count]); 2257 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 2258 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2259 count++; 2260 } 2261 2262 count=0; 2263 BCM_PBMP_ITER(pbmp, port_iter) { 2264 rv = READ_XMAC_PAUSE_CTRLr(unit, port_iter, &rval64); 2265 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2266 soc_reg64_field32_set(unit, XMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf, pause_rx[count]); 2267 rv = WRITE_XMAC_PAUSE_CTRLr(unit, port_iter, rval64); 2268 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2269 2270 rv = READ_XMAC_PFC_CTRLr(unit, port_iter, &rval64); 2271 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2272 soc_reg64_field32_set(unit, XMAC_PFC_CTRLr, &rval64, RX_PFC_ENf, rx_pfc_en[count]); 2273 rv = WRITE_XMAC_PFC_CTRLr(unit, port_iter, rval64); 2274 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2275 2276 rv = READ_XMAC_LLFC_CTRLr(unit, port_iter, &rval64); 2277 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2278 soc_reg64_field32_set(unit, XMAC_LLFC_CTRLr, &rval64, RX_LLFC_ENf, rx_llfc_en[count]); 2279 rv = WRITE_XMAC_LLFC_CTRLr(unit, port_iter, rval64); 2280 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2281 count++; 2282 } 2283 2284 rv = soc_link_mask2_set(unit, mask_restore); 2285 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 2286 PORT_UNLOCK(unit); 2287 /* Release the ibod recovery port group lock */ 2288 _bcm_esw_ibod_recovery_port_unlock(unit, port); 2289 2290 rv = soc_link_fwd_set(unit, mask1_restore); 2291 if (BCM_FAILURE(rv)) { 2292 _bcm_esw_lc_unlock(unit); 2293 LOG_ERROR(BSL_LS_BCM_PORT, 2294 (BSL_META_U(unit,"\n Error in re-setting the mask FWD" 2295 " for WAR on port %s"), SOC_PORT_NAME(unit,port))); 2296 return BCM_E_NONE; 2297 } 2298 2299 _bcm_esw_lc_unlock(unit); 2300 time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 2301 ibod_ctrl->txerr_count++; 2302 ibod_ctrl->txerr_avg_time = (ibod_ctrl->txerr_avg_time*(ibod_ctrl->txerr_count-1) + 2303 time2 - time1) /ibod_ctrl->txerr_count; 2304 2305 return SOC_E_NONE; 2306 } 2307 2308 2309 STATIC int 2310 _bcm_tr3_mmu_recovery(_port_ibod_ctrl_t *ibod_ctrl) 2311 { 2312 mac_driver_t *macd; 2313 bcm_port_t port_iter; 2314 uint32 rval, rval_1, count; 2315 uint64 rval64,txerr, val64; 2316 int unit=ibod_ctrl->unit, rv = BCM_E_NONE; 2317 soc_info_t *si = &SOC_INFO(unit); 2318 egr_mmu_requests_entry_t mmu_entry; 2319 int linkscan_interval, counter_interval; 2320 uint32 counter_flags; 2321 uint32 l2x_flags; 2322 int scan_rate, l2x_running = 0, mem_scan_running = 0; 2323 sal_usecs_t l2x_interval, scan_interval; 2324 bcm_pbmp_t rx_en_pbmp, rx_llfc_en_pbmp, tx_llfc_en_pbmp; 2325 bcm_pbmp_t rx_pfc_en_pbmp, tx_pfc_en_pbmp; 2326 bcm_pbmp_t pause_rx_pbmp, pause_tx_pbmp; 2327 bcm_pbmp_t rx_lss_local_pbmp,rx_lss_remote_pbmp, counter_pbmp; 2328 uint64 egrmeteringconfig[_SOC_TR3_MAX_NUM_LPORTS]; 2329 soc_timeout_t timeout; 2330 int num_mmu_port, mmu_port, phy_port, port; 2331 pbmp_t pbm; 2332 epc_link_bmap_entry_t entry, epc_lin_bmap_entry; 2333 static const soc_reg_t lls_port_credit_reg[] = { 2334 LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr, 2335 LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr, 2336 LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr, 2337 LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr, 2338 LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr, 2339 LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr, 2340 LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr, 2341 LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr, 2342 LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr, 2343 LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr, 2344 LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr, 2345 LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr, 2346 LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr, 2347 LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr, 2348 LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr, 2349 LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr, 2350 LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr, 2351 LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr, 2352 LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr, 2353 LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr, 2354 LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr 2355 }; 2356 sal_usecs_t time1, time2; 2357 2358 time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 2359 2360 /*****"Preparation and Stop ingress traffic Start*****/ 2361 /*1. Disable all back ground threads to prevent any SBUS acitivities (software handling)*/ 2362 BCM_IF_ERROR_RETURN(bcm_esw_linkscan_enable_get(unit, &linkscan_interval)); 2363 BCM_IF_ERROR_RETURN(bcm_esw_linkscan_enable_set(unit, 0)); 2364 BCM_IF_ERROR_RETURN(soc_counter_status(unit, &counter_flags, 2365 &counter_interval, &counter_pbmp)); 2366 BCM_IF_ERROR_RETURN(soc_counter_stop(unit)); 2367 if (soc_l2x_running(unit, &l2x_flags, &l2x_interval)) { 2368 l2x_running = 1; 2369 BCM_IF_ERROR_RETURN(soc_l2x_stop(unit)); 2370 } 2371 #ifdef INCLUDE_MEM_SCAN 2372 if (soc_mem_scan_running(unit, &scan_rate, &scan_interval)) { 2373 mem_scan_running = 1; 2374 BCM_IF_ERROR_RETURN(soc_mem_scan_stop(unit)); 2375 } 2376 #endif 2377 2378 /*2. Disable "TX" API to prevent CPU packet from going into MMU (software handling)*/ 2379 PBMP_PORT_ITER(unit, port_iter){ 2380 _bcm_esw_ibod_recovery_port_lock(unit, port_iter); 2381 } 2382 2383 /*3. Stop all ingress ports traffic to prevent any packet from going into MMU */ 2384 sal_memset(&rx_en_pbmp, 0, sizeof(bcm_pbmp_t)); 2385 PBMP_PORT_ITER(unit, port_iter){ 2386 macd = PORT(unit, port_iter).p_mac; 2387 rv = MAC_CONTROL_GET(macd,unit, port_iter, SOC_MAC_CONTROL_RX_SET, (int *)&rval); 2388 if (BCM_FAILURE(rv)) { 2389 goto end; 2390 } 2391 if (rval) { 2392 BCM_PBMP_PORT_ADD(rx_en_pbmp, port_iter); 2393 } 2394 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_RX_SET, 0); 2395 if (BCM_FAILURE(rv)) { 2396 goto end; 2397 } 2398 } 2399 2400 /*4. Stop all AXP traffic to prevent any packet from going into MMU */ 2401 sal_memset(&pbm, 0, sizeof(pbmp_t)); 2402 /* coverity[check_return] */ 2403 rv = READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry); 2404 if (BCM_FAILURE(rv)) { 2405 goto end; 2406 } 2407 sal_memcpy(&epc_lin_bmap_entry, &entry, sizeof(epc_link_bmap_entry_t)); 2408 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm); 2409 rv = WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry); 2410 if (BCM_FAILURE(rv)) { 2411 goto end; 2412 } 2413 /*****"Preparation and Stop ingress traffic End*****/ 2414 2415 /*****Packet Drain Start*****/ 2416 /* 1.Stop all pauses to speed up draining*/ 2417 sal_memset(&pause_rx_pbmp, 0, sizeof(bcm_pbmp_t)); 2418 sal_memset(&pause_tx_pbmp, 0, sizeof(bcm_pbmp_t)); 2419 2420 PBMP_PORT_ITER(unit, port_iter){ 2421 macd = PORT(unit, port_iter).p_mac; 2422 rv = MAC_PAUSE_GET(macd, unit, port_iter, (int *)&rval, (int *)&rval_1); 2423 if (BCM_FAILURE(rv)) { 2424 goto end; 2425 } 2426 if (rval) { 2427 BCM_PBMP_PORT_ADD(pause_tx_pbmp, port_iter); 2428 } 2429 if (rval_1) { 2430 BCM_PBMP_PORT_ADD(pause_rx_pbmp, port_iter); 2431 } 2432 rv = MAC_PAUSE_SET(macd, unit, port_iter, 0, 0); 2433 if (BCM_FAILURE(rv)) { 2434 goto end; 2435 } 2436 } 2437 2438 sal_memset(&rx_llfc_en_pbmp, 0, sizeof(bcm_pbmp_t)); 2439 sal_memset(&tx_llfc_en_pbmp, 0, sizeof(bcm_pbmp_t)); 2440 PBMP_PORT_ITER(unit, port_iter){ 2441 macd = PORT(unit, port_iter).p_mac; 2442 rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_TX_ENABLE, (int *)&rval); 2443 if (BCM_FAILURE(rv)) { 2444 goto end; 2445 } 2446 if (rval) { 2447 BCM_PBMP_PORT_ADD(tx_llfc_en_pbmp, port_iter); 2448 } 2449 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_TX_ENABLE, 0); 2450 if (BCM_FAILURE(rv)) { 2451 goto end; 2452 } 2453 rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_RX_ENABLE, (int *)&rval); 2454 if (BCM_FAILURE(rv)) { 2455 goto end; 2456 } 2457 if (rval) { 2458 BCM_PBMP_PORT_ADD(rx_llfc_en_pbmp, port_iter); 2459 } 2460 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_RX_ENABLE, 0); 2461 if (BCM_FAILURE(rv)) { 2462 goto end; 2463 } 2464 } 2465 2466 sal_memset(&tx_pfc_en_pbmp, 0, sizeof(bcm_pbmp_t)); 2467 sal_memset(&rx_pfc_en_pbmp, 0, sizeof(bcm_pbmp_t)); 2468 PBMP_PORT_ITER(unit, port_iter){ 2469 macd = PORT(unit, port_iter).p_mac; 2470 rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_TX_ENABLE, (int *)&rval); 2471 if (BCM_FAILURE(rv)) { 2472 goto end; 2473 } 2474 if (rval) { 2475 BCM_PBMP_PORT_ADD(tx_pfc_en_pbmp, port_iter); 2476 } 2477 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_TX_ENABLE, 0); 2478 if (BCM_FAILURE(rv)) { 2479 goto end; 2480 } 2481 rv = MAC_CONTROL_GET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_RX_ENABLE, (int *)&rval); 2482 if (BCM_FAILURE(rv)) { 2483 goto end; 2484 } 2485 if (rval) { 2486 BCM_PBMP_PORT_ADD(rx_pfc_en_pbmp, port_iter); 2487 } 2488 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_RX_ENABLE, 0); 2489 if (BCM_FAILURE(rv)) { 2490 goto end; 2491 } 2492 } 2493 2494 /*2. Set XMAC LLS CTRL to ignore Serdes fault signal which may prevent packets from draining at cable unplug case*/ 2495 sal_memset(&rx_lss_local_pbmp, 0, sizeof(bcm_pbmp_t)); 2496 sal_memset(&rx_lss_remote_pbmp, 0, sizeof(bcm_pbmp_t)); 2497 PBMP_PORT_ITER(unit, port_iter){ 2498 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 2499 if (BCM_FAILURE(rv)) { 2500 goto end; 2501 } 2502 rval = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64, 2503 DROP_TX_DATA_ON_LOCAL_FAULTf); 2504 if (0 == rval) { 2505 BCM_PBMP_PORT_ADD(rx_lss_local_pbmp, port_iter); 2506 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1); 2507 } 2508 2509 rval = soc_reg64_field32_get(unit, XMAC_RX_LSS_CTRLr, rval64, 2510 DROP_TX_DATA_ON_REMOTE_FAULTf); 2511 if (0 == rval) { 2512 BCM_PBMP_PORT_ADD(rx_lss_remote_pbmp, port_iter); 2513 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1); 2514 } 2515 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 2516 if (BCM_FAILURE(rv)) { 2517 goto end; 2518 } 2519 } 2520 2521 /*3. Enable IPMC fast flush */ 2522 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 2523 if (BCM_FAILURE(rv)) { 2524 goto end; 2525 } 2526 2527 COMPILER_64_SET(val64, 0x3fffffff, 0xffffffff); 2528 soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, val64); 2529 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 2530 if (BCM_FAILURE(rv)) { 2531 goto end; 2532 } 2533 2534 /*4. Set PORT fast flush */ 2535 PBMP_PORT_ITER(unit, port_iter){ 2536 rv = soc_reg_field32_modify(unit, PORT_TXFIFO_PKT_DROP_CTLr, port_iter, 2537 DROP_ENf, 1); 2538 if (BCM_FAILURE(rv)) { 2539 goto end; 2540 } 2541 } 2542 2543 /*5.Stop MMU egress */ 2544 PBMP_PORT_ITER(unit, port_iter){ 2545 rv = READ_EGRMETERINGCONFIG_64r(unit, port_iter, &rval64); 2546 if (BCM_FAILURE(rv)) { 2547 goto end; 2548 } 2549 2550 COMPILER_64_SET(egrmeteringconfig[port_iter], COMPILER_64_HI(rval64), COMPILER_64_LO(rval64)); 2551 COMPILER_64_SET(val64, 0, 0); 2552 soc_reg64_field_set(unit, EGRMETERINGCONFIG_64r, &rval64, REFRESHf, val64); 2553 COMPILER_64_SET(val64, 0, 1); 2554 soc_reg64_field_set(unit, EGRMETERINGCONFIG_64r, &rval64, THD_SELf, val64); 2555 COMPILER_64_SET(val64, 0, 0); 2556 soc_reg64_field_set(unit, EGRMETERINGCONFIG_64r, &rval64, METER_GRANf, val64); 2557 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, rval64); 2558 if (BCM_FAILURE(rv)) { 2559 goto end; 2560 } 2561 } 2562 2563 /*6.Wait until all PORT TXFIFO count == 0*/ 2564 soc_timeout_init(&timeout, 30000, 0); 2565 do { 2566 if (soc_timeout_check(&timeout)) { 2567 LOG_ERROR(BSL_LS_BCM_PORT, 2568 (BSL_META_U(unit, "\n MMU Recovery Timeout Ports Drain packets unit:%d"), ibod_ctrl->unit)); 2569 break; 2570 } 2571 count=0; 2572 PBMP_PORT_ITER(unit, port_iter){ 2573 rv = READ_PORT_CDC_TXFIFO_CELL_CNTr(unit, port_iter, &rval); 2574 if (BCM_FAILURE(rv)) { 2575 goto end; 2576 } 2577 count += soc_reg_field_get(unit, PORT_CDC_TXFIFO_CELL_CNTr,rval, CELL_CNTf); 2578 rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port_iter, &rval); 2579 if (BCM_FAILURE(rv)) { 2580 goto end; 2581 } 2582 count += soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf); 2583 } 2584 } while (count); 2585 2586 /*****Packet Drain End*****/ 2587 2588 /*****MMU reset Start*****/ 2589 /*1. Backup all necessary MMU configurations */ 2590 rv = soc_tr3_mmu_register_store(unit); 2591 if (BCM_FAILURE(rv)) { 2592 goto end; 2593 } 2594 rv = soc_tr3_mmu_memory_store(unit); 2595 if (BCM_FAILURE(rv)) { 2596 goto end; 2597 } 2598 2599 /*2. Do TOP level MMU reset*/ 2600 rv = READ_TOP_SOFT_RESET_REGr(unit, &rval); 2601 if (BCM_FAILURE(rv)) { 2602 goto end; 2603 } 2604 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 0); 2605 rv = WRITE_TOP_SOFT_RESET_REGr(unit, rval); 2606 if (BCM_FAILURE(rv)) { 2607 goto end; 2608 } 2609 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1); 2610 rv = WRITE_TOP_SOFT_RESET_REGr(unit, rval); 2611 if (BCM_FAILURE(rv)) { 2612 goto end; 2613 } 2614 /* 3. REFRESH_ENF*/ 2615 rv = soc_reg32_get(unit, MISCCONFIGr, REG_PORT_ANY, 0, &rval); 2616 if (BCM_FAILURE(rv)) { 2617 goto end; 2618 } 2619 soc_reg_field_set(unit, MISCCONFIGr, &rval, METERING_CLK_ENf, 1); 2620 rv = soc_reg32_set(unit, MISCCONFIGr, REG_PORT_ANY, 0, rval); 2621 if(BCM_FAILURE(rv)) { 2622 goto end; 2623 } 2624 2625 /*4. Call soc_mmu_init to init MMU*/ 2626 rv = soc_mmu_init(unit); 2627 if (BCM_FAILURE(rv)) { 2628 goto end; 2629 } 2630 2631 /*5.Restore Registers/Memories which are called in MMU init (following MMU init sequence)*/ 2632 rv = soc_tr3_mmu_init_restore(unit); 2633 if (BCM_FAILURE(rv)) { 2634 goto end; 2635 } 2636 2637 /*6.Restore other MMU registers without sequence*/ 2638 rv = soc_tr3_mmu_register_restore(unit); 2639 if (BCM_FAILURE(rv)) { 2640 goto end; 2641 } 2642 2643 /*7.Restore other MMU memories without sequence*/ 2644 rv = soc_tr3_mmu_memory_restore(unit); 2645 if (BCM_FAILURE(rv)) { 2646 goto end; 2647 } 2648 2649 /*8.Restore MMU2PHY port mapping and MMU2LOGIC port mapping*/ 2650 num_mmu_port = SOC_REG_NUMELS(unit, MMU_TO_PHY_PORT_MAPPINGr); 2651 for (mmu_port = 0; mmu_port < num_mmu_port; mmu_port++) { 2652 phy_port = si->port_m2p_mapping[mmu_port]; 2653 port = phy_port == -1 ? -1 : si->port_p2l_mapping[phy_port]; 2654 2655 rval = 0; 2656 soc_reg_field_set(unit, MMU_TO_PHY_PORT_MAPPINGr, &rval, PHY_PORTf, 2657 phy_port == -1 ? 0x7f : phy_port); 2658 rv = WRITE_MMU_TO_PHY_PORT_MAPPINGr(unit, mmu_port, rval); 2659 if (BCM_FAILURE(rv)) { 2660 goto end; 2661 } 2662 rval = 0; 2663 soc_reg_field_set(unit, MMU_TO_LOGIC_PORT_MAPPINGr, &rval, LOGIC_PORTf, 2664 port == -1 ? 0x3f : port); 2665 rv = WRITE_MMU_TO_LOGIC_PORT_MAPPINGr(unit, mmu_port, rval); 2666 if (BCM_FAILURE(rv)) { 2667 goto end; 2668 } 2669 } 2670 2671 /* 9. Restore MMU to EP credicts after EP restore because EP port enable will update EGR_MMU_REQUESTSm*/ 2672 PBMP_ALL_ITER(unit, port_iter){ 2673 if (!IS_CPU_PORT(unit, port_iter) && !IS_PORT(unit, port_iter)) { 2674 continue; 2675 } 2676 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port_iter], &mmu_entry); 2677 if (BCM_FAILURE(rv)) { 2678 goto end; 2679 } 2680 rval = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 2681 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 2682 REG_PORT_ANY, 0, &rval_1); 2683 if (BCM_FAILURE(rv)) { 2684 goto end; 2685 } 2686 if (rval != rval_1) { 2687 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port_iter]]], 2688 REG_PORT_ANY, 0, rval); 2689 if(BCM_FAILURE(rv)) { 2690 goto end; 2691 } 2692 } 2693 } 2694 /*restore axp credit*/ 2695 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[58]]], 2696 REG_PORT_ANY, 0, 0x14); 2697 if (BCM_FAILURE(rv)) { 2698 goto end; 2699 } 2700 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[59]]], 2701 REG_PORT_ANY, 0, 0x14); 2702 if (BCM_FAILURE(rv)) { 2703 goto end; 2704 } 2705 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[60]]], 2706 REG_PORT_ANY, 0, 4); 2707 if (BCM_FAILURE(rv)) { 2708 goto end; 2709 } 2710 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[61]]], 2711 REG_PORT_ANY, 0, 0x14); 2712 if (BCM_FAILURE(rv)) { 2713 goto end; 2714 } 2715 /*****MMU reset End*****/ 2716 2717 /***** Resume ingress traffic Start*****/ 2718 /*1.Restore XMAC_RX_LSS_CTRL setting*/ 2719 BCM_PBMP_ITER(rx_lss_local_pbmp, port_iter){ 2720 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 2721 if (BCM_FAILURE(rv)) { 2722 goto end; 2723 } 2724 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 0); 2725 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 2726 if (BCM_FAILURE(rv)) { 2727 goto end; 2728 } 2729 } 2730 BCM_PBMP_ITER(rx_lss_remote_pbmp, port_iter){ 2731 rv = READ_XMAC_RX_LSS_CTRLr(unit, port_iter, &rval64); 2732 if (BCM_FAILURE(rv)) { 2733 goto end; 2734 } 2735 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 0); 2736 soc_reg64_field32_set(unit, XMAC_RX_LSS_CTRLr, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 0); 2737 rv = WRITE_XMAC_RX_LSS_CTRLr(unit, port_iter, rval64); 2738 if (BCM_FAILURE(rv)) { 2739 goto end; 2740 } 2741 } 2742 2743 /*2.Restore MMU egress */ 2744 PBMP_PORT_ITER(unit, port_iter){ 2745 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port_iter, egrmeteringconfig[port_iter]); 2746 if (BCM_FAILURE(rv)) { 2747 goto end; 2748 } 2749 } 2750 2751 /*3.Disable PORT fast flush*/ 2752 PBMP_PORT_ITER(unit, port_iter){ 2753 rv = soc_reg_field32_modify(unit, PORT_TXFIFO_PKT_DROP_CTLr, port_iter, 2754 DROP_ENf, 0); 2755 if (BCM_FAILURE(rv)) { 2756 goto end; 2757 } 2758 } 2759 /*4.Disable IPMC fast flush */ 2760 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 2761 if (BCM_FAILURE(rv)) { 2762 goto end; 2763 } 2764 soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0); 2765 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 2766 if (BCM_FAILURE(rv)) { 2767 goto end; 2768 } 2769 /* 5.Restore pause settings*/ 2770 BCM_PBMP_ITER(pause_tx_pbmp, port_iter){ 2771 macd = PORT(unit, port_iter).p_mac; 2772 rv = MAC_PAUSE_GET(macd, unit, port_iter, (int *)&rval, (int *)&rval_1); 2773 if (BCM_FAILURE(rv)) { 2774 goto end; 2775 } 2776 rv = MAC_PAUSE_SET(macd, unit, port_iter, 1, rval_1); 2777 if (BCM_FAILURE(rv)) { 2778 goto end; 2779 } 2780 } 2781 BCM_PBMP_ITER(pause_rx_pbmp, port_iter){ 2782 macd = PORT(unit, port_iter).p_mac; 2783 rv = MAC_PAUSE_GET(macd, unit, port_iter, (int *)&rval, (int *)&rval_1); 2784 if (BCM_FAILURE(rv)) { 2785 goto end; 2786 } 2787 rv = MAC_PAUSE_SET(macd, unit, port_iter, rval, 1); 2788 if (BCM_FAILURE(rv)) { 2789 goto end; 2790 } 2791 } 2792 BCM_PBMP_ITER(tx_llfc_en_pbmp, port_iter){ 2793 macd = PORT(unit, port_iter).p_mac; 2794 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_TX_ENABLE, 1); 2795 if (BCM_FAILURE(rv)) { 2796 goto end; 2797 } 2798 } 2799 BCM_PBMP_ITER(rx_llfc_en_pbmp, port_iter){ 2800 macd = PORT(unit, port_iter).p_mac; 2801 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_LLFC_RX_ENABLE, 1); 2802 if (BCM_FAILURE(rv)) { 2803 goto end; 2804 } 2805 } 2806 BCM_PBMP_ITER(tx_pfc_en_pbmp, port_iter){ 2807 macd = PORT(unit, port_iter).p_mac; 2808 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_TX_ENABLE, 1); 2809 if (BCM_FAILURE(rv)) { 2810 goto end; 2811 } 2812 } 2813 BCM_PBMP_ITER(rx_pfc_en_pbmp, port_iter){ 2814 macd = PORT(unit, port_iter).p_mac; 2815 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_PFC_RX_ENABLE, 1); 2816 if (BCM_FAILURE(rv)) { 2817 goto end; 2818 } 2819 } 2820 /* 6. Refresh FLOW CONTROL XOFF state*/ 2821 PBMP_PORT_ITER(unit, port_iter){ 2822 rv = WRITE_FLOW_CONTROL_XOFF_STATEr(unit, port_iter, 0xff); 2823 if (BCM_FAILURE(rv)) { 2824 goto end; 2825 } 2826 rv = WRITE_FLOW_CONTROL_XOFF_STATEr(unit, port_iter, 0); 2827 if (BCM_FAILURE(rv)) { 2828 goto end; 2829 } 2830 } 2831 /*Wait until all EDATABUF FIFO count == 0 (Optional ?)*/ 2832 /*7.Do IBOD reset for all ports*/ 2833 rv = READ_IBOD_BOD_FIFO_CONTROLr(unit, &rval); 2834 if (BCM_FAILURE(rv)) { 2835 goto end; 2836 } 2837 soc_reg_field_set(unit, IBOD_BOD_FIFO_CONTROLr, &rval, BOD_SW_RST_Lf, 0); 2838 rv = WRITE_IBOD_BOD_FIFO_CONTROLr(unit, rval); 2839 if (BCM_FAILURE(rv)) { 2840 goto end; 2841 } 2842 soc_reg_field_set(unit, IBOD_BOD_FIFO_CONTROLr, &rval, BOD_SW_RST_Lf, 1); 2843 rv = WRITE_IBOD_BOD_FIFO_CONTROLr(unit, rval); 2844 if (BCM_FAILURE(rv)) { 2845 goto end; 2846 } 2847 2848 /*8. Restore EPC link*/ 2849 rv = WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&epc_lin_bmap_entry); 2850 if (BCM_FAILURE(rv)) { 2851 goto end; 2852 } 2853 2854 if (SOC_IS_HELIX4(unit)) { 2855 /*9. Update txerrpkt after modules reset*/ 2856 PBMP_ITER(PBMP_XW_ALL(unit), port) { 2857 rv = READ_TERRr(unit, port, &txerr); 2858 if (SOC_FAILURE(rv)) { 2859 continue; 2860 } 2861 /* coverity[overrun-local : FALSE] */ 2862 ibod_ctrl->txerrpkt[port] = txerr; 2863 } 2864 } 2865 else { 2866 /*9. Update txerrpkt and tuflpkt after modules reset*/ 2867 PBMP_CL_ITER(unit, port_iter){ 2868 rv = READ_TERRr(unit, port_iter, &rval64); 2869 if(BCM_FAILURE(rv)) { 2870 goto end; 2871 } 2872 COMPILER_64_SET(ibod_ctrl->txerrpkt[port_iter], 2873 COMPILER_64_HI(rval64), COMPILER_64_LO(rval64)); 2874 rv = READ_TUFLr(unit, port_iter, &rval64); 2875 if(BCM_FAILURE(rv)) { 2876 goto end; 2877 } 2878 COMPILER_64_SET(ibod_ctrl->tuflpkt[port_iter], 2879 COMPILER_64_HI(rval64), COMPILER_64_LO(rval64)); 2880 } 2881 2882 /* MAC RESET*/ 2883 PBMP_PORT_ITER(unit, port_iter){ 2884 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, port_iter, &rval64)); 2885 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 1); 2886 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 2887 if (BCM_FAILURE(rv)) { 2888 goto end; 2889 } 2890 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf, 0); 2891 rv = WRITE_XMAC_CTRLr(unit, port_iter, rval64); 2892 if (BCM_FAILURE(rv)) { 2893 goto end; 2894 } 2895 } 2896 } 2897 2898 /*10.Resume ingress traffic*/ 2899 BCM_PBMP_ITER(rx_en_pbmp, port_iter){ 2900 macd = PORT(unit, port_iter).p_mac; 2901 rv = MAC_CONTROL_SET(macd, unit, port_iter, SOC_MAC_CONTROL_RX_SET, 1); 2902 if (BCM_FAILURE(rv)) { 2903 goto end; 2904 } 2905 } 2906 /***** Resume ingress traffic End*****/ 2907 2908 /***** Enable software handling Start*****/ 2909 /*1. Enable all back ground threads to prevent any SBUS acitivities (software handling)*/ 2910 rv = bcm_esw_linkscan_enable_set(unit, linkscan_interval); 2911 if (BCM_FAILURE(rv)) { 2912 goto end; 2913 } 2914 rv = soc_counter_start(unit, counter_flags, counter_interval, counter_pbmp); 2915 if (BCM_FAILURE(rv)) { 2916 goto end; 2917 } 2918 if (l2x_running) { 2919 rv = soc_l2x_start(unit, l2x_flags, l2x_interval); 2920 if (BCM_FAILURE(rv)) { 2921 goto end; 2922 } 2923 } 2924 #ifdef INCLUDE_MEM_SCAN 2925 if (mem_scan_running) { 2926 rv = soc_mem_scan_start(unit, scan_rate, scan_interval); 2927 if (BCM_FAILURE(rv)) { 2928 goto end; 2929 } 2930 } 2931 #endif 2932 2933 end: 2934 /*2. Enable "TX" API to prevent CPU packet from going into MMU (software handling)*/ 2935 PBMP_PORT_ITER(unit, port_iter){ 2936 _bcm_esw_ibod_recovery_port_unlock(unit, port_iter); 2937 } 2938 2939 /***** Enable software handling End*****/ 2940 time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 2941 ibod_ctrl->mmu_war_count++; 2942 ibod_ctrl->mmu_avg_time= (ibod_ctrl->mmu_avg_time*(ibod_ctrl->mmu_war_count-1) 2943 + time2 - time1) /ibod_ctrl->mmu_war_count; 2944 2945 return rv; 2946 } 2947 2948 STATIC int 2949 _bcm_tr3_mmu_check_and_recovery(_port_ibod_ctrl_t *ibod_ctrl) 2950 { 2951 int rv = BCM_E_NONE; 2952 uint32 overflow0,overflow1; 2953 int ibod_timeout_flag = 0; 2954 int txerr_timeout_flag = 0; 2955 int port_recovery_failed_flag = 0; 2956 int unit = ibod_ctrl->unit; 2957 2958 overflow0 = 0; 2959 overflow1 = 0; 2960 2961 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0); 2962 if (SOC_FAILURE(rv)) { 2963 LOG_ERROR(BSL_LS_BCM_PORT, 2964 (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW0"))); 2965 return rv; 2966 } 2967 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1); 2968 if (SOC_FAILURE(rv)) { 2969 LOG_ERROR(BSL_LS_BCM_PORT, 2970 (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW1"))); 2971 return rv; 2972 } 2973 2974 _soc_egress_drain_timeout_flag_get(unit, &ibod_timeout_flag); 2975 txerr_timeout_flag = ibod_ctrl->drain_timeout_flag; 2976 port_recovery_failed_flag = ibod_ctrl->port_recovery_failed_flag; 2977 2978 if ((overflow0 != 0) || (overflow1 != 0) || ibod_timeout_flag || txerr_timeout_flag 2979 || port_recovery_failed_flag || (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER)) { 2980 rv = _bcm_tr3_mmu_recovery(ibod_ctrl); 2981 if (txerr_timeout_flag) { 2982 ibod_ctrl->drain_timeout_flag = 0; 2983 ibod_ctrl->drain_timeout_count++; 2984 } 2985 if (port_recovery_failed_flag) { 2986 ibod_ctrl->port_recovery_failed_flag = 0; 2987 ibod_ctrl->port_recovery_failed_count++; 2988 } 2989 if (ibod_timeout_flag) { 2990 _soc_egress_drain_timeout_flag_set(unit, 0); 2991 ibod_ctrl->egress_drain_timeout_count++; 2992 } 2993 if (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER) { 2994 _ibod_debug_flag &= (~_PORT_IBOD_FLAG_MMU_TRIGGER); 2995 } 2996 if (SOC_FAILURE(rv)) { 2997 LOG_ERROR(BSL_LS_BCM_PORT, 2998 (BSL_META_U(unit, "\n Error in MMU recovery "))); 2999 } 3000 } 3001 3002 return rv; 3003 } 3004 3005 STATIC int 3006 _bcm_tr3_txerr_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, 3007 bcm_port_t port) 3008 { 3009 bcm_pbmp_t pbmp; 3010 uint32 rval; 3011 uint64 rval64, txerr, tufl, flush_enable_pbm, tmp64; 3012 uint64 egress_meter; 3013 int unit=ibod_ctrl->unit, okay=0, rv = BCM_E_NONE; 3014 pbmp_t mask, mask1, mask1_restore, mask_restore; 3015 soc_timeout_t timeout; 3016 int txerr_status,tufl_status, underflow_status, lanes; 3017 uint32 cur_cells, new_cells, mmu_cells,credit_set; 3018 uint32 cdc_fifo_cells, tx_fifo_cells; 3019 uint32 overflow0, overflow1, total_cell; 3020 soc_info_t *si = &SOC_INFO(unit); 3021 egr_mmu_requests_entry_t mmu_entry; 3022 uint32 max_used_entry; 3023 #ifdef TXERR_DEBUG 3024 uint64 tpkt, tfcs; 3025 uint32 ep_max_level = 0; 3026 #endif 3027 uint32 credit, mmu_req, ep_level; 3028 int rx_llfc_en,rx_pfc_en,pause_rx, rx_lss, rx_lss_1; 3029 soc_reg_t temp_reg_id; 3030 static const soc_reg_t lls_port_credit_reg[] = { 3031 LLS_PORT_0_CREDITr, LLS_PORT_1_CREDITr, LLS_PORT_2_CREDITr, 3032 LLS_PORT_3_CREDITr, LLS_PORT_4_CREDITr, LLS_PORT_5_CREDITr, 3033 LLS_PORT_6_CREDITr, LLS_PORT_7_CREDITr, LLS_PORT_8_CREDITr, 3034 LLS_PORT_9_CREDITr, LLS_PORT_10_CREDITr, LLS_PORT_11_CREDITr, 3035 LLS_PORT_12_CREDITr, LLS_PORT_13_CREDITr, LLS_PORT_14_CREDITr, 3036 LLS_PORT_15_CREDITr, LLS_PORT_16_CREDITr, LLS_PORT_17_CREDITr, 3037 LLS_PORT_18_CREDITr, LLS_PORT_19_CREDITr, LLS_PORT_20_CREDITr, 3038 LLS_PORT_21_CREDITr, LLS_PORT_22_CREDITr, LLS_PORT_23_CREDITr, 3039 LLS_PORT_24_CREDITr, LLS_PORT_25_CREDITr, LLS_PORT_26_CREDITr, 3040 LLS_PORT_27_CREDITr, LLS_PORT_28_CREDITr, LLS_PORT_29_CREDITr, 3041 LLS_PORT_30_CREDITr, LLS_PORT_31_CREDITr, LLS_PORT_32_CREDITr, 3042 LLS_PORT_33_CREDITr, LLS_PORT_34_CREDITr, LLS_PORT_35_CREDITr, 3043 LLS_PORT_36_CREDITr, LLS_PORT_37_CREDITr, LLS_PORT_38_CREDITr, 3044 LLS_PORT_39_CREDITr, LLS_PORT_40_CREDITr, LLS_PORT_41_CREDITr, 3045 LLS_PORT_42_CREDITr, LLS_PORT_43_CREDITr, LLS_PORT_44_CREDITr, 3046 LLS_PORT_45_CREDITr, LLS_PORT_46_CREDITr, LLS_PORT_47_CREDITr, 3047 LLS_PORT_48_CREDITr, LLS_PORT_49_CREDITr, LLS_PORT_50_CREDITr, 3048 LLS_PORT_51_CREDITr, LLS_PORT_52_CREDITr, LLS_PORT_53_CREDITr, 3049 LLS_PORT_54_CREDITr, LLS_PORT_55_CREDITr, LLS_PORT_56_CREDITr, 3050 LLS_PORT_57_CREDITr, LLS_PORT_58_CREDITr, LLS_PORT_59_CREDITr, 3051 LLS_PORT_60_CREDITr, LLS_PORT_61_CREDITr, LLS_PORT_62_CREDITr 3052 }; 3053 sal_usecs_t time1, time2; 3054 3055 sal_memset(&pbmp, 0, sizeof(bcm_pbmp_t)); 3056 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay)); 3057 if (okay) { 3058 SOC_PBMP_PORT_ADD(pbmp, port); 3059 } else { 3060 return SOC_E_NONE; 3061 } 3062 3063 txerr_status = 0; 3064 /* check and update tx err counter */ 3065 SOC_IF_ERROR_RETURN(READ_TERRr(unit, port, &txerr)); 3066 if (COMPILER_64_NE(ibod_ctrl->txerrpkt[port], txerr)) { 3067 ibod_ctrl->txerrpkt[port] = txerr; 3068 txerr_status = 1; 3069 } 3070 3071 tufl_status = 0; 3072 /* check and update tx underflow counter */ 3073 SOC_IF_ERROR_RETURN(READ_TUFLr(unit, port, &tufl)); 3074 if (COMPILER_64_NE(ibod_ctrl->tuflpkt[port], tufl)) { 3075 ibod_ctrl->tuflpkt[port] = tufl; 3076 tufl_status = 1; 3077 } 3078 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_FIFO_STATUSr : XMAC_FIFO_STATUSr; 3079 BCM_IF_ERROR_RETURN(soc_reg64_get(unit, temp_reg_id, port, 0, &rval64)); 3080 underflow_status = soc_reg64_field32_get(unit, temp_reg_id, rval64, TX_PKT_UNDERFLOWf); 3081 3082 /* check tx error and tx underflow */ 3083 if ((txerr_status == 0) && (tufl_status == 0) &&(underflow_status == 0) && 3084 (txerr_trigger_flag[port] == 0)) { 3085 return SOC_E_NONE; 3086 } 3087 3088 if ((txerr_status != 0) || (tufl_status != 0) || (underflow_status != 0)) { 3089 txerr_trigger_flag[port] = 1; 3090 } 3091 else if (txerr_trigger_flag[port] == 1) { 3092 txerr_trigger_flag[port] = 0; 3093 } 3094 3095 #ifdef TXERR_DEBUG 3096 cli_out("WAR TER Trigerred [port %d]:txerr_status:%d, tufl_status:%d, underflow_status:%d\r\n", 3097 port, txerr_status, tufl_status, underflow_status); 3098 #endif 3099 rv = (soc_tr3_port_lanes_get(unit, port, &lanes)); 3100 if (BCM_FAILURE(rv)) { 3101 return rv; 3102 } 3103 3104 switch (lanes) { 3105 case 10: /* 100G */ 3106 si->port_credit[port] = 108; 3107 break; 3108 case 4: /* SINGLE */ 3109 si->port_credit[port] = 36; 3110 break; 3111 case 2: /* DUAL */ 3112 si->port_credit[port] = 18; 3113 break; 3114 case 1: /* QUAD */ 3115 si->port_credit[port] = 9; 3116 break; 3117 default: 3118 si->port_credit[port] = 36; 3119 break; 3120 } 3121 3122 time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 3123 3124 _bcm_esw_lc_lock(unit); 3125 soc_link_fwd_get(unit, &mask1); 3126 SOC_PBMP_ASSIGN(mask1_restore,mask1); 3127 BCM_PBMP_PORT_REMOVE(mask1,port); 3128 rv = soc_link_fwd_set(unit, mask1); 3129 if (BCM_FAILURE(rv)) { 3130 _bcm_esw_lc_unlock(unit); 3131 LOG_ERROR(BSL_LS_BCM_PORT, 3132 (BSL_META_U(unit,"\n Error in setting the mask FWD" 3133 " for WAR on port %s"), SOC_PORT_NAME(unit,port))); 3134 return BCM_E_NONE; 3135 } 3136 3137 PORT_LOCK(unit); 3138 _bcm_esw_ibod_recovery_port_lock(unit, port); 3139 3140 /* move port from EPC_LINK_BMAP */ 3141 soc_link_mask2_get(unit, &mask); 3142 SOC_PBMP_ASSIGN(mask_restore,mask); 3143 BCM_PBMP_PORT_REMOVE(mask,port); 3144 rv = soc_link_mask2_set(unit, mask); 3145 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3146 3147 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PAUSE_CTRLr : XMAC_PAUSE_CTRLr; 3148 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3149 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3150 pause_rx = soc_reg64_field32_get(unit, temp_reg_id, rval64, RX_PAUSE_ENf); 3151 soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PAUSE_ENf, 0); 3152 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3153 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3154 3155 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PFC_CTRLr : XMAC_PFC_CTRLr; 3156 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3157 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3158 rx_pfc_en = soc_reg64_field32_get(unit, temp_reg_id, rval64, RX_PFC_ENf); 3159 soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PFC_ENf, 0); 3160 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3161 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3162 3163 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_LLFC_CTRLr : XMAC_LLFC_CTRLr; 3164 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3165 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3166 rx_llfc_en = soc_reg64_field32_get(unit, temp_reg_id, rval64, RX_LLFC_ENf); 3167 soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_LLFC_ENf, 0); 3168 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3169 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3170 3171 rv = READ_EGRMETERINGCONFIG_64r(unit, port, &rval64); 3172 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3173 egress_meter = rval64; 3174 COMPILER_64_ZERO(tmp64); 3175 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, tmp64); 3176 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3177 3178 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_RX_LSS_CTRLr : XMAC_RX_LSS_CTRLr; 3179 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3180 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3181 rx_lss = soc_reg64_field32_get(unit, temp_reg_id, rval64, 3182 DROP_TX_DATA_ON_LOCAL_FAULTf); 3183 rx_lss_1 = soc_reg64_field32_get(unit, temp_reg_id, rval64, 3184 DROP_TX_DATA_ON_REMOTE_FAULTf); 3185 soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, 1); 3186 soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, 1); 3187 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3188 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3189 3190 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 3191 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3192 COMPILER_64_SET(flush_enable_pbm, pbmp.pbits[1], pbmp.pbits[0]); 3193 soc_reg64_field_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, flush_enable_pbm); 3194 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 3195 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3196 3197 /* drop packets */ 3198 rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, &rval); 3199 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3200 soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 1); 3201 rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, rval); 3202 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3203 3204 cur_cells = 0xffffffff; 3205 soc_timeout_init(&timeout, 30000, 0); 3206 3207 while(1) { 3208 #ifdef TXERR_DEBUG 3209 /* check epc_link_bmap for debug */ 3210 pbmp_t pbm; 3211 epc_link_bmap_entry_t entry; 3212 READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry); 3213 soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm); 3214 if (SOC_PBMP_MEMBER(pbm, port)) { 3215 LOG_WARN(BSL_LS_BCM_PORT, 3216 (BSL_META_U(unit, "TXERR recovery:uint %d port %d still in epc link bitmap 0x%x\r\n"), 3217 unit, port, pbm.pbits[0])); 3218 } 3219 #endif 3220 new_cells=0; 3221 3222 /*1. check MMU cell */ 3223 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, &rval); 3224 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3225 mmu_cells = soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr,rval, TOTAL_COUNTf); 3226 new_cells += mmu_cells; 3227 3228 /*2. check port CDC fifo */ 3229 rv = READ_PORT_CDC_TXFIFO_CELL_CNTr(unit, port, &rval); 3230 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3231 cdc_fifo_cells = soc_reg_field_get(unit, PORT_CDC_TXFIFO_CELL_CNTr, rval, CELL_CNTf); 3232 new_cells += cdc_fifo_cells; 3233 3234 /*3. check port tx fifo */ 3235 rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port, &rval); 3236 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3237 tx_fifo_cells = soc_reg_field_get(unit, PORT_TXFIFO_CELL_CNTr, rval, CELL_CNTf); 3238 new_cells += tx_fifo_cells; 3239 3240 /* read MMU credit */ 3241 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit); 3242 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3243 3244 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry); 3245 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3246 mmu_req = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 3247 3248 /* read EP level */ 3249 rv = READ_EGR_EDB_MISC_CTRLr(unit, &rval); 3250 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3251 soc_reg_field_set(unit, EGR_EDB_MISC_CTRLr, &rval, SELECT_CURRENT_USED_ENTRIESf, 1); 3252 rv = WRITE_EGR_EDB_MISC_CTRLr(unit, rval); 3253 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3254 rv = READ_EGR_MAX_USED_ENTRIESm(unit, MEM_BLOCK_ALL, si->port_l2p_mapping[port], &max_used_entry); 3255 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3256 ep_level = soc_mem_field32_get(unit, EGR_MAX_USED_ENTRIESm, &max_used_entry, LEVELf); 3257 3258 /* Update cur_cells and give more time to drain packets. */ 3259 if (new_cells < cur_cells) { 3260 soc_timeout_init(&timeout, 30000, 0); 3261 cur_cells = new_cells; 3262 } 3263 else { 3264 #ifdef TXERR_DEBUG 3265 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", 3266 new_cells, cur_cells, mmu_cells, ep_level, credit, mmu_req); 3267 #endif 3268 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]); 3269 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3270 } 3271 3272 if (soc_timeout_check(&timeout)) { 3273 if(ep_level == 0) { 3274 ibod_ctrl->drain_timeout_flag = 1; 3275 } 3276 else { 3277 rv = READ_PQEFIFOOVERFLOW0r(unit, &overflow0); 3278 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3279 rv = READ_PQEFIFOOVERFLOW1r(unit, &overflow1); 3280 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3281 rv = READ_OP_PORT_TOTAL_COUNT_CELLr(unit,port, &total_cell); 3282 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3283 LOG_ERROR(BSL_LS_BCM_PORT, 3284 (BSL_META_U(unit, "\n TXERR recovery Timeout Drain packets %d PORT: %s, " 3285 "ep_level:%d, overflow0:%d, overflow1:%d total_cell %d " 3286 "credit %d mmu_req %d \n"), 3287 ibod_ctrl->unit, SOC_PORT_NAME(unit,port), ep_level, overflow0, 3288 overflow1, total_cell, credit, mmu_req)); 3289 } 3290 break; 3291 } 3292 #ifdef TXERR_DEBUG 3293 /* for debug */ 3294 uint32 mmu_req_1; 3295 3296 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry); 3297 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3298 mmu_req_1 = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 3299 if(mmu_req_1 != mmu_req){ 3300 cli_out("TXERR recovery: credit %d mmu_req %d is not equal mmu_req_1 %d !!!!!\r\n",credit, mmu_req, mmu_req_1); 3301 3302 } 3303 #endif 3304 /* All packets were drained */ 3305 if (new_cells == 0) { 3306 if (_soc_egress_drain_credit_calc(credit, si->port_credit[port], mmu_req, ep_level, &credit_set)) { 3307 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, credit_set); 3308 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3309 } 3310 #ifdef TXERR_DEBUG 3311 rv = _soc_egress_drain_ep_max_level_get(unit, port, &ep_max_level); 3312 if(rv == BCM_E_NONE) 3313 { 3314 cli_out("TXERR recovery: MacDrainOK max_level %d !!!!!\r\n", ep_max_level); 3315 } 3316 3317 rv = READ_TPKTr(unit, port, &tpkt); 3318 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3319 rv = READ_TFCSr(unit, port, &tfcs); 3320 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3321 3322 cli_out("TXERR recovery: MacDrainOK credit = %d, Port:%d, tpkt:%lld, tfcs=%lld\r\n", credit, port, tpkt, tfcs); 3323 #endif 3324 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit); 3325 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3326 if(credit == 0) { 3327 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], 3328 REG_PORT_ANY, 0, si->port_credit[port]); 3329 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3330 } 3331 break; 3332 } 3333 else if (mmu_cells){ /* some packets still stay in MMU */ 3334 if((credit == 0)) { 3335 rv = soc_reg32_get(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, &credit); 3336 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3337 if(credit == 0) { 3338 rv = soc_mem_read(unit, EGR_MMU_REQUESTSm, MEM_BLOCK_ANY, si->port_l2p_mapping[port], &mmu_entry); 3339 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3340 mmu_req = soc_mem_field32_get(unit, EGR_MMU_REQUESTSm, &mmu_entry, OUTSTANDING_MMU_REQUESTSf); 3341 3342 if (_soc_egress_drain_credit_calc(credit, si->port_credit[port], mmu_req, ep_level, &credit_set)) { 3343 rv = soc_reg32_set(unit,lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]], REG_PORT_ANY, 0, credit_set); 3344 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3345 } 3346 } 3347 else { 3348 #ifdef TXERR_DEBUG 3349 _soc_egress_drain_debug(unit, port, lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]]); 3350 #endif 3351 } 3352 } 3353 else { 3354 #ifdef TXERR_DEBUG 3355 _soc_egress_drain_debug(unit, port, lls_port_credit_reg[si->port_p2m_mapping[si->port_l2p_mapping[port]]]); 3356 #endif 3357 } 3358 } 3359 } 3360 3361 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_CLEAR_FIFO_STATUSr : XMAC_CLEAR_FIFO_STATUSr; 3362 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3363 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3364 soc_reg64_field32_set(unit, temp_reg_id, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 1); 3365 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3366 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3367 3368 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3369 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3370 soc_reg64_field32_set(unit, temp_reg_id, &rval64, CLEAR_TX_PKT_UNDERFLOWf, 0); 3371 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3372 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3373 3374 rv = WRITE_EGRMETERINGCONFIG_64r(unit, port, egress_meter); 3375 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3376 3377 rv = READ_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, &rval); 3378 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3379 soc_reg_field_set(unit, PORT_TXFIFO_PKT_DROP_CTLr, &rval, DROP_ENf, 0); 3380 rv = WRITE_PORT_TXFIFO_PKT_DROP_CTLr(unit, port, rval); 3381 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3382 3383 rv = READ_MCQ_IPMC_FAST_FLUSHr(unit, &rval64); 3384 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3385 soc_reg64_field32_set(unit, MCQ_IPMC_FAST_FLUSHr, &rval64, ENABLEf, 0); 3386 rv = WRITE_MCQ_IPMC_FAST_FLUSHr(unit, rval64); 3387 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3388 3389 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_RX_LSS_CTRLr : XMAC_RX_LSS_CTRLr; 3390 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3391 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3392 soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_LOCAL_FAULTf, rx_lss); 3393 soc_reg64_field32_set(unit, temp_reg_id, &rval64, DROP_TX_DATA_ON_REMOTE_FAULTf, rx_lss_1); 3394 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3395 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3396 3397 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PAUSE_CTRLr : XMAC_PAUSE_CTRLr; 3398 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3399 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3400 soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PAUSE_ENf, pause_rx); 3401 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3402 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3403 3404 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_PFC_CTRLr : XMAC_PFC_CTRLr; 3405 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3406 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3407 soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_PFC_ENf, rx_pfc_en); 3408 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3409 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3410 3411 temp_reg_id = IS_C_PORT(unit, port) ? CMAC_LLFC_CTRLr : XMAC_LLFC_CTRLr; 3412 rv = soc_reg64_get(unit, temp_reg_id, port, 0, &rval64); 3413 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3414 soc_reg64_field32_set(unit, temp_reg_id, &rval64, RX_LLFC_ENf, rx_llfc_en); 3415 rv = soc_reg64_set(unit, temp_reg_id, port, 0, rval64); 3416 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3417 3418 /* restore port from EPC_LINK_BMAP */ 3419 rv = soc_link_mask2_set(unit, mask_restore); 3420 TXERR_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3421 3422 _bcm_esw_ibod_recovery_port_unlock(unit, port); 3423 PORT_UNLOCK(unit); 3424 rv = soc_link_fwd_set(unit, mask1_restore); 3425 if (BCM_FAILURE(rv)) { 3426 _bcm_esw_lc_unlock(unit); 3427 LOG_ERROR(BSL_LS_BCM_PORT, 3428 (BSL_META_U(unit,"\n Error in re-setting the mask FWD" 3429 " for WAR on port %s"), SOC_PORT_NAME(unit,port))); 3430 return BCM_E_NONE; 3431 } 3432 3433 _bcm_esw_lc_unlock(unit); 3434 3435 time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 3436 ibod_ctrl->txerr_count++; 3437 ibod_ctrl->txerr_avg_time = (ibod_ctrl->txerr_avg_time*(ibod_ctrl->txerr_count-1) + 3438 time2 - time1) /ibod_ctrl->txerr_count; 3439 3440 return SOC_E_NONE; 3441 } 3442 3443 STATIC int 3444 _bcm_tr3_ibod_port_check( 3445 _port_ibod_ctrl_t *ibod_ctrl, bcm_port_t port, int *need_recovery) 3446 { 3447 int rv, unit = ibod_ctrl->unit; 3448 uint64 rrpkt, rrbyt; 3449 uint64 rrpkt_diff, rrbyt_diff; 3450 uint64 rval64; 3451 int runt_threshold; 3452 3453 /* Only check HG port */ 3454 if (!IS_HG_PORT(unit, port)) { 3455 return BCM_E_NONE; 3456 } 3457 3458 /* Check if any new runt packet logged in RRPKT */ 3459 rv = READ_RRPKTr(unit, port, &rrpkt); 3460 if (SOC_FAILURE(rv)) { 3461 return BCM_E_FAIL; 3462 } 3463 if (COMPILER_64_EQ(rrpkt, ibod_ctrl->rrpkt[port])) { 3464 return BCM_E_NONE; 3465 } 3466 3467 /* Check total runt byte count */ 3468 rv = READ_RRBYTr(unit, port, &rrbyt); 3469 if (SOC_FAILURE(rv)) { 3470 return BCM_E_FAIL; 3471 } 3472 3473 /* It's very unlikely both packet and byte counters wrap around 3474 * and stop at 0, the code assume this is from clear counter */ 3475 if (COMPILER_64_IS_ZERO(rrpkt) && COMPILER_64_IS_ZERO(rrbyt)) { 3476 ibod_ctrl->rrpkt_old[port] = ibod_ctrl->rrpkt[port]; 3477 ibod_ctrl->rrbyt_old[port] = ibod_ctrl->rrbyt[port]; 3478 ibod_ctrl->rrpkt[port] = rrpkt; 3479 ibod_ctrl->rrbyt[port] = rrbyt; 3480 return BCM_E_NONE; 3481 } 3482 3483 rrpkt_diff = rrpkt; 3484 rrbyt_diff = rrbyt; 3485 COMPILER_64_SUB_64(rrpkt_diff, ibod_ctrl->rrpkt[port]); 3486 COMPILER_64_SUB_64(rrbyt_diff, ibod_ctrl->rrbyt[port]); 3487 ibod_ctrl->rrpkt_old[port] = ibod_ctrl->rrpkt[port]; 3488 ibod_ctrl->rrbyt_old[port] = ibod_ctrl->rrbyt[port]; 3489 ibod_ctrl->rrpkt[port] = rrpkt; 3490 ibod_ctrl->rrbyt[port] = rrbyt; 3491 #ifdef IBOD_DEBUG 3492 cli_out("WAR IBOD Check [port %d] rrbyt %lld rrpkt %lld, rrpkt_diff %lld rrbyt_diff %lld\r\n", 3493 port, ibod_ctrl->rrbyt[port], ibod_ctrl->rrpkt[port], rrpkt_diff, rrbyt_diff); 3494 #endif 3495 rv = READ_XMAC_RX_CTRLr(unit,port, &rval64); 3496 if (SOC_FAILURE(rv)) { 3497 return BCM_E_FAIL; 3498 } 3499 3500 runt_threshold = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval64, RUNT_THRESHOLDf); 3501 3502 /* Recovery is needed only for packet size between 33 and threshold */ 3503 if (COMPILER_64_HI(rrpkt_diff) == 0 && 3504 COMPILER_64_LO(rrpkt_diff) == 1) { 3505 if (COMPILER_64_LO(rrbyt_diff) >= runt_threshold) { 3506 return BCM_E_NONE; 3507 } 3508 } 3509 if (COMPILER_64_HI(rrbyt_diff) == 0 && 3510 COMPILER_64_LO(rrbyt_diff) <= 32) { 3511 return BCM_E_NONE; 3512 } 3513 3514 *need_recovery = TRUE; 3515 3516 return BCM_E_NONE; 3517 } 3518 3519 STATIC int 3520 _bcm_tr3_ibod_sync_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, int port_set, 3521 bcm_port_t port) 3522 { 3523 int idx, fifo_len, send_time; 3524 int rv = BCM_E_NONE; 3525 int rv1 = BCM_E_NONE; 3526 int enable, tdm_length; 3527 uint64 rrpkt, rrbyt; 3528 uint64 rpkt, tpkt; 3529 pbmp_t pbm; 3530 epc_link_bmap_entry_t entry; 3531 int lanes, unit = ibod_ctrl->unit; 3532 soc_info_t *si = &SOC_INFO(unit); 3533 int phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 3534 uint32 *tdm_array; 3535 int port_dis_tag=0, port_dis_untag=0; 3536 bcm_pkt_t *pkt = &ibod_ctrl->pkt; 3537 SHR_BITDCLNAME(used_bmp, TR3_IARB_TDM_TABLE_LENGTH); 3538 uint32 _tdm_array_hw[380] = {-1}; 3539 int pause_tx, pause_rx, pfc_rx, llfc_rx; 3540 iarb_tdm_table_entry_t new_entry; 3541 uint32 rval; 3542 pbmp_t mask, mask1, mask1_restore; 3543 int ibod_data_fifo_full_intr_status = 0; 3544 soc_field_t cl_data_fifo_full_err_intr_status = 0; 3545 soc_field_t cl_ctrl_fifo_full_err_intr_status = 0; 3546 #ifdef IBOD_DEBUG 3547 uint64 rpkt, tpkt; 3548 uint64 rpkt_fin, tpkt_fin, rrpkt_fin, rrbyt_fin; 3549 #endif 3550 3551 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 3552 rv = (soc_tr3_port_lanes_get(unit, port, &lanes)); 3553 if (BCM_FAILURE(rv)) { 3554 return rv; 3555 } 3556 3557 switch (lanes) { 3558 case 10: /* 100G */ 3559 fifo_len = 34; 3560 si->port_credit[port] = 108; 3561 break; 3562 case 4: /* SINGLE */ 3563 fifo_len = 34; 3564 si->port_credit[port] = 36; 3565 break; 3566 case 2: /* DUAL */ 3567 fifo_len = 34; 3568 si->port_credit[port] = 18; 3569 break; 3570 case 1: /* QUAD */ 3571 fifo_len = 34; 3572 si->port_credit[port] = 9; 3573 break; 3574 default: 3575 fifo_len = 34; 3576 si->port_credit[port] = 36; 3577 break; 3578 } 3579 3580 3581 if ((phy_port >= 53) && (phy_port <= 64 )){ 3582 cl_data_fifo_full_err_intr_status = CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf; 3583 cl_ctrl_fifo_full_err_intr_status = CL0_CTRL_FIFO_FULL_ERR_INTR_STATUSf; 3584 } 3585 else if ((phy_port >= 69) && (phy_port <= 80)) { 3586 cl_data_fifo_full_err_intr_status = CL1_DATA_FIFO_FULL_ERR_INTR_STATUSf; 3587 cl_ctrl_fifo_full_err_intr_status = CL1_CTRL_FIFO_FULL_ERR_INTR_STATUSf; 3588 } 3589 else { 3590 LOG_ERROR(BSL_LS_BCM_PORT, 3591 (BSL_META_U(unit, "IBOD port:%d is not CL port\n\r"), port)); 3592 return BCM_E_PORT; 3593 } 3594 fifo_len = soc_property_get(unit, "ibod_fifo_len", fifo_len); 3595 3596 soc_link_fwd_get(unit, &mask1); 3597 SOC_PBMP_ASSIGN(mask1_restore,mask1); 3598 BCM_PBMP_PORT_REMOVE(mask1,port); 3599 rv = soc_link_fwd_set(unit, mask1); 3600 if (BCM_FAILURE(rv)) { 3601 LOG_ERROR(BSL_LS_BCM_PORT, 3602 (BSL_META_U(unit, 3603 "IBOD Link fwd set failed[%d] on port:%d\n\r"), 3604 rv, port)); 3605 return rv; 3606 } 3607 3608 PORT_LOCK(unit); /* Begin port atomic */ 3609 _bcm_esw_ibod_recovery_port_lock(unit, port); 3610 soc_ibod_recovery_in_progress_set(unit, 1); 3611 3612 if (port_set == 0) { 3613 soc_link_mask2_get(unit, &mask); 3614 rv = bcm_esw_port_enable_get(unit, port, &enable); 3615 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3616 /* port is disabled */ 3617 if ((enable == 0) || !SOC_PBMP_MEMBER(mask, port)) { 3618 soc_ibod_recovery_in_progress_set(unit, 0); 3619 _bcm_esw_ibod_recovery_port_unlock(unit, port); 3620 PORT_UNLOCK(unit); 3621 rv = soc_link_fwd_set(unit, mask1_restore); 3622 /* 3623 * Since the recovery is not run when the port is down the 3624 * rrpkt is updated back to the original value, as the 3625 * recovery will happen when the port is up 3626 */ 3627 ibod_ctrl->rrpkt[port] = ibod_ctrl->rrpkt_old[port]; 3628 ibod_ctrl->rrbyt[port] = ibod_ctrl->rrbyt_old[port]; 3629 LOG_INFO(BSL_LS_BCM_PORT, 3630 (BSL_META_U(unit, 3631 "Skip ibod sync war if port %d is disabled %d.\n"), 3632 port, enable)); 3633 return rv; 3634 } 3635 } 3636 3637 /* Isolate port */ 3638 rv = _bcm_tr3_ibod_port_isolate(unit, port_set, port, &port_dis_untag, &port_dis_tag); 3639 if (BCM_FAILURE(rv)) { 3640 soc_ibod_recovery_in_progress_set(unit, 0); 3641 _bcm_esw_ibod_recovery_port_unlock(unit, port); 3642 PORT_UNLOCK(unit); 3643 rv1 = soc_link_fwd_set(unit, mask1_restore); 3644 LOG_ERROR(BSL_LS_BCM_PORT, 3645 (BSL_META_U(unit, "IBOD port(%d) isolate Failed[%d %d]\n\r"), 3646 port, rv, rv1)); 3647 return rv; 3648 } 3649 3650 sal_memset(&used_bmp, 0, sizeof(used_bmp)); 3651 3652 /* Remove the port from IARB_TDM_TABLE */ 3653 tdm_length = _soc_tr3_tdm_size; 3654 for (idx = 0; idx < _soc_tr3_tdm_size; idx++) { 3655 /* coverity[unchecked_value] */ 3656 (void)soc_mem_read(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx,&new_entry); 3657 _tdm_array_hw[idx] = 3658 soc_mem_field32_get(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf); 3659 } 3660 tdm_array = _tdm_array_hw; 3661 3662 sal_memset(&new_entry, 0, sizeof(iarb_tdm_table_entry_t)); 3663 soc_mem_field32_set(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf, 127); 3664 for (idx = 0; idx < _soc_tr3_tdm_size; idx++) { 3665 if (tdm_array[idx] != phy_port) { 3666 continue; 3667 } 3668 (void)soc_mem_write(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx, 3669 &new_entry); 3670 SHR_BITSET(used_bmp, idx); 3671 } 3672 sal_udelay(10000); 3673 3674 /* Disable pause/pfc/llfc function */ 3675 rv = soc_mac_x.md_pause_get(unit, port, &pause_tx, &pause_rx); 3676 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3677 3678 rv = soc_mac_x.md_pause_set(unit, port, 0, 0); 3679 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3680 3681 rv = soc_mac_x.md_control_get(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, &pfc_rx); 3682 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3683 3684 rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, 0); 3685 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3686 3687 rv = soc_mac_x.md_control_get(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,&llfc_rx); 3688 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3689 3690 rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,0); 3691 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3692 3693 /* check epc_link_bmap */ 3694 /* coverity[check_return] */ 3695 READ_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0,&entry); 3696 soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, &entry, PORT_BITMAPf, &pbm); 3697 if (SOC_PBMP_MEMBER(pbm, port)) { 3698 LOG_WARN(BSL_LS_BCM_PORT, 3699 (BSL_META_U(unit, "uint %d port %d still in epc link bitmap 0x%x\r\n"), 3700 unit, port, pbm.pbits[0])); 3701 } 3702 3703 rv = READ_RRBYTr(unit, port, &rrbyt); 3704 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3705 3706 rv = READ_RRPKTr(unit, port, &rrpkt); 3707 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3708 3709 rv = READ_RPKTr(unit, port, &rpkt); 3710 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3711 rv = READ_TPKTr(unit, port, &tpkt); 3712 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3713 #ifdef IBOD_DEBUG 3714 cli_out("WAR Trigerred IBOD recovery [port %d] enable %d orign rrbyt %lld rrpkt %lld rpkt %lld tpkt %lld\r\n", 3715 port, port_set, rrbyt, rrpkt, rpkt, tpkt ); 3716 #endif 3717 send_time = 0; 3718 3719 /* send loopback packets untill fifo full error occurred. */ 3720 do { 3721 /* Send 80-byte packets to fill IBOD FIFO */ 3722 for (idx = 0; idx < fifo_len; idx++) { 3723 BCM_PKT_TX_LEN_SET(pkt, 68); 3724 BCM_PKT_PORT_SET(pkt, port, TRUE, FALSE); 3725 BCM_PKT_HGHDR_REQUIRE(pkt); 3726 rv = bcm_common_tx(unit, pkt, NULL); 3727 if (BCM_FAILURE(rv)) { 3728 LOG_ERROR(BSL_LS_BCM_PORT, 3729 (BSL_META_U(unit, "IBOD 80-byte packet transmit" 3730 " failed[%d] on port:%d, send_time:%d\n\r"), rv, port, send_time)); 3731 ibod_ctrl->port_recovery_failed_flag = 1; 3732 break; 3733 } 3734 } 3735 if (ibod_ctrl->port_recovery_failed_flag) { 3736 break; 3737 } 3738 3739 send_time ++; 3740 rv = READ_IBOD_INTR_STATUSr(unit, &rval); 3741 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3742 ibod_data_fifo_full_intr_status = soc_reg_field_get(unit, IBOD_INTR_STATUSr, 3743 rval, cl_data_fifo_full_err_intr_status); 3744 #ifdef IBOD_DEBUG 3745 if (!ibod_data_fifo_full_intr_status){ 3746 cli_out("%s IBOD intr data fifo full err status is 0 !!!!!!!%d\r\n", 3747 (cl_data_fifo_full_err_intr_status == CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf)?"CL0":"CL1", ibod_data_fifo_full_intr_status); 3748 } 3749 #endif 3750 3751 if (send_time >= 5) { 3752 #ifdef IBOD_DEBUG 3753 int lb = 0; 3754 MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &lb); 3755 3756 rv = READ_RPKTr(unit, port, &rpkt_fin); 3757 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3758 rv = READ_TPKTr(unit, port, &tpkt_fin); 3759 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3760 3761 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"), 3762 ibod_ctrl->unit, SOC_PORT_NAME(unit,port),rpkt_fin,tpkt_fin, lb)); 3763 #else 3764 LOG_ERROR(BSL_LS_BCM_PORT, 3765 (BSL_META_U(unit,"\n IBOD recovery (unit %d PORT: %s) fill IBOD FIFO full failed\r\n"), 3766 unit, SOC_PORT_NAME(unit,port))); 3767 #endif 3768 ibod_ctrl->port_recovery_failed_flag = 1; 3769 break; 3770 } 3771 }while (ibod_data_fifo_full_intr_status == 0); 3772 3773 #ifdef IBOD_DEBUG 3774 rv = READ_RRBYTr(unit, port, &rrbyt); 3775 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3776 3777 rv = READ_RRPKTr(unit, port, &rrpkt); 3778 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3779 3780 rv = READ_RPKTr(unit, port, &rpkt_fin); 3781 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3782 3783 rv = READ_TPKTr(unit, port, &tpkt_fin); 3784 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3785 cli_out("WAR Trigerred IBOD recovery [port %d] normal rrbyt %lld rrpkt %lld rpkt_fin %lld tpkt_fin %lld send_time %d\r\n", 3786 port, rrbyt, rrpkt, rpkt_fin,tpkt_fin, send_time); 3787 if((rpkt_fin - rpkt) != fifo_len * send_time ) { 3788 cli_out("IBOD recovery loopback regular counter is not right!!!!!!! \r\n"); 3789 if((rpkt_fin - rpkt) < fifo_len * send_time ) { 3790 cli_out("IBOD recovery loopback regular counter is less than tx!!!!!!!! \r\n"); 3791 } 3792 } 3793 #endif 3794 /* Restore IARB_TDM_TABLE */ 3795 soc_mem_field32_set(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf, 3796 phy_port); 3797 for (idx = 0; idx < tdm_length; idx++) { 3798 if (!SHR_BITGET(used_bmp, idx)) { 3799 continue; 3800 } 3801 (void)soc_mem_write(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx, 3802 &new_entry); 3803 } 3804 3805 for (idx = 0; idx < tdm_length; idx++) { 3806 if (tdm_array[idx] != phy_port) { 3807 continue; 3808 } 3809 #ifdef IBOD_DEBUG 3810 (void)soc_mem_read(unit, IARB_TDM_TABLEm, MEM_BLOCK_ALL, idx,&new_entry); 3811 _tdm_array_hw[idx] = soc_mem_field32_get(unit, IARB_TDM_TABLEm, &new_entry, PORT_NUMf); 3812 if(_tdm_array_hw[idx] != phy_port){ 3813 cli_out("IBOD IARB TDM port number idx %d _tdm_array_hw[idx] %d !!!!!!\r\n",idx, _tdm_array_hw[idx]); 3814 } 3815 #endif 3816 } 3817 /* waiting for IARB_TDM_TABLE ready */ 3818 sal_udelay(30000); 3819 /* Send 72-byte RUNT packet */ 3820 if (BCM_SUCCESS(rv)) { 3821 BCM_PKT_TX_LEN_SET(pkt, 60); 3822 BCM_PKT_PORT_SET(pkt, port, TRUE, FALSE); 3823 rv = bcm_common_tx(unit, pkt, NULL); 3824 if (BCM_FAILURE(rv)) { 3825 LOG_ERROR(BSL_LS_BCM_PORT, 3826 (BSL_META_U(unit, 3827 "IBOD Runt Pkt transmit failed[%d] on port:%d\n\r"), 3828 rv, port)); 3829 ibod_ctrl->port_recovery_failed_flag = 1; 3830 } 3831 } 3832 3833 #ifdef IBOD_DEBUG 3834 rv = READ_RRPKTr(unit, port, &rrpkt_fin); 3835 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3836 rv = READ_RRBYTr(unit, port, &rrbyt_fin); 3837 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3838 rv = READ_RPKTr(unit, port, &rpkt_fin); 3839 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3840 rv = READ_TPKTr(unit, port, &tpkt_fin); 3841 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3842 3843 cli_out("recovery runt rrbyt_fin %lld rrpkt_fin %lld rpkt_fin %lld tpkt_fin %lld\r\n",rrbyt_fin, rrpkt_fin, 3844 rpkt_fin, tpkt_fin); 3845 3846 if((rrpkt_fin - rrpkt) != 1 ) { 3847 cli_out("IBOD recovery loopback runt counter is not right!!!! \r\n"); 3848 } 3849 #endif 3850 /* Update ibod_ctrl rrbyt and rrpkt */ 3851 rv = READ_RRPKTr(unit, port, &rrpkt); 3852 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3853 rv = READ_RRBYTr(unit, port, &rrbyt); 3854 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3855 3856 ibod_ctrl->rrpkt[port] = rrpkt; 3857 ibod_ctrl->rrbyt[port] = rrbyt; 3858 3859 /* Restore original pause/pfc/llfc configuration */ 3860 rv = soc_mac_x.md_pause_set(unit, port, pause_tx, pause_rx); 3861 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3862 3863 rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_PFC_RX_ENABLE, pfc_rx); 3864 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3865 rv = soc_mac_x.md_control_set(unit, port, SOC_MAC_CONTROL_LLFC_RX_ENABLE,llfc_rx); 3866 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3867 3868 /* clear and check IBOD FIFO full interrupt */ 3869 rv = READ_IBOD_INTR_STATUSr(unit, &rval); 3870 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3871 ibod_data_fifo_full_intr_status = soc_reg_field_get(unit, IBOD_INTR_STATUSr, 3872 rval, cl_data_fifo_full_err_intr_status); 3873 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 3874 &rval, cl_data_fifo_full_err_intr_status, 1); 3875 soc_reg_field_set(unit, IBOD_INTR_STATUSr, 3876 &rval, cl_ctrl_fifo_full_err_intr_status, 1); 3877 rv = WRITE_IBOD_INTR_STATUSr(unit, rval); 3878 IBOD_IF_ERROR_RETURN_UNLOCK(unit, port, rv); 3879 #ifdef IBOD_DEBUG 3880 READ_IBOD_INTR_STATUSr(unit, &rval); 3881 ibod_data_fifo_full_intr_status = soc_reg_field_get(unit, IBOD_INTR_STATUSr, 3882 rval, cl_data_fifo_full_err_intr_status); 3883 cli_out("after set. %s IBOD intr data fifo full err status %d\r\n", 3884 (cl_data_fifo_full_err_intr_status == CL0_DATA_FIFO_FULL_ERR_INTR_STATUSf)?"CL0":"CL1", ibod_data_fifo_full_intr_status); 3885 #endif 3886 /* Restore port operation */ 3887 rv = _bcm_tr3_ibod_port_resume(unit, port, port_dis_untag, port_dis_tag); 3888 if (BCM_FAILURE(rv)) { 3889 soc_ibod_recovery_in_progress_set(unit, 0); 3890 _bcm_esw_ibod_recovery_port_unlock(unit, port); 3891 PORT_UNLOCK(unit); 3892 rv1 = soc_link_fwd_set(unit, mask1_restore); 3893 LOG_ERROR(BSL_LS_BCM_PORT, 3894 (BSL_META_U(unit, 3895 "IBOD Port[%d] Resume failed[%d %d]\n\r"), port, rv, rv1)); 3896 return rv; 3897 } 3898 3899 soc_ibod_recovery_in_progress_set(unit, 0); 3900 _bcm_esw_ibod_recovery_port_unlock(unit, port); 3901 PORT_UNLOCK(unit); /* End port atomic */ 3902 3903 rv = soc_link_fwd_set(unit, mask1_restore); 3904 if (BCM_FAILURE(rv)) { 3905 LOG_ERROR(BSL_LS_BCM_PORT, 3906 (BSL_META_U(unit, 3907 "IBOD link fwd set failed[%d] on port:%d\n\r"), rv, port)); 3908 return rv; 3909 } 3910 3911 return rv; 3912 } 3913 3914 STATIC int 3915 _bcm_tr3_ibod_recovery_port(_port_ibod_ctrl_t *ibod_ctrl, bcm_port_t port) 3916 { 3917 int rv = BCM_E_NONE; 3918 int need_recovery = FALSE; 3919 sal_usecs_t time1, time2; 3920 3921 /* Check and update runt counter */ 3922 rv = _bcm_tr3_ibod_port_check(ibod_ctrl, port, &need_recovery); 3923 if (BCM_FAILURE(rv)) { 3924 LOG_ERROR(BSL_LS_BCM_PORT, 3925 (BSL_META_U(ibod_ctrl->unit, 3926 "Ibod recovery port %d check error\n"), port)); 3927 return rv; 3928 } 3929 else if(need_recovery == FALSE){ 3930 return BCM_E_NONE; 3931 } 3932 3933 time1 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 3934 3935 rv = _bcm_tr3_ibod_sync_recovery_port(ibod_ctrl, 0, port); 3936 3937 time2 = SAL_USECS_SUB(sal_time_usecs(), ibod_ctrl->start_time); 3938 ibod_ctrl->event_count++; 3939 ibod_ctrl->port_avg_time = (ibod_ctrl->port_avg_time*(ibod_ctrl->event_count-1) + 3940 time2 - time1) /ibod_ctrl->event_count; 3941 3942 return rv; 3943 } 3944 3945 STATIC void 3946 _bcm_tr3_ibod_sync_recovery_thread(void *context) 3947 { 3948 _port_ibod_ctrl_t *ibod_ctrl = context; 3949 int port, rv, unit = ibod_ctrl->unit; 3950 3951 LOG_VERBOSE(BSL_LS_BCM_PORT, 3952 (BSL_META_U(unit, 3953 "IBOD recovery started on unit %d\n"), ibod_ctrl->unit)); 3954 3955 ibod_ctrl->running = 1; 3956 while (!ibod_ctrl->stop) { 3957 if (!SOC_IS_DONE_INIT(unit)) { 3958 (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval); 3959 continue; 3960 } 3961 /* Need to wait until warmboot recovery of ibod related stats is done */ 3962 if (!SOC_WARM_BOOT(unit)) { 3963 PBMP_CL_ITER(unit, port) { 3964 if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) { 3965 continue; 3966 } 3967 ibod_ctrl->start_time = sal_time_usecs(); 3968 if(!IS_C_PORT(unit, port)) { 3969 (void)_bcm_tr3_ibod_recovery_port(ibod_ctrl, port); 3970 } 3971 3972 rv = _bcm_tr3_txerr_recovery_port(ibod_ctrl, port); 3973 if (SOC_FAILURE(rv)) { 3974 LOG_ERROR(BSL_LS_BCM_PORT, 3975 (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,port))); 3976 } 3977 } 3978 3979 rv = _bcm_tr3_mmu_check_and_recovery(ibod_ctrl); 3980 if (SOC_FAILURE(rv)) { 3981 LOG_ERROR(BSL_LS_BCM_PORT, 3982 (BSL_META_U(unit, "\n Error in MMU recovery "))); 3983 } 3984 3985 } 3986 (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval); 3987 } 3988 ibod_ctrl->running = 0; 3989 } 3990 3991 STATIC void 3992 _bcm_hx4_ibod_sync_recovery_thread(void *context) 3993 { 3994 _port_ibod_ctrl_t *ibod_ctrl = context; 3995 int port, flex_port=0, rv, unit = ibod_ctrl->unit; 3996 uint64 rrpkt, rrbyt; 3997 uint64 rrpkt_diff, rrbyt_diff; 3998 uint32 rval,rval_1,port_mode=0,encap_mode=0,next_flex_port=0; 3999 int port_group_iter; 4000 int flex_port_arr[3]={-1,-1,-1},cou,i; 4001 uint64 rval64; 4002 int runt_threshold; 4003 uint64 txerr; 4004 int egress_drain_timeout, port_drain_timeout, port_recovery_failed_flag; 4005 4006 LOG_VERBOSE(BSL_LS_BCM_PORT, 4007 (BSL_META_U(unit, "IBOD recovery started on unit %d\n"),ibod_ctrl->unit)); 4008 4009 cou=0; 4010 PBMP_ITER(PBMP_XW_ALL(unit), port) { 4011 (void) READ_PORT_MODE_REGr(unit, port, &rval); 4012 port_mode=soc_reg_field_get(unit, PORT_MODE_REGr, 4013 rval, XPORT0_CORE_PORT_MODEf); 4014 4015 if (port_mode != 3) { 4016 /* coverity[overrun-call : FALSE] */ 4017 if (_bcm_tr3_port_is_control_port(unit, port)) { 4018 flex_port_arr[cou] = port; 4019 cou++; 4020 } 4021 } 4022 rv = READ_RRPKTr(unit, port, &rrpkt); 4023 if (SOC_FAILURE(rv)) { 4024 LOG_ERROR(BSL_LS_BCM_PORT, 4025 (BSL_META_U(unit, "Error in reading RRPKTr %d\n"),ibod_ctrl->unit)); 4026 4027 } 4028 4029 rv = READ_RRBYTr(unit, port, &rrbyt); 4030 if (SOC_FAILURE(rv)) { 4031 LOG_ERROR(BSL_LS_BCM_PORT, 4032 (BSL_META_U(unit, "Error in reading RRBYTr %d\n"),ibod_ctrl->unit)); 4033 } 4034 /* coverity[overrun-local : FALSE] */ 4035 ibod_ctrl->rrpkt[port] = rrpkt; 4036 /* coverity[overrun-local : FALSE] */ 4037 ibod_ctrl->rrbyt[port] = rrbyt; 4038 } 4039 4040 ibod_ctrl->running = 1; 4041 while (!ibod_ctrl->stop) { 4042 if (!SOC_IS_DONE_INIT(unit)) { 4043 (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval); 4044 continue; 4045 } 4046 /* Need to wait until warmboot recovery of ibod related stats is done */ 4047 if (!SOC_WARM_BOOT(unit)) { 4048 next_flex_port=0; 4049 port_group_iter=-1; 4050 PBMP_ITER(PBMP_XW_ALL(unit), port) { 4051 if (!((IS_HG_PORT(unit,port)) || (IS_XE_PORT(unit,port)))) { 4052 continue; 4053 } 4054 /* coverity[overrun-local : FALSE] */ 4055 if (SOC_INFO(unit).port_speed_max[port] >= 100000) { 4056 continue; 4057 } 4058 ibod_ctrl->start_time = sal_time_usecs(); 4059 /* coverity[overrun-call : FALSE] */ 4060 if (_bcm_tr3_port_is_control_port(unit, port)) { 4061 flex_port=port; 4062 next_flex_port=0; 4063 port_group_iter++; 4064 } 4065 if (next_flex_port) { 4066 continue; 4067 } 4068 (void) READ_PORT_EHG_RX_CONTROLr(unit, port, &rval); 4069 encap_mode = soc_reg_field_get(unit, PORT_EHG_RX_CONTROLr, 4070 rval, MODEf); 4071 if (encap_mode) { 4072 (void) READ_PORT_EHG_RX_PKT_DROPr(unit, port, &rval); 4073 if (rval) { 4074 LOG_VERBOSE(BSL_LS_BCM_PORT, 4075 (BSL_META_U(unit, "\n WAR Trigerred by Embedded HG RX control"))); 4076 rv = BCM_E_NONE; 4077 /* coverity[overrun-call : FALSE] */ 4078 rv = _bcm_hx4_ibod_sync_recovery_port(ibod_ctrl, port_group_iter, flex_port); 4079 if (SOC_FAILURE(rv)) { 4080 PORT_UNLOCK(unit); 4081 /* Release the ibod recovery port group lock */ 4082 /* coverity[overrun-call : FALSE] */ 4083 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port); 4084 _bcm_esw_lc_unlock(unit); 4085 LOG_ERROR(BSL_LS_BCM_PORT, 4086 (BSL_META_U(unit, "\n Error in RRPKT WAR %s"),SOC_PORT_NAME(unit,flex_port))); 4087 } 4088 soc_event_generate(unit, SOC_SWITCH_EVENT_RUNT_DETECT, port, 0, 0); 4089 for (i=0; i<3; i++) { 4090 if ((flex_port_arr[i] != flex_port) && (flex_port_arr[i] != -1)) { 4091 rv = BCM_E_NONE; 4092 rv = _bcm_hx4_txerr_recovery_port(ibod_ctrl, flex_port_arr[i]); 4093 if (SOC_FAILURE(rv)) { 4094 PORT_UNLOCK(unit); 4095 /* Release the ibod recovery port group lock */ 4096 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port_arr[i]); 4097 _bcm_esw_lc_unlock(unit); 4098 LOG_ERROR(BSL_LS_BCM_PORT, 4099 (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,flex_port_arr[i]))); 4100 } 4101 } 4102 } 4103 next_flex_port=1; 4104 continue; 4105 } 4106 } 4107 4108 rv = READ_TERRr(unit, port, &txerr); 4109 if (SOC_FAILURE(rv)) { 4110 continue; 4111 } 4112 /* coverity[overrun-local : FALSE] */ 4113 if (COMPILER_64_NE(txerr, ibod_ctrl->txerrpkt[port])) { 4114 /* coverity[overrun-call : FALSE] */ 4115 rv = _bcm_hx4_txerr_recovery_port(ibod_ctrl, flex_port); 4116 if (SOC_FAILURE(rv)) { 4117 PORT_UNLOCK(unit); 4118 /* Release the ibod recovery port group lock */ 4119 /* coverity[overrun-call : FALSE] */ 4120 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port); 4121 _bcm_esw_lc_unlock(unit); 4122 LOG_ERROR(BSL_LS_BCM_PORT, 4123 (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,flex_port))); 4124 } 4125 } 4126 /* Check if any new runt packet logged in RRPKT */ 4127 rv = READ_RRPKTr(unit, port, &rrpkt); 4128 if (SOC_FAILURE(rv)) { 4129 continue; 4130 } 4131 if (COMPILER_64_EQ(rrpkt, ibod_ctrl->rrpkt[port])) { 4132 continue; 4133 } 4134 /* Check total runt byte count */ 4135 rv = READ_RRBYTr(unit, port, &rrbyt); 4136 if (SOC_FAILURE(rv)) { 4137 continue; 4138 } 4139 4140 /* It's very unlikely both packet and byte counters wrap around 4141 * and stop at 0, the code assume this is from clear counter */ 4142 if (COMPILER_64_IS_ZERO(rrpkt) && COMPILER_64_IS_ZERO(rrbyt)) { 4143 ibod_ctrl->rrpkt[port] = rrpkt; 4144 ibod_ctrl->rrbyt[port] = rrbyt; 4145 continue; 4146 } 4147 4148 rrpkt_diff = rrpkt; 4149 rrbyt_diff = rrbyt; 4150 COMPILER_64_SUB_64(rrpkt_diff, ibod_ctrl->rrpkt[port]); 4151 COMPILER_64_SUB_64(rrbyt_diff, ibod_ctrl->rrbyt[port]); 4152 ibod_ctrl->rrpkt[port] = rrpkt; 4153 ibod_ctrl->rrbyt[port] = rrbyt; 4154 4155 rv = READ_XMAC_RX_CTRLr(unit,port, &rval64); 4156 if (SOC_FAILURE(rv)) { 4157 continue; 4158 } 4159 runt_threshold = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval64, RUNT_THRESHOLDf); 4160 4161 /* Recovery is needed only for packet size between 33 and 76 */ 4162 if (COMPILER_64_HI(rrpkt_diff) == 0 && 4163 COMPILER_64_LO(rrpkt_diff) == 1) { 4164 if (COMPILER_64_LO(rrbyt_diff) >= runt_threshold) { 4165 continue; 4166 } 4167 } 4168 if (COMPILER_64_HI(rrbyt_diff) == 0 && 4169 COMPILER_64_LO(rrbyt_diff) <= 32) { 4170 continue; 4171 } 4172 LOG_VERBOSE(BSL_LS_BCM_PORT, 4173 (BSL_META_U(unit,"\n WAR Trigerred by RRPKT/RRBYT"))); 4174 /* coverity[overrun-call : FALSE] */ 4175 rv = _bcm_hx4_ibod_sync_recovery_port(ibod_ctrl, port_group_iter, flex_port); 4176 if (SOC_FAILURE(rv)) { 4177 PORT_UNLOCK(unit); 4178 /* Release the ibod recovery port group lock */ 4179 /* coverity[overrun-call : FALSE] */ 4180 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port); 4181 _bcm_esw_lc_unlock(unit); 4182 LOG_ERROR(BSL_LS_BCM_PORT, 4183 (BSL_META_U(unit, "\n Error in RRPKT WAR %s"),SOC_PORT_NAME(unit,flex_port))); 4184 } 4185 soc_event_generate(unit, SOC_SWITCH_EVENT_RUNT_DETECT, port, 0, 0); 4186 for (i=0; i<3; i++) { 4187 if ((flex_port_arr[i] != flex_port) && (flex_port_arr[i] != -1)) { 4188 rv = BCM_E_NONE; 4189 rv = _bcm_hx4_txerr_recovery_port(ibod_ctrl, flex_port_arr[i]); 4190 if (SOC_FAILURE(rv)) { 4191 PORT_UNLOCK(unit); 4192 /* Release the ibod recovery port group lock */ 4193 /* coverity[overrun-call : FALSE] */ 4194 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port_arr[i]); 4195 _bcm_esw_lc_unlock(unit); 4196 LOG_ERROR(BSL_LS_BCM_PORT, 4197 (BSL_META_U(unit, "\n Error in TXERR WAR %s"),SOC_PORT_NAME(unit,flex_port_arr[i]))); 4198 } 4199 } 4200 } 4201 next_flex_port=1; 4202 } 4203 4204 _soc_egress_drain_timeout_flag_get(unit, &egress_drain_timeout); 4205 port_drain_timeout = ibod_ctrl->drain_timeout_flag; 4206 port_recovery_failed_flag = ibod_ctrl->port_recovery_failed_flag; 4207 4208 rv = READ_PQEFIFOOVERFLOW0r(unit, &rval); 4209 if (SOC_FAILURE(rv)) { 4210 LOG_ERROR(BSL_LS_BCM_PORT, 4211 (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW0"))); 4212 } 4213 rv = READ_PQEFIFOOVERFLOW1r(unit, &rval_1); 4214 if (SOC_FAILURE(rv)) { 4215 LOG_ERROR(BSL_LS_BCM_PORT, 4216 (BSL_META_U(unit, "\n Error in ibod recovery thread when reading register PQEFIFOOVERFLOW1"))); 4217 } 4218 4219 if ((rval != 0) || (rval_1 != 0) || (egress_drain_timeout != 0) || (port_drain_timeout != 0) 4220 || port_recovery_failed_flag || (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER)) { 4221 rv = _bcm_tr3_mmu_recovery(ibod_ctrl); 4222 ibod_ctrl->drain_timeout_flag = 0; 4223 _soc_egress_drain_timeout_flag_set(unit, 0); 4224 if (port_drain_timeout) { 4225 ibod_ctrl->drain_timeout_flag = 0; 4226 ibod_ctrl->drain_timeout_count++; 4227 } 4228 if (egress_drain_timeout) { 4229 _soc_egress_drain_timeout_flag_set(unit, 0); 4230 ibod_ctrl->egress_drain_timeout_count++; 4231 } 4232 if (port_recovery_failed_flag) { 4233 ibod_ctrl->port_recovery_failed_flag = 0; 4234 ibod_ctrl->port_recovery_failed_count++; 4235 } 4236 if (_ibod_debug_flag & _PORT_IBOD_FLAG_MMU_TRIGGER) { 4237 _ibod_debug_flag &= (~_PORT_IBOD_FLAG_MMU_TRIGGER); 4238 } 4239 if (SOC_FAILURE(rv)) { 4240 LOG_ERROR(BSL_LS_BCM_PORT, 4241 (BSL_META_U(unit, "\n Error in MMU recovery "))); 4242 } 4243 } 4244 } 4245 (void)sal_sem_take(ibod_ctrl->sema, ibod_ctrl->interval); 4246 } 4247 ibod_ctrl->running = 0; 4248 } 4249 4250 int _bcm_esw_ibod_syn_port_down (int unit, int port) 4251 { 4252 _port_ibod_ctrl_t *ibod_ctrl = _port_ibod_ctrl[unit]; 4253 int rv; 4254 uint64 rrpkt, rrbyt,rval64; 4255 uint64 rrpkt_diff, rrbyt_diff; 4256 int runt_threshold; 4257 uint32 port_mode, rval; 4258 4259 if (!SOC_IS_TRIUMPH3(unit) || !ibod_ctrl) { 4260 return BCM_E_NONE; 4261 } 4262 4263 if (SOC_IS_HELIX4(unit)) { 4264 if (!IS_XE_PORT(unit, port) && !IS_HG_PORT(unit, port)) { 4265 return SOC_E_NONE; 4266 } 4267 } else { 4268 if (!IS_HG_PORT(unit, port)) { 4269 return SOC_E_NONE; 4270 } 4271 } 4272 4273 if (SOC_INFO(unit).port_speed_max[port] >= 100000 || 4274 !(SOC_CONTROL(unit)->soc_flags & SOC_F_INITED)) { 4275 return SOC_E_NONE; 4276 } 4277 4278 BCM_IF_ERROR_RETURN(READ_PORT_MODE_REGr(unit, port, &rval)); 4279 port_mode=soc_reg_field_get(unit, PORT_MODE_REGr, 4280 rval, XPORT0_CORE_PORT_MODEf); 4281 4282 /* Port mode must be Dual or Qual */ 4283 if ((port_mode != 1) && (port_mode != 2)) { 4284 return SOC_E_NONE; 4285 } 4286 4287 /* Check if any new runt packet logged in RRPKT */ 4288 rv = READ_RRPKTr(unit, port, &rrpkt); 4289 if (SOC_FAILURE(rv)) { 4290 return SOC_E_NONE; 4291 } 4292 if (COMPILER_64_EQ(rrpkt, ibod_ctrl->rrpkt[port])) { 4293 return SOC_E_NONE; 4294 } 4295 /* Check total runt byte count */ 4296 rv = READ_RRBYTr(unit, port, &rrbyt); 4297 if (SOC_FAILURE(rv)) { 4298 return SOC_E_NONE; 4299 } 4300 4301 /* It's very unlikely both packet and byte counters wrap around 4302 * and stop at 0, the code assume this is from clear counter */ 4303 if (COMPILER_64_IS_ZERO(rrpkt) && COMPILER_64_IS_ZERO(rrbyt)) { 4304 ibod_ctrl->rrpkt[port] = rrpkt; 4305 ibod_ctrl->rrbyt[port] = rrbyt; 4306 return SOC_E_NONE; 4307 } 4308 4309 rrpkt_diff = rrpkt; 4310 rrbyt_diff = rrbyt; 4311 COMPILER_64_SUB_64(rrpkt_diff, ibod_ctrl->rrpkt[port]); 4312 COMPILER_64_SUB_64(rrbyt_diff, ibod_ctrl->rrbyt[port]); 4313 ibod_ctrl->rrpkt[port] = rrpkt; 4314 ibod_ctrl->rrbyt[port] = rrbyt; 4315 4316 rv = READ_XMAC_RX_CTRLr(unit,port, &rval64); 4317 if (SOC_FAILURE(rv)) { 4318 return SOC_E_NONE; 4319 } 4320 runt_threshold = soc_reg64_field32_get(unit, XMAC_RX_CTRLr, rval64, RUNT_THRESHOLDf); 4321 4322 /* Recovery is needed only for packet size between 33 and 76 */ 4323 if (COMPILER_64_HI(rrpkt_diff) == 0 && 4324 COMPILER_64_LO(rrpkt_diff) == 1) { 4325 if (COMPILER_64_LO(rrbyt_diff) >= runt_threshold) { 4326 return SOC_E_NONE; 4327 } 4328 } 4329 if (COMPILER_64_HI(rrbyt_diff) == 0 && 4330 COMPILER_64_LO(rrbyt_diff) <= 32) { 4331 return SOC_E_NONE; 4332 } 4333 4334 ibod_ctrl->start_time = sal_time_usecs(); 4335 if (SOC_IS_HELIX4(unit)) { 4336 int port_group_iter, port_iter, flex_port=0; 4337 bcm_pbmp_t pbmp; 4338 4339 port_group_iter=-1; 4340 PBMP_ITER(PBMP_XW_ALL(unit), port_iter) { 4341 /* coverity[overrun-call : FALSE] */ 4342 if (!(_bcm_tr3_port_is_control_port(unit, port_iter))) { 4343 continue; 4344 } 4345 flex_port = port_iter; 4346 port_group_iter++; 4347 BCM_IF_ERROR_RETURN(bcm_esw_port_subsidiary_ports_get(unit, flex_port, &pbmp)); 4348 if (SOC_PBMP_MEMBER(pbmp, port)) { 4349 break; 4350 } 4351 } 4352 /* coverity[overrun-call : FALSE] */ 4353 rv = _bcm_hx4_ibod_sync_recovery_port(ibod_ctrl, port_group_iter, flex_port); 4354 if (SOC_FAILURE(rv)) { 4355 PORT_UNLOCK(unit); 4356 /* Release the ibod recovery port group lock */ 4357 _bcm_esw_ibod_recovery_port_unlock(unit, flex_port); 4358 _bcm_esw_lc_unlock(unit); 4359 } 4360 } else { 4361 rv = _bcm_tr3_ibod_sync_recovery_port(ibod_ctrl, 1, port); 4362 } 4363 4364 if (SOC_FAILURE(rv)) { 4365 LOG_ERROR(BSL_LS_BCM_PORT, 4366 (BSL_META_U(unit, "\n Error in RRPKT WAR %s"), SOC_PORT_NAME(unit, port))); 4367 } 4368 return SOC_E_NONE; 4369 4370 } 4371 4372 int 4373 _bcm_esw_ibod_sync_recovery_start(int unit, sal_usecs_t interval) 4374 { 4375 int cnt; 4376 bcm_pkt_t *pkt; 4377 uint8 *buf; 4378 int buf_size = 72; 4379 uint32 rval; 4380 int rv = BCM_E_NONE; 4381 _port_ibod_ctrl_t *ibod_ctrl; 4382 uint16 dev_id; 4383 uint8 rev_id; 4384 4385 if (!SOC_IS_TRIUMPH3(unit)) { 4386 return BCM_E_NONE; 4387 } 4388 4389 /* APOLLO2 devices dont need ibod sync */ 4390 soc_cm_get_id(unit, &dev_id, &rev_id); 4391 switch (dev_id) { 4392 case BCM56542_DEVICE_ID: 4393 case BCM56544_DEVICE_ID: 4394 return BCM_E_NONE; 4395 } 4396 4397 ibod_ctrl = _port_ibod_ctrl[unit]; 4398 if (ibod_ctrl == NULL) { 4399 ibod_ctrl = sal_alloc(sizeof(_port_ibod_ctrl_t), "_port_ibod_ctrl_t"); 4400 if (ibod_ctrl == NULL) { 4401 return BCM_E_MEMORY; 4402 } 4403 sal_memset(ibod_ctrl, 0, sizeof(_port_ibod_ctrl_t)); 4404 _port_ibod_ctrl[unit] = ibod_ctrl; 4405 } 4406 4407 ibod_ctrl->interval = interval; 4408 4409 if (ibod_ctrl->interval < IBOD_SYNC_INTERVAL_MIN) { 4410 ibod_ctrl->interval = IBOD_SYNC_INTERVAL_MIN; 4411 } 4412 4413 if (ibod_ctrl->running) { 4414 return BCM_E_NONE; 4415 } 4416 4417 ibod_ctrl->unit = unit; 4418 4419 /* Setup packet field */ 4420 pkt = &ibod_ctrl->pkt; 4421 buf = soc_cm_salloc(unit, buf_size, "pkt alloc data"); 4422 if (buf == NULL) { 4423 return BCM_E_MEMORY; 4424 } 4425 BCM_PKT_ONE_BUF_SETUP(pkt, buf, buf_size); 4426 pkt->unit = unit; 4427 pkt->flags = BCM_TX_CRC_APPEND | BCM_TX_HG_READY | BCM_TX_NO_PAD | 4428 BCM_TX_LINKDOWN_TRANSMIT; 4429 pkt->opcode = BCM_PKT_OPCODE_UC; /* do not to CPU */ 4430 4431 if (ibod_ctrl->sema == NULL) { 4432 ibod_ctrl->sema = sal_sem_create("ibod recovery", sal_sem_BINARY, 0); 4433 if (ibod_ctrl->sema == NULL) { 4434 return BCM_E_MEMORY; 4435 } 4436 } 4437 4438 sal_snprintf(ibod_ctrl->taskname, sizeof (ibod_ctrl->taskname), 4439 "bcmIbodSync.%d", unit); 4440 ibod_ctrl->stop = 0; 4441 SOC_IF_ERROR_RETURN(_bcm_esw_ibod_recovery_lock_init(unit)); 4442 rv = soc_tr3_mmu_store_alloc(unit); 4443 if(BCM_FAILURE(rv)) { 4444 return rv; 4445 } 4446 soc_ibod_recovery_in_progress_set(unit, 0); 4447 _soc_egress_drain_timeout_flag_set(unit, 0); 4448 sal_memset(txerr_trigger_flag, 0, sizeof(txerr_trigger_flag)); 4449 if (SOC_IS_HELIX4(unit)) { 4450 SOC_IF_ERROR_RETURN(READ_IBOD_INTR_MASKr(unit, &rval)); 4451 soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL0_CTRL_FIFO_FULL_ERR_INTR_MASKf, 1); 4452 soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL0_DATA_FIFO_FULL_ERR_INTR_MASKf, 1); 4453 soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL1_CTRL_FIFO_FULL_ERR_INTR_MASKf, 1); 4454 soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL1_DATA_FIFO_FULL_ERR_INTR_MASKf, 1); 4455 soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL2_CTRL_FIFO_FULL_ERR_INTR_MASKf, 1); 4456 soc_reg_field_set(unit, IBOD_INTR_MASKr, &rval, CL2_DATA_FIFO_FULL_ERR_INTR_MASKf, 1); 4457 SOC_IF_ERROR_RETURN(WRITE_IBOD_INTR_MASKr(unit, rval)); 4458 if (sal_thread_create(ibod_ctrl->taskname, SAL_THREAD_STKSZ, 4459 soc_property_get(unit, spn_IBOD_SYNC_THREAD_PRI, 50), 4460 _bcm_hx4_ibod_sync_recovery_thread, 4461 ibod_ctrl) == SAL_THREAD_ERROR) { 4462 return BCM_E_MEMORY; 4463 } 4464 } else { 4465 if (sal_thread_create(ibod_ctrl->taskname, SAL_THREAD_STKSZ, 4466 soc_property_get(unit, spn_IBOD_SYNC_THREAD_PRI, 50), 4467 _bcm_tr3_ibod_sync_recovery_thread, 4468 ibod_ctrl) == SAL_THREAD_ERROR) { 4469 return BCM_E_MEMORY; 4470 } 4471 } 4472 cnt = 10; 4473 while (!ibod_ctrl->running && cnt--) { 4474 sal_usleep(100000); 4475 } 4476 if (!ibod_ctrl->running) { 4477 LOG_ERROR(BSL_LS_BCM_PORT, 4478 (BSL_META_U(unit, 4479 "%s: Thread did not start\n"), ibod_ctrl->taskname)); 4480 return BCM_E_TIMEOUT; 4481 } 4482 return BCM_E_NONE; 4483 } 4484 4485 int 4486 _bcm_esw_ibod_sync_recovery_stop(int unit) 4487 { 4488 int cnt; 4489 bcm_pkt_t *pkt; 4490 _port_ibod_ctrl_t *ibod_ctrl = _port_ibod_ctrl[unit]; 4491 4492 if (ibod_ctrl == NULL) { 4493 return BCM_E_NONE; 4494 } 4495 4496 ibod_ctrl->stop = 1; 4497 if (ibod_ctrl->sema != NULL) { 4498 sal_sem_give(ibod_ctrl->sema); 4499 } 4500 cnt = 10; 4501 while (ibod_ctrl->running && cnt--) { 4502 sal_usleep(100000); 4503 } 4504 if (ibod_ctrl->running) { 4505 LOG_ERROR(BSL_LS_BCM_PORT, 4506 (BSL_META_U(unit, 4507 "%s: Thread did not start\n"), ibod_ctrl->taskname)); 4508 return BCM_E_TIMEOUT; 4509 } 4510 pkt = &ibod_ctrl->pkt; 4511 if (pkt->_pkt_data.data != NULL) { 4512 soc_cm_sfree(unit, pkt->_pkt_data.data); 4513 pkt->_pkt_data.data = NULL; 4514 pkt->_pkt_data.len = 0; 4515 } 4516 if (ibod_ctrl->sema != NULL) { 4517 sal_sem_destroy(ibod_ctrl->sema); 4518 } 4519 4520 sal_free(ibod_ctrl); 4521 _port_ibod_ctrl[unit] = NULL; 4522 4523 _bcm_esw_ibod_recovery_lock_deinit(unit); 4524 4525 soc_tr3_mmu_store_free(unit); 4526 return BCM_E_NONE; 4527 } 4528 4529 int _bcm_esw_ibod_sync_recovery_running(int unit, _port_ibod_ctrl_t *ibod_ctrl) 4530 { 4531 if (_port_ibod_ctrl[unit] == NULL) { 4532 return BCM_E_FAIL; 4533 } 4534 if(ibod_ctrl != NULL) { 4535 sal_memcpy(ibod_ctrl, _port_ibod_ctrl[unit], sizeof(_port_ibod_ctrl_t)); 4536 } 4537 return BCM_E_NONE; 4538 } 4539 4540 STATIC int _bcm_tr3_xmac_fifo_check(int unit, bcm_port_t port, uint8 lu_tpo) 4541 { 4542 int rv_xmac_fifo = BCM_E_NONE; 4543 int rv = BCM_E_NONE; 4544 bcm_pkt_t *pkt = NULL; 4545 uint8 *payload; 4546 uint32 req_cnt = 0, cell_cnt = 0; 4547 uint64 rval64; 4548 int rx_enable_org = 0,speed_mode=0,port_enable; 4549 pbmp_t act_tx_pbmp, tx_pbmp; 4550 4551 COMPILER_64_ZERO(rval64); 4552 SOC_PBMP_CLEAR(act_tx_pbmp); 4553 SOC_PBMP_CLEAR(tx_pbmp); 4554 4555 /* Create test packet */ 4556 pkt = soc_cm_salloc(unit, sizeof(bcm_pkt_t), "pkt buffer"); 4557 if (pkt == NULL) { 4558 return BCM_E_FAIL; 4559 } 4560 4561 sal_memset(pkt, 0, sizeof(bcm_pkt_t)); 4562 payload = soc_cm_salloc(unit, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ, 4563 "pkt alloc data"); 4564 if (payload == NULL) { 4565 soc_cm_sfree(unit, pkt); 4566 return BCM_E_FAIL; 4567 } 4568 sal_memset(payload, 0, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ); 4569 BCM_PKT_ONE_BUF_SETUP(pkt, payload, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ); 4570 pkt->unit = unit; 4571 pkt->flags = BCM_TX_CRC_APPEND | BCM_TX_HG_READY | BCM_TX_NO_PAD | 4572 BCM_TX_LINKDOWN_TRANSMIT; 4573 pkt->call_back = NULL; 4574 4575 #ifdef BCM_PORT_DEFAULT_DISABLE 4576 port_enable = FALSE; 4577 #else 4578 port_enable = TRUE; 4579 #endif /* BCM_PORT_DEFAULT_DISABLE */ 4580 4581 if (BCM_E_NONE != 4582 (rv = MAC_ENABLE_GET(PORT(unit, port).p_mac, unit, port, &port_enable))) { 4583 goto cleanup; 4584 } 4585 /* Put the port in MAC loopback and enable it for transmit */ 4586 if (BCM_E_NONE != 4587 (rv = MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, TRUE))) { 4588 goto cleanup; 4589 } 4590 if (BCM_E_NONE != 4591 (rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE))) { 4592 goto cleanup; 4593 } 4594 /* Ensure that we are in MAC line-side loopback */ 4595 if (SOC_E_NONE != (rv = READ_XMAC_CTRLr(unit, port, &rval64))) { 4596 goto cleanup; 4597 } 4598 4599 rx_enable_org = soc_reg64_field32_get(unit, XMAC_CTRLr, rval64, RX_ENf); 4600 /* RX Disable */ 4601 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf, 0); 4602 /* Line local LB */ 4603 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, LINE_LOCAL_LPBKf, 1); 4604 /* Core local LB */ 4605 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, CORE_LOCAL_LPBKf, 0); 4606 if (SOC_E_NONE != (rv = WRITE_XMAC_CTRLr(unit, port, rval64))) { 4607 goto cleanup; 4608 } 4609 /* Ensure that we are back in same MAC MODE*/ 4610 if (SOC_E_NONE != (rv = READ_XMAC_MODEr(unit, port, &rval64))) { 4611 goto cleanup; 4612 } 4613 speed_mode = soc_reg64_field32_get(unit, XMAC_MODEr, rval64, SPEED_MODEf); 4614 4615 /* Stall the XMAC's transmit FIFO */ 4616 if (SOC_E_NONE != 4617 (rv = soc_reg_field32_modify(unit, XMAC_MODEr, port, SPEED_MODEf, 4))) { 4618 goto cleanup; 4619 } 4620 4621 if (SOC_E_NONE != 4622 (rv = soc_reg_field32_modify(unit, XMAC_MACSEC_CTRLr, port, 4623 MACSEC_TX_LAUNCH_ENf, 1))) { 4624 goto cleanup; 4625 } 4626 4627 /* EPC_LINK */ 4628 soc_link_mask2_get(unit, &act_tx_pbmp); 4629 SOC_PBMP_PORT_ADD(tx_pbmp, port); 4630 if (!lu_tpo) { 4631 /* Use original state and add new ports as well */ 4632 SOC_PBMP_OR(tx_pbmp, act_tx_pbmp); 4633 } 4634 if (SOC_E_NONE != (rv = soc_link_mask2_set(unit, tx_pbmp))) { 4635 goto cleanup; 4636 } 4637 /* Transmit the test packet */ 4638 BCM_PKT_TX_LEN_SET(pkt, _SOC_HX4_XMAC_FIFO_CHK_PKT_SZ); 4639 BCM_PKT_PORT_SET(pkt, port, TRUE, FALSE); 4640 rv = bcm_esw_tx(unit, pkt, NULL); 4641 if (BCM_FAILURE(rv)) { 4642 rv = BCM_E_FAIL; 4643 goto cleanup; 4644 } 4645 4646 /* Wait for a short period of time to allow 4647 the packet to reach the end of the EP */ 4648 sal_udelay(1000); 4649 4650 /* Read the request count value */ 4651 if (SOC_E_NONE != 4652 (rv = READ_PORT_TXFIFO_CELL_REQ_CNTr(unit, port, &req_cnt))) { 4653 goto cleanup; 4654 } 4655 /* Read the cell count value */ 4656 if (SOC_E_NONE != 4657 (rv = READ_PORT_TXFIFO_CELL_CNTr(unit, port, &cell_cnt))) { 4658 goto cleanup; 4659 } 4660 LOG_VERBOSE(BSL_LS_BCM_PORT, 4661 (BSL_META_U(unit, 4662 "Check: cell_req_cnt: %d cell_cnt: %d\n"), 4663 req_cnt, cell_cnt)); 4664 /* Check to make sure that the request count is exactly zero */ 4665 if (req_cnt != 0) { 4666 rv_xmac_fifo = BCM_E_INTERNAL; 4667 goto cleanup; 4668 } 4669 4670 cleanup: 4671 /* free packet memory */ 4672 if (payload != NULL) { 4673 soc_cm_sfree(unit, payload); 4674 } 4675 if (pkt != NULL) { 4676 soc_cm_sfree(unit, pkt); 4677 } 4678 /* Clear the MAC loopback (flushes the test packet) */ 4679 if (SOC_E_NONE != MAC_LOOPBACK_SET(PORT(unit, port).p_mac, 4680 unit, port, FALSE)) { 4681 rv = BCM_E_FAIL; 4682 } 4683 /* Clear the MAC Enable Set */ 4684 if (SOC_E_NONE != MAC_ENABLE_SET(PORT(unit, port).p_mac, 4685 unit, port, FALSE)) { 4686 rv = BCM_E_FAIL; 4687 } 4688 /* Restoring the MAC Enable Set */ 4689 if (port_enable) { 4690 if (SOC_E_NONE != 4691 (rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE))) { 4692 rv = BCM_E_FAIL; 4693 } 4694 } 4695 /* Remove the MAC FIFO stall */ 4696 if (SOC_E_NONE != soc_reg_field32_modify(unit, XMAC_MODEr, port, 4697 SPEED_MODEf, speed_mode)) { 4698 rv = BCM_E_FAIL; 4699 } 4700 if (SOC_E_NONE != soc_reg_field32_modify(unit, XMAC_MACSEC_CTRLr, port, 4701 MACSEC_TX_LAUNCH_ENf, 0)) { 4702 rv = BCM_E_FAIL; 4703 } 4704 /* revert rx_enable */ 4705 if (SOC_E_NONE != soc_reg_field32_modify(unit, XMAC_CTRLr, port, RX_ENf, 4706 rx_enable_org)) { 4707 rv = BCM_E_FAIL; 4708 } 4709 /* EPC_LINK restore */ 4710 if (SOC_E_NONE != soc_link_mask2_set(unit, act_tx_pbmp)) { 4711 rv = BCM_E_FAIL; 4712 } 4713 /* Clear the counters from tx port*/ 4714 SOC_PBMP_PORT_SET(tx_pbmp, port); 4715 if (SOC_E_NONE != soc_counter_set32_by_port(unit, tx_pbmp, 0)) { 4716 rv = BCM_E_FAIL; 4717 } 4718 if (BCM_E_NONE != rv) { 4719 return rv; 4720 } else { 4721 return rv_xmac_fifo; 4722 } 4723 } 4724 4725 #define _BCM_TR3_PORT_UR_RETRY_MAX 15 4726 int _bcm_tr3_port_ur_chk(int unit, int num_ports, bcm_port_t port) 4727 { 4728 uint8 lu_tpo = 0; /* link up test port only */ 4729 int retry = _BCM_TR3_PORT_UR_RETRY_MAX; 4730 int fifo_underrun = FALSE, issue_overcome = TRUE; 4731 soc_info_t *si = &SOC_INFO(unit); 4732 int rv = BCM_E_NONE; 4733 int okay = 0; 4734 uint32 expected_cell_req_cnt, cell_req_cnt, cell_cnt; 4735 soc_block_type_t pbt; 4736 int _num_ports = (num_ports == -1) ? 4 : num_ports; 4737 int phy_port = SOC_IS_HELIX4(unit) ? 4738 _SOC_HX4_MGMT_PHY_PORT : _SOC_TR3_MGMT_PHY_PORT; 4739 4740 #ifdef BCM_TRIUMPH3_SUPPORT 4741 if (!(SOC_IS_HELIX4(unit))) { 4742 /* Skipping in for Disabled Ports */ 4743 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay)); 4744 if (!okay) { 4745 return BCM_E_NONE; 4746 } 4747 } 4748 #endif 4749 #ifdef BCM_HELIX4_SUPPORT 4750 if ( SOC_IS_HELIX4(unit) && 4751 ((_tr3_port_config_id[unit] == 463)|| 4752 (_tr3_port_config_id[unit] == 413)) && 4753 (57 == si->port_l2p_mapping[port] || 61 == si->port_l2p_mapping[port])) 4754 { 4755 switch (_num_ports) { 4756 case 1: expected_cell_req_cnt = 8; break; 4757 case 2: expected_cell_req_cnt = 4; break; 4758 case 4: expected_cell_req_cnt = 4; break; 4759 default: expected_cell_req_cnt = 4; 4760 } 4761 }else 4762 #endif 4763 { 4764 switch (_num_ports) { 4765 case 1: expected_cell_req_cnt = 16; break; 4766 case 2: expected_cell_req_cnt = 8; break; 4767 case 4: expected_cell_req_cnt = 4; break; 4768 default: expected_cell_req_cnt = 4; 4769 } 4770 } 4771 if (-1 == port) { 4772 lu_tpo = 1; 4773 port = si->port_p2l_mapping[phy_port]; 4774 } else { 4775 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 4776 } 4777 LOG_VERBOSE(BSL_LS_BCM_PORT, 4778 (BSL_META_U(unit, 4779 "UR test: %s\n"), SOC_PORT_NAME(unit, port))); 4780 4781 /* nothing to do if port is not a valid port */ 4782 if (!SOC_PORT_VALID(unit, port)) { 4783 LOG_VERBOSE(BSL_LS_BCM_PORT, (BSL_META_U(unit, 4784 "Port %s is not valid - skipping WAR\n"), 4785 SOC_PORT_NAME(unit, port))); 4786 return BCM_E_NONE; 4787 } 4788 4789 pbt = SOC_BLOCK_TYPE(unit, SOC_PORT_BLOCK(unit, phy_port)); 4790 while (retry--) { 4791 rv = _bcm_tr3_xmac_fifo_check(unit, port, lu_tpo); 4792 if (BCM_E_INTERNAL == rv) { 4793 if (num_ports != -1 && (_num_ports > 1)) { 4794 /* This is a case of flex port transform to dual or quad lane 4795 mode and one of the newly created ports is failing */ 4796 return BCM_E_PORT; 4797 } 4798 fifo_underrun = TRUE; 4799 issue_overcome = FALSE; 4800 4801 if (SOC_E_NONE != (rv = _soc_tr3_ur_port_reset(unit, _num_ports, port, pbt))) { 4802 rv = BCM_E_INTERNAL; 4803 goto cleanup; 4804 } 4805 if ((rv = _bcm_port_mac_init(unit, port, &okay)) != BCM_E_NONE) { 4806 goto cleanup; 4807 } 4808 /* Read cell req count value to see if reset cleared it */ 4809 if ((rv = READ_PORT_TXFIFO_CELL_REQ_CNTr( 4810 unit, port, &cell_req_cnt)) != SOC_E_NONE) { 4811 goto cleanup; 4812 } 4813 /* Read cell count value again to see if reset cleared it */ 4814 if ((rv = READ_PORT_TXFIFO_CELL_CNTr( 4815 unit, port, &cell_cnt))!= SOC_E_NONE) { 4816 goto cleanup; 4817 } 4818 LOG_VERBOSE(BSL_LS_BCM_PORT, 4819 (BSL_META_U(unit, 4820 "After reset: cell_req_cnt: " 4821 "%d cell_cnt: %d\n"), cell_req_cnt, cell_cnt)); 4822 /* Check to make sure that the request count is exactly zero */ 4823 if ((cell_req_cnt != expected_cell_req_cnt) || (cell_cnt != 0)) { 4824 rv = BCM_E_INTERNAL; 4825 goto cleanup; 4826 } 4827 } else { 4828 if (BCM_E_NONE != rv) { 4829 goto cleanup; 4830 } 4831 if (TRUE == fifo_underrun) { 4832 issue_overcome = TRUE; 4833 } 4834 /* either underrun didn't occur or war fixed it */ 4835 break; 4836 } 4837 }/* while */ 4838 4839 if (fifo_underrun) { 4840 rv = BCM_E_INTERNAL; 4841 if (issue_overcome) { 4842 rv = BCM_E_NONE; 4843 LOG_VERBOSE(BSL_LS_BCM_PORT, 4844 (BSL_META_U(unit, 4845 "Port %s recovered from XMAC FIFO underrun\n"), 4846 SOC_PORT_NAME(unit, port))); 4847 } else { 4848 LOG_ERROR(BSL_LS_BCM_PORT, 4849 (BSL_META_U(unit, 4850 "Port %s did not recover from XMAC FIFO underrun\n"), 4851 SOC_PORT_NAME(unit, port))); 4852 } 4853 } 4854 4855 cleanup: 4856 if (BCM_E_NONE != rv) { 4857 LOG_ERROR(BSL_LS_BCM_PORT, 4858 (BSL_META_U(unit, 4859 "Port %s, failed while checking/recovering " 4860 "XL port underrun\n"), 4861 SOC_PORT_NAME(unit, port))); 4862 } 4863 4864 return rv; 4865 } 4866 #endif /* BCM_TRIUMPH3_SUPPORT */ 4867 4868 4869 /* 4870 * Function: 4871 * _bcm_esw_port_gport_validate 4872 * Description: 4873 * Helper funtion to validate port/gport parameter 4874 * Parameters: 4875 * unit - (IN) BCM device number 4876 * port_in - (IN) Port / Gport to validate 4877 * port_out - (OUT) Port number if valid. 4878 * Return Value: 4879 * BCM_E_NONE - Port OK 4880 * BCM_E_INIT - Not initialized 4881 * BCM_E_PORT - Port Invalid 4882 */ 4883 int 4884 _bcm_esw_port_gport_validate(int unit, bcm_port_t port_in, bcm_port_t *port_out) 4885 { 4886 if (bcm_port_info[unit] == NULL) { 4887 return BCM_E_INIT; 4888 } 4889 4890 #if defined (BCM_HGPROXY_COE_SUPPORT) 4891 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 4892 BCM_GPORT_IS_SUBPORT_PORT(port_in)) { 4893 return _bcm_xgs5_subport_gport_validate(unit, 4894 port_in, 4895 port_out); 4896 } else 4897 #endif /* defined (BCM_HGPROXY_COE_SUPPORT) */ 4898 4899 #ifdef BCM_KATANA2_SUPPORT 4900 if (soc_feature(unit, soc_feature_linkphy_coe) || 4901 soc_feature(unit, soc_feature_subtag_coe)) { 4902 return _bcm_kt2_port_gport_validate(unit, port_in, port_out); 4903 } 4904 #endif 4905 4906 if (BCM_GPORT_IS_SET(port_in)) { 4907 BCM_IF_ERROR_RETURN( 4908 bcm_esw_port_local_get(unit, port_in, port_out)); 4909 } else if (SOC_PORT_VALID(unit, port_in)) { 4910 *port_out = port_in; 4911 } else { 4912 return BCM_E_PORT; 4913 } 4914 4915 return BCM_E_NONE; 4916 } 4917 4918 /* 4919 * Function: 4920 * _bcm_port_link_delay_update 4921 * Description: 4922 * Helper funtion: Update link delay based on configured values 4923 * Parameters: 4924 * unit - (IN) BCM device number 4925 * port - (IN) Port number 4926 * speed - (IN) New speed 4927 * Return Value: 4928 * BCM_E_XXX 4929 */ 4930 int 4931 _bcm_esw_port_link_delay_update(int unit, bcm_port_t port, int speed) 4932 { 4933 int32 link_delay; 4934 int mac_rx_latency = 0; 4935 _bcm_port_info_t *port_info; 4936 int rv; 4937 4938 _bcm_port_info_access(unit, port, &port_info); 4939 rv = MAC_CONTROL_GET(port_info->p_mac, unit, port, 4940 SOC_MAC_CONTROL_EXPECTED_RX_LATENCY, 4941 &mac_rx_latency); 4942 if (rv != BCM_E_NONE) { 4943 LOG_INFO(BSL_LS_BCM_PORT, (BSL_META( 4944 "Port updating LINK_DELAY, but MAC doesn't have a default value\n") 4945 )); 4946 } 4947 4948 link_delay = (int32)soc_property_port_get(unit, port, spn_LINK_DELAY(speed), mac_rx_latency); 4949 /* use bcmPortControl1588P2PDelay control field as an offset from this value */ 4950 link_delay += PORT(unit, port).link_delay_offset; 4951 4952 if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) { 4953 BCM_IF_ERROR_RETURN( 4954 soc_reg_field32_modify(unit, EGR_1588_LINK_DELAYr, 4955 port, LINK_DELAYf, (uint32)link_delay)); 4956 } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) { 4957 BCM_IF_ERROR_RETURN( 4958 soc_reg_above_64_field32_modify(unit, EGR_1588_LINK_DELAY_64r, 4959 port, 0, LINK_DELAYf, (uint32)link_delay)); 4960 } else { 4961 /* No LINK_DELAY register, so no-op */ 4962 } 4963 4964 return BCM_E_NONE; 4965 } 4966 4967 STATIC int 4968 _bcm_esw_port_link_delay_recover(int unit, bcm_port_t port, int speed) 4969 { 4970 uint32 link_delay = 0; 4971 uint32 mac_rx_latency = 0; 4972 4973 mac_rx_latency = soc_property_port_get(unit, port, spn_LINK_DELAY(speed), mac_rx_latency); 4974 4975 if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) { 4976 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, EGR_1588_LINK_DELAYr, port, LINK_DELAYf, &link_delay)); 4977 } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) { 4978 SOC_IF_ERROR_RETURN(soc_reg_above_64_field32_read(unit, EGR_1588_LINK_DELAY_64r, 4979 port, 0, LINK_DELAYf, &link_delay)); 4980 } 4981 4982 PORT(unit, port).link_delay_offset = link_delay - mac_rx_latency; 4983 4984 return BCM_E_NONE; 4985 } 4986 4987 /* 4988 * Function: 4989 * _bcm_port_info_get 4990 * Description: 4991 * Helper funtion 4992 * Parameters: 4993 * unit - (IN) BCM device number 4994 * port - (IN) Port number 4995 * pinfo - (OUT) Port info. 4996 * Return Value: 4997 * BCM_E_XXX 4998 */ 4999 int 5000 _bcm_port_info_get(int unit, bcm_port_t port, _bcm_port_info_t **pinfo) 5001 { 5002 /* Input parameters check. */ 5003 if (NULL == pinfo) { 5004 return (BCM_E_PARAM); 5005 } 5006 5007 PORT_INIT(unit); 5008 5009 *pinfo = &PORT(unit, port); 5010 return (BCM_E_NONE); 5011 } 5012 5013 /* 5014 * Function: 5015 * _bcm_esw_iport_tab_set 5016 * Description: 5017 * Set field in either IPORT_TABLE or the special CPU Higig entry in 5018 * the PORT_TAB. 5019 * Parameters: 5020 * unit - Device number 5021 * port - Port number 5022 * field - Field name within PORT_TAB table entry 5023 * value - new field value 5024 * Return Value: 5025 * BCM_E_NONE 5026 * BCM_E_XXX - an error occurred accessing PORT_TAB table. 5027 */ 5028 int 5029 _bcm_esw_iport_tab_set(int unit, bcm_port_t port, 5030 soc_field_t field, int value) 5031 5032 { 5033 port_tab_entry_t pent; 5034 soc_mem_t mem; 5035 int rv, index, cpu_hg_index, cur_val; 5036 5037 cpu_hg_index = SOC_IS_KATANA2(unit) ? 5038 SOC_INFO(unit).cpu_hg_pp_port_index : 5039 SOC_INFO(unit).cpu_hg_index; 5040 5041 if (SOC_MEM_IS_VALID(unit, IPORT_TABLEm)) { 5042 mem = IPORT_TABLEm; 5043 index = SOC_PORT_MOD_OFFSET(unit, port); 5044 } else if (IS_CPU_PORT(unit, port) && cpu_hg_index != -1) { 5045 mem = PORT_TABm; 5046 index = cpu_hg_index; 5047 } else { 5048 return BCM_E_NONE; 5049 } 5050 5051 if (!SOC_MEM_FIELD_VALID(unit, mem, field)) { 5052 return (BCM_E_UNAVAIL); 5053 } 5054 5055 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &pent); 5056 if (BCM_SUCCESS(rv)) { 5057 cur_val = soc_mem_field32_get(unit, mem, &pent, field); 5058 if (value != cur_val) { 5059 soc_mem_field32_set(unit, mem, &pent, field, value); 5060 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &pent); 5061 } 5062 } 5063 return rv; 5064 } 5065 5066 /* 5067 * Function: 5068 * _bcm_phy_cb_xlate_port 5069 * Description: 5070 * Provides port translation for API call-backs 5071 * Parameter: 5072 * unit -- unit number 5073 * port -- port number to be translated 5074 * Returns: 5075 * SOC_E_xxx 5076 */ 5077 STATIC int 5078 _bcm_phy_cb_xlate_port(int unit, int *port) 5079 { 5080 BCM_API_XLATE_PORT_P2A(unit, port); 5081 5082 return BCM_E_NONE; 5083 } 5084 5085 /* 5086 * Function: 5087 * _bcm_port_autoneg_advert_remote_get 5088 * Purpose: 5089 * Main part of bcm_port_advert_get_remote 5090 */ 5091 5092 STATIC int 5093 _bcm_port_autoneg_advert_remote_get(int unit, bcm_port_t port, 5094 bcm_port_ability_t *ability_mask) 5095 { 5096 int an, an_done; 5097 5098 if(bcm_common_oamp_port_enable_get(unit, port)) { 5099 LOG_ERROR(BSL_LS_BCM_PORT, 5100 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 5101 port)); 5102 return BCM_E_PARAM; 5103 } 5104 5105 SOC_IF_ERROR_RETURN 5106 (soc_phyctrl_auto_negotiate_get(unit, port, 5107 &an, &an_done)); 5108 5109 if (an && an_done) { 5110 SOC_IF_ERROR_RETURN 5111 (soc_phyctrl_ability_remote_get(unit, port, ability_mask)); 5112 } 5113 5114 return BCM_E_NONE; 5115 } 5116 5117 /* 5118 * Function: 5119 * _bcm_port_ability_local_get 5120 * Purpose: 5121 * Main part of bcm_port_ability_local_get 5122 */ 5123 5124 STATIC int 5125 _bcm_port_ability_local_get(int unit, bcm_port_t port, 5126 bcm_port_ability_t *ability_mask) 5127 { 5128 soc_port_ability_t mac_ability, phy_ability; 5129 soc_pa_encap_t encap_ability; 5130 #ifdef BCM_TRIUMPH3_SUPPORT 5131 int lanes; 5132 #endif 5133 #ifdef INCLUDE_MACSEC 5134 phy_ctrl_t *ext_pc; 5135 ext_pc = EXT_PHY_SW_STATE(unit, port); 5136 #endif /* INCLUDE_MACSEC */ 5137 sal_memset(&phy_ability, 0, sizeof(soc_port_ability_t)); 5138 sal_memset(&mac_ability, 0, sizeof(soc_port_ability_t)); 5139 5140 if(bcm_common_oamp_port_enable_get(unit, port)) { 5141 LOG_ERROR(BSL_LS_BCM_PORT, 5142 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 5143 port)); 5144 return BCM_E_PARAM; 5145 } 5146 5147 SOC_IF_ERROR_RETURN 5148 (soc_phyctrl_ability_local_get(unit, port, &phy_ability)); 5149 5150 if (!(IS_TDM_PORT(unit, port))) { 5151 SOC_IF_ERROR_RETURN 5152 (MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit, 5153 port, &mac_ability)); 5154 } 5155 5156 /* Combine MAC and PHY abilities */ 5157 5158 #ifdef INCLUDE_MACSEC 5159 /* 5160 MACSEC phys have their own MAC. If macsec is enabled, 5161 phy's MAC is used for MAC operation on the line side. 5162 Check added to use half duplex ability of phy/MAC. 5163 */ 5164 if((NULL != ext_pc) && ext_pc->macsec_enable) { 5165 ability_mask->speed_half_duplex = phy_ability.speed_half_duplex; 5166 } else 5167 #endif /* INCLUDE_MACSEC */ 5168 { 5169 ability_mask->speed_half_duplex = 5170 mac_ability.speed_half_duplex & phy_ability.speed_half_duplex; 5171 } 5172 ability_mask->speed_full_duplex = 5173 mac_ability.speed_full_duplex & phy_ability.speed_full_duplex; 5174 ability_mask->pause = mac_ability.pause & phy_ability.pause; 5175 if (phy_ability.interface == 0) { 5176 ability_mask->interface = mac_ability.interface; 5177 } else { 5178 ability_mask->interface = phy_ability.interface; 5179 } 5180 ability_mask->medium = phy_ability.medium; 5181 ability_mask->channel = phy_ability.channel; 5182 ability_mask->fec = phy_ability.fec; 5183 /* mac_ability.eee without phy_ability.eee makes no sense */ 5184 ability_mask->eee = phy_ability.eee; 5185 ability_mask->loopback = mac_ability.loopback | phy_ability.loopback | 5186 BCM_PORT_ABILITY_LB_NONE; 5187 ability_mask->flags = mac_ability.flags | phy_ability.flags; 5188 5189 /* Get port encapsulation ability */ 5190 encap_ability = mac_ability.encap; 5191 5192 if ((soc_feature(unit, soc_feature_embedded_higig)) 5193 && IS_E_PORT(unit, port)) { 5194 encap_ability |= BCM_PA_ENCAP_HIGIG2_L2; 5195 encap_ability |= BCM_PA_ENCAP_HIGIG2_IP_GRE; 5196 } 5197 5198 #if defined(BCM_RAPTOR_SUPPORT) 5199 if ((SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit)) && 5200 IS_S_PORT(unit, port)) { 5201 encap_ability |= BCM_PA_ENCAP_HIGIG2; 5202 /* should be HiGig-Lite, not Higig2 */ 5203 encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE; 5204 } 5205 #endif 5206 5207 #ifdef BCM_TRIUMPH2_SUPPORT 5208 if (IS_HL_PORT(unit, port) && (SOC_IS_APOLLO(unit) || 5209 SOC_IS_TRIUMPH2(unit) || 5210 SOC_IS_VALKYRIE2(unit))) { 5211 /* HiGig-Lite port */ 5212 encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE; 5213 } 5214 #endif 5215 5216 if (IS_HL_PORT(unit, port) && 5217 (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) || 5218 SOC_IS_KATANA2(unit) )) { 5219 encap_ability |= BCM_PA_ENCAP_HIGIG2; 5220 /* should be HiGig-Lite, not Higig2 */ 5221 encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE; 5222 } 5223 5224 #ifdef BCM_GREYHOUND_SUPPORT 5225 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 5226 SOC_IS_GREYHOUND2(unit)) { 5227 if (IS_HL_PORT(unit, port)) { 5228 encap_ability |= BCM_PA_ENCAP_HIGIG2; 5229 encap_ability |= BCM_PA_ENCAP_HIGIG2_LITE; 5230 } else if (IS_HG_PORT(unit, port)) { 5231 encap_ability |= BCM_PA_ENCAP_HIGIG; 5232 } 5233 } 5234 #endif /* BCM_GREYHOUND_SUPPORT */ 5235 5236 #if defined (BCM_HURRICANE_SUPPORT) 5237 if (IS_XQ_PORT(unit, port) && SOC_IS_HURRICANEX(unit) && (CMDEV(unit).dev.rev_id == BCM56142_A0_REV_ID) ) { 5238 ability_mask->speed_half_duplex &= ~(BCM_PORT_ABILITY_100MB); 5239 ability_mask->speed_full_duplex &= ~(BCM_PORT_ABILITY_100MB); 5240 } 5241 #endif 5242 5243 #if defined (BCM_TRIUMPH3_SUPPORT) 5244 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) && 5245 (_tr3_port_config_id[unit] == 112 || _tr3_port_config_id[unit] == 12) && 5246 (port == 54 || port == 55)) { 5247 if (IS_XE_PORT(unit, port)) { 5248 BCM_IF_ERROR_RETURN(_bcm_tr3_port_lanes_get(unit, port, &lanes)); 5249 if (lanes == 1) { 5250 /* In one lanes mode, only support 100Mbps */ 5251 ability_mask->speed_full_duplex = (BCM_PORT_ABILITY_100MB); 5252 } else if (lanes == 4) { 5253 /* In four lanes mode, remove the 100Mbps ability */ 5254 ability_mask->speed_full_duplex &= ~(BCM_PORT_ABILITY_100MB); 5255 } 5256 } 5257 } 5258 #endif 5259 5260 #ifdef BCM_SABER2_SUPPORT 5261 if (SOC_IS_SABER2(unit)) { 5262 if (IS_XE_PORT(unit, port) && IS_MXQ_PORT(unit, port)) { 5263 /* XE port, only support 10Gbps */ 5264 ability_mask->speed_full_duplex = (BCM_PORT_ABILITY_10GB); 5265 } 5266 } 5267 #endif 5268 5269 ability_mask->encap = encap_ability; 5270 return BCM_E_NONE; 5271 } 5272 5273 int 5274 bcm_esw_port_lport_prof_src_check(int unit, int port_type, int *src_tbl_is_stm) 5275 { 5276 int rv = BCM_E_NONE; 5277 #if defined(CANCUN_SUPPORT) 5278 if (soc_feature(unit, soc_feature_cancun)) { 5279 if (src_tbl_is_stm != NULL) { 5280 switch (port_type) { 5281 case _BCM_ESW_PT_COE: 5282 case _BCM_ESW_PT_HGPROXY: 5283 *src_tbl_is_stm = 1; 5284 break; 5285 default: 5286 *src_tbl_is_stm = 0; 5287 break; 5288 } 5289 } 5290 } 5291 #endif 5292 return rv; 5293 } 5294 5295 #ifdef BCM_TRIUMPH2_SUPPORT 5296 /* 5297 * Function: 5298 * bcm_esw_port_lport_profile_recover 5299 * Description: 5300 * Recovers the LPORT profile reference count in the 5301 * Source Trunk Map Table. 5302 * Parameters: 5303 * unit - (IN) Device number 5304 * Return Value: 5305 * BCM_E_NONE 5306 * BCM_E_XXX 5307 * Note: 5308 * - Called when LPORT profile is supported. 5309 */ 5310 STATIC int 5311 bcm_esw_port_lport_profile_recover(int unit) 5312 { 5313 int rv = BCM_E_NONE; 5314 #ifdef BCM_TOMAHAWK3_SUPPORT 5315 int entries_per_pipe; 5316 #endif 5317 #if defined(BCM_TRX_SUPPORT) 5318 int i, m; 5319 uint32 lport_index; 5320 soc_mem_t src_mem[2] = {SOURCE_TRUNK_MAP_TABLEm, INVALIDm}; 5321 int entry_count; 5322 int table_sz; 5323 uint32 *src_table; 5324 uint32 *src_entry; 5325 uint32 rtag7_index; 5326 lport_tab_entry_t lport_entry; 5327 5328 /* Make sure port module is initialized. */ 5329 PORT_INIT(unit); 5330 5331 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 5332 src_mem[1] = ING_DEVICE_PORTm; 5333 } 5334 5335 for (m = 0; m < 2; m++) { 5336 if (src_mem[m] == INVALIDm) { 5337 continue; 5338 } 5339 5340 /* Alloc DMA memory */ 5341 entry_count = soc_mem_index_count(unit, src_mem[m]); 5342 table_sz = SOC_MEM_TABLE_BYTES(unit, src_mem[m]); 5343 src_table = soc_cm_salloc(unit, table_sz, "LPORT index recover\n"); 5344 if (src_table == NULL) { 5345 return BCM_E_MEMORY; 5346 } 5347 sal_memset(src_table, 0, table_sz); 5348 5349 /* DMA Read */ 5350 rv = soc_mem_read_range(unit, src_mem[m], MEM_BLOCK_ANY, 5351 soc_mem_index_min(unit, src_mem[m]), 5352 soc_mem_index_max(unit, src_mem[m]), 5353 src_table); 5354 /* Recover LPORT index reference count from Source Trunk Map table */ 5355 if (BCM_SUCCESS(rv)) { 5356 for (i = 0; i < entry_count; i++) { 5357 src_entry = 5358 soc_mem_table_idx_to_pointer(unit, src_mem[m], void *, 5359 src_table, i); 5360 lport_index = soc_mem_field32_get(unit, src_mem[m], src_entry, 5361 LPORT_PROFILE_IDXf); 5362 5363 if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) { 5364 rv = _bcm_lport_ind_profile_mem_reference(unit, lport_index, 1); 5365 if (BCM_FAILURE(rv)) { 5366 break; 5367 } 5368 rv = READ_LPORT_TABm(unit, MEM_BLOCK_ANY, lport_index, &lport_entry); 5369 if (BCM_FAILURE(rv)) { 5370 break; 5371 } 5372 rtag7_index = soc_LPORT_TABm_field32_get( 5373 unit, &lport_entry, RTAG7_PORT_PROFILE_INDEXf); 5374 rv = _bcm_rtag7_ind_profile_mem_reference(unit, rtag7_index, 1); 5375 5376 } else { 5377 #ifdef BCM_TOMAHAWK3_SUPPORT 5378 if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 5379 entries_per_pipe = SOC_MEM_SIZE(unit, LPORT_TABm); 5380 rv = _bcm_lport_profile_mem_reference_unique(unit, lport_index, 5381 1, i/entries_per_pipe); 5382 } else 5383 #endif 5384 { 5385 rv = _bcm_lport_profile_mem_reference(unit, lport_index, 1); 5386 } 5387 } 5388 if (BCM_FAILURE(rv)) { 5389 break; 5390 } 5391 } 5392 } 5393 5394 soc_cm_sfree(unit, src_table); 5395 if (BCM_FAILURE(rv)) { 5396 break; 5397 } 5398 } 5399 5400 #endif /* BCM_TRX_SUPPORT */ 5401 5402 return rv; 5403 } 5404 5405 STATIC int 5406 _bcm_td3_port_egr_lport_profile_recover(int unit) 5407 { 5408 int rv = BCM_E_NONE; 5409 int i, m; 5410 uint32 egr_lport_index; 5411 soc_mem_t ep_mem[2] = {EGR_GPP_ATTRIBUTESm, INVALIDm}; 5412 int ega_num_entries; 5413 int ega_table_size; 5414 void *ep_tbl; 5415 void *ep_ent; 5416 5417 /* Make sure port module is initialized. */ 5418 PORT_INIT(unit); 5419 5420 if (SOC_IS_TRIDENT3X(unit)) { 5421 ep_mem[1] = EGR_PORTm; 5422 } 5423 5424 /* Alloc DMA memory */ 5425 for (m = 0; m < 2; m++) { 5426 if (ep_mem[m] == INVALIDm) { 5427 continue; 5428 } 5429 ega_num_entries = soc_mem_index_count(unit, ep_mem[m]); 5430 ega_table_size = soc_mem_entry_words(unit, ep_mem[m]) * 4 * ega_num_entries; 5431 ep_tbl = soc_cm_salloc(unit, ega_table_size, 5432 "EGA for EGR LPORT index recover\n"); 5433 if (ep_tbl == NULL) { 5434 return BCM_E_MEMORY; 5435 } 5436 sal_memset(ep_tbl, 0, ega_table_size); 5437 5438 /* DMA Read */ 5439 rv = soc_mem_read_range(unit, ep_mem[m], MEM_BLOCK_ANY, 5440 soc_mem_index_min(unit, ep_mem[m]), 5441 soc_mem_index_max(unit, ep_mem[m]), 5442 ep_tbl); 5443 /* Recover EGR LPORT index reference count from EGR GPP Attributes table */ 5444 if (SOC_SUCCESS(rv)) { 5445 for (i = 0; i < ega_num_entries; i++) { 5446 ep_ent = 5447 soc_mem_table_idx_to_pointer(unit, ep_mem[m], 5448 void *, ep_tbl, i); 5449 egr_lport_index = 5450 soc_mem_field32_get(unit, ep_mem[m], ep_ent, EGR_LPORT_PROFILE_IDXf); 5451 rv = _bcm_egr_lport_profile_mem_reference(unit, egr_lport_index, 1); 5452 if (BCM_FAILURE(rv)) { 5453 break; 5454 } 5455 } 5456 } 5457 5458 soc_cm_sfree(unit, ep_tbl); 5459 5460 if (BCM_FAILURE(rv)) { 5461 break; 5462 } 5463 } 5464 5465 return rv; 5466 } 5467 5468 /* 5469 * Function: 5470 * bcm_esw_port_egr_lport_profile_recover 5471 * Description: 5472 * Recovers the EGR LPORT profile reference count in the 5473 * EGR GPP Attributes Table. 5474 * Parameters: 5475 * unit - (IN) Device number 5476 * Return Value: 5477 * BCM_E_NONE 5478 * BCM_E_XXX 5479 * Note: 5480 * - Called when EGR LPORT profile is supported. 5481 */ 5482 STATIC int 5483 bcm_esw_port_egr_lport_profile_recover(int unit) 5484 { 5485 int rv = BCM_E_NONE; 5486 int i; 5487 uint32 egr_lport_index; 5488 soc_mem_t ega_mem; 5489 int ega_num_entries; 5490 int ega_table_size; 5491 egr_gpp_attributes_entry_t *ega_table; 5492 egr_gpp_attributes_entry_t *ega_entry; 5493 5494 /* Make sure port module is initialized. */ 5495 PORT_INIT(unit); 5496 5497 if (SOC_IS_TRIDENT3X(unit)) { 5498 return _bcm_td3_port_egr_lport_profile_recover(unit); 5499 } 5500 5501 /* Alloc DMA memory */ 5502 ega_mem = EGR_GPP_ATTRIBUTESm; 5503 ega_num_entries = soc_mem_index_count(unit, ega_mem); 5504 ega_table_size = sizeof(egr_gpp_attributes_entry_t ) * ega_num_entries; 5505 ega_table = soc_cm_salloc(unit, ega_table_size, 5506 "EGA for EGR LPORT index recover\n"); 5507 if (ega_table == NULL) { 5508 return BCM_E_MEMORY; 5509 } 5510 sal_memset(ega_table, 0, ega_table_size); 5511 5512 /* DMA Read */ 5513 rv = soc_mem_read_range(unit, ega_mem, MEM_BLOCK_ANY, 5514 soc_mem_index_min(unit, ega_mem), 5515 soc_mem_index_max(unit, ega_mem), 5516 ega_table); 5517 5518 /* Recover EGR LPORT index reference count from EGR GPP Attributes table */ 5519 if (SOC_SUCCESS(rv)) { 5520 for (i = 0; i < ega_num_entries; i++) { 5521 ega_entry = 5522 soc_mem_table_idx_to_pointer(unit, ega_mem, 5523 egr_gpp_attributes_entry_t *, 5524 ega_table, i); 5525 egr_lport_index = 5526 soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, ega_entry, 5527 EGR_LPORT_PROFILE_IDXf); 5528 rv = _bcm_egr_lport_profile_mem_reference(unit, egr_lport_index, 1); 5529 if (BCM_FAILURE(rv)) { 5530 break; 5531 } 5532 } 5533 } 5534 5535 soc_cm_sfree(unit, ega_table); 5536 5537 return rv; 5538 } 5539 #endif /* BCM_TRIUMPH2_SUPPORT */ 5540 5541 int 5542 bcm_esw_port_egr_lport_prof_src_get(int unit, 5543 bcm_module_t modid, bcm_port_t port, int *src_tbl_is_gpp) 5544 { 5545 int rv = BCM_E_NONE; 5546 5547 #if defined(CANCUN_SUPPORT) 5548 bcm_gport_t gport; 5549 5550 if (soc_feature(unit, soc_feature_cancun)) { 5551 soc_mem_t pfs_mem = EGR_PKT_FLOW_SELECT_TCAMm; 5552 5553 gport = _bcm_esw_port_gport_get_from_modport(unit, modid, port); 5554 /* COE flows use the port attrs from the EGR_GPP_ATTRIBUTES 5555 table, rest all flows use the EGR_PORT table */ 5556 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) { 5557 *src_tbl_is_gpp = 1; 5558 } else if (SOC_MEM_IS_VALID(unit, pfs_mem)) { 5559 *src_tbl_is_gpp = 0; 5560 } 5561 } 5562 #endif 5563 5564 return rv; 5565 } 5566 5567 #if defined(BCM_TRX_SUPPORT) 5568 /* 5569 * Function: 5570 * bcm_esw_port_separate_lport_rtag7_profile_fields_set 5571 * Description: 5572 * Sets the fields in the LPORT Profile Table and updates 5573 * the corresponding reference index in the Source Trunk Map Table. 5574 * Parameters: 5575 * unit - (IN) Device number 5576 * modid - (IN) Module number for port 5577 * port - (IN) Port number (NON gport) 5578 * table_id - (IN) Index of table to modify, LPORT or RTAG7 5579 * field_count - (IN) Number of fields to modify 5580 * fields - (IN) Array of fields to modify 5581 * values - (IN) Array of new field values 5582 * Return Value: 5583 * BCM_E_NONE 5584 * BCM_E_XXX 5585 * Note: 5586 * - Assumes: lock, 5587 * valid bcm module id and port number, 5588 * valid table id, 5589 * valid HW fields. 5590 * - Called when LPORT profile is supported. 5591 * - Helper routine for bcm_esw_port_lport_fields_set(); 5592 * callers should be calling bcm_esw_port_lport_fields_set() instead. 5593 */ 5594 STATIC int 5595 bcm_esw_port_separate_lport_rtag7_profile_fields_set(int unit, int port_type, 5596 bcm_module_t modid, bcm_port_t port, 5597 int table_id, int field_count, 5598 soc_field_t *fields, uint32 *values) 5599 { 5600 int i, rv; 5601 int src_index; 5602 uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS]; 5603 lport_tab_entry_t lport_entry; 5604 rtag7_port_based_hash_entry_t rtag7_entry; 5605 uint32 lport_index, rtag7_index, old_lport_index, old_rtag7_index = 0; 5606 soc_mem_t mem; 5607 void *entries[2], *entry; 5608 5609 int src_tbl_is_stm = 1; 5610 soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm; 5611 5612 /* Make sure port module is initialized. */ 5613 PORT_INIT(unit); 5614 5615 BCM_IF_ERROR_RETURN 5616 (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm)); 5617 if (!src_tbl_is_stm) { 5618 src_mem = ING_DEVICE_PORTm; 5619 } 5620 5621 soc_mem_lock(unit, src_mem); 5622 5623 if (src_tbl_is_stm) { 5624 rv = _bcm_esw_src_mod_port_table_index_get(unit, modid, port, 5625 &src_index); 5626 if(BCM_FAILURE(rv)) { 5627 soc_mem_unlock(unit, src_mem); 5628 return rv; 5629 } 5630 } else { 5631 src_index = port; 5632 } 5633 5634 rv = soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent); 5635 if(BCM_FAILURE(rv)) { 5636 soc_mem_unlock(unit, src_mem); 5637 return rv; 5638 } 5639 5640 old_lport_index = 5641 soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf); 5642 5643 if (table_id == LPORT_PROFILE_RTAG7_TAB) { 5644 5645 /* Get the associated LPORT entry */ 5646 rv = READ_LPORT_TABm(unit, MEM_BLOCK_ANY, old_lport_index, 5647 &lport_entry); 5648 if(BCM_FAILURE(rv)) { 5649 soc_mem_unlock(unit, src_mem); 5650 return rv; 5651 } 5652 5653 /* Get the current RTAG7 index from there */ 5654 old_rtag7_index = 5655 soc_LPORT_TABm_field32_get(unit, &lport_entry, 5656 RTAG7_PORT_PROFILE_INDEXf); 5657 } 5658 5659 if (table_id == LPORT_PROFILE_LPORT_TAB) { 5660 entries[0] = &lport_entry; 5661 rv = _bcm_lport_ind_profile_entry_get(unit, old_lport_index, 5662 1, entries); 5663 } else { 5664 entries[0] = &rtag7_entry; 5665 rv = _bcm_rtag7_ind_profile_entry_get(unit, old_rtag7_index, 5666 1, entries); 5667 } 5668 5669 if(BCM_FAILURE(rv)) { 5670 soc_mem_unlock(unit, src_mem); 5671 return rv; 5672 } 5673 5674 /* Update fields */ 5675 entry = entries[0]; 5676 if (table_id == LPORT_PROFILE_LPORT_TAB) { 5677 mem = LPORT_TABm; 5678 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 5679 mem = RTAG7_PORT_BASED_HASHm; 5680 } else { 5681 soc_mem_unlock(unit, src_mem); 5682 return BCM_E_INTERNAL; 5683 } 5684 5685 for (i = 0; i < field_count; i++) { 5686 soc_mem_field32_set(unit, mem, entry, fields[i], values[i]); 5687 } 5688 5689 /* Note that when 'soc_feature_separate_ing_lport_rtag7_profiling' is in 5690 effect, the LPORT and RTAG7 tables are profiled separately, due to which 5691 we will be making separate calls and not a generic single call like 5692 earlier */ 5693 if (table_id == LPORT_PROFILE_LPORT_TAB) { 5694 5695 #ifdef BCM_MONTEREY_SUPPORT 5696 if (SOC_IS_MONTEREY(unit)) { 5697 soc_mem_field32_set(unit, mem, entry, MISC_PORT_PROFILE_INDEXf, port); 5698 } 5699 #endif 5700 5701 rv = _bcm_lport_ind_profile_entry_add(unit, entries, 1, &lport_index); 5702 5703 } else { 5704 rv = _bcm_rtag7_ind_profile_entry_add(unit, entries, 1, &rtag7_index); 5705 } 5706 5707 if(BCM_FAILURE(rv)) { 5708 soc_mem_unlock(unit, src_mem); 5709 return rv; 5710 } 5711 5712 if (table_id == LPORT_PROFILE_LPORT_TAB) { 5713 /* Update Source Table LPORT profile index */ 5714 soc_mem_field32_set(unit, src_mem, src_ent, LPORT_PROFILE_IDXf, 5715 lport_index); 5716 rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL, src_index, src_ent); 5717 } else { 5718 /* Write to the LPORT table here */ 5719 soc_LPORT_TABm_field32_set(unit, &lport_entry, RTAG7_PORT_PROFILE_INDEXf, 5720 rtag7_index); 5721 if (SOC_IS_TRIDENT3X(unit)) { 5722 entries[0] = &lport_entry; 5723 rv = _bcm_lport_ind_profile_entry_add(unit, entries, 1, &lport_index); 5724 5725 if(BCM_FAILURE(rv)) { 5726 soc_mem_unlock(unit, src_mem); 5727 return rv; 5728 } 5729 /* Update Source Table LPORT profile index */ 5730 soc_mem_field32_set(unit, src_mem, src_ent, LPORT_PROFILE_IDXf, 5731 lport_index); 5732 rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL, 5733 src_index, src_ent); 5734 } else { 5735 rv = WRITE_LPORT_TABm(unit, MEM_BLOCK_ANY, old_lport_index, &lport_entry); 5736 } 5737 } 5738 5739 soc_mem_unlock(unit, src_mem); 5740 if(BCM_FAILURE(rv)) { 5741 return rv; 5742 } 5743 5744 /* 5745 * Entry must be 'deleted' because the mem profile 'add' routine 5746 * always increments count even though the same entry is used. 5747 */ 5748 if (table_id == LPORT_PROFILE_LPORT_TAB) { 5749 BCM_IF_ERROR_RETURN 5750 (_bcm_lport_ind_profile_entry_delete(unit, old_lport_index)); 5751 5752 } else { 5753 if (SOC_IS_TRIDENT3X(unit)) { 5754 BCM_IF_ERROR_RETURN 5755 (_bcm_lport_ind_profile_entry_delete(unit, old_lport_index)); 5756 } 5757 BCM_IF_ERROR_RETURN 5758 (_bcm_rtag7_ind_profile_entry_delete(unit, old_rtag7_index)); 5759 } 5760 5761 return BCM_E_NONE; 5762 } 5763 #endif /* BCM_TRX_SUPPORT */ 5764 5765 /* 5766 * Function: 5767 * bcm_esw_port_lport_profile_fields_set 5768 * Description: 5769 * Sets the fields in the LPORT Profile Table and updates 5770 * the corresponding reference index in the Source Trunk Map Table. 5771 * Parameters: 5772 * unit - (IN) Device number 5773 * modid - (IN) Module number for port 5774 * port - (IN) Port number (NON gport) 5775 * table_id - (IN) Index of table to modify, LPORT or RTAG7 5776 * field_count - (IN) Number of fields to modify 5777 * fields - (IN) Array of fields to modify 5778 * values - (IN) Array of new field values 5779 * Return Value: 5780 * BCM_E_NONE 5781 * BCM_E_XXX 5782 * Note: 5783 * - Assumes: lock, 5784 * valid bcm module id and port number, 5785 * valid table id, 5786 * valid HW fields. 5787 * - Called when LPORT profile is supported. 5788 * - Helper routine for bcm_esw_port_lport_fields_set(); 5789 * callers should be calling bcm_esw_port_lport_fields_set() instead. 5790 */ 5791 STATIC int 5792 bcm_esw_port_lport_profile_fields_set(int unit, int port_type, 5793 bcm_module_t modid, bcm_port_t port, 5794 int table_id, int field_count, 5795 soc_field_t *fields, uint32 *values) 5796 { 5797 #if defined(BCM_TRX_SUPPORT) 5798 int i; 5799 int src_index; 5800 uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS]; 5801 int src_tbl_is_stm = 1; 5802 soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm; 5803 lport_tab_entry_t lport_entry; 5804 rtag7_port_based_hash_entry_t rtag7_entry; 5805 uint32 lport_index, old_lport_index; 5806 void *entries[2]; 5807 soc_mem_t mem; 5808 void *entry; 5809 int rv; 5810 int pipe = 0; 5811 int num_entries_per_pipe = 0; 5812 5813 if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) { 5814 return bcm_esw_port_separate_lport_rtag7_profile_fields_set(unit, 5815 port_type, modid, port, table_id, field_count, 5816 fields, values); 5817 } 5818 5819 /* Make sure port module is initialized. */ 5820 PORT_INIT(unit); 5821 5822 BCM_IF_ERROR_RETURN 5823 (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm)); 5824 #if defined(CANCUN_SUPPORT) 5825 if (soc_feature(unit, soc_feature_cancun) && src_tbl_is_stm == 0) { 5826 src_mem = ING_DEVICE_PORTm; 5827 } 5828 #endif 5829 5830 soc_mem_lock(unit, src_mem); 5831 5832 /* Get LPORT profile index Source table */ 5833 if (src_tbl_is_stm) { 5834 rv = _bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index); 5835 if(BCM_FAILURE(rv)) { 5836 soc_mem_unlock(unit, src_mem); 5837 return rv; 5838 } 5839 } else { 5840 src_index = port; 5841 } 5842 5843 rv = soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent); 5844 if(BCM_FAILURE(rv)) { 5845 soc_mem_unlock(unit, src_mem); 5846 return rv; 5847 } 5848 5849 old_lport_index = 5850 soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf); 5851 5852 /* Get LPORT profile entry */ 5853 entries[0] = &lport_entry; 5854 entries[1] = &rtag7_entry; 5855 5856 /* Tomahawk 3 split this memory into a per pipe unique access, 5857 * so it is indexed in SOURCE_TRUNK_MAP on a per pipe basis */ 5858 if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 5859 pipe = SOC_INFO(unit).port_pipe[src_index]; 5860 mem = SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)[pipe]; 5861 num_entries_per_pipe = SOC_MEM_SIZE(unit, mem); 5862 5863 /* the profile cache is stored in one large logical table (all the pipes 5864 * put together), so we need to index into the pipe being used so that 5865 * we can access the index of that one big logical table */ 5866 old_lport_index += pipe*num_entries_per_pipe; 5867 } 5868 5869 rv = _bcm_lport_profile_entry_get(unit, old_lport_index, 1, entries); 5870 if(BCM_FAILURE(rv)) { 5871 soc_mem_unlock(unit, src_mem); 5872 return rv; 5873 } 5874 5875 /* Update fields */ 5876 if (table_id == LPORT_PROFILE_LPORT_TAB) { 5877 mem = LPORT_TABm; 5878 entry = entries[0]; 5879 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 5880 mem = RTAG7_PORT_BASED_HASHm; 5881 entry = entries[1]; 5882 } else { 5883 soc_mem_unlock(unit, src_mem); 5884 return BCM_E_INTERNAL; 5885 } 5886 5887 for (i = 0; i < field_count; i++) { 5888 soc_mem_field32_set(unit, mem, entry, fields[i], values[i]); 5889 } 5890 5891 /* Tomahawk 3 split this memory into a per pipe unique access, 5892 * so it must be handled differently */ 5893 if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 5894 /* Restore the old_lport_index to its per pipe index because the call 5895 * below to entry_add_unique will get its lport_index based on a per 5896 * pipe index and they will be compared. */ 5897 old_lport_index -= pipe*num_entries_per_pipe; 5898 5899 rv = _bcm_lport_profile_entry_add_unique(unit, entries, 1, pipe, &lport_index); 5900 } else { 5901 rv = _bcm_lport_profile_entry_add(unit, entries, 1, &lport_index); 5902 } 5903 if(BCM_FAILURE(rv)) { 5904 soc_mem_unlock(unit, src_mem); 5905 return rv; 5906 } 5907 5908 /* Update STM LPORT profile index */ 5909 if (old_lport_index != lport_index) { 5910 soc_mem_field32_set(unit, src_mem, src_ent, 5911 LPORT_PROFILE_IDXf, lport_index); 5912 rv = soc_mem_write(unit, src_mem, MEM_BLOCK_ALL, 5913 src_index, src_ent); 5914 } 5915 5916 soc_mem_unlock(unit, src_mem); 5917 if(BCM_FAILURE(rv)) { 5918 return rv; 5919 } 5920 5921 /* 5922 * Entry must be 'deleted' because the mem profile 'add' routine 5923 * always increments count even though the same entry is used. 5924 */ 5925 if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 5926 BCM_IF_ERROR_RETURN 5927 (_bcm_lport_profile_entry_delete_unique(unit, old_lport_index, pipe)); 5928 } else { 5929 BCM_IF_ERROR_RETURN 5930 (_bcm_lport_profile_entry_delete(unit, old_lport_index)); 5931 } 5932 5933 return BCM_E_NONE; 5934 #else 5935 return BCM_E_UNAVAIL; 5936 #endif /* BCM_TRX_SUPPORT */ 5937 } 5938 5939 /* 5940 * Function: 5941 * bcm_esw_port_egr_lport_profile_fields_set 5942 * Description: 5943 * Sets the fields in the EGR_LPORT Profile Table and updates 5944 * the corresponding reference index in the Source Trunk Map Table. 5945 * Parameters: 5946 * unit - (IN) Device number 5947 * modid - (IN) Module number for port 5948 * port - (IN) Port number (NON gport) 5949 * mem - (IN) Table to modify 5950 * field_count - (IN) Number of fields to modify 5951 * fields - (IN) Array of fields to modify 5952 * values - (IN) Array of new field values 5953 * Return Value: 5954 * BCM_E_NONE 5955 * BCM_E_XXX 5956 * Note: 5957 * - Assumes: lock, 5958 * valid bcm module id and port number, 5959 * valid table id, 5960 * valid HW fields. 5961 * - Called when EGR_LPORT profile is supported. 5962 * - Helper routine for bcm_esw_port_egr_lport_fields_set(); 5963 * callers should be calling bcm_esw_port_egr_lport_fields_set() instead. 5964 */ 5965 STATIC int 5966 bcm_esw_port_egr_lport_profile_fields_set(int unit, 5967 bcm_module_t modid, bcm_port_t port, 5968 soc_mem_t mem, int field_count, 5969 soc_field_t *fields, uint32 *values) 5970 { 5971 #if defined(BCM_TRX_SUPPORT) 5972 int i, index; 5973 int egr_gpp_index = 0; 5974 egr_gpp_attributes_entry_t egr_gpp_entry; 5975 egr_lport_profile_entry_t egr_lport_entry; 5976 egr_vlan_control_1_entry_t egr_vlan_control_1; 5977 egr_vlan_control_2_entry_t egr_vlan_control_2; 5978 egr_vlan_control_3_entry_t egr_vlan_control_3; 5979 egr_ipmc_cfg2_entry_t egr_ipmc_cfg2; 5980 egr_mtu_entry_t egr_mtu; 5981 egr_port_1_entry_t egr_port_1; 5982 egr_counter_control_entry_t egr_counter_control; 5983 egr_shaping_control_entry_t egr_shaping_control; 5984 egr_port_entry_t egr_port; 5985 uint32 egr_lport_index, old_egr_lport_index; 5986 void *entries[_BCM_EGR_LPROF_MEM_COUNT]; 5987 void *entry; 5988 int use_gpp_index = 1; 5989 5990 /* Make sure port module is initialized. */ 5991 PORT_INIT(unit); 5992 5993 if (mem == EGR_GPP_ATTRIBUTESm) { 5994 BCM_IF_ERROR_RETURN 5995 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 5996 &egr_gpp_index)); 5997 BCM_IF_ERROR_RETURN 5998 (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 5999 egr_gpp_index, &egr_gpp_entry)); 6000 for (i = 0; i < field_count; i++) { 6001 soc_mem_field32_set(unit, EGR_GPP_ATTRIBUTESm, 6002 &egr_gpp_entry, fields[i], values[i]); 6003 } 6004 BCM_IF_ERROR_RETURN 6005 (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ALL, 6006 egr_gpp_index, &egr_gpp_entry)); 6007 6008 return BCM_E_NONE; 6009 } 6010 6011 BCM_IF_ERROR_RETURN( 6012 bcm_esw_port_egr_lport_prof_src_get(unit, modid, port, &use_gpp_index)); 6013 6014 if (use_gpp_index) { 6015 /* Get LPORT profile index Source Trunk Map table */ 6016 BCM_IF_ERROR_RETURN 6017 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 6018 &egr_gpp_index)); 6019 BCM_IF_ERROR_RETURN 6020 (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6021 egr_gpp_index, &egr_gpp_entry)); 6022 old_egr_lport_index = 6023 soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_entry, 6024 EGR_LPORT_PROFILE_IDXf); 6025 } else { 6026 BCM_IF_ERROR_RETURN 6027 (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &egr_port)); 6028 old_egr_lport_index = 6029 soc_mem_field32_get(unit, EGR_PORTm, &egr_port, 6030 EGR_LPORT_PROFILE_IDXf); 6031 } 6032 6033 /* Get LPORT profile entry */ 6034 index = 0; 6035 if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) { 6036 entries[index++] = &egr_lport_entry; 6037 } 6038 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) { 6039 entries[index++] = &egr_vlan_control_1; 6040 } 6041 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) { 6042 entries[index++] = &egr_vlan_control_2; 6043 } 6044 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) { 6045 entries[index++] = &egr_vlan_control_3; 6046 } 6047 if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) { 6048 entries[index++] = &egr_ipmc_cfg2; 6049 } 6050 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 6051 entries[index++] = &egr_mtu; 6052 } 6053 if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) { 6054 entries[index++] = &egr_port_1; 6055 } 6056 if (soc_feature(unit, soc_feature_egr_all_profile) == 0) { 6057 if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) { 6058 entries[index++] = &egr_counter_control; 6059 } 6060 if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) { 6061 entries[index++] = &egr_shaping_control; 6062 } 6063 } 6064 6065 BCM_IF_ERROR_RETURN 6066 (_bcm_egr_lport_profile_entry_get(unit, old_egr_lport_index, 1, entries)); 6067 6068 BCM_IF_ERROR_RETURN 6069 (_bcm_egr_lport_profile_mem_index_get(unit, mem, &index)); 6070 entry = entries[index]; 6071 /* Update fields */ 6072 for (i = 0; i < field_count; i++) { 6073 soc_mem_field32_set(unit, mem, entry, fields[i], values[i]); 6074 } 6075 6076 BCM_IF_ERROR_RETURN 6077 (_bcm_egr_lport_profile_entry_add(unit, entries, 1, &egr_lport_index)); 6078 6079 /* Update STM LPORT profile index */ 6080 if (use_gpp_index) { 6081 soc_EGR_GPP_ATTRIBUTESm_field32_set(unit, &egr_gpp_entry, 6082 EGR_LPORT_PROFILE_IDXf, 6083 egr_lport_index); 6084 BCM_IF_ERROR_RETURN 6085 (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6086 egr_gpp_index, &egr_gpp_entry)); 6087 } else { 6088 soc_mem_field32_set(unit, EGR_PORTm, &egr_port, 6089 EGR_LPORT_PROFILE_IDXf, egr_lport_index); 6090 BCM_IF_ERROR_RETURN 6091 (WRITE_EGR_PORTm(unit, MEM_BLOCK_ALL, port, &egr_port)); 6092 } 6093 /* 6094 * Entry must be 'deleted' because the mem profile 'add' routine 6095 * always increments count even though the same entry is used. 6096 */ 6097 if(old_egr_lport_index != 0) { 6098 BCM_IF_ERROR_RETURN 6099 (_bcm_egr_lport_profile_entry_delete(unit, old_egr_lport_index)); 6100 } 6101 6102 return BCM_E_NONE; 6103 #else 6104 return BCM_E_UNAVAIL; 6105 #endif /* BCM_TRX_SUPPORT */ 6106 } 6107 6108 /* 6109 * Function: 6110 * bcm_esw_port_egr_lport_profile_clear 6111 * Description: 6112 * Similar function as bcm_esw_port_egr_lport_profile_fields_set, 6113 * for clear purpose only. 6114 */ 6115 STATIC int 6116 bcm_esw_port_egr_lport_profile_clear(int unit, 6117 bcm_module_t modid, bcm_port_t port, 6118 soc_mem_t mem) 6119 { 6120 #if defined(BCM_TRX_SUPPORT) 6121 int index; 6122 int egr_gpp_index = 0; 6123 egr_gpp_attributes_entry_t egr_gpp_entry; 6124 egr_lport_profile_entry_t egr_lport_entry; 6125 egr_vlan_control_1_entry_t egr_vlan_control_1; 6126 egr_vlan_control_2_entry_t egr_vlan_control_2; 6127 egr_vlan_control_3_entry_t egr_vlan_control_3; 6128 egr_ipmc_cfg2_entry_t egr_ipmc_cfg2; 6129 egr_mtu_entry_t egr_mtu; 6130 egr_port_1_entry_t egr_port_1; 6131 egr_counter_control_entry_t egr_counter_control; 6132 egr_shaping_control_entry_t egr_shaping_control; 6133 egr_port_entry_t egr_port; 6134 uint32 egr_lport_index, old_egr_lport_index; 6135 void *entries[_BCM_EGR_LPROF_MEM_COUNT]; 6136 void *entry; 6137 int ent_size[_BCM_EGR_LPROF_MEM_COUNT] = {0}; 6138 int use_gpp_index = 1; 6139 6140 /* Make sure port module is initialized. */ 6141 PORT_INIT(unit); 6142 6143 if (mem == EGR_GPP_ATTRIBUTESm) { 6144 BCM_IF_ERROR_RETURN 6145 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 6146 &egr_gpp_index)); 6147 BCM_IF_ERROR_RETURN 6148 (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6149 egr_gpp_index, &egr_gpp_entry)); 6150 sal_memset(&egr_gpp_entry, 0, sizeof(egr_gpp_entry)); 6151 BCM_IF_ERROR_RETURN 6152 (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ALL, 6153 egr_gpp_index, &egr_gpp_entry)); 6154 6155 return BCM_E_NONE; 6156 } 6157 6158 BCM_IF_ERROR_RETURN( 6159 bcm_esw_port_egr_lport_prof_src_get(unit, modid, port, &use_gpp_index)); 6160 6161 if (use_gpp_index) { 6162 /* Get LPORT profile index Source Trunk Map table */ 6163 BCM_IF_ERROR_RETURN 6164 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 6165 &egr_gpp_index)); 6166 BCM_IF_ERROR_RETURN 6167 (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6168 egr_gpp_index, &egr_gpp_entry)); 6169 old_egr_lport_index = 6170 soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_entry, 6171 EGR_LPORT_PROFILE_IDXf); 6172 } else { 6173 BCM_IF_ERROR_RETURN 6174 (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &egr_port)); 6175 old_egr_lport_index = 6176 soc_mem_field32_get(unit, EGR_PORTm, &egr_port, 6177 EGR_LPORT_PROFILE_IDXf); 6178 } 6179 6180 /* Get LPORT profile entry */ 6181 index = 0; 6182 if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) { 6183 ent_size[index] = sizeof(egr_lport_entry); 6184 entries[index++] = &egr_lport_entry; 6185 } 6186 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) { 6187 ent_size[index] = sizeof(egr_vlan_control_1); 6188 entries[index++] = &egr_vlan_control_1; 6189 } 6190 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) { 6191 ent_size[index] = sizeof(egr_vlan_control_2); 6192 entries[index++] = &egr_vlan_control_2; 6193 } 6194 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) { 6195 ent_size[index] = sizeof(egr_vlan_control_3); 6196 entries[index++] = &egr_vlan_control_3; 6197 } 6198 if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) { 6199 ent_size[index] = sizeof(egr_ipmc_cfg2); 6200 entries[index++] = &egr_ipmc_cfg2; 6201 } 6202 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 6203 ent_size[index] = sizeof(egr_mtu); 6204 entries[index++] = &egr_mtu; 6205 } 6206 if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) { 6207 ent_size[index] = sizeof(egr_port_1); 6208 entries[index++] = &egr_port_1; 6209 } 6210 if (soc_feature(unit, soc_feature_egr_all_profile) == 0) { 6211 if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) { 6212 ent_size[index] = sizeof(egr_counter_control); 6213 entries[index++] = &egr_counter_control; 6214 } 6215 if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) { 6216 ent_size[index] = sizeof(egr_shaping_control); 6217 entries[index++] = &egr_shaping_control; 6218 } 6219 } 6220 6221 BCM_IF_ERROR_RETURN 6222 (_bcm_egr_lport_profile_entry_get(unit, old_egr_lport_index, 1, entries)); 6223 6224 BCM_IF_ERROR_RETURN 6225 (_bcm_egr_lport_profile_mem_index_get(unit, mem, &index)); 6226 entry = entries[index]; 6227 /* Clear fields */ 6228 sal_memset(entry, 0, ent_size[index]); 6229 6230 BCM_IF_ERROR_RETURN 6231 (_bcm_egr_lport_profile_entry_add(unit, entries, 1, &egr_lport_index)); 6232 6233 /* Update STM LPORT profile index */ 6234 if (use_gpp_index) { 6235 soc_EGR_GPP_ATTRIBUTESm_field32_set(unit, &egr_gpp_entry, 6236 EGR_LPORT_PROFILE_IDXf, 6237 egr_lport_index); 6238 BCM_IF_ERROR_RETURN 6239 (WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6240 egr_gpp_index, &egr_gpp_entry)); 6241 } else { 6242 soc_mem_field32_set(unit, EGR_PORTm, &egr_port, 6243 EGR_LPORT_PROFILE_IDXf, egr_lport_index); 6244 BCM_IF_ERROR_RETURN 6245 (WRITE_EGR_PORTm(unit, MEM_BLOCK_ALL, port, &egr_port)); 6246 } 6247 /* 6248 * Entry must be 'deleted' because the mem profile 'add' routine 6249 * always increments count even though the same entry is used. 6250 */ 6251 if (old_egr_lport_index != 0) { 6252 BCM_IF_ERROR_RETURN 6253 (_bcm_egr_lport_profile_entry_delete(unit, old_egr_lport_index)); 6254 } 6255 6256 return BCM_E_NONE; 6257 #else 6258 return BCM_E_UNAVAIL; 6259 #endif /* BCM_TRX_SUPPORT */ 6260 } 6261 6262 /* 6263 * Function: 6264 * _bcm_esw_egr_port_tab_multi_set 6265 * Description: 6266 * Function to set multiple fields in EGR port tables 6267 * Parameters: 6268 * unit - Device number 6269 * port - Port number 6270 * field_count - Number of fields to modify 6271 * fields - Array of fields to modify 6272 * values - Array of new field values 6273 * Return Value: 6274 * BCM_E_NONE 6275 * BCM_E_XXX - an error occurred accessing EGR_PORT table. 6276 */ 6277 int 6278 _bcm_esw_egr_port_tab_multi_set(int unit, bcm_port_t port, int field_count, 6279 soc_field_t *fields, uint32 *values) 6280 6281 { 6282 soc_mem_t mem = EGR_PORTm; 6283 int rv = BCM_E_NONE, i, index; 6284 6285 soc_field_t egr_port_tab_fields[SOC_MAX_MEM_FIELD_NUM]; 6286 uint32 egr_port_tab_values[SOC_MAX_MEM_FIELD_NUM]; 6287 int egr_port_tab_field_count = 0; 6288 soc_field_t egr_lport_tab_fields[SOC_MAX_MEM_FIELD_NUM]; 6289 uint32 egr_lport_tab_values[SOC_MAX_MEM_FIELD_NUM]; 6290 int egr_lport_tab_field_count = 0; 6291 soc_field_t egr_gpp_fields[SOC_MAX_MEM_FIELD_NUM]; 6292 uint32 egr_gpp_values[SOC_MAX_MEM_FIELD_NUM]; 6293 int egr_gpp_field_count = 0; 6294 #if defined BCM_HGPROXY_COE_SUPPORT 6295 int is_lport_cfg = 0; 6296 #endif 6297 6298 6299 if ((fields == NULL) || (values == NULL) ) { 6300 return BCM_E_PARAM; 6301 } 6302 if (field_count <= 0) { 6303 return BCM_E_NONE; 6304 } 6305 6306 #if defined BCM_HGPROXY_COE_SUPPORT 6307 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 6308 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 6309 is_lport_cfg = 1; 6310 } 6311 6312 if (is_lport_cfg == 1) { 6313 mem = EGR_LPORT_PROFILEm; 6314 } else 6315 #endif 6316 if (BCM_GPORT_IS_SET(port)) { 6317 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 6318 } 6319 6320 for(i = 0; i < field_count; i++) { 6321 #if defined(CANCUN_SUPPORT) 6322 if (SOC_IS_TRIDENT3X(unit)) { 6323 if (soc_cancun_cmh_check(unit, mem, fields[i]) == SOC_E_NONE) { 6324 rv = soc_cancun_cmh_mem_set(unit, mem, port, fields[i], 6325 values[i]); 6326 } 6327 _bcm_td3_egr_port_tab_conv(unit, &fields[i], &mem); 6328 } 6329 #endif 6330 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 6331 return (SOC_E_UNAVAIL); 6332 } 6333 6334 switch (mem) { 6335 case EGR_GPP_ATTRIBUTESm: 6336 soc_mem_set_field_value_array(egr_gpp_fields, fields[i], 6337 egr_gpp_values, values[i], 6338 egr_gpp_field_count); 6339 break; 6340 case EGR_PORTm: 6341 soc_mem_set_field_value_array(egr_port_tab_fields, fields[i], 6342 egr_port_tab_values, values[i], 6343 egr_port_tab_field_count); 6344 break; 6345 case EGR_LPORT_PROFILEm: 6346 soc_mem_set_field_value_array(egr_lport_tab_fields, fields[i], 6347 egr_lport_tab_values, values[i], 6348 egr_lport_tab_field_count); 6349 break; 6350 default: 6351 BCM_IF_ERROR_RETURN 6352 (soc_mem_field32_modify(unit, mem, port, fields[i], 6353 values[i])); 6354 break; 6355 } 6356 } 6357 6358 #if defined BCM_HGPROXY_COE_SUPPORT 6359 if (is_lport_cfg == 1) { /* remote port */ 6360 return bcm_esw_port_egr_lport_fields_set(unit, port, 6361 EGR_LPORT_PROFILEm, 6362 egr_lport_tab_field_count, 6363 egr_lport_tab_fields, 6364 egr_lport_tab_values); 6365 } 6366 #endif 6367 6368 index = SOC_PORT_MOD_OFFSET(unit, port); 6369 6370 if (egr_port_tab_field_count) { 6371 rv = soc_mem_fields32_modify(unit, EGR_PORTm, index, 6372 egr_port_tab_field_count, 6373 egr_port_tab_fields, egr_port_tab_values); 6374 } 6375 6376 if (egr_lport_tab_field_count && BCM_SUCCESS(rv)) { 6377 rv = bcm_esw_port_egr_lport_fields_set(unit, index, 6378 EGR_LPORT_PROFILEm, egr_lport_tab_field_count, 6379 egr_lport_tab_fields, egr_lport_tab_values); 6380 } 6381 6382 if (egr_gpp_field_count && BCM_SUCCESS(rv)) { 6383 rv = bcm_esw_port_egr_lport_fields_set(unit, index, 6384 EGR_GPP_ATTRIBUTESm, egr_gpp_field_count, 6385 egr_gpp_fields, egr_gpp_values); 6386 } 6387 6388 return rv; 6389 } 6390 6391 /* 6392 * Function: 6393 * _bcm_esw_egr_port_tab_set 6394 * Description: 6395 * Helper funtion for bcm_esw_port_control_set. 6396 * Parameters: 6397 * unit - Device number 6398 * port - Port number 6399 * field - Field name within EGR_PORT table entry 6400 * value - new field value 6401 * Return Value: 6402 * BCM_E_NONE 6403 * BCM_E_XXX - an error occurred accessing EGR_PORT table. 6404 */ 6405 int 6406 _bcm_esw_egr_port_tab_set(int unit, bcm_port_t port, 6407 soc_field_t field, uint32 value) 6408 6409 { 6410 return (_bcm_esw_egr_port_tab_multi_set(unit, port, 1, &field, &value)); 6411 } 6412 6413 /* 6414 * Function: 6415 * _bcm_esw_egr_port_tab_get 6416 * Description: 6417 * Helper funtion for bcm_esw_port_control_get. 6418 * Parameters: 6419 * unit - Device number 6420 * port - Port number 6421 * field - Field name within PORT_TAB table entry 6422 * value - (OUT) field value 6423 * Return Value: 6424 * BCM_E_NONE 6425 * BCM_E_XXX - an error occurred accessing PORT_TAB table. 6426 * Notes: 6427 * Due to the large number of callers for this routine, 6428 * function is expanded to take a GPORT PROXY, which 6429 * get the property from the LPORT profile table. 6430 * 6431 * Current valid port types are: 6432 * GPORT SUBPORT 6433 * BCM port (non-gport), assumes a valid local physical port 6434 */ 6435 6436 int 6437 _bcm_esw_egr_port_tab_get(int unit, bcm_port_t port, 6438 soc_field_t field, int *value) 6439 { 6440 int rv = BCM_E_UNAVAIL; 6441 egr_port_entry_t pent; 6442 soc_mem_t mem; 6443 int index, is_lport_cfg = 0, is_gpp_attr = 0; 6444 uint32 value32; 6445 6446 mem = EGR_PORTm; 6447 #if defined(BCM_TRIDENT3_SUPPORT) 6448 if (SOC_IS_TRIDENT3X(unit)) { 6449 BCM_IF_ERROR_RETURN(_bcm_td3_egr_port_tab_conv(unit, &field, &mem)); 6450 if (mem == EGR_GPP_ATTRIBUTESm) { 6451 is_gpp_attr = 1; 6452 } else if (mem != EGR_PORTm) { 6453 is_lport_cfg = 1; 6454 } 6455 } 6456 #endif 6457 6458 if (!SOC_MEM_FIELD_VALID(unit, mem, field)) { 6459 return (BCM_E_UNAVAIL); 6460 } 6461 6462 #if defined BCM_HGPROXY_COE_SUPPORT 6463 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 6464 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 6465 is_lport_cfg = 1; 6466 } else 6467 #endif 6468 if (BCM_GPORT_IS_PROXY(port)) { 6469 is_lport_cfg = 1; 6470 } 6471 6472 /* If LPORT, then get property from LPORT table */ 6473 if (is_lport_cfg) { 6474 rv = bcm_esw_port_egr_lport_field_get(unit, port, 6475 EGR_LPORT_PROFILEm, 6476 field, &value32); 6477 *value = value32; 6478 return rv; 6479 } else if (is_gpp_attr) { 6480 rv = bcm_esw_port_egr_lport_field_get(unit, port, 6481 EGR_GPP_ATTRIBUTESm, 6482 field, &value32); 6483 *value = value32; 6484 return rv; 6485 } 6486 6487 /* At this point, 'port' needs to be a BCM port (non-gport) */ 6488 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 6489 6490 index = SOC_PORT_MOD_OFFSET(unit, port); 6491 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &pent); 6492 6493 if (BCM_SUCCESS(rv)) { 6494 *value = soc_mem_field32_get(unit, mem, &pent, field); 6495 } 6496 6497 return rv; 6498 } 6499 6500 6501 #if defined(BCM_TRX_SUPPORT) 6502 /* 6503 * Function: 6504 * bcm_esw_port_separate_lport_rtag7_profile_fields_get 6505 * Description: 6506 * Gets the fields from the LPORT Profile Table. 6507 * Parameters: 6508 * unit - (IN) Device number 6509 * modid - (IN) Module number for port 6510 * port - (IN) Port number (NON gport) 6511 * table_id - (IN) Index of table to modify, LPORT or RTAG7 6512 * field_count - (IN) Number of fields to read 6513 * fields - (IN) Array of fields to return 6514 * values - (OUT) Array of return values 6515 * Return Value: 6516 * BCM_E_NONE 6517 * BCM_E_XXX 6518 * Note: 6519 * - Assumes: lock, 6520 * valid bcm module id and port number, 6521 * valid table id, 6522 * valid HW fields. 6523 * - Called when LPORT profile is supported. 6524 * - Helper routine for bcm_esw_port_lport_fields_get(); 6525 * callers should be calling bcm_esw_port_lport_fields_get() instead. 6526 */ 6527 STATIC int 6528 bcm_esw_port_separate_lport_rtag7_profile_fields_get(int unit, int port_type, 6529 bcm_module_t modid, bcm_port_t port, 6530 int table_id, int field_count, 6531 soc_field_t *fields, uint32 *values) 6532 { 6533 int i; 6534 int src_index; 6535 uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS]; 6536 int src_tbl_is_stm = 1; 6537 soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm; 6538 lport_tab_entry_t lport_entry; 6539 rtag7_port_based_hash_entry_t rtag7_entry; 6540 uint32 lport_index = 0, rtag7_index = 0; 6541 void *entries[1]; 6542 soc_mem_t mem; 6543 void *entry; 6544 6545 BCM_IF_ERROR_RETURN 6546 (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm)); 6547 6548 /* Get LPORT profile index Source table */ 6549 if (src_tbl_is_stm) { 6550 BCM_IF_ERROR_RETURN 6551 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index)); 6552 } else { 6553 src_mem = ING_DEVICE_PORTm; 6554 src_index = port; 6555 } 6556 6557 BCM_IF_ERROR_RETURN 6558 (soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, 6559 src_index, src_ent)); 6560 6561 lport_index = 6562 soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf); 6563 6564 /* If this is a RTAG7 table, extract the RTAG7 index from the LPORT table */ 6565 if(table_id == LPORT_PROFILE_RTAG7_TAB) { 6566 6567 /* Get the associated LPORT entry */ 6568 BCM_IF_ERROR_RETURN 6569 (READ_LPORT_TABm(unit, MEM_BLOCK_ANY, lport_index, &lport_entry)); 6570 6571 rtag7_index = 6572 soc_LPORT_TABm_field32_get(unit, &lport_entry, 6573 RTAG7_PORT_PROFILE_INDEXf); 6574 } 6575 6576 /* Read the appropriate profile table entry */ 6577 if (table_id == LPORT_PROFILE_LPORT_TAB) { 6578 mem = LPORT_TABm; 6579 entries[0] = &lport_entry; 6580 entry = entries[0]; 6581 BCM_IF_ERROR_RETURN 6582 (_bcm_lport_ind_profile_entry_get(unit, lport_index, 6583 1, entries)); 6584 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 6585 mem = RTAG7_PORT_BASED_HASHm; 6586 entries[0] = &rtag7_entry; 6587 entry = entries[0]; 6588 BCM_IF_ERROR_RETURN 6589 (_bcm_rtag7_ind_profile_entry_get(unit, rtag7_index, 6590 1, entries)); 6591 } else { 6592 return BCM_E_INTERNAL; 6593 } 6594 6595 for (i = 0; i < field_count; i++) { 6596 values[i] = soc_mem_field32_get(unit, mem, entry, fields[i]); 6597 } 6598 6599 return BCM_E_NONE; 6600 } 6601 #endif /* BCM_TRX_SUPPORT */ 6602 6603 6604 /* 6605 * Function: 6606 * bcm_esw_port_egr_lport_profile_fields_get 6607 * Description: 6608 * Gets the fields from the LPORT Profile Table. 6609 * Parameters: 6610 * unit - (IN) Device number 6611 * modid - (IN) Module number for port 6612 * port - (IN) Port number (NON gport) 6613 * mem - (IN) Table to modify 6614 * field_count - (IN) Number of fields to read 6615 * fields - (IN) Array of fields to return 6616 * values - (OUT) Array of return values 6617 * Return Value: 6618 * BCM_E_NONE 6619 * BCM_E_XXX 6620 * Note: 6621 * - Assumes: lock, 6622 * valid bcm module id and port number, 6623 * valid table id, 6624 * valid HW fields. 6625 * - Called when LPORT profile is supported. 6626 * - Helper routine for bcm_esw_port_egr_lport_fields_get(); 6627 * callers should be calling bcm_esw_port_egr_lport_fields_get() instead. 6628 */ 6629 STATIC int 6630 bcm_esw_port_egr_lport_profile_fields_get(int unit, 6631 bcm_module_t modid, bcm_port_t port, 6632 soc_mem_t mem, int field_count, 6633 soc_field_t *fields, uint32 *values) 6634 { 6635 #if defined(BCM_TRX_SUPPORT) 6636 int i, index; 6637 int egr_gpp_index = 0; 6638 egr_gpp_attributes_entry_t egr_gpp_entry; 6639 egr_lport_profile_entry_t egr_lport_entry; 6640 egr_vlan_control_1_entry_t egr_vlan_control_1; 6641 egr_vlan_control_2_entry_t egr_vlan_control_2; 6642 egr_vlan_control_3_entry_t egr_vlan_control_3; 6643 egr_ipmc_cfg2_entry_t egr_ipmc_cfg2; 6644 egr_mtu_entry_t egr_mtu; 6645 egr_port_1_entry_t egr_port_1; 6646 egr_counter_control_entry_t egr_counter_control; 6647 egr_shaping_control_entry_t egr_shaping_control; 6648 uint32 egr_lport_index; 6649 void *entries[_BCM_EGR_LPROF_MEM_COUNT]; 6650 void *entry = NULL; 6651 int use_gpp_index = 1; 6652 6653 if (mem == EGR_GPP_ATTRIBUTESm) { 6654 BCM_IF_ERROR_RETURN 6655 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 6656 &egr_gpp_index)); 6657 BCM_IF_ERROR_RETURN 6658 (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6659 egr_gpp_index, &egr_gpp_entry)); 6660 for (i = 0; i < field_count; i++) { 6661 values[i] = soc_mem_field32_get(unit, EGR_GPP_ATTRIBUTESm, 6662 &egr_gpp_entry, fields[i]); 6663 } 6664 return BCM_E_NONE; 6665 } 6666 6667 BCM_IF_ERROR_RETURN( 6668 bcm_esw_port_egr_lport_prof_src_get(unit, modid, port, &use_gpp_index)); 6669 6670 if (use_gpp_index) { 6671 /* Get LPORT profile index Source Trunk Map table */ 6672 BCM_IF_ERROR_RETURN 6673 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, 6674 &egr_gpp_index)); 6675 BCM_IF_ERROR_RETURN 6676 (READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, 6677 egr_gpp_index, &egr_gpp_entry)); 6678 egr_lport_index = 6679 soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_entry, 6680 EGR_LPORT_PROFILE_IDXf); 6681 } else { 6682 egr_port_entry_t entry2; 6683 BCM_IF_ERROR_RETURN 6684 (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &entry2)); 6685 egr_lport_index = 6686 soc_mem_field32_get(unit, EGR_PORTm, &entry2, 6687 EGR_LPORT_PROFILE_IDXf); 6688 } 6689 6690 /* Get EGR_LPORT profile entry */ 6691 index = 0; 6692 if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm)) { 6693 entries[index++] = &egr_lport_entry; 6694 } 6695 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_1m)) { 6696 entries[index++] = &egr_vlan_control_1; 6697 } 6698 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_2m)) { 6699 entries[index++] = &egr_vlan_control_2; 6700 } 6701 if (SOC_MEM_IS_VALID(unit, EGR_VLAN_CONTROL_3m)) { 6702 entries[index++] = &egr_vlan_control_3; 6703 } 6704 if (SOC_MEM_IS_VALID(unit, EGR_IPMC_CFG2m)) { 6705 entries[index++] = &egr_ipmc_cfg2; 6706 } 6707 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 6708 entries[index++] = &egr_mtu; 6709 } 6710 if (SOC_MEM_IS_VALID(unit, EGR_PORT_1m)) { 6711 entries[index++] = &egr_port_1; 6712 } 6713 if (soc_feature(unit, soc_feature_egr_all_profile) == 0) { 6714 if (SOC_MEM_IS_VALID(unit, EGR_COUNTER_CONTROLm)) { 6715 entries[index++] = &egr_counter_control; 6716 } 6717 if (SOC_MEM_IS_VALID(unit, EGR_SHAPING_CONTROLm)) { 6718 entries[index++] = &egr_shaping_control; 6719 } 6720 } 6721 6722 BCM_IF_ERROR_RETURN 6723 (_bcm_egr_lport_profile_entry_get(unit, egr_lport_index, 1, entries)); 6724 6725 BCM_IF_ERROR_RETURN 6726 (_bcm_egr_lport_profile_mem_index_get(unit, mem, &index)); 6727 entry = entries[index]; 6728 /* Get fields */ 6729 6730 for (i = 0; i < field_count; i++) { 6731 values[i] = soc_mem_field32_get(unit, mem, entry, fields[i]); 6732 } 6733 6734 return BCM_E_NONE; 6735 #else 6736 return BCM_E_UNAVAIL; 6737 #endif /* BCM_TRX_SUPPORT */ 6738 } 6739 6740 /* 6741 * Function: 6742 * bcm_esw_port_lport_profile_fields_get 6743 * Description: 6744 * Gets the fields from the LPORT Profile Table. 6745 * Parameters: 6746 * unit - (IN) Device number 6747 * modid - (IN) Module number for port 6748 * port - (IN) Port number (NON gport) 6749 * table_id - (IN) Index of table to modify, LPORT or RTAG7 6750 * field_count - (IN) Number of fields to read 6751 * fields - (IN) Array of fields to return 6752 * values - (OUT) Array of return values 6753 * Return Value: 6754 * BCM_E_NONE 6755 * BCM_E_XXX 6756 * Note: 6757 * - Assumes: lock, 6758 * valid bcm module id and port number, 6759 * valid table id, 6760 * valid HW fields. 6761 * - Called when LPORT profile is supported. 6762 * - Helper routine for bcm_esw_port_lport_fields_get(); 6763 * callers should be calling bcm_esw_port_lport_fields_get() instead. 6764 */ 6765 STATIC int 6766 bcm_esw_port_lport_profile_fields_get(int unit, int port_type, 6767 bcm_module_t modid, bcm_port_t port, 6768 int table_id, int field_count, 6769 soc_field_t *fields, uint32 *values) 6770 { 6771 #if defined(BCM_TRX_SUPPORT) 6772 int i; 6773 int src_index; 6774 uint32 src_ent[SOC_MAX_MEM_FIELD_WORDS]; 6775 int src_tbl_is_stm = 1; 6776 soc_mem_t src_mem = SOURCE_TRUNK_MAP_TABLEm; 6777 lport_tab_entry_t lport_entry; 6778 rtag7_port_based_hash_entry_t rtag7_entry; 6779 uint32 lport_index; 6780 void *entries[2]; 6781 soc_mem_t mem; 6782 void *entry; 6783 int pipe; 6784 6785 if (soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) { 6786 return bcm_esw_port_separate_lport_rtag7_profile_fields_get(unit, 6787 port_type, modid, port, table_id, field_count, fields, values); 6788 } 6789 6790 BCM_IF_ERROR_RETURN 6791 (bcm_esw_port_lport_prof_src_check(unit, port_type, &src_tbl_is_stm)); 6792 6793 /* Get LPORT profile index Source table */ 6794 if (src_tbl_is_stm) { 6795 BCM_IF_ERROR_RETURN 6796 (_bcm_esw_src_mod_port_table_index_get(unit, modid, port, &src_index)); 6797 } else { 6798 src_mem = ING_DEVICE_PORTm; 6799 src_index = port; 6800 } 6801 6802 BCM_IF_ERROR_RETURN 6803 (soc_mem_read(unit, src_mem, MEM_BLOCK_ANY, src_index, src_ent)); 6804 6805 lport_index = 6806 soc_mem_field32_get(unit, src_mem, src_ent, LPORT_PROFILE_IDXf); 6807 6808 /* Get LPORT profile entry */ 6809 entries[0] = &lport_entry; 6810 entries[1] = &rtag7_entry; 6811 if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 6812 pipe = SOC_INFO(unit).port_pipe[src_index]; 6813 mem = SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)[pipe]; 6814 /* Need to index into the proper entry of the profile table, 6815 * which is stored as one logical table while LPORT_PROFILE_IDX 6816 * is from 0-19 of each pipe */ 6817 lport_index += pipe*SOC_MEM_SIZE(unit, mem); 6818 } 6819 6820 BCM_IF_ERROR_RETURN 6821 (_bcm_lport_profile_entry_get(unit, lport_index, 1, entries)); 6822 6823 /* Get fields */ 6824 if (table_id == LPORT_PROFILE_LPORT_TAB) { 6825 mem = LPORT_TABm; 6826 if (SOC_MEM_UNIQUE_ACC(unit, mem)) { 6827 int pipe = SOC_INFO(unit).port_pipe[src_index]; 6828 mem = SOC_MEM_UNIQUE_ACC(unit, mem)[pipe]; 6829 } 6830 entry = entries[0]; 6831 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 6832 mem = RTAG7_PORT_BASED_HASHm; 6833 entry = entries[1]; 6834 } else { 6835 return BCM_E_INTERNAL; 6836 } 6837 6838 for (i = 0; i < field_count; i++) { 6839 values[i] = soc_mem_field32_get(unit, mem, entry, fields[i]); 6840 } 6841 6842 return BCM_E_NONE; 6843 #else 6844 return BCM_E_UNAVAIL; 6845 #endif /* BCM_TRX_SUPPORT */ 6846 } 6847 6848 /* 6849 * Function: 6850 * bcm_esw_port_lport_non_profile_fields_set 6851 * Description: 6852 * Sets the fields only in the LPORT Table for local HG ports. 6853 * There is no reference update to the SOURCE TRUNK MAP table. 6854 * Parameters: 6855 * unit - (IN) Device number 6856 * port - (IN) Local Port number (NON gport) 6857 * field_count - (IN) Number of fields to modify 6858 * fields - (IN) Array of fields to modify 6859 * values - (IN) Array of new field values 6860 * Return Value: 6861 * BCM_E_NONE 6862 * BCM_E_XXX 6863 * Note: 6864 * Assumes: lock, 6865 * valid bcm port number, 6866 * valid HW fields. 6867 * - Maintained for backwards compatibility with old code. This only 6868 * updates local HG ports. 6869 * - Called when LPORT profile is NOT supported. 6870 * - Helper routine for bcm_esw_port_lport_fields_set(); 6871 * callers should be calling bcm_esw_port_lport_fields_set() instead. 6872 */ 6873 STATIC int 6874 bcm_esw_port_lport_non_profile_fields_set(int unit, bcm_port_t port, 6875 int field_count, 6876 soc_field_t *fields, uint32 *values) 6877 { 6878 bcm_port_config_t port_config; 6879 soc_mem_t mem = LPORT_TABm; 6880 int lport_index; 6881 6882 BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &port_config)); 6883 6884 if (PBMP_MEMBER(port_config.hg, port) == 0) { 6885 return BCM_E_NONE; 6886 } 6887 6888 lport_index = SOC_PORT_MOD_OFFSET(unit, port); 6889 6890 return soc_mem_fields32_modify(unit, mem, lport_index, 6891 field_count, fields, values); 6892 } 6893 6894 /* 6895 * Function: 6896 * bcm_esw_port_lport_non_profile_fields_get 6897 * Description: 6898 * Gets the fields from the LPORT Table for local HG ports. 6899 * Parameters: 6900 * unit - (IN) Device number 6901 * port - (IN) Local Port number (NON gport) 6902 * field_count - (IN) Number of fields to read 6903 * fields - (IN) Array of fields to return 6904 * values - (OUT) Array of return values 6905 * Return Value: 6906 * BCM_E_NONE 6907 * BCM_E_XXX 6908 * Note: 6909 * Assumes: lock, 6910 * valid bcm port number, 6911 * valid HW fields. 6912 * - Maintained for backwards compatibility with old code. This only 6913 * updates local HG ports. 6914 * - Called when LPORT profile is NOT supported. 6915 * - Helper routine for bcm_esw_port_lport_fields_get(); 6916 * callers should be calling bcm_esw_port_lport_fields_get() instead. 6917 */ 6918 STATIC int 6919 bcm_esw_port_lport_non_profile_fields_get(int unit, bcm_port_t port, 6920 int field_count, 6921 soc_field_t *fields, uint32 *values) 6922 { 6923 lport_tab_entry_t lport_entry; 6924 int lport_index; 6925 int i; 6926 6927 if (!IS_HG_PORT(unit,port)) { 6928 return BCM_E_NONE; 6929 } 6930 6931 lport_index = SOC_PORT_MOD_OFFSET(unit, port); 6932 6933 BCM_IF_ERROR_RETURN 6934 (READ_LPORT_TABm(unit, MEM_BLOCK_ANY, lport_index, &lport_entry)); 6935 6936 for (i = 0; i < field_count; i++) { 6937 values[i] = soc_LPORT_TABm_field32_get(unit, &lport_entry, fields[i]); 6938 } 6939 6940 return BCM_E_NONE; 6941 } 6942 6943 /* 6944 * Function: 6945 * bcm_esw_port_lport_resolve 6946 * Description: 6947 * Resolves given port to use in the LPORT table as follows. 6948 * Current valid "port" for LPORT are: 6949 * GPORT_PROXY - Resolve to module ID and port 6950 * GPORT_xxx - Should result in a valid local physical port 6951 * Not GPORT - Should be a valid local port number 6952 * Parameters: 6953 * unit - (IN) Device number 6954 * port - (IN) Port number or GPORT 6955 * modid_out - (OUT) Module ID 6956 * port_out - (OUT) Port number 6957 * Return Value: 6958 * BCM_E_XXX 6959 * Notes: 6960 * If port is GPORT_PROXY, then module-id is derived from GPORT. 6961 * Else, module-is is the id of the local device. 6962 */ 6963 STATIC int 6964 bcm_esw_port_lport_resolve(int unit, bcm_port_t port, 6965 bcm_module_t *modid_out, bcm_port_t *port_out) 6966 { 6967 bcm_trunk_t trunk; 6968 int id, rv; 6969 6970 /* Make sure port module is initialized. */ 6971 PORT_INIT(unit); 6972 6973 /* Resolve port */ 6974 if (BCM_GPORT_IS_PROXY(port)) { 6975 if (!soc_feature(unit, soc_feature_proxy_port_property)) { 6976 return BCM_E_PORT; 6977 } 6978 BCM_IF_ERROR_RETURN 6979 (_bcm_esw_gport_resolve(unit, port, 6980 modid_out, port_out, 6981 &trunk, &id)); 6982 } else { 6983 6984 #if defined BCM_HGPROXY_COE_SUPPORT 6985 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 6986 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 6987 BCM_IF_ERROR_RETURN 6988 (_bcm_esw_gport_resolve(unit, port, 6989 modid_out, port_out, 6990 &trunk, &id)); 6991 } else 6992 #endif 6993 6994 #if defined(BCM_KATANA2_SUPPORT) 6995 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port) && 6996 (soc_feature(unit, soc_feature_subtag_coe) || 6997 soc_feature(unit, soc_feature_linkphy_coe))) { 6998 BCM_IF_ERROR_RETURN 6999 (_bcm_esw_gport_resolve(unit, port, 7000 modid_out, port_out, 7001 &trunk, &id)); 7002 } else 7003 #endif 7004 7005 { 7006 /* Gport should resolve to a local valid port */ 7007 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, modid_out)); 7008 rv = _bcm_esw_port_gport_validate(unit, port, port_out); 7009 7010 if (rv == BCM_E_PORT && 7011 SOC_IS_TRIDENT3X(unit) && 7012 SOC_INFO(unit).cpu_hg_index == port) { 7013 *port_out = port; 7014 rv = BCM_E_NONE; 7015 } 7016 BCM_IF_ERROR_RETURN(rv); 7017 } 7018 } 7019 7020 return BCM_E_NONE; 7021 } 7022 7023 /* 7024 * Function: 7025 * bcm_esw_port_egr_lport_resolve 7026 * Description: 7027 * Resolves given port to use in the EGR_LPORT table as follows. 7028 * Current valid "port" for EGR_LPORT are: 7029 * GPORT_SUBPORT - Resolve to module ID and port 7030 * Parameters: 7031 * unit - (IN) Device number 7032 * port - (IN) Port number or GPORT 7033 * modid_out - (OUT) Module ID 7034 * port_out - (OUT) Port number 7035 * Return Value: 7036 * BCM_E_XXX 7037 * Notes: 7038 * If port is GPORT_PROXY, then module-id is derived from GPORT. 7039 * Else, module-is is the id of the local device. 7040 */ 7041 STATIC int 7042 bcm_esw_port_egr_lport_resolve(int unit, bcm_port_t port, 7043 bcm_module_t *modid_out, bcm_port_t *port_out) 7044 { 7045 #if defined BCM_HGPROXY_COE_SUPPORT 7046 bcm_trunk_t trunk; 7047 int id; 7048 #endif 7049 7050 /* Make sure port module is initialized. */ 7051 PORT_INIT(unit); 7052 7053 /* Resolve port */ 7054 #if defined BCM_HGPROXY_COE_SUPPORT 7055 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 7056 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 7057 BCM_IF_ERROR_RETURN 7058 (_bcm_esw_gport_resolve(unit, port, 7059 modid_out, port_out, 7060 &trunk, &id)); 7061 } else 7062 #endif 7063 { 7064 /* Gport should resolve to a local valid port */ 7065 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, modid_out)); 7066 BCM_IF_ERROR_RETURN 7067 (_bcm_esw_port_gport_validate(unit, port, port_out)); 7068 } 7069 7070 return BCM_E_NONE; 7071 } 7072 7073 7074 /* 7075 * Function: 7076 * bcm_esw_port_lport_fields_set 7077 * Description: 7078 * Sets the fields in the LPORT Table as follows: 7079 * - If LPORT profile is available, update fields in the 7080 * LPORT Profile Table and corresponding index in the 7081 * Source Trunk Map table. 7082 * - Else, update fields in the LPORT table only (old logic). 7083 * Parameters: 7084 * unit - (IN) Device number 7085 * port - (IN) Port number or GPORT (see Notes) 7086 * table_id - (IN) Index of table to modify, LPORT or RTAG7 7087 * field_count - (IN) Number of fields to modify 7088 * fields - (IN) Array of fields to modify 7089 * values - (IN) Array of new field values 7090 * Return Value: 7091 * BCM_E_XXX 7092 * Notes: 7093 * Current valid port/gport types: 7094 * GPORT_PROXY 7095 * GPORT_xxx - should result in a valid local physical port 7096 * Not GPORT - assumes a valid local port number 7097 */ 7098 int 7099 bcm_esw_port_lport_fields_set(int unit, bcm_port_t port, 7100 int table_id, int field_count, 7101 soc_field_t *fields, uint32 *values) 7102 { 7103 int rv = BCM_E_NONE; 7104 int i; 7105 soc_mem_t mem; 7106 bcm_module_t lmodid; 7107 bcm_port_t lport; 7108 int ptype = _BCM_ESW_PT_PORT; 7109 7110 /* Make sure port module is initialized. */ 7111 PORT_INIT(unit); 7112 7113 #if defined BCM_HGPROXY_COE_SUPPORT 7114 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 7115 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 7116 ptype = _BCM_ESW_PT_COE; 7117 } else 7118 #endif 7119 if (BCM_GPORT_IS_PROXY(port)) { 7120 ptype = _BCM_ESW_PT_HGPROXY; 7121 } 7122 7123 /* Check table */ 7124 if (table_id == LPORT_PROFILE_LPORT_TAB) { 7125 mem = LPORT_TABm; 7126 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 7127 if (!SOC_MEM_IS_VALID(unit, RTAG7_PORT_BASED_HASHm)) { 7128 return BCM_E_UNAVAIL; 7129 } 7130 mem = RTAG7_PORT_BASED_HASHm; 7131 } else { 7132 return BCM_E_INTERNAL; 7133 } 7134 7135 /* Check all fields are valid */ 7136 for (i = 0; i < field_count; i++) { 7137 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 7138 return BCM_E_UNAVAIL; 7139 } 7140 } 7141 7142 /* Resolve port */ 7143 BCM_IF_ERROR_RETURN 7144 (bcm_esw_port_lport_resolve(unit, port, 7145 &lmodid, &lport)); 7146 7147 if (soc_feature(unit, soc_feature_lport_tab_profile)) { 7148 rv = bcm_esw_port_lport_profile_fields_set(unit, ptype, 7149 lmodid, lport, table_id, field_count, fields, values); 7150 } else { 7151 rv = bcm_esw_port_lport_non_profile_fields_set(unit, 7152 lport, field_count, fields, values); 7153 } 7154 7155 return rv; 7156 } 7157 7158 /* 7159 * Function: 7160 * bcm_esw_port_egr_lport_fields_set 7161 * Description: 7162 * Sets the fields in the LPORT Table as follows: 7163 * - If LPORT profile is available, update fields in the 7164 * LPORT Profile Table and corresponding index in the 7165 * Source Trunk Map table. 7166 * - Else, update fields in the LPORT table only (old logic). 7167 * Parameters: 7168 * unit - (IN) Device number 7169 * port - (IN) Port number or GPORT (see Notes) 7170 * mem - (IN) Table to modify 7171 * field_count - (IN) Number of fields to modify 7172 * fields - (IN) Array of fields to modify 7173 * values - (IN) Array of new field values 7174 * Return Value: 7175 * BCM_E_XXX 7176 * Notes: 7177 * Current valid port/gport types: 7178 * GPORT_PROXY 7179 * GPORT_xxx - should result in a valid local physical port 7180 * Not GPORT - assumes a valid local port number 7181 */ 7182 int 7183 bcm_esw_port_egr_lport_fields_set(int unit, bcm_port_t port, 7184 soc_mem_t mem, int field_count, 7185 soc_field_t *fields, uint32 *values) 7186 { 7187 int rv = BCM_E_NONE; 7188 int i; 7189 bcm_module_t lmodid; 7190 bcm_port_t lport; 7191 7192 /* Make sure port module is initialized. */ 7193 PORT_INIT(unit); 7194 7195 /* Check all fields are valid */ 7196 for (i = 0; i < field_count; i++) { 7197 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 7198 return BCM_E_UNAVAIL; 7199 } 7200 } 7201 7202 /* Resolve port */ 7203 BCM_IF_ERROR_RETURN 7204 (bcm_esw_port_egr_lport_resolve(unit, port, 7205 &lmodid, &lport)); 7206 7207 PORT_LOCK(unit); 7208 if (soc_feature(unit, soc_feature_egr_lport_tab_profile)) { 7209 rv = bcm_esw_port_egr_lport_profile_fields_set(unit, lmodid, lport, 7210 mem, field_count, 7211 fields, values); 7212 } 7213 7214 PORT_UNLOCK(unit); 7215 7216 return rv; 7217 } 7218 7219 /* 7220 * Function: 7221 * bcm_esw_port_egr_lport_fields_clear 7222 * Description: 7223 * Similar function as bcm_esw_port_egr_lport_fields_set. 7224 * For clear purpose only. 7225 * Parameters: 7226 * unit - (IN) Device number 7227 * port - (IN) Port number or GPORT (see Notes) 7228 * mem - (IN) Table to modify 7229 * Return Value: 7230 * BCM_E_XXX 7231 * Notes: 7232 * Current valid port/gport types: 7233 * GPORT_PROXY 7234 * GPORT_xxx - should result in a valid local physical port 7235 * Not GPORT - assumes a valid local port number 7236 */ 7237 int 7238 bcm_esw_port_egr_lport_fields_clear(int unit, bcm_port_t port, 7239 soc_mem_t mem) 7240 { 7241 int rv = BCM_E_NONE; 7242 bcm_module_t lmodid; 7243 bcm_port_t lport; 7244 7245 /* Make sure port module is initialized. */ 7246 PORT_INIT(unit); 7247 7248 /* Resolve port */ 7249 BCM_IF_ERROR_RETURN 7250 (bcm_esw_port_egr_lport_resolve(unit, port, 7251 &lmodid, &lport)); 7252 7253 PORT_LOCK(unit); 7254 if (soc_feature(unit, soc_feature_egr_lport_tab_profile)) { 7255 rv = bcm_esw_port_egr_lport_profile_clear(unit, lmodid, lport, mem); 7256 } 7257 7258 PORT_UNLOCK(unit); 7259 7260 return rv; 7261 } 7262 7263 /* 7264 * Function: 7265 * bcm_esw_port_lport_fields_get 7266 * Description: 7267 * Gets the values from the LPORT Table fields as follows: 7268 * - If LPORT profile is available, gets fields from the 7269 * LPORT Profile Table and corresponding index in the 7270 * Source Trunk Map table. 7271 * - Else, get fields from the LPORT table only (old logic). 7272 * Parameters: 7273 * unit - (IN) Device number 7274 * port - (IN) Port number or GPORT (see Notes) 7275 * table_id - (IN) Index of table to modify, LPORT or RTAG7 7276 * field_count - (IN) Number of fields to get 7277 * fields - (IN) Array of fields values to get 7278 * values - (OUT) Array of returned values 7279 * Return Value: 7280 * BCM_E_XXX 7281 * Notes: 7282 * Current valid port/gport types: 7283 * GPORT_PROXY 7284 * GPORT_xxx - should result in a valid local physical port 7285 * Not GPORT - assumes a valid local port number 7286 */ 7287 int 7288 bcm_esw_port_lport_fields_get(int unit, bcm_port_t port, 7289 int table_id, int field_count, 7290 soc_field_t *fields, uint32 *values) 7291 { 7292 int rv = BCM_E_NONE; 7293 int i; 7294 soc_mem_t mem; 7295 bcm_module_t lmodid; 7296 bcm_port_t lport; 7297 int ptype = _BCM_ESW_PT_PORT; 7298 7299 /* Make sure port module is initialized. */ 7300 PORT_INIT(unit); 7301 7302 #if defined BCM_HGPROXY_COE_SUPPORT 7303 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 7304 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 7305 ptype = _BCM_ESW_PT_COE; 7306 } else 7307 #endif 7308 if (BCM_GPORT_IS_PROXY(port)) { 7309 ptype = _BCM_ESW_PT_HGPROXY; 7310 } 7311 7312 /* Check table */ 7313 if (table_id == LPORT_PROFILE_LPORT_TAB) { 7314 mem = LPORT_TABm; 7315 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 7316 if (!SOC_MEM_IS_VALID(unit, RTAG7_PORT_BASED_HASHm)) { 7317 return BCM_E_UNAVAIL; 7318 } 7319 mem = RTAG7_PORT_BASED_HASHm; 7320 } else { 7321 return BCM_E_INTERNAL; 7322 } 7323 7324 /* Check all fields are valid */ 7325 for (i = 0; i < field_count; i++) { 7326 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 7327 return BCM_E_UNAVAIL; 7328 } 7329 } 7330 7331 /* Resolve port */ 7332 BCM_IF_ERROR_RETURN 7333 (bcm_esw_port_lport_resolve(unit, port, 7334 &lmodid, &lport)); 7335 7336 if (soc_feature(unit, soc_feature_lport_tab_profile)) { 7337 rv = bcm_esw_port_lport_profile_fields_get(unit, ptype, 7338 lmodid, lport, table_id, field_count, fields, values); 7339 } else { 7340 rv = bcm_esw_port_lport_non_profile_fields_get(unit, lport, 7341 field_count, fields, values); 7342 } 7343 7344 return rv; 7345 } 7346 7347 /* 7348 * Function: 7349 * bcm_esw_port_egr_lport_fields_get 7350 * Description: 7351 * Gets the values from the LPORT Table fields as follows: 7352 * - If LPORT profile is available, gets fields from the 7353 * LPORT Profile Table and corresponding index in the 7354 * Source Trunk Map table. 7355 * - Else, get fields from the LPORT table only (old logic). 7356 * Parameters: 7357 * unit - (IN) Device number 7358 * port - (IN) Port number or GPORT (see Notes) 7359 * mem - (IN) Table to modify 7360 * field_count - (IN) Number of fields to get 7361 * fields - (IN) Array of fields values to get 7362 * values - (OUT) Array of returned values 7363 * Return Value: 7364 * BCM_E_XXX 7365 * Notes: 7366 * Current valid port/gport types: 7367 * GPORT_PROXY 7368 * GPORT_xxx - should result in a valid local physical port 7369 * Not GPORT - assumes a valid local port number 7370 */ 7371 int 7372 bcm_esw_port_egr_lport_fields_get(int unit, bcm_port_t port, 7373 soc_mem_t mem, int field_count, 7374 soc_field_t *fields, uint32 *values) 7375 { 7376 int rv = BCM_E_NONE; 7377 int i; 7378 bcm_module_t lmodid; 7379 bcm_port_t lport; 7380 7381 /* Sanity check */ 7382 if((fields == NULL) || (values == NULL)) { 7383 return BCM_E_PARAM; 7384 } 7385 7386 /* Make sure port module is initialized. */ 7387 PORT_INIT(unit); 7388 7389 /* Check all fields are valid */ 7390 for (i = 0; i < field_count; i++) { 7391 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 7392 return BCM_E_UNAVAIL; 7393 } 7394 } 7395 7396 /* Resolve port */ 7397 BCM_IF_ERROR_RETURN 7398 (bcm_esw_port_egr_lport_resolve(unit, port, 7399 &lmodid, &lport)); 7400 7401 PORT_LOCK(unit); 7402 rv = bcm_esw_port_egr_lport_profile_fields_get(unit, lmodid, lport, 7403 mem, field_count, 7404 fields, values); 7405 PORT_UNLOCK(unit); 7406 7407 return rv; 7408 } 7409 7410 /* 7411 * Function: 7412 * bcm_esw_port_lport_field_set 7413 * Description: 7414 * Sets given field in the LPORT Table as follows: 7415 * - If LPORT profile is available, update field in the 7416 * LPORT Profile Table and corresponding index in the 7417 * Source Trunk Map table. 7418 * - Else, update field in the LPORT table only (old logic). 7419 * Parameters: 7420 * unit - (IN) Device number 7421 * port - (IN) Port number or GPORT (see Notes) 7422 * table_id - (IN) Index of table to modify, LPORT or RTAG7 7423 * field - (IN) Field to modify 7424 * value - (IN) New field value 7425 * Return Value: 7426 * BCM_E_XXX 7427 * Notes: 7428 * See bcm_esw_port_lport_fields_set(). 7429 */ 7430 int 7431 bcm_esw_port_lport_field_set(int unit, bcm_port_t port, 7432 int table_id, soc_field_t field, uint32 value) 7433 { 7434 /* Make sure port module is initialized. */ 7435 PORT_INIT(unit); 7436 7437 return bcm_esw_port_lport_fields_set(unit, port, 7438 table_id, 1, &field, &value); 7439 } 7440 7441 /* 7442 * Function: 7443 * bcm_esw_port_egr_lport_field_set 7444 * Description: 7445 * Sets given field in the LPORT Table as follows: 7446 * - If LPORT profile is available, update field in the 7447 * LPORT Profile Table and corresponding index in the 7448 * Source Trunk Map table. 7449 * - Else, update field in the LPORT table only (old logic). 7450 * Parameters: 7451 * unit - (IN) Device number 7452 * port - (IN) Port number or GPORT (see Notes) 7453 * mem - (IN) Table to modify 7454 * field - (IN) Field to modify 7455 * value - (IN) New field value 7456 * Return Value: 7457 * BCM_E_XXX 7458 * Notes: 7459 * See bcm_esw_port_egr_lport_fields_set(). 7460 */ 7461 int 7462 bcm_esw_port_egr_lport_field_set(int unit, bcm_port_t port, soc_mem_t mem, 7463 soc_field_t field, uint32 value) 7464 { 7465 /* Make sure port module is initialized. */ 7466 PORT_INIT(unit); 7467 7468 return bcm_esw_port_egr_lport_fields_set(unit, port, mem, 1, &field, &value); 7469 } 7470 7471 7472 /* 7473 * Function: 7474 * bcm_esw_port_lport_field_get 7475 * Description: 7476 * Gets given field from the LPORT Table as follows: 7477 * - If LPORT profile is available, gets fields from the 7478 * LPORT Profile Table and corresponding index in the 7479 * Source Trunk Map table. 7480 * - Else, get fields from the LPORT table only (old logic). 7481 * Parameters: 7482 * unit - (IN) Device number 7483 * port - (IN) Port number or GPORT (see Notes) 7484 * table_id - (IN) Index of table to modify, LPORT or RTAG7 7485 * field - (IN) Field value to get 7486 * value - (OUT) Returned value 7487 * Return Value: 7488 * BCM_E_XXX 7489 * Notes: 7490 * See bcm_esw_port_lport_fields_get(). 7491 */ 7492 int 7493 bcm_esw_port_lport_field_get(int unit, bcm_port_t port, 7494 int table_id, soc_field_t field, uint32 *value) 7495 { 7496 /* Make sure port module is initialized. */ 7497 PORT_INIT(unit); 7498 7499 return bcm_esw_port_lport_fields_get(unit, port, 7500 table_id, 1, &field, value); 7501 } 7502 7503 7504 /* 7505 * Function: 7506 * bcm_esw_port_egr_lport_field_get 7507 * Description: 7508 * Gets given field from the LPORT Table as follows: 7509 * - If LPORT profile is available, gets fields from the 7510 * LPORT Profile Table and corresponding index in the 7511 * Source Trunk Map table. 7512 * - Else, get fields from the LPORT table only (old logic). 7513 * Parameters: 7514 * unit - (IN) Device number 7515 * port - (IN) Port number or GPORT (see Notes) 7516 * mem - (IN) Table to modify 7517 * field - (IN) Field value to get 7518 * value - (OUT) Returned value 7519 * Return Value: 7520 * BCM_E_XXX 7521 * Notes: 7522 * See bcm_esw_port_egr_lport_fields_get(). 7523 */ 7524 int 7525 bcm_esw_port_egr_lport_field_get(int unit, bcm_port_t port, soc_mem_t mem, 7526 soc_field_t field, uint32 *value) 7527 { 7528 /* Make sure port module is initialized. */ 7529 PORT_INIT(unit); 7530 7531 return bcm_esw_port_egr_lport_fields_get(unit, port, mem, 1, &field, value); 7532 } 7533 7534 /* 7535 * Function: 7536 * _bcm_esw_port_tab_multi_set 7537 * Description: 7538 * Sets multiple port property fields in the HW table. 7539 * Helper funtion for bcm_esw_port_control_set. 7540 * Parameters: 7541 * unit - Device number 7542 * port - Port number (see Notes for valid port formats) 7543 * cpu_tabs - If CPU port, which ingress tables should be written? 7544 * field_count - Number of fields to modify 7545 * fields - Array of fields to modify 7546 * values - Array of new field values 7547 * Return Value: 7548 * BCM_E_NONE 7549 * BCM_E_XXX - an error occurred accessing PORT_TAB table. 7550 * Notes: 7551 * Due to the large number of callers for this routine, 7552 * function is expanded to take a GPORT PROXY, which 7553 * sets the property in the LPORT profile table (similar 7554 * to what was done for the GPORT_WLAN_PORT). 7555 * 7556 * Current valid port types are: 7557 * GPORT WLAN 7558 * GPORT PROXY 7559 * GPORT SUBPORT 7560 * BCM port (non-gport), assumes a valid local physical port 7561 * 7562 * For GPORT PROXY port, this routine only accesses the properties 7563 * in the LPORT table (not the RTAG7). 7564 */ 7565 int 7566 _bcm_esw_port_tab_multi_set(int unit, bcm_port_t port, int cpu_tabs, 7567 int field_count, soc_field_t *fields, 7568 uint32 *values) 7569 { 7570 soc_mem_t port_tab_mem = PORT_TABm; 7571 int rv = BCM_E_NONE, i, cpu_hg_index = -1; 7572 int is_lport_cfg=0, is_wlan_cfg = 0, is_in_warm_boot = 0; 7573 int index = 0, is_local_port = 0; 7574 int ptype = _BCM_ESW_PT_PORT; 7575 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 7576 && defined(INCLUDE_L3)) 7577 bcm_port_t wport = 0; 7578 #endif 7579 port_tab_entry_t pent; 7580 7581 soc_field_t port_tab_fields[SOC_MAX_MEM_FIELD_NUM]; 7582 uint32 port_tab_values[SOC_MAX_MEM_FIELD_NUM]; 7583 int port_tab_field_count = 0; 7584 soc_field_t lport_tab_fields[SOC_MAX_MEM_FIELD_NUM]; 7585 uint32 lport_tab_values[SOC_MAX_MEM_FIELD_NUM]; 7586 int lport_tab_field_count = 0; 7587 soc_field_t ing_dev_port_fields[SOC_MAX_MEM_FIELD_NUM]; 7588 uint32 ing_dev_port_values[SOC_MAX_MEM_FIELD_NUM]; 7589 int ing_dev_port_field_count = 0; 7590 7591 if ((fields == NULL) || (values == NULL) ) { 7592 return BCM_E_PARAM; 7593 } 7594 if (field_count <= 0) { 7595 return BCM_E_NONE; 7596 } 7597 7598 #if defined BCM_HGPROXY_COE_SUPPORT 7599 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 7600 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 7601 is_lport_cfg = 1; 7602 ptype = _BCM_ESW_PT_COE; 7603 } else 7604 #endif 7605 if (BCM_GPORT_IS_PROXY(port)) { 7606 is_lport_cfg = 1; 7607 ptype = _BCM_ESW_PT_HGPROXY; 7608 if(bcm_esw_port_local_get(unit, port, &port) == BCM_E_NONE) { 7609 is_local_port = 1; 7610 index = SOC_PORT_MOD_OFFSET(unit, port); 7611 } 7612 } 7613 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 7614 && defined(INCLUDE_L3)) 7615 else if (BCM_GPORT_IS_WLAN_PORT(port)) { 7616 is_wlan_cfg = 1; 7617 wport = port; 7618 } 7619 #endif 7620 7621 if (is_lport_cfg) { 7622 port_tab_mem = LPORT_TABm; 7623 } else if (!is_wlan_cfg) { 7624 /* 7625 * At this point, 'port' needs to be a BCM port (non-gport) 7626 * convert the gport to local port 7627 */ 7628 if (BCM_GPORT_IS_SET(port)) { 7629 BCM_IF_ERROR_RETURN( 7630 _bcm_esw_port_gport_validate(unit, port, &port)); 7631 } 7632 index = SOC_PORT_MOD_OFFSET(unit, port); 7633 port_tab_mem = SOC_PORT_MEM_TAB(unit, port); 7634 } 7635 7636 if (!is_wlan_cfg && port_tab_mem == PORT_TABm && 7637 (!IS_CPU_PORT(unit, port) || (cpu_tabs & _BCM_CPU_TABS_ETHER))) { 7638 sal_memset(&pent, 0, sizeof(pent)); 7639 if (port_tab_mem == PORT_TABm && 7640 SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 7641 port_tab_mem = ING_DEVICE_PORTm; 7642 } 7643 BCM_IF_ERROR_RETURN( 7644 soc_mem_read(unit, port_tab_mem, MEM_BLOCK_ANY, index, &pent)); 7645 } 7646 7647 /* Loop to set field values into corresponding memory */ 7648 for (i = 0; i < field_count; i++) { 7649 /* If LPORT, then set property in LPORT table */ 7650 if (is_lport_cfg) { 7651 #if defined(CANCUN_SUPPORT) 7652 if(SOC_IS_TRIDENT3X(unit)) { 7653 if(soc_cancun_cmh_check(unit, port_tab_mem, fields[i]) 7654 == SOC_E_NONE) { 7655 rv = soc_cancun_cmh_mem_set(unit, port_tab_mem, port, 7656 fields[i], values[i]); 7657 } 7658 _bcm_td3_port_tab_conv(unit, &fields[i], &port_tab_mem); 7659 } 7660 #endif 7661 soc_mem_set_field_value_array(lport_tab_fields, fields[i], 7662 lport_tab_values, values[i], 7663 lport_tab_field_count); 7664 7665 /* Synchronize PORT and LPORT profile tables if port is local*/ 7666 if(is_local_port) { 7667 if(SOC_MEM_FIELD_VALID(unit, port_tab_mem, fields[i])) { 7668 soc_mem_set_field_value_array(port_tab_fields, fields[i], 7669 port_tab_values, values[i], 7670 port_tab_field_count); 7671 } 7672 } 7673 7674 continue; 7675 } 7676 7677 /* GPORT WLAN */ 7678 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 7679 && defined(INCLUDE_L3)) 7680 7681 if (is_wlan_cfg) { 7682 #if defined(BCM_TRIUMPH3_SUPPORT) 7683 if (soc_feature(unit, soc_feature_axp)) { 7684 rv = _bcm_tr3_wlan_port_set(unit, wport, fields[i], values[i]); 7685 } else 7686 #endif /* BCM_TRIUMPH3_SUPPORT */ 7687 if (soc_feature(unit, soc_feature_wlan)) { 7688 rv = _bcm_tr2_wlan_port_set(unit, wport, fields[i], values[i]); 7689 } 7690 if (rv != BCM_E_NONE) { 7691 return rv; 7692 } 7693 continue; 7694 } 7695 #endif 7696 7697 /* BCM port (non-gport) */ 7698 #if defined(CANCUN_SUPPORT) 7699 if (SOC_IS_TRIDENT3X(unit)) { 7700 port_tab_mem = PORT_TABm; 7701 if (soc_cancun_cmh_check(unit, port_tab_mem, fields[i]) 7702 == SOC_E_NONE) { 7703 rv = soc_cancun_cmh_mem_set(unit, port_tab_mem, port, 7704 fields[i], values[i]); 7705 continue; 7706 } 7707 _bcm_td3_port_tab_conv(unit, &fields[i], &port_tab_mem); 7708 } 7709 #endif 7710 if (!SOC_MEM_FIELD_VALID(unit, port_tab_mem, fields[i])) { 7711 LOG_INFO(BSL_LS_SOC_CANCUN, (BSL_META_U(unit, 7712 "%s.%s is INVALID\n"), 7713 SOC_MEM_NAME(unit, port_tab_mem), 7714 SOC_FIELD_NAME(unit, fields[i]))); 7715 return (BCM_E_UNAVAIL); 7716 } 7717 7718 if ((!IS_CPU_PORT(unit, port) || (cpu_tabs & _BCM_CPU_TABS_ETHER)) || 7719 (IS_CPU_PORT(unit, port) && 7720 (cpu_tabs & _BCM_CPU_TABS_HIGIG) && 7721 (port_tab_mem == PORT_TABm))) { 7722 switch (port_tab_mem) { 7723 #ifdef BCM_TUCANA_SUPPORT 7724 case PORT_TAB1m: 7725 #endif 7726 case PORT_TABm: 7727 if ((soc_mem_field32_get(unit, port_tab_mem, 7728 &pent, fields[i]) != values[i]) || 7729 (fields[i] == TRILL_ENABLEf) || 7730 (fields[i] == ALLOW_TRILL_FRAMESf) || 7731 (fields[i] == ALLOW_NON_TRILL_FRAMESf) || 7732 (fields[i] == COPY_CORE_IS_IS_TO_CPUf) || 7733 (fields[i] == RTAG7_HASH_CFG_SEL_TRILL_ECMPf)) { 7734 soc_mem_field32_set(unit, port_tab_mem, 7735 &pent, fields[i], values[i]); 7736 soc_mem_set_field_value_array(port_tab_fields, 7737 fields[i], port_tab_values, values[i], 7738 port_tab_field_count); 7739 if ((SOC_MEM_IS_VALID(unit, LPORT_TABm)) && 7740 (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TD2P_TT2P(unit) || 7741 SOC_IS_APACHE(unit) || 7742 soc_feature(unit, 7743 soc_feature_sync_port_lport_tab))) { 7744 soc_mem_set_field_value_array(lport_tab_fields, 7745 fields[i], lport_tab_values, values[i], 7746 lport_tab_field_count); 7747 } 7748 } 7749 break; 7750 case LPORT_TABm: 7751 soc_mem_set_field_value_array(lport_tab_fields, fields[i], 7752 lport_tab_values, values[i], 7753 lport_tab_field_count); 7754 break; 7755 case ING_DEVICE_PORTm: 7756 soc_mem_set_field_value_array(ing_dev_port_fields, 7757 fields[i], 7758 ing_dev_port_values, 7759 values[i], 7760 ing_dev_port_field_count); 7761 break; 7762 default: 7763 soc_mem_field32_modify(unit, port_tab_mem, port, 7764 fields[i], values[i]); 7765 continue; 7766 } 7767 } 7768 } 7769 7770 /* wlan_cfg is handled outside of this function */ 7771 if (is_wlan_cfg == 1) { 7772 return BCM_E_NONE; 7773 } 7774 7775 is_in_warm_boot = (inside_bcm_shutdown[unit] == TRUE) || 7776 SOC_WARM_BOOT(unit); 7777 7778 /* Apply the changes to tables their field_count is not 0 */ 7779 if (port_tab_field_count != 0) { 7780 if (port_tab_mem == PORT_TABm && 7781 (!IS_CPU_PORT(unit, port) || (cpu_tabs & _BCM_CPU_TABS_ETHER))) { 7782 BCM_IF_ERROR_RETURN 7783 (soc_mem_write(unit, port_tab_mem, MEM_BLOCK_ALL, index, &pent)); 7784 } else { 7785 if ((!IS_CPU_PORT(unit, port)) || 7786 (IS_CPU_PORT(unit, port) && (cpu_tabs & _BCM_CPU_TABS_ETHER))) { 7787 BCM_IF_ERROR_RETURN 7788 (soc_mem_fields32_modify(unit, port_tab_mem, index, 7789 port_tab_field_count, port_tab_fields, 7790 port_tab_values)); 7791 } 7792 } 7793 } 7794 7795 if (ing_dev_port_field_count != 0) { 7796 if(is_in_warm_boot) { 7797 SOC_WARM_BOOT_DONE(unit); 7798 } 7799 7800 BCM_IF_ERROR_RETURN 7801 (soc_mem_fields32_modify(unit, ING_DEVICE_PORTm, index, 7802 ing_dev_port_field_count, 7803 ing_dev_port_fields, 7804 ing_dev_port_values)); 7805 if(is_in_warm_boot) { 7806 SOC_WARM_BOOT_START(unit); 7807 } 7808 } 7809 7810 if (lport_tab_field_count != 0) { 7811 #if defined(BCM_KATANA2_SUPPORT) 7812 if (SOC_IS_KATANA2(unit) && (port > KT2_MAX_PHYSICAL_PORTS)) { 7813 /* Skip programming */; 7814 } else 7815 #endif 7816 #if defined(BCM_SABER2_SUPPORT) 7817 if (SOC_IS_SABER2(unit) && (port > SB2_MAX_PHYSICAL_PORTS)) { 7818 /* Skip programming */; 7819 } else 7820 #endif 7821 { 7822 if (is_in_warm_boot) { 7823 SOC_WARM_BOOT_DONE(unit); 7824 } 7825 7826 if (is_lport_cfg == 1) { /* remote port */ 7827 rv = bcm_esw_port_lport_fields_set(unit, port, 7828 LPORT_PROFILE_LPORT_TAB, 7829 lport_tab_field_count, 7830 lport_tab_fields, 7831 lport_tab_values); 7832 7833 if (is_in_warm_boot) { 7834 SOC_WARM_BOOT_START(unit); 7835 } 7836 return rv; 7837 } 7838 7839 BCM_IF_ERROR_RETURN 7840 (bcm_esw_port_lport_fields_set(unit, 7841 index, 7842 LPORT_PROFILE_LPORT_TAB, 7843 lport_tab_field_count, 7844 lport_tab_fields, 7845 lport_tab_values)); 7846 if (is_in_warm_boot) { 7847 SOC_WARM_BOOT_START(unit); 7848 } 7849 } 7850 } 7851 7852 /* Copy to Higig port if needed */ 7853 if (IS_CPU_PORT(unit, port) && (cpu_tabs & _BCM_CPU_TABS_HIGIG)) { 7854 cpu_hg_index = SOC_IS_KATANA2(unit) ? 7855 SOC_INFO(unit).cpu_hg_pp_port_index : 7856 SOC_INFO(unit).cpu_hg_index; 7857 7858 if (SOC_MEM_IS_VALID(unit, IPORT_TABLEm)) { 7859 if (port_tab_field_count != 0) { 7860 BCM_IF_ERROR_RETURN 7861 (soc_mem_fields32_modify(unit, IPORT_TABLEm, index, 7862 port_tab_field_count, 7863 port_tab_fields, port_tab_values)); 7864 } 7865 } else if (cpu_hg_index != -1) { 7866 if (port_tab_field_count != 0) { 7867 BCM_IF_ERROR_RETURN 7868 (soc_mem_fields32_modify(unit, port_tab_mem, cpu_hg_index, 7869 port_tab_field_count, 7870 port_tab_fields, 7871 port_tab_values)); 7872 } 7873 if (ing_dev_port_field_count != 0) { 7874 BCM_IF_ERROR_RETURN 7875 (soc_mem_fields32_modify(unit, ING_DEVICE_PORTm, 7876 cpu_hg_index, 7877 ing_dev_port_field_count, 7878 ing_dev_port_fields, 7879 ing_dev_port_values)); 7880 } 7881 if (lport_tab_field_count != 0) { 7882 if (SOC_IS_TRIDENT3X(unit)) { 7883 /* TD3TBD Should use a feature check? */ 7884 int my_modid = 0; 7885 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 7886 if (soc_feature(unit, soc_feature_lport_tab_profile)) { 7887 BCM_IF_ERROR_RETURN( 7888 bcm_esw_port_lport_profile_fields_set(unit, ptype, 7889 my_modid, cpu_hg_index, LPORT_PROFILE_LPORT_TAB, 7890 lport_tab_field_count, lport_tab_fields, 7891 lport_tab_values)); 7892 } 7893 } 7894 } 7895 } 7896 } 7897 7898 return rv; 7899 } 7900 7901 int 7902 _bcm_esw_port_tab_set_without_portlock(int unit, bcm_port_t port, int cpu_tabs, 7903 soc_field_t field, int value) 7904 { 7905 return (_bcm_esw_port_tab_multi_set(unit, port, cpu_tabs, 1, &field, 7906 (uint32*) &value)); 7907 } 7908 7909 /* 7910 * Function: 7911 * _bcm_esw_port_tab_set 7912 * Description: 7913 * Sets the port property field in the HW table. 7914 * Helper funtion for bcm_esw_port_control_set. 7915 * Parameters: 7916 * unit - Device number 7917 * port - Port number (see Notes for valid port formats) 7918 * cpu_tabs - If CPU port, which ingress tables should be written? 7919 * field - Field name within PORT_TAB table entry 7920 * value - new field value 7921 * Return Value: 7922 * BCM_E_NONE 7923 * BCM_E_XXX - an error occurred accessing PORT_TAB table. 7924 * Notes: 7925 * Due to the large number of callers for this routine, 7926 * function is expanded to take a GPORT PROXY, which 7927 * sets the property in the LPORT profile table (similar 7928 * to what was done for the GPORT_WLAN_PORT). 7929 * 7930 * Current valid port types are: 7931 * GPORT WLAN 7932 * GPORT PROXY 7933 * GPORT SUBPORT 7934 * BCM port (non-gport), assumes a valid local physical port 7935 * 7936 * For GPORT PROXY port, this routine only accesses the properties 7937 * in the LPORT table (not the RTAG7). 7938 */ 7939 int 7940 _bcm_esw_port_tab_set(int unit, bcm_port_t port, int cpu_tabs, 7941 soc_field_t field, int value) 7942 { 7943 int rv = BCM_E_UNAVAIL; 7944 PORT_LOCK(unit); 7945 rv = _bcm_esw_port_tab_set_without_portlock(unit, port, cpu_tabs, field, 7946 value); 7947 PORT_UNLOCK(unit); 7948 7949 return rv; 7950 } 7951 7952 #if defined(BCM_TRX_SUPPORT) 7953 /* 7954 * Function: 7955 * _bcm_esw_iport_tab_get 7956 * Description: 7957 * Helper funtion for bcm_esw_port_control_get. 7958 * Parameters: 7959 * unit - Device number 7960 * port - Port number 7961 * field - Field name within IPORT_TAB table entry 7962 * value - (OUT) field value 7963 * Return Value: 7964 * BCM_E_NONE 7965 * BCM_E_XXX - an error occurred accessing IPORT_TAB table. 7966 */ 7967 STATIC int 7968 _bcm_esw_iport_tab_get(int unit, bcm_port_t port, 7969 soc_field_t field, int *value) 7970 { 7971 port_tab_entry_t pent; 7972 soc_mem_t mem = INVALIDm; 7973 int rv, index = -1; 7974 7975 if (SOC_MEM_IS_VALID(unit, IPORT_TABLEm)) { 7976 mem = IPORT_TABLEm; 7977 index = SOC_PORT_MOD_OFFSET(unit, port); 7978 } else if (IS_CPU_PORT(unit, port)) { 7979 int cpu_hg_index; 7980 7981 cpu_hg_index = SOC_IS_KATANA2(unit) ? 7982 SOC_INFO(unit).cpu_hg_pp_port_index : 7983 SOC_INFO(unit).cpu_hg_index; 7984 if (cpu_hg_index != -1){ 7985 mem = PORT_TABm; 7986 index = cpu_hg_index; 7987 } 7988 } 7989 if (index == -1) { 7990 return BCM_E_UNAVAIL; 7991 } 7992 7993 if (!SOC_MEM_FIELD_VALID(unit, mem, field)) { 7994 return (BCM_E_UNAVAIL); 7995 } 7996 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 7997 index, &pent); 7998 7999 if (BCM_SUCCESS(rv)) { 8000 *value = soc_mem_field32_get(unit, mem, &pent, field); 8001 } 8002 8003 return rv; 8004 } 8005 #endif /* BCM_TRX_SUPPORT */ 8006 8007 /* 8008 * Function: 8009 * _bcm_esw_port_tab_get 8010 * Description: 8011 * Helper funtion for bcm_esw_port_control_get. 8012 * Parameters: 8013 * unit - Device number 8014 * port - Port number 8015 * field - Field name within PORT_TAB table entry 8016 * value - (OUT) field value 8017 * Return Value: 8018 * BCM_E_NONE 8019 * BCM_E_XXX - an error occurred accessing PORT_TAB table. 8020 * Notes: 8021 * Due to the large number of callers for this routine, 8022 * function is expanded to take a GPORT PROXY, which 8023 * get the property from the LPORT profile table (similar 8024 * to what was done for the GPORT_WLAN_PORT). 8025 * 8026 * Current valid port types are: 8027 * GPORT WLAN 8028 * GPORT PROXY 8029 * GPORT SUBPORT 8030 * BCM port (non-gport), assumes a valid local physical port 8031 * GPORT Local 8032 * 8033 * For GPORT PROXY port, this routine only accesses the properties 8034 * in the LPORT table (not the RTAG7). 8035 */ 8036 int 8037 _bcm_esw_port_tab_get(int unit, bcm_port_t port, 8038 soc_field_t field, int *value) 8039 { 8040 int rv = BCM_E_UNAVAIL; 8041 port_tab_entry_t pent; 8042 soc_mem_t mem; 8043 int index, is_lport_cfg = 0; 8044 uint32 value32; 8045 8046 mem = SOC_PORT_MEM_TAB(unit, port); 8047 #if defined(BCM_TRIDENT3_SUPPORT) 8048 if (SOC_IS_TRIDENT3X(unit)) { 8049 _bcm_td3_port_tab_conv(unit, &field, &mem); 8050 if (mem == LPORT_TABm) { 8051 is_lport_cfg = 1; 8052 } 8053 } 8054 #endif 8055 8056 #if defined BCM_HGPROXY_COE_SUPPORT 8057 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 8058 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 8059 is_lport_cfg = 1; 8060 } else 8061 #endif 8062 if (BCM_GPORT_IS_PROXY(port)) { 8063 is_lport_cfg = 1; 8064 } 8065 8066 /* If LPORT, then get property from LPORT table */ 8067 if (is_lport_cfg) { 8068 rv = bcm_esw_port_lport_field_get(unit, port, 8069 LPORT_PROFILE_LPORT_TAB, 8070 field, &value32); 8071 *value = value32; 8072 return rv; 8073 } 8074 8075 /* GPORT WLAN */ 8076 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 8077 && defined(INCLUDE_L3)) 8078 if (BCM_GPORT_IS_WLAN_PORT(port)) { 8079 #if defined(BCM_TRIUMPH3_SUPPORT) 8080 if (soc_feature(unit, soc_feature_axp)) { 8081 rv = bcm_tr3_wlan_lport_field_get(unit, port, field, value); 8082 } else 8083 #endif /* BCM_TRIUMPH3_SUPPORT */ 8084 if (soc_feature(unit, soc_feature_wlan)) { 8085 rv = bcm_tr2_wlan_lport_field_get(unit, port, field, value); 8086 } 8087 return rv; 8088 } 8089 #endif 8090 8091 /* At this point, 'port' needs to be a BCM port (non-gport). 8092 * convert the gport to local port. 8093 */ 8094 if (BCM_GPORT_IS_SET(port)) { 8095 BCM_IF_ERROR_RETURN( 8096 _bcm_esw_port_gport_validate(unit, port, &port)); 8097 } 8098 8099 #if defined(CANCUN_SUPPORT) 8100 if (soc_feature(unit, soc_feature_cancun)) { 8101 if (soc_cancun_cmh_check(unit, mem, field) == SOC_E_NONE) { 8102 rv = soc_cancun_cmh_mem_get(unit, mem, port, 8103 field, (void *)value); 8104 if (!BCM_SUCCESS(rv)) { 8105 return rv; 8106 } 8107 } 8108 } 8109 #endif 8110 8111 index = SOC_PORT_MOD_OFFSET(unit, port); 8112 if (!SOC_MEM_FIELD_VALID(unit, mem, field)) { 8113 return (BCM_E_UNAVAIL); 8114 } 8115 8116 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 8117 index, &pent); 8118 8119 if (BCM_SUCCESS(rv)) { 8120 *value = soc_mem_field32_get(unit, mem, &pent, field); 8121 } 8122 8123 return rv; 8124 } 8125 8126 /* 8127 * Function: 8128 * bcm_port_untagged_vlan_get 8129 * Purpose: 8130 * Retrieve the default VLAN ID for the port. 8131 * This is the VLAN ID assigned to received untagged packets. 8132 * Parameters: 8133 * unit - StrataSwitch unit number. 8134 * port - StrataSwitch port number of port to get info for 8135 * vid_ptr - (OUT) Pointer to VLAN ID for return 8136 * Returns: 8137 * BCM_E_NONE 8138 * BCM_E_INTERNAL if table read failed. 8139 */ 8140 8141 int 8142 bcm_esw_port_untagged_vlan_get(int unit, bcm_port_t port, bcm_vlan_t *vid_ptr) 8143 { 8144 bcm_port_cfg_t pcfg; 8145 int vid; 8146 int rv; 8147 8148 /* Make sure port module is initialized. */ 8149 PORT_INIT(unit); 8150 8151 if(bcm_common_oamp_port_enable_get(unit, port)) { 8152 LOG_ERROR(BSL_LS_BCM_PORT, 8153 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 8154 port)); 8155 return BCM_E_PARAM; 8156 } 8157 8158 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 8159 && defined(INCLUDE_L3)) 8160 if (BCM_GPORT_IS_WLAN_PORT(port)) { 8161 #if defined(BCM_TRIUMPH3_SUPPORT) 8162 if (SOC_IS_TRIUMPH3(unit)) { 8163 return bcm_tr3_wlan_port_untagged_vlan_get(unit, port, vid_ptr); 8164 } else 8165 #endif /* BCM_TRIUMPH3_SUPPORT */ 8166 { 8167 return bcm_tr2_wlan_port_untagged_vlan_get(unit, port, vid_ptr); 8168 } 8169 } 8170 #endif 8171 8172 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 8173 if (BCM_GPORT_IS_NIV_PORT(port)) { 8174 return bcm_trident_niv_port_untagged_vlan_get(unit, port, vid_ptr); 8175 } 8176 #endif 8177 8178 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 8179 if (BCM_GPORT_IS_EXTENDER_PORT(port)) { 8180 return bcm_tr3_extender_port_untagged_vlan_get(unit, port, vid_ptr); 8181 } 8182 #endif 8183 8184 #ifdef BCM_HGPROXY_COE_SUPPORT 8185 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 8186 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 8187 rv = _bcm_esw_port_tab_get(unit, port, PORT_VIDf, &vid); 8188 } else 8189 #endif 8190 { 8191 BCM_IF_ERROR_RETURN( 8192 _bcm_esw_port_gport_validate(unit, port, &port)); 8193 8194 PORT_LOCK(unit); 8195 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 8196 PORT_UNLOCK(unit); 8197 vid = pcfg.pc_vlan; 8198 } 8199 8200 if (BCM_SUCCESS(rv)) { 8201 *vid_ptr = vid; 8202 } else { 8203 *vid_ptr = BCM_VLAN_INVALID; 8204 } 8205 8206 LOG_INFO(BSL_LS_BCM_PORT, 8207 (BSL_META_U(unit, 8208 "bcm_port_untagged_vlan_get: u=%d p=%d vid=%d rv=%d\n"), 8209 unit, port, *vid_ptr, rv)); 8210 8211 return rv; 8212 } 8213 8214 8215 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_SCORPION_SUPPORT) 8216 /* 8217 * Function: 8218 * _bcm_port_mmu_update 8219 * Purpose: 8220 * Adjust MMU settings depending on port status. 8221 * Parameters: 8222 * unit - StrataSwitch Unit #. 8223 * port - StrataSwitch port #. 8224 * link - True if link is active, false if link is inactive. 8225 * Returns: 8226 * BCM_E_NONE 8227 * BCM_E_XXX 8228 */ 8229 8230 STATIC int 8231 _bcm_port_mmu_update(int unit, bcm_port_t port, int link) 8232 { 8233 int pause_tx, pause_rx, q_limit_enable, cos; 8234 uint32 psl_rval, opc_rval, oqc_rval; 8235 8236 if (!SOC_IS_HBX(unit)) { 8237 return (BCM_E_UNAVAIL); 8238 } 8239 8240 if (link < 0) { 8241 SOC_IF_ERROR_RETURN 8242 (bcm_esw_port_link_status_get(unit, port, &link)); 8243 } 8244 8245 SOC_IF_ERROR_RETURN 8246 (MAC_PAUSE_GET(PORT(unit, port).p_mac, unit, port, 8247 &pause_tx, &pause_rx)); 8248 8249 SOC_IF_ERROR_RETURN(READ_PORT_SHARED_LIMITr(unit, port, &psl_rval)); 8250 SOC_IF_ERROR_RETURN(READ_OP_PORT_CONFIGr(unit, port, &opc_rval)); 8251 if (link && pause_tx) { 8252 soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval, 8253 PORT_SHARED_LIMITf, 8254 SOC_IS_SC_CQ(unit) ? 0x5 : 0x3); 8255 soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval, 8256 PORT_SHARED_DYNAMICf, 1); 8257 soc_reg_field_set(unit, OP_PORT_CONFIGr, &opc_rval, 8258 PORT_LIMIT_ENABLEf, 1); 8259 q_limit_enable = 0; 8260 } else { 8261 /* Turn off */ 8262 soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval, 8263 PORT_SHARED_LIMITf, 8264 SOC_IS_SC_CQ(unit) ? 0x3fff : 0x3000); 8265 soc_reg_field_set(unit, PORT_SHARED_LIMITr, &psl_rval, 8266 PORT_SHARED_DYNAMICf, 0); 8267 soc_reg_field_set(unit, OP_PORT_CONFIGr, &opc_rval, 8268 PORT_LIMIT_ENABLEf, 0); 8269 q_limit_enable = 1; 8270 } 8271 SOC_IF_ERROR_RETURN(WRITE_PORT_SHARED_LIMITr(unit, port, psl_rval)); 8272 SOC_IF_ERROR_RETURN(WRITE_OP_PORT_CONFIGr(unit, port, opc_rval)); 8273 for (cos = 0; cos < NUM_COS(unit); cos++) { 8274 SOC_IF_ERROR_RETURN 8275 (READ_OP_QUEUE_CONFIGr(unit, port, cos, &oqc_rval)); 8276 soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &oqc_rval, 8277 Q_LIMIT_ENABLEf, q_limit_enable); 8278 SOC_IF_ERROR_RETURN 8279 (WRITE_OP_QUEUE_CONFIGr(unit, port, cos, oqc_rval)); 8280 } 8281 8282 return (BCM_E_NONE); 8283 } 8284 #endif /* BCM_BRADLEY_SUPPORT || BCM_SCORPION_SUPPORT */ 8285 8286 /* 8287 * Function: 8288 * _bcm_port_untagged_vlan_set 8289 * Purpose: 8290 * Main part of bcm_port_untagged_vlan_set. 8291 * Notes: 8292 * Port does not have to be a member of the VLAN. 8293 */ 8294 8295 STATIC int 8296 _bcm_port_untagged_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vid) 8297 { 8298 bcm_port_cfg_t pcfg; 8299 int ut_prio; 8300 #if defined(BCM_FIREBOLT_SUPPORT) 8301 bcm_vlan_t pdvid; 8302 #endif /* BCM_FIREBOLT_SUPPORT */ 8303 8304 #ifdef BCM_TRX_SUPPORT 8305 if (soc_feature(unit, soc_feature_vlan_action)) { 8306 bcm_port_t local_port; 8307 bcm_vlan_action_set_t action; 8308 #if defined(BCM_TOMAHAWK_SUPPORT) 8309 bcm_port_cfg_t pcfg; 8310 #endif 8311 BCM_IF_ERROR_RETURN( 8312 _bcm_esw_port_gport_validate(unit, port, &local_port)); 8313 8314 #if defined(BCM_TOMAHAWK3_SUPPORT) 8315 if (SOC_IS_TOMAHAWK3(unit)) { 8316 BCM_IF_ERROR_RETURN 8317 (_bcm_th3_vlan_port_default_action_get(unit, port, &action)); 8318 } else 8319 #endif 8320 { 8321 BCM_IF_ERROR_RETURN 8322 (_bcm_trx_vlan_port_default_action_get(unit, port, &action)); 8323 } 8324 action.new_outer_vlan = vid; 8325 action.priority = PORT(unit, local_port).p_ut_prio; 8326 #if defined(BCM_TOMAHAWK_SUPPORT) 8327 if (soc_feature(unit, soc_feature_decouple_protocol_vlan)){ 8328 BCM_IF_ERROR_RETURN(_bcm_trx_vlan_action_verify(unit, &action)); 8329 BCM_IF_ERROR_RETURN 8330 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 8331 pcfg.pc_vlan = action.new_outer_vlan; 8332 if (action.priority >= BCM_PRIO_MIN && 8333 action.priority <= BCM_PRIO_MAX) { 8334 pcfg.pc_new_opri = action.priority; 8335 } 8336 return (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 8337 } 8338 #endif /* BCM_TOMAHAWK2_SUPPORT */ 8339 #if defined(BCM_TOMAHAWK3_SUPPORT) 8340 if(SOC_IS_TOMAHAWK3(unit)) { 8341 return _bcm_th3_vlan_port_default_action_set(unit, port, &action); 8342 } else 8343 #endif 8344 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 8345 if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 8346 return _bcm_trx_vlan_port_default_action_profile_set(unit, port, &action); 8347 } else 8348 #endif 8349 { 8350 return _bcm_trx_vlan_port_default_action_set(unit, port, &action); 8351 } 8352 } 8353 #endif 8354 8355 BCM_IF_ERROR_RETURN 8356 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 8357 8358 #if defined(BCM_FIREBOLT_SUPPORT) 8359 pdvid = pcfg.pc_vlan; 8360 #endif /* BCM_FIREBOLT_SUPPORT */ 8361 pcfg.pc_vlan = vid; 8362 8363 BCM_IF_ERROR_RETURN 8364 (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 8365 8366 #if defined(BCM_FIREBOLT_SUPPORT) 8367 if (SOC_IS_FBX(unit)) { 8368 /* 8369 * Update default VLAN ID in VLAN_PROTOCOL_DATA 8370 */ 8371 int rv = _bcm_fb_port_untagged_vlan_data_update(unit, port, 8372 pdvid, vid); 8373 if (rv != BCM_E_NONE) { 8374 LOG_ERROR(BSL_LS_BCM_PORT, 8375 (BSL_META_U(unit, 8376 "failed updating default VLAN ID " 8377 "in VLAN_PROTOCOL_DATA: %s\n"), bcm_errmsg(rv))); 8378 } 8379 } 8380 #endif /* BCM_FIREBOLT_SUPPORT */ 8381 8382 if (!soc_feature(unit, soc_feature_remap_ut_prio)) { 8383 /* Reset the untagged port priority filter entry, if any */ 8384 8385 BCM_IF_ERROR_RETURN 8386 (bcm_esw_port_untagged_priority_get(unit, port, &ut_prio)); 8387 8388 BCM_IF_ERROR_RETURN 8389 (bcm_esw_port_untagged_priority_set(unit, port, ut_prio)); 8390 } 8391 8392 return BCM_E_NONE; 8393 } 8394 8395 /* 8396 * Function: 8397 * bcm_port_untagged_vlan_set 8398 * Purpose: 8399 * Set the default VLAN ID for the port. 8400 * This is the VLAN ID assigned to received untagged packets. 8401 * Parameters: 8402 * unit - StrataSwitch unit number. 8403 * port - StrataSwitch port number. 8404 * vid - VLAN ID used for packets that ingress the port untagged 8405 * Returns: 8406 * BCM_E_NONE 8407 * BCM_E_NOT_FOUND if vid not in VTABLE 8408 * BCM_E_INTERNAL if table read failed. 8409 * BCM_E_CONFIG - port does not belong to the VLAN 8410 * Notes: 8411 * BCM_LOCK is used because bcm_vlan_port_get is called internally 8412 * which also takes it. BCM_LOCK must be taken before PORT_LOCK. 8413 */ 8414 8415 int 8416 bcm_esw_port_untagged_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vid) 8417 { 8418 int rv; 8419 8420 VLAN_CHK_ID(unit, vid); 8421 8422 /* Make sure port module is initialized. */ 8423 PORT_INIT(unit); 8424 8425 if(bcm_common_oamp_port_enable_get(unit, port)) { 8426 LOG_ERROR(BSL_LS_BCM_PORT, 8427 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 8428 port)); 8429 return BCM_E_PARAM; 8430 } 8431 8432 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 8433 && defined(INCLUDE_L3)) 8434 if (BCM_GPORT_IS_WLAN_PORT(port)) { 8435 #if defined(BCM_TRIUMPH3_SUPPORT) 8436 if (SOC_IS_TRIUMPH3(unit)) { 8437 return bcm_tr3_wlan_port_untagged_vlan_set(unit, port, vid); 8438 } else 8439 #endif /* BCM_TRIUMPH3_SUPPORT */ 8440 { 8441 return bcm_tr2_wlan_port_untagged_vlan_set(unit, port, vid); 8442 } 8443 } 8444 #endif 8445 8446 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 8447 if (BCM_GPORT_IS_NIV_PORT(port)) { 8448 return bcm_trident_niv_port_untagged_vlan_set(unit, port, vid); 8449 } 8450 #endif 8451 8452 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 8453 if (BCM_GPORT_IS_EXTENDER_PORT(port)) { 8454 return bcm_tr3_extender_port_untagged_vlan_set(unit, port, vid); 8455 } 8456 #endif 8457 8458 #ifdef BCM_HGPROXY_COE_SUPPORT 8459 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 8460 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 8461 } else 8462 #endif 8463 { 8464 BCM_IF_ERROR_RETURN( 8465 _bcm_esw_port_gport_validate(unit, port, &port)); 8466 } 8467 8468 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TD2P_TT2P(unit) || 8469 SOC_IS_TRIDENT3X(unit) || 8470 SOC_IS_KATANAX(unit) || SOC_IS_SABER2(unit)) { 8471 BCM_IF_ERROR_RETURN 8472 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 8473 PORT_VIDf, vid)); 8474 } 8475 8476 PORT_LOCK(unit); 8477 rv = _bcm_port_untagged_vlan_set(unit, port, vid); 8478 PORT_UNLOCK(unit); 8479 8480 LOG_INFO(BSL_LS_BCM_PORT, 8481 (BSL_META_U(unit, 8482 "bcm_port_untagged_vlan_set: u=%d p=%d vid=%d rv=%d\n"), 8483 unit, port, vid, rv)); 8484 8485 return rv; 8486 } 8487 8488 /* 8489 * Function: 8490 * _bcm_esw_port_ingress_dest_enable 8491 * Purpose: 8492 * Enables/disables all forwarding to port in the last stage 8493 * of the ingress pipeline, including SOBMH and all 8494 * other types of traffic. Works for all egress ports, 8495 * including CPU port. 8496 * Parameters: 8497 * unit - (IN) Device number. 8498 * port - (IN) Port number. 8499 * enable - (IN) TRUE, forward traffic 8500 * FALSE, block traffic 8501 * Returns: 8502 * BCM_E_XXX 8503 */ 8504 int 8505 _bcm_esw_port_ingress_dest_enable(int unit, bcm_port_t port, int enable) 8506 { 8507 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK2_SUPPORT) 8508 ing_dest_port_enable_entry_t dest_e; 8509 bcm_pbmp_t dest_e_pbmp; 8510 sal_usecs_t delay; 8511 int speed; 8512 int change = FALSE; 8513 8514 SOC_IF_ERROR_RETURN 8515 (READ_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ANY, 0, &dest_e)); 8516 8517 soc_mem_pbmp_field_get(unit, ING_DEST_PORT_ENABLEm, 8518 &dest_e, PORT_BITMAPf, &dest_e_pbmp); 8519 8520 if (enable) { 8521 if (!SOC_PBMP_MEMBER(dest_e_pbmp, port)) { 8522 SOC_PBMP_PORT_ADD(dest_e_pbmp, port); 8523 change = TRUE; 8524 } 8525 } else { 8526 if (SOC_PBMP_MEMBER(dest_e_pbmp, port)) { 8527 SOC_PBMP_PORT_REMOVE(dest_e_pbmp, port); 8528 change = TRUE; 8529 } 8530 } 8531 8532 if (change) { 8533 soc_mem_pbmp_field_set(unit, ING_DEST_PORT_ENABLEm, 8534 &dest_e, PORT_BITMAPf, &dest_e_pbmp); 8535 SOC_IF_ERROR_RETURN 8536 (WRITE_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ANY, 0, &dest_e)); 8537 8538 /* 8539 * On a disable operation, ensure that no further cells 8540 * arrive to MMU in order to reconfigure the MMU safely, 8541 * and the flush mechanism in the MMU to work properly. 8542 * 8543 * This requires a delay to ensure packet EOP has arrived at MMU 8544 * (the is the only method. The time is based on the largest 8545 * possible frame at the slowest possible source port speed. 8546 */ 8547 if (!enable) { 8548 BCM_IF_ERROR_RETURN 8549 (bcm_esw_port_speed_get(unit, port, &speed)); 8550 8551 if ((speed == 10) || (speed == 100)) { 8552 delay = 8000; /* 8 msecs */ 8553 } else { 8554 /* 8555 * This assumes the CPU port can sustain 1GE performance 8556 * over the duration of an MTU. 8557 */ 8558 delay = 80; /* 80 usecs */ 8559 } 8560 sal_udelay(delay); 8561 } 8562 } 8563 8564 return BCM_E_NONE; 8565 #else /* BCM_TRIDENT2PLUS_SUPPORT */ 8566 return BCM_E_UNAVAIL; 8567 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 8568 } 8569 8570 /* 8571 * Function: 8572 * _bcmi_esw_port_linkphy_subport_dfc_update 8573 * Purpose: 8574 * Updates the DFC for the stream ids associated with Linkphy gport. 8575 * Parameters: 8576 * unit - (IN) Device number. 8577 * subport_gport - (IN) Linkphy gport. 8578 * enable - (IN) Port enable/disable status. 8579 * Returns: 8580 * BCM_E_XXX 8581 */ 8582 8583 #ifdef BCM_KATANA2_SUPPORT 8584 int 8585 _bcmi_esw_port_linkphy_subport_dfc_update(int unit, bcm_port_t subport_gport, 8586 int enable) 8587 { 8588 bcm_subport_config_t config; 8589 int stream_id = 0; 8590 8591 BCM_IF_ERROR_RETURN(bcm_esw_subport_port_get(unit, subport_gport, &config)); 8592 8593 /* Run through the streams and perform needed actions */ 8594 for (stream_id = 0; stream_id < config.num_streams; stream_id++) { 8595 BCM_IF_ERROR_RETURN(_bcmi_linkphy_subport_stream_dfc_update(unit, 8596 &config, 8597 _BCM_KT2_SUBPORT_PORT_ID_GET(subport_gport), 8598 config.stream_id_array[stream_id], enable)); 8599 } 8600 8601 return BCM_E_NONE; 8602 } 8603 8604 int 8605 _bcmi_esw_port_linkphy_subport_flush(int unit, bcm_port_t subport_gport) 8606 { 8607 bcm_subport_config_t config; 8608 int stream_id = 0; 8609 8610 BCM_IF_ERROR_RETURN(bcm_esw_subport_port_get(unit, subport_gport, &config)); 8611 8612 /* Run through the streams and perform needed actions */ 8613 for (stream_id = 0; stream_id < config.num_streams; stream_id++) { 8614 BCM_IF_ERROR_RETURN(_bcmi_linkphy_subport_stream_flush(unit, 8615 &config, 8616 _BCM_KT2_SUBPORT_PORT_ID_GET(subport_gport), 8617 config.stream_id_array[stream_id])); 8618 } 8619 8620 return BCM_E_NONE; 8621 } 8622 #endif 8623 8624 /* 8625 * Function: 8626 * _bcmi_esw_port_subport_enable_set 8627 * Purpose: 8628 * Enable/disable a subport. 8629 * Parameters: 8630 * unit - StrataSwitch unit #. 8631 * port - StrataSwitch port #. 8632 * is_subtag_port - TRUE if this is subtag port, linkphy otherwise 8633 * enable - TRUE, port is enabled, FALSE port is disabled. 8634 * Returns: 8635 * BCM_E_XXX 8636 */ 8637 int 8638 _bcmi_esw_port_subport_enable_set(int unit, bcm_port_t port, 8639 int is_subtag_port, int enable) 8640 { 8641 8642 int rv = BCM_E_NONE; 8643 8644 #ifdef BCM_KATANA2_SUPPORT 8645 pbmp_t mask; 8646 int subport_gport = port; 8647 8648 BCM_IF_ERROR_RETURN( 8649 _bcm_esw_port_gport_validate(unit, port, &port)); 8650 8651 /* Set/Unset the port in the relevant enabled pbmp */ 8652 if(is_subtag_port) { 8653 8654 /* Check if the setting is already in effect */ 8655 if((enable && 8656 BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_subtag_pp_port_pbm, 8657 port)) || 8658 (!enable && 8659 !(BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_subtag_pp_port_pbm, 8660 port)))) { 8661 /* Already in effect, return OK */ 8662 return BCM_E_NONE; 8663 } 8664 8665 if(enable) { 8666 BCM_PBMP_PORT_ADD(SOC_INFO(unit).enabled_subtag_pp_port_pbm, 8667 port); 8668 } else { 8669 BCM_PBMP_PORT_REMOVE(SOC_INFO(unit).enabled_subtag_pp_port_pbm, 8670 port); 8671 } 8672 } else { 8673 8674 /* Check if the setting is already in effect */ 8675 if((enable && 8676 BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_linkphy_pp_port_pbm, 8677 port)) || 8678 (!enable && 8679 !(BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_linkphy_pp_port_pbm, 8680 port)))) { 8681 /* Already in effect, return OK */ 8682 return BCM_E_NONE; 8683 } 8684 8685 if(enable) { 8686 BCM_PBMP_PORT_ADD(SOC_INFO(unit).enabled_linkphy_pp_port_pbm, 8687 port); 8688 } else { 8689 BCM_PBMP_PORT_REMOVE(SOC_INFO(unit).enabled_linkphy_pp_port_pbm, 8690 port); 8691 } 8692 } 8693 8694 /* Get the current mask */ 8695 soc_link_mask2_get(unit, &mask); 8696 /* Make a call so that the enable/disable we did above take effect, 8697 * note that 'soc_link_mask2_set' works on the pbmps we updated above, 8698 * we still pass the existing bpmp since it gets re-assigned 8699 */ 8700 SOC_IF_ERROR_RETURN(soc_link_mask2_set(unit, mask)); 8701 8702 /* Some special processing needed for enable/disable of LinkPhy ports */ 8703 if (!is_subtag_port) { 8704 8705 /* Updates DFC for the streams */ 8706 BCM_IF_ERROR_RETURN(_bcmi_esw_port_linkphy_subport_dfc_update(unit, 8707 subport_gport, enable)); 8708 if (!enable) { 8709 /* Flush the related MMU queues */ 8710 BCM_IF_ERROR_RETURN(bcm_kt2_cosq_port_flush(unit, 8711 port, bcmCosqFlushTypeQueue)); 8712 8713 /* Flush the relevant RXLP */ 8714 BCM_IF_ERROR_RETURN(_bcmi_esw_port_linkphy_subport_flush(unit, 8715 subport_gport)); 8716 } 8717 } 8718 8719 #endif 8720 8721 return rv; 8722 } 8723 8724 /* 8725 * Function: 8726 * _bcmi_esw_port_subport_enable_get 8727 * Purpose: 8728 * Get Enable/disable state of a subport. 8729 * Parameters: 8730 * unit - StrataSwitch unit #. 8731 * port - StrataSwitch port #. 8732 * is_subtag_port - TRUE if this is subtag port, linkphy otherwise 8733 * *enable - Return enable value. 8734 * Returns: 8735 * BCM_E_XXX 8736 */ 8737 int 8738 _bcmi_esw_port_subport_enable_get(int unit, bcm_port_t port, 8739 int is_subtag_port, int *enable) 8740 { 8741 int rv = BCM_E_NONE; 8742 8743 #ifdef BCM_KATANA2_SUPPORT 8744 /* Start with enabled set to 0 */ 8745 *enable = 0; 8746 8747 BCM_IF_ERROR_RETURN( 8748 _bcm_esw_port_gport_validate(unit, port, &port)); 8749 8750 /* Depending on subtag/linkphy, check if the port is enabled */ 8751 if(is_subtag_port) { 8752 if (BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_subtag_pp_port_pbm, 8753 port)) { 8754 *enable = 1; 8755 } 8756 } else { 8757 if (BCM_PBMP_MEMBER(SOC_INFO(unit).enabled_linkphy_pp_port_pbm, 8758 port)) { 8759 *enable = 1; 8760 } 8761 } 8762 rv = BCM_E_NONE; 8763 #endif 8764 8765 return rv; 8766 } 8767 8768 /* 8769 * Function: 8770 * bcm_port_enable_set 8771 * Purpose: 8772 * Physically enable/disable the MAC/PHY on this port. 8773 * Parameters: 8774 * unit - StrataSwitch unit #. 8775 * port - StrataSwitch port #. 8776 * enable - TRUE, port is enabled, FALSE port is disabled. 8777 * Returns: 8778 * BCM_E_XXX 8779 * Notes: 8780 * If linkscan is running, it also controls the MAC enable state. 8781 */ 8782 8783 int 8784 bcm_esw_port_enable_set(int unit, bcm_port_t port, int enable) 8785 { 8786 int rv = BCM_E_NONE; 8787 int link, loopback = BCM_PORT_LOOPBACK_NONE; 8788 pbmp_t mask; 8789 8790 #if defined (BCM_TRIUMPH3_SUPPORT) || defined (BCM_MONTEREY_SUPPPORT) 8791 int skip_phy_en = 0; 8792 #endif /* BCM_TRIUMPH3_SUPPORT */ 8793 soc_persist_t *sop = SOC_PERSIST(unit); 8794 8795 #if defined(BCM_KATANA2_SUPPORT) 8796 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 8797 uint8 is_subtag_port = FALSE, is_linkphy_port = FALSE; 8798 #endif 8799 /* Make sure port module is initialized. */ 8800 PORT_INIT(unit); 8801 8802 #ifdef BCM_KATANA2_SUPPORT 8803 if(BCM_GPORT_IS_SUBPORT_PORT(port)) { 8804 if (soc_feature(unit, soc_feature_subtag_coe) && 8805 _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 8806 is_subtag_port = TRUE; 8807 } else if (soc_feature(unit, soc_feature_linkphy_coe) && 8808 _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)) { 8809 is_linkphy_port = TRUE; 8810 } 8811 if(is_subtag_port || is_linkphy_port) { 8812 PORT_LOCK(unit); 8813 rv = _bcmi_esw_port_subport_enable_set(unit, port, 8814 is_subtag_port, enable); 8815 PORT_UNLOCK(unit); 8816 return rv; 8817 } 8818 } 8819 #endif 8820 8821 /* Call Port Control module */ 8822 if (SOC_USE_PORTCTRL(unit)) { 8823 return (bcmi_esw_portctrl_enable_set(unit, port, enable)); 8824 } 8825 8826 if(bcm_common_oamp_port_enable_get(unit, port)) { 8827 LOG_ERROR(BSL_LS_BCM_PORT, 8828 (BSL_META("Error: Cannot enable OAMP Port %d.\n"), 8829 port)); 8830 return BCM_E_PARAM; 8831 } 8832 8833 #if defined(BCM_KATANA2_SUPPORT) 8834 #if defined(BCM_SABER2_SUPPORT) 8835 if(SOC_IS_SABER2(unit)) { 8836 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 8837 } 8838 #endif 8839 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 8840 (!((port >= 1) && (port <= max_phy_port)))) { 8841 return BCM_E_PORT; 8842 } 8843 #endif 8844 8845 if (!BCM_GPORT_IS_SET(port)) { 8846 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)) { 8847 return BCM_E_PORT; 8848 } 8849 } 8850 8851 BCM_IF_ERROR_RETURN( 8852 _bcm_esw_port_gport_validate(unit, port, &port)); 8853 8854 #ifdef BCM_RCPU_SUPPORT 8855 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 8856 return BCM_E_PORT; 8857 } 8858 #endif /* BCM_RCPU_SUPPORT */ 8859 8860 #ifdef BCM_TRIUMPH3_SUPPORT 8861 if (SOC_IS_TRIUMPH3(unit) && !enable) { 8862 _bcm_esw_ibod_syn_port_down(unit, port); 8863 } 8864 #endif /* BCM_TRIUMPH3_SUPPORT */ 8865 8866 PORT_LOCK(unit); 8867 8868 bcm_esw_port_loopback_get(unit, port, &loopback); 8869 8870 if (enable) { 8871 if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) { 8872 PORT_UNLOCK(unit); 8873 return BCM_E_NONE; 8874 } 8875 8876 #ifdef BCM_TRIUMPH3_SUPPORT 8877 if (!skip_phy_en) { 8878 #endif /* BCM_TRIUMPH3_SUPPORT */ 8879 #ifdef BCM_TRIDENT2_SUPPORT 8880 /* 8881 * When the PHY is TSC and port is configured to MAC loopback, 8882 * need to unsquelch TX LANE. 8883 */ 8884 if ((SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit)) 8885 && (loopback == BCM_PORT_LOOPBACK_MAC)) { 8886 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, FALSE); 8887 } 8888 #endif /* BCM_TRIDENT2_SUPPORT */ 8889 rv = soc_phyctrl_enable_set(unit, port, TRUE); 8890 #ifdef BCM_TRIUMPH3_SUPPORT 8891 } 8892 #endif /* BCM_TRIUMPH3_SUPPORT */ 8893 if (SOC_SUCCESS(rv)) { 8894 /* Get link status after PHY state has been set */ 8895 rv = bcm_esw_port_link_status_get(unit, port, &link); 8896 if (BCM_FAILURE(rv)) { 8897 if (rv == BCM_E_INIT) { 8898 link = FALSE; 8899 rv = BCM_E_NONE; 8900 } else { 8901 PORT_UNLOCK(unit); 8902 return rv; 8903 } 8904 } 8905 8906 if (link || (loopback != BCM_PORT_LOOPBACK_NONE) 8907 || SOC_PBMP_MEMBER(sop->lc_pbm_fc, port) 8908 || SOC_PBMP_MEMBER(sop->lc_pbm_linkdown_tx, port)) { 8909 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE); 8910 if (loopback == BCM_PORT_LOOPBACK_MAC) { 8911 /* Add port to EPC_LINK */ 8912 soc_link_mask2_get(unit, &mask); 8913 SOC_PBMP_PORT_ADD(mask, port); 8914 rv = soc_link_mask2_set(unit, mask); 8915 if (BCM_FAILURE(rv)) { 8916 PORT_UNLOCK(unit); 8917 return (rv); 8918 } 8919 } 8920 } 8921 } 8922 8923 if (SOC_SUCCESS(rv)) { 8924 /* Enable forwarding traffic */ 8925 if (soc_feature(unit, soc_feature_ingress_dest_port_enable)) { 8926 rv = _bcm_esw_port_ingress_dest_enable(unit, port, enable); 8927 if (BCM_FAILURE(rv)) { 8928 PORT_UNLOCK(unit); 8929 return rv; 8930 } 8931 } 8932 } 8933 8934 } else { 8935 8936 /* Disable all forwarding traffic */ 8937 if (soc_feature(unit, soc_feature_ingress_dest_port_enable)) { 8938 rv = _bcm_esw_port_ingress_dest_enable(unit, port, enable); 8939 if (BCM_FAILURE(rv)) { 8940 PORT_UNLOCK(unit); 8941 return rv; 8942 } 8943 } 8944 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) 8945 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 8946 bcm_port_info_t tmp_port_info; 8947 bcm_port_info_t_init(&tmp_port_info); 8948 tmp_port_info.linkstatus = BCM_PORT_LINK_STATUS_DOWN; 8949 SOC_LINKSCAN_MODPORT_MAP_LOCK(unit); 8950 rv = _bcm_td_stk_modport_map_linkscan_handler(unit, port, 8951 &tmp_port_info); 8952 SOC_LINKSCAN_MODPORT_MAP_UNLOCK(unit); 8953 if (BCM_FAILURE(rv)) { 8954 PORT_UNLOCK(unit); 8955 return (rv); 8956 } 8957 } 8958 #endif /* #(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) */ 8959 /* Remove from EPC_LINK to prevent packet queued to this port from TX */ 8960 soc_link_mask2_get(unit, &mask); 8961 SOC_PBMP_PORT_REMOVE(mask, port); 8962 rv = soc_link_mask2_set(unit, mask); 8963 if (BCM_FAILURE(rv)) { 8964 PORT_UNLOCK(unit); 8965 return (rv); 8966 } 8967 LOG_VERBOSE(BSL_LS_BCM_PORT, 8968 (BSL_META_U(unit, 8969 "Disable and isolate port %d..\n"), 8970 port)); 8971 if ((!SOC_IS_TD2_TT2(unit) && (loopback != BCM_PORT_LOOPBACK_MAC)) || 8972 (SOC_IS_TOMAHAWKX(unit) && (loopback != BCM_PORT_LOOPBACK_MAC))) { 8973 /* Disable MAC RX to prevent traffic going into this port */ 8974 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 8975 SOC_MAC_CONTROL_RX_SET, FALSE); 8976 sal_udelay(100); /* Wait for 1 jumbo packet transmission time */ 8977 } 8978 8979 #ifdef BCM_KATANA_SUPPORT 8980 if (SOC_IS_KATANA(unit)) { 8981 /* 8982 * When the port is configured to MAC loopback, 8983 * can't disabling MAC. 8984 * But in Saber2, credits are released when MAC goes down. 8985 */ 8986 if (SOC_IS_SABER2(unit) || (loopback != BCM_PORT_LOOPBACK_MAC)) { 8987 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE); 8988 } 8989 if ((SOC_SUCCESS(rv))) { 8990 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 8991 SOC_MAC_CONTROL_DISABLE_PHY, TRUE); 8992 rv = soc_phyctrl_enable_set(unit, port, FALSE); 8993 if (BCM_FAILURE(rv)) { 8994 LOG_WARN(BSL_LS_BCM_PORT, 8995 (BSL_META_U(unit, 8996 "u=%d p=%d soc_phyctrl_enable_set rv=%d\n"), 8997 unit, port, rv)); 8998 } 8999 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 9000 SOC_MAC_CONTROL_DISABLE_PHY, FALSE); 9001 } 9002 } else 9003 #endif /* BCM_KATANA_SUPPORT */ 9004 { 9005 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 9006 SOC_MAC_CONTROL_DISABLE_PHY, TRUE); 9007 9008 #ifdef BCM_TRIDENT2_SUPPORT 9009 /* 9010 * When the PHY is TSC and port is configured to MAC loopback, 9011 * need to squelch the TX lane instead of disabling PHY. 9012 */ 9013 if ((SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit)) 9014 && (loopback == BCM_PORT_LOOPBACK_MAC)) { 9015 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, TRUE); 9016 } else 9017 #endif /* BCM_TRIDENT2_SUPPORT */ 9018 { 9019 rv = soc_phyctrl_enable_set(unit, port, FALSE); 9020 } 9021 9022 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 9023 SOC_MAC_CONTROL_DISABLE_PHY, FALSE); 9024 /* 9025 * When the port is configured to MAC loopback, 9026 * can't disabling MAC. 9027 */ 9028 if (SOC_IS_SABER2(unit) || (loopback != BCM_PORT_LOOPBACK_MAC)) { 9029 if (SOC_SUCCESS(rv)) { 9030 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE); 9031 } 9032 } 9033 } 9034 } 9035 9036 #ifdef BCM_SABER2_SUPPORT 9037 if (SOC_IS_SABER2(unit)) { 9038 rv = soc_saber2_port_enable_set(unit, port, enable); 9039 if (BCM_FAILURE(rv)) { 9040 LOG_WARN(BSL_LS_BCM_PORT, 9041 (BSL_META_U(unit, 9042 "u=%d p=%d soc_saber2_port_enable_set rv=%d\n"), 9043 unit, port, rv)); 9044 } 9045 } else 9046 #endif 9047 #ifdef BCM_KATANA2_SUPPORT 9048 if (SOC_IS_KATANA2(unit)) { 9049 rv = soc_katana2_port_enable_set(unit, port, enable); 9050 if (BCM_FAILURE(rv)) { 9051 LOG_WARN(BSL_LS_BCM_PORT, 9052 (BSL_META_U(unit, 9053 "u=%d p=%d soc_katana2_port_enable_set rv=%d\n"), 9054 unit, port, rv)); 9055 } 9056 } 9057 #endif 9058 #ifdef BCM_TRIDENT2_SUPPORT 9059 if (SOC_IS_TD2_TT2(unit)) { 9060 PORT(unit, port).enable = enable; 9061 } 9062 #endif /* BCM_TRIDENT2_SUPPORT */ 9063 9064 #ifdef SW_AUTONEG_SUPPORT 9065 rv = _bcm_esw_port_notify_link_down_evt(unit, port); 9066 if (BCM_FAILURE(rv)) { 9067 LOG_WARN(BSL_LS_BCM_PORT, 9068 (BSL_META_U(unit, 9069 "u=%d p=%d NOTIFY LINK DOWN EVT rv=%d\n"), 9070 unit, port, rv)); 9071 PORT_UNLOCK(unit); 9072 return rv; 9073 } 9074 #endif 9075 9076 PORT_UNLOCK(unit); 9077 9078 if (loopback != BCM_PORT_LOOPBACK_NONE) { 9079 if (loopback == BCM_PORT_LOOPBACK_MAC) { 9080 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, TRUE); 9081 } else { 9082 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, enable); 9083 } 9084 } 9085 LOG_INFO(BSL_LS_BCM_PORT, 9086 (BSL_META_U(unit, 9087 "bcm_port_enable_set: u=%d p=%d enable=%d rv=%d\n"), 9088 unit, port, enable, rv)); 9089 9090 #ifdef BCM_WARM_BOOT_SUPPORT 9091 SOC_CONTROL_LOCK(unit); 9092 SOC_CONTROL(unit)->scache_dirty = 1; 9093 SOC_CONTROL_UNLOCK(unit); 9094 #endif 9095 9096 return rv; 9097 } 9098 9099 /* 9100 * Function: 9101 * bcm_port_enable_get 9102 * Purpose: 9103 * Gets the enable state as defined by bcm_port_enable_set() 9104 * Parameters: 9105 * unit - StrataSwitch unit #. 9106 * port - StrataSwitch port #. 9107 * enable - (OUT) TRUE, port is enabled, FALSE port is disabled. 9108 * Returns: 9109 * BCM_E_XXX 9110 * Notes: 9111 * The PHY enable holds the port enable state set by the user. 9112 * The MAC enable transitions up and down automatically via linkscan 9113 * even if user port enable is always up. 9114 */ 9115 9116 int 9117 bcm_esw_port_enable_get(int unit, bcm_port_t port, int *enable) 9118 { 9119 int rv=BCM_E_NONE; 9120 #if defined(BCM_KATANA2_SUPPORT) 9121 uint8 is_subtag_port = FALSE, is_linkphy_port = FALSE; 9122 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 9123 #endif 9124 9125 /* Make sure port module is initialized. */ 9126 PORT_INIT(unit); 9127 9128 /* Check for PortMod */ 9129 if (SOC_USE_PORTCTRL(unit)) { 9130 return bcmi_esw_portctrl_enable_get(unit, port, enable); 9131 } 9132 9133 if(bcm_common_oamp_port_enable_get(unit, port)) { 9134 LOG_ERROR(BSL_LS_BCM_PORT, 9135 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 9136 port)); 9137 return BCM_E_PARAM; 9138 } 9139 9140 #if defined(BCM_KATANA2_SUPPORT) 9141 #if defined(BCM_SABER2_SUPPORT) 9142 if(SOC_IS_SABER2(unit)) { 9143 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 9144 } 9145 #endif 9146 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 9147 (!((port >= 1) && (port <= max_phy_port)))) { 9148 return BCM_E_PORT; 9149 } 9150 #endif 9151 9152 9153 #ifdef BCM_KATANA2_SUPPORT 9154 if(BCM_GPORT_IS_SUBPORT_PORT(port)) { 9155 if (soc_feature(unit, soc_feature_subtag_coe) && 9156 _BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 9157 is_subtag_port = TRUE; 9158 } else if (soc_feature(unit, soc_feature_linkphy_coe) && 9159 _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)) { 9160 is_linkphy_port = TRUE; 9161 } 9162 9163 if (is_subtag_port || is_linkphy_port) { 9164 return _bcmi_esw_port_subport_enable_get(unit, port, 9165 is_subtag_port, enable); 9166 } 9167 } 9168 #endif 9169 9170 BCM_IF_ERROR_RETURN( 9171 _bcm_esw_port_gport_validate(unit, port, &port)); 9172 9173 if (SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) { 9174 *enable = 0; 9175 return BCM_E_NONE; 9176 } 9177 9178 PORT_LOCK(unit); 9179 rv = soc_phyctrl_enable_get(unit, port, enable); 9180 #ifdef BCM_TRIDENT2_SUPPORT 9181 if (SOC_IS_TD2_TT2(unit)) { 9182 *enable = (PORT(unit, port).enable) & (*enable); 9183 } 9184 #endif /* BCM_TRIDENT2_SUPPORT */ 9185 9186 PORT_UNLOCK(unit); 9187 9188 LOG_INFO(BSL_LS_BCM_PORT, 9189 (BSL_META_U(unit, 9190 "bcm_port_enable_get: u=%d p=%d rv=%d enable=%d\n"), 9191 unit, port, rv, *enable)); 9192 9193 return rv; 9194 } 9195 9196 /* 9197 * Function: 9198 * _bcm_port_mode_setup 9199 * Purpose: 9200 * Set initial operating mode for a port. 9201 * Parameters: 9202 * unit - StrataSwitch unit #. 9203 * port - StrataSwitch port #. 9204 * enable - Whether to enable or disable 9205 * Returns: 9206 * BCM_E_XXX 9207 * Notes: 9208 * Must be called with PORT_LOCK held. 9209 */ 9210 9211 int 9212 _bcm_port_mode_setup(int unit, bcm_port_t port, int enable) 9213 { 9214 soc_port_if_t pif; 9215 bcm_port_ability_t local_pa, advert_pa; 9216 9217 if (SOC_USE_PORTCTRL(unit)) { 9218 return (bcmi_esw_portctrl_mode_setup(unit, port, enable)); 9219 } 9220 9221 sal_memset(&local_pa, 0, sizeof(bcm_port_ability_t)); 9222 sal_memset(&advert_pa, 0, sizeof(bcm_port_ability_t)); 9223 9224 LOG_INFO(BSL_LS_BCM_PORT, 9225 (BSL_META_U(unit, 9226 "_bcm_port_mode_setup: u=%d p=%d\n"), unit, port)); 9227 9228 SOC_IF_ERROR_RETURN(bcm_esw_port_ability_local_get(unit, port, &local_pa)); 9229 9230 if (IS_TDM_PORT(unit, port)) { 9231 return BCM_E_NONE; 9232 } 9233 9234 /* If MII supported, enable it, otherwise use TBI */ 9235 if (local_pa.interface & (SOC_PA_INTF_MII | SOC_PA_INTF_GMII | 9236 SOC_PA_INTF_SGMII | SOC_PA_INTF_XGMII)) { 9237 if (IS_GE_PORT(unit, port)) { 9238 pif = SOC_PORT_IF_GMII; 9239 } else if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port)) { 9240 if (local_pa.interface & SOC_PA_INTF_XGMII) { 9241 pif = SOC_PORT_IF_XGMII; 9242 } else { /* external GbE phy in xe port mode */ 9243 pif = SOC_PORT_IF_SGMII; 9244 } 9245 } else { 9246 pif = SOC_PORT_IF_MII; 9247 } 9248 } else if (local_pa.interface & SOC_PA_INTF_CGMII) { 9249 pif = SOC_PORT_IF_CGMII; 9250 } else { 9251 pif = SOC_PORT_IF_TBI; 9252 } 9253 9254 SOC_IF_ERROR_RETURN 9255 (soc_phyctrl_interface_set(unit, port, pif)); 9256 SOC_IF_ERROR_RETURN 9257 (MAC_INTERFACE_SET(PORT(unit, port).p_mac, unit, port, pif)); 9258 9259 if (IS_ST_PORT(unit, port)) { 9260 9261 /* Since stacking port doesn't support flow control, 9262 * make sure that PHY is not advertising flow control capabilities. 9263 */ 9264 SOC_IF_ERROR_RETURN( 9265 soc_phyctrl_ability_advert_get(unit, port, &advert_pa)); 9266 advert_pa.pause &= ~(SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM); 9267 SOC_IF_ERROR_RETURN( 9268 soc_phyctrl_ability_advert_set(unit, port, &advert_pa)); 9269 } 9270 9271 if (!SOC_WARM_BOOT(unit) && 9272 !(SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit,all), port)) ) { 9273 #ifdef BCM_RCPU_SUPPORT 9274 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 9275 /* Do not enable/disable rcpu port. */ 9276 return BCM_E_NONE; 9277 } 9278 #endif /* BCM_RCPU_SUPPORT */ 9279 SOC_IF_ERROR_RETURN 9280 (MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, enable)); 9281 } 9282 9283 return BCM_E_NONE; 9284 } 9285 9286 STATIC int 9287 _bcm_esw_port_e2ecc_hdr_set(int unit, int port, soc_higig_e2ecc_hdr_t *e2ecc_hdr) 9288 { 9289 uint64 rval64; 9290 9291 if (SOC_USE_PORTCTRL(unit)) { 9292 return bcmi_esw_portctrl_e2ecc_hdr_set(unit, port, e2ecc_hdr); 9293 } 9294 9295 if (!e2ecc_hdr) { 9296 return BCM_E_PARAM; 9297 } 9298 9299 if (SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 9300 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 9301 if (IS_CL_PORT(unit, port)) { 9302 COMPILER_64_ZERO(rval64); 9303 soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_0r, &rval64, 9304 E2ECC_MODULE_HDR_0_HIf, e2ecc_hdr->overlay1.words[0]); 9305 soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_0r, &rval64, 9306 E2ECC_MODULE_HDR_0_LOf, e2ecc_hdr->overlay1.words[1]); 9307 BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_MODULE_HDR_0r, 9308 port, 0, rval64)); 9309 9310 COMPILER_64_ZERO(rval64); 9311 soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_1r, &rval64, 9312 E2ECC_MODULE_HDR_1_HIf, e2ecc_hdr->overlay1.words[2]); 9313 soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_1r, &rval64, 9314 E2ECC_MODULE_HDR_1_LOf, e2ecc_hdr->overlay1.words[3]); 9315 BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_MODULE_HDR_1r, 9316 port, 0, rval64)); 9317 9318 COMPILER_64_ZERO(rval64); 9319 soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_0r, &rval64, 9320 E2ECC_DATA_HDR_0_HIf, e2ecc_hdr->overlay1.words[4]); 9321 soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_0r, &rval64, 9322 E2ECC_DATA_HDR_0_LOf, e2ecc_hdr->overlay1.words[5]); 9323 BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_DATA_HDR_0r, 9324 port, 0, rval64)); 9325 9326 COMPILER_64_ZERO(rval64); 9327 soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_1r, &rval64, 9328 E2ECC_DATA_HDR_1_HIf, e2ecc_hdr->overlay1.words[6]); 9329 soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_1r, &rval64, 9330 E2ECC_DATA_HDR_1_LOf, e2ecc_hdr->overlay1.words[7]); 9331 BCM_IF_ERROR_RETURN(soc_reg_set(unit, CLMAC_E2ECC_DATA_HDR_1r, 9332 port, 0, rval64)); 9333 } else { 9334 COMPILER_64_ZERO(rval64); 9335 soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_0r, &rval64, 9336 E2ECC_MODULE_HDR_0_HIf, e2ecc_hdr->overlay1.words[0]); 9337 soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_0r, &rval64, 9338 E2ECC_MODULE_HDR_0_LOf, e2ecc_hdr->overlay1.words[1]); 9339 BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_MODULE_HDR_0r, 9340 port, 0, rval64)); 9341 9342 COMPILER_64_ZERO(rval64); 9343 soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_1r, &rval64, 9344 E2ECC_MODULE_HDR_1_HIf, e2ecc_hdr->overlay1.words[2]); 9345 soc_reg64_field32_set(unit, XLMAC_E2ECC_MODULE_HDR_1r, &rval64, 9346 E2ECC_MODULE_HDR_1_LOf, e2ecc_hdr->overlay1.words[3]); 9347 BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_MODULE_HDR_1r, 9348 port, 0, rval64)); 9349 9350 COMPILER_64_ZERO(rval64); 9351 soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_0r, &rval64, 9352 E2ECC_DATA_HDR_0_HIf, e2ecc_hdr->overlay1.words[4]); 9353 soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_0r, &rval64, 9354 E2ECC_DATA_HDR_0_LOf, e2ecc_hdr->overlay1.words[5]); 9355 BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_DATA_HDR_0r, 9356 port, 0, rval64)); 9357 9358 COMPILER_64_ZERO(rval64); 9359 soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_1r, &rval64, 9360 E2ECC_DATA_HDR_1_HIf, e2ecc_hdr->overlay1.words[6]); 9361 soc_reg64_field32_set(unit, XLMAC_E2ECC_DATA_HDR_1r, &rval64, 9362 E2ECC_DATA_HDR_1_LOf, e2ecc_hdr->overlay1.words[7]); 9363 BCM_IF_ERROR_RETURN(soc_reg_set(unit, XLMAC_E2ECC_DATA_HDR_1r, 9364 port, 0, rval64)); 9365 } 9366 } else { 9367 SOC_IF_ERROR_RETURN 9368 (WRITE_XHOL_MH0r(unit, port, e2ecc_hdr->overlay1.words[0])); 9369 SOC_IF_ERROR_RETURN 9370 (WRITE_XHOL_MH1r(unit, port, e2ecc_hdr->overlay1.words[1])); 9371 SOC_IF_ERROR_RETURN 9372 (WRITE_XHOL_MH2r(unit, port, e2ecc_hdr->overlay1.words[2])); 9373 SOC_IF_ERROR_RETURN 9374 (WRITE_XHOL_MH3r(unit, port, e2ecc_hdr->overlay1.words[3])); 9375 9376 SOC_IF_ERROR_RETURN 9377 (WRITE_XHOL_D0r(unit, port, e2ecc_hdr->overlay1.words[4])); 9378 SOC_IF_ERROR_RETURN 9379 (WRITE_XHOL_D1r(unit, port, e2ecc_hdr->overlay1.words[5])); 9380 SOC_IF_ERROR_RETURN 9381 (WRITE_XHOL_D2r(unit, port, e2ecc_hdr->overlay1.words[6])); 9382 SOC_IF_ERROR_RETURN 9383 (WRITE_XHOL_D3r(unit, port, e2ecc_hdr->overlay1.words[7])); 9384 } 9385 9386 return BCM_E_NONE; 9387 } 9388 9389 #ifdef BCM_WARM_BOOT_SUPPORT 9390 #if defined(BCM_TRX_SUPPORT) 9391 STATIC int 9392 _bcm_esw_port_e2ecc_hdr_get(int unit, int port, soc_higig_e2ecc_hdr_t *e2ecc_hdr) 9393 { 9394 uint64 rval64; 9395 9396 if (SOC_USE_PORTCTRL(unit)) { 9397 return bcmi_esw_portctrl_e2ecc_hdr_get(unit, port, e2ecc_hdr); 9398 } 9399 9400 if (!e2ecc_hdr) { 9401 return BCM_E_PARAM; 9402 } 9403 9404 sal_memset(e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t)); 9405 9406 if (SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 9407 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 9408 if (IS_CL_PORT(unit, port)) { 9409 BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_MODULE_HDR_0r, 9410 port, 0, &rval64)); 9411 e2ecc_hdr->overlay1.words[0] = soc_reg64_field32_get(unit, 9412 CLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_HIf); 9413 e2ecc_hdr->overlay1.words[1] = soc_reg64_field32_get(unit, 9414 CLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_LOf); 9415 9416 BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_MODULE_HDR_1r, 9417 port, 0, &rval64)); 9418 e2ecc_hdr->overlay1.words[2] = soc_reg64_field32_get(unit, 9419 CLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_HIf); 9420 e2ecc_hdr->overlay1.words[3] = soc_reg64_field32_get(unit, 9421 CLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_LOf); 9422 9423 BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_DATA_HDR_0r, 9424 port, 0, &rval64)); 9425 e2ecc_hdr->overlay1.words[4] = soc_reg64_field32_get(unit, 9426 CLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_HIf); 9427 e2ecc_hdr->overlay1.words[5] = soc_reg64_field32_get(unit, 9428 CLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_LOf); 9429 9430 BCM_IF_ERROR_RETURN(soc_reg_get(unit, CLMAC_E2ECC_DATA_HDR_1r, 9431 port, 0, &rval64)); 9432 e2ecc_hdr->overlay1.words[6] = soc_reg64_field32_get(unit, 9433 CLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_HIf); 9434 e2ecc_hdr->overlay1.words[7] = soc_reg64_field32_get(unit, 9435 CLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_LOf); 9436 } else { 9437 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_MODULE_HDR_0r, 9438 port, 0, &rval64)); 9439 e2ecc_hdr->overlay1.words[0] = soc_reg64_field32_get(unit, 9440 XLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_HIf); 9441 e2ecc_hdr->overlay1.words[1] = soc_reg64_field32_get(unit, 9442 XLMAC_E2ECC_MODULE_HDR_0r, rval64, E2ECC_MODULE_HDR_0_LOf); 9443 9444 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_MODULE_HDR_1r, 9445 port, 0, &rval64)); 9446 e2ecc_hdr->overlay1.words[2] = soc_reg64_field32_get(unit, 9447 XLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_HIf); 9448 e2ecc_hdr->overlay1.words[3] = soc_reg64_field32_get(unit, 9449 XLMAC_E2ECC_MODULE_HDR_1r, rval64, E2ECC_MODULE_HDR_1_LOf); 9450 9451 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_DATA_HDR_0r, 9452 port, 0, &rval64)); 9453 e2ecc_hdr->overlay1.words[4] = soc_reg64_field32_get(unit, 9454 XLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_HIf); 9455 e2ecc_hdr->overlay1.words[5] = soc_reg64_field32_get(unit, 9456 XLMAC_E2ECC_DATA_HDR_0r, rval64, E2ECC_DATA_HDR_0_LOf); 9457 9458 BCM_IF_ERROR_RETURN(soc_reg_get(unit, XLMAC_E2ECC_DATA_HDR_1r, 9459 port, 0, &rval64)); 9460 e2ecc_hdr->overlay1.words[6] = soc_reg64_field32_get(unit, 9461 XLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_HIf); 9462 e2ecc_hdr->overlay1.words[7] = soc_reg64_field32_get(unit, 9463 XLMAC_E2ECC_DATA_HDR_1r, rval64, E2ECC_DATA_HDR_1_LOf); 9464 } 9465 } else { 9466 SOC_IF_ERROR_RETURN 9467 (READ_XHOL_MH0r(unit, port, &e2ecc_hdr->overlay1.words[0])); 9468 SOC_IF_ERROR_RETURN 9469 (READ_XHOL_MH1r(unit, port, &e2ecc_hdr->overlay1.words[1])); 9470 SOC_IF_ERROR_RETURN 9471 (READ_XHOL_MH2r(unit, port, &e2ecc_hdr->overlay1.words[2])); 9472 SOC_IF_ERROR_RETURN 9473 (READ_XHOL_MH3r(unit, port, &e2ecc_hdr->overlay1.words[3])); 9474 9475 SOC_IF_ERROR_RETURN 9476 (READ_XHOL_D0r(unit, port, &e2ecc_hdr->overlay1.words[4])); 9477 SOC_IF_ERROR_RETURN 9478 (READ_XHOL_D1r(unit, port, &e2ecc_hdr->overlay1.words[5])); 9479 SOC_IF_ERROR_RETURN 9480 (READ_XHOL_D2r(unit, port, &e2ecc_hdr->overlay1.words[6])); 9481 SOC_IF_ERROR_RETURN 9482 (READ_XHOL_D3r(unit, port, &e2ecc_hdr->overlay1.words[7])); 9483 } 9484 9485 return BCM_E_NONE; 9486 } 9487 #endif 9488 #endif /* BCM_WARM_BOOT_SUPPORT */ 9489 9490 #ifdef BCM_WARM_BOOT_SUPPORT 9491 9492 STATIC int 9493 _bcm_port_vd_pbvl_reinit(int unit) 9494 { 9495 9496 #if defined(BCM_TRX_SUPPORT) 9497 if (SOC_IS_TRX(unit)) { 9498 /* 9499 * Reinit of vd_pbvl takes place at the end of function 9500 * _bcm_trx_vlan_action_profile_init(). This routine initializes 9501 * the VLAN profile tables first, which need to happen before 9502 * the vd_pbvl data is recovered. 9503 */ 9504 return BCM_E_NONE; 9505 } 9506 #endif /* BCM_TRX_SUPPORT */ 9507 9508 #ifdef BCM_FIREBOLT_SUPPORT 9509 if (SOC_IS_FBX(unit)) { 9510 bcm_port_t port; 9511 _bcm_port_info_t *pinfo; 9512 int idxmin, idx, i, index; 9513 int start, end; 9514 vlan_protocol_data_entry_t vde; 9515 vlan_protocol_entry_t vpe; 9516 bcm_vlan_t cvid, defvid; 9517 uint32 ft; 9518 bcm_pbmp_t all_pbmp; 9519 9520 BCM_PBMP_CLEAR(all_pbmp); 9521 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 9522 9523 #ifdef BCM_KATANA2_SUPPORT 9524 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 9525 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 9526 } 9527 if (soc_feature(unit, soc_feature_linkphy_coe) || 9528 soc_feature(unit, soc_feature_subtag_coe)) { 9529 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 9530 } 9531 #endif 9532 9533 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOL_DATAm); 9534 idx = soc_mem_index_min(unit, VLAN_PROTOCOLm); 9535 PBMP_ITER(all_pbmp, port) { 9536 9537 start = idxmin + port*16; 9538 end = start + 16; 9539 BCM_IF_ERROR_RETURN 9540 (bcm_esw_port_untagged_vlan_get(unit, port, &defvid)); 9541 for (i = start; i < end; i++) { 9542 9543 SOC_IF_ERROR_RETURN 9544 (READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, 9545 i, &vde)); 9546 cvid = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, 9547 VLAN_IDf); 9548 if ((cvid == 0) || (cvid == defvid)) { 9549 9550 continue; 9551 } 9552 9553 /* 9554 * Check against the VLAN_PROTOCOL table to see if a 9555 * valid entry exists for matching the packet protocol 9556 */ 9557 index = i - start; 9558 SOC_IF_ERROR_RETURN 9559 (READ_VLAN_PROTOCOLm(unit, MEM_BLOCK_ANY, 9560 idx+index, &vpe)); 9561 ft = 0; 9562 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, ETHERIIf)) { 9563 ft |= BCM_PORT_FRAMETYPE_ETHER2; 9564 } 9565 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, SNAPf)) { 9566 ft |= BCM_PORT_FRAMETYPE_8023; 9567 } 9568 if (soc_VLAN_PROTOCOLm_field32_get(unit, &vpe, LLCf)) { 9569 ft |= BCM_PORT_FRAMETYPE_LLC; 9570 } 9571 if (ft == 0) { 9572 /* 9573 * Something wrong here.. bail out 9574 */ 9575 continue; 9576 } 9577 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 9578 if (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, idx+index)) { 9579 /* Set as explicit VID */ 9580 _BCM_PORT_VD_PBVL_SET(pinfo, idx+index); 9581 } 9582 } 9583 } 9584 return BCM_E_NONE; 9585 } 9586 #endif /* BCM_FIREBOLT_SUPPORT */ 9587 9588 return BCM_E_NONE; 9589 } 9590 9591 #if defined(BCM_TRX_SUPPORT) 9592 /* Recover the port dtag_mode from Warm Boot cached info, if available. */ 9593 STATIC int 9594 _bcm_trx_port_dtag_mode_reinit(int unit, bcm_pbmp_t dtm_pbmp, int use_pbmp) 9595 { 9596 uint32 tpid_enable; 9597 bcm_port_t port; 9598 _bcm_port_info_t *pinfo; 9599 bcm_vlan_action_set_t action; 9600 bcm_pbmp_t all_pbmp; 9601 9602 BCM_PBMP_CLEAR(all_pbmp); 9603 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 9604 sal_memset(&action, 0, sizeof(bcm_vlan_action_set_t)); 9605 9606 #ifdef BCM_KATANA2_SUPPORT 9607 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 9608 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 9609 } 9610 if (soc_feature(unit, soc_feature_linkphy_coe) || 9611 soc_feature(unit, soc_feature_subtag_coe)) { 9612 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 9613 } 9614 #endif 9615 9616 #if defined(BCM_SABER2_SUPPORT) 9617 if(SOC_IS_SABER2(unit)){ 9618 int oamp_enable; 9619 (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable); 9620 /* Skip OAMP port for saber2 device */ 9621 if(oamp_enable) { 9622 SOC_PBMP_PORT_REMOVE(all_pbmp, 9623 _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER); 9624 } 9625 } 9626 #endif 9627 9628 PBMP_ITER(all_pbmp, port) { 9629 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 9630 BCM_IF_ERROR_RETURN 9631 (_bcm_esw_port_tab_get(unit, port, OUTER_TPID_ENABLEf, (int *)&tpid_enable)); 9632 9633 if (0 == tpid_enable) { 9634 if (use_pbmp && !BCM_PBMP_MEMBER(dtm_pbmp, port)) { 9635 /* Bitmap claims this is DT mode NONE, but it is 9636 * configured for EXTERNAL */ 9637 BCM_IF_ERROR_RETURN 9638 (soc_event_generate(unit, 9639 BCM_SWITCH_EVENT_STABLE_ERROR, 9640 SOC_STABLE_STALE, 9641 SOC_STABLE_BASIC, 0)); 9642 use_pbmp = FALSE; /* Cached info is not trustworthy */ 9643 } else { 9644 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_EXTERNAL; 9645 } 9646 } else { 9647 if (use_pbmp && BCM_PBMP_MEMBER(dtm_pbmp, port)) { 9648 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_INTERNAL; 9649 } else { 9650 pinfo->dtag_mode = BCM_PORT_DTAG_MODE_NONE; 9651 } 9652 } 9653 9654 if (!SOC_IS_SHADOW(unit) && !SOC_IS_TOMAHAWK3(unit)) { 9655 if (soc_feature(unit, soc_feature_vlan_action)) { 9656 BCM_IF_ERROR_RETURN 9657 (_bcm_trx_vlan_port_default_action_get(unit, port, &action)); 9658 9659 9660 if (bcmVlanActionAdd == action.ut_inner) { 9661 pinfo->dtag_mode |= BCM_PORT_DTAG_ADD_EXTERNAL_TAG; 9662 } 9663 9664 9665 BCM_IF_ERROR_RETURN 9666 (_bcm_trx_vlan_port_egress_default_action_get(unit, port, 9667 &action)); 9668 if ((bcmVlanActionDelete == action.dt_inner) && 9669 (bcmVlanActionDelete == action.dt_inner_prio)) { 9670 pinfo->dtag_mode |= BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG; 9671 } 9672 } 9673 } 9674 } 9675 return BCM_E_NONE; 9676 } 9677 9678 /** 9679 * Function: 9680 * _bcm_esw_hcfc_ingress_enable_check(); 9681 * Purpose: 9682 * check HCFC ingress enable status of unit. If any port ingress enable, enable =1; 9683 * 9684 * Parameters: 9685 * unit - (IN)device number 9686 * enable - (OUT) hcfc ingress enable 9687 * 9688 * Returns: 9689 * BCM_E_xxx 9690 * Notes: 9691 */ 9692 STATIC int 9693 _bcm_esw_hcfc_ingress_enable_check(int unit, int *enable) 9694 { 9695 soc_reg_t reg0, reg1; 9696 uint64 rval64, fval64; 9697 9698 if (SOC_REG_IS_VALID(unit, OOBFC_ING_PORT_EN0_64r)) { 9699 reg0 = OOBFC_ING_PORT_EN0_64r; 9700 reg1 = OOBFC_ING_PORT_EN1_64r; 9701 } else { 9702 reg0 = OOBFC_ING_PORT_EN_0_64r; 9703 reg1 = OOBFC_ING_PORT_EN_1_64r; 9704 } 9705 9706 if (!(SOC_REG_IS_VALID(unit, reg0) && SOC_REG_IS_VALID(unit, reg1))) { 9707 *enable = 0; 9708 return BCM_E_NONE; 9709 } 9710 9711 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg0, REG_PORT_ANY, 0, &rval64)); 9712 fval64 = soc_reg64_field_get(unit, reg0, rval64, ING_PORT_ENf); 9713 if(0 != fval64) { 9714 *enable = 1; 9715 return BCM_E_NONE; 9716 } 9717 else { 9718 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg1, REG_PORT_ANY, 0, &rval64)); 9719 fval64 = soc_reg64_field_get(unit, reg1, rval64, ING_PORT_ENf); 9720 if(0 != fval64) { 9721 *enable = 1; 9722 return BCM_E_NONE; 9723 } 9724 } 9725 9726 return BCM_E_NONE; 9727 } 9728 9729 /** 9730 * Function: 9731 * _bcm_esw_hcfc_egress_enable_check(); 9732 * Purpose: 9733 * check HCFC ingress enable status of unit. If any port egress enable, enable =1; 9734 * 9735 * Parameters: 9736 * unit - (IN)device number 9737 * enable - (OUT) hcfc egress enable 9738 * 9739 * Returns: 9740 * BCM_E_xxx 9741 * Notes: 9742 */ 9743 STATIC int 9744 _bcm_esw_hcfc_egress_enable_check(int unit, int *enable) 9745 { 9746 soc_reg_t reg0, reg1; 9747 uint64 rval64, fval64; 9748 9749 if (SOC_REG_IS_VALID(unit, OOBFC_ENG_PORT_EN0_64r)) { 9750 reg0 = OOBFC_ENG_PORT_EN0_64r; 9751 reg1 = OOBFC_ENG_PORT_EN1_64r; 9752 } else { 9753 reg0 = OOBFC_ENG_PORT_EN_0_64r; 9754 reg1 = OOBFC_ENG_PORT_EN_1_64r; 9755 } 9756 9757 if (!(SOC_REG_IS_VALID(unit, reg0) && SOC_REG_IS_VALID(unit, reg1))) { 9758 *enable = 0; 9759 return BCM_E_NONE; 9760 } 9761 9762 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg0, REG_PORT_ANY, 0, &rval64)); 9763 fval64 = soc_reg64_field_get(unit, reg0, rval64, ENG_PORT_ENf); 9764 if(0 != fval64) { 9765 *enable = 1; 9766 return BCM_E_NONE; 9767 } 9768 else { 9769 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg1, REG_PORT_ANY, 0, &rval64)); 9770 fval64 = soc_reg64_field_get(unit, reg1, rval64, ENG_PORT_ENf); 9771 if(0 != fval64) { 9772 *enable = 1; 9773 return BCM_E_NONE; 9774 } 9775 } 9776 9777 return BCM_E_NONE; 9778 } 9779 9780 /** 9781 * Function: 9782 * _bcm_esw_port_hcfc_ingress_enable_check(); 9783 * Purpose: 9784 * check HCFC ingress enable status of given port. 9785 * 9786 * Parameters: 9787 * unit - (IN)device number 9788 * port - (IN)port number 9789 * enable - (OUT)hcfc ingress enable 9790 * 9791 * Returns: 9792 * BCM_E_xxx 9793 * Notes: 9794 */ 9795 STATIC int 9796 _bcm_esw_port_hcfc_ingress_enable_check(int unit, bcm_port_t port, int *enable) 9797 { 9798 soc_reg_t reg, reg0, reg1; 9799 int len; 9800 uint64 rval64, fval64; 9801 uint32 fval_hi, fval_lo; 9802 9803 if (!SOC_PORT_VALID(unit, port)) { 9804 return BCM_E_PORT; 9805 } 9806 9807 if (SOC_REG_IS_VALID(unit, OOBFC_ING_PORT_EN0_64r)) { 9808 reg0 = OOBFC_ING_PORT_EN0_64r; 9809 reg1 = OOBFC_ING_PORT_EN1_64r; 9810 } else { 9811 reg0 = OOBFC_ING_PORT_EN_0_64r; 9812 reg1 = OOBFC_ING_PORT_EN_1_64r; 9813 } 9814 if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) { 9815 *enable = 0; 9816 return BCM_E_NONE; 9817 } 9818 9819 /* Configure ingress status reporting */ 9820 len = soc_reg_field_length(unit, reg0, ING_PORT_ENf); 9821 if (len < 1) { 9822 return BCM_E_PORT; 9823 } 9824 if (port < len) { /* First half of logical ports (not mmu port) */ 9825 reg = reg0; 9826 } else { /* Second half of logical ports (not mmu port) */ 9827 reg = reg1; 9828 } 9829 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 9830 fval64 = soc_reg64_field_get(unit, reg, rval64, ING_PORT_ENf); 9831 fval_hi = COMPILER_64_HI(fval64); 9832 fval_lo = COMPILER_64_LO(fval64); 9833 9834 if (port < len) { 9835 if ( port < 32 ) { 9836 *enable = fval_lo & (1 << port); 9837 } else { 9838 /* coverity[large_shift : FALSE] */ 9839 *enable = fval_hi & (1 << (port - 32)); 9840 } 9841 } else { 9842 int port_offset = port - len; 9843 if ( port_offset < 32 ) { 9844 *enable = fval_lo & (1 << port_offset); 9845 } else { 9846 *enable = fval_hi & (1 << (port_offset - 32)); 9847 } 9848 } 9849 9850 return BCM_E_NONE; 9851 } 9852 9853 /** 9854 * Function: 9855 * _bcm_esw_port_hcfc_egress_enable_check(); 9856 * Purpose: 9857 * check HCFC egress enable status of given port. 9858 * 9859 * Parameters: 9860 * unit - (IN)device number 9861 * port - (IN)port number 9862 * enable - (OUT)hcfc egress enable 9863 * 9864 * Returns: 9865 * BCM_E_xxx 9866 * Notes: 9867 */ 9868 STATIC int 9869 _bcm_esw_port_hcfc_egress_enable_check(int unit, bcm_port_t port, int *enable) 9870 { 9871 soc_reg_t reg, reg0, reg1; 9872 int len; 9873 uint64 rval64, fval64; 9874 uint32 fval_hi, fval_lo; 9875 9876 if (!SOC_PORT_VALID(unit, port)) { 9877 return BCM_E_PORT; 9878 } 9879 9880 if (SOC_REG_IS_VALID(unit, OOBFC_ENG_PORT_EN0_64r)) { 9881 reg0 = OOBFC_ENG_PORT_EN0_64r; 9882 reg1 = OOBFC_ENG_PORT_EN1_64r; 9883 } else { 9884 reg0 = OOBFC_ENG_PORT_EN_0_64r; 9885 reg1 = OOBFC_ENG_PORT_EN_1_64r; 9886 } 9887 if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) { 9888 *enable = 0; 9889 return BCM_E_NONE; 9890 } 9891 9892 /* Configure egress status reporting */ 9893 len = soc_reg_field_length(unit, reg0, ENG_PORT_ENf); 9894 if (len < 1) { 9895 return BCM_E_PORT; 9896 } 9897 if (port < len) { /* First half of logical ports (not mmu port) */ 9898 reg = reg0; 9899 } else { /* Second half of logical ports (not mmu port) */ 9900 reg = reg1; 9901 } 9902 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 9903 fval64 = soc_reg64_field_get(unit, reg, rval64, ENG_PORT_ENf); 9904 fval_hi = COMPILER_64_HI(fval64); 9905 fval_lo = COMPILER_64_LO(fval64); 9906 if (port < len) { 9907 if ( port < 32 ) { 9908 *enable = fval_lo & (1 << port); 9909 } else { 9910 /* coverity[large_shift : FALSE] */ 9911 *enable = fval_hi & (1 << (port - 32)); 9912 } 9913 } else { 9914 int port_offset = port - len; 9915 if ( port_offset < 32 ) { 9916 *enable = fval_lo & (1 << port_offset); 9917 } else { 9918 *enable = fval_hi & (1 << (port_offset - 32)); 9919 } 9920 } 9921 9922 return BCM_E_NONE; 9923 } 9924 9925 9926 STATIC int 9927 _bcm_esw_port_e2ecc_reinit(int unit) 9928 { 9929 bcm_port_t port, phy_port; 9930 bcm_port_congestion_config_t *config; 9931 int time_unit_sel = 0, time_units = 0; 9932 soc_higig_e2ecc_hdr_t e2ecc_hdr; 9933 int src_modid, src_pid; 9934 uint64 regval64; 9935 uint32 regval, field_val = 0; 9936 int tx_enabled = FALSE, rx_enabled = FALSE; 9937 int port_tx_enabled, port_rx_enabled, voqfc = 0; 9938 int hcfc_tx = 0, hcfc_rx = 0; 9939 int port_hcfc_tx = 0, port_hcfc_rx = 0; 9940 int blk, blk_num = -1, bindex = 0; 9941 #ifdef BCM_KATANA2_SUPPORT 9942 uint16 dev_id; 9943 uint8 rev_id; 9944 int e2ecc_coe = 0; 9945 int e2ecc_strict = 0; 9946 #endif 9947 #ifdef BCM_TRIDENT2PLUS_SUPPORT 9948 int fc_format; 9949 int copy_to_cpu = 0 ; 9950 #endif 9951 if (SOC_IS_SC_CQ(unit)) { 9952 SOC_IF_ERROR_RETURN(READ_E2E_HOL_ENr(unit, ®val)); 9953 if (0 != soc_reg_field_get(unit, E2E_HOL_ENr, regval, ENf)) { 9954 tx_enabled = TRUE; 9955 } 9956 } else { 9957 SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_ENr(unit, ®val)); 9958 if (0 != soc_reg_field_get(unit, E2ECC_HOL_ENr, regval, ENf)) { 9959 tx_enabled = TRUE; 9960 } 9961 } 9962 9963 BCM_IF_ERROR_RETURN(_bcm_esw_hcfc_egress_enable_check(unit, &hcfc_tx)); 9964 if (hcfc_tx) { 9965 tx_enabled = TRUE; 9966 } 9967 9968 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, ®val64)); 9969 if (0 == soc_reg64_field32_get(unit, ING_CONFIG_64r, regval64, 9970 DISABLE_E2E_HOL_CHECKf)) { 9971 rx_enabled = TRUE; 9972 } 9973 9974 BCM_IF_ERROR_RETURN(_bcm_esw_hcfc_ingress_enable_check(unit, &hcfc_rx)); 9975 if (hcfc_rx) { 9976 rx_enabled = TRUE; 9977 } 9978 9979 if (!tx_enabled && !rx_enabled) { 9980 /* Nothing further to do */ 9981 return BCM_E_NONE; 9982 } 9983 9984 PBMP_HG_ITER(unit, port) { 9985 port_tx_enabled = port_rx_enabled = FALSE; 9986 9987 if (tx_enabled) { 9988 if (hcfc_tx) { 9989 port_hcfc_tx = 0; 9990 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_egress_enable_check(unit, port, &port_hcfc_tx)); 9991 if (port_hcfc_tx) { 9992 port_tx_enabled = 1; 9993 } 9994 } 9995 else { 9996 if (soc_reg_field_valid(unit, XPORT_CONFIGr, E2E_HOL_ENf)) { 9997 SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, ®val)); 9998 port_tx_enabled = 9999 (0 != soc_reg_field_get(unit, XPORT_CONFIGr, regval, 10000 E2E_HOL_ENf)); 10001 } else { 10002 if (soc_feature(unit, soc_feature_logical_port_num)) { 10003 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 10004 } else { 10005 phy_port = port; 10006 } 10007 blk = SOC_PORT_BLOCK(unit, phy_port); 10008 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 10009 if (SOC_IS_TRIDENT2X(unit)) { 10010 blk_num = SOC_INFO(unit).port_serdes[port]; 10011 } else 10012 #endif 10013 { 10014 blk_num = SOC_BLOCK_INFO(unit, blk).number; 10015 } 10016 bindex = SOC_PORT_BINDEX(unit, phy_port); 10017 /* In TR3 E2ECC is implemented only in blocks CL, XL1 */ 10018 if (!SOC_IS_TRIUMPH3(unit) || (IS_CL_PORT(unit, port) || (blk == 13))) { 10019 if (SOC_IS_TRIUMPH3(unit)) { 10020 if (IS_CL_PORT(unit, port)) { 10021 blk_num = (blk_num ? 4 + bindex/4 : bindex/4); 10022 bindex = bindex%4; 10023 } else { 10024 blk_num = 3; 10025 } 10026 } 10027 if (SOC_IS_KATANA2(unit)) { 10028 /* In KT2 E2ECC is implemented only in blocks 6..9 */ 10029 if (blk_num >= 6) { 10030 blk_num -= 6; 10031 } 10032 } 10033 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num, 10034 ®val)); 10035 if ((regval & (1 << bindex))) { 10036 port_tx_enabled= TRUE; 10037 } 10038 } 10039 } 10040 } 10041 } 10042 10043 if (rx_enabled) { 10044 if (hcfc_rx) { 10045 port_hcfc_rx = 0; 10046 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_ingress_enable_check(unit, port, &port_hcfc_rx)); 10047 if (port_hcfc_rx) { 10048 port_rx_enabled = 1; 10049 } 10050 } 10051 else { 10052 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 10053 port_rx_enabled = 0; 10054 voqfc = 0; 10055 if (0 != soc_reg_field_get(unit, IE2E_CONTROLr, regval, HOL_ENABLEf)) { 10056 port_rx_enabled = 1; 10057 } 10058 10059 if (soc_reg_field_valid(unit, IE2E_CONTROLr, VOQFC_ENABLEf)) { 10060 if (0 != soc_reg_field_get(unit, IE2E_CONTROLr, 10061 regval, VOQFC_ENABLEf)) { 10062 port_rx_enabled = 1; 10063 voqfc = 1; 10064 } 10065 } 10066 } 10067 } 10068 10069 /* For HX4 and TR3, tx restore from OP_QUEUE_CONFIG1_CELLr */ 10070 if (SOC_IS_TRIUMPH3(unit)) { 10071 BCM_IF_ERROR_RETURN(READ_OP_QUEUE_CONFIG1_CELLr(unit, port, 0, ®val)); 10072 port_tx_enabled = soc_reg_field_get(unit,OP_QUEUE_CONFIG1_CELLr, regval, Q_E2E_DS_EN_CELLf); 10073 } 10074 10075 if (!port_tx_enabled && !port_rx_enabled) { 10076 /* On to the next port */ 10077 continue; 10078 } 10079 10080 /* Allocate space for the E2ECC configuration */ 10081 if (PORT(unit, port).e2ecc_config == NULL) { 10082 PORT(unit, port).e2ecc_config = 10083 sal_alloc(sizeof(bcm_port_congestion_config_t), 10084 "bcm_port_congestion_config"); 10085 if (PORT(unit, port).e2ecc_config == NULL) { 10086 LOG_ERROR(BSL_LS_BCM_PORT, 10087 (BSL_META_U(unit, 10088 "Error: unable to allocate memory for" 10089 " bcm_port_congestion_config.\n"))); 10090 return BCM_E_MEMORY; 10091 } 10092 } else { 10093 /* This is initialized to NULL pointers by 10094 * port init. How did it get changed? */ 10095 return BCM_E_INTERNAL; 10096 } 10097 10098 config = PORT(unit, port).e2ecc_config; 10099 bcm_port_congestion_config_t_init(config); 10100 10101 if (port_tx_enabled) { 10102 if (port_hcfc_tx) { 10103 config->flags |= BCM_PORT_CONGESTION_CONFIG_HCFC| 10104 BCM_PORT_CONGESTION_CONFIG_TX; 10105 } else { 10106 /* Recover TX state */ 10107 config->flags |= BCM_PORT_CONGESTION_CONFIG_E2ECC | 10108 BCM_PORT_CONGESTION_CONFIG_TX; 10109 10110 /* Message timer paramters to packets/sec */ 10111 if (SOC_IS_SC_CQ(unit)) { 10112 SOC_IF_ERROR_RETURN(READ_E2E_MAX_TX_TIMERr(unit, ®val)); 10113 time_unit_sel = soc_reg_field_get(unit, E2E_MAX_TX_TIMERr, 10114 regval, LGf); 10115 time_units = soc_reg_field_get(unit, E2E_MAX_TX_TIMERr, 10116 regval, TIMERf); 10117 } else { 10118 SOC_IF_ERROR_RETURN(READ_E2ECC_MAX_TX_TIMERr(unit, ®val)); 10119 time_unit_sel = soc_reg_field_get(unit, E2ECC_MAX_TX_TIMERr, 10120 regval, LGf); 10121 time_units = soc_reg_field_get(unit, E2ECC_MAX_TX_TIMERr, 10122 regval, TIMERf); 10123 SOC_IF_ERROR_RETURN(WRITE_E2ECC_MAX_TX_TIMERr(unit, regval)); 10124 } 10125 10126 /* See _bcm_esw_port_e2ecc_tx for an explanation of 10127 * the timer calculation. */ 10128 config->packets_per_sec = time_unit_sel ? 10129 (40000 / time_units) : (4000000 / time_units); 10130 10131 /* Recover the E2ECC module header 10132 * (see _bcm_esw_port_e2ecc_tx for the header format) */ 10133 BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hdr_get(unit, port, &e2ecc_hdr)); 10134 10135 config->traffic_class = 10136 (e2ecc_hdr.overlay1.words[0] >> 16) & 0x0F; 10137 config->multicast_id = e2ecc_hdr.overlay1.words[0] & 0xFFFF; 10138 10139 src_modid = (e2ecc_hdr.overlay1.words[1] >> 24) & 0xFF; 10140 src_pid = (e2ecc_hdr.overlay1.words[1] >> 16) & 0xFF; 10141 BCM_GPORT_MODPORT_SET(config->src_port, src_modid, src_pid); 10142 10143 config->color = (e2ecc_hdr.overlay1.words[1] >> 6) & 0x3; 10144 10145 config->pri = (e2ecc_hdr.overlay1.words[3] >> 29) & 0x7; 10146 config->cfi = (e2ecc_hdr.overlay1.words[3] >> 28) & 0x1; 10147 config->vlan = (e2ecc_hdr.overlay1.words[3] >> 16) & 0xfff; 10148 10149 config->dest_mac[0] = 10150 ((e2ecc_hdr.overlay1.words[4] >> 24) & 0xff); 10151 config->dest_mac[1] = 10152 ((e2ecc_hdr.overlay1.words[4] >> 16) & 0xff); 10153 config->dest_mac[2] = 10154 ((e2ecc_hdr.overlay1.words[4] >> 8) & 0xff); 10155 config->dest_mac[3] = 10156 (e2ecc_hdr.overlay1.words[4] & 0xff); 10157 config->dest_mac[4] = 10158 ((e2ecc_hdr.overlay1.words[5] >> 24) & 0xff); 10159 config->dest_mac[5] = 10160 ((e2ecc_hdr.overlay1.words[5] >> 16) & 0xff); 10161 10162 config->src_mac[0] = 10163 ((e2ecc_hdr.overlay1.words[5] >> 8) & 0xff); 10164 config->src_mac[1] = 10165 (e2ecc_hdr.overlay1.words[5] & 0xff); 10166 config->src_mac[2] = 10167 ((e2ecc_hdr.overlay1.words[6] >> 24) & 0xff); 10168 config->src_mac[3] = 10169 ((e2ecc_hdr.overlay1.words[6] >> 16) & 0xff); 10170 config->src_mac[4] = 10171 ((e2ecc_hdr.overlay1.words[6] >> 8) & 0xff); 10172 config->src_mac[5] = 10173 (e2ecc_hdr.overlay1.words[6] & 0xff); 10174 10175 config->ethertype = 10176 (e2ecc_hdr.overlay1.words[7] >> 16) & 0xFFFF; 10177 config->opcode = e2ecc_hdr.overlay1.words[7] & 0xFFFF; 10178 10179 /* All the info from RX is encoded in the header, so 10180 * just mark if it is enabled. */ 10181 if (port_rx_enabled) { 10182 config->flags |= BCM_PORT_CONGESTION_CONFIG_RX; 10183 } 10184 } 10185 } else if (port_rx_enabled) { 10186 /* Recover RX state */ 10187 config->flags |= BCM_PORT_CONGESTION_CONFIG_RX; 10188 10189 if (port_hcfc_rx) { 10190 config->flags |= BCM_PORT_CONGESTION_CONFIG_HCFC; 10191 } else if (voqfc) { 10192 config->flags |= BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL; 10193 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_MSr(unit, ®val)); 10194 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_MSr, 10195 regval, DAf); 10196 config->dest_mac[0] = ((field_val >> 8) & 0xff); 10197 config->dest_mac[1] = (field_val & 0xff); 10198 10199 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_LSr(unit, ®val)); 10200 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_LSr, 10201 regval, DAf); 10202 config->dest_mac[2] = ((field_val >> 24) & 0xff); 10203 config->dest_mac[3] = ((field_val >> 16) & 0xff); 10204 config->dest_mac[4] = ((field_val >> 8) & 0xff); 10205 config->dest_mac[5] = (field_val & 0xff); 10206 10207 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, ®val)); 10208 config->ethertype = 10209 soc_reg_field_get(unit, ING_VOQFC_IDr, regval, LENGTH_TYPEf); 10210 config->opcode = 10211 soc_reg_field_get(unit, ING_VOQFC_IDr, regval, OPCODEf); 10212 10213 } else { 10214 config->flags |= BCM_PORT_CONGESTION_CONFIG_E2ECC; 10215 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_MSr(unit, ®val)); 10216 field_val = soc_reg_field_get(unit, E2E_HOL_RX_DA_MSr, 10217 regval, DAf); 10218 config->dest_mac[0] = ((field_val >> 8) & 0xff); 10219 config->dest_mac[1] = (field_val & 0xff); 10220 10221 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_LSr(unit, ®val)); 10222 field_val = soc_reg_field_get(unit, E2E_HOL_RX_DA_LSr, 10223 regval, DAf); 10224 config->dest_mac[2] = ((field_val >> 24) & 0xff); 10225 config->dest_mac[3] = ((field_val >> 16) & 0xff); 10226 config->dest_mac[4] = ((field_val >> 8) & 0xff); 10227 config->dest_mac[5] = (field_val & 0xff); 10228 10229 SOC_IF_ERROR_RETURN 10230 (READ_E2E_HOL_RX_LENGTH_TYPEr(unit, ®val)); 10231 config->ethertype = 10232 soc_reg_field_get(unit, E2E_HOL_RX_LENGTH_TYPEr, 10233 regval, LENGTH_TYPEf); 10234 10235 SOC_IF_ERROR_RETURN 10236 (READ_E2E_HOL_RX_OPCODEr(unit, ®val)); 10237 config->opcode = 10238 soc_reg_field_get(unit, E2E_HOL_RX_OPCODEr, 10239 regval, OPCODEf); 10240 } 10241 } 10242 } 10243 #ifdef BCM_TRIDENT2PLUS_SUPPORT 10244 if (SOC_IS_TRIDENT2PLUS(unit) || 10245 (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit))) { 10246 PBMP_ALL_ITER(unit, port) { 10247 10248 if (IS_HG_PORT(unit, port)) { 10249 continue; 10250 } 10251 SOC_IF_ERROR_RETURN( 10252 READ_COE_FLOW_CONTROL_CONFIGr (unit, port, ®val)); 10253 10254 fc_format = soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr, 10255 regval, FLOW_CONTROL_FORMATf); 10256 copy_to_cpu = soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr, 10257 regval, COPY_TO_CPUf); 10258 if(!fc_format) 10259 { 10260 continue; 10261 } 10262 10263 /* Allocate space for the E2ECC configuration */ 10264 if (PORT(unit, port).e2ecc_config == NULL) { 10265 PORT(unit, port).e2ecc_config = 10266 sal_alloc(sizeof(bcm_port_congestion_config_t), 10267 "bcm_port_congestion_config"); 10268 if (PORT(unit, port).e2ecc_config == NULL) { 10269 LOG_ERROR(BSL_LS_BCM_PORT, 10270 (BSL_META_U(unit, 10271 "Error: unable to allocate memory for" 10272 " bcm_port_congestion_config.\n"))); 10273 return BCM_E_MEMORY; 10274 } 10275 } else { 10276 /* This is initialized to NULL pointers by 10277 * port init. How did it get changed? */ 10278 return BCM_E_INTERNAL; 10279 } 10280 10281 config = PORT(unit, port).e2ecc_config; 10282 bcm_port_congestion_config_t_init(config); 10283 10284 /* Recover RX state */ 10285 config->flags |= BCM_PORT_CONGESTION_CONFIG_RX; 10286 if (copy_to_cpu == 1) { 10287 config->flags |= 10288 BCM_PORT_CONGESTION_CONFIG_COPY_TO_CPU; 10289 } 10290 if (fc_format == 1) { 10291 config->flags |= 10292 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE; 10293 SOC_IF_ERROR_RETURN( 10294 READ_ING_VOQFC_MACDA_MSr(unit, ®val)); 10295 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_MSr, 10296 regval, DAf); 10297 config->dest_mac[0] = ((field_val >> 8) & 0xff); 10298 config->dest_mac[1] = (field_val & 0xff); 10299 SOC_IF_ERROR_RETURN( 10300 READ_ING_VOQFC_MACDA_LSr(unit, ®val)); 10301 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_LSr, 10302 regval, DAf); 10303 config->dest_mac[2] = ((field_val >> 24) & 0xff); 10304 config->dest_mac[3] = ((field_val >> 16) & 0xff); 10305 config->dest_mac[4] = ((field_val >> 8) & 0xff); 10306 config->dest_mac[5] = (field_val & 0xff); 10307 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, ®val)); 10308 config->ethertype = 10309 soc_reg_field_get(unit, ING_VOQFC_IDr, 10310 regval, LENGTH_TYPEf); 10311 config->opcode = 10312 soc_reg_field_get(unit, ING_VOQFC_IDr, 10313 regval, OPCODEf); 10314 10315 } else if (fc_format == 2) { 10316 config->flags |= 10317 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE; 10318 SOC_IF_ERROR_RETURN( 10319 READ_COE_VLAN_PAUSE_MACDA_MSr(unit, ®val)); 10320 field_val = soc_reg_field_get(unit, COE_VLAN_PAUSE_MACDA_MSr, 10321 regval, DAf); 10322 config->dest_mac[0] = ((field_val >> 8) & 0xff); 10323 config->dest_mac[1] = (field_val & 0xff); 10324 SOC_IF_ERROR_RETURN( 10325 READ_COE_VLAN_PAUSE_MACDA_LSr(unit, ®val)); 10326 field_val = soc_reg_field_get(unit, COE_VLAN_PAUSE_MACDA_LSr, 10327 regval, DAf); 10328 config->dest_mac[2] = ((field_val >> 24) & 0xff); 10329 config->dest_mac[3] = ((field_val >> 16) & 0xff); 10330 config->dest_mac[4] = ((field_val >> 8) & 0xff); 10331 config->dest_mac[5] = (field_val & 0xff); 10332 SOC_IF_ERROR_RETURN(READ_COE_VLAN_PAUSE_IDr(unit, ®val)); 10333 config->ethertype = 10334 soc_reg_field_get(unit, COE_VLAN_PAUSE_IDr, 10335 regval, LENGTH_TYPEf); 10336 config->opcode = 10337 soc_reg_field_get(unit, COE_VLAN_PAUSE_IDr, 10338 regval, OPCODEf); 10339 } 10340 10341 } 10342 } 10343 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 10344 #ifdef BCM_KATANA2_SUPPORT 10345 if (SOC_IS_KATANA2(unit)) { 10346 PBMP_ALL_ITER(unit, port) { 10347 port_rx_enabled = 0; 10348 e2ecc_coe = 0; 10349 10350 if (IS_HG_PORT(unit, port)) { 10351 continue; 10352 } 10353 soc_cm_get_id(unit, &dev_id, &rev_id); 10354 10355 if ((rev_id >= BCM56450_B0_REV_ID) || SOC_IS_SABER2(unit)) { 10356 SOC_IF_ERROR_RETURN( 10357 READ_COE_FLOW_CONTROL_CONFIGr (unit, port, ®val)); 10358 10359 if (soc_reg_field_valid(unit, COE_FLOW_CONTROL_CONFIGr, 10360 FLOW_CONTROL_FORMATf)) { 10361 if (0 != soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr, 10362 regval, FLOW_CONTROL_FORMATf)) { 10363 port_rx_enabled = 1; 10364 e2ecc_coe = 1; 10365 e2ecc_strict = soc_reg_field_get(unit, 10366 COE_FLOW_CONTROL_CONFIGr, 10367 regval, E2ECC_MODEf); 10368 } 10369 } 10370 } else if (rev_id == BCM56450_A0_REV_ID) { 10371 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 10372 if (soc_reg_field_valid(unit, IE2E_CONTROLr, VOQFC_ENABLEf)) { 10373 if (0 != soc_reg_field_get(unit, IE2E_CONTROLr, 10374 regval, VOQFC_ENABLEf)) { 10375 port_rx_enabled = 1; 10376 e2ecc_coe = 1; 10377 } 10378 } 10379 } 10380 if (!port_rx_enabled) { 10381 /* On to the next port */ 10382 continue; 10383 } 10384 10385 /* Allocate space for the E2ECC configuration */ 10386 if (PORT(unit, port).e2ecc_config == NULL) { 10387 PORT(unit, port).e2ecc_config = 10388 10389 sal_alloc(sizeof(bcm_port_congestion_config_t), 10390 "bcm_port_congestion_config"); 10391 if (PORT(unit, port).e2ecc_config == NULL) { 10392 LOG_ERROR(BSL_LS_BCM_PORT, 10393 (BSL_META_U(unit, 10394 "Error: unable to allocate memory for" 10395 " bcm_port_congestion_config.\n"))); 10396 return BCM_E_MEMORY; 10397 } 10398 } else { 10399 /* This is initialized to NULL pointers by 10400 * port init. How did it get changed? */ 10401 return BCM_E_INTERNAL; 10402 } 10403 10404 config = PORT(unit, port).e2ecc_config; 10405 bcm_port_congestion_config_t_init(config); 10406 10407 if (port_rx_enabled) { 10408 /* Recover RX state */ 10409 config->flags |= BCM_PORT_CONGESTION_CONFIG_RX; 10410 if (e2ecc_coe) { 10411 if ((rev_id >= BCM56450_B0_REV_ID) || SOC_IS_SABER2(unit)) { 10412 if (e2ecc_strict) { 10413 config->flags |= 10414 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE; 10415 } else { 10416 config->flags |= 10417 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE; 10418 } 10419 } else if (rev_id == BCM56450_A0_REV_ID) { 10420 config->flags |= 10421 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE; 10422 } 10423 SOC_IF_ERROR_RETURN( 10424 READ_ING_VOQFC_MACDA_MSr(unit, ®val)); 10425 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_MSr, 10426 regval, DAf); 10427 config->dest_mac[0] = ((field_val >> 8) & 0xff); 10428 config->dest_mac[1] = (field_val & 0xff); 10429 10430 SOC_IF_ERROR_RETURN( 10431 READ_ING_VOQFC_MACDA_LSr(unit, ®val)); 10432 field_val = soc_reg_field_get(unit, ING_VOQFC_MACDA_LSr, 10433 regval, DAf); 10434 config->dest_mac[2] = ((field_val >> 24) & 0xff); 10435 config->dest_mac[3] = ((field_val >> 16) & 0xff); 10436 config->dest_mac[4] = ((field_val >> 8) & 0xff); 10437 config->dest_mac[5] = (field_val & 0xff); 10438 10439 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, ®val)); 10440 config->ethertype = 10441 soc_reg_field_get(unit, ING_VOQFC_IDr, 10442 regval, LENGTH_TYPEf); 10443 config->opcode = 10444 soc_reg_field_get(unit, ING_VOQFC_IDr, 10445 regval, OPCODEf); 10446 } 10447 } 10448 } 10449 } 10450 #endif /* BCM_KATANA2_SUPPORT */ 10451 10452 return BCM_E_NONE; 10453 } 10454 #endif /* BCM_TRX_SUPPORT */ 10455 10456 /* 10457 * Function: 10458 * _bcm_esw_port_sync 10459 * Purpose: 10460 * Record Port module persisitent info for Level 2 Warm Boot 10461 * 10462 * Warm Boot Version Map: 10463 * Fields for previous version to be documented 10464 * BCM_PORT_WB_VERSION_1_0 10465 * ... 10466 * BCM_PORT_WB_VERSION_1_1 10467 * ... 10468 * BCM_PORT_WB_VERSION_1_2 10469 * rx_los SW RX LOS 10470 * ... 10471 * BCM_PORT_WB_VERSION_1_3 10472 * enable port eanble status 10473 * 10474 * Parameters: 10475 * unit - StrataSwitch unit number. 10476 * Returns: 10477 * BCM_E_XXX 10478 */ 10479 int 10480 _bcm_esw_port_sync(int unit) 10481 { 10482 int rv = BCM_E_NONE; 10483 10484 #if defined(BCM_TRX_SUPPORT) 10485 if (SOC_IS_TRX(unit)) { 10486 int alloc_sz; 10487 bcm_port_t port; 10488 uint8 *port_state; 10489 _bcm_port_info_t *pinfo = NULL; 10490 bcm_pbmp_t dtm_pbmp; 10491 int stable_size; 10492 soc_scache_handle_t scache_handle; 10493 #ifdef BCM_TRIDENT_SUPPORT 10494 soc_info_t *si = &SOC_INFO(unit); 10495 #endif 10496 bcm_pbmp_t all_pbmp; 10497 #ifdef BCM_TOMAHAWK_SUPPORT 10498 uint32 asf_wbmem_sz = 0; 10499 /* Switch Latency Bypass WB will move to a different module later */ 10500 uint32 latency_wbmem_sz = 0; 10501 #endif 10502 10503 BCM_PBMP_CLEAR(all_pbmp); 10504 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 10505 10506 #ifdef BCM_KATANA2_SUPPORT 10507 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 10508 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 10509 } 10510 if (soc_feature(unit, soc_feature_linkphy_coe) || 10511 soc_feature(unit, soc_feature_subtag_coe)) { 10512 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 10513 } 10514 #endif 10515 10516 #ifdef BCM_TRIDENT2PLUS_SUPPORT 10517 if (SOC_IS_TD2P_TT2P(unit)) { 10518 BCM_IF_ERROR_RETURN(bcm_td2p_flexport_pbmp_update(unit, 10519 &all_pbmp)); 10520 } 10521 #endif 10522 #ifdef BCM_MONTEREY_SUPPORT 10523 if (SOC_IS_MONTEREY(unit)) { 10524 BCM_IF_ERROR_RETURN(bcm_monterey_flexport_pbmp_update(unit, &all_pbmp)); 10525 } 10526 #endif 10527 #ifdef BCM_APACHE_SUPPORT 10528 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 10529 BCM_IF_ERROR_RETURN(bcm_apache_flexport_pbmp_update(unit, &all_pbmp)); 10530 } 10531 #endif 10532 10533 alloc_sz = 0; 10534 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 10535 PBMP_ITER(all_pbmp, port) { 10536 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 10537 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) { 10538 /* vp entry and vlan prot ptr */ 10539 alloc_sz += (sizeof(int) + sizeof(uint32)); 10540 } 10541 #endif 10542 alloc_sz += sizeof(int); /* vp count */ 10543 } 10544 alloc_sz += sizeof(dtm_pbmp); /* Bitmap of dtag_mode set */ 10545 10546 PBMP_ITER(all_pbmp, port) { 10547 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 10548 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 10549 alloc_sz += sizeof(uint32); 10550 } else { 10551 alloc_sz += sizeof(_bcm_port_metering_info_t); 10552 } 10553 alloc_sz += sizeof(uint8); /* flags */ 10554 } 10555 } 10556 10557 #ifdef BCM_TRIDENT_SUPPORT 10558 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) && 10559 soc_feature(unit, soc_feature_flex_port)) { 10560 /* Number of lanes per port needs to be stored.*/ 10561 alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int)); 10562 } 10563 #endif 10564 10565 /* Size for SW RX LOS status */ 10566 PBMP_ITER(all_pbmp, port) { 10567 alloc_sz += sizeof(uint8); 10568 } 10569 10570 #ifdef BCM_TRIDENT2_SUPPORT 10571 if (SOC_IS_TD2_TT2(unit)) { 10572 /* Size for port enable status */ 10573 PBMP_ITER(all_pbmp, port) { 10574 alloc_sz += sizeof(int); 10575 } 10576 } 10577 #endif /* BCM_TRIDENT2_SUPPORT */ 10578 #ifdef BCM_TRIUMPH3_SUPPORT 10579 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) { 10580 alloc_sz += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt) 10581 + sizeof((((_port_ibod_ctrl_t *)0)->event_count)); 10582 } 10583 #endif /* BCM_TRIUMPH3_SUPPORT */ 10584 #if defined(BCM_TRIUMPH3_SUPPORT) 10585 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 10586 int port_forward_size; 10587 BCM_IF_ERROR_RETURN( 10588 _bcm_port_force_forward_scache_size(unit, 10589 &port_forward_size)); 10590 alloc_sz += port_forward_size; 10591 } 10592 #endif 10593 10594 #ifdef BCM_TOMAHAWK_SUPPORT 10595 /* ASF WB */ 10596 rv = _bcm_esw_asf_wb_memsz_get(unit, &asf_wbmem_sz, 10597 BCM_PORT_WB_DEFAULT_VERSION); 10598 if (BCM_E_NONE == rv) { 10599 alloc_sz += asf_wbmem_sz; 10600 } 10601 10602 /* Switch Latency Bypass WB */ 10603 rv = bcmi_esw_switch_latency_wb_memsz_get(unit, &latency_wbmem_sz, 10604 BCM_PORT_WB_DEFAULT_VERSION); 10605 if (BCM_E_NONE == rv) { 10606 alloc_sz += latency_wbmem_sz; 10607 } 10608 #endif /* BCM_TOMAHAWK_SUPPORT */ 10609 10610 /*IFG WB*/ 10611 if (soc_feature(unit, soc_feature_xmac) || 10612 soc_feature(unit, soc_feature_xlmac) || 10613 soc_feature(unit, soc_feature_cmac) || 10614 soc_feature(unit, soc_feature_clmac)) { 10615 PBMP_ITER(all_pbmp, port) { 10616 alloc_sz += sizeof(uint32); 10617 } 10618 } 10619 /* PORT DSCP MAP SETTING */ 10620 if (soc_feature(unit, soc_feature_dscp) && 10621 soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 10622 /* Allocate size for port dscp map setting status */ 10623 PBMP_ITER(all_pbmp, port) { 10624 alloc_sz += sizeof(int); 10625 } 10626 } 10627 10628 #ifdef BCM_TOMAHAWK_SUPPORT 10629 if (SOC_IS_TOMAHAWK(unit)) { 10630 /* Allocate size for port interface type */ 10631 PBMP_ITER(all_pbmp, port) { 10632 alloc_sz += sizeof(int); 10633 } 10634 } 10635 #endif /* BCM_TOMAHAWK_SUPPORT */ 10636 10637 if (soc_feature(unit, soc_feature_phy_interface_wb)) { 10638 /* Allocate size for port interface type */ 10639 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 10640 alloc_sz += sizeof(int); 10641 } 10642 } 10643 10644 SOC_SCACHE_HANDLE_SET(scache_handle, 10645 unit, BCM_MODULE_PORT, 10646 BCM_PORT_WB_SCACHE_PART_DEFAULT); 10647 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 10648 alloc_sz, (uint8**)&port_state, 10649 BCM_PORT_WB_DEFAULT_VERSION, NULL); 10650 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 10651 return rv; 10652 } 10653 10654 BCM_PBMP_CLEAR(dtm_pbmp); 10655 10656 PORT_LOCK(unit); 10657 PBMP_ITER(all_pbmp, port) { 10658 if (port < SOC_MAX_NUM_PORTS) { 10659 rv = _bcm_port_info_get(unit, port, &pinfo); 10660 } 10661 if (BCM_FAILURE(rv)) { 10662 PORT_UNLOCK(unit); 10663 return (rv); 10664 } 10665 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 10666 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) { 10667 int idxmin, idxmax, idx; 10668 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm); 10669 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm); 10670 10671 for (idx = idxmin; idx <= idxmax; idx++) { 10672 if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, idx)) { 10673 sal_memcpy(port_state, &idx, sizeof(int)); 10674 port_state += sizeof(int); 10675 break; 10676 } 10677 } 10678 if (idx > idxmax) { 10679 idx = -1; 10680 sal_memcpy(port_state, &idx, sizeof(int)); 10681 port_state += sizeof(int); 10682 } 10683 sal_memcpy(port_state, &(pinfo->vlan_prot_ptr), 10684 sizeof(uint32)); 10685 port_state += sizeof(uint32); 10686 } 10687 #endif 10688 /* In Apache information is saved and recovered for 76 ports which is 10689 * greater than SOC_MAX_NUM_PORTS value of 75. These checks are 10690 * needed to prevent invalid memory access. 10691 */ 10692 if (port < SOC_MAX_NUM_PORTS) { 10693 if (0 != (pinfo->dtag_mode & 10694 (BCM_PORT_DTAG_MODE_INTERNAL | BCM_PORT_DTAG_MODE_EXTERNAL))) { 10695 /* Some sort of double-tagged mode */ 10696 BCM_PBMP_PORT_ADD(dtm_pbmp, port); 10697 } 10698 sal_memcpy(port_state, &(pinfo->vp_count), sizeof(pinfo->vp_count)); 10699 } 10700 port_state += sizeof(int); 10701 } 10702 sal_memcpy(port_state, &dtm_pbmp, sizeof(dtm_pbmp)); 10703 port_state += sizeof(dtm_pbmp); 10704 PBMP_ITER(all_pbmp, port) { 10705 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 10706 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 10707 if (port < SOC_MAX_NUM_PORTS) { 10708 sal_memcpy(port_state, &(PORT(unit, port).cosmask), sizeof(uint32)); 10709 } 10710 port_state += sizeof(uint32); 10711 } else { 10712 if (port < SOC_MAX_NUM_PORTS) { 10713 sal_memcpy(port_state, &(PORT(unit, port).m_info), 10714 sizeof(_bcm_port_metering_info_t)); 10715 } 10716 port_state += sizeof(_bcm_port_metering_info_t); 10717 } 10718 if (port < SOC_MAX_NUM_PORTS) { 10719 sal_memcpy(port_state, &(PORT(unit, port).flags), sizeof(uint8)); 10720 } 10721 port_state += sizeof(uint8); 10722 } 10723 } 10724 #ifdef BCM_TRIDENT_SUPPORT 10725 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) && 10726 soc_feature(unit, soc_feature_flex_port)) { 10727 /* coverity[overrun-local] */ 10728 PBMP_ALL_ITER(unit, port) { 10729 if (port < SOC_MAX_NUM_PORTS) { 10730 sal_memcpy(port_state, &(si->port_num_lanes[port]), sizeof(int)); 10731 } 10732 port_state += sizeof(int); 10733 } 10734 } 10735 #endif 10736 10737 /* Restore SW RX LOS status */ 10738 PBMP_ITER(all_pbmp, port) { 10739 if (port < SOC_MAX_NUM_PORTS) { 10740 sal_memcpy(port_state, &(PORT(unit, port).rx_los), sizeof(uint8)); 10741 } 10742 port_state += sizeof(uint8); 10743 } 10744 10745 #ifdef BCM_TRIDENT2_SUPPORT 10746 if (SOC_IS_TD2_TT2(unit)) { 10747 /* Restore port enable status */ 10748 PBMP_ITER(all_pbmp, port) { 10749 if (port < SOC_MAX_NUM_PORTS) { 10750 sal_memcpy(port_state, &(PORT(unit, port).enable), sizeof(int)); 10751 } 10752 port_state += sizeof(int); 10753 } 10754 } 10755 #endif /* BCM_TRIDENT2_SUPPORT */ 10756 #ifdef BCM_TRIUMPH3_SUPPORT 10757 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) { 10758 if (_port_ibod_ctrl[unit]) { 10759 sal_memcpy(port_state, _port_ibod_ctrl[unit]->rrbyt, 10760 sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)); 10761 port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrbyt); 10762 sal_memcpy(port_state, _port_ibod_ctrl[unit]->rrpkt, 10763 sizeof(((_port_ibod_ctrl_t *)0)->rrpkt)); 10764 port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrpkt); 10765 sal_memcpy(port_state, &(_port_ibod_ctrl[unit]->event_count), 10766 sizeof(((_port_ibod_ctrl_t *)0)->event_count)); 10767 port_state += sizeof(((_port_ibod_ctrl_t *)0)->event_count); 10768 } else { 10769 sal_memset(port_state, 0, 10770 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt) 10771 + sizeof((((_port_ibod_ctrl_t *)0)->event_count))); 10772 port_state += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt) 10773 + sizeof((((_port_ibod_ctrl_t *)0)->event_count)); 10774 } 10775 10776 } 10777 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 10778 rv = _bcm_port_force_forward_sync(unit, &port_state); 10779 if (BCM_FAILURE(rv)) { 10780 PORT_UNLOCK(unit); 10781 return (rv); 10782 } 10783 } 10784 #endif /* BCM_TRIUMPH3_SUPPORT */ 10785 10786 #ifdef BCM_TOMAHAWK_SUPPORT 10787 /* ASF WB */ 10788 rv = _bcm_esw_asf_wb_sync(unit, port_state); 10789 10790 if (BCM_E_NONE == rv) { 10791 port_state += asf_wbmem_sz; 10792 } 10793 10794 /* Switch Latency Bypass WB */ 10795 rv = bcmi_esw_switch_latency_wb_sync(unit, port_state); 10796 10797 if (BCM_E_NONE == rv) { 10798 port_state += latency_wbmem_sz; 10799 } 10800 #endif /* BCM_TOMAHAWK_SUPPORT */ 10801 10802 /*IFG WB*/ 10803 if (soc_feature(unit, soc_feature_xmac) || 10804 soc_feature(unit, soc_feature_xlmac) || 10805 soc_feature(unit, soc_feature_cmac) || 10806 soc_feature(unit, soc_feature_clmac)) { 10807 rv = _bcm_esw_port_ifg_wb_sync(unit, &port_state); 10808 } 10809 /* PORT DSCP MAP SETTING */ 10810 if (soc_feature(unit, soc_feature_dscp) && 10811 soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 10812 /* Allocate size for port dscp map setting status */ 10813 PBMP_ITER(all_pbmp, port) { 10814 sal_memcpy(port_state, &(PORT(unit, port).port_dscp_map_set), sizeof(int)); 10815 port_state += sizeof(int); 10816 } 10817 } 10818 10819 #if defined(BCM_CLMAC_SUPPORT) 10820 if (SOC_IS_TOMAHAWK(unit)) { 10821 soc_port_if_t pif; 10822 /* Restore port interface type */ 10823 PBMP_ITER(all_pbmp, port) { 10824 if (IS_XE_PORT(unit, port) || 10825 IS_CE_PORT(unit, port) || 10826 IS_HG_PORT(unit, port) || 10827 IS_GE_PORT(unit, port) || 10828 IS_MANAGEMENT_PORT(unit, port)) { 10829 SOC_IF_ERROR_RETURN 10830 (soc_phyctrl_interface_get(unit, port, &pif)); 10831 sal_memcpy(port_state, &pif, sizeof(int)); 10832 port_state += sizeof(int); 10833 } 10834 } 10835 } 10836 #endif 10837 10838 if (soc_feature(unit, soc_feature_phy_interface_wb)) { 10839 soc_port_if_t pif; 10840 10841 /* Restore port interface type */ 10842 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 10843 rv = soc_phyctrl_interface_get(unit, port, &pif); 10844 if (BCM_FAILURE(rv)) { 10845 pif = 0; 10846 } 10847 sal_memcpy(port_state, &pif, sizeof(int)); 10848 port_state += sizeof(int); 10849 } 10850 } 10851 PORT_UNLOCK(unit); 10852 } 10853 #endif /* BCM_TRX_SUPPORT */ 10854 10855 #ifdef BCM_PREEMPTION_SUPPORT 10856 if (BCM_SUCCESS(rv) && soc_feature(unit, soc_feature_preemption)) { 10857 soc_scache_handle_t scache_handle; 10858 10859 SOC_SCACHE_HANDLE_SET(scache_handle, 10860 unit, BCM_MODULE_PORT, 10861 BCM_PORT_WB_SCACHE_PART_PREMMPTION); 10862 BCM_IF_ERROR_RETURN( 10863 bcmi_esw_preemption_sync(unit, scache_handle)); 10864 } 10865 #endif /* BCM_PREEMPTION_SUPPORT */ 10866 10867 return rv; 10868 } 10869 10870 int 10871 _bcm_esw_port_wb_alloc(int unit) 10872 { 10873 10874 #if defined(BCM_TRX_SUPPORT) 10875 if (SOC_IS_TRX(unit)) { 10876 int alloc_sz, rv = BCM_E_NONE; 10877 bcm_port_t port; 10878 uint8 *port_state; 10879 int stable_size; 10880 bcm_pbmp_t all_pbmp; 10881 soc_scache_handle_t scache_handle; 10882 #ifdef BCM_TOMAHAWK_SUPPORT 10883 uint32 asf_wbmem_sz = 0; 10884 10885 /* Switch Latency Bypass WB will move to a different module later */ 10886 uint32 latency_wbmem_sz = 0; 10887 #endif /* BCM_TOMAHAWK_SUPPORT */ 10888 10889 BCM_PBMP_CLEAR(all_pbmp); 10890 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 10891 10892 #ifdef BCM_KATANA2_SUPPORT 10893 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 10894 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 10895 } 10896 if (soc_feature(unit, soc_feature_linkphy_coe) || 10897 soc_feature(unit, soc_feature_subtag_coe)) { 10898 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 10899 } 10900 #endif 10901 10902 #ifdef BCM_TRIDENT2PLUS_SUPPORT 10903 if (SOC_IS_TD2P_TT2P(unit)) { 10904 BCM_IF_ERROR_RETURN(bcm_td2p_flexport_pbmp_update(unit, 10905 &all_pbmp)); 10906 } 10907 #endif 10908 #ifdef BCM_MONTEREY_SUPPORT 10909 if (SOC_IS_MONTEREY(unit)) { 10910 BCM_IF_ERROR_RETURN(bcm_monterey_flexport_pbmp_update(unit, &all_pbmp)); 10911 } 10912 #endif 10913 #ifdef BCM_APACHE_SUPPORT 10914 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 10915 BCM_IF_ERROR_RETURN(bcm_apache_flexport_pbmp_update(unit, &all_pbmp)); 10916 } 10917 #endif 10918 alloc_sz = 0; 10919 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 10920 PBMP_ITER(all_pbmp, port) { 10921 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 10922 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) { 10923 /* vp entry and vlan prot ptr */ 10924 alloc_sz += (sizeof(int) + sizeof(uint32)); 10925 } 10926 #endif 10927 alloc_sz += sizeof(int); /* vp count */ 10928 } 10929 alloc_sz += sizeof(bcm_pbmp_t); /* Bitmap of dtag_mode == NONE */ 10930 PBMP_ITER(all_pbmp, port) { 10931 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 10932 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 10933 alloc_sz += sizeof(uint32); 10934 } else { 10935 alloc_sz += sizeof(_bcm_port_metering_info_t); 10936 } 10937 alloc_sz += sizeof(uint8); /* flags */ 10938 } 10939 } 10940 10941 #ifdef BCM_TRIDENT_SUPPORT 10942 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) && 10943 soc_feature(unit, soc_feature_flex_port)) { 10944 alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int)); 10945 } 10946 #endif 10947 10948 /* Restore SW RX LOS status */ 10949 PBMP_ITER(all_pbmp, port) { 10950 alloc_sz += sizeof(uint8); 10951 } 10952 10953 #ifdef BCM_TRIDENT2_SUPPORT 10954 if (SOC_IS_TD2_TT2(unit)) { 10955 /* Allocate size for port enable status */ 10956 PBMP_ITER(all_pbmp, port) { 10957 alloc_sz += sizeof(int); 10958 } 10959 } 10960 #endif /* BCM_TRIDENT2_SUPPORT */ 10961 #ifdef BCM_TRIUMPH3_SUPPORT 10962 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) { 10963 alloc_sz += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt) 10964 + sizeof((((_port_ibod_ctrl_t *)0)->event_count)); 10965 } 10966 #endif /* BCM_TRIUMPH3_SUPPORT */ 10967 #if defined(BCM_TRIUMPH3_SUPPORT) 10968 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 10969 int port_forward_size; 10970 BCM_IF_ERROR_RETURN( 10971 _bcm_port_force_forward_scache_size(unit, &port_forward_size)); 10972 alloc_sz += port_forward_size; 10973 } 10974 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */ 10975 10976 #ifdef BCM_TOMAHAWK_SUPPORT 10977 /* ASF WB */ 10978 rv = _bcm_esw_asf_wb_memsz_get(unit, &asf_wbmem_sz, BCM_PORT_WB_DEFAULT_VERSION); 10979 if (BCM_E_NONE == rv) { 10980 alloc_sz += asf_wbmem_sz; 10981 } 10982 10983 /* Switch Latency Bypass WB */ 10984 rv = bcmi_esw_switch_latency_wb_memsz_get(unit, &latency_wbmem_sz, 10985 BCM_PORT_WB_DEFAULT_VERSION); 10986 if (BCM_E_NONE == rv) { 10987 alloc_sz += latency_wbmem_sz; 10988 } 10989 #endif /* BCM_TOMAHAWK_SUPPORT */ 10990 10991 /*IFG WB*/ 10992 if (soc_feature(unit, soc_feature_xmac) || 10993 soc_feature(unit, soc_feature_xlmac) || 10994 soc_feature(unit, soc_feature_cmac) || 10995 soc_feature(unit, soc_feature_clmac)) { 10996 PBMP_ITER(all_pbmp, port) { 10997 alloc_sz += sizeof(uint32); 10998 } 10999 } 11000 /* PORT DSCP MAP SETTING */ 11001 if (soc_feature(unit, soc_feature_dscp) && 11002 soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 11003 /* Allocate size for port dscp map setting status */ 11004 PBMP_ITER(all_pbmp, port) { 11005 alloc_sz += sizeof(int); 11006 } 11007 } 11008 11009 #ifdef BCM_TOMAHAWK_SUPPORT 11010 if (SOC_IS_TOMAHAWK(unit)) { 11011 /* Allocate size for port interface type */ 11012 PBMP_ITER(all_pbmp, port) { 11013 alloc_sz += sizeof(int); 11014 } 11015 } 11016 #endif /* BCM_TOMAHAWK_SUPPORT */ 11017 11018 if (soc_feature(unit, soc_feature_phy_interface_wb)) { 11019 /* Allocate size for port interface type */ 11020 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 11021 alloc_sz += sizeof(int); 11022 } 11023 } 11024 11025 SOC_SCACHE_HANDLE_SET(scache_handle, 11026 unit, BCM_MODULE_PORT, 11027 BCM_PORT_WB_SCACHE_PART_DEFAULT); 11028 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, 11029 alloc_sz, (uint8**)&port_state, 11030 BCM_PORT_WB_DEFAULT_VERSION, NULL); 11031 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 11032 return rv; 11033 } 11034 } 11035 #endif /* BCM_TRX_SUPPORT */ 11036 11037 #ifdef BCM_PREEMPTION_SUPPORT 11038 if (soc_feature(unit, soc_feature_preemption)) { 11039 soc_scache_handle_t scache_handle; 11040 11041 SOC_SCACHE_HANDLE_SET(scache_handle, 11042 unit, BCM_MODULE_PORT, 11043 BCM_PORT_WB_SCACHE_PART_PREMMPTION); 11044 BCM_IF_ERROR_RETURN( 11045 bcmi_esw_preemption_wb_alloc(unit, scache_handle)); 11046 } 11047 #endif /* BCM_PREEMPTION_SUPPORT */ 11048 11049 return BCM_E_NONE; 11050 } 11051 11052 #ifdef BCM_TRIUMPH2_SUPPORT 11053 /* 11054 * Function: 11055 * _bcm_tr2_flexport_recover 11056 * Purpose: 11057 * To recover/reconstruct the HL port configuration 11058 * during warmboot. This is a 'level one' warmboot 11059 * recovery. It depends on the reg configuration of 11060 * EDATABUF_XQP_FLEXPORT_CONFIGr which maintains the 11061 * flexport config of the HL ports that was done 11062 * in coldboot mode. 11063 * Parameters: 11064 * unit - StrataSwitch unit number. 11065 * port - Port number of the HL 11066 * flexport controlling port. 11067 * Returns: 11068 * BCM_E_XXX 11069 */ 11070 STATIC int 11071 _bcm_tr2_flexport_recover(int unit, bcm_port_t port) 11072 { 11073 uint8 rev_id; 11074 uint16 dev_id; 11075 uint32 port_type; 11076 int i, old_value, rv; 11077 bcm_port_t it_port; 11078 port_tab_entry_t pent; 11079 soc_info_t *si = &SOC_INFO(unit); 11080 11081 soc_cm_get_id(unit, &dev_id, &rev_id); 11082 BCM_IF_ERROR_RETURN(_bcm_tr2_port_lanes_get(unit, port, &old_value)); 11083 11084 #define RECONFIGURE_TR2_PORT_TYPE_INFO(ptype) \ 11085 si->ptype.num = 0; \ 11086 si->ptype.min = si->ptype.max = -1; \ 11087 PBMP_ITER(si->ptype.bitmap, it_port) { \ 11088 si->ptype.port[si->ptype.num++] = it_port; \ 11089 if (si->ptype.min < 0) { \ 11090 si->ptype.min = it_port; \ 11091 } \ 11092 if (it_port > si->ptype.max) { \ 11093 si->ptype.max = it_port; \ 11094 } \ 11095 } 11096 11097 /* Step 1: Change the SOC bitmaps */ 11098 if ((old_value == 1)) { 11099 /* The block originally had 4 GE ports */ 11100 SOC_CONTROL_LOCK(unit); 11101 SOC_PBMP_PORT_REMOVE(si->st.bitmap, port); 11102 SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port); 11103 SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port); 11104 SOC_PBMP_PORT_ADD(si->ether.bitmap, port); 11105 SOC_PBMP_PORT_ADD(si->ge.bitmap, port); 11106 si->port_speed_max[port] = 1000; 11107 soc_port_cmap_set(unit, port, SOC_CTR_TYPE_GE); 11108 for (i = port + 1; i < port + 4; i++) { 11109 SOC_PBMP_PORT_REMOVE(si->ge.disabled_bitmap, i); 11110 SOC_PBMP_PORT_REMOVE(si->ether.disabled_bitmap, i); 11111 SOC_PBMP_PORT_REMOVE(si->port.disabled_bitmap, i); 11112 SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, i); 11113 si->port_speed_max[i] = 1000; 11114 soc_port_cmap_set(unit, i, SOC_CTR_TYPE_GE); 11115 } 11116 RECONFIGURE_TR2_PORT_TYPE_INFO(ether); 11117 RECONFIGURE_TR2_PORT_TYPE_INFO(st); 11118 RECONFIGURE_TR2_PORT_TYPE_INFO(hg); 11119 RECONFIGURE_TR2_PORT_TYPE_INFO(xe); 11120 RECONFIGURE_TR2_PORT_TYPE_INFO(ge); 11121 SOC_CONTROL_UNLOCK(unit); 11122 } else if (old_value == 4) { 11123 /* The block was originally a single high-speed port */ 11124 SOC_CONTROL_LOCK(unit); 11125 rv = soc_mem_read(unit, SOC_PORT_MEM_TAB(unit, port), 11126 MEM_BLOCK_ANY, SOC_PORT_MOD_OFFSET(unit, port), &pent); 11127 if (BCM_FAILURE(rv)) { 11128 SOC_CONTROL_UNLOCK(unit); 11129 return rv; 11130 } 11131 port_type = soc_PORT_TABm_field32_get(unit, &pent, PORT_TYPEf); 11132 switch(port_type) { 11133 case 0 : /* xe */ 11134 SOC_PBMP_PORT_ADD(si->xe.bitmap, port); 11135 SOC_PBMP_PORT_ADD(si->ether.bitmap, port); 11136 SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port); 11137 SOC_PBMP_PORT_REMOVE(si->st.bitmap, port); 11138 break; 11139 case 1 : /* hg */ 11140 SOC_PBMP_PORT_ADD(si->hg.bitmap, port); 11141 SOC_PBMP_PORT_ADD(si->st.bitmap, port); 11142 SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port); 11143 SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port); 11144 default: 11145 break; 11146 } 11147 SOC_PBMP_PORT_REMOVE(si->ge.bitmap, port); 11148 switch (dev_id) { 11149 case BCM56526_DEVICE_ID: 11150 si->port_speed_max[port] = 13000; 11151 break; 11152 case BCM56636_DEVICE_ID: 11153 case BCM56638_DEVICE_ID: 11154 si->port_speed_max[port] = 12000; 11155 break; 11156 default: 11157 si->port_speed_max[port] = 10000; 11158 } 11159 soc_port_cmap_set(unit, port, SOC_CTR_TYPE_XE); 11160 for (i = port + 1; i < port + 4; i++) { 11161 SOC_PBMP_PORT_ADD(si->ge.disabled_bitmap, i); 11162 SOC_PBMP_PORT_ADD(si->ether.disabled_bitmap, i); 11163 SOC_PBMP_PORT_ADD(si->port.disabled_bitmap, i); 11164 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, i); 11165 } 11166 RECONFIGURE_TR2_PORT_TYPE_INFO(ether); 11167 RECONFIGURE_TR2_PORT_TYPE_INFO(st); 11168 RECONFIGURE_TR2_PORT_TYPE_INFO(hg); 11169 RECONFIGURE_TR2_PORT_TYPE_INFO(ge); 11170 SOC_CONTROL_UNLOCK(unit); 11171 } 11172 #undef RECONFIGURE_PORT_TYPE_INFO 11173 soc_dport_map_update(unit); 11174 11175 return BCM_E_NONE; 11176 } 11177 #endif /* BCM_TRIUMPH2_SUPPORT */ 11178 11179 #ifdef BCM_TRIDENT2_SUPPORT 11180 /* 11181 * Function: 11182 * _bcm_td2_flexport_recover 11183 * Purpose: 11184 * To recover/reconstruct the HL port configuration 11185 * during warmboot. This is a 'level one' warmboot 11186 * recovery. It depends on the reg configuration of 11187 * XLPORT_MODE_REGr which maintains the 11188 * flexport config of the HL ports that was done 11189 * in coldboot mode. 11190 * Parameters: 11191 * unit - StrataSwitch unit number. 11192 * port - Port number of the HL 11193 * flexport controlling port. 11194 * Returns: 11195 * BCM_E_XXX 11196 */ 11197 STATIC int 11198 _bcm_td2_flexport_recover(int unit, bcm_port_t port) 11199 { 11200 soc_info_t *si = &SOC_INFO(unit); 11201 int i, phy_port, phy_port_base, port_base, lp; 11202 int mode, phy_port_actived[4]; 11203 uint32 rval; 11204 11205 phy_port = si->port_l2p_mapping[port]; 11206 phy_port_base = (phy_port & ~0x3) + 1; 11207 port_base = si->port_p2l_mapping[phy_port_base]; 11208 11209 if (phy_port == -1 || phy_port != phy_port_base) { 11210 return BCM_E_NONE; 11211 } 11212 11213 sal_memset(phy_port_actived, 0, sizeof(phy_port_actived)); 11214 11215 /* Get the current mode */ 11216 if (SOC_USE_PORTCTRL(unit)) { 11217 BCM_IF_ERROR_RETURN(bcmi_esw_portctrl_mode_get(unit, port, &mode)); 11218 } else { 11219 SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port_base, &rval)); 11220 mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, 11221 XPORT0_CORE_PORT_MODEf); 11222 } 11223 11224 switch(mode) { 11225 case SOC_TD2_PORT_MODE_QUAD: 11226 phy_port_actived[0] = 11227 phy_port_actived[1] = 11228 phy_port_actived[2] = 11229 phy_port_actived[3] = 1; 11230 break; 11231 case SOC_TD2_PORT_MODE_TRI_012: 11232 phy_port_actived[0] = 11233 phy_port_actived[1] = 11234 phy_port_actived[2] = 1; 11235 break; 11236 case SOC_TD2_PORT_MODE_TRI_023: 11237 phy_port_actived[0] = 11238 phy_port_actived[2] = 11239 phy_port_actived[3] = 1; 11240 break; 11241 case SOC_TD2_PORT_MODE_DUAL: 11242 phy_port_actived[0] = 11243 phy_port_actived[2] = 1; 11244 break; 11245 case SOC_TD2_PORT_MODE_SINGLE: 11246 phy_port_actived[0] = 1; 11247 break; 11248 default: 11249 return SOC_E_FAIL; 11250 } 11251 11252 SOC_CONTROL_LOCK(unit); 11253 for (i = 0; i < 4; i++) { 11254 lp = si->port_p2l_mapping[phy_port_base + i]; 11255 if (lp != -1 && 11256 BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), lp)) { 11257 if (phy_port_actived[i]) { 11258 SOC_PBMP_PORT_REMOVE(/* port(s) to be added */ 11259 SOC_PORT_DISABLED_BITMAP(unit, all), lp); 11260 } else { 11261 SOC_PBMP_PORT_ADD( /* port(s) to be removed */ 11262 SOC_PORT_DISABLED_BITMAP(unit, all), lp); 11263 } 11264 } 11265 } 11266 SOC_CONTROL_UNLOCK(unit); 11267 11268 return SOC_E_NONE; 11269 } 11270 #endif /* BCM_TRIDENT2_SUPPORT */ 11271 11272 void bcm_esw_port_mdix_wb_update(int unit) 11273 { 11274 int p; 11275 bcm_port_mdix_t mdix; 11276 11277 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 11278 /* Intentionally return value is not checked as this function 11279 * is called to wb update mdix value for the port, if it exists. 11280 */ 11281 bcm_esw_port_mdix_get(unit,p,&mdix); 11282 LOG_VERBOSE(BSL_LS_BCM_PORT, 11283 (BSL_META_U(unit, "Port %d MDIX udate in wb !!\n"), p)); 11284 } 11285 } 11286 11287 int 11288 _bcm_esw_port_wb_recover(int unit) 11289 { 11290 int rv = BCM_E_NONE; 11291 11292 #if defined(BCM_TRX_SUPPORT) 11293 if (SOC_IS_TRX(unit)) { 11294 int alloc_sz, use_pbmp = FALSE; 11295 uint8 *port_state; 11296 uint16 recovered_ver; 11297 bcm_port_t port; 11298 _bcm_port_info_t *pinfo; 11299 bcm_pbmp_t dtm_pbmp; 11300 int stable_size; 11301 soc_scache_handle_t scache_handle; 11302 #if defined(BCM_SABER2_SUPPORT) 11303 uint32 rval = 0, oamp_status = 0; 11304 #endif 11305 #ifdef BCM_TRIUMPH2_SUPPORT 11306 pbmp_t port_bitmap; 11307 #ifdef BCM_TRIDENT_SUPPORT 11308 soc_info_t *si = &SOC_INFO(unit); 11309 int _port_lanes_valid = 0; 11310 #ifdef BCM_TRIUMPH3_SUPPORT 11311 int _port_num_lanes[SOC_MAX_NUM_PORTS] = {0}; 11312 #endif /* BCM_TRIUMPH3_SUPPORT */ 11313 #endif /* BCM_TRIDENT_SUPPORT */ 11314 #endif /* BCM_TRIUMPH2_SUPPORT */ 11315 bcm_pbmp_t all_pbmp; 11316 int realloc_size = 0; 11317 #ifdef BCM_TOMAHAWK_SUPPORT 11318 uint32 asf_wbmem_sz = 0; 11319 uint16 scache_ver = BCM_PORT_WB_DEFAULT_VERSION; 11320 11321 /* Switch Latency Bypass WB will move to a different module later */ 11322 uint32 latency_wbmem_sz = 0; 11323 #endif 11324 11325 BCM_PBMP_CLEAR(all_pbmp); 11326 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 11327 11328 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_PORT, 11329 BCM_PORT_WB_SCACHE_PART_DEFAULT); 11330 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 11331 0, (uint8**)&port_state, 11332 BCM_PORT_WB_DEFAULT_VERSION, &recovered_ver); 11333 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 11334 return rv; 11335 } 11336 11337 #if defined(BCM_SABER2_SUPPORT) 11338 if(SOC_IS_SABER2(unit)) { 11339 SOC_IF_ERROR_RETURN(READ_OAMP_ENABLEr(unit, &rval)); 11340 oamp_status = soc_reg_field_get(unit, OAMP_ENABLEr, rval, ENABLEf); 11341 } 11342 #endif 11343 #ifdef BCM_KATANA2_SUPPORT 11344 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 11345 #if defined(BCM_SABER2_SUPPORT) 11346 if ( SOC_IS_SABER2(unit) && !SOC_IS_METROLITE(unit) && 11347 (recovered_ver < BCM_PORT_WB_VERSION_1_10) ) { 11348 BCM_IF_ERROR_RETURN(_bcm_sb2_wb_v1_flexio_pbmp_update(unit, &all_pbmp)); 11349 } else 11350 #endif 11351 { 11352 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 11353 #if defined(BCM_SABER2_SUPPORT) 11354 bcm_sb2_wb_v2_flexio_update = 1; 11355 #endif 11356 } 11357 } 11358 if (soc_feature(unit, soc_feature_linkphy_coe) || 11359 soc_feature(unit, soc_feature_subtag_coe)) { 11360 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 11361 } 11362 #endif 11363 #ifdef BCM_TRIDENT2PLUS_SUPPORT 11364 if (SOC_IS_TD2P_TT2P(unit)) { 11365 BCM_IF_ERROR_RETURN(bcm_td2p_flexport_pbmp_update(unit, 11366 &all_pbmp)); 11367 } 11368 #endif 11369 #ifdef BCM_MONTEREY_SUPPORT 11370 if (SOC_IS_MONTEREY(unit)) { 11371 BCM_IF_ERROR_RETURN(bcm_monterey_flexport_pbmp_update(unit, &all_pbmp)); 11372 } 11373 #endif 11374 #ifdef BCM_APACHE_SUPPORT 11375 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 11376 BCM_IF_ERROR_RETURN(bcm_apache_flexport_pbmp_update(unit, &all_pbmp)); 11377 } 11378 #endif 11379 11380 alloc_sz = 0; 11381 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 11382 PBMP_ITER(all_pbmp, port) { 11383 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 11384 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit))) { 11385 /* vp entry and vlan prot ptr */ 11386 alloc_sz += (sizeof(int) + sizeof(uint32)); 11387 } 11388 #endif 11389 alloc_sz += sizeof(int); /* vp count */ 11390 } 11391 alloc_sz += sizeof(bcm_pbmp_t); /* Bitmap of dtag_mode == NONE */ 11392 PBMP_ITER(all_pbmp, port) { 11393 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 11394 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 11395 alloc_sz += sizeof(uint32); 11396 } else { 11397 alloc_sz += sizeof(_bcm_port_metering_info_t); 11398 } 11399 alloc_sz += sizeof(uint8); 11400 } 11401 } 11402 11403 #ifdef BCM_TRIDENT_SUPPORT 11404 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) && 11405 soc_feature(unit, soc_feature_flex_port)) { 11406 alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int)); 11407 } 11408 #endif 11409 11410 /* Restore SW RX LOS status */ 11411 PBMP_ITER(all_pbmp, port) { 11412 alloc_sz += sizeof(uint8); 11413 } 11414 11415 #ifdef BCM_TRIDENT2_SUPPORT 11416 if (SOC_IS_TD2_TT2(unit)) { 11417 /* Allocate size for port enable status */ 11418 PBMP_ITER(all_pbmp, port) { 11419 alloc_sz += sizeof(int); 11420 } 11421 } 11422 #endif /* BCM_TRIDENT2_SUPPORT */ 11423 #ifdef BCM_TRIUMPH3_SUPPORT 11424 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) { 11425 alloc_sz += 2 * sizeof(((_port_ibod_ctrl_t *)0)->rrbyt) 11426 + sizeof((((_port_ibod_ctrl_t *)0)->event_count)); 11427 } 11428 #endif /* BCM_TRIUMPH3_SUPPORT */ 11429 #if defined(BCM_TRIUMPH3_SUPPORT) 11430 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 11431 int port_forward_size; 11432 BCM_IF_ERROR_RETURN( 11433 _bcm_port_force_forward_scache_size(unit, &port_forward_size)); 11434 alloc_sz += port_forward_size; 11435 } 11436 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */ 11437 11438 #ifdef BCM_TOMAHAWK_SUPPORT 11439 if (SOC_WARM_BOOT(unit)) { 11440 BCM_IF_ERROR_RETURN( 11441 bcm_esw_scache_ver_get(unit, BCM_MODULE_PORT, &scache_ver)); 11442 } 11443 /* ASF WB */ 11444 rv = _bcm_esw_asf_wb_memsz_get(unit, &asf_wbmem_sz, scache_ver); 11445 if (BCM_E_NONE == rv) { 11446 alloc_sz += asf_wbmem_sz; 11447 } 11448 11449 /* Switch Latency Bypass WB */ 11450 rv = bcmi_esw_switch_latency_wb_memsz_get(unit, &latency_wbmem_sz, 11451 scache_ver); 11452 if (BCM_E_NONE == rv) { 11453 alloc_sz += latency_wbmem_sz; 11454 } 11455 #endif /* BCM_TOMAHAWK_SUPPORT */ 11456 11457 /*IFG WB*/ 11458 if (soc_feature(unit, soc_feature_xmac) || 11459 soc_feature(unit, soc_feature_xlmac) || 11460 soc_feature(unit, soc_feature_cmac) || 11461 soc_feature(unit, soc_feature_clmac)) { 11462 PBMP_ITER(all_pbmp, port) { 11463 alloc_sz += sizeof(uint32); 11464 } 11465 } 11466 /* PORT DSCP MAP SETTING */ 11467 if (soc_feature(unit, soc_feature_dscp) && 11468 soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 11469 /* Allocate size for port dscp map setting status */ 11470 PBMP_ITER(all_pbmp, port) { 11471 alloc_sz += sizeof(int); 11472 } 11473 } 11474 11475 #ifdef BCM_TOMAHAWK_SUPPORT 11476 if (SOC_IS_TOMAHAWK(unit)) { 11477 /* Allocate size for port interface type */ 11478 PBMP_ITER(all_pbmp, port) { 11479 alloc_sz += sizeof(int); 11480 } 11481 } 11482 #endif /* BCM_TOMAHAWK_SUPPORT */ 11483 11484 if (soc_feature(unit, soc_feature_phy_interface_wb)) { 11485 /* Allocate size for port interface type */ 11486 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 11487 alloc_sz += sizeof(int); 11488 } 11489 } 11490 11491 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_PORT, 11492 BCM_PORT_WB_SCACHE_PART_DEFAULT); 11493 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 11494 alloc_sz, (uint8**)&port_state, 11495 BCM_PORT_WB_DEFAULT_VERSION, &recovered_ver); 11496 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 11497 return rv; 11498 } 11499 if (BCM_SUCCESS(rv)) { 11500 PBMP_ITER(all_pbmp, port) { 11501 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 11502 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 11503 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWK2(unit) || SOC_IS_TRIDENT3X(unit)) && 11504 (recovered_ver >= BCM_PORT_WB_VERSION_1_9)) { 11505 /* Recover vp entry and vlan prot ptr */ 11506 uint32 vlan_protocol_data_index = 0; 11507 int idxmin, idxmax, vpentry = 0; 11508 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm); 11509 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm); 11510 11511 sal_memcpy(&vpentry, port_state, sizeof(int)); 11512 port_state += sizeof(int); 11513 if ((vpentry >= idxmin) && (vpentry <= idxmax) && 11514 (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, vpentry))) { 11515 /* Set as explicit VID */ 11516 _BCM_PORT_VD_PBVL_SET(pinfo, vpentry); 11517 } 11518 11519 sal_memcpy(&vlan_protocol_data_index, port_state, 11520 sizeof(uint32)); 11521 port_state += sizeof(uint32); 11522 pinfo->vp_count = 0; 11523 /* update vlan port protocol data memory */ 11524 if (!IS_LB_PORT(unit, port)) { 11525 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, 11526 _BCM_CPU_TABS_ETHER, 11527 VLAN_PROTOCOL_DATA_INDEXf, 11528 vlan_protocol_data_index / 16)); 11529 11530 pinfo->vlan_prot_ptr = vlan_protocol_data_index; 11531 BCM_IF_ERROR_RETURN( 11532 _bcm_port_vlan_protocol_data_entry_reference (unit, 11533 vlan_protocol_data_index, 16)); 11534 } 11535 } 11536 #endif 11537 /* In Apache information is saved and recovered for 76 ports which is 11538 * greater than SOC_MAX_NUM_PORTS value of 75. These checks are 11539 * needed to prevent invalid memory access. 11540 */ 11541 if (port < SOC_MAX_NUM_PORTS) { 11542 /* Recover VP reference counts */ 11543 sal_memcpy(&(pinfo->vp_count), port_state, sizeof(pinfo->vp_count)); 11544 } 11545 port_state += sizeof(int); 11546 } 11547 #ifdef BCM_KATANA2_SUPPORT 11548 if (SOC_IS_KATANA2(unit) && (recovered_ver >= BCM_PORT_WB_VERSION_1_9)) { 11549 /* Keep one extra reference to the default profile */ 11550 BCM_IF_ERROR_RETURN( 11551 _bcm_port_vlan_protocol_data_entry_reference (unit, 11552 0, 16)); 11553 } 11554 #endif 11555 /* Recover dtag_mode port bitmap */ 11556 sal_memcpy(&dtm_pbmp, port_state, sizeof(dtm_pbmp)); 11557 port_state += sizeof(dtm_pbmp); 11558 use_pbmp = TRUE; /* Cached info available */ 11559 11560 if (recovered_ver >= BCM_PORT_WB_VERSION_1_1) { 11561 PBMP_ITER(all_pbmp, port) { 11562 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 11563 /* Recover port tx stop related info */ 11564 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 11565 if (port < SOC_MAX_NUM_PORTS) { 11566 sal_memcpy(&(PORT(unit, port).cosmask), port_state, 11567 sizeof(uint32)); 11568 } 11569 port_state += sizeof(uint32); 11570 } else { 11571 if (port < SOC_MAX_NUM_PORTS) { 11572 sal_memcpy(&(PORT(unit, port).m_info), port_state, 11573 sizeof(_bcm_port_metering_info_t)); 11574 } 11575 port_state += sizeof(_bcm_port_metering_info_t); 11576 } 11577 if (port < SOC_MAX_NUM_PORTS) { 11578 /* Recover flags */ 11579 sal_memcpy(&(PORT(unit, port).flags), port_state, sizeof(uint8)); 11580 } 11581 port_state += sizeof(uint8); 11582 } 11583 } 11584 #if defined(BCM_TOMAHAWK_SUPPORT) 11585 if (SOC_IS_TOMAHAWK(unit)) { 11586 PBMP_ALL_ITER(unit, port) { 11587 SOC_IF_ERROR_RETURN(soc_th_port_speed_recover(unit, port)); 11588 } 11589 } 11590 #endif 11591 #ifdef BCM_TRIDENT_SUPPORT 11592 if ((SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit)) && 11593 soc_feature(unit, soc_feature_flex_port)) { 11594 int num_lanes = 0; 11595 if (SOC_IS_TD_TT(unit)) { 11596 PBMP_ALL_ITER(unit, port) { 11597 sal_memcpy(&num_lanes, port_state, sizeof(int)); 11598 port_state += sizeof(int); 11599 if (si->port_num_lanes[port] != num_lanes) { 11600 #if defined(BCM_TOMAHAWK_SUPPORT) 11601 if (SOC_IS_TOMAHAWK(unit)) { 11602 SOC_IF_ERROR_RETURN 11603 (soc_th_flexport_recover(unit, port)); 11604 } 11605 #endif /* BCM_TOMAHAWK_SUPPORT */ 11606 #ifdef BCM_TRIDENT2_SUPPORT 11607 if (SOC_IS_TD2_TT2(unit) && 11608 (!(SOC_IS_TD2P_TT2P(unit) || 11609 SOC_IS_APACHE(unit) || 11610 SOC_IS_TOMAHAWK2(unit)))) { 11611 BCM_IF_ERROR_RETURN( 11612 _bcm_td2_flexport_recover(unit, port)); 11613 } 11614 #endif /* BCM_TRIDENT2_SUPPORT */ 11615 si->port_num_lanes[port] = num_lanes; 11616 _port_lanes_valid++; 11617 } 11618 } 11619 } 11620 #ifdef BCM_TRIUMPH3_SUPPORT 11621 else if (SOC_IS_TRIUMPH3(unit)) { 11622 PBMP_ALL_ITER(unit, port) { 11623 sal_memcpy(&_port_num_lanes[port], port_state, 11624 sizeof(int)); 11625 port_state += sizeof(int); 11626 _port_lanes_valid++; 11627 } 11628 } 11629 #endif /* BCM_TRIUMPH2_SUPPORT */ 11630 if (SOC_IS_TD_TT(unit) && (_port_lanes_valid > 0)) { 11631 /* Call PHY probe for flex port config to take effect */ 11632 if ((rv = bcm_esw_port_probe(unit, PBMP_PORT_ALL(unit), 11633 &port_bitmap)) != BCM_E_NONE) { 11634 LOG_ERROR(BSL_LS_BCM_PORT, \ 11635 (BSL_META_U(unit, \ 11636 "Error unit %d:\ 11637 Failed port probe: %s\n"), 11638 unit, bcm_errmsg(rv))); 11639 return rv; 11640 } 11641 } 11642 } 11643 #endif /* BCM_TRIDENT_SUPPORT */ 11644 } else { 11645 PBMP_ITER(all_pbmp, port) { 11646 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 11647 /* Recover port tx stop related info */ 11648 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 11649 realloc_size += sizeof(uint32); 11650 } else { 11651 realloc_size += sizeof(_bcm_port_metering_info_t); 11652 } 11653 /* Recover flags */ 11654 realloc_size += sizeof(uint8); 11655 } 11656 } 11657 } 11658 11659 if (recovered_ver >= BCM_PORT_WB_VERSION_1_2) { 11660 uint8 rx_los = 0; 11661 PBMP_ITER(all_pbmp, port) { 11662 #if defined(BCM_SABER2_SUPPORT) 11663 if(SOC_IS_SABER2(unit)) { 11664 if ((port == SOC_SB2_SAT_OAMP_PHY_PORT_NUMBER) && (oamp_status == 1)){ 11665 continue; 11666 } 11667 } 11668 #endif 11669 /* Recover RX_LOS */ 11670 rx_los = *port_state; 11671 port_state += sizeof(uint8); 11672 11673 if (IS_E_PORT(unit, port)) { 11674 /* Call PHY control for RX_lOS config to take effect */ 11675 if (rx_los == BCM_PORT_PHY_CONTROL_RX_LOS_NONE || 11676 rx_los == BCM_PORT_PHY_CONTROL_RX_LOS_SOFTWARE) { 11677 11678 if (!soc_feature(unit, soc_feature_no_sw_rx_los)){ 11679 rv = bcm_esw_port_phy_control_set(unit, port, 11680 BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, rx_los); 11681 if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) { 11682 LOG_ERROR(BSL_LS_BCM_PORT, 11683 (BSL_META_U(unit, 11684 "Error unit %d: " 11685 "Failed port phy control set: %s\n"), 11686 unit, bcm_errmsg(rv))); 11687 return rv; 11688 } 11689 } 11690 } 11691 } 11692 } 11693 } else { 11694 PBMP_ITER(all_pbmp, port) { 11695 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) 11696 && (stable_size > 0)) { 11697 /* Recover SW RX LOS status */ 11698 realloc_size += sizeof(uint8); 11699 } 11700 } 11701 } 11702 11703 #ifdef BCM_TRIDENT2_SUPPORT 11704 if (SOC_IS_TD2_TT2(unit)) { 11705 if (recovered_ver >= BCM_PORT_WB_VERSION_1_3) { 11706 PBMP_ITER(all_pbmp, port) { 11707 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) 11708 && (stable_size > 0)) { 11709 if (port < SOC_MAX_NUM_PORTS) { 11710 /* Recover port enable status */ 11711 sal_memcpy(&(PORT(unit, port).enable), 11712 port_state, sizeof(int)); 11713 } 11714 port_state += sizeof(int); 11715 } 11716 } 11717 } else { 11718 PBMP_ITER(all_pbmp, port) { 11719 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) 11720 && (stable_size > 0)) { 11721 /* Recover SW port enable status */ 11722 realloc_size += sizeof(int); 11723 } 11724 } 11725 } 11726 } 11727 #endif /* BCM_TRIDENT2_SUPPORT */ 11728 #ifdef BCM_TRIUMPH3_SUPPORT 11729 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit)) { 11730 if ((recovered_ver >= BCM_PORT_WB_VERSION_1_4) && _port_ibod_ctrl[unit]) { 11731 sal_memcpy(_port_ibod_ctrl[unit]->rrbyt, port_state, 11732 sizeof(((_port_ibod_ctrl_t *)0)->rrbyt)); 11733 port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrbyt); 11734 sal_memcpy(_port_ibod_ctrl[unit]->rrpkt, port_state, 11735 sizeof(((_port_ibod_ctrl_t *)0)->rrpkt)); 11736 port_state += sizeof(((_port_ibod_ctrl_t *)0)->rrpkt); 11737 sal_memcpy(&(_port_ibod_ctrl[unit]->event_count), port_state, 11738 sizeof(((_port_ibod_ctrl_t *)0)->event_count)); 11739 port_state += sizeof(((_port_ibod_ctrl_t *)0)->event_count); 11740 } else { 11741 realloc_size += sizeof(((_port_ibod_ctrl_t *)0)->rrbyt); 11742 realloc_size += sizeof(((_port_ibod_ctrl_t *)0)->rrpkt); 11743 realloc_size += sizeof(((_port_ibod_ctrl_t *)0)->event_count); 11744 } 11745 } 11746 /* 11747 * Recover the port force forward information from scache. 11748 * If the recovered version is lower than 1.5, allocate 11749 * space in scache for any further sync. 11750 */ 11751 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 11752 if (recovered_ver >= BCM_PORT_WB_VERSION_1_5) { 11753 BCM_IF_ERROR_RETURN( 11754 _bcm_port_force_forward_reinit(unit, &port_state)); 11755 } else { 11756 bcm_port_t egr_port; 11757 int enabled = 0; 11758 int port_forward_size = 0; 11759 PBMP_ITER(all_pbmp, port) { 11760 BCM_IF_ERROR_RETURN 11761 (bcm_esw_port_force_forward_get(unit, port, 11762 &egr_port, &enabled)); 11763 if (enabled) { 11764 _bcm_port_force_forward_add(unit, port, 11765 egr_port); 11766 } 11767 } 11768 BCM_IF_ERROR_RETURN( 11769 _bcm_port_force_forward_scache_size(unit, 11770 &port_forward_size)); 11771 realloc_size += port_forward_size; 11772 } 11773 } 11774 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */ 11775 11776 #ifdef BCM_TOMAHAWK_SUPPORT 11777 if (recovered_ver >= BCM_PORT_WB_VERSION_1_6) { 11778 /* ASF WB Recovery */ 11779 rv = _bcm_esw_asf_wb_recover(unit, port_state, recovered_ver); 11780 if (BCM_E_NONE != rv) { 11781 LOG_ERROR(BSL_LS_BCM_PORT, \ 11782 (BSL_META_U(unit, \ 11783 "Error unit %d:\ 11784 ASF Warmboot Recovery Failed: %s\n"), \ 11785 unit, bcm_errmsg(rv))); 11786 return rv; 11787 } 11788 port_state += asf_wbmem_sz; 11789 } 11790 11791 if (recovered_ver >= BCM_PORT_WB_VERSION_1_6) { 11792 /* Switch Latency Bypass WB Recovery */ 11793 rv = bcmi_esw_switch_latency_wb_recover(unit, port_state, recovered_ver); 11794 if (BCM_E_NONE != rv) { 11795 LOG_ERROR(BSL_LS_BCM_PORT, \ 11796 (BSL_META_U(unit, \ 11797 "Error unit %d:\ 11798 Switch Latency Bypass \ 11799 Warmboot Recovery Failed: %s\n"), \ 11800 unit, bcm_errmsg(rv))); 11801 return rv; 11802 } 11803 port_state += latency_wbmem_sz; 11804 } 11805 11806 /* sflow WB recovery */ 11807 rv = _bcm_esw_sflow_wb_recover(unit); 11808 if (BCM_E_NONE != rv) { 11809 LOG_ERROR(BSL_LS_BCM_PORT, (BSL_META_U(unit, "Error \ 11810 unit %d: sflow Warmboot Recovery Failed: %s\n"), unit, 11811 bcm_errmsg(rv))); 11812 return rv; 11813 } 11814 #endif /* BCM_TOMAHAWK_SUPPORT */ 11815 /*IFG WB*/ 11816 if (soc_feature(unit, soc_feature_xmac) || 11817 soc_feature(unit, soc_feature_xlmac) || 11818 soc_feature(unit, soc_feature_cmac) || 11819 soc_feature(unit, soc_feature_clmac)) { 11820 if (recovered_ver >= BCM_PORT_WB_VERSION_1_7) { 11821 BCM_IF_ERROR_RETURN( 11822 _bcm_esw_port_ifg_wb_reinit(unit, &port_state)); 11823 } else { 11824 PBMP_ITER(all_pbmp, port) { 11825 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) 11826 && (stable_size > 0)) { 11827 realloc_size += sizeof(uint32); 11828 } 11829 } 11830 } 11831 } 11832 /* PORT DSCP MAP SETTING */ 11833 if (soc_feature(unit, soc_feature_dscp) && 11834 soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 11835 if (recovered_ver >= BCM_PORT_WB_VERSION_1_11) { 11836 PBMP_ITER(all_pbmp, port) { 11837 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) 11838 && (stable_size > 0)) { 11839 /* Recover port dscp map status */ 11840 sal_memcpy(&(PORT(unit, port).port_dscp_map_set), 11841 port_state, sizeof(int)); 11842 port_state += sizeof(int); 11843 if (PORT(unit, port).port_dscp_map_set) { 11844 BCM_IF_ERROR_RETURN( 11845 _bcm_egr_dscp_table_entry_reference( 11846 unit, port * _BCM_QOS_MAP_CHUNK_EGR_DSCP, 11847 _BCM_QOS_MAP_CHUNK_EGR_DSCP)); 11848 } 11849 } 11850 } 11851 } else { 11852 PBMP_ITER(all_pbmp, port) { 11853 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) 11854 && (stable_size > 0)) { 11855 /* Recover SW port dscp map status */ 11856 realloc_size += sizeof(int); 11857 } 11858 } 11859 } 11860 } 11861 11862 #ifdef BCM_TOMAHAWK_SUPPORT 11863 if (SOC_IS_TOMAHAWK(unit) && recovered_ver >= BCM_PORT_WB_VERSION_1_12) { 11864 /* Recover port interface type */ 11865 int pif; 11866 PBMP_ITER(all_pbmp, port) { 11867 if (IS_XE_PORT(unit, port) || 11868 IS_CE_PORT(unit, port) || 11869 IS_HG_PORT(unit, port) || 11870 IS_GE_PORT(unit, port) || 11871 IS_MANAGEMENT_PORT(unit, port)) { 11872 sal_memcpy(&pif, port_state, sizeof(int)); 11873 port_state += sizeof(int); 11874 SOC_IF_ERROR_RETURN 11875 (soc_phyctrl_interface_set(unit, port, pif)); 11876 } 11877 } 11878 } 11879 #endif /* BCM_TOMAHAWK_SUPPORT */ 11880 if (soc_feature(unit, soc_feature_phy_interface_wb) && 11881 (recovered_ver >= BCM_PORT_WB_VERSION_1_13)) { 11882 /* Recover port interface type */ 11883 int pif; 11884 11885 PBMP_ITER(PBMP_PORT_ALL(unit), port) { 11886 sal_memcpy(&pif, port_state, sizeof(int)); 11887 port_state += sizeof(int); 11888 if (pif) { 11889 SOC_IF_ERROR_RETURN 11890 (soc_phyctrl_interface_set(unit, port, pif)); 11891 } 11892 } 11893 } 11894 11895 if (realloc_size > 0) { 11896 SOC_IF_ERROR_RETURN 11897 (soc_scache_realloc(unit, scache_handle, realloc_size)); 11898 } 11899 } else { 11900 /* 11901 * No level-2 cache configured. Proceed to Level-1 only recovery 11902 */ 11903 BCM_PBMP_CLEAR(dtm_pbmp); /* Default is dtag_mode == NONE */ 11904 #if defined(BCM_TRIUMPH3_SUPPORT) 11905 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 11906 bcm_port_t egr_port; 11907 int enabled = 0; 11908 11909 PBMP_ITER(all_pbmp, port) { 11910 SOC_IF_ERROR_RETURN 11911 (bcm_esw_port_force_forward_get(unit, port, 11912 &egr_port, &enabled)); 11913 if (enabled) { 11914 _bcm_port_force_forward_add(unit, port, 11915 egr_port); 11916 } 11917 } 11918 } 11919 #endif /* defined(BCM_TRIUMPH3_SUPPORT) */ 11920 } 11921 11922 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) || \ 11923 defined(BCM_KATANA2_SUPPORT) 11924 if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TOMAHAWK2(unit) || 11925 SOC_IS_TRIDENT3X(unit) || SOC_IS_KATANA2(unit)) { 11926 /* Recover port vlan action profile */ 11927 rv = _bcm_th_port_vlan_action_profile_reinit(unit); 11928 if (BCM_FAILURE(rv)) { 11929 return rv; 11930 } 11931 } 11932 #endif 11933 11934 /* Recover DT mode */ 11935 rv = _bcm_trx_port_dtag_mode_reinit(unit, dtm_pbmp, use_pbmp); 11936 if (BCM_FAILURE(rv)) { 11937 return rv; 11938 } 11939 #ifdef BCM_TRIUMPH2_SUPPORT 11940 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 11941 /* Recover ING_PRI_CNG_MAP references */ 11942 port_tab_entry_t pent; 11943 int ptr; 11944 uint32 ipc_ref_bmp[3]; 11945 /* Required: ING_PRI_CNG_MAP size <= 3 * 32 * 16 = 1536 */ 11946 11947 SHR_BITCLR_RANGE(ipc_ref_bmp, 0, 3*32); 11948 11949 /* Read port pointer, recover reference count */ 11950 PBMP_ITER(all_pbmp, port) { 11951 #ifdef BCM_TRIDENT3_SUPPORT 11952 if (SOC_IS_TRIDENT3X(unit)) { 11953 rv = _bcm_esw_port_tab_get(unit, port, 11954 TRUST_DOT1P_PTRf, &ptr); 11955 if (BCM_FAILURE(rv)) { 11956 break; 11957 } 11958 if (0 != ptr) { 11959 rv = _bcm_ing_pri_cng_map_entry_reference(unit, 11960 ptr * _BCM_TD3_PRI_CNG_MAP_SIZE, 11961 _BCM_TD3_PRI_CNG_MAP_SIZE); 11962 if (BCM_FAILURE(rv)) { 11963 break; 11964 } 11965 } 11966 11967 /* Recover PROTOCOL_PKT_CONTROL & 11968 * IGMP_MLD_PKT_CONTROL references */ 11969 if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype == 11970 soc_portreg) { 11971 /* Memory not allocated so no need to proceed */ 11972 continue; 11973 } 11974 rv = _bcm_esw_port_tab_get(unit, port, 11975 PROTOCOL_PKT_INDEXf, &ptr); 11976 if (BCM_FAILURE(rv)) { 11977 break; 11978 } 11979 if (0 != ptr) { 11980 rv = _bcm_prot_pkt_ctrl_reference(unit, ptr); 11981 if (BCM_FAILURE(rv)) { 11982 break; 11983 } 11984 /* Remove default reference */ 11985 rv = _bcm_prot_pkt_ctrl_delete(unit, 0); 11986 if (BCM_FAILURE(rv)) { 11987 break; 11988 } 11989 } 11990 } else 11991 #endif 11992 { 11993 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, 11994 SOC_PORT_MOD_OFFSET(unit, port), &pent); 11995 if (BCM_FAILURE(rv)) { 11996 break; 11997 } 11998 if (soc_feature(unit, soc_feature_color)) { 11999 ptr = soc_PORT_TABm_field32_get(unit, &pent, 12000 TRUST_DOT1P_PTRf); 12001 if (0 != ptr) { 12002 rv = _bcm_ing_pri_cng_map_entry_reference(unit, 12003 ptr * _BCM_TR2_PRI_CNG_MAP_SIZE, 12004 _BCM_TR2_PRI_CNG_MAP_SIZE); 12005 if (BCM_FAILURE(rv)) { 12006 break; 12007 } 12008 } 12009 } 12010 12011 /* Recover PROTOCOL_PKT_CONTROL & 12012 * IGMP_MLD_PKT_CONTROL references */ 12013 if (soc_mem_field_valid(unit, PORT_TABm, 12014 PROTOCOL_PKT_INDEXf)) { 12015 if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype == 12016 soc_portreg) { 12017 /* ========================================== */ 12018 /* Memory not allocated so no need to proceed */ 12019 /* if (SOC_IS_HURRICANE(unit)) */ 12020 /* ========================================== */ 12021 continue; 12022 } 12023 ptr = soc_PORT_TABm_field32_get(unit, &pent, 12024 PROTOCOL_PKT_INDEXf); 12025 if (0 != ptr) { 12026 rv = _bcm_prot_pkt_ctrl_reference(unit, ptr); 12027 if (BCM_FAILURE(rv)) { 12028 break; 12029 } 12030 /* Remove default reference */ 12031 rv = _bcm_prot_pkt_ctrl_delete(unit, 0); 12032 if (BCM_FAILURE(rv)) { 12033 break; 12034 } 12035 } 12036 } 12037 } 12038 } 12039 } 12040 if (BCM_FAILURE(rv)) { 12041 return rv; 12042 } 12043 #endif /* BCM_TRIUMPH2_SUPPORT */ 12044 #ifdef BCM_TRIDENT2PLUS_SUPPORT 12045 if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) { 12046 port_tab_entry_t pent; 12047 int ptr; 12048 PBMP_ITER(all_pbmp, port) { 12049 if (port > SOC_MAX_NUM_PORTS) { 12050 break; 12051 } 12052 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, 12053 SOC_PORT_MOD_OFFSET(unit, port), &pent); 12054 if (BCM_FAILURE(rv)) { 12055 break; 12056 } 12057 ptr = soc_PORT_TABm_field32_get(unit, &pent, 12058 MISC_PORT_PROFILE_INDEXf); 12059 if (0 != ptr) { 12060 rv = _bcm_misc_port_profile_mem_reference(unit, ptr, 1); 12061 if (BCM_FAILURE(rv)) { 12062 break; 12063 } 12064 } 12065 } 12066 } 12067 if (BCM_FAILURE(rv)) { 12068 return rv; 12069 } 12070 #endif 12071 12072 if (soc_feature(unit, soc_feature_e2ecc)) { 12073 rv = _bcm_esw_port_e2ecc_reinit(unit); 12074 } 12075 if (BCM_FAILURE(rv)) { 12076 return rv; 12077 } 12078 12079 #ifdef BCM_TRIUMPH2_SUPPORT 12080 /* Recover source modid egress blocking profiles */ 12081 if (soc_feature(unit, soc_feature_src_modid_blk_profile)) { 12082 uint32 regval, srcmod_index; 12083 int i, modid_count; 12084 12085 modid_count = SOC_MODID_MAX(unit) + 1; 12086 12087 PBMP_ITER(all_pbmp, port) { 12088 BCM_IF_ERROR_RETURN 12089 (READ_SRC_MODID_EGRESS_SELr(unit, port, ®val)); 12090 if (soc_reg_field_get(unit, 12091 SRC_MODID_EGRESS_SELr, regval, ENABLEf)) { 12092 srcmod_index = soc_reg_field_get(unit, 12093 SRC_MODID_EGRESS_SELr, regval, SRCMOD_INDEXf); 12094 PORT_SRC_MOD_EGR_PROF_PTR(unit, port) = srcmod_index; 12095 srcmod_index *= modid_count; 12096 for (i = 0; i < modid_count; i++) { 12097 SOC_PROFILE_MEM_REFERENCE(unit, 12098 PORT_SRC_MOD_EGR_PROFILE(unit), 12099 srcmod_index + i, 1); 12100 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, 12101 PORT_SRC_MOD_EGR_PROFILE(unit), 12102 srcmod_index + i, 12103 modid_count); 12104 } 12105 } 12106 } 12107 } 12108 #endif /* BCM_TRIUMPH2_SUPPORT */ 12109 12110 #ifdef BCM_TRIUMPH2_SUPPORT 12111 if ((SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 12112 SOC_IS_VALKYRIE2(unit)) && 12113 soc_feature(unit, soc_feature_flex_port)) { 12114 PBMP_ALL_ITER(unit, port) { 12115 if (_bcm_esw_valid_flex_port_controlling_port(unit, port)) { 12116 BCM_IF_ERROR_RETURN(_bcm_tr2_flexport_recover(unit, port)); 12117 } 12118 } 12119 /* Call PHY probe for config to take effect */ 12120 if ((rv = bcm_esw_port_probe(unit, PBMP_PORT_ALL(unit), 12121 &port_bitmap)) != BCM_E_NONE) { 12122 LOG_ERROR(BSL_LS_BCM_PORT, \ 12123 (BSL_META_U(unit, \ 12124 "Error unit %d:\ 12125 Failed port probe: %s\n"), 12126 unit, bcm_errmsg(rv))); 12127 return rv; 12128 } 12129 } 12130 #endif /* BCM_TRIUMPH2_SUPPORT */ 12131 12132 #if defined(BCM_GREYHOUND_SUPPORT) 12133 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 12134 /* 12135 * Recover the ref_cnt of enabling treat packet priority as 12136 * dot1p priority for different packet types or port controls, 12137 * if available. 12138 */ 12139 rv = bcmi_esw_port_treat_pktpri_as_dot1p_reinit(unit); 12140 if (BCM_FAILURE(rv)) { 12141 return rv; 12142 } 12143 } 12144 #endif /* BCM_GREYHOUND_SUPPORT */ 12145 12146 if (SOC_IS_HURRICANEX(unit) || SOC_IS_TRIUMPH2(unit) || \ 12147 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA(unit) || \ 12148 SOC_IS_ENDURO(unit) || SOC_IS_GREYHOUND(unit) || \ 12149 SOC_IS_VALKYRIE(unit)) { 12150 bcm_esw_port_mdix_wb_update(unit); 12151 } 12152 } 12153 #endif /* BCM_TRX_SUPPORT */ 12154 #if defined(BCM_RAVEN_SUPPORT) 12155 if (SOC_IS_RAVEN(unit)) { 12156 bcm_esw_port_mdix_wb_update(unit); 12157 } 12158 #endif /* BCM_RAVEN_SUPPORT */ 12159 #ifdef BCM_PREEMPTION_SUPPORT 12160 if (soc_feature(unit, soc_feature_preemption)) { 12161 soc_scache_handle_t scache_handle; 12162 12163 SOC_SCACHE_HANDLE_SET(scache_handle, 12164 unit, BCM_MODULE_PORT, 12165 BCM_PORT_WB_SCACHE_PART_PREMMPTION); 12166 rv = bcmi_esw_preemption_recover(unit, scache_handle); 12167 if (BCM_FAILURE(rv)) { 12168 return rv; 12169 } 12170 } 12171 #endif /* BCM_PREEMPTION_SUPPORT */ 12172 12173 return rv; 12174 } 12175 #else 12176 #define _bcm_port_vd_pbvl_reinit(u) (BCM_E_NONE) 12177 #define _bcm_esw_port_wb_recover(u) (BCM_E_NONE) 12178 #define _bcm_esw_port_wb_alloc(u) (BCM_E_NONE) 12179 #endif /* BCM_WARM_BOOT_SUPPORT */ 12180 12181 #ifndef BCM_SW_STATE_DUMP_DISABLE 12182 /* 12183 * Function: 12184 * _bcm_esw_flexport_sw_dump 12185 * Purpose: 12186 * Displays port information after flexport. 12187 * Parameters: 12188 * unit - Device unit number 12189 * Returns: 12190 * None 12191 * Note: 12192 */ 12193 void 12194 _bcm_esw_flexport_sw_dump(int unit) 12195 { 12196 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 12197 if (SOC_IS_TRIDENT2PLUS(unit)) { 12198 soc_flexport_sw_dump(unit); 12199 } 12200 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 12201 12202 #if defined(BCM_TOMAHAWK3_SUPPORT) 12203 if (SOC_IS_TOMAHAWK3(unit)) { 12204 soc_th3_flexport_sw_dump(unit); 12205 } 12206 #endif /* BCM_TOMAHAWK3_SUPPORT */ 12207 12208 #if defined(BCM_TOMAHAWK2_SUPPORT) 12209 if (SOC_IS_TOMAHAWK2(unit)) { 12210 soc_th2_flexport_sw_dump(unit); 12211 } 12212 #endif /* BCM_TOMAHAWK2_SUPPORT */ 12213 12214 #if defined(BCM_TOMAHAWK_SUPPORT) 12215 if (SOC_IS_TOMAHAWK(unit)) { 12216 soc_th_flexport_sw_dump(unit); 12217 } 12218 #endif /* BCM_TOMAHAWK_SUPPORT */ 12219 12220 } 12221 12222 void 12223 _bcm_esw_flexport_sw_pipe_speed_group_dump( 12224 int unit, 12225 int pipe, 12226 int speed_id) 12227 { 12228 #if defined(BCM_TOMAHAWK_SUPPORT) 12229 if (SOC_IS_TOMAHAWK(unit)) { 12230 soc_th_flexport_sw_pipe_speed_group_dump( 12231 unit, pipe, speed_id); 12232 } 12233 #endif /* BCM_TOMAHAWK_SUPPORT */ 12234 } 12235 12236 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 12237 12238 static int 12239 _bcm_esw_glp_bits_pos(int unit, 12240 uint8 *trunk_pos, uint8 *max_modid, 12241 uint8 *modid_pos, uint8 *max_port); 12242 12243 #if defined(BCM_FIREBOLT_SUPPORT) 12244 /* 12245 * Function: 12246 * _bcm_port_vd_pbvl_init 12247 * Purpose: 12248 * Initialization of vd_pbvl bitmap in port 12249 * Parameters: 12250 * unit - StrataSwitch unit number. 12251 * Returns: 12252 * BCM_E_NONE - success (or already initialized) 12253 * BCM_E_MEMORY - failed to allocate required memory. 12254 */ 12255 12256 STATIC int 12257 _bcm_port_vd_pbvl_init(int unit) 12258 { 12259 bcm_port_t port; 12260 int idxmax; 12261 int inds_bytes; 12262 bcm_pbmp_t all_pbmp; 12263 12264 #if defined(BCM_TOMAHAWK3_SUPPORT) 12265 /* TH3 does not support VLAN Protocol feature. Return doing nothing */ 12266 if (SOC_IS_TOMAHAWK3(unit)) { 12267 return BCM_E_NONE; 12268 } 12269 #endif 12270 12271 idxmax = soc_mem_index_count(unit, VLAN_PROTOCOLm); 12272 /* Round to the next entry */ 12273 inds_bytes = 12274 (idxmax + (_BCM_PORT_VD_PBVL_ESIZE - 1)) / _BCM_PORT_VD_PBVL_ESIZE; 12275 12276 BCM_PBMP_CLEAR(all_pbmp); 12277 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 12278 12279 #ifdef BCM_KATANA2_SUPPORT 12280 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 12281 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 12282 } 12283 if (soc_feature(unit, soc_feature_linkphy_coe) || 12284 soc_feature(unit, soc_feature_subtag_coe)) { 12285 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 12286 } 12287 #endif 12288 12289 PBMP_ITER(all_pbmp, port) { 12290 PORT(unit, port).p_vd_pbvl = sal_alloc(inds_bytes, "vdv_info"); 12291 if (NULL == PORT(unit, port).p_vd_pbvl) { 12292 return (BCM_E_MEMORY); 12293 } 12294 12295 sal_memset(PORT(unit, port).p_vd_pbvl, 0, inds_bytes); 12296 } 12297 12298 #ifdef BCM_WARM_BOOT_SUPPORT 12299 if (SOC_WARM_BOOT(unit)) { 12300 BCM_IF_ERROR_RETURN(_bcm_port_vd_pbvl_reinit(unit)); 12301 } 12302 #endif 12303 12304 return BCM_E_NONE; 12305 } 12306 #endif /* BCM_FIREBOLT_SUPPORT */ 12307 12308 /* 12309 * Function: 12310 * _bcm_esw_port_software_detach 12311 * Purpose: 12312 * De-initialization of software for port subsystem. 12313 * Parameters: 12314 * unit - StrataSwitch unit number. 12315 * Returns: 12316 * BCM_E_NONE - success (or already initialized) 12317 * BCM_E_INTERNAL- failed to write PTABLE entries 12318 * BCM_E_MEMORY - failed to allocate required memory. 12319 */ 12320 12321 int 12322 _bcm_esw_port_software_detach(int unit) 12323 { 12324 bcm_port_t port; 12325 bcm_pbmp_t all_pbmp; 12326 12327 BCM_PBMP_CLEAR(all_pbmp); 12328 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 12329 12330 #ifdef BCM_KATANA2_SUPPORT 12331 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 12332 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 12333 } 12334 if (soc_feature(unit, soc_feature_linkphy_coe) || 12335 soc_feature(unit, soc_feature_subtag_coe)) { 12336 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 12337 } 12338 #endif 12339 12340 if (bcm_port_info[unit] == NULL) { 12341 return (BCM_E_NONE); 12342 } 12343 12344 PBMP_ITER(all_pbmp, port) { 12345 if (NULL != PORT(unit, port).p_vd_pbvl) { 12346 sal_free(PORT(unit, port).p_vd_pbvl); 12347 PORT(unit, port).p_vd_pbvl = NULL; 12348 } 12349 12350 if (NULL != PORT(unit, port).e2ecc_config) { 12351 sal_free(PORT(unit, port).e2ecc_config); 12352 PORT(unit, port).e2ecc_config = NULL; 12353 } 12354 } 12355 12356 SOC_IF_ERROR_RETURN(soc_phy_common_detach(unit)); 12357 12358 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 12359 || defined(BCM_RAVEN_SUPPORT) 12360 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 12361 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_detach(unit)); 12362 } 12363 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT \ 12364 || BCM_RAPTOR_SUPPORT */ 12365 12366 #ifdef BCM_TRIUMPH2_SUPPORT 12367 if (NULL != PORT_SRC_MOD_EGR_PROFILE(unit)) { 12368 BCM_IF_ERROR_RETURN 12369 (soc_profile_mem_destroy(unit, PORT_SRC_MOD_EGR_PROFILE(unit))); 12370 sal_free(PORT_SRC_MOD_EGR_PROFILE(unit)); 12371 PORT_SRC_MOD_EGR_PROFILE(unit) = NULL; 12372 } 12373 #endif /* BCM_TRIUMPH2_SUPPORT */ 12374 #if defined(BCM_TRIDENT_SUPPORT) 12375 if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 12376 BCM_IF_ERROR_RETURN(bcm_td_port_deinit(unit)); 12377 } 12378 #endif /* BCM_TRIDENT_SUPPORT */ 12379 12380 sal_free (bcm_port_info[unit]); 12381 bcm_port_info[unit] = NULL; 12382 12383 return BCM_E_NONE; 12384 } 12385 12386 /* 12387 * Function: 12388 * _bcm_port_software_init 12389 * Purpose: 12390 * Initialization of software for port subsystem. 12391 * Parameters: 12392 * unit - StrataSwitch unit number. 12393 * Returns: 12394 * BCM_E_NONE - success (or already initialized) 12395 * BCM_E_INTERNAL- failed to write PTABLE entries 12396 * BCM_E_MEMORY - failed to allocate required memory. 12397 */ 12398 12399 STATIC int 12400 _bcm_port_software_init(int unit) 12401 { 12402 bcm_port_t port = 0; 12403 int max_num_port = 0; 12404 bcm_pbmp_t all_pbmp; 12405 12406 BCM_PBMP_CLEAR(all_pbmp); 12407 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 12408 max_num_port = SOC_MAX_NUM_PORTS; 12409 12410 #ifdef BCM_KATANA2_SUPPORT 12411 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 12412 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 12413 } 12414 if (soc_feature(unit, soc_feature_linkphy_coe) || 12415 soc_feature(unit, soc_feature_subtag_coe)) { 12416 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 12417 max_num_port = SOC_MAX_NUM_PP_PORTS; 12418 } 12419 #endif 12420 12421 if (bcm_port_info[unit] != NULL) { 12422 PBMP_ITER(all_pbmp, port) { 12423 if (PORT(unit, port).p_vd_pbvl != NULL) { 12424 sal_free(PORT(unit, port).p_vd_pbvl); 12425 PORT(unit, port).p_vd_pbvl = NULL; 12426 } 12427 12428 if (PORT(unit, port).e2ecc_config != NULL) { 12429 sal_free(PORT(unit, port).e2ecc_config); 12430 PORT(unit, port).e2ecc_config = NULL; 12431 } 12432 12433 PORT(unit, port).flags = 0; 12434 #ifdef BCM_TRIDENT2_SUPPORT 12435 if (SOC_IS_TD2_TT2(unit)) { 12436 PORT(unit, port).enable = TRUE; 12437 } 12438 #endif /* BCM_TRIDENT2_SUPPORT */ 12439 } 12440 } 12441 12442 if (bcm_port_info[unit] == NULL) { 12443 bcm_port_info[unit] = sal_alloc(sizeof(_bcm_port_info_t) * max_num_port, 12444 "bcm_port_info"); 12445 if (bcm_port_info[unit] == NULL) { 12446 return BCM_E_MEMORY; 12447 } 12448 } 12449 sal_memset(bcm_port_info[unit], 0, sizeof(_bcm_port_info_t) * max_num_port); 12450 12451 SOC_IF_ERROR_RETURN(soc_phy_common_init(unit)); 12452 #if defined(BCM_FIREBOLT_SUPPORT) 12453 if (SOC_IS_FBX(unit)) { 12454 BCM_IF_ERROR_RETURN(_bcm_port_vd_pbvl_init(unit)); 12455 } 12456 #endif /* BCM_FIREBOLT_SUPPORT */ 12457 12458 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 12459 || defined(BCM_RAVEN_SUPPORT) 12460 if (SOC_WARM_BOOT(unit)) { 12461 #ifdef BCM_TRIUMPH2_SUPPORT 12462 /* Moved to here for TD3 since the warm boot function call order changed */ 12463 if (soc_feature(unit, soc_feature_lport_tab_profile)) { 12464 BCM_IF_ERROR_RETURN(bcm_esw_port_lport_profile_recover(unit)); 12465 } 12466 if (soc_feature(unit, soc_feature_egr_lport_tab_profile)) { 12467 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_profile_recover(unit)); 12468 } 12469 #endif 12470 } 12471 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 12472 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_init(unit)); 12473 } 12474 if (soc_feature(unit, soc_feature_color_prio_map)) { 12475 BCM_IF_ERROR_RETURN(_bcm_fb2_priority_map_init(unit)); 12476 } 12477 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT \ 12478 || BCM_RAPTOR_SUPPORT */ 12479 12480 #if defined(BCM_TRX_SUPPORT) 12481 if (SOC_IS_TRX(unit)) { 12482 for (port = 0; port < max_num_port; port++) { 12483 PORT(unit, port).dtag_mode = BCM_PORT_DTAG_MODE_NONE; 12484 } 12485 } 12486 #endif 12487 12488 #ifdef BCM_WARM_BOOT_SUPPORT 12489 if (SOC_WARM_BOOT(unit)) { 12490 #if defined(BCM_XGS_SWITCH_SUPPORT) 12491 if (soc_feature(unit, soc_feature_remap_ut_prio)) { 12492 bcm_port_cfg_t pcfg; 12493 PBMP_ITER(all_pbmp, port) { 12494 SOC_IF_ERROR_RETURN 12495 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, 12496 &pcfg)); 12497 PORT(unit, port).p_ut_prio = pcfg.pc_new_opri; 12498 } 12499 } 12500 #ifdef BCM_TRIDENT2_SUPPORT 12501 if (SOC_IS_TD2_TT2(unit)) { 12502 PBMP_ITER(all_pbmp, port) { 12503 PORT(unit, port).enable = TRUE; 12504 } 12505 } 12506 #endif /* BCM_TRIDENT2_SUPPORT */ 12507 #endif /* BCM_XGS_SWITCH_SUPPORT */ 12508 #if defined(BCM_TRX_SUPPORT) 12509 if (SOC_IS_TRX(unit)) { 12510 PBMP_ITER(all_pbmp, port) { 12511 /* Recover port's dtag_mode */ 12512 PORT(unit, port).dtag_mode = BCM_PORT_DTAG_MODE_NONE; 12513 } 12514 } 12515 #endif /* BCM_TRX_SUPPORT */ 12516 } 12517 #endif /* BCM_WARM_BOOT_SUPPORT */ 12518 12519 return BCM_E_NONE; 12520 } 12521 12522 /* 12523 * Function: 12524 * _bcm_port_settings_init 12525 * Purpose: 12526 * Initialize port settings if they are to be different from the 12527 * default ones 12528 * Parameters: 12529 * unit - StrataSwitch unit number. 12530 * port - port number 12531 * Returns: 12532 * BCM_E_NONE - success (or already initialized) 12533 * BCM_E_INTERNAL- failed to write PTABLE entries 12534 * Notes: 12535 * This function initializes port settings based on the folowing config 12536 * variables: 12537 * port_init_speed 12538 * port_init_duplex 12539 * port_init_adv 12540 * port_init_autoneg 12541 * If a variable is not set, then no additional initialization of the 12542 * corresponding parameter is done (and the defaults will normally be 12543 * advertize everything you can do and use autonegotiation). 12544 * 12545 * A typical use would be to set: 12546 * port_init_adv=0 12547 * port_init_autoneg=1 12548 * to force link down in the beginning. 12549 * 12550 * Another setup that makes sense is something like: 12551 * port_init_speed=10 12552 * port_init_duplex=0 12553 * port_init_autoneg=0 12554 * in order to force link into a certain mode. (It is very important to 12555 * disable autonegotiation in this case). 12556 * 12557 * PLEASE NOTE: 12558 * The standard rc.soc forces autoneg=on on all the ethernet ports 12559 * (FE and GE). Thus, to use the second example one has to edit rc.soc 12560 * as well. 12561 * 12562 * This function has been declared as global, but not exported. This will 12563 * make port initialization easier when using VxWorks shell. 12564 */ 12565 int 12566 bcm_port_settings_init(int unit, bcm_port_t port) 12567 { 12568 int val; 12569 bcm_port_info_t info; 12570 12571 LOG_INFO(BSL_LS_BCM_PORT, 12572 (BSL_META_U(unit, 12573 "bcm_port_settings_init: u=%d p=%d\n"),unit, port)); 12574 12575 bcm_port_info_t_init(&info); 12576 12577 val = soc_property_port_get(unit, port, spn_PORT_INIT_SPEED, -1); 12578 if (val != -1) { 12579 info.speed = val; 12580 info.action_mask |= BCM_PORT_ATTR_SPEED_MASK; 12581 } 12582 12583 val = soc_property_port_get(unit, port, spn_PORT_INIT_DUPLEX, -1); 12584 if (val != -1) { 12585 info.duplex = val; 12586 info.action_mask |= BCM_PORT_ATTR_DUPLEX_MASK; 12587 } 12588 12589 val = soc_property_port_get(unit, port, spn_PORT_INIT_ADV, -1); 12590 if (val != -1) { 12591 info.local_advert = val; 12592 info.action_mask |= BCM_PORT_ATTR_LOCAL_ADVERT_MASK; 12593 } 12594 12595 val = soc_property_port_get(unit, port, spn_PORT_INIT_AUTONEG, -1); 12596 if (val != -1) { 12597 info.autoneg = val; 12598 info.action_mask |= BCM_PORT_ATTR_AUTONEG_MASK; 12599 } 12600 return bcm_esw_port_selective_set(unit, port, &info); 12601 } 12602 12603 #ifdef BCM_TRIUMPH2_SUPPORT 12604 /* Helper function to program logical to physical (and reverse) port mapping */ 12605 STATIC int 12606 _bcm_port_remap_set(int unit, bcm_port_t phys, bcm_port_t logical) 12607 { 12608 port_tab_entry_t ptab; 12609 sys_portmap_entry_t sys_portmap; 12610 uint32 regval; 12611 12612 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, 12613 MEM_BLOCK_ANY, phys, &ptab)); 12614 soc_PORT_TABm_field32_set(unit, &ptab, SRC_SYS_PORT_IDf, logical); 12615 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_TABm, 12616 MEM_BLOCK_ALL, phys, &ptab)); 12617 12618 SOC_IF_ERROR_RETURN(soc_mem_read(unit, SYS_PORTMAPm, 12619 MEM_BLOCK_ANY, logical, &sys_portmap)); 12620 soc_SYS_PORTMAPm_field32_set(unit, &sys_portmap, PHYS_PORT_IDf, phys); 12621 SOC_IF_ERROR_RETURN(soc_mem_write(unit, SYS_PORTMAPm, 12622 MEM_BLOCK_ALL, logical, &sys_portmap)); 12623 12624 /* Configure E2ECC port mapping register */ 12625 SOC_IF_ERROR_RETURN(READ_E2ECC_PORT_MAPPINGr(unit, phys, ®val)); 12626 soc_reg_field_set(unit, E2ECC_PORT_MAPPINGr, ®val, MAPPED_PORT_NUMf, logical); 12627 SOC_IF_ERROR_RETURN(WRITE_E2ECC_PORT_MAPPINGr(unit, phys, regval)); 12628 12629 return BCM_E_NONE; 12630 } 12631 12632 STATIC int 12633 _bcm_tr2_system_tpid_init(int unit) 12634 { 12635 int tpid_index, sys_index, rv = BCM_E_NONE; 12636 bcm_module_t module; 12637 bcm_port_t port; 12638 system_config_table_entry_t systab; 12639 uint32 tpid_enable; 12640 uint16 tpid; 12641 12642 tpid = _bcm_fb2_outer_tpid_default_get(unit); 12643 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_lkup(unit, tpid, &tpid_index)); 12644 12645 for (module = 0; module <= SOC_MODID_MAX(unit); module++) { 12646 for (port = 0; port < 64; port++) { 12647 sys_index = module * 64 + port; 12648 rv = READ_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ANY, 12649 sys_index, &systab); 12650 BCM_IF_ERROR_RETURN(rv); 12651 tpid_enable = (1 << tpid_index); 12652 soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &systab, 12653 OUTER_TPID_ENABLEf, 12654 tpid_enable); 12655 rv = WRITE_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ALL, 12656 sys_index, &systab); 12657 BCM_IF_ERROR_RETURN(rv); 12658 } 12659 } 12660 return rv; 12661 } 12662 #endif 12663 12664 /* 12665 * Function: 12666 * _bcm_esw_port_deinit 12667 * Purpose: 12668 * De-initialize the PORT interface layer for the specified SOC device. 12669 * Parameters: 12670 * unit - StrataSwitch unit number. 12671 * Returns: 12672 * BCM_E_XXX 12673 */ 12674 int 12675 _bcm_esw_port_deinit(int unit) 12676 { 12677 int rv; 12678 12679 if (NULL == bcm_port_info[unit]) { 12680 return (BCM_E_NONE); 12681 } 12682 12683 rv = _bcm_esw_port_software_detach(unit); 12684 BCM_IF_ERROR_RETURN(rv); 12685 12686 #ifdef BCM_TRX_SUPPORT 12687 if (soc_feature(unit, soc_feature_vlan_action) || 12688 soc_feature(unit,soc_feature_egr_vlan_action)) { 12689 #ifdef BCM_TRIUMPH2_SUPPORT 12690 if (soc_feature(unit, soc_feature_vpd_profile)) { 12691 _bcm_tr2_port_vpd_bitmap_free(unit); 12692 } 12693 #endif /* BCM_TRIUMPH2_SUPPORT */ 12694 12695 /* Initialize the vlan action profile table */ 12696 #if defined(BCM_TOMAHAWK3_SUPPORT) 12697 if (SOC_IS_TOMAHAWK3(unit)) { 12698 rv = _bcm_th3_vlan_action_profile_detach(unit); 12699 } else 12700 #endif /* BCM_TOMAHAWK3_SUPPORT */ 12701 { 12702 rv = _bcm_trx_vlan_action_profile_detach(unit); 12703 } 12704 BCM_IF_ERROR_RETURN(rv); 12705 } 12706 #endif /* BCM_TRX_SUPPORT */ 12707 12708 #ifdef BCM_TRIUMPH2_SUPPORT 12709 if (soc_feature(unit, soc_feature_gport_service_counters)) { 12710 rv = _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeGport); 12711 BCM_IF_ERROR_RETURN(rv); 12712 } 12713 #endif /* BCM_TRIUMPH2_SUPPORT */ 12714 12715 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \ 12716 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) 12717 if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) || 12718 SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 12719 SOC_IS_APACHE(unit)) && 12720 (soc_feature(unit,soc_feature_timesync_support))) { 12721 _bcm_esw_port_timesync_profile_delete(unit); 12722 } 12723 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || 12724 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */ 12725 12726 #if defined(BCM_TRIUMPH3_SUPPORT) 12727 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 12728 rv = _bcm_port_force_forward_deinit(unit); 12729 if(BCM_FAILURE(rv)) { 12730 return rv; 12731 } 12732 } 12733 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/ 12734 #if defined(BCM_TOMAHAWK_SUPPORT) 12735 if (soc_feature(unit, soc_feature_asf_multimode)) { 12736 /* deinit ASF (cutthrough) subsystem */ 12737 BCM_IF_ERROR_RETURN(_bcm_esw_asf_deinit(unit)); 12738 } 12739 #endif 12740 #ifdef BCM_TRIUMPH3_SUPPORT 12741 if (SOC_IS_TRIUMPH3(unit)) { 12742 _bcm_esw_ibod_sync_recovery_stop(unit); 12743 } 12744 #endif 12745 #ifdef BCM_PREEMPTION_SUPPORT 12746 if (soc_feature(unit, soc_feature_preemption)) { 12747 bcmi_esw_preemption_cleanup(unit); 12748 } 12749 if (soc_feature(unit, soc_feature_preemption_cnt)) { 12750 bcmi_esw_preemption_counter_cleanup(unit); 12751 } 12752 #endif /* BCM_PREEMPTION_SUPPORT */ 12753 #if defined(BCM_GREYHOUND_SUPPORT) 12754 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 12755 BCM_IF_ERROR_RETURN( 12756 bcmi_esw_port_treat_pktpri_as_dot1p_cleanup(unit)); 12757 } 12758 #endif /* BCM_GREYHOUND_SUPPORT */ 12759 12760 return BCM_E_NONE; 12761 } 12762 12763 #ifdef BCM_TRIDENT_SUPPORT 12764 #ifdef BCM_WARM_BOOT_SUPPORT 12765 /* 12766 * Function: 12767 * _bcm_td_phymode_reconfigure 12768 * Purpose: 12769 * Reconfigure the mode of the phys during warmboot. 12770 * This function has code copied from _soc_trident_misc_init 12771 * to keep the phy modes consistent in cold and warmboot modes. 12772 * This is required to be called before the phy probe routines 12773 * in order for the mode to be configured correctly. 12774 * Parameters: 12775 * unit - StrataSwitch unit number. 12776 * Returns: 12777 * BCM_E_XXX 12778 */ 12779 STATIC int 12780 _bcm_td_phymode_reconfigure(int unit) { 12781 12782 soc_info_t *si = &SOC_INFO(unit); 12783 int port, blk, blk_port, num_lanes, phy_port, bindex; 12784 12785 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 12786 blk_port = SOC_BLOCK_PORT(unit, blk); 12787 if (blk_port < 0) { 12788 continue; 12789 } 12790 /* 12791 * Program XLPORT mode and default Warpcore lanes setting 12792 * core_mode: the number of ports on the system side of XMAC 12793 * phy_mode: the number of ports on the Warpcore side of XMAC 12794 * num_lanes: the number of lanes on the line side of Warpcore 12795 */ 12796 if (si->port_speed_max[blk_port] > 20000) { 12797 num_lanes = 4; 12798 } else if (si->port_speed_max[blk_port] > 10000) { 12799 if (si->port_speed_max[blk_port] == 20000 && 12800 si->port_num_lanes[blk_port] == 4) { 12801 num_lanes = 4; 12802 } else { 12803 num_lanes = 2; 12804 } 12805 } else { 12806 num_lanes = 1; 12807 } 12808 12809 phy_port = ((si->port_l2p_mapping[blk_port] - 1) & ~0x3) + 1; 12810 for (bindex = 0; bindex < 4; bindex++) { 12811 port = si->port_p2l_mapping[phy_port + bindex]; 12812 if (port == -1) { 12813 continue; 12814 } 12815 si->port_num_lanes[port] = num_lanes; 12816 } 12817 } 12818 return BCM_E_NONE; 12819 } 12820 #endif /* BCM_WARM_BOOT_SUPPORT */ 12821 #endif /* BCM_TRIDENT_SUPPORT */ 12822 12823 #ifdef BCM_WARM_BOOT_SUPPORT 12824 #ifdef BCM_TRIUMPH3_SUPPORT 12825 STATIC int _bcm_tr3_flexport_wb_recover(int unit) 12826 { 12827 int rv = BCM_E_NONE; 12828 int alloc_sz = 0; 12829 uint8 *port_state; 12830 uint16 recovered_ver; 12831 bcm_port_t port; 12832 int stable_size; 12833 soc_scache_handle_t scache_handle; 12834 soc_info_t *si = &SOC_INFO(unit); 12835 int _port_lanes_valid = 0; 12836 int _port_num_lanes[SOC_MAX_NUM_PORTS] = {0}; 12837 bcm_pbmp_t all_pbmp; 12838 12839 BCM_PBMP_CLEAR(all_pbmp); 12840 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 12841 12842 /* Calculate the offset of port_num_lanes */ 12843 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 12844 PBMP_ITER(all_pbmp, port) { 12845 alloc_sz += sizeof(int); /* vp count */ 12846 } 12847 alloc_sz += sizeof(bcm_pbmp_t); /* Bitmap of dtag_mode == NONE */ 12848 PBMP_ITER(all_pbmp, port) { 12849 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 12850 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 12851 alloc_sz += sizeof(uint32); 12852 } else { 12853 alloc_sz += sizeof(_bcm_port_metering_info_t); 12854 } 12855 alloc_sz += sizeof(uint8); /* flags */ 12856 } 12857 } 12858 alloc_sz += (SOC_MAX_NUM_PORTS * sizeof(int)); /* num lanes of port */ 12859 12860 /* Get port_num_lanes from scahe */ 12861 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_PORT, 12862 BCM_PORT_WB_SCACHE_PART_DEFAULT); 12863 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 12864 alloc_sz, (uint8**)&port_state, 12865 BCM_PORT_WB_DEFAULT_VERSION, &recovered_ver); 12866 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 12867 return rv; 12868 } 12869 12870 port_state += (alloc_sz - (SOC_MAX_NUM_PORTS * sizeof(int))); 12871 if (recovered_ver >= BCM_PORT_WB_VERSION_1_1) { 12872 PBMP_ALL_ITER(unit, port) { 12873 sal_memcpy(&_port_num_lanes[port], port_state, 12874 sizeof(int)); 12875 port_state += sizeof(int); 12876 _port_lanes_valid++; 12877 } 12878 } 12879 12880 /* Recover port_num_lanes */ 12881 if (_port_lanes_valid) { 12882 PBMP_ALL_ITER(unit, port) { 12883 if (soc_tr3_port_is_flex_port(unit, port) && 12884 (si->port_num_lanes[port] != _port_num_lanes[port])) { 12885 LOG_VERBOSE(BSL_LS_BCM_PORT, 12886 (BSL_META_U(unit, 12887 "Port %d needs flex transform !!\n"), 12888 port)); 12889 if ((rv = _bcm_tr3_port_lanes_set(unit, port, 12890 _port_num_lanes[port])) != BCM_E_NONE) { 12891 LOG_ERROR(BSL_LS_BCM_PORT, \ 12892 (BSL_META_U(unit, \ 12893 "Error unit %d: "\ 12894 "Failed port lanes set: %s\n"), 12895 unit, bcm_errmsg(rv))); 12896 return rv; 12897 } 12898 } 12899 } 12900 (void)soc_port_type_verify(unit); 12901 } 12902 12903 return rv; 12904 } 12905 12906 STATIC void 12907 _bcm_tr3_port_info_reconfig(int unit) 12908 { 12909 soc_port_t port; 12910 12911 PBMP_ALL_ITER(unit, port) { 12912 if (IS_AXP_PORT(unit, port)) { 12913 /* Physical port table index doesn't exist for AXP ports */ 12914 continue; 12915 } 12916 /* cache num of port lanes */ 12917 (void)soc_tr3_port_lanes_gen(unit, port, &SOC_INFO(unit).port_num_lanes[port], NULL); 12918 } 12919 12920 if (soc_feature(unit, soc_feature_flex_port)) { 12921 _bcm_tr3_flexport_wb_recover(unit); 12922 } 12923 } 12924 #endif /* BCM_TRIUMPH3_SUPPORT */ 12925 #endif /* BCM_WARM_BOOT_SUPPORT */ 12926 12927 #ifdef BCM_HIGIG2_SUPPORT 12928 /* 12929 * Function: 12930 * _bcm_esw_port_higig2_mode_set 12931 * Purpose: 12932 * Set port Higig2 mode 12933 * Parameters: 12934 * unit - StrataSwitch unit # 12935 * port - StrataSwitch port # 12936 * higig2_mode - Higig2 mode 12937 * Returns: 12938 * BCM_E_XXX 12939 */ 12940 int 12941 _bcm_esw_port_higig2_mode_set(int unit, bcm_port_t port, int higig2_mode) 12942 { 12943 soc_reg_t egr_port_reg; 12944 soc_mem_t egr_port_mem; 12945 12946 if (SOC_USE_PORTCTRL(unit)) { 12947 return bcmi_esw_portctrl_higig2_mode_set(unit, port, higig2_mode); 12948 } 12949 12950 if (!SOC_IS_KATANA2(unit)) { 12951 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, port, 12952 _BCM_CPU_TABS_NONE, HIGIG2f, higig2_mode)); 12953 } 12954 egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 12955 SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) || 12956 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ? 12957 EGR_PORT_64r : EGR_PORTr; 12958 if (SOC_REG_FIELD_VALID(unit, egr_port_reg, HIGIG2f)) { 12959 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, egr_port_reg, port, 12960 HIGIG2f, higig2_mode)); 12961 } else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, HIGIG2f)) { 12962 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, EGR_PORTm, port, 12963 HIGIG2f, higig2_mode)); 12964 } 12965 12966 #if defined(BCM_SABER2_SUPPORT) 12967 if(SOC_IS_SABER2(unit)) { 12968 /* For Saber2, configure IECELL along with XLPORT */ 12969 if (SOC_REG_PORT_VALID(unit, IECELL_CONFIGr, port)) { 12970 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 12971 IECELL_CONFIGr, port, HIGIG2_MODEf, higig2_mode)); 12972 12973 } 12974 } 12975 #endif 12976 12977 if (IS_CL_PORT(unit, port) && 12978 SOC_REG_FIELD_VALID(unit, CLPORT_CONFIGr, HIGIG2_MODEf)) { 12979 uint32 clp_hg2_mode = higig2_mode; 12980 12981 #ifdef BCM_GREYHOUND2_SUPPORT 12982 if (SOC_IS_GREYHOUND2(unit)) { 12983 /* GH2 for CL port has PGW interface config for HG2/HG2-Lite */ 12984 BCM_IF_ERROR_RETURN(soc_greyhound2_pgw_encap_field_modify(unit, 12985 port, HIGIG2_MODEf, higig2_mode)); 12986 12987 /* GH2 sepcial design to set CLPORT_CONFIGr as IEEE encap mode for 12988 * HG2-Lite. Thus the CLPORT_CONFIGr.HIGIG2_MODEf must be 0 here. 12989 */ 12990 if (IS_HL_PORT(unit, port)) { 12991 clp_hg2_mode = 0; 12992 } 12993 } 12994 #endif /* GREYHOUND2 */ 12995 12996 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CLPORT_CONFIGr, port, 12997 HIGIG2_MODEf, clp_hg2_mode)); 12998 } else if (IS_C_PORT(unit, port) && 12999 SOC_REG_FIELD_VALID(unit, CPORT_CONFIGr, HIGIG2_MODEf)) { 13000 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, CPORT_CONFIGr, port, 13001 HIGIG2_MODEf, higig2_mode)); 13002 } else if (SOC_REG_FIELD_VALID(unit, XLPORT_CONFIGr, HIGIG2_MODEf)) { 13003 uint32 xlp_hg2_mode = higig2_mode; 13004 13005 #ifdef BCM_GREYHOUND_SUPPORT 13006 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 13007 SOC_IS_GREYHOUND2(unit)){ 13008 BCM_IF_ERROR_RETURN(soc_greyhound_pgw_encap_field_modify(unit, 13009 port, HIGIG2_MODEf, higig2_mode)); 13010 13011 /* GH sepcial design to set XLPORT_CONFIGr as IEEE encap mode for 13012 * HG2-Lite. Thus the XLPORT_CONFIGr.HIGIG2_MODEf must be 0 here. 13013 */ 13014 if (IS_HL_PORT(unit, port)) { 13015 xlp_hg2_mode = 0; 13016 } 13017 } 13018 #endif /* BCM_GREYHOUND_SUPPORT */ 13019 13020 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XLPORT_CONFIGr, port, 13021 HIGIG2_MODEf, xlp_hg2_mode)); 13022 } else if (SOC_REG_FIELD_VALID(unit, XPORT_CONFIGr, HIGIG2_MODEf)) { 13023 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, XPORT_CONFIGr, port, 13024 HIGIG2_MODEf, higig2_mode)); 13025 } else if (SOC_REG_FIELD_VALID(unit, PORT_CONFIGr, HIGIG2_MODEf)) { 13026 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, PORT_CONFIGr, port, 13027 HIGIG2_MODEf, higig2_mode)); 13028 } 13029 if (soc_feature(unit, soc_feature_wh2)) { 13030 SOC_IF_ERROR_RETURN( 13031 soc_reg_field32_modify(unit, PGW_GE_CONFIGr, port, 13032 HIGIG2_MODEf, higig2_mode)); 13033 } 13034 13035 egr_port_mem = SOC_IS_KATANA2(unit) ? EGR_PHYSICAL_PORTm : EGR_ING_PORTm; 13036 if (SOC_MEM_FIELD_VALID(unit, egr_port_mem, HIGIG2f)) { 13037 if (IS_CPU_PORT(unit, port)) { 13038 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, egr_port_mem, 13039 SOC_INFO(unit).cpu_hg_index, HIGIG2f, higig2_mode)); 13040 } else { 13041 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, egr_port_mem, 13042 port, HIGIG2f, higig2_mode)); 13043 } 13044 } 13045 13046 return BCM_E_NONE; 13047 } 13048 #endif /* BCM_HIGIG2_SUPPORT */ 13049 13050 #ifdef BCM_TRIUMPH3_SUPPORT 13051 /* 13052 * Function: 13053 * _bcm_esw_tr3_port_lanes_init 13054 * Purpose: 13055 * Initialize port lanes settings for 40g port of 13056 * Triumph3(56541,56542, 56545 and 56546) 13057 * Parameters: 13058 * unit - StrataSwitch unit number. 13059 * port - port number 13060 * Returns: 13061 * BCM_E_NONE - success (or already initialized) 13062 * BCM_E_INTERNAL- failed to set lane mode 13063 * Notes: 13064 * This function initializes port lanes settings based on the following config 13065 * variables: 13066 * port_max_speed 13067 * If a variable is not set, then no additional initialization of the 13068 * parameter is done. 13069 * 13070 * If user want to use 100Mbps on WC ports(xe4,xe5), configuration 13071 * must be setted as below: 13072 * port_max_speed=100 13073 */ 13074 int 13075 _bcm_esw_tr3_port_lanes_init(int unit) 13076 { 13077 int rv; 13078 int max_speed; 13079 int old_lanes = 0, new_lanes = -1; 13080 int enable; 13081 bcm_port_t port; 13082 PBMP_PORT_ITER(unit, port) { 13083 if (port != 54 && port != 55) { 13084 continue; 13085 } 13086 if (soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, 0)) { 13087 max_speed = soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, 0); 13088 if (max_speed == 100) { 13089 new_lanes = 1; 13090 } else if (max_speed != 100) { 13091 new_lanes = 4; 13092 } 13093 BCM_IF_ERROR_RETURN(_bcm_tr3_port_lanes_get(unit, port, &old_lanes)); 13094 if (new_lanes > 0 && old_lanes != new_lanes) { 13095 /* Cache original configurations */ 13096 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable)); 13097 COUNTER_LOCK(unit); 13098 rv = _bcm_tr3_port_lanes_set(unit, port, new_lanes); 13099 COUNTER_UNLOCK(unit); 13100 BCM_IF_ERROR_RETURN(rv); 13101 bcm_port_settings_init(unit, port); 13102 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, enable)); 13103 } 13104 } 13105 } 13106 return BCM_E_NONE; 13107 } 13108 #endif 13109 13110 #if defined(BCM_TRIDENT3_SUPPORT) && defined(CANCUN_SUPPORT) 13111 /* 13112 * Function: 13113 * _bcm_esw_td3_port_cmh_ctrl_set 13114 * Description: 13115 * Configure CANCUN redefined port control. 13116 * Parameters: 13117 * unit - Device number 13118 * port - Port number 13119 * type - Enum value of the feature 13120 * value - value to be set 13121 * Return Value: 13122 * BCM_E_NONE 13123 * BCM_E_UNAVAIL - Functionality not available 13124 */ 13125 int 13126 _bcm_esw_td3_port_cmh_ctrl_set(int unit, bcm_port_t port, 13127 bcm_port_control_t type, int value) 13128 { 13129 int rv = BCM_E_NONE; 13130 uint32 entry[SOC_MAX_MEM_WORDS]; 13131 bcm_module_t my_modid = 0, modid_out; 13132 bcm_port_t port_out; 13133 bcm_trunk_t trunk_out; 13134 int src_trk_idx = 0, id_out; 13135 soc_mem_t mem = SOURCE_TRUNK_MAP_TABLEm; 13136 13137 if (BCM_GPORT_IS_SET(port)) { 13138 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 13139 &modid_out, &port_out, &trunk_out, &id_out)); 13140 } else { 13141 port_out = port; 13142 } 13143 13144 if (!soc_cancun_cmh_check(unit, LPORT_TABm, VXLAN_SVP_ASSIGNMENT_KEY_TYPEf)) { 13145 return rv; 13146 } 13147 13148 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 13149 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, my_modid, 13150 port_out, &src_trk_idx)); 13151 13152 mem = SOURCE_TRUNK_MAP_TABLEm; 13153 sal_memset(entry, 0, sizeof(entry)); 13154 soc_mem_lock(unit, mem); 13155 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, src_trk_idx, entry); 13156 if (SOC_SUCCESS(rv)) { 13157 soc_mem_field32_set(unit, mem, entry, CTRL_PROFILE_IDX_0f, 13158 value? 0x1: 0x0); 13159 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, src_trk_idx, entry); 13160 } 13161 soc_mem_unlock(unit, mem); 13162 13163 return rv; 13164 } 13165 13166 #endif 13167 13168 /* 13169 * Function: 13170 * bcm_port_init 13171 * Purpose: 13172 * Initialize the PORT interface layer for the specified SOC device. 13173 * Parameters: 13174 * unit - StrataSwitch unit number. 13175 * Returns: 13176 * BCM_E_NONE - success (or already initialized) 13177 * BCM_E_INTERNAL- failed to write PTABLE entries 13178 * BCM_E_MEMORY - failed to allocate required memory. 13179 * Notes: 13180 * By default ports come up enabled. They can be made to come up disabled 13181 * at startup by a compile-time application policy flag in your Make.local 13182 * PTABLE initialized. 13183 */ 13184 int 13185 bcm_esw_port_init(int unit) 13186 { 13187 int rv, port_enable, length_check; 13188 bcm_port_t p; 13189 int p_speed; 13190 pbmp_t okay_ports; 13191 bcm_vlan_data_t vd; 13192 char pfmtok[SOC_PBMP_FMT_LEN], 13193 pfmtall[SOC_PBMP_FMT_LEN]; 13194 bcm_pbmp_t all_pbmp; 13195 #ifdef BCM_TRX_SUPPORT 13196 bcm_pbmp_t hg_pbmp; 13197 #endif /* BCM_TRX_SUPPORT */ 13198 #if defined(BCM_KATANA2_SUPPORT) 13199 uint32 entry[SOC_MAX_MEM_WORDS]; 13200 #endif /* BCM_KATANA_SUPPORT */ 13201 uint32 rx_los; 13202 #ifdef BCM_TRIDENT2_SUPPORT 13203 int enable; 13204 #endif /* BCM_TRIDENT2_SUPPORT */ 13205 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 13206 int index; 13207 mmu_intfi_st_trans_tbl_entry_t st_trans_entry; 13208 #endif 13209 13210 13211 LOG_VERBOSE(BSL_LS_BCM_PORT, 13212 (BSL_META_U(unit, 13213 "bcm_port_init: unit %d\n"), unit)); 13214 assert(unit < BCM_MAX_NUM_UNITS); 13215 if ((rv = _bcm_port_software_init(unit)) != BCM_E_NONE) { 13216 LOG_ERROR(BSL_LS_BCM_PORT, 13217 (BSL_META_U(unit, 13218 "Error unit %d: Failed software port init: %s\n"), 13219 unit, bcm_errmsg(rv))); 13220 return rv; 13221 } 13222 if (SAL_BOOT_SIMULATION && 13223 soc_property_get(unit, "skip_port_hw_init", 0)) { 13224 return BCM_E_NONE; 13225 } 13226 13227 /* Initialize Port Function driver */ 13228 BCM_ESW_PORT_DRV(unit) = NULL; 13229 13230 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT 13231 #if defined(BCM_KATANA2_SUPPORT) 13232 if (SOC_IS_KATANA2(unit)) { 13233 BCM_IF_ERROR_RETURN(bcmi_katana2_port_fn_drv_init(unit)); 13234 } else 13235 #endif 13236 #if defined(BCM_MONTEREY_SUPPORT) 13237 if (SOC_IS_MONTEREY(unit)) { 13238 BCM_IF_ERROR_RETURN(bcmi_monterey_port_fn_drv_init(unit)); 13239 } else 13240 #endif 13241 #if defined(BCM_APACHE_SUPPORT) 13242 if (SOC_IS_APACHE(unit)) { 13243 BCM_IF_ERROR_RETURN(bcmi_apache_port_fn_drv_init(unit)); 13244 } else 13245 #endif 13246 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 13247 if (SOC_IS_TD2P_TT2P(unit)) { 13248 BCM_IF_ERROR_RETURN(bcmi_td2p_port_fn_drv_init(unit)); 13249 } else 13250 #endif 13251 #ifdef BCM_TRIDENT3_SUPPORT 13252 if (SOC_IS_TRIDENT3(unit)) { 13253 BCM_IF_ERROR_RETURN(bcmi_td3_port_fn_drv_init(unit)); 13254 } else 13255 #endif 13256 #ifdef BCM_HELIX5_SUPPORT 13257 if (SOC_IS_HELIX5(unit)) { 13258 BCM_IF_ERROR_RETURN(bcmi_hx5_port_fn_drv_init(unit)); 13259 } else 13260 #endif 13261 #ifdef BCM_MAVERICK2_SUPPORT 13262 if (SOC_IS_MAVERICK2(unit)) { 13263 BCM_IF_ERROR_RETURN(bcmi_mv2_port_fn_drv_init(unit)); 13264 } else 13265 #endif 13266 #ifdef BCM_TOMAHAWK2_SUPPORT 13267 if (SOC_IS_TOMAHAWK2(unit)) { 13268 BCM_IF_ERROR_RETURN(bcmi_th2_port_fn_drv_init(unit)); 13269 } else 13270 #endif 13271 #ifdef BCM_TOMAHAWK3_SUPPORT 13272 if (SOC_IS_TOMAHAWK3(unit)) { 13273 BCM_IF_ERROR_RETURN(bcmi_th3_port_fn_drv_init(unit)); 13274 } else 13275 #endif 13276 { 13277 } 13278 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */ 13279 13280 SOC_PBMP_CLEAR(all_pbmp); 13281 13282 #ifdef BCM_TRX_SUPPORT 13283 SOC_PBMP_CLEAR(hg_pbmp); 13284 13285 if (soc_feature(unit, soc_feature_vlan_action) || 13286 soc_feature(unit, soc_feature_egr_vlan_action)) { 13287 bcm_vlan_action_set_t action; 13288 13289 bcm_vlan_action_set_t_init(&action); 13290 13291 #ifdef BCM_TRIUMPH2_SUPPORT 13292 if (soc_feature(unit, soc_feature_vpd_profile)) { 13293 BCM_IF_ERROR_RETURN(_bcm_tr2_port_vpd_bitmap_alloc(unit)); 13294 } 13295 #endif 13296 13297 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 13298 13299 #ifdef BCM_KATANA2_SUPPORT 13300 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 13301 /* The HW defaults for EGR_VLAN_CONTROL_1.VT_MISS_UNTAG == 1, which 13302 * causes the outer tag to be removed from packets that don't have 13303 * a hit in the egress vlan tranlation table. Set to 0 to disable this. 13304 */ 13305 uint32 rval = 0; 13306 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, VT_MISS_UNTAGf, 0); 13307 soc_reg_field_set(unit, EGR_VLAN_CONTROL_1r, &rval, REMARK_OUTER_DOT1Pf,1); 13308 13309 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 13310 PBMP_ITER(all_pbmp, p) { 13311 BCM_IF_ERROR_RETURN(WRITE_EGR_VLAN_CONTROL_1r(unit, p, rval)); 13312 } 13313 } 13314 13315 if (soc_feature(unit, soc_feature_linkphy_coe) || 13316 soc_feature(unit, soc_feature_subtag_coe)) { 13317 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 13318 } 13319 #endif 13320 13321 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 13322 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) 13323 || SOC_IS_TRIDENT3X(unit)) && 13324 (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOL_DATAm) && 13325 soc_mem_index_max(unit, VLAN_PROTOCOL_DATAm) > 0)) { 13326 vlan_protocol_data_entry_t vlan_protocol_data_entries[16]; 13327 uint32 vlan_protocol_data_index =0; 13328 void *entries_buf[1]; 13329 int i, count = 0; 13330 vlan_protocol_data_entry_t vde; 13331 13332 /* Create the default VLAN_PROTOCOL_DATA profile */ 13333 sal_memset(vlan_protocol_data_entries, 0, 13334 sizeof(vlan_protocol_data_entries)); 13335 13336 entries_buf[0] = &vlan_protocol_data_entries; 13337 BCM_IF_ERROR_RETURN( 13338 _bcm_port_vlan_protocol_data_entry_add(unit, entries_buf, 13339 16, (uint32 *)&vlan_protocol_data_index)); 13340 13341 /* First 16 entries of VLAN_PROTOCOL_DATA table are used for 13342 * default profile for Katana2 */ 13343 for (i = 0; i < soc_mem_index_count(unit, VLAN_PROTOCOLm); i++) { 13344 sal_memset(&vde, 0, sizeof(vlan_protocol_data_entry_t)); 13345 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde, 13346 OVIDf, BCM_VLAN_DEFAULT); 13347 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde, 13348 TAG_ACTION_PROFILE_PTRf, 0); 13349 BCM_IF_ERROR_RETURN(WRITE_VLAN_PROTOCOL_DATAm(unit, 13350 MEM_BLOCK_ALL, i, &vde)); 13351 } 13352 13353 count = 0; 13354 PBMP_ITER(all_pbmp, p) { 13355 PORT(unit, p).vp_count = 0; 13356 if (!IS_LB_PORT(unit, p) && !SOC_WARM_BOOT(unit)) { 13357 13358 /* Set vlan_protocol_data_ptr profile index in port table. */ 13359 BCM_IF_ERROR_RETURN( 13360 _bcm_esw_port_tab_set(unit, p, 13361 _BCM_CPU_TABS_ETHER, 13362 VLAN_PROTOCOL_DATA_INDEXf, 13363 vlan_protocol_data_index / 16)); 13364 PORT(unit, p).vlan_prot_ptr = vlan_protocol_data_index; 13365 count++; 13366 } 13367 } 13368 13369 /* Keep one extra reference to the default profile */ 13370 for (i = 1; i < count + 1; i++) { 13371 BCM_IF_ERROR_RETURN( 13372 _bcm_port_vlan_protocol_data_entry_reference (unit, 13373 vlan_protocol_data_index, 16)); 13374 } 13375 } else 13376 13377 #endif 13378 { 13379 PBMP_ITER(all_pbmp, p) { 13380 PORT(unit, p).vp_count = 0; 13381 if (!IS_LB_PORT(unit, p)) { 13382 if (!SOC_IS_TOMAHAWKX(unit) && 13383 !SOC_IS_TOMAHAWK3(unit) && !SOC_IS_TRIDENT3(unit)) { 13384 /* there are more ports the profile */ 13385 #ifdef BCM_TRIUMPH2_SUPPORT 13386 if (soc_feature(unit, soc_feature_vpd_profile)) { 13387 BCM_IF_ERROR_RETURN 13388 (_bcm_port_vlan_prot_index_alloc 13389 (unit, &(PORT(unit, p).vlan_prot_ptr))); 13390 } else 13391 #endif 13392 { 13393 PORT(unit, p).vlan_prot_ptr = p * soc_mem_index_count 13394 (unit, VLAN_PROTOCOLm); 13395 } 13396 } 13397 } 13398 } 13399 } 13400 13401 if (!SOC_WARM_BOOT(unit)) { 13402 /* Clear the profile ptr of source table */ 13403 PBMP_ALL_ITER(unit, p) { 13404 BCM_IF_ERROR_RETURN 13405 (_bcm_trx_vlan_port_egress_action_profile_clear(unit, p)); 13406 } 13407 } 13408 13409 /* Initialize the vlan action profile table */ 13410 #if defined(BCM_TOMAHAWK3_SUPPORT) 13411 if (SOC_IS_TOMAHAWK3(unit)) { 13412 BCM_IF_ERROR_RETURN (_bcm_th3_vlan_action_profile_init(unit)); 13413 } else 13414 #endif /* BCM_TOMAHAWK3_SUPPORT */ 13415 { 13416 BCM_IF_ERROR_RETURN (_bcm_trx_vlan_action_profile_init(unit)); 13417 } 13418 13419 if (SOC_IS_KATANA2(unit)) { 13420 SOC_PBMP_ASSIGN(hg_pbmp,PBMP_ST_ALL(unit)); 13421 } else { 13422 SOC_PBMP_ASSIGN(hg_pbmp,PBMP_HG_ALL(unit)); 13423 } 13424 13425 if (!SOC_IS_TRIDENT3X(unit)) { 13426 PBMP_ITER(hg_pbmp, p) { 13427 BCM_IF_ERROR_RETURN 13428 (_bcm_trx_vlan_port_egress_default_action_get(unit, 13429 p, &action)); 13430 /* Backward compatible defaults */ 13431 action.ot_outer = bcmVlanActionDelete; 13432 action.dt_outer = bcmVlanActionDelete; 13433 BCM_IF_ERROR_RETURN 13434 (_bcm_trx_vlan_port_egress_default_action_set(unit, 13435 p, &action)); 13436 } 13437 } 13438 } 13439 #endif /* BCM_TRX_SUPPORT*/ 13440 13441 #ifdef BCM_TRIDENT2PLUS_SUPPORT 13442 if (soc_feature(unit, soc_feature_higig_over_ethernet)) { 13443 #ifdef BCM_WARM_BOOT_SUPPORT 13444 if (SOC_WARM_BOOT(unit)) { 13445 uint32 port_type, hg_type, update = 0; 13446 bcm_pbmp_t e_pbm; 13447 soc_info_t *si; 13448 egr_port_entry_t egr_port; 13449 13450 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 13451 si = &SOC_INFO(unit); 13452 SOC_PBMP_ASSIGN(e_pbm, PBMP_E_ALL(unit)); 13453 PBMP_ITER(e_pbm, p) { 13454 BCM_IF_ERROR_RETURN 13455 (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, p, &egr_port)); 13456 port_type = 13457 soc_mem_field32_get(unit, EGR_PORTm, &egr_port, PORT_TYPEf); 13458 hg_type = 13459 soc_mem_field32_get(unit, EGR_PORTm, &egr_port, HG_TYPEf); 13460 if ((port_type == 1) && 13461 (hg_type == BCM_PORT_HG_TYPE_HGOE_TRANSPORT)) { 13462 SOC_PBMP_PORT_ADD(si->st.bitmap, p); 13463 SOC_PBMP_PORT_REMOVE(si->ether.bitmap, p); 13464 SOC_PBMP_PORT_REMOVE(si->hg2_pbm, p); 13465 update = 1; 13466 } 13467 } 13468 #define RECONFIGURE_PORT_TYPE_INFO(ptype) \ 13469 si->ptype.num = 0; \ 13470 si->ptype.min = si->ptype.max = -1; \ 13471 PBMP_ITER(si->ptype.bitmap, p) { \ 13472 si->ptype.port[si->ptype.num++] = p; \ 13473 if (si->ptype.min < 0) { \ 13474 si->ptype.min = p; \ 13475 } \ 13476 if (p > si->ptype.max) { \ 13477 si->ptype.max = p; \ 13478 } \ 13479 } 13480 13481 if (update) { 13482 /* Recalculate port type data */ 13483 RECONFIGURE_PORT_TYPE_INFO(ether); 13484 RECONFIGURE_PORT_TYPE_INFO(st); 13485 } 13486 #undef RECONFIGURE_PORT_TYPE_INFO 13487 } 13488 } 13489 #endif /* BCM_WARM_BOOT_SUPPORT */ 13490 } 13491 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 13492 13493 #ifdef BCM_TRIUMPH2_SUPPORT 13494 if (soc_feature(unit, soc_feature_gport_service_counters)) { 13495 #ifdef BCM_WARM_BOOT_SUPPORT 13496 if (SOC_WARM_BOOT(unit)) { 13497 port_tab_entry_t ptab; 13498 int fs_idx; 13499 bcm_gport_t gport; 13500 13501 #ifdef BCM_TRIDENT_SUPPORT 13502 if (SOC_IS_TD_TT(unit)) { 13503 BCM_IF_ERROR_RETURN(_bcm_td_phymode_reconfigure(unit)); 13504 } 13505 #endif /* BCM_TRIDENT_SUPPORT */ 13506 PBMP_ITER(all_pbmp, p) { 13507 BCM_IF_ERROR_RETURN(soc_mem_read(unit, PORT_TABm, 13508 MEM_BLOCK_ANY, p, &ptab)); 13509 fs_idx = 13510 soc_mem_field32_get(unit, PORT_TABm, &ptab, 13511 VINTF_CTR_IDXf); 13512 if (fs_idx) { 13513 BCM_IF_ERROR_RETURN 13514 (bcm_esw_port_gport_get(unit, p, &gport)); 13515 _bcm_esw_flex_stat_reinit_add(unit, 13516 _bcmFlexStatTypeGport, fs_idx, gport); 13517 } 13518 } 13519 } 13520 #endif /* BCM_WARM_BOOT_SUPPORT */ 13521 } 13522 #endif /* BCM_TRIUMPH2_SUPPORT */ 13523 13524 #ifdef BCM_WARM_BOOT_SUPPORT 13525 #ifdef BCM_TRIUMPH3_SUPPORT 13526 if (SOC_IS_TRIUMPH3(unit)) { 13527 if (SOC_WARM_BOOT(unit)) { 13528 _bcm_tr3_port_info_reconfig(unit); 13529 } 13530 } 13531 #endif /* BCM_TRIUMPH3_SUPPORT */ 13532 #endif /* BCM_WARM_BOOT_SUPPORT */ 13533 if (!SOC_WARM_BOOT(unit)) { 13534 /* 13535 * Write port configuration tables to contain the Initial System 13536 * Configuration (see init.c). 13537 */ 13538 13539 SOC_PBMP_CLEAR(all_pbmp); 13540 BCM_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 13541 13542 #ifdef BCM_KATANA2_SUPPORT 13543 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 13544 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 13545 } 13546 #endif 13547 13548 SOC_PBMP_REMOVE(all_pbmp, PBMP_TDM(unit)); 13549 13550 #ifdef BCM_KATANA2_SUPPORT 13551 if (soc_feature(unit, soc_feature_linkphy_coe) || 13552 soc_feature(unit, soc_feature_subtag_coe)) { 13553 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 13554 } 13555 #endif 13556 13557 vd.vlan_tag = BCM_VLAN_DEFAULT; 13558 BCM_PBMP_ASSIGN(vd.port_bitmap, all_pbmp); 13559 BCM_PBMP_ASSIGN(vd.ut_port_bitmap, all_pbmp); 13560 BCM_PBMP_REMOVE(vd.ut_port_bitmap, PBMP_CMIC(unit)); 13561 13562 PBMP_ITER(all_pbmp, p) { 13563 BCM_IF_ERROR_RETURN 13564 (mbcm_driver[unit]->mbcm_port_cfg_init(unit, p, &vd)); 13565 } 13566 13567 if (SOC_IS_TRIDENT3X(unit)) { 13568 /* Initialize inner TPID 13569 * (WAR)Set to 0x9100 then change back to take effort 13570 */ 13571 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, VLAN_CTRLr, 13572 REG_PORT_ANY, INNER_TPIDf, 0x9100)); 13573 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, VLAN_CTRLr, 13574 REG_PORT_ANY, INNER_TPIDf, 0x8100)); 13575 13576 if (SOC_REG_FIELD_VALID(unit, EGR_CONFIG_1_64r, INNER_TPIDf)) { 13577 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1_64r, 13578 REG_PORT_ANY, INNER_TPIDf, 0x9100)); 13579 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1_64r, 13580 REG_PORT_ANY, INNER_TPIDf, 0x8100)); 13581 } 13582 } 13583 13584 /* 13585 * Clear egress port blocking table 13586 */ 13587 if (SOC_IS_XGS_SWITCH(unit)) { 13588 #ifdef BCM_SHADOW_SUPPORT 13589 if (!SOC_IS_SHADOW(unit)) { 13590 #endif 13591 if (!SAL_BOOT_SIMULATION || SAL_BOOT_QUICKTURN) { 13592 SOC_IF_ERROR_RETURN 13593 (soc_mem_clear(unit, MAC_BLOCKm, COPYNO_ALL, TRUE)); 13594 } 13595 #ifdef BCM_SHADOW_SUPPORT 13596 } 13597 #endif 13598 } 13599 } 13600 13601 #ifdef BCM_SHADOW_SUPPORT 13602 if (SOC_IS_SHADOW(unit)) { 13603 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 13604 if (BCM_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, p)) { 13605 SOC_PBMP_PORT_REMOVE(PBMP_PORT_ALL(unit), p); 13606 } 13607 } 13608 } 13609 #endif 13610 #ifdef BCM_PREEMPTION_SUPPORT 13611 if (soc_feature(unit, soc_feature_preemption)) { 13612 BCM_IF_ERROR_RETURN(bcmi_esw_preemption_init(unit)); 13613 } 13614 #endif 13615 13616 /* Probe for ports */ 13617 SOC_PBMP_CLEAR(okay_ports); 13618 if ((rv = bcm_esw_port_probe(unit, PBMP_PORT_ALL(unit), &okay_ports)) != 13619 BCM_E_NONE) { 13620 LOG_ERROR(BSL_LS_BCM_PORT, 13621 (BSL_META_U(unit, 13622 "Error unit %d: Failed port probe: %s\n"), 13623 unit, bcm_errmsg(rv))); 13624 return rv; 13625 } 13626 13627 LOG_VERBOSE(BSL_LS_BCM_PORT, 13628 (BSL_META_U(unit, 13629 "Probed ports okay: %s of %s\n"), 13630 SOC_PBMP_FMT(okay_ports, pfmtok), 13631 SOC_PBMP_FMT(PBMP_PORT_ALL(unit), pfmtall))); 13632 /* 13633 * A compile-time application policy may prefer to disable ports 13634 * when switch boots up 13635 */ 13636 #ifdef BCM_PORT_DEFAULT_DISABLE 13637 port_enable = FALSE; 13638 #else 13639 port_enable = TRUE; 13640 #endif /* BCM_PORT_DEFAULT_DISABLE */ 13641 13642 if(SOC_IS_SABER2(unit) && (!SOC_WARM_BOOT(unit))) { 13643 PBMP_ITER(okay_ports, p) { 13644 if ((rv = bcm_esw_port_enable_set(unit, p, port_enable)) < 0) { 13645 LOG_WARN(BSL_LS_BCM_PORT, 13646 (BSL_META_U(unit, 13647 "Warning: Unit %d Port %s: " 13648 "Failed to %s port: %s\n"), 13649 unit, SOC_PORT_NAME(unit, p),(port_enable) ? \ 13650 "enable" : "disable" ,bcm_errmsg(rv))); 13651 } 13652 } 13653 } 13654 13655 13656 13657 length_check = soc_property_get(unit, spn_MAC_LENGTH_CHECK_ENABLE, 0); 13658 13659 /* Probe and initialize MAC and PHY drivers for ports that were OK */ 13660 PBMP_ITER(okay_ports, p) { 13661 LOG_VERBOSE(BSL_LS_BCM_PORT, 13662 (BSL_META_U(unit, 13663 "bcm_port_init: unit %d port %s\n"), 13664 unit, SOC_PORT_NAME(unit, p))); 13665 13666 PORT_LOCK(unit); 13667 13668 13669 if(SOC_USE_PORTCTRL(unit)) { 13670 } else { 13671 if ((rv = _bcm_port_mode_setup(unit, p, TRUE)) < 0) { 13672 LOG_WARN(BSL_LS_BCM_PORT, 13673 (BSL_META_U(unit, 13674 "Warning: Port %s: " 13675 "Failed to set initial mode: %s\n"), 13676 SOC_PORT_NAME(unit, p), bcm_errmsg(rv))); 13677 } 13678 } 13679 PORT_UNLOCK(unit); 13680 13681 #ifdef BCM_RCPU_SUPPORT 13682 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, p)) { 13683 if (SOC_USE_PORTCTRL(unit)) { 13684 bcmi_esw_portctrl_phy_enable_set(unit, p, TRUE); 13685 } else { 13686 soc_phyctrl_enable_set(unit, p, TRUE); 13687 } 13688 continue; 13689 } 13690 #endif /* BCM_RCPU_SUPPORT */ 13691 13692 #ifdef BCM_WARM_BOOT_SUPPORT 13693 if (SOC_WARM_BOOT(unit)) { 13694 continue; 13695 } 13696 #endif /* BCM_WARM_BOOT_SUPPORT */ 13697 if ((rv = bcm_port_settings_init(unit, p)) < 0) { 13698 LOG_WARN(BSL_LS_BCM_PORT, 13699 (BSL_META_U(unit, 13700 "Warning: Port %s: " 13701 "Failed to configure initial settings: %s\n"), 13702 SOC_PORT_NAME(unit, p), bcm_errmsg(rv))); 13703 } 13704 13705 #ifdef BCM_TRIDENT2_SUPPORT 13706 if (soc_feature(unit, soc_feature_pgw_mac_rsv_mask_remap)) { 13707 uint32 addr; 13708 int block; 13709 uint8 acc_type; 13710 uint32 rval; 13711 13712 addr = soc_reg_addr_get(unit, PGW_MAC_RSV_MASKr, p, 0, 13713 SOC_REG_ADDR_OPTION_NONE, &block, 13714 &acc_type); 13715 addr &= 0xffffff00; 13716 /* coverity[overrun-local : FALSE] */ 13717 addr |= (SOC_INFO(unit).port_l2p_mapping[p] - 1) & 0xf; 13718 SOC_IF_ERROR_RETURN(_soc_reg32_get(unit, block, acc_type, addr, 13719 &rval)); 13720 if (length_check) { 13721 rval |= 0x20; /* set bit 5 to enable frame length check */ 13722 } else { 13723 rval &= ~0x20; /* clear bit 5 to disable frame length check */ 13724 } 13725 rval |= 1 << 18; /* set PFC frame detected indicator */ 13726 SOC_IF_ERROR_RETURN(_soc_reg32_set(unit, block, acc_type, addr, 13727 rval)); 13728 } else 13729 #endif /* BCM_TRIDENT2_SUPPORT */ 13730 /* Control 802.3 frame length field check in MAC for 13731 * XL, XLB0, XT, CL, CLG2, XW (helix4) or MXQ blocks */ 13732 if (IS_XL_PORT(unit, p) || IS_XLB0_PORT(unit, p) || IS_XT_PORT(unit, p) || 13733 IS_CL_PORT(unit, p) || IS_CLG2_PORT(unit, p) || IS_MXQ_PORT(unit,p) || 13734 IS_XW_PORT(unit,p) || IS_CD_PORT(unit, p)) { 13735 uint32 rval; 13736 soc_reg_t reg = INVALIDr; 13737 13738 if ((IS_CL_PORT(unit, p) || IS_CLG2_PORT(unit, p)) && 13739 SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) { 13740 reg = CLPORT_MAC_RSV_MASKr; 13741 } else if (IS_CD_PORT(unit, p)) { 13742 reg = CDMAC_RSV_MASKr; 13743 } else if (SOC_REG_IS_VALID(unit, PGW_MAC_RSV_MASKr)) { 13744 reg = PGW_MAC_RSV_MASKr; 13745 } else if (SOC_IS_SABER2(unit) && SOC_REG_PORT_VALID(unit, XLPORT_MAC_RSV_MASKr, p)) { 13746 reg = XLPORT_MAC_RSV_MASKr; 13747 } else if (SOC_REG_IS_VALID(unit, MAC_RSV_MASKr)) { 13748 reg = MAC_RSV_MASKr; 13749 } else if (SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) { 13750 reg = XLPORT_MAC_RSV_MASKr; 13751 } 13752 13753 if (reg != INVALIDr) { 13754 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, p, 0, &rval)); 13755 if (length_check) { 13756 rval |= 0x20; /* set bit 5 to enable frame length check */ 13757 } else { 13758 rval &= ~0x20; /* clear bit 5 to disable frame length check */ 13759 } 13760 if (SOC_IS_TD2_TT2(unit)|| SOC_IS_HELIX4(unit)) { 13761 rval |= 1 << 18; /* set PFC frame detected indicator */ 13762 } 13763 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, p, 0, rval)); 13764 } 13765 } 13766 13767 /* 13768 * A compile-time application policy may prefer to disable ports 13769 * when switch boots up 13770 */ 13771 13772 #ifdef BCM_PORT_DEFAULT_DISABLE 13773 port_enable = FALSE; 13774 #else 13775 port_enable = TRUE; 13776 #endif /* BCM_PORT_DEFAULT_DISABLE */ 13777 13778 if(!SOC_IS_SABER2(unit)) { 13779 if ((rv = bcm_esw_port_enable_set(unit, p, port_enable)) < 0) { 13780 LOG_WARN(BSL_LS_BCM_PORT, 13781 (BSL_META_U(unit, 13782 "Warning: Port %s: " 13783 "Failed to %s port: %s\n"), 13784 SOC_PORT_NAME(unit, p),(port_enable) ? \ 13785 "enable" : "disable" ,bcm_errmsg(rv))); 13786 } 13787 } 13788 13789 /* 13790 * JAM should be enabled by default 13791 */ 13792 if (IS_E_PORT(unit, p)) { 13793 if (soc_mem_field_valid(unit, PORT_TABm, JAM_ENf) || 13794 soc_reg_field_valid(unit, GE_PORT_CONFIGr, JAM_ENf) || 13795 soc_feature(unit, soc_feature_unimac)) { 13796 13797 #if defined(BCM_HURRICANE_SUPPORT) 13798 if (SOC_IS_HURRICANEX(unit) || SOC_IS_GREYHOUND(unit) || 13799 SOC_IS_GREYHOUND2(unit)) { 13800 rv = bcm_esw_port_jam_set(unit, p, 0); 13801 } else 13802 #endif 13803 { 13804 rv = bcm_esw_port_jam_set(unit, p, 1); 13805 } 13806 if (BCM_FAILURE(rv) && (rv != BCM_E_UNAVAIL)) { 13807 LOG_WARN(BSL_LS_BCM_PORT, 13808 (BSL_META_U(unit, 13809 "Warning: Port %s: " 13810 "Failed to enable JAM %s\n"), 13811 SOC_PORT_NAME(unit, p), bcm_errmsg(rv))); 13812 } 13813 } 13814 } 13815 #ifdef BCM_TRIUMPH2_SUPPORT 13816 if (soc_feature(unit, soc_feature_unimac_tx_crs) && IS_XQ_PORT(unit, p) 13817 && IS_GE_PORT(unit, p)) { 13818 BCM_IF_ERROR_RETURN 13819 (soc_reg_field32_modify(unit, XPORT_CONFIGr, p, 13820 UNIMAC_HD_ECO_ENABLEf, 1)); 13821 } 13822 #endif 13823 #ifdef BCM_RCPU_SUPPORT 13824 if ((uint32)p == soc_property_get(unit, spn_RCPU_PORT, -1)) { 13825 BCM_IF_ERROR_RETURN 13826 (bcm_esw_port_frame_max_set(unit, p, BCM_PORT_JUMBO_MAXSZ)); 13827 } 13828 #endif /* BCM_RCPU_SUPPORT */ 13829 } 13830 13831 #if defined(BCM_GREYHOUND_SUPPORT) 13832 if (SOC_IS_GREYHOUND(unit)) { 13833 BCM_IF_ERROR_RETURN(bcm_gh_port_init(unit)); 13834 } 13835 #endif 13836 13837 #if defined(BCM_HURRICANE3_SUPPORT) 13838 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 13839 BCM_IF_ERROR_RETURN(bcm_hr3_port_init(unit)); 13840 } 13841 #endif 13842 13843 #if defined(BCM_TRIDENT_SUPPORT) 13844 if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 13845 BCM_IF_ERROR_RETURN(bcm_td_port_init(unit)); 13846 } 13847 #endif /* BCM_TRIDENT_SUPPORT */ 13848 13849 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 13850 defined(BCM_TRX_SUPPORT) 13851 if (!SOC_WARM_BOOT(unit) && !SOC_IS_RELOADING(unit)) { 13852 /* Enable the default outer TPID. */ 13853 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 13854 /* if (soc_feature(unit, soc_feature_vlan_ctrl) && * SOC_IS_SHADOW(unit)) { */ 13855 13856 SOC_PBMP_CLEAR(all_pbmp); 13857 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 13858 13859 #ifdef BCM_KATANA2_SUPPORT 13860 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 13861 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 13862 } 13863 #endif 13864 13865 SOC_PBMP_REMOVE(all_pbmp, PBMP_TDM(unit)); 13866 13867 #ifdef BCM_KATANA2_SUPPORT 13868 if (soc_feature(unit, soc_feature_linkphy_coe) || 13869 soc_feature(unit, soc_feature_subtag_coe)) { 13870 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 13871 } 13872 #endif 13873 13874 #if defined(BCM_SABER2_SUPPORT) 13875 /* If OAMP is enabled by default, skip the port init for oamp port */ 13876 if(SOC_IS_SABER2(unit)) { 13877 int oamp_enable; 13878 (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable); 13879 13880 if (soc_feature(unit, soc_feature_sat) && 13881 ((!SOC_WARM_BOOT(unit) && 13882 soc_property_get(unit, spn_SAT_ENABLE, 0)) || 13883 (SOC_WARM_BOOT(unit) && (oamp_enable == TRUE)))) { 13884 SOC_PBMP_PORT_REMOVE(all_pbmp, 13885 _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER); 13886 } 13887 } 13888 #endif 13889 13890 PBMP_ITER(all_pbmp, p) { 13891 rv = bcm_esw_port_tpid_set(unit, p, 13892 _bcm_fb2_outer_tpid_default_get(unit)); 13893 if (BCM_FAILURE(rv)) { 13894 LOG_WARN(BSL_LS_BCM_PORT, 13895 (BSL_META_U(unit, 13896 "Warning: " 13897 "Failed to set %s port default TPID: %s\n"), 13898 SOC_PORT_NAME(unit, p), bcm_errmsg(rv))); 13899 } 13900 if (soc_feature(unit, soc_feature_inner_tpid_enable)) { 13901 /* Enable the default inner TPID. */ 13902 rv = bcm_esw_port_inner_tpid_set(unit, p, 13903 _bcm_fb2_outer_tpid_default_get(unit)); 13904 if (BCM_FAILURE(rv)) { 13905 LOG_WARN(BSL_LS_BCM_PORT, 13906 (BSL_META_U(unit, 13907 "Warning: " 13908 "Failed to set %s port default inner TPID: %s\n"), 13909 SOC_PORT_NAME(unit, p), bcm_errmsg(rv))); 13910 } 13911 } 13912 } 13913 } 13914 } 13915 #endif 13916 13917 #ifdef BCM_XGS3_FABRIC_SUPPORT 13918 if (SOC_IS_XGS3_FABRIC(unit)) { 13919 PBMP_ALL_ITER(unit, p) { 13920 bcm_esw_port_learn_set(unit, p, BCM_PORT_LEARN_FWD); 13921 } 13922 } 13923 #endif 13924 if (SAL_BOOT_SIMULATION && 13925 soc_property_get(unit, "skip_partial_port_hw_init", 0)) { 13926 return BCM_E_NONE; 13927 } 13928 #ifdef BCM_TRIUMPH2_SUPPORT 13929 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 13930 SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) || 13931 SOC_IS_TD_TT(unit) || SOC_IS_HURRICANEX(unit) || 13932 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit) || 13933 SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit)) { 13934 uint32 regval, profile_index; 13935 bcm_pbmp_t port_pbmp; 13936 13937 /* Set the chip-wide E2ECC port mapping enable bit */ 13938 if (soc_feature(unit, soc_feature_sysport_remap)) { 13939 SOC_IF_ERROR_RETURN(READ_E2ECC_PORT_MAPPING_CONFIGr(unit, ®val)); 13940 soc_reg_field_set(unit, E2ECC_PORT_MAPPING_CONFIGr, ®val, PORT_MAPPING_ENf, 1); 13941 SOC_IF_ERROR_RETURN(WRITE_E2ECC_PORT_MAPPING_CONFIGr(unit, regval)); 13942 } 13943 13944 SOC_PBMP_CLEAR(all_pbmp); 13945 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 13946 SOC_PBMP_CLEAR(port_pbmp); 13947 SOC_PBMP_ASSIGN(port_pbmp, PBMP_PORT_ALL(unit)); 13948 13949 #ifdef BCM_KATANA2_SUPPORT 13950 if (soc_feature(unit, soc_feature_linkphy_coe) || 13951 soc_feature(unit, soc_feature_subtag_coe)) { 13952 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 13953 _bcm_kt2_subport_pbmp_update(unit, &port_pbmp); 13954 } 13955 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 13956 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &all_pbmp)); 13957 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &port_pbmp)); 13958 } 13959 #endif 13960 13961 PBMP_ITER(all_pbmp, p) { 13962 /* Initialize the logical to physical port mapping */ 13963 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 13964 !SOC_IS_TD_TT(unit) && !SOC_IS_TRIUMPH3(unit) && 13965 !SOC_IS_KATANAX(unit) && !SOC_IS_GREYHOUND(unit) && 13966 !SOC_IS_GREYHOUND2(unit)) { 13967 bcm_port_t sp = p; 13968 if (soc_feature(unit, soc_feature_sysport_remap)) { 13969 BCM_XLATE_SYSPORT_P2S(unit, &sp); 13970 } 13971 _bcm_port_remap_set(unit, p, sp); 13972 } 13973 13974 /* Initialize egress block profile pointer to invalid value */ 13975 PORT_SRC_MOD_EGR_PROF_PTR(unit, p) = -1; 13976 13977 /* Program the VLAN_PROTOCOL_DATA / FP_PORT_FIELD_SEL_INDEX 13978 / PROTOCOL_PKT_INDEX pointers */ 13979 if (!IS_LB_PORT(unit, p) && !IS_TDM_PORT(unit, p)) { 13980 int value = 0; 13981 if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOLm)) { 13982 value = PORT(unit, p).vlan_prot_ptr / 13983 soc_mem_index_count(unit, VLAN_PROTOCOLm); 13984 } 13985 if ((0 != value) && 13986 (soc_mem_index_max(unit, VLAN_PROTOCOL_DATAm) > 0)) { 13987 BCM_IF_ERROR_RETURN( 13988 _bcm_esw_port_tab_set(unit, p, 13989 _BCM_CPU_TABS_ETHER, 13990 VLAN_PROTOCOL_DATA_INDEXf, 13991 BCM_PBMP_MEMBER(port_pbmp, p) ? value : 0)); 13992 } 13993 13994 if (soc_mem_field_valid(unit, PORT_TABm, 13995 FP_PORT_FIELD_SEL_INDEXf)) { 13996 BCM_IF_ERROR_RETURN( 13997 _bcm_esw_port_tab_set(unit, p, 13998 _BCM_CPU_TABS_ETHER, 13999 FP_PORT_FIELD_SEL_INDEXf, p)); 14000 } 14001 if (soc_mem_field_valid(unit, PORT_TABm, PROTOCOL_PKT_INDEXf) || 14002 soc_mem_field_valid(unit, LPORT_TABm, 14003 PROTOCOL_PKT_INDEXf)) { 14004 if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype == 14005 soc_portreg) { 14006 BCM_IF_ERROR_RETURN( 14007 _bcm_esw_port_tab_set(unit, p, 14008 _BCM_CPU_TABS_ETHER, 14009 PROTOCOL_PKT_INDEXf, 14010 p)); 14011 } else { 14012 BCM_IF_ERROR_RETURN 14013 (_bcm_prot_pkt_ctrl_add(unit, 0, 0, 14014 &profile_index)); 14015 BCM_IF_ERROR_RETURN( 14016 _bcm_esw_port_tab_set(unit, p, 14017 _BCM_CPU_TABS_ETHER, 14018 PROTOCOL_PKT_INDEXf, 14019 profile_index)); 14020 } 14021 } 14022 14023 if (soc_feature(unit, soc_feature_embedded_higig) 14024 && IS_E_PORT(unit, p)) { 14025 uint32 buffer[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ]; 14026 uint32 mask[SOC_MAX_MEM_FIELD_WORDS]; 14027 14028 sal_memset(buffer, 0, 14029 WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ)); 14030 sal_memset(mask, 0xFF, sizeof(mask)); 14031 /* coverity[overrun-call : FALSE] */ 14032 BCM_IF_ERROR_RETURN( 14033 _bcm_port_ehg_header_write(unit, p, buffer, buffer, mask, 14034 _BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ)); 14035 } 14036 } 14037 } 14038 14039 if (!SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLE_MODBASEm) && 14040 !SOC_MEM_IS_VALID(unit, SOURCE_TRUNK_MAP_MODBASEm) && 14041 SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLEm)) { 14042 BCM_IF_ERROR_RETURN(_bcm_tr2_system_tpid_init(unit)); 14043 } 14044 } 14045 #endif /* BCM_TRIUMPH2_SUPPORT */ 14046 14047 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \ 14048 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) 14049 if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) || 14050 SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 14051 SOC_IS_APACHE(unit)) && 14052 (soc_feature(unit,soc_feature_timesync_support))) { 14053 _bcm_esw_port_timesync_profile_init(unit); 14054 } 14055 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || 14056 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */ 14057 14058 #ifdef BCM_SHADOW_SUPPORT 14059 /* Static port load balancing configuration for shadow */ 14060 if (SOC_IS_SHADOW(unit)) { 14061 port_tab_entry_t ptab; 14062 14063 for (p = 0; p <= 16; p++) { 14064 /* Enable IPV4 and IPV6 */ 14065 BCM_IF_ERROR_RETURN( 14066 _bcm_esw_port_tab_set(unit, p, 14067 _BCM_CPU_TABS_ETHER, 14068 IPV4_ENABLEf, 1)); 14069 14070 BCM_IF_ERROR_RETURN( 14071 _bcm_esw_port_tab_set(unit, p, 14072 _BCM_CPU_TABS_ETHER, 14073 IPV6_ENABLEf, 1)); 14074 } 14075 14076 /* For shadow-petrab mode, configure uflow_A(xe0) and uflow_b(xe1)*/ 14077 if(soc_property_get(unit, spn_BCM88732_DEVICE_MODE, 0) && 14078 ((soc_property_get(unit, spn_BCM88732_2X40_1X40, 0)) || 14079 (soc_property_get(unit, spn_BCM88732_2X40_2X40, 0)))) { 14080 BCM_IF_ERROR_RETURN( 14081 _bcm_esw_port_tab_set(unit, 1, 14082 _BCM_CPU_TABS_ETHER, 14083 AGGREGATION_GROUP_SELECTf, 0)); 14084 14085 /* port 5 (xe1) configure uflow_b for static load balancing */ 14086 BCM_IF_ERROR_RETURN( 14087 _bcm_esw_port_tab_set(unit, 5, 14088 _BCM_CPU_TABS_ETHER, 14089 AGGREGATION_GROUP_SELECTf, 1)); 14090 14091 /* Enable SAND interop header for Interlaken ports */ 14092 for (p = 9; p <= 16; p++) { 14093 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p, 14094 _BCM_CPU_TABS_ETHER, 14095 SAND_COS_ENABLEf, 1)); 14096 } 14097 } 14098 if(soc_property_get(unit, spn_BCM88732_2X40_8X10, 0)) { 14099 sal_memset(&ptab, 0, sizeof(ptab)); 14100 /* port 1 (xe0) configure uflow_a for static load balancing */ 14101 SOC_IF_ERROR_RETURN( 14102 READ_PORT_TABm(unit, MEM_BLOCK_ANY, 1, &ptab)); 14103 soc_PORT_TABm_field32_set(unit, &ptab, AGGREGATION_GROUP_SELECTf, 0); 14104 SOC_IF_ERROR_RETURN( 14105 WRITE_PORT_TABm(unit,MEM_BLOCK_ALL, 1, &ptab)); 14106 14107 /* port 5 (xe1) configure uflow_b for static load balancing */ 14108 SOC_IF_ERROR_RETURN( 14109 READ_PORT_TABm(unit, MEM_BLOCK_ANY, 5, &ptab)); 14110 soc_PORT_TABm_field32_set(unit, &ptab, AGGREGATION_GROUP_SELECTf, 1); 14111 SOC_IF_ERROR_RETURN( 14112 WRITE_PORT_TABm(unit,MEM_BLOCK_ALL, 5, &ptab)); 14113 14114 } 14115 14116 /* By default Disable VLAN checks and enable TPID in port table */ 14117 for (p = 0; p <= 16; p++) { 14118 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p, 14119 _BCM_CPU_TABS_ETHER, 14120 DISABLE_VLAN_CHECKSf, 1)); 14121 14122 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p, 14123 _BCM_CPU_TABS_ETHER, 14124 OUTER_TPID_ENABLEf, 1)); 14125 } 14126 } 14127 #endif /* BCM_SHADOW_SUPPORT */ 14128 14129 #ifdef BCM_TRIDENT_SUPPORT 14130 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) { 14131 uint32 regval; 14132 int blk; 14133 int blk_num = -1; 14134 int bindex = 0; 14135 int tx_pbm = 0; 14136 bcm_pbmp_t all_pbmp; 14137 14138 if (SOC_IS_TRIUMPH3(unit)) { 14139 /* Clear all bits for flex port considerations */ 14140 for (blk_num = 0; blk_num < 7; blk_num++) { 14141 SOC_IF_ERROR_RETURN 14142 (WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, 0)); 14143 } 14144 } 14145 14146 SOC_PBMP_CLEAR(all_pbmp); 14147 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 14148 14149 #ifdef BCM_KATANA2_SUPPORT 14150 if (soc_feature(unit, soc_feature_linkphy_coe) || 14151 soc_feature(unit, soc_feature_subtag_coe)) { 14152 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 14153 } 14154 #endif 14155 14156 PBMP_ITER(all_pbmp, p) { 14157 if (!IS_LB_PORT(unit, p) && !IS_TDM_PORT(unit, p)) { 14158 if (soc_mem_field_valid(unit, PORT_TABm, 14159 FP_PORT_FIELD_SEL_INDEXf)) { 14160 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_set(unit, p, 14161 _BCM_CPU_TABS_ETHER, 14162 FP_PORT_FIELD_SEL_INDEXf, p)); 14163 } 14164 } 14165 } 14166 14167 PBMP_ITER(PBMP_PORT_ALL(unit), p) { 14168 /* In Trident all ports are enabled to send E2ECC messages by 14169 * default. Disable E2ECC message TX here until congestion config 14170 * set enables the port. 14171 */ 14172 14173 if (soc_feature(unit, soc_feature_logical_port_num)) { 14174 /* coverity[overrun-local : FALSE] */ 14175 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[p]); 14176 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[p]); 14177 } else{ 14178 blk = SOC_PORT_BLOCK(unit, p); 14179 bindex = SOC_PORT_BINDEX(unit, p); 14180 } 14181 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 14182 if (SOC_IS_TRIDENT2X(unit)) { 14183 blk_num = SOC_INFO(unit).port_serdes[p]; 14184 } else 14185 #endif 14186 { 14187 blk_num = SOC_BLOCK_INFO(unit, blk).number; 14188 } 14189 if (SOC_IS_KATANA2(unit)) { 14190 if (!IS_HG_PORT(unit, p)) { 14191 continue; 14192 } 14193 /* In KT2 E2ECC is implemented only in blocks 6..9 */ 14194 if (blk_num >= 6) { 14195 blk_num -= 6; 14196 } else { 14197 continue; 14198 } 14199 } 14200 if (!SOC_IS_TRIUMPH3(unit) && 14201 SOC_REG_IS_VALID(unit, E2ECC_TX_ENABLE_BMPr)) { 14202 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num, 14203 ®val)); 14204 tx_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval, 14205 TX_ENABLE_BMPf); 14206 tx_pbm &= ~(1 << bindex); 14207 soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, ®val, 14208 TX_ENABLE_BMPf, tx_pbm); 14209 SOC_IF_ERROR_RETURN(WRITE_E2ECC_TX_ENABLE_BMPr(unit, 14210 blk_num, regval)); 14211 } 14212 } 14213 /* Set the chip-wide E2ECC port mapping enable bit */ 14214 if (soc_feature(unit, soc_feature_sysport_remap)) { 14215 SOC_IF_ERROR_RETURN(READ_E2ECC_PORT_MAPPING_CONFIGr(unit, ®val)); 14216 soc_reg_field_set(unit, E2ECC_PORT_MAPPING_CONFIGr, ®val, 14217 PORT_MAPPING_ENf, 1); 14218 SOC_IF_ERROR_RETURN(WRITE_E2ECC_PORT_MAPPING_CONFIGr(unit, regval)); 14219 } 14220 } 14221 #endif 14222 14223 #if defined (BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) \ 14224 || defined (BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 14225 || defined (BCM_HURRICANE2_SUPPORT) 14226 if (SOC_IS_HURRICANE (unit) || SOC_IS_TD_TT (unit) || 14227 SOC_IS_HAWKEYE (unit) || SOC_IS_SHADOW(unit) || 14228 SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || 14229 SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || 14230 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 14231 if (soc_feature (unit, soc_feature_eee)) { 14232 int mac_val = 0; 14233 _bcm_port_info_t *port_info; 14234 PBMP_ALL_ITER(unit, p) { 14235 if (!IS_LB_PORT(unit, p) && !IS_CPU_PORT (unit, p) && !IS_FAE_PORT (unit, p) && 14236 !IS_TDM_PORT(unit, p) && !IS_RDB_PORT(unit,p) && !IS_MACSEC_PORT(unit,p)) { 14237 /* EEE standard compliance Work Around: 14238 * Initialize the software state of native eee in MAC 14239 */ 14240 eee_cfg[unit][p] = 0; 14241 /* Check if MAC supports Native EEE and set the value of 14242 * eee_cfg by reading the EEE status from MAC*/ 14243 if (SOC_USE_PORTCTRL(unit)) { 14244 rv = bcmi_esw_portctrl_eee_enable_get(unit, p, 14245 &mac_val); 14246 14247 } else { 14248 _bcm_port_info_access(unit, p, &port_info); 14249 rv = MAC_CONTROL_GET(port_info->p_mac, unit, p, 14250 SOC_MAC_CONTROL_EEE_ENABLE, 14251 &mac_val); 14252 } 14253 if (rv != BCM_E_UNAVAIL) { 14254 eee_cfg[unit][p] = mac_val; 14255 } 14256 } 14257 } 14258 } 14259 } 14260 #endif /* (BCM_HURRICANE_SUPPORT) || (BCM_TRIDENT_SUPPORT) || (BCM_HAWKEYE_SUPPORT)*/ 14261 14262 /* 14263 * CES TDM Port initialization 14264 */ 14265 /* Set Higig/Higig2 mode */ 14266 if (!SOC_WARM_BOOT(unit)) { 14267 if (SOC_USE_PORTCTRL(unit)) { 14268 int hg_port; 14269 PBMP_HG_ITER(unit, hg_port) { 14270 BCM_IF_ERROR_RETURN 14271 (bcmi_esw_portctrl_higig_mode_set(unit, hg_port, TRUE)); 14272 } 14273 } 14274 #ifdef BCM_HIGIG2_SUPPORT 14275 if (soc_feature(unit, soc_feature_higig2)) { 14276 int hg_port; 14277 #if defined(BCM_KATANA_SUPPORT) 14278 int hl_port; 14279 14280 if (SOC_IS_KATANA(unit)) { 14281 PBMP_HL_ITER(unit, hl_port) { 14282 BCM_IF_ERROR_RETURN 14283 (_bcm_esw_port_higig2_mode_set(unit, hl_port, TRUE)); 14284 SOC_HG2_ENABLED_PORT_ADD(unit, hl_port); 14285 } 14286 } 14287 #endif 14288 PBMP_HG_ITER(unit, hg_port) { 14289 /* 14290 * Make all HG ports default to HiGig2, when 14291 * 1. spn_HIGIG2_HDR_MODE = 1. Or 14292 * 2. portmod is enabled 14293 */ 14294 if (soc_property_port_get(unit, hg_port, spn_HIGIG2_HDR_MODE, 14295 soc_feature(unit, soc_feature_no_higig_plus) ? 1 : 0) || 14296 SOC_USE_PORTCTRL(unit)) { 14297 BCM_IF_ERROR_RETURN 14298 (_bcm_esw_port_higig2_mode_set(unit, hg_port, TRUE)); 14299 SOC_HG2_ENABLED_PORT_ADD(unit, hg_port); 14300 } 14301 } 14302 } 14303 #endif /* BCM_HIGIG2_SUPPORT */ 14304 } 14305 14306 BCM_IF_ERROR_RETURN(_bcm_esw_port_mon_start(unit)); 14307 #ifdef BCM_TRIUMPH3_SUPPORT 14308 if (SOC_IS_TRIUMPH3(unit)) { 14309 BCM_IF_ERROR_RETURN 14310 (_bcm_esw_ibod_sync_recovery_start(unit, 14311 soc_property_get(unit, spn_PORTMON_INTERVAL, IBOD_SYNC_INTERVAL_MIN))); 14312 } 14313 #endif /* BCM_TRIUMPH3_SUPPORT */ 14314 /* Port translation call-back function for PHY drivers */ 14315 soc_phy_cb_xlate_port_func = _bcm_phy_cb_xlate_port; 14316 14317 #ifdef BCM_TRIUMPH2_SUPPORT 14318 if (soc_feature(unit, soc_feature_src_modid_blk_profile)) { 14319 soc_mem_t mem = SRC_MODID_EGRESSm; 14320 int mem_words; 14321 int rv; 14322 14323 if (SOC_MEM_IS_VALID(unit, mem)) { 14324 if (NULL == PORT_SRC_MOD_EGR_PROFILE(unit)) { 14325 PORT_SRC_MOD_EGR_PROFILE(unit) = 14326 sal_alloc(sizeof(soc_profile_mem_t), 14327 "SRC_MODID_EGRESS Profile Mem"); 14328 if (NULL == PORT_SRC_MOD_EGR_PROFILE(unit)) { 14329 return BCM_E_MEMORY; 14330 } 14331 soc_profile_mem_t_init(PORT_SRC_MOD_EGR_PROFILE(unit)); 14332 14333 mem_words = sizeof(src_modid_egress_entry_t) / 14334 sizeof(uint32); 14335 14336 rv = soc_profile_mem_create(unit, &mem, &mem_words, 1, 14337 PORT_SRC_MOD_EGR_PROFILE(unit)); 14338 if (rv < 0) { 14339 sal_free(PORT_SRC_MOD_EGR_PROFILE(unit)); 14340 PORT_SRC_MOD_EGR_PROFILE(unit) = NULL; 14341 return rv; 14342 } 14343 } 14344 } 14345 } 14346 #endif /* BCM_TRIUMPH2_SUPPORT */ 14347 14348 #if defined(BCM_KATANA2_SUPPORT) 14349 if (SOC_IS_KATANA2(unit)) { 14350 /* Enable EGR_ENABLEm:PRT_ENABLEf for cpu port */ 14351 LOG_VERBOSE(BSL_LS_BCM_PORT, 14352 (BSL_META_U(unit, 14353 "\nEnable EGR_ENABLEm:PRT_ENABLEf for cpu port \n"))); 14354 sal_memset(entry, 0, sizeof(egr_enable_entry_t)); 14355 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1); 14356 SOC_IF_ERROR_RETURN( 14357 WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, CMIC_PORT(unit), entry)); 14358 SOC_IF_ERROR_RETURN( 14359 WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, LB_PORT(unit), entry)); 14360 } 14361 #endif /* BCM_KATANA_SUPPORT */ 14362 14363 if (!soc_feature(unit, soc_feature_no_sw_rx_los)){ 14364 /* Get Initial SW RX LOS configuration from PHY driver */ 14365 PBMP_ITER(all_pbmp, p) { 14366 if (IS_E_PORT(unit, p)) { 14367 rv = bcm_esw_port_phy_control_get(unit, p, 14368 BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, 14369 &rx_los); 14370 if (BCM_SUCCESS(rv)) { 14371 PORT(unit, p).rx_los = rx_los; 14372 } 14373 } 14374 } 14375 } 14376 14377 /* set link delay offset */ 14378 PBMP_ITER(all_pbmp, p) { 14379 PORT(unit, p).link_delay_offset = 0; 14380 if (SOC_WARM_BOOT(unit)) { 14381 rv = bcm_esw_port_speed_get(unit, p, &p_speed); 14382 if (BCM_FAILURE(rv)) { 14383 continue; 14384 } 14385 BCM_IF_ERROR_RETURN(_bcm_esw_port_link_delay_recover(unit, p, p_speed)); 14386 } 14387 } 14388 14389 /* set port dscp map set to zero */ 14390 PBMP_ITER(all_pbmp, p) { 14391 PORT(unit, p).port_dscp_map_set = 0; 14392 } 14393 14394 #ifdef BCM_TRIDENT2_SUPPORT 14395 if (SOC_IS_TD2_TT2(unit)) { 14396 /* Get Initial SW port enable status from HW */ 14397 PBMP_ITER(all_pbmp, p) { 14398 if (IS_E_PORT(unit, p)) { 14399 rv = bcm_esw_port_enable_get(unit, p, &enable); 14400 if (BCM_SUCCESS(rv)) { 14401 PORT(unit, p).enable = enable; 14402 } 14403 } 14404 } 14405 } 14406 #endif /* BCM_TRIDENT2_SUPPORT */ 14407 14408 PBMP_PORT_ITER(unit, p) { 14409 rv = bcm_esw_port_speed_get(unit, p, &p_speed); 14410 if (BCM_FAILURE(rv)) { 14411 continue; 14412 } 14413 _bcm_esw_port_link_delay_update(unit, p, p_speed); 14414 } 14415 14416 #if defined(BCM_TRIUMPH3_SUPPORT) 14417 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 14418 rv = _bcm_port_force_forward_init(unit); 14419 if (BCM_FAILURE(rv)) { 14420 return rv; 14421 } 14422 } 14423 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/ 14424 14425 #if defined(BCM_TOMAHAWK_SUPPORT) 14426 /* TH ASF */ 14427 if (soc_feature(unit, soc_feature_asf_multimode) 14428 #ifdef BCM_WARM_BOOT_SUPPORT 14429 && !SOC_WARM_BOOT(unit) 14430 /* WB recovery happens in _bcm_esw_port_wb_recover context */ 14431 #endif /* BCM_WARM_BOOT_SUPPORT */ 14432 ) { 14433 #ifdef BCM_MAVERICK2_SUPPORT 14434 if (SOC_IS_MAVERICK2(unit)) { 14435 BCM_IF_ERROR_RETURN( 14436 _bcm_esw_mv2_asf_init(unit, _SOC_MV2_ASF_MODE_INIT)); 14437 } else 14438 #endif 14439 #ifdef BCM_TRIDENT3_SUPPORT 14440 if (SOC_IS_TRIDENT3X(unit)) { 14441 BCM_IF_ERROR_RETURN( 14442 _bcm_esw_td3_asf_init(unit, _SOC_TD3_ASF_MODE_INIT)); 14443 } else 14444 #endif 14445 { 14446 BCM_IF_ERROR_RETURN( 14447 _bcm_esw_asf_init(unit, _SOC_TH_ASF_MODE_INIT)); 14448 } 14449 } 14450 #endif 14451 14452 #if defined (BCM_EP_REDIRECT_VERSION_2) 14453 /* Mark the RDB port as loopback mode */ 14454 if (soc_feature(unit, soc_feature_ep_redirect_v2)) { 14455 SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, PORT_TABm, 14456 BCMI_EP_REDIRECT_PORT, PORT_TYPEf, 2)); 14457 } 14458 #endif 14459 14460 #ifdef BCM_PREEMPTION_SUPPORT 14461 if (soc_feature(unit, soc_feature_preemption_cnt)) { 14462 BCM_IF_ERROR_RETURN(bcmi_esw_preemption_counter_init(unit)); 14463 } 14464 #endif 14465 14466 #if defined(BCM_GREYHOUND_SUPPORT) 14467 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 14468 /* 14469 * The ref_cnt of system-wise treat packet priority as dot1p priority 14470 * for different packet types or port controls. 14471 */ 14472 BCM_IF_ERROR_RETURN( 14473 bcmi_esw_port_treat_pktpri_as_dot1p_init(unit)); 14474 } 14475 #endif /* BCM_GREYHOUND_SUPPORT */ 14476 14477 if (SOC_WARM_BOOT(unit)) { 14478 return (_bcm_esw_port_wb_recover(unit)); 14479 } 14480 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \ 14481 defined(BCM_APACHE_SUPPORT) 14482 else { 14483 if(SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT2(unit) || SOC_IS_APACHE(unit)) { 14484 /* 14485 * Hardcoding the MMU_INTFI_ST_TRANS_TBL so the 14486 * congestion data is written as it is 14487 * in FC_ST_TABLE, This we are doing so that 14488 * congestion data is updated as it is how 14489 * it recevied 14490 */ 14491 for (index=0 ; index < soc_mem_index_count(unit, 14492 MMU_INTFI_ST_TRANS_TBLm); index++) { 14493 SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm( 14494 unit, MEM_BLOCK_ALL,index, 14495 &st_trans_entry)); 14496 soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm, 14497 &st_trans_entry, FC_ST_XLATEf, 14498 index % (SOC_IS_KATANA2(unit) ? 256 : 16)); 14499 SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm( 14500 unit, MEM_BLOCK_ALL, index, 14501 &st_trans_entry)); 14502 } 14503 } 14504 } 14505 #endif 14506 #if defined(BCM_GREYHOUND2_SUPPORT) 14507 if (SOC_IS_GREYHOUND2(unit)) { 14508 if (soc_feature(unit, soc_feature_e2efc)) { 14509 bcmi_gh2_port_e2efc_remote_port_init(unit); 14510 } 14511 } 14512 #endif /* BCM_GHREYHOUND2 */ 14513 return (_bcm_esw_port_wb_alloc(unit)); 14514 } 14515 14516 /* 14517 * Function: 14518 * bcm_port_clear 14519 * Purpose: 14520 * Initialize the PORT interface layer for the specified SOC device 14521 * without resetting stacking ports. 14522 * Parameters: 14523 * unit - StrataSwitch unit number. 14524 * Returns: 14525 * BCM_E_NONE - success (or already initialized) 14526 * BCM_E_INTERNAL- failed to write PTABLE entries 14527 * BCM_E_MEMORY - failed to allocate required memory. 14528 * Notes: 14529 * By default ports come up enabled. They can be made to come up disabled 14530 * at startup by a compile-time application policy flag in your Make.local 14531 * A call to bcm_port_clear should exhibit similar behavior for 14532 * non-stacking ethernet ports 14533 * PTABLE initialized. 14534 */ 14535 14536 int 14537 bcm_esw_port_clear(int unit) 14538 { 14539 bcm_port_config_t port_config; 14540 bcm_pbmp_t reset_ports; 14541 bcm_port_t port; 14542 int rv, port_enable; 14543 14544 PORT_INIT(unit); 14545 14546 BCM_IF_ERROR_RETURN(bcm_esw_port_config_get(unit, &port_config)); 14547 14548 /* Clear all non-stacking ethernet ports */ 14549 BCM_PBMP_ASSIGN(reset_ports, port_config.e); 14550 BCM_PBMP_REMOVE(reset_ports, SOC_PBMP_STACK_CURRENT(unit)); 14551 14552 PBMP_ITER(reset_ports, port) { 14553 LOG_VERBOSE(BSL_LS_BCM_PORT, 14554 (BSL_META_U(unit, 14555 "bcm_port_clear: unit %d port %s\n"), 14556 unit, SOC_PORT_NAME(unit, port))); 14557 14558 PORT_LOCK(unit); 14559 if ((rv = _bcm_port_mode_setup(unit, port, TRUE)) < 0) { 14560 LOG_WARN(BSL_LS_BCM_PORT, 14561 (BSL_META_U(unit, 14562 "Warning: Port %s: " 14563 "Failed to set initial mode: %s\n"), 14564 SOC_PORT_NAME(unit, port), bcm_errmsg(rv))); 14565 } 14566 PORT_UNLOCK(unit); 14567 14568 #ifdef BCM_RCPU_SUPPORT 14569 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 14570 /* Do not enable/disable rcpu port. */ 14571 continue; 14572 } 14573 #endif /* BCM_RCPU_SUPPORT */ 14574 14575 /* 14576 * A compile-time application policy may prefer to disable 14577 * ports at startup. The same behavior should be observed 14578 * when bcm_port_clear gets called. 14579 */ 14580 14581 #ifdef BCM_PORT_DEFAULT_DISABLE 14582 port_enable = FALSE; 14583 #else 14584 port_enable = TRUE; 14585 #endif /* BCM_PORT_DEFAULT_DISABLE */ 14586 14587 14588 if ((rv = bcm_esw_port_enable_set(unit, port, port_enable)) < 0) { 14589 LOG_WARN(BSL_LS_BCM_PORT, 14590 (BSL_META_U(unit, 14591 "Warning: Port %s: " 14592 "Failed to %s port: %s\n"), 14593 SOC_PORT_NAME(unit, port),(port_enable) ?\ 14594 "enable" : "disable" ,bcm_errmsg(rv))); 14595 } 14596 14597 } 14598 14599 return BCM_E_NONE; 14600 } 14601 14602 /* 14603 * Function: 14604 * _bcm_port_phy_probe 14605 * Purpose: 14606 * Probe the phy and set up the phy of the indicated port 14607 * Parameters: 14608 * unit - StrataSwitch unit number. 14609 * port - Port to probe 14610 * okay - Output parameter indicates port can be enabled. 14611 * Returns: 14612 * BCM_E_NONE 14613 * BCM_E_INTERNAL - internal error. 14614 * Notes: 14615 * If error is returned, the port should not be enabled. 14616 */ 14617 int 14618 _bcm_port_phy_probe(int unit, bcm_port_t port, int *okay) 14619 { 14620 int rv; 14621 bcm_pbmp_t pbmp; 14622 bcm_pbmp_t okay_pbmp; 14623 14624 /* Check for PortMod */ 14625 if(SOC_USE_PORTCTRL(unit)) { 14626 return BCM_E_UNAVAIL; 14627 } 14628 14629 *okay = FALSE; 14630 14631 LOG_VERBOSE(BSL_LS_BCM_PORT, 14632 (BSL_META_U(unit, 14633 "Init port %d PHY...\n"), port)); 14634 14635 BCM_PBMP_CLEAR(okay_pbmp); 14636 BCM_PBMP_CLEAR(pbmp); 14637 BCM_PBMP_PORT_SET(pbmp, port); 14638 14639 rv = soc_phyctrl_pbm_probe_init(unit,pbmp,&okay_pbmp); 14640 if (rv != BCM_E_NONE) { 14641 LOG_ERROR(BSL_LS_BCM_PORT, \ 14642 (BSL_META_U(unit, \ 14643 "Error unit %d:\ 14644 Failed port init probe: %s\n"), 14645 unit, bcm_errmsg(rv))); 14646 return rv; 14647 } 14648 14649 if (!SOC_WARM_BOOT(unit)) { 14650 /* Probe function should leave port disabled */ 14651 if ((rv = soc_phyctrl_enable_set(unit, port, 0)) < 0) { 14652 return rv; 14653 } 14654 } 14655 14656 *okay = TRUE; 14657 14658 return BCM_E_NONE; 14659 } 14660 14661 /* 14662 * Function: 14663 * _bcm_port_mac_init 14664 * Purpose: 14665 * Set up the mac of the indicated port 14666 * Parameters: 14667 * unit - StrataSwitch unit number. 14668 * port - Port to setup 14669 * okay - Output parameter indicates port can be enabled. 14670 * Returns: 14671 * BCM_E_NONE 14672 * BCM_E_INTERNAL - internal error. 14673 * Notes: 14674 * If error is returned, the port should not be enabled. 14675 */ 14676 int 14677 _bcm_port_mac_init(int unit, bcm_port_t port, int *okay) 14678 { 14679 int rv; 14680 mac_driver_t *macd; 14681 14682 /* Check for PortMod */ 14683 if (SOC_USE_PORTCTRL(unit)) { 14684 return BCM_E_UNAVAIL; 14685 } 14686 14687 *okay = FALSE; 14688 14689 LOG_VERBOSE(BSL_LS_BCM_PORT, 14690 (BSL_META_U(unit, 14691 "Init port %d MAC...\n"), port)); 14692 14693 if ((rv = soc_mac_probe(unit, port, &macd)) < 0) { 14694 LOG_WARN(BSL_LS_BCM_PORT, 14695 (BSL_META_U(unit, 14696 "Port %s: Failed to probe MAC: %s\n"), 14697 SOC_PORT_NAME(unit, port), soc_errmsg(rv))); 14698 return rv; 14699 } 14700 14701 PORT(unit, port).p_mac = macd; 14702 14703 if (!SOC_WARM_BOOT(unit) && !SOC_IS_RELOADING(unit)) { 14704 14705 #ifdef BCM_RCPU_SUPPORT 14706 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 14707 *okay = TRUE; 14708 return BCM_E_NONE; 14709 } 14710 #endif /* BCM_RCPU_SUPPORT */ 14711 14712 if ((rv = MAC_INIT(PORT(unit, port).p_mac, unit, port)) < 0) { 14713 LOG_WARN(BSL_LS_BCM_PORT, 14714 (BSL_META_U(unit, 14715 "Port %s: Failed to initialize MAC: %s\n"), 14716 SOC_PORT_NAME(unit, port), soc_errmsg(rv))); 14717 return rv; 14718 } 14719 14720 /* Probe function should leave port disabled */ 14721 if ((rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, 0)) < 0) { 14722 return rv; 14723 } 14724 } 14725 14726 *okay = TRUE; 14727 14728 return BCM_E_NONE; 14729 } 14730 14731 /* 14732 * Function: 14733 * _bcm_port_probe 14734 * Purpose: 14735 * Probe the phy and set up the phy and mac of the indicated port 14736 * Parameters: 14737 * unit - StrataSwitch unit number. 14738 * port - Port to probe 14739 * okay - Output parameter indicates port can be enabled. 14740 * Returns: 14741 * BCM_E_NONE 14742 * BCM_E_INTERNAL - internal error. 14743 * Notes: 14744 * If error is returned, the port should not be enabled. 14745 */ 14746 14747 int 14748 _bcm_port_probe(int unit, bcm_port_t port, int *okay) 14749 { 14750 /* Check for PortMod */ 14751 if (SOC_USE_PORTCTRL(unit)) { 14752 return bcmi_esw_portctrl_probe(unit, port, 0, NULL, okay); 14753 } 14754 14755 BCM_IF_ERROR_RETURN(_bcm_port_phy_probe(unit, port, okay)); 14756 14757 /* 14758 * Currently initializing MAC after PHY is required because of 14759 * phy_5690_notify_init(). 14760 */ 14761 BCM_IF_ERROR_RETURN(_bcm_port_mac_init(unit, port, okay)); 14762 14763 return BCM_E_NONE; 14764 } 14765 14766 /* 14767 * Function: 14768 * bcm_port_probe 14769 * Purpose: 14770 * Probe the PHY and set up the PHY and MAC for the specified ports. 14771 * This is purely a discovery routine and does no configuration. 14772 * Parameters: 14773 * unit - StrataSwitch unit number. 14774 * pbmp - Bitmap of ports to probe. 14775 * okay_pbmp (OUT) - Ports which were successfully probed. 14776 * Returns: 14777 * BCM_E_NONE 14778 * BCM_E_INTERNAL - internal error. 14779 * Notes: 14780 * If error is returned, the port should not be enabled. 14781 * Assumes port_init done. 14782 * Note that if a PHY is not present, the port will still probe 14783 * successfully. The default driver will be installed. 14784 */ 14785 int 14786 bcm_esw_port_probe(int unit, pbmp_t pbmp, pbmp_t *okay_pbmp) 14787 { 14788 int rv = BCM_E_NONE; 14789 bcm_port_t port; 14790 int okay; 14791 int skip_mac_reset = 0; 14792 soc_persist_t *sop; 14793 #ifdef BCM_TRIDENT_SUPPORT 14794 int port_speed; 14795 soc_port_ability_t mac_ability; 14796 #endif 14797 14798 SOC_PBMP_CLEAR(*okay_pbmp); 14799 14800 PORT_INIT(unit); 14801 PORT_LOCK(unit); 14802 #ifdef BCM_TOMAHAWK2_SUPPORT 14803 if (SOC_IS_TOMAHAWK2(unit)) { 14804 rv = bcmi_th2_tsc_xgxs_reset(unit, pbmp); 14805 if (SOC_FAILURE(rv)) { 14806 PORT_UNLOCK(unit); 14807 return (rv); 14808 } 14809 } else 14810 #endif /* BCM_TOMAHAWK2_SUPPORT */ 14811 { 14812 #ifdef BCM_TRIDENT2_SUPPORT 14813 if (SOC_IS_TD2_TT2(unit)) { 14814 soc_info_t *si; 14815 uint32 tsc_map, reset_tsc_map; 14816 int tsc, ports[32]; 14817 14818 si = &SOC_INFO(unit); 14819 /* Construct tsc_map covered by the specified pbmp */ 14820 tsc_map = 0; 14821 PBMP_ITER(pbmp, port) { 14822 tsc = si->port_serdes[port]; 14823 if (tsc != -1) { 14824 tsc_map |= 1 << tsc; 14825 } 14826 } 14827 14828 reset_tsc_map = 0; 14829 PBMP_PORT_ITER(unit, port) { 14830 tsc = si->port_serdes[port]; 14831 if (tsc_map & (1 << tsc)) { 14832 if (PORT(unit, port).flags & _PORT_INFO_PROBE_RESET_SERDES) { 14833 PORT(unit, port).flags &= ~_PORT_INFO_PROBE_RESET_SERDES; 14834 reset_tsc_map |= 1 << tsc; 14835 ports[tsc] = port; 14836 } 14837 } 14838 } 14839 for (tsc = 0; tsc < 32; tsc++) { 14840 if (reset_tsc_map & (1 << tsc)) { 14841 rv = soc_tsc_xgxs_reset(unit, ports[tsc], 0); 14842 if (SOC_FAILURE(rv)) { 14843 PORT_UNLOCK(unit); 14844 return (rv); 14845 } 14846 } 14847 } 14848 } 14849 #endif /* BCM_TRIDENT2_SUPPORT */ 14850 } 14851 #if defined(BCM_SABER2_SUPPORT) 14852 /* If OAMP is enabled by default, skip the port init for oamp port */ 14853 if(SOC_IS_SABER2(unit)) { 14854 int oamp_enable; 14855 (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable); 14856 14857 if (soc_feature(unit, soc_feature_sat) && 14858 ((!SOC_WARM_BOOT(unit) && 14859 soc_property_get(unit, spn_SAT_ENABLE, 0)) || 14860 (SOC_WARM_BOOT(unit) && (oamp_enable == TRUE)))) { 14861 SOC_PBMP_PORT_REMOVE(pbmp, _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER); 14862 SOC_PBMP_PORT_REMOVE(*okay_pbmp, 14863 _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER); 14864 } 14865 } 14866 #endif 14867 /* Check for PortMod */ 14868 if (SOC_USE_PORTCTRL(unit)) { 14869 rv = bcmi_esw_portctrl_probe_pbmp(unit, pbmp, okay_pbmp); 14870 PORT_UNLOCK(unit); 14871 return (rv); 14872 } 14873 14874 rv = soc_phyctrl_pbm_probe_init(unit,pbmp,okay_pbmp); 14875 if (!SOC_WARM_BOOT(unit)) { 14876 PBMP_ITER(*okay_pbmp, port) { 14877 /* Probe function should leave port disabled */ 14878 if ((rv = soc_phyctrl_enable_set(unit, port, 0)) < 0) { 14879 break; 14880 } 14881 } 14882 } 14883 if (soc_property_get(unit, spn_SAME_SPEED_INTF_DO_NOT_OVERWRITE, 14884 (SAL_BOOT_BCMSIM || SAL_BOOT_XGSSIM))) { 14885 PBMP_ITER(*okay_pbmp, port) { 14886 if ((rv = bcm_esw_port_interface_get(unit, port, &(PORT(unit, port).intf))) < 0) { 14887 PORT(unit, port).intf = 0; 14888 continue; 14889 } 14890 } 14891 } 14892 14893 if (SOC_IS_GREYHOUND(unit) || SOC_IS_SABER2(unit) || 14894 SOC_IS_TOMAHAWKX(unit) || SOC_IS_APACHE(unit)) { 14895 /* XLPORT_MAC_CONTROLr.XMAC0_RESETf has been toggled duirng soc_reset */ 14896 skip_mac_reset = 1; 14897 } 14898 14899 if (SOC_REG_IS_VALID(unit, GPORT_UMAC_CONTROLr)) { 14900 int blk; 14901 uint32 rval; 14902 pbmp_t block_pbmp; 14903 int port_blk_index; 14904 int i; 14905 14906 SOC_BLOCK_ITER(unit, blk, SOC_BLK_GPORT) { 14907 rval = 0; 14908 BCM_PBMP_ASSIGN(block_pbmp, SOC_BLOCK_BITMAP(unit, blk)); 14909 BCM_PBMP_AND(block_pbmp, pbmp); 14910 if (BCM_PBMP_IS_NULL(block_pbmp)) { 14911 continue; 14912 } 14913 14914 /* get the port number */ 14915 SOC_PBMP_ITER(block_pbmp, i) 14916 { 14917 /* get the index of the port in blk*/ 14918 port_blk_index = SOC_PORT_BLOCK_INDEX(unit, i); 14919 rval |= 1 << port_blk_index; 14920 } 14921 14922 port = SOC_BLOCK_PORT(unit, blk); 14923 /* just Write.. No need for RMW as no other field is there.. */ 14924 /* (void)READ_GPORT_UMAC_CONTROLr(unit, port, &rval); */ 14925 /* Set UMAC0_RESETf..UMAC7_RESETf */ 14926 #ifdef BCM_RCPU_SUPPORT 14927 if (SOC_IS_RCPU_ONLY(unit) && 14928 SOC_PORT_VALID(unit, RCPU_PORT(unit)) && 14929 BCM_PBMP_MEMBER(block_pbmp, RCPU_PORT(unit))) { 14930 rval &= ~ (1 << SOC_PORT_BLOCK_INDEX(unit, RCPU_PORT(unit))); 14931 } 14932 #endif /* BCM_RCPU_SUPPORT */ 14933 (void)WRITE_GPORT_UMAC_CONTROLr(unit, port, rval); 14934 sal_udelay(10); 14935 rval = 0; /* Reset UMAC0_RESETf..UMAC7_RESETf */ 14936 (void)WRITE_GPORT_UMAC_CONTROLr(unit, port, rval); 14937 } 14938 } 14939 14940 if (SOC_REG_IS_VALID(unit, XLPORT_MAC_CONTROLr) && !skip_mac_reset) { 14941 int blk, port; 14942 14943 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 14944 port = SOC_BLOCK_PORT(unit, blk); 14945 if (port == -1) { 14946 continue; 14947 } 14948 14949 if (SOC_INFO(unit).port_speed_max[port] >= 100000) { 14950 continue; 14951 } 14952 14953 /* Reset the entire block only if it is called from port init */ 14954 if (PORT(unit, port).p_mac != NULL) { 14955 continue; 14956 } 14957 14958 #ifdef BCM_RCPU_SUPPORT 14959 if (SOC_IS_RCPU_ONLY(unit) && 14960 SOC_PORT_VALID(unit, RCPU_PORT(unit)) && 14961 BCM_PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), RCPU_PORT(unit))) { 14962 continue; 14963 } 14964 #endif /* BCM_RCPU_SUPPORT */ 14965 14966 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 14967 (soc_reg_field32_modify(unit, XLPORT_MAC_CONTROLr, port, 14968 XMAC0_RESETf, 1)); 14969 sal_udelay(10); 14970 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 14971 (soc_reg_field32_modify(unit, XLPORT_MAC_CONTROLr, port, 14972 XMAC0_RESETf, 0)); 14973 if (soc_feature (unit, soc_feature_xlmac_timestamp_disable)) { 14974 if (soc_reg_field_valid(unit, XLPORT_MAC_CONTROLr, XLMAC_TS_DISABLEf)) { 14975 /* Disable MAC timestamp by default */ 14976 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 14977 (soc_reg_field32_modify(unit, XLPORT_MAC_CONTROLr, port, 14978 XLMAC_TS_DISABLEf, 1)); 14979 } 14980 } 14981 } 14982 } 14983 14984 if (SOC_REG_IS_VALID(unit, GPORT_UMAC_CONTROLr)) { 14985 int blk, port; 14986 14987 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CPORT) { 14988 port = SOC_BLOCK_PORT(unit, blk); 14989 if (port == -1) { 14990 continue; 14991 } 14992 14993 if (SOC_INFO(unit).port_speed_max[port] < 100000) { 14994 continue; 14995 } 14996 14997 /* Reset the entire block only if it is called from port init */ 14998 if (PORT(unit, port).p_mac != NULL) { 14999 continue; 15000 } 15001 15002 #ifdef BCM_RCPU_SUPPORT 15003 if (SOC_IS_RCPU_ONLY(unit) && 15004 SOC_PORT_VALID(unit, RCPU_PORT(unit)) && 15005 BCM_PBMP_MEMBER(SOC_BLOCK_BITMAP(unit, blk), RCPU_PORT(unit))) { 15006 continue; 15007 } 15008 #endif /* BCM_RCPU_SUPPORT */ 15009 15010 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15011 (soc_reg_field32_modify(unit, CPORT_MAC_CONTROLr, port, 15012 CMAC_RESETf, 1)); 15013 if (SOC_REG_IS_VALID(unit, CPORT_SOFT_RESETr)) { 15014 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15015 (soc_reg_field32_modify(unit, CPORT_SOFT_RESETr, port, 15016 CPORT_COREf, 1)); 15017 } 15018 sal_udelay(10); 15019 if (SOC_REG_IS_VALID(unit, CPORT_SOFT_RESETr)) { 15020 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15021 (soc_reg_field32_modify(unit, CPORT_SOFT_RESETr, port, 15022 CPORT_COREf, 0)); 15023 } 15024 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15025 (soc_reg_field32_modify(unit, CPORT_MAC_CONTROLr, port, 15026 CMAC_RESETf, 0)); 15027 } 15028 } 15029 15030 if (SOC_REG_IS_VALID(unit, XLPORT_XMAC_CONTROLr)) { 15031 int blk; 15032 uint32 rval; 15033 pbmp_t block_pbmp; 15034 15035 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 15036 BCM_PBMP_ASSIGN(block_pbmp, SOC_BLOCK_BITMAP(unit, blk)); 15037 BCM_PBMP_AND(block_pbmp, pbmp); 15038 if (BCM_PBMP_IS_NULL(block_pbmp)) { 15039 continue; 15040 } 15041 15042 port = SOC_BLOCK_PORT(unit, blk); 15043 15044 /* Reset the entire block only if it is called from port init */ 15045 if (PORT(unit, port).p_mac != NULL) { 15046 continue; 15047 } 15048 15049 #ifdef BCM_RCPU_SUPPORT 15050 if (SOC_IS_RCPU_ONLY(unit) && 15051 SOC_PORT_VALID(unit, RCPU_PORT(unit)) && 15052 BCM_PBMP_MEMBER(block_pbmp, RCPU_PORT(unit))) { 15053 continue; 15054 } 15055 #endif /* BCM_RCPU_SUPPORT */ 15056 15057 (void)READ_XLPORT_XMAC_CONTROLr(unit, port, &rval); 15058 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 15059 1); 15060 (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval); 15061 sal_udelay(10); 15062 15063 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 15064 0); 15065 (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval); 15066 } 15067 } 15068 #ifdef BCM_SHADOW_SUPPORT 15069 /* Interlaken need to be taken out of reset after PHY is initialized */ 15070 if (SOC_IS_SHADOW(unit)) { 15071 int active_il = 0; 15072 uint32 rval; 15073 15074 if (soc_property_get(unit, spn_BCM88732_2X40_1X40, 0) || 15075 soc_property_get(unit, spn_BCM88732_8X10_1X40, 0)) { 15076 active_il = 1; 15077 } else { 15078 if (soc_property_get(unit, spn_BCM88732_1X40_4X10, 0) || 15079 soc_property_get(unit, spn_BCM88732_4X10_4X10, 0) || 15080 soc_property_get(unit, spn_BCM88732_2X40_2X40, 0) || 15081 soc_property_get(unit, spn_BCM88732_2X40_8X12, 0) || 15082 soc_property_get(unit, spn_BCM88732_8X10_8X12, 0) || 15083 soc_property_get(unit, spn_BCM88732_2X40_8X10, 0) || 15084 soc_property_get(unit, spn_BCM88732_8X10_8X10, 0) || 15085 soc_property_get(unit, spn_BCM88732_8X10_4X12, 0) || 15086 soc_property_get(unit, spn_BCM88732_8X10_2X12, 0) || 15087 soc_property_get(unit, spn_BCM88732_1X40_4X10_8X12, 0) || 15088 soc_property_get(unit, spn_BCM88732_4X10_1X40_8X12, 0) || 15089 soc_property_get(unit, spn_BCM88732_6X10_2X12, 0)) { 15090 active_il = 0; 15091 } else { 15092 active_il = 2; 15093 } 15094 } 15095 if (active_il) { 15096 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15097 (READ_IL_GLOBAL_CONTROLr(unit, 9, &rval)); 15098 soc_reg_field_set(unit, IL_GLOBAL_CONTROLr, &rval, SOFT_RESETf, 0); 15099 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15100 (WRITE_IL_GLOBAL_CONTROLr(unit, 9, rval)); 15101 } 15102 if (active_il == 2) { 15103 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15104 (READ_IL_GLOBAL_CONTROLr(unit, 13, &rval)); 15105 soc_reg_field_set(unit, IL_GLOBAL_CONTROLr, &rval, SOFT_RESETf, 0); 15106 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 15107 (WRITE_IL_GLOBAL_CONTROLr(unit, 13, rval)); 15108 } 15109 } 15110 #endif /* BCM_SHADOW_SUPPORT */ 15111 15112 if (SOC_REG_IS_VALID(unit, XPORT_XMAC_CONTROLr)) { 15113 int blk; 15114 uint32 rval; 15115 pbmp_t block_pbmp; 15116 15117 SOC_BLOCK_ITER(unit, blk, SOC_BLK_MXQPORT) { 15118 BCM_PBMP_ASSIGN(block_pbmp, SOC_BLOCK_BITMAP(unit, blk)); 15119 BCM_PBMP_AND(block_pbmp, pbmp); 15120 if (BCM_PBMP_IS_NULL(block_pbmp)) { 15121 continue; 15122 } 15123 15124 port = SOC_BLOCK_PORT(unit, blk); 15125 15126 /* Reset the entire block only if it is called from port init */ 15127 if (PORT(unit, port).p_mac != NULL) { 15128 continue; 15129 } 15130 15131 #ifdef BCM_RCPU_SUPPORT 15132 if (SOC_IS_RCPU_ONLY(unit) && 15133 SOC_PORT_VALID(unit, RCPU_PORT(unit)) && 15134 BCM_PBMP_MEMBER(block_pbmp, RCPU_PORT(unit))) { 15135 continue; 15136 } 15137 #endif /* BCM_RCPU_SUPPORT */ 15138 15139 (void)READ_XPORT_XMAC_CONTROLr(unit, port, &rval); 15140 soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 15141 1); 15142 (void)WRITE_XPORT_XMAC_CONTROLr(unit, port, rval); 15143 sal_udelay(10); 15144 15145 soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 15146 0); 15147 (void)WRITE_XPORT_XMAC_CONTROLr(unit, port, rval); 15148 } 15149 } 15150 15151 #ifdef BCM_TRIUMPH3_SUPPORT 15152 if (SOC_IS_TRIUMPH3(unit)) { 15153 uint8 rev_id; 15154 uint16 dev_id; 15155 soc_info_t *si; 15156 soc_port_t port; 15157 int phy, lane, blk, block_has_ports, high_speed_port; 15158 uint32 rval; 15159 15160 si = &SOC_INFO(unit); 15161 soc_cm_get_id(unit, &dev_id, &rev_id); 15162 SOC_BLOCK_ITER(unit, blk, SOC_BLK_CLPORT) { 15163 block_has_ports = FALSE; 15164 high_speed_port = -1; 15165 for (phy = 0; phy < _SOC_TR3_PHY_PER_PORT_BLOCK; phy++) { 15166 for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) { 15167 port = si->port_p2l_mapping[si->blk_fpp[blk] + 15168 ((phy * _SOC_TR3_LANES_PER_PHY) + lane)]; 15169 /* coverity[overrun-local : FALSE] */ 15170 if (SOC_PORT_VALID(unit, port) && 15171 si->port_speed_max[port] >= 100000) { 15172 /* Save the 100G+ speed port becuase we must 15173 * init the other two PHYs, even though they don't 15174 * match a valid port. */ 15175 high_speed_port = port; 15176 } else if (high_speed_port >= 0) { 15177 port = high_speed_port; 15178 } 15179 if (SOC_PORT_VALID(unit, port)) { 15180 block_has_ports |= 1 << phy; 15181 break; /* Only need to reset PHY once */ 15182 } 15183 } 15184 } 15185 if (!block_has_ports) { 15186 continue; /* All ports disabled */ 15187 } 15188 port = SOC_BLOCK_PORT(unit, blk); 15189 15190 /* Reset only when called from port init */ 15191 if (PORT(unit, port).p_mac != NULL) { 15192 continue; 15193 } 15194 15195 rv = READ_PORT_MAC_CONTROLr(unit, port, &rval); 15196 if (SOC_FAILURE(rv)) { 15197 PORT_UNLOCK(unit); 15198 return (rv); 15199 } 15200 if ((soc_feature(unit, soc_feature_cmac)) && (high_speed_port >= 0)) { 15201 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15202 CMAC_RESETf, 1); 15203 } 15204 if (block_has_ports & 1) { 15205 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15206 XMAC0_RESETf, 1); 15207 } 15208 if (block_has_ports & 2) { 15209 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15210 XMAC1_RESETf, 1); 15211 } 15212 if (block_has_ports & 4) { 15213 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15214 XMAC2_RESETf, 1); 15215 } 15216 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 15217 if (SOC_FAILURE(rv)) { 15218 PORT_UNLOCK(unit); 15219 return (rv); 15220 } 15221 15222 sal_udelay(10); 15223 if ((soc_feature(unit, soc_feature_cmac)) && (high_speed_port >= 0)) { 15224 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15225 CMAC_RESETf, 0); 15226 } 15227 if (block_has_ports & 1) { 15228 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15229 XMAC0_RESETf, 0); 15230 } 15231 if (block_has_ports & 2) { 15232 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15233 XMAC1_RESETf, 0); 15234 } 15235 if (block_has_ports & 4) { 15236 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15237 XMAC2_RESETf, 0); 15238 } 15239 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 15240 if (SOC_FAILURE(rv)) { 15241 PORT_UNLOCK(unit); 15242 return (rv); 15243 } 15244 } 15245 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XTPORT) { 15246 block_has_ports = FALSE; 15247 for (phy = 0; phy < _SOC_TR3_PHY_PER_PORT_BLOCK; phy++) { 15248 for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) { 15249 port = si->port_p2l_mapping[si->blk_fpp[blk] + 15250 ((phy * _SOC_TR3_LANES_PER_PHY) + lane)]; 15251 if (SOC_PORT_VALID(unit, port)) { 15252 block_has_ports |= 1 << phy; 15253 break; /* Only need to reset PHY once */ 15254 } 15255 } 15256 } 15257 if (!block_has_ports) { 15258 continue; /* All ports disabled */ 15259 } 15260 port = SOC_BLOCK_PORT(unit, blk); 15261 15262 /* Reset only when called from port init */ 15263 if (PORT(unit, port).p_mac != NULL) { 15264 continue; 15265 } 15266 15267 rv = READ_PORT_MAC_CONTROLr(unit, port, &rval); 15268 if (SOC_FAILURE(rv)) { 15269 PORT_UNLOCK(unit); 15270 return (rv); 15271 } 15272 if (block_has_ports & 1) { 15273 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15274 XMAC0_RESETf, 1); 15275 } 15276 if (block_has_ports & 2) { 15277 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15278 XMAC1_RESETf, 1); 15279 } 15280 if (block_has_ports & 4) { 15281 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15282 XMAC2_RESETf, 1); 15283 } 15284 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 15285 if (SOC_FAILURE(rv)) { 15286 PORT_UNLOCK(unit); 15287 return (rv); 15288 } 15289 sal_udelay(10); 15290 if (block_has_ports & 1) { 15291 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15292 XMAC0_RESETf, 0); 15293 } 15294 if (block_has_ports & 2) { 15295 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15296 XMAC1_RESETf, 0); 15297 } 15298 if (block_has_ports & 4) { 15299 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15300 XMAC2_RESETf, 0); 15301 } 15302 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 15303 if (SOC_FAILURE(rv)) { 15304 PORT_UNLOCK(unit); 15305 return (rv); 15306 } 15307 } 15308 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XLPORT) { 15309 block_has_ports = FALSE; 15310 /* Only one PHY per XLPORT */ 15311 for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) { 15312 port = si->port_p2l_mapping[si->blk_fpp[blk] + lane]; 15313 if (SOC_PORT_VALID(unit, port)) { 15314 block_has_ports = TRUE; 15315 break; 15316 } 15317 } 15318 if (!block_has_ports) { 15319 continue; /* All ports disabled */ 15320 } 15321 port = SOC_BLOCK_PORT(unit, blk); 15322 15323 /* Reset only when called from port init */ 15324 if (PORT(unit, port).p_mac != NULL) { 15325 continue; 15326 } 15327 15328 rv = READ_PORT_MAC_CONTROLr(unit, port, &rval); 15329 if (SOC_FAILURE(rv)) { 15330 PORT_UNLOCK(unit); 15331 return (rv); 15332 } 15333 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15334 XMAC0_RESETf, 1); 15335 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 15336 if (SOC_FAILURE(rv)) { 15337 PORT_UNLOCK(unit); 15338 return (rv); 15339 } 15340 sal_udelay(10); 15341 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15342 XMAC0_RESETf, 0); 15343 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 15344 if (SOC_FAILURE(rv)) { 15345 PORT_UNLOCK(unit); 15346 return (rv); 15347 } 15348 } 15349 #ifdef BCM_HELIX4_SUPPORT 15350 SOC_BLOCK_ITER(unit, blk, SOC_BLK_XWPORT) { 15351 block_has_ports = FALSE; 15352 /* Only one PHY per XWPORT */ 15353 for (lane = 0; lane < _SOC_TR3_LANES_PER_PHY; lane++) { 15354 port = si->port_p2l_mapping[si->blk_fpp[blk] + lane]; 15355 if (SOC_PORT_VALID(unit, port)) { 15356 block_has_ports = TRUE; 15357 break; 15358 } 15359 } 15360 if (!block_has_ports) { 15361 continue; /* All ports disabled */ 15362 } 15363 port = SOC_BLOCK_PORT(unit, blk); 15364 15365 /* Reset only when called from port init */ 15366 if (PORT(unit, port).p_mac != NULL) { 15367 continue; 15368 } 15369 15370 rv = READ_PORT_MAC_CONTROLr(unit, port, &rval); 15371 if (SOC_FAILURE(rv)) { 15372 PORT_UNLOCK(unit); 15373 return (rv); 15374 } 15375 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15376 XMAC0_RESETf, 1); 15377 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 15378 if (SOC_FAILURE(rv)) { 15379 PORT_UNLOCK(unit); 15380 return (rv); 15381 } 15382 sal_udelay(10); 15383 soc_reg_field_set(unit, PORT_MAC_CONTROLr, &rval, 15384 XMAC0_RESETf, 0); 15385 rv = WRITE_PORT_MAC_CONTROLr(unit, port, rval); 15386 if (SOC_FAILURE(rv)) { 15387 PORT_UNLOCK(unit); 15388 return (rv); 15389 } 15390 } 15391 #endif /* BCM_HELIX4_SUPPORT */ 15392 } 15393 #endif /* BCM_TRIUMPH3_SUPPORT */ 15394 15395 PBMP_ITER(pbmp, port) { 15396 if (!(IS_TDM_PORT(unit, port)) && 15397 !SOC_USE_PORTCTRL(unit)) { 15398 rv = _bcm_port_mac_init(unit, port, &okay); 15399 15400 if (!okay) { 15401 SOC_PBMP_PORT_REMOVE(*okay_pbmp, port); 15402 #if defined(BCM_ESW_SUPPORT) 15403 soc_counter_port_pbmp_remove(unit, port); 15404 #endif 15405 } 15406 if (rv < 0) { 15407 LOG_WARN(BSL_LS_BCM_PORT, 15408 (BSL_META_U(unit, 15409 "MAC init failed on port %s\n"), 15410 SOC_PORT_NAME(unit, port))); 15411 break; 15412 } 15413 15414 #ifdef BCM_TRIDENT_SUPPORT 15415 if (SOC_IS_TD_TT(unit) && 15416 !SOC_PBMP_MEMBER(SOC_INFO(unit).all.disabled_bitmap, port)) { 15417 soc_ipg_t *si; 15418 int ifg, duplex; 15419 15420 rv = MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &duplex); 15421 if (rv < 0) { 15422 LOG_WARN(BSL_LS_BCM_PORT, 15423 (BSL_META_U(unit, 15424 "MAC_DUPLEX_GET failed on port %s\n"), 15425 SOC_PORT_NAME(unit, port))); 15426 break; 15427 } 15428 15429 si = &SOC_PERSIST(unit)->ipg[port]; 15430 if (IS_HG_PORT(unit, port)) { 15431 ifg = si->fd_hg = SOC_AVERAGE_IPG_HG; 15432 } else { 15433 ifg = si->fd_xe = SOC_AVERAGE_IPG_IEEE; 15434 } 15435 15436 if (SOC_IS_TOMAHAWKX(unit)) { 15437 port_speed = (0 != SOC_INFO(unit).port_init_speed[port]) ? 15438 SOC_INFO(unit).port_init_speed[port] : SOC_INFO(unit).port_speed_max[port]; 15439 } else if (SOC_IS_TRIDENT2(unit)) { 15440 sal_memset(&mac_ability, 0, sizeof(soc_port_ability_t)); 15441 rv = MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit, port, 15442 &mac_ability); 15443 if (rv < 0) { 15444 LOG_WARN(BSL_LS_BCM_PORT, 15445 (BSL_META_U(unit, 15446 "MAC_ABILITY_LOCAL_GET failed on port %s\n"), 15447 SOC_PORT_NAME(unit, port))); 15448 break; 15449 } 15450 port_speed = BCM_PORT_ABILITY_SPEED_MAX(mac_ability.speed_full_duplex); 15451 } else { 15452 port_speed = SOC_INFO(unit).port_speed_max[port]; 15453 } 15454 15455 rv = MAC_IFG_SET(PORT(unit, port).p_mac, unit, port, 15456 port_speed, duplex, ifg); 15457 if (rv < 0) { 15458 LOG_WARN(BSL_LS_BCM_PORT, 15459 (BSL_META_U(unit, 15460 "MAC_IFG_SET failed on port %s\n"), 15461 SOC_PORT_NAME(unit, port))); 15462 break; 15463 } 15464 } 15465 #endif 15466 } 15467 15468 /* This is needed for run-time probing */ 15469 sop = SOC_PERSIST(unit); 15470 if (soc_property_port_get(unit, port, spn_FCMAP_ENABLE, 0)) { 15471 SOC_PBMP_PORT_ADD(sop->lc_pbm_fc, port); 15472 } else { 15473 SOC_PBMP_PORT_REMOVE(sop->lc_pbm_fc, port); 15474 } 15475 15476 /* Check if the external phy is set in EBE/EtherRAM buffer mode */ 15477 if (soc_property_port_get(unit, port, spn_PHY_OPERATIONAL_MODE, 0) == 3) { 15478 SOC_PBMP_PORT_ADD(sop->lc_pbm_eth_buffer_mode, port); 15479 } else { 15480 SOC_PBMP_PORT_REMOVE(sop->lc_pbm_eth_buffer_mode, port); 15481 } 15482 15483 } 15484 15485 PORT_UNLOCK(unit); 15486 15487 return rv; 15488 } 15489 15490 /* 15491 * Function: 15492 * _bcm_port_detach 15493 * Purpose: 15494 * Main part of bcm_port_detach 15495 */ 15496 15497 int 15498 _bcm_port_detach(int unit, pbmp_t pbmp, pbmp_t *detached) 15499 { 15500 bcm_port_t port; 15501 int rv; 15502 soc_persist_t *sop = SOC_PERSIST(unit); 15503 15504 SOC_PBMP_CLEAR(*detached); 15505 15506 PBMP_ITER(pbmp, port) { 15507 BCM_IF_ERROR_RETURN(bcm_esw_port_stp_set(unit, port, BCM_STG_STP_DISABLE)); 15508 PORT_LOCK(unit); 15509 rv = _bcm_port_mode_setup(unit, port, FALSE); 15510 PORT_UNLOCK(unit); 15511 BCM_IF_ERROR_RETURN(rv); 15512 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port)); 15513 SOC_PBMP_PORT_ADD(*detached, port); 15514 15515 if (SOC_PBMP_MEMBER(sop->lc_pbm_fc, port)) { 15516 /* Bring down the internal PHY */ 15517 rv = bcm_esw_port_update(unit, port, FALSE); 15518 BCM_IF_ERROR_RETURN(rv); 15519 SOC_PBMP_PORT_REMOVE(sop->lc_pbm_fc, port); 15520 } 15521 } 15522 #ifdef BCM_TRIUMPH2_SUPPORT 15523 if (soc_feature(unit, soc_feature_vpd_profile)) { 15524 _bcm_tr2_port_vpd_bitmap_free(unit); 15525 } 15526 #endif 15527 return BCM_E_NONE; 15528 } 15529 15530 /* 15531 * Function: 15532 * bcm_port_detach 15533 * Purpose: 15534 * Detach a port. Set phy driver to no connection. 15535 * Parameters: 15536 * unit - StrataSwitch unit number. 15537 * pbmp - Bitmap of ports to detach. 15538 * detached (OUT) - Bitmap of ports successfully detached. 15539 * Returns: 15540 * BCM_E_NONE 15541 * BCM_E_INTERNAL - internal error. 15542 * Notes: 15543 * If a port to be detached does not appear in detached, its 15544 * state is not defined. 15545 */ 15546 15547 int 15548 bcm_esw_port_detach(int unit, pbmp_t pbmp, pbmp_t *detached) 15549 { 15550 int rv; 15551 #ifdef BROADCOM_DEBUG 15552 char pfmtp[SOC_PBMP_FMT_LEN], 15553 pfmtd[SOC_PBMP_FMT_LEN]; 15554 #endif /* BROADCOM_DEBUG */ 15555 15556 PORT_INIT(unit); 15557 if (SOC_USE_PORTCTRL(unit)) { 15558 return bcmi_esw_portctrl_detach(unit, pbmp, detached); 15559 } 15560 15561 PORT_LOCK(unit); 15562 rv = _bcm_port_detach(unit, pbmp, detached); 15563 PORT_UNLOCK(unit); 15564 #ifdef BROADCOM_DEBUG 15565 LOG_INFO(BSL_LS_BCM_PORT, 15566 (BSL_META_U(unit, 15567 "bcm_port_detach: u=%d pbmp=%s det=%s rv=%d\n"), 15568 unit, 15569 SOC_PBMP_FMT(pbmp, pfmtp), 15570 SOC_PBMP_FMT(*detached, pfmtd), 15571 rv)); 15572 #endif 15573 return rv; 15574 } 15575 15576 /* 15577 * Function: 15578 * bcm_port_config_get 15579 * Purpose: 15580 * Get port configuration of a device 15581 * Parameters: 15582 * unit - StrataSwitch Unit #. 15583 * config - (OUT) Structure returning configuration 15584 * Returns: 15585 * BCM_E_XXX 15586 */ 15587 15588 int 15589 bcm_esw_port_config_get(int unit, bcm_port_config_t *config) 15590 { 15591 int i; 15592 15593 PORT_INIT(unit); 15594 PORT_LOCK(unit); 15595 15596 config->fe = PBMP_FE_ALL(unit); 15597 config->ge = PBMP_GE_ALL(unit); 15598 config->xe = PBMP_XE_ALL(unit); 15599 config->ce = PBMP_CE_ALL(unit); 15600 config->cd = PBMP_CDE_ALL(unit); 15601 config->e = PBMP_E_ALL(unit); 15602 config->hg = PBMP_HG_ALL(unit); 15603 config->tdm = PBMP_TDM_ALL(unit); 15604 config->port = PBMP_PORT_ALL(unit); 15605 config->cpu = PBMP_CMIC(unit); 15606 config->roe = PBMP_CPRI_ALL(unit); 15607 config->all = PBMP_ALL(unit); 15608 /* Remove LB and RDB port from the PBMP_ALL bitmap for backward compatibility */ 15609 SOC_PBMP_REMOVE(config->all, PBMP_LB(unit)); 15610 SOC_PBMP_REMOVE(config->all, PBMP_RDB_ALL(unit)); 15611 SOC_PBMP_REMOVE(config->all, PBMP_FAE_ALL(unit)); 15612 #ifdef BCM_MONTEREY_SUPPORT 15613 if (SOC_IS_MONTEREY(unit)) { 15614 SOC_PBMP_REMOVE(config->all, PBMP_MACSEC_ALL(unit)); 15615 } 15616 #endif 15617 config->stack_ext = PBMP_ST_ALL(unit); 15618 15619 15620 BCM_PBMP_CLEAR(config->stack_int); 15621 BCM_PBMP_CLEAR(config->sci); 15622 BCM_PBMP_CLEAR(config->sfi); 15623 BCM_PBMP_CLEAR(config->spi); 15624 BCM_PBMP_CLEAR(config->spi_subport); 15625 15626 for (i = 0; i < NUM_PIPE(unit); i++) { 15627 config->per_pipe[i] = PBMP_PIPE(unit, i); 15628 SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_LB(unit)); 15629 SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_RDB_ALL(unit)); 15630 SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_FAE_ALL(unit)); 15631 #ifdef BCM_MONTEREY_SUPPORT 15632 if (SOC_IS_MONTEREY(unit)) { 15633 SOC_PBMP_REMOVE(config->per_pipe[i], PBMP_MACSEC_ALL(unit)); 15634 } 15635 #endif 15636 } 15637 15638 #if defined(BCM_SABER2_SUPPORT) 15639 /* Remove OAMP port from port config list */ 15640 if(SOC_IS_SABER2(unit)) { 15641 soc_info_t *si = &SOC_INFO(unit); 15642 bcm_port_t oamp_port = _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER; 15643 15644 if(bcm_common_oamp_port_enable_get(unit, oamp_port)) { 15645 SOC_PBMP_PORT_REMOVE(config->port, oamp_port); 15646 SOC_PBMP_PORT_REMOVE(config->e, oamp_port); 15647 15648 if(si->port_speed_max[oamp_port] < 10000) { 15649 SOC_PBMP_PORT_REMOVE(config->ge, oamp_port); 15650 } else { 15651 SOC_PBMP_PORT_REMOVE(config->xe, oamp_port); 15652 } 15653 } 15654 } 15655 #endif 15656 15657 #if defined(BCM_TRIUMPH3_SUPPORT) 15658 if (SOC_IS_TRIUMPH3(unit)) { 15659 config->control = soc_tr3_get_control_port_bitmap(unit); 15660 } 15661 #endif 15662 15663 #if defined(BCM_KATANA2_SUPPORT) 15664 if (SOC_IS_KATANA2(unit) && (soc_feature(unit, soc_feature_linkphy_coe) || 15665 soc_feature(unit, soc_feature_subtag_coe))) { 15666 _bcm_kt2_subport_pbmp_update(unit, &(config->all)); 15667 } 15668 #endif 15669 15670 PORT_UNLOCK(unit); 15671 return BCM_E_NONE; 15672 } 15673 15674 STATIC int 15675 _bcm_td_port_mode_update(int unit, bcm_port_t port, int speed) 15676 { 15677 soc_info_t *si; 15678 int enable[2], duplex[2], loopback[2], pause_tx[2], pause_rx[2]; 15679 int frame_max[2], encap[2]; 15680 sal_mac_addr_t address[2]; 15681 bcm_port_t port_list[2], phy_port, cur_port; 15682 uint32 rval; 15683 int core_mode, phy_mode, old_phy_mode; 15684 int i; 15685 15686 /* Get the original phy_mode */ 15687 SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port, &rval)); 15688 core_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, 15689 CORE_PORT_MODEf); 15690 old_phy_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, 15691 PHY_PORT_MODEf); 15692 15693 si = &SOC_INFO(unit); 15694 /* speed is the only factor to determine phy_mode */ 15695 if ((speed > 20000) && si->port_speed_max[port] > 20000){ 15696 phy_mode = 0; 15697 } else if (speed > 10000) { 15698 if ((si->port_num_lanes[port] == 1) && (speed == 11000) && 15699 IS_HG_PORT(unit, port)) { 15700 phy_mode = 2; 15701 } else { 15702 phy_mode = 1; 15703 } 15704 } else { 15705 if ((si->port_num_lanes[port] == 2) && (speed == 10000) && 15706 IS_HG_PORT(unit, port)) { 15707 phy_mode = 1; /* Warpcore uses DXGXS 10.5G in HG mode */ 15708 } else if ((si->port_num_lanes[port] == 4) && (speed == 10000)) { 15709 phy_mode = 2; 15710 core_mode = 0; 15711 } else { 15712 phy_mode = 2; 15713 } 15714 } 15715 15716 if (phy_mode == old_phy_mode) { 15717 return BCM_E_NONE; 15718 } 15719 15720 port_list[0] = port; 15721 port_list[1] = -1; 15722 if (core_mode == 1) { /* dual mode */ 15723 si = &SOC_INFO(unit); 15724 phy_port = si->port_l2p_mapping[port]; 15725 port_list[1] = si->port_p2l_mapping[((phy_port - 1) ^ 2) + 1]; 15726 } 15727 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, PHY_PORT_MODEf, phy_mode); 15728 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, CORE_PORT_MODEf, core_mode); 15729 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval)); 15730 15731 /* Retain MAC setting */ 15732 for (i = 0; i < 2; i++) { 15733 if (port_list[i] == -1) { 15734 continue; 15735 } 15736 cur_port = port_list[i]; 15737 15738 /* no need to save speed since speed change trigger this, in addition, 15739 * mac may not be able to tell you exact speed in many cases */ 15740 SOC_IF_ERROR_RETURN 15741 (MAC_DUPLEX_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 15742 &duplex[i])); 15743 SOC_IF_ERROR_RETURN 15744 (MAC_PAUSE_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 15745 &pause_tx[i], &pause_rx[i])); 15746 SOC_IF_ERROR_RETURN 15747 (MAC_PAUSE_ADDR_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 15748 address[i])); 15749 SOC_IF_ERROR_RETURN 15750 (MAC_FRAME_MAX_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 15751 &frame_max[i])); 15752 /* not saving ifg setting */ 15753 SOC_IF_ERROR_RETURN 15754 (MAC_ENCAP_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 15755 &encap[i])); 15756 SOC_IF_ERROR_RETURN 15757 (MAC_LOOPBACK_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 15758 &loopback[i])); 15759 SOC_IF_ERROR_RETURN 15760 (MAC_ENABLE_GET(PORT(unit, cur_port).p_mac, unit, cur_port, 15761 &enable[i])); 15762 } 15763 15764 /* Do XMAC hard reset when phy_mode changed */ 15765 (void)READ_XLPORT_XMAC_CONTROLr(unit, port, &rval); 15766 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1); 15767 (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval); 15768 sal_udelay(10); 15769 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0); 15770 (void)WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval); 15771 15772 for (i = 0; i < 2; i++) { 15773 if (port_list[i] == -1) { 15774 continue; 15775 } 15776 cur_port = port_list[i]; 15777 15778 /* mac init */ 15779 SOC_IF_ERROR_RETURN 15780 (MAC_INIT(PORT(unit, cur_port).p_mac, unit, cur_port)); 15781 15782 /* Restore MAC setting */ 15783 /* no need to save speed since speed change trigger this, in addition, 15784 * mac may not be able to tell you exact speed in many cases */ 15785 /* coverity[uninit_use_in_call] : FALSE */ 15786 SOC_IF_ERROR_RETURN 15787 (MAC_DUPLEX_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 15788 duplex[i])); 15789 /* coverity[uninit_use_in_call] : FALSE */ 15790 SOC_IF_ERROR_RETURN 15791 (MAC_PAUSE_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 15792 pause_tx[i], pause_rx[i])); 15793 SOC_IF_ERROR_RETURN 15794 (MAC_PAUSE_ADDR_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 15795 address[i])); 15796 /* coverity[uninit_use_in_call] : FALSE */ 15797 SOC_IF_ERROR_RETURN 15798 (MAC_FRAME_MAX_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 15799 frame_max[i])); 15800 /* not saving ifg setting */ 15801 /* coverity[uninit_use_in_call] : FALSE */ 15802 SOC_IF_ERROR_RETURN 15803 (MAC_ENCAP_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 15804 encap[i])); 15805 /* coverity[uninit_use_in_call] : FALSE */ 15806 SOC_IF_ERROR_RETURN 15807 (MAC_LOOPBACK_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 15808 loopback[i])); 15809 /* coverity[uninit_use_in_call] : FALSE */ 15810 SOC_IF_ERROR_RETURN 15811 (MAC_ENABLE_SET(PORT(unit, cur_port).p_mac, unit, cur_port, 15812 enable[i])); 15813 } 15814 15815 return BCM_E_NONE; 15816 } 15817 15818 /* 15819 * Function: 15820 * _bcm_port_update 15821 * Purpose: 15822 * Get port characteristics from PHY and program MAC to match. 15823 * Parameters: 15824 * unit - StrataSwitch Unit #. 15825 * port - StrataSwitch port #. 15826 * link - True if link is active, false if link is inactive. 15827 * Returns: 15828 * BCM_E_NONE 15829 * BCM_E_XXX 15830 */ 15831 15832 STATIC int 15833 _bcm_port_update(int unit, bcm_port_t port, int link) 15834 { 15835 int rv; 15836 int duplex, speed, an, an_done; 15837 soc_port_if_t pif; 15838 int cur_mac_speed; 15839 int enable; 15840 #ifdef INCLUDE_MACSEC 15841 int policy = 0; 15842 int duplex_old = 0; 15843 #endif 15844 #ifdef INCLUDE_FCMAP 15845 phy_ctrl_t *pc; 15846 #endif 15847 15848 /* Call Port Control module */ 15849 if (SOC_USE_PORTCTRL(unit)) { 15850 return bcmi_esw_portctrl_update(unit, port, link); 15851 } 15852 if(bcm_common_oamp_port_enable_get(unit, port)) { 15853 LOG_ERROR(BSL_LS_BCM_PORT, 15854 (BSL_META("Error: Not permitted on OAMP port %d.update.\n"), 15855 port)); 15856 return BCM_E_PARAM; 15857 } 15858 15859 if (PORT(unit, port).p_mac == NULL) { 15860 return BCM_E_INIT; 15861 } 15862 15863 if (!link) { 15864 /* PHY is down. Disable the MAC. */ 15865 #ifdef SW_AUTONEG_SUPPORT 15866 rv = _bcm_esw_port_notify_link_down_evt(unit, port); 15867 if (BCM_FAILURE(rv)) { 15868 LOG_WARN(BSL_LS_BCM_PORT, 15869 (BSL_META_U(unit, 15870 "u=%d p=%d NOTIFY LINK DOWN EVT rv=%d\n"), 15871 unit, port, rv)); 15872 return rv; 15873 } 15874 #endif 15875 15876 rv = (MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE)); 15877 if (BCM_FAILURE(rv)) { 15878 LOG_WARN(BSL_LS_BCM_PORT, 15879 (BSL_META_U(unit, 15880 "u=%d p=%d MAC_ENABLE_SET FALSE rv=%d\n"), 15881 unit, port, rv)); 15882 return rv; 15883 } 15884 /* PHY link down event */ 15885 rv = (soc_phyctrl_linkdn_evt(unit, port)); 15886 if (BCM_FAILURE(rv) && (BCM_E_UNAVAIL != rv)) { 15887 LOG_WARN(BSL_LS_BCM_PORT, 15888 (BSL_META_U(unit, 15889 "u=%d p=%d soc_phyctrl_linkdn_evt rv=%d\n"),unit, port, rv)); 15890 return rv; 15891 } 15892 return BCM_E_NONE; 15893 } 15894 15895 /* PHY link up event may not be support by all PHY driver. 15896 * Just ignore it if not supported */ 15897 rv = (soc_phyctrl_linkup_evt(unit, port)); 15898 if (BCM_FAILURE(rv) && (BCM_E_UNAVAIL != rv)) { 15899 LOG_WARN(BSL_LS_BCM_PORT, 15900 (BSL_META_U(unit, 15901 "u=%d p=%d soc_phyctrl_linkup_evt rv=%d\n"),unit, port, rv)); 15902 return rv; 15903 } 15904 15905 if (soc_feature(unit, soc_feature_internal_phy_link_check)) { 15906 int up = 0; 15907 15908 SOC_IF_ERROR_RETURN 15909 (soc_phyctrl_link_get(unit, port, &up)); 15910 15911 /* Wait internal PHY link when external PHY is link up */ 15912 if (up) { 15913 (void)soc_phyctrl_notify(unit, port, phyEventLinkWait, 0); 15914 } 15915 } 15916 15917 /* 15918 * Set MAC speed first, since for GTH ports, this will switch 15919 * between the 1000Mb/s or 10/100Mb/s MACs. 15920 */ 15921 15922 if (!IS_HG_PORT(unit, port) || IS_GX_PORT(unit, port)) { 15923 rv = (soc_phyctrl_speed_get(unit, port, &speed)); 15924 if (BCM_FAILURE(rv) && (BCM_E_UNAVAIL != rv)) { 15925 LOG_WARN(BSL_LS_BCM_PORT, 15926 (BSL_META_U(unit, 15927 "u=%d p=%d phyctrl_speed_get rv=%d\n"),unit, port, rv)); 15928 return rv; 15929 } 15930 if (IS_HG_PORT(unit, port) && speed < 5000) { 15931 speed = 0; 15932 } 15933 LOG_INFO(BSL_LS_BCM_PORT, 15934 (BSL_META_U(unit, 15935 "u=%d p=%d phyctrl_speed_get speed=%d\n"),unit, port, speed)); 15936 15937 if (BCM_E_UNAVAIL == rv ) { 15938 /* If PHY driver doesn't support speed_get, don't change 15939 * MAC speed. E.g, Null PHY driver 15940 */ 15941 rv = BCM_E_NONE; 15942 } else { 15943 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 15944 BCM_IF_ERROR_RETURN 15945 (_bcm_td_port_mode_update(unit, port, speed)); 15946 } 15947 #ifdef INCLUDE_FCMAP 15948 /* FOR MONTREAL-1 ONLY 15949 * 15950 * In FCMAP mode, the port is operating in FC-Mode. The switch and the 15951 * system side of the PHY operates in 10G, FullDuplex and Pause enabled 15952 * mode 15953 * For MT1, the phy max speed will always be 10G (never 25G which MT2 supports) 15954 */ 15955 if (soc_property_port_get(unit, port, spn_FCMAP_ENABLE, 0)) { 15956 15957 pc = EXT_PHY_SW_STATE(unit, port); 15958 15959 if ((pc != NULL) && !PHY_IS_BCM8806X(pc)) { 15960 speed = 10000; 15961 } 15962 LOG_WARN(BSL_LS_BCM_PORT, 15963 (BSL_META_U(unit, 15964 "u=%d p=%d speed_max=%d speed=%d\n"),unit, port, 15965 pc->speed_max, speed)); 15966 } 15967 #endif 15968 rv = (MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, &cur_mac_speed)); 15969 if (BCM_FAILURE(rv)) { 15970 LOG_WARN(BSL_LS_BCM_PORT, 15971 (BSL_META_U(unit, 15972 "u=%d p=%d MAC_SPEED_GET rv=%d\n"),unit, port, rv)); 15973 return rv; 15974 } 15975 15976 rv = (MAC_ENABLE_GET(PORT(unit, port).p_mac, unit, port, &enable)); 15977 if (BCM_FAILURE(rv)) { 15978 LOG_WARN(BSL_LS_BCM_PORT, 15979 (BSL_META_U(unit, 15980 "u=%d p=%d MAC_ENABLE_GET rv=%d\n"),unit, port, rv)); 15981 return rv; 15982 } 15983 15984 /* If current MAC speed is the same as PHY speed, no need set it again */ 15985 if (cur_mac_speed != speed || enable != TRUE) { 15986 rv = (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, speed)); 15987 } 15988 } 15989 if (BCM_FAILURE(rv)) { 15990 LOG_WARN(BSL_LS_BCM_PORT, 15991 (BSL_META_U(unit, 15992 "u=%d p=%d MAC_SPEED_SET speed=%d rv=%d\n"), 15993 unit, port, speed, rv)); 15994 return rv; 15995 } 15996 15997 rv = (soc_phyctrl_duplex_get(unit, port, &duplex)); 15998 if (BCM_FAILURE(rv)) { 15999 LOG_WARN(BSL_LS_BCM_PORT, 16000 (BSL_META_U(unit, 16001 "u=%d p=%d phyctrl_duplex_get rv=%d\n"), 16002 unit, port, rv)); 16003 return rv; 16004 } 16005 16006 #ifdef INCLUDE_MACSEC 16007 /* When macsec is enabled, the switch and system side of the PHY 16008 * operate in full-duplex mode. 16009 */ 16010 duplex_old = duplex; 16011 if ( soc_property_port_get(unit, port, spn_MACSEC_ENABLE, 0) ) { 16012 duplex = 1; 16013 } 16014 16015 policy = soc_property_port_get(unit, port, spn_MACSEC_SWITCH_SIDE_POLICY, 1); 16016 if ( (policy == 2) && (! duplex_old) ) { 16017 /* if line-side linked up at half-duplex under Duplex Gateway mode */ 16018 duplex = 1; /* force to full-duplex */ 16019 } 16020 #endif 16021 16022 #ifdef INCLUDE_FCMAP 16023 /* 16024 * In FCMAP mode, the port is operating in FC-Mode. The switch and the 16025 * system side of the PHY operates in 10G, FullDuplex and Pause enabled 16026 * mode 16027 */ 16028 if (soc_property_port_get(unit, port, spn_FCMAP_ENABLE, 0)) { 16029 duplex = 1; 16030 } 16031 #endif 16032 rv = (MAC_DUPLEX_SET(PORT(unit, port).p_mac, unit, port, duplex)); 16033 if (BCM_FAILURE(rv)) { 16034 LOG_WARN(BSL_LS_BCM_PORT, 16035 (BSL_META_U(unit, 16036 "u=%d p=%d MAC_DUPLEX_SET %s sp=%d rv=%d\n"), 16037 unit, port, 16038 duplex ? "FULL" : "HALF", speed, rv)); 16039 return rv; 16040 } 16041 } else { 16042 16043 duplex = 1; 16044 } 16045 16046 rv = (soc_phyctrl_interface_get(unit, port, &pif)); 16047 if (BCM_FAILURE(rv)) { 16048 LOG_WARN(BSL_LS_BCM_PORT, 16049 (BSL_META_U(unit, 16050 "u=%d p=%d phyctrl_interface_get rv=%d\n"), 16051 unit, port, rv)); 16052 return rv; 16053 } 16054 rv = (MAC_INTERFACE_SET(PORT(unit, port).p_mac, unit, port, pif)); 16055 if (BCM_FAILURE(rv)) { 16056 LOG_WARN(BSL_LS_BCM_PORT, 16057 (BSL_META_U(unit, 16058 "u=%d p=%d MAC_INTERFACE_GET rv=%d\n"), 16059 unit, port,rv)); 16060 return rv; 16061 } 16062 16063 SOC_IF_ERROR_RETURN 16064 (soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done)); 16065 16066 /* 16067 * If autonegotiating, check the negotiated PAUSE values, and program 16068 * MACs accordingly. Link can also be achieved thru parallel detect. 16069 * In this case, it should be treated as in the forced mode. 16070 */ 16071 if (an && an_done) { 16072 bcm_port_ability_t remote_advert, local_advert; 16073 int tx_pause, rx_pause; 16074 16075 sal_memset(&local_advert, 0, sizeof(bcm_port_ability_t)); 16076 sal_memset(&remote_advert, 0, sizeof(bcm_port_ability_t)); 16077 16078 rv = soc_phyctrl_ability_advert_get(unit, port, &local_advert); 16079 if (BCM_FAILURE(rv)) { 16080 LOG_WARN(BSL_LS_BCM_PORT, 16081 (BSL_META_U(unit, 16082 "u=%d p=%d soc_phyctrl_adv_local_get rv=%d\n"), 16083 unit, port, rv)); 16084 return rv; 16085 } 16086 rv = soc_phyctrl_ability_remote_get(unit, port, &remote_advert); 16087 if (BCM_FAILURE(rv)) { 16088 LOG_WARN(BSL_LS_BCM_PORT, 16089 (BSL_META_U(unit, 16090 "u=%d p=%d soc_phyctrl_adv_remote_get rv=%d\n"), 16091 unit, port, rv)); 16092 return rv; 16093 } 16094 16095 /* 16096 * IEEE 802.3 Flow Control Resolution. 16097 * Please see $SDK/doc/pause-resolution.txt for more information. 16098 */ 16099 16100 if (duplex) { 16101 tx_pause = 16102 ((remote_advert.pause & SOC_PA_PAUSE_RX) && 16103 (local_advert.pause & SOC_PA_PAUSE_RX)) || 16104 ((remote_advert.pause & SOC_PA_PAUSE_RX) && 16105 !(remote_advert.pause & SOC_PA_PAUSE_TX) && 16106 (local_advert.pause & SOC_PA_PAUSE_TX)); 16107 16108 rx_pause = 16109 ((remote_advert.pause & SOC_PA_PAUSE_RX) && 16110 (local_advert.pause & SOC_PA_PAUSE_RX)) || 16111 ((local_advert.pause & SOC_PA_PAUSE_RX) && 16112 (remote_advert.pause & SOC_PA_PAUSE_TX) && 16113 !(local_advert.pause & SOC_PA_PAUSE_TX)); 16114 } else { 16115 rx_pause = tx_pause = 0; 16116 } 16117 #ifdef INCLUDE_MACSEC 16118 if ( (policy == 2) && (! duplex_old) ) { 16119 /* if line-side linked up at half-duplex under Duplex Gateway mode */ 16120 rx_pause = 1; /* turn on flow control Rx pause frames */ 16121 } 16122 #endif 16123 rv = (MAC_PAUSE_SET(PORT(unit, port).p_mac, 16124 unit, port, tx_pause, rx_pause)); 16125 if (BCM_FAILURE(rv)) { 16126 LOG_WARN(BSL_LS_BCM_PORT, 16127 (BSL_META_U(unit, 16128 "u=%d p=%d MAC_PAUSE_SET rv=%d\n"), 16129 unit, port, rv)); 16130 return rv; 16131 } 16132 } 16133 16134 #ifdef INCLUDE_MACSEC 16135 { 16136 /* 16137 * In MACSEC based PHYs the switch side could be operating with 16138 * different speed,duplex and pause compared to line speed, duplex and 16139 * pause settings. The above setting will be overridden if the switch side 16140 * of the PHY is set to operate in fixed mode 16141 */ 16142 uint32 value; 16143 rv = (soc_phyctrl_control_get(unit, port, 16144 BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED, 16145 &value)); 16146 16147 if (BCM_E_UNAVAIL != rv) { /* Switch fixed speed is supported */ 16148 16149 if (value == 1) { 16150 /* Get and Set Speed */ 16151 rv = (soc_phyctrl_control_get(unit, port, 16152 BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED_SPEED, 16153 &value)); 16154 if (BCM_FAILURE(rv)) { 16155 LOG_WARN(BSL_LS_BCM_PORT, 16156 (BSL_META_U(unit, 16157 "u=%d p=%d phyctrl_control_get(speed) rv=%d\n"), 16158 unit, port, rv)); 16159 return rv; 16160 } 16161 16162 rv = (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, value)); 16163 if (BCM_FAILURE(rv)) { 16164 LOG_WARN(BSL_LS_BCM_PORT, 16165 (BSL_META_U(unit, 16166 "u=%d p=%d MAC_SPEED_SET speed=%d rv=%d\n"), 16167 unit, port, value, rv)); 16168 return rv; 16169 } 16170 16171 /* Get and Set Duplex */ 16172 rv = (soc_phyctrl_control_get(unit, port, 16173 BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED_DUPLEX, 16174 &value)); 16175 if (BCM_FAILURE(rv)) { 16176 LOG_WARN(BSL_LS_BCM_PORT, 16177 (BSL_META_U(unit, 16178 "u=%d p=%d phyctrl_control_get(duplex) rv=%d\n"), 16179 unit, port, rv)); 16180 return rv; 16181 } 16182 rv = (MAC_DUPLEX_SET(PORT(unit, port).p_mac, unit, port, value)); 16183 if (BCM_FAILURE(rv)) { 16184 LOG_WARN(BSL_LS_BCM_PORT, 16185 (BSL_META_U(unit, 16186 "u=%d p=%d MAC_DUPLEX_SET %s sp=%d rv=%d\n"), 16187 unit, port, 16188 value ? "FULL" : "HALF", value, rv)); 16189 return rv; 16190 } 16191 16192 /* Get and Set PAUSE */ 16193 rv = (soc_phyctrl_control_get(unit, port, 16194 BCM_PORT_PHY_CONTROL_MACSEC_SWITCH_FIXED_PAUSE, 16195 &value)); 16196 if (BCM_FAILURE(rv)) { 16197 LOG_WARN(BSL_LS_BCM_PORT, 16198 (BSL_META_U(unit, 16199 "u=%d p=%d phyctrl_control_get(Pause) rv=%d\n"), 16200 unit, port, rv)); 16201 return rv; 16202 } 16203 if (value == 1) { 16204 /* 16205 * Flow control domain is between switch MAC and PHY MAC. 16206 * If the flow control domain is not between switch and PHY's 16207 * switch MAC, then the flow control domain is extended to that 16208 * of GPHY. 16209 */ 16210 rv = (MAC_PAUSE_SET(PORT(unit, port).p_mac, 16211 unit, port, value, value)); 16212 if (BCM_FAILURE(rv)) { 16213 LOG_WARN(BSL_LS_BCM_PORT, 16214 (BSL_META_U(unit, 16215 "u=%d p=%d MAC_PAUSE_SET rv=%d\n"), 16216 unit, port, rv)); 16217 return rv; 16218 } 16219 } 16220 16221 } 16222 } 16223 } 16224 #endif 16225 16226 /* Enable the MAC. */ 16227 rv = (MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE)); 16228 if (BCM_FAILURE(rv)) { 16229 LOG_WARN(BSL_LS_BCM_PORT, 16230 (BSL_META_U(unit, 16231 "u=%d p=%d MAC_ENABLE_SET TRUE rv=%d\n"), 16232 unit, port, rv)); 16233 return rv; 16234 } 16235 16236 #ifdef BCM_BRADLEY_SUPPORT 16237 /* When a link comes up, hardware will not update the 16238 * LINK_STATUS register until software has toggled the 16239 * the LAG_FAILOVER_CONFIG.LINK_STATUS_UP field. 16240 * When a link goes down, hardware will update the 16241 * LINK_STATUS register without software intervention. 16242 */ 16243 if ((SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr) && 16244 IS_GX_PORT(unit, port)) || 16245 (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) || 16246 (SOC_REG_IS_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr) && 16247 (IS_XL_PORT(unit, port) || IS_MXQ_PORT(unit, port) )) || 16248 (SOC_REG_IS_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr) && 16249 IS_CL_PORT(unit, port))) { 16250 soc_reg_t reg; 16251 uint32 rval; 16252 16253 if (SOC_IS_SABER2(unit) && SOC_REG_PORT_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr, port)) { 16254 reg = XLPORT_LAG_FAILOVER_CONFIGr; 16255 } else if (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) { 16256 reg = LAG_FAILOVER_CONFIGr; 16257 } else if (SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr)) { 16258 reg = GXPORT_LAG_FAILOVER_CONFIGr; 16259 } else if (SOC_REG_PORT_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr, port) && 16260 (SOC_IS_TOMAHAWKX(unit) || IS_CL_PORT(unit, port))) { 16261 reg = CLPORT_LAG_FAILOVER_CONFIGr; 16262 } else { 16263 reg = XLPORT_LAG_FAILOVER_CONFIGr; 16264 } 16265 16266 /* Toggle link bit to notify IPIPE on link up */ 16267 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 16268 soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 1); 16269 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 16270 soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 0); 16271 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 16272 } 16273 #endif /* BCM_BRADLEY_SUPPORT */ 16274 16275 return BCM_E_NONE; 16276 } 16277 16278 16279 16280 /* 16281 * Function: 16282 * bcm_port_update 16283 * Purpose: 16284 * Get port characteristics from PHY and program MAC to match. 16285 * Parameters: 16286 * unit - StrataSwitch Unit #. 16287 * port - StrataSwitch port #. 16288 * link - TRUE - process as link up. 16289 * FALSE - process as link down. 16290 * Returns: 16291 * BCM_E_NONE 16292 * BCM_E_XXX 16293 */ 16294 16295 int 16296 bcm_esw_port_update(int unit, bcm_port_t port, int link) 16297 { 16298 int rv = BCM_E_NONE; 16299 #if defined(BCM_KATANA2_SUPPORT) 16300 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 16301 #endif 16302 16303 /* Make sure port module is initialized. */ 16304 PORT_INIT(unit); 16305 16306 #if defined(BCM_KATANA2_SUPPORT) 16307 #if defined(BCM_SABER2_SUPPORT) 16308 if(SOC_IS_SABER2(unit)) { 16309 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 16310 } 16311 #endif 16312 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 16313 (!((port >= 1) && (port <= max_phy_port)))) { 16314 return BCM_E_PORT; 16315 } 16316 #endif 16317 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 16318 16319 #if defined(BCM_RCPU_SUPPORT) 16320 if (SOC_IS_RCPU_ONLY(unit) && link) { 16321 /* Can not do this unless real phy driver is used for RCPU device. */ 16322 return BCM_E_NONE; 16323 } 16324 #endif /* BCM_RCPU_SUPPORT */ 16325 PORT_LOCK(unit); 16326 rv = _bcm_port_update(unit, port, link); 16327 if (BCM_FAILURE(rv)) { 16328 PORT_UNLOCK(unit); 16329 return (rv); 16330 } 16331 #if defined(BCM_BRADLEY_SUPPORT) 16332 if (SOC_IS_HBX(unit) && !SOC_IS_SHADOW(unit)) { 16333 rv = _bcm_port_mmu_update(unit, port, link); 16334 } 16335 #endif /* BCM_BRADLEY_SUPPORT */ 16336 16337 #if defined(BCM_KATANA2_SUPPORT) 16338 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 16339 rv = soc_katana2_mmu_port_enable_set(unit, port, link); 16340 } 16341 #endif 16342 16343 PORT_UNLOCK(unit); 16344 16345 LOG_INFO(BSL_LS_BCM_PORT, 16346 (BSL_META_U(unit, 16347 "bcm_port_update: u=%d p=%d link=%d rv=%d\n"), 16348 unit, port, link, rv)); 16349 16350 return(rv); 16351 } 16352 16353 /* 16354 * Function: 16355 * bcm_port_stp_set 16356 * Purpose: 16357 * Set the spanning tree state for a port. 16358 * All STGs containing all VLANs containing the port are updated. 16359 * Parameters: 16360 * unit - StrataSwitch unit number. 16361 * port - StrataSwitch port number. 16362 * stp_state - State to place port in, one of BCM_PORT_STP_xxx. 16363 * Returns: 16364 * BCM_E_NONE 16365 * BCM_E_INTERNAL 16366 * Notes: 16367 * BCM_LOCK is taken so that the current list of VLANs 16368 * can't change during the operation. 16369 */ 16370 16371 int 16372 bcm_esw_port_stp_set(int unit, bcm_port_t port, int stp_state) 16373 { 16374 bcm_stg_t *list = NULL; 16375 int count = 0, i; 16376 int rv = BCM_E_NONE; 16377 16378 /* Make sure port module is initialized. */ 16379 PORT_INIT(unit); 16380 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 16381 16382 #ifdef BCM_RCPU_SUPPORT 16383 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port) && 16384 !(stp_state == BCM_STG_STP_FORWARD)) { 16385 return BCM_E_PORT; 16386 } 16387 #endif /* BCM_RCPU_SUPPORT */ 16388 16389 BCM_LOCK(unit); 16390 16391 rv = bcm_esw_stg_list(unit, &list, &count); 16392 16393 if (rv == BCM_E_UNAVAIL) { 16394 if (stp_state == BCM_STG_STP_FORWARD) { 16395 rv = BCM_E_NONE; 16396 } else { 16397 rv = BCM_E_PARAM; 16398 } 16399 } else if (BCM_SUCCESS(rv)) { 16400 for (i = 0; i < count; i++) { 16401 if ((rv = bcm_esw_stg_stp_set(unit, list[i], 16402 port, stp_state)) < 0) { 16403 break; 16404 } 16405 } 16406 16407 bcm_esw_stg_list_destroy(unit, list, count); 16408 } 16409 16410 BCM_UNLOCK(unit); 16411 16412 LOG_INFO(BSL_LS_BCM_PORT, 16413 (BSL_META_U(unit, 16414 "bcm_port_stp_set: u=%d p=%d state=%d rv=%d\n"), 16415 unit, port, stp_state, rv)); 16416 16417 return rv; 16418 } 16419 16420 /* 16421 * Function: 16422 * bcm_port_stp_get 16423 * Purpose: 16424 * Get the spanning tree state for a port in the default STG. 16425 * Parameters: 16426 * unit - StrataSwitch unit number. 16427 * port - StrataSwitch port number. 16428 * stp_state - Pointer where state stored. 16429 * Returns: 16430 * BCM_E_NONE 16431 * BCM_E_INTERNAL 16432 */ 16433 16434 int 16435 bcm_esw_port_stp_get(int unit, bcm_port_t port, int *stp_state) 16436 { 16437 int stg_defl, rv; 16438 16439 /* Make sure port module is initialized. */ 16440 PORT_INIT(unit); 16441 16442 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 16443 16444 rv = bcm_esw_stg_default_get(unit, &stg_defl); 16445 if (rv >= 0) { 16446 rv = bcm_esw_stg_stp_get(unit, stg_defl, port, stp_state); 16447 } else if (rv == BCM_E_UNAVAIL) { /* FABRIC switches, etc */ 16448 *stp_state = BCM_STG_STP_FORWARD; 16449 rv = BCM_E_NONE; 16450 } 16451 16452 LOG_INFO(BSL_LS_BCM_PORT, 16453 (BSL_META_U(unit, 16454 "bcm_port_stp_get: u=%d p=%d state=%d rv=%d\n"), 16455 unit, port, *stp_state, rv)); 16456 16457 return rv; 16458 } 16459 16460 /* 16461 * Function: 16462 * bcm_port_bpdu_enable_set 16463 * Purpose: 16464 * Enable/Disable BPDU reception on the specified port. 16465 * Parameters: 16466 * unit - SOC unit # 16467 * port - Port number (0 based) 16468 * enable - TRUE to enable, FALSE to disable (reject bpdu). 16469 * Returns: 16470 * BCM_E_NONE 16471 * BCM_E_INTERNAL 16472 */ 16473 16474 int 16475 bcm_esw_port_bpdu_enable_set(int unit, bcm_port_t port, int enable) 16476 { 16477 bcm_port_cfg_t pcfg; 16478 int rv; 16479 16480 /* Make sure port module is initialized. */ 16481 PORT_INIT(unit); 16482 16483 if(bcm_common_oamp_port_enable_get(unit, port)) { 16484 LOG_ERROR(BSL_LS_BCM_PORT, 16485 (BSL_META("Error: Cannot enable pbdu on OAMP Port %d.\n"), 16486 port)); 16487 return BCM_E_PARAM; 16488 } 16489 16490 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 16491 16492 PORT_LOCK(unit); 16493 16494 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 16495 16496 if (BCM_SUCCESS(rv)) { 16497 pcfg.pc_bpdu_disable = !enable; 16498 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg); 16499 } 16500 16501 PORT_UNLOCK(unit); 16502 16503 return rv; 16504 } 16505 16506 /* 16507 * Function: 16508 * bcm_port_bpdu_enable_get 16509 * Purpose: 16510 * Return whether BPDU reception is enabled on the specified port. 16511 * Parameters: 16512 * unit - SOC unit # 16513 * port - Port number (0 based) 16514 * enable - (OUT) TRUE if enabled, FALSE if disabled 16515 * Returns: 16516 * BCM_E_NONE 16517 * BCM_E_INTERNAL 16518 */ 16519 16520 int 16521 bcm_esw_port_bpdu_enable_get(int unit, bcm_port_t port, int *enable) 16522 { 16523 bcm_port_cfg_t pcfg; 16524 int rv; 16525 16526 /* Make sure port module is initialized. */ 16527 PORT_INIT(unit); 16528 16529 if(bcm_common_oamp_port_enable_get(unit, port)) { 16530 LOG_ERROR(BSL_LS_BCM_PORT, 16531 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 16532 port)); 16533 return BCM_E_PARAM; 16534 } 16535 16536 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 16537 16538 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 16539 16540 if (BCM_SUCCESS(rv)) { 16541 *enable = !pcfg.pc_bpdu_disable; 16542 } 16543 16544 return rv; 16545 } 16546 16547 /* 16548 * Function: 16549 * bcm_port_l3_enable_set 16550 * Purpose: 16551 * Enable/Disable L3 switching on the specified port. 16552 * Parameters: 16553 * unit - device number 16554 * port - port number 16555 * enable - TRUE to enable, FALSE to disable. 16556 * Returns: 16557 * BCM_E_XXX 16558 */ 16559 16560 int 16561 bcm_esw_port_l3_enable_set(int unit, bcm_port_t port, int enable) 16562 { 16563 int rv = BCM_E_UNAVAIL; 16564 #if defined(INCLUDE_L3) 16565 bcm_port_cfg_t pcfg; 16566 16567 /* Make sure port module is initialized. */ 16568 PORT_INIT(unit); 16569 16570 if(bcm_common_oamp_port_enable_get(unit, port)) { 16571 LOG_ERROR(BSL_LS_BCM_PORT, 16572 (BSL_META("Error: Cannot enable l3 on OAMP Port %d.\n"), 16573 port)); 16574 return BCM_E_PARAM; 16575 } 16576 16577 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 16578 16579 PORT_LOCK(unit); 16580 16581 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 16582 16583 if (BCM_SUCCESS(rv)) { 16584 if (enable) { 16585 pcfg.pc_l3_flags |= (BCM_PORT_L3_V4_ENABLE | BCM_PORT_L3_V6_ENABLE); 16586 } else { 16587 pcfg.pc_l3_flags &= 16588 ~(BCM_PORT_L3_V4_ENABLE | BCM_PORT_L3_V6_ENABLE); 16589 } 16590 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg); 16591 } 16592 16593 PORT_UNLOCK(unit); 16594 #endif /* INCLUDE_L3 */ 16595 return rv; 16596 } 16597 16598 /* 16599 * Function: 16600 * bcm_port_l3_enable_get 16601 * Purpose: 16602 * Return whether L3 switching is enabled on the specified port. 16603 * Parameters: 16604 * unit - device number 16605 * port - port number 16606 * enable - (OUT) TRUE if enabled, FALSE if disabled 16607 * Returns: 16608 * BCM_E_XXX 16609 */ 16610 16611 int 16612 bcm_esw_port_l3_enable_get(int unit, bcm_port_t port, int *enable) 16613 { 16614 int rv = BCM_E_UNAVAIL; 16615 #if defined(INCLUDE_L3) 16616 bcm_port_cfg_t pcfg; 16617 16618 /* Make sure port module is initialized. */ 16619 PORT_INIT(unit); 16620 16621 if(bcm_common_oamp_port_enable_get(unit, port)) { 16622 LOG_ERROR(BSL_LS_BCM_PORT, 16623 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 16624 port)); 16625 return BCM_E_PARAM; 16626 } 16627 16628 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 16629 16630 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 16631 16632 if (BCM_SUCCESS(rv)) { 16633 *enable = ((pcfg.pc_l3_flags & BCM_PORT_L3_V4_ENABLE) || 16634 (pcfg.pc_l3_flags & BCM_PORT_L3_V6_ENABLE)); 16635 } 16636 #endif /* INCLUDE_L3 */ 16637 16638 return rv; 16639 } 16640 16641 /* 16642 * Function: 16643 * bcm_port_tgid_get 16644 * Purpose: 16645 * Get the trunk group for a given port. 16646 * Parameters: 16647 * unit - SOC unit # 16648 * port - Port number (0 based) 16649 * tid - trunk ID 16650 * psc - trunk selection criterion 16651 * Returns: 16652 * BCM_E_NONE 16653 * BCM_E_INTERNAL 16654 */ 16655 16656 int 16657 bcm_esw_port_tgid_get(int unit, bcm_port_t port, int *tid, int *psc) 16658 { 16659 bcm_port_cfg_t pcfg; 16660 int rv; 16661 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 16662 soc_field_t tgid_fld = TGIDf; 16663 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SRC_TGIDf)) { 16664 tgid_fld = SRC_TGIDf; 16665 } 16666 #endif 16667 16668 /* Make sure port module is initialized. */ 16669 PORT_INIT(unit); 16670 16671 if(bcm_common_oamp_port_enable_get(unit, port)) { 16672 LOG_ERROR(BSL_LS_BCM_PORT, 16673 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 16674 port)); 16675 return BCM_E_PARAM; 16676 } 16677 16678 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 16679 16680 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 16681 if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, tgid_fld)) { 16682 #if defined(BCM_KATANA2_SUPPORT) 16683 if (SOC_IS_KATANA2(unit)) { 16684 rv = _bcm_kt2_trunk_table_read(unit, port, tid); 16685 } else 16686 #endif 16687 { 16688 rv = _bcm_xgs3_trunk_table_read(unit, port, tid); 16689 } 16690 if (BCM_SUCCESS(rv)) { 16691 *psc = 0; 16692 } 16693 return rv; 16694 } 16695 #endif /* BCM_FIREBOLT_SUPPORT */ 16696 16697 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 16698 16699 if (BCM_SUCCESS(rv)) { 16700 *tid = pcfg.pc_tgid; 16701 *psc = 0; 16702 } 16703 16704 return rv; 16705 16706 } 16707 16708 /* 16709 * Function: 16710 * bcm_port_tgid_set 16711 * Purpose: 16712 * Set the trunk group for a given port. 16713 * Parameters: 16714 * unit - SOC unit # 16715 * port - Port number (0 based) 16716 * tid - trunk ID 16717 * psc - trunk selection criterion 16718 * Returns: 16719 * BCM_E_NONE 16720 * BCM_E_INTERNAL 16721 */ 16722 16723 int 16724 bcm_esw_port_tgid_set(int unit, bcm_port_t port, int tid, int psc) 16725 { 16726 bcm_port_cfg_t pcfg; 16727 int rv; 16728 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 16729 soc_field_t tgid_fld = TGIDf; 16730 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, SRC_TGIDf)) { 16731 tgid_fld = SRC_TGIDf; 16732 } 16733 #endif 16734 16735 /* Make sure port module is initialized. */ 16736 PORT_INIT(unit); 16737 16738 if(bcm_common_oamp_port_enable_get(unit, port)) { 16739 LOG_ERROR(BSL_LS_BCM_PORT, 16740 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 16741 port)); 16742 return BCM_E_PARAM; 16743 } 16744 16745 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 16746 16747 #if defined(BCM_FIREBOLT_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 16748 if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, tgid_fld)) { 16749 #if defined(BCM_KATANA2_SUPPORT) 16750 if (SOC_IS_KATANA2(unit)) { 16751 return _bcm_kt2_trunk_table_write(unit, port, tid); 16752 } else 16753 #endif 16754 { 16755 return _bcm_xgs3_trunk_table_write(unit, port, tid); 16756 } 16757 } 16758 #endif /* BCM_FIREBOLT_SUPPORT */ 16759 16760 PORT_LOCK(unit); 16761 16762 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 16763 16764 if (BCM_SUCCESS(rv)) { 16765 if (tid != BCM_TRUNK_INVALID) { 16766 pcfg.pc_tgid = tid; 16767 pcfg.pc_trunk = 1; 16768 } else { 16769 pcfg.pc_tgid = 0; 16770 pcfg.pc_trunk = 0; 16771 } 16772 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg); 16773 } 16774 16775 PORT_UNLOCK(unit); 16776 16777 return rv; 16778 } 16779 16780 /* 16781 * Function: 16782 * _bcm_port_mirror_enable_get (internal) 16783 * Purpose: 16784 * Return whether mirroring is enabled on the specified port. 16785 * Parameters: 16786 * unit - (IN) BCM device number. 16787 * port - (IN) Port number (0 based). 16788 * enable - (OUT) Bitmap of ingress mirror enabled. 16789 * Returns: 16790 * BCM_E_NONE 16791 * BCM_E_INTERNAL 16792 */ 16793 16794 int 16795 _bcm_port_mirror_enable_get(int unit, bcm_port_t port, int *enable) 16796 { 16797 bcm_port_cfg_t pcfg; 16798 int rv; 16799 16800 /* Input parameters check. */ 16801 if (NULL == enable) { 16802 return (BCM_E_PARAM); 16803 } 16804 16805 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 16806 16807 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 16808 16809 if (BCM_SUCCESS(rv)) { 16810 *enable = pcfg.pc_mirror_ing; 16811 } 16812 16813 return rv; 16814 } 16815 16816 /* 16817 * Function: 16818 * _bcm_port_mirror_enable_set (internal) 16819 * Purpose: 16820 * Enable/Disable mirroring for a given port. 16821 * Parameters: 16822 * unit - (IN) BCM unit # 16823 * port - (IN) Port number (0 based) 16824 * enable - (IN) Bitmap of ingress mirror enabled. 16825 * Returns: 16826 * BCM_E_NONE 16827 * BCM_E_INTERNAL 16828 */ 16829 16830 int 16831 _bcm_port_mirror_enable_set(int unit, bcm_port_t port, int enable) 16832 { 16833 bcm_port_cfg_t pcfg; 16834 int rv; 16835 16836 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 16837 16838 PORT_LOCK(unit); 16839 16840 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 16841 16842 if (BCM_SUCCESS(rv)) { 16843 pcfg.pc_mirror_ing = enable; 16844 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg); 16845 } 16846 16847 PORT_UNLOCK(unit); 16848 16849 return rv; 16850 } 16851 16852 #ifdef BCM_TRIUMPH2_SUPPORT 16853 /* 16854 * Function: 16855 * _bcm_port_mirror_egress_true_enable_get (internal) 16856 * Purpose: 16857 * Return whether true egress mirroring is enabled on the 16858 * specified port. 16859 * Parameters: 16860 * unit - (IN) BCM device number. 16861 * port - (IN) Port number (0 based). 16862 * enable - (OUT) Bitmap of true egress mirrors enabled. 16863 * Returns: 16864 * BCM_E_NONE 16865 * BCM_E_INTERNAL 16866 */ 16867 16868 int 16869 _bcm_port_mirror_egress_true_enable_get(int unit, bcm_port_t port, 16870 int *enable) 16871 { 16872 int rv; 16873 16874 /* Input parameters check. */ 16875 if (NULL == enable) { 16876 return (BCM_E_PARAM); 16877 } 16878 16879 #if defined(BCM_TRIUMPH3_SUPPORT) 16880 if (soc_feature(unit, soc_feature_ep_redirect) || 16881 soc_feature(unit, soc_feature_ep_redirect_v2)) { 16882 egr_port_entry_t egr_port_entry; 16883 int ep_redirect_v2 = FALSE; 16884 16885 rv = READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, 16886 &egr_port_entry); 16887 16888 /* Check if this device supports version 2 of redirect, 16889 based on which we will access different fields below */ 16890 ep_redirect_v2 = soc_feature(unit, soc_feature_ep_redirect_v2); 16891 16892 if (BCM_SUCCESS(rv)) { 16893 if (SOC_EPT_REDIRECT_MIRROR == 16894 soc_mem_field32_get(unit, EGR_PORTm, &egr_port_entry, 16895 (ep_redirect_v2 ? ER_REDIR_DEST_TYPEf : 16896 REDIRECTION_TYPEf))) { 16897 *enable = soc_mem_field32_get(unit, EGR_PORTm, 16898 &egr_port_entry, 16899 (ep_redirect_v2 ? ER_REDIR_DESTINATIONf : 16900 REDIRECTION_DESTINATIONf)); 16901 } else { 16902 *enable = 0; 16903 } 16904 } 16905 } else 16906 #endif /* BCM_TRIUMPH3_SUPPORT */ 16907 16908 { 16909 uint64 egr_val64; 16910 16911 rv = READ_EGR_PORT_64r(unit, port, &egr_val64); 16912 if (BCM_SUCCESS(rv)) { 16913 *enable = soc_reg64_field32_get(unit, EGR_PORT_64r, 16914 egr_val64, MIRRORf); 16915 } 16916 } 16917 16918 return rv; 16919 } 16920 16921 /* 16922 * Function: 16923 * _bcm_port_mirror_egress_true_enable_set (internal) 16924 * Purpose: 16925 * Enable/Disable true egress mirroring for a given port. 16926 * Parameters: 16927 * unit - (IN) BCM unit # 16928 * port - (IN) Port number (0 based) 16929 * enable - (IN) Bitmap of true egress mirrors enabled. 16930 * Returns: 16931 * BCM_E_NONE 16932 * BCM_E_INTERNAL 16933 */ 16934 16935 int 16936 _bcm_port_mirror_egress_true_enable_set(int unit, bcm_port_t port, 16937 int enable) 16938 { 16939 int rv = BCM_E_NONE; 16940 16941 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 16942 16943 PORT_LOCK(unit); 16944 16945 #if defined(BCM_TRIUMPH3_SUPPORT) 16946 if (soc_feature(unit, soc_feature_ep_redirect) || 16947 soc_feature(unit, soc_feature_ep_redirect_v2)) { 16948 16949 uint32 egr_port_vals[2]; 16950 soc_field_t egr_port_fields[2]; 16951 16952 /* Based on if the device support version 2 of redirect, 16953 select the appropriate fields */ 16954 if (soc_feature(unit, soc_feature_ep_redirect_v2)) { 16955 egr_port_fields[0] = ER_REDIR_DEST_TYPEf; 16956 egr_port_fields[1] = ER_REDIR_DESTINATIONf; 16957 } else { 16958 egr_port_fields[0] = REDIRECTION_TYPEf; 16959 egr_port_fields[1] = REDIRECTION_DESTINATIONf; 16960 } 16961 16962 egr_port_vals[0] = 16963 (0 != enable) ? SOC_EPT_REDIRECT_MIRROR : SOC_EPT_REDIRECT_NOOP; 16964 egr_port_vals[1] = enable; 16965 16966 /* Egress port table */ 16967 rv = soc_mem_fields32_modify(unit, EGR_PORTm, port, 2, 16968 egr_port_fields, egr_port_vals); 16969 16970 /* If ep-redirect-v2 also set the action, always-redirect vs do-not-redirect */ 16971 if(rv == BCM_E_NONE) { 16972 if (soc_feature(unit, soc_feature_ep_redirect_v2)) { 16973 rv = soc_mem_field32_modify(unit, EGR_PORTm, 16974 port, ER_REDIR_ACTIONf, 16975 (enable ? _BCM_REDIRECT_ALWAYS : _BCM_REDIRECT_NONE)); 16976 } 16977 } 16978 16979 } else 16980 #endif /* BCM_TRIUMPH3_SUPPORT */ 16981 16982 { 16983 rv = soc_reg_field32_modify(unit, EGR_PORT_64r, port, 16984 MIRRORf, enable); 16985 if (BCM_SUCCESS(rv) && IS_HG_PORT(unit, port)) { 16986 rv = soc_reg_field32_modify(unit, IEGR_PORT_64r, port, 16987 MIRRORf, enable); 16988 } 16989 } 16990 16991 PORT_UNLOCK(unit); 16992 return rv; 16993 } 16994 #endif /* BCM_TRIUMPH2_SUPPORT */ 16995 16996 /* 16997 * Function: 16998 * bcm_port_linkscan_get 16999 * Purpose: 17000 * Get the link scan state of the port 17001 * Parameters: 17002 * unit - StrataSwitch Unit #. 17003 * port - StrataSwitch port #. 17004 * linkscan - (OUT) Linkscan value (None, S/W, H/W) 17005 * Returns: 17006 * BCM_E_NONE 17007 * BCM_E_XXX 17008 */ 17009 17010 int 17011 bcm_esw_port_linkscan_get(int unit, bcm_port_t port, int *linkscan) 17012 { 17013 /* Make sure port module is initialized. */ 17014 PORT_INIT(unit); 17015 17016 return bcm_esw_linkscan_mode_get(unit, port, linkscan); 17017 } 17018 17019 /* 17020 * Function: 17021 * bcm_port_linkscan_set 17022 * Purpose: 17023 * Set the linkscan state for a given port 17024 * Parameters: 17025 * unit - StrataSwitch Unit #. 17026 * port - StrataSwitch port #. 17027 * linkscan - Linkscan value (None, S/W, H/W) 17028 * Returns: 17029 * BCM_E_NONE 17030 * BCM_E_XXX 17031 */ 17032 17033 int 17034 bcm_esw_port_linkscan_set(int unit, bcm_port_t port, int linkscan) 17035 { 17036 /* Make sure port module is initialized. */ 17037 PORT_INIT(unit); 17038 17039 if(bcm_common_oamp_port_enable_get(unit, port)) { 17040 LOG_ERROR(BSL_LS_BCM_PORT, 17041 (BSL_META("Error: Cannot enable linkscan on OAMP Port %d.\n"), 17042 port)); 17043 return BCM_E_PARAM; 17044 } 17045 17046 return bcm_esw_linkscan_mode_set(unit, port, linkscan); 17047 } 17048 17049 /* 17050 * Function: 17051 * bcm_port_autoneg_get 17052 * Purpose: 17053 * Get the autonegotiation state of the port 17054 * Parameters: 17055 * unit - StrataSwitch Unit #. 17056 * port - StrataSwitch port #. 17057 * autoneg - (OUT) Boolean value 17058 * Returns: 17059 * BCM_E_NONE 17060 * BCM_E_XXX 17061 */ 17062 17063 int 17064 bcm_esw_port_autoneg_get(int unit, bcm_port_t port, int *autoneg) 17065 { 17066 int done=0, rv=BCM_E_NONE; 17067 int phy_lane = -1; 17068 int phyn = 0, sys_side = 0; 17069 bcm_port_t local_port = -1; 17070 #if defined(BCM_KATANA2_SUPPORT) 17071 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 17072 #endif 17073 17074 /* Make sure port module is initialized. */ 17075 PORT_INIT(unit); 17076 17077 if (SOC_USE_PORTCTRL(unit)) { 17078 return bcmi_esw_portctrl_autoneg_get(unit, port, autoneg); 17079 } 17080 17081 #if defined(BCM_KATANA2_SUPPORT) 17082 #if defined(BCM_SABER2_SUPPORT) 17083 if(SOC_IS_SABER2(unit)) { 17084 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 17085 } 17086 #endif 17087 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 17088 (!((port >= 1) && (port <= max_phy_port)))) { 17089 return BCM_E_PORT; 17090 } 17091 #endif 17092 17093 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port, 17094 &local_port, &phyn, &phy_lane, &sys_side)); 17095 17096 if (local_port == -1) { 17097 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17098 } 17099 17100 PORT_LOCK(unit); 17101 if (local_port == -1) { 17102 rv = soc_phyctrl_auto_negotiate_get(unit, port, autoneg, &done); 17103 } else { 17104 rv = soc_phyctrl_redirect_auto_negotiate_get(unit, local_port, phyn, 17105 phy_lane, sys_side, 17106 autoneg, &done); 17107 } 17108 PORT_UNLOCK(unit); 17109 LOG_INFO(BSL_LS_BCM_PORT, 17110 (BSL_META_U(unit, 17111 "bcm_port_autoneg_get: u=%d p=%d an=%d done=%d rv=%d\n"), 17112 unit, port, *autoneg, done, rv)); 17113 17114 return rv; 17115 } 17116 17117 /* 17118 * Function: 17119 * bcm_port_autoneg_set 17120 * Purpose: 17121 * Set the autonegotiation state for a given port 17122 * Parameters: 17123 * unit - StrataSwitch Unit #. 17124 * port - StrataSwitch port #. 17125 * autoneg - Boolean value 17126 * Returns: 17127 * BCM_E_NONE 17128 * BCM_E_XXX 17129 */ 17130 17131 int 17132 bcm_esw_port_autoneg_set(int unit, bcm_port_t port, int autoneg) 17133 { 17134 int rv=BCM_E_NONE; 17135 int phy_lane = -1; 17136 int phyn = 0, sys_side = 0; 17137 bcm_port_t local_port = -1; 17138 17139 #if defined(BCM_SABER2_SUPPORT) 17140 int phy_status; 17141 #endif 17142 #if defined(BCM_KATANA2_SUPPORT) 17143 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 17144 #endif 17145 17146 /* Make sure port module is initialized. */ 17147 PORT_INIT(unit); 17148 17149 if (SOC_USE_PORTCTRL(unit)) { 17150 return bcmi_esw_portctrl_autoneg_set(unit, port, autoneg); 17151 } 17152 17153 if(bcm_common_oamp_port_enable_get(unit, port)) { 17154 LOG_ERROR(BSL_LS_BCM_PORT, 17155 (BSL_META("Error: Cannot set autoneg on OAMP Port %d.\n"), 17156 port)); 17157 return BCM_E_PARAM; 17158 } 17159 17160 #if defined(BCM_KATANA2_SUPPORT) 17161 #if defined(BCM_SABER2_SUPPORT) 17162 if(SOC_IS_SABER2(unit)) { 17163 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 17164 } 17165 #endif 17166 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 17167 (!((port >= 1) && (port <= max_phy_port)))) { 17168 return BCM_E_PORT; 17169 } 17170 #endif 17171 #ifdef BCM_RCPU_SUPPORT 17172 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 17173 return BCM_E_PORT; 17174 } 17175 #endif /* BCM_RCPU_SUPPORT */ 17176 17177 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port, 17178 &local_port, &phyn, &phy_lane, &sys_side)); 17179 17180 if (local_port == -1) { 17181 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17182 } 17183 17184 PORT_LOCK(unit); 17185 17186 #if defined(BCM_SABER2_SUPPORT) 17187 if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) { 17188 rv = soc_phyctrl_enable_get(unit, port, &phy_status); 17189 if (BCM_FAILURE(rv)) { 17190 PORT_UNLOCK(unit); 17191 return (rv); 17192 } 17193 if(phy_status == TRUE) { 17194 rv = soc_phyctrl_enable_set(unit, port, FALSE); 17195 if (BCM_FAILURE(rv)) { 17196 PORT_UNLOCK(unit); 17197 return (rv); 17198 } 17199 } 17200 } 17201 #endif 17202 17203 #ifdef SW_AUTONEG_SUPPORT 17204 if (soc_feature(unit, soc_feature_sw_autoneg)) { 17205 17206 int an_mode = 0; 17207 17208 an_mode = soc_property_port_get(unit, port, 17209 spn_PHY_AN_C73, an_mode); 17210 17211 /* phy_an_c73 value of 3 indicated MSA AN mode */ 17212 if ((an_mode == SW_AN_MODE_CL73_MSA) || 17213 (an_mode == SW_AN_MODE_MSA_ONLY)) { 17214 if (autoneg) { 17215 rv = bcm_sw_an_port_register(unit, port); 17216 if (rv == BCM_E_NONE) { 17217 PORT_UNLOCK(unit); 17218 return rv; 17219 } else if (rv == BCM_E_PORT) { 17220 /* when an_set is called during the init 17221 * ports wouldn't have been added to SW AN 17222 */ 17223 rv = BCM_E_NONE; 17224 PORT_UNLOCK(unit); 17225 return rv; 17226 } else { 17227 /* add bsl log */ 17228 PORT_UNLOCK(unit); 17229 return rv; 17230 } 17231 17232 } else { 17233 rv = bcm_sw_an_port_unregister(unit, port); 17234 if (rv == BCM_E_NONE) { 17235 PORT_UNLOCK(unit); 17236 return rv; 17237 } else if (rv == BCM_E_PORT) { 17238 /* when an_set is called during the init 17239 * ports wouldn't have been added to SW AN 17240 */ 17241 rv = BCM_E_NONE; 17242 PORT_UNLOCK(unit); 17243 return rv; 17244 } else { 17245 /* add bsl log */ 17246 PORT_UNLOCK(unit); 17247 return rv; 17248 } 17249 } 17250 } 17251 } 17252 #endif 17253 17254 if (local_port == -1) { 17255 rv = soc_phyctrl_auto_negotiate_set(unit, port, autoneg); 17256 } else { 17257 rv = soc_phyctrl_redirect_auto_negotiate_set(unit, local_port, phyn, 17258 phy_lane, sys_side, autoneg); 17259 } 17260 17261 #if defined(BCM_SABER2_SUPPORT) 17262 if(SOC_IS_SABER2(unit) && 17263 IS_XL_PORT(unit, port) && (phy_status == TRUE)) { 17264 /* Enable phy in tsc only if already enabled before config change */ 17265 rv = soc_phyctrl_enable_set(unit, port, TRUE); 17266 if (BCM_FAILURE(rv)) { 17267 PORT_UNLOCK(unit); 17268 return (rv); 17269 } 17270 } 17271 #endif 17272 17273 #if defined(BCM_XMAC_SUPPORT) 17274 if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) || 17275 SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 17276 uint32 vco_disturbed = 0; 17277 phy_ctrl_t *int_pc, *ext_pc; 17278 ext_pc = EXT_PHY_SW_STATE(unit, port); 17279 if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) || 17280 IS_XE_PORT(unit, port)) && (ext_pc == NULL)) { 17281 int_pc = INT_PHY_SW_STATE(unit, port); 17282 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed); 17283 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) { 17284 PORT_UNLOCK(unit); 17285 return rv; 17286 } 17287 if (vco_disturbed) { 17288 rv = _mac_x_reinit(unit, port); 17289 if (BCM_FAILURE(rv)) { 17290 PORT_UNLOCK(unit); 17291 return rv; 17292 } 17293 } 17294 } 17295 } 17296 #endif 17297 PORT_UNLOCK(unit); 17298 17299 LOG_INFO(BSL_LS_BCM_PORT, 17300 (BSL_META_U(unit, 17301 "bcm_port_autoneg_set: u=%d p=%d an=%d rv=%d\n"), 17302 unit, port, autoneg, rv)); 17303 17304 return rv; 17305 } 17306 17307 /* 17308 * Function: 17309 * bcm_port_speed_get 17310 * Purpose: 17311 * Getting the speed of the port 17312 * Parameters: 17313 * unit - StrataSwitch Unit #. 17314 * port - StrataSwitch port #. 17315 * speed - (OUT) Value in megabits/sec (10, 100, etc) 17316 * Returns: 17317 * BCM_E_NONE 17318 * BCM_E_XXX 17319 * Notes: 17320 * If port is in MAC loopback, the speed of the loopback is returned. 17321 */ 17322 17323 int 17324 bcm_esw_port_speed_get(int unit, bcm_port_t port, int *speed) 17325 { 17326 int rv = BCM_E_NONE; 17327 int mac_lb; 17328 int max_speed; 17329 #if defined(BCM_KATANA2_SUPPORT) 17330 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 17331 #endif 17332 17333 /* Make sure port module is initialized. */ 17334 PORT_INIT(unit); 17335 17336 /* Check for PortMod */ 17337 if ((SOC_USE_PORTCTRL(unit)) && (port != CMIC_PORT(unit))) { 17338 return bcmi_esw_portctrl_speed_get(unit, port, speed); 17339 } 17340 17341 #if defined(BCM_KATANA2_SUPPORT) 17342 #if defined(BCM_SABER2_SUPPORT) 17343 if(SOC_IS_SABER2(unit)) { 17344 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 17345 } 17346 #endif 17347 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 17348 (!((port >= 1) && (port <= max_phy_port) && 17349 SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)))) { 17350 return BCM_E_PORT; 17351 } 17352 #endif 17353 17354 if(bcm_common_oamp_port_enable_get(unit, port)) { 17355 LOG_ERROR(BSL_LS_BCM_PORT, 17356 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 17357 port)); 17358 return BCM_E_PARAM; 17359 } 17360 17361 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17362 17363 PORT_LOCK(unit); 17364 17365 rv = MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb); 17366 17367 if (BCM_SUCCESS(rv)) { 17368 if (mac_lb) { 17369 rv = MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, speed); 17370 } else { 17371 rv = soc_phyctrl_speed_get(unit, port, speed); 17372 17373 if (BCM_E_UNAVAIL == rv) { 17374 /* PHY driver doesn't support speed_get. Get the speed from 17375 * MAC. 17376 */ 17377 rv = MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, speed); 17378 } 17379 if ((IS_HG_PORT(unit, port) && *speed < 5000) && !(IS_HL_PORT(unit,port))) { 17380 *speed = 0; 17381 } 17382 if (soc_feature(unit, soc_feature_port_encap_speed_max_config)) { 17383 rv = bcm_esw_port_speed_max(unit, port, &max_speed); 17384 if (BCM_FAILURE(rv)) { 17385 PORT_UNLOCK(unit); 17386 return (rv); 17387 } 17388 if (*speed > max_speed) { 17389 *speed = max_speed; 17390 } 17391 } 17392 } 17393 } 17394 17395 PORT_UNLOCK(unit); 17396 17397 LOG_INFO(BSL_LS_BCM_PORT, 17398 (BSL_META_U(unit, 17399 "bcm_port_speed_get: u=%d p=%d speed=%d rv=%d\n"), 17400 unit, port, BCM_SUCCESS(rv) ? *speed : 0, rv)); 17401 17402 return rv; 17403 } 17404 17405 /* 17406 * Function: 17407 * bcm_port_speed_max 17408 * Purpose: 17409 * Getting the maximum speed of the port 17410 * Parameters: 17411 * unit - StrataSwitch Unit #. 17412 * port - StrataSwitch port #. 17413 * speed - (OUT) Value in megabits/sec (10, 100, etc) 17414 * Returns: 17415 * BCM_E_NONE 17416 * BCM_E_XXX 17417 */ 17418 17419 int 17420 bcm_esw_port_speed_max(int unit, bcm_port_t port, int *speed) 17421 { 17422 bcm_port_ability_t ability, phy_ability; 17423 int rv; 17424 int phy_speed; 17425 #if defined(BCM_KATANA2_SUPPORT) 17426 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 17427 #endif 17428 17429 if (NULL == speed) { 17430 return (BCM_E_PARAM); 17431 } 17432 17433 /* Make sure port module is initialized. */ 17434 PORT_INIT(unit); 17435 17436 17437 /* Check for PortMod */ 17438 if (SOC_USE_PORTCTRL(unit)) { 17439 return bcmi_esw_portctrl_speed_max(unit, port, speed); 17440 } 17441 17442 #if defined(BCM_KATANA2_SUPPORT) 17443 #if defined(BCM_SABER2_SUPPORT) 17444 if(SOC_IS_SABER2(unit)) { 17445 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 17446 } 17447 #endif 17448 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 17449 (!((port >= 1) && (port <= max_phy_port)))) { 17450 return BCM_E_PORT; 17451 } 17452 #endif 17453 17454 if(bcm_common_oamp_port_enable_get(unit, port)) { 17455 LOG_ERROR(BSL_LS_BCM_PORT, 17456 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 17457 port)); 17458 return BCM_E_PARAM; 17459 } 17460 17461 17462 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17463 rv = bcm_esw_port_ability_local_get(unit, port, &ability); 17464 17465 if (BCM_SUCCESS(rv)) { 17466 17467 *speed = BCM_PORT_ABILITY_SPEED_MAX(ability.speed_full_duplex | 17468 ability.speed_half_duplex); 17469 17470 if (10000 == *speed) { 17471 if (IS_HG_PORT(unit, port) && SOC_INFO(unit).port_speed_max[port]) { 17472 *speed = SOC_INFO(unit).port_speed_max[port]; 17473 /* Retrieving the internal PHY ability */ 17474 rv = soc_phyctrl_ability_local_get(unit, port, &phy_ability); 17475 if (BCM_SUCCESS(rv)) { 17476 /* considering the common supported speed among phy and mac */ 17477 phy_speed = BCM_PORT_ABILITY_SPEED_MAX( 17478 phy_ability.speed_full_duplex | 17479 phy_ability.speed_half_duplex); 17480 *speed = (*speed > phy_speed) ? phy_speed : *speed; 17481 } else { 17482 *speed = 0; 17483 } 17484 } 17485 } 17486 } else { 17487 *speed = 0; 17488 } 17489 17490 LOG_INFO(BSL_LS_BCM_PORT, 17491 (BSL_META_U(unit, 17492 "bcm_port_speed_max: u=%d p=%d speed=%d rv=%d\n"), 17493 unit, port, *speed, rv)); 17494 17495 return rv; 17496 } 17497 17498 /* 17499 * Function : _bcm_port_speed_supported 17500 * Description : Determine whether port speed is supported based on 17501 * number of lanes configured 17502 * Parameters : unit (IN) 17503 * port (IN) 17504 * speed (IN) 17505 * Returns : BCM_E_XXX 17506 * Note : Caller needs to ensure soc_feature_flexport_based_speed_set 17507 * is defined 17508 */ 17509 STATIC bcm_error_t 17510 _bcm_port_speed_supported(int unit, bcm_port_t port, int speed) 17511 { 17512 #ifdef BCM_TOMAHAWK_SUPPORT 17513 if (SOC_IS_TOMAHAWKX(unit)) { 17514 BCM_IF_ERROR_RETURN(_bcm_th_port_speed_supported(unit, port, speed)); 17515 } 17516 #endif 17517 return BCM_E_NONE; 17518 } 17519 17520 /* 17521 * Function: 17522 * _bcm_port_speed_set 17523 * Purpose: 17524 * Main part of bcm_port_speed_set. 17525 */ 17526 17527 STATIC int 17528 _bcm_port_speed_set(int unit, bcm_port_t port, int speed) 17529 { 17530 int phy_lb, rv, enable; 17531 int mac_lb; 17532 int ignore_ability_check = FALSE; 17533 bcm_port_ability_t mac_ability, phy_ability, requested_ability; 17534 #if defined(BCM_SABER2_SUPPORT) 17535 int phy_status; 17536 #endif 17537 17538 #if defined(BCM_TOMAHAWK_SUPPORT) 17539 int cur_speed; 17540 #endif 17541 #if defined(BCM_KATANA2_SUPPORT) 17542 bcmMxqPhyPortMode_t phy_mode = bcmMxqPhyPortModeQuad; 17543 #endif 17544 17545 17546 if (SOC_USE_PORTCTRL(unit)) { 17547 return bcmi_esw_portctrl_speed_set(unit, port, speed); 17548 } 17549 17550 if(bcm_common_oamp_port_enable_get(unit, port)) { 17551 LOG_ERROR(BSL_LS_BCM_PORT, 17552 (BSL_META("Error: Cannot set speed on OAMP Port %d.\n"), 17553 port)); 17554 return BCM_E_PARAM; 17555 } 17556 17557 sal_memset(&mac_ability, 0, sizeof(bcm_port_ability_t)); 17558 sal_memset(&phy_ability, 0, sizeof(bcm_port_ability_t)); 17559 sal_memset(&requested_ability, 0, sizeof(bcm_port_ability_t)); 17560 17561 /* 17562 * If port is in MAC loopback mode, do not try setting the PHY 17563 * speed. This allows MAC loopback at 10/100 even if the PHY is 17564 * 1000 only. Loopback diagnostic tests should enable loopback 17565 * before setting the speed, and vice versa when cleaning up. 17566 */ 17567 17568 SOC_IF_ERROR_RETURN 17569 (MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb)); 17570 17571 if (speed == 0) { 17572 /* if speed is 0, set the port speed to max */ 17573 SOC_IF_ERROR_RETURN 17574 (bcm_esw_port_speed_max(unit, port, &speed)); 17575 } 17576 17577 /* Make sure MAC can handle the requested speed. */ 17578 SOC_IF_ERROR_RETURN 17579 (MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit, port, 17580 &mac_ability)); 17581 requested_ability.speed_full_duplex = SOC_PA_SPEED(speed); 17582 requested_ability.speed_half_duplex = SOC_PA_SPEED(speed); 17583 LOG_INFO(BSL_LS_BCM_PHY, 17584 (BSL_META_U(unit, 17585 "_bcm_port_speed_set: u=%u p=%d " 17586 "MAC FD speed %08X MAC HD speed %08X " 17587 "Requested FD Speed %08X Requested HD Speed %08X\n"), 17588 unit, 17589 port, 17590 mac_ability.speed_full_duplex, 17591 mac_ability.speed_half_duplex, 17592 requested_ability.speed_full_duplex, 17593 requested_ability.speed_half_duplex)); 17594 /* 17595 * On certain devices such as TH speed set is a flexport operation, 17596 * due to changes needed to the calendar. This is not applicable to 17597 * mgmt ports on TH as they are guranteed a fixed amount of BW in the 17598 * calendar. 17599 */ 17600 if ((soc_feature(unit, soc_feature_flexport_based_speed_set)) && 17601 !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port)) { 17602 rv = _bcm_port_speed_supported(unit, port, speed); 17603 if (BCM_SUCCESS(rv)) { 17604 ignore_ability_check = TRUE; 17605 } 17606 } 17607 17608 #if defined(BCM_TOMAHAWK_SUPPORT) 17609 if (SOC_IS_TOMAHAWK(unit)) { 17610 int encap; 17611 BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, port, &encap)); 17612 17613 if (IS_HG2_SPEED(speed) && (encap == BCM_PORT_ENCAP_IEEE)) { 17614 LOG_ERROR(BSL_LS_BCM_PORT, 17615 (BSL_META_U(unit, 17616 "Speed and encapsulation configuration unmatch " 17617 "for port=%d, speed=%d, encap=%d\n"), 17618 port, speed, encap)); 17619 return BCM_E_CONFIG; 17620 } 17621 } 17622 #endif 17623 17624 if (((mac_ability.speed_full_duplex & 17625 requested_ability.speed_full_duplex) == 0) && 17626 ((mac_ability.speed_half_duplex & 17627 requested_ability.speed_half_duplex) == 0) && 17628 !ignore_ability_check) { 17629 LOG_ERROR(BSL_LS_BCM_PORT, 17630 (BSL_META_U(unit, 17631 "u=%d p=%d MAC doesn't support %d Mbps speed.\n"), 17632 unit, port, speed)); 17633 return SOC_E_CONFIG; 17634 } 17635 SOC_IF_ERROR_RETURN 17636 (soc_phyctrl_ability_local_get(unit, port, &phy_ability)); 17637 17638 if (((phy_ability.speed_full_duplex & 17639 requested_ability.speed_full_duplex) == 0) && 17640 ((phy_ability.speed_half_duplex & 17641 requested_ability.speed_half_duplex) == 0) && 17642 !ignore_ability_check) { 17643 LOG_VERBOSE(BSL_LS_BCM_PORT, 17644 (BSL_META_U(unit, 17645 "u=%d p=%d PHY doesn't support %d Mbps speed.\n"), 17646 unit, port, speed)); 17647 return SOC_E_CONFIG; 17648 } else { 17649 17650 #if defined(BCM_SABER2_SUPPORT) 17651 if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) { 17652 BCM_IF_ERROR_RETURN(soc_phyctrl_enable_get(unit, port, &phy_status)); 17653 if(phy_status == TRUE) { 17654 BCM_IF_ERROR_RETURN(soc_phyctrl_enable_set(unit, port, FALSE)); 17655 } 17656 } 17657 #endif 17658 17659 #if defined(BCM_TOMAHAWK_SUPPORT) 17660 if (SOC_IS_TOMAHAWKX(unit)) { 17661 SOC_IF_ERROR_RETURN 17662 (soc_phyctrl_speed_get(unit, port, &cur_speed)); 17663 } 17664 #endif 17665 #if defined(BCM_KATANA2_SUPPORT) 17666 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 17667 SOC_IF_ERROR_RETURN 17668 (soc_katana2_get_phy_port_mode(unit, port, speed, &phy_mode)); 17669 } 17670 #endif 17671 SOC_IF_ERROR_RETURN 17672 (soc_phyctrl_auto_negotiate_set(unit, port, FALSE)); 17673 SOC_IF_ERROR_RETURN 17674 (soc_phyctrl_speed_set(unit, port, speed)); 17675 17676 #if defined(BCM_SABER2_SUPPORT) 17677 if(SOC_IS_SABER2(unit) && 17678 IS_XL_PORT(unit, port) && (phy_status == TRUE)) { 17679 /* Enable phy in tsc only if already enabled before config change */ 17680 BCM_IF_ERROR_RETURN(soc_phyctrl_enable_set(unit, port, TRUE)); 17681 } 17682 #endif 17683 17684 #if defined(BCM_XMAC_SUPPORT) 17685 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) || 17686 SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 17687 uint32 vco_disturbed = 0; 17688 phy_ctrl_t *int_pc, *ext_pc; 17689 ext_pc = EXT_PHY_SW_STATE(unit, port); 17690 if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) || 17691 IS_XE_PORT(unit, port)) && (ext_pc == NULL)) { 17692 17693 int_pc = INT_PHY_SW_STATE(unit, port); 17694 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed); 17695 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) { 17696 return rv; 17697 } 17698 if (vco_disturbed) { 17699 BCM_IF_ERROR_RETURN(_mac_x_reinit(unit, port)); 17700 } 17701 } 17702 } 17703 #endif 17704 } 17705 17706 /* TSC needs no legacy war */ 17707 if (!SOC_IS_TD2_TT2(unit)) { 17708 /* Prevent PHY register access while resetting BigMAC and Fusion core */ 17709 if (IS_HG_PORT(unit, port)) { 17710 soc_phyctrl_enable_get(unit, port, &enable); 17711 soc_phyctrl_enable_set(unit, port, 0); 17712 soc_phyctrl_loopback_get(unit, port, &phy_lb); 17713 } 17714 } 17715 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 17716 BCM_IF_ERROR_RETURN(_bcm_td_port_mode_update(unit, port, speed)); 17717 } 17718 17719 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 17720 /* Reconfigure chip(PGW/TDM/IP/EP/MMU) for speed set change */ 17721 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 17722 if (BCM_ESW_PORT_DRV(unit)->resource_speed_set != NULL) { 17723 rv = BCM_ESW_PORT_DRV(unit)->resource_speed_set(unit, port, speed); 17724 if (BCM_FAILURE(rv)) { 17725 LOG_VERBOSE(BSL_LS_BCM_PORT, 17726 (BSL_META_UP(unit, port, 17727 "resource_speed_set failed: %s\n"), 17728 bcm_errmsg(rv))); 17729 return rv; 17730 } 17731 } 17732 } 17733 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT*/ 17734 17735 rv = MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, speed); 17736 if (BCM_FAILURE(rv)) { 17737 #if defined(BCM_TOMAHAWK_SUPPORT) 17738 if (SOC_IS_TOMAHAWKX(unit)) { 17739 /* Restore phy's speed state based on what was read periously */ 17740 SOC_IF_ERROR_RETURN 17741 (soc_phyctrl_speed_set(unit, port, cur_speed)); 17742 } 17743 #endif 17744 17745 LOG_VERBOSE(BSL_LS_BCM_PORT, 17746 (BSL_META_U(unit, 17747 "MAC_SPEED_SET failed: %s\n"), bcm_errmsg(rv))); 17748 } 17749 17750 if (!SOC_IS_MONTEREY(unit)) { 17751 /* TSC needs no legacy war */ 17752 if (!SOC_IS_TD2_TT2(unit)) { 17753 /* Restore PHY register access */ 17754 if (IS_HG_PORT(unit, port)) { 17755 soc_phyctrl_enable_set(unit, port, enable); 17756 soc_phyctrl_loopback_set(unit, port, phy_lb, TRUE); 17757 } 17758 } 17759 } 17760 17761 return rv; 17762 } 17763 17764 /* 17765 * Function: 17766 * bcm_port_speed_set 17767 * Purpose: 17768 * Setting the speed for a given port 17769 * Parameters: 17770 * unit - StrataSwitch Unit #. 17771 * port - StrataSwitch port #. 17772 * speed - Value in megabits/sec (10, 100, etc) 17773 * Returns: 17774 * BCM_E_NONE 17775 * BCM_E_XXX 17776 * Notes: 17777 * Turns off autonegotiation. Caller must make sure other forced 17778 * parameters (such as duplex) are set. 17779 */ 17780 17781 int 17782 bcm_esw_port_speed_set(int unit, bcm_port_t port, int speed) 17783 { 17784 int rv=BCM_E_NONE, max_speed, enable; 17785 pbmp_t pbm; 17786 int curr_speed = 0; 17787 bcm_port_if_t curr_intf = 0; 17788 #if defined(BCM_KATANA2_SUPPORT) 17789 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 17790 #endif 17791 17792 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK) 17793 sal_usecs_t time_start = 0; 17794 sal_usecs_t time_end = 0; 17795 #endif 17796 17797 /* Make sure port module is initialized. */ 17798 PORT_INIT(unit); 17799 17800 #if defined(BCM_TOMAHAWK3_SUPPORT) 17801 /* Don't allow PM8x50 to do bcm_port_speed_set */ 17802 if (SOC_IS_TOMAHAWK3(unit) && IS_CD_PORT(unit, port)) { 17803 return BCM_E_UNAVAIL; 17804 } 17805 #endif 17806 17807 if(bcm_common_oamp_port_enable_get(unit, port)) { 17808 LOG_ERROR(BSL_LS_BCM_PORT, 17809 (BSL_META("Error: Cannot set speed on OAMP Port %d.\n"), 17810 port)); 17811 return BCM_E_PARAM; 17812 } 17813 17814 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK) 17815 time_start = sal_time_usecs(); 17816 #endif 17817 17818 #if defined(BCM_KATANA2_SUPPORT) 17819 #if defined(BCM_SABER2_SUPPORT) 17820 if(SOC_IS_SABER2(unit)) { 17821 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 17822 } 17823 #endif 17824 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 17825 (!((port >= 1) && (port <= max_phy_port)))) { 17826 return BCM_E_PORT; 17827 } 17828 #endif 17829 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17830 17831 if (soc_property_get(unit, spn_SAME_SPEED_INTF_DO_NOT_OVERWRITE, 17832 (SAL_BOOT_BCMSIM || SAL_BOOT_XGSSIM))) { 17833 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &curr_speed)); 17834 BCM_IF_ERROR_RETURN(bcm_esw_port_interface_get(unit, port, &curr_intf)); 17835 if((speed == curr_speed) && (PORT(unit, port).intf == curr_intf)) { 17836 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK) 17837 time_end = SAL_USECS_SUB(sal_time_usecs(), time_start); 17838 LOG_INFO(BSL_LS_BCM_BENCHMARK, 17839 (BSL_META_U(unit, 17840 "\nPort %d speed change to %d processing took %d usecs\n"), 17841 port, 17842 speed, 17843 time_end)); 17844 #endif 17845 return BCM_E_NONE; 17846 } 17847 } 17848 17849 #ifdef BCM_RCPU_SUPPORT 17850 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 17851 return BCM_E_PORT; 17852 } 17853 #endif /* BCM_RCPU_SUPPORT */ 17854 17855 /* coverity[uninit_use_in_call : FALSE] */ 17856 BCM_IF_ERROR_RETURN 17857 (bcm_esw_port_speed_max(unit,port, &max_speed)); 17858 17859 if (IS_XL_PORT(unit,port) && (speed == 12700)) { 17860 speed = 13000; 17861 } 17862 17863 if ((speed < 0) || (speed > max_speed)) { 17864 if ((speed > max_speed) && 17865 !soc_feature(unit, soc_feature_flexport_based_speed_set)) 17866 return BCM_E_CONFIG; 17867 } 17868 17869 #if defined(BCM_TOMAHAWK_SUPPORT) 17870 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit)) { 17871 int cur_speed; 17872 17873 BCM_IF_ERROR_RETURN 17874 (bcm_esw_port_speed_get(unit, port, &cur_speed)); 17875 if ((speed == 0) && (max_speed == cur_speed)) { 17876 /* no speed set is required */ 17877 return BCM_E_NONE; 17878 } 17879 } 17880 #endif /* BCM_TOMAHAWK_SUPPORT */ 17881 17882 /* 17883 * When performing flexport based speed changes, disable port 17884 * first prior to affecting speed change 17885 */ 17886 if (soc_feature(unit, soc_feature_flexport_based_speed_set) && 17887 !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port) && 17888 !SOC_USE_PORTCTRL(unit)) { 17889 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable)); 17890 if (TRUE == enable) { 17891 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, FALSE)); 17892 } 17893 } 17894 17895 PORT_LOCK(unit); /* multiple operations operation */ 17896 17897 rv = _bcm_port_speed_set(unit, port, speed); 17898 PORT_UNLOCK(unit); /* Unlock before link call */ 17899 /* 17900 * Restore port's enable state based on what was read prior 17901 * to setting speed 17902 */ 17903 if (soc_feature(unit, soc_feature_flexport_based_speed_set) && 17904 !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port) && 17905 !SOC_USE_PORTCTRL(unit)) { 17906 if (TRUE == enable) { 17907 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, TRUE)); 17908 } 17909 } 17910 17911 if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) { 17912 SOC_PBMP_CLEAR(pbm); 17913 SOC_PBMP_PORT_ADD(pbm, port); 17914 (void)bcm_esw_link_change(unit, pbm); 17915 } 17916 PORT_LOCK(unit); /* multiple operations operation */ 17917 BCM_IF_ERROR_RETURN(_bcm_esw_port_link_delay_update(unit, port, speed)); 17918 PORT_UNLOCK(unit); /* Unlock before link call */ 17919 17920 #if defined(BCM_PORT_SPEED_CHANGE_BENCHMARK) 17921 time_end = SAL_USECS_SUB(sal_time_usecs(), time_start); 17922 LOG_INFO(BSL_LS_BCM_BENCHMARK, 17923 (BSL_META_U(unit, 17924 "\nPort %d speed change to %d processing took %d usecs\n"), 17925 port, 17926 speed, 17927 time_end)); 17928 #endif 17929 17930 LOG_INFO(BSL_LS_BCM_PORT, 17931 (BSL_META_U(unit, 17932 "bcm_port_speed_set: u=%d p=%d speed=%d rv=%d\n"), 17933 unit, port, speed, rv)); 17934 17935 return rv; 17936 } 17937 17938 /* 17939 * Function: 17940 * bcm_port_master_get 17941 * Purpose: 17942 * Getting the master status of the port 17943 * Parameters: 17944 * unit - StrataSwitch Unit #. 17945 * port - StrataSwitch port #. 17946 * ms - (OUT) BCM_PORT_MS_* 17947 * Returns: 17948 * BCM_E_NONE 17949 * BCM_E_XXX 17950 * Notes: 17951 * WARNING: assumes BCM_PORT_MS_* matches SOC_PORT_MS_* 17952 */ 17953 17954 int 17955 bcm_esw_port_master_get(int unit, bcm_port_t port, int *ms) 17956 { 17957 int rv=BCM_E_NONE; 17958 #if defined(BCM_KATANA2_SUPPORT) 17959 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 17960 #endif 17961 17962 /* Make sure port module is initialized. */ 17963 PORT_INIT(unit); 17964 17965 /* Call Port Control module */ 17966 if (SOC_USE_PORTCTRL(unit)) { 17967 return bcmi_esw_portctrl_master_get(unit, port, ms); 17968 } 17969 17970 #if defined(BCM_KATANA2_SUPPORT) 17971 #if defined(BCM_SABER2_SUPPORT) 17972 if(SOC_IS_SABER2(unit)) { 17973 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 17974 } 17975 #endif 17976 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 17977 (!((port >= 1) && (port <= max_phy_port)))) { 17978 return BCM_E_PORT; 17979 } 17980 #endif 17981 17982 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 17983 PORT_LOCK(unit); 17984 rv = soc_phyctrl_master_get(unit, port, ms); 17985 PORT_UNLOCK(unit); 17986 return rv; 17987 } 17988 17989 /* 17990 * Function: 17991 * bcm_port_master_set 17992 * Purpose: 17993 * Setting the master status for a given port 17994 * Parameters: 17995 * unit - StrataSwitch Unit #. 17996 * port - StrataSwitch port #. 17997 * ms - BCM_PORT_MS_* 17998 * Returns: 17999 * BCM_E_NONE 18000 * BCM_E_XXX 18001 * Notes: 18002 * Ignored if not supported on port. 18003 * WARNING: assumes BCM_PORT_MS_* matches SOC_PORT_MS_* 18004 */ 18005 18006 int 18007 bcm_esw_port_master_set(int unit, bcm_port_t port, int ms) 18008 { 18009 int rv; 18010 pbmp_t pbm; 18011 #if defined(BCM_KATANA2_SUPPORT) 18012 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18013 #endif 18014 18015 /* Make sure port module is initialized. */ 18016 PORT_INIT(unit); 18017 18018 /* Call Port Control module */ 18019 if (SOC_USE_PORTCTRL(unit)) { 18020 return bcmi_esw_portctrl_master_set(unit, port, ms); 18021 } 18022 18023 if(bcm_common_oamp_port_enable_get(unit, port)) { 18024 LOG_ERROR(BSL_LS_BCM_PORT, 18025 (BSL_META("Error: Cannot configure OAMP Port %d to be master.\n"), 18026 port)); 18027 return BCM_E_PARAM; 18028 } 18029 18030 #if defined(BCM_KATANA2_SUPPORT) 18031 #if defined(BCM_SABER2_SUPPORT) 18032 if(SOC_IS_SABER2(unit)) { 18033 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18034 } 18035 #endif 18036 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18037 (!((port >= 1) && (port <= max_phy_port)))) { 18038 return BCM_E_PORT; 18039 } 18040 #endif 18041 18042 /* Make sure port module is initialized. */ 18043 PORT_INIT(unit); 18044 18045 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18046 18047 #ifdef BCM_RCPU_SUPPORT 18048 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 18049 return BCM_E_PORT; 18050 } 18051 #endif /* BCM_RCPU_SUPPORT */ 18052 18053 PORT_LOCK(unit); /* multiple operations operation */ 18054 18055 rv = soc_phyctrl_master_set(unit, port, ms); 18056 if (BCM_FAILURE(rv)) { 18057 LOG_VERBOSE(BSL_LS_BCM_PORT, 18058 (BSL_META_U(unit, 18059 "PHY_MASTER_SETfailed:%s\n"), bcm_errmsg(rv))); 18060 } 18061 18062 #if defined(BCM_XMAC_SUPPORT) 18063 if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) || 18064 SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 18065 uint32 vco_disturbed = 0; 18066 phy_ctrl_t *int_pc, *ext_pc; 18067 ext_pc = EXT_PHY_SW_STATE(unit, port); 18068 if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) || 18069 IS_XE_PORT(unit, port)) && (ext_pc == NULL)) { 18070 18071 int_pc = INT_PHY_SW_STATE(unit, port); 18072 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed); 18073 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) { 18074 PORT_UNLOCK(unit); 18075 return rv; 18076 } 18077 if (vco_disturbed) { 18078 rv = _mac_x_reinit(unit, port); 18079 if (BCM_FAILURE(rv)) { 18080 PORT_UNLOCK(unit); 18081 return rv; 18082 } 18083 } 18084 } 18085 } 18086 #endif 18087 PORT_UNLOCK(unit); /* Unlock before link call */ 18088 18089 if (BCM_SUCCESS(rv)) { 18090 SOC_PBMP_CLEAR(pbm); 18091 SOC_PBMP_PORT_ADD(pbm, port); 18092 (void)bcm_esw_link_change(unit, pbm); 18093 } 18094 18095 return rv; 18096 } 18097 18098 /* 18099 * Function: 18100 * bcm_port_interface_get 18101 * Purpose: 18102 * Getting the interface type of a port 18103 * Parameters: 18104 * unit - StrataSwitch Unit #. 18105 * port - StrataSwitch port #. 18106 * intf - (OUT) BCM_PORT_IF_* 18107 * Returns: 18108 * BCM_E_NONE 18109 * BCM_E_XXX 18110 * Notes: 18111 * WARNING: assumes BCM_PORT_IF_* matches SOC_PORT_IF_* 18112 */ 18113 18114 int 18115 bcm_esw_port_interface_get(int unit, bcm_port_t port, bcm_port_if_t *intf) 18116 { 18117 int rv=BCM_E_NONE; 18118 #if defined(BCM_KATANA2_SUPPORT) 18119 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18120 #endif 18121 18122 /* Make sure port module is initialized. */ 18123 PORT_INIT(unit); 18124 18125 /* Call Port Control module */ 18126 if (SOC_USE_PORTCTRL(unit)) { 18127 return bcmi_esw_portctrl_interface_get(unit, port, intf); 18128 } 18129 18130 if(bcm_common_oamp_port_enable_get(unit, port)) { 18131 LOG_ERROR(BSL_LS_BCM_PORT, 18132 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 18133 port)); 18134 return BCM_E_PARAM; 18135 } 18136 18137 #if defined(BCM_KATANA2_SUPPORT) 18138 #if defined(BCM_SABER2_SUPPORT) 18139 if(SOC_IS_SABER2(unit)) { 18140 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18141 } 18142 #endif 18143 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18144 (!((port >= 1) && (port <= max_phy_port)))) { 18145 return BCM_E_PORT; 18146 } 18147 #endif 18148 18149 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18150 18151 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) { 18152 return BCM_E_PORT; 18153 } 18154 PORT_LOCK(unit); 18155 rv = soc_phyctrl_interface_get(unit, port, intf); 18156 PORT_UNLOCK(unit); 18157 return rv; 18158 } 18159 18160 /* 18161 * Function: 18162 * bcm_port_interface_set 18163 * Purpose: 18164 * Setting the interface type for a given port 18165 * Parameters: 18166 * unit - StrataSwitch Unit #. 18167 * port - StrataSwitch port #. 18168 * if - BCM_PORT_IF_* 18169 * Returns: 18170 * BCM_E_NONE 18171 * BCM_E_XXX 18172 * Notes: 18173 * WARNING: assumes BCM_PORT_IF_* matches SOC_PORT_IF_* 18174 */ 18175 18176 int 18177 bcm_esw_port_interface_set(int unit, bcm_port_t port, bcm_port_if_t intf) 18178 { 18179 int rv; 18180 pbmp_t pbm; 18181 #if defined(BCM_KATANA2_SUPPORT) 18182 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18183 #endif 18184 18185 /* Make sure port module is initialized. */ 18186 PORT_INIT(unit); 18187 18188 /* Call Port Control module */ 18189 if (SOC_USE_PORTCTRL(unit)) { 18190 return bcmi_esw_portctrl_interface_set(unit, port, intf); 18191 } 18192 18193 if(bcm_common_oamp_port_enable_get(unit, port)) { 18194 LOG_ERROR(BSL_LS_BCM_PORT, 18195 (BSL_META( 18196 "Error: Cannot set interface type on OAMP Port %d.\n"), 18197 port)); 18198 return BCM_E_PARAM; 18199 } 18200 18201 #if defined(BCM_KATANA2_SUPPORT) 18202 #if defined(BCM_SABER2_SUPPORT) 18203 if(SOC_IS_SABER2(unit)) { 18204 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18205 } 18206 #endif 18207 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18208 (!((port >= 1) && (port <= max_phy_port)))) { 18209 return BCM_E_PORT; 18210 } 18211 #endif 18212 18213 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18214 18215 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) { 18216 return BCM_E_PORT; 18217 } 18218 18219 #ifdef BCM_RCPU_SUPPORT 18220 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 18221 return BCM_E_PORT; 18222 } 18223 #endif /* BCM_RCPU_SUPPORT */ 18224 18225 PORT_LOCK(unit); /* multiple operations operation */ 18226 18227 rv = soc_phyctrl_interface_set(unit, port, intf); 18228 if (BCM_FAILURE(rv)) { 18229 LOG_VERBOSE(BSL_LS_BCM_PORT, 18230 (BSL_META_U(unit, 18231 "PHY_INTERFACE_SETfailed:%s\n"), bcm_errmsg(rv))); 18232 } 18233 #if defined(BCM_XMAC_SUPPORT) 18234 if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) || 18235 SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 18236 uint32 vco_disturbed = 0; 18237 phy_ctrl_t *int_pc, *ext_pc; 18238 ext_pc = EXT_PHY_SW_STATE(unit, port); 18239 if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) || 18240 IS_XE_PORT(unit, port)) && (ext_pc == NULL)) { 18241 18242 int_pc = INT_PHY_SW_STATE(unit, port); 18243 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed); 18244 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) { 18245 PORT_UNLOCK(unit); 18246 return rv; 18247 } 18248 if (vco_disturbed) { 18249 rv = _mac_x_reinit(unit, port); 18250 if (BCM_FAILURE(rv)) { 18251 PORT_UNLOCK(unit); 18252 return rv; 18253 } 18254 } 18255 } 18256 } 18257 #endif 18258 18259 PORT_UNLOCK(unit); /* Unlock before link call */ 18260 18261 if (BCM_SUCCESS(rv)) { 18262 SOC_PBMP_CLEAR(pbm); 18263 SOC_PBMP_PORT_ADD(pbm, port); 18264 (void)bcm_esw_link_change(unit, pbm); 18265 PORT(unit, port).intf = intf; 18266 } 18267 18268 return rv; 18269 } 18270 18271 /* 18272 * Function: 18273 * bcm_port_loopback_set 18274 * Purpose: 18275 * Setting the speed for a given port 18276 * Parameters: 18277 * unit - StrataSwitch Unit #. 18278 * port - StrataSwitch port #. 18279 * loopback - one of: 18280 * BCM_PORT_LOOPBACK_NONE 18281 * BCM_PORT_LOOPBACK_MAC 18282 * BCM_PORT_LOOPBACK_PHY 18283 * Returns: 18284 * BCM_E_NONE 18285 * BCM_E_XXX 18286 */ 18287 18288 int 18289 bcm_esw_port_loopback_set(int unit, bcm_port_t port, int loopback) 18290 { 18291 int rv, link = TRUE; 18292 int phy_lane = -1; 18293 int phyn = 0, sys_side = 0; 18294 bcm_port_t local_port = -1; 18295 #if defined(BCM_TOMAHAWK_SUPPORT) 18296 uint32 link_st = 0; 18297 soc_timeout_t to; 18298 int phy_port; 18299 #endif 18300 soc_persist_t *sop = SOC_PERSIST(unit); 18301 18302 #ifdef BCM_TRIDENT2_SUPPORT 18303 int enable; 18304 #endif /* BCM_TRIDENT2_SUPPORT */ 18305 #if defined(BCM_KATANA2_SUPPORT) 18306 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18307 #endif 18308 18309 /* Make sure port module is initialized. */ 18310 PORT_INIT(unit); 18311 18312 if (SOC_USE_PORTCTRL(unit)) { 18313 /* Check if port have to force-loopback */ 18314 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 18315 if (BCM_ESW_PORT_DRV(unit)->force_lb_check != NULL) { 18316 rv = BCM_ESW_PORT_DRV(unit)->force_lb_check(unit, port, 18317 loopback); 18318 if (rv != BCM_E_NONE) { 18319 LOG_ERROR(BSL_LS_BCM_PORT, 18320 (BSL_META("Error: Port %d allow PHY internal " 18321 "loopback only.\n"), 18322 port)); 18323 return BCM_E_PARAM; 18324 } 18325 } 18326 } 18327 18328 return bcmi_esw_portctrl_loopback_set(unit, port, loopback); 18329 } 18330 18331 if(bcm_common_oamp_port_enable_get(unit, port)) { 18332 LOG_ERROR(BSL_LS_BCM_PORT, 18333 (BSL_META("Error: Cannot set loopback on OAMP Port %d.\n"), 18334 port)); 18335 return BCM_E_PARAM; 18336 } 18337 18338 #if defined(BCM_KATANA2_SUPPORT) 18339 #if defined(BCM_SABER2_SUPPORT) 18340 if(SOC_IS_SABER2(unit)) { 18341 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18342 } 18343 #endif 18344 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18345 (!((port >= 1) && (port <= max_phy_port)))) { 18346 return BCM_E_PORT; 18347 } 18348 #endif 18349 18350 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port, 18351 &local_port, &phyn, 18352 &phy_lane, &sys_side)); 18353 18354 if (local_port == -1) { 18355 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18356 } else { 18357 port = local_port; 18358 } 18359 18360 #if defined(BCM_TOMAHAWK_SUPPORT) 18361 if (SOC_IS_TOMAHAWKX(unit)) { 18362 BCM_IF_ERROR_RETURN(bcm_th_phy_lb_check(unit, port, loopback)); 18363 } 18364 #endif 18365 18366 #ifdef BCM_RCPU_SUPPORT 18367 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 18368 return BCM_E_PORT; 18369 } 18370 #endif /* BCM_RCPU_SUPPORT */ 18371 18372 PORT_LOCK(unit); 18373 soc_phyctrl_enable_get(unit, port, &link); 18374 PORT_UNLOCK(unit); 18375 if (TRUE == link) { 18376 if (SOC_PBMP_MEMBER(sop->lc_pbm_override_ports, port)) { 18377 if(!SOC_PBMP_MEMBER(sop->lc_pbm_override_link, port)) { 18378 link = FALSE; 18379 } 18380 } 18381 } 18382 18383 rv = BCM_E_NONE; 18384 /* 18385 * Always force link before changing hardware to avoid 18386 * race with the linkscan thread. 18387 */ 18388 if (!(loopback == BCM_PORT_LOOPBACK_NONE)) { 18389 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, FALSE); 18390 18391 if(rv == BCM_E_NONE) { 18392 /* Force the update function to be called so the state is 18393 updated */ 18394 if (_soc_linkscan_phy_flags_test(unit, port, PHY_FLAGS_EXTERNAL_PHY)) { 18395 rv = bcm_esw_port_update(unit, port, TRUE); 18396 } 18397 } 18398 } 18399 18400 PORT_LOCK(unit); 18401 18402 if (BCM_SUCCESS(rv)) { 18403 rv = MAC_LOOPBACK_SET(PORT(unit, port).p_mac, unit, port, 18404 (loopback == BCM_PORT_LOOPBACK_MAC)); 18405 } 18406 if (BCM_SUCCESS(rv)) { 18407 if (local_port == -1) { 18408 if (loopback == BCM_PORT_LOOPBACK_PHY_REMOTE) { 18409 rv = soc_phyctrl_control_set(unit, port, 18410 SOC_PHY_CONTROL_LOOPBACK_REMOTE, 1); 18411 } else { 18412 if (loopback == BCM_PORT_LOOPBACK_NONE) { 18413 rv = soc_phyctrl_control_set(unit, port, 18414 SOC_PHY_CONTROL_LOOPBACK_REMOTE, 0); 18415 } 18416 18417 if (rv == SOC_E_NONE || rv == SOC_E_UNAVAIL) { 18418 rv = soc_phyctrl_loopback_set(unit, port, 18419 (loopback == BCM_PORT_LOOPBACK_PHY), 18420 TRUE); 18421 } 18422 } 18423 18424 } else { 18425 rv = soc_phyctrl_redirect_loopback_set 18426 (unit, port, phyn, 18427 phy_lane, sys_side, 18428 (loopback == BCM_PORT_LOOPBACK_PHY), 18429 TRUE); 18430 } 18431 } 18432 /* some mac loopback implementations require the phy to also be in loopback */ 18433 if (soc_feature(unit, soc_feature_phy_lb_needed_in_mac_lb) && 18434 (loopback == BCM_PORT_LOOPBACK_MAC)) { 18435 if (local_port == -1) { 18436 rv = soc_phyctrl_loopback_set(unit, port, 1, TRUE); 18437 } else { 18438 rv = soc_phyctrl_redirect_loopback_set(unit, port, phyn, 18439 phy_lane, sys_side, 18440 1, TRUE); 18441 } 18442 } 18443 18444 PORT_UNLOCK(unit); /* unlock before link call */ 18445 18446 if ((loopback == BCM_PORT_LOOPBACK_NONE) || !BCM_SUCCESS(rv)) { 18447 _bcm_esw_link_force(unit, 0 /*flags*/, port, FALSE, DONT_CARE); 18448 PORT_LOCK(unit); 18449 #ifdef BCM_TRIDENT2_SUPPORT 18450 /* When the PHY is TSC, need to unsquelch TX LANE. */ 18451 if (SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit)){ 18452 enable = PORT(unit, port).enable; 18453 if ((FALSE == enable) && (loopback == BCM_PORT_LOOPBACK_NONE)) { 18454 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, FALSE); 18455 rv = soc_phyctrl_enable_set(unit, port, FALSE); 18456 if (SOC_FAILURE(rv)) { 18457 PORT_UNLOCK(unit); 18458 return (rv); 18459 } 18460 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE); 18461 } 18462 } else 18463 #endif /* BCM_TRIDENT2_SUPPORT */ 18464 { 18465 if ((FALSE == link) && (loopback == BCM_PORT_LOOPBACK_NONE)) { 18466 /* Disable MAC RX to prevent traffic going into this port */ 18467 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 18468 SOC_MAC_CONTROL_RX_SET, FALSE); 18469 sal_udelay(100); /* Wait for 1 jumbo packet transmission time */ 18470 18471 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, FALSE); 18472 } 18473 } 18474 PORT_UNLOCK(unit); 18475 } else { 18476 /* Enable only MAC instead of calling bcm_port_enable_set so 18477 * that this API doesn't silently enable the port if the 18478 * port is disabled by application. 18479 */ 18480 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, TRUE); 18481 18482 #ifdef BCM_TRIDENT2_SUPPORT 18483 /* When the PHY is TSC, need to enable the PHY to support MAC loopback 18484 * on a disabled port. In order to avoid link flap of link partner, 18485 * need to squelch TX LANE before enabling PHY. 18486 */ 18487 if (BCM_FAILURE(rv)) { 18488 return (rv); 18489 } 18490 if ((SOC_IS_TD2_TT2(unit) && !SOC_IS_TOMAHAWKX(unit)) && (FALSE == link) 18491 && (loopback == BCM_PORT_LOOPBACK_MAC)) { 18492 PORT_LOCK(unit); 18493 (void)soc_phyctrl_notify(unit, port, phyEventTxSquelch, TRUE); 18494 rv = soc_phyctrl_enable_set(unit, port, TRUE); 18495 PORT_UNLOCK(unit); 18496 if (SOC_FAILURE(rv)) { 18497 return (rv); 18498 } 18499 } 18500 #endif /* BCM_TRIDENT2_SUPPORT */ 18501 18502 if (BCM_SUCCESS(rv)) { 18503 /* Make sure that the link status is updated only after the 18504 * MAC is enabled so that link_mask2 is set before the 18505 * calling thread synchronizes with linkscan thread in 18506 * _bcm_link_force call. 18507 * If the link is forced before MAC is enabled, there could 18508 * be a race condition in _soc_link_update where linkscan 18509 * may use an old view of link_mask2 and override the 18510 * EPC_LINK_BMAP after the mac_enable_set updates 18511 * link_mask2 and EPC_LINK_BMAP. 18512 */ 18513 if (loopback == BCM_PORT_LOOPBACK_MAC) { 18514 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, TRUE); 18515 } else { 18516 rv = _bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, link); 18517 } 18518 } 18519 if (BCM_FAILURE(rv)) { 18520 return (rv); 18521 } 18522 18523 #if defined(BCM_BRADLEY_SUPPORT) 18524 /* 18525 * Call _bcm_port_mmu_update explicitly because linkscan 18526 * will not call bcm_port_update when the link is forced. 18527 */ 18528 if (SOC_IS_HBX(unit) && !SOC_IS_SHADOW(unit)) { 18529 rv = _bcm_port_mmu_update(unit, port, 1); 18530 } 18531 18532 /* When a link comes up, hardware will not update the 18533 * LINK_STATUS register until software has toggled the 18534 * the LAG_FAILOVER_CONFIG.LINK_STATUS_UP field. 18535 * Normally, this is done by bcm_port_update. But since 18536 * linkscan will not call bcm_port_update when a link is 18537 * forced up, the toggling of LAG_FAILOVER_CONFIG.LINK_STATUS_UP 18538 * is done here. 18539 */ 18540 if ((SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr) && 18541 IS_GX_PORT(unit, port)) || 18542 (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) || 18543 (SOC_REG_IS_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr) && 18544 (IS_XL_PORT(unit, port) || IS_MXQ_PORT(unit, port))) || 18545 (SOC_REG_IS_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr) && 18546 IS_CL_PORT(unit, port))) { 18547 soc_reg_t reg; 18548 uint32 rval; 18549 18550 if (SOC_IS_SABER2(unit) && SOC_REG_PORT_VALID(unit, XLPORT_LAG_FAILOVER_CONFIGr, port)) { 18551 reg = XLPORT_LAG_FAILOVER_CONFIGr; 18552 } else if (SOC_REG_IS_VALID(unit, LAG_FAILOVER_CONFIGr)) { 18553 reg = LAG_FAILOVER_CONFIGr; 18554 } else if (SOC_REG_IS_VALID(unit, GXPORT_LAG_FAILOVER_CONFIGr)) { 18555 reg = GXPORT_LAG_FAILOVER_CONFIGr; 18556 } else if (SOC_REG_PORT_VALID(unit, CLPORT_LAG_FAILOVER_CONFIGr, port) && 18557 (SOC_IS_TOMAHAWKX(unit) || IS_CL_PORT(unit, port))) { 18558 reg = CLPORT_LAG_FAILOVER_CONFIGr; 18559 } else { 18560 reg = XLPORT_LAG_FAILOVER_CONFIGr; 18561 } 18562 18563 #if defined(BCM_TOMAHAWK_SUPPORT) 18564 if (SOC_IS_TOMAHAWK(unit)) { 18565 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 18566 if((phy_port == TH_MGMT_PORT0_NUM) || 18567 (phy_port == TH_MGMT_PORT1_NUM)) { 18568 reg = XLPORT_LAG_FAILOVER_CONFIGr; 18569 } 18570 /* Link status to IPIPE is updated by H/W and driven based on both the 18571 * rising edge of XLPORT_LAG_FAILOVER_CONFIG.LINK_STATUS_UP and 18572 * actual link up status from Serdes. 18573 * In some loopback scenarios it may take longer time to see Serdes link up status. 18574 */ 18575 soc_timeout_init(&to, 10000, 0); 18576 do { 18577 if (((phy_port != TH_MGMT_PORT0_NUM) && 18578 (phy_port != TH_MGMT_PORT1_NUM)) || 18579 (loopback == BCM_PORT_LOOPBACK_NONE)) { 18580 break; 18581 } 18582 18583 switch(phy_port) { 18584 case TH_MGMT_PORT0_NUM: 18585 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XLPORT_XGXS0_LN0_STATUS0_REGr, port, 0, &rval)); 18586 link_st = soc_reg_field_get(unit, XLPORT_XGXS0_LN0_STATUS0_REGr, rval, LINK_STATUSf); 18587 break; 18588 case TH_MGMT_PORT1_NUM: 18589 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XLPORT_XGXS0_LN2_STATUS0_REGr, port, 0, &rval)); 18590 link_st = soc_reg_field_get(unit, XLPORT_XGXS0_LN2_STATUS0_REGr, rval, LINK_STATUSf); 18591 break; 18592 } 18593 if(link_st) { 18594 break; 18595 } 18596 } while (!soc_timeout_check(&to)); 18597 } 18598 #endif 18599 /* Toggle link bit to notify IPIPE on link up */ 18600 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 18601 soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 1); 18602 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 18603 soc_reg_field_set(unit, reg, &rval, LINK_STATUS_UPf, 0); 18604 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 18605 } 18606 #endif /* BCM_BRADLEY_SUPPORT */ 18607 } 18608 18609 LOG_INFO(BSL_LS_BCM_PORT, 18610 (BSL_META_U(unit, 18611 "bcm_port_loopback_set: u=%d p=%d lb=%d rv=%d\n"), 18612 unit, port, loopback, rv)); 18613 18614 return rv; 18615 } 18616 18617 /* 18618 * Function: 18619 * bcm_port_loopback_get 18620 * Purpose: 18621 * Recover the current loopback operation for the specified port. 18622 * Parameters: 18623 * unit - StrataSwitch Unit #. 18624 * port - StrataSwitch port #. 18625 * loopback - (OUT) one of: 18626 * BCM_PORT_LOOPBACK_NONE 18627 * BCM_PORT_LOOPBACK_MAC 18628 * BCM_PORT_LOOPBACK_PHY 18629 * Returns: 18630 * BCM_E_NONE 18631 * BCM_E_XXX 18632 */ 18633 18634 int 18635 bcm_esw_port_loopback_get(int unit, bcm_port_t port, int *loopback) 18636 { 18637 int rv = BCM_E_NONE; 18638 int phy_lb = 0; 18639 uint32 phy_rlb = 0; 18640 int mac_lb = 0; 18641 int phy_lane = -1; 18642 int phyn = 0, sys_side = 0; 18643 bcm_port_t local_port = -1; 18644 #if defined(BCM_KATANA2_SUPPORT) 18645 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18646 #endif 18647 18648 /* Make sure port module is initialized. */ 18649 PORT_INIT(unit); 18650 18651 if (SOC_USE_PORTCTRL(unit)) { 18652 return bcmi_esw_portctrl_loopback_get(unit, port, loopback); 18653 } 18654 18655 if(bcm_common_oamp_port_enable_get(unit, port)) { 18656 LOG_ERROR(BSL_LS_BCM_PORT, 18657 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 18658 port)); 18659 return BCM_E_PARAM; 18660 } 18661 18662 #if defined(BCM_KATANA2_SUPPORT) 18663 #if defined(BCM_SABER2_SUPPORT) 18664 if(SOC_IS_SABER2(unit)) { 18665 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18666 } 18667 #endif 18668 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18669 (!((port >= 1) && (port <= max_phy_port)))) { 18670 return BCM_E_PORT; 18671 } 18672 #endif 18673 18674 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_phyn_validate(unit, port, 18675 &local_port, &phyn, 18676 &phy_lane, &sys_side)); 18677 18678 if (local_port == -1) { 18679 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18680 } else { 18681 port = local_port; 18682 } 18683 PORT_LOCK(unit); /* multiple operations operation */ 18684 18685 if (local_port == -1) { 18686 /* Most ext-phys don't support remote loopback and return SOC_E_UNAVAIL. 18687 * When the return value is SOC_E_UNAVAIL, continue to get phy or mac 18688 * loopback mode 18689 */ 18690 rv = soc_phyctrl_control_get(unit, port, 18691 SOC_PHY_CONTROL_LOOPBACK_REMOTE, 18692 &phy_rlb); 18693 if (rv >= 0 || rv == SOC_E_UNAVAIL) { 18694 rv = soc_phyctrl_loopback_get(unit, port, &phy_lb); 18695 } 18696 } else { 18697 rv = soc_phyctrl_redirect_loopback_get(unit, port, phyn, 18698 phy_lane, sys_side, 18699 &phy_lb); 18700 } 18701 18702 rv = MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb); 18703 18704 PORT_UNLOCK(unit); 18705 if (rv >= 0) { 18706 if (mac_lb) { 18707 *loopback = BCM_PORT_LOOPBACK_MAC; 18708 } else if (phy_lb) { 18709 *loopback = BCM_PORT_LOOPBACK_PHY; 18710 } else if (phy_rlb) { 18711 *loopback = BCM_PORT_LOOPBACK_PHY_REMOTE; 18712 } else { 18713 *loopback = BCM_PORT_LOOPBACK_NONE; 18714 } 18715 } else { 18716 *loopback = BCM_PORT_LOOPBACK_NONE; 18717 } 18718 18719 LOG_INFO(BSL_LS_BCM_PORT, 18720 (BSL_META_U(unit, 18721 "bcm_port_loopback_get: u=%d p=%d lb=%d rv=%d\n"), 18722 unit, port, *loopback, rv)); 18723 18724 return rv; 18725 } 18726 18727 /* 18728 * Function: 18729 * bcm_port_duplex_get 18730 * Purpose: 18731 * Get the port duplex settings 18732 * Parameters: 18733 * unit - StrataSwitch Unit #. 18734 * port - StrataSwitch port #. 18735 * duplex - (OUT) Duplex setting, one of SOC_PORT_DUPLEX_xxx 18736 * Returns: 18737 * BCM_E_NONE 18738 * BCM_E_XXX 18739 */ 18740 18741 int 18742 bcm_esw_port_duplex_get(int unit, bcm_port_t port, int *duplex) 18743 { 18744 int phy_duplex; 18745 int rv=BCM_E_NONE; 18746 #if defined(BCM_KATANA2_SUPPORT) 18747 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18748 #endif 18749 18750 /* Make sure port module is initialized. */ 18751 PORT_INIT(unit); 18752 18753 if (SOC_USE_PORTCTRL(unit)) { 18754 return bcmi_esw_portctrl_duplex_get(unit, port, duplex); 18755 } 18756 18757 if(bcm_common_oamp_port_enable_get(unit, port)) { 18758 LOG_ERROR(BSL_LS_BCM_PORT, 18759 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 18760 port)); 18761 return BCM_E_PARAM; 18762 } 18763 18764 #if defined(BCM_KATANA2_SUPPORT) 18765 #if defined(BCM_SABER2_SUPPORT) 18766 if(SOC_IS_SABER2(unit)) { 18767 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18768 } 18769 #endif 18770 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18771 (!((port >= 1) && (port <= max_phy_port)))) { 18772 return BCM_E_PORT; 18773 } 18774 #endif 18775 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18776 PORT_LOCK(unit); 18777 rv = soc_phyctrl_duplex_get(unit, port, &phy_duplex); 18778 PORT_UNLOCK(unit); 18779 18780 if (BCM_SUCCESS(rv)) { 18781 *duplex = phy_duplex ? SOC_PORT_DUPLEX_FULL : SOC_PORT_DUPLEX_HALF; 18782 } else { 18783 *duplex = SOC_PORT_DUPLEX_FULL; 18784 } 18785 18786 LOG_INFO(BSL_LS_BCM_PORT, 18787 (BSL_META_U(unit, 18788 "bcm_port_duplex_get: u=%d p=%d dup=%d rv=%d\n"), 18789 unit, port, *duplex, rv)); 18790 18791 return rv; 18792 } 18793 18794 /* 18795 * Function: 18796 * _bcm_port_duplex_ability_check 18797 * Purpose: 18798 * Check the port duplex ability. 18799 * Parameters: 18800 * unit - StrataSwitch Unit #. 18801 * port - StrataSwitch port #. 18802 * duplex - Duplex setting, one of SOC_PORT_DUPLEX_xxx 18803 * Returns: 18804 * BCM_E_NONE 18805 * BCM_E_XXX 18806 */ 18807 STATIC int 18808 _bcm_esw_port_duplex_ability_check(int unit, bcm_port_t port, int duplex) 18809 { 18810 bcm_port_ability_t ability_mask; 18811 int rv; 18812 int mac_lb; 18813 int speed = 0, full_duplex_speed, half_duplex_speed; 18814 uint32 pa_speed = 0; 18815 sal_memset(&ability_mask, 0, sizeof(bcm_port_ability_t)); 18816 rv = MAC_LOOPBACK_GET(PORT(unit, port).p_mac, unit, port, &mac_lb); 18817 if (BCM_SUCCESS(rv)) { 18818 /* If the port is in mac loopback, we get mac_ability rather than port_ability. */ 18819 if(mac_lb) { 18820 rv = MAC_ABILITY_LOCAL_GET(PORT(unit, port).p_mac, unit,port, &ability_mask); 18821 } else { 18822 rv = bcm_esw_port_ability_local_get(unit, port, &ability_mask); 18823 } 18824 if (rv < 0) { 18825 LOG_VERBOSE(BSL_LS_BCM_PORT, 18826 (BSL_META("Error: Could not get port %d ability: %s\n"), 18827 port, bcm_errmsg(rv))); 18828 return rv; 18829 } 18830 if ((rv = bcm_esw_port_speed_get(unit, port, &speed)) < 0) { 18831 LOG_VERBOSE(BSL_LS_BCM_PORT, 18832 (BSL_META("Error: Could not get port %d speed: %s\n"), 18833 port, bcm_errmsg(rv))); 18834 return rv; 18835 } 18836 pa_speed = SOC_PA_SPEED(speed); 18837 full_duplex_speed = ability_mask.speed_full_duplex & pa_speed; 18838 half_duplex_speed = ability_mask.speed_half_duplex & pa_speed; 18839 if (!soc_feature(unit, soc_feature_flexport_based_speed_set) && (speed != 0)) { 18840 if (duplex) { 18841 if (!full_duplex_speed) { 18842 LOG_WARN(BSL_LS_BCM_PORT, 18843 (BSL_META_U(unit, "Warning: port %d does not support %d mbps full duplex\n"), 18844 port, speed)); 18845 return BCM_E_UNAVAIL; 18846 } 18847 } else { 18848 if (!half_duplex_speed) { 18849 LOG_WARN(BSL_LS_BCM_PORT, 18850 (BSL_META_U(unit, "Warning: port %d does not support %d mbps half duplex\n"), 18851 port, speed)); 18852 return BCM_E_UNAVAIL; 18853 } 18854 } 18855 } 18856 } 18857 return BCM_E_NONE; 18858 } 18859 18860 /* 18861 * Function: 18862 * bcm_port_duplex_set 18863 * Purpose: 18864 * Set the port duplex settings. 18865 * Parameters: 18866 * unit - StrataSwitch Unit #. 18867 * port - StrataSwitch port #. 18868 * duplex - Duplex setting, one of SOC_PORT_DUPLEX_xxx 18869 * Returns: 18870 * BCM_E_NONE 18871 * BCM_E_XXX 18872 * Notes: 18873 * Turns off autonegotiation. Caller must make sure other forced 18874 * parameters (such as speed) are set. 18875 */ 18876 18877 int 18878 bcm_esw_port_duplex_set(int unit, bcm_port_t port, int duplex) 18879 { 18880 int rv; 18881 pbmp_t pbm; 18882 int an = 0 ; 18883 int an_done=0; 18884 #if defined(BCM_SABER2_SUPPORT) 18885 int phy_status; 18886 #endif 18887 #if defined(BCM_KATANA2_SUPPORT) 18888 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 18889 #endif 18890 18891 /* Make sure port module is initialized. */ 18892 PORT_INIT(unit); 18893 18894 if (SOC_USE_PORTCTRL(unit)) { 18895 return bcmi_esw_portctrl_duplex_set(unit, port, duplex); 18896 } 18897 18898 if(bcm_common_oamp_port_enable_get(unit, port)) { 18899 LOG_ERROR(BSL_LS_BCM_PORT, 18900 (BSL_META("Error: Cannot set duplex mode on OAMP Port %d.\n"), 18901 port)); 18902 return BCM_E_PARAM; 18903 } 18904 18905 #if defined(BCM_KATANA2_SUPPORT) 18906 #if defined(BCM_SABER2_SUPPORT) 18907 if(SOC_IS_SABER2(unit)) { 18908 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 18909 } 18910 #endif 18911 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 18912 (!((port >= 1) && (port <= max_phy_port)))) { 18913 return BCM_E_PORT; 18914 } else 18915 #endif 18916 if((!BCM_GPORT_IS_SET(port)) && (!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)))) { 18917 return BCM_E_PORT; 18918 } 18919 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 18920 18921 #ifdef BCM_RCPU_SUPPORT 18922 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 18923 return BCM_E_PORT; 18924 } 18925 #endif /* BCM_RCPU_SUPPORT */ 18926 18927 #if defined(BCM_TOMAHAWK_SUPPORT) 18928 if (SOC_IS_TOMAHAWK(unit)) { 18929 /*half-duplex is not supported at any speed Eagle & Falcon */ 18930 if (duplex == 0) { 18931 return BCM_E_UNAVAIL; 18932 } 18933 } 18934 #endif 18935 18936 /* in SIMULATION, port's alility_mask may not be correct due to NULL phy */ 18937 if (!SAL_BOOT_SIMULATION) { 18938 BCM_IF_ERROR_RETURN(_bcm_esw_port_duplex_ability_check(unit, port, duplex)); 18939 } 18940 18941 PORT_LOCK(unit); 18942 18943 #if defined(BCM_SABER2_SUPPORT) 18944 if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) { 18945 rv = soc_phyctrl_enable_get(unit, port, &phy_status); 18946 if (BCM_FAILURE(rv)) { 18947 PORT_UNLOCK(unit); 18948 return (rv); 18949 } 18950 if(phy_status == TRUE) { 18951 rv = soc_phyctrl_enable_set(unit, port, FALSE); 18952 if (BCM_FAILURE(rv)) { 18953 PORT_UNLOCK(unit); 18954 return (rv); 18955 } 18956 } 18957 } 18958 #endif 18959 rv = soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done); 18960 if (BCM_FAILURE(rv)) { 18961 LOG_VERBOSE(BSL_LS_BCM_PORT, 18962 (BSL_META_U(unit, 18963 "PHY_AUTONEG_GETfailed:%s\n"), bcm_errmsg(rv))); 18964 } 18965 if(an != FALSE) 18966 { 18967 rv = soc_phyctrl_auto_negotiate_set(unit, port, FALSE); 18968 if (BCM_FAILURE(rv)) { 18969 LOG_VERBOSE(BSL_LS_BCM_PORT, 18970 (BSL_META_U(unit, 18971 "PHY_AUTONEG_SETfailed:%s\n"), bcm_errmsg(rv))); 18972 } 18973 } 18974 18975 #if defined(BCM_SABER2_SUPPORT) 18976 if(SOC_IS_SABER2(unit) && 18977 IS_XL_PORT(unit, port) && (phy_status == TRUE)) { 18978 /* Enable phy in tsc only if already enabled before config change */ 18979 rv = soc_phyctrl_enable_set(unit, port, TRUE); 18980 if (BCM_FAILURE(rv)) { 18981 PORT_UNLOCK(unit); 18982 return (rv); 18983 } 18984 } 18985 #endif 18986 18987 if (BCM_SUCCESS(rv)) { 18988 rv = soc_phyctrl_duplex_set(unit, port, duplex); 18989 if (BCM_FAILURE(rv)) { 18990 LOG_VERBOSE(BSL_LS_BCM_PORT, 18991 (BSL_META_U(unit, 18992 "PHY_DUPLEX_SETfailed:%s\n"), bcm_errmsg(rv))); 18993 } 18994 } 18995 18996 if (BCM_SUCCESS(rv)) { 18997 rv = MAC_DUPLEX_SET(PORT(unit, port).p_mac, unit, port, duplex); 18998 if (BCM_FAILURE(rv)) { 18999 LOG_VERBOSE(BSL_LS_BCM_PORT, 19000 (BSL_META_U(unit, 19001 "MAC_DUPLEX_SETfailed:%s\n"), bcm_errmsg(rv))); 19002 } 19003 } 19004 #if defined(BCM_XMAC_SUPPORT) 19005 if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) || 19006 SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 19007 uint32 vco_disturbed = 0; 19008 phy_ctrl_t *int_pc, *ext_pc; 19009 ext_pc = EXT_PHY_SW_STATE(unit, port); 19010 if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) || 19011 IS_XE_PORT(unit, port)) && (ext_pc == NULL)) { 19012 19013 int_pc = INT_PHY_SW_STATE(unit, port); 19014 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed); 19015 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) { 19016 PORT_UNLOCK(unit); 19017 return rv; 19018 } 19019 if (vco_disturbed) { 19020 rv = _mac_x_reinit(unit, port); 19021 if (BCM_FAILURE(rv)) { 19022 PORT_UNLOCK(unit); 19023 return rv; 19024 } 19025 } 19026 } 19027 } 19028 #endif 19029 19030 PORT_UNLOCK(unit); /* Unlock before link call */ 19031 19032 if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) { 19033 SOC_PBMP_CLEAR(pbm); 19034 SOC_PBMP_PORT_ADD(pbm, port); 19035 (void)bcm_esw_link_change(unit, pbm); 19036 } 19037 19038 LOG_INFO(BSL_LS_BCM_PORT, 19039 (BSL_META_U(unit, 19040 "bcm_port_duplex_set: u=%d p=%d dup=%d rv=%d\n"), 19041 unit, port, duplex, rv)); 19042 19043 return rv; 19044 } 19045 19046 /* 19047 * Function: 19048 * bcm_port_pause_get 19049 * Purpose: 19050 * Get the source address for transmitted PAUSE frames. 19051 * Parameters: 19052 * unit - StrataSwitch Unit #. 19053 * port - StrataSwitch port #. 19054 * pause_tx - (OUT) Boolean value 19055 * pause_rx - (OUT) Boolean value 19056 * Returns: 19057 * BCM_E_NONE 19058 * BCM_E_XXX 19059 */ 19060 19061 int 19062 bcm_esw_port_pause_get(int unit, bcm_port_t port, int *pause_tx, int *pause_rx) 19063 { 19064 int rv; 19065 #if defined(BCM_KATANA2_SUPPORT) 19066 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19067 #endif 19068 19069 /* Make sure port module is initialized. */ 19070 PORT_INIT(unit); 19071 19072 /* Call Port Control module */ 19073 if (SOC_USE_PORTCTRL(unit)) { 19074 return bcmi_esw_portctrl_pause_get(unit, port, pause_tx, pause_rx); 19075 } 19076 19077 if(bcm_common_oamp_port_enable_get(unit, port)) { 19078 LOG_ERROR(BSL_LS_BCM_PORT, 19079 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 19080 port)); 19081 return BCM_E_PARAM; 19082 } 19083 19084 #if defined(BCM_KATANA2_SUPPORT) 19085 #if defined(BCM_SABER2_SUPPORT) 19086 if(SOC_IS_SABER2(unit)) { 19087 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19088 } 19089 #endif 19090 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19091 (!((port >= 1) && (port <= max_phy_port)))) { 19092 return BCM_E_PORT; 19093 } 19094 #endif 19095 19096 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19097 19098 PORT_LOCK(unit); 19099 rv = MAC_PAUSE_GET(PORT(unit, port).p_mac, unit, port, pause_tx, pause_rx); 19100 PORT_UNLOCK(unit); 19101 19102 return rv; 19103 } 19104 19105 /* 19106 * Function: 19107 * bcm_port_pause_set 19108 * Purpose: 19109 * Set the pause state for a given port 19110 * Parameters: 19111 * unit - StrataSwitch Unit #. 19112 * port - StrataSwitch port #. 19113 * pause_tx - Boolean value, or -1 (don't change) 19114 * pause_rx - Boolean value, or -1 (don't change) 19115 * Returns: 19116 * BCM_E_NONE 19117 * BCM_E_XXX 19118 * Notes: 19119 * Symmetric pause requires the two "pause" values to be the same. 19120 */ 19121 19122 int 19123 bcm_esw_port_pause_set(int unit, bcm_port_t port, int pause_tx, int pause_rx) 19124 { 19125 int rv; 19126 #ifdef BCM_MONTEREY_SUPPORT 19127 uint32 enable = 0; 19128 #endif 19129 #if defined(BCM_KATANA2_SUPPORT) 19130 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19131 #endif 19132 19133 /* Make sure port module is initialized. */ 19134 PORT_INIT(unit); 19135 19136 /* Call Port Control module */ 19137 if (SOC_USE_PORTCTRL(unit)) { 19138 #ifdef BCM_MONTEREY_SUPPORT 19139 if (SOC_IS_MONTEREY(unit)) { 19140 BCM_IF_ERROR_RETURN( 19141 bcmi_esw_portctrl_preemption_mac_config_get( 19142 unit, port, bcmPortPreemptControlEnableTx, &enable)); 19143 if (enable && (pause_tx || pause_rx)) { 19144 return BCM_E_PARAM; 19145 } 19146 } 19147 #endif 19148 return bcmi_esw_portctrl_pause_set(unit, port, pause_tx, pause_rx); 19149 } 19150 19151 if(bcm_common_oamp_port_enable_get(unit, port)) { 19152 LOG_ERROR(BSL_LS_BCM_PORT, 19153 (BSL_META("Error: Cannot set pause state on OAMP Port %d.\n"), 19154 port)); 19155 return BCM_E_PARAM; 19156 } 19157 19158 #if defined(BCM_KATANA2_SUPPORT) 19159 #if defined(BCM_SABER2_SUPPORT) 19160 if(SOC_IS_SABER2(unit)) { 19161 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19162 } 19163 #endif 19164 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19165 (!((port >= 1) && (port <= max_phy_port)))) { 19166 return BCM_E_PORT; 19167 } 19168 #endif 19169 19170 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19171 19172 PORT_LOCK(unit); 19173 rv = MAC_PAUSE_SET(PORT(unit, port).p_mac, unit, port, pause_tx, pause_rx); 19174 if (BCM_FAILURE(rv)) { 19175 PORT_UNLOCK(unit); 19176 return (rv); 19177 } 19178 19179 #if defined(BCM_BRADLEY_SUPPORT) 19180 if (SOC_IS_HBX(unit)) { 19181 #ifdef BCM_SHADOW_SUPPORT 19182 if (!SOC_IS_SHADOW(unit)) { 19183 #endif 19184 rv = _bcm_port_mmu_update(unit, port, -1); 19185 #ifdef BCM_SHADOW_SUPPORT 19186 } 19187 #endif 19188 } 19189 #endif /* BCM_BRADLEY_SUPPORT */ 19190 19191 PORT_UNLOCK(unit); 19192 return rv; 19193 } 19194 19195 /* 19196 * Function: 19197 * bcm_port_pause_sym_get 19198 * Purpose: 19199 * Get the current pause setting for pause 19200 * Parameters: 19201 * unit - StrataSwitch Unit #. 19202 * port - StrataSwitch port #. 19203 * pause - (OUT) returns a bcm_port_pause_e enum value 19204 * Returns: 19205 * BCM_E_NONE 19206 * BCM_E_XXX 19207 */ 19208 19209 int 19210 bcm_esw_port_pause_sym_get(int unit, bcm_port_t port, int *pause) 19211 { 19212 int pause_rx, pause_tx; 19213 #if defined(BCM_KATANA2_SUPPORT) 19214 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19215 #endif 19216 19217 #if defined(BCM_KATANA2_SUPPORT) 19218 #if defined(BCM_SABER2_SUPPORT) 19219 if(SOC_IS_SABER2(unit)) { 19220 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19221 } 19222 #endif 19223 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19224 (!((port >= 1) && (port <= max_phy_port)))) { 19225 return BCM_E_PORT; 19226 } 19227 #endif 19228 19229 /* Make sure port module is initialized. */ 19230 PORT_INIT(unit); 19231 19232 if(bcm_common_oamp_port_enable_get(unit, port)) { 19233 LOG_ERROR(BSL_LS_BCM_PORT, 19234 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 19235 port)); 19236 return BCM_E_PARAM; 19237 } 19238 19239 BCM_IF_ERROR_RETURN 19240 (bcm_esw_port_pause_get(unit, port, &pause_tx, &pause_rx)); 19241 if (pause_tx) { 19242 if (pause_rx) { 19243 *pause = BCM_PORT_PAUSE_SYM; 19244 } else { 19245 *pause = BCM_PORT_PAUSE_ASYM_TX; 19246 } 19247 } else if (pause_rx) { 19248 *pause = BCM_PORT_PAUSE_ASYM_RX; 19249 } else { 19250 *pause = BCM_PORT_PAUSE_NONE; 19251 } 19252 19253 return BCM_E_NONE; 19254 } 19255 19256 /* 19257 * Function: 19258 * bcm_port_pause_sym_set 19259 * Purpose: 19260 * Set the pause values for the port using single integer 19261 * Parameters: 19262 * unit - StrataSwitch Unit #. 19263 * port - StrataSwitch port #. 19264 * pause - a bcm_port_pause_e enum value 19265 * Returns: 19266 * BCM_E_NONE 19267 * BCM_E_XXX 19268 */ 19269 19270 int 19271 bcm_esw_port_pause_sym_set(int unit, bcm_port_t port, int pause) 19272 { 19273 int pause_rx, pause_tx; 19274 #if defined(BCM_KATANA2_SUPPORT) 19275 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19276 #endif 19277 19278 #if defined(BCM_KATANA2_SUPPORT) 19279 #if defined(BCM_SABER2_SUPPORT) 19280 if(SOC_IS_SABER2(unit)) { 19281 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19282 } 19283 #endif 19284 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19285 (!((port >= 1) && (port <= max_phy_port)))) { 19286 return BCM_E_PORT; 19287 } 19288 #endif 19289 /* Make sure port module is initialized. */ 19290 PORT_INIT(unit); 19291 19292 if(bcm_common_oamp_port_enable_get(unit, port)) { 19293 LOG_ERROR(BSL_LS_BCM_PORT, 19294 (BSL_META("Error: Cannot set pause values on OAMP Port %d.\n"), 19295 port)); 19296 return BCM_E_PARAM; 19297 } 19298 19299 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19300 19301 pause_tx = pause_rx = 0; 19302 19303 switch (pause) { 19304 case BCM_PORT_PAUSE_SYM: 19305 pause_tx = pause_rx = 1; 19306 break; 19307 case BCM_PORT_PAUSE_ASYM_RX: 19308 pause_rx = 1; 19309 break; 19310 case BCM_PORT_PAUSE_ASYM_TX: 19311 pause_tx = 1; 19312 break; 19313 case BCM_PORT_PAUSE_NONE: 19314 break; 19315 default: 19316 return BCM_E_PARAM; 19317 } 19318 19319 return bcm_esw_port_pause_set(unit, port, pause_tx, pause_rx); 19320 } 19321 19322 /* 19323 * Function: 19324 * bcm_port_pause_addr_get 19325 * Purpose: 19326 * Get the source address for transmitted PAUSE frames. 19327 * Parameters: 19328 * unit - StrataSwitch Unit #. 19329 * port - StrataSwitch port #. 19330 * mac - (OUT) MAC address sent with pause frames. 19331 * Returns: 19332 * BCM_E_NONE 19333 * BCM_E_XXX 19334 */ 19335 19336 int 19337 bcm_esw_port_pause_addr_get(int unit, bcm_port_t port, bcm_mac_t mac) 19338 { 19339 int rv; 19340 #if defined(BCM_KATANA2_SUPPORT) 19341 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19342 #endif 19343 19344 /* Make sure port module is initialized. */ 19345 PORT_INIT(unit); 19346 19347 /* Call Port Control module */ 19348 if (SOC_USE_PORTCTRL(unit)) { 19349 return bcmi_esw_portctrl_pause_addr_get(unit, port, mac); 19350 } 19351 19352 if(bcm_common_oamp_port_enable_get(unit, port)) { 19353 LOG_ERROR(BSL_LS_BCM_PORT, 19354 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 19355 port)); 19356 return BCM_E_PARAM; 19357 } 19358 19359 #if defined(BCM_KATANA2_SUPPORT) 19360 #if defined(BCM_SABER2_SUPPORT) 19361 if(SOC_IS_SABER2(unit)) { 19362 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19363 } 19364 #endif 19365 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19366 (!((port >= 1) && (port <= max_phy_port)))) { 19367 return BCM_E_PORT; 19368 } 19369 #endif 19370 19371 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19372 19373 PORT_LOCK(unit); 19374 rv = MAC_PAUSE_ADDR_GET(PORT(unit, port).p_mac, unit, port, mac); 19375 PORT_UNLOCK(unit); 19376 19377 return rv; 19378 } 19379 19380 /* 19381 * Function: 19382 * bcm_port_pause_addr_set 19383 * Purpose: 19384 * Set the source address for transmitted PAUSE frames. 19385 * Parameters: 19386 * unit - StrataSwitch Unit #. 19387 * port - StrataSwitch port #. 19388 * mac - station address used for pause frames. 19389 * Returns: 19390 * BCM_E_NONE 19391 * BCM_E_XXX 19392 * Notes: 19393 * Symmetric pause requires the two "pause" values to be the same. 19394 */ 19395 19396 int 19397 bcm_esw_port_pause_addr_set(int unit, bcm_port_t port, bcm_mac_t mac) 19398 { 19399 int rv; 19400 #if defined(BCM_KATANA2_SUPPORT) 19401 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19402 #endif 19403 19404 /* Make sure port module is initialized. */ 19405 PORT_INIT(unit); 19406 19407 /* Call Port Control module */ 19408 if (SOC_USE_PORTCTRL(unit)) { 19409 return bcmi_esw_portctrl_pause_addr_set(unit, port, mac); 19410 } 19411 19412 if(bcm_common_oamp_port_enable_get(unit, port)) { 19413 LOG_ERROR(BSL_LS_BCM_PORT, 19414 (BSL_META("Error: Cannot set pause addr on OAMP Port %d.\n"), 19415 port)); 19416 return BCM_E_PARAM; 19417 } 19418 19419 #if defined(BCM_KATANA2_SUPPORT) 19420 #if defined(BCM_SABER2_SUPPORT) 19421 if(SOC_IS_SABER2(unit)) { 19422 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19423 } 19424 #endif 19425 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19426 (!((port >= 1) && (port <= max_phy_port)))) { 19427 return BCM_E_PORT; 19428 } 19429 #endif 19430 19431 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19432 19433 PORT_LOCK(unit); 19434 rv = MAC_PAUSE_ADDR_SET(PORT(unit, port).p_mac, unit, port, mac); 19435 PORT_UNLOCK(unit); 19436 19437 return rv; 19438 } 19439 19440 /* 19441 * Function: 19442 * bcm_port_advert_get 19443 * Purpose: 19444 * Retrieve the local port advertisement for autonegotiation. 19445 * Parameters: 19446 * unit - StrataSwitch Unit #. 19447 * port - StrataSwitch port #. 19448 * ability_mask - (OUT) Local advertisement. 19449 * Returns: 19450 * BCM_E_NONE 19451 * BCM_E_XXX 19452 */ 19453 19454 int 19455 bcm_esw_port_advert_get(int unit, bcm_port_t port, bcm_port_abil_t *ability_mask) 19456 { 19457 int rv; 19458 bcm_port_ability_t ability; 19459 #if defined(BCM_KATANA2_SUPPORT) 19460 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19461 #endif 19462 19463 /* Make sure port module is initialized. */ 19464 PORT_INIT(unit); 19465 19466 if (SOC_USE_PORTCTRL(unit)) { 19467 return bcmi_esw_portctrl_ability_advert_get(unit, port, 19468 &ability, ability_mask); 19469 } 19470 sal_memset(&ability, 0, sizeof(bcm_port_ability_t)); 19471 19472 #if defined(BCM_KATANA2_SUPPORT) 19473 #if defined(BCM_SABER2_SUPPORT) 19474 if(SOC_IS_SABER2(unit)) { 19475 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19476 } 19477 #endif 19478 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19479 (!((port >= 1) && (port <= max_phy_port)))) { 19480 return BCM_E_PORT; 19481 } 19482 #endif 19483 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19484 19485 PORT_LOCK(unit); 19486 rv = soc_phyctrl_ability_advert_get(unit, port, &ability); 19487 if (BCM_SUCCESS(rv)) { 19488 rv = soc_port_ability_to_mode(&ability, ability_mask); 19489 } 19490 PORT_UNLOCK(unit); 19491 19492 19493 19494 LOG_INFO(BSL_LS_BCM_PORT, 19495 (BSL_META_U(unit, 19496 "bcm_port_advert_get: u=%d p=%d abil=0x%x rv=%d\n"), 19497 unit, port, *ability_mask, rv)); 19498 19499 return rv; 19500 } 19501 19502 /* 19503 * Function: 19504 * bcm_esw_port_ability_advert_get 19505 * Purpose: 19506 * Retrieve the local port advertisement for autonegotiation. 19507 * Parameters: 19508 * unit - StrataSwitch Unit #. 19509 * port - StrataSwitch port #. 19510 * ability_mask - (OUT) Local advertisement. 19511 * Returns: 19512 * BCM_E_NONE 19513 * BCM_E_XXX 19514 */ 19515 19516 int 19517 bcm_esw_port_ability_advert_get(int unit, bcm_port_t port, 19518 bcm_port_ability_t *ability_mask) 19519 { 19520 int rv=BCM_E_NONE; 19521 #if defined(BCM_KATANA2_SUPPORT) 19522 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19523 #endif 19524 19525 /* Make sure port module is initialized. */ 19526 PORT_INIT(unit); 19527 19528 /* Call Port Control module */ 19529 if (SOC_USE_PORTCTRL(unit)) { 19530 return bcmi_esw_portctrl_ability_advert_get(unit, port, 19531 ability_mask, NULL); 19532 } 19533 19534 if(bcm_common_oamp_port_enable_get(unit, port)) { 19535 LOG_ERROR(BSL_LS_BCM_PORT, 19536 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 19537 port)); 19538 return BCM_E_PARAM; 19539 } 19540 19541 #if defined(BCM_KATANA2_SUPPORT) 19542 #if defined(BCM_SABER2_SUPPORT) 19543 if(SOC_IS_SABER2(unit)) { 19544 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19545 } 19546 #endif 19547 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19548 (!((port >= 1) && (port <= max_phy_port)))) { 19549 return BCM_E_PORT; 19550 } 19551 #endif 19552 19553 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19554 19555 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) { 19556 return BCM_E_PORT; 19557 } 19558 19559 sal_memset(ability_mask, 0, sizeof(bcm_port_ability_t)); 19560 PORT_LOCK(unit); 19561 rv = soc_phyctrl_ability_advert_get(unit, port, ability_mask); 19562 PORT_UNLOCK(unit); 19563 19564 LOG_INFO(BSL_LS_BCM_PORT, 19565 (BSL_META_U(unit, 19566 "bcm_esw_port_ability_advert_get: u=%d p=%d rv=%d\n"), 19567 unit, port, rv)); 19568 19569 return rv; 19570 } 19571 /* 19572 * Function: 19573 * bcm_port_autoneg_ability_advert_get 19574 * Purpose: 19575 * Retrieve the local port abilities. 19576 * Parameters: 19577 * unit - StrataSwitch Unit #. 19578 * port - StrataSwitch port #. 19579 * max_num_ability -- the max num of autoneg ability this port can advertise 19580 * ability - (OUT) values indicating the ability this port advertise 19581 * actual_num_ability - (OUT) the actual num of ability that this port advertise 19582 * Returns: 19583 * BCM_E_NONE 19584 * BCM_E_XXX 19585 */ 19586 int 19587 bcm_esw_port_autoneg_ability_advert_get(int unit, 19588 bcm_port_t port, 19589 int max_num_ability, 19590 bcm_port_speed_ability_t *abilities, 19591 int *actual_num_ability) 19592 { 19593 int rv = BCM_E_UNAVAIL; 19594 19595 /* Make sure port module is initialized. */ 19596 PORT_INIT(unit); 19597 19598 /* Call Port Control module */ 19599 if (SOC_USE_PORTCTRL(unit)) { 19600 rv = bcmi_esw_portctrl_autoneg_ability_advert_get(unit, port, max_num_ability, 19601 abilities, actual_num_ability); 19602 } 19603 19604 return rv; 19605 } 19606 19607 19608 /* 19609 * Function: 19610 * bcm_port_advert_set 19611 * Purpose: 19612 * Set the local port advertisement for autonegotiation. 19613 * Parameters: 19614 * unit - StrataSwitch Unit #. 19615 * port - StrataSwitch port #. 19616 * ability_mask - Local advertisement. 19617 * Returns: 19618 * BCM_E_NONE 19619 * BCM_E_XXX 19620 * Notes: 19621 * This call MAY NOT restart autonegotiation (depending on the phy). 19622 * To do that, follow this call with bcm_port_autoneg_set(TRUE). 19623 */ 19624 19625 int 19626 bcm_esw_port_advert_set(int unit, bcm_port_t port, bcm_port_abil_t ability_mask) 19627 { 19628 int rv; 19629 bcm_port_ability_t given_ability, port_ability, temp_ability; 19630 #if defined(BCM_KATANA2_SUPPORT) 19631 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19632 #endif 19633 19634 /* Make sure port module is initialized. */ 19635 PORT_INIT(unit); 19636 19637 /* Call Port Control module */ 19638 if (SOC_USE_PORTCTRL(unit)) { 19639 return bcmi_esw_portctrl_ability_advert_set(unit, port, 19640 NULL, ability_mask); 19641 } 19642 19643 if(bcm_common_oamp_port_enable_get(unit, port)) { 19644 LOG_ERROR(BSL_LS_BCM_PORT, 19645 (BSL_META("Error: Cannot set port advert on OAMP Port %d.\n"), 19646 port)); 19647 return BCM_E_PARAM; 19648 } 19649 19650 #if defined(BCM_KATANA2_SUPPORT) 19651 #if defined(BCM_SABER2_SUPPORT) 19652 if(SOC_IS_SABER2(unit)) { 19653 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19654 } 19655 #endif 19656 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19657 (!((port >= 1) && (port <= max_phy_port)))) { 19658 return BCM_E_PORT; 19659 } 19660 #endif 19661 19662 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19663 19664 BCM_IF_ERROR_RETURN 19665 (bcm_esw_port_ability_local_get(unit, port, &port_ability)); 19666 19667 BCM_IF_ERROR_RETURN 19668 (bcm_esw_port_ability_advert_get(unit, port, &given_ability)); 19669 19670 BCM_IF_ERROR_RETURN( 19671 soc_port_mode_to_ability(ability_mask, &given_ability)); 19672 19673 /* temporary store ability of half duplex */ 19674 temp_ability.speed_half_duplex = given_ability.speed_half_duplex; 19675 /* make sure that the ability advertising in PHY is supported by MAC */ 19676 soc_port_ability_mask(&given_ability, &port_ability); 19677 /* restore half duplex ability */ 19678 given_ability.speed_half_duplex = temp_ability.speed_half_duplex; 19679 19680 if (IS_HG_PORT(unit, port) && SOC_INFO(unit).port_speed_max[port]) { 19681 if (SOC_INFO(unit).port_speed_max[port] < 16000) { 19682 given_ability.speed_full_duplex &= ~(BCM_PORT_ABILITY_16GB); 19683 given_ability.speed_half_duplex &= ~(BCM_PORT_ABILITY_16GB); 19684 } 19685 19686 if (SOC_INFO(unit).port_speed_max[port] < 13000) { 19687 given_ability.speed_full_duplex &= ~(BCM_PORT_ABILITY_13GB); 19688 given_ability.speed_half_duplex &= ~(BCM_PORT_ABILITY_13GB); 19689 } 19690 19691 if (SOC_INFO(unit).port_speed_max[port] < 12000) { 19692 given_ability.speed_full_duplex &= ~(BCM_PORT_ABILITY_12GB); 19693 given_ability.speed_half_duplex &= ~(BCM_PORT_ABILITY_12GB); 19694 } 19695 19696 if (IS_HL_PORT(unit, port)) { 19697 if (!(given_ability.speed_full_duplex & BCM_PORT_ABILITY_2500MB)) { 19698 return BCM_E_CONFIG; 19699 } 19700 } else if (!(given_ability.speed_full_duplex & (BCM_PORT_ABILITY_16GB | 19701 BCM_PORT_ABILITY_13GB | BCM_PORT_ABILITY_12GB | 19702 BCM_PORT_ABILITY_10GB))) { 19703 return BCM_E_CONFIG; 19704 } 19705 } 19706 19707 PORT_LOCK(unit); 19708 rv = soc_phyctrl_ability_advert_set(unit, port, &given_ability); 19709 PORT_UNLOCK(unit); 19710 19711 LOG_INFO(BSL_LS_BCM_PORT, 19712 (BSL_META_U(unit, 19713 "bcm_port_advert_set: u=%d p=%d abil=0x%x rv=%d\n"), 19714 unit, port, ability_mask, rv)); 19715 19716 return rv; 19717 } 19718 19719 /* 19720 * Function: 19721 * bcm_port_ability_advert_set 19722 * Purpose: 19723 * Set the local port advertisement for autonegotiation. 19724 * Parameters: 19725 * unit - StrataSwitch Unit #. 19726 * port - StrataSwitch port #. 19727 * ability_mask - Local advertisement. 19728 * Returns: 19729 * BCM_E_NONE 19730 * BCM_E_XXX 19731 * Notes: 19732 * This call MAY NOT restart autonegotiation (depending on the phy). 19733 * To do that, follow this call with bcm_port_autoneg_set(TRUE). 19734 */ 19735 19736 int 19737 bcm_esw_port_ability_advert_set(int unit, bcm_port_t port, 19738 bcm_port_ability_t *ability_mask) 19739 { 19740 int rv=BCM_E_NONE; 19741 bcm_port_ability_t port_ability, temp_ability; 19742 #if defined(BCM_KATANA2_SUPPORT) 19743 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19744 #endif 19745 19746 /* Make sure port module is initialized. */ 19747 PORT_INIT(unit); 19748 19749 /* Call Port Control module */ 19750 if (SOC_USE_PORTCTRL(unit)) { 19751 return bcmi_esw_portctrl_ability_advert_set(unit, port, 19752 ability_mask, 0); 19753 } 19754 19755 if(bcm_common_oamp_port_enable_get(unit, port)) { 19756 LOG_ERROR(BSL_LS_BCM_PORT, 19757 (BSL_META( 19758 "Error: Cannot set port ability on OAMP Port %d.\n"), 19759 port)); 19760 return BCM_E_PARAM; 19761 } 19762 19763 #if defined(BCM_KATANA2_SUPPORT) 19764 #if defined(BCM_SABER2_SUPPORT) 19765 if(SOC_IS_SABER2(unit)) { 19766 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19767 } 19768 #endif 19769 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19770 (!((port >= 1) && (port <= max_phy_port)))) { 19771 return BCM_E_PORT; 19772 } 19773 #endif 19774 19775 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19776 19777 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) { 19778 return BCM_E_PORT; 19779 } 19780 19781 BCM_IF_ERROR_RETURN 19782 (bcm_esw_port_ability_local_get(unit, port, &port_ability)); 19783 19784 /* temporary store speed_half_duplex ability */ 19785 temp_ability.speed_half_duplex = ability_mask->speed_half_duplex; 19786 /* Make sure to advertise only abilities supported by the port */ 19787 soc_port_ability_mask(&port_ability, ability_mask); 19788 /* restore speed_half_duplex ability even some mac don't support it */ 19789 port_ability.speed_half_duplex = temp_ability.speed_half_duplex; 19790 PORT_LOCK(unit); 19791 rv = soc_phyctrl_ability_advert_set(unit, port, &port_ability); 19792 PORT_UNLOCK(unit); 19793 LOG_INFO(BSL_LS_BCM_PORT, 19794 (BSL_META_U(unit, 19795 "bcm_port_ability_advert_set: u=%d p=%d rv=%d\n"), 19796 unit, port, rv)); 19797 LOG_VERBOSE(BSL_LS_BCM_PORT, 19798 (BSL_META_U(unit, 19799 "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x advert_set\n" 19800 "Interface=0x%08x Medium=0x%08x Loopback=0x%08x Flags=0x%08x\n"), 19801 port_ability.speed_half_duplex, 19802 port_ability.speed_full_duplex, 19803 port_ability.pause, port_ability.interface, 19804 port_ability.medium, port_ability.loopback, 19805 port_ability.flags)); 19806 19807 return rv; 19808 } 19809 19810 /* 19811 * Function: 19812 * bcm_port_autoneg_ability_advert_set 19813 * Purpose: 19814 * Set the local port advertisement for autonegotiation. 19815 * Parameters: 19816 * unit - StrataSwitch Unit #. 19817 * port - StrataSwitch port #. 19818 * num_ability - number of ability the port will advertise 19819 * ability - Local advertisement for each ability. 19820 * Returns: 19821 * BCM_E_NONE 19822 * BCM_E_XXX 19823 * Notes: 19824 * This call WILL NOT restart autonegotiation (depending on the phy). 19825 * To do that, follow this call with bcm_port_autoneg_set(TRUE). 19826 */ 19827 19828 int bcm_esw_port_autoneg_ability_advert_set(int unit, 19829 bcm_port_t port, 19830 int num_ability, 19831 bcm_port_speed_ability_t *abilities) 19832 { 19833 int rv = BCM_E_UNAVAIL; 19834 19835 /* Make sure port module is initialized. */ 19836 PORT_INIT(unit); 19837 19838 /* Call Port Control module */ 19839 if (SOC_USE_PORTCTRL(unit)) { 19840 rv = bcmi_esw_portctrl_autoneg_ability_advert_set(unit, port, 19841 num_ability, abilities); 19842 } 19843 19844 return rv; 19845 } 19846 19847 19848 /* 19849 * Function: 19850 * bcm_port_advert_remote_get 19851 * Purpose: 19852 * Retrieve the local port advertisement for autonegotiation. 19853 * Parameters: 19854 * unit - StrataSwitch Unit #. 19855 * port - StrataSwitch port #. 19856 * ability_mask - (OUT) Remote advertisement. 19857 * Returns: 19858 * BCM_E_NONE 19859 * BCM_E_XXX 19860 */ 19861 19862 int 19863 bcm_esw_port_advert_remote_get(int unit, bcm_port_t port, 19864 bcm_port_abil_t *ability_mask) 19865 { 19866 int rv; 19867 bcm_port_ability_t port_ability; 19868 #if defined(BCM_KATANA2_SUPPORT) 19869 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19870 #endif 19871 19872 /* Make sure port module is initialized. */ 19873 PORT_INIT(unit); 19874 19875 /* Call Port Control module */ 19876 if (SOC_USE_PORTCTRL(unit)) { 19877 return bcmi_esw_portctrl_ability_remote_get(unit, port, 19878 &port_ability, 19879 ability_mask); 19880 } 19881 19882 sal_memset(&port_ability, 0, sizeof(bcm_port_ability_t)); 19883 19884 #if defined(BCM_KATANA2_SUPPORT) 19885 #if defined(BCM_SABER2_SUPPORT) 19886 if(SOC_IS_SABER2(unit)) { 19887 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19888 } 19889 #endif 19890 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19891 (!((port >= 1) && (port <= max_phy_port)))) { 19892 return BCM_E_PORT; 19893 } 19894 #endif 19895 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19896 19897 PORT_LOCK(unit); 19898 rv = _bcm_port_autoneg_advert_remote_get(unit, port, &port_ability); 19899 if (BCM_SUCCESS(rv)) { 19900 rv = soc_port_ability_to_mode(&port_ability, ability_mask); 19901 } 19902 PORT_UNLOCK(unit); 19903 19904 LOG_INFO(BSL_LS_BCM_PORT, 19905 (BSL_META_U(unit, 19906 "bcm_port_advert_remote_get: u=%d p=%d abil=0x%x rv=%d\n"), 19907 unit, port, *ability_mask, rv)); 19908 19909 return rv; 19910 } 19911 19912 19913 /* 19914 * Function: 19915 * bcm_port_ability_remote_get 19916 * Purpose: 19917 * Retrieve the local port advertisement for autonegotiation. 19918 * Parameters: 19919 * unit - StrataSwitch Unit #. 19920 * port - StrataSwitch port #. 19921 * ability_mask - (OUT) Remote advertisement. 19922 * Returns: 19923 * BCM_E_NONE 19924 * BCM_E_XXX 19925 */ 19926 int 19927 bcm_esw_port_ability_remote_get(int unit, bcm_port_t port, 19928 bcm_port_ability_t *ability_mask) 19929 { 19930 int rv; 19931 #if defined(BCM_KATANA2_SUPPORT) 19932 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 19933 #endif 19934 19935 /* Make sure port module is initialized. */ 19936 PORT_INIT(unit); 19937 19938 /* Call Port Control module */ 19939 if (SOC_USE_PORTCTRL(unit)) { 19940 return bcmi_esw_portctrl_ability_remote_get(unit, port, 19941 ability_mask, NULL); 19942 } 19943 19944 #if defined(BCM_KATANA2_SUPPORT) 19945 #if defined(BCM_SABER2_SUPPORT) 19946 if(SOC_IS_SABER2(unit)) { 19947 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 19948 } 19949 #endif 19950 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 19951 (!((port >= 1) && (port <= max_phy_port)))) { 19952 return BCM_E_PORT; 19953 } 19954 #endif 19955 19956 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 19957 19958 sal_memset(ability_mask, 0, sizeof(bcm_port_ability_t)); 19959 PORT_LOCK(unit); 19960 rv = _bcm_port_autoneg_advert_remote_get(unit, port, ability_mask); 19961 PORT_UNLOCK(unit); 19962 19963 LOG_INFO(BSL_LS_BCM_PORT, 19964 (BSL_META_U(unit, 19965 "bcm_port_ability_remote_get: u=%d p=%d rv=%d\n"), 19966 unit, port, rv)); 19967 LOG_VERBOSE(BSL_LS_BCM_PORT, 19968 (BSL_META_U(unit, 19969 "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x remote_get\n" 19970 "Interface=0x%08x Medium=0x%08x Loopback=0x%08x Flags=0x%08x\n"), 19971 ability_mask->speed_half_duplex, 19972 ability_mask->speed_full_duplex, 19973 ability_mask->pause, ability_mask->interface, 19974 ability_mask->medium, ability_mask->loopback, 19975 ability_mask->flags)); 19976 19977 return rv; 19978 } 19979 /* 19980 * Function: 19981 * bcm_port_autoneg_ability_remote_get 19982 * Purpose: 19983 * Retrieve the local port abilities. 19984 * Parameters: 19985 * unit - StrataSwitch Unit #. 19986 * port - StrataSwitch port #. 19987 * max_num_ability -- the max num of speed ability remote partner can advertise 19988 * ability - (OUT) values indicating the ability of the MAC/PHY 19989 * actual_num_ability - (OUT) the actual num of ability that remote partner advertise 19990 * Returns: 19991 * BCM_E_NONE 19992 * BCM_E_XXX 19993 */ 19994 int 19995 bcm_esw_port_autoneg_ability_remote_get(int unit, 19996 bcm_port_t port, 19997 int max_num_ability, 19998 bcm_port_speed_ability_t *abilities, 19999 int *actual_num_ability) 20000 { 20001 int rv = BCM_E_UNAVAIL; 20002 20003 /* Make sure port module is initialized. */ 20004 PORT_INIT(unit); 20005 20006 /* Call Port Control module */ 20007 if (SOC_USE_PORTCTRL(unit)) { 20008 rv = bcmi_esw_portctrl_autoneg_ability_remote_get(unit, port, max_num_ability, 20009 abilities, actual_num_ability); 20010 } 20011 return rv; 20012 } 20013 20014 20015 /* 20016 * Function: 20017 * bcm_port_ability_get 20018 * Purpose: 20019 * Retrieve the local port abilities. 20020 * Parameters: 20021 * unit - StrataSwitch Unit #. 20022 * port - StrataSwitch port #. 20023 * ability_mask - (OUT) Mask of BCM_PORT_ABIL_ values indicating the 20024 * ability of the MAC/PHY. 20025 * Returns: 20026 * BCM_E_NONE 20027 * BCM_E_XXX 20028 */ 20029 20030 int 20031 bcm_esw_port_ability_get(int unit, bcm_port_t port, bcm_port_abil_t *ability_mask) 20032 { 20033 int rv; 20034 bcm_port_ability_t port_ability; 20035 #if defined(BCM_KATANA2_SUPPORT) 20036 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20037 #endif 20038 20039 /* Make sure port module is initialized. */ 20040 PORT_INIT(unit); 20041 20042 if (SOC_USE_PORTCTRL(unit)) { 20043 return bcmi_esw_portctrl_ability_get(unit, port, 20044 &port_ability, ability_mask); 20045 } 20046 20047 if(bcm_common_oamp_port_enable_get(unit, port)) { 20048 LOG_ERROR(BSL_LS_BCM_PORT, 20049 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 20050 port)); 20051 return BCM_E_PARAM; 20052 } 20053 20054 #if defined(BCM_KATANA2_SUPPORT) 20055 #if defined(BCM_SABER2_SUPPORT) 20056 if(SOC_IS_SABER2(unit)) { 20057 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20058 } 20059 #endif 20060 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20061 (!((port >= 1) && (port <= max_phy_port)))) { 20062 return BCM_E_PORT; 20063 } 20064 #endif 20065 20066 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20067 20068 if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) { 20069 return BCM_E_PORT; 20070 } 20071 20072 PORT_LOCK(unit); 20073 rv = _bcm_port_ability_local_get(unit, port, &port_ability); 20074 if (BCM_SUCCESS(rv)) { 20075 rv = soc_port_ability_to_mode(&port_ability, ability_mask); 20076 } 20077 PORT_UNLOCK(unit); 20078 20079 LOG_INFO(BSL_LS_BCM_PORT, 20080 (BSL_META_U(unit, 20081 "bcm_port_ability_get: u=%d p=%d abil=0x%x rv=%d\n"), 20082 unit, port, *ability_mask, rv)); 20083 20084 return rv; 20085 } 20086 20087 /* 20088 * Function: 20089 * bcm_port_ability_local_get 20090 * Purpose: 20091 * Retrieve the local port abilities. 20092 * Parameters: 20093 * unit - StrataSwitch Unit #. 20094 * port - StrataSwitch port #. 20095 * ability_mask - (OUT) Mask of BCM_PORT_ABIL_ values indicating the 20096 * ability of the MAC/PHY. 20097 * Returns: 20098 * BCM_E_NONE 20099 * BCM_E_XXX 20100 */ 20101 20102 int 20103 bcm_esw_port_ability_local_get(int unit, bcm_port_t port, 20104 bcm_port_ability_t *ability_mask) 20105 { 20106 int rv; 20107 #if defined(BCM_KATANA2_SUPPORT) 20108 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 20109 #endif 20110 20111 /* Make sure port module is initialized. */ 20112 PORT_INIT(unit); 20113 20114 20115 /* Call Port Control module */ 20116 if (SOC_USE_PORTCTRL(unit)) { 20117 return bcmi_esw_portctrl_ability_get(unit, port, 20118 ability_mask, NULL); 20119 } 20120 20121 if(bcm_common_oamp_port_enable_get(unit, port)) { 20122 LOG_ERROR(BSL_LS_BCM_PORT, 20123 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 20124 port)); 20125 return BCM_E_PARAM; 20126 } 20127 20128 #if defined(BCM_KATANA2_SUPPORT) 20129 #if defined(BCM_SABER2_SUPPORT) 20130 if(SOC_IS_SABER2(unit)) { 20131 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 20132 } 20133 #endif 20134 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 20135 (!((port >= 1) && (port <= max_phy_port)))) { 20136 return BCM_E_PORT; 20137 } 20138 #endif 20139 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20140 20141 sal_memset(ability_mask, 0, sizeof(bcm_port_ability_t)); 20142 PORT_LOCK(unit); 20143 rv = _bcm_port_ability_local_get(unit, port, ability_mask); 20144 PORT_UNLOCK(unit); 20145 20146 LOG_INFO(BSL_LS_BCM_PORT, 20147 (BSL_META_U(unit, 20148 "bcm_port_ability_local_get: u=%d p=%d rv=%d\n"), 20149 unit, port, rv)); 20150 LOG_VERBOSE(BSL_LS_BCM_PORT, 20151 (BSL_META_U(unit, 20152 "Speed(HD=0x%08x, FD=0x%08x) Pause=0x%08x local_get\n" 20153 "Interface=0x%08x Medium=0x%08x EEE=0x%08x Loopback=0x%08x Flags=0x%08x\n"), 20154 ability_mask->speed_half_duplex, 20155 ability_mask->speed_full_duplex, 20156 ability_mask->pause, ability_mask->interface, 20157 ability_mask->medium, ability_mask->eee, 20158 ability_mask->loopback, ability_mask->flags)); 20159 20160 return rv; 20161 } 20162 /* 20163 * Function: 20164 * bcm_port_speed_ability_local_get 20165 * Purpose: 20166 * Retrieve the local port abilities. 20167 * Parameters: 20168 * unit - StrataSwitch Unit #. 20169 * port - StrataSwitch port #. 20170 * max_num_ability -- the max num of speed ability this port support 20171 * ability - (OUT) values indicating the ability of the MAC/PHY 20172 * actual_num_ability - (OUT) the actual num of ability that this port can support 20173 * Returns: 20174 * BCM_E_NONE 20175 * BCM_E_XXX 20176 */ 20177 int 20178 bcm_esw_port_speed_ability_local_get(int unit, 20179 bcm_port_t port, 20180 int max_num_ability, 20181 bcm_port_speed_ability_t *abilities, 20182 int *actual_num_ability) 20183 { 20184 int rv = BCM_E_UNAVAIL; 20185 20186 /* Make sure port module is initialized. */ 20187 PORT_INIT(unit); 20188 20189 /* Call Port Control module */ 20190 if (SOC_USE_PORTCTRL(unit)) { 20191 rv = bcmi_esw_portctrl_speed_ability_local_get(unit, port, max_num_ability, 20192 abilities, actual_num_ability); 20193 } 20194 return rv; 20195 } 20196 20197 /* 20198 * Function: 20199 * bcm_port_discard_get 20200 * Purpose: 20201 * Get port discard attributes for the specified port 20202 * Parameters: 20203 * unit - StrataSwitch Unit #. 20204 * port - StrataSwitch port #. 20205 * mode - (OUT) Port discard mode, one of BCM_PORT_DISCARD_xxx 20206 * Returns: 20207 * BCM_E_NONE 20208 * BCM_E_XXX 20209 */ 20210 20211 int 20212 bcm_esw_port_discard_get(int unit, bcm_port_t port, int *mode) 20213 { 20214 bcm_port_cfg_t pcfg; 20215 int rv; 20216 20217 /* Make sure port module is initialized. */ 20218 PORT_INIT(unit); 20219 20220 if(bcm_common_oamp_port_enable_get(unit, port)) { 20221 LOG_ERROR(BSL_LS_BCM_PORT, 20222 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 20223 port)); 20224 return BCM_E_PARAM; 20225 } 20226 20227 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20228 20229 if ((rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)) == 20230 BCM_E_NONE) { 20231 *mode = pcfg.pc_disc; 20232 } 20233 20234 return(rv); 20235 } 20236 20237 /* 20238 * Function: 20239 * bcm_port_discard_set 20240 * Purpose: 20241 * Set port discard attributes for the specified port. 20242 * Parameters: 20243 * unit - StrataSwitch Unit #. 20244 * port - StrataSwitch port #. 20245 * mode - Port discard mode, one of BCM_PORT_DISCARD_xxx 20246 * Returns: 20247 * BCM_E_NONE 20248 * BCM_E_XXX 20249 */ 20250 20251 int 20252 bcm_esw_port_discard_set(int unit, bcm_port_t port, int mode) 20253 { 20254 bcm_port_cfg_t pcfg; 20255 int rv; 20256 20257 /* Make sure port module is initialized. */ 20258 PORT_INIT(unit); 20259 20260 if(bcm_common_oamp_port_enable_get(unit, port)) { 20261 LOG_ERROR(BSL_LS_BCM_PORT, 20262 (BSL_META("Error: Cannot set discard attr on OAMP Port %d.\n"), 20263 port)); 20264 return BCM_E_PARAM; 20265 } 20266 20267 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20268 20269 switch (mode) { 20270 case BCM_PORT_DISCARD_TAG: 20271 case BCM_PORT_DISCARD_NONE: 20272 case BCM_PORT_DISCARD_ALL: 20273 case BCM_PORT_DISCARD_UNTAG: 20274 break; 20275 default: 20276 return BCM_E_PARAM; 20277 } 20278 20279 PORT_LOCK(unit); 20280 20281 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 20282 20283 if (BCM_SUCCESS(rv)) { 20284 pcfg.pc_disc = mode; 20285 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg); 20286 } 20287 20288 PORT_UNLOCK(unit); 20289 20290 return rv; 20291 } 20292 20293 /* 20294 * Function: 20295 * _bcm_port_learn_modify 20296 * Purpose: 20297 * Main part of bcm_port_learn_modify. 20298 */ 20299 20300 STATIC int 20301 _bcm_port_learn_modify(int unit, bcm_port_t port, uint32 add, uint32 remove) 20302 { 20303 uint32 flags; 20304 20305 SOC_IF_ERROR_RETURN(bcm_esw_port_learn_get(unit, port, &flags)); 20306 20307 flags |= add; 20308 flags &= ~remove; 20309 20310 SOC_IF_ERROR_RETURN(bcm_esw_port_learn_set(unit, port, flags)); 20311 20312 return BCM_E_NONE; 20313 } 20314 20315 /* 20316 * Function: 20317 * bcm_port_learn_modify 20318 * Purpose: 20319 * Modify the port learn flags, adding add and removing remove flags. 20320 * Parameters: 20321 * unit - StrataSwitch Unit #. 20322 * port - StrataSwitch port #. 20323 * add - Flags to set. 20324 * remove - Flags to clear. 20325 * Returns: 20326 * BCM_E_NONE 20327 * BCM_E_XXX 20328 */ 20329 20330 int 20331 bcm_esw_port_learn_modify(int unit, bcm_port_t port, uint32 add, uint32 remove) 20332 { 20333 int rv; 20334 bcm_port_t port_out; 20335 20336 /* Make sure port module is initialized. */ 20337 PORT_INIT(unit); 20338 20339 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port_out)); 20340 20341 PORT_LOCK(unit); 20342 rv = _bcm_port_learn_modify(unit, port, add, remove); 20343 PORT_UNLOCK(unit); 20344 20345 return rv; 20346 } 20347 20348 /* 20349 * Function: 20350 * bcm_port_learn_get 20351 * Purpose: 20352 * Get the ARL hardware learning options for this port. 20353 * This defines what the hardware will do when a packet 20354 * is seen with an unknown address. 20355 * Parameters: 20356 * unit - StrataSwitch Unit #. 20357 * port - StrataSwitch port #. 20358 * flags - (OUT) Logical OR of BCM_PORT_LEARN_xxx flags 20359 * Returns: 20360 * BCM_E_NONE 20361 * BCM_E_XXX 20362 */ 20363 20364 int 20365 bcm_esw_port_learn_get(int unit, bcm_port_t port, uint32 *flags) 20366 { 20367 bcm_port_cfg_t pcfg; 20368 int rv; 20369 20370 /* Make sure port module is initialized. */ 20371 PORT_INIT(unit); 20372 20373 if(bcm_common_oamp_port_enable_get(unit, port)) { 20374 LOG_ERROR(BSL_LS_BCM_PORT, 20375 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 20376 port)); 20377 return BCM_E_PARAM; 20378 } 20379 20380 if (flags == NULL) { 20381 return BCM_E_PARAM; 20382 } 20383 20384 #if defined(BCM_TRX_SUPPORT) && defined(INCLUDE_L3) 20385 if (BCM_GPORT_IS_SUBPORT_GROUP(port)) { 20386 if (SOC_IS_SCORPION(unit)) { 20387 return BCM_E_UNAVAIL; 20388 } else { 20389 return bcm_tr_subport_learn_get(unit, (bcm_gport_t) port, flags); 20390 } 20391 } 20392 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */ 20393 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \ 20394 defined(INCLUDE_L3) 20395 if (BCM_GPORT_IS_MPLS_PORT(port)) { 20396 return bcm_tr_mpls_port_learn_get(unit, (bcm_gport_t) port, flags); 20397 } 20398 #endif 20399 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 20400 && defined(INCLUDE_L3)) 20401 if (BCM_GPORT_IS_MIM_PORT(port)) { 20402 return bcm_tr2_mim_port_learn_get(unit, (bcm_gport_t) port, flags); 20403 } 20404 if (BCM_GPORT_IS_WLAN_PORT(port)) { 20405 #if defined(BCM_TRIUMPH3_SUPPORT) 20406 if (SOC_IS_TRIUMPH3(unit)) { 20407 return bcm_tr3_wlan_port_learn_get(unit, (bcm_gport_t) port, flags); 20408 } else 20409 #endif /* BCM_TRIUMPH3_SUPPORT */ 20410 { 20411 return bcm_tr2_wlan_port_learn_get(unit, (bcm_gport_t) port, flags); 20412 } 20413 } 20414 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 20415 #if defined(BCM_TRIDENT_SUPPORT)&& defined(INCLUDE_L3) 20416 if (BCM_GPORT_IS_NIV_PORT(port)) { 20417 return bcm_trident_niv_port_learn_get(unit, (bcm_gport_t) port, flags); 20418 } 20419 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 20420 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 20421 if (SOC_IS_TD2_TT2(unit)) { 20422 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 20423 return bcm_td2_vxlan_port_learn_get(unit, (bcm_gport_t) port, flags); 20424 } 20425 } 20426 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 20427 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 20428 if (BCM_GPORT_IS_L2GRE_PORT(port)){ 20429 return bcm_tr3_l2gre_port_learn_get(unit, (bcm_gport_t) port, flags); 20430 } 20431 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 20432 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 20433 if (BCM_GPORT_IS_EXTENDER_PORT(port)){ 20434 if (soc_feature(unit, soc_feature_port_extension)) { 20435 return bcm_tr3_extender_port_learn_get(unit, port, flags); 20436 } 20437 } 20438 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 20439 #if defined(BCM_HGPROXY_COE_SUPPORT) && defined(INCLUDE_L3) 20440 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 20441 BCM_GPORT_IS_SUBPORT_PORT(port)) { 20442 return bcmi_xgs5_subport_port_learn_get(unit, (bcm_gport_t) port, flags); 20443 } 20444 #endif /* BCM_HGPROXY_COE_SUPPORT && INCLUDE_L3 */ 20445 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 20446 if (BCM_GPORT_IS_TRUNK(port)){ 20447 if (soc_feature(unit, soc_feature_vp_lag)) { 20448 return bcm_td2_vp_lag_port_learn_get(unit, 20449 BCM_GPORT_TRUNK_GET(port), flags); 20450 } 20451 } 20452 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 20453 20454 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20455 20456 PORT_LOCK(unit); 20457 20458 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 20459 20460 PORT_UNLOCK(unit); 20461 20462 BCM_IF_ERROR_RETURN(rv); 20463 20464 #ifdef BCM_TRX_SUPPORT 20465 if (SOC_IS_TRX(unit)) { 20466 *flags = 0; 20467 BCM_IF_ERROR_RETURN( 20468 _bcm_trx_port_cml_hw2flags(unit, pcfg.pc_cml, flags)); 20469 } else 20470 #endif 20471 { 20472 switch (pcfg.pc_cml) { 20473 case PVP_CML_SWITCH: 20474 *flags = (BCM_PORT_LEARN_ARL | 20475 BCM_PORT_LEARN_FWD | 20476 (pcfg.pc_cpu ? BCM_PORT_LEARN_CPU : 0)); 20477 break; 20478 case PVP_CML_CPU: 20479 *flags = BCM_PORT_LEARN_CPU; 20480 break; 20481 case PVP_CML_FORWARD: 20482 *flags = BCM_PORT_LEARN_FWD; 20483 break; 20484 case PVP_CML_DROP: 20485 *flags = 0; 20486 break; 20487 case PVP_CML_CPU_SWITCH: 20488 *flags = (BCM_PORT_LEARN_ARL | 20489 BCM_PORT_LEARN_CPU | 20490 BCM_PORT_LEARN_FWD); 20491 break; 20492 case PVP_CML_CPU_FORWARD: 20493 *flags = BCM_PORT_LEARN_CPU | BCM_PORT_LEARN_FWD; 20494 break; 20495 default: 20496 return BCM_E_INTERNAL; 20497 } 20498 } 20499 20500 return BCM_E_NONE; 20501 } 20502 20503 /* 20504 * Function: 20505 * bcm_port_learn_set 20506 * Purpose: 20507 * Set the ARL hardware learning options for this port. 20508 * This defines what the hardware will do when a packet 20509 * is seen with an unknown address. 20510 * Parameters: 20511 * unit - StrataSwitch Unit #. 20512 * port - StrataSwitch port #. 20513 * flags - Logical OR of BCM_PORT_LEARN_xxx flags 20514 * Returns: 20515 * BCM_E_NONE 20516 * BCM_E_XXX 20517 */ 20518 20519 #define Arl BCM_PORT_LEARN_ARL 20520 #define Cpu BCM_PORT_LEARN_CPU 20521 #define Fwd BCM_PORT_LEARN_FWD 20522 20523 int 20524 bcm_esw_port_learn_set(int unit, bcm_port_t port, uint32 flags) 20525 { 20526 bcm_port_cfg_t pcfg; 20527 int rv; 20528 20529 /* Make sure port module is initialized. */ 20530 PORT_INIT(unit); 20531 20532 if(bcm_common_oamp_port_enable_get(unit, port)) { 20533 LOG_ERROR(BSL_LS_BCM_PORT, 20534 (BSL_META("Error: Not permitted on OAMP Port %d.\n"), 20535 port)); 20536 return BCM_E_PARAM; 20537 } 20538 20539 #if defined(BCM_TRX_SUPPORT) && defined(INCLUDE_L3) 20540 if (BCM_GPORT_IS_SUBPORT_GROUP(port)) { 20541 if (SOC_IS_SCORPION(unit)) { 20542 return BCM_E_UNAVAIL; 20543 } else { 20544 return bcm_tr_subport_learn_set(unit, (bcm_gport_t) port, flags); 20545 } 20546 } 20547 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */ 20548 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \ 20549 defined(INCLUDE_L3) 20550 if (BCM_GPORT_IS_MPLS_PORT(port)) { 20551 return bcm_tr_mpls_port_learn_set(unit, (bcm_gport_t) port, flags); 20552 } 20553 #endif 20554 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 20555 && defined(INCLUDE_L3)) 20556 if (BCM_GPORT_IS_MIM_PORT(port)) { 20557 return bcm_tr2_mim_port_learn_set(unit, (bcm_gport_t) port, flags); 20558 } 20559 if (BCM_GPORT_IS_VLAN_PORT(port)) { 20560 if (soc_feature(unit, soc_feature_vlan_vp)) { 20561 return bcm_tr2_vlan_port_learn_set(unit, (bcm_gport_t) port, flags); 20562 } 20563 } 20564 if (BCM_GPORT_IS_WLAN_PORT(port)) { 20565 #if defined(BCM_TRIUMPH3_SUPPORT) 20566 if (SOC_IS_TRIUMPH3(unit)) { 20567 return bcm_tr3_wlan_port_learn_set(unit, (bcm_gport_t) port, flags); 20568 } else 20569 #endif /* BCM_TRIUMPH3_SUPPORT */ 20570 { 20571 return bcm_tr2_wlan_port_learn_set(unit, (bcm_gport_t) port, flags); 20572 } 20573 } 20574 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 20575 #if defined(BCM_TRIDENT_SUPPORT)&& defined(INCLUDE_L3) 20576 if (BCM_GPORT_IS_NIV_PORT(port)) { 20577 return bcm_trident_niv_port_learn_set(unit, (bcm_gport_t) port, flags); 20578 } 20579 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 20580 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 20581 if (SOC_IS_TD2_TT2(unit)) { 20582 if (BCM_GPORT_IS_VXLAN_PORT(port)){ 20583 return bcm_td2_vxlan_port_learn_set(unit, (bcm_gport_t) port, flags); 20584 } 20585 } 20586 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 20587 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 20588 if (BCM_GPORT_IS_L2GRE_PORT(port)){ 20589 return bcm_tr3_l2gre_port_learn_set(unit, (bcm_gport_t) port, flags); 20590 } 20591 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 20592 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 20593 if (BCM_GPORT_IS_EXTENDER_PORT(port)){ 20594 if (soc_feature(unit, soc_feature_port_extension)) { 20595 return bcm_tr3_extender_port_learn_set(unit, port, flags); 20596 } 20597 } 20598 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 20599 #if defined(BCM_HGPROXY_COE_SUPPORT) && defined(INCLUDE_L3) 20600 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 20601 BCM_GPORT_IS_SUBPORT_PORT(port)) { 20602 return bcmi_xgs5_subport_port_learn_set(unit, (bcm_gport_t) port, flags); 20603 } 20604 #endif /* BCM_HGPROXY_COE_SUPPORT && INCLUDE_L3 */ 20605 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 20606 if (BCM_GPORT_IS_TRUNK(port)){ 20607 if (soc_feature(unit, soc_feature_vp_lag)) { 20608 return bcm_td2_vp_lag_port_learn_set(unit, 20609 BCM_GPORT_TRUNK_GET(port), flags); 20610 } 20611 } 20612 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 20613 20614 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 20615 20616 if (flags & BCM_PORT_LEARN_PENDING) { 20617 if (!soc_feature(unit, soc_feature_l2_pending)) { 20618 return BCM_E_UNAVAIL; 20619 } else if (!IS_CPU_PORT(unit, port) & (!(flags & BCM_PORT_LEARN_ARL))) { 20620 /* When the PENDING flag is set, the ARL must also be set */ 20621 return BCM_E_PARAM; 20622 } 20623 } 20624 20625 PORT_LOCK(unit); 20626 20627 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg); 20628 20629 pcfg.pc_cpu = ((flags & BCM_PORT_LEARN_CPU) != 0); 20630 20631 /* Use shortened names to handle each flag combination individually */ 20632 20633 #ifdef BCM_TRX_SUPPORT 20634 if (SOC_IS_TRX(unit)) { 20635 pcfg.pc_cml = 0; 20636 rv = _bcm_trx_port_cml_flags2hw(unit, flags, (uint32 *)&pcfg.pc_cml); 20637 if (BCM_FAILURE(rv)) { 20638 PORT_UNLOCK(unit); 20639 return (rv); 20640 } 20641 } else 20642 #endif 20643 { 20644 switch (flags) { 20645 case ((!Arl) | (!Cpu) | (!Fwd)): 20646 pcfg.pc_cml = PVP_CML_DROP; 20647 break; 20648 case ((!Arl) | (!Cpu) | ( Fwd)): 20649 pcfg.pc_cml = PVP_CML_FORWARD; 20650 break; 20651 case ((!Arl) | ( Cpu) | (!Fwd)): 20652 pcfg.pc_cml = PVP_CML_CPU; 20653 break; 20654 case ((!Arl) | ( Cpu) | ( Fwd)): 20655 if (SOC_IS_XGS_SWITCH(unit)) { 20656 pcfg.pc_cml = PVP_CML_CPU_FORWARD; 20657 } else { 20658 rv = BCM_E_UNAVAIL; 20659 } 20660 break; 20661 case (( Arl) | (!Cpu) | (!Fwd)): 20662 rv = BCM_E_UNAVAIL; 20663 break; 20664 case (( Arl) | (!Cpu) | ( Fwd)): 20665 pcfg.pc_cml = PVP_CML_SWITCH; 20666 break; 20667 case (( Arl) | ( Cpu) | (!Fwd)): 20668 rv = BCM_E_UNAVAIL; 20669 break; 20670 case (( Arl) | ( Cpu) | ( Fwd)): 20671 if (SOC_IS_XGS_SWITCH(unit)) { 20672 pcfg.pc_cml = PVP_CML_CPU_SWITCH; 20673 } else { 20674 pcfg.pc_cml = PVP_CML_SWITCH; /* pc_cpu also being set */ 20675 } 20676 break; 20677 } 20678 } 20679 20680 if (BCM_SUCCESS(rv)) { 20681 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg); 20682 } 20683 20684 PORT_UNLOCK(unit); 20685 20686 return rv; 20687 } 20688 20689 #undef Arl 20690 #undef Cpu 20691 #undef Fwd 20692 20693 /* 20694 * Function: 20695 * bcm_port_ifilter_get 20696 * Description: 20697 * Return input filter mode for a port. 20698 * Parameters: 20699 * unit - StrataSwitch PCI device unit number (driver internal). 20700 * port - Port number to operate on 20701 * mode - (OUT) Filter mode, 1 is enable; 0 is disable. 20702 * Returns: 20703 * BCM_E_NONE Success. 20704 * BCM_E_INTERNAL Chip access failure. 20705 * Notes: 20706 * This API is superseded by bcm_port_vlan_member_get. 20707 */ 20708 20709 int 20710 bcm_esw_port_ifilter_get(int unit, bcm_port_t port, int *mode) 20711 { 20712 int rv; 20713 uint32 flags; 20714 20715 /* Make sure port module is initialized. */ 20716 PORT_INIT(unit); 20717 20718 rv = bcm_esw_port_vlan_member_get(unit, port, &flags); 20719 20720 if (BCM_SUCCESS(rv)) { 20721 *mode = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? 1 : 0; 20722 } 20723 20724 return rv; 20725 } 20726 20727 /* 20728 * Function: 20729 * bcm_port_ifilter_set 20730 * Description: 20731 * Set input filter mode for a port. 20732 * Parameters: 20733 * unit - StrataSwitch PCI device unit number (driver internal). 20734 * port - Port number to operate on 20735 * mode - 1 to enable, 0 to disable. 20736 * Returns: 20737 * BCM_E_NONE Success. 20738 * BCM_E_INTERNAL Chip access failure. 20739 * Notes: 20740 * This API is superseded by bcm_port_vlan_member_set. 20741 * 20742 * When input filtering is turned on for a port, packets received 20743 * on the port that do not match the port's VLAN classifications 20744 * are discarded. 20745 */ 20746 20747 int 20748 bcm_esw_port_ifilter_set(int unit, bcm_port_t port, int mode) 20749 { 20750 uint32 flags; 20751 20752 /* Make sure port module is initialized. */ 20753 PORT_INIT(unit); 20754 20755 BCM_IF_ERROR_RETURN(bcm_esw_port_vlan_member_get(unit, port, &flags)); 20756 20757 if (mode) { 20758 flags |= BCM_PORT_VLAN_MEMBER_INGRESS; 20759 } else { 20760 flags &= (~BCM_PORT_VLAN_MEMBER_INGRESS); 20761 } 20762 20763 return bcm_esw_port_vlan_member_set(unit, port, flags); 20764 } 20765 20766 /* 20767 * Function: 20768 * bcm_esw_port_vlan_member_get 20769 * Description: 20770 * Return filter mode for a port. 20771 * Parameters: 20772 * unit - StrataSwitch PCI device unit number (driver internal). 20773 * port - Port number to operate on 20774 * flags - (OUT) Filter mode, one of BCM_PORT_VLAN_MEMBER_xxx. 20775 * Returns: 20776 * BCM_E_NONE Success. 20777 * BCM_E_INTERNAL Chip access failure. 20778 */ 20779 20780 int 20781 bcm_esw_port_vlan_member_get(int unit, bcm_port_t port, uint32 *flags) 20782 { 20783 int rv = BCM_E_UNAVAIL; 20784 20785 *flags = 0; 20786 20787 /* Make sure port module is initialized. */ 20788 PORT_INIT(unit); 20789 20790 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 20791 if (BCMI_GPORT_TYPE_VALID(port)) { 20792 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 20793 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 20794 return bcm_td2p_vp_vlan_member_get(unit, port, flags); 20795 } else 20796 #endif 20797 { 20798 return bcm_td_vp_vlan_member_get(unit, port, flags); 20799 } 20800 } else 20801 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 20802 if (BCM_GPORT_IS_WLAN_PORT(port)) { 20803 rv = BCM_E_NONE; 20804 } else { 20805 rv = _bcm_esw_port_gport_validate(unit, port, &port); 20806 } 20807 BCM_IF_ERROR_RETURN(rv); 20808 rv = BCM_E_UNAVAIL; 20809 20810 switch (BCM_CHIP_FAMILY(unit)) { 20811 20812 case BCM_FAMILY_HERCULES: 20813 rv = BCM_E_NONE; 20814 break; 20815 20816 case BCM_FAMILY_FIREBOLT: 20817 case BCM_FAMILY_BRADLEY: 20818 case BCM_FAMILY_HUMV: 20819 case BCM_FAMILY_TRIUMPH: 20820 case BCM_FAMILY_SCORPION: 20821 case BCM_FAMILY_CONQUEROR: 20822 case BCM_FAMILY_TRIUMPH2: 20823 case BCM_FAMILY_TRIDENT: 20824 case BCM_FAMILY_TITAN: 20825 case BCM_FAMILY_KATANA: 20826 if (SOC_IS_XGS12_SWITCH(unit) && IS_HG_PORT(unit, port)) { 20827 rv = BCM_E_NONE; 20828 } else { 20829 uint32 ent[SOC_MAX_MEM_FIELD_WORDS]; 20830 soc_mem_t mem; 20831 soc_field_t field = EN_EFILTERf; 20832 20833 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 20834 && defined(INCLUDE_L3)) 20835 if (BCM_GPORT_IS_WLAN_PORT(port)) { 20836 int value; 20837 if (!soc_feature(unit, soc_feature_wlan)) { 20838 return BCM_E_PORT; 20839 } 20840 #if defined(BCM_TRIUMPH3_SUPPORT) 20841 if (SOC_IS_TRIUMPH3(unit)) { 20842 rv = bcm_tr3_wlan_lport_field_get(unit, port, 20843 EN_IFILTERf, &value); 20844 } else 20845 #endif /* BCM_TRIUMPH3_SUPPORT */ 20846 { 20847 rv = bcm_tr2_wlan_lport_field_get(unit, port, 20848 EN_IFILTERf, &value); 20849 } 20850 if (value) { 20851 *flags |= BCM_PORT_VLAN_MEMBER_INGRESS; 20852 } 20853 return rv; 20854 } 20855 #endif 20856 20857 mem = SOC_PORT_MEM_TAB(unit, port); 20858 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 20859 #ifdef BCM_TRIDENT3_SUPPORT 20860 int value; 20861 rv = _bcm_esw_port_tab_get(unit, port, EN_IFILTERf, &value); 20862 if (rv == BCM_E_NONE) { 20863 if(value) { 20864 *flags |= BCM_PORT_VLAN_MEMBER_INGRESS; 20865 if (value == 2) { 20866 *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP; 20867 } 20868 } 20869 } 20870 #endif 20871 } else { 20872 uint32 value = 0; 20873 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 20874 SOC_PORT_MOD_OFFSET(unit, port), &ent); 20875 20876 if (BCM_SUCCESS(rv)) { 20877 value = soc_PORT_TABm_field32_get(unit, &ent, EN_IFILTERf); 20878 if (value) { 20879 *flags |= BCM_PORT_VLAN_MEMBER_INGRESS; 20880 if (value == 2) { 20881 *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP; 20882 } 20883 } 20884 } 20885 } 20886 20887 #ifdef BCM_TRIDENT_SUPPORT 20888 mem = EGR_PORTm; 20889 field = EN_EFILTERf; 20890 #ifdef BCM_TRIDENT3_SUPPORT 20891 if (SOC_IS_TRIDENT3X(unit)) { 20892 int val = 0; 20893 rv = _bcm_esw_egr_port_tab_get(unit, port, field, &val); 20894 if (BCM_SUCCESS(rv) && val != 0) { 20895 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS; 20896 if(val == 2) { 20897 *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP; 20898 } 20899 } 20900 } else 20901 #endif 20902 if (SOC_MEM_IS_VALID(unit, mem)) { 20903 int val = 0; 20904 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, &ent); 20905 val = soc_mem_field32_get(unit, mem, &ent, field); 20906 if (BCM_SUCCESS(rv) && val) { 20907 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS; 20908 if(val == 2) { 20909 *flags |= BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP; 20910 } 20911 } 20912 } else 20913 #endif /* BCM_TRIDENT_SUPPORT */ 20914 if (SOC_IS_XGS3_SWITCH(unit)) { 20915 uint32 egr_val; 20916 uint64 egr_val64; 20917 if (SOC_REG_IS_VALID(unit, EGR_PORTr)) { 20918 rv = READ_EGR_PORTr(unit, port, &egr_val); 20919 } else { 20920 rv = READ_EGR_PORT_64r(unit, port, &egr_val64); 20921 } 20922 if (BCM_SUCCESS(rv)) { 20923 if (SOC_REG_IS_VALID(unit, EGR_PORTr)) { 20924 if (soc_reg_field_valid(unit, EGR_PORTr, field)) { 20925 if (soc_reg_field_get(unit, EGR_PORTr, 20926 egr_val, field)) { 20927 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS; 20928 } 20929 } 20930 } else if (soc_reg64_field32_get(unit, 20931 EGR_PORT_64r, egr_val64, field)) { 20932 *flags |= BCM_PORT_VLAN_MEMBER_EGRESS; 20933 } 20934 } 20935 } 20936 } 20937 break; 20938 20939 default: 20940 break; 20941 } 20942 20943 return rv; 20944 } 20945 20946 /* 20947 * Function: 20948 * bcm_esw_port_vlan_member_set 20949 * Description: 20950 * Set ingress and egress filter mode for a port. 20951 * Parameters: 20952 * unit - StrataSwitch PCI device unit number (driver internal). 20953 * port - Port number to operate on 20954 * flags - BCM_PORT_VLAN_MEMBER_xxx. 20955 * Returns: 20956 * BCM_E_NONE Success. 20957 * BCM_E_INTERNAL Chip access failure. 20958 */ 20959 20960 int 20961 bcm_esw_port_vlan_member_set(int unit, bcm_port_t port, uint32 flags) 20962 { 20963 int rv = BCM_E_UNAVAIL; 20964 int fieldLen = 0; 20965 20966 /* Make sure port module is initialized. */ 20967 PORT_INIT(unit); 20968 20969 if(bcm_common_oamp_port_enable_get(unit, port)) { 20970 LOG_ERROR(BSL_LS_BCM_PORT, 20971 (BSL_META("Error: Not permitted on OAMP Port %d.\n"), 20972 port)); 20973 return BCM_E_PARAM; 20974 } 20975 20976 if (BCMI_GPORT_TYPE_VALID(port)) { 20977 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 20978 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 20979 if (soc_feature(unit, soc_feature_vlan_vfi_membership)) { 20980 rv = bcm_td2p_vp_vlan_member_set(unit, port, flags); 20981 } else 20982 #endif 20983 { 20984 rv = bcm_td_vp_vlan_member_set(unit, port, flags); 20985 } 20986 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 20987 return rv; 20988 } else if (BCM_GPORT_IS_WLAN_PORT(port)) { 20989 rv = BCM_E_NONE; 20990 } else { 20991 rv = _bcm_esw_port_gport_validate(unit, port, &port); 20992 } 20993 BCM_IF_ERROR_RETURN(rv); 20994 rv = BCM_E_UNAVAIL; 20995 20996 PORT_LOCK(unit); 20997 20998 switch (BCM_CHIP_FAMILY(unit)) { 20999 21000 case BCM_FAMILY_HERCULES: 21001 rv = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? BCM_E_UNAVAIL : 21002 ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) ? BCM_E_UNAVAIL : BCM_E_NONE); 21003 break; 21004 21005 case BCM_FAMILY_FIREBOLT: 21006 case BCM_FAMILY_BRADLEY: 21007 case BCM_FAMILY_HUMV: 21008 case BCM_FAMILY_TRIUMPH: 21009 case BCM_FAMILY_SCORPION: 21010 case BCM_FAMILY_CONQUEROR: 21011 case BCM_FAMILY_TRIUMPH2: 21012 case BCM_FAMILY_TRIDENT: 21013 case BCM_FAMILY_TITAN: 21014 case BCM_FAMILY_KATANA: 21015 if (SOC_IS_XGS12_SWITCH(unit) && IS_HG_PORT(unit, port)) { 21016 rv = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? BCM_E_UNAVAIL : 21017 ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) ? BCM_E_UNAVAIL : 21018 BCM_E_NONE); 21019 } else { 21020 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 21021 && defined(INCLUDE_L3)) 21022 21023 if (BCM_GPORT_IS_WLAN_PORT(port)) { 21024 if (!soc_feature(unit, soc_feature_wlan)) { 21025 PORT_UNLOCK(unit); 21026 return BCM_E_PORT; 21027 } 21028 if (flags & BCM_PORT_VLAN_MEMBER_INGRESS) { 21029 #if defined(BCM_TRIUMPH3_SUPPORT) 21030 if (SOC_IS_TRIUMPH3(unit)) { 21031 rv = _bcm_tr3_wlan_port_set(unit, port, EN_IFILTERf, 1); 21032 } else 21033 #endif /* BCM_TRIUMPH3_SUPPORT */ 21034 { 21035 rv = _bcm_tr2_wlan_port_set(unit, port, EN_IFILTERf, 1); 21036 } 21037 } else { 21038 #if defined(BCM_TRIUMPH3_SUPPORT) 21039 if (SOC_IS_TRIUMPH3(unit)) { 21040 rv = _bcm_tr3_wlan_port_set(unit, port, EN_IFILTERf, 0); 21041 } else 21042 #endif /* BCM_TRIUMPH3_SUPPORT */ 21043 { 21044 rv = _bcm_tr2_wlan_port_set(unit, port, EN_IFILTERf, 0); 21045 } 21046 } 21047 PORT_UNLOCK(unit); 21048 return rv; 21049 } 21050 #endif 21051 if (SOC_MEM_IS_VALID(unit, PORT_TABm) && 21052 SOC_MEM_FIELD_VALID(unit, PORT_TABm, EN_IFILTERf)) { 21053 fieldLen = soc_mem_field_length(unit, PORT_TABm, EN_IFILTERf); 21054 } else if (SOC_MEM_IS_VALID(unit, LPORT_TABm) && 21055 SOC_MEM_FIELD_VALID(unit, LPORT_TABm, EN_IFILTERf)) { 21056 fieldLen = soc_mem_field_length(unit, LPORT_TABm, EN_IFILTERf); 21057 } 21058 if (fieldLen > 0) { 21059 /* value = 2 requires EN_IFILTERf to have 2 bits. In some 21060 * chips the field only has 1 bit */ 21061 if ((flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) && 21062 fieldLen == 1) { 21063 PORT_UNLOCK(unit); 21064 return BCM_E_PARAM; 21065 } 21066 } 21067 21068 if (SOC_MEM_IS_VALID(unit, ING_DEVICE_PORTm)) { 21069 int value = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? 1 : 0; 21070 if (soc_feature(unit, soc_feature_vlan_vfi_membership) && 21071 (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 21072 if (value == 1) { 21073 value = 2; 21074 } 21075 } 21076 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 21077 EN_IFILTERf, value); 21078 } else { 21079 int value = (flags & BCM_PORT_VLAN_MEMBER_INGRESS) ? 1 : 0; 21080 if (soc_feature(unit, soc_feature_vlan_vfi_membership) && 21081 (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 21082 if (value == 1) { 21083 value = 2; 21084 } 21085 } 21086 rv = _bcm_esw_port_tab_set(unit, port, 0, EN_IFILTERf, value); 21087 } 21088 21089 #ifdef BCM_TRIDENT_SUPPORT 21090 if (SOC_MEM_IS_VALID(unit, ING_EN_EFILTER_BITMAPm)) { 21091 uint32 efilter; 21092 ing_en_efilter_bitmap_entry_t entry; 21093 pbmp_t pbmp; 21094 21095 if (SOC_MEM_IS_VALID(unit, EGR_PORTm) && 21096 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EN_EFILTERf)) { 21097 fieldLen = soc_mem_field_length(unit, EGR_PORTm, EN_EFILTERf); 21098 } else if (SOC_MEM_IS_VALID(unit, EGR_LPORT_PROFILEm) && 21099 SOC_MEM_FIELD_VALID(unit, EGR_LPORT_PROFILEm, EN_EFILTERf)) { 21100 fieldLen = soc_mem_field_length(unit, EGR_LPORT_PROFILEm, EN_EFILTERf); 21101 } 21102 if (fieldLen > 0) { 21103 /* value = 2 requires EN_EFILTERf to have 2 bits. In some 21104 * chips the field only has 1 bit */ 21105 if ((flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP) && 21106 fieldLen == 1) { 21107 PORT_UNLOCK(unit); 21108 return BCM_E_PARAM; 21109 } 21110 } 21111 21112 efilter = flags & BCM_PORT_VLAN_MEMBER_EGRESS ? 1 : 0; 21113 if((efilter == 1) && (flags & BCM_PORT_VLAN_MEMBER_VP_VLAN_MEMBERSHIP)) { 21114 efilter = 2; 21115 } 21116 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EGR_LPORT_PROFILE_IDXf)) { 21117 rv = _bcm_esw_egr_port_tab_set(unit, port, EN_EFILTERf, 21118 efilter); 21119 } else { 21120 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, EN_EFILTERf, 21121 efilter); 21122 } 21123 if (BCM_SUCCESS(rv)) { 21124 rv = soc_mem_read(unit, ING_EN_EFILTER_BITMAPm, 21125 MEM_BLOCK_ANY, 0, &entry); 21126 } 21127 if (BCM_SUCCESS(rv)) { 21128 soc_mem_pbmp_field_get(unit, ING_EN_EFILTER_BITMAPm, 21129 &entry, BITMAPf, &pbmp); 21130 if (efilter && PORT(unit, port).vp_count == 0) { 21131 SOC_PBMP_PORT_ADD(pbmp, port); 21132 } else { 21133 SOC_PBMP_PORT_REMOVE(pbmp, port); 21134 } 21135 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, 21136 &entry, BITMAPf, &pbmp); 21137 rv = soc_mem_write(unit, ING_EN_EFILTER_BITMAPm, 21138 MEM_BLOCK_ANY, 0, &entry); 21139 } 21140 } else 21141 #endif /* BCM_TRIDENT_SUPPORT */ 21142 if (SOC_IS_XGS3_SWITCH(unit)) { 21143 soc_reg_t egr_port_reg; 21144 egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 21145 SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) || 21146 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ? 21147 EGR_PORT_64r : EGR_PORTr; 21148 rv = soc_reg_field32_modify(unit, egr_port_reg, port, EN_EFILTERf, 21149 (flags & BCM_PORT_VLAN_MEMBER_EGRESS) ? 1 : 0); 21150 if (BCM_SUCCESS(rv)) { 21151 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 21152 defined(BCM_SCORPION_SUPPORT) 21153 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || 21154 SOC_IS_SC_CQ(unit) || SOC_IS_HAWKEYE(unit)) { 21155 uint32 egr_val; 21156 pbmp_t pbmp; 21157 uint32 bitmap, pbmp32; 21158 21159 rv = READ_ING_EN_EFILTER_BITMAPr(unit, &egr_val); 21160 if (BCM_SUCCESS(rv)) { 21161 SOC_PBMP_PORT_SET(pbmp, port); 21162 pbmp32 = SOC_PBMP_WORD_GET(pbmp, 0); 21163 bitmap = 21164 soc_reg_field_get(unit, 21165 ING_EN_EFILTER_BITMAPr, 21166 egr_val, BITMAPf); 21167 if (flags & BCM_PORT_VLAN_MEMBER_EGRESS) { 21168 bitmap |= pbmp32; 21169 } else { 21170 bitmap &= ~pbmp32; 21171 } 21172 soc_reg_field_set(unit, ING_EN_EFILTER_BITMAPr, 21173 &egr_val, BITMAPf, bitmap); 21174 rv = WRITE_ING_EN_EFILTER_BITMAPr(unit, egr_val); 21175 } 21176 } 21177 #endif /* BCM_FIREBOLT_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 21178 #if defined(BCM_TRIUMPH_SUPPORT) 21179 /* Do this only if there is no VP on this port */ 21180 if (soc_feature (unit, soc_feature_high_portcount_register)) { 21181 /* 21182 * pbmp reg split to multiple reg due to high port count 21183 * Note : 21184 * - ING_EN_EFILTER_BITMAP_64r here is split to 21185 * {ING_EN_EFILTER_BITMAP_LOr + ING_EN_EFILTER_BITMAP_HIr} 21186 */ 21187 uint64 fval64, rval64; 21188 uint32 t_port; 21189 soc_reg_t reg; 21190 pbmp_t curr_pbmp; 21191 21192 BCM_PBMP_CLEAR(curr_pbmp); 21193 COMPILER_64_ZERO(fval64); 21194 COMPILER_64_ZERO(rval64); 21195 21196 if (port < 64) { 21197 reg = ING_EN_EFILTER_BITMAP_LOr; 21198 t_port = port; 21199 } else { 21200 reg = ING_EN_EFILTER_BITMAP_HIr; 21201 t_port = port - 64; 21202 } 21203 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64); 21204 if (BCM_SUCCESS(rv)) { 21205 fval64 = soc_reg64_field_get(unit, reg, 21206 rval64, BITMAPf); 21207 SOC_PBMP_WORD_SET(curr_pbmp, 0, 21208 COMPILER_64_LO(fval64)); 21209 SOC_PBMP_WORD_SET(curr_pbmp, 1, 21210 COMPILER_64_HI(fval64)); 21211 21212 if ((flags & BCM_PORT_VLAN_MEMBER_EGRESS)){ 21213 SOC_PBMP_PORT_ADD(curr_pbmp, t_port); 21214 } else { 21215 SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port); 21216 } 21217 21218 COMPILER_64_SET(fval64, 21219 SOC_PBMP_WORD_GET(curr_pbmp, 1), 21220 SOC_PBMP_WORD_GET(curr_pbmp, 0)); 21221 soc_reg64_field_set(unit, reg, &rval64, 21222 BITMAPf, fval64); 21223 rv = soc_reg_set(unit, reg, 21224 REG_PORT_ANY, 0, rval64); 21225 } 21226 } else if (SOC_IS_TR_VL(unit)) { 21227 uint64 egr_val_64; 21228 pbmp_t pbmp; 21229 uint32 bitmap, pbmp32; 21230 21231 rv = READ_ING_EN_EFILTER_BITMAP_64r(unit, &egr_val_64); 21232 if (BCM_SUCCESS(rv)) { 21233 SOC_PBMP_PORT_SET(pbmp, port); 21234 /* Low bitmap */ 21235 bitmap = 21236 soc_reg64_field32_get(unit, 21237 ING_EN_EFILTER_BITMAP_64r, 21238 egr_val_64, BITMAP_LOf); 21239 pbmp32 = SOC_PBMP_WORD_GET(pbmp, 0); 21240 if ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) && 21241 (PORT(unit, port).vp_count == 0)) { 21242 bitmap |= pbmp32; 21243 } else { 21244 bitmap &= ~pbmp32; 21245 } 21246 soc_reg64_field32_set(unit, ING_EN_EFILTER_BITMAP_64r, 21247 &egr_val_64, BITMAP_LOf, bitmap); 21248 21249 if(!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 21250 !SOC_IS_GREYHOUND(unit)) { 21251 /* High bitmap */ 21252 bitmap = 21253 soc_reg64_field32_get(unit, 21254 ING_EN_EFILTER_BITMAP_64r, 21255 egr_val_64, BITMAP_HIf); 21256 pbmp32 = SOC_PBMP_WORD_GET(pbmp, 1); 21257 if ((flags & BCM_PORT_VLAN_MEMBER_EGRESS) && 21258 (PORT(unit, port).vp_count == 0)) { 21259 bitmap |= pbmp32; 21260 } else { 21261 bitmap &= ~pbmp32; 21262 } 21263 soc_reg64_field32_set(unit, ING_EN_EFILTER_BITMAP_64r, 21264 &egr_val_64, BITMAP_HIf, bitmap); 21265 } 21266 21267 rv = WRITE_ING_EN_EFILTER_BITMAP_64r(unit, egr_val_64); 21268 } 21269 } 21270 #endif 21271 } 21272 } 21273 } 21274 break; 21275 21276 default: 21277 break; 21278 } 21279 21280 PORT_UNLOCK(unit); 21281 21282 return rv; 21283 } 21284 21285 /* 21286 * Function: 21287 * _bcm_port_link_get 21288 * Purpose: 21289 * Return current PHY up/down status 21290 * Parameters: 21291 * unit - StrataSwitch Unit #. 21292 * port - StrataSwitch port #. 21293 * hw - If TRUE, assume hardware linkscan is active and use it 21294 * to reduce PHY reads. 21295 * If FALSE, do not use information from hardware linkscan. 21296 * up - (OUT) TRUE for link up, FALSE for link down. 21297 * Returns: 21298 * BCM_E_NONE 21299 * BCM_E_XXX 21300 */ 21301 21302 int 21303 _bcm_port_link_get(int unit, bcm_port_t port, int hw, int *up) 21304 { 21305 int rv = 0; 21306 #if defined(BCM_KATANA2_SUPPORT) 21307 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 21308 #endif 21309 21310 if (SOC_USE_PORTCTRL(unit)) { 21311 return bcmi_esw_portctrl_link_get(unit, port, hw, up); 21312 } 21313 21314 #if defined(BCM_KATANA2_SUPPORT) 21315 #if defined(BCM_SABER2_SUPPORT) 21316 if(SOC_IS_SABER2(unit)) { 21317 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 21318 } 21319 #endif 21320 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 21321 (!((port >= 1) && (port <= max_phy_port)))) { 21322 return BCM_E_PORT; 21323 } 21324 #endif 21325 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 21326 21327 PORT_LOCK(unit); 21328 21329 if (hw) { 21330 pbmp_t hw_linkstat; 21331 21332 rv = soc_linkscan_hw_link_get(unit, &hw_linkstat); 21333 21334 *up = PBMP_MEMBER(hw_linkstat, port); 21335 21336 /* 21337 * We need to confirm link down because we may receive false link 21338 * change interrupts when hardware and software linkscan are mixed. 21339 * Processing a false link down event is known to cause packet 21340 * loss, which is obviously unacceptable. 21341 */ 21342 if(!(*up)) { 21343 rv = soc_phyctrl_link_get(unit, port, up); 21344 } 21345 } else { 21346 if (SOC_IS_RCPU_ONLY(unit)) { 21347 rv = MAC_ENABLE_GET(PORT(unit, port).p_mac, unit, port, up); 21348 } else { 21349 rv = soc_phyctrl_link_get(unit, port, up); 21350 } 21351 } 21352 21353 if (BCM_SUCCESS(rv)) { 21354 if (PHY_FLAGS_TST(unit, port, PHY_FLAGS_MEDIUM_CHANGE)) { 21355 soc_port_medium_t medium; 21356 soc_phyctrl_medium_get(unit, port, &medium); 21357 soc_phy_medium_status_notify(unit, port, medium); 21358 } 21359 } 21360 PORT_UNLOCK(unit); 21361 21362 LOG_VERBOSE(BSL_LS_BCM_PORT, 21363 (BSL_META_U(unit, 21364 "_bcm_port_link_get: u=%d p=%d hw=%d up=%d rv=%d\n"), 21365 unit, port, hw, *up, rv)); 21366 21367 return rv; 21368 } 21369 21370 /* 21371 * Function: 21372 * bcm_port_link_status_get 21373 * Purpose: 21374 * Return current Link up/down status, queries linkscan, if unable to 21375 * retrieve status queries the PHY. 21376 * Parameters: 21377 * unit - StrataSwitch Unit #. 21378 * port - StrataSwitch port #. 21379 * up - (OUT) Boolean value, FALSE for link down and TRUE for link up 21380 * Returns: 21381 * BCM_E_NONE 21382 * BCM_E_XXX 21383 */ 21384 21385 int 21386 bcm_esw_port_link_status_get(int unit, bcm_port_t port, int *up) 21387 { 21388 int rv; 21389 #if defined(BCM_KATANA2_SUPPORT) 21390 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 21391 #endif 21392 21393 /* Make sure port module is initialized. */ 21394 PORT_INIT(unit); 21395 21396 if(bcm_common_oamp_port_enable_get(unit, port)) { 21397 LOG_ERROR(BSL_LS_BCM_PORT, 21398 (BSL_META("Error: Not permitted on OAMP port %d.\n"), 21399 port)); 21400 return BCM_E_PARAM; 21401 } 21402 21403 #if defined(BCM_KATANA2_SUPPORT) 21404 #if defined(BCM_SABER2_SUPPORT) 21405 if(SOC_IS_SABER2(unit)) { 21406 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 21407 } 21408 #endif 21409 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 21410 (!((port >= 1) && (port <= max_phy_port)))) { 21411 return BCM_E_PORT; 21412 } 21413 #endif 21414 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 21415 21416 rv = _bcm_esw_link_get(unit, port, up); 21417 21418 if (rv == BCM_E_DISABLED) { 21419 int mode; 21420 mode = BCM_LINKSCAN_MODE_NONE; 21421 21422 rv = bcm_esw_linkscan_mode_get(unit, port, &mode); 21423 21424 #if defined(BCM_KATANA2_SUPPORT) 21425 /* 21426 * Check added for invalid ports where the port number 21427 * lies between the maximum and minimum port values. 21428 */ 21429 if (SOC_IS_KATANA2(unit) && rv == BCM_E_PORT) { 21430 return rv; 21431 } 21432 #endif 21433 if (mode == BCM_LINKSCAN_MODE_HW) { 21434 rv = _bcm_port_link_get(unit, port, 1, up); 21435 } else { 21436 rv = _bcm_port_link_get(unit, port, 0, up); 21437 } 21438 } 21439 21440 21441 return rv; 21442 } 21443 21444 /* 21445 * Function: 21446 * bcm_esw_port_link_failed_clear 21447 * Purpose: 21448 * Clear failed link status from a port which has undergone 21449 * LAG failover. 21450 * Parameters: 21451 * unit - StrataSwitch Unit #. 21452 * port - StrataSwitch port #. 21453 * Notes: 21454 * The port is moved to down status. The application is responsible 21455 * for removing the port from all trunk memberships before calling this 21456 * function. 21457 * Returns: 21458 * BCM_E_NONE 21459 * BCM_E_XXX 21460 */ 21461 21462 int 21463 bcm_esw_port_link_failed_clear(int unit, bcm_port_t port) 21464 { 21465 /* Make sure port module is initialized. */ 21466 PORT_INIT(unit); 21467 21468 return _bcm_esw_link_failed_clear(unit, port); 21469 } 21470 21471 /* 21472 * Function: 21473 * _bcm_port_pfm_set 21474 * Purpose: 21475 * Main part of function bcm_port_pfm_set 21476 */ 21477 21478 STATIC int 21479 _bcm_port_pfm_set(int unit, bcm_port_t port, int mode) 21480 { 21481 int rv = BCM_E_NONE; 21482 21483 /* 21484 * The filter mode for the first 16 ports is in one register 21485 * and for the rest in another 21486 */ 21487 switch (BCM_CHIP_FAMILY(unit)) { 21488 21489 #ifdef BCM_XGS12_FABRIC_SUPPORT 21490 case BCM_FAMILY_HERCULES: 21491 /* See remarks under bcm_port_pfm_get below */ 21492 break; 21493 #endif 21494 21495 #ifdef BCM_XGS3_SWITCH_SUPPORT 21496 case BCM_FAMILY_FIREBOLT: 21497 case BCM_FAMILY_BRADLEY: 21498 case BCM_FAMILY_HUMV: 21499 case BCM_FAMILY_TRIUMPH: 21500 case BCM_FAMILY_SCORPION: 21501 case BCM_FAMILY_CONQUEROR: 21502 case BCM_FAMILY_TRIUMPH2: 21503 case BCM_FAMILY_TRIDENT: 21504 case BCM_FAMILY_TITAN: 21505 case BCM_FAMILY_KATANA: 21506 /* 21507 * PFM is a per VLAN attribute. It is not a per port attribute 21508 * on XGS3 21509 */ 21510 return BCM_E_UNAVAIL; 21511 #endif 21512 21513 default: 21514 return BCM_E_UNAVAIL; 21515 break; 21516 } 21517 21518 return rv; 21519 } 21520 21521 /* 21522 * Function: 21523 * bcm_port_pfm_set 21524 * Purpose: 21525 * Set current port filtering mode (see port.h) 21526 * Parameters: 21527 * unit - StrataSwitch Unit #. 21528 * port - StrataSwitch port #. 21529 * mode - mode for PFM bits (see port.h) 21530 * Returns: 21531 * BCM_E_NONE 21532 * BCM_E_XXX 21533 */ 21534 21535 int 21536 bcm_esw_port_pfm_set(int unit, bcm_port_t port, int mode) 21537 { 21538 int rv; 21539 21540 /* Make sure port module is initialized. */ 21541 PORT_INIT(unit); 21542 21543 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 21544 if (!IS_PORT(unit, port)) { 21545 return BCM_E_PORT; 21546 } 21547 21548 PORT_LOCK(unit); 21549 rv = _bcm_port_pfm_set(unit, port, mode); 21550 PORT_UNLOCK(unit); 21551 21552 return rv; 21553 } 21554 21555 /* 21556 * Function: 21557 * bcm_port_pfm_get 21558 * Purpose: 21559 * Return current port filtering mode (see port.h) 21560 * Parameters: 21561 * unit - StrataSwitch Unit #. 21562 * port - StrataSwitch port #. 21563 * mode - (OUT) mode read from StrataSwitch for PFM bits (see port.h) 21564 * Returns: 21565 * BCM_E_NONE 21566 * BCM_E_XXX 21567 * Notes: 21568 * This function not supported on 5670. 21569 */ 21570 21571 int 21572 bcm_esw_port_pfm_get(int unit, bcm_port_t port, int *mode) 21573 { 21574 /* Make sure port module is initialized. */ 21575 PORT_INIT(unit); 21576 21577 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 21578 if (!IS_PORT(unit, port)) { 21579 return BCM_E_PORT; 21580 } 21581 21582 switch (BCM_CHIP_FAMILY(unit)) { 21583 21584 #ifdef BCM_HERCULES_SUPPORT 21585 case BCM_FAMILY_HERCULES: 21586 /* 21587 * Packets marked as multicast prompt a lookup in the 21588 * MC table in 567x. There is no notion of missing a multicast 21589 * address. 21590 * 21591 * Alternatively, we can mess with the MC/IPMC table 21592 * entries to support the different modes. This is 21593 * probably not worth the trouble when we look at how 21594 * 567x is meant to fit into the system. 21595 */ 21596 *mode = BCM_PORT_PFM_MODEC; 21597 break; 21598 #endif 21599 21600 #ifdef BCM_XGS3_SWITCH_SUPPORT 21601 case BCM_FAMILY_FIREBOLT: 21602 case BCM_FAMILY_BRADLEY: 21603 case BCM_FAMILY_HUMV: 21604 case BCM_FAMILY_TRIUMPH: 21605 case BCM_FAMILY_SCORPION: 21606 case BCM_FAMILY_CONQUEROR: 21607 case BCM_FAMILY_TRIUMPH2: 21608 case BCM_FAMILY_TRIDENT: 21609 case BCM_FAMILY_TITAN: 21610 case BCM_FAMILY_KATANA: 21611 /* 21612 * PFM is a per VLAN attribute. It is not a per port attribute 21613 * on XGS3 21614 */ 21615 *mode = BCM_PORT_PFM_MODEC; 21616 return BCM_E_UNAVAIL; 21617 #endif 21618 21619 default: 21620 return BCM_E_UNAVAIL; 21621 break; 21622 } 21623 21624 return BCM_E_NONE; 21625 } 21626 21627 /* 21628 * Function: 21629 * _bcm_port_untagged_priority_set 21630 * Purpose: 21631 * Main part of bcm_port_untagged_priority_set. 21632 */ 21633 21634 STATIC int 21635 _bcm_port_untagged_priority_set(int unit, bcm_port_t port, int priority) 21636 { 21637 if (priority > 7) { 21638 return BCM_E_PARAM; 21639 } 21640 21641 if(bcm_common_oamp_port_enable_get(unit, port)) { 21642 LOG_ERROR(BSL_LS_BCM_PORT, 21643 (BSL_META("Error: Not permitted on OAMP port %d.n"), 21644 port)); 21645 return BCM_E_PARAM; 21646 } 21647 21648 #if defined(BCM_XGS_SWITCH_SUPPORT) 21649 if (soc_feature(unit, soc_feature_remap_ut_prio) && (priority >= 0)) { 21650 bcm_port_cfg_t pcfg; 21651 SOC_IF_ERROR_RETURN( 21652 mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 21653 pcfg.pc_remap_pri_en = 1; 21654 pcfg.pc_new_opri = priority; 21655 SOC_IF_ERROR_RETURN( 21656 mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 21657 PORT(unit, port).p_ut_prio = pcfg.pc_new_opri; 21658 return SOC_E_NONE; 21659 } 21660 #endif /* BCM_XGS_SWITCH_SUPPORT */ 21661 21662 if (priority < 0) { 21663 return BCM_E_PARAM; 21664 } 21665 21666 return BCM_E_UNAVAIL; 21667 } 21668 21669 /* 21670 * Function: 21671 * bcm_port_untagged_priority_set 21672 * Purpose: 21673 * Set the 802.1P priority for untagged packets coming in on a 21674 * port. This value will be written into the priority field of the 21675 * tag that is added at the ingress. 21676 * Parameters: 21677 * unit - StrataSwitch Unit #. 21678 * port - StrataSwitch port #. 21679 * priority - Priority to be set in 802.1p priority tag, from 0 to 7. 21680 * A negative priority leaves the ingress port priority as 21681 * is, but disables it from overriding ARL-based priorities. 21682 * (on those devices that support ARL-based priority). 21683 * Returns: 21684 * BCM_E_NONE 21685 * BCM_E_XXX 21686 */ 21687 21688 int 21689 bcm_esw_port_untagged_priority_set(int unit, bcm_port_t port, int priority) 21690 { 21691 int rv; 21692 21693 /* Make sure port module is initialized. */ 21694 PORT_INIT(unit); 21695 21696 if(bcm_common_oamp_port_enable_get(unit, port)) { 21697 LOG_ERROR(BSL_LS_BCM_PORT, 21698 (BSL_META("Error: Not permitted on OAMP port %d.n"), 21699 port)); 21700 return BCM_E_PARAM; 21701 } 21702 21703 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 21704 && defined(INCLUDE_L3)) 21705 if (BCM_GPORT_IS_WLAN_PORT(port)) { 21706 #if defined(BCM_TRIUMPH3_SUPPORT) 21707 if (SOC_IS_TRIUMPH3(unit)) { 21708 return bcm_tr3_wlan_port_untagged_prio_set(unit, port, priority); 21709 } else 21710 #endif /* BCM_TRIUMPH3_SUPPORT */ 21711 { 21712 return bcm_tr2_wlan_port_untagged_prio_set(unit, port, priority); 21713 } 21714 } 21715 #endif 21716 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 21717 21718 PORT_LOCK(unit); 21719 rv = _bcm_port_untagged_priority_set(unit, port, priority); 21720 PORT_UNLOCK(unit); 21721 21722 LOG_INFO(BSL_LS_BCM_PORT, 21723 (BSL_META_U(unit, 21724 "bcm_port_ut_priority_set: u=%d p=%d pri=%d rv=%d\n"), 21725 unit, port, priority, rv)); 21726 21727 return rv; 21728 } 21729 21730 /* 21731 * Function: 21732 * bcm_port_untagged_priority_get 21733 * Purpose: 21734 * Returns priority being assigned to untagged receive packets 21735 * Parameters: 21736 * unit - StrataSwitch Unit #. 21737 * port - StrataSwitch port #. 21738 * priority - Pointer to an int in which priority value is returned. 21739 * Returns: 21740 * BCM_E_NONE 21741 * BCM_E_XXX 21742 */ 21743 21744 int 21745 bcm_esw_port_untagged_priority_get(int unit, bcm_port_t port, int *priority) 21746 { 21747 /* Make sure port module is initialized. */ 21748 PORT_INIT(unit); 21749 21750 if(bcm_common_oamp_port_enable_get(unit, port)) { 21751 LOG_ERROR(BSL_LS_BCM_PORT, 21752 (BSL_META("Error: Not permitted on OAMP port %d.n"), 21753 port)); 21754 return BCM_E_PARAM; 21755 } 21756 21757 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 21758 && defined(INCLUDE_L3)) 21759 if (BCM_GPORT_IS_WLAN_PORT(port)) { 21760 #if defined(BCM_TRIUMPH3_SUPPORT) 21761 if (SOC_IS_TRIUMPH3(unit)) { 21762 return bcm_tr3_wlan_port_untagged_prio_get(unit, port, priority); 21763 } else 21764 #endif /* BCM_TRIUMPH3_SUPPORT */ 21765 { 21766 return bcm_tr2_wlan_port_untagged_prio_get(unit, port, priority); 21767 } 21768 } 21769 #endif 21770 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 21771 21772 if (priority != NULL) { 21773 *priority = PORT(unit, port).p_ut_prio; 21774 LOG_INFO(BSL_LS_BCM_PORT, 21775 (BSL_META_U(unit, 21776 "bcm_port_ut_priority_get: u=%d p=%d pri=%d\n"), 21777 unit, port, *priority)); 21778 } 21779 21780 return BCM_E_NONE; 21781 } 21782 21783 /* 21784 * Function: 21785 * bcm_port_selective_get 21786 * Purpose: 21787 * Get requested port parameters 21788 * Parameters: 21789 * unit - switch Unit 21790 * port - switch port 21791 * info - (IN/OUT) port information structure 21792 * Returns: 21793 * BCM_E_XXX 21794 * Notes: 21795 * The action_mask field of the info argument is used as an input 21796 */ 21797 21798 int 21799 bcm_esw_port_selective_get(int unit, bcm_port_t port, bcm_port_info_t *info) 21800 { 21801 int r; 21802 uint32 mask; 21803 21804 /* Make sure port module is initialized. */ 21805 PORT_INIT(unit); 21806 if (!BCM_GPORT_IS_SET(port)) { 21807 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)) { 21808 return BCM_E_PORT; 21809 } 21810 } 21811 21812 if(bcm_common_oamp_port_enable_get(unit, port)) { 21813 LOG_ERROR(BSL_LS_BCM_PORT, 21814 (BSL_META("Error: Not permitted on OAMP port %d.n"), 21815 port)); 21816 return BCM_E_PARAM; 21817 } 21818 21819 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 21820 21821 mask = info->action_mask; 21822 21823 /* PM8x50 does not support these things, so do not try to fetch them */ 21824 if (IS_CD_PORT(unit, port)) { 21825 mask &= ~BCM_PORT_ATTR_ABILITY_MASK; 21826 mask &= ~BCM_PORT_ATTR_LOCAL_ADVERT_MASK; 21827 mask &= ~BCM_PORT_ATTR_INTERFACE_MASK; 21828 } 21829 21830 if (IS_QSGMII_PORT(unit, port)) { 21831 mask &= ~BCM_PORT_ATTR_FAULT_MASK; 21832 } 21833 21834 if (mask & BCM_PORT_ATTR_ENCAP_MASK) { 21835 r = bcm_esw_port_encap_get(unit, port, &info->encap_mode); 21836 if (BCM_FAILURE(r)) { 21837 LOG_VERBOSE(BSL_LS_BCM_PORT, 21838 (BSL_META_U(unit, 21839 "bcm_port_encap_getfailed:%s\n"), bcm_errmsg(r))); 21840 } 21841 BCM_IF_ERROR_RETURN(r); 21842 } 21843 21844 if (mask & BCM_PORT_ATTR_ENABLE_MASK) { 21845 r = bcm_esw_port_enable_get(unit, port, &info->enable); 21846 if (BCM_FAILURE(r)) { 21847 LOG_VERBOSE(BSL_LS_BCM_PORT, 21848 (BSL_META_U(unit, 21849 "bcm_port_enable_getfailed:%s\n"), bcm_errmsg(r))); 21850 } 21851 BCM_IF_ERROR_RETURN(r); 21852 } 21853 21854 if (mask & BCM_PORT_ATTR_LINKSTAT_MASK) { 21855 r = bcm_esw_port_link_status_get(unit, port, &info->linkstatus); 21856 if (BCM_FAILURE(r)) { 21857 /* LOG_VERBOSE(BSL_LS_BCM_PORT, 21858 (BSL_META_U(unit, 21859 "bcm_port_link_status_getfailed:%s\n"), bcm_errmsg(r))); */ 21860 } 21861 BCM_IF_ERROR_RETURN(r); 21862 } 21863 21864 if (mask & BCM_PORT_ATTR_AUTONEG_MASK) { 21865 r = bcm_esw_port_autoneg_get(unit, port, &info->autoneg); 21866 if (BCM_FAILURE(r)) { 21867 LOG_VERBOSE(BSL_LS_BCM_PORT, 21868 (BSL_META_U(unit, 21869 "bcm_port_autoneg_getfailed:%s\n"), bcm_errmsg(r))); 21870 } 21871 BCM_IF_ERROR_RETURN(r); 21872 } 21873 21874 if (mask & BCM_PORT_ATTR_LOCAL_ADVERT_MASK) { 21875 r = bcm_esw_port_ability_advert_get(unit, port, 21876 &info->local_ability); 21877 if (BCM_FAILURE(r)) { 21878 LOG_VERBOSE(BSL_LS_BCM_PORT, 21879 (BSL_META_U(unit, 21880 "bcm_port_ability_advert_getfailed:%s\n"), 21881 bcm_errmsg(r))); 21882 } 21883 BCM_IF_ERROR_RETURN(r); 21884 r = soc_port_ability_to_mode(&info->local_ability, 21885 &info->local_advert); 21886 BCM_IF_ERROR_RETURN(r); 21887 } 21888 21889 if (mask & BCM_PORT_ATTR_REMOTE_ADVERT_MASK) { 21890 21891 if ((r = bcm_esw_port_ability_remote_get(unit, port, 21892 &info->remote_ability)) < 0) { 21893 info->remote_advert = 0; 21894 info->remote_advert_valid = FALSE; 21895 } else { 21896 r = soc_port_ability_to_mode(&info->remote_ability, 21897 &info->remote_advert); 21898 BCM_IF_ERROR_RETURN(r); 21899 info->remote_advert_valid = TRUE; 21900 } 21901 } 21902 21903 if (mask & BCM_PORT_ATTR_SPEED_MASK) { 21904 if ((r = bcm_esw_port_speed_get(unit, port, &info->speed)) < 0) { 21905 if (r != BCM_E_BUSY) { 21906 LOG_VERBOSE(BSL_LS_BCM_PORT, 21907 (BSL_META_U(unit, 21908 "bcm_port_speed_get failed: %s\n"), bcm_errmsg(r))); 21909 return(r); 21910 } else { 21911 info->speed = 0; 21912 } 21913 } 21914 } 21915 21916 if (mask & BCM_PORT_ATTR_DUPLEX_MASK) { 21917 if ((r = bcm_esw_port_duplex_get(unit, port, &info->duplex)) < 0) { 21918 if (r != BCM_E_BUSY) { 21919 LOG_VERBOSE(BSL_LS_BCM_PORT, 21920 (BSL_META_U(unit, 21921 "bcm_port_duplex_get failed: %s\n"), bcm_errmsg(r))); 21922 return r; 21923 } else { 21924 info->duplex = 0; 21925 } 21926 } 21927 } 21928 21929 /* get both if either mask bit set */ 21930 if (mask & (BCM_PORT_ATTR_PAUSE_TX_MASK | 21931 BCM_PORT_ATTR_PAUSE_RX_MASK)) { 21932 r = bcm_esw_port_pause_get(unit, port, 21933 &info->pause_tx, &info->pause_rx); 21934 if (BCM_FAILURE(r)) { 21935 LOG_VERBOSE(BSL_LS_BCM_PORT, 21936 (BSL_META_U(unit, 21937 "bcm_port_pause_get failed:%s\n"), bcm_errmsg(r))); 21938 } 21939 BCM_IF_ERROR_RETURN(r); 21940 } 21941 21942 if (mask & BCM_PORT_ATTR_PAUSE_MAC_MASK) { 21943 r = bcm_esw_port_pause_addr_get(unit, port, info->pause_mac); 21944 if (BCM_FAILURE(r)) { 21945 LOG_VERBOSE(BSL_LS_BCM_PORT, 21946 (BSL_META_U(unit, 21947 "bcm_port_pause_addr_get failed:%s\n"), bcm_errmsg(r))); 21948 } 21949 BCM_IF_ERROR_RETURN(r); 21950 } 21951 21952 if (mask & BCM_PORT_ATTR_LINKSCAN_MASK) { 21953 r = bcm_esw_port_linkscan_get(unit, port, &info->linkscan); 21954 if (BCM_FAILURE(r)) { 21955 LOG_VERBOSE(BSL_LS_BCM_PORT, 21956 (BSL_META_U(unit, 21957 "bcm_port_linkscan_get failed:%s\n"), bcm_errmsg(r))); 21958 } 21959 BCM_IF_ERROR_RETURN(r); 21960 } 21961 21962 if (mask & BCM_PORT_ATTR_LEARN_MASK) { 21963 r = bcm_esw_port_learn_get(unit, port, &info->learn); 21964 if (BCM_FAILURE(r)) { 21965 LOG_VERBOSE(BSL_LS_BCM_PORT, 21966 (BSL_META_U(unit, 21967 "bcm_port_learn_getfailed:%s\n"), bcm_errmsg(r))); 21968 } 21969 BCM_IF_ERROR_RETURN(r); 21970 } 21971 21972 if (mask & BCM_PORT_ATTR_DISCARD_MASK) { 21973 r = bcm_esw_port_discard_get(unit, port, &info->discard); 21974 if (BCM_FAILURE(r)) { 21975 LOG_VERBOSE(BSL_LS_BCM_PORT, 21976 (BSL_META_U(unit, 21977 "bcm_port_discard_get failed:%s\n"), bcm_errmsg(r))); 21978 } 21979 BCM_IF_ERROR_RETURN(r); 21980 } 21981 21982 if (mask & BCM_PORT_ATTR_VLANFILTER_MASK) { 21983 r = bcm_esw_port_vlan_member_get(unit, port, &info->vlanfilter); 21984 if (BCM_FAILURE(r)) { 21985 LOG_VERBOSE(BSL_LS_BCM_PORT, 21986 (BSL_META_U(unit, 21987 "bcm_esw_port_vlan_member_get failed:%s\n"), 21988 bcm_errmsg(r))); 21989 } 21990 BCM_IF_ERROR_RETURN(r); 21991 } 21992 21993 if (mask & BCM_PORT_ATTR_UNTAG_PRI_MASK) { 21994 r = bcm_esw_port_untagged_priority_get(unit, port, 21995 &info->untagged_priority); 21996 if (BCM_FAILURE(r)) { 21997 LOG_VERBOSE(BSL_LS_BCM_PORT, 21998 (BSL_META_U(unit, 21999 "bcm_port_untagged_priority_get failed:%s\n"), 22000 bcm_errmsg(r))); 22001 } 22002 BCM_IF_ERROR_RETURN(r); 22003 } 22004 22005 if (mask & BCM_PORT_ATTR_UNTAG_VLAN_MASK) { 22006 r = bcm_esw_port_untagged_vlan_get(unit, port, 22007 &info->untagged_vlan); 22008 if (BCM_FAILURE(r)) { 22009 LOG_VERBOSE(BSL_LS_BCM_PORT, 22010 (BSL_META_U(unit, 22011 "bcm_port_untagged_vlan_get failed:%s\n"), 22012 bcm_errmsg(r))); 22013 } 22014 BCM_IF_ERROR_RETURN(r); 22015 } 22016 22017 if (mask & BCM_PORT_ATTR_STP_STATE_MASK) { 22018 r = bcm_esw_port_stp_get(unit, port, &info->stp_state); 22019 if (BCM_FAILURE(r)) { 22020 LOG_VERBOSE(BSL_LS_BCM_PORT, 22021 (BSL_META_U(unit, 22022 "bcm_port_stp_get failed:%s\n"), bcm_errmsg(r))); 22023 } 22024 BCM_IF_ERROR_RETURN(r); 22025 } 22026 22027 if (mask & BCM_PORT_ATTR_PFM_MASK) { 22028 r = bcm_esw_port_pfm_get(unit, port, &info->pfm); 22029 if (r != BCM_E_UNAVAIL) { 22030 if (BCM_FAILURE(r)) { 22031 LOG_VERBOSE(BSL_LS_BCM_PORT, 22032 (BSL_META_U(unit, 22033 "bcm_port_pfm_get failed:%s\n"), bcm_errmsg(r))); 22034 } 22035 } 22036 BCM_IF_ERROR_NOT_UNAVAIL_RETURN(r); 22037 } 22038 22039 if (mask & BCM_PORT_ATTR_LOOPBACK_MASK) { 22040 r = bcm_esw_port_loopback_get(unit, port, &info->loopback); 22041 if (BCM_FAILURE(r)) { 22042 LOG_VERBOSE(BSL_LS_BCM_PORT, 22043 (BSL_META_U(unit, 22044 "bcm_port_loopback_get failed:%s\n"), bcm_errmsg(r))); 22045 } 22046 BCM_IF_ERROR_RETURN(r); 22047 } 22048 22049 if (mask & BCM_PORT_ATTR_PHY_MASTER_MASK) { 22050 r = bcm_esw_port_master_get(unit, port, &info->phy_master); 22051 if (BCM_FAILURE(r)) { 22052 LOG_VERBOSE(BSL_LS_BCM_PORT, 22053 (BSL_META_U(unit, 22054 "bcm_port_master_get failed:%s\n"), bcm_errmsg(r))); 22055 } 22056 BCM_IF_ERROR_RETURN(r); 22057 } 22058 22059 if (mask & BCM_PORT_ATTR_INTERFACE_MASK) { 22060 r = bcm_esw_port_interface_get(unit, port, &info->interface); 22061 if (BCM_FAILURE(r)) { 22062 LOG_VERBOSE(BSL_LS_BCM_PORT, 22063 (BSL_META_U(unit, 22064 "bcm_port_interface_get failed:%s\n"), bcm_errmsg(r))); 22065 } 22066 BCM_IF_ERROR_RETURN(r); 22067 } 22068 22069 if (mask & BCM_PORT_ATTR_RATE_MCAST_MASK) { 22070 r = bcm_esw_rate_mcast_get(unit, &info->mcast_limit, 22071 &info->mcast_limit_enable, port); 22072 if (r == BCM_E_UNAVAIL) { 22073 r = BCM_E_NONE; /* Ignore if not supported on chip */ 22074 } 22075 if (BCM_FAILURE(r)) { 22076 LOG_VERBOSE(BSL_LS_BCM_PORT, 22077 (BSL_META_U(unit, 22078 "bcm_rate_mcast_get failed:%s\n"), bcm_errmsg(r))); 22079 } 22080 BCM_IF_ERROR_RETURN(r); 22081 } 22082 22083 if (mask & BCM_PORT_ATTR_RATE_BCAST_MASK) { 22084 r = bcm_esw_rate_bcast_get(unit, &info->bcast_limit, 22085 &info->bcast_limit_enable, port); 22086 if (r == BCM_E_UNAVAIL) { 22087 r = BCM_E_NONE; /* Ignore if not supported on chip */ 22088 } 22089 if (BCM_FAILURE(r)) { 22090 LOG_VERBOSE(BSL_LS_BCM_PORT, 22091 (BSL_META_U(unit, 22092 "bcm_rate_bcast_get failed:%s\n"), bcm_errmsg(r))); 22093 } 22094 BCM_IF_ERROR_RETURN(r); 22095 } 22096 22097 if (mask & BCM_PORT_ATTR_RATE_DLFBC_MASK) { 22098 r = bcm_esw_rate_dlfbc_get(unit, &info->dlfbc_limit, 22099 &info->dlfbc_limit_enable, port); 22100 if (r == BCM_E_UNAVAIL) { 22101 r = BCM_E_NONE; /* Ignore if not supported on chip */ 22102 } 22103 if (BCM_FAILURE(r)) { 22104 LOG_VERBOSE(BSL_LS_BCM_PORT, 22105 (BSL_META_U(unit, 22106 "bcm_rate_dlfbc_get failed:%s\n"), bcm_errmsg(r))); 22107 } 22108 BCM_IF_ERROR_RETURN(r); 22109 } 22110 22111 if (mask & BCM_PORT_ATTR_SPEED_MAX_MASK) { 22112 r = bcm_esw_port_speed_max(unit, port, &info->speed_max); 22113 if (BCM_FAILURE(r)) { 22114 LOG_VERBOSE(BSL_LS_BCM_PORT, 22115 (BSL_META_U(unit, 22116 "bcm_port_speed_max failed:%s\n"), bcm_errmsg(r))); 22117 } 22118 BCM_IF_ERROR_RETURN(r); 22119 } 22120 22121 if (mask & BCM_PORT_ATTR_ABILITY_MASK) { 22122 r = bcm_esw_port_ability_local_get(unit, port, &info->port_ability); 22123 if (BCM_FAILURE(r)) { 22124 LOG_VERBOSE(BSL_LS_BCM_PORT, 22125 (BSL_META_U(unit, 22126 "bcm_port_ability_get failed:%s\n"), bcm_errmsg(r))); 22127 } 22128 BCM_IF_ERROR_RETURN(r); 22129 r = soc_port_ability_to_mode(&info->port_ability, 22130 &info->ability); 22131 BCM_IF_ERROR_RETURN(r); 22132 } 22133 22134 if (mask & BCM_PORT_ATTR_FRAME_MAX_MASK) { 22135 r = bcm_esw_port_frame_max_get(unit, port, &info->frame_max); 22136 if (BCM_FAILURE(r)) { 22137 LOG_VERBOSE(BSL_LS_BCM_PORT, 22138 (BSL_META_U(unit, 22139 "bcm_port_frame_max_get failed:%s\n"), bcm_errmsg(r))); 22140 } 22141 BCM_IF_ERROR_RETURN(r); 22142 } 22143 22144 if (mask & BCM_PORT_ATTR_MDIX_MASK) { 22145 r = bcm_esw_port_mdix_get(unit, port, &info->mdix); 22146 if (BCM_FAILURE(r)) { 22147 LOG_VERBOSE(BSL_LS_BCM_PORT, 22148 (BSL_META_U(unit, 22149 "bcm_port_mdix_get failed:%s\n"), bcm_errmsg(r))); 22150 } 22151 BCM_IF_ERROR_RETURN(r); 22152 } 22153 22154 if (mask & BCM_PORT_ATTR_MDIX_STATUS_MASK) { 22155 r = bcm_esw_port_mdix_status_get(unit, port, &info->mdix_status); 22156 if (BCM_FAILURE(r)) { 22157 LOG_VERBOSE(BSL_LS_BCM_PORT, 22158 (BSL_META_U(unit, 22159 "bcm_port_mdix_status_get failed:%s\n"), bcm_errmsg(r))); 22160 } 22161 BCM_IF_ERROR_RETURN(r); 22162 } 22163 22164 if (mask & BCM_PORT_ATTR_MEDIUM_MASK) { 22165 r = bcm_esw_port_medium_get(unit, port, &info->medium); 22166 if (BCM_FAILURE(r)) { 22167 LOG_VERBOSE(BSL_LS_BCM_PORT, 22168 (BSL_META_U(unit, 22169 "bcm_port_medium_get failed:%s\n"), bcm_errmsg(r))); 22170 } 22171 BCM_IF_ERROR_RETURN(r); 22172 } 22173 22174 if (mask & BCM_PORT_ATTR_FAULT_MASK) { 22175 r = bcm_esw_port_fault_get(unit, port, &info->fault); 22176 if (r == BCM_E_PORT) { 22177 r = BCM_E_NONE; /* Ignore if not supported on chip/port */ 22178 } 22179 if (BCM_FAILURE(r)) { 22180 LOG_VERBOSE(BSL_LS_BCM_PORT, 22181 (BSL_META_U(unit, 22182 "bcm_port_fault_get failed:%s\n"), bcm_errmsg(r))); 22183 } 22184 BCM_IF_ERROR_RETURN(r); 22185 } 22186 22187 return BCM_E_NONE; 22188 } 22189 22190 /* 22191 * Function: 22192 * bcm_port_selective_set 22193 * Purpose: 22194 * Set requested port parameters 22195 * Parameters: 22196 * unit - switch unit 22197 * port - switch port 22198 * info - port information structure 22199 * Returns: 22200 * BCM_E_NONE 22201 * BCM_E_XXX 22202 * Notes: 22203 * Does not set spanning tree state. 22204 */ 22205 22206 int 22207 bcm_esw_port_selective_set(int unit, bcm_port_t port, bcm_port_info_t *info) 22208 { 22209 int r; 22210 uint32 mask; 22211 int flags = 0; 22212 soc_info_t *si; 22213 22214 if (!(si = &SOC_INFO(unit))) { 22215 return SOC_E_INTERNAL; 22216 } 22217 22218 LOG_INFO(BSL_LS_BCM_PORT, 22219 (BSL_META_U(unit, 22220 "bcm_port_selective_set: u=%d p=%d\n"), unit, port)); 22221 22222 /* Make sure port module is initialized. */ 22223 PORT_INIT(unit); 22224 if (!BCM_GPORT_IS_SET(port)) { 22225 if (!SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),port)) { 22226 return BCM_E_PORT; 22227 } 22228 } 22229 22230 if(bcm_common_oamp_port_enable_get(unit, port)) { 22231 LOG_ERROR(BSL_LS_BCM_PORT, 22232 (BSL_META("Error: Not permitted on OAMP port %d.n"), 22233 port)); 22234 return BCM_E_PARAM; 22235 } 22236 22237 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 22238 22239 mask = info->action_mask; 22240 22241 /* PM8x50 does not support these things, so do not try to fetch them */ 22242 if (IS_CD_PORT(unit, port)) { 22243 mask &= ~BCM_PORT_ATTR_ABILITY_MASK; 22244 mask &= ~BCM_PORT_ATTR_LOCAL_ADVERT_MASK; 22245 mask &= ~BCM_PORT_ATTR_INTERFACE_MASK; 22246 } 22247 22248 if (mask & BCM_PORT_ATTR_ENCAP_MASK) { 22249 if (info->encap_mode == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) { 22250 /* HGOE mode valid only for TD3 fabric */ 22251 #ifdef BCM_TRIDENT3_SUPPORT 22252 if (SOC_IS_TRIDENT3X(unit) && 22253 soc_feature(unit, soc_feature_higig_over_ethernet)) { 22254 bcm_port_encap_config_t config; 22255 config.encap = info->encap_mode; 22256 BCM_IF_ERROR_RETURN( 22257 bcm_esw_port_encap_config_set(unit, port, &config)); 22258 } else 22259 #endif 22260 { 22261 return BCM_E_PARAM; 22262 } 22263 } else { 22264 22265 BCM_IF_ERROR_RETURN 22266 (bcmi_esw_port_encap_validate(unit, port, info->encap_mode, 22267 ((mask & BCM_PORT_ATTR_SPEED_MASK) ? info->speed : 0))); 22268 r = _bcm_esw_port_encap_set(unit, port, info->encap_mode); 22269 if (BCM_FAILURE(r)) { 22270 LOG_ERROR(BSL_LS_BCM_PORT, 22271 (BSL_META_U(unit, 22272 "bcm_port_encap_set failed:%s\n"), bcm_errmsg(r))); 22273 } 22274 BCM_IF_ERROR_RETURN(r); 22275 } 22276 } 22277 22278 if (mask & BCM_PORT_ATTR_ENABLE_MASK) { 22279 r = bcm_esw_port_enable_set(unit, port, info->enable); 22280 if (BCM_FAILURE(r)) { 22281 LOG_ERROR(BSL_LS_BCM_PORT, 22282 (BSL_META_U(unit, 22283 "bcm_port_enable_set failed:%s\n"), bcm_errmsg(r))); 22284 } 22285 BCM_IF_ERROR_RETURN(r); 22286 } 22287 22288 if (mask & BCM_PORT_ATTR_PAUSE_MAC_MASK) { 22289 r = bcm_esw_port_pause_addr_set(unit, port, info->pause_mac); 22290 if (BCM_FAILURE(r)) { 22291 LOG_ERROR(BSL_LS_BCM_PORT, 22292 (BSL_META_U(unit, 22293 "bcm_port_pause_addr_set failed:%s\n"), bcm_errmsg(r))); 22294 } 22295 BCM_IF_ERROR_RETURN(r); 22296 } 22297 22298 if (mask & BCM_PORT_ATTR_INTERFACE_MASK) { 22299 r = bcm_esw_port_interface_set(unit, port, info->interface); 22300 if (BCM_FAILURE(r)) { 22301 LOG_ERROR(BSL_LS_BCM_PORT, 22302 (BSL_META_U(unit, 22303 "bcm_port_interface_set failed:%s\n"), bcm_errmsg(r))); 22304 } 22305 BCM_IF_ERROR_RETURN(r); 22306 } 22307 22308 if (mask & BCM_PORT_ATTR_PHY_MASTER_MASK) { 22309 r = bcm_esw_port_master_set(unit, port, info->phy_master); 22310 if (r != BCM_E_UNAVAIL) { 22311 if (BCM_FAILURE(r)) { 22312 LOG_VERBOSE(BSL_LS_BCM_PORT, 22313 (BSL_META_U(unit, 22314 "bcm_port_master_set failed:%s\n"), bcm_errmsg(r))); 22315 } 22316 } 22317 BCM_IF_ERROR_NOT_UNAVAIL_RETURN(r); 22318 } 22319 22320 if (mask & BCM_PORT_ATTR_LINKSCAN_MASK) { 22321 r = bcm_esw_port_linkscan_set(unit, port, info->linkscan); 22322 if (BCM_FAILURE(r)) { 22323 LOG_ERROR(BSL_LS_BCM_PORT, 22324 (BSL_META_U(unit, 22325 "bcm_port_linkscan_set failed:%s\n"), bcm_errmsg(r))); 22326 } 22327 BCM_IF_ERROR_RETURN(r); 22328 } 22329 22330 if (mask & BCM_PORT_ATTR_LEARN_MASK) { 22331 r = bcm_esw_port_learn_set(unit, port, info->learn); 22332 if (BCM_FAILURE(r)) { 22333 LOG_ERROR(BSL_LS_BCM_PORT, 22334 (BSL_META_U(unit, 22335 "bcm_port_learn_set failed:%s\n"), bcm_errmsg(r))); 22336 } 22337 BCM_IF_ERROR_RETURN(r); 22338 } 22339 22340 if (mask & BCM_PORT_ATTR_DISCARD_MASK) { 22341 r = bcm_esw_port_discard_set(unit, port, info->discard); 22342 if (BCM_FAILURE(r)) { 22343 LOG_ERROR(BSL_LS_BCM_PORT, 22344 (BSL_META_U(unit, 22345 "bcm_port_discard_set failed:%s\n"), bcm_errmsg(r))); 22346 } 22347 BCM_IF_ERROR_RETURN(r); 22348 } 22349 22350 if (mask & BCM_PORT_ATTR_VLANFILTER_MASK) { 22351 r = bcm_esw_port_vlan_member_set(unit, port, info->vlanfilter); 22352 if (BCM_FAILURE(r)) { 22353 LOG_ERROR(BSL_LS_BCM_PORT, 22354 (BSL_META_U(unit, 22355 "bcm_esw_port_vlan_member_set failed:%s\n"), 22356 bcm_errmsg(r))); 22357 } 22358 BCM_IF_ERROR_RETURN(r); 22359 } 22360 22361 if (mask & BCM_PORT_ATTR_UNTAG_PRI_MASK) { 22362 r = bcm_esw_port_untagged_priority_set(unit, port, 22363 info->untagged_priority); 22364 if (BCM_FAILURE(r)) { 22365 LOG_ERROR(BSL_LS_BCM_PORT, 22366 (BSL_META_U(unit, 22367 "bcm_port_untagged_priority_set failed:%s\n"), 22368 bcm_errmsg(r))); 22369 } 22370 BCM_IF_ERROR_RETURN(r); 22371 } 22372 22373 if (mask & BCM_PORT_ATTR_UNTAG_VLAN_MASK) { 22374 r = bcm_esw_port_untagged_vlan_set(unit, port, info->untagged_vlan); 22375 if (BCM_FAILURE(r)) { 22376 LOG_ERROR(BSL_LS_BCM_PORT, 22377 (BSL_META_U(unit, 22378 "bcm_port_untagged_vlan_set (%d) failed: %s\n"), 22379 info->untagged_vlan, bcm_errmsg(r))); 22380 } 22381 BCM_IF_ERROR_RETURN(r); 22382 } 22383 22384 if (mask & BCM_PORT_ATTR_PFM_MASK) { 22385 r = bcm_esw_port_pfm_set(unit, port, info->pfm); 22386 if (r != BCM_E_UNAVAIL) { 22387 if (BCM_FAILURE(r)) { 22388 LOG_ERROR(BSL_LS_BCM_PORT, 22389 (BSL_META_U(unit, 22390 "bcm_port_pfm_set failed:%s\n"), bcm_errmsg(r))); 22391 } 22392 } 22393 BCM_IF_ERROR_NOT_UNAVAIL_RETURN(r); 22394 } 22395 22396 /* 22397 * Set loopback mode before setting the speed/duplex, since it may 22398 * affect the allowable values for speed/duplex. 22399 */ 22400 22401 if (mask & BCM_PORT_ATTR_LOOPBACK_MASK) { 22402 r = bcm_esw_port_loopback_set(unit, port, info->loopback); 22403 if (BCM_FAILURE(r)) { 22404 LOG_ERROR(BSL_LS_BCM_PORT, 22405 (BSL_META_U(unit, 22406 "bcm_port_loopback_set failed:%s\n"), bcm_errmsg(r))); 22407 } 22408 BCM_IF_ERROR_RETURN(r); 22409 } 22410 22411 if (mask & BCM_PORT_ATTR_LOCAL_ADVERT_MASK) { 22412 if (info->action_mask2 & BCM_PORT_ATTR2_PORT_ABILITY) { 22413 r = bcm_esw_port_ability_advert_set(unit, port, 22414 &(info->local_ability)); 22415 if (BCM_FAILURE(r)) { 22416 LOG_ERROR(BSL_LS_BCM_PORT, 22417 (BSL_META_U(unit, 22418 "bcm_port_ability_advert_set failed: %s\n"), 22419 bcm_errmsg(r))); 22420 } 22421 BCM_IF_ERROR_RETURN(r); 22422 } else { 22423 r = bcm_esw_port_advert_set(unit, port, info->local_advert); 22424 if (BCM_FAILURE(r)) { 22425 LOG_ERROR(BSL_LS_BCM_PORT, 22426 (BSL_META_U(unit, 22427 "bcm_port_advert_set failed: (0x%x): %s\n"), 22428 info->local_advert, bcm_errmsg(r))); 22429 } 22430 BCM_IF_ERROR_RETURN(r); 22431 } 22432 } 22433 22434 if (mask & BCM_PORT_ATTR_AUTONEG_MASK) { 22435 #if defined(BCM_TOMAHAWK_SUPPORT) 22436 if ((SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3(unit)) && IS_CL_PORT(unit, port)) { 22437 int speed = si->port_init_speed[port]; 22438 if (1000 == speed) { /* 1G ports do not support autoneg, force off */ 22439 info->autoneg = 0; 22440 } 22441 } 22442 #endif 22443 r = bcm_esw_port_autoneg_set(unit, port, info->autoneg); 22444 if (BCM_FAILURE(r)) { 22445 LOG_ERROR(BSL_LS_BCM_PORT, 22446 (BSL_META_U(unit, 22447 "bcm_port_autoneg_set failed:%s\n"), bcm_errmsg(r))); 22448 } 22449 BCM_IF_ERROR_RETURN(r); 22450 } 22451 22452 if (mask & BCM_PORT_ATTR_SPEED_MASK) { 22453 /*When AN=on, speed will be auto-detected. Hence don't set*/ 22454 if ((mask & BCM_PORT_ATTR_AUTONEG_MASK) && info->autoneg) { 22455 r = BCM_E_PARAM; 22456 if (BCM_FAILURE(r)) { 22457 LOG_ERROR(BSL_LS_BCM_PORT, 22458 (BSL_META_U(unit, 22459 "Autoneg:On. SPEED will be " 22460 "auto-detected :%s\n"), bcm_errmsg(r))); 22461 } 22462 BCM_IF_ERROR_RETURN(r); 22463 } 22464 #ifdef BCM_TOMAHAWK3_SUPPORT 22465 if (SOC_IS_TOMAHAWK3(unit) && IS_CD_PORT(unit, port)) { 22466 bcm_port_resource_t pr; 22467 r = bcm_esw_port_resource_get(unit, port, &pr); 22468 BCM_IF_ERROR_RETURN(r); 22469 if (pr.speed != info->speed) { 22470 LOG_INFO(BSL_LS_BCM_PORT, 22471 (BSL_META_U(unit, 22472 "Warning: bcm_port_info speed (%d) does NOT match " 22473 " current speed (%d). May have fec/link training/" 22474 "phy lane config mismatches!\n"), 22475 pr.speed, info->speed)); 22476 } 22477 pr.speed = info->speed; 22478 r = bcm_esw_port_resource_speed_set(unit, port, &pr); 22479 BCM_IF_ERROR_RETURN(r); 22480 } else 22481 #endif 22482 { 22483 r = bcm_esw_port_speed_set(unit, port, info->speed); 22484 } 22485 if (BCM_FAILURE(r)) { 22486 LOG_ERROR(BSL_LS_BCM_PORT, 22487 (BSL_META_U(unit, 22488 "bcm_port_speed_set failed:%s\n"), bcm_errmsg(r))); 22489 } 22490 BCM_IF_ERROR_RETURN(r); 22491 } 22492 22493 if (mask & BCM_PORT_ATTR_DUPLEX_MASK) { 22494 /*When AN=on, then duplex method will be auto-detected, hence don't set*/ 22495 if ((mask & BCM_PORT_ATTR_AUTONEG_MASK) && info->autoneg) { 22496 r = BCM_E_PARAM; 22497 if (BCM_FAILURE(r)) { 22498 LOG_ERROR(BSL_LS_BCM_PORT, 22499 (BSL_META_U(unit, 22500 "Autoneg:On. DUPLEX should be " 22501 "auto-detected :%s\n"), bcm_errmsg(r))); 22502 } 22503 BCM_IF_ERROR_RETURN(r); 22504 } 22505 r = bcm_esw_port_duplex_set(unit, port, info->duplex); 22506 if (BCM_FAILURE(r)) { 22507 LOG_ERROR(BSL_LS_BCM_PORT, 22508 (BSL_META_U(unit, 22509 "bcm_port_duplex_set failed:%s\n"), bcm_errmsg(r))); 22510 } 22511 BCM_IF_ERROR_RETURN(r); 22512 } 22513 22514 if (mask & (BCM_PORT_ATTR_PAUSE_TX_MASK | 22515 BCM_PORT_ATTR_PAUSE_RX_MASK)) { 22516 int tpause, rpause; 22517 22518 tpause = rpause = -1; 22519 if (mask & BCM_PORT_ATTR_PAUSE_TX_MASK) { 22520 tpause = info->pause_tx; 22521 } 22522 if (mask & BCM_PORT_ATTR_PAUSE_RX_MASK) { 22523 rpause = info->pause_rx; 22524 } 22525 r = bcm_esw_port_pause_set(unit, port, tpause, rpause); 22526 if (BCM_FAILURE(r)) { 22527 LOG_ERROR(BSL_LS_BCM_PORT, 22528 (BSL_META_U(unit, 22529 "bcm_port_pause_set failed:%s\n"), bcm_errmsg(r))); 22530 } 22531 BCM_IF_ERROR_RETURN(r); 22532 } 22533 22534 if (mask & BCM_PORT_ATTR_RATE_MCAST_MASK) { 22535 flags = (info->mcast_limit_enable) ? BCM_RATE_MCAST : 0; 22536 r = bcm_esw_rate_mcast_set(unit, info->mcast_limit, flags, port); 22537 if (r == BCM_E_UNAVAIL) { 22538 r = BCM_E_NONE; /* Ignore if not supported on chip */ 22539 } 22540 if (BCM_FAILURE(r)) { 22541 LOG_ERROR(BSL_LS_BCM_PORT, 22542 (BSL_META_U(unit, 22543 "bcm_rate_mcast_port_set failed:%s\n"), bcm_errmsg(r))); 22544 } 22545 BCM_IF_ERROR_RETURN(r); 22546 } 22547 22548 if (mask & BCM_PORT_ATTR_RATE_BCAST_MASK) { 22549 flags = (info->bcast_limit_enable) ? BCM_RATE_BCAST : 0; 22550 r = bcm_esw_rate_bcast_set(unit, info->bcast_limit, flags, port); 22551 if (r == BCM_E_UNAVAIL) { 22552 r = BCM_E_NONE; /* Ignore if not supported on chip */ 22553 } 22554 if (BCM_FAILURE(r)) { 22555 LOG_ERROR(BSL_LS_BCM_PORT, 22556 (BSL_META_U(unit, 22557 "bcm_rate_bcast_port_set failed:%s\n"), bcm_errmsg(r))); 22558 } 22559 BCM_IF_ERROR_RETURN(r); 22560 } 22561 22562 if (mask & BCM_PORT_ATTR_RATE_DLFBC_MASK) { 22563 flags = (info->dlfbc_limit_enable) ? BCM_RATE_DLF : 0; 22564 r = bcm_esw_rate_dlfbc_set(unit, info->dlfbc_limit, flags, port); 22565 if (r == BCM_E_UNAVAIL) { 22566 r = BCM_E_NONE; /* Ignore if not supported on chip */ 22567 } 22568 if (BCM_FAILURE(r)) { 22569 LOG_ERROR(BSL_LS_BCM_PORT, 22570 (BSL_META_U(unit, 22571 "bcm_rate_dlfbcast_port_set failed:%s\n"), 22572 bcm_errmsg(r))); 22573 } 22574 BCM_IF_ERROR_RETURN(r); 22575 } 22576 22577 if (mask & BCM_PORT_ATTR_STP_STATE_MASK) { 22578 r = bcm_esw_port_stp_set(unit, port, info->stp_state); 22579 if (BCM_FAILURE(r)) { 22580 LOG_ERROR(BSL_LS_BCM_PORT, 22581 (BSL_META_U(unit, 22582 "bcm_port_stp_set failed:%s\n"), bcm_errmsg(r))); 22583 } 22584 BCM_IF_ERROR_RETURN(r); 22585 } 22586 22587 if (mask & BCM_PORT_ATTR_FRAME_MAX_MASK) { 22588 r = bcm_esw_port_frame_max_set(unit, port, info->frame_max); 22589 if (BCM_FAILURE(r)) { 22590 LOG_ERROR(BSL_LS_BCM_PORT, 22591 (BSL_META_U(unit, 22592 "bcm_port_frame_max_set failed:%s\n"), bcm_errmsg(r))); 22593 } 22594 BCM_IF_ERROR_RETURN(r); 22595 } 22596 22597 if (mask & BCM_PORT_ATTR_MDIX_MASK) { 22598 r = bcm_esw_port_mdix_set(unit, port, info->mdix); 22599 if (BCM_FAILURE(r)) { 22600 LOG_ERROR(BSL_LS_BCM_PORT, 22601 (BSL_META_U(unit, 22602 "bcm_port_mdix_set failed:%s\n"), bcm_errmsg(r))); 22603 } 22604 BCM_IF_ERROR_RETURN(r); 22605 } 22606 22607 return BCM_E_NONE; 22608 } 22609 22610 /* 22611 * Function: 22612 * bcm_port_info_get 22613 * Purpose: 22614 * Get all information on the port 22615 * Parameters: 22616 * unit - StrataSwitch unit # 22617 * port - StrataSwitch port # 22618 * info - Pointer to structure in which to save values 22619 * Returns: 22620 * BCM_E_XXX 22621 */ 22622 22623 int 22624 bcm_esw_port_info_get(int unit, bcm_port_t port, bcm_port_info_t *info) 22625 { 22626 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 22627 22628 /* Make sure port module is initialized. */ 22629 PORT_INIT(unit); 22630 22631 bcm_port_info_t_init(info); 22632 22633 if (IS_ST_PORT(unit, port)) { 22634 info->action_mask = BCM_PORT_HERC_ATTRS; 22635 if (SOC_IS_XGS_SWITCH(unit)) { 22636 info->action_mask |= BCM_PORT_ATTR_STP_STATE_MASK | 22637 BCM_PORT_ATTR_DISCARD_MASK | 22638 BCM_PORT_ATTR_LEARN_MASK; 22639 } 22640 } else { 22641 info->action_mask = BCM_PORT_ATTR_ALL_MASK; 22642 } 22643 22644 return bcm_esw_port_selective_get(unit, port, info); 22645 } 22646 22647 /* 22648 * Function: 22649 * bcm_port_info_set 22650 * Purpose: 22651 * Set all information on the port 22652 * Parameters: 22653 * unit - StrataSwitch unit # 22654 * port - StrataSwitch port # 22655 * info - Pointer to structure in which to save values 22656 * Returns: 22657 * BCM_E_XXX 22658 * Notes: 22659 * Checks if AN is on, and if so, clears the 22660 * proper bits in the action mask. 22661 */ 22662 22663 int 22664 bcm_esw_port_info_set(int unit, bcm_port_t port, bcm_port_info_t *info) 22665 { 22666 /* Make sure port module is initialized. */ 22667 PORT_INIT(unit); 22668 22669 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 22670 22671 if (IS_ST_PORT(unit, port)) { 22672 info->action_mask = BCM_PORT_HERC_ATTRS; 22673 if (SOC_IS_XGS_SWITCH(unit)) { 22674 info->action_mask |= BCM_PORT_ATTR_STP_STATE_MASK | 22675 BCM_PORT_ATTR_DISCARD_MASK | 22676 BCM_PORT_ATTR_LEARN_MASK; 22677 } 22678 } else { 22679 info->action_mask = BCM_PORT_ATTR_ALL_MASK; 22680 } 22681 22682 /* If autoneg is set, remove those attributes controlled by it */ 22683 if (info->autoneg) { 22684 info->action_mask &= ~BCM_PORT_AN_ATTRS; 22685 } 22686 22687 return bcm_esw_port_selective_set(unit, port, info); 22688 } 22689 22690 /* 22691 * Function: 22692 * bcm_port_info_save 22693 * Purpose: 22694 * Save the current settings of a port 22695 * Parameters: 22696 * unit - StrataSwitch unit # 22697 * port - StrataSwitch port # 22698 * info - Pointer to structure in which to save values 22699 * Returns: 22700 * BCM_E_XXX 22701 * Notes: 22702 * The action_mask will be adjusted so that the 22703 * proper values will be set when a restore is made. 22704 * This mask should not be altered between these calls. 22705 */ 22706 22707 int 22708 bcm_esw_port_info_save(int unit, bcm_port_t port, bcm_port_info_t *info) 22709 { 22710 /* Make sure port module is initialized. */ 22711 PORT_INIT(unit); 22712 22713 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 22714 22715 if (IS_ST_PORT(unit, port)) { 22716 info->action_mask = BCM_PORT_HERC_ATTRS; 22717 if (SOC_IS_XGS_SWITCH(unit)) { 22718 info->action_mask |= BCM_PORT_ATTR_STP_STATE_MASK; 22719 } 22720 #ifdef BCM_GXPORT_SUPPORT 22721 if (IS_GX_PORT(unit, port)) { 22722 info->action_mask |= BCM_PORT_ATTR_AUTONEG_MASK; 22723 } 22724 #endif 22725 } else { 22726 info->action_mask = BCM_PORT_ATTR_ALL_MASK; 22727 } 22728 info->action_mask2 = BCM_PORT_ATTR2_PORT_ABILITY; 22729 22730 BCM_IF_ERROR_RETURN(bcm_esw_port_selective_get(unit, port, info)); 22731 22732 if (info->autoneg) { 22733 info->action_mask &= ~BCM_PORT_AN_ATTRS; 22734 } 22735 22736 return BCM_E_NONE; 22737 } 22738 22739 /* 22740 * Function: 22741 * bcm_port_info_restore 22742 * Purpose: 22743 * Restore port settings saved by info_save 22744 * Parameters: 22745 * unit - StrataSwitch unit # 22746 * port - StrataSwitch port # 22747 * info - Pointer to structure with info from port_info_save 22748 * Returns: 22749 * BCM_E_XXX 22750 * Notes: 22751 * bcm_port_info_save has done all the work. 22752 * We just call port_selective_set. 22753 */ 22754 22755 int 22756 bcm_esw_port_info_restore(int unit, bcm_port_t port, bcm_port_info_t *info) 22757 { 22758 /* Make sure port module is initialized. */ 22759 PORT_INIT(unit); 22760 22761 return bcm_esw_port_selective_set(unit, port, info); 22762 } 22763 22764 /* 22765 * Function: 22766 * bcm_port_phy_drv_name_get 22767 * Purpose: 22768 * Return the name of the PHY driver being used on a port. 22769 * Parameters: 22770 * unit - StrataSwitch unit # 22771 * port - StrataSwitch port # 22772 * Returns: 22773 * Pointer to static string 22774 */ 22775 int 22776 bcm_esw_port_phy_drv_name_get(int unit, bcm_port_t port, char *name, int len) 22777 { 22778 int str_len; 22779 22780 /* Make sure port module is initialized. */ 22781 PORT_INIT(unit); 22782 22783 if(bcm_common_oamp_port_enable_get(unit, port)) { 22784 LOG_ERROR(BSL_LS_BCM_PORT, 22785 (BSL_META("Error: Not permitted on OAMP port %d.n"), 22786 port)); 22787 return BCM_E_PARAM; 22788 } 22789 22790 /* Call Port Control module */ 22791 if (SOC_USE_PORTCTRL(unit)) { 22792 return bcmi_esw_portctrl_phy_drv_name_get(unit, port, name, len); 22793 } 22794 22795 if (bcm_port_info[unit] == NULL) { 22796 str_len = sal_strlen("driver not initialized"); 22797 if (str_len <= len) { 22798 sal_strncpy(name, "driver not initialized", len); 22799 } 22800 return BCM_E_INIT; 22801 } 22802 if (!SOC_PORT_VALID(unit, port)) { 22803 str_len = sal_strlen("invalid port"); 22804 if (str_len <= len) { 22805 sal_strncpy(name, "invalid port", len); 22806 } 22807 return BCM_E_PORT; 22808 } 22809 return (soc_phyctrl_drv_name_get(unit, port, name, len)); 22810 } 22811 22812 /* 22813 * Function: 22814 * _bcm_port_encap_xport_set 22815 * Purpose: 22816 * Convert 10G Ether port to Higig port, or reverse 22817 * Notes; 22818 * Must be called with PORT_LOCK held. 22819 */ 22820 22821 int 22822 _bcm_port_encap_xport_set(int unit, bcm_port_t port, int mode, 22823 int update_port_mode) 22824 { 22825 #ifdef BCM_FIREBOLT_SUPPORT 22826 bcm_stg_t stg; 22827 int to_higig; 22828 soc_field_t port_type_field; 22829 soc_reg_t egr_port_reg; 22830 soc_port_ability_t ability; 22831 soc_port_mode_t non_ieee_speed; 22832 int an, an_done, force_speed, port_type; 22833 uint32 entry[SOC_MAX_MEM_WORDS]; 22834 #ifdef BCM_TRIDENT2_SUPPORT 22835 int config_speed = 0; 22836 #endif 22837 #if defined(BCM_KATANA2_SUPPORT) 22838 int speed = 0; 22839 bcmMxqPhyPortMode_t phy_mode; 22840 #endif 22841 int enable = 0; 22842 #if defined(BCM_XGS3_SWITCH_SUPPORT) 22843 uint32 rval = 0; 22844 uint32 mtu = 0; 22845 soc_info_t *si = &SOC_INFO(unit); 22846 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 22847 22848 if (SOC_USE_PORTCTRL(unit)) { 22849 return bcmi_esw_portctrl_encap_xport_set(unit, port, mode); 22850 } 22851 22852 to_higig = (mode != BCM_PORT_ENCAP_IEEE); 22853 port_type_field = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 22854 SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) || 22855 SOC_IS_HURRICANEX(unit) || SOC_IS_TD_TT(unit) || 22856 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)|| 22857 SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit)) ? 22858 PORT_TYPEf : HIGIG_PACKETf; 22859 egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 22860 SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) || 22861 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ? 22862 EGR_PORT_64r : EGR_PORTr; 22863 22864 #if defined(BCM_KATANA2_SUPPORT) 22865 if (to_higig && SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit) && 22866 update_port_mode) { 22867 /* 22868 * Updating the phy_mode according to the port encap type. 22869 * Using 13G as default speed for higig since the underlying routine 22870 * do not differentiate on higig speeds. 22871 */ 22872 SOC_IF_ERROR_RETURN 22873 (soc_katana2_get_phy_port_mode(unit, port, 13000, &phy_mode)); 22874 } 22875 #endif 22876 SOC_IF_ERROR_RETURN 22877 (MAC_ENCAP_SET(PORT(unit, port).p_mac, unit, port, mode)); 22878 22879 if ((SOC_IS_SABER2(unit) || SOC_IS_HURRICANE2(unit)) && IS_XL_PORT(unit, port)) { 22880 if (mode == BCM_PORT_ENCAP_HIGIG2_LITE) { 22881 SOC_PBMP_PORT_ADD(SOC_INFO(unit).hl.bitmap, port); 22882 } else { 22883 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port); 22884 } 22885 } 22886 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 22887 if ((mode == BCM_PORT_ENCAP_HIGIG2_LITE) && IS_ST_PORT(unit, port)) { 22888 /*KT2: HL port is treated as GE port too*/ 22889 SOC_PBMP_PORT_ADD(SOC_INFO(unit).hl.bitmap, port); 22890 SOC_PBMP_PORT_ADD(SOC_INFO(unit).ge.bitmap, port); 22891 } else if ((mode == BCM_PORT_ENCAP_IEEE) && IS_XE_PORT(unit,port)) { 22892 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port); 22893 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).ge.bitmap, port); 22894 } 22895 soc_dport_map_update(unit); 22896 } 22897 /* 22898 * MAC_ENCAP_SET() would change the ING_MTU to defalut value. 22899 * So also change EGR_MTU to default value manually. 22900 */ 22901 #ifdef BCM_SHADOW_SUPPORT 22902 if (SOC_IS_SHADOW(unit)) { 22903 mtu = (1 << soc_reg_field_length(unit, EGR_L2_MTUr, VALUEf)) - 1; 22904 soc_reg_field_set(unit, EGR_L2_MTUr, &rval, 22905 VALUEf, mtu); 22906 SOC_IF_ERROR_RETURN(WRITE_EGR_L2_MTUr(unit, port, rval)); 22907 } else 22908 #endif /* BCM_SHADOW_SUPPORT */ 22909 22910 #ifdef BCM_XGS3_SWITCH_SUPPORT 22911 if (SOC_IS_XGS3_SWITCH(unit)) { 22912 soc_reg_t reg; 22913 soc_mem_t mem; 22914 uint32 field_val_clear = 0; 22915 22916 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 22917 mem = EGR_MTUm; 22918 mtu = si->max_mtu; 22919 if (soc_feature(unit, soc_feature_egr_all_profile)) { 22920 BCM_IF_ERROR_RETURN( 22921 bcm_esw_port_egr_lport_field_set(unit, port, mem, 22922 MTU_SIZEf, mtu)); 22923 } else { 22924 SOC_IF_ERROR_RETURN( 22925 soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, entry)); 22926 soc_mem_field_set(unit, mem, entry, MTU_SIZEf, &mtu); 22927 if (soc_mem_field_valid(unit, mem, MTU_ENABLEf)) { 22928 soc_mem_field_set(unit, mem, entry, MTU_ENABLEf, 22929 &field_val_clear); 22930 } 22931 SOC_IF_ERROR_RETURN( 22932 soc_mem_write(unit, mem, MEM_BLOCK_ANY, port, entry)); 22933 } 22934 } else { 22935 reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr; 22936 mtu = si->max_mtu; 22937 soc_reg_field_set(unit, reg, &rval, MTU_SIZEf, mtu); 22938 if (soc_reg_field_valid(unit, reg, MTU_ENABLEf)) { 22939 soc_reg_field_set(unit, reg, &rval, MTU_ENABLEf, 0); 22940 } 22941 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 22942 } 22943 } 22944 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 22945 22946 if (!to_higig) { 22947 SOC_IF_ERROR_RETURN 22948 (MAC_INTERFACE_SET(PORT(unit, port).p_mac, 22949 unit, port, SOC_PORT_IF_XGMII)); 22950 } 22951 22952 /* Sepcific for GH on avoiding port speed change */ 22953 if (!soc_feature(unit, soc_feature_hg_no_speed_change)) { 22954 BCM_IF_ERROR_RETURN 22955 (bcm_esw_port_ability_local_get(unit, port, &ability)); 22956 22957 non_ieee_speed = ability.speed_full_duplex & 22958 ~(SOC_PA_SPEED_100GB | SOC_PA_SPEED_40GB | SOC_PA_SPEED_10GB | 22959 SOC_PA_SPEED_2500MB | SOC_PA_SPEED_1000MB | SOC_PA_SPEED_100MB | 22960 SOC_PA_SPEED_10MB); 22961 22962 BCM_IF_ERROR_RETURN 22963 (bcm_esw_port_ability_advert_get(unit, port, &ability)); 22964 if (to_higig) { 22965 ability.speed_full_duplex |= non_ieee_speed; 22966 ability.pause &= ~(SOC_PA_PAUSE | SOC_PA_PAUSE_ASYMM); 22967 /* Retrieving the max speed */ 22968 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_max(unit, port, &force_speed)); 22969 force_speed = force_speed == 0 ? 22970 SOC_CONTROL(unit)->info.port_speed_max[port] : force_speed; 22971 22972 #ifdef BCM_TRIDENT2_SUPPORT 22973 if (SOC_IS_TRIDENT2(unit) && 22974 soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, 0) && 22975 (si->port_num_lanes[port] != 4)) { 22976 config_speed = soc_property_port_get(unit, port, spn_PORT_MAX_SPEED, force_speed); 22977 force_speed = (force_speed > config_speed) ? config_speed : force_speed; 22978 } 22979 #endif 22980 22981 ability.speed_full_duplex |= SOC_PA_SPEED(force_speed); 22982 } else { 22983 ability.speed_full_duplex &= ~non_ieee_speed; 22984 force_speed = IS_GE_PORT(unit , port) ? 1000 : IS_CE_PORT(unit , port) ? 22985 100000 : SOC_CONTROL(unit)->info.port_speed_max[port] >= 40000 ? 22986 40000 : SOC_CONTROL(unit)->info.port_speed_max[port] >= 10000 ? 22987 10000 : 1000; 22988 #if defined(BCM_KATANA2_SUPPORT) 22989 /* For Katana2 Warpcore the xlport_mode_reg. The phy_port_mode value 22990 * differs when speed is 1000 vs 2500. 22991 * GE port does not necessarily have 1000 speed always. 22992 * The VCO frequency can change ased on phy_port_mode, 22993 * core_port_mode and number of lanes on Warpcore. 22994 * The lower layer Warpcore driver relies on these values. 22995 * So we need to set the correct forced speed for the port */ 22996 if ((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && force_speed == 1000) { 22997 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed)); 22998 force_speed = (speed == 2500) ? speed : force_speed; 22999 } 23000 #endif 23001 } 23002 23003 BCM_IF_ERROR_RETURN 23004 (bcm_esw_port_ability_advert_set(unit, port, &ability)); 23005 23006 #ifdef BCM_KATANA2_SUPPORT 23007 #ifdef BCM_METROLITE_SUPPORT 23008 if (SOC_IS_METROLITE(unit)) { 23009 BCM_IF_ERROR_RETURN 23010 (_bcm_ml_update_port_mode(unit, port, force_speed)); 23011 23012 if (IS_XL_PORT(unit,port) && 23013 ((mode == BCM_PORT_ENCAP_HIGIG2) || (mode == BCM_PORT_ENCAP_HIGIG))) { 23014 SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, force_speed)); 23015 SOC_IF_ERROR_RETURN(MAC_SPEED_SET(PORT(unit, port).p_mac, 23016 unit, port, force_speed)); 23017 } 23018 } else 23019 #endif 23020 23021 #ifdef BCM_SABER2_SUPPORT 23022 if (SOC_IS_SABER2(unit)) { 23023 BCM_IF_ERROR_RETURN 23024 (_bcm_sb2_update_port_mode(unit, port, force_speed)); 23025 23026 if (IS_XL_PORT(unit,port) && 23027 ((mode == BCM_PORT_ENCAP_HIGIG2) || (mode == BCM_PORT_ENCAP_HIGIG))) { 23028 SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, force_speed)); 23029 SOC_IF_ERROR_RETURN(MAC_SPEED_SET(PORT(unit, port).p_mac, 23030 unit, port, force_speed)); 23031 } 23032 } else 23033 #endif 23034 if(SOC_IS_KATANA2(unit) && update_port_mode) { 23035 BCM_IF_ERROR_RETURN 23036 (_bcm_kt2_update_port_mode(unit, port, force_speed)); 23037 } 23038 #endif 23039 SOC_IF_ERROR_RETURN 23040 (soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done)); 23041 /* some phy driver will enable the port no matter previous port 23042 * state while executing speed_set or autoneg_set. So we need to 23043 * get the port state before speed_set or autoneg_set, and set it 23044 * back after speed_set or autoneg_set. So that it can keep the 23045 * same port state before after speed_set or autoneg_set*/ 23046 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable)); 23047 23048 /* Some mac driver re-init phy while executing MAC_ENCAP_SET, in that case 23049 * autoneg is probably always true here */ 23050 if (an) { 23051 SOC_IF_ERROR_RETURN(bcm_esw_port_autoneg_set(unit, port, TRUE)); 23052 } else { 23053 SOC_IF_ERROR_RETURN(soc_phyctrl_speed_set(unit, port, force_speed)); 23054 } 23055 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, enable)); 23056 } 23057 23058 /* Now we propagate the changes */ 23059 port_type = to_higig ? 1 : 0; 23060 if (soc_mem_field_valid(unit, PORT_TABm, port_type_field)) { 23061 SOC_IF_ERROR_RETURN(soc_mem_field32_modify( 23062 unit, PORT_TABm, port, port_type_field, port_type)); 23063 } 23064 if (SOC_MEM_IS_VALID(unit, EGR_PORTm)) { 23065 if (soc_mem_field_valid(unit, EGR_PORTm, port_type_field)) { 23066 SOC_IF_ERROR_RETURN 23067 (soc_mem_field32_modify(unit, EGR_PORTm, port, port_type_field, 23068 port_type)); 23069 } 23070 } else { 23071 SOC_IF_ERROR_RETURN 23072 (soc_reg_field32_modify(unit, egr_port_reg, port, port_type_field, 23073 port_type)); 23074 } 23075 23076 if (SOC_MEM_IS_VALID(unit, EGR_ING_PORTm)) { 23077 if (!IS_CPU_PORT(unit, port) && !IS_LB_PORT(unit, port)) { 23078 SOC_IF_ERROR_RETURN 23079 (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, PORT_TYPEf, 23080 mode == BCM_PORT_ENCAP_IEEE ? 0 : 1)); 23081 } 23082 } 23083 23084 23085 if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) { 23086 icontrol_opcode_bitmap_entry_t entry; 23087 soc_pbmp_t pbmp; 23088 23089 SOC_IF_ERROR_RETURN 23090 (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 23091 SOC_PBMP_CLEAR(pbmp); 23092 if (to_higig) { 23093 SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit)); 23094 } 23095 soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry, 23096 BITMAPf, &pbmp); 23097 SOC_IF_ERROR_RETURN 23098 (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 23099 } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 23100 SOC_IS_VALKYRIE2(unit)) { 23101 uint64 cpu_pbm64; 23102 uint64 rval64; /* Current 64 bit register data. */ 23103 COMPILER_64_ZERO(cpu_pbm64); 23104 COMPILER_64_SET(cpu_pbm64, 0, to_higig ? 1 : 0); 23105 SOC_IF_ERROR_RETURN(READ_ICONTROL_OPCODE_BITMAP_64r(unit, port, 23106 &rval64)); 23107 soc_reg64_field_set(unit, ICONTROL_OPCODE_BITMAP_64r, &rval64, 23108 BITMAPf, cpu_pbm64); 23109 SOC_IF_ERROR_RETURN(WRITE_ICONTROL_OPCODE_BITMAP_64r(unit, port, 23110 rval64)); 23111 } else if (SOC_REG_IS_VALID(unit,ICONTROL_OPCODE_BITMAP_LOr) && 23112 SOC_REG_IS_VALID(unit,ICONTROL_OPCODE_BITMAP_HIr)) { 23113 uint64 fval64, rval64; 23114 uint32 t_port; 23115 pbmp_t curr_pbmp; 23116 soc_reg_t reg; 23117 23118 BCM_PBMP_CLEAR(curr_pbmp); 23119 COMPILER_64_ZERO(fval64); 23120 23121 /* Set HG ingress CPU Opcode map to the CPU */ 23122 if (CMIC_PORT(unit) < 64) { 23123 reg = ICONTROL_OPCODE_BITMAP_LOr; 23124 t_port = CMIC_PORT(unit); 23125 } else { 23126 reg = ICONTROL_OPCODE_BITMAP_HIr; 23127 t_port = CMIC_PORT(unit) - 64; 23128 } 23129 23130 23131 if (to_higig) { 23132 SOC_PBMP_PORT_ADD(curr_pbmp, t_port); 23133 } 23134 23135 BCM_IF_ERROR_RETURN(soc_reg_get(unit, 23136 reg, port, 0, &rval64)); 23137 COMPILER_64_SET(fval64, 23138 SOC_PBMP_WORD_GET(curr_pbmp, 1), 23139 SOC_PBMP_WORD_GET(curr_pbmp, 0)); 23140 23141 soc_reg64_field_set(unit, 23142 reg, &rval64, BITMAPf, fval64); 23143 BCM_IF_ERROR_RETURN(soc_reg_set(unit, 23144 reg, port, 0, rval64)); 23145 23146 } else if (SOC_REG_IS_VALID(unit,ICONTROL_OPCODE_BITMAPr)) { 23147 23148 /* Set HG ingress CPU Opcode map to the CPU */ 23149 int pbm_len; 23150 uint32 cpu_pbm = 0; 23151 23152 if (to_higig) { 23153 if (SOC_IS_TR_VL(unit)) { 23154 soc_xgs3_port_to_higig_bitmap(unit, CMIC_PORT(unit), 23155 &cpu_pbm); 23156 } else if (CMIC_PORT(unit)) { 23157 pbm_len = soc_reg_field_length(unit, ICONTROL_OPCODE_BITMAPr, 23158 BITMAPf); 23159 cpu_pbm = 1 << (pbm_len - 1); 23160 } else { 23161 cpu_pbm = 1; 23162 } 23163 } /* else, cpu_pbm = 0 */ 23164 23165 SOC_IF_ERROR_RETURN 23166 (soc_reg_field32_modify(unit, ICONTROL_OPCODE_BITMAPr, 23167 port, BITMAPf, cpu_pbm)); 23168 } 23169 23170 if (to_higig) { 23171 /* HG ports to forwarding */ 23172 BCM_IF_ERROR_RETURN(bcm_esw_port_stp_set(unit, port, 23173 BCM_STG_STP_FORWARD)); 23174 } 23175 23176 #if defined(BCM_XGS3_SWITCH_SUPPORT) 23177 /* 23178 * Higig ports need the MIRROR_CONTROL.M_ENABLE=1 in order to respond to 23179 * the mirror bit in the Higig headers. 23180 */ 23181 if (to_higig) { 23182 BCM_IF_ERROR_RETURN(_bcm_esw_mirror_enable_set(unit, port, TRUE)); 23183 } 23184 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 23185 23186 /* Clear mirror enable settings */ 23187 /* coverity[stack_use_callee] */ 23188 /* coverity[stack_use_overflow] */ 23189 BCM_IF_ERROR_RETURN(bcm_esw_mirror_port_set(unit, port, -1, -1, 0)); 23190 23191 /* Set untagged state in default VLAN properly */ 23192 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_untag_update(unit, port, to_higig)); 23193 23194 /* Resolve STG 0 */ 23195 BCM_IF_ERROR_RETURN(bcm_esw_stg_default_get(unit, &stg)); 23196 BCM_IF_ERROR_RETURN 23197 (bcm_esw_stg_stp_set(unit, 0, port, 23198 to_higig ? BCM_STG_STP_FORWARD : BCM_STG_STP_DISABLE)); 23199 23200 #ifdef BCM_TRX_SUPPORT 23201 /* Reset the vlan default action */ 23202 if (SOC_IS_TRX(unit) && 23203 (soc_feature(unit, soc_feature_vlan_action) || 23204 soc_feature(unit, soc_feature_egr_vlan_action))) { 23205 bcm_vlan_action_set_t action; 23206 23207 BCM_IF_ERROR_RETURN 23208 (_bcm_trx_vlan_port_egress_default_action_get(unit, 23209 port, &action)); 23210 /* Backward compatible defaults */ 23211 if (to_higig && (!SOC_IS_TRIDENT3X(unit))) { 23212 action.ot_outer = bcmVlanActionDelete; 23213 action.dt_outer = bcmVlanActionDelete; 23214 } else { 23215 action.ot_outer = bcmVlanActionNone; 23216 action.dt_outer = bcmVlanActionNone; 23217 } 23218 BCM_IF_ERROR_RETURN 23219 (_bcm_trx_vlan_port_egress_default_action_set(unit, 23220 port, &action)); 23221 } 23222 #endif 23223 23224 #ifdef INCLUDE_L3 23225 if (soc_feature(unit, soc_feature_ip_mcast)) { 23226 BCM_IF_ERROR_RETURN(bcm_esw_ipmc_egress_port_set(unit, port, 23227 to_higig ? _soc_mac_all_ones :_soc_mac_all_zeroes, 23228 0, 0, 0)); 23229 } 23230 #endif /* INCLUDE_L3 */ 23231 23232 return BCM_E_NONE; 23233 #else 23234 return BCM_E_PARAM; 23235 #endif 23236 } 23237 23238 /* 23239 * Function: 23240 * _bcm_port_encap_stport_set 23241 * Purpose: 23242 * Convert 2.5G Higig 2 port to Ether port, or reverse 23243 */ 23244 int 23245 _bcm_port_encap_stport_set(int unit, bcm_port_t port, int mode) 23246 { 23247 #if defined(BCM_RAVEN_SUPPORT) || defined (BCM_TRIUMPH2_SUPPORT) || \ 23248 defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 23249 uint32 rval; 23250 bcm_stg_t stg; 23251 int to_higig = 0, max_mtu = 0; 23252 uint32 tab_higig_type; 23253 soc_info_t *si = &SOC_INFO(unit); 23254 soc_field_t hg_en[6] = {-1, HGIG2_EN_S0f, HGIG2_EN_S1f, -1, 23255 HGIG2_EN_S3f, HGIG2_EN_S4f}; 23256 soc_field_t port_type; 23257 soc_reg_t egr_port; 23258 23259 if (mode == BCM_PORT_ENCAP_HIGIG2 || mode == BCM_PORT_ENCAP_HIGIG2_LITE 23260 || mode == BCM_PORT_ENCAP_HIGIG || mode == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) { 23261 to_higig = TRUE; 23262 } 23263 23264 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 23265 SOC_IS_GREYHOUND2(unit)) { 23266 if (!soc_feature(unit, soc_feature_wh2)) { 23267 return BCM_E_INTERNAL; 23268 } 23269 } 23270 23271 /* This check is not correct for devices supporting embedded higig */ 23272 if (!soc_feature(unit, soc_feature_embedded_higig) && 23273 !soc_feature(unit, soc_feature_higig_over_ethernet)) { 23274 if (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit)) { 23275 if ((port != 26) && (port != 27) && (port != 28) && (port != 29)) { 23276 return BCM_E_PORT; 23277 } 23278 SOC_IF_ERROR_RETURN 23279 (soc_reg_field32_modify(unit, EHG_RX_CONTROLr, port, MODEf, 23280 to_higig ? 2 : 0)); 23281 } else if (SOC_IS_HURRICANE2(unit)) { 23282 if ((port < 26) || (port > 29)) { 23283 return BCM_E_PORT; 23284 } 23285 } else if (SOC_IS_KATANA(unit)) { 23286 /* Only ports 25..34 are HGL capable */ 23287 if ((port < 25) || (port > 34)) { 23288 return BCM_E_PORT; 23289 } 23290 } else if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 23291 /* Only ports 25..40 are HGL capable */ 23292 if ((port < 25) || (port > 40)) { 23293 return BCM_E_PORT; 23294 } 23295 } else if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TOMAHAWKX(unit) || 23296 SOC_IS_TRIDENT3X(unit)) { 23297 /* Need to check what is the right condition for Embedded Higig */ 23298 } else if (soc_feature(unit, soc_feature_wh2)) { 23299 /* All ports are HGL capable */ 23300 } else { 23301 if ((port != 1) && (port != 2) && (port != 4) && (port != 5)) { 23302 return BCM_E_PORT; 23303 } 23304 } 23305 } 23306 23307 #if defined(BCM_KATANA2_SUPPORT) 23308 if (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) { 23309 SOC_IF_ERROR_RETURN(MAC_ENCAP_SET(PORT(unit, port).p_mac, 23310 unit, port, mode)); 23311 } else 23312 #endif 23313 { 23314 port_type = SOC_MEM_FIELD_VALID(unit, 23315 SOC_PORT_MEM_TAB(unit, port), 23316 HIGIG_PACKETf) ? 23317 HIGIG_PACKETf : PORT_TYPEf; 23318 23319 BCM_IF_ERROR_RETURN 23320 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 23321 port_type, to_higig)); 23322 23323 if (to_higig == 1) { 23324 if (mode == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) { 23325 tab_higig_type = BCM_PORT_HG_TYPE_HGOE_TRANSPORT; 23326 } else if (mode == BCM_PORT_ENCAP_HIGIG) { 23327 tab_higig_type = BCM_PORT_HG_TYPE_HIGIGPLUS; 23328 } else { 23329 tab_higig_type = BCM_PORT_HG_TYPE_HIGIG2_NORMAL; 23330 } 23331 } else { 23332 tab_higig_type = 0; 23333 } 23334 23335 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, HG_TYPEf)) { 23336 SOC_IF_ERROR_RETURN 23337 (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, 23338 HG_TYPEf, tab_higig_type)); 23339 } 23340 23341 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, HG_TYPEf)) { 23342 SOC_IF_ERROR_RETURN 23343 (soc_mem_field32_modify(unit, EGR_PORTm, port, 23344 HG_TYPEf, tab_higig_type)); 23345 } 23346 23347 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, PORT_TYPEf)) { 23348 SOC_IF_ERROR_RETURN 23349 (soc_mem_field32_modify(unit, EGR_PORTm, port, 23350 PORT_TYPEf, to_higig)); 23351 } else { 23352 if (SOC_REG_IS_VALID(unit, EGR_PORT_64r)) { 23353 egr_port = EGR_PORT_64r; 23354 } else { 23355 egr_port = EGR_PORTr; 23356 } 23357 SOC_IF_ERROR_RETURN 23358 (soc_reg_field32_modify(unit, egr_port, port, 23359 port_type, to_higig)); 23360 } 23361 23362 /* The port number check is for Coverity. No port > 6 will 23363 * reach this logic on Raven. */ 23364 if (SOC_IS_RAVEN(unit) && (port < 6)) { 23365 SOC_IF_ERROR_RETURN 23366 (soc_reg_field32_modify(unit, GPORT_CONFIGr, port, 23367 hg_en[port], to_higig)); 23368 } 23369 } 23370 23371 if (to_higig) { 23372 BCM_IF_ERROR_RETURN(bcm_esw_port_pause_set(unit, port, 0, 0)); 23373 /* For encap to hg/st port, SOC_PORT_MIN need to update or 23374 cannot do SOC_PBMP_PORT_ADD if the port is lower than 23375 SOC_PORT_MIN 23376 */ 23377 if ((port < SOC_PORT_MIN(unit,st)) || (SOC_PORT_MIN(unit,st) == -1)) { 23378 SOC_PORT_MIN(unit,st) = port; 23379 } 23380 if (port > SOC_PORT_MAX(unit,st)) { 23381 SOC_PORT_MAX(unit,st) = port; 23382 } 23383 23384 SOC_PBMP_PORT_ADD(si->st.bitmap, port); 23385 SOC_PBMP_PORT_ADD(si->hl.bitmap, port); 23386 SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port); 23387 SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port); 23388 23389 SOC_PBMP_PORT_INFO_UPDATE(si->xe); 23390 23391 max_mtu = SOC_INFO(unit).max_mtu; 23392 BCM_IF_ERROR_RETURN(bcm_esw_port_frame_max_set(unit, port, max_mtu)); 23393 } else { 23394 SOC_PBMP_PORT_REMOVE(si->st.bitmap, port); 23395 SOC_PBMP_PORT_REMOVE(si->hl.bitmap, port); 23396 SOC_PBMP_PORT_ADD(si->ether.bitmap, port); 23397 23398 /* Set pause and frame - other abilities depend on the board and 23399 * the application needs to call other APIs appropriately */ 23400 BCM_IF_ERROR_RETURN(bcm_esw_port_pause_set(unit, port, 1, 1)); 23401 max_mtu = SOC_INFO(unit).max_mtu - 4; 23402 BCM_IF_ERROR_RETURN(bcm_esw_port_frame_max_set(unit, port, max_mtu)); 23403 } 23404 SOC_PBMP_PORT_INFO_UPDATE(si->ether); 23405 SOC_PBMP_PORT_INFO_UPDATE(si->st); 23406 SOC_PBMP_PORT_INFO_UPDATE(si->hl); 23407 23408 /* Set HG ingress CPU Opcode map to the CPU */ 23409 if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) { 23410 icontrol_opcode_bitmap_entry_t entry; 23411 soc_pbmp_t pbmp; 23412 23413 SOC_IF_ERROR_RETURN 23414 (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 23415 SOC_PBMP_CLEAR(pbmp); 23416 if (to_higig) { 23417 SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit)); 23418 } 23419 soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry, 23420 BITMAPf, &pbmp); 23421 SOC_IF_ERROR_RETURN 23422 (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 23423 } else if (SOC_REG_IS_VALID(unit, ICONTROL_OPCODE_BITMAP_64r)) { 23424 uint64 cpu_pbm64; 23425 uint64 rval64; /* Current 64 bit register data. */ 23426 COMPILER_64_ZERO(cpu_pbm64); 23427 COMPILER_64_SET(cpu_pbm64, 0, to_higig ? 1 : 0); 23428 SOC_IF_ERROR_RETURN( 23429 READ_ICONTROL_OPCODE_BITMAP_64r(unit, port,&rval64)); 23430 23431 soc_reg64_field_set(unit, ICONTROL_OPCODE_BITMAP_64r, &rval64, 23432 BITMAPf, cpu_pbm64); 23433 23434 SOC_IF_ERROR_RETURN( 23435 WRITE_ICONTROL_OPCODE_BITMAP_64r(unit, port, rval64)); 23436 } else { 23437 uint32 cpu_pbm; 23438 23439 if(SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit)) { 23440 if(to_higig) { 23441 SOC_IF_ERROR_RETURN 23442 (soc_xgs3_port_to_higig_bitmap(unit, CMIC_PORT(unit), 23443 &cpu_pbm)); 23444 } else { 23445 cpu_pbm = 0; 23446 } 23447 } else { 23448 cpu_pbm = to_higig ? 1 : 0; 23449 } 23450 SOC_IF_ERROR_RETURN( 23451 READ_ICONTROL_OPCODE_BITMAPr(unit, port,&rval)); 23452 23453 soc_reg_field_set(unit, ICONTROL_OPCODE_BITMAPr, 23454 &rval, BITMAPf, cpu_pbm); 23455 23456 SOC_IF_ERROR_RETURN( 23457 WRITE_ICONTROL_OPCODE_BITMAPr(unit, port, rval)); 23458 } 23459 23460 /* HG ports to forwarding */ 23461 BCM_IF_ERROR_RETURN( 23462 bcm_esw_port_stp_set(unit, port, BCM_STG_STP_FORWARD)); 23463 23464 /* Set untagged state in default VLAN properly */ 23465 BCM_IF_ERROR_RETURN(_bcm_esw_vlan_untag_update(unit, port, to_higig)); 23466 23467 /* Resolve STG 0 */ 23468 BCM_IF_ERROR_RETURN(bcm_esw_stg_default_get(unit, &stg)); 23469 BCM_IF_ERROR_RETURN( 23470 bcm_esw_stg_stp_set(unit, stg, port, BCM_STG_STP_FORWARD)); 23471 23472 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 23473 /* Reset the vlan default action */ 23474 if ((SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) || 23475 SOC_IS_KATANA2(unit)) && 23476 soc_feature(unit, soc_feature_vlan_action)) { 23477 bcm_vlan_action_set_t action; 23478 23479 BCM_IF_ERROR_RETURN 23480 (_bcm_trx_vlan_port_egress_default_action_get(unit, 23481 port, &action)); 23482 if (to_higig) { 23483 action.ot_outer = bcmVlanActionDelete; 23484 action.dt_outer = bcmVlanActionDelete; 23485 } else { 23486 action.ot_outer = bcmVlanActionNone; 23487 action.dt_outer = bcmVlanActionNone; 23488 } 23489 BCM_IF_ERROR_RETURN 23490 (_bcm_trx_vlan_port_egress_default_action_set(unit, 23491 port, &action)); 23492 } 23493 #endif /* BCM_ENDURO_SUPPORT */ 23494 23495 return BCM_E_NONE; 23496 #else 23497 return BCM_E_PARAM; 23498 #endif 23499 } 23500 23501 /* 23502 * Function: 23503 * _bcm_port_ehg_header_mem_get 23504 * Purpose: 23505 * Calculates the correct memories for a given port 23506 * Parameters: 23507 * unit - (IN) device id 23508 * port - (IN) Physical port 23509 * tx_mem - (OUT) tx memory for EHG heade 23510 * rx_mem - (OUT) rx memory for EHG heade 23511 * rx_mask_mem - (OUT) rx mask memory for EHG heade 23512 * Returns: 23513 * BCM_E_XXX 23514 */ 23515 STATIC int 23516 _bcm_port_ehg_header_mem_get(int unit, bcm_port_t port, soc_mem_t *tx_mem, 23517 soc_mem_t *rx_mem, soc_mem_t *rx_mask_mem) 23518 { 23519 int phy_port; 23520 23521 if (NULL == tx_mem || NULL == rx_mem || NULL == rx_mask_mem) { 23522 return BCM_E_PARAM; 23523 } 23524 23525 if (soc_feature(unit, soc_feature_logical_port_num)) { 23526 /* coverity[overrun-local : FALSE] */ 23527 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 23528 } else { 23529 phy_port = port; 23530 } 23531 switch (SOC_PORT_BLOCK_TYPE(unit, phy_port)) { 23532 case SOC_BLK_GXPORT: 23533 *tx_mem = XPORT_EHG_TX_TUNNEL_DATAm; 23534 *rx_mem = XPORT_EHG_RX_TUNNEL_DATAm; 23535 *rx_mask_mem = XPORT_EHG_RX_TUNNEL_MASKm; 23536 break; 23537 case SOC_BLK_GPORT: 23538 *tx_mem = GPORT_EHG_TX_TUNNEL_DATAm; 23539 *rx_mem = GPORT_EHG_RX_TUNNEL_DATAm; 23540 *rx_mask_mem = GPORT_EHG_RX_TUNNEL_MASKm; 23541 break; 23542 case SOC_BLK_SPORT: 23543 *tx_mem = SPORT_EHG_TX_TUNNEL_DATAm; 23544 *rx_mem = SPORT_EHG_RX_TUNNEL_DATAm; 23545 *rx_mask_mem = SPORT_EHG_RX_TUNNEL_MASKm; 23546 break; 23547 case SOC_BLK_XQPORT: 23548 *tx_mem = XQPORT_EHG_TX_TUNNEL_DATAm; 23549 *rx_mem = XQPORT_EHG_RX_TUNNEL_DATAm; 23550 *rx_mask_mem = XQPORT_EHG_RX_TUNNEL_MASKm; 23551 break; 23552 case SOC_BLK_CLPORT: 23553 case SOC_BLK_XLPORT: 23554 case SOC_BLK_XTPORT: 23555 case SOC_BLK_XWPORT: 23556 *tx_mem = PORT_EHG_TX_TUNNEL_DATAm; 23557 *rx_mem = PORT_EHG_RX_TUNNEL_DATAm; 23558 *rx_mask_mem = PORT_EHG_RX_TUNNEL_MASKm; 23559 break; 23560 default: 23561 *tx_mem = *rx_mem = *rx_mask_mem = INVALIDm; 23562 } 23563 23564 return BCM_E_NONE; 23565 } 23566 23567 /* 23568 * Function: 23569 * _bcm_port_ehg_header_read 23570 * Purpose: 23571 * Reads EHG header from the HW tables 23572 * Parameters: 23573 * unit - (IN) device id 23574 * port - (IN) Physical port 23575 * buffer - (OUT) Pointer to the buffer to contain header 23576 * Returns: 23577 * BCM_E_XXX 23578 */ 23579 23580 STATIC int 23581 _bcm_port_ehg_header_read(int unit, bcm_port_t port, uint32 *buffer) 23582 { 23583 soc_mem_t tx_mem, rx_mem, rx_mask_mem; 23584 int tbl_idx_start, tbl_idx_end, idx; 23585 xqport_ehg_rx_tunnel_data_entry_t entry; 23586 int phy_port; 23587 23588 BCM_IF_ERROR_RETURN 23589 (_bcm_port_ehg_header_mem_get(unit, port, &tx_mem, &rx_mem, 23590 &rx_mask_mem)); 23591 23592 if (INVALIDm == tx_mem) { 23593 return (BCM_E_PORT); 23594 } 23595 23596 if (soc_feature(unit, soc_feature_logical_port_num)) { 23597 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 23598 } else { 23599 phy_port = port; 23600 } 23601 23602 tbl_idx_start = SOC_PORT_BINDEX(unit, phy_port) * 4; 23603 tbl_idx_end = tbl_idx_start + 3; 23604 23605 for (idx = 0 ; idx <= (tbl_idx_end - tbl_idx_start); idx ++) { 23606 BCM_IF_ERROR_RETURN 23607 (soc_mem_read(unit, tx_mem, SOC_PORT_BLOCK(unit, phy_port), 23608 (idx + tbl_idx_start), (void *)&entry)); 23609 soc_mem_field_get(unit, tx_mem, (void *)&entry, TUNNEL_DATAf, 23610 (buffer + ((tbl_idx_end - tbl_idx_start - idx) * 4))); 23611 } 23612 23613 return (BCM_E_NONE); 23614 } 23615 23616 /* 23617 * Function: 23618 * _bcm_port_ehg_header_write 23619 * Purpose: 23620 * Writes EHG header into the HW tables 23621 * Parameters: 23622 * unit - (IN) device id 23623 * port - (IN) Physical port 23624 * tx_buff - (IN) Pointer to the tx header 23625 * rx_buff - (IN) Pointer to the rx header 23626 * mask - (IN) Pointer to the mask header 23627 * len - (IN) Header length 23628 * Returns: 23629 * BCM_E_XXX 23630 */ 23631 int 23632 _bcm_port_ehg_header_write(int unit, bcm_port_t port, uint32 *tx_buf, 23633 uint32 *rx_buf, uint32 *mask, int len) 23634 { 23635 soc_mem_t tx_mem, rx_mem, rx_mask_mem; 23636 int tbl_idx_start, tbl_idx_end, idx; 23637 xqport_ehg_rx_tunnel_data_entry_t data_entry; 23638 xqport_ehg_rx_tunnel_mask_entry_t mask_entry; 23639 int phy_port; 23640 23641 BCM_IF_ERROR_RETURN 23642 (_bcm_port_ehg_header_mem_get(unit, port, &tx_mem, &rx_mem, 23643 &rx_mask_mem)); 23644 23645 if (INVALIDm == tx_mem) { 23646 return (BCM_E_PORT); 23647 } 23648 23649 if (soc_feature(unit, soc_feature_logical_port_num)) { 23650 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 23651 } else { 23652 phy_port = port; 23653 } 23654 23655 tbl_idx_start = SOC_PORT_BINDEX(unit, phy_port) * 4; 23656 tbl_idx_end = tbl_idx_start + (len / 4) - 1; 23657 23658 for (idx = 0; idx <= (tbl_idx_end - tbl_idx_start); idx ++) { 23659 /* Reset hw buffer. */ 23660 sal_memset(&data_entry, 0, sizeof(xqport_ehg_rx_tunnel_data_entry_t)); 23661 soc_mem_field_set(unit, tx_mem, (uint32 *)&data_entry, TUNNEL_DATAf, 23662 (tx_buf + ((tbl_idx_end - tbl_idx_start - idx) * 4))); 23663 BCM_IF_ERROR_RETURN 23664 (soc_mem_write(unit, tx_mem, SOC_PORT_BLOCK(unit, phy_port), 23665 (idx + tbl_idx_start), &data_entry)); 23666 23667 /* Reset hw buffer. */ 23668 sal_memset(&data_entry, 0, sizeof(xqport_ehg_rx_tunnel_data_entry_t)); 23669 soc_mem_field_set(unit, rx_mem, (uint32 *)&data_entry, TUNNEL_DATAf, 23670 (rx_buf + ((tbl_idx_end - tbl_idx_start - idx) * 4))); 23671 BCM_IF_ERROR_RETURN 23672 (soc_mem_write(unit, rx_mem, SOC_PORT_BLOCK(unit, phy_port), 23673 (idx + tbl_idx_start), &data_entry)); 23674 23675 /* Reset hw buffer. */ 23676 sal_memset(&mask_entry, 0, sizeof(xqport_ehg_rx_tunnel_mask_entry_t)); 23677 soc_mem_field_set(unit, rx_mask_mem, (uint32 *)&mask_entry, TUNNEL_MASKf, 23678 (mask + ((tbl_idx_end - tbl_idx_start - idx)* 4))); 23679 BCM_IF_ERROR_RETURN 23680 (soc_mem_write(unit, rx_mask_mem, SOC_PORT_BLOCK(unit, phy_port), 23681 (idx + tbl_idx_start), &mask_entry)); 23682 } 23683 23684 return (BCM_E_NONE); 23685 } 23686 23687 23688 /* 23689 * Function: 23690 * _bcm_port_ehg_setup_txrx_ethernet_hdr 23691 * Purpose: 23692 * Prepares SRC and DEST MAC addresses into rx and tx buffers on a given index 23693 * Parameters: 23694 * tx_buffer -(IN/OUT) - tx buffer to fill 23695 * rx_buffer -(IN/OUT) - rx buffer to fill 23696 * index -(IN/OUT) - index to the right location in buffer 23697 * encap_config - (IN) structure describes port encapsulation configuration 23698 * Returns: 23699 * BCM_E_XXX 23700 */ 23701 23702 STATIC void 23703 _bcm_port_ehg_setup_txrx_ethernet_hdr(uint32 *tx_buffer, uint32 *rx_buffer, 23704 int *index, 23705 bcm_port_encap_config_t *encap_config) 23706 { 23707 int idx = *index; 23708 23709 /* Destination mac address. */ 23710 tx_buffer[idx] = (((uint32)(encap_config->dst_mac)[0]) << 24 | \ 23711 ((uint32)(encap_config->dst_mac)[1]) << 16 | \ 23712 ((uint32)(encap_config->dst_mac)[2]) << 8 | \ 23713 ((uint32)(encap_config->dst_mac)[3])); 23714 /* TX dest MAC is RX src MAC */ 23715 rx_buffer[idx] = (((uint32)(encap_config->src_mac)[0]) << 24 | \ 23716 ((uint32)(encap_config->src_mac)[1]) << 16 | \ 23717 ((uint32)(encap_config->src_mac)[2]) << 8 | \ 23718 ((uint32)(encap_config->src_mac)[3])); 23719 idx--; 23720 23721 tx_buffer[idx] = (((uint32)(encap_config->dst_mac)[4]) << 24 | \ 23722 ((uint32)(encap_config->dst_mac)[5]) << 16 | \ 23723 ((uint32)(encap_config->src_mac)[0]) << 8 | \ 23724 ((uint32)(encap_config->src_mac)[1])); 23725 /* TX dest MAC is RX src MAC */ 23726 rx_buffer[idx] = (((uint32)(encap_config->src_mac)[4]) << 24 | \ 23727 ((uint32)(encap_config->src_mac)[5]) << 16 | \ 23728 ((uint32)(encap_config->dst_mac)[0]) << 8 | \ 23729 ((uint32)(encap_config->dst_mac)[1])); 23730 idx--; 23731 /* Source mac address. */ 23732 tx_buffer[idx] = (((uint32)(encap_config->src_mac)[2]) << 24 | \ 23733 ((uint32)(encap_config->src_mac)[3]) << 16 | \ 23734 ((uint32)(encap_config->src_mac)[4]) << 8 | \ 23735 ((uint32)(encap_config->src_mac)[5])); 23736 /* TX src MAC is RX dest MAC */ 23737 rx_buffer[idx] = (((uint32)(encap_config->dst_mac)[2]) << 24 | \ 23738 ((uint32)(encap_config->dst_mac)[3]) << 16 | \ 23739 ((uint32)(encap_config->dst_mac)[4]) << 8 | \ 23740 ((uint32)(encap_config->dst_mac)[5])); 23741 idx--; 23742 23743 *index = idx; 23744 return; 23745 } 23746 23747 /* Embedded Higig register access macros */ 23748 #define EHG_TX_REG(unit) \ 23749 (SOC_IS_TRIUMPH3(unit) ? PORT_EHG_TX_CONTROLr : EHG_TX_CONTROLr) 23750 #define EHG_RX_REG(unit) \ 23751 (SOC_IS_TRIUMPH3(unit) ? PORT_EHG_RX_CONTROLr : EHG_RX_CONTROLr) 23752 #define EHG_TPID_REG(unit) \ 23753 (SOC_IS_TRIUMPH3(unit) ? PORT_EHG_TPIDr : EHG_TPIDr) 23754 23755 /* 23756 * Function: 23757 * _bcm_port_ehg_ethernet_header_parse 23758 * Purpose: 23759 * Parses Ethernet header from EHG header 23760 * Parameters: 23761 * unit - (IN) device id 23762 * port - (IN) Physical port 23763 * header - (IN) pointer to the EHG header buffer 23764 * encap_config - (IN/OUT) structure describes port encapsulation configuration 23765 * index - (IN/OUT) index to the right location in buffer 23766 * Returns: 23767 * BCM_E_XXX 23768 */ 23769 STATIC int 23770 _bcm_port_ehg_ethernet_header_parse(int unit, bcm_port_t port, uint32 *header, 23771 bcm_port_encap_config_t *encap_config, int *index) 23772 { 23773 uint32 val; 23774 int idx = *index; 23775 soc_reg_t ehg_tx_reg = EHG_TX_REG(unit); 23776 23777 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val)); 23778 encap_config->dst_mac[0] = (uint8)(header[idx] >> 24); 23779 encap_config->dst_mac[1] = (uint8)(header[idx] >> 16); 23780 encap_config->dst_mac[2] = (uint8)(header[idx] >> 8); 23781 encap_config->dst_mac[3] = (uint8)(header[idx]); 23782 idx--; 23783 encap_config->dst_mac[4] = (uint8)(header[idx] >> 24); 23784 encap_config->dst_mac[5] = (uint8)(header[idx] >> 16); 23785 encap_config->src_mac[0] = (uint8)(header[idx] >> 8); 23786 encap_config->src_mac[1] = (uint8)(header[idx]); 23787 idx--; 23788 encap_config->src_mac[2] = (uint8)(header[idx] >> 24); 23789 encap_config->src_mac[3] = (uint8)(header[idx] >> 16); 23790 encap_config->src_mac[4] = (uint8)(header[idx] >> 8); 23791 encap_config->src_mac[5] = (uint8)(header[idx]); 23792 idx--; 23793 23794 if (soc_reg_field_get(unit, ehg_tx_reg, val, VLAN_TAG_CONTROLf)) { 23795 encap_config->tpid = (uint16)(header[idx] >> 16); 23796 encap_config->vlan = (uint16)(header[idx]); 23797 idx--; 23798 } else { 23799 encap_config->vlan = BCM_VLAN_NONE; 23800 encap_config->tpid = BCM_VLAN_NONE; 23801 } 23802 23803 *index = idx; 23804 return BCM_E_NONE; 23805 } 23806 /* 23807 * Function: 23808 * _bcm_port_ip4_tunnel_header_set 23809 * Purpose: 23810 * Prepares and sets IP GRE tunnel header for Embedded higig 23811 * Parameters: 23812 * unit - (IN) device id 23813 * port - (IN) Physical port 23814 * encap_config - (IN) structure describes port encapsulation configuration 23815 * Returns: 23816 * BCM_E_XXX 23817 */ 23818 STATIC int 23819 _bcm_port_ip4_tunnel_header_set(int unit, bcm_port_t port, 23820 bcm_port_encap_config_t *encap_config) 23821 { 23822 /*SW tunnel tx encap buffer.*/ 23823 uint32 tx_buffer[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ]; 23824 /*SW tunnel rx encap buffer.*/ 23825 uint32 rx_buffer[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ]; 23826 uint32 mask[_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ]; 23827 int idx; /* Headers offset iterator.*/ 23828 int adjust_rx_offset = 0; 23829 23830 sal_memset(tx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ)); 23831 sal_memset(rx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ)); 23832 sal_memset(mask, 0, WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ)); 23833 23834 idx = _BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ - 1; 23835 23836 _bcm_port_ehg_setup_txrx_ethernet_hdr(tx_buffer, rx_buffer, &idx, 23837 encap_config); 23838 23839 /* Set tpid & vlan id. */ 23840 if (BCM_VLAN_VALID(encap_config->vlan)) { 23841 /* Tpid. Priority, Cfi, Vlan id. */ 23842 tx_buffer[idx] |= (((uint32)(encap_config->tpid)) << 16 | \ 23843 ((uint32)(encap_config->vlan))); 23844 /*rx_buffer should not have the VLAN and TPID included*/ 23845 idx--; 23846 adjust_rx_offset = 1; 23847 } 23848 23849 /* 23850 * IPv4 header. 23851 */ 23852 /* Set ether type to ip. 0x800 */ 23853 /* Version + 5 word no options length. + Tos */ 23854 /* Length, Id, Flags, Fragmentation offset. */ 23855 tx_buffer[idx] |= (((uint32)(0x0800) << 16) | \ 23856 ((uint32)(0x45) << 8) | \ 23857 ((uint32)(encap_config->tos))); 23858 rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx]; 23859 idx--; 23860 idx--; 23861 23862 /* Ttl */ 23863 /* Protocol (GRE 0x2f) */ 23864 tx_buffer[idx] = (((uint32)(encap_config->ttl) << 8) | \ 23865 ((uint32)(0x2f))); 23866 rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx]; 23867 idx--; 23868 23869 /* TX Src Ip. */ 23870 tx_buffer[idx] |= ((uint32)(encap_config->src_addr) >> 16); 23871 23872 /* RX Dst Ip. */ 23873 rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->dst_addr) >> 16); 23874 idx--; 23875 23876 /* TX Src Ip. */ 23877 tx_buffer[idx] |= ((uint32)(encap_config->src_addr) << 16); 23878 23879 /* RX Dst Ip. */ 23880 rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->dst_addr) << 16); 23881 23882 /* TX Dst Ip. */ 23883 tx_buffer[idx] |= ((uint32)(encap_config->dst_addr) >> 16); 23884 23885 /* RX Src Ip */ 23886 rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->src_addr) >> 16); 23887 idx--; 23888 23889 23890 /* TX Dst Ip. */ 23891 tx_buffer[idx] |= ((uint32)(encap_config->dst_addr) << 16); 23892 23893 /* RX Src Ip */ 23894 rx_buffer[idx + adjust_rx_offset] |= ((uint32)(encap_config->src_addr) << 16); 23895 idx--; 23896 23897 /* Gre header */ 23898 /* Set protocol type in GRE header to ether type specified by user */ 23899 tx_buffer[idx] |= (((uint32)(encap_config->higig_ethertype) << 16) | \ 23900 ((uint32)(encap_config->oui)[0]) << 8 | \ 23901 ((uint32)(encap_config->oui)[1])); 23902 rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx]; 23903 mask[idx + adjust_rx_offset]=0x0000FFFF;/*TUNNEL_TYPE=1:The first 38 bytes will be compared against the rx table data*/ 23904 sal_memset(mask, 0xFF, WORDS2BYTES(idx + adjust_rx_offset)); 23905 idx--; 23906 23907 /* Set TX OUI and OUI Ethertype*/ 23908 tx_buffer[idx] |= (((uint32)(encap_config->oui)[2]) << 24 | \ 23909 ((uint32)(encap_config->oui_ethertype)) << 8); 23910 rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx]; 23911 23912 return _bcm_port_ehg_header_write(unit, port, tx_buffer, rx_buffer, mask, 23913 _BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ); 23914 } 23915 23916 /* 23917 * Function: 23918 * _bcm_port_ipv4_tunnel_header_parse 23919 * Purpose: 23920 * Parse IPv4 GRE tunnel header for Embedded higig and updates encap_config 23921 * structure accordingly 23922 * Parameters: 23923 * unit - (IN) device id 23924 * port - (IN) Physical port 23925 * header - (IN) Buffer contains EHG header to parse 23926 * encap_config - (OUT) structure describes port encapsulation configuration 23927 * Returns: 23928 * BCM_E_XXX 23929 */ 23930 STATIC int 23931 _bcm_port_ipv4_tunnel_header_parse(int unit, bcm_port_t port, uint32 *header, 23932 bcm_port_encap_config_t *encap_config) 23933 { 23934 /* Headers offset iterator, begins at end of header */ 23935 int idx = 4 * BYTES2WORDS(sizeof(xport_ehg_tx_tunnel_data_entry_t)) - 1; 23936 23937 BCM_IF_ERROR_RETURN( 23938 _bcm_port_ehg_ethernet_header_parse(unit, port, header, encap_config, 23939 &idx)); 23940 23941 encap_config->tos = (uint8)(header[idx]); 23942 idx--; 23943 idx--; 23944 encap_config->ttl = (uint8)(header[idx] >> 8); 23945 idx--; 23946 encap_config->src_addr = ((uint16)(header[idx])) << 16; 23947 idx--; 23948 encap_config->src_addr |=(uint16)(header[idx] >> 16); 23949 encap_config->dst_addr = ((uint16)(header[idx])) << 16; 23950 idx--; 23951 encap_config->dst_addr |=(uint16)(header[idx] >> 16); 23952 idx--; 23953 encap_config->higig_ethertype = (uint16)(header[idx] >> 16); 23954 encap_config->oui[0] = (uint8)(header[idx] >> 8); 23955 encap_config->oui[1] = (uint8)(header[idx]); 23956 idx--; 23957 encap_config->oui[2] = (uint8)(header[idx] >> 24); 23958 encap_config->oui_ethertype = (uint16)(header[idx] >> 8); 23959 23960 return BCM_E_NONE; 23961 } 23962 23963 /* 23964 * Function: 23965 * _bcm_port_l2_tunnel_header_set 23966 * Purpose: 23967 * Prepares and sets L2 tunnel header for Embedded higig 23968 * Parameters: 23969 * unit - (IN) device id 23970 * port - (IN) Physical port 23971 * encap_config - (IN) structure describes port encapsulation configuration 23972 * Returns: 23973 * BCM_E_XXX 23974 */ 23975 STATIC int 23976 _bcm_port_l2_tunnel_header_set(int unit, bcm_port_t port, 23977 bcm_port_encap_config_t *encap_config) 23978 { 23979 /*SW tunnel tx encap buffer.*/ 23980 uint32 tx_buffer[_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ]; 23981 /*SW tunnel rx encap buffer.*/ 23982 uint32 rx_buffer[_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ]; 23983 uint32 mask[_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ]; 23984 int idx; /* Headers offset iterator.*/ 23985 int adjust_rx_offset = 0; 23986 23987 sal_memset(tx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ)); 23988 sal_memset(rx_buffer, 0, WORDS2BYTES(_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ)); 23989 sal_memset(mask, 0, WORDS2BYTES(_BCM_PORT_EHG_L2_HEADER_BUFFER_SZ)); 23990 23991 idx = _BCM_PORT_EHG_L2_HEADER_BUFFER_SZ - 1; 23992 23993 _bcm_port_ehg_setup_txrx_ethernet_hdr(tx_buffer, rx_buffer, &idx, 23994 encap_config); 23995 23996 /* Set tpid & vlan id. */ 23997 if (BCM_VLAN_VALID(encap_config->vlan)) { 23998 /* Tpid. Priority, Cfi, Vlan id. */ 23999 tx_buffer[idx] |= (((uint32)(encap_config->tpid)) << 16 | \ 24000 ((uint32)(encap_config->vlan))); 24001 /*rx_buffer should not have the VLAN and TPID included*/ 24002 idx--; 24003 adjust_rx_offset = 1; 24004 } 24005 24006 /* Set ether type to OUI and TX OUI */ 24007 tx_buffer[idx] |= (((uint32)(encap_config->higig_ethertype)) << 16 | \ 24008 ((uint32)(encap_config->oui)[0]) << 8 | \ 24009 ((uint32)(encap_config->oui)[1])); 24010 rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx]; 24011 mask[idx + adjust_rx_offset] = 0x0000FFFF; /*TUNNEL_TYPE=0:The first 14 bytes will be compared against the rx table data*/ 24012 sal_memset(mask, 0xFF, WORDS2BYTES(idx + adjust_rx_offset)); 24013 idx--; 24014 /* Set TX OUI and HG ether type */ 24015 tx_buffer[idx] |= (((uint32)(encap_config->oui)[2]) << 24 | \ 24016 ((uint32)(encap_config->oui_ethertype)) << 8); 24017 rx_buffer[idx + adjust_rx_offset] = tx_buffer[idx]; 24018 24019 return _bcm_port_ehg_header_write(unit, port, tx_buffer, rx_buffer, mask, 24020 _BCM_PORT_EHG_L2_HEADER_BUFFER_SZ); 24021 } 24022 24023 24024 /* 24025 * Function: 24026 * _bcm_port_l2_tunnel_header_parse 24027 * Purpose: 24028 * Parse L2 tunnel header for Embedded higig and updates encap_config 24029 * structure accordingly 24030 * Parameters: 24031 * unit - (IN) device id 24032 * port - (IN) Physical port 24033 * header - (IN) Buffer contains EHG header to parse 24034 * encap_config - (OUT) structure describes port encapsulation configuration 24035 * Returns: 24036 * BCM_E_XXX 24037 */ 24038 STATIC int 24039 _bcm_port_l2_tunnel_header_parse(int unit, bcm_port_t port, uint32 *header, 24040 bcm_port_encap_config_t *encap_config) 24041 { 24042 /* Headers offset iterator, begins at end of header */ 24043 int idx = 4 * BYTES2WORDS(sizeof(xport_ehg_tx_tunnel_data_entry_t)) - 1; 24044 24045 BCM_IF_ERROR_RETURN 24046 (_bcm_port_ehg_ethernet_header_parse(unit, port, header, 24047 encap_config, &idx)); 24048 24049 encap_config->higig_ethertype = (uint16)(header[idx] >> 16); 24050 encap_config->oui[0] = (uint8)(header[idx] >> 8); 24051 encap_config->oui[1] = (uint8)(header[idx]); 24052 idx--; 24053 encap_config->oui[2] = (uint8)(header[idx] >> 24); 24054 encap_config->oui_ethertype = (uint16)(header[idx] >> 8); 24055 24056 return BCM_E_NONE; 24057 } 24058 24059 /* 24060 * Function: 24061 * _bcm_port_encap_ehg_xport_update 24062 * Purpose: 24063 * Updates XPORT higig config for EHG 24064 * Parameters: 24065 * unit - (IN) device id 24066 * port - (IN) Physical port 24067 * Returns: 24068 */ 24069 STATIC int 24070 _bcm_port_encap_ehg_xport_update(int unit, bcm_port_t port) 24071 { 24072 #if defined(BCM_TRIUMPH3_SUPPORT) 24073 if (SOC_IS_TRIUMPH3(unit)) { 24074 24075 soc_field_t ept_fields[2] = { HIGIG2f, PORT_TYPEf }; 24076 uint32 ept_vals[2] = { BCM_EGR_PORT_HIGIG2, BCM_EGR_PORT_TYPE_EHG }; 24077 24078 /* Ingress port table */ 24079 BCM_IF_ERROR_RETURN 24080 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 24081 HIGIG2f, 1)); 24082 BCM_IF_ERROR_RETURN 24083 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 24084 PORT_TYPEf, BCM_EGR_PORT_TYPE_EHG)); 24085 24086 /* Egress port table */ 24087 BCM_IF_ERROR_RETURN 24088 (soc_mem_fields32_modify(unit, EGR_PORTm, port, 2, 24089 ept_fields, ept_vals)); 24090 24091 /* Egress ingress port table */ 24092 BCM_IF_ERROR_RETURN 24093 (soc_mem_fields32_modify(unit, EGR_ING_PORTm, port, 2, 24094 ept_fields, ept_vals)); 24095 24096 BCM_IF_ERROR_RETURN 24097 (soc_reg_field32_modify(unit, PORT_CONFIGr, port, 24098 HIGIG2_MODEf, 1)); 24099 24100 if (SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) { 24101 icontrol_opcode_bitmap_entry_t entry; 24102 soc_pbmp_t pbmp; 24103 24104 BCM_IF_ERROR_RETURN 24105 (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 24106 24107 SOC_PBMP_CLEAR(pbmp); 24108 24109 SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit)); 24110 24111 soc_mem_pbmp_field_set(unit, ICONTROL_OPCODE_BITMAPm, &entry, 24112 BITMAPf, &pbmp); 24113 24114 BCM_IF_ERROR_RETURN 24115 (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 24116 } 24117 24118 return (BCM_E_NONE); 24119 } 24120 #endif /* BCM_TRIUMPH3_SUPPORT */ 24121 24122 #ifdef BCM_GXPORT_SUPPORT 24123 { 24124 soc_reg_t egr_port_reg; 24125 24126 if (IS_GX_PORT(unit, port) || IS_XQ_PORT(unit,port)) { 24127 24128 egr_port_reg = 24129 (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 24130 SOC_IS_VALKYRIE2(unit)|| SOC_IS_GREYHOUND(unit) || 24131 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ? 24132 EGR_PORT_64r : EGR_PORTr; 24133 24134 BCM_IF_ERROR_RETURN 24135 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 24136 HIGIG2f, 1)); 24137 24138 BCM_IF_ERROR_RETURN 24139 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 24140 PORT_TYPEf, BCM_EGR_PORT_TYPE_EHG)); 24141 BCM_IF_ERROR_RETURN 24142 (soc_reg_field32_modify(unit, egr_port_reg, port, HIGIG2f, 24143 BCM_EGR_PORT_HIGIG2)); 24144 BCM_IF_ERROR_RETURN 24145 (soc_reg_field32_modify(unit, egr_port_reg, port, 24146 PORT_TYPEf, BCM_EGR_PORT_TYPE_EHG)); 24147 24148 if(SOC_REG_IS_VALID(unit, XPORT_CONFIGr)) { 24149 BCM_IF_ERROR_RETURN 24150 (soc_reg_field32_modify(unit, XPORT_CONFIGr, port, 24151 HIGIG2_MODEf, 1)); 24152 } 24153 } 24154 } 24155 #endif /* BCM_GXPORT_SUPPORT */ 24156 return (BCM_E_NONE); 24157 } 24158 24159 /* 24160 * Function: 24161 * _bcm_port_ehg_transport_mode_set 24162 * Purpose: 24163 * Set the port into embedded higig transport mode 24164 * Parameters: 24165 * unit - (IN) device id 24166 * port - (IN) Physical port 24167 * encap_config - (IN) structure describes port encapsulation configuration 24168 * Returns: 24169 * BCM_E_XXX 24170 */ 24171 STATIC int 24172 _bcm_port_ehg_transport_mode_set(int unit, bcm_port_t port, 24173 bcm_port_encap_config_t *encap_config) 24174 { 24175 int vlan_valid; 24176 uint32 val; 24177 soc_reg_t ehg_tx_reg = EHG_TX_REG(unit); 24178 soc_reg_t ehg_rx_reg = EHG_RX_REG(unit); 24179 soc_reg_t ehg_tpid_reg = EHG_TPID_REG(unit); 24180 24181 if (IS_HG_PORT(unit, port)) { 24182 return BCM_E_CONFIG; 24183 } 24184 24185 BCM_IF_ERROR_RETURN 24186 (_bcm_port_encap_ehg_xport_update(unit, port)); 24187 24188 vlan_valid = BCM_VLAN_VALID(encap_config->vlan); 24189 24190 /* Configure TX control */ 24191 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val)); 24192 soc_reg_field_set(unit, ehg_tx_reg, &val, ENABLEf, 1); 24193 soc_reg_field_set(unit, ehg_tx_reg, &val, TUNNEL_TYPEf, 0); 24194 soc_reg_field_set(unit, ehg_tx_reg, &val, VLAN_TAG_CONTROLf, 24195 vlan_valid); 24196 soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_VLAN_PRI_CFIf, 24197 vlan_valid); 24198 soc_reg_field_set(unit, ehg_tx_reg, &val, PAYLOAD_LENGTH_ADJUSTMENTf, 24199 0); 24200 soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_DSCPf, 0); 24201 soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_IPf, 0); 24202 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tx_reg, port, 0, val)); 24203 24204 /* Configure RX control */ 24205 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_rx_reg, port, 0, &val)); 24206 soc_reg_field_set(unit, ehg_rx_reg, &val, TUNNEL_TYPEf, 0); 24207 soc_reg_field_set(unit, ehg_rx_reg, &val, MODEf, 1); 24208 soc_reg_field_set(unit, ehg_rx_reg, &val, VLAN_TAG_CONTROLf, 24209 vlan_valid); 24210 soc_reg_field_set(unit, ehg_rx_reg, &val, COMPARE_VLANf, 24211 vlan_valid); 24212 soc_reg_field_set(unit, ehg_rx_reg, &val, VLANf, 24213 (vlan_valid) ? encap_config->vlan : 0); 24214 soc_reg_field_set(unit, ehg_rx_reg, &val, IPV4_CHKSUM_ENABLEf, 0); 24215 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_rx_reg, port, 0, val)); 24216 24217 /* Configure EHG-tpid */ 24218 if (vlan_valid) { 24219 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tpid_reg, port, 0, &val)); 24220 soc_reg_field_set(unit, ehg_tpid_reg, &val, TPIDf, 24221 encap_config->tpid); 24222 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tpid_reg, port, 0, val)); 24223 } 24224 24225 return _bcm_port_l2_tunnel_header_set(unit, port, encap_config); 24226 } 24227 24228 /* 24229 * Function: 24230 * _bcm_port_ehg_tunnel_mode_set 24231 * Purpose: 24232 * Set the port into embedded higig tunnel mode 24233 * Parameters: 24234 * unit - (IN) device id 24235 * port - (IN) Physical port 24236 * encap_config - (IN) structure describes port encapsulation configuration 24237 * Returns: 24238 * BCM_E_XXX 24239 */ 24240 STATIC int 24241 _bcm_port_ehg_tunnel_mode_set(int unit, bcm_port_t port, 24242 bcm_port_encap_config_t *encap_config) 24243 { 24244 int vlan_valid; 24245 uint32 val; 24246 soc_reg_t ehg_tx_reg = EHG_TX_REG(unit); 24247 soc_reg_t ehg_rx_reg = EHG_RX_REG(unit); 24248 soc_reg_t ehg_tpid_reg = EHG_TPID_REG(unit); 24249 24250 if (IS_HG_PORT(unit, port)) { 24251 return BCM_E_CONFIG; 24252 } 24253 24254 BCM_IF_ERROR_RETURN 24255 (_bcm_port_encap_ehg_xport_update(unit, port)); 24256 24257 vlan_valid = BCM_VLAN_VALID(encap_config->vlan); 24258 24259 /* Configure TX control */ 24260 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val)); 24261 soc_reg_field_set(unit, ehg_tx_reg, &val, ENABLEf, 1); 24262 soc_reg_field_set(unit, ehg_tx_reg, &val, TUNNEL_TYPEf, 1); 24263 soc_reg_field_set(unit, ehg_tx_reg, &val, VLAN_TAG_CONTROLf, 24264 vlan_valid); 24265 soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_VLAN_PRI_CFIf, 24266 vlan_valid); 24267 soc_reg_field_set(unit, ehg_tx_reg, &val, PAYLOAD_LENGTH_ADJUSTMENTf, 24268 vlan_valid ? (WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ) - 1): 24269 (WORDS2BYTES(_BCM_PORT_EHG_IP_GRE_HEADER_BUFFER_SZ - 1) - 1)); 24270 soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_DSCPf, 1); 24271 soc_reg_field_set(unit, ehg_tx_reg, &val, UPDATE_IPf, 1); 24272 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tx_reg, port, 0, val)); 24273 24274 /* Configure RX control */ 24275 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_rx_reg, port, 0, &val)); 24276 soc_reg_field_set(unit, ehg_rx_reg, &val, MODEf, 1); 24277 soc_reg_field_set(unit, ehg_rx_reg, &val, TUNNEL_TYPEf, 1); 24278 soc_reg_field_set(unit, ehg_rx_reg, &val, VLAN_TAG_CONTROLf, 24279 vlan_valid); 24280 soc_reg_field_set(unit, ehg_rx_reg, &val, COMPARE_VLANf, 24281 vlan_valid); 24282 soc_reg_field_set(unit, ehg_rx_reg, &val, VLANf, 24283 (vlan_valid) ? encap_config->vlan : 0); 24284 soc_reg_field_set(unit, ehg_rx_reg, &val, IPV4_CHKSUM_ENABLEf, 1); 24285 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_rx_reg, port, 0, val)); 24286 24287 /* Configure EHG-tpid */ 24288 if (vlan_valid) { 24289 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tpid_reg, port, 0, &val)); 24290 soc_reg_field_set(unit, ehg_tpid_reg, &val, TPIDf, 24291 encap_config->tpid); 24292 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, ehg_tpid_reg, port, 0, val)); 24293 } 24294 24295 return _bcm_port_ip4_tunnel_header_set(unit, port, encap_config); 24296 } 24297 24298 /* 24299 * Function: 24300 * _bcm_port_hgoe_transport_mode_set 24301 * Purpose: 24302 * Set the port into Higig over Ethernet transport mode 24303 * Parameters: 24304 * unit - (IN) device id 24305 * port - (IN) Physical port 24306 * encap_config - (IN) structure describes port encapsulation configuration 24307 * Returns: 24308 * BCM_E_XXX 24309 */ 24310 STATIC int 24311 _bcm_port_hgoe_transport_mode_set(int unit, bcm_port_t port, 24312 bcm_port_encap_config_t *encap_config) 24313 { 24314 uint64 val64; 24315 uint32 val; 24316 24317 24318 if (IS_HG_PORT(unit, port)) { 24319 return BCM_E_CONFIG; 24320 } 24321 #if defined(BCM_TRIDENT3_SUPPORT) 24322 if (SOC_IS_TRIDENT3X(unit)) { 24323 if (BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET == encap_config->encap) { 24324 return bcm_td3_port_hgoe_mode_set(unit, port); 24325 } else { 24326 return BCM_E_UNAVAIL; 24327 } 24328 } 24329 #endif 24330 /* Configure HGoE TX control */ 24331 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, HG_TYPEf)) { 24332 BCM_IF_ERROR_RETURN 24333 (soc_mem_field32_modify(unit, EGR_PORTm, port, PORT_TYPEf, 24334 encap_config->encap == 24335 BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET? 24336 1 : 0)); 24337 BCM_IF_ERROR_RETURN 24338 (soc_mem_field32_modify(unit, EGR_PORTm, port, HG_TYPEf, 24339 BCM_PORT_HG_TYPE_HGOE_TRANSPORT)); 24340 } 24341 24342 if (SOC_REG_IS_VALID(unit, EGR_EHG_ETHERTYPEr)) { 24343 BCM_IF_ERROR_RETURN 24344 (soc_reg32_get(unit, EGR_EHG_ETHERTYPEr, port, 0, &val)); 24345 soc_reg_field_set(unit, EGR_EHG_ETHERTYPEr, 24346 &val, ETHERTYPEf, encap_config->higig_ethertype); 24347 BCM_IF_ERROR_RETURN 24348 (soc_reg32_set(unit, EGR_EHG_ETHERTYPEr, port, 0, val)); 24349 } 24350 24351 if (SOC_REG_IS_VALID(unit, EGR_EHG_HEADER_CONTROLr)) { 24352 BCM_IF_ERROR_RETURN 24353 (soc_reg32_get(unit, EGR_EHG_HEADER_CONTROLr, port, 0, &val)); 24354 soc_reg_field_set(unit, EGR_EHG_HEADER_CONTROLr, 24355 &val, EHG_RESERVEDf, encap_config->hgoe_reserved); 24356 BCM_IF_ERROR_RETURN 24357 (soc_reg32_set(unit, EGR_EHG_HEADER_CONTROLr, port, 0, val)); 24358 } 24359 24360 /* Configure HGoE RX control */ 24361 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, HG_TYPEf)) { 24362 BCM_IF_ERROR_RETURN 24363 (_bcm_esw_port_tab_set(unit, port, 24364 _BCM_CPU_TABS_NONE, PORT_TYPEf, 24365 encap_config->encap == 24366 BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET? 24367 1 : 0)); 24368 24369 BCM_IF_ERROR_RETURN 24370 (_bcm_esw_port_tab_set(unit, port, 24371 _BCM_CPU_TABS_NONE, HG_TYPEf, 24372 BCM_PORT_HG_TYPE_HGOE_TRANSPORT)); 24373 } 24374 24375 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, HG_TYPEf)) { 24376 BCM_IF_ERROR_RETURN 24377 (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, PORT_TYPEf, 24378 encap_config->encap == 24379 BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET? 24380 1 : 0)); 24381 BCM_IF_ERROR_RETURN 24382 (soc_mem_field32_modify(unit, EGR_ING_PORTm, port, HG_TYPEf, 24383 BCM_PORT_HG_TYPE_HGOE_TRANSPORT)); 24384 } 24385 24386 if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr)) { 24387 uint64 v64; 24388 COMPILER_64_SET(v64, 0, encap_config->higig_ethertype); 24389 BCM_IF_ERROR_RETURN 24390 (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, port, 0, 24391 &val64)); 24392 soc_reg64_field_set(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, 24393 &val64, ETHERTYPEf, v64); 24394 BCM_IF_ERROR_RETURN 24395 (soc_reg_set(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, port, 0, 24396 val64)); 24397 } 24398 24399 /* Enable HGoE */ 24400 if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r)) { 24401 uint64 one = COMPILER_64_INIT(0, 1); 24402 BCM_IF_ERROR_RETURN 24403 (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, port, 0, 24404 &val64)); 24405 soc_reg64_field_set(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, 24406 &val64, TRANSPORT_ENf, one); 24407 BCM_IF_ERROR_RETURN 24408 (soc_reg_set(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, port, 0, 24409 val64)); 24410 } 24411 #ifdef BCM_TRX_SUPPORT 24412 /* Set the vlan default action */ 24413 if (soc_feature(unit, soc_feature_vlan_action) && 24414 (!SOC_IS_TRIDENT3X(unit))) { 24415 bcm_vlan_action_set_t action; 24416 24417 BCM_IF_ERROR_RETURN 24418 (_bcm_trx_vlan_port_egress_default_action_get(unit, 24419 port, &action)); 24420 /* Backward compatible defaults */ 24421 action.ot_outer = bcmVlanActionDelete; 24422 action.dt_outer = bcmVlanActionDelete; 24423 BCM_IF_ERROR_RETURN 24424 (_bcm_trx_vlan_port_egress_default_action_set(unit, 24425 port, &action)); 24426 } 24427 #endif 24428 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(BCM_TX_HGOE_LIMITED_SOLUTION) 24429 if (SOC_IS_TRIDENT2PLUS(unit) 24430 && SOC_MEM_IS_VALID(unit, ICONTROL_OPCODE_BITMAPm)) { 24431 icontrol_opcode_bitmap_entry_t entry; 24432 soc_pbmp_t pbmp; 24433 24434 SOC_IF_ERROR_RETURN 24435 (READ_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 24436 SOC_PBMP_CLEAR(pbmp); 24437 SOC_PBMP_PORT_SET(pbmp, CMIC_PORT(unit)); 24438 soc_mem_pbmp_field_set(unit, 24439 ICONTROL_OPCODE_BITMAPm, &entry, BITMAPf, &pbmp); 24440 SOC_IF_ERROR_RETURN 24441 (WRITE_ICONTROL_OPCODE_BITMAPm(unit, MEM_BLOCK_ANY, port, &entry)); 24442 } 24443 #endif /* BCM_TRIDENT2PLUS_SUPPORT && BCM_TX_HGOE_LIMITED_SOLUTION */ 24444 24445 return BCM_E_NONE; 24446 } 24447 24448 24449 /* 24450 * Function: 24451 * _bcm_esw_port_encap_higig_lite_set 24452 * Purpose: 24453 * Helper function to force a port into HIGIG2_LITE mode 24454 * Parameters: 24455 * unit - (IN) device id 24456 * port - (IN) port number 24457 * Returns: 24458 * BCM_E_XXX 24459 */ 24460 STATIC int 24461 _bcm_esw_port_encap_higig_lite_set(int unit, bcm_port_t port) 24462 { 24463 soc_port_ability_t ability; 24464 int an, an_done; 24465 int rv = BCM_E_CONFIG; 24466 24467 if (SOC_USE_PORTCTRL(unit)) { 24468 return bcmi_esw_portctrl_encap_higig_lite_set(unit, port); 24469 } 24470 24471 sal_memset(&ability, 0, sizeof(soc_port_ability_t)); 24472 24473 if (soc_feature(unit, soc_feature_hg_no_speed_change)) { 24474 /* HG-Lite process without 2.5G speed setting can calls to 24475 * _bcm_port_encap_xport_set() directly. 24476 */ 24477 return _bcm_port_encap_xport_set(unit, port, 24478 BCM_PORT_ENCAP_HIGIG2_LITE, TRUE); 24479 } else { 24480 if (IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port)) { 24481 /* Restrict the speed to <= 2.5G and set the encap to HG2 */ 24482 if ((SOC_IS_SABER2(unit) || SOC_IS_HURRICANE2(unit)) && IS_XL_PORT(unit, port)) { 24483 rv = _bcm_port_encap_xport_set(unit, port, 24484 BCM_PORT_ENCAP_HIGIG2_LITE, 24485 TRUE); 24486 if (rv != BCM_E_NONE) { 24487 return rv; 24488 } 24489 SOC_IF_ERROR_RETURN 24490 (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, 2500)); 24491 } 24492 if((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && IS_XE_PORT(unit, port)) { 24493 /*Restrict the speed to <= 2.5G and set the encap to HG_LITE*/ 24494 rv = _bcm_port_encap_xport_set(unit, port, 24495 BCM_PORT_ENCAP_HIGIG2_LITE, 24496 TRUE); 24497 if (rv != BCM_E_NONE) { 24498 return rv; 24499 } 24500 SOC_IF_ERROR_RETURN 24501 (MAC_SPEED_SET(PORT(unit, port).p_mac, unit, port, 2500)); 24502 } 24503 BCM_IF_ERROR_RETURN( 24504 soc_phyctrl_ability_local_get(unit, port, &ability)); 24505 24506 ability.speed_full_duplex &= ~(SOC_PA_SPEED_10GB | 24507 SOC_PA_SPEED_12GB | SOC_PA_SPEED_13GB | SOC_PA_SPEED_15GB | 24508 SOC_PA_SPEED_16GB | SOC_PA_SPEED_20GB | SOC_PA_SPEED_21GB | 24509 SOC_PA_SPEED_25GB | SOC_PA_SPEED_30GB | SOC_PA_SPEED_40GB); 24510 24511 BCM_IF_ERROR_RETURN( 24512 soc_phyctrl_ability_advert_set(unit, port, &ability)); 24513 BCM_IF_ERROR_RETURN( 24514 soc_phyctrl_auto_negotiate_get(unit, port, &an, &an_done)); 24515 if (!an) { 24516 BCM_IF_ERROR_RETURN( 24517 soc_phyctrl_speed_set(unit, port, 2500)); 24518 } 24519 if (!SOC_IS_SABER2(unit) && !SOC_IS_KATANA2(unit) && !SOC_IS_HURRICANE2(unit)) { 24520 return _bcm_port_encap_xport_set(unit, port, 24521 BCM_PORT_ENCAP_HIGIG2, TRUE); 24522 } 24523 } else if (IS_ST_PORT(unit, port) || IS_E_PORT(unit, port)) { 24524 return _bcm_port_encap_stport_set(unit, port, BCM_PORT_ENCAP_HIGIG2); 24525 } 24526 } /* if soc_feature(soc_feature_hg_no_speed_change) */ 24527 24528 return rv; 24529 } 24530 24531 24532 /* 24533 * Function: 24534 * bcm_esw_port_encap_config_set 24535 * Purpose: 24536 * Set the port encapsulation 24537 * Parameters: 24538 * unit - (IN) device id 24539 * gport - (IN) Generic port 24540 * encap_config - (IN) structure describes port encapsulation configuration 24541 * Returns: 24542 * BCM_E_XXX 24543 */ 24544 int 24545 bcm_esw_port_encap_config_set(int unit, bcm_gport_t gport, 24546 bcm_port_encap_config_t *encap_config) 24547 { 24548 bcm_port_t port; 24549 int rv = BCM_E_UNAVAIL, curr_mode=0; 24550 soc_info_t *si = &SOC_INFO(unit); 24551 bcm_stg_t stg = 0; 24552 24553 if (NULL == encap_config) { 24554 return BCM_E_PARAM; 24555 } 24556 /* Make sure port module is initialized. */ 24557 PORT_INIT(unit); 24558 24559 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, gport, &port)); 24560 if(bcm_common_oamp_port_enable_get(unit, port)) { 24561 LOG_ERROR(BSL_LS_BCM_PORT, 24562 (BSL_META("Error: Not permitted on OAMP port %d.n"), 24563 port)); 24564 return BCM_E_PARAM; 24565 } 24566 24567 24568 if (encap_config->encap != BCM_PORT_ENCAP_HIGIG2_L2 && 24569 encap_config->encap != BCM_PORT_ENCAP_HIGIG2_LITE && 24570 encap_config->encap != BCM_PORT_ENCAP_HIGIG2_IP_GRE && 24571 encap_config->encap != BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) { 24572 return bcm_esw_port_encap_set(unit, port, encap_config->encap); 24573 } 24574 24575 if (encap_config->encap == BCM_PORT_ENCAP_HIGIG2_LITE && 24576 (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) || SOC_IS_RAVEN(unit) 24577 || SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit))) { 24578 return bcm_esw_port_encap_set(unit, port, encap_config->encap); 24579 } 24580 24581 if (!soc_feature(unit, soc_feature_embedded_higig) && 24582 !soc_feature(unit, soc_feature_higig_over_ethernet)) { 24583 return (BCM_E_UNAVAIL); 24584 } 24585 24586 #if defined(BCM_SABER2_SUPPORT) 24587 if (SOC_IS_SABER2(unit) && (!BCM_GPORT_IS_SET(port))) { 24588 if(!IS_XL_PORT(unit, port)) { 24589 /* On saber2 non XL port, shouldn't have reached till here */ 24590 return BCM_E_UNAVAIL; 24591 } 24592 } 24593 #endif 24594 #if defined(BCM_TRIDENT3_SUPPORT) 24595 if (SOC_IS_TRIDENT3X(unit) 24596 && encap_config->encap == BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET) { 24597 24598 if (!soc_feature(unit, soc_feature_higig_over_ethernet)) { 24599 return BCM_E_UNAVAIL; 24600 } 24601 } 24602 #endif 24603 PORT_LOCK(unit); 24604 24605 if (encap_config->encap == BCM_PORT_ENCAP_HIGIG2_LITE) { 24606 rv = _bcm_esw_port_encap_higig_lite_set(unit, port); 24607 } else { 24608 if ((IS_XE_PORT(unit, port) || IS_HG_PORT(unit, port))) { 24609 if (BCM_PORT_ENCAP_HIGIG2_L2 == encap_config->encap) { 24610 rv = BCM_E_NONE; 24611 rv = bcm_esw_port_encap_get(unit, port, &curr_mode); 24612 if ((BCM_SUCCESS(rv)) && (curr_mode != BCM_PORT_ENCAP_IEEE)) { 24613 rv = _bcm_port_encap_xport_set(unit, port, 24614 BCM_PORT_ENCAP_IEEE, TRUE); 24615 } 24616 } else { 24617 rv = _bcm_port_encap_xport_set(unit, port, 24618 BCM_PORT_ENCAP_IEEE, TRUE); 24619 } 24620 /* Update soc_info_t after changing port to ethernet */ 24621 soc_xport_type_update(unit, port, 0); 24622 } else if (IS_ST_PORT(unit, port) || IS_E_PORT(unit, port)) { 24623 rv = _bcm_port_encap_stport_set(unit, port, BCM_PORT_ENCAP_IEEE); 24624 } 24625 } 24626 24627 if (BCM_SUCCESS(rv)) { 24628 if (BCM_PORT_ENCAP_HIGIG2_L2 == encap_config->encap) { 24629 rv = _bcm_port_ehg_transport_mode_set(unit, port, encap_config); 24630 } else if (BCM_PORT_ENCAP_HIGIG2_IP_GRE == encap_config->encap){ 24631 rv = _bcm_port_ehg_tunnel_mode_set(unit, port, encap_config); 24632 } else if (BCM_PORT_ENCAP_HIGIG2_LITE == encap_config->encap){ 24633 rv = soc_reg_field32_modify(unit, EHG_RX_REG(unit), 24634 port, MODEf, 2); 24635 } else if (BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET == encap_config->encap){ 24636 rv = _bcm_port_hgoe_transport_mode_set(unit, port, encap_config); 24637 } 24638 } 24639 24640 /* Embedded Higig ports should be configured and marked as ST ports */ 24641 if (BCM_SUCCESS(rv)) { 24642 rv = bcm_esw_port_pause_set(unit, port, 0, 0); 24643 } 24644 if (BCM_SUCCESS(rv)) { 24645 /* Stack ports to forwarding */ 24646 rv = bcm_esw_port_stp_set(unit, port, BCM_STG_STP_FORWARD); 24647 } 24648 if (BCM_SUCCESS(rv)) { 24649 /* Set untagged state in default VLAN properly */ 24650 rv = _bcm_esw_vlan_untag_update(unit, port, TRUE); 24651 } 24652 if (BCM_SUCCESS(rv)) { 24653 /* Resolve STG 0 */ 24654 rv = bcm_esw_stg_default_get(unit, &stg); 24655 } 24656 if (BCM_SUCCESS(rv)) { 24657 rv = bcm_esw_stg_stp_set(unit, stg, port, BCM_STG_STP_FORWARD); 24658 } 24659 if (BCM_SUCCESS(rv)) { 24660 SOC_PBMP_PORT_ADD(si->st.bitmap, port); 24661 SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port); 24662 SOC_PBMP_PORT_REMOVE(si->hg2_pbm, port); 24663 } 24664 24665 PORT_UNLOCK(unit); 24666 24667 return (rv); 24668 } 24669 24670 /* 24671 * Function: 24672 * bcm_esw_port_encap_config_get 24673 * Purpose: 24674 * Get the port encapsulation 24675 * Parameters: 24676 * unit - (IN) device id 24677 * gport - (IN) Generic port 24678 * encap_config - (OUT) structure describes port encapsulation configuration 24679 * Returns: 24680 * BCM_E_XXX 24681 */ 24682 int 24683 bcm_esw_port_encap_config_get(int unit, bcm_gport_t gport, 24684 bcm_port_encap_config_t *encap_config) 24685 { 24686 bcm_port_t port; 24687 uint32 val, buffer[16]; /* 64 bytes max EHG header size */ 24688 uint64 val64; 24689 int rv = BCM_E_NONE, mode = 0; 24690 soc_reg_t ehg_tx_reg = EHG_TX_REG(unit); 24691 soc_reg_t ehg_rx_reg = EHG_RX_REG(unit); 24692 24693 if (NULL == encap_config) { 24694 return (BCM_E_PARAM); 24695 } 24696 /* Make sure port module is initialized. */ 24697 PORT_INIT(unit); 24698 24699 sal_memset(encap_config, 0, sizeof(bcm_port_encap_config_t)); 24700 24701 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, gport, &port)); 24702 if(bcm_common_oamp_port_enable_get(unit, port)) { 24703 LOG_ERROR(BSL_LS_BCM_PORT, 24704 (BSL_META("Error: Not permitted on OAMP port %d.n"), 24705 port)); 24706 return BCM_E_PARAM; 24707 } 24708 24709 if (!soc_feature(unit, soc_feature_embedded_higig) && 24710 !soc_feature(unit, soc_feature_higig_over_ethernet)) { 24711 24712 rv = bcm_esw_port_encap_get(unit, port, &mode); 24713 if (BCM_SUCCESS(rv)) { 24714 encap_config->encap = (bcm_port_encap_t)mode; 24715 } 24716 return rv; 24717 } 24718 24719 if (soc_feature(unit, soc_feature_embedded_higig)) { 24720 /* Check for Raptor-style stacking */ 24721 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_rx_reg, port, 0, &val)); 24722 if (soc_reg_field_get(unit, ehg_rx_reg, val, MODEf) == 2) { 24723 encap_config->encap = BCM_PORT_ENCAP_HIGIG2_LITE; 24724 return rv; 24725 } 24726 24727 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, ehg_tx_reg, port, 0, &val)); 24728 /* If no EHG was programmed the just read port encapsulation */ 24729 if (!soc_reg_field_get(unit, ehg_tx_reg, val, ENABLEf)) { 24730 rv = bcm_esw_port_encap_get(unit, port, &mode); 24731 if (BCM_SUCCESS(rv)) { 24732 encap_config->encap = (bcm_port_encap_t)mode; 24733 } 24734 return rv; 24735 } 24736 24737 /* EHG is enabled. */ 24738 if (!IS_ST_PORT(unit, port)) { 24739 return (BCM_E_CONFIG); 24740 } 24741 24742 BCM_IF_ERROR_RETURN(_bcm_port_ehg_header_read(unit, port, buffer)); 24743 24744 if (!soc_reg_field_get(unit, ehg_tx_reg, val, TUNNEL_TYPEf)) { 24745 encap_config->encap = BCM_PORT_ENCAP_HIGIG2_L2; 24746 rv = _bcm_port_l2_tunnel_header_parse(unit, port, buffer, 24747 encap_config); 24748 } else { 24749 encap_config->encap = BCM_PORT_ENCAP_HIGIG2_IP_GRE; 24750 rv = _bcm_port_ipv4_tunnel_header_parse(unit, port, buffer, 24751 encap_config); 24752 } 24753 } else if(soc_feature(unit, soc_feature_higig_over_ethernet)) { 24754 uint64 v64 = COMPILER_64_INIT(0, 0); 24755 uint32 v32=0; 24756 24757 /* If HGoE disabled and then just read port encapsulation */ 24758 if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r)) { 24759 BCM_IF_ERROR_RETURN 24760 (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, port, 0, 24761 &val64)); 24762 v64 = soc_reg64_field_get(unit, PGW_CELL_ASM_EMBEDDED_HG_CONTROL0r, 24763 val64, TRANSPORT_ENf); 24764 } 24765 #ifdef BCM_TRIDENT3_SUPPORT 24766 if (SOC_IS_TRIDENT3X(unit)) { 24767 uint8 is_hgoe = 0; 24768 BCM_IF_ERROR_RETURN(bcm_td3_port_hgoe_mode_get( 24769 unit, port, &is_hgoe)); 24770 if (is_hgoe) { 24771 encap_config->encap = BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET; 24772 encap_config->higig_ethertype = BCM_TD3_HGOE_HDR_TYPE; 24773 return BCM_E_NONE; 24774 } else { 24775 rv = bcm_esw_port_encap_get(unit, port, &mode); 24776 if (BCM_SUCCESS(rv)) { 24777 encap_config->encap = (bcm_port_encap_t)mode; 24778 } 24779 return rv; 24780 } 24781 } else 24782 #endif 24783 if (COMPILER_64_IS_ZERO(v64)) { 24784 rv = bcm_esw_port_encap_get(unit, port, &mode); 24785 if (BCM_SUCCESS(rv)) { 24786 encap_config->encap = (bcm_port_encap_t)mode; 24787 } 24788 return rv; 24789 } 24790 24791 if (!IS_ST_PORT(unit, port)) { 24792 return (BCM_E_CONFIG); 24793 } 24794 24795 sal_memset(encap_config, 0, sizeof(bcm_port_encap_config_t)); 24796 encap_config->encap = BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET; 24797 24798 if (SOC_REG_IS_VALID(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr)) { 24799 BCM_IF_ERROR_RETURN 24800 (soc_reg_get(unit, PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, port, 24801 0, &val64)); 24802 v64 = soc_reg64_field_get(unit, 24803 PGW_CELL_ASM_EMBEDDED_HG_ETHERTYPEr, val64, ETHERTYPEf); 24804 encap_config->higig_ethertype = (uint16) COMPILER_64_LO(v64); 24805 } 24806 24807 if (SOC_REG_IS_VALID(unit, EGR_EHG_HEADER_CONTROLr)) { 24808 BCM_IF_ERROR_RETURN 24809 (soc_reg_get(unit, EGR_EHG_HEADER_CONTROLr, port, 0, &val64)); 24810 v32 = COMPILER_64_LO(val64); 24811 encap_config->hgoe_reserved = soc_reg_field_get(unit, 24812 EGR_EHG_HEADER_CONTROLr, v32, EHG_RESERVEDf); 24813 } 24814 } 24815 24816 return (rv); 24817 } 24818 24819 /* 24820 * Function: 24821 * _bcm_esw_port_mirror_lock 24822 * Purpose: 24823 * Take the mirror and port mutexes 24824 * Parameters: 24825 * unit - unit # 24826 * Returns: 24827 * None 24828 */ 24829 void 24830 _bcm_esw_port_mirror_lock(int unit) { 24831 bcm_esw_mirror_lock(unit); 24832 PORT_LOCK(unit); 24833 } 24834 24835 /* 24836 * Function: 24837 * _bcm_esw_port_mirror_unlock 24838 * Purpose: 24839 * Give up the mirror and port mutexes 24840 * Parameters: 24841 * unit - unit # 24842 * Returns: 24843 * None 24844 */ 24845 void 24846 _bcm_esw_port_mirror_unlock(int unit) { 24847 PORT_UNLOCK(unit); 24848 bcm_esw_mirror_unlock(unit); 24849 } 24850 24851 /* 24852 * Function: 24853 * bcmi_esw_port_encap_set 24854 * Purpose: 24855 * Set the port encapsulation mode 24856 * Parameters: 24857 * unit - StrataSwitch unit # 24858 * port - StrataSwitch port # 24859 * mode - One of BCM_PORT_ENCAP_xxx (see port.h) 24860 * Returns: 24861 * BCM_E_XXX 24862 */ 24863 int 24864 bcmi_esw_port_encap_set(int unit, bcm_port_t port, int mode) 24865 { 24866 int rv=BCM_E_NONE, xport_swap = FALSE; 24867 int stport_swap = FALSE; 24868 #if defined(BCM_KATANA2_SUPPORT) 24869 uint64 rval64; 24870 ing_physical_port_table_entry_t ing_entry={{0}}; 24871 ing_physical_port_table_entry_t ing_entry_dup={{0}}; 24872 egr_physical_port_entry_t egr_entry={{0}}; 24873 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 24874 #endif 24875 #ifdef BCM_HELIX4_SUPPORT 24876 uint16 dev_id = 0; 24877 uint8 rev_id = 0; 24878 #endif 24879 /* Make sure port module is initialized. */ 24880 PORT_INIT(unit); 24881 24882 if(bcm_common_oamp_port_enable_get(unit, port)) { 24883 LOG_ERROR(BSL_LS_BCM_PORT, 24884 (BSL_META("Error: Not permitted on OAMP port %d.n"), 24885 port)); 24886 return BCM_E_PARAM; 24887 } 24888 24889 #ifdef BCM_HELIX4_SUPPORT 24890 soc_cm_get_id(unit, &dev_id, &rev_id); 24891 if ((BCM56548H_DEVICE_ID == dev_id) && 24892 (mode == BCM_PORT_ENCAP_IEEE) && ((port >= 46) && (port <= 53))) { 24893 /* IEEE encap mode shouldn't be supported on WC1 and WC2 for BCM56548H*/ 24894 return BCM_E_UNAVAIL; 24895 } 24896 #endif 24897 24898 #if defined(BCM_KATANA2_SUPPORT) 24899 #if defined(BCM_SABER2_SUPPORT) 24900 if(SOC_IS_SABER2(unit)) { 24901 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 24902 } 24903 #endif 24904 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 24905 (!((port >= 1) && (port <= max_phy_port)))) { 24906 return BCM_E_PORT; 24907 } 24908 #endif 24909 24910 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 24911 LOG_INFO(BSL_LS_BCM_PORT, 24912 (BSL_META_U(unit, 24913 "bcm_esw_port_encap_set: u=%d p=%d mode=%d\n"), 24914 unit, port, mode)); 24915 #if defined(BCM_METROLITE_SUPPORT) 24916 if (SOC_IS_METROLITE(unit)){ 24917 if (!BCM_GPORT_IS_SET(port)) { 24918 if(!IS_XL_PORT(unit, port) && (mode != BCM_PORT_ENCAP_IEEE)) { 24919 return BCM_E_UNAVAIL; 24920 } 24921 if((0 == SOC_PORT_BLOCK_NUMBER(unit, port)) && 24922 (mode != BCM_PORT_ENCAP_IEEE)) { 24923 return BCM_E_UNAVAIL; 24924 } 24925 } 24926 }else 24927 #endif 24928 #if defined(BCM_SABER2_SUPPORT) 24929 if (SOC_IS_SABER2(unit) && (!BCM_GPORT_IS_SET(port))) { 24930 if(!IS_XL_PORT(unit, port) && (mode != BCM_PORT_ENCAP_IEEE)) { 24931 return BCM_E_UNAVAIL; 24932 } 24933 } 24934 #endif 24935 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) ||\ 24936 defined (BCM_SABER2_SUPPORT) 24937 if (SOC_IS_GREYHOUND(unit) || SOC_IS_TOMAHAWKX(unit) || 24938 SOC_IS_HURRICANE3(unit) || SOC_IS_SABER2(unit) || 24939 SOC_IS_TRIDENT3X(unit) || SOC_IS_GREYHOUND2(unit)) { 24940 int encap_mode; 24941 BCM_IF_ERROR_RETURN(bcm_esw_port_encap_get(unit, port, &encap_mode)); 24942 if (encap_mode == mode) { 24943 /* no encap set is required */ 24944 return BCM_E_NONE; 24945 } 24946 } 24947 #endif /* BCM_GREYHOUND_SUPPORT || BCM_TOMAHAWK_SUPPORT || BCM_SABER2_SUPPORT */ 24948 24949 #if defined(BCM_HURRICANE3_SUPPORT) 24950 if (soc_feature(unit, soc_feature_wh2)){ 24951 return bcmi_wh2_port_encap_set(unit, port, mode); 24952 } 24953 #endif /* BCM_HURRICANE3_SUPPORT */ 24954 _bcm_esw_port_mirror_lock(unit); 24955 24956 if ((IS_HG_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) || 24957 ((IS_XE_PORT(unit,port) || IS_CE_PORT(unit,port)) && 24958 (mode != BCM_PORT_ENCAP_IEEE))) { 24959 if (soc_feature(unit, soc_feature_xport_convertible)) { 24960 xport_swap = TRUE; 24961 } else { 24962 /* Ether <=> Higig not allowed on all systems */ 24963 _bcm_esw_port_mirror_unlock(unit); 24964 return BCM_E_UNAVAIL; 24965 } 24966 } 24967 #if defined(BCM_GREYHOUND_SUPPORT) 24968 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 24969 SOC_IS_GREYHOUND2(unit)) { 24970 if ((IS_HG_PORT(unit, port) && (mode != BCM_PORT_ENCAP_IEEE)) || 24971 (IS_HL_PORT(unit, port) && (mode == BCM_PORT_ENCAP_IEEE))) { 24972 /* HG port encap swap between HG/HG2/HG-Lite and 24973 * HG-Lite encap swap to IEEE. 24974 */ 24975 xport_swap = TRUE; 24976 } else if (IS_GE_PORT(unit, port)) { 24977 if ((IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) && 24978 (mode == BCM_PORT_ENCAP_IEEE || 24979 mode == BCM_PORT_ENCAP_HIGIG2_LITE)){ 24980 /* GE+XL/CL port encap set between IEEE/HG-Lite */ 24981 xport_swap = TRUE; 24982 } else { 24983 /* unavail encap configuration : 24984 * 1. QSGMII port for HG/HG2/HG2-Lite related encap 24985 * 2. GE(+XL) port for HG/HG2 24986 */ 24987 _bcm_esw_port_mirror_unlock(unit); 24988 return BCM_E_UNAVAIL; 24989 } 24990 } 24991 } 24992 #endif /* BCM_GREYHOUND_SUPPORT */ 24993 #if defined(BCM_KATANA_SUPPORT) 24994 if (SOC_IS_KATANA(unit) && IS_MXQ_PORT(unit,port) && 24995 IS_GE_PORT(unit,port)) { 24996 if ((IS_ST_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) || 24997 (IS_E_PORT(unit,port) && (mode == BCM_PORT_ENCAP_HIGIG2 || 24998 mode == BCM_PORT_ENCAP_HIGIG2_LITE))) { 24999 stport_swap = TRUE; 25000 } 25001 } 25002 #endif 25003 #if defined(BCM_KATANA2_SUPPORT) 25004 if ((SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit)) && 25005 (port >= 25 && port <= 40)) { 25006 if ((IS_ST_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) || 25007 (IS_E_PORT(unit,port) && (mode == BCM_PORT_ENCAP_HIGIG2 || 25008 mode == BCM_PORT_ENCAP_HIGIG2_LITE))) { 25009 stport_swap = TRUE; 25010 } 25011 } 25012 #endif 25013 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 25014 /* There could be hg to hg (hg2 -> hg2 lite) which require special processing */ 25015 if ((SOC_IS_SABER2(unit) || SOC_IS_HURRICANE2(unit)) && IS_XL_PORT(unit, port)) { 25016 xport_swap = TRUE; 25017 } 25018 #endif 25019 if (SOC_IS_RAVEN(unit) || SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit)) { 25020 if ((IS_ST_PORT(unit,port) && (mode == BCM_PORT_ENCAP_IEEE)) || 25021 (IS_E_PORT(unit,port) && (mode == BCM_PORT_ENCAP_HIGIG2 || 25022 mode == BCM_PORT_ENCAP_HIGIG2_LITE))) { 25023 stport_swap = TRUE; 25024 } 25025 } 25026 #ifdef BCM_TRIUMPH3_SUPPORT 25027 if (SOC_IS_TRIUMPH3(unit) && IS_XT_PORT(unit,port) && 25028 !((mode == BCM_PORT_ENCAP_IEEE) || (mode == BCM_PORT_ENCAP_HIGIG2_L2))) { 25029 /* Ether => Higig not allowed on XT ports */ 25030 _bcm_esw_port_mirror_unlock(unit); 25031 return BCM_E_UNAVAIL; 25032 } 25033 if (SOC_IS_TRIUMPH3(unit) && (mode != BCM_PORT_ENCAP_IEEE) && 25034 !IS_HG_PORT(unit, port)) { 25035 int hp, hgc = 0; 25036 25037 PBMP_HG_ITER(unit, hp) { 25038 if (!SOC_PBMP_MEMBER(SOC_PORT_DISABLED_BITMAP(unit, port), hp)) { 25039 hgc++; 25040 } 25041 } 25042 if (hgc+1 > _SOC_TR3_MAX_HG_PORT_COUNT) { 25043 LOG_ERROR(BSL_LS_BCM_PORT, \ 25044 (BSL_META_U(unit, \ 25045 "Error: Port %d config error "\ 25046 "(Higig port count(%d) exceeded) !!\n"), 25047 port, hgc)); 25048 _bcm_esw_port_mirror_unlock(unit); 25049 return BCM_E_RESOURCE; 25050 } 25051 } 25052 #endif /* BCM_TRIUMPH3_SUPPORT */ 25053 25054 if (xport_swap) { 25055 COUNTER_LOCK(unit); 25056 if ((BCM_PORT_ENCAP_HIGIG2_LITE == mode)) { 25057 rv = _bcm_esw_port_encap_higig_lite_set(unit, port); 25058 } else { 25059 rv = _bcm_port_encap_xport_set(unit, port, mode, TRUE); 25060 } 25061 25062 COUNTER_UNLOCK(unit); 25063 } else if (stport_swap) { 25064 rv = _bcm_port_encap_stport_set(unit, port, mode); 25065 } else if (IS_HG_PORT(unit, port)) { 25066 rv = MAC_ENCAP_SET(PORT(unit, port).p_mac, unit, port, mode); 25067 } else if (IS_GE_PORT(unit, port) && IS_ST_PORT(unit, port)) { 25068 if (mode == BCM_PORT_ENCAP_IEEE) { 25069 bcm_port_encap_config_t encap_config; 25070 25071 rv = bcm_esw_port_encap_config_get(unit, port, 25072 &encap_config); 25073 if (BCM_SUCCESS(rv)) { 25074 if ((BCM_PORT_ENCAP_HIGIG2_L2 == encap_config.encap) || 25075 (BCM_PORT_ENCAP_HIGIG2_IP_GRE == encap_config.encap) || 25076 (BCM_PORT_ENCAP_HIGIG2_LITE == encap_config.encap) || 25077 (BCM_PORT_ENCAP_HIGIG_OVER_ETHERNET == encap_config.encap)) { 25078 rv = _bcm_port_encap_stport_set(unit, port, 25079 BCM_PORT_ENCAP_IEEE); 25080 } else { 25081 rv = BCM_E_UNAVAIL; 25082 } 25083 } 25084 } else { 25085 if ((mode == BCM_PORT_ENCAP_HIGIG2) || 25086 (mode == BCM_PORT_ENCAP_HIGIG2_LITE && 25087 (SOC_IS_RAVEN(unit) || SOC_IS_ENDURO(unit) || 25088 SOC_IS_HURRICANEX( unit) || SOC_IS_GREYHOUND(unit) || 25089 SOC_IS_GREYHOUND2(unit)))) { 25090 rv = BCM_E_NONE; 25091 } else { 25092 rv = BCM_E_UNAVAIL; 25093 } 25094 } 25095 #if defined(BCM_TRIUMPH3_SUPPORT) 25096 } else if (IS_CE_PORT(unit, port)) { 25097 if ((mode == BCM_PORT_ENCAP_HIGIG2) || (mode == BCM_PORT_ENCAP_HIGIG) 25098 || (mode == BCM_PORT_ENCAP_IEEE)) { 25099 rv = _bcm_port_encap_stport_set(unit, port, mode); 25100 } else { 25101 rv = BCM_E_UNAVAIL; 25102 } 25103 #endif 25104 } else if (mode == BCM_PORT_ENCAP_IEEE) { 25105 rv = BCM_E_NONE; 25106 } else { 25107 rv = BCM_E_UNAVAIL; 25108 } 25109 25110 #ifdef BCM_GXPORT_SUPPORT 25111 if ( IS_GX_PORT(unit, port) 25112 || IS_XG_PORT(unit,port) 25113 || (IS_XQ_PORT(unit, port) && 25114 (SOC_IS_ENDURO(unit) || SOC_IS_HURRICANE(unit))) 25115 || (IS_XL_PORT(unit, port) && 25116 (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || 25117 (SOC_IS_SABER2(unit) || SOC_IS_HURRICANE3(unit)) || 25118 SOC_IS_GREYHOUND2(unit))) 25119 || (IS_CL_PORT(unit, port) && (SOC_IS_GREYHOUND2(unit))) 25120 || (IS_MXQ_PORT(unit, port) && (SOC_IS_KATANAX(unit) && !SOC_IS_SABER2(unit))) 25121 || ((IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port) || 25122 IS_CE_PORT(unit, port)) && 25123 (SOC_IS_TRIUMPH3(unit) 25124 || (SOC_IS_TRIDENT2X(unit) || SOC_IS_TITAN2PLUS(unit)) || 25125 SOC_IS_TOMAHAWKX(unit))) ) { 25126 int hg2 = FALSE; 25127 soc_reg_t port_config_reg; 25128 uint32 regval, new_hg_pbm; 25129 int blk, blk_num, bindex; 25130 25131 if (mode == BCM_PORT_ENCAP_HIGIG2 || mode == BCM_PORT_ENCAP_HIGIG2_LITE) { 25132 hg2 = TRUE; 25133 } 25134 if (BCM_SUCCESS(rv)) { 25135 rv = _bcm_esw_port_higig2_mode_set(unit, port, hg2); 25136 } 25137 25138 if (IS_CL_PORT(unit, port) && 25139 SOC_REG_IS_VALID(unit, CLPORT_CONFIGr)) { 25140 port_config_reg = CLPORT_CONFIGr; 25141 } else if (IS_C_PORT(unit, port) && 25142 SOC_REG_IS_VALID(unit, CPORT_CONFIGr)) { 25143 port_config_reg = CPORT_CONFIGr; 25144 } else if (SOC_REG_IS_VALID(unit, XLPORT_CONFIGr)) { 25145 port_config_reg = XLPORT_CONFIGr; 25146 } else if (SOC_REG_IS_VALID(unit, PORT_CONFIGr)) { 25147 port_config_reg = PORT_CONFIGr; 25148 } else { 25149 port_config_reg = XPORT_CONFIGr; 25150 } 25151 if (BCM_SUCCESS(rv)) { 25152 #if defined(BCM_GREYHOUND_SUPPORT)||defined(BCM_GREYHOUND2_SUPPORT) 25153 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 25154 SOC_IS_GREYHOUND2(unit)){ 25155 uint32 port_hg_mode; 25156 25157 /* XLPORT/CLPORT and PGW register for HIGIG_MODEf is confirmed 25158 * will be '1' for HG/HG+ setting only and '0' for other 25159 * encap mode{IEEE/HG2/HG2-LITE} 25160 */ 25161 port_hg_mode = (mode == BCM_PORT_ENCAP_HIGIG) ? 1 : 0; 25162 rv = soc_reg_field32_modify(unit, port_config_reg, port, 25163 HIGIG_MODEf, port_hg_mode); 25164 if (BCM_FAILURE(rv)) { 25165 _bcm_esw_port_mirror_unlock(unit); 25166 return rv; 25167 } 25168 25169 /* only port available for HG2 configuration allows PGW encap 25170 * setting below 25171 */ 25172 #if defined(BCM_GREYHOUND2_SUPPORT) 25173 if (SOC_IS_GREYHOUND2(unit)) { 25174 rv = soc_greyhound2_pgw_encap_field_modify(unit, 25175 port, HIGIG_MODEf, port_hg_mode); 25176 } else 25177 #endif /* BCM_GREYHOUND2_SUPPORT */ 25178 { 25179 rv = soc_greyhound_pgw_encap_field_modify(unit, 25180 port, HIGIG_MODEf, port_hg_mode); 25181 } 25182 if (BCM_FAILURE(rv)) { 25183 _bcm_esw_port_mirror_unlock(unit); 25184 return rv; 25185 } 25186 } else 25187 #endif /* BCM_GREYHOUND_SUPPORT||BCM_GREYHOUND2_SUPPORT */ 25188 { 25189 #if defined(BCM_SABER2_SUPPORT) 25190 if(SOC_IS_SABER2(unit)) { 25191 /* For Saber2, configure IECELL along with XLPORT */ 25192 if (SOC_REG_PORT_VALID(unit, IECELL_CONFIGr, port)) { 25193 if ((mode == BCM_PORT_ENCAP_HIGIG2) || 25194 (mode == BCM_PORT_ENCAP_HIGIG2_LITE) || 25195 (mode == BCM_PORT_ENCAP_HIGIG)) { 25196 rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port, 25197 HIGIG_MODEf, mode == BCM_PORT_ENCAP_HIGIG ? 25198 1 : 0); 25199 rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port, 25200 HIGIG2_MODEf, mode == BCM_PORT_ENCAP_HIGIG ? 25201 0 : 1); 25202 } else { 25203 rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port, 25204 HIGIG2_MODEf, 0); 25205 rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port, 25206 HIGIG_MODEf, 0); 25207 } 25208 } 25209 } 25210 #endif 25211 #ifdef BCM_KATANA2_SUPPORT 25212 if (SOC_IS_KATANA2(unit)) { 25213 if (SOC_REG_FIELD_VALID(unit, port_config_reg, HIGIG_MODEf)) { 25214 if ((mode == BCM_PORT_ENCAP_HIGIG2) || 25215 (mode == BCM_PORT_ENCAP_HIGIG2_LITE) || 25216 (mode == BCM_PORT_ENCAP_HIGIG)) { 25217 25218 rv = soc_reg_field32_modify(unit, port_config_reg, port, 25219 HIGIG_MODEf, mode == BCM_PORT_ENCAP_HIGIG ? 25220 1 : 0); 25221 rv = soc_reg_field32_modify(unit, port_config_reg, port, 25222 HIGIG2_MODEf, mode == BCM_PORT_ENCAP_HIGIG ? 25223 0 : 1); 25224 } else { 25225 rv = soc_reg_field32_modify(unit, port_config_reg, port, 25226 HIGIG2_MODEf, 0); 25227 rv = soc_reg_field32_modify(unit, port_config_reg, port, 25228 HIGIG_MODEf, 0); 25229 } 25230 } 25231 } else 25232 #endif 25233 { 25234 if (SOC_REG_FIELD_VALID(unit, port_config_reg, HIGIG_MODEf)) { 25235 rv = soc_reg_field32_modify(unit, port_config_reg, port, 25236 HIGIG_MODEf, mode == BCM_PORT_ENCAP_IEEE ? 25237 0 : 1); 25238 } 25239 if (SOC_IS_TOMAHAWKX(unit)) { 25240 if (IS_CL_PORT(unit, port) && 25241 (mode == BCM_PORT_ENCAP_HIGIG)) { 25242 if (SOC_REG_FIELD_VALID(unit, port_config_reg, 25243 HIGIG2_MODEf)) { 25244 rv = soc_reg_field32_modify(unit, 25245 port_config_reg, port, HIGIG2_MODEf, 1); 25246 } 25247 } 25248 } 25249 } 25250 } 25251 } 25252 if (BCM_SUCCESS(rv)) { 25253 if (SOC_MEM_IS_VALID(unit, EGR_PORTm) && 25254 soc_mem_field_valid(unit, EGR_PORTm, PORT_TYPEf)) { 25255 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 25256 PORT_TYPEf, mode == BCM_PORT_ENCAP_IEEE ? 25257 0 : 1); 25258 } 25259 } 25260 if (SOC_IS_TRIUMPH3(unit) && (mode == BCM_PORT_ENCAP_IEEE)) { 25261 /* Disable E2ECC */ 25262 if (soc_feature(unit, soc_feature_logical_port_num)) { 25263 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[port]); 25264 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[port]); 25265 } else{ 25266 blk = SOC_PORT_BLOCK(unit, port); 25267 bindex = SOC_PORT_BINDEX(unit, port); 25268 } 25269 blk_num = SOC_BLOCK_INFO(unit, blk).number; 25270 /* In TR3 E2ECC is implemented only in blocks CL, XL1 */ 25271 if (IS_CL_PORT(unit, port) || (blk == 13)) { 25272 if (IS_CL_PORT(unit, port)) { 25273 blk_num = (blk_num ? 4 + bindex/4 : bindex/4); 25274 bindex = bindex%4; 25275 } else { 25276 blk_num = 3; 25277 } 25278 #if defined(BCM_KATANA2_SUPPORT) 25279 if (SOC_IS_KATANA2(unit)) { 25280 /* In KT2 E2ECC is implemented only in blocks 6..9 */ 25281 blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ; 25282 } 25283 #endif 25284 rv = READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num, ®val); 25285 if (BCM_FAILURE(rv)) { 25286 _bcm_esw_port_mirror_unlock(unit); 25287 return rv; 25288 } 25289 if (regval & (1 << bindex)) { 25290 new_hg_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval, 25291 TX_ENABLE_BMPf); 25292 new_hg_pbm &= ~(1 << bindex); 25293 soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, ®val, 25294 TX_ENABLE_BMPf, new_hg_pbm); 25295 rv = WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, regval); 25296 } 25297 } 25298 } 25299 } 25300 #endif /* BCM_GXPORT_SUPPORT */ 25301 25302 if (soc_feature(unit, soc_feature_embedded_higig)) { 25303 /* Clear embedded Higig regs, if present */ 25304 soc_reg_t ehg_tx_reg = EHG_TX_REG(unit); 25305 soc_reg_t ehg_rx_reg = EHG_RX_REG(unit); 25306 25307 if (BCM_SUCCESS(rv) && SOC_REG_IS_VALID(unit, ehg_tx_reg)) { 25308 rv = soc_reg32_set(unit, ehg_tx_reg, port, 0, 0); 25309 } 25310 if (BCM_SUCCESS(rv) && SOC_REG_IS_VALID(unit, ehg_rx_reg)) { 25311 rv = soc_reg32_set(unit, ehg_rx_reg, port, 0, 0); 25312 } 25313 } 25314 25315 #ifdef BCM_HIGIG2_SUPPORT 25316 /* Update cached version of HiGig2 encapsulation */ 25317 if (BCM_SUCCESS(rv)) { 25318 if (mode == BCM_PORT_ENCAP_HIGIG2 || mode == BCM_PORT_ENCAP_HIGIG2_LITE) { 25319 SOC_HG2_ENABLED_PORT_ADD(unit, port); 25320 25321 if(SOC_IS_SABER2(unit)){ 25322 if(mode == BCM_PORT_ENCAP_HIGIG2_LITE) { 25323 SOC_PBMP_PORT_ADD(SOC_INFO(unit).hl.bitmap, port); 25324 } else { 25325 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port); 25326 } 25327 } 25328 } else { 25329 SOC_HG2_ENABLED_PORT_REMOVE(unit, port); 25330 if(SOC_IS_SABER2(unit) && IS_XL_PORT(unit, port)) { 25331 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).hl.bitmap, port); 25332 } 25333 } 25334 } 25335 #endif /* BCM_HIGIG2_SUPPORT */ 25336 25337 #ifdef BCM_KATANA2_SUPPORT 25338 if (BCM_SUCCESS(rv)) { 25339 if (SOC_IS_KATANA2(unit)) { 25340 int hdr_mode = 0; 25341 25342 do { 25343 rv = soc_mem_read(unit, ING_PHYSICAL_PORT_TABLEm, 25344 MEM_BLOCK_ANY, port, &ing_entry); 25345 sal_memcpy(&ing_entry_dup,&ing_entry, 25346 sizeof(ing_physical_port_table_entry_t)); 25347 if (BCM_FAILURE(rv)) { 25348 LOG_ERROR(BSL_LS_BCM_PORT, 25349 (BSL_META_U(unit, 25350 "Error: Encap Set: " 25351 "ING_PHYSICAL_PORT_TABLEm read failure"))); 25352 break; 25353 } 25354 rv = soc_mem_read(unit, EGR_PHYSICAL_PORTm, 25355 MEM_BLOCK_ANY, port, &egr_entry); 25356 if (BCM_FAILURE(rv)) { 25357 LOG_ERROR(BSL_LS_BCM_PORT, 25358 (BSL_META_U(unit, 25359 "Error: Encap Set: " 25360 "EGR_PHYSICAL_PORTm read failure"))); 25361 break; 25362 } 25363 /* Initialize */ 25364 soc_mem_field32_set(unit, ING_PHYSICAL_PORT_TABLEm, 25365 &ing_entry, PORT_TYPEf, 0); 25366 soc_mem_field32_set(unit, ING_PHYSICAL_PORT_TABLEm, 25367 &ing_entry, HIGIG2f, 0); 25368 soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm, 25369 &egr_entry, PORT_TYPEf, 0); 25370 soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm, 25371 &egr_entry, HIGIG2f, 0); 25372 if ((mode == BCM_PORT_ENCAP_HIGIG) || 25373 (mode == BCM_PORT_ENCAP_HIGIG2) || 25374 (mode == BCM_PORT_ENCAP_HIGIG2_LITE)) { 25375 if (((mode == BCM_PORT_ENCAP_HIGIG2) || 25376 (mode == BCM_PORT_ENCAP_HIGIG2_LITE)) && 25377 soc_feature(unit, soc_feature_higig2)) { 25378 if (mode == BCM_PORT_ENCAP_HIGIG2_LITE) { 25379 hdr_mode = 0; /* Ieee mode */ 25380 } else { 25381 hdr_mode = 2; /* Higig2 */ 25382 } 25383 soc_mem_field32_set(unit, 25384 ING_PHYSICAL_PORT_TABLEm, 25385 &ing_entry, HIGIG2f, 1); 25386 soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm, 25387 &egr_entry, HIGIG2f, 1); 25388 } else { 25389 hdr_mode = 1; /* HG, hg+ */ 25390 } 25391 soc_mem_field32_set(unit, ING_PHYSICAL_PORT_TABLEm, 25392 &ing_entry, PORT_TYPEf, 1); 25393 soc_mem_field32_set(unit, EGR_PHYSICAL_PORTm, 25394 &egr_entry, PORT_TYPEf, 1); 25395 } else { 25396 hdr_mode = 0; /* Ieee mode */ 25397 } 25398 if (SOC_REG_IS_VALID(unit, XMAC_MODEr)) { 25399 SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit,port, &rval64)); 25400 soc_reg64_field32_set(unit, XMAC_MODEr, &rval64,HDR_MODEf, hdr_mode); 25401 SOC_IF_ERROR_RETURN(WRITE_XMAC_MODEr(unit, port, rval64)); 25402 } 25403 if (SOC_REG_IS_VALID(unit, XLMAC_MODEr)) { 25404 SOC_IF_ERROR_RETURN(READ_XLMAC_MODEr(unit,port, &rval64)); 25405 soc_reg64_field32_set(unit, XLMAC_MODEr, &rval64,HDR_MODEf, hdr_mode); 25406 SOC_IF_ERROR_RETURN(WRITE_XLMAC_MODEr(unit, port, rval64)); 25407 } 25408 25409 if (sal_memcmp(&ing_entry_dup,&ing_entry, 25410 sizeof(ing_physical_port_table_entry_t)) == 0) { 25411 LOG_VERBOSE(BSL_LS_BCM_PORT, 25412 (BSL_META_U(unit, 25413 "##No Change in entry so skipping write##\n"))); 25414 rv = BCM_E_NONE; 25415 } else { 25416 LOG_ERROR(BSL_LS_BCM_PORT, 25417 (BSL_META_U(unit, 25418 "##Change in entry so Need to update##\n"))); 25419 rv = soc_mem_write(unit, ING_PHYSICAL_PORT_TABLEm, 25420 MEM_BLOCK_ALL, port, &ing_entry); 25421 } 25422 if (BCM_FAILURE(rv)) { 25423 LOG_ERROR(BSL_LS_BCM_PORT, 25424 (BSL_META_U(unit, 25425 "Error: Encap Set: " 25426 "ING_PHYSICAL_PORT_TABLEm write failure"))); 25427 break; 25428 } 25429 rv = soc_mem_write(unit, EGR_PHYSICAL_PORTm, 25430 MEM_BLOCK_ALL, port, &egr_entry); 25431 if (BCM_FAILURE(rv)) { 25432 LOG_ERROR(BSL_LS_BCM_PORT, 25433 (BSL_META_U(unit, 25434 "Error: Encap Set: " 25435 "EGR_PHYSICAL_PORTm write failure"))); 25436 break; 25437 } 25438 25439 #ifdef BCM_KATANA2_SUPPORT 25440 if (SOC_IS_KATANA2(unit )) { 25441 rv = _bcm_kt2_cosq_dynamic_port_encap_change(unit,port); 25442 if (BCM_FAILURE(rv)) { 25443 LOG_ERROR(BSL_LS_BCM_PORT, 25444 (BSL_META_U(unit, 25445 "Error: Encap Set: " 25446 "MMU config failure"))); 25447 break; 25448 } 25449 } 25450 #endif 25451 25452 }while (0); 25453 } 25454 } 25455 #endif 25456 25457 #if defined(BCM_XMAC_SUPPORT) 25458 if(SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA2(unit) || 25459 SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 25460 uint32 vco_disturbed = 0; 25461 phy_ctrl_t *int_pc, *ext_pc; 25462 ext_pc = EXT_PHY_SW_STATE(unit, port); 25463 if (soc_feature(unit, soc_feature_xmac) && (IS_HG_PORT(unit, port) || 25464 IS_XE_PORT(unit, port)) && (ext_pc == NULL)) { 25465 25466 int_pc = INT_PHY_SW_STATE(unit, port); 25467 rv = PHYCTRL_CONTROL_GET(int_pc, unit, port, SOC_PHY_CONTROL_VCO_DISTURBED, &vco_disturbed); 25468 if (!((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL))) { 25469 _bcm_esw_port_mirror_unlock(unit); 25470 return rv; 25471 } 25472 if (vco_disturbed) { 25473 rv = _mac_x_reinit(unit, port); 25474 if (BCM_FAILURE(rv)) { 25475 _bcm_esw_port_mirror_unlock(unit); 25476 return rv; 25477 } 25478 } 25479 } 25480 } 25481 #endif 25482 _bcm_esw_port_mirror_unlock(unit); 25483 25484 return rv; 25485 } 25486 25487 25488 /* 25489 * Function: 25490 * bcmi_esw_port_encap_validate 25491 * Purpose: 25492 * Check if the encap change for this port can be acceptable or not. 25493 * Parameters: 25494 * unit - (IN) Unit number 25495 * port - (IN) Logical port number 25496 * encap - (IN) encap mode 25497 * speed - (IN) speed 25498 * Returns: 25499 * BCM_E_NONE 25500 * BCM_E_XXX 25501 * Notes: 25502 */ 25503 STATIC int 25504 bcmi_esw_port_encap_validate(int unit, bcm_port_t port, int mode, int speed) 25505 { 25506 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT 25507 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 25508 25509 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 25510 if (BCM_ESW_PORT_DRV(unit)->encap_speed_check != NULL) { 25511 BCM_IF_ERROR_RETURN 25512 (BCM_ESW_PORT_DRV(unit)->encap_speed_check(unit, port, 25513 mode, speed)); 25514 } 25515 } 25516 return BCM_E_NONE; 25517 #else 25518 return BCM_E_NONE; 25519 #endif 25520 } 25521 25522 STATIC int 25523 _bcm_esw_port_encap_set(int unit, bcm_port_t port, int mode) 25524 { 25525 int rv; 25526 #if defined(BCM_TOMAHAWK2_SUPPORT) 25527 int asf_mode; 25528 #endif /* BCM_TOMAHAWK2_SUPPORT */ 25529 25530 25531 #if defined(BCM_TOMAHAWK3_SUPPORT) 25532 if (SOC_IS_TOMAHAWK3(unit)) { 25533 return BCM_E_NONE; 25534 } 25535 #endif /* BCM_TOMAHAWK3_SUPPORT */ 25536 25537 #if defined(BCM_TOMAHAWK2_SUPPORT) 25538 if (SOC_IS_TOMAHAWK2(unit)) { 25539 BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_get(unit, port, &asf_mode)); 25540 if (asf_mode != _SOC_TH_ASF_MODE_SAF) { 25541 BCM_IF_ERROR_RETURN 25542 (bcm_esw_port_asf_mode_set(unit, port, _SOC_TH_ASF_MODE_SAF)); 25543 } 25544 } 25545 #endif /* BCM_TOMAHAWK2_SUPPORT */ 25546 25547 /* Call Port Control module */ 25548 if (SOC_USE_PORTCTRL(unit)) { 25549 rv = bcmi_esw_portctrl_encap_set(unit, port, mode, FALSE); 25550 } else { 25551 rv = bcmi_esw_port_encap_set(unit, port, mode); 25552 } 25553 25554 #if defined(BCM_TOMAHAWK2_SUPPORT) 25555 if (SOC_IS_TOMAHAWK2(unit)) { 25556 if (asf_mode != _SOC_TH_ASF_MODE_SAF) { 25557 BCM_IF_ERROR_RETURN 25558 (bcm_esw_port_asf_mode_set(unit, port, asf_mode)); 25559 } 25560 } 25561 #endif /* BCM_TOMAHAWK2_SUPPORT */ 25562 25563 return rv; 25564 } 25565 25566 /* 25567 * Function: 25568 * bcm_port_encap_set 25569 * Purpose: 25570 * Set the port encapsulation mode 25571 * Parameters: 25572 * unit - StrataSwitch unit # 25573 * port - StrataSwitch port # 25574 * mode - One of BCM_PORT_ENCAP_xxx (see port.h) 25575 * Returns: 25576 * BCM_E_XXX 25577 */ 25578 int 25579 bcm_esw_port_encap_set(int unit, bcm_port_t port, int mode) 25580 { 25581 /* Make sure port module is initialized. */ 25582 PORT_INIT(unit); 25583 25584 BCM_IF_ERROR_RETURN(bcmi_esw_port_encap_validate(unit, port, mode, 0)); 25585 BCM_IF_ERROR_RETURN(_bcm_esw_port_encap_set(unit, port, mode)); 25586 25587 return BCM_E_NONE; 25588 } 25589 25590 /* 25591 * Function: 25592 * bcm_port_encap_get 25593 * Purpose: 25594 * Get the port encapsulation mode 25595 * Parameters: 25596 * unit - StrataSwitch unit # 25597 * port - StrataSwitch port # 25598 * mode (OUT) - One of BCM_PORT_ENCAP_xxx (see port.h) 25599 * Returns: 25600 * BCM_E_XXX 25601 */ 25602 25603 int 25604 bcm_esw_port_encap_get(int unit, bcm_port_t port, int *mode) 25605 { 25606 25607 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_KATANA_SUPPORT) 25608 int speed_mode = 0; 25609 uint64 rval64; 25610 #endif 25611 25612 #if defined(BCM_KATANA2_SUPPORT) 25613 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 25614 #endif 25615 25616 *mode = -1; 25617 25618 /* Make sure port module is initialized. */ 25619 PORT_INIT(unit); 25620 25621 /* Call Port Control module */ 25622 if (SOC_USE_PORTCTRL(unit)) { 25623 return (bcmi_esw_portctrl_encap_get(unit, port, mode)); 25624 } 25625 if(bcm_common_oamp_port_enable_get(unit, port)) { 25626 LOG_ERROR(BSL_LS_BCM_PORT, 25627 (BSL_META("Error: Not permitted on OAMP port %d.n"), 25628 port)); 25629 return BCM_E_PARAM; 25630 } 25631 25632 25633 #if defined(BCM_KATANA2_SUPPORT) 25634 #if defined(BCM_SABER2_SUPPORT) 25635 if(SOC_IS_SABER2(unit)) { 25636 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 25637 } 25638 #endif 25639 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(port)) && 25640 (!((port >= 1) && (port <= max_phy_port)))) { 25641 return BCM_E_PORT; 25642 } 25643 #endif 25644 25645 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 25646 25647 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_KATANA_SUPPORT) 25648 if (SOC_IS_ENDURO(unit) || SOC_IS_KATANAX(unit) || 25649 SOC_IS_HURRICANE(unit) || SOC_IS_HURRICANE2(unit)) { 25650 if (IS_HL_PORT(unit, port)) { 25651 *mode = BCM_PORT_ENCAP_HIGIG2; 25652 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 25653 if (SOC_IS_KATANAX(unit)) { 25654 if (SOC_REG_PORT_VALID(unit, XMAC_MODEr, port)) { 25655 SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit, port, &rval64)); 25656 speed_mode = soc_reg64_field32_get(unit, XMAC_MODEr, rval64, 25657 SPEED_MODEf); 25658 25659 } else if (SOC_REG_PORT_VALID(unit, XLMAC_MODEr, port)) { 25660 25661 SOC_IF_ERROR_RETURN(READ_XLMAC_MODEr(unit, port, &rval64)); 25662 speed_mode = soc_reg64_field32_get(unit, XLMAC_MODEr, rval64, 25663 SPEED_MODEf); 25664 } 25665 #if defined(BCM_METROLITE_SUPPORT) 25666 if (SOC_IS_METROLITE(unit)) { 25667 /* 2.5G and 1G speed in HIGIG2_LITE */ 25668 if ((speed_mode == 3)||(speed_mode == 2)) { 25669 *mode = BCM_PORT_ENCAP_HIGIG2_LITE; 25670 } 25671 } else 25672 #endif 25673 if (speed_mode == 3) { 25674 *mode = BCM_PORT_ENCAP_HIGIG2_LITE; 25675 } 25676 } 25677 #endif 25678 } else { 25679 SOC_IF_ERROR_RETURN 25680 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode)); 25681 } 25682 } else 25683 #endif /* BCM_ENDURO_SUPPORT */ 25684 #ifdef BCM_GREYHOUND_SUPPORT 25685 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 25686 SOC_IS_GREYHOUND2(unit)) { 25687 int rv; 25688 uint32 hg2_mode = 0; 25689 25690 #if defined(BCM_HURRICANE3_SUPPORT) 25691 if (soc_feature(unit, soc_feature_wh2)) { 25692 return bcmi_wh2_port_encap_get(unit, port, mode); 25693 } 25694 #endif /* BCM_HURRICANE3_SUPPORT */ 25695 /* MAC encap can report the proper encap type but special setting 25696 * in port marcro for HG2-Lite case. 25697 * 25698 * For HG2-Lite condition : 25699 * - in Port Macro(MAC is included in PM), the encap will be IEEE. 25700 * - Out of Port Macro, the encap will be HG2 25701 */ 25702 BCM_IF_ERROR_RETURN 25703 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode)); 25704 if (*mode == BCM_PORT_ENCAP_IEEE) { 25705 #ifdef BCM_GREYHOUND2_SUPPORT 25706 if (SOC_IS_GREYHOUND2(unit)) { 25707 rv = soc_greyhound2_pgw_encap_field_get(unit, 25708 port, HIGIG2_MODEf, &hg2_mode); 25709 } else 25710 #endif /* GREYHOUDN2 */ 25711 { 25712 /* only port in XLMAC allows PGW encap setting below */ 25713 rv = soc_greyhound_pgw_encap_field_get(unit, 25714 port, HIGIG2_MODEf, &hg2_mode); 25715 } 25716 25717 if (BCM_SUCCESS(rv)){ 25718 *mode = (hg2_mode) ? BCM_PORT_ENCAP_HIGIG2_LITE : *mode; 25719 } else if (rv != BCM_E_UNAVAIL) { 25720 /* BCM_E_UNAVAIL can be occurred on the port at QSGMII */ 25721 return rv; 25722 } 25723 } 25724 } else 25725 #endif /* BCM_GREYHOUND_SUPPORT */ 25726 if (IS_GE_PORT(unit, port) && IS_ST_PORT(unit, port)) { 25727 if (soc_feature(unit, soc_feature_embedded_higig)) { 25728 *mode = BCM_PORT_ENCAP_IEEE; 25729 } else { 25730 uint32 rval; 25731 soc_field_t hg_en[6] = {-1, HGIG2_EN_S0f, HGIG2_EN_S1f, -1, 25732 HGIG2_EN_S3f, HGIG2_EN_S4f}; 25733 /* The port number check is for Coverity. No port > 6 will 25734 * reach this logic on Raven. */ 25735 if (SOC_IS_RAVEN(unit) && (port < 6)) { 25736 BCM_IF_ERROR_RETURN(READ_GPORT_CONFIGr(unit, port, &rval)); 25737 25738 if (SOC_REG_FIELD_VALID(unit, GPORT_CONFIGr, hg_en[port])) { 25739 *mode = soc_reg_field_get(unit, GPORT_CONFIGr, rval, 25740 hg_en[port]) ? 25741 BCM_PORT_ENCAP_HIGIG2 : BCM_PORT_ENCAP_IEEE; 25742 } else { 25743 return (BCM_E_CONFIG); 25744 } 25745 } 25746 } 25747 #if defined(BCM_TRIUMPH3_SUPPORT) 25748 } else if (SOC_IS_TRIUMPH3(unit) && IS_CE_PORT(unit, port)) { 25749 uint32 regval; 25750 BCM_IF_ERROR_RETURN(READ_PORT_CONFIGr(unit, port, ®val)); 25751 if (soc_reg_field_get(unit, PORT_CONFIGr, regval, HIGIG2_MODEf)) { 25752 *mode = BCM_PORT_ENCAP_HIGIG2; 25753 } else if (soc_reg_field_get(unit, PORT_CONFIGr, regval, HIGIG_MODEf)) { 25754 *mode = BCM_PORT_ENCAP_HIGIG; 25755 } else { 25756 SOC_IF_ERROR_RETURN 25757 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode)); 25758 } 25759 #endif 25760 } else { 25761 SOC_IF_ERROR_RETURN 25762 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode)); 25763 } 25764 25765 if(*mode == -1) { 25766 /* Default : Return MAC encap mode */ 25767 SOC_IF_ERROR_RETURN 25768 (MAC_ENCAP_GET(PORT(unit, port).p_mac, unit, port, mode)); 25769 } 25770 25771 LOG_INFO(BSL_LS_BCM_PORT, 25772 (BSL_META_U(unit, 25773 "bcm_esw_port_encap_get: u=%d p=%d mode=%d\n"), 25774 unit, port, *mode)); 25775 return BCM_E_NONE; 25776 } 25777 25778 /* 25779 * Function: 25780 * bcm_port_queued_count_get 25781 * Purpose: 25782 * Returns the count of packets (or cells) currently buffered 25783 * for a port. Useful to know when a port has drained all 25784 * data and can then be re-configured. 25785 * Parameters: 25786 * unit - StrataSwitch unit # 25787 * port - StrataSwitch port # 25788 * count (OUT) - count of packets currently buffered 25789 * Returns: 25790 * BCM_E_XXX 25791 * Notes: 25792 * "packets" may actually be cells on most chips, 25793 * If no packets are buffered, the cell count is 0, 25794 * If some packets are buffered the cell count will be 25795 * greater than or equal to the packet count. 25796 */ 25797 25798 int 25799 bcm_esw_port_queued_count_get(int unit, bcm_port_t port, uint32 *count) 25800 { 25801 uint32 regval; 25802 int cos; 25803 25804 *count = 0; 25805 25806 /* Make sure port module is initialized. */ 25807 PORT_INIT(unit); 25808 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 25809 25810 if (SOC_IS_FB_FX_HX(unit) || SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 25811 SOC_IS_GREYHOUND2(unit)) { 25812 for (cos = 0; cos < NUM_COS(unit); cos++) { 25813 regval = 0; 25814 SOC_IF_ERROR_RETURN(READ_COSLCCOUNTr(unit, port, cos, ®val)); 25815 *count += soc_reg_field_get(unit, COSLCCOUNTr, regval, LCCOUNTf); 25816 } 25817 return BCM_E_NONE; 25818 } 25819 25820 #if defined(BCM_XGS12_FABRIC_SUPPORT) 25821 if (SOC_IS_XGS12_FABRIC(unit)) { 25822 regval = 0; 25823 SOC_IF_ERROR_RETURN(READ_MMU_CELLCNTTOTALr(unit, port, ®val)); 25824 *count += soc_reg_field_get(unit, MMU_CELLCNTTOTALr, regval, COUNTf); 25825 return BCM_E_NONE; 25826 } 25827 #endif /* BCM_XGS12_FABRIC_SUPPORT */ 25828 25829 #if defined(BCM_BRADLEY_SUPPORT) 25830 if (SOC_IS_HBX(unit)) { 25831 regval = 0; 25832 SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNTr(unit, port, ®val)); 25833 *count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNTr, 25834 regval, OP_PORT_TOTAL_COUNTf); 25835 return BCM_E_NONE; 25836 } 25837 #endif /* BCM_BRADLEY_SUPPORT */ 25838 25839 #if defined(BCM_TRIDENT_SUPPORT) 25840 if (SOC_IS_TD_TT(unit)) { 25841 return soc_egress_cell_count(unit, port, count); 25842 } 25843 #endif /* BCM_TRIDENT_SUPPORT */ 25844 25845 #if defined(BCM_TRIUMPH3_SUPPORT) 25846 if (SOC_IS_TRIUMPH3(unit)) { 25847 regval = 0; 25848 SOC_IF_ERROR_RETURN(READ_OP_PORT_TOTAL_COUNT_CELLr(unit, port, ®val)); 25849 *count += soc_reg_field_get(unit, OP_PORT_TOTAL_COUNT_CELLr, 25850 regval, TOTAL_COUNTf); 25851 return BCM_E_NONE; 25852 } 25853 #endif /* BCM_TRIUMPH3_SUPPORT */ 25854 25855 return BCM_E_UNAVAIL; 25856 } 25857 25858 /* 25859 * Function: 25860 * bcm_port_protocol_vlan_add 25861 * Purpose: 25862 * Adds a protocol based vlan to a port. The protocol 25863 * is matched by frame type and ether type. Returns an 25864 * error if hardware does not support protocol vlans 25865 * (Strata and Hercules). 25866 * Parameters: 25867 * unit - StrataSwitch unit # 25868 * port - StrataSwitch port # 25869 * frame - one of BCM_PORT_FRAMETYPE_{ETHER2,8023,LLC} 25870 * ether - 16 bit Ethernet type field 25871 * vid - VLAN ID 25872 * Returns: 25873 * BCM_E_XXX 25874 */ 25875 25876 int 25877 bcm_esw_port_protocol_vlan_add(int unit, 25878 bcm_port_t port, 25879 bcm_port_frametype_t frame, 25880 bcm_port_ethertype_t ether, 25881 bcm_vlan_t vid) 25882 { 25883 int rv = BCM_E_UNAVAIL; 25884 25885 /* Make sure port module is initialized. */ 25886 PORT_INIT(unit); 25887 #ifdef BCM_XGS_SWITCH_SUPPORT 25888 25889 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 25890 PORT_SWITCHED_CHECK(unit, port); 25891 25892 PORT_LOCK(unit); 25893 #ifdef BCM_TRX_SUPPORT 25894 if (SOC_IS_TRX(unit)) { 25895 bcm_vlan_action_set_t action; 25896 25897 if (!soc_feature(unit, soc_feature_vlan_action)) { 25898 PORT_UNLOCK(unit); 25899 return BCM_E_UNAVAIL; 25900 } 25901 25902 bcm_vlan_action_set_t_init(&action); 25903 action.new_outer_vlan = vid; 25904 action.new_inner_vlan = 0; 25905 action.priority = PORT(unit, port).p_ut_prio; 25906 action.ut_outer = bcmVlanActionAdd; 25907 action.it_outer = bcmVlanActionAdd; 25908 action.it_inner = bcmVlanActionDelete; 25909 action.it_inner_prio = bcmVlanActionNone; 25910 action.ot_outer_prio = bcmVlanActionReplace; 25911 action.dt_outer_prio = bcmVlanActionReplace; 25912 25913 rv = _bcm_trx_vlan_port_protocol_action_add(unit, port, frame, 25914 ether, &action); 25915 PORT_UNLOCK(unit); 25916 return rv; 25917 } 25918 #endif /* BCM_TRX_SUPPORT */ 25919 25920 #if defined(BCM_FIREBOLT_SUPPORT) 25921 if (SOC_IS_FBX(unit)) { 25922 rv = _bcm_fb_port_protocol_vlan_add(unit, port, frame, ether, vid); 25923 PORT_UNLOCK(unit); 25924 return rv; 25925 } 25926 #endif /* BCM_FIREBOLT_SUPPORT */ 25927 PORT_UNLOCK(unit); 25928 #endif /* BCM_XGS_SWITCH_SUPPORT */ 25929 /* not supported on STRATA and HERCULES */ 25930 return rv; 25931 } 25932 25933 /* 25934 * Function: 25935 * bcm_port_protocol_vlan_delete 25936 * Purpose: 25937 * Remove an already created proto protocol based vlan 25938 * on a port. 25939 * Parameters: 25940 * unit - StrataSwitch unit # 25941 * port - StrataSwitch port # 25942 * frame - one of BCM_PORT_FRAMETYPE_{ETHER2,8023,LLC} 25943 * ether - 16 bit Ethernet type field 25944 * Returns: 25945 * BCM_E_XXX 25946 */ 25947 25948 int 25949 bcm_esw_port_protocol_vlan_delete(int unit, 25950 bcm_port_t port, 25951 bcm_port_frametype_t frame, 25952 bcm_port_ethertype_t ether) 25953 { 25954 int rv = BCM_E_UNAVAIL; 25955 /* Make sure port module is initialized. */ 25956 PORT_INIT(unit); 25957 #ifdef BCM_XGS_SWITCH_SUPPORT 25958 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 25959 PORT_SWITCHED_CHECK(unit, port); 25960 25961 PORT_LOCK(unit); 25962 25963 #ifdef BCM_TRX_SUPPORT 25964 if (SOC_IS_TRX(unit)) { 25965 if (!soc_feature(unit, soc_feature_vlan_action)) { 25966 PORT_UNLOCK(unit); 25967 return BCM_E_UNAVAIL; 25968 } 25969 rv = _bcm_trx_vlan_port_protocol_delete(unit, port, frame, ether); 25970 PORT_UNLOCK(unit); 25971 return rv; 25972 } 25973 #endif /* BCM_TRX_SUPPORT */ 25974 25975 #if defined(BCM_FIREBOLT_SUPPORT) 25976 if (SOC_IS_FBX(unit)) { 25977 rv = _bcm_fb_port_protocol_vlan_delete(unit, port, frame, ether); 25978 PORT_UNLOCK(unit); 25979 return rv; 25980 25981 } 25982 #endif /* BCM_FIREBOLT_SUPPORT */ 25983 25984 PORT_UNLOCK(unit); 25985 #endif /* BCM_XGS_SWITCH_SUPPORT */ 25986 /* not supported on STRATA and HERCULES */ 25987 return rv; 25988 } 25989 25990 /* 25991 * Function: 25992 * bcm_port_protocol_vlan_delete_all 25993 * Purpose: 25994 * Remove all protocol based vlans on a port. 25995 * Parameters: 25996 * unit - StrataSwitch unit # 25997 * port - StrataSwitch port # 25998 * Returns: 25999 * BCM_E_XXX 26000 */ 26001 26002 int 26003 bcm_esw_port_protocol_vlan_delete_all(int unit, bcm_port_t port) 26004 { 26005 #ifdef BCM_XGS_SWITCH_SUPPORT 26006 int i; 26007 26008 /* Make sure port module is initialized. */ 26009 PORT_INIT(unit); 26010 26011 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 26012 PORT_SWITCHED_CHECK(unit, port); 26013 26014 #ifdef BCM_TRX_SUPPORT 26015 if (SOC_IS_TRX(unit)) { 26016 int rv; 26017 if (!soc_feature(unit, soc_feature_vlan_action)) { 26018 return BCM_E_UNAVAIL; 26019 } 26020 PORT_LOCK(unit); 26021 rv = _bcm_trx_vlan_port_protocol_delete_all(unit, port); 26022 PORT_UNLOCK(unit); 26023 return rv; 26024 } 26025 #endif /* BCM_TRX_SUPPORT */ 26026 26027 #if defined(BCM_FIREBOLT_SUPPORT) 26028 if (SOC_IS_FBX(unit)) { 26029 vlan_protocol_entry_t vpe; 26030 vlan_protocol_data_entry_t vde; 26031 bcm_vlan_t cvid, defvid; 26032 int idxmin, idxmax; 26033 int vlan_prot_entries; 26034 int vdentry, p, valid; 26035 _bcm_port_info_t *pinfo; 26036 bcm_pbmp_t switched_pbm; 26037 26038 idxmin = soc_mem_index_min(unit, VLAN_PROTOCOLm); 26039 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm); 26040 vlan_prot_entries = idxmax + 1; 26041 26042 for (i = idxmin; i <= idxmax; i++) { 26043 vdentry = (port * vlan_prot_entries) + i; 26044 SOC_IF_ERROR_RETURN 26045 (READ_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ANY, 26046 vdentry, &vde)); 26047 cvid = soc_VLAN_PROTOCOL_DATAm_field32_get(unit, &vde, VLAN_IDf); 26048 BCM_IF_ERROR_RETURN 26049 (bcm_esw_port_untagged_vlan_get(unit, port, &defvid)); 26050 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, port, &pinfo)); 26051 if (cvid == 0 || 26052 (cvid == defvid && (!_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)))) { 26053 continue; 26054 } 26055 sal_memset(&vde, 0, sizeof(vde)); 26056 soc_VLAN_PROTOCOL_DATAm_field32_set(unit, &vde, VLAN_IDf, defvid); 26057 SOC_IF_ERROR_RETURN 26058 (WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL, vdentry, &vde)); 26059 _BCM_PORT_VD_PBVL_CLEAR(pinfo, i); 26060 /* 26061 * see if any vlan_protocol_data entries are still valid 26062 * for the current protocol. 26063 */ 26064 valid = 0; 26065 switched_pbm = PBMP_E_ALL(unit); 26066 if (soc_feature(unit, soc_feature_cpuport_switched)) { 26067 BCM_PBMP_OR(switched_pbm, PBMP_CMIC(unit)); 26068 } 26069 26070 BCM_PBMP_ITER(switched_pbm, p) { 26071 if (p == port) { /* skip the entry we just "defaulted" */ 26072 continue; 26073 } 26074 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo)); 26075 /* entry valid if programmed VLAN ID for port */ 26076 if (_BCM_PORT_VD_PBVL_IS_SET(pinfo, i)) { 26077 valid = 1; 26078 break; 26079 } 26080 } 26081 if (!valid) { 26082 /* 26083 * Clear all VLAN_PROTOCOL_DATA entries associated 26084 * with this protocol. 26085 */ 26086 BCM_PBMP_ITER(switched_pbm, p) { 26087 vdentry = (p * vlan_prot_entries) + i; 26088 sal_memset(&vde, 0, sizeof(vde)); 26089 SOC_IF_ERROR_RETURN 26090 (WRITE_VLAN_PROTOCOL_DATAm(unit, MEM_BLOCK_ALL, 26091 vdentry, &vde)); 26092 BCM_IF_ERROR_RETURN(_bcm_port_info_get(unit, p, &pinfo)); 26093 _BCM_PORT_VD_PBVL_CLEAR(pinfo, i); 26094 } 26095 /* clear VLAN_PROTOCOL entry */ 26096 sal_memset(&vpe, 0, sizeof(vpe)); 26097 SOC_IF_ERROR_RETURN 26098 (WRITE_VLAN_PROTOCOLm(unit, MEM_BLOCK_ALL, i, &vpe)); 26099 } 26100 } 26101 return BCM_E_NONE; 26102 } 26103 #endif /* BCM_FIREBOLT_SUPPORT */ 26104 26105 #endif /* BCM_XGS_SWITCH_SUPPORT */ 26106 26107 /* not supported on STRATA and HERCULES */ 26108 26109 return BCM_E_UNAVAIL; 26110 } 26111 26112 /* 26113 * Differentiated Services Code Point Mapping 26114 */ 26115 26116 /* 26117 * Function: 26118 * bcm_esw_port_dscp_map_mode_set 26119 * Purpose: 26120 * Set DSCP mapping for the port. 26121 * Parameters: 26122 * unit - switch device 26123 * port - switch port or -1 to apply on all the ports. 26124 * mode - BCM_PORT_DSCP_MAP_NONE 26125 * - BCM_PORT_DSCP_MAP_ZERO Map if incomming DSCP = 0 26126 * - BCM_PORT_DSCP_MAP_ALL DSCP -> DSCP mapping. 26127 * Returns: 26128 * BCM_E_XXX 26129 */ 26130 static int 26131 _bcm_esw_port_dscp_map_mode_set(int unit, bcm_port_t port, int mode) 26132 { 26133 bcm_port_cfg_t pcfg; 26134 26135 BCM_IF_ERROR_RETURN 26136 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 26137 if (pcfg.pc_dse_mode == -1) { /* STRATA1 for example */ 26138 return BCM_E_UNAVAIL; 26139 } 26140 switch(mode) { 26141 case BCM_PORT_DSCP_MAP_NONE: 26142 pcfg.pc_dse_mode = 0; 26143 pcfg.pc_dse_mode_ipv6 = 0; 26144 #if defined(BCM_XGS_SWITCH_SUPPORT) 26145 pcfg.pc_dscp_prio = 0; 26146 #endif /* BCM_XGS_SWITCH_SUPPORT */ 26147 break; 26148 case BCM_PORT_DSCP_MAP_ZERO: 26149 if (soc_feature(unit, soc_feature_dscp_map_mode_all)) { 26150 return BCM_E_UNAVAIL; 26151 } 26152 pcfg.pc_dse_mode = 1; 26153 #if defined(BCM_XGS_SWITCH_SUPPORT) 26154 pcfg.pc_dscp_prio = 1; 26155 #endif /* BCM_XGS_SWITCH_SUPPORT */ 26156 break; 26157 case BCM_PORT_DSCP_MAP_ALL: 26158 if (soc_feature(unit, soc_feature_dscp_map_mode_all)) { 26159 pcfg.pc_dse_mode = 1; 26160 pcfg.pc_dse_mode_ipv6 = 1; 26161 } else { 26162 pcfg.pc_dse_mode = 2; 26163 } 26164 #if defined(BCM_XGS_SWITCH_SUPPORT) 26165 pcfg.pc_dscp_prio = 1; 26166 #endif /* BCM_XGS_SWITCH_SUPPORT */ 26167 break; 26168 case BCM_PORT_DSCP_MAP_IPV4_ONLY: 26169 if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) { 26170 return BCM_E_UNAVAIL; 26171 } 26172 pcfg.pc_dse_mode = 1; 26173 #if defined(BCM_XGS_SWITCH_SUPPORT) 26174 pcfg.pc_dscp_prio = 1; 26175 #endif /* BCM_XGS_SWITCH_SUPPORT */ 26176 break; 26177 case BCM_PORT_DSCP_MAP_IPV6_ONLY: 26178 if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) { 26179 return BCM_E_UNAVAIL; 26180 } 26181 pcfg.pc_dse_mode_ipv6 = 1; 26182 #if defined(BCM_XGS_SWITCH_SUPPORT) 26183 pcfg.pc_dscp_prio = 1; 26184 #endif /* BCM_XGS_SWITCH_SUPPORT */ 26185 break; 26186 case BCM_PORT_DSCP_MAP_IPV4_NONE: 26187 if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) { 26188 return BCM_E_UNAVAIL; 26189 } 26190 pcfg.pc_dse_mode = 0; 26191 #if defined(BCM_XGS_SWITCH_SUPPORT) 26192 if (!pcfg.pc_dse_mode_ipv6) { 26193 pcfg.pc_dscp_prio = 0; 26194 } 26195 #endif /* BCM_XGS_SWITCH_SUPPORT */ 26196 break; 26197 case BCM_PORT_DSCP_MAP_IPV6_NONE: 26198 if (!soc_feature(unit, soc_feature_dscp_map_mode_all)) { 26199 return BCM_E_UNAVAIL; 26200 } 26201 pcfg.pc_dse_mode_ipv6 = 0; 26202 #if defined(BCM_XGS_SWITCH_SUPPORT) 26203 if (!pcfg.pc_dse_mode) { 26204 pcfg.pc_dscp_prio = 0; 26205 } 26206 #endif /* BCM_XGS_SWITCH_SUPPORT */ 26207 break; 26208 default: 26209 return BCM_E_PARAM; 26210 } 26211 BCM_IF_ERROR_RETURN 26212 (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 26213 26214 return BCM_E_NONE; 26215 } 26216 26217 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 26218 static int 26219 _bcm_esw_vp_dscp_map_mode_set(int unit, bcm_gport_t port, int mode) { 26220 if (SOC_IS_KATANAX(unit) || 26221 SOC_IS_TD_TT(unit)|| 26222 soc_feature(unit, soc_feature_vp_dscp_map)) { 26223 return _bcm_tr2_vp_dscp_map_mode_set(unit, port, mode); 26224 } 26225 return BCM_E_UNAVAIL; 26226 } 26227 26228 STATIC int 26229 _bcm_esw_vp_dscp_map_set(int unit, bcm_gport_t port, int srccp, int mapcp, 26230 int prio) 26231 { 26232 if (SOC_IS_TD_TT(unit) || soc_feature(unit, soc_feature_vp_dscp_map)) { 26233 return _bcm_tr2_vp_dscp_map_set(unit, port, srccp, mapcp, prio); 26234 } 26235 return BCM_E_UNAVAIL; 26236 } 26237 #endif 26238 26239 int 26240 bcm_esw_port_dscp_map_mode_set(int unit, bcm_port_t port, int mode) 26241 { 26242 int rv; 26243 bcm_port_config_t port_conf; 26244 bcm_pbmp_t pbmp; 26245 26246 /* Make sure port module is initialized. */ 26247 PORT_INIT(unit); 26248 26249 if (!soc_feature(unit, soc_feature_dscp)) { 26250 return BCM_E_UNAVAIL; 26251 } 26252 26253 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 26254 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 26255 !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) { 26256 return _bcm_esw_vp_dscp_map_mode_set(unit, port, mode); 26257 } 26258 #endif 26259 26260 if (port != -1) { 26261 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 26262 } 26263 26264 PORT_LOCK(unit); 26265 26266 /* Get device port configuration. */ 26267 rv = bcm_esw_port_config_get(unit, &port_conf); 26268 if (BCM_FAILURE(rv)) { 26269 PORT_UNLOCK(unit); 26270 return rv; 26271 } 26272 BCM_PBMP_ASSIGN(pbmp, port_conf.e); 26273 if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) { 26274 BCM_PBMP_OR(pbmp, port_conf.cpu); 26275 } 26276 #ifdef BCM_KATANA2_SUPPORT 26277 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 26278 rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp); 26279 if (BCM_FAILURE(rv)) { 26280 PORT_UNLOCK(unit); 26281 return (rv); 26282 } 26283 } 26284 if (soc_feature(unit, soc_feature_linkphy_coe) || 26285 soc_feature(unit, soc_feature_subtag_coe)) { 26286 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 26287 } 26288 #endif 26289 26290 if (port == -1) { 26291 PBMP_ITER(pbmp, port) { 26292 rv = _bcm_esw_port_dscp_map_mode_set(unit, port, mode); 26293 if (BCM_FAILURE(rv)) { 26294 PORT_UNLOCK(unit); 26295 return rv; 26296 } 26297 } 26298 } else { 26299 if (BCM_PBMP_MEMBER(pbmp, port)) { 26300 rv = _bcm_esw_port_dscp_map_mode_set(unit, port, mode); 26301 } else { 26302 rv = BCM_E_PORT; 26303 } 26304 } 26305 PORT_UNLOCK(unit); 26306 return rv; 26307 } 26308 26309 /* 26310 * Function: 26311 * bcm_esw_port_dscp_map_mode_get 26312 * Purpose: 26313 * DSCP mapping status for the port. 26314 * Parameters: 26315 * unit - switch device 26316 * port - switch port or -1 to get mode from first available port 26317 * mode - (OUT) 26318 * - BCM_PORT_DSCP_MAP_NONE 26319 * - BCM_PORT_DSCP_MAP_ZERO Map if incomming DSCP = 0 26320 * - BCM_PORT_DSCP_MAP_ALL DSCP -> DSCP mapping. 26321 * Returns: 26322 * BCM_E_XXX 26323 */ 26324 26325 static int 26326 _bcm_esw_port_dscp_map_mode_get(int unit, bcm_port_t port, int *mode) 26327 { 26328 bcm_port_cfg_t pcfg; 26329 26330 BCM_IF_ERROR_RETURN 26331 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 26332 if (pcfg.pc_dse_mode == -1) { /* STRATA1 for example */ 26333 return BCM_E_UNAVAIL; 26334 } 26335 switch(pcfg.pc_dse_mode) { 26336 case 1: 26337 if (soc_feature(unit, soc_feature_dscp_map_mode_all)) { 26338 if (pcfg.pc_dse_mode_ipv6) { 26339 *mode = BCM_PORT_DSCP_MAP_ALL; 26340 } else { 26341 *mode = BCM_PORT_DSCP_MAP_IPV4_ONLY; 26342 } 26343 } else { 26344 *mode = BCM_PORT_DSCP_MAP_ZERO; 26345 } 26346 break; 26347 case 2: 26348 if (soc_feature(unit, soc_feature_dscp_map_mode_all)) { 26349 if (pcfg.pc_dse_mode_ipv6) { 26350 *mode = BCM_PORT_DSCP_MAP_ALL; 26351 } else { 26352 *mode = BCM_PORT_DSCP_MAP_IPV4_ONLY; 26353 } 26354 } else { 26355 *mode = BCM_PORT_DSCP_MAP_ALL; 26356 } 26357 break; 26358 case 0: 26359 if (pcfg.pc_dse_mode_ipv6) { 26360 *mode = BCM_PORT_DSCP_MAP_IPV6_ONLY; 26361 } else { 26362 *mode = BCM_PORT_DSCP_MAP_NONE; 26363 } 26364 break; 26365 26366 default: 26367 *mode = BCM_PORT_DSCP_MAP_NONE; 26368 break; 26369 } 26370 26371 return BCM_E_NONE; 26372 } 26373 26374 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 26375 static int 26376 _bcm_esw_vp_dscp_map_mode_get(int unit, bcm_gport_t port, int *mode) { 26377 if (SOC_IS_KATANAX(unit) || 26378 SOC_IS_TD_TT(unit) || 26379 soc_feature(unit, soc_feature_vp_dscp_map)) { 26380 return _bcm_tr2_vp_dscp_map_mode_get(unit, port, mode); 26381 } 26382 return BCM_E_UNAVAIL; 26383 } 26384 26385 STATIC int 26386 _bcm_esw_vp_dscp_map_get(int unit, bcm_gport_t port, int srccp, int *mapcp, 26387 int *prio) 26388 { 26389 if (SOC_IS_TD_TT(unit) || soc_feature(unit, soc_feature_vp_dscp_map)) { 26390 return _bcm_tr2_vp_dscp_map_get(unit, port, srccp, mapcp, prio); 26391 } 26392 return BCM_E_UNAVAIL; 26393 } 26394 #endif 26395 26396 int 26397 bcm_esw_port_dscp_map_mode_get(int unit, bcm_port_t port, int *mode) 26398 { 26399 int rv; 26400 bcm_port_config_t port_conf; 26401 bcm_pbmp_t pbmp; 26402 26403 /* Make sure port module is initialized. */ 26404 PORT_INIT(unit); 26405 26406 if (!soc_feature(unit, soc_feature_dscp)) { 26407 return BCM_E_UNAVAIL; 26408 } 26409 26410 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 26411 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 26412 !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) { 26413 return _bcm_esw_vp_dscp_map_mode_get(unit, port, mode); 26414 } 26415 #endif 26416 26417 if (port != -1) { 26418 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 26419 } 26420 26421 PORT_LOCK(unit); 26422 26423 /* Get device port configuration. */ 26424 rv = bcm_esw_port_config_get(unit, &port_conf); 26425 if (BCM_FAILURE(rv)) { 26426 PORT_UNLOCK(unit); 26427 return rv; 26428 } 26429 BCM_PBMP_ASSIGN(pbmp, port_conf.e); 26430 if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) { 26431 BCM_PBMP_OR(pbmp, port_conf.cpu); 26432 } 26433 #ifdef BCM_KATANA2_SUPPORT 26434 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 26435 rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp); 26436 if (BCM_FAILURE(rv)) { 26437 PORT_UNLOCK(unit); 26438 return (rv); 26439 } 26440 } 26441 if (soc_feature(unit, soc_feature_linkphy_coe) || 26442 soc_feature(unit, soc_feature_subtag_coe)) { 26443 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 26444 } 26445 #endif 26446 26447 if (port == -1) { 26448 PBMP_ITER(pbmp, port) { 26449 break; 26450 } 26451 } 26452 26453 /* coverity[overrun-local : FALSE] */ 26454 if (BCM_PBMP_MEMBER(pbmp, port)) { 26455 rv = _bcm_esw_port_dscp_map_mode_get(unit, port, mode); 26456 } else { 26457 rv = BCM_E_PORT; 26458 } 26459 PORT_UNLOCK(unit); 26460 return rv; 26461 } 26462 26463 /* 26464 * Function: 26465 * _bcm_port_dscp_map_set 26466 * Purpose: 26467 * Internal implementation for bcm_port_dscp_map_set 26468 * Parameters: 26469 * unit - switch device 26470 * port - switch port or -1 for global table 26471 * srccp - src code point or -1 26472 * mapcp - mapped code point or -1 26473 * prio - priority value for mapped code point 26474 * -1 to use port default untagged priority 26475 * BCM_PRIO_RED can be or'ed into the priority 26476 * BCM_PRIO_YELLOW can be or'ed into the priority 26477 * Returns: 26478 * BCM_E_XXX 26479 */ 26480 26481 STATIC int 26482 _bcm_port_dscp_map_set(int unit, bcm_port_t port, 26483 int srccp, int mapcp, int prio) 26484 { 26485 #define DSCP_CODE_POINT_CNT 64 26486 #define DSCP_CODE_POINT_MAX (DSCP_CODE_POINT_CNT - 1) 26487 bcm_port_cfg_t pcfg; 26488 26489 if (mapcp < -1 || mapcp > DSCP_CODE_POINT_MAX) { 26490 return BCM_E_PARAM; 26491 } 26492 26493 #if defined(BCM_XGS3_SWITCH_SUPPORT) 26494 if (SOC_IS_XGS3_SWITCH(unit)) { 26495 int i, cng; 26496 dscp_table_entry_t de; 26497 phb_mapping_tbl_2_entry_t phb_tbl_2; 26498 int max_index; 26499 int min_index; 26500 int field_len; 26501 26502 if (SOC_IS_TRIDENT3X(unit)) { 26503 field_len = soc_mem_field_length(unit, PHB_MAPPING_TBL_2m, INT_PRIf); 26504 } else { 26505 field_len = soc_mem_field_length(unit, DSCP_TABLEm, PRIf); 26506 } 26507 26508 if (srccp < -1 || srccp > DSCP_CODE_POINT_MAX) { 26509 return BCM_E_PARAM; 26510 } 26511 /* Extract cng bits and check for valid priority. */ 26512 26513 cng = 0; /* Green */ 26514 if (prio < BCM_PRIO_MIN) { 26515 return BCM_E_PARAM; 26516 } 26517 if (prio & BCM_PRIO_RED) { 26518 cng = 0x01; /* Red */ 26519 prio &= ~BCM_PRIO_RED; 26520 } else if (prio & BCM_PRIO_YELLOW) { 26521 cng = 0x03; /* Yellow */ 26522 prio &= ~BCM_PRIO_YELLOW; 26523 } 26524 if ((prio & ~BCM_PRIO_MASK) != 0) { 26525 return BCM_E_PARAM; 26526 } 26527 if (prio >= (1 << field_len)) { 26528 return BCM_E_PARAM; 26529 } 26530 if (srccp < 0 && mapcp < 0) { 26531 /* No mapping */ 26532 return BCM_E_NONE; 26533 } else if (srccp < 0) { 26534 /* Map all DSCPs to a new DSCP */ 26535 /* fill all entries in DSCP_TABLEm with mapcp */ 26536 26537 #ifdef BCM_TRIDENT2_SUPPORT 26538 if (SOC_IS_TD2_TT2(unit)) { 26539 return (bcm_td2_port_dscp_map_set(unit, 26540 port, srccp, mapcp, prio, cng)); 26541 } 26542 #endif 26543 #ifdef BCM_KATANA2_SUPPORT 26544 if (SOC_IS_KATANA2(unit)) { 26545 return (bcm_kt2_port_dscp_map_set(unit, port, 26546 srccp, mapcp, prio, cng)); 26547 } 26548 #endif 26549 26550 if (SOC_IS_TRIDENT3X(unit)) { 26551 sal_memset(&phb_tbl_2, 0, sizeof(phb_tbl_2)); 26552 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, DSCPf, mapcp); 26553 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, INT_PRIf, prio); 26554 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, CNGf, cng); 26555 } else { 26556 sal_memset(&de, 0, sizeof(de)); 26557 soc_DSCP_TABLEm_field32_set(unit, &de, DSCPf, mapcp); 26558 soc_DSCP_TABLEm_field32_set(unit, &de, PRIf, prio); 26559 soc_DSCP_TABLEm_field32_set(unit, &de, CNGf, cng); 26560 } 26561 if (soc_feature(unit, soc_feature_dscp_map_per_port)) { 26562 min_index = port * DSCP_CODE_POINT_CNT; 26563 max_index = min_index + DSCP_CODE_POINT_MAX; 26564 } else { 26565 if (SOC_IS_TRIDENT3X(unit)) { 26566 max_index = soc_mem_index_max(unit, PHB_MAPPING_TBL_2m); 26567 } else { 26568 max_index = soc_mem_index_max(unit, DSCP_TABLEm); 26569 } 26570 min_index = 0; 26571 } 26572 26573 for (i = min_index; i <= max_index; i++) { 26574 if (SOC_IS_TRIDENT3X(unit)) { 26575 SOC_IF_ERROR_RETURN 26576 (WRITE_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ALL, i, &phb_tbl_2)); 26577 } else { 26578 SOC_IF_ERROR_RETURN 26579 (WRITE_DSCP_TABLEm(unit, MEM_BLOCK_ALL, i, &de)); 26580 } 26581 } 26582 } else { 26583 int num_cosq; 26584 26585 #ifdef BCM_TRIDENT2_SUPPORT 26586 if (SOC_IS_TD2_TT2(unit)) { 26587 return (bcm_td2_port_dscp_map_set(unit, port, 26588 srccp, mapcp, prio, cng)); 26589 } 26590 #endif 26591 #ifdef BCM_KATANA2_SUPPORT 26592 if (SOC_IS_KATANA2(unit)) { 26593 return (bcm_kt2_port_dscp_map_set(unit, port, 26594 srccp, mapcp, prio, cng)); 26595 } 26596 #endif 26597 26598 num_cosq = 1; /* For all cosqs */ 26599 /* Map a specific DSCP to a new DSCP */ 26600 sal_memset(&de, 0, sizeof(de)); 26601 /* fill specific srccp entry/entries in DSCP_TABLEm with mapcp */ 26602 if (SOC_IS_TRIDENT3X(unit)) { 26603 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, DSCPf, mapcp); 26604 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, INT_PRIf, prio); 26605 soc_PHB_MAPPING_TBL_2m_field32_set(unit, &phb_tbl_2, CNGf, cng); 26606 } else { 26607 soc_DSCP_TABLEm_field32_set(unit, &de, DSCPf, mapcp); 26608 soc_DSCP_TABLEm_field32_set(unit, &de, PRIf, prio); 26609 soc_DSCP_TABLEm_field32_set(unit, &de, CNGf, cng); 26610 } 26611 26612 if (soc_feature(unit, soc_feature_dscp_map_per_port)) { 26613 if (SOC_IS_TRIDENT3X(unit)) { 26614 SOC_IF_ERROR_RETURN 26615 (WRITE_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ALL, 26616 (port * DSCP_CODE_POINT_CNT) + srccp, &phb_tbl_2)); 26617 } else { 26618 SOC_IF_ERROR_RETURN 26619 (WRITE_DSCP_TABLEm(unit, MEM_BLOCK_ALL, 26620 (port * DSCP_CODE_POINT_CNT) + srccp, &de)); 26621 } 26622 26623 } else { 26624 for (i = 0; i < num_cosq ; i++) { 26625 if (SOC_IS_TRIDENT3X(unit)) { 26626 SOC_IF_ERROR_RETURN 26627 (WRITE_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ALL, 26628 (i * DSCP_CODE_POINT_CNT) + srccp, &phb_tbl_2)); 26629 } else { 26630 SOC_IF_ERROR_RETURN 26631 (WRITE_DSCP_TABLEm(unit, MEM_BLOCK_ALL, 26632 (i * DSCP_CODE_POINT_CNT) + srccp, &de)); 26633 } 26634 } 26635 } 26636 } 26637 return BCM_E_NONE; 26638 } 26639 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 26640 26641 /* all other switches */ 26642 if (srccp < -1 || srccp > 0) { 26643 return BCM_E_PARAM; 26644 } 26645 26646 pcfg.pc_dse_mode = -1; 26647 BCM_IF_ERROR_RETURN 26648 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 26649 if (pcfg.pc_dse_mode == -1) { /* STRATA1 for example */ 26650 return BCM_E_UNAVAIL; 26651 } 26652 26653 if (mapcp >= 0) { 26654 pcfg.pc_dscp = mapcp; 26655 26656 BCM_IF_ERROR_RETURN 26657 (mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &pcfg)); 26658 } 26659 26660 return BCM_E_NONE; 26661 } 26662 26663 /* 26664 * Function: 26665 * bcm_port_dscp_map_set 26666 * Purpose: 26667 * Define a mapping for diffserv code points 26668 * The mapping enable/disable is controlled by a seperate API 26669 * bcm_port_dscp_map_enable_set/get 26670 * Also Enable/Disable control for DSCP mapping for tunnels 26671 * are available in the respective tunnel create APIs. 26672 * Parameters: 26673 * unit - switch device 26674 * port - switch port or -1 to setup global mapping table. 26675 * srccp - src code point or -1 26676 * mapcp - mapped code point or -1 26677 * prio - priority value for mapped code point 26678 * -1 to use port default untagged priority 26679 * BCM_PRIO_DROP_FIRST can be or'ed into the priority 26680 * Returns: 26681 * BCM_E_XXX 26682 * Notes: 26683 * On most xgs switches there are a limited set 26684 * of mappings that are possible: 26685 * srccp -1, mapcp -1: no mapping 26686 * srccp -1, mapcp 0..63: map all packets 26687 * srccp 0, mapcp 0..63: map packets with cp 0 26688 * On Firebolt/Helix/Felix, there is no per port mapping table. 26689 * Only a global mapping table is available. 26690 */ 26691 26692 int 26693 bcm_esw_port_dscp_map_set(int unit, bcm_port_t port, int srccp, int mapcp, 26694 int prio) 26695 { 26696 int rv; 26697 bcm_port_config_t port_conf; 26698 bcm_pbmp_t pbmp; 26699 26700 /* Make sure port module is initialized. */ 26701 PORT_INIT(unit); 26702 26703 if (!soc_feature(unit, soc_feature_dscp)) { 26704 return BCM_E_UNAVAIL; 26705 } 26706 26707 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 26708 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 26709 !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) { 26710 return _bcm_esw_vp_dscp_map_set(unit, port, srccp, mapcp, prio); 26711 } 26712 #endif 26713 26714 if (port != -1) { 26715 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 26716 if (!soc_feature(unit, soc_feature_dscp_map_per_port)) { 26717 return BCM_E_PORT; 26718 } 26719 } 26720 26721 PORT_LOCK(unit); 26722 26723 /* Get device port configuration. */ 26724 rv = bcm_esw_port_config_get(unit, &port_conf); 26725 if (BCM_FAILURE(rv)) { 26726 PORT_UNLOCK(unit); 26727 return rv; 26728 } 26729 BCM_PBMP_ASSIGN(pbmp, port_conf.e); 26730 if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) { 26731 BCM_PBMP_OR(pbmp, port_conf.cpu); 26732 } 26733 #ifdef BCM_KATANA2_SUPPORT 26734 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 26735 rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp); 26736 if (BCM_FAILURE(rv)) { 26737 PORT_UNLOCK(unit); 26738 return (rv); 26739 } 26740 } 26741 if (soc_feature(unit, soc_feature_linkphy_coe) || 26742 soc_feature(unit, soc_feature_subtag_coe)) { 26743 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 26744 } 26745 #endif 26746 26747 if ((port == -1) && (soc_feature(unit, soc_feature_dscp_map_per_port))) { 26748 PBMP_ITER(pbmp, port) { 26749 /* coverity[stack_use_callee] */ 26750 /* coverity[stack_use_overflow] */ 26751 rv = _bcm_port_dscp_map_set(unit, port, srccp, mapcp, prio); 26752 if (BCM_FAILURE(rv)) { 26753 PORT_UNLOCK(unit); 26754 return rv; 26755 } 26756 } 26757 } else { 26758 if (BCM_PBMP_MEMBER(pbmp, port) || (port == -1)) { 26759 rv = _bcm_port_dscp_map_set(unit, port, srccp, mapcp, prio); 26760 } else { 26761 rv = BCM_E_PORT; 26762 } 26763 } 26764 PORT_UNLOCK(unit); 26765 26766 return rv; 26767 } 26768 26769 /* 26770 * Function: 26771 * _bcm_port_dscp_map_get 26772 * Purpose: 26773 * Get a mapping for diffserv code points 26774 * Parameters: 26775 * unit - switch device 26776 * port - switch port 26777 * srccp - src code point or -1 26778 * mapcp - (OUT) pointer to returned mapped code point 26779 * prio - (OUT) Priority value for mapped code point or -1 26780 * May have BCM_PRIO_DROP_FIRST or'ed into it 26781 * Returns: 26782 * BCM_E_XXX 26783 */ 26784 26785 STATIC int 26786 _bcm_esw_port_dscp_map_get(int unit, bcm_port_t port, int srccp, int *mapcp, 26787 int *prio) 26788 { 26789 bcm_port_cfg_t pcfg; 26790 port_tab_entry_t pent; 26791 #if defined(BCM_XGS3_SWITCH_SUPPORT) 26792 int index = 0; 26793 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 26794 int rv = BCM_E_NONE; 26795 26796 if (SOC_IS_TRIDENT3X(unit)) { 26797 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, port, 26798 TRUST_DSCP_PTRf, &index)); 26799 } else if (SOC_IS_TD2_TT2(unit) || SOC_IS_KATANA2(unit)) { 26800 /* Get profile index from port table. */ 26801 rv = soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, 26802 port, &pent); 26803 if (BCM_FAILURE(rv)) { 26804 return rv; 26805 } 26806 26807 #if defined(BCM_XGS3_SWITCH_SUPPORT) 26808 index = soc_mem_field32_get(unit, PORT_TABm, &pent, TRUST_DSCP_PTRf); 26809 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 26810 } 26811 26812 if (srccp < -1 || srccp > DSCP_CODE_POINT_MAX || 26813 mapcp == NULL || prio == NULL) { 26814 return BCM_E_PARAM; 26815 } 26816 26817 #if defined(BCM_XGS3_SWITCH_SUPPORT) 26818 if (SOC_IS_XGS3_SWITCH(unit)) { 26819 int base; 26820 int cng; 26821 dscp_table_entry_t de; 26822 phb_mapping_tbl_2_entry_t phb_tbl_2; 26823 26824 /* look up in DSCP_TABLEm */ 26825 if (srccp < 0) { 26826 srccp = 0; 26827 } 26828 if (soc_feature(unit, soc_feature_dscp_map_per_port)) { 26829 base = (port * DSCP_CODE_POINT_CNT); 26830 26831 if (SOC_IS_TD2_TT2(unit) || SOC_IS_KATANA2(unit)) { 26832 base = (index * DSCP_CODE_POINT_CNT); 26833 } 26834 } else { 26835 base = 0; 26836 } 26837 26838 if (SOC_IS_TRIDENT3X(unit)) { 26839 SOC_IF_ERROR_RETURN 26840 (READ_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ANY, base + srccp, &phb_tbl_2)); 26841 *mapcp = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &phb_tbl_2, DSCPf); 26842 *prio = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &phb_tbl_2, INT_PRIf); 26843 26844 cng = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &phb_tbl_2, CNGf); 26845 } else { 26846 SOC_IF_ERROR_RETURN 26847 (READ_DSCP_TABLEm(unit, MEM_BLOCK_ANY, base + srccp, &de)); 26848 *mapcp = soc_DSCP_TABLEm_field32_get(unit, &de, DSCPf); 26849 *prio = soc_DSCP_TABLEm_field32_get(unit, &de, PRIf); 26850 26851 cng = soc_DSCP_TABLEm_field32_get(unit, &de, CNGf); 26852 } 26853 if (cng == 1) { 26854 *prio |= BCM_PRIO_RED; 26855 } else if (cng == 3) { 26856 *prio |= BCM_PRIO_YELLOW; 26857 } else if (cng != 0) { 26858 *prio |= BCM_PRIO_DROP_FIRST; 26859 } 26860 26861 return BCM_E_NONE; 26862 } 26863 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 26864 26865 /* all other switches */ 26866 26867 pcfg.pc_dse_mode = -1; 26868 BCM_IF_ERROR_RETURN 26869 (mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &pcfg)); 26870 if (pcfg.pc_dse_mode == -1) { /* STRATA1 for example */ 26871 return BCM_E_UNAVAIL; 26872 } 26873 26874 /* 26875 * The mapping table is set independently of the mapping mode. 26876 * So the _get API will return the mapping table setup and not 26877 * necessarily the actual mapping that will be applied to the packet. 26878 * The mapping applied to the packet is determined by mapping mode 26879 * set using bcm_port_dscp_map_mode_set 26880 */ 26881 *mapcp = pcfg.pc_dscp; 26882 26883 *prio = -1; 26884 26885 return BCM_E_NONE; 26886 } 26887 26888 /* 26889 * Function: 26890 * bcm_port_dscp_map_get 26891 * Purpose: 26892 * Get a mapping for diffserv code points 26893 * Parameters: 26894 * unit - switch device 26895 * port - switch port 26896 * srccp - src code point or -1 26897 * mapcp - (OUT) pointer to returned mapped code point 26898 * prio - (OUT) Priority value for mapped code point or -1 26899 * May have BCM_PRIO_DROP_FIRST or'ed into it 26900 * Returns: 26901 * BCM_E_XXX 26902 */ 26903 26904 int 26905 bcm_esw_port_dscp_map_get(int unit, bcm_port_t port, int srccp, int *mapcp, 26906 int *prio) 26907 { 26908 int rv; 26909 bcm_port_config_t port_conf; 26910 bcm_pbmp_t pbmp; 26911 26912 /* Make sure port module is initialized. */ 26913 PORT_INIT(unit); 26914 26915 if (!soc_feature(unit, soc_feature_dscp)) { 26916 return BCM_E_UNAVAIL; 26917 } 26918 26919 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 26920 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 26921 !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) { 26922 return _bcm_esw_vp_dscp_map_get(unit, port, srccp, mapcp, prio); 26923 } 26924 #endif 26925 26926 if (port != -1) { 26927 if (0 == soc_feature(unit, soc_feature_dscp_map_per_port)) { 26928 return BCM_E_PORT; 26929 } 26930 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 26931 } 26932 26933 PORT_LOCK(unit); 26934 26935 /* Get device port configuration. */ 26936 rv = bcm_esw_port_config_get(unit, &port_conf); 26937 if (BCM_FAILURE(rv)) { 26938 PORT_UNLOCK(unit); 26939 return rv; 26940 } 26941 BCM_PBMP_ASSIGN(pbmp, port_conf.e); 26942 if (SOC_IS_XGS3_SWITCH(unit) || SOC_IS_XGS3_FABRIC(unit)) { 26943 BCM_PBMP_OR(pbmp, port_conf.cpu); 26944 } 26945 #ifdef BCM_KATANA2_SUPPORT 26946 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 26947 rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp); 26948 if (BCM_FAILURE(rv)) { 26949 PORT_UNLOCK(unit); 26950 return (rv); 26951 } 26952 } 26953 if (soc_feature(unit, soc_feature_linkphy_coe) || 26954 soc_feature(unit, soc_feature_subtag_coe)) { 26955 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 26956 } 26957 #endif 26958 26959 if (port == -1) { 26960 PBMP_ITER(pbmp, port) { 26961 break; 26962 } 26963 } 26964 26965 if (SOC_PORT_VALID(unit, port) && BCM_PBMP_MEMBER(pbmp, port)) { 26966 rv = _bcm_esw_port_dscp_map_get(unit, port, srccp, mapcp, prio); 26967 } else { 26968 rv = BCM_E_PORT; 26969 } 26970 26971 PORT_UNLOCK(unit); 26972 return rv; 26973 } 26974 26975 #ifdef BCM_TRIDENT_SUPPORT 26976 STATIC int 26977 _bcm_td_egr_l3_intf_dscp_map_update(int unit, uint32 dscp_map_id, uint32 new_dscp_map_id) 26978 { 26979 char *egr_intf_tbl_ptr = NULL; /* EGR_L3_INTF dma table pointer. */ 26980 int rv; 26981 uint32 *egr_intf_entry_ptr; /* EGR_L3_INTF entry pointer. */ 26982 int ifindex; 26983 uint32 dscp_map_ptr; 26984 int tbl_size; 26985 int alloc_size; 26986 26987 if (dscp_map_id == new_dscp_map_id) { 26988 return BCM_E_NONE; 26989 } 26990 26991 /* Calculate table size. */ 26992 tbl_size = soc_mem_index_count(unit, EGR_L3_INTFm); 26993 if (!tbl_size) { 26994 return (BCM_E_NOT_FOUND); 26995 } 26996 alloc_size = sizeof(egr_l3_intf_entry_t) * tbl_size; 26997 26998 /* Allocate memory buffer. */ 26999 egr_intf_tbl_ptr = soc_cm_salloc(unit, alloc_size, "egr_l3_intf_tbl"); 27000 if (egr_intf_tbl_ptr == NULL) { 27001 return (BCM_E_MEMORY); 27002 } 27003 27004 /* Reset allocated buffer. */ 27005 sal_memset(egr_intf_tbl_ptr, 0, alloc_size); 27006 27007 /* Read table to the buffer. */ 27008 rv = soc_mem_read_range(unit, EGR_L3_INTFm, MEM_BLOCK_ANY, 27009 soc_mem_index_min(unit, EGR_L3_INTFm), 27010 soc_mem_index_max(unit, EGR_L3_INTFm), egr_intf_tbl_ptr); 27011 if (BCM_FAILURE(rv)) { 27012 goto cleanup; 27013 } 27014 for (ifindex = 0; ifindex < tbl_size; ifindex++) { 27015 egr_intf_entry_ptr = 27016 soc_mem_table_idx_to_pointer(unit, EGR_L3_INTFm, 27017 uint32 *, egr_intf_tbl_ptr, 27018 ifindex); 27019 dscp_map_ptr = soc_mem_field32_get(unit, EGR_L3_INTFm, 27020 egr_intf_entry_ptr, DSCP_MAPPING_PTRf); 27021 if (dscp_map_ptr == dscp_map_id) { 27022 27023 soc_mem_field32_set(unit, EGR_L3_INTFm, 27024 egr_intf_entry_ptr, DSCP_MAPPING_PTRf, 27025 new_dscp_map_id); 27026 } 27027 } 27028 rv = soc_mem_write_range(unit, EGR_L3_INTFm, MEM_BLOCK_ALL, 27029 soc_mem_index_min(unit, EGR_L3_INTFm), 27030 soc_mem_index_max(unit, EGR_L3_INTFm), 27031 egr_intf_tbl_ptr); 27032 if (SOC_FAILURE(rv)) { 27033 goto cleanup; 27034 } 27035 27036 _bcm_tr2_qos_id_update(unit, dscp_map_id, new_dscp_map_id); 27037 27038 cleanup: 27039 27040 if (egr_intf_tbl_ptr) { 27041 soc_cm_sfree(unit, egr_intf_tbl_ptr); 27042 } 27043 return rv; 27044 27045 } 27046 #endif 27047 27048 /* 27049 * Function: 27050 * _bcm_port_dscp_unmap_set 27051 * Purpose: 27052 * Internal implementation for bcm_port_dscp_unmap_set 27053 * Returns: 27054 * BCM_E_XXX 27055 */ 27056 STATIC int 27057 _bcm_port_dscp_unmap_set(int unit, bcm_port_t port, int internal_pri, 27058 bcm_color_t color, int pkt_dscp) 27059 { 27060 int index, port_shift = 6; 27061 egr_dscp_table_entry_t dscp_unmap; 27062 egr_zone_4_qos_mapping_table_entry_t z4_qos_unmap; 27063 #if defined(BCM_TRIDENT_SUPPORT) 27064 egr_dscp_table_entry_t egr_dscp_map_entries[64]; 27065 void *entries[1]; 27066 uint32 dscp_index = 0; 27067 uint32 new_dscp_index; 27068 int ref_count; 27069 void *entry; 27070 int port_dscp_map_set; 27071 int old_pkt_dscp; 27072 #endif 27073 if (pkt_dscp < 0 || pkt_dscp > DSCP_CODE_POINT_MAX) { 27074 return BCM_E_PARAM; 27075 } 27076 if ((internal_pri < 0) || (internal_pri > 15) || 27077 ((color != bcmColorGreen) && (color != bcmColorYellow) && 27078 (color != bcmColorRed))) { 27079 return BCM_E_PARAM; 27080 } 27081 27082 /* EGR_DSCP_TABLE table is indexed with 27083 * port[5:0] priority[3:0] CNG [1:0] 27084 */ 27085 27086 index = (port << port_shift) | (internal_pri << 2) | 27087 _BCM_COLOR_ENCODING(unit, color); 27088 27089 if (SOC_IS_TRIDENT3X(unit)) { 27090 /* This function is obselete - put in the right register for readability*/ 27091 sal_memset(&z4_qos_unmap, 0, sizeof(z4_qos_unmap)); 27092 soc_mem_field32_set(unit, EGR_ZONE_4_QOS_MAPPING_TABLEm, &z4_qos_unmap, QOSf, pkt_dscp); 27093 SOC_IF_ERROR_RETURN 27094 (WRITE_EGR_ZONE_4_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ALL, index, &z4_qos_unmap)); 27095 27096 soc_mem_field32_set(unit, EGR_ZONE_2_QOS_MAPPING_TABLEm, &z4_qos_unmap, QOSf, pkt_dscp); 27097 SOC_IF_ERROR_RETURN 27098 (WRITE_EGR_ZONE_2_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ALL, index, &z4_qos_unmap)); 27099 } else 27100 #ifdef BCM_TRIDENT_SUPPORT 27101 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_SELf)) { 27102 dscp_index = port << port_shift; 27103 index = (internal_pri << 2) | _BCM_COLOR_ENCODING(unit, color); 27104 27105 sal_memset(egr_dscp_map_entries, 0, sizeof(egr_dscp_map_entries)); 27106 entries[0] = &egr_dscp_map_entries; 27107 27108 entry = &egr_dscp_map_entries[index]; 27109 BCM_IF_ERROR_RETURN( 27110 _bcm_egr_dscp_table_entry_ref_count_get(unit, dscp_index, &ref_count)); 27111 port_dscp_map_set = PORT(unit, port).port_dscp_map_set; 27112 if (ref_count > 0) { 27113 BCM_IF_ERROR_RETURN( 27114 _bcm_egr_dscp_table_entry_get(unit, dscp_index, 27115 _BCM_QOS_MAP_CHUNK_EGR_DSCP, entries)); 27116 old_pkt_dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm, entry, DSCPf); 27117 if (pkt_dscp != old_pkt_dscp) { 27118 int i; 27119 int port_dscp_map_count = port_dscp_map_set; 27120 /* If this profile is only used by port */ 27121 if ((ref_count == 1) && (port_dscp_map_set == 1)) { 27122 soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, pkt_dscp); 27123 BCM_IF_ERROR_RETURN( 27124 _bcm_egr_dscp_table_entry_set(unit, entries, dscp_index)); 27125 BCM_IF_ERROR_RETURN( 27126 _bcm_egr_dscp_table_entry_delete(unit, dscp_index)); 27127 } else { /* If this profile is used not only by port */ 27128 soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, 27129 old_pkt_dscp); 27130 BCM_IF_ERROR_RETURN( 27131 _bcm_egr_dscp_table_entry_add(unit, entries, 27132 _BCM_QOS_MAP_CHUNK_EGR_DSCP, 27133 &new_dscp_index, 27134 SOC_PROFILE_MEM_F_NO_SHARE)); 27135 for (i = 0; i < (ref_count - port_dscp_map_count - 1); i++) { 27136 BCM_IF_ERROR_RETURN( 27137 _bcm_egr_dscp_table_entry_reference(unit, new_dscp_index, 27138 _BCM_QOS_MAP_CHUNK_EGR_DSCP)); 27139 } 27140 BCM_IF_ERROR_RETURN( 27141 _bcm_td_egr_l3_intf_dscp_map_update(unit, port, 27142 (new_dscp_index >> port_shift))); 27143 soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, pkt_dscp); 27144 BCM_IF_ERROR_RETURN( 27145 _bcm_egr_dscp_table_entry_set(unit, entries, dscp_index)); 27146 for (i = 0; i < ref_count; i++) { 27147 BCM_IF_ERROR_RETURN( 27148 _bcm_egr_dscp_table_entry_delete(unit, dscp_index)); 27149 } 27150 } 27151 } 27152 } else { 27153 soc_mem_field32_set(unit, EGR_DSCP_TABLEm, entry, DSCPf, pkt_dscp); 27154 _bcm_common_profile_mem_ref_cnt_update(unit, EGR_DSCP_TABLEm, port, 1); 27155 BCM_IF_ERROR_RETURN( 27156 _bcm_egr_dscp_table_entry_set(unit, entries, dscp_index)); 27157 BCM_IF_ERROR_RETURN( 27158 _bcm_egr_dscp_table_entry_delete(unit, dscp_index)); 27159 } 27160 PORT(unit, port).port_dscp_map_set = 1; 27161 27162 } else 27163 #endif 27164 { 27165 sal_memset(&dscp_unmap, 0, sizeof(dscp_unmap)); 27166 soc_mem_field32_set(unit, EGR_DSCP_TABLEm, &dscp_unmap, DSCPf, pkt_dscp); 27167 SOC_IF_ERROR_RETURN 27168 (WRITE_EGR_DSCP_TABLEm(unit, MEM_BLOCK_ALL, index, &dscp_unmap)); 27169 } 27170 return BCM_E_NONE; 27171 } 27172 27173 /* 27174 * Function: 27175 * bcm_port_dscp_unmap_set 27176 * Purpose: 27177 * Define a mapping for diffserv code points 27178 * The mapping enable/disable is controlled by a seperate API 27179 * bcm_port_dscp_map_enable_set/get 27180 * Also Enable/Disable control for DSCP mapping for tunnels 27181 * are available in the respective tunnel create APIs. 27182 * Parameters: 27183 * unit - switch device 27184 * port - switch port or -1 to setup global mapping table. 27185 * internal_pri - internal priority 27186 * color - Red/Yellow/Green 27187 * pkt_dscp - DSCP marking on outgoing packet 27188 * Returns: 27189 * BCM_E_XXX 27190 */ 27191 int 27192 bcm_esw_port_dscp_unmap_set(int unit, bcm_port_t port, int internal_pri, 27193 bcm_color_t color, int pkt_dscp) 27194 { 27195 int rv; 27196 bcm_port_config_t port_conf; 27197 bcm_pbmp_t pbmp; 27198 27199 /* Make sure port module is initialized. */ 27200 PORT_INIT(unit); 27201 if (!soc_feature(unit, soc_feature_dscp) || 27202 !soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 27203 return BCM_E_UNAVAIL; 27204 } 27205 27206 if (port != -1) { 27207 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 27208 if (IS_HG_PORT(unit, port) || IS_ST_PORT(unit, port)) { 27209 return BCM_E_PORT; 27210 } 27211 } 27212 27213 PORT_LOCK(unit); 27214 27215 /* Get device port configuration. */ 27216 rv = bcm_esw_port_config_get(unit, &port_conf); 27217 if (BCM_FAILURE(rv)) { 27218 PORT_UNLOCK(unit); 27219 return rv; 27220 } 27221 BCM_PBMP_ASSIGN(pbmp, port_conf.e); 27222 BCM_PBMP_OR(pbmp, port_conf.cpu); 27223 #ifdef BCM_KATANA2_SUPPORT 27224 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 27225 rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp); 27226 if (BCM_FAILURE(rv)) { 27227 PORT_UNLOCK(unit); 27228 return (rv); 27229 } 27230 } 27231 if (soc_feature(unit, soc_feature_linkphy_coe) || 27232 soc_feature(unit, soc_feature_subtag_coe)) { 27233 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 27234 } 27235 #endif 27236 27237 if (port == -1) { 27238 PBMP_ITER(pbmp, port) { 27239 rv = _bcm_port_dscp_unmap_set(unit, port, internal_pri, color, 27240 pkt_dscp); 27241 if (BCM_FAILURE(rv)) { 27242 PORT_UNLOCK(unit); 27243 return rv; 27244 } 27245 } 27246 } else if (SOC_PORT_VALID(unit, port) && BCM_PBMP_MEMBER(pbmp, port)) { 27247 rv = _bcm_port_dscp_unmap_set(unit, port, internal_pri, color, 27248 pkt_dscp); 27249 } else { 27250 rv = BCM_E_PORT; 27251 } 27252 PORT_UNLOCK(unit); 27253 27254 return rv; 27255 } 27256 27257 /* 27258 * Function: 27259 * _bcm_port_dscp_unmap_get 27260 * Purpose: 27261 * Internal implementation for bcm_port_dscp_unmap_get 27262 * Returns: 27263 * BCM_E_XXX 27264 */ 27265 STATIC int 27266 _bcm_port_dscp_unmap_get(int unit, bcm_port_t port, int internal_pri, 27267 bcm_color_t color, int *pkt_dscp) 27268 { 27269 int index, port_shift = 6; 27270 egr_dscp_table_entry_t dscp_unmap; 27271 #if defined(BCM_TRIDENT_SUPPORT) 27272 egr_dscp_table_entry_t egr_dscp_map_entries[64]; 27273 void *entries[1]; 27274 uint32 dscp_index = 0; 27275 void *entry; 27276 #endif 27277 if ((internal_pri < 0) || (internal_pri > 15) || 27278 ((color != bcmColorGreen) && (color != bcmColorYellow) && 27279 (color != bcmColorRed))) { 27280 return BCM_E_PARAM; 27281 } 27282 27283 /* EGR_DSCP_TABLE table is indexed with 27284 * port[5:0] priority[3:0] CNG [1:0] 27285 */ 27286 index = (port << port_shift) | (internal_pri << 2) | 27287 _BCM_COLOR_ENCODING(unit, color); 27288 27289 if (SOC_IS_TRIDENT3X(unit)) { 27290 SOC_IF_ERROR_RETURN 27291 (READ_EGR_ZONE_4_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ANY, index, &dscp_unmap)); 27292 *pkt_dscp = soc_mem_field32_get(unit, EGR_ZONE_4_QOS_MAPPING_TABLEm, 27293 &dscp_unmap, QOSf); 27294 27295 SOC_IF_ERROR_RETURN 27296 (READ_EGR_ZONE_2_QOS_MAPPING_TABLEm(unit, MEM_BLOCK_ANY, index, &dscp_unmap)); 27297 *pkt_dscp = soc_mem_field32_get(unit, EGR_ZONE_2_QOS_MAPPING_TABLEm, 27298 &dscp_unmap, QOSf); 27299 } else 27300 #if defined(BCM_TRIDENT_SUPPORT) 27301 if (SOC_MEM_FIELD_VALID(unit, EGR_L3_INTFm, OPRI_OCFI_SELf)) { 27302 dscp_index = port << port_shift; 27303 index = (internal_pri << 2) | _BCM_COLOR_ENCODING(unit, color); 27304 27305 sal_memset(egr_dscp_map_entries, 0, sizeof(egr_dscp_map_entries)); 27306 entries[0] = &egr_dscp_map_entries; 27307 27308 BCM_IF_ERROR_RETURN( 27309 _bcm_egr_dscp_table_entry_get(unit, dscp_index, 27310 _BCM_QOS_MAP_CHUNK_EGR_DSCP, entries)); 27311 entry = &egr_dscp_map_entries[index]; 27312 *pkt_dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm, 27313 entry, DSCPf); 27314 } else 27315 #endif 27316 { 27317 SOC_IF_ERROR_RETURN 27318 (READ_EGR_DSCP_TABLEm(unit, MEM_BLOCK_ANY, index, &dscp_unmap)); 27319 *pkt_dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm, 27320 &dscp_unmap, DSCPf); 27321 } 27322 return BCM_E_NONE; 27323 } 27324 27325 /* 27326 * Function: 27327 * bcm_port_dscp_unmap_get 27328 * Purpose: 27329 * Retrieve a mapping for diffserv code points 27330 * The mapping enable/disable is controlled by a seperate API 27331 * bcm_port_dscp_map_enable_set/get 27332 * Also Enable/Disable control for DSCP mapping for tunnels 27333 * are available in the respective tunnel create APIs. 27334 * Parameters: 27335 * unit - switch device 27336 * port - switch port. 27337 * internal_pri - internal priority 27338 * color - Red/Yellow/Green 27339 * pkt_dscp - DSCP marking on outgoing packet 27340 * Returns: 27341 * BCM_E_XXX 27342 */ 27343 int 27344 bcm_esw_port_dscp_unmap_get(int unit, bcm_port_t port, int internal_pri, 27345 bcm_color_t color, int *pkt_dscp) 27346 { 27347 int rv; 27348 bcm_port_config_t port_conf; 27349 bcm_pbmp_t pbmp; 27350 27351 /* Make sure port module is initialized. */ 27352 PORT_INIT(unit); 27353 if (!soc_feature(unit, soc_feature_dscp) || 27354 !soc_feature(unit, soc_feature_egr_dscp_map_per_port)) { 27355 return BCM_E_UNAVAIL; 27356 } 27357 27358 if (port != -1) { 27359 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 27360 if (IS_HG_PORT(unit, port) || IS_ST_PORT(unit, port)) { 27361 return BCM_E_PORT; 27362 } 27363 } 27364 27365 PORT_LOCK(unit); 27366 27367 /* Get device port configuration. */ 27368 rv = bcm_esw_port_config_get(unit, &port_conf); 27369 if (BCM_FAILURE(rv)) { 27370 PORT_UNLOCK(unit); 27371 return rv; 27372 } 27373 BCM_PBMP_ASSIGN(pbmp, port_conf.e); 27374 BCM_PBMP_OR(pbmp, port_conf.cpu); 27375 #ifdef BCM_KATANA2_SUPPORT 27376 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_flex_port)) { 27377 rv = _bcm_kt2_flexio_pbmp_update(unit, &pbmp); 27378 if (BCM_FAILURE(rv)) { 27379 PORT_UNLOCK(unit); 27380 return (rv); 27381 } 27382 } 27383 if (soc_feature(unit, soc_feature_linkphy_coe) || 27384 soc_feature(unit, soc_feature_subtag_coe)) { 27385 _bcm_kt2_subport_pbmp_update(unit, &pbmp); 27386 } 27387 #endif 27388 27389 if (port == -1) { 27390 PBMP_ITER(pbmp, port) { 27391 break; 27392 } 27393 } 27394 27395 if (SOC_PORT_VALID(unit, port) && BCM_PBMP_MEMBER(pbmp, port)) { 27396 rv = _bcm_port_dscp_unmap_get(unit, port, internal_pri, color, 27397 pkt_dscp); 27398 } else { 27399 rv = BCM_E_PORT; 27400 } 27401 27402 PORT_UNLOCK(unit); 27403 return rv; 27404 } 27405 27406 #undef DSCP_CODE_POINT_MAX 27407 #undef DSCP_CODE_POINT_CNT 27408 27409 STATIC int 27410 _bcm_esw_port_modid_egress_resolve(int unit, _bcm_port_egr_dest_t *egr_dst) 27411 { 27412 int port_adjst = 0, mod_adjust = 0; 27413 int isLocal = 0; 27414 bcm_module_t my_mod, modid; 27415 27416 if (BCM_GPORT_IS_SET(egr_dst->in_port)) { 27417 bcm_trunk_t tid; 27418 int id; 27419 bcm_port_t port; 27420 27421 BCM_IF_ERROR_RETURN( 27422 _bcm_esw_gport_resolve(unit, egr_dst->in_port, &modid, &port, 27423 &tid, &id)); 27424 if ((-1 != id) || (-1 != tid)) { 27425 return BCM_E_PORT; 27426 } 27427 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_mod)); 27428 BCM_IF_ERROR_RETURN( 27429 _bcm_esw_modid_is_local(unit, modid, &isLocal)); 27430 27431 if ((TRUE == isLocal) && (modid != my_mod)){ 27432 port_adjst = 32; 27433 mod_adjust = 1; 27434 } 27435 egr_dst->out_min_port = egr_dst->out_max_port = port + port_adjst; 27436 egr_dst->out_min_modid = egr_dst->out_max_modid = modid - mod_adjust; 27437 } else { 27438 if (egr_dst->in_modid < 0) { 27439 egr_dst->out_min_modid = 0; 27440 egr_dst->out_max_modid = SOC_MODID_MAX(unit); 27441 } else if (!SOC_MODID_ADDRESSABLE(unit, egr_dst->in_modid)) { 27442 return BCM_E_PARAM; 27443 } else { 27444 egr_dst->out_min_modid = egr_dst->out_max_modid = egr_dst->in_modid; 27445 } 27446 27447 if (egr_dst->in_port < 0) { 27448 egr_dst->out_min_port = 0; 27449 egr_dst->out_max_port = SOC_PORT_MAX(unit, all); 27450 } else if (!SOC_PORT_ADDRESSABLE(unit, egr_dst->in_port)) { 27451 return BCM_E_PORT; 27452 } else { 27453 egr_dst->out_min_port = egr_dst->out_max_port = egr_dst->in_port; 27454 } 27455 } 27456 27457 return BCM_E_NONE; 27458 } 27459 27460 27461 /* 27462 * Function: 27463 * bcm_port_egress_set 27464 * Description: 27465 * Set switching only to indicated ports from given (modid, port). 27466 * Parameters: 27467 * unit - StrataSwitch PCI device unit number (driver internal). 27468 * port - ingress port number. 27469 * modid - source module ID index (in HiGig mod header). 27470 * pbmp - bitmap of ports to allow egress. 27471 * Returns: 27472 * BCM_E_xxxx 27473 * Note: 27474 * if port < 0, means all/any port 27475 * if modid < 0, means all/any modid 27476 */ 27477 int 27478 bcm_esw_port_egress_set(int unit, bcm_port_t port, int modid, bcm_pbmp_t pbmp) 27479 { 27480 egr_mask_entry_t em_entry; 27481 int em_index; 27482 bcm_module_t cur_mod, hw_mod; 27483 bcm_pbmp_t em_pbmp; 27484 bcm_port_t cur_port, hw_port; 27485 int rv = BCM_E_NONE; 27486 _bcm_port_egr_dest_t egr_dst; 27487 int mod_is_local = 0; 27488 int mod_port_map_done = 0; 27489 27490 /* Make sure port module is initialized. */ 27491 PORT_INIT(unit); 27492 27493 if(bcm_common_oamp_port_enable_get(unit, port)) { 27494 LOG_ERROR(BSL_LS_BCM_PORT, 27495 (BSL_META("Error: Not permitted on OAMP port %d.n"), 27496 port)); 27497 return BCM_E_PARAM; 27498 } 27499 27500 #ifdef BCM_TRIDENT_SUPPORT 27501 if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 27502 return bcm_td_port_egress_set(unit, port, modid, pbmp); 27503 } 27504 #endif /* BCM_TRIDENT_SUPPORT */ 27505 27506 #ifdef BCM_HURRICANE3_SUPPORT 27507 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 27508 return bcm_hr3_port_egress_set(unit, port, modid, pbmp); 27509 } 27510 #endif /* BCM_HURRICANE3_SUPPORT */ 27511 27512 if (!SOC_IS_XGS_SWITCH(unit)) { 27513 if (BCM_PBMP_EQ(pbmp, PBMP_ALL(unit))) { 27514 return BCM_E_NONE; 27515 } else { 27516 return BCM_E_UNAVAIL; 27517 } 27518 } 27519 27520 sal_memset(&em_entry, 0, sizeof(egr_mask_entry_t)); 27521 27522 BCM_PBMP_NEGATE(em_pbmp, pbmp); 27523 BCM_PBMP_AND(em_pbmp, PBMP_ALL(unit)); 27524 BCM_PBMP_REMOVE(em_pbmp, PBMP_LB(unit)); 27525 soc_mem_pbmp_field_set(unit, EGR_MASKm, &em_entry, EGRESS_MASKf, 27526 &em_pbmp); 27527 27528 egr_dst.in_modid = modid; 27529 egr_dst.in_port = port; 27530 BCM_IF_ERROR_RETURN(_bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 27531 /* If the given port is a gport, _bcm_esw_port_modid_egress_resolve had 27532 * already performed module and port mapping for devices with 27533 * multiple module IDs. 27534 */ 27535 mod_port_map_done = BCM_GPORT_IS_SET(port) ? 1 : 0; 27536 27537 soc_mem_lock(unit, EGR_MASKm); 27538 for (cur_mod = egr_dst.out_min_modid; cur_mod <= egr_dst.out_max_modid; cur_mod++) { 27539 rv = _bcm_esw_modid_is_local(unit, cur_mod, &mod_is_local); 27540 if (BCM_FAILURE(rv)) { 27541 break; 27542 } 27543 for (cur_port = egr_dst.out_min_port; cur_port <= egr_dst.out_max_port; cur_port++) { 27544 if (mod_is_local && (NUM_MODID(unit) > 1) && !mod_port_map_done) { 27545 if (cur_port <= SOC_MODPORT_MAX(unit)) { 27546 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET, 27547 cur_mod, cur_port, &hw_mod, &hw_port); 27548 if (BCM_FAILURE(rv)) { 27549 break; 27550 } 27551 } else { 27552 break; 27553 } 27554 } else { 27555 hw_mod = cur_mod; 27556 hw_port = cur_port; 27557 } 27558 27559 em_index = (hw_mod & SOC_MODID_MAX(unit)) * 27560 (SOC_PORT_ADDR_MAX(unit) + 1) | 27561 (hw_port & SOC_PORT_ADDR_MAX(unit)); 27562 rv = soc_mem_write(unit, EGR_MASKm, MEM_BLOCK_ALL, 27563 em_index, &em_entry); 27564 if (!BCM_SUCCESS(rv)) { 27565 break; 27566 } 27567 } 27568 if (!BCM_SUCCESS(rv)) { 27569 break; 27570 } 27571 } 27572 soc_mem_unlock(unit, EGR_MASKm); 27573 27574 return rv; 27575 } 27576 27577 /* 27578 * Function: 27579 * bcm_port_egress_get 27580 * Description: 27581 * Retrieve bitmap of ports for which switching is enabled 27582 * for (modid, port). 27583 * Parameters: 27584 * unit - StrataSwitch PCI device unit number (driver internal). 27585 * port - ingress port number. 27586 * modid - source module ID index (in HiGig mod header). 27587 * pbmp - (OUT) bitmap of ports where egress allowed. 27588 * Returns: 27589 * BCM_E_xxxx 27590 */ 27591 int 27592 bcm_esw_port_egress_get(int unit, bcm_port_t port, int modid, bcm_pbmp_t *pbmp) 27593 { 27594 egr_mask_entry_t em_entry; 27595 int em_index; 27596 bcm_pbmp_t em_pbmp, temp_pbmp; 27597 _bcm_port_egr_dest_t egr_dst; 27598 int mod_port_map_done = 0; 27599 bcm_module_t hw_mod; 27600 bcm_port_t hw_port; 27601 27602 /* Make sure port module is initialized. */ 27603 PORT_INIT(unit); 27604 27605 if(bcm_common_oamp_port_enable_get(unit, port)) { 27606 LOG_ERROR(BSL_LS_BCM_PORT, 27607 (BSL_META("Error: Not permitted on OAMP port %d.n"), 27608 port)); 27609 return BCM_E_PARAM; 27610 } 27611 27612 #ifdef BCM_TRIDENT_SUPPORT 27613 if (SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 27614 return bcm_td_port_egress_get(unit, port, modid, pbmp); 27615 } 27616 #endif /* BCM_TRIDENT_SUPPORT */ 27617 27618 #ifdef BCM_HURRICANE3_SUPPORT 27619 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 27620 return bcm_hr3_port_egress_get(unit, port, modid, pbmp); 27621 } 27622 #endif /* BCM_HURRICANE3_SUPPORT */ 27623 27624 if (!SOC_IS_XGS_SWITCH(unit)) { 27625 BCM_PBMP_ASSIGN(*pbmp, PBMP_ALL(unit)); 27626 return BCM_E_NONE; 27627 } 27628 27629 if ((modid < 0) || (port < 0) ){ 27630 return BCM_E_PARAM; 27631 } 27632 27633 egr_dst.in_modid = modid; 27634 egr_dst.in_port = port; 27635 BCM_IF_ERROR_RETURN(_bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 27636 /* If the given port is a gport, _bcm_esw_port_modid_egress_resolve had 27637 * already performed module and port mapping for devices with 27638 * multiple module IDs. 27639 */ 27640 mod_port_map_done = BCM_GPORT_IS_SET(port) ? 1 : 0; 27641 27642 if (!mod_port_map_done) { 27643 PORT_DUALMODID_VALID(unit, egr_dst.out_min_port); 27644 BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET, 27645 egr_dst.out_min_modid, egr_dst.out_min_port, 27646 &hw_mod, &hw_port)); 27647 } else { 27648 hw_mod = egr_dst.out_min_modid; 27649 hw_port = egr_dst.out_min_port; 27650 } 27651 em_index = (hw_mod & SOC_MODID_MAX(unit)) * 27652 (SOC_PORT_ADDR_MAX(unit) + 1) | (hw_port & SOC_PORT_ADDR_MAX(unit)); 27653 27654 BCM_IF_ERROR_RETURN 27655 (READ_EGR_MASKm(unit, MEM_BLOCK_ALL, em_index, &em_entry)); 27656 27657 BCM_PBMP_CLEAR(em_pbmp); 27658 soc_mem_pbmp_field_get(unit, EGR_MASKm, &em_entry, EGRESS_MASKf, 27659 &em_pbmp); 27660 BCM_PBMP_NEGATE(temp_pbmp, em_pbmp); 27661 BCM_PBMP_AND(temp_pbmp, PBMP_ALL(unit)); 27662 BCM_PBMP_REMOVE(temp_pbmp, PBMP_LB(unit)); 27663 BCM_PBMP_ASSIGN(*pbmp, temp_pbmp); 27664 27665 return BCM_E_NONE; 27666 } 27667 27668 #ifdef BCM_TRIUMPH2_SUPPORT 27669 STATIC int 27670 _bcm_port_src_mod_egress_profile_add(int unit, bcm_port_t port, 27671 int min_mod, int max_mod, pbmp_t pbmp) 27672 { 27673 int i, region, modid_cnt, new_region, empty_profile, alloc_size; 27674 int rv = BCM_E_NONE; 27675 uint32 val, add_index; 27676 src_modid_egress_entry_t *srcmodegr_p, *sme_buf; 27677 pbmp_t test_pbmp; 27678 void *entries[1]; /* for profile memories */ 27679 27680 modid_cnt = SOC_MODID_MAX(unit) + 1; 27681 region = PORT_SRC_MOD_EGR_PROF_PTR(unit, port); 27682 empty_profile = TRUE; 27683 new_region = -1; 27684 27685 alloc_size = modid_cnt * sizeof(*srcmodegr_p); 27686 sme_buf = sal_alloc(alloc_size, "SRC_MODID_EGRESS update buffer"); 27687 if (NULL == sme_buf) { 27688 return BCM_E_MEMORY; 27689 } 27690 sal_memset(sme_buf, 0, alloc_size); 27691 entries[0] = sme_buf; 27692 27693 if (0 <= region) { 27694 rv = soc_profile_mem_get(unit, PORT_SRC_MOD_EGR_PROFILE(unit), 27695 region * modid_cnt, modid_cnt, entries); 27696 } /* Else cleared by memset above. Null entry is all 0's */ 27697 27698 if (BCM_SUCCESS(rv)) { 27699 for (i = min_mod; i <= max_mod; i++) { 27700 /* Profile memory is an array of entries, not a DMA buffer */ 27701 srcmodegr_p = sme_buf + i; /* Both same pointer type */ 27702 soc_mem_pbmp_field_set(unit, SRC_MODID_EGRESSm, srcmodegr_p, 27703 PORT_BLOCK_MASK_BITMAPf, &pbmp); 27704 } 27705 27706 if (BCM_PBMP_IS_NULL(pbmp)) { 27707 /* Check for empty bitmap */ 27708 for (i = 0; i < modid_cnt; i++) { 27709 srcmodegr_p = sme_buf + i; /* Both same pointer type */ 27710 soc_mem_pbmp_field_get(unit, SRC_MODID_EGRESSm, srcmodegr_p, 27711 PORT_BLOCK_MASK_BITMAPf, &test_pbmp); 27712 if (BCM_PBMP_NOT_NULL(test_pbmp)) { 27713 empty_profile = FALSE; 27714 break; 27715 } 27716 } 27717 } else { 27718 empty_profile = FALSE; 27719 } 27720 27721 if (!empty_profile) { 27722 rv = soc_profile_mem_add(unit, PORT_SRC_MOD_EGR_PROFILE(unit), 27723 entries, modid_cnt, &add_index); 27724 if (BCM_SUCCESS(rv)) { 27725 new_region = add_index / modid_cnt; 27726 } 27727 } 27728 } 27729 27730 sal_free(sme_buf); 27731 BCM_IF_ERROR_RETURN(rv); 27732 27733 BCM_IF_ERROR_RETURN(READ_SRC_MODID_EGRESS_SELr(unit, port, &val)); 27734 if (empty_profile) { 27735 soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val, ENABLEf, 0); 27736 soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val, 27737 SRCMOD_INDEXf, 0); 27738 } else { 27739 soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val, ENABLEf, 1); 27740 soc_reg_field_set(unit, SRC_MODID_EGRESS_SELr, &val, 27741 SRCMOD_INDEXf, new_region); 27742 } 27743 BCM_IF_ERROR_RETURN(WRITE_SRC_MODID_EGRESS_SELr(unit, port, val)); 27744 27745 if (-1 != region) { 27746 BCM_IF_ERROR_RETURN 27747 (soc_profile_mem_delete(unit, PORT_SRC_MOD_EGR_PROFILE(unit), 27748 region * modid_cnt)); 27749 } 27750 27751 PORT_SRC_MOD_EGR_PROF_PTR(unit, port) = new_region; 27752 return BCM_E_NONE; 27753 } 27754 #endif 27755 27756 /* 27757 * Function: 27758 * bcm_port_modid_egress_set 27759 * Description: 27760 * Set port bitmap of egress ports on which the incoming packets 27761 * will be forwarded. 27762 * Parameters: 27763 * unit - StrataSwitch PCI device unit number (driver internal). 27764 * port - ingress port number. 27765 * modid - source module ID index (in HiGig mod header). 27766 * pbmp - bitmap of ports to allow egress. 27767 * Returns: 27768 * BCM_E_xxxx 27769 * Note: 27770 * if port < 0, means all/any port 27771 * if modid < 0, means all/any modid 27772 */ 27773 int 27774 bcm_esw_port_modid_egress_set(int unit, bcm_port_t port, 27775 bcm_module_t modid, bcm_pbmp_t pbmp) 27776 { 27777 #if defined(BCM_HERCULES15_SUPPORT) || defined(BCM_FIREBOLT_SUPPORT) 27778 int rv=BCM_E_UNAVAIL; 27779 27780 /* Make sure port module is initialized. */ 27781 PORT_INIT(unit); 27782 27783 #ifdef BCM_HERCULES15_SUPPORT 27784 if (SOC_IS_HERCULES15(unit)) { 27785 mem_ing_srcmodblk_entry_t srcmod; 27786 uint32 smf; 27787 bcm_module_t mod_idx, min_mod, max_mod; 27788 bcm_pbmp_t mod_pbmp; 27789 int bk=-1, blk; 27790 27791 if (port >= 0) { 27792 if (!SOC_PORT_VALID(unit, port) || !IS_HG_PORT(unit, port)) { 27793 return BCM_E_PORT; 27794 } 27795 bk = SOC_PORT_BLOCK(unit, port); 27796 } 27797 27798 if (modid < 0) { 27799 min_mod = soc_mem_index_min(unit, MEM_ING_SRCMODBLKm); 27800 max_mod = soc_mem_index_max(unit, MEM_ING_SRCMODBLKm); 27801 } else if (modid > soc_mem_index_max(unit, MEM_ING_SRCMODBLKm)) { 27802 return BCM_E_PARAM; 27803 } else { 27804 min_mod = max_mod = modid; 27805 } 27806 27807 BCM_PBMP_ASSIGN(mod_pbmp, pbmp); 27808 BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit)); 27809 if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) { 27810 return BCM_E_PARAM; 27811 } 27812 27813 soc_mem_lock(unit, MEM_ING_SRCMODBLKm); 27814 SOC_MEM_BLOCK_ITER(unit, MEM_ING_SRCMODBLKm, blk) { 27815 if ((port >= 0) && (bk !=blk)) { 27816 continue; 27817 } 27818 for (mod_idx = min_mod; mod_idx <= max_mod; mod_idx++) { 27819 sal_memset(&srcmod, 0, sizeof(srcmod)); 27820 rv = READ_MEM_ING_SRCMODBLKm(unit, blk, mod_idx, &srcmod); 27821 if (rv >= 0) { 27822 SOC_PBMP_WORD_SET(mod_pbmp, 0, 27823 soc_MEM_ING_SRCMODBLKm_field32_get(unit, &srcmod, BITMAPf)); 27824 if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) { 27825 smf = SOC_PBMP_WORD_GET(pbmp, 0); 27826 soc_MEM_ING_SRCMODBLKm_field_set(unit, &srcmod, BITMAPf, &smf); 27827 rv = WRITE_MEM_ING_SRCMODBLKm(unit, blk, mod_idx, &srcmod); 27828 } 27829 } 27830 } 27831 } 27832 soc_mem_unlock(unit, MEM_ING_SRCMODBLKm); 27833 } 27834 #endif /* BCM_HERCULES15_SUPPORT */ 27835 27836 #ifdef BCM_TRIUMPH2_SUPPORT 27837 if (soc_feature(unit, soc_feature_src_modid_blk_profile)) { 27838 src_modid_ingress_block_entry_t srcmoding; 27839 _bcm_port_egr_dest_t egr_dst; 27840 int all_st_ports; 27841 int i; 27842 bcm_port_t p; 27843 pbmp_t mod_pbmp, all_pbmp; 27844 27845 if ((port != -1) && (!SOC_PORT_VALID(unit, port))) { 27846 return BCM_E_PORT; 27847 } 27848 egr_dst.in_port = port; 27849 egr_dst.in_modid = modid; 27850 BCM_IF_ERROR_RETURN( 27851 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 27852 27853 if (egr_dst.out_min_port == egr_dst.out_max_port) { 27854 all_st_ports = 0; 27855 } else { 27856 all_st_ports = 1; 27857 } 27858 27859 SOC_PBMP_CLEAR(all_pbmp); 27860 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 27861 27862 #ifdef BCM_KATANA2_SUPPORT 27863 if (soc_feature(unit, soc_feature_linkphy_coe) || 27864 soc_feature(unit, soc_feature_subtag_coe)) { 27865 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 27866 } 27867 #endif 27868 /* First program the ingress blocking */ 27869 soc_mem_lock(unit, SRC_MODID_INGRESS_BLOCKm); 27870 for (i = egr_dst.out_min_modid; i <= egr_dst.out_max_modid; i++) { 27871 rv = READ_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ANY, i, 27872 &srcmoding); 27873 if (BCM_FAILURE(rv)) { 27874 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm); 27875 return rv; 27876 } 27877 if (!all_st_ports) { 27878 soc_mem_pbmp_field_get(unit, SRC_MODID_INGRESS_BLOCKm, 27879 &srcmoding, PORT_BITMAPf, &mod_pbmp); 27880 BCM_PBMP_PORT_REMOVE(mod_pbmp, egr_dst.out_min_port); 27881 } else { 27882 BCM_PBMP_ASSIGN(mod_pbmp, all_pbmp); 27883 BCM_PBMP_OR(mod_pbmp, PBMP_LB(unit)); 27884 PBMP_ST_ITER(unit, p) { 27885 BCM_PBMP_PORT_REMOVE(mod_pbmp, p); 27886 } 27887 } 27888 soc_mem_pbmp_field_set(unit, SRC_MODID_INGRESS_BLOCKm, 27889 &srcmoding, PORT_BITMAPf, &mod_pbmp); 27890 rv = WRITE_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ALL, i, 27891 &srcmoding); 27892 if (BCM_FAILURE(rv)) { 27893 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm); 27894 return rv; 27895 } 27896 } 27897 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm); 27898 27899 /* Deal with the egress blocking - use one of 8 profiles */ 27900 BCM_PBMP_ASSIGN(mod_pbmp, pbmp); 27901 BCM_PBMP_AND(mod_pbmp, all_pbmp); 27902 BCM_PBMP_REMOVE(mod_pbmp, PBMP_LB(unit)); 27903 if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) { 27904 return BCM_E_PARAM; 27905 } 27906 27907 BCM_PBMP_NEGATE(mod_pbmp, pbmp); 27908 BCM_PBMP_AND(mod_pbmp, all_pbmp); 27909 BCM_PBMP_REMOVE(mod_pbmp, PBMP_LB(unit)); 27910 27911 soc_mem_lock(unit, SRC_MODID_EGRESSm); 27912 if (!all_st_ports) { 27913 /* Deal with a single stack port and its profile */ 27914 /* coverity[overrun-call : FALSE] */ 27915 rv = _bcm_port_src_mod_egress_profile_add(unit, 27916 egr_dst.out_min_port, 27917 egr_dst.out_min_modid, 27918 egr_dst.out_max_modid, 27919 mod_pbmp); 27920 if (BCM_FAILURE(rv)) { 27921 soc_mem_unlock(unit, SRC_MODID_EGRESSm); 27922 return rv; 27923 } 27924 } else { 27925 /* Deal with all stack ports and their profiles */ 27926 PBMP_ST_ITER(unit, p) { 27927 /* coverity[overrun-local : FALSE] */ 27928 rv = _bcm_port_src_mod_egress_profile_add(unit, p, 27929 egr_dst.out_min_modid, 27930 egr_dst.out_max_modid, 27931 mod_pbmp); 27932 if (BCM_FAILURE(rv)) { 27933 soc_mem_unlock(unit, SRC_MODID_EGRESSm); 27934 return rv; 27935 } 27936 } 27937 } 27938 soc_mem_unlock(unit, SRC_MODID_EGRESSm); 27939 27940 return rv; 27941 } 27942 #endif 27943 27944 #ifdef BCM_TRX_SUPPORT 27945 if (SOC_IS_TRX(unit)) { 27946 src_modid_block_entry_t srcmod; 27947 int modid_cnt, idx, i, j; 27948 bcm_pbmp_t mod_pbmp; 27949 _bcm_port_egr_dest_t egr_dst; 27950 27951 /* Number of supported MODIDs for this unit */ 27952 modid_cnt = SOC_MODID_MAX(unit) + 1; 27953 27954 egr_dst.in_port = port; 27955 egr_dst.in_modid = modid; 27956 BCM_IF_ERROR_RETURN( 27957 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 27958 27959 if (egr_dst.out_min_port == egr_dst.out_max_port) { 27960 /* process to retrieve hg_port index from port */ 27961 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 27962 SOC_IS_GREYHOUND2(unit)) { 27963 egr_dst.out_min_port = egr_dst.out_max_port; 27964 } else { 27965 SOC_IF_ERROR_RETURN( 27966 soc_xgs3_port_num_to_higig_port_num(unit, 27967 egr_dst.out_max_port, &egr_dst.out_min_port)); 27968 } 27969 27970 egr_dst.out_max_port = egr_dst.out_min_port; 27971 } else { 27972 egr_dst.out_min_port = soc_mem_index_min(unit, SRC_MODID_BLOCKm) / modid_cnt; 27973 egr_dst.out_max_port = soc_mem_index_max(unit, SRC_MODID_BLOCKm) / modid_cnt; 27974 } 27975 27976 BCM_PBMP_ASSIGN(mod_pbmp, pbmp); 27977 BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit)); 27978 if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) { 27979 return BCM_E_PARAM; 27980 } 27981 27982 BCM_PBMP_NEGATE(mod_pbmp, pbmp); 27983 BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit)); 27984 27985 soc_mem_lock(unit, SRC_MODID_BLOCKm); 27986 for (i = egr_dst.out_min_port; i <= egr_dst.out_max_port; i++) { 27987 for (j = egr_dst.out_min_modid; j <= egr_dst.out_max_modid; j++) { 27988 idx = i * modid_cnt + j; 27989 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod); 27990 if (rv >= 0) { 27991 soc_SRC_MODID_BLOCKm_field_set(unit, &srcmod, 27992 PORT_BLOCK_MASK_BITMAPf, 27993 (uint32 *)&mod_pbmp); 27994 rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL, idx, 27995 &srcmod); 27996 } 27997 if (rv < 0) { 27998 soc_mem_unlock(unit, SRC_MODID_BLOCKm); 27999 return rv; 28000 } 28001 } 28002 } 28003 soc_mem_unlock(unit, SRC_MODID_BLOCKm); 28004 return rv; 28005 } 28006 #endif /* BCM_TRX_SUPPORT */ 28007 28008 #ifdef BCM_FIREBOLT_SUPPORT 28009 if (soc_feature(unit, soc_feature_src_modid_blk)) { 28010 src_modid_block_entry_t srcmod; 28011 bcm_module_t mod_idx; 28012 int p_idx, min_p, max_p; 28013 int tbl_size, modid_cnt, idx; 28014 bcm_pbmp_t mod_pbmp, tst_pbmp, hg_pbmp; 28015 int cpu=0, ether=0; 28016 uint32 xge_val; 28017 _bcm_port_egr_dest_t egr_dst; 28018 #if defined(BCM_RAPTOR_SUPPORT) 28019 uint32 rp_val; 28020 #endif /* BCM_RAPTOR_SUPPORT */ 28021 /* Number of supported MODIDs for this unit */ 28022 modid_cnt = SOC_MODID_MAX(unit) + 1; 28023 28024 28025 egr_dst.in_port = port; 28026 egr_dst.in_modid = modid; 28027 BCM_IF_ERROR_RETURN( 28028 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28029 28030 if (egr_dst.out_min_port == egr_dst.out_max_port) { 28031 min_p = max_p = egr_dst.out_min_port - SOC_HG_OFFSET(unit); 28032 } else { 28033 min_p = 0; 28034 tbl_size = soc_mem_index_count(unit, SRC_MODID_BLOCKm); 28035 max_p = (tbl_size / modid_cnt) - 1; 28036 assert(max_p >= 0); 28037 } 28038 28039 BCM_PBMP_ASSIGN(mod_pbmp, pbmp); 28040 BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit)); 28041 if (BCM_PBMP_NEQ(pbmp, mod_pbmp)) { 28042 return BCM_E_PARAM; 28043 } 28044 28045 BCM_PBMP_NEGATE(mod_pbmp, pbmp); 28046 BCM_PBMP_AND(mod_pbmp, PBMP_ALL(unit)); 28047 28048 BCM_PBMP_ASSIGN(tst_pbmp, mod_pbmp); 28049 BCM_PBMP_AND(tst_pbmp, PBMP_CMIC(unit)); 28050 if (BCM_PBMP_NOT_NULL(tst_pbmp)) { 28051 cpu = 1; 28052 } 28053 28054 BCM_PBMP_ASSIGN(tst_pbmp, mod_pbmp); 28055 BCM_PBMP_AND(tst_pbmp, PBMP_E_ALL(unit)); 28056 if (BCM_PBMP_NOT_NULL(tst_pbmp)) { 28057 ether = 1; 28058 BCM_PBMP_ASSIGN(tst_pbmp, PBMP_XE_ALL(unit)); 28059 } 28060 28061 BCM_PBMP_ASSIGN(hg_pbmp, mod_pbmp); 28062 BCM_PBMP_AND(hg_pbmp, PBMP_ST_ALL(unit)); 28063 28064 if (ether && BCM_PBMP_NOT_NULL(tst_pbmp)) { 28065 BCM_PBMP_OR(hg_pbmp, tst_pbmp); 28066 } 28067 xge_val = SOC_PBMP_WORD_GET(hg_pbmp, 0) >> SOC_HG_OFFSET(unit); 28068 28069 /* In Raven, port #3 is the GMII port and it introduces a hole in the ST pbmp */ 28070 soc_mem_lock(unit, SRC_MODID_BLOCKm); 28071 for (p_idx = min_p; p_idx <= max_p; p_idx++) { 28072 if (SOC_IS_RAVEN(unit) && p_idx == 3) { 28073 continue; 28074 } 28075 for (mod_idx = egr_dst.out_min_modid; mod_idx <= egr_dst.out_max_modid; mod_idx++) { 28076 sal_memset(&srcmod, 0, sizeof(srcmod)); 28077 /* Table is 2-dimensional array */ 28078 if (SOC_IS_RAVEN(unit) && p_idx >= 4) { 28079 idx = (p_idx - 1) * modid_cnt + mod_idx; 28080 } else { 28081 idx = (p_idx * modid_cnt) + mod_idx; 28082 } 28083 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod); 28084 if (rv >= 0) { 28085 soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod, 28086 CPU_PORT_BLOCK_MASKf, 28087 (cpu) ? 1 : 0); 28088 if (SOC_IS_FB_FX_HX(unit)) { 28089 soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod, 28090 GE_PORT_BLOCK_MASKf, 28091 (ether) ? 1 : 0); 28092 } 28093 soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod, 28094 HIGIG_XGE_PORT_BLOCK_MASKf, 28095 xge_val); 28096 #if defined(BCM_RAPTOR_SUPPORT) 28097 if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm, 28098 PORT_0_5_BLOCK_MASKf)) { 28099 rp_val = (SOC_PBMP_WORD_GET(mod_pbmp, 0)) & 28100 ((1 << soc_reg_field_length(unit, SRC_MODID_BLOCKm, 28101 PORT_0_5_BLOCK_MASKf )) - 1); 28102 soc_SRC_MODID_BLOCKm_field32_set(unit, &srcmod, 28103 PORT_0_5_BLOCK_MASKf, 28104 rp_val); 28105 } 28106 #endif /* BCM_RAPTOR_SUPPORT */ 28107 rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL, 28108 idx, &srcmod); 28109 } 28110 } 28111 } 28112 soc_mem_unlock(unit, SRC_MODID_BLOCKm); 28113 } 28114 #endif /* BCM_FIREBOLT_SUPPORT */ 28115 28116 return rv; 28117 #else 28118 return BCM_E_UNAVAIL; 28119 #endif /* BCM_HERCULES15_SUPPORT || BCM_FIREBOLT_SUPPORT */ 28120 } 28121 28122 /* 28123 * Function: 28124 * bcm_port_modid_egress_get 28125 * Description: 28126 * Retrieve port bitmap of egress ports on which the incoming packets 28127 * will be forwarded. 28128 * Parameters: 28129 * unit - StrataSwitch PCI device unit number (driver internal). 28130 * port - ingress port number. 28131 * modid - source module ID index (in HiGig mod header). 28132 * pbmp - (OUT) bitmap of ports where egress allowed. 28133 * Returns: 28134 * BCM_E_xxxx 28135 */ 28136 int 28137 bcm_esw_port_modid_egress_get(int unit, bcm_port_t port, 28138 bcm_module_t modid, bcm_pbmp_t *pbmp) 28139 { 28140 #if defined(BCM_HERCULES15_SUPPORT) || defined(BCM_FIREBOLT_SUPPORT) 28141 int rv=BCM_E_UNAVAIL; 28142 28143 /* Make sure port module is initialized. */ 28144 PORT_INIT(unit); 28145 28146 #ifdef BCM_HERCULES15_SUPPORT 28147 if (SOC_IS_HERCULES15(unit)) { 28148 mem_ing_srcmodblk_entry_t srcmod; 28149 bcm_module_t min_mod, max_mod; 28150 int blk, rv=BCM_E_NONE; 28151 28152 if (!SOC_PORT_VALID(unit, port) || !IS_HG_PORT(unit, port)) { 28153 return BCM_E_PORT; 28154 } 28155 28156 min_mod = soc_mem_index_min(unit, MEM_ING_SRCMODBLKm); 28157 max_mod = soc_mem_index_max(unit, MEM_ING_SRCMODBLKm); 28158 if ((modid < min_mod) || (modid > max_mod)) { 28159 return BCM_E_PARAM; 28160 } 28161 28162 blk = SOC_PORT_BLOCK(unit, port); 28163 SOC_PBMP_CLEAR(*pbmp); 28164 rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod); 28165 if (rv >= 0) { 28166 SOC_PBMP_WORD_SET(*pbmp, 0, 28167 soc_MEM_ING_SRCMODBLKm_field32_get(unit, &srcmod, BITMAPf)); 28168 } 28169 } 28170 #endif /* BCM_HERCULES15_SUPPORT */ 28171 28172 #ifdef BCM_TRIUMPH2_SUPPORT 28173 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 28174 SOC_IS_VALKYRIE2(unit) || SOC_IS_TD_TT(unit) || 28175 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 28176 src_modid_egress_entry_t srcmodegr; 28177 int idx; 28178 _bcm_port_egr_dest_t egr_dst; 28179 bcm_pbmp_t all_pbmp; 28180 28181 SOC_PBMP_CLEAR(all_pbmp); 28182 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 28183 28184 #ifdef BCM_KATANA2_SUPPORT 28185 if (soc_feature(unit, soc_feature_linkphy_coe) || 28186 soc_feature(unit, soc_feature_subtag_coe)) { 28187 _bcm_kt2_subport_pbmp_update(unit, &all_pbmp); 28188 } 28189 #endif 28190 28191 egr_dst.in_port = port; 28192 egr_dst.in_modid = modid; 28193 BCM_IF_ERROR_RETURN( 28194 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28195 28196 if (egr_dst.out_min_modid != egr_dst.out_max_modid) { 28197 return BCM_E_PARAM; 28198 } 28199 if (egr_dst.out_max_port != egr_dst.out_min_port) { 28200 return BCM_E_PORT; 28201 } 28202 28203 idx = PORT_SRC_MOD_EGR_PROF_PTR(unit, egr_dst.out_min_port) * 28204 (SOC_MODID_MAX(unit) + 1) + egr_dst.out_min_modid; 28205 SOC_IF_ERROR_RETURN(READ_SRC_MODID_EGRESSm(unit, MEM_BLOCK_ANY, idx, 28206 &srcmodegr)); 28207 soc_mem_pbmp_field_get(unit, SRC_MODID_EGRESSm, &srcmodegr, 28208 PORT_BLOCK_MASK_BITMAPf, pbmp); 28209 BCM_PBMP_NEGATE(*pbmp, *pbmp); 28210 BCM_PBMP_AND(*pbmp, all_pbmp); 28211 BCM_PBMP_REMOVE(*pbmp, PBMP_LB(unit)); 28212 return SOC_E_NONE; 28213 } 28214 #endif 28215 28216 #ifdef BCM_TRX_SUPPORT 28217 if (SOC_IS_TRX(unit)) { 28218 src_modid_block_entry_t srcmod; 28219 int hg_port, idx; 28220 _bcm_port_egr_dest_t egr_dst; 28221 28222 egr_dst.in_port = port; 28223 egr_dst.in_modid = modid; 28224 BCM_IF_ERROR_RETURN( 28225 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28226 28227 if (egr_dst.out_min_modid != egr_dst.out_max_modid) { 28228 return BCM_E_PARAM; 28229 } 28230 if (egr_dst.out_max_port != egr_dst.out_min_port) { 28231 return BCM_E_PORT; 28232 } 28233 28234 /* process to retrieve hg_port index from port */ 28235 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 28236 SOC_IS_GREYHOUND2(unit)) { 28237 hg_port = egr_dst.out_min_port; 28238 } else { 28239 SOC_IF_ERROR_RETURN( 28240 soc_xgs3_port_num_to_higig_port_num(unit, 28241 egr_dst.out_min_port, &hg_port)); 28242 } 28243 28244 idx = hg_port * (SOC_MODID_MAX(unit) + 1) + egr_dst.out_min_modid; 28245 SOC_IF_ERROR_RETURN(READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, 28246 &srcmod)); 28247 soc_SRC_MODID_BLOCKm_field_get(unit, &srcmod, PORT_BLOCK_MASK_BITMAPf, 28248 (uint32 *)pbmp); 28249 BCM_PBMP_NEGATE(*pbmp, *pbmp); 28250 BCM_PBMP_AND(*pbmp, PBMP_ALL(unit)); 28251 28252 return SOC_E_NONE; 28253 } 28254 #endif 28255 28256 #ifdef BCM_FIREBOLT_SUPPORT 28257 if (soc_feature(unit, soc_feature_src_modid_blk)) { 28258 src_modid_block_entry_t srcmod; 28259 int modid_cnt, p_idx, idx; 28260 _bcm_port_egr_dest_t egr_dst; 28261 28262 egr_dst.in_port = port; 28263 egr_dst.in_modid = modid; 28264 BCM_IF_ERROR_RETURN( 28265 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28266 28267 if (egr_dst.out_min_modid != egr_dst.out_max_modid) { 28268 return BCM_E_PARAM; 28269 } 28270 if (egr_dst.out_max_port != egr_dst.out_min_port) { 28271 return BCM_E_PORT; 28272 } 28273 28274 modid_cnt = SOC_MODID_MAX(unit) + 1; 28275 p_idx = egr_dst.out_min_port - SOC_HG_OFFSET(unit); 28276 if (SOC_IS_RAVEN(unit) && p_idx >= 4) { 28277 idx = (p_idx - 1) * modid_cnt + egr_dst.out_min_modid; 28278 } else { 28279 idx = (p_idx * modid_cnt) + egr_dst.out_min_modid; 28280 } 28281 28282 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod); 28283 BCM_PBMP_CLEAR(*pbmp); 28284 if (rv >= 0) { 28285 int cpu, ether; 28286 pbmp_t hg_pbmp; 28287 uint32 xge_val; 28288 #if defined(BCM_RAPTOR_SUPPORT) 28289 uint32 rp_val; 28290 #endif /* BCM_RAPTOR_SUPPORT */ 28291 cpu = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod, 28292 CPU_PORT_BLOCK_MASKf); 28293 if (SOC_IS_FB_FX_HX(unit)) { 28294 ether = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod, 28295 GE_PORT_BLOCK_MASKf); 28296 } else { 28297 ether = 0; 28298 } 28299 xge_val = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod, 28300 HIGIG_XGE_PORT_BLOCK_MASKf); 28301 SOC_PBMP_CLEAR(hg_pbmp); 28302 SOC_PBMP_WORD_SET(hg_pbmp, 0, xge_val << SOC_HG_OFFSET(unit)); 28303 28304 #if defined(BCM_RAPTOR_SUPPORT) 28305 if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm, 28306 PORT_0_5_BLOCK_MASKf)) { 28307 rp_val = soc_SRC_MODID_BLOCKm_field32_get(unit, &srcmod, 28308 PORT_0_5_BLOCK_MASKf); 28309 SOC_PBMP_WORD_SET(hg_pbmp, 0, rp_val); 28310 } 28311 #endif /* BCM_RAPTOR_SUPPORT */ 28312 BCM_PBMP_ASSIGN(*pbmp, PBMP_ALL(unit)); 28313 if (cpu) { 28314 BCM_PBMP_REMOVE(*pbmp, PBMP_CMIC(unit)); 28315 } 28316 if (ether) { 28317 BCM_PBMP_REMOVE(*pbmp, PBMP_E_ALL(unit)); 28318 } 28319 if (BCM_PBMP_NOT_NULL(hg_pbmp)) { 28320 BCM_PBMP_REMOVE(*pbmp, hg_pbmp); 28321 } 28322 } 28323 } 28324 #endif /* BCM_FIREBOLT_SUPPORT */ 28325 28326 return rv; 28327 #else 28328 return BCM_E_UNAVAIL; 28329 #endif /* BCM_HERCULES15_SUPPORT || BCM_FIREBOLT_SUPPORT */ 28330 } 28331 28332 /* 28333 * Function: 28334 * bcm_port_modid_enable_set 28335 * Purpose: 28336 * Enable/block packets from a specific module on a port. 28337 * Parameters: 28338 * unit - StrataSwitch PCI device unit number (driver internal). 28339 * port - StrataSwitch port number. 28340 * modid - Which source module id to enable/disable 28341 * enable - TRUE/FALSE Enable/disable forwarding packets from 28342 * source module arriving on port. 28343 * Returns: 28344 * BCM_E_XXX 28345 */ 28346 int 28347 bcm_esw_port_modid_enable_set(int unit, bcm_port_t port, int modid, int enable) 28348 { 28349 int max_mod; 28350 #ifdef BCM_HERCULES_SUPPORT 28351 uint32 smf, osmf; 28352 #endif /* BCM_HERCULES_SUPPORT */ 28353 #ifdef BCM_HERCULES1_SUPPORT 28354 uint32 mask; 28355 #endif /* BCM_HERCULES1_SUPPORT */ 28356 #ifdef BCM_HERCULES15_SUPPORT 28357 mem_ing_srcmodblk_entry_t srcmod; 28358 int blk; 28359 #endif /* BCM_HERCULES15_SUPPORT */ 28360 #if defined(BCM_HERCULES15_SUPPORT) || defined(BCM_FIREBOLT_SUPPORT) 28361 int rv=BCM_E_NONE; 28362 #endif /* BCM_HERCULES15_SUPPORT || BCM_FIREBOLT_SUPPORT */ 28363 28364 /* Make sure port module is initialized. */ 28365 PORT_INIT(unit); 28366 28367 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 28368 28369 #ifdef BCM_TRX_SUPPORT 28370 if (SOC_IS_TRX(unit)) { 28371 src_modid_ingress_block_entry_t srcmoding; 28372 src_modid_block_entry_t srcmod; 28373 int modid_cnt, hg_port, idx, i; 28374 bcm_pbmp_t pbmp; 28375 _bcm_port_egr_dest_t egr_dst; 28376 28377 egr_dst.in_port = port; 28378 egr_dst.in_modid = modid; 28379 BCM_IF_ERROR_RETURN( 28380 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28381 28382 if (egr_dst.out_max_port != egr_dst.out_min_port) { 28383 return BCM_E_PORT; 28384 } 28385 28386 if (!IS_E_PORT(unit, egr_dst.out_max_port) && 28387 !IS_ST_PORT(unit, egr_dst.out_max_port)) { 28388 return BCM_E_PORT; 28389 } 28390 28391 28392 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 28393 SOC_IS_VALKYRIE2(unit) || SOC_IS_TD_TT(unit) || 28394 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 28395 soc_mem_lock(unit, SRC_MODID_INGRESS_BLOCKm); 28396 for (i = egr_dst.out_min_modid; i <= egr_dst.out_max_modid; i++) { 28397 rv = READ_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ANY, i, 28398 &srcmoding); 28399 if (rv >= 0) { 28400 soc_mem_pbmp_field_get(unit, SRC_MODID_INGRESS_BLOCKm, 28401 &srcmoding, PORT_BITMAPf, &pbmp); 28402 if (enable) { 28403 BCM_PBMP_PORT_REMOVE(pbmp, egr_dst.out_max_port); 28404 } else { 28405 BCM_PBMP_PORT_ADD(pbmp, egr_dst.out_max_port); 28406 } 28407 soc_mem_pbmp_field_set(unit, SRC_MODID_INGRESS_BLOCKm, 28408 &srcmoding, PORT_BITMAPf, &pbmp); 28409 rv = WRITE_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ALL, i, 28410 &srcmoding); 28411 } 28412 if (rv < 0) { 28413 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm); 28414 return rv; 28415 } 28416 } 28417 soc_mem_unlock(unit, SRC_MODID_INGRESS_BLOCKm); 28418 } else { 28419 modid_cnt = SOC_MODID_MAX(unit) + 1; 28420 28421 /* process to retrieve hg_port index from port */ 28422 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 28423 SOC_IS_GREYHOUND2(unit)) { 28424 hg_port = port; 28425 } else { 28426 SOC_IF_ERROR_RETURN( 28427 soc_xgs3_port_num_to_higig_port_num(unit, port, &hg_port)); 28428 } 28429 28430 soc_mem_lock(unit, SRC_MODID_BLOCKm); 28431 for (i = egr_dst.out_min_modid; i <= egr_dst.out_max_modid; i++) { 28432 idx = hg_port * modid_cnt + i; 28433 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &srcmod); 28434 if (rv >= 0) { 28435 if (!enable) { 28436 SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 28437 } else { 28438 SOC_PBMP_CLEAR(pbmp); 28439 } 28440 soc_mem_pbmp_field_set(unit, SRC_MODID_BLOCKm, &srcmod, 28441 PORT_BLOCK_MASK_BITMAPf,&pbmp); 28442 rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL, idx, &srcmod); 28443 } 28444 if (rv < 0) { 28445 soc_mem_unlock(unit, SRC_MODID_BLOCKm); 28446 return rv; 28447 } 28448 } 28449 soc_mem_unlock(unit, SRC_MODID_BLOCKm); 28450 } 28451 return rv; 28452 } 28453 #endif /* BCM_TRX_SUPPORT */ 28454 28455 #ifdef BCM_FIREBOLT_SUPPORT 28456 if (soc_feature(unit, soc_feature_src_modid_blk)) { 28457 src_modid_block_entry_t src_mod; 28458 int modid_cnt, mod_idx, p_idx, idx, val; 28459 _bcm_port_egr_dest_t egr_dst; 28460 28461 egr_dst.in_port = port; 28462 egr_dst.in_modid = modid; 28463 BCM_IF_ERROR_RETURN( 28464 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28465 28466 if (egr_dst.out_max_port != egr_dst.out_min_port) { 28467 return BCM_E_PORT; 28468 } 28469 28470 modid_cnt = SOC_MODID_MAX(unit) + 1; 28471 p_idx = egr_dst.out_min_port - SOC_HG_OFFSET(unit); 28472 soc_mem_lock(unit, SRC_MODID_BLOCKm); 28473 for (mod_idx = egr_dst.out_min_modid; mod_idx <= egr_dst.out_max_modid; mod_idx++) { 28474 sal_memset(&src_mod, 0, sizeof(src_mod)); 28475 if (SOC_IS_RAVEN(unit) && p_idx >= 4) { 28476 idx = (p_idx - 1) * modid_cnt + mod_idx; 28477 } else { 28478 idx = (p_idx * modid_cnt) + mod_idx; 28479 } 28480 rv = READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, &src_mod); 28481 if (rv >= 0) { 28482 soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod, 28483 CPU_PORT_BLOCK_MASKf, 28484 (enable) ? 0 : 1); 28485 if (SOC_IS_FB_FX_HX(unit)) { 28486 soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod, 28487 GE_PORT_BLOCK_MASKf, 28488 (enable) ? 0 : 1); 28489 } 28490 28491 val = (1 << soc_mem_field_length(unit, SRC_MODID_BLOCKm, 28492 HIGIG_XGE_PORT_BLOCK_MASKf)) - 1; 28493 28494 soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod, 28495 HIGIG_XGE_PORT_BLOCK_MASKf, 28496 (enable) ? 0 : val); 28497 #if defined(BCM_RAPTOR_SUPPORT) 28498 if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm, 28499 PORT_0_5_BLOCK_MASKf)) { 28500 28501 val = (1 << soc_mem_field_length(unit, SRC_MODID_BLOCKm, 28502 PORT_0_5_BLOCK_MASKf)) - 1; 28503 28504 soc_SRC_MODID_BLOCKm_field32_set(unit, &src_mod, 28505 PORT_0_5_BLOCK_MASKf, 28506 (enable) ? 0 : val); 28507 28508 } 28509 #endif /* BCM_RAPTOR_SUPPORT */ 28510 rv = WRITE_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ALL, 28511 idx, &src_mod); 28512 } 28513 } 28514 soc_mem_unlock(unit, SRC_MODID_BLOCKm); 28515 28516 return rv; 28517 } 28518 #endif /* BCM_FIREBOLT_SUPPORT */ 28519 28520 if (!IS_PORT(unit, port)) { 28521 return BCM_E_PORT; 28522 } 28523 28524 if (!soc_feature(unit, soc_feature_srcmod_filter)) { 28525 if (enable) { 28526 return BCM_E_NONE; 28527 } else { 28528 return BCM_E_UNAVAIL; 28529 } 28530 } 28531 28532 max_mod = 128; 28533 if (modid >= max_mod) { 28534 return BCM_E_PARAM; 28535 } 28536 28537 #ifdef BCM_HERCULES15_SUPPORT 28538 if (SOC_IS_HERCULES15(unit)) { 28539 blk = SOC_PORT_BLOCK(unit, port); 28540 soc_mem_lock(unit, MEM_ING_SRCMODBLKm); 28541 if (modid < 0) { 28542 for (modid = 0; modid < max_mod; modid++) { 28543 rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod); 28544 if (rv < 0) { 28545 break; 28546 } 28547 soc_MEM_ING_SRCMODBLKm_field_get(unit, &srcmod, BITMAPf, 28548 &osmf); 28549 smf = (enable) ? SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0) : 0; 28550 if (osmf != smf) { 28551 soc_MEM_ING_SRCMODBLKm_field_set(unit, &srcmod, BITMAPf, 28552 &smf); 28553 rv = WRITE_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod); 28554 if (rv < 0) { 28555 break; 28556 } 28557 } 28558 } 28559 } else { 28560 rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod); 28561 if (rv >= 0) { 28562 soc_MEM_ING_SRCMODBLKm_field_get(unit, &srcmod, BITMAPf, 28563 &osmf); 28564 smf = (enable) ? SOC_PBMP_WORD_GET(PBMP_ALL(unit), 0) : 0; 28565 if (osmf != smf) { 28566 soc_MEM_ING_SRCMODBLKm_field_set(unit, &srcmod, BITMAPf, 28567 &smf); 28568 rv = WRITE_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod); 28569 } 28570 } 28571 } 28572 soc_mem_unlock(unit, MEM_ING_SRCMODBLKm); 28573 } 28574 #endif /* BCM_HERCULES15_SUPPORT */ 28575 28576 return BCM_E_NONE; 28577 } 28578 28579 /* 28580 * Function: 28581 * bcm_port_modid_enable_get 28582 * Purpose: 28583 * Return enable/block state for a specific module on a port. 28584 * Parameters: 28585 * unit - StrataSwitch PCI device unit number (driver internal). 28586 * port - StrataSwitch port number. 28587 * modid - Which source module id to enable/disable 28588 * enable - (OUT) TRUE/FALSE Enable/disable forwarding packets from 28589 * source module arriving on port. 28590 * Returns: 28591 * BCM_E_XXX 28592 */ 28593 int 28594 bcm_esw_port_modid_enable_get(int unit, bcm_port_t port, int modid, int *enable) 28595 { 28596 int max_mod; 28597 #ifdef BCM_HERCULES_SUPPORT 28598 uint32 smf; 28599 #endif /* BCM_HERCULES_SUPPORT */ 28600 #ifdef BCM_HERCULES1_SUPPORT 28601 uint32 mask; 28602 #endif /* BCM_HERCULES1_SUPPORT */ 28603 #ifdef BCM_HERCULES15_SUPPORT 28604 mem_ing_srcmodblk_entry_t srcmod; 28605 int blk, rv; 28606 #endif /* BCM_HERCULES15_SUPPORT */ 28607 28608 /* Make sure port module is initialized. */ 28609 PORT_INIT(unit); 28610 28611 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 28612 28613 #ifdef BCM_TRX_SUPPORT 28614 if (SOC_IS_TRX(unit)) { 28615 src_modid_ingress_block_entry_t srcmoding; 28616 src_modid_block_entry_t srcmod; 28617 int hg_port, idx; 28618 bcm_pbmp_t pbmp; 28619 _bcm_port_egr_dest_t egr_dst; 28620 28621 egr_dst.in_port = port; 28622 egr_dst.in_modid = modid; 28623 BCM_IF_ERROR_RETURN( 28624 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28625 28626 if (egr_dst.out_max_port != egr_dst.out_min_port) { 28627 return BCM_E_PORT; 28628 } 28629 if (egr_dst.out_max_modid != egr_dst.out_min_modid) { 28630 return BCM_E_PARAM; 28631 } 28632 28633 if (!IS_E_PORT(unit, egr_dst.out_max_port) && 28634 !IS_ST_PORT(unit, egr_dst.out_max_port)) { 28635 return BCM_E_PORT; 28636 } 28637 28638 SOC_PBMP_CLEAR(pbmp); 28639 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 28640 SOC_IS_VALKYRIE2(unit) || SOC_IS_TD_TT(unit) || 28641 SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANAX(unit)) { 28642 SOC_IF_ERROR_RETURN( 28643 READ_SRC_MODID_INGRESS_BLOCKm(unit, MEM_BLOCK_ANY, 28644 egr_dst.out_min_modid, &srcmoding)); 28645 soc_mem_pbmp_field_get(unit, SRC_MODID_INGRESS_BLOCKm, 28646 &srcmoding, PORT_BITMAPf, &pbmp); 28647 } else { 28648 /* process to retrieve hg_port index from port */ 28649 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 28650 SOC_IS_GREYHOUND2(unit)) { 28651 hg_port = egr_dst.out_min_port; 28652 } else { 28653 SOC_IF_ERROR_RETURN(soc_xgs3_port_num_to_higig_port_num(unit, 28654 egr_dst.out_min_port, &hg_port)); 28655 } 28656 28657 idx = hg_port * (SOC_MODID_MAX(unit) + 1) + egr_dst.out_min_modid; 28658 SOC_IF_ERROR_RETURN(READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, idx, 28659 &srcmod)); 28660 soc_mem_pbmp_field_get(unit, SRC_MODID_BLOCKm, &srcmod, 28661 PORT_BLOCK_MASK_BITMAPf, &pbmp); 28662 } 28663 28664 *enable = !SOC_PBMP_MEMBER(pbmp, egr_dst.out_max_port); 28665 28666 return BCM_E_NONE; 28667 } 28668 #endif /* BCM_TRIUMPH_SUPPORT */ 28669 28670 #ifdef BCM_FIREBOLT_SUPPORT 28671 if (soc_feature(unit, soc_feature_src_modid_blk)) { 28672 uint32 config; 28673 src_modid_block_entry_t src_mod; 28674 int gable, modid_cnt, p_idx, idx; 28675 _bcm_port_egr_dest_t egr_dst; 28676 28677 egr_dst.in_port = port; 28678 egr_dst.in_modid = modid; 28679 BCM_IF_ERROR_RETURN( 28680 _bcm_esw_port_modid_egress_resolve(unit, &egr_dst)); 28681 28682 if (egr_dst.out_max_port != egr_dst.out_min_port) { 28683 return BCM_E_PORT; 28684 } 28685 if (egr_dst.out_max_modid != egr_dst.out_min_modid) { 28686 return BCM_E_PARAM; 28687 } 28688 28689 SOC_IF_ERROR_RETURN(READ_ING_CONFIGr(unit, &config)); 28690 gable = !soc_reg_field_get(unit, ING_CONFIGr, config, 28691 FB_A0_COMPATIBLEf); 28692 if (gable) { 28693 modid_cnt = SOC_MODID_MAX(unit) + 1; 28694 p_idx = egr_dst.out_min_port - SOC_HG_OFFSET(unit); 28695 if (SOC_IS_RAVEN(unit) && p_idx >= 4) { 28696 idx = (p_idx - 1) * modid_cnt + egr_dst.out_min_modid; 28697 } else { 28698 idx = (p_idx * modid_cnt) + egr_dst.out_min_modid; 28699 } 28700 SOC_IF_ERROR_RETURN 28701 (READ_SRC_MODID_BLOCKm(unit, MEM_BLOCK_ANY, 28702 idx, &src_mod)); 28703 *enable = (soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod, 28704 CPU_PORT_BLOCK_MASKf) | 28705 soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod, 28706 HIGIG_XGE_PORT_BLOCK_MASKf) 28707 ) ? 0 : 1; 28708 if (SOC_IS_FB_FX_HX(unit)) { 28709 *enable = (soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod, 28710 GE_PORT_BLOCK_MASKf) 28711 ) ? 0 : 1; 28712 } 28713 28714 #if defined(BCM_RAPTOR_SUPPORT) 28715 if (soc_mem_field_valid(unit, SRC_MODID_BLOCKm, 28716 PORT_0_5_BLOCK_MASKf)) { 28717 *enable = (soc_SRC_MODID_BLOCKm_field32_get(unit, &src_mod, 28718 PORT_0_5_BLOCK_MASKf) 28719 ) ? 0 : 1; 28720 } 28721 #endif /* BCM_RAPTOR_SUPPORT */ 28722 28723 } else { 28724 *enable = gable; 28725 } 28726 28727 return BCM_E_NONE; 28728 } 28729 #endif /* BCM_FIREBOLT_SUPPORT */ 28730 28731 if (!IS_PORT(unit, port)) { 28732 return BCM_E_PORT; 28733 } 28734 28735 if (!soc_feature(unit, soc_feature_srcmod_filter)) { 28736 *enable = TRUE; 28737 return BCM_E_NONE; 28738 } 28739 28740 max_mod = 128; 28741 if (!((modid >= 0) && (modid < max_mod))) { 28742 return BCM_E_PARAM; 28743 } 28744 28745 #ifdef BCM_HERCULES15_SUPPORT 28746 if (SOC_IS_HERCULES15(unit)) { 28747 blk = SOC_PORT_BLOCK(unit, port); 28748 rv = READ_MEM_ING_SRCMODBLKm(unit, blk, modid, &srcmod); 28749 if (rv >= 0) { 28750 soc_MEM_ING_SRCMODBLKm_field_get(unit, &srcmod, BITMAPf, &smf); 28751 *enable = (smf & SOC_PBMP_WORD_GET(PBMP_ALL(unit),0)) ? 1 : 0; 28752 } 28753 } 28754 #endif /* BCM_HERCULES15_SUPPORT */ 28755 28756 return BCM_E_NONE; 28757 } 28758 28759 28760 /* 28761 * Function: 28762 * _bcm_port_flood_block_op 28763 * Purpose: 28764 * Set or get port membership in one of the egress block registers 28765 * Parameters: 28766 * unit 28767 * set_op - TRUE for set, FALSE for get 28768 * ingress_port - ingress port on which the egress blocking 28769 * will be enabled 28770 * egress_port - port for which egress will be blocked 28771 * mode - BCM_PORT_FLOOD_BLOCK_XXX 28772 * enable - Whether blocking should be enabled or disabled 28773 * This is also BCM_PORT_FLOOD_BLOCK_XXX 28774 * Returns: 28775 * BCM_E_UNAVAIL - This chip does not support this feature 28776 * BCM_E_NONE 28777 */ 28778 STATIC int 28779 _bcm_port_flood_block_op(int unit, int set_op, 28780 bcm_port_t ingress_port, bcm_port_t egress_port, 28781 uint32 mode, uint32 *enable) 28782 { 28783 soc_reg_t reg, mask_reg[2], mask_hi_reg[2]; 28784 soc_mem_t mem; 28785 soc_field_t field; 28786 uint64 rval; 28787 uint32 fval; 28788 uint32 entry[SOC_MAX_MEM_WORDS]; 28789 pbmp_t pbmp; 28790 int index; 28791 int cpu_hg_index = 0; 28792 28793 mask_reg[0] = mask_reg[1] = INVALIDr; 28794 mask_hi_reg[0] = mask_hi_reg[1] = INVALIDr; 28795 mem = INVALIDm; 28796 field = INVALIDf; 28797 28798 switch (mode) { 28799 case BCM_PORT_FLOOD_BLOCK_BCAST: 28800 if (SOC_MEM_IS_VALID(unit, BCAST_BLOCK_MASKm)) { 28801 mem = BCAST_BLOCK_MASKm; 28802 field = BLK_BITMAPf; 28803 /* coverity[result_independent_of_operands] */ 28804 } else if (SOC_REG_IS_VALID(unit, BCAST_BLOCK_MASK_64r)) { 28805 mask_reg[0] = BCAST_BLOCK_MASK_64r; 28806 mask_reg[1] = IBCAST_BLOCK_MASK_64r; 28807 } else if (SOC_REG_IS_VALID(unit, BCAST_BLOCK_MASK_LO_64r)) { 28808 mask_reg[0] = BCAST_BLOCK_MASK_LO_64r; 28809 mask_reg[1] = IBCAST_BLOCK_MASK_LO_64r; 28810 mask_hi_reg[0] = BCAST_BLOCK_MASK_HI_64r; 28811 mask_hi_reg[1] = IBCAST_BLOCK_MASK_HI_64r; 28812 } else if (SOC_REG_IS_VALID(unit, BCAST_BLOCK_MASKr)) { 28813 mask_reg[0] = BCAST_BLOCK_MASKr; 28814 mask_reg[1] = IBCAST_BLOCK_MASKr; 28815 } else { 28816 return BCM_E_UNAVAIL; 28817 } 28818 break; 28819 case BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST: 28820 if (SOC_MEM_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASKm)) { 28821 mem = UNKNOWN_UCAST_BLOCK_MASKm; 28822 field = BLK_BITMAPf; 28823 } else if (SOC_REG_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASK_64r)) { 28824 mask_reg[0] = UNKNOWN_UCAST_BLOCK_MASK_64r; 28825 mask_reg[1] = IUNKNOWN_UCAST_BLOCK_MASK_64r; 28826 } else if (SOC_REG_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASK_LO_64r)) { 28827 mask_reg[0] = UNKNOWN_UCAST_BLOCK_MASK_LO_64r; 28828 mask_reg[1] = IUNKNOWN_UCAST_BLOCK_MASK_LO_64r; 28829 mask_hi_reg[0] = UNKNOWN_UCAST_BLOCK_MASK_HI_64r; 28830 mask_hi_reg[1] = IUNKNOWN_UCAST_BLOCK_MASK_HI_64r; 28831 } else if (SOC_REG_IS_VALID(unit, UNKNOWN_UCAST_BLOCK_MASKr)) { 28832 mask_reg[0] = UNKNOWN_UCAST_BLOCK_MASKr; 28833 mask_reg[1] = IUNKNOWN_UCAST_BLOCK_MASKr; 28834 } else { 28835 return BCM_E_UNAVAIL; 28836 } 28837 break; 28838 case BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST: 28839 if (SOC_MEM_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASKm)) { 28840 mem = UNKNOWN_MCAST_BLOCK_MASKm; 28841 field = BLK_BITMAPf; 28842 } else if (SOC_REG_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASK_64r)) { 28843 mask_reg[0] = UNKNOWN_MCAST_BLOCK_MASK_64r; 28844 mask_reg[1] = IUNKNOWN_MCAST_BLOCK_MASK_64r; 28845 } else if (SOC_REG_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASK_LO_64r)) { 28846 mask_reg[0] = UNKNOWN_MCAST_BLOCK_MASK_LO_64r; 28847 mask_reg[1] = IUNKNOWN_MCAST_BLOCK_MASK_LO_64r; 28848 mask_hi_reg[0] = UNKNOWN_MCAST_BLOCK_MASK_HI_64r; 28849 mask_hi_reg[1] = IUNKNOWN_MCAST_BLOCK_MASK_HI_64r; 28850 } else if (SOC_REG_IS_VALID(unit, UNKNOWN_MCAST_BLOCK_MASKr)) { 28851 mask_reg[0] = UNKNOWN_MCAST_BLOCK_MASKr; 28852 mask_reg[1] = IUNKNOWN_MCAST_BLOCK_MASKr; 28853 } else { 28854 return BCM_E_UNAVAIL; 28855 } 28856 break; 28857 case BCM_PORT_FLOOD_BLOCK_KNOWN_MCAST: 28858 if (SOC_MEM_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASKm)) { 28859 mem = KNOWN_MCAST_BLOCK_MASKm; 28860 field = BLK_BITMAPf; 28861 } else if (SOC_REG_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASK_64r)) { 28862 mask_reg[0] = KNOWN_MCAST_BLOCK_MASK_64r; 28863 mask_reg[1] = IKNOWN_MCAST_BLOCK_MASK_64r; 28864 } else if (SOC_REG_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASK_LOr)) { 28865 mask_reg[0] = KNOWN_MCAST_BLOCK_MASK_LOr; 28866 mask_reg[1] = IKNOWN_MCAST_BLOCK_MASK_LOr; 28867 mask_hi_reg[0] = KNOWN_MCAST_BLOCK_MASK_HIr; 28868 mask_hi_reg[1] = IKNOWN_MCAST_BLOCK_MASK_HIr; 28869 } else if (SOC_REG_IS_VALID(unit, KNOWN_MCAST_BLOCK_MASKr)) { 28870 mask_reg[0] = KNOWN_MCAST_BLOCK_MASKr; 28871 mask_reg[1] = IKNOWN_MCAST_BLOCK_MASKr; 28872 } else { 28873 return BCM_E_UNAVAIL; 28874 } 28875 break; 28876 case BCM_PORT_FLOOD_BLOCK_ALL: 28877 if (SOC_MEM_IS_VALID(unit, ING_EGRMSKBMAPm)) { 28878 mem = ING_EGRMSKBMAPm; 28879 field = BITMAPf; 28880 } else if (SOC_REG_IS_VALID(unit, ING_EGRMSKBMAP_64r)) { 28881 mask_reg[0] = ING_EGRMSKBMAP_64r; 28882 mask_reg[1] = IING_EGRMSKBMAP_64r; 28883 } else if (SOC_REG_IS_VALID(unit, ING_EGRMSKBMAP_LOr)) { 28884 mask_reg[0] = ING_EGRMSKBMAP_LOr; 28885 mask_reg[1] = IING_EGRMSKBMAP_LOr; 28886 mask_hi_reg[0] = ING_EGRMSKBMAP_HIr; 28887 mask_hi_reg[1] = IING_EGRMSKBMAP_HIr; 28888 } else if (SOC_REG_IS_VALID(unit, ING_EGRMSKBMAPr)) { 28889 mask_reg[0] = ING_EGRMSKBMAPr; 28890 mask_reg[1] = IING_EGRMSKBMAPr; 28891 } else { 28892 return BCM_E_UNAVAIL; 28893 } 28894 break; 28895 default: 28896 return BCM_E_INTERNAL; 28897 } 28898 28899 if (mem != INVALIDm) { 28900 BCM_IF_ERROR_RETURN 28901 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, ingress_port, entry)); 28902 soc_mem_pbmp_field_get(unit, mem, entry, field, &pbmp); 28903 if (!set_op) { 28904 *enable = SOC_PBMP_WORD_GET(pbmp, egress_port / 32) & 28905 (1 << (egress_port & 0x1f)) ? mode : 0; 28906 return BCM_E_NONE; 28907 } 28908 if (*enable & mode) { 28909 SOC_PBMP_PORT_ADD(pbmp, egress_port); 28910 } else { 28911 SOC_PBMP_PORT_REMOVE(pbmp, egress_port); 28912 } 28913 soc_mem_pbmp_field_set(unit, mem, entry, field, &pbmp); 28914 BCM_IF_ERROR_RETURN 28915 (soc_mem_write(unit, mem, MEM_BLOCK_ANY, ingress_port, entry)); 28916 28917 cpu_hg_index = SOC_IS_KATANA2(unit) ? 28918 SOC_INFO(unit).cpu_hg_pp_port_index : 28919 SOC_INFO(unit).cpu_hg_index; 28920 if (IS_CPU_PORT(unit, ingress_port) && cpu_hg_index != -1) { 28921 BCM_IF_ERROR_RETURN 28922 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, cpu_hg_index, entry)); 28923 soc_mem_pbmp_field_get(unit, mem, entry, field, &pbmp); 28924 if (*enable & mode) { 28925 SOC_PBMP_PORT_ADD(pbmp, egress_port); 28926 } else { 28927 SOC_PBMP_PORT_REMOVE(pbmp, egress_port); 28928 } 28929 soc_mem_pbmp_field_set(unit, mem, entry, field, &pbmp); 28930 BCM_IF_ERROR_RETURN 28931 (soc_mem_write(unit, mem, MEM_BLOCK_ANY, cpu_hg_index, entry)); 28932 } 28933 } else { 28934 if (!IS_CPU_PORT(unit, ingress_port)) { 28935 if (IS_ST_PORT(unit, ingress_port)) { 28936 mask_reg[0] = INVALIDr; 28937 mask_hi_reg[0] = INVALIDr; 28938 } else { 28939 mask_reg[1] = INVALIDr; 28940 mask_hi_reg[1] = INVALIDr; 28941 } 28942 } 28943 28944 for (index = 0; index < 2; index++) { 28945 if (soc_feature (unit, soc_feature_high_portcount_register)) { 28946 uint64 fval64, rval64; 28947 uint32 t_port; 28948 pbmp_t curr_pbmp; 28949 28950 /* 28951 * pbmp reg split to multiple reg due to high port count 28952 * example : 28953 * - BCAST_BLOCK_MASK_64r was split to 28954 * {BCAST_BLOCK_MASK_LO_64r + BCAST_BLOCK_MASK_HI_64r} 28955 * - ING_EGRMSKBMAP_64r was split to 28956 * {ING_EGRMSKBMAP_LOr + ING_EGRMSKBMAP_HIr} 28957 */ 28958 BCM_PBMP_CLEAR(curr_pbmp); 28959 COMPILER_64_ZERO(fval64); 28960 COMPILER_64_ZERO(rval64); 28961 28962 if (egress_port < 64) { 28963 reg = mask_reg[index]; 28964 t_port = egress_port; 28965 } else { 28966 reg = mask_hi_reg[index]; 28967 t_port = egress_port - 64; 28968 } 28969 field = BLK_BITMAPf; 28970 28971 if (SOC_REG_IS_VALID(unit, reg)) { 28972 BCM_IF_ERROR_RETURN(soc_reg_get(unit, 28973 reg, ingress_port, 0, &rval64)); 28974 28975 fval64 = soc_reg64_field_get(unit, reg, rval64, field); 28976 SOC_PBMP_WORD_SET(curr_pbmp, 0, COMPILER_64_LO(fval64)); 28977 SOC_PBMP_WORD_SET(curr_pbmp, 1, COMPILER_64_HI(fval64)); 28978 28979 if (!set_op) { 28980 /* for GET */ 28981 *enable = SOC_PBMP_MEMBER(curr_pbmp, t_port) ? mode : 0; 28982 } else { 28983 /* for SET */ 28984 if (*enable & mode) { 28985 SOC_PBMP_PORT_ADD(curr_pbmp, t_port); 28986 } else { 28987 SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port); 28988 } 28989 COMPILER_64_SET(fval64, 28990 SOC_PBMP_WORD_GET(curr_pbmp, 1), 28991 SOC_PBMP_WORD_GET(curr_pbmp, 0)); 28992 soc_reg64_field_set(unit, reg, 28993 &rval64, field, fval64); 28994 BCM_IF_ERROR_RETURN(soc_reg_set(unit, 28995 reg, ingress_port, 0, rval64)); 28996 } 28997 } 28998 } else { 28999 reg = mask_reg[index]; 29000 if (reg == INVALIDr) { 29001 continue; 29002 } 29003 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, ingress_port, 0, &rval)); 29004 if (SOC_REG_IS_64(unit, reg)) { 29005 if (egress_port < 32) { 29006 if (soc_reg_field_valid(unit, reg, BLK_BITMAP_LOf)) { 29007 field = BLK_BITMAP_LOf; 29008 } else { 29009 field = BLK_BITMAP_0f; 29010 } 29011 } else { 29012 if (soc_reg_field_valid(unit, reg, BLK_BITMAP_HIf)) { 29013 field = BLK_BITMAP_HIf; 29014 } else { 29015 field = BLK_BITMAP_1f; 29016 } 29017 } 29018 } else { 29019 field = BLK_BITMAPf; 29020 } 29021 fval = soc_reg64_field32_get(unit, reg, rval, field); 29022 if (!set_op) { 29023 *enable = fval & (1 << (egress_port & 0x1f)) ? mode : 0; 29024 return BCM_E_NONE; 29025 } 29026 if (*enable & mode) { 29027 fval |= 1 << (egress_port & 0x1f); 29028 } else { 29029 fval &= ~(1 << (egress_port & 0x1f)); 29030 } 29031 soc_reg64_field32_set(unit, reg, &rval, field, fval); 29032 BCM_IF_ERROR_RETURN(soc_reg_set(unit, reg, ingress_port, 0, rval)); 29033 } 29034 } 29035 } 29036 29037 return BCM_E_NONE; 29038 } 29039 29040 #if defined(BCM_RAPTOR_SUPPORT) 29041 /* 29042 * Function: 29043 * _bcm_port_flood_block_hi_set 29044 * Purpose: 29045 * Enable/disable port membership in one of the egress block registers 29046 * Parameters: 29047 * unit 29048 * ingress_port - ingress port on which the egress blocking 29049 * will be enabled 29050 * egress_port - port for which egress will be blocked 29051 * reg - egress block register. 29052 * enable - Whether blocking should be enabled or disabled 29053 * Returns: 29054 * BCM_E_UNAVAIL - This chip does not support this feature 29055 * BCM_E_NONE 29056 * Notes: 29057 * 'reg' must be one of BCAST_BLOCK_MASKr, 29058 * UNKNOWN_UCAST_BLOCK_MASKr, UNKNOWN_MCAST_BLOCK_MASKr, or 29059 * their Stack port variants. 29060 * 29061 * This function is a helper for bcm_port_flood_block_set() 29062 */ 29063 29064 STATIC int 29065 _bcm_port_flood_block_hi_set(int unit, 29066 bcm_port_t ingress_port, bcm_port_t egress_port, 29067 soc_reg_t reg, uint32 enable) 29068 { 29069 uint32 rval; 29070 pbmp_t pbmp; 29071 uint32 pbmp32; 29072 uint32 bitmap32, obitmap32; 29073 29074 if (!soc_feature(unit, soc_feature_register_hi)) { 29075 return BCM_E_UNAVAIL; 29076 } 29077 29078 SOC_PBMP_PORT_SET(pbmp, egress_port); 29079 pbmp32 = SOC_PBMP_WORD_GET(pbmp, 1); 29080 29081 if (!pbmp32) { 29082 return BCM_E_NONE; 29083 } 29084 29085 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, ingress_port, 0, &rval)); 29086 29087 obitmap32 = bitmap32 = soc_reg_field_get(unit, reg, rval, BLK_BITMAPf); 29088 if (enable) { 29089 bitmap32 |= pbmp32; 29090 } else { 29091 bitmap32 &= ~pbmp32; 29092 } 29093 29094 if (obitmap32 != bitmap32) { 29095 soc_reg_field_set(unit, reg, &rval, BLK_BITMAPf, bitmap32); 29096 return soc_reg32_set(unit, reg, ingress_port, 0, rval); 29097 } 29098 29099 return BCM_E_NONE; 29100 } 29101 29102 /* 29103 * Function: 29104 * _bcm_port_flood_block_hi_get 29105 * Purpose: 29106 * Retrieve the current state egress block state on a port 29107 * Parameters: 29108 * unit 29109 * ingress_port - ingress_port for which the state will be retreived 29110 * egress_port - port for which the egress blocking state 29111 * on ingress_port is requested 29112 * reg - block mask register 29113 * enable - (OUT) receives the block state 29114 * Returns: 29115 * BCM_E_UNAVAIL - Feature unavailable on this chip 29116 * BCM_E_NONE 29117 * Notes: 29118 * See _bcm_port_flood_block_hi_set() 29119 * This is a helper function for bcm_port_flood_block_get() 29120 */ 29121 29122 STATIC int 29123 _bcm_port_flood_block_hi_get(int unit, 29124 bcm_port_t ingress_port, bcm_port_t egress_port, 29125 soc_reg_t reg, uint32 *enable) 29126 { 29127 uint32 rval; 29128 pbmp_t pbmp; 29129 uint32 pbmp32; 29130 uint32 bitmap32; 29131 29132 if (!soc_feature(unit, soc_feature_register_hi)) { 29133 return BCM_E_UNAVAIL; 29134 } 29135 29136 SOC_PBMP_PORT_SET(pbmp, egress_port); 29137 pbmp32 = SOC_PBMP_WORD_GET(pbmp, 1); 29138 if (!pbmp32) { 29139 *enable = 0; 29140 return BCM_E_NONE; 29141 } 29142 29143 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, reg, ingress_port, 0, &rval)); 29144 29145 bitmap32 = soc_reg_field_get(unit, reg, rval, BLK_BITMAPf); 29146 *enable = (pbmp32 & bitmap32) ? 1 : 0; 29147 29148 return BCM_E_NONE; 29149 } 29150 #endif /* BCM_RAPTOR_SUPPORT */ 29151 29152 /* 29153 * Function: 29154 * bcm_port_flood_block_set 29155 * Purpose: 29156 * Set selective per-port blocking of flooded VLAN traffic 29157 * Parameters: 29158 * unit - unit number 29159 * ingress_port - Port traffic is ingressing 29160 * egress_port - Port for which the traffic should be blocked. 29161 * flags - Specifies the type of traffic to block 29162 * Returns: 29163 * BCM_E_UNAVAIL - Functionality not available 29164 * BCM_E_NONE 29165 * 29166 * NOTE: For fabrics, this changes egrmskbmap; as a result, all traffic 29167 * will be blocked (or enabled) to the given egress port, including 29168 * unicast traffic. 29169 */ 29170 29171 int 29172 bcm_esw_port_flood_block_set(int unit, 29173 bcm_port_t ingress_port, bcm_port_t egress_port, 29174 uint32 flags) 29175 { 29176 /* Make sure port module is initialized. */ 29177 PORT_INIT(unit); 29178 29179 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, ingress_port, 29180 &ingress_port)); 29181 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, egress_port, 29182 &egress_port)); 29183 29184 #if defined(BCM_XGS12_FABRIC_SUPPORT) 29185 /* See note above */ 29186 if (SOC_IS_XGS12_FABRIC(unit)) { 29187 uint32 ports, oports; 29188 pbmp_t pbmp; 29189 29190 if (!IS_HG_PORT(unit, ingress_port)) { 29191 return BCM_E_PORT; 29192 } 29193 29194 SOC_IF_ERROR_RETURN 29195 (READ_ING_EGRMSKBMAPr(unit, ingress_port, &ports)); 29196 oports = ports; 29197 SOC_PBMP_CLEAR(pbmp); 29198 SOC_PBMP_WORD_SET(pbmp, 0, ports); 29199 if (flags) { 29200 SOC_PBMP_PORT_REMOVE(pbmp, egress_port); 29201 } else { 29202 SOC_PBMP_PORT_ADD(pbmp, egress_port); 29203 } 29204 ports = SOC_PBMP_WORD_GET(pbmp, 0); 29205 if (ports != oports) { 29206 SOC_IF_ERROR_RETURN 29207 (WRITE_ING_EGRMSKBMAPr(unit, ingress_port, ports)); 29208 } 29209 return BCM_E_NONE; 29210 } 29211 #endif /* BCM_XGS12_FABRIC_SUPPORT */ 29212 29213 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 29214 || defined(BCM_BRADLEY_SUPPORT) 29215 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit)|| 29216 SOC_IS_HBX(unit) || SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) { 29217 BCM_IF_ERROR_RETURN 29218 (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port, 29219 BCM_PORT_FLOOD_BLOCK_ALL, &flags)); 29220 } 29221 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || \ 29222 BCM_BRADLEY_SUPPORT */ 29223 29224 BCM_IF_ERROR_RETURN 29225 (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port, 29226 BCM_PORT_FLOOD_BLOCK_BCAST, &flags)); 29227 29228 BCM_IF_ERROR_RETURN 29229 (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port, 29230 BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST, &flags)); 29231 29232 /* 29233 * For some devices like RAVEN , which do not have support for 29234 * blocking KNOWN_MCAST , continue processing. 29235 */ 29236 BCM_IF_ERROR_NOT_UNAVAIL_RETURN 29237 (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port, 29238 BCM_PORT_FLOOD_BLOCK_KNOWN_MCAST, &flags)); 29239 29240 BCM_IF_ERROR_RETURN 29241 (_bcm_port_flood_block_op(unit, TRUE, ingress_port, egress_port, 29242 BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST, &flags)); 29243 29244 /* 29245 * Handle the devices with > 32 ports that use _HI convention 29246 */ 29247 #if defined(BCM_RAPTOR_SUPPORT) 29248 if (soc_feature(unit, soc_feature_register_hi)){ 29249 soc_reg_t reg; 29250 uint32 enable; 29251 reg = IS_ST_PORT(unit, ingress_port) ? 29252 IUNKNOWN_UCAST_BLOCK_MASK_HIr : UNKNOWN_UCAST_BLOCK_MASK_HIr; 29253 enable = flags & BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST; 29254 BCM_IF_ERROR_RETURN 29255 (_bcm_port_flood_block_hi_set(unit, ingress_port, egress_port, 29256 reg, enable)); 29257 29258 reg = IS_ST_PORT(unit, ingress_port) ? 29259 IUNKNOWN_MCAST_BLOCK_MASK_HIr : UNKNOWN_MCAST_BLOCK_MASK_HIr; 29260 enable = flags & BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST; 29261 BCM_IF_ERROR_RETURN 29262 (_bcm_port_flood_block_hi_set(unit, ingress_port, egress_port, 29263 reg, enable)); 29264 29265 reg = IS_ST_PORT(unit, ingress_port) ? 29266 IBCAST_BLOCK_MASK_HIr : BCAST_BLOCK_MASK_HIr; 29267 enable = flags & BCM_PORT_FLOOD_BLOCK_BCAST; 29268 BCM_IF_ERROR_RETURN 29269 (_bcm_port_flood_block_hi_set(unit, ingress_port, egress_port, 29270 reg, enable)); 29271 } 29272 #endif /* BCM_RAPTOR_SUPPORT */ 29273 29274 return BCM_E_NONE; 29275 } 29276 29277 /* 29278 * Function: 29279 * bcm_port_flood_block_get 29280 * Purpose: 29281 * Get the current per-port flood block settings 29282 * Parameters: 29283 * unit - unit number 29284 * ingress_port - Port traffic is ingressing 29285 * egress_port - Port for which the traffic would be blocked 29286 * flags - (OUT) Returns the current settings 29287 * Returns: 29288 * BCM_E_UNAVAIL - Functionality not available 29289 * BCM_E_NONE 29290 */ 29291 29292 int 29293 bcm_esw_port_flood_block_get(int unit, 29294 bcm_port_t ingress_port, bcm_port_t egress_port, 29295 uint32 *flags) 29296 { 29297 uint32 enable; 29298 29299 /* Make sure port module is initialized. */ 29300 PORT_INIT(unit); 29301 29302 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, ingress_port, 29303 &ingress_port)); 29304 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, egress_port, 29305 &egress_port)); 29306 29307 *flags = 0; 29308 29309 #if defined(BCM_XGS12_FABRIC_SUPPORT) 29310 if (SOC_IS_XGS12_FABRIC(unit)) { 29311 uint32 ports; 29312 pbmp_t pbmp; 29313 29314 if (!IS_HG_PORT(unit, ingress_port)) { 29315 return BCM_E_PORT; 29316 } 29317 29318 SOC_IF_ERROR_RETURN 29319 (READ_ING_EGRMSKBMAPr(unit, ingress_port, &ports)); 29320 SOC_PBMP_CLEAR(pbmp); 29321 SOC_PBMP_WORD_SET(pbmp, 0, ports); 29322 if (!SOC_PBMP_MEMBER(pbmp, egress_port)) { 29323 *flags = -1; 29324 } 29325 return BCM_E_NONE; 29326 } 29327 #endif 29328 29329 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 29330 || defined(BCM_BRADLEY_SUPPORT) 29331 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit)|| 29332 SOC_IS_HBX(unit) || SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) { 29333 BCM_IF_ERROR_RETURN 29334 (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port, 29335 BCM_PORT_FLOOD_BLOCK_ALL, &enable)); 29336 *flags |= enable; 29337 } 29338 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_BRADLEY_SUPPORT */ 29339 29340 BCM_IF_ERROR_RETURN 29341 (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port, 29342 BCM_PORT_FLOOD_BLOCK_BCAST, &enable)); 29343 *flags |= enable; 29344 29345 BCM_IF_ERROR_RETURN 29346 (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port, 29347 BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST, 29348 &enable)); 29349 *flags |= enable; 29350 29351 /* 29352 * For some devices like RAVEN , which do not have support for 29353 * blocking KNOWN_MCAST , continue processing. 29354 */ 29355 BCM_IF_ERROR_NOT_UNAVAIL_RETURN 29356 (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port, 29357 BCM_PORT_FLOOD_BLOCK_KNOWN_MCAST, 29358 &enable)); 29359 *flags |= enable; 29360 29361 BCM_IF_ERROR_RETURN 29362 (_bcm_port_flood_block_op(unit, FALSE, ingress_port, egress_port, 29363 BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST, 29364 &enable)); 29365 *flags |= enable; 29366 29367 #if defined(BCM_RAPTOR_SUPPORT) 29368 if (soc_feature(unit, soc_feature_register_hi)){ 29369 soc_reg_t reg; 29370 reg = IS_ST_PORT(unit, ingress_port) ? 29371 IBCAST_BLOCK_MASK_HIr : BCAST_BLOCK_MASK_HIr; 29372 BCM_IF_ERROR_RETURN 29373 (_bcm_port_flood_block_hi_get(unit, ingress_port, egress_port, 29374 reg, &enable)); 29375 *flags |= (enable) ? BCM_PORT_FLOOD_BLOCK_BCAST : 0; 29376 29377 reg = IS_ST_PORT(unit, ingress_port) ? 29378 IUNKNOWN_MCAST_BLOCK_MASK_HIr : UNKNOWN_MCAST_BLOCK_MASK_HIr; 29379 BCM_IF_ERROR_RETURN 29380 (_bcm_port_flood_block_hi_get(unit, ingress_port, egress_port, 29381 reg, &enable)); 29382 *flags |= (enable) ? BCM_PORT_FLOOD_BLOCK_UNKNOWN_MCAST : 0; 29383 29384 reg = IS_ST_PORT(unit, ingress_port) ? 29385 IUNKNOWN_UCAST_BLOCK_MASK_HIr : UNKNOWN_UCAST_BLOCK_MASK_HIr; 29386 BCM_IF_ERROR_RETURN 29387 (_bcm_port_flood_block_hi_get(unit, ingress_port, egress_port, 29388 reg, &enable)); 29389 *flags |= (enable) ? BCM_PORT_FLOOD_BLOCK_UNKNOWN_UCAST : 0; 29390 } 29391 #endif /* BCM_RAPTOR_SUPPORT */ 29392 29393 return BCM_E_NONE; 29394 } 29395 29396 /* 29397 * Per-port leaky bucket ingress and egress rate limiting 29398 * 29399 * Granularity is in kbits/sec and a rate of 0 disables rate limiting. 29400 * The max burst size is set in kbits. 29401 */ 29402 29403 /* 29404 * Function: 29405 * bcm_port_rate_egress_set 29406 * Purpose: 29407 * Set egress rate limiting parameters 29408 * Parameters: 29409 * unit - Device number 29410 * port - Port number 29411 * kbits_sec - Rate in kilobits (1000 bits) per second. 29412 * Rate of 0 disables rate limiting. 29413 * kbits_burst - Maximum burst size in kilobits (1000 bits). 29414 * Returns: 29415 * BCM_E_XXX 29416 */ 29417 29418 int 29419 bcm_esw_port_rate_egress_set(int unit, 29420 bcm_port_t port, 29421 uint32 kbits_sec, 29422 uint32 kbits_burst) 29423 { 29424 /* Make sure port module is initialized. */ 29425 PORT_INIT(unit); 29426 29427 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 29428 29429 if (!soc_feature(unit, soc_feature_egress_metering)) { 29430 return BCM_E_UNAVAIL; 29431 } else { 29432 return mbcm_driver[unit]->mbcm_port_rate_egress_set(unit, port, 29433 kbits_sec, 29434 kbits_burst, 29435 _BCM_PORT_RATE_BYTE_MODE); 29436 } 29437 29438 return BCM_E_NONE; 29439 } 29440 29441 /* 29442 * Function: 29443 * bcm_port_rate_egress_pps_set 29444 * Purpose: 29445 * Set egress rate limiting parameter in packet mode. 29446 * Parameters: 29447 * unit - Device number 29448 * port - Port number 29449 * pps - Rate in pps 29450 * Rate of 0 disables rate limiting. 29451 * burst - Maximum burst size 29452 * Returns: 29453 * BCM_E_XXX 29454 */ 29455 29456 int 29457 bcm_esw_port_rate_egress_pps_set(int unit, 29458 bcm_port_t port, 29459 uint32 pps, 29460 uint32 burst) 29461 { 29462 /* Make sure port module is initialized. */ 29463 PORT_INIT(unit); 29464 29465 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 29466 29467 if (!soc_feature(unit, soc_feature_egress_metering)) { 29468 return BCM_E_UNAVAIL; 29469 } else { 29470 return mbcm_driver[unit]->mbcm_port_rate_egress_set(unit, port, 29471 pps, 29472 burst, 29473 _BCM_PORT_RATE_PPS_MODE); 29474 } 29475 29476 return BCM_E_NONE; 29477 } 29478 29479 29480 /* 29481 * Function: 29482 * bcm_port_rate_egress_get 29483 * Purpose: 29484 * Get egress rate limiting parameters 29485 * Parameters: 29486 * unit - Device number 29487 * port - Port number 29488 * kbits_sec - (OUT) Rate in kilobits (1000 bits) per second, or 29489 * zero if rate limiting is disabled. 29490 * kbits_burst - (OUT) Maximum burst size in kilobits (1000 bits). 29491 * Returns: 29492 * BCM_E_XXX 29493 */ 29494 29495 int 29496 bcm_esw_port_rate_egress_get(int unit, 29497 bcm_port_t port, 29498 uint32 *kbits_sec, 29499 uint32 *kbits_burst) 29500 { 29501 uint32 flags = 0; 29502 int rv = BCM_E_NONE; 29503 29504 /* Make sure port module is initialized. */ 29505 PORT_INIT(unit); 29506 29507 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 29508 29509 if (!soc_feature(unit, soc_feature_egress_metering)) { 29510 return BCM_E_UNAVAIL; 29511 } else { 29512 rv = mbcm_driver[unit]->mbcm_port_rate_egress_get(unit, port, 29513 kbits_sec, 29514 kbits_burst, 29515 &flags); 29516 } 29517 29518 if (BCM_SUCCESS(rv)) { 29519 if (flags == _BCM_PORT_RATE_BYTE_MODE) { 29520 return BCM_E_NONE; 29521 } else { 29522 /* Set as pps; kbits cannot be returned */ 29523 return BCM_E_CONFIG; 29524 } 29525 } 29526 29527 return rv; 29528 } 29529 29530 /* 29531 * Function: 29532 * bcm_port_rate_egress_pps_get 29533 * Purpose: 29534 * Get egress rate limiting parameter in packet mode. 29535 * Parameters: 29536 * unit - Device number 29537 * port - Port number 29538 * pps - (OUT) Rate in pps 29539 * 0 if rate limiting is disabled 29540 * burst -(OUT) burst size 29541 * Returns: 29542 * BCM_E_XXX 29543 */ 29544 29545 int 29546 bcm_esw_port_rate_egress_pps_get(int unit, 29547 bcm_port_t port, 29548 uint32 *pps, 29549 uint32 *burst) 29550 { 29551 uint32 flags = 0; 29552 int rv = BCM_E_NONE; 29553 29554 /* Make sure port module is initialized. */ 29555 PORT_INIT(unit); 29556 29557 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 29558 29559 if (!soc_feature(unit, soc_feature_egress_metering)) { 29560 return BCM_E_UNAVAIL; 29561 } else { 29562 rv = mbcm_driver[unit]->mbcm_port_rate_egress_get(unit, port, 29563 pps, 29564 burst, 29565 &flags); 29566 } 29567 29568 if (BCM_SUCCESS(rv)) { 29569 if (flags == _BCM_PORT_RATE_PPS_MODE) { 29570 return BCM_E_NONE; 29571 } else { 29572 /* Set as kbits; pps cannot be returned */ 29573 return BCM_E_CONFIG; 29574 } 29575 } 29576 return rv; 29577 } 29578 29579 /* 29580 * Function: 29581 * bcm_port_rate_ingress_set 29582 * Purpose: 29583 * Set ingress rate limiting parameters 29584 * Parameters: 29585 * unit - Device number 29586 * port - Port number 29587 * kbits_sec - Rate in kilobits (1000 bits) per second. 29588 * Rate of 0 disables rate limiting. 29589 * kbits_burst - Maximum burst size in kilobits (1000 bits). 29590 * Returns: 29591 * BCM_E_XXX 29592 */ 29593 29594 int 29595 bcm_esw_port_rate_ingress_set(int unit, 29596 bcm_port_t port, 29597 uint32 kbits_sec, 29598 uint32 kbits_burst) 29599 { 29600 /* Make sure port module is initialized. */ 29601 PORT_INIT(unit); 29602 29603 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 29604 29605 #ifdef BCM_XGS3_SWITCH_SUPPORT 29606 if (SOC_IS_XGS3_SWITCH(unit)) { 29607 /* 29608 * Use port-based ingress metering function. 29609 * Enabling rate-based ingress metering on the Firebolt 29610 * will also enable rate-based pause frames on this port. 29611 */ 29612 return bcm_xgs3_port_rate_ingress_set(unit, port, kbits_sec, 29613 kbits_burst); 29614 } 29615 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 29616 29617 return BCM_E_UNAVAIL; 29618 } 29619 29620 /* 29621 * Function: 29622 * bcm_port_rate_ingress_get 29623 * Purpose: 29624 * Get ingress rate limiting parameters 29625 * Parameters: 29626 * unit - Device number 29627 * port - Port number 29628 * kbits_sec - (OUT) Rate in kilobits (1000 bits) per second, or 29629 * zero if rate limiting is disabled. 29630 * kbits_burst - (OUT) Maximum burst size in kilobits (1000 bits). 29631 * Returns: 29632 * BCM_E_XXX 29633 */ 29634 29635 int 29636 bcm_esw_port_rate_ingress_get(int unit, 29637 bcm_port_t port, 29638 uint32 *kbits_sec, 29639 uint32 *kbits_burst) 29640 { 29641 /* Make sure port module is initialized. */ 29642 PORT_INIT(unit); 29643 29644 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 29645 29646 if (!kbits_sec || !kbits_burst) { 29647 return BCM_E_PARAM; 29648 } 29649 29650 #ifdef BCM_XGS3_SWITCH_SUPPORT 29651 if (SOC_IS_XGS3_SWITCH(unit)) { 29652 /* Use port-based ingress metering function */ 29653 return bcm_xgs3_port_rate_ingress_get(unit, port, kbits_sec, 29654 kbits_burst); 29655 } 29656 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 29657 29658 *kbits_sec = 0; 29659 *kbits_burst = 0; 29660 29661 return BCM_E_UNAVAIL; 29662 } 29663 29664 /* 29665 * Function: 29666 * bcm_port_rate_pause_set 29667 * Purpose: 29668 * Set ingress rate limiting pause frame control parameters 29669 * Parameters: 29670 * unit - Device number 29671 * port - Port number 29672 * kbits_pause - Pause threshold in kbits (1000 bits). 29673 * A value of zero disables the pause/resume mechanism. 29674 * kbits_resume - Resume threshold in kbits (1000 bits). 29675 * Returns: 29676 * BCM_E_XXX 29677 * Notes: 29678 * This interface applies only when port ingress rate limiting 29679 * is active. Currently, only the 566x supports this feature. 29680 * 29681 * If the maximum of bits that could be received before dropping a 29682 * frame falls below the kbits_pause, a pause frame is sent. 29683 * A resume frame will be sent once it becomes possible to receive 29684 * kbits_resume bits of data without dropping. 29685 */ 29686 29687 int 29688 bcm_esw_port_rate_pause_set(int unit, 29689 bcm_port_t port, 29690 uint32 kbits_pause, 29691 uint32 kbits_resume) 29692 { 29693 /* Make sure port module is initialized. */ 29694 PORT_INIT(unit); 29695 29696 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 29697 29698 #ifdef BCM_FIREBOLT_SUPPORT 29699 /* 29700 * For Firebolt, rate-based pause frames are generated as 29701 * a result of rate-based metering. As such, their behavior 29702 * is not directly controllable, but may be read. 29703 * see bcm_port_rate_pause_get(). 29704 */ 29705 #endif /* BCM_FIREBOLT_SUPPORT */ 29706 /* Otherwise, not supported */ 29707 return (kbits_pause == 0) ? BCM_E_NONE : BCM_E_UNAVAIL; 29708 } 29709 29710 /* 29711 * Function: 29712 * bcm_port_rate_pause_get 29713 * Purpose: 29714 * Get ingress rate limiting pause frame control parameters 29715 * Parameters: 29716 * unit - Device number 29717 * port - Port number 29718 * kbits_pause - (OUT) Pause threshold in kbits (1000 bits). 29719 * Zero indicates the pause/resume mechanism is disabled. 29720 * kbits_resume - (OUT) Resume threshold in kbits (1000 bits). 29721 * Returns: 29722 * BCM_E_XXX 29723 */ 29724 29725 int 29726 bcm_esw_port_rate_pause_get(int unit, 29727 bcm_port_t port, 29728 uint32 *kbits_pause, 29729 uint32 *kbits_resume) 29730 { 29731 /* Make sure port module is initialized. */ 29732 PORT_INIT(unit); 29733 29734 #if defined(BCM_HGPROXY_COE_SUPPORT) 29735 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 29736 BCM_GPORT_IS_SET(port) && 29737 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 29738 return BCM_E_PORT; 29739 } else 29740 #endif /* BCM_HGPROXY_COE_SUPPORT */ 29741 29742 #if defined(BCM_KATANA2_SUPPORT) 29743 if (BCM_GPORT_IS_SET(port) && 29744 _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)) { 29745 return BCM_E_PORT; 29746 } 29747 #endif 29748 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 29749 29750 #ifdef BCM_MONTEREY_SUPPORT 29751 if (SOC_IS_MONTEREY(unit)) { 29752 *kbits_pause = 0; 29753 *kbits_resume = 0; 29754 return BCM_E_UNAVAIL; 29755 } else 29756 #endif 29757 #ifdef BCM_TOMAHAWK_SUPPORT 29758 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 29759 *kbits_pause = 0; 29760 *kbits_resume = 0; 29761 return BCM_E_UNAVAIL; 29762 } else 29763 #endif /* BCM_TOMAHAWK_SUPPORT */ 29764 #ifdef BCM_TRIDENT2_SUPPORT 29765 if (SOC_IS_TD2_TT2(unit)) { 29766 return bcm_td2_port_rate_pause_get(unit, port, kbits_pause, 29767 kbits_resume); 29768 } else 29769 #endif /* BCM_TRIDENT2_SUPPORT */ 29770 #ifdef BCM_TRIUMPH_SUPPORT 29771 if (SOC_IS_TR_VL(unit) && !SOC_IS_HURRICANEX(unit) && 29772 !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) { 29773 return bcm_tr_port_rate_pause_get(unit, port, kbits_pause, 29774 kbits_resume); 29775 } 29776 #endif /* BCM_TRIUMPH_SUPPORT */ 29777 #ifdef BCM_FIREBOLT_SUPPORT 29778 if (SOC_IS_FBX(unit)) { 29779 return bcm_fb_port_rate_pause_get(unit, port, kbits_pause, 29780 kbits_resume); 29781 } 29782 #endif /* BCM_FIREBOLT_SUPPORT */ 29783 /* Otherwise, not supported */ 29784 *kbits_pause = 0; 29785 *kbits_resume = 0; 29786 return BCM_E_UNAVAIL; 29787 } 29788 29789 /* 29790 * Function: 29791 * bcm_port_sample_rate_set 29792 * Purpose: 29793 * Control the sampling of packets ingressing or egressing a port 29794 * Parameters: 29795 * unit - Device number 29796 * port - Port number 29797 * ingress_rate - Every 1/ingress_rate packets will be sampled 29798 * 0 indicates no sampling 29799 * 1 indicates sampling all packets 29800 * egress_rate - Every 1/egress_rate packets will be sampled 29801 * 0 indicates no sampling 29802 * 1 indicates sampling all packets 29803 * Returns: 29804 * BCM_E_XXX 29805 * Notes: 29806 * This API is a building block for supporting sFlow (RFC 3176) 29807 */ 29808 29809 int 29810 bcm_esw_port_sample_rate_set(int unit, bcm_port_t port, 29811 int ingress_rate, int egress_rate) 29812 { 29813 /* Make sure port module is initialized. */ 29814 PORT_INIT(unit); 29815 29816 /* 29817 * IMPLEMENTATION NOTES 29818 * 29819 * ingress_rate maps into the per port SFLOW_ING_THRESHOLD reg: 29820 * if (ingress_rate <= 0) { 29821 * SFLOW_ING_THRESHOLD.ENABLE=0 29822 * SFLOW_ING_THRESHOLD.THRESHOLD=0 29823 * } else { 29824 * SFLOW_ING_THRESHOLD.ENABLE=1 29825 * SFLOW_ING_THRESHOLD.THRESHOLD=0xffff/ingress_rate 29826 * } 29827 * egress_rate maps into the per port SFLOW_EGR_THRESHOLD reg: 29828 * if (egress_rate <= 0) { 29829 * SFLOW_EGR_THRESHOLD.ENABLE=0 29830 * SFLOW_EGR_THRESHOLD.THRESHOLD=0 29831 * } else { 29832 * SFLOW_EGR_THRESHOLD.ENABLE=1 29833 * SFLOW_EGR_THRESHOLD.THRESHOLD=0xffff/egress_rate 29834 * } 29835 * 29836 * bcmSwitchCpuSamplePrio maps to CPU_CONTROL_2.CPU_SFLOW_PRIORITY 29837 * bcmSwitchSampleIngressRandomSeed maps to SFLOW_ING_RAND_SEED.SEED 29838 * bcmSwitchSampleEgressRandomSeed maps to SFLOW_EGR_RAND_SEED.SEED 29839 * 29840 * There are two related RX reason codes defined in <bcm/rx.h> 29841 * BCM_RX_PR_SAMPLE_SRC 29842 * BCM_RX_PR_SAMPLE_DST 29843 */ 29844 29845 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 29846 if (ingress_rate < 0 || egress_rate < 0) { 29847 return BCM_E_PARAM; 29848 } 29849 29850 #ifdef BCM_XGS3_SWITCH_SUPPORT 29851 if (SOC_IS_XGS3_SWITCH(unit)) { 29852 return bcm_xgs3_port_sample_rate_set(unit, port, 29853 ingress_rate, egress_rate); 29854 } 29855 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 29856 29857 return BCM_E_UNAVAIL; 29858 } 29859 29860 /* 29861 * Function: 29862 * bcm_port_sample_rate_get 29863 * Purpose: 29864 * Get the sampling of packets ingressing or egressing a port 29865 * Parameters: 29866 * unit - Device number 29867 * port - Port number 29868 * ingress_rate - Every 1/ingress_rate packets will be sampled 29869 * 0 indicates no sampling 29870 * 1 indicates sampling all packets 29871 * egress_rate - Every 1/egress_rate packets will be sampled 29872 * 0 indicates no sampling 29873 * 1 indicates sampling all packets 29874 * Returns: 29875 * BCM_E_UNIT 29876 * BCM_E_PARAM 29877 * BCM_E_UNAVAIL 29878 * BCM_E_XXX 29879 * Notes: 29880 * This API is a building block for supporting sFlow (RFC 3176) 29881 */ 29882 29883 int 29884 bcm_esw_port_sample_rate_get(int unit, bcm_port_t port, 29885 int *ingress_rate, int *egress_rate) 29886 { 29887 /* Make sure port module is initialized. */ 29888 PORT_INIT(unit); 29889 29890 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 29891 29892 if (ingress_rate == NULL || egress_rate == NULL) { 29893 return BCM_E_PARAM; 29894 } 29895 29896 #ifdef BCM_XGS3_SWITCH_SUPPORT 29897 if (SOC_IS_XGS3_SWITCH(unit)) { 29898 return bcm_xgs3_port_sample_rate_get(unit, port, 29899 ingress_rate, egress_rate); 29900 } 29901 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 29902 29903 29904 return BCM_E_UNAVAIL; 29905 } 29906 29907 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 29908 #ifdef BCM_WARM_BOOT_SUPPORT 29909 STATIC int 29910 _bcm_esw_sflow_counter_wb_recover(int unit, soc_mem_t mem) 29911 { 29912 int idx_min, idx_max, i, id, rv = 0; 29913 soc_counter_non_dma_t *non_dma = NULL; 29914 soc_control_t *soc; 29915 uint32 count = 0, subset_ct = 0, sflow_enable = 0; 29916 uint8 *sflow_tbl_chunk = NULL; 29917 void *sflow_entry; 29918 29919 soc = SOC_CONTROL(unit); 29920 29921 idx_min = soc_mem_index_min(unit, mem); 29922 idx_max = soc_mem_index_max(unit, mem); 29923 sflow_tbl_chunk = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem), 29924 "sFlow Ingress Data Source table buffer"); 29925 if (sflow_tbl_chunk == NULL) { 29926 return BCM_E_MEMORY; 29927 } 29928 29929 /* Read Ingress rate data table entries */ 29930 sal_memset(sflow_tbl_chunk, 0, SOC_MEM_TABLE_BYTES(unit, mem)); 29931 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max, 29932 sflow_tbl_chunk); 29933 if (SOC_FAILURE(rv)) { 29934 soc_cm_sfree(unit, sflow_tbl_chunk); 29935 return rv; 29936 } 29937 29938 if (mem == SFLOW_ING_DATA_SOURCEm) { 29939 id = SOC_COUNTER_NON_DMA_SFLOW_ING_PKT; 29940 } else { 29941 id = SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT; 29942 } 29943 29944 for(i = idx_min; i < idx_max; i++) { 29945 sflow_entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 29946 sflow_tbl_chunk, i); 29947 sflow_enable = soc_mem_field32_get(unit, mem, sflow_entry, ENABLEf); 29948 29949 if (sflow_enable) { 29950 non_dma = &soc->counter_non_dma[id - SOC_COUNTER_NON_DMA_START]; 29951 /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */ 29952 subset_ct = non_dma->extra_ctr_ct << 1; 29953 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 29954 non_dma = non_dma->extra_ctrs; 29955 29956 do { 29957 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 29958 /* BYTE_CTRf not currently supported */ 29959 count += 2; 29960 non_dma += 2; 29961 } while ((count < subset_ct)); 29962 break; 29963 } 29964 } 29965 29966 soc_cm_sfree(unit, sflow_tbl_chunk); 29967 return BCM_E_NONE; 29968 } 29969 29970 /** 29971 * Function: 29972 * _bcm_esw_sflow_wb_recover 29973 * Purpose: 29974 * sFlow Warmboot Recovery 29975 * Parameters: 29976 * unit - (IN) Unit number 29977 * Returns: 29978 * BCM_E_xxx 29979 */ 29980 STATIC int 29981 _bcm_esw_sflow_wb_recover(int unit) { 29982 int rv = 0; 29983 29984 if (soc_feature(unit, soc_feature_sflow_ing_mem)) { 29985 rv = _bcm_esw_sflow_counter_wb_recover(unit, SFLOW_ING_DATA_SOURCEm); 29986 if (BCM_FAILURE(rv)) { 29987 return rv; 29988 } 29989 } 29990 29991 if (soc_feature(unit, soc_feature_sflow_flex)) { 29992 rv = _bcm_esw_sflow_counter_wb_recover(unit, 29993 SFLOW_ING_FLEX_DATA_SOURCEm); 29994 if (BCM_FAILURE(rv)) { 29995 return rv; 29996 } 29997 } 29998 29999 return BCM_E_NONE; 30000 } 30001 #endif /* BCM_WARM_BOOT_SUPPORT */ 30002 #endif /* BCM_TOMAHAWK_SUPPORT */ 30003 30004 /* 30005 * Double Tagging 30006 */ 30007 30008 /* 30009 * Function: 30010 * bcm_port_dtag_mode_set 30011 * Description: 30012 * Set the double-tagging mode of a port. 30013 * Parameters: 30014 * unit - Device number 30015 * port - Port number 30016 * mode - Double-tagging mode, one of: 30017 * BCM_PORT_DTAG_MODE_NONE No double tagging 30018 * BCM_PORT_DTAG_MODE_INTERNAL Service Provider port 30019 * BCM_PORT_DTAG_MODE_EXTERNAL Customer port 30020 * BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG Remove customer tag 30021 * BCM_PORT_DTAG_ADD_EXTERNAL_TAG Add customer tag 30022 * Return Value: 30023 * BCM_E_XXX 30024 * Notes: 30025 * BCM_PORT_DTAG_MODE_INTERNAL is for service provider ports. 30026 * A tag will be added if the packet does not already 30027 * have the internal TPID (see bcm_port_tpid_set below). 30028 * Internally this sets DT_MODE and clears IGNORE_TAG. 30029 * BCM_PORT_DTAG_MODE_EXTERNAL is for customer ports. 30030 * The service provider TPID will always be added 30031 * (see bcm_port_tpid_set below). 30032 * Internally this sets DT_MODE and sets IGNORE_TAG. 30033 * On some chips, such as BCM5665, double-tag enable is a system-wide 30034 * setting rather than a port setting, so enabling double- 30035 * tagging on one port may enable it on all ports. 30036 */ 30037 30038 int 30039 bcm_esw_port_dtag_mode_set(int unit, bcm_port_t port, int mode) 30040 { 30041 #ifdef BCM_FIREBOLT_SUPPORT 30042 int dt_mode, ignore_tag; 30043 #endif 30044 int dt_mode_mask; 30045 30046 /* Make sure port module is initialized. */ 30047 PORT_INIT(unit); 30048 30049 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30050 /* Skip PORT_SWITCHED_CHECK for Higig lookup (for q-in-q proxy) */ 30051 if (!(IS_ST_PORT(unit, port) && 30052 soc_feature(unit, soc_feature_higig_lookup))) { 30053 PORT_SWITCHED_CHECK(unit, port); 30054 } 30055 30056 dt_mode_mask = BCM_PORT_DTAG_MODE_INTERNAL | 30057 BCM_PORT_DTAG_MODE_EXTERNAL; 30058 30059 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT) 30060 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || \ 30061 SOC_IS_HAWKEYE(unit) || SOC_IS_TRX(unit)) { 30062 if (mode & ~(BCM_PORT_DTAG_MODE_INTERNAL | 30063 BCM_PORT_DTAG_MODE_EXTERNAL | 30064 BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG | 30065 BCM_PORT_DTAG_ADD_EXTERNAL_TAG)) { 30066 return BCM_E_UNAVAIL; 30067 } 30068 30069 if (IS_ST_PORT(unit, port)) { 30070 /* Addition or removal of two tags is not supported on 30071 * Higig / Higig Lite ports. 30072 */ 30073 if (mode & BCM_PORT_DTAG_ADD_EXTERNAL_TAG || 30074 mode & BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG) { 30075 return BCM_E_PARAM; 30076 } 30077 } 30078 30079 /* Removal of two tags should be enable only for UNI egress ports. */ 30080 if (mode == (BCM_PORT_DTAG_MODE_INTERNAL | 30081 BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG)) { 30082 return BCM_E_PARAM; 30083 } 30084 30085 #ifdef BCM_TRX_SUPPORT 30086 if (SOC_IS_TRX(unit)) { 30087 if (!soc_feature(unit, soc_feature_vlan_action)) { 30088 return BCM_E_UNAVAIL; 30089 } 30090 return _bcm_trx_port_dtag_mode_set(unit, port, mode); 30091 } 30092 #endif 30093 } else 30094 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 30095 if (0 != (mode & ~dt_mode_mask)) { 30096 /* Some devices do not support the add/remove tag options */ 30097 return BCM_E_UNAVAIL; 30098 } 30099 30100 #ifdef BCM_FIREBOLT_SUPPORT 30101 switch (mode & dt_mode_mask) { 30102 case BCM_PORT_DTAG_MODE_NONE: 30103 dt_mode = 0; 30104 ignore_tag = 0; 30105 break; 30106 case BCM_PORT_DTAG_MODE_INTERNAL: 30107 dt_mode = 1; 30108 ignore_tag = 0; 30109 break; 30110 case BCM_PORT_DTAG_MODE_EXTERNAL: 30111 dt_mode = 1; 30112 ignore_tag = 1; 30113 break; 30114 default: 30115 return BCM_E_PARAM; 30116 } 30117 30118 if (SOC_IS_FBX(unit)) { 30119 return _bcm_fb_port_dtag_mode_set(unit, port, mode, 30120 dt_mode, ignore_tag); 30121 } 30122 #endif 30123 return BCM_E_UNAVAIL; 30124 } 30125 30126 /* 30127 * Function: 30128 * bcm_port_dtag_mode_get 30129 * Description: 30130 * Return the current double-tagging mode of a port. 30131 * Parameters: 30132 * unit - Device number 30133 * port - Port number 30134 * mode - (OUT) Double-tagging mode 30135 * Return Value: 30136 * BCM_E_XXX 30137 */ 30138 30139 int 30140 bcm_esw_port_dtag_mode_get(int unit, bcm_port_t port, int *mode) 30141 { 30142 /* Make sure port module is initialized. */ 30143 PORT_INIT(unit); 30144 30145 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 30146 /* Skip PORT_SWITCHED_CHECK for Higig lookup (for q-in-q proxy) */ 30147 if (!(IS_ST_PORT(unit, port) && 30148 soc_feature(unit, soc_feature_higig_lookup))) { 30149 PORT_SWITCHED_CHECK(unit, port); 30150 } 30151 30152 if (mode == NULL) { 30153 return BCM_E_PARAM; 30154 } 30155 30156 #ifdef BCM_TRX_SUPPORT 30157 if (SOC_IS_TRX(unit)) { 30158 *mode = PORT(unit, port).dtag_mode; 30159 return BCM_E_NONE; 30160 } 30161 #endif 30162 30163 #ifdef BCM_FIREBOLT_SUPPORT 30164 if (SOC_IS_FBX(unit)) { 30165 return _bcm_fb_port_dtag_mode_get(unit, port, mode); 30166 } 30167 #endif 30168 30169 return BCM_E_UNAVAIL; 30170 } 30171 30172 /* 30173 * Function: 30174 * _bcm_esw_mod_port_tpid_set 30175 * Description: 30176 * Set the Tag Protocol ID for a (module, port). 30177 * Parameters: 30178 * unit - Device number 30179 * mod - Module ID 30180 * port - Port number 30181 * tpid - Tag Protocol ID 30182 * Return Value: 30183 * BCM_E_XXX 30184 */ 30185 STATIC int 30186 _bcm_esw_mod_port_tpid_set(int unit, bcm_module_t mod, bcm_port_t port, 30187 uint16 tpid) 30188 { 30189 #ifdef BCM_HURRICANE3_SUPPORT 30190 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 30191 return _bcm_hr3_mod_port_tpid_set(unit, mod, port, tpid); 30192 } else 30193 #endif /* BCM_HURRICANE3_SUPPORT */ 30194 #ifdef BCM_TRIDENT_SUPPORT 30195 { 30196 return _bcm_td_mod_port_tpid_set(unit, mod, port, tpid); 30197 } 30198 #endif /* BCM_TRIDENT_SUPPORT */ 30199 return BCM_E_UNAVAIL; 30200 } 30201 30202 #if defined(BCM_MONTEREY_SUPPORT) 30203 STATIC 30204 void bcm_port_inner_tpid_obm_set(int unit, bcm_port_t port, uint16 tpid) 30205 { 30206 uint32 rval32 = 0; 30207 int obm, pgw, pgw_inst; 30208 soc_info_t *si; 30209 soc_reg_t reg; 30210 static const soc_reg_t obm_inner_tpid_regs[] = { 30211 IDB_OBM0_INNER_TPIDr, IDB_OBM1_INNER_TPIDr, 30212 IDB_OBM2_INNER_TPIDr, IDB_OBM3_INNER_TPIDr, 30213 IDB_OBM4_INNER_TPIDr, IDB_OBM5_INNER_TPIDr, 30214 IDB_OBM6_INNER_TPIDr, IDB_OBM7_INNER_TPIDr 30215 }; 30216 if ((port < 1) || (port > 64)) { 30217 return; 30218 } 30219 si = &SOC_INFO(unit); 30220 obm = si->port_serdes[port]; 30221 obm %= MONTEREY_TSCS_PER_PGW; 30222 30223 pgw = si->port_group[port]; 30224 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 30225 30226 reg = obm_inner_tpid_regs[obm]; 30227 30228 soc_reg32_get(unit, reg, pgw_inst, 0, &rval32); 30229 soc_reg_field_set(unit, reg, &rval32, TPIDf, tpid); 30230 soc_reg_field_set(unit, reg, &rval32, ENABLEf, tpid ? 1 : 0); 30231 soc_reg32_set(unit, reg, pgw_inst, 0, rval32); 30232 return; 30233 } 30234 STATIC 30235 void bcm_inner_tpid_obm_set(int unit, uint16 tpid) 30236 { 30237 int port; 30238 BCM_PBMP_ITER(PBMP_PORT_ALL(unit), port) { 30239 bcm_port_inner_tpid_obm_set(unit, port, tpid); 30240 } 30241 return; 30242 } 30243 STATIC 30244 void bcm_port_outer_tpid_obm_set(int unit, bcm_port_t port, 30245 uint16 tpid, int tpid_index) 30246 { 30247 uint32 rval32 = 0; 30248 int obm, pgw, pgw_inst; 30249 soc_info_t *si; 30250 soc_reg_t reg; 30251 static const soc_reg_t obm_inner_tpid_regs[][4] = { 30252 {IDB_OBM0_OUTER_TPID_0r, IDB_OBM0_OUTER_TPID_1r, 30253 IDB_OBM0_OUTER_TPID_2r, IDB_OBM0_OUTER_TPID_3r}, 30254 {IDB_OBM1_OUTER_TPID_0r, IDB_OBM1_OUTER_TPID_1r, 30255 IDB_OBM1_OUTER_TPID_2r, IDB_OBM1_OUTER_TPID_3r}, 30256 {IDB_OBM2_OUTER_TPID_0r, IDB_OBM2_OUTER_TPID_1r, 30257 IDB_OBM2_OUTER_TPID_2r, IDB_OBM2_OUTER_TPID_3r}, 30258 {IDB_OBM3_OUTER_TPID_0r, IDB_OBM3_OUTER_TPID_1r, 30259 IDB_OBM3_OUTER_TPID_2r, IDB_OBM3_OUTER_TPID_3r}, 30260 {IDB_OBM4_OUTER_TPID_0r, IDB_OBM4_OUTER_TPID_1r, 30261 IDB_OBM4_OUTER_TPID_2r, IDB_OBM4_OUTER_TPID_3r}, 30262 {IDB_OBM5_OUTER_TPID_0r, IDB_OBM5_OUTER_TPID_1r, 30263 IDB_OBM5_OUTER_TPID_2r, IDB_OBM5_OUTER_TPID_3r}, 30264 {IDB_OBM6_OUTER_TPID_0r, IDB_OBM6_OUTER_TPID_1r, 30265 IDB_OBM6_OUTER_TPID_2r, IDB_OBM6_OUTER_TPID_3r}, 30266 {IDB_OBM7_OUTER_TPID_0r, IDB_OBM7_OUTER_TPID_1r, 30267 IDB_OBM7_OUTER_TPID_2r, IDB_OBM7_OUTER_TPID_3r} 30268 }; 30269 if ((port < 1) || (port > 64) || 30270 (tpid_index < 0) || (tpid_index > 3)) { 30271 return; 30272 } 30273 si = &SOC_INFO(unit); 30274 obm = si->port_serdes[port]; 30275 obm %= MONTEREY_TSCS_PER_PGW; 30276 30277 pgw = si->port_group[port]; 30278 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 30279 30280 reg = obm_inner_tpid_regs[obm][tpid_index]; 30281 30282 soc_reg32_get(unit, reg, pgw_inst, 0, &rval32); 30283 soc_reg_field_set(unit, reg, &rval32, TPIDf, tpid); 30284 soc_reg_field_set(unit, reg, &rval32, ENABLEf, tpid ? 1 : 0); 30285 soc_reg32_set(unit, reg, pgw_inst, 0, rval32); 30286 return; 30287 } 30288 #endif 30289 /* 30290 * Function: 30291 * bcm_port_tpid_set 30292 * Description: 30293 * Set the default Tag Protocol ID for a port. 30294 * Parameters: 30295 * unit - Device number 30296 * port - Port number 30297 * tpid - Tag Protocol ID 30298 * Return Value: 30299 * BCM_E_XXX 30300 * Notes: 30301 * This API is not specifically double-tagging-related, but 30302 * the port TPID becomes the service provider TPID when double-tagging 30303 * is enabled on a port. The default TPID is 0x8100. 30304 * On BCM5665, only 0x8100 is allowed for the inner (customer) tag. 30305 */ 30306 30307 int 30308 bcm_esw_port_tpid_set(int unit, bcm_port_t port, uint16 tpid) 30309 { 30310 int rv = BCM_E_UNAVAIL; 30311 bcm_module_t mod_out; 30312 bcm_port_t port_out; 30313 bcm_trunk_t tgid_out; 30314 int id_out; 30315 int is_local = 0, tpid_index = 0; 30316 #ifdef BCM_FIREBOLT_SUPPORT 30317 bcm_port_t orig_port = -1; 30318 #endif 30319 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 30320 int vp = -1; 30321 #endif 30322 30323 /* Make sure port module is initialized. */ 30324 PORT_INIT(unit); 30325 30326 if(bcm_common_oamp_port_enable_get(unit, port)) { 30327 LOG_ERROR(BSL_LS_BCM_PORT, 30328 (BSL_META("Error: Not permitted on OAMP port %d.n"), 30329 port)); 30330 return BCM_E_PARAM; 30331 } 30332 30333 if (BCM_GPORT_IS_SET(port)) { 30334 /* Handle virtual ports separetly */ 30335 if (BCM_GPORT_IS_MPLS_PORT(port) || 30336 BCM_GPORT_IS_MIM_PORT(port) || 30337 BCM_GPORT_IS_VXLAN_PORT(port) || 30338 BCM_GPORT_IS_VLAN_PORT(port)) { 30339 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 30340 #if defined(BCM_TRX_SUPPORT) 30341 PORT_LOCK(unit); 30342 rv = _bcm_trx_vp_tpid_set(unit, port, tpid); 30343 PORT_UNLOCK(unit); 30344 #endif 30345 } 30346 return rv; 30347 } else if (BCM_GPORT_IS_SUBPORT_GROUP(port)) { 30348 if (soc_feature(unit, soc_feature_subtag_coe)) { 30349 #if defined(BCM_KATANA2_SUPPORT) 30350 PORT_LOCK(unit); 30351 rv = bcm_kt2_subport_subtag_port_tpid_set(unit, port, tpid); 30352 PORT_UNLOCK(unit); 30353 #endif 30354 } 30355 return rv; 30356 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 30357 30358 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 30359 #ifdef BCM_HGPROXY_COE_SUPPORT 30360 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 30361 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 30362 &mod_out, &port_out, &tgid_out, &id_out)); 30363 orig_port = port; 30364 BCM_IF_ERROR_RETURN( 30365 _bcmi_coe_subport_physical_port_get(unit, 30366 port, &port)); 30367 } else { 30368 return BCM_E_PORT; 30369 } 30370 #endif 30371 } else if (soc_feature(unit, soc_feature_subtag_coe) || 30372 soc_feature(unit, soc_feature_linkphy_coe)) { 30373 #ifdef BCM_KATANA2_SUPPORT 30374 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 30375 port)) { 30376 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 30377 &mod_out, &port_out, &tgid_out, &id_out)); 30378 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 30379 mod_out, port_out, &port)); 30380 } else { 30381 return BCM_E_PORT; 30382 } 30383 #endif 30384 } else { 30385 return BCM_E_PORT; 30386 } 30387 } else if (BCM_GPORT_IS_TRUNK(port)) { 30388 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 30389 if (soc_feature(unit, soc_feature_vp_lag)) { 30390 BCM_IF_ERROR_RETURN( 30391 _bcm_esw_trunk_tid_to_vp_lag_vp( 30392 unit, BCM_GPORT_TRUNK_GET(port), &vp)); 30393 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 30394 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 30395 PORT_LOCK(unit); 30396 rv = _bcm_trx_vp_tpid_set(unit, port, tpid); 30397 PORT_UNLOCK(unit); 30398 return rv; 30399 } 30400 } else { 30401 return BCM_E_PARAM; 30402 } 30403 } 30404 #endif 30405 return BCM_E_PARAM; 30406 } else { 30407 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 30408 &mod_out, &port_out, &tgid_out, &id_out)); 30409 if ((-1 != tgid_out) || (-1 != id_out)) { 30410 return BCM_E_PARAM; 30411 } 30412 30413 BCM_IF_ERROR_RETURN 30414 (_bcm_esw_modid_is_local(unit, mod_out, &is_local)); 30415 #if defined(BCM_HURRICANE3_SUPPORT) 30416 /* Here only take care non-local port, the local port will 30417 * be handled later (by _bcm_fb2_port_tpid_set) */ 30418 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 30419 if (!is_local) { 30420 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 30421 return _bcm_esw_mod_port_tpid_set(unit, mod_out, 30422 port_out, tpid); 30423 } else { 30424 return BCM_E_PARAM; 30425 } 30426 } else { 30427 BCM_IF_ERROR_RETURN( 30428 bcm_esw_port_local_get(unit, port, &port)); 30429 } 30430 } else 30431 #endif 30432 { 30433 if (!is_local) { 30434 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 30435 return _bcm_esw_mod_port_tpid_set(unit, mod_out, 30436 port_out, tpid); 30437 } else { 30438 return BCM_E_PARAM; 30439 } 30440 } else { 30441 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 30442 BCM_IF_ERROR_RETURN 30443 (_bcm_esw_mod_port_tpid_set(unit, mod_out, 30444 port_out, tpid)); 30445 } 30446 BCM_IF_ERROR_RETURN( 30447 bcm_esw_port_local_get(unit, port, &port)); 30448 } 30449 } 30450 } 30451 } else if (!SOC_PORT_VALID(unit, port)) { 30452 return BCM_E_PORT; 30453 } 30454 30455 #if defined (BCM_TRX_SUPPORT) 30456 if (SOC_IS_TRX(unit) && 30457 (PORT(unit, port).dtag_mode == BCM_PORT_DTAG_MODE_EXTERNAL)) { 30458 /* For DT mode external ports, don't enable any outer TPIDs */ 30459 return BCM_E_NONE; 30460 } 30461 #endif 30462 30463 #ifdef BCM_FIREBOLT_SUPPORT 30464 if (SOC_IS_FBX(unit)) { 30465 PORT_LOCK(unit); 30466 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) || \ 30467 defined(BCM_RAVEN_SUPPORT) 30468 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 30469 if (orig_port != -1) { 30470 rv = _bcm_fb2_port_tpid_set(unit, orig_port, tpid, &tpid_index); 30471 } else { 30472 rv = _bcm_fb2_port_tpid_set(unit, port, tpid, &tpid_index); 30473 } 30474 #if defined(BCM_TOMAHAWK_SUPPORT) 30475 /* For Tomahawk low latency mode, use outer_tpid field */ 30476 /* of EGR_VLAN_TAG_ACTION_FOR_BYPASSr on egress side */ 30477 if (soc_feature(unit, soc_feature_fast_egr_vlan_action)) { 30478 uint32 rval; 30479 bcm_port_t local_port; 30480 30481 if (orig_port != -1) 30482 local_port = orig_port; 30483 else { 30484 local_port = port; 30485 } 30486 30487 rv = READ_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, local_port, 30488 &rval); 30489 if (SOC_FAILURE(rv)) { 30490 PORT_UNLOCK(unit); 30491 return (rv); 30492 } 30493 30494 soc_reg_field_set(unit, EGR_VLAN_TAG_ACTION_FOR_BYPASSr, &rval, 30495 OUTER_TPIDf, tpid); 30496 30497 rv = WRITE_EGR_VLAN_TAG_ACTION_FOR_BYPASSr(unit, local_port, 30498 rval); 30499 if (SOC_FAILURE(rv)) { 30500 PORT_UNLOCK(unit); 30501 return (rv); 30502 } 30503 } 30504 #endif 30505 #if defined(BCM_MONTEREY_SUPPORT) 30506 if (soc_feature(unit, soc_feature_obm_tpid_sync)) { 30507 bcm_port_outer_tpid_obm_set(unit, port, tpid, tpid_index); 30508 } 30509 #endif 30510 } else 30511 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 30512 { 30513 rv = _bcm_fb_port_tpid_set(unit, port, tpid); 30514 } 30515 /* coverity[negative_shift] */ 30516 if (BCM_SUCCESS(rv) && SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) { 30517 30518 30519 if(!SOC_IS_TOMAHAWK3(unit)) { 30520 /* 30521 * At now, this mac drvier is only supported by XMAC & XLMAC 30522 * If function return BCM_E_UNAVAIL, it should be correct. 30523 */ 30524 if (SOC_USE_PORTCTRL(unit)) { 30525 rv = bcmi_esw_portctrl_vlan_tpid_set(unit, port, tpid); 30526 } else { 30527 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 30528 SOC_MAC_CONTROL_RX_VLAN_TAG_OUTER_TPID, tpid); 30529 if (rv == BCM_E_UNAVAIL) { 30530 rv = BCM_E_NONE; 30531 } 30532 } 30533 } 30534 } 30535 PORT_UNLOCK(unit); 30536 return rv; 30537 } 30538 #endif 30539 30540 if (tpid == 0x8100) { 30541 return BCM_E_NONE; 30542 } 30543 return BCM_E_UNAVAIL; 30544 } 30545 30546 /* 30547 * Function: 30548 * _bcm_esw_mod_port_tpid_get 30549 * Description: 30550 * Retrieve the Tag Protocol ID for a (module, port). 30551 * Parameters: 30552 * unit - Device number 30553 * mod - Module ID 30554 * port - Port number 30555 * tpid - (OUT) Tag Protocol ID 30556 * Return Value: 30557 * BCM_E_XXX 30558 */ 30559 STATIC int 30560 _bcm_esw_mod_port_tpid_get(int unit, bcm_module_t mod, bcm_port_t port, 30561 uint16 *tpid) 30562 { 30563 #ifdef BCM_HURRICANE3_SUPPORT 30564 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 30565 return _bcm_hr3_mod_port_tpid_get(unit, mod, port, tpid); 30566 } else 30567 #endif /* BCM_HURRICANE3_SUPPORT */ 30568 #ifdef BCM_TRIDENT_SUPPORT 30569 { 30570 return _bcm_td_mod_port_tpid_get(unit, mod, port, tpid); 30571 } 30572 #endif /* BCM_TRIDENT_SUPPORT */ 30573 return BCM_E_UNAVAIL; 30574 } 30575 30576 30577 /* 30578 * Function: 30579 * bcm_port_tpid_get 30580 * Description: 30581 * Retrieve the default Tag Protocol ID for a port. 30582 * Parameters: 30583 * unit - Device number 30584 * port - Port number 30585 * tpid - (OUT) Tag Protocol ID 30586 * Return Value: 30587 * BCM_E_XXX 30588 */ 30589 30590 int 30591 bcm_esw_port_tpid_get(int unit, bcm_port_t port, uint16 *tpid) 30592 { 30593 int rv = BCM_E_UNAVAIL; 30594 bcm_module_t mod_out; 30595 bcm_port_t port_out; 30596 bcm_trunk_t tgid_out; 30597 int id_out; 30598 int is_local = 0; 30599 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 30600 int vp = -1; 30601 #endif 30602 30603 /* Make sure port module is initialized. */ 30604 PORT_INIT(unit); 30605 30606 if(bcm_common_oamp_port_enable_get(unit, port)) { 30607 LOG_ERROR(BSL_LS_BCM_PORT, 30608 (BSL_META("Error: Not permitted on OAMP port %d.n"), 30609 port)); 30610 return BCM_E_PARAM; 30611 } 30612 30613 if (BCM_GPORT_IS_SET(port)) { 30614 /* Handle virtual ports separetly */ 30615 if (BCM_GPORT_IS_MPLS_PORT(port) || 30616 BCM_GPORT_IS_MIM_PORT(port) || 30617 BCM_GPORT_IS_VXLAN_PORT(port) || 30618 BCM_GPORT_IS_VLAN_PORT(port)) { 30619 30620 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 30621 #if defined(BCM_TRX_SUPPORT) 30622 PORT_LOCK(unit); 30623 rv = _bcm_trx_vp_tpid_get(unit, port, tpid); 30624 PORT_UNLOCK(unit); 30625 #endif 30626 } 30627 return rv; 30628 } else if (BCM_GPORT_IS_SUBPORT_GROUP(port)) { 30629 if (soc_feature(unit, soc_feature_subtag_coe)) { 30630 #if defined(BCM_KATANA2_SUPPORT) 30631 PORT_LOCK(unit); 30632 rv = bcm_kt2_subport_subtag_port_tpid_get(unit, port, tpid); 30633 PORT_UNLOCK(unit); 30634 #endif 30635 } 30636 return rv; 30637 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 30638 30639 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 30640 #ifdef BCM_HGPROXY_COE_SUPPORT 30641 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 30642 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 30643 &mod_out, &port_out, &tgid_out, &id_out)); 30644 } else { 30645 return BCM_E_PORT; 30646 } 30647 #endif 30648 } else if (soc_feature(unit, soc_feature_subtag_coe) || 30649 soc_feature(unit, soc_feature_linkphy_coe)) { 30650 #ifdef BCM_KATANA2_SUPPORT 30651 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 30652 port)) { 30653 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 30654 &mod_out, &port_out, &tgid_out, &id_out)); 30655 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 30656 mod_out, port_out, &port)); 30657 } else { 30658 return BCM_E_PORT; 30659 } 30660 #endif 30661 } else { 30662 return BCM_E_PORT; 30663 } 30664 } else if (BCM_GPORT_IS_TRUNK(port)) { 30665 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 30666 if (soc_feature(unit, soc_feature_vp_lag)) { 30667 BCM_IF_ERROR_RETURN( 30668 _bcm_esw_trunk_tid_to_vp_lag_vp( 30669 unit, BCM_GPORT_TRUNK_GET(port), &vp)); 30670 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 30671 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 30672 PORT_LOCK(unit); 30673 rv = _bcm_trx_vp_tpid_get(unit, port, tpid); 30674 PORT_UNLOCK(unit); 30675 return rv; 30676 } 30677 } else { 30678 return BCM_E_PARAM; 30679 } 30680 } 30681 #endif 30682 return BCM_E_PARAM; 30683 } else { 30684 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 30685 &mod_out, &port_out, &tgid_out, &id_out)); 30686 if ((-1 != tgid_out) || (-1 != id_out)) { 30687 return BCM_E_PARAM; 30688 } 30689 30690 BCM_IF_ERROR_RETURN 30691 (_bcm_esw_modid_is_local(unit, mod_out, &is_local)); 30692 if (!is_local) { 30693 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 30694 return _bcm_esw_mod_port_tpid_get(unit, mod_out, port_out, 30695 tpid); 30696 } else { 30697 return BCM_E_PARAM; 30698 } 30699 } else { 30700 BCM_IF_ERROR_RETURN( 30701 bcm_esw_port_local_get(unit, port, &port)); 30702 } 30703 } 30704 30705 } else if (!SOC_PORT_VALID(unit, port)) { 30706 return BCM_E_PORT; 30707 } 30708 30709 if (tpid == NULL) { 30710 return BCM_E_PARAM; 30711 } 30712 30713 #ifdef BCM_FIREBOLT_SUPPORT 30714 if (SOC_IS_FBX(unit)) { 30715 PORT_LOCK(unit); 30716 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 30717 || defined(BCM_RAVEN_SUPPORT) 30718 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 30719 rv = _bcm_fb2_port_tpid_get(unit, port, tpid); 30720 } else 30721 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 30722 { 30723 rv = _bcm_fb_port_tpid_get(unit, port, tpid); 30724 } 30725 PORT_UNLOCK(unit); 30726 return rv; 30727 } 30728 #endif /* BCM_FIREBOLT_SUPPORT */ 30729 *tpid = 0x8100; 30730 return (BCM_E_NONE); 30731 } 30732 30733 /* 30734 * Function: 30735 * _bcm_esw_mod_port_tpid_add 30736 * Description: 30737 * Add TPID for a (module, port). 30738 * Parameters: 30739 * unit - (IN) Device number 30740 * mod - (IN) Module ID 30741 * port - (IN) Port number 30742 * tpid - (IN) Tag Protocol ID 30743 * Return Value: 30744 * BCM_E_XXX 30745 */ 30746 STATIC int 30747 _bcm_esw_mod_port_tpid_add(int unit, bcm_module_t mod, bcm_port_t port, 30748 uint16 tpid) 30749 { 30750 #ifdef BCM_HURRICANE3_SUPPORT 30751 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 30752 return _bcm_hr3_mod_port_tpid_add(unit, mod, port, tpid); 30753 } else 30754 #endif /* BCM_HURRICANE3_SUPPORT */ 30755 #ifdef BCM_TRIDENT_SUPPORT 30756 { 30757 return _bcm_td_mod_port_tpid_add(unit, mod, port, tpid); 30758 } 30759 #endif /* BCM_TRIDENT_SUPPORT */ 30760 return BCM_E_UNAVAIL; 30761 } 30762 30763 /* 30764 * Function: 30765 * bcm_esw_port_tpid_add 30766 * Description: 30767 * Add allowed TPID for a port. 30768 * Parameters: 30769 * unit - (IN) Device number 30770 * port - (IN) Port number 30771 * tpid - (IN) Tag Protocol ID 30772 * color_select - (IN) Color mode for TPID 30773 * Return Value: 30774 * BCM_E_XXX 30775 */ 30776 int 30777 bcm_esw_port_tpid_add(int unit, bcm_port_t port, 30778 uint16 tpid, int color_select) 30779 { 30780 int rv = BCM_E_UNAVAIL; 30781 bcm_module_t mod_out; 30782 bcm_port_t port_out; 30783 bcm_trunk_t tgid_out; 30784 int id_out; 30785 int is_local = 0; 30786 #ifdef BCM_FIREBOLT_SUPPORT 30787 bcm_port_t orig_port = -1; 30788 #endif 30789 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 30790 int vp = -1; 30791 #endif 30792 30793 if (color_select != BCM_COLOR_PRIORITY && 30794 color_select != BCM_COLOR_OUTER_CFI && 30795 color_select != BCM_COLOR_INNER_CFI) { 30796 return BCM_E_PARAM; 30797 } 30798 30799 /* Make sure port module is initialized. */ 30800 PORT_INIT(unit); 30801 30802 if(bcm_common_oamp_port_enable_get(unit, port)) { 30803 LOG_ERROR(BSL_LS_BCM_PORT, 30804 (BSL_META("Error: Not permitted on OAMP port %d.n"), 30805 port)); 30806 return BCM_E_PARAM; 30807 } 30808 30809 if (BCM_GPORT_IS_SET(port)) { 30810 /* Handle virtual ports separetly */ 30811 if (BCM_GPORT_IS_MPLS_PORT(port) || 30812 BCM_GPORT_IS_MIM_PORT(port) || 30813 BCM_GPORT_IS_TRILL_PORT(port) || 30814 BCM_GPORT_IS_VXLAN_PORT(port) || 30815 BCM_GPORT_IS_VLAN_PORT(port)) { 30816 30817 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 30818 #if defined(BCM_TRX_SUPPORT) 30819 PORT_LOCK(unit); 30820 rv = _bcm_trx_vp_tpid_add(unit, port, tpid, color_select); 30821 PORT_UNLOCK(unit); 30822 #endif 30823 } 30824 return rv; 30825 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 30826 30827 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 30828 #ifdef BCM_HGPROXY_COE_SUPPORT 30829 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 30830 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 30831 &mod_out, &port_out, &tgid_out, &id_out)); 30832 orig_port = port; 30833 BCM_IF_ERROR_RETURN( 30834 _bcmi_coe_subport_physical_port_get(unit, 30835 port, &port)); 30836 } else { 30837 return BCM_E_PORT; 30838 } 30839 #endif 30840 } else if (soc_feature(unit, soc_feature_subtag_coe) || 30841 soc_feature(unit, soc_feature_linkphy_coe)) { 30842 #ifdef BCM_KATANA2_SUPPORT 30843 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 30844 port)) { 30845 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 30846 &mod_out, &port_out, &tgid_out, &id_out)); 30847 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 30848 mod_out, port_out, &port)); 30849 } else { 30850 return BCM_E_PORT; 30851 } 30852 #endif 30853 } else { 30854 return BCM_E_PORT; 30855 } 30856 } else if (BCM_GPORT_IS_TRUNK(port)) { 30857 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 30858 if (soc_feature(unit, soc_feature_vp_lag)) { 30859 BCM_IF_ERROR_RETURN( 30860 _bcm_esw_trunk_tid_to_vp_lag_vp( 30861 unit, BCM_GPORT_TRUNK_GET(port), &vp)); 30862 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 30863 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 30864 PORT_LOCK(unit); 30865 rv = _bcm_trx_vp_tpid_add(unit, port, tpid, 30866 color_select); 30867 PORT_UNLOCK(unit); 30868 return rv; 30869 } 30870 } else { 30871 return BCM_E_PARAM; 30872 } 30873 } 30874 #endif 30875 return BCM_E_PARAM; 30876 } else { 30877 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 30878 &mod_out, &port_out, &tgid_out, &id_out)); 30879 if ((-1 != tgid_out) || (-1 != id_out)) { 30880 return BCM_E_PARAM; 30881 } 30882 30883 BCM_IF_ERROR_RETURN 30884 (_bcm_esw_modid_is_local(unit, mod_out, &is_local)); 30885 #if defined(BCM_HURRICANE3_SUPPORT) 30886 /* Here only take care non-local port, the local port will 30887 * be handled later (by _bcm_fb2_port_tpid_add) */ 30888 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 30889 if (!is_local) { 30890 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 30891 return _bcm_esw_mod_port_tpid_add(unit, mod_out, 30892 port_out, tpid); 30893 } else { 30894 return BCM_E_PARAM; 30895 } 30896 } else { 30897 BCM_IF_ERROR_RETURN( 30898 bcm_esw_port_local_get(unit, port, &port)); 30899 } 30900 } else 30901 #endif 30902 { 30903 if (!is_local) { 30904 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 30905 return _bcm_esw_mod_port_tpid_add(unit, mod_out, 30906 port_out, tpid); 30907 } else { 30908 return BCM_E_PARAM; 30909 } 30910 } else { 30911 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 30912 BCM_IF_ERROR_RETURN 30913 (_bcm_esw_mod_port_tpid_add(unit, mod_out, 30914 port_out, tpid)); 30915 } 30916 BCM_IF_ERROR_RETURN( 30917 bcm_esw_port_local_get(unit, port, &port)); 30918 } 30919 } 30920 } 30921 30922 } else if (!SOC_PORT_VALID(unit, port)) { 30923 return BCM_E_PORT; 30924 } 30925 30926 #if defined (BCM_TRX_SUPPORT) 30927 if (SOC_IS_TRX(unit) && 30928 (PORT(unit, port).dtag_mode == BCM_PORT_DTAG_MODE_EXTERNAL)) { 30929 /* For DT mode external ports, don't enable any outer TPIDs */ 30930 return BCM_E_NONE; 30931 } 30932 #endif 30933 30934 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 30935 || defined(BCM_RAVEN_SUPPORT) 30936 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 30937 PORT_LOCK(unit); 30938 if (orig_port != -1) { 30939 rv = _bcm_fb2_port_tpid_add(unit, orig_port, tpid, color_select); 30940 } else { 30941 rv = _bcm_fb2_port_tpid_add(unit, port, tpid, color_select); 30942 } 30943 PORT_UNLOCK(unit); 30944 } 30945 #endif 30946 return rv; 30947 } 30948 30949 /* 30950 * Function: 30951 * _bcm_esw_mod_port_tpid_delete 30952 * Description: 30953 * Delete TPID for a (module, port). 30954 * Parameters: 30955 * unit - (IN) Device number 30956 * mod - (IN) Module ID 30957 * port - (IN) Port number 30958 * tpid - (IN) Tag Protocol ID 30959 * Return Value: 30960 * BCM_E_XXX 30961 */ 30962 STATIC int 30963 _bcm_esw_mod_port_tpid_delete(int unit, bcm_module_t mod, bcm_port_t port, 30964 uint16 tpid) 30965 { 30966 #ifdef BCM_HURRICANE3_SUPPORT 30967 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 30968 return _bcm_hr3_mod_port_tpid_delete(unit, mod, port, tpid); 30969 } else 30970 #endif /* BCM_HURRICANE3_SUPPORT */ 30971 #ifdef BCM_TRIDENT_SUPPORT 30972 { 30973 return _bcm_td_mod_port_tpid_delete(unit, mod, port, tpid); 30974 } 30975 #endif /* BCM_TRIDENT_SUPPORT */ 30976 return BCM_E_UNAVAIL; 30977 } 30978 30979 /* 30980 * Function: 30981 * bcm_esw_port_tpid_delete 30982 * Description: 30983 * Delete allowed TPID for a port. 30984 * Parameters: 30985 * unit - (IN) Device number 30986 * port - (IN) Port number 30987 * tpid - (IN) Tag Protocol ID 30988 * Return Value: 30989 * BCM_E_XXX 30990 */ 30991 int 30992 bcm_esw_port_tpid_delete(int unit, bcm_port_t port, uint16 tpid) 30993 { 30994 int rv = BCM_E_UNAVAIL; 30995 bcm_module_t mod_out; 30996 bcm_port_t port_out; 30997 bcm_trunk_t tgid_out; 30998 int id_out; 30999 int is_local = 0; 31000 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 31001 int vp = -1; 31002 #endif 31003 31004 /* Make sure port module is initialized. */ 31005 PORT_INIT(unit); 31006 31007 if(bcm_common_oamp_port_enable_get(unit, port)) { 31008 LOG_ERROR(BSL_LS_BCM_PORT, 31009 (BSL_META("Error: Not permitted on OAMP port %d.n"), 31010 port)); 31011 return BCM_E_PARAM; 31012 } 31013 31014 if (BCM_GPORT_IS_SET(port)) { 31015 /* Handle virtual ports separetly */ 31016 if (BCM_GPORT_IS_MPLS_PORT(port) || 31017 BCM_GPORT_IS_TRILL_PORT(port) || 31018 BCM_GPORT_IS_MIM_PORT(port) || 31019 BCM_GPORT_IS_VXLAN_PORT(port) || 31020 BCM_GPORT_IS_VLAN_PORT(port)) { 31021 31022 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31023 #if defined(BCM_TRX_SUPPORT) 31024 PORT_LOCK(unit); 31025 rv = _bcm_trx_vp_tpid_delete(unit, port, tpid); 31026 PORT_UNLOCK(unit); 31027 #endif 31028 } 31029 return rv; 31030 } else if (BCM_GPORT_IS_SUBPORT_GROUP(port)) { 31031 if (soc_feature(unit, soc_feature_subtag_coe)) { 31032 #if defined(BCM_KATANA2_SUPPORT) 31033 PORT_LOCK(unit); 31034 rv = bcm_kt2_subport_subtag_port_tpid_delete(unit, port, tpid); 31035 PORT_UNLOCK(unit); 31036 #endif 31037 } 31038 return rv; 31039 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 31040 31041 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 31042 #ifdef BCM_HGPROXY_COE_SUPPORT 31043 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 31044 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31045 &mod_out, &port_out, &tgid_out, &id_out)); 31046 } else { 31047 return BCM_E_PORT; 31048 } 31049 #endif 31050 } else if (soc_feature(unit, soc_feature_subtag_coe) || 31051 soc_feature(unit, soc_feature_linkphy_coe)) { 31052 #ifdef BCM_KATANA2_SUPPORT 31053 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 31054 port)) { 31055 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31056 &mod_out, &port_out, &tgid_out, &id_out)); 31057 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 31058 mod_out, port_out, &port)); 31059 } else { 31060 return BCM_E_PORT; 31061 } 31062 #endif 31063 } else { 31064 return BCM_E_PORT; 31065 } 31066 } else if (BCM_GPORT_IS_TRUNK(port)) { 31067 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 31068 if (soc_feature(unit, soc_feature_vp_lag)) { 31069 BCM_IF_ERROR_RETURN( 31070 _bcm_esw_trunk_tid_to_vp_lag_vp( 31071 unit, BCM_GPORT_TRUNK_GET(port), &vp)); 31072 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 31073 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31074 PORT_LOCK(unit); 31075 rv = _bcm_trx_vp_tpid_delete(unit, port, tpid); 31076 PORT_UNLOCK(unit); 31077 return rv; 31078 } 31079 } else { 31080 return BCM_E_PARAM; 31081 } 31082 } 31083 #endif 31084 return BCM_E_PARAM; 31085 } else { 31086 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31087 &mod_out, &port_out, &tgid_out, &id_out)); 31088 if ((-1 != tgid_out) || (-1 != id_out)) { 31089 return BCM_E_PARAM; 31090 } 31091 31092 BCM_IF_ERROR_RETURN 31093 (_bcm_esw_modid_is_local(unit, mod_out, &is_local)); 31094 #if defined(BCM_HURRICANE3_SUPPORT) 31095 /* Here only take care non-local port, the local port will 31096 * be handled later (by _bcm_fb2_port_tpid_delete) */ 31097 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 31098 if (!is_local) { 31099 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31100 return _bcm_esw_mod_port_tpid_delete(unit, mod_out, 31101 port_out, tpid); 31102 } else { 31103 return BCM_E_PARAM; 31104 } 31105 } else { 31106 BCM_IF_ERROR_RETURN( 31107 bcm_esw_port_local_get(unit, port, &port)); 31108 } 31109 } else 31110 #endif 31111 { 31112 if (!is_local) { 31113 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31114 return _bcm_esw_mod_port_tpid_delete(unit, mod_out, 31115 port_out, tpid); 31116 } else { 31117 return BCM_E_PARAM; 31118 } 31119 } else { 31120 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31121 BCM_IF_ERROR_RETURN 31122 (_bcm_esw_mod_port_tpid_delete(unit, mod_out, 31123 port_out, tpid)); 31124 } 31125 BCM_IF_ERROR_RETURN( 31126 bcm_esw_port_local_get(unit, port, &port)); 31127 } 31128 } 31129 } 31130 31131 } else if (!SOC_PORT_VALID(unit, port)) { 31132 return BCM_E_PORT; 31133 } 31134 31135 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 31136 || defined(BCM_RAVEN_SUPPORT) 31137 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31138 PORT_LOCK(unit); 31139 rv = _bcm_fb2_port_tpid_delete(unit, port, tpid); 31140 PORT_UNLOCK(unit); 31141 } 31142 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 31143 return rv; 31144 } 31145 31146 /* 31147 * Function: 31148 * _bcm_esw_mod_port_tpid_delete_all 31149 * Description: 31150 * Delete all TPID for a (module, port). 31151 * Parameters: 31152 * unit - (IN) Device number 31153 * mod - (IN) Module ID 31154 * port - (IN) Port number 31155 * Return Value: 31156 * BCM_E_XXX 31157 */ 31158 STATIC int 31159 _bcm_esw_mod_port_tpid_delete_all(int unit, bcm_module_t mod, bcm_port_t port) 31160 { 31161 #ifdef BCM_HURRICANE3_SUPPORT 31162 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 31163 return _bcm_hr3_mod_port_tpid_delete_all(unit, mod, port); 31164 } else 31165 #endif /* BCM_HURRICANE3_SUPPORT */ 31166 #ifdef BCM_TRIDENT_SUPPORT 31167 { 31168 return _bcm_td_mod_port_tpid_delete_all(unit, mod, port); 31169 } 31170 #endif /* BCM_TRIDENT_SUPPORT */ 31171 return BCM_E_UNAVAIL; 31172 } 31173 31174 /* 31175 * Function: 31176 * bcm_esw_port_tpid_delete_all 31177 * Description: 31178 * Delete all allowed TPID for a port. 31179 * Parameters: 31180 * unit - (IN) Device number 31181 * port - (IN) Port number 31182 * Return Value: 31183 * BCM_E_XXX 31184 */ 31185 int 31186 bcm_esw_port_tpid_delete_all(int unit, bcm_port_t port) 31187 { 31188 int rv = BCM_E_UNAVAIL; 31189 bcm_module_t mod_out; 31190 bcm_port_t port_out; 31191 bcm_trunk_t tgid_out; 31192 int id_out; 31193 int is_local = 0; 31194 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 31195 int vp = -1; 31196 #endif 31197 31198 /* Make sure port module is initialized. */ 31199 PORT_INIT(unit); 31200 31201 if(bcm_common_oamp_port_enable_get(unit, port)) { 31202 LOG_ERROR(BSL_LS_BCM_PORT, 31203 (BSL_META("Error: Not permitted on OAMP port %d.n"), 31204 port)); 31205 return BCM_E_PARAM; 31206 } 31207 31208 if (BCM_GPORT_IS_SET(port)) { 31209 /* Handle virtual ports separetly */ 31210 if (BCM_GPORT_IS_MPLS_PORT(port) || 31211 BCM_GPORT_IS_MIM_PORT(port) || 31212 BCM_GPORT_IS_VXLAN_PORT(port) || 31213 BCM_GPORT_IS_VLAN_PORT(port)) { 31214 31215 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31216 #if defined(BCM_TRX_SUPPORT) 31217 PORT_LOCK(unit); 31218 rv = _bcm_trx_vp_tpid_delete_all(unit, port); 31219 PORT_UNLOCK(unit); 31220 #endif 31221 } 31222 return rv; 31223 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 31224 31225 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 31226 #ifdef BCM_HGPROXY_COE_SUPPORT 31227 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 31228 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31229 &mod_out, &port_out, &tgid_out, &id_out)); 31230 } else { 31231 return BCM_E_PORT; 31232 } 31233 #endif 31234 } else if (soc_feature(unit, soc_feature_subtag_coe) || 31235 soc_feature(unit, soc_feature_linkphy_coe)) { 31236 #ifdef BCM_KATANA2_SUPPORT 31237 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 31238 port)) { 31239 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31240 &mod_out, &port_out, &tgid_out, &id_out)); 31241 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 31242 mod_out, port_out, &port)); 31243 } else { 31244 return BCM_E_PORT; 31245 } 31246 #endif 31247 } else { 31248 return BCM_E_PORT; 31249 } 31250 } else if (BCM_GPORT_IS_TRUNK(port)) { 31251 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 31252 if (soc_feature(unit, soc_feature_vp_lag)) { 31253 BCM_IF_ERROR_RETURN( 31254 _bcm_esw_trunk_tid_to_vp_lag_vp( 31255 unit, BCM_GPORT_TRUNK_GET(port), &vp)); 31256 if (_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 31257 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31258 PORT_LOCK(unit); 31259 rv = _bcm_trx_vp_tpid_delete_all(unit, port); 31260 PORT_UNLOCK(unit); 31261 return rv; 31262 } 31263 } else { 31264 return BCM_E_PARAM; 31265 } 31266 } 31267 #endif 31268 return BCM_E_PARAM; 31269 } else { 31270 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31271 &mod_out, &port_out, &tgid_out, &id_out)); 31272 if ((-1 != tgid_out) || (-1 != id_out)) { 31273 return BCM_E_PARAM; 31274 } 31275 31276 BCM_IF_ERROR_RETURN 31277 (_bcm_esw_modid_is_local(unit, mod_out, &is_local)); 31278 #if defined(BCM_HURRICANE3_SUPPORT) 31279 /* Here only take care non-local port, the local port will 31280 * be handled later (by _bcm_fb2_port_tpid_delete_all) */ 31281 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 31282 if (!is_local) { 31283 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31284 return _bcm_esw_mod_port_tpid_delete_all(unit, mod_out, 31285 port_out); 31286 } else { 31287 return BCM_E_PARAM; 31288 } 31289 } else { 31290 BCM_IF_ERROR_RETURN( 31291 bcm_esw_port_local_get(unit, port, &port)); 31292 } 31293 } else 31294 #endif 31295 { 31296 if (!is_local) { 31297 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31298 return _bcm_esw_mod_port_tpid_delete_all(unit, mod_out, 31299 port_out); 31300 } else { 31301 return BCM_E_PARAM; 31302 } 31303 } else { 31304 if (soc_mem_is_valid(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31305 BCM_IF_ERROR_RETURN 31306 (_bcm_esw_mod_port_tpid_delete_all(unit, mod_out, 31307 port_out)); 31308 } 31309 BCM_IF_ERROR_RETURN( 31310 bcm_esw_port_local_get(unit, port, &port)); 31311 } 31312 } 31313 } 31314 31315 } else if (!SOC_PORT_VALID(unit, port)) { 31316 return BCM_E_PORT; 31317 } 31318 31319 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 31320 || defined(BCM_RAVEN_SUPPORT) 31321 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31322 PORT_LOCK(unit); 31323 rv = _bcm_fb2_port_tpid_delete_all(unit, port); 31324 PORT_UNLOCK(unit); 31325 } 31326 #endif 31327 return rv; 31328 } 31329 31330 /* 31331 * Function: 31332 * _bcm_esw_mod_port_inner_tpid_enable 31333 * Description: 31334 * Enable the Inner Tag Protocol ID for a (module, port). 31335 * Parameters: 31336 * unit - Device number 31337 * mod - Module ID 31338 * port - Port number 31339 * Return Value: 31340 * BCM_E_XXX 31341 */ 31342 STATIC int 31343 _bcm_esw_mod_port_inner_tpid_enable(int unit, bcm_module_t mod, bcm_port_t port) 31344 { 31345 int rv = BCM_E_NONE; 31346 if (!SOC_MEM_IS_VALID(unit, SYSTEM_CONFIG_TABLE_MODBASEm)) { 31347 int sys_index = 0; 31348 uint32 enable = 1; 31349 system_config_table_entry_t systab; 31350 sys_index = mod * 64 + port; 31351 rv = READ_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ANY, sys_index, 31352 &systab); 31353 if (BCM_SUCCESS(rv)) { 31354 soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &systab, 31355 INNER_TPID_ENABLEf, enable); 31356 rv = WRITE_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ALL, 31357 sys_index, &systab); 31358 } 31359 } else { 31360 #ifdef BCM_HURRICANE3_SUPPORT 31361 if (SOC_IS_HURRICANE3(unit)) { 31362 rv = _bcm_hr3_mod_port_inner_tpid_enable_write(unit, mod, port, 1); 31363 } 31364 #endif /* BCM_HURRICANE3_SUPPORT */ 31365 } 31366 return rv; 31367 } 31368 31369 /* 31370 * Function: 31371 * bcm_port_inner_tpid_set 31372 * Purpose: 31373 * Set the expected TPID for the inner tag in double-tagging mode. 31374 * Parameters: 31375 * unit - Device number 31376 * port - Port number 31377 * tpid - Tag Protocol ID 31378 * Returns: 31379 * BCM_E_NONE - Success. 31380 * BCM_E_XXX 31381 */ 31382 int 31383 bcm_esw_port_inner_tpid_set(int unit, bcm_port_t port, uint16 tpid) 31384 { 31385 int rv = BCM_E_UNAVAIL; 31386 bcm_module_t mod_out = BCM_MODID_INVALID; 31387 bcm_port_t port_out; 31388 bcm_trunk_t tgid_out; 31389 int is_local = TRUE; 31390 int id_out; 31391 31392 /* Make sure port module is initialized. */ 31393 PORT_INIT(unit); 31394 31395 if(bcm_common_oamp_port_enable_get(unit, port)) { 31396 LOG_ERROR(BSL_LS_BCM_PORT, 31397 (BSL_META("Error: Not permitted on OAMP port %d.n"), 31398 port)); 31399 return BCM_E_PARAM; 31400 } 31401 31402 if (BCM_GPORT_IS_SET(port)) { 31403 /* Handle virtual ports separetly */ 31404 if (BCM_GPORT_IS_MPLS_PORT(port) || 31405 BCM_GPORT_IS_MIM_PORT(port) || 31406 BCM_GPORT_IS_VLAN_PORT(port)) { 31407 31408 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31409 #if defined(BCM_TRX_SUPPORT) 31410 PORT_LOCK(unit); 31411 rv = _bcm_trx_vp_tpid_set(unit, port,tpid); 31412 PORT_UNLOCK(unit); 31413 #endif 31414 } 31415 return rv; 31416 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 31417 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 31418 #ifdef BCM_HGPROXY_COE_SUPPORT 31419 if (_BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 31420 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31421 &mod_out, &port_out, &tgid_out, &id_out)); 31422 BCM_IF_ERROR_RETURN( 31423 _bcmi_coe_subport_physical_port_get(unit, 31424 port, &port)); 31425 } else { 31426 return BCM_E_PORT; 31427 } 31428 #endif 31429 } else if (soc_feature(unit, soc_feature_subtag_coe) || 31430 soc_feature(unit, soc_feature_linkphy_coe)) { 31431 #ifdef BCM_KATANA2_SUPPORT 31432 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, 31433 port)) { 31434 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 31435 &mod_out, &port_out, &tgid_out, &id_out)); 31436 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 31437 mod_out, port_out, &port)); 31438 } else { 31439 return BCM_E_PORT; 31440 } 31441 #endif 31442 } else { 31443 return BCM_E_PORT; 31444 } 31445 } else { 31446 BCM_IF_ERROR_RETURN( 31447 _bcm_esw_gport_resolve(unit, port, &mod_out, &port_out, 31448 &tgid_out, &id_out)); 31449 if ((-1 != tgid_out) || (-1 != id_out)) { 31450 return BCM_E_PARAM; 31451 } 31452 port = port_out; 31453 BCM_IF_ERROR_RETURN( 31454 _bcm_esw_modid_is_local(unit, mod_out, &is_local)); 31455 } 31456 } else if (!SOC_PORT_VALID(unit, port)) { 31457 return BCM_E_PORT; 31458 } 31459 31460 if (soc_feature(unit, soc_feature_inner_tpid_enable)) { 31461 if (BCM_MODID_INVALID == mod_out) { 31462 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod_out)); 31463 } 31464 BCM_IF_ERROR_RETURN( 31465 _bcm_esw_mod_port_inner_tpid_enable(unit, mod_out, port)); 31466 31467 if (TRUE == is_local) { 31468 uint32 enable = 1; 31469 BCM_IF_ERROR_RETURN( 31470 soc_mem_field32_modify(unit, PORT_TABm, port, 31471 INNER_TPID_ENABLEf, enable)); 31472 if(soc_reg_field_valid(unit, EGR_VLAN_CONTROL_1r, INNER_TPID_ENABLEf)){ 31473 soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port, 31474 INNER_TPID_ENABLEf, enable); 31475 } 31476 } 31477 } else { 31478 /* INNER_TPID_ENABLEf is also in SYSTEM_CONFIG_TABLE which is for Higig. 31479 * Hence, bypass the switched port check */ 31480 31481 PORT_SWITCHED_CHECK(unit, port); 31482 } 31483 31484 #ifdef BCM_FIREBOLT_SUPPORT 31485 if (SOC_IS_FBX(unit)) { 31486 uint32 rval; 31487 #if 0 31488 int tpid_index; 31489 31490 for (tpid_index = 0; tpid_index < 4; tpid_index++) { 31491 if (SOC_REG_IS_VALID(unit, PARSER1_ING_INNER_TPIDr)) { 31492 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 31493 PARSER1_ING_INNER_TPIDr, tpid_index, TPIDf, tpid)); 31494 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 31495 PARSER2_ING_INNER_TPIDr, tpid_index, TPIDf, tpid)); 31496 } 31497 31498 if (SOC_REG_IS_VALID(unit, EGR_INNER_TPIDr)) { 31499 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 31500 EGR_INNER_TPIDr, tpid_index, TPIDf, tpid)); 31501 } 31502 31503 if (SOC_REG_IS_VALID(unit, EGR_PARSER_INNER_TPIDr)) { 31504 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 31505 EGR_PARSER_INNER_TPIDr, tpid_index, TPIDf, tpid)); 31506 } 31507 } 31508 #endif 31509 31510 BCM_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &rval)); 31511 soc_reg_field_set(unit, VLAN_CTRLr, &rval, INNER_TPIDf, tpid); 31512 BCM_IF_ERROR_RETURN(WRITE_VLAN_CTRLr(unit, rval)); 31513 if (soc_reg_field_valid(unit, EGR_CONFIGr, INNER_TPIDf)) { 31514 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIGr, 31515 REG_PORT_ANY, INNER_TPIDf, tpid)); 31516 } 31517 #ifdef BCM_TRIDENT3_SUPPORT 31518 if (SOC_IS_TRIDENT3X(unit)) { 31519 if (soc_reg_field_valid(unit, EGR_CONFIG_1_64r, INNER_TPIDf)) { 31520 BCM_IF_ERROR_RETURN(soc_reg_field32_modify(unit, EGR_CONFIG_1_64r, 31521 REG_PORT_ANY, INNER_TPIDf, tpid)); 31522 } 31523 } 31524 #endif 31525 if (SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port)) { 31526 /* 31527 * At now, this mac drvier is only supported by XMAC & XLMAC 31528 * If function return BCM_E_UNAVAIL, it should be correct. 31529 */ 31530 if (SOC_USE_PORTCTRL(unit)) { 31531 (void)bcmi_esw_portctrl_vlan_inner_tpid_set(unit, port, tpid); 31532 } else { 31533 BCM_IF_ERROR_NOT_UNAVAIL_RETURN( 31534 MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 31535 SOC_MAC_CONTROL_RX_VLAN_TAG_INNER_TPID, tpid)); 31536 } 31537 } 31538 rv = BCM_E_NONE; 31539 } 31540 #endif 31541 #if defined(BCM_MONTEREY_SUPPORT) 31542 if (soc_feature(unit, soc_feature_obm_tpid_sync) && (rv == BCM_E_NONE)) { 31543 bcm_inner_tpid_obm_set(unit, tpid); 31544 } 31545 #endif 31546 return rv; 31547 } 31548 31549 /* 31550 * Function: 31551 * bcm_port_inner_tpid_get 31552 * Purpose: 31553 * Get the expected TPID for the inner tag in double-tagging mode. 31554 * Parameters: 31555 * unit - Device number 31556 * port - Port number 31557 * tpid - (OUT) Tag Protocol ID 31558 * Returns: 31559 * BCM_E_NONE - Success. 31560 * BCM_E_XXX 31561 */ 31562 int 31563 bcm_esw_port_inner_tpid_get(int unit, bcm_port_t port, uint16 *tpid) 31564 { 31565 int rv = BCM_E_UNAVAIL; 31566 31567 /* Make sure port module is initialized. */ 31568 PORT_INIT(unit); 31569 31570 if(bcm_common_oamp_port_enable_get(unit, port)) { 31571 LOG_ERROR(BSL_LS_BCM_PORT, 31572 (BSL_META("Error: Not permitted on OAMP port %d.n"), 31573 port)); 31574 return BCM_E_PARAM; 31575 } 31576 31577 if (BCM_GPORT_IS_SET(port)) { 31578 /* Handle virtual ports separetly */ 31579 if (BCM_GPORT_IS_MPLS_PORT(port) || 31580 BCM_GPORT_IS_MIM_PORT(port) || 31581 BCM_GPORT_IS_VLAN_PORT(port)) { 31582 31583 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 31584 #if defined(BCM_TRX_SUPPORT) 31585 PORT_LOCK(unit); 31586 rv = _bcm_trx_vp_tpid_get(unit, port,tpid); 31587 PORT_UNLOCK(unit); 31588 #endif 31589 } 31590 return rv; 31591 } else { 31592 BCM_IF_ERROR_RETURN( 31593 _bcm_esw_port_gport_validate(unit, port, &port)); 31594 } 31595 31596 } else if (!SOC_PORT_VALID(unit, port)) { 31597 return BCM_E_PORT; 31598 } 31599 31600 PORT_SWITCHED_CHECK(unit, port); 31601 31602 if (tpid == NULL) { 31603 return BCM_E_PARAM; 31604 } 31605 31606 #ifdef BCM_FIREBOLT_SUPPORT 31607 if (SOC_IS_FBX(unit)) { 31608 uint32 rval; 31609 BCM_IF_ERROR_RETURN(READ_VLAN_CTRLr(unit, &rval)); 31610 *tpid = soc_reg_field_get(unit, VLAN_CTRLr, rval, INNER_TPIDf); 31611 return BCM_E_NONE; 31612 } 31613 #endif 31614 31615 return BCM_E_UNAVAIL; 31616 } 31617 31618 /* 31619 * Function: 31620 * bcm_esw_port_frame_max_set 31621 * Description: 31622 * Set the maximum receive frame size for the port 31623 * Parameters: 31624 * unit - Device number 31625 * in_port - Port number 31626 * size - Maximum frame size in bytes 31627 * Return Value: 31628 * BCM_E_XXX 31629 * Notes: 31630 * Depending on chip or port type the actual maximum receive frame size 31631 * might be slightly higher. 31632 * 31633 * It looks like this operation is performed the same way on all the chips 31634 * and the only depends on the port type. 31635 */ 31636 int 31637 bcm_esw_port_frame_max_set(int unit, bcm_port_t in_port, int size) 31638 { 31639 bcm_port_t port; 31640 int max_size = BCM_PORT_JUMBO_MAXSZ; 31641 #if defined(BCM_XGS3_SWITCH_SUPPORT) 31642 uint32 rval; 31643 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 31644 #if defined(BCM_KATANA2_SUPPORT) 31645 int min_pp_port = SOC_INFO(unit).pp_port_index_min; 31646 #endif /* BCM_KATANA2_SUPPORT */ 31647 31648 /* Make sure port module is initialized. */ 31649 PORT_INIT(unit); 31650 31651 if(bcm_common_oamp_port_enable_get(unit, in_port)) { 31652 LOG_ERROR(BSL_LS_BCM_PORT, 31653 (BSL_META("Error: Not permitted on OAMP port %d.n"), 31654 in_port)); 31655 return BCM_E_PARAM; 31656 } 31657 31658 /* Call Port Control module */ 31659 if (SOC_USE_PORTCTRL(unit)) { 31660 return bcmi_esw_portctrl_frame_max_set(unit, in_port, size); 31661 } 31662 31663 /* Set jumbo max size to 12k for Katana2 as per Arch team recommendation */ 31664 max_size = SOC_INFO(unit).max_mtu; 31665 #ifdef BCM_TRIDENT2_SUPPORT 31666 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TOMAHAWKX(unit)) { 31667 if (IS_XE_PORT(unit, in_port) || IS_GE_PORT(unit, in_port) 31668 || IS_CE_PORT(unit, in_port) 31669 || (IS_C_PORT(unit, in_port) && IS_E_PORT(unit, in_port))) { 31670 max_size -= 4; 31671 } 31672 } 31673 #endif 31674 if (size < 0 || size > max_size) { 31675 return BCM_E_PARAM; 31676 } 31677 31678 if (!BCM_GPORT_IS_SET(in_port)) { 31679 if (!SOC_PBMP_MEMBER((PBMP_PORT_ALL(unit)), in_port)) { 31680 return BCM_E_PORT; 31681 } 31682 } 31683 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, in_port, &port)); 31684 31685 #if defined(BCM_KATANA2_SUPPORT) 31686 /* LinkPHY/SubportTag CoE subport does not have MAC */ 31687 #if defined(BCM_METROLITE_SUPPORT) 31688 if ((soc_feature(unit, soc_feature_linkphy_coe) || 31689 soc_feature(unit, soc_feature_subtag_coe)) && 31690 soc_feature(unit, soc_feature_discontinuous_pp_port) && 31691 (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, port) && 31692 !_SOC_IS_PORT_LINKPHY_SUBTAG(unit, port))) { 31693 } else 31694 #endif 31695 if ((soc_feature(unit, soc_feature_linkphy_coe) || 31696 soc_feature(unit, soc_feature_subtag_coe)) && 31697 !soc_feature(unit, soc_feature_discontinuous_pp_port) && 31698 (port >= min_pp_port)) { 31699 } else 31700 #endif 31701 { 31702 SOC_IF_ERROR_RETURN 31703 (MAC_FRAME_MAX_SET(PORT(unit, port).p_mac, unit, port, size)); 31704 } 31705 31706 #ifdef BCM_SHADOW_SUPPORT 31707 if (SOC_IS_SHADOW(unit)) { 31708 SOC_IF_ERROR_RETURN(READ_EGR_L2_MTUr(unit, port, &rval)); 31709 soc_reg_field_set(unit, EGR_L2_MTUr, &rval, 31710 VALUEf, size + 4); 31711 SOC_IF_ERROR_RETURN(WRITE_EGR_L2_MTUr(unit, port, rval)); 31712 } else 31713 #endif /* BCM_SHADOW_SUPPORT */ 31714 31715 #ifdef BCM_XGS3_SWITCH_SUPPORT 31716 if (SOC_IS_XGS3_SWITCH(unit)) { 31717 soc_reg_t reg; 31718 egr_mtu_entry_t mtu; 31719 uint32 mtu_size = size; 31720 uint32 field_val_set = 1; 31721 31722 if (IS_XE_PORT(unit, port) || IS_GE_PORT(unit, port) 31723 || IS_CE_PORT(unit, port) 31724 || (IS_C_PORT(unit, port) && IS_E_PORT(unit, port))) { 31725 mtu_size += 4; 31726 } 31727 31728 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 31729 soc_mem_t mem = EGR_MTUm; 31730 if (soc_feature(unit, soc_feature_egr_all_profile)) { 31731 BCM_IF_ERROR_RETURN( 31732 bcm_esw_port_egr_lport_field_set(unit, port, mem, 31733 MTU_SIZEf, mtu_size)); 31734 31735 } else { 31736 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 31737 port, &mtu)); 31738 soc_mem_field_set (unit, mem, (uint32 *)&mtu, MTU_SIZEf, 31739 &mtu_size); 31740 if (soc_mem_field_valid(unit, EGR_MTUm, MTU_ENABLEf)) { 31741 soc_mem_field_set(unit, EGR_MTUm, (uint32 *)&mtu, 31742 MTU_ENABLEf, &field_val_set); 31743 } 31744 31745 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ANY, 31746 port, &mtu)); 31747 } 31748 } else { 31749 reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr; 31750 31751 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 31752 soc_reg_field_set(unit, reg, &rval, MTU_SIZEf, mtu_size); 31753 if (soc_reg_field_valid(unit, reg, MTU_ENABLEf)) { 31754 soc_reg_field_set(unit, reg, &rval, MTU_ENABLEf, 1); 31755 } 31756 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 31757 } 31758 } 31759 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 31760 31761 return BCM_E_NONE; 31762 } 31763 31764 /* 31765 * Function: 31766 * bcm_esw_port_frame_max_get 31767 * Description: 31768 * Get the maximum receive frame size for the port 31769 * Parameters: 31770 * unit - Device number 31771 * in_port - Port number 31772 * size - Maximum frame size in bytes 31773 * Return Value: 31774 * BCM_E_XXX 31775 * Notes: 31776 * Depending on chip or port type the actual maximum receive frame size 31777 * might be slightly higher. 31778 * 31779 * For GE ports that use 2 separate MACs (one for GE and another one for 31780 * 10/100 modes) the function returns the maximum rx frame size set for 31781 * the current mode. 31782 */ 31783 int 31784 bcm_esw_port_frame_max_get(int unit, bcm_port_t in_port, int *size) 31785 { 31786 int rv = BCM_E_UNAVAIL; 31787 bcm_port_t port; 31788 #if defined(BCM_KATANA2_SUPPORT) 31789 uint32 rval; 31790 int min_pp_port = SOC_INFO(unit).pp_port_index_min; 31791 int max_phy_port = KT2_MAX_PHYSICAL_PORTS; 31792 31793 #if defined(BCM_SABER2_SUPPORT) 31794 if(SOC_IS_SABER2(unit)) { 31795 max_phy_port = SB2_MAX_PHYSICAL_PORTS; 31796 } 31797 #endif 31798 #endif 31799 31800 /* Make sure port module is initialized. */ 31801 PORT_INIT(unit); 31802 31803 /* Call Port Control module */ 31804 if (SOC_USE_PORTCTRL(unit)) { 31805 return bcmi_esw_portctrl_frame_max_get(unit, in_port, size); 31806 } 31807 31808 #if defined(BCM_KATANA2_SUPPORT) 31809 if (SOC_IS_KATANA2(unit) && (!BCM_GPORT_IS_SET(in_port)) && 31810 (!((in_port >= 1) && (in_port <= max_phy_port) && 31811 SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit),in_port)))) { 31812 return BCM_E_PORT; 31813 } 31814 #endif 31815 31816 if(bcm_common_oamp_port_enable_get(unit, in_port)) { 31817 LOG_ERROR(BSL_LS_BCM_PORT, 31818 (BSL_META("Error: Not permitted on OAMP port %d.n"), 31819 in_port)); 31820 return BCM_E_PARAM; 31821 } 31822 31823 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, in_port, &port)); 31824 31825 #if defined(BCM_KATANA2_SUPPORT) 31826 /* LinkPHY/SubportTag CoE subport does not have MAC */ 31827 #if defined(BCM_METROLITE_SUPPORT) 31828 if ((soc_feature(unit, soc_feature_linkphy_coe) || 31829 soc_feature(unit, soc_feature_subtag_coe)) && 31830 soc_feature(unit, soc_feature_discontinuous_pp_port) && 31831 (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, port) && 31832 !_SOC_IS_PORT_LINKPHY_SUBTAG(unit, port))) { 31833 *size = 0; 31834 if (SOC_REG_IS_VALID(unit, EGR_MTUr)) { 31835 SOC_IF_ERROR_RETURN(READ_EGR_MTUr(unit, port, &rval)); 31836 if (soc_reg_field_get(unit, EGR_MTUr, rval, MTU_ENABLEf)) { 31837 *size = soc_reg_field_get(unit, EGR_MTUr, rval, MTU_SIZEf) - 4; 31838 } 31839 } 31840 rv = BCM_E_NONE; 31841 } else 31842 #endif 31843 if ((soc_feature(unit, soc_feature_linkphy_coe) || 31844 soc_feature(unit, soc_feature_subtag_coe)) && 31845 !soc_feature(unit, soc_feature_discontinuous_pp_port) && 31846 (port >= min_pp_port)) { 31847 *size = 0; 31848 if (SOC_REG_IS_VALID(unit, EGR_MTUr)) { 31849 SOC_IF_ERROR_RETURN(READ_EGR_MTUr(unit, port, &rval)); 31850 if (soc_reg_field_get(unit, EGR_MTUr, rval, MTU_ENABLEf)) { 31851 *size = soc_reg_field_get(unit, EGR_MTUr, rval, MTU_SIZEf) - 4; 31852 } 31853 } 31854 rv = BCM_E_NONE; 31855 } else 31856 #endif 31857 { 31858 rv = MAC_FRAME_MAX_GET(PORT(unit, port).p_mac, unit, port, size); 31859 } 31860 31861 return rv; 31862 } 31863 31864 /* 31865 * Function: 31866 * bcm_esw_port_l3_mtu_set 31867 * Description: 31868 * Set the maximum L3 frame size for the port 31869 * Parameters: 31870 * unit - Device number 31871 * port - Port number 31872 * size - Maximum frame size in bytes 31873 * Return Value: 31874 * BCM_E_XXX 31875 */ 31876 int 31877 bcm_esw_port_l3_mtu_set(int unit, bcm_port_t port, int size) 31878 { 31879 int rv = BCM_E_UNAVAIL; 31880 /* Make sure port module is initialized. */ 31881 PORT_INIT(unit); 31882 31883 COMPILER_REFERENCE(rv); 31884 31885 if(bcm_common_oamp_port_enable_get(unit, port)) { 31886 LOG_ERROR(BSL_LS_BCM_PORT, 31887 (BSL_META("Error: Not permitted on OAMP port %d.n"), 31888 port)); 31889 return BCM_E_PARAM; 31890 } 31891 31892 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3) 31893 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 31894 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 31895 31896 soc_field_t fields[2]; 31897 uint32 values[2]; 31898 31899 if (soc_feature(unit, soc_feature_egr_all_profile) || 31900 (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 31901 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))) { 31902 31903 /* Setup the fields and their values */ 31904 fields[0] = MTU_SIZEf; values[0] = size; 31905 fields[1] = MTU_ENABLEf; values[1] = 1; 31906 31907 return bcm_esw_port_egr_lport_fields_set(unit, port, 31908 EGR_MTUm, 2, fields, values); 31909 31910 } else { 31911 egr_mtu_entry_t egr_mtu_entry; 31912 31913 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 31914 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_MTUm, 31915 MEM_BLOCK_ANY, port, &egr_mtu_entry)); 31916 /* Set up the fields */ 31917 soc_mem_field32_set(unit, EGR_MTUm, &egr_mtu_entry, MTU_SIZEf, size); 31918 soc_mem_field32_set(unit, EGR_MTUm, &egr_mtu_entry, MTU_ENABLEf, 31919 1); 31920 /* Write data to hardware */ 31921 return soc_mem_write(unit, EGR_MTUm, MEM_BLOCK_ANY, port, &egr_mtu_entry); 31922 } 31923 } else 31924 #endif 31925 { 31926 if (soc_feature(unit, soc_feature_egr_l3_mtu)) { 31927 soc_reg_t reg; 31928 31929 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 31930 reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr; 31931 return soc_reg_field32_modify(unit, reg, port, 31932 (SOC_REG_FIELD_VALID(unit, reg, L3_MTU_SIZEf) ? 31933 L3_MTU_SIZEf : MTU_SIZEf), size); 31934 } 31935 } 31936 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */ 31937 31938 return BCM_E_UNAVAIL; 31939 31940 } 31941 31942 /* 31943 * Function: 31944 * bcm_esw_port_l3_mtu_get 31945 * Description: 31946 * Get the maximum L3 frame size for the port 31947 * Parameters: 31948 * unit - Device number 31949 * port - Port number 31950 * size - Maximum frame size in bytes 31951 * Return Value: 31952 * BCM_E_XXX 31953 */ 31954 int 31955 bcm_esw_port_l3_mtu_get(int unit, bcm_port_t port, int *size) 31956 { 31957 /* Make sure port module is initialized. */ 31958 PORT_INIT(unit); 31959 31960 if(bcm_common_oamp_port_enable_get(unit, port)) { 31961 LOG_ERROR(BSL_LS_BCM_PORT, 31962 (BSL_META("Error: Not permitted on OAMP port %d.n"), 31963 port)); 31964 return BCM_E_PARAM; 31965 } 31966 31967 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3) 31968 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 31969 if (SOC_MEM_IS_VALID(unit, EGR_MTUm)) { 31970 if (soc_feature(unit, soc_feature_egr_all_profile) || 31971 (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 31972 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port))) { 31973 return bcm_esw_port_egr_lport_field_get(unit, port, 31974 EGR_MTUm, MTU_SIZEf, (uint32*)size); 31975 } else { 31976 egr_mtu_entry_t entry; 31977 31978 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 31979 SOC_IF_ERROR_RETURN(soc_mem_read(unit, EGR_MTUm, MEM_BLOCK_ANY, port, &entry)); 31980 *size = soc_mem_field32_get(unit, EGR_MTUm, &entry, MTU_SIZEf); 31981 return BCM_E_NONE; 31982 } 31983 } else 31984 #endif 31985 { 31986 if (soc_feature(unit, soc_feature_egr_l3_mtu)) { 31987 soc_reg_t reg; 31988 uint32 rval; 31989 31990 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 31991 31992 reg = SOC_REG_IS_VALID(unit, EGR_MTUr) ? EGR_MTUr : EGR_MTU_SIZEr; 31993 31994 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 31995 *size = soc_reg_field_get(unit, reg, rval, 31996 (SOC_REG_FIELD_VALID(unit, reg,L3_MTU_SIZEf) ? 31997 L3_MTU_SIZEf : MTU_SIZEf)); 31998 return BCM_E_NONE; 31999 } 32000 } 32001 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */ 32002 32003 return BCM_E_UNAVAIL; 32004 } 32005 32006 #ifdef BCM_WARM_BOOT_SUPPORT 32007 /* 32008 * Function: 32009 * _bcm_esw_port_ipg_ifg_wb_set 32010 * Purpose: 32011 * Restore the ifg based on the working speed and duplex 32012 */ 32013 STATIC int 32014 _bcm_esw_port_ipg_ifg_wb_set( 32015 int unit, 32016 bcm_port_t port, 32017 soc_ipg_t *ipg, 32018 uint32 ifg) 32019 { 32020 int speed, duplex; 32021 32022 if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) { 32023 /* XLMAC or CLMAC */ 32024 ipg->fd_xe = ifg; 32025 } else { 32026 /* UNIMAC */ 32027 BCM_IF_ERROR_RETURN( 32028 MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, &speed)); 32029 BCM_IF_ERROR_RETURN( 32030 MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &duplex)); 32031 if (duplex == BCM_PORT_DUPLEX_FULL) { 32032 switch (speed) { 32033 case 10: 32034 ipg->fd_10 = ifg; 32035 break; 32036 case 100: 32037 ipg->fd_100 = ifg; 32038 break; 32039 case 1000: 32040 ipg->fd_1000 = ifg; 32041 break; 32042 case 2500: 32043 ipg->fd_2500 = ifg; 32044 break; 32045 default: 32046 return BCM_E_PARAM; 32047 } 32048 } else { 32049 switch (speed) { 32050 case 10: 32051 ipg->hd_10 = ifg; 32052 break; 32053 case 100: 32054 ipg->hd_100 = ifg; 32055 break; 32056 default: 32057 return BCM_E_PARAM; 32058 } 32059 } 32060 } 32061 return BCM_E_NONE; 32062 } 32063 32064 /* 32065 * Function: 32066 * _bcm_esw_port_ipg_ifg_wb_get 32067 * Purpose: 32068 * Get the ifg based on the working speed and duplex 32069 */ 32070 STATIC int 32071 _bcm_esw_port_ipg_ifg_wb_get( 32072 int unit, 32073 bcm_port_t port, 32074 soc_ipg_t *ipg, 32075 uint32 *ifg) 32076 { 32077 int speed, duplex; 32078 32079 if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) { 32080 /* XLMAC or CLMAC */ 32081 *ifg = ipg->fd_xe; 32082 } else { 32083 /* UNIMAC */ 32084 BCM_IF_ERROR_RETURN( 32085 MAC_SPEED_GET(PORT(unit, port).p_mac, unit, port, &speed)); 32086 BCM_IF_ERROR_RETURN( 32087 MAC_DUPLEX_GET(PORT(unit, port).p_mac, unit, port, &duplex)); 32088 if (duplex == BCM_PORT_DUPLEX_FULL) { 32089 switch (speed) { 32090 case 10: 32091 *ifg = ipg->fd_10; 32092 break; 32093 case 100: 32094 *ifg = ipg->fd_100; 32095 break; 32096 case 1000: 32097 *ifg = ipg->fd_1000; 32098 break; 32099 case 2500: 32100 *ifg = ipg->fd_2500; 32101 break; 32102 default: 32103 return BCM_E_PARAM; 32104 } 32105 } else { 32106 switch (speed) { 32107 case 10: 32108 *ifg = ipg->hd_10; 32109 break; 32110 case 100: 32111 *ifg = ipg->hd_100; 32112 break; 32113 default: 32114 return BCM_E_PARAM; 32115 } 32116 } 32117 } 32118 return BCM_E_NONE; 32119 } 32120 32121 /* 32122 * Function: 32123 * _bcm_esw_port_ifg_wb_sync 32124 * Purpose: 32125 * Sync port_ifg DB to scache. 32126 * Parameters: 32127 * unit - Device unit number 32128 * scache_ptr - Scache pointer. 32129 * Returns: 32130 * BCM_E_XXX 32131 */ 32132 STATIC int 32133 _bcm_esw_port_ifg_wb_sync(int unit, uint8 **scache_ptr) 32134 { 32135 bcm_port_t port; 32136 soc_ipg_t *si = NULL; 32137 uint32 ifg = 0; 32138 int mode = 0; 32139 int rv = BCM_E_NONE; 32140 32141 if ((scache_ptr == NULL) || (*scache_ptr == NULL)) { 32142 return BCM_E_PARAM; 32143 } 32144 32145 PBMP_ALL_ITER(unit, port) { 32146 si = &SOC_PERSIST(unit)->ipg[port]; 32147 if (IS_E_PORT(unit, port)) { 32148 if (soc_feature(unit, soc_feature_ifg_wb_include_unimac)) { 32149 BCM_IF_ERROR_RETURN( 32150 _bcm_esw_port_ipg_ifg_wb_get(unit, port, si, &ifg)); 32151 } else { 32152 ifg = si->fd_xe; 32153 } 32154 } else { 32155 if (soc_feature(unit, soc_feature_xmac)) { 32156 rv = bcm_esw_port_encap_get(unit, port, &mode); 32157 if (BCM_E_NONE == rv) { 32158 if (BCM_PORT_ENCAP_HIGIG2 == mode) { 32159 ifg = si->fd_hg2; 32160 } else { 32161 ifg = si->fd_hg; 32162 } 32163 } 32164 } else { 32165 ifg = si->fd_hg; 32166 } 32167 } 32168 sal_memcpy(*scache_ptr, &ifg, sizeof(uint32)); 32169 *scache_ptr += sizeof(uint32); 32170 } 32171 32172 return BCM_E_NONE; 32173 } 32174 32175 /* 32176 * Function: 32177 * _bcm_esw_port_ifg_wb_reinit 32178 * Purpose: 32179 * Retrieve port_ifg from scache. 32180 * Parameters: 32181 * unit - Device unit number 32182 * scache_ptr - Scache pointer. 32183 * Returns: 32184 * BCM_E_XXX 32185 */ 32186 STATIC int 32187 _bcm_esw_port_ifg_wb_reinit(int unit, uint8 **scache_ptr) 32188 { 32189 bcm_port_t port; 32190 soc_ipg_t *si = NULL; 32191 uint32 ifg = 0; 32192 int mode = 0; 32193 int rv = BCM_E_NONE; 32194 32195 if ((scache_ptr == NULL) || (*scache_ptr == NULL)) { 32196 return BCM_E_PARAM; 32197 } 32198 32199 PBMP_ALL_ITER(unit, port) { 32200 si = &SOC_PERSIST(unit)->ipg[port]; 32201 sal_memcpy(&ifg, *scache_ptr, sizeof(uint32)); 32202 if (IS_E_PORT(unit, port)) { 32203 if (soc_feature(unit, soc_feature_ifg_wb_include_unimac)) { 32204 BCM_IF_ERROR_RETURN( 32205 _bcm_esw_port_ipg_ifg_wb_set(unit, port, si, ifg)); 32206 } else { 32207 si->fd_xe = ifg; 32208 } 32209 } else { 32210 if (soc_feature(unit, soc_feature_xmac)) { 32211 rv = bcm_esw_port_encap_get(unit, port, &mode); 32212 if (BCM_E_NONE == rv) { 32213 if (BCM_PORT_ENCAP_HIGIG2 == mode) { 32214 si->fd_hg2 = ifg; 32215 } else { 32216 si->fd_hg = ifg; 32217 } 32218 } 32219 } else { 32220 si->fd_hg = ifg; 32221 } 32222 } 32223 *scache_ptr += sizeof(uint32); 32224 } 32225 32226 return BCM_E_NONE; 32227 } 32228 #endif 32229 32230 /* 32231 * Function: 32232 * bcm_esw_port_ifg_set 32233 * Description: 32234 * Sets the new ifg (Inter-frame gap) value 32235 * Parameters: 32236 * unit - Device number 32237 * port - Port number 32238 * speed - the speed for which the IFG is being set 32239 * duplex - the duplex for which the IFG is being set 32240 * ifg - Inter-frame gap in bit-times 32241 * Return Value: 32242 * BCM_E_XXX 32243 * Notes: 32244 * The function makes sure the IFG value makes sense and updates the 32245 * IPG register in case the speed/duplex match the current settings 32246 */ 32247 int 32248 bcm_esw_port_ifg_set(int unit, bcm_port_t port, 32249 int speed, bcm_port_duplex_t duplex, 32250 int ifg) 32251 { 32252 32253 /* Make sure port module is initialized. */ 32254 PORT_INIT(unit); 32255 32256 if (SOC_USE_PORTCTRL(unit)) { 32257 return bcmi_esw_portctrl_ifg_set(unit, port, speed, duplex, ifg); 32258 } 32259 32260 if(bcm_common_oamp_port_enable_get(unit, port)) { 32261 LOG_ERROR(BSL_LS_BCM_PORT, 32262 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32263 port)); 32264 return BCM_E_PARAM; 32265 } 32266 32267 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32268 32269 return MAC_IFG_SET(PORT(unit, port).p_mac, unit, port, 32270 speed, duplex, ifg); 32271 } 32272 32273 /* 32274 * Function: 32275 * bcm_port_ifg_get 32276 * Description: 32277 * Gets the new ifg (Inter-frame gap) value 32278 * Parameters: 32279 * unit - Device number 32280 * port - Port number 32281 * speed - the speed for which the IFG is being set 32282 * duplex - the duplex for which the IFG is being set 32283 * ifg - Inter-frame gap in bit-times 32284 * Return Value: 32285 * BCM_E_XXX 32286 * Notes: 32287 */ 32288 int 32289 bcm_esw_port_ifg_get(int unit, bcm_port_t port, 32290 int speed, bcm_port_duplex_t duplex, 32291 int *ifg) 32292 { 32293 /* Make sure port module is initialized. */ 32294 PORT_INIT(unit); 32295 32296 if (SOC_USE_PORTCTRL(unit)) { 32297 return bcmi_esw_portctrl_ifg_get(unit, port, speed, duplex, ifg); 32298 } 32299 32300 if(bcm_common_oamp_port_enable_get(unit, port)) { 32301 LOG_ERROR(BSL_LS_BCM_PORT, 32302 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32303 port)); 32304 return BCM_E_PARAM; 32305 } 32306 32307 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32308 32309 return MAC_IFG_GET(PORT(unit, port).p_mac, unit, port, 32310 speed, duplex, ifg); 32311 } 32312 32313 /* 32314 * Function: 32315 * bcm_port_phy_get 32316 * Description: 32317 * General PHY register read 32318 * Parameters: 32319 * unit - Device number 32320 * port - Port number or PHY MDIO address (refer BCM_PORT_PHY_NOMAP) 32321 * flags - Logical OR of one or more of the following flags: 32322 * BCM_PORT_PHY_INTERNAL 32323 * Address internal SERDES PHY for port 32324 * BCM_PORT_PHY_NOMAP 32325 * Instead of mapping port to PHY MDIO address, 32326 * treat port parameter as actual PHY MDIO address. 32327 * BCM_PORT_PHY_CLAUSE45 32328 * Assume Clause 45 device instead of Clause 22 32329 * phy_addr - PHY internal register address 32330 * phy_data - (OUT) Data that was read 32331 * Returns: 32332 * BCM_E_XXX 32333 */ 32334 int 32335 bcm_esw_port_phy_get(int unit, bcm_port_t port, uint32 flags, 32336 uint32 phy_reg_addr, uint32 *phy_data) 32337 { 32338 uint16 phy_id; 32339 uint8 phy_devad; 32340 uint16 phy_reg; 32341 uint16 phy_rd_data; 32342 uint32 reg_flag; 32343 int rv; 32344 int lane = -1; 32345 int phyn = -1, sys_side = 0; 32346 bcm_port_t local_port = -1; 32347 32348 if (SOC_USE_PORTCTRL(unit)) { 32349 return bcmi_esw_portctrl_phy_get(unit, port, flags, phy_reg_addr, 32350 phy_data); 32351 } 32352 32353 /* Make sure port module is initialized. */ 32354 PORT_INIT(unit); 32355 32356 if(bcm_common_oamp_port_enable_get(unit, port)) { 32357 LOG_ERROR(BSL_LS_BCM_PORT, 32358 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32359 port)); 32360 return BCM_E_PARAM; 32361 } 32362 32363 if (!(flags & BCM_PORT_PHY_NOMAP)) { 32364 BCM_IF_ERROR_RETURN 32365 (_bcm_esw_port_gport_phyn_validate(unit, port, 32366 &local_port, &phyn, 32367 &lane, &sys_side)); 32368 if (local_port != -1) { 32369 port = local_port; 32370 } 32371 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32372 32373 if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) { 32374 return BCM_E_PORT; 32375 } 32376 } 32377 32378 if (flags & (SOC_PHY_I2C_DATA8 | SOC_PHY_I2C_DATA16 | SOC_PHY_PVT_DATA)) { 32379 PORT_LOCK(unit); 32380 rv = soc_phyctrl_reg_read(unit, port, flags, phy_reg_addr, phy_data); 32381 PORT_UNLOCK(unit); 32382 return rv; 32383 } 32384 32385 rv = BCM_E_UNAVAIL; 32386 reg_flag = BCM_PORT_PHY_REG_FLAGS(phy_reg_addr); 32387 if ( (reg_flag & SOC_PHY_REG_INDIRECT) || 32388 (flags & (BCM_PORT_PHY_REG_RDB | BCM_PORT_PHY_REG_MACSEC)) ) { 32389 if (flags & BCM_PORT_PHY_NOMAP) { 32390 /* Indirect register access is performed through PHY driver. 32391 * Therefore, indirect register access is not supported if 32392 * BCM_PORT_PHY_NOMAP flag is set. 32393 */ 32394 return BCM_E_PARAM; 32395 } 32396 phy_reg_addr &= ~SOC_PHY_REG_INDIRECT; 32397 32398 if (lane >= 0) { 32399 #if defined(PHYMOD_SUPPORT) 32400 SOC_PHY_PHYMOD_FORCE_LANE_SET(phy_reg_addr, lane); 32401 #endif 32402 } 32403 if (phyn == 1) { 32404 flags |= SOC_PHY_INTERNAL; 32405 } 32406 PORT_LOCK(unit); 32407 rv = soc_phyctrl_reg_read(unit, port, flags, phy_reg_addr, phy_data); 32408 PORT_UNLOCK(unit); 32409 } 32410 32411 if (rv == BCM_E_UNAVAIL) { 32412 if (flags & BCM_PORT_PHY_NOMAP) { 32413 phy_id = port; 32414 } else if (flags & BCM_PORT_PHY_INTERNAL) { 32415 phy_id = PORT_TO_PHY_ADDR_INT(unit, port); 32416 } else { 32417 phy_id = PORT_TO_PHY_ADDR(unit, port); 32418 } 32419 32420 PORT_LOCK(unit); 32421 if (flags & BCM_PORT_PHY_CLAUSE45) { 32422 phy_devad = BCM_PORT_PHY_CLAUSE45_DEVAD(phy_reg_addr); 32423 phy_reg = BCM_PORT_PHY_CLAUSE45_REGAD(phy_reg_addr); 32424 rv = soc_miimc45_read(unit, phy_id, phy_devad, 32425 phy_reg, &phy_rd_data); 32426 32427 } else { 32428 phy_reg = phy_reg_addr; 32429 rv = soc_miim_read(unit, phy_id, phy_reg, &phy_rd_data); 32430 } 32431 PORT_UNLOCK(unit); 32432 32433 if (BCM_SUCCESS(rv)) { 32434 *phy_data = phy_rd_data; 32435 } 32436 } 32437 32438 LOG_INFO(BSL_LS_BCM_PORT, 32439 (BSL_META_U(unit, 32440 "bcm_esw_port_phy_get: u=%d p=%d flags=0x%08x " 32441 "phy_reg=0x%08x, phy_data=0x%08x, rv=%d\n"), 32442 unit, port, flags, phy_reg_addr, *phy_data, rv)); 32443 32444 return rv; 32445 } 32446 32447 /* 32448 * Function: 32449 * bcm_port_phy_set 32450 * Description: 32451 * General PHY register write 32452 * Parameters: 32453 * unit - Device number 32454 * port - Port number or PHY MDIO address (refer BCM_PORT_PHY_NOMAP) 32455 * flags - Logical OR of one or more of the following flags: 32456 * BCM_PORT_PHY_INTERNAL 32457 * Address internal SERDES PHY for port 32458 * BCM_PORT_PHY_NOMAP 32459 * Instead of mapping port to PHY MDIO address, 32460 * treat port parameter as actual PHY MDIO address. 32461 * BCM_PORT_PHY_CLAUSE45 32462 * Assume Clause 45 device instead of Clause 22 32463 * phy_addr - PHY internal register address 32464 * phy_data - Data to write 32465 * Returns: 32466 * BCM_E_XXX 32467 */ 32468 int 32469 bcm_esw_port_phy_set(int unit, bcm_port_t port, uint32 flags, 32470 uint32 phy_reg_addr, uint32 phy_data) 32471 { 32472 uint16 phy_id; 32473 uint8 phy_devad; 32474 uint16 phy_reg; 32475 uint16 phy_wr_data; 32476 uint32 reg_flag; 32477 int rv; 32478 int lane = -1; 32479 int phyn = -1, sys_side = 0; 32480 bcm_port_t local_port = -1; 32481 32482 if (SOC_USE_PORTCTRL(unit)) { 32483 return bcmi_esw_portctrl_phy_set(unit, port, flags, phy_reg_addr, 32484 phy_data); 32485 } 32486 32487 /* Make sure port module is initialized. */ 32488 PORT_INIT(unit); 32489 32490 if(bcm_common_oamp_port_enable_get(unit, port)) { 32491 LOG_ERROR(BSL_LS_BCM_PORT, 32492 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32493 port)); 32494 return BCM_E_PARAM; 32495 } 32496 32497 if (!(flags & BCM_PORT_PHY_NOMAP)) { 32498 BCM_IF_ERROR_RETURN 32499 (_bcm_esw_port_gport_phyn_validate(unit, port, 32500 &local_port, &phyn, 32501 &lane, &sys_side)); 32502 if (local_port != -1) { 32503 port = local_port; 32504 } 32505 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32506 32507 if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) { 32508 return BCM_E_PORT; 32509 } 32510 } 32511 32512 LOG_INFO(BSL_LS_BCM_PORT, 32513 (BSL_META_U(unit, 32514 "bcm_esw_port_phy_set: u=%d p=%d flags=0x%08x " 32515 "phy_reg=0x%08x phy_data=0x%08x\n"), 32516 unit, port, flags, phy_reg_addr, phy_data)); 32517 32518 if (flags & (SOC_PHY_I2C_DATA8 | SOC_PHY_I2C_DATA16 | SOC_PHY_PVT_DATA)) { 32519 PORT_LOCK(unit); 32520 rv = soc_phyctrl_reg_write(unit, port, flags, phy_reg_addr, phy_data); 32521 PORT_UNLOCK(unit); 32522 return rv; 32523 } 32524 32525 rv = BCM_E_UNAVAIL; 32526 reg_flag = BCM_PORT_PHY_REG_FLAGS(phy_reg_addr); 32527 if ( (reg_flag & SOC_PHY_REG_INDIRECT) || 32528 (flags & (BCM_PORT_PHY_REG_RDB | BCM_PORT_PHY_REG_MACSEC)) ) { 32529 if (flags & BCM_PORT_PHY_NOMAP) { 32530 /* Indirect register access is performed through PHY driver. 32531 * Therefore, indirect register access is not supported if 32532 * BCM_PORT_PHY_NOMAP flag is set. 32533 */ 32534 return BCM_E_PARAM; 32535 } 32536 phy_reg_addr &= ~SOC_PHY_REG_INDIRECT; 32537 if (lane >= 0) { 32538 #if defined(PHYMOD_SUPPORT) 32539 SOC_PHY_PHYMOD_FORCE_LANE_SET(phy_reg_addr, lane); 32540 #endif 32541 } 32542 if (phyn == 1) { 32543 flags |= SOC_PHY_INTERNAL; 32544 } 32545 PORT_LOCK(unit); 32546 rv = soc_phyctrl_reg_write(unit, port, flags, phy_reg_addr, phy_data); 32547 PORT_UNLOCK(unit); 32548 } 32549 32550 if (rv == BCM_E_UNAVAIL) { 32551 if (flags & BCM_PORT_PHY_NOMAP) { 32552 phy_id = port; 32553 } else if (flags & BCM_PORT_PHY_INTERNAL) { 32554 phy_id = PORT_TO_PHY_ADDR_INT(unit, port); 32555 } else { 32556 phy_id = PORT_TO_PHY_ADDR(unit, port); 32557 } 32558 32559 phy_wr_data = (uint16) (phy_data & 0xffff); 32560 PORT_LOCK(unit); 32561 if (flags & BCM_PORT_PHY_CLAUSE45) { 32562 phy_devad = BCM_PORT_PHY_CLAUSE45_DEVAD(phy_reg_addr); 32563 phy_reg = BCM_PORT_PHY_CLAUSE45_REGAD(phy_reg_addr); 32564 rv = soc_miimc45_write(unit, phy_id, phy_devad, 32565 phy_reg, phy_wr_data); 32566 } else { 32567 phy_reg = phy_reg_addr; 32568 rv = soc_miim_write(unit, phy_id, phy_reg, phy_wr_data); 32569 } 32570 PORT_UNLOCK(unit); 32571 } 32572 return rv; 32573 } 32574 /* 32575 * Function: 32576 * bcm_port_phy_multi_get 32577 * Description: 32578 * General PHY register read 32579 * Parameters: 32580 * unit - Device number 32581 * port - Port number 32582 * flags - TBD 32583 * dev_addr - Device address on the PHY's bus (ex. I2C addr) 32584 * offset - Offset within device 32585 * max_size - Requested data size 32586 * data - Data buffer 32587 * actual_size - Received data size 32588 * Returns: 32589 * BCM_E_XXX 32590 */ 32591 int 32592 bcm_esw_port_phy_multi_get(int unit, bcm_port_t port, uint32 flags, 32593 uint32 dev_addr, uint32 offset, int max_size, uint8 *data, int *actual_size) 32594 { 32595 int rv; 32596 32597 if (SOC_USE_PORTCTRL(unit)) { 32598 return bcmi_esw_portctrl_phy_multi_get(unit, port, flags, dev_addr, 32599 offset, max_size, data, 32600 actual_size); 32601 } 32602 32603 /* Make sure port module is initialized. */ 32604 PORT_INIT(unit); 32605 32606 if(bcm_common_oamp_port_enable_get(unit, port)) { 32607 LOG_ERROR(BSL_LS_BCM_PORT, 32608 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32609 port)); 32610 return BCM_E_PARAM; 32611 } 32612 32613 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32614 32615 PORT_LOCK(unit); 32616 rv = soc_phyctrl_port_phy_multi_get(unit, port, flags, dev_addr, offset, max_size, data, actual_size); 32617 PORT_UNLOCK(unit); 32618 /* 32619 LOG_INFO(BSL_LS_BCM_PORT, 32620 (BSL_META_U(unit, 32621 "bcm_esw_port_phy_multi_get: u=%d p=%d flags=0x%08x " 32622 "dev_addr=0x%08x, offset=0x%08x, max_size=%d data=%p actual_size=%d rv=%d\n"), 32623 unit, port, flags, dev_addr, offset, max_size, data, *actual_size, rv)); 32624 */ 32625 return rv; 32626 } 32627 32628 /* 32629 * Function: 32630 * bcm_port_phy_modify 32631 * Description: 32632 * General PHY register modify 32633 * Parameters: 32634 * unit - Device number 32635 * port - Port number or PHY MDIO address (refer BCM_PORT_PHY_NOMAP) 32636 * flags - Logical OR of one or more of the following flags: 32637 * BCM_PORT_PHY_INTERNAL 32638 * Address internal SERDES PHY for port 32639 * BCM_PORT_PHY_NOMAP 32640 * Instead of mapping port to PHY MDIO address, 32641 * treat port parameter as actual PHY MDIO address. 32642 * BCM_PORT_PHY_CLAUSE45 32643 * Assume Clause 45 device instead of Clause 22 32644 * phy_addr - PHY internal register address 32645 * phy_data - Data to write 32646 * phy_mask - Bits to modify using phy_data 32647 * Returns: 32648 * BCM_E_XXX 32649 */ 32650 int 32651 bcm_esw_port_phy_modify(int unit, bcm_port_t port, uint32 flags, 32652 uint32 phy_reg_addr, uint32 phy_data, uint32 phy_mask) 32653 { 32654 uint16 phy_id; 32655 uint8 phy_devad; 32656 uint16 phy_reg; 32657 uint16 phy_rd_data; 32658 uint16 phy_wr_data; 32659 uint32 reg_flag; 32660 int rv; 32661 int lane = -1; 32662 int phyn = -1, sys_side = 0; 32663 bcm_port_t local_port = -1; 32664 32665 if (SOC_USE_PORTCTRL(unit)) { 32666 return bcmi_esw_portctrl_phy_modify(unit, port, flags, phy_reg_addr, 32667 phy_data, phy_mask); 32668 } 32669 32670 /* Make sure port module is initialized. */ 32671 PORT_INIT(unit); 32672 32673 if(bcm_common_oamp_port_enable_get(unit, port)) { 32674 LOG_ERROR(BSL_LS_BCM_PORT, 32675 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32676 port)); 32677 return BCM_E_PARAM; 32678 } 32679 32680 if (!(flags & BCM_PORT_PHY_NOMAP)) { 32681 BCM_IF_ERROR_RETURN 32682 (_bcm_esw_port_gport_phyn_validate(unit, port, 32683 &local_port, &phyn, 32684 &lane, &sys_side)); 32685 if (local_port != -1) { 32686 port = local_port; 32687 } 32688 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32689 32690 if(!(SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) { 32691 return BCM_E_PORT; 32692 } 32693 } 32694 32695 LOG_INFO(BSL_LS_BCM_PORT, 32696 (BSL_META_U(unit, 32697 "bcm_esw_port_phy_modify: u=%d p=%d flags=0x%08x " 32698 "phy_reg=0x%08x phy_data=0x%08x phy_mask=0x%08x\n"), 32699 unit, port, flags, phy_reg_addr, phy_data, phy_mask)); 32700 32701 rv = BCM_E_UNAVAIL; 32702 reg_flag = BCM_PORT_PHY_REG_FLAGS(phy_reg_addr); 32703 if (reg_flag & SOC_PHY_REG_INDIRECT) { 32704 if (flags & BCM_PORT_PHY_NOMAP) { 32705 /* Indirect register access is performed through PHY driver. 32706 * Therefore, indirect register access is not supported if 32707 * BCM_PORT_PHY_NOMAP flag is set. 32708 */ 32709 return BCM_E_PARAM; 32710 } 32711 phy_reg_addr &= ~SOC_PHY_REG_INDIRECT; 32712 if (lane >= 0) { 32713 #if defined(PHYMOD_SUPPORT) 32714 SOC_PHY_PHYMOD_FORCE_LANE_SET(phy_reg_addr, lane); 32715 #endif 32716 } 32717 if (phyn == 1) { 32718 flags |= SOC_PHY_INTERNAL; 32719 } 32720 PORT_LOCK(unit); 32721 rv = soc_phyctrl_reg_modify(unit, port, flags, phy_reg_addr, 32722 phy_data, phy_mask); 32723 PORT_UNLOCK(unit); 32724 } 32725 32726 if (rv == BCM_E_UNAVAIL) { 32727 if (flags & BCM_PORT_PHY_NOMAP) { 32728 phy_id = port; 32729 } else if (flags & BCM_PORT_PHY_INTERNAL) { 32730 phy_id = PORT_TO_PHY_ADDR_INT(unit, port); 32731 } else { 32732 phy_id = PORT_TO_PHY_ADDR(unit, port); 32733 } 32734 32735 phy_wr_data = (uint16) (phy_data & phy_mask & 0xffff); 32736 PORT_LOCK(unit); 32737 if (flags & BCM_PORT_PHY_CLAUSE45) { 32738 phy_devad = BCM_PORT_PHY_CLAUSE45_DEVAD(phy_reg_addr); 32739 phy_reg = BCM_PORT_PHY_CLAUSE45_REGAD(phy_reg_addr); 32740 rv = soc_miimc45_read(unit, phy_id, phy_devad, 32741 phy_reg, &phy_rd_data); 32742 phy_wr_data |= (phy_rd_data & ~phy_mask); 32743 rv = soc_miimc45_write(unit, phy_id, phy_devad, 32744 phy_reg, phy_wr_data); 32745 } else { 32746 phy_reg = phy_reg_addr; 32747 rv = soc_miim_read(unit, phy_id, phy_reg, &phy_rd_data); 32748 if (BCM_SUCCESS(rv)) { 32749 phy_wr_data |= (phy_rd_data & ~phy_mask); 32750 rv = soc_miim_write(unit, phy_id, phy_reg, phy_wr_data); 32751 } 32752 } 32753 PORT_UNLOCK(unit); 32754 } 32755 return rv; 32756 } 32757 32758 /* 32759 * Function: 32760 * bcm_port_mdix_set 32761 * Description: 32762 * Set the Auto-MDIX mode of a port/PHY 32763 * Parameters: 32764 * unit - Device number 32765 * port - Port number 32766 * mode - One of: 32767 * BCM_PORT_MDIX_AUTO 32768 * Enable auto-MDIX when autonegotiation is enabled 32769 * BCM_PORT_MDIX_FORCE_AUTO 32770 * Enable auto-MDIX always 32771 * BCM_PORT_MDIX_NORMAL 32772 * Disable auto-MDIX 32773 * BCM_PORT_MDIX_XOVER 32774 * Disable auto-MDIX, and swap cable pairs 32775 * Return Value: 32776 * BCM_E_UNAVAIL - feature unsupported by hardware 32777 * BCM_E_XXX - other error 32778 */ 32779 int 32780 bcm_esw_port_mdix_set(int unit, bcm_port_t port, bcm_port_mdix_t mode) 32781 { 32782 int rv; 32783 32784 /* Make sure port module is initialized. */ 32785 PORT_INIT(unit); 32786 32787 /* Call Port Control module */ 32788 if (SOC_USE_PORTCTRL(unit)) { 32789 return bcmi_esw_portctrl_mdix_set(unit, port, mode); 32790 } 32791 32792 if(bcm_common_oamp_port_enable_get(unit, port)) { 32793 LOG_ERROR(BSL_LS_BCM_PORT, 32794 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32795 port)); 32796 return BCM_E_PARAM; 32797 } 32798 32799 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32800 32801 PORT_LOCK(unit); 32802 rv = soc_phyctrl_mdix_set(unit, port, mode); 32803 PORT_UNLOCK(unit); 32804 return rv; 32805 } 32806 32807 /* 32808 * Function: 32809 * bcm_port_mdix_get 32810 * Description: 32811 * Get the Auto-MDIX mode of a port/PHY 32812 * Parameters: 32813 * unit - Device number 32814 * port - Port number 32815 * mode - (Out) One of: 32816 * BCM_PORT_MDIX_AUTO 32817 * Enable auto-MDIX when autonegotiation is enabled 32818 * BCM_PORT_MDIX_FORCE_AUTO 32819 * Enable auto-MDIX always 32820 * BCM_PORT_MDIX_NORMAL 32821 * Disable auto-MDIX 32822 * BCM_PORT_MDIX_XOVER 32823 * Disable auto-MDIX, and swap cable pairs 32824 * Return Value: 32825 * BCM_E_UNAVAIL - feature unsupported by hardware 32826 * BCM_E_XXX - other error 32827 */ 32828 int 32829 bcm_esw_port_mdix_get(int unit, bcm_port_t port, bcm_port_mdix_t *mode) 32830 { 32831 int rv=BCM_E_NONE; 32832 32833 /* Make sure port module is initialized. */ 32834 PORT_INIT(unit); 32835 32836 /* Call Port Control module */ 32837 if (SOC_USE_PORTCTRL(unit)) { 32838 return bcmi_esw_portctrl_mdix_get(unit, port, mode); 32839 } 32840 32841 if(bcm_common_oamp_port_enable_get(unit, port)) { 32842 LOG_ERROR(BSL_LS_BCM_PORT, 32843 (BSL_META("Error: Not permitted on OAMP port %d.n"), 32844 port)); 32845 return BCM_E_PARAM; 32846 } 32847 32848 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32849 PORT_LOCK(unit); 32850 rv = soc_phyctrl_mdix_get(unit, port, mode); 32851 PORT_UNLOCK(unit); 32852 32853 return rv; 32854 } 32855 32856 /* 32857 * Function: 32858 * bcm_port_mdix_status_get 32859 * Description: 32860 * Get the current MDIX status on a port/PHY 32861 * Parameters: 32862 * unit - Device number 32863 * port - Port number 32864 * status - (OUT) One of: 32865 * BCM_PORT_MDIX_STATUS_NORMAL 32866 * Straight connection 32867 * BCM_PORT_MDIX_STATUS_XOVER 32868 * Crossover has been performed 32869 * Return Value: 32870 * BCM_E_UNAVAIL - feature unsupported by hardware 32871 * BCM_E_XXX - other error 32872 */ 32873 int 32874 bcm_esw_port_mdix_status_get(int unit, bcm_port_t port, 32875 bcm_port_mdix_status_t *status) 32876 { 32877 int rv=BCM_E_NONE; 32878 32879 /* Make sure port module is initialized. */ 32880 PORT_INIT(unit); 32881 32882 /* Call Port Control module */ 32883 if (SOC_USE_PORTCTRL(unit)) { 32884 return bcmi_esw_portctrl_mdix_status_get(unit, port, status); 32885 } 32886 32887 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32888 PORT_LOCK(unit); 32889 rv = soc_phyctrl_mdix_status_get(unit, port, status); 32890 PORT_UNLOCK(unit); 32891 return rv; 32892 } 32893 32894 /* 32895 * Function: 32896 * bcm_port_medium_config_set 32897 * Description: 32898 * Set the medium-specific configuration for a combo port 32899 * Parameters: 32900 * unit - Device number 32901 * port - Port number 32902 * medium - The medium (BCM_PORT_MEDIUM_COPPER or BCM_PORT_MEDIUM_FIBER) 32903 * to apply the configuration to 32904 * config - per-medium configuration 32905 * Return Value: 32906 * BCM_E_XXX 32907 */ 32908 int 32909 bcm_esw_port_medium_config_set(int unit, bcm_port_t port, 32910 bcm_port_medium_t medium, 32911 bcm_phy_config_t *config) 32912 { 32913 int rv; 32914 32915 /* Make sure port module is initialized. */ 32916 PORT_INIT(unit); 32917 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32918 32919 #ifdef PORTMOD_SUPPORT 32920 if (SOC_USE_PORTCTRL(unit)) { 32921 rv = bcmi_esw_portctrl_medium_config_set(unit, port, medium, config); 32922 } else 32923 #endif /* PORTMOD_SUPPORT */ 32924 { 32925 PORT_LOCK(unit); 32926 rv = soc_phyctrl_medium_config_set(unit, port, medium, config); 32927 PORT_UNLOCK(unit); 32928 } 32929 32930 return rv; 32931 } 32932 32933 /* 32934 * Function: 32935 * bcm_port_medium_config_get 32936 * Description: 32937 * Get the medium-specific configuration for a combo port 32938 * Parameters: 32939 * unit - Device number 32940 * port - Port number 32941 * medium - The medium (BCM_PORT_MEDIUM_COPPER or BCM_PORT_MEDIUM_FIBER) 32942 * to get the config for 32943 * config - per-medium configuration 32944 * Return Value: 32945 * BCM_E_XXX 32946 */ 32947 int 32948 bcm_esw_port_medium_config_get(int unit, bcm_port_t port, 32949 bcm_port_medium_t medium, 32950 bcm_phy_config_t *config) 32951 { 32952 int rv; 32953 32954 /* Make sure port module is initialized. */ 32955 PORT_INIT(unit); 32956 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32957 32958 #ifdef PORTMOD_SUPPORT 32959 if (SOC_USE_PORTCTRL(unit)) { 32960 rv = bcmi_esw_portctrl_medium_config_get(unit, port, medium, config); 32961 } else 32962 #endif /* PORTMOD_SUPPORT */ 32963 { 32964 PORT_LOCK(unit); 32965 rv = soc_phyctrl_medium_config_get(unit, port, medium, config); 32966 PORT_UNLOCK(unit); 32967 } 32968 return rv; 32969 } 32970 32971 /* 32972 * Function: 32973 * bcm_port_medium_get 32974 * Description: 32975 * Get the current medium used by a combo port 32976 * Parameters: 32977 * unit - Device number 32978 * port - Port number 32979 * medium - The medium (BCM_PORT_MEDIUM_COPPER or BCM_PORT_MEDIUM_FIBER) 32980 * which is currently selected 32981 * Return Value: 32982 * BCM_E_XXX 32983 */ 32984 int 32985 bcm_esw_port_medium_get(int unit, bcm_port_t port, 32986 bcm_port_medium_t *medium) 32987 { 32988 int rv=BCM_E_NONE; 32989 /* Make sure port module is initialized. */ 32990 PORT_INIT(unit); 32991 32992 /* Call Port Control module */ 32993 if (SOC_USE_PORTCTRL(unit)) { 32994 return bcmi_esw_portctrl_medium_get(unit, port, medium); 32995 } 32996 32997 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 32998 PORT_LOCK(unit); 32999 rv = soc_phyctrl_medium_get(unit, port, medium); 33000 PORT_UNLOCK(unit); 33001 return rv; 33002 } 33003 33004 /* 33005 * Function: 33006 * bcm_port_medium_status_register 33007 * Description: 33008 * Register a callback function to be called on medium change event 33009 * Parameters: 33010 * unit - Device number 33011 * port - port number 33012 * callback - The callback function to call 33013 * user_data - An opaque cookie to pass to callback function 33014 * whenever it is called 33015 * Returns: 33016 * BCM_E_NONE 33017 * BCM_E_PARAM -- NULL function pointer or bad {unit, port} combination 33018 * BCM_E_FULL -- Cannot register more than 1 callback per {unit, port} 33019 */ 33020 int 33021 bcm_esw_port_medium_status_register(int unit, 33022 bcm_port_t port, 33023 bcm_port_medium_status_cb_t callback, 33024 void *user_data) 33025 { 33026 /* Make sure port module is initialized. */ 33027 PORT_INIT(unit); 33028 33029 return soc_phy_medium_status_register(unit, port, callback, user_data); 33030 } 33031 33032 /* 33033 * Function: 33034 * bcm_port_medium_status_unregister 33035 * Description: 33036 * Unregister a callback function to be called on medium change event 33037 * Parameters: 33038 * unit - Device number 33039 * port - port number 33040 * callback - The callback function to call 33041 * user_data - An opaque cookie to pass to callback function 33042 * whenever it is called 33043 * Returns: 33044 * BCM_E_NONE 33045 * BCM_E_PARAM -- Bad {unit, port} combination 33046 * BCM_E_NOT_FOUND -- The specified {unit, port, callback, user_data} 33047 * combination have not been registered before 33048 */ 33049 int 33050 bcm_esw_port_medium_status_unregister(int unit, 33051 bcm_port_t port, 33052 bcm_port_medium_status_cb_t callback, 33053 void *user_data) 33054 { 33055 /* Make sure port module is initialized. */ 33056 PORT_INIT(unit); 33057 33058 return soc_phy_medium_status_unregister(unit, port, callback, user_data); 33059 } 33060 33061 /* 33062 * Function: 33063 * bcm_port_phy_reset 33064 * Description: 33065 * This function performs the low-level PHY reset and is intended to be 33066 * called ONLY from callback function registered with 33067 * bcm_port_phy_reset_register. Attempting to call it from any other 33068 * place will break lots of things. 33069 * Parameters: 33070 * unit - Device number 33071 * port - Port number 33072 * Returns: 33073 * BCM_E_XXX 33074 */ 33075 int 33076 bcm_esw_port_phy_reset(int unit, bcm_port_t port) 33077 { 33078 int rv; 33079 33080 /* Make sure port module is initialized. */ 33081 PORT_INIT(unit); 33082 33083 /* Call Port Control module */ 33084 if (SOC_USE_PORTCTRL(unit)) { 33085 return (bcmi_esw_portctrl_phy_reset(unit, port)); 33086 } 33087 33088 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33089 33090 if (!(BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), port))) { 33091 return BCM_E_PORT; 33092 } 33093 33094 PORT_LOCK(unit); 33095 rv = soc_phyctrl_reset(unit, port, NULL); 33096 PORT_UNLOCK(unit); 33097 return rv; 33098 } 33099 33100 /* 33101 * Function: 33102 * bcm_port_phy_reset_register 33103 * Description: 33104 * Register a callback function to be called whenever a PHY driver 33105 * needs to perform a PHY reset 33106 * Parameters: 33107 * unit - Device number 33108 * port - port number 33109 * callback - The callback function to call 33110 * user_data - An opaque cookie to pass to callback function 33111 * whenever it is called 33112 * Returns: 33113 * BCM_E_NONE 33114 * BCM_E_PARAM -- Bad {unit, port} combination 33115 * BCM_E_NOT_FOUND -- The specified {unit, port, callback, user_data} 33116 * combination have not been registered before 33117 */ 33118 int 33119 bcm_esw_port_phy_reset_register(int unit, bcm_port_t port, 33120 bcm_port_phy_reset_cb_t callback, 33121 void *user_data) 33122 { 33123 /* Make sure port module is initialized. */ 33124 PORT_INIT(unit); 33125 33126 return soc_phy_reset_register(unit, port, callback, user_data, FALSE); 33127 } 33128 33129 /* 33130 * Function: 33131 * bcm_port_phy_reset_unregister 33132 * Description: 33133 * Unregister a callback function to be called whenever a PHY driver 33134 * needs to perform a PHY reset 33135 * Parameters: 33136 * unit - Device number 33137 * port - port number 33138 * callback - The callback function to call 33139 * user_data - An opaque cookie to pass to callback function 33140 * whenever it is called 33141 * Returns: 33142 * BCM_E_NONE 33143 * BCM_E_PARAM -- Bad {unit, port} combination 33144 * BCM_E_NOT_FOUND -- The specified {unit, port, callback, user_data} 33145 * combination have not been registered before 33146 */ 33147 int 33148 bcm_esw_port_phy_reset_unregister(int unit, bcm_port_t port, 33149 bcm_port_phy_reset_cb_t callback, 33150 void *user_data) 33151 { 33152 /* Make sure port module is initialized. */ 33153 PORT_INIT(unit); 33154 33155 return soc_phy_reset_unregister(unit, port, callback, user_data); 33156 } 33157 33158 /* 33159 * Function: 33160 * bcm_port_jam_set 33161 * Description: 33162 * Enable or disable half duplex jamming on a port 33163 * Parameters: 33164 * unit - Device number 33165 * port - Port number 33166 * enable - non-zero to enable jamming 33167 * Return Value: 33168 * BCM_E_XXX 33169 */ 33170 int 33171 bcm_esw_port_jam_set(int unit, bcm_port_t port, int enable) 33172 { 33173 /* Make sure port module is initialized. */ 33174 PORT_INIT(unit); 33175 33176 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33177 33178 if (!IS_E_PORT(unit, port)) { /* HG, CPU ports */ 33179 return enable ? BCM_E_CONFIG : BCM_E_NONE; 33180 } 33181 33182 #ifdef BCM_XGS3_SWITCH_SUPPORT 33183 if (SOC_IS_XGS3_SWITCH(unit)) { 33184 uint32 rval; 33185 int oenable; 33186 33187 if (!IS_GE_PORT(unit, port) && !IS_FE_PORT(unit, port)) { 33188 return BCM_E_UNAVAIL; 33189 } else if (!soc_reg_field_valid(unit, GE_PORT_CONFIGr, JAM_ENf) && 33190 !soc_feature(unit, soc_feature_unimac)) { 33191 return BCM_E_UNAVAIL; 33192 } 33193 33194 if (soc_feature(unit, soc_feature_unimac)) { 33195 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_HURRICANE_SUPPORT) 33196 if ((SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANEX(unit) || 33197 SOC_IS_GREYHOUND2(unit)) && 33198 (IS_XL_PORT(unit,port) || IS_CL_PORT(unit, port))) { 33199 return BCM_E_UNAVAIL; 33200 } 33201 #endif 33202 #ifdef BCM_KATANA_SUPPORT 33203 /* In KATANA, certain GE ports do not use UNIMAC driver */ 33204 if ((SOC_IS_KATANA(unit)) && (IS_MXQ_PORT(unit, port))) { 33205 return BCM_E_UNAVAIL; 33206 } 33207 #endif 33208 SOC_IF_ERROR_RETURN(READ_IPG_HD_BKP_CNTLr(unit, port, &rval)); 33209 oenable = soc_reg_field_get(unit, IPG_HD_BKP_CNTLr, rval, 33210 HD_FC_ENAf); 33211 #ifdef BCM_HAWKEYE_SUPPORT 33212 if(SOC_IS_HAWKEYE(unit)) { 33213 /* 33214 * In HAWKEYE A0, the back-pressure is disabled 33215 * when the bit HD_FC_ENA is cleared (binary 0). 33216 * In other revision of HAWKEYE, the back-pressure is disabled 33217 * when the bit HD_FC_ENA is set (binary 1). 33218 */ 33219 if(soc_feature(unit, soc_feature_hawkeye_a0_war)) { 33220 enable = enable ? 1 : 0; 33221 } else { 33222 enable = enable ? 0 : 1; 33223 } 33224 } else 33225 #endif /* BCM_HAWKEYE_SUPPORT */ 33226 { 33227 enable = enable ? 1 : 0; 33228 } 33229 if (oenable != enable) { 33230 soc_reg_field_set(unit, IPG_HD_BKP_CNTLr, &rval, HD_FC_ENAf, 33231 enable); 33232 SOC_IF_ERROR_RETURN(WRITE_IPG_HD_BKP_CNTLr(unit, port, rval)); 33233 } 33234 } else { 33235 SOC_IF_ERROR_RETURN(READ_GE_PORT_CONFIGr(unit, port, &rval)); 33236 oenable = soc_reg_field_get(unit, GE_PORT_CONFIGr, rval, JAM_ENf); 33237 enable = enable ? 1 : 0; 33238 if (oenable != enable) { 33239 soc_reg_field_set(unit, GE_PORT_CONFIGr, &rval, JAM_ENf, enable); 33240 SOC_IF_ERROR_RETURN(WRITE_GE_PORT_CONFIGr(unit, port, rval)); 33241 } 33242 } 33243 return BCM_E_NONE; 33244 } 33245 #endif 33246 33247 /* XE ports */ 33248 return enable ? BCM_E_CONFIG : BCM_E_NONE; 33249 } 33250 33251 /* 33252 * Function: 33253 * bcm_port_jam_get 33254 * Description: 33255 * Return half duplex jamming state 33256 * Parameters: 33257 * unit - Device number 33258 * port - Port number 33259 * enable - (OUT) non-zero if jamming enabled 33260 * Return Value: 33261 * BCM_E_XXX 33262 */ 33263 int 33264 bcm_esw_port_jam_get(int unit, bcm_port_t port, int *enable) 33265 { 33266 /* Make sure port module is initialized. */ 33267 PORT_INIT(unit); 33268 33269 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33270 33271 if (!IS_E_PORT(unit, port)) { /* HG, CPU ports */ 33272 *enable = 0; 33273 return BCM_E_NONE; 33274 } 33275 33276 #ifdef BCM_XGS3_SWITCH_SUPPORT 33277 if (SOC_IS_XGS3_SWITCH(unit)) { 33278 uint32 rval; 33279 33280 if (!IS_GE_PORT(unit, port) && !IS_FE_PORT(unit, port)) { 33281 return BCM_E_UNAVAIL; 33282 } else if (!soc_reg_field_valid(unit, GE_PORT_CONFIGr, JAM_ENf) && 33283 !soc_feature(unit, soc_feature_unimac)) { 33284 return BCM_E_UNAVAIL; 33285 } 33286 #if defined(BCM_GREYHOUND_SUPPORT) || defined(BCM_HURRICANE_SUPPORT) 33287 else if ((SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANEX(unit) || 33288 SOC_IS_GREYHOUND2(unit)) && 33289 (IS_XL_PORT(unit,port) || IS_CL_PORT(unit, port))) { 33290 return BCM_E_UNAVAIL; 33291 } 33292 #endif 33293 33294 if (soc_feature(unit, soc_feature_unimac)) { 33295 #ifdef BCM_KATANA_SUPPORT 33296 /* In KATANA, certain GE ports do not use UNIMAC driver */ 33297 if ((SOC_IS_KATANA(unit)) && (IS_MXQ_PORT(unit, port))) { 33298 return BCM_E_UNAVAIL; 33299 } 33300 #endif 33301 SOC_IF_ERROR_RETURN(READ_IPG_HD_BKP_CNTLr(unit, port, &rval)); 33302 *enable = soc_reg_field_get(unit, IPG_HD_BKP_CNTLr, rval, HD_FC_ENAf); 33303 } else { 33304 SOC_IF_ERROR_RETURN(READ_GE_PORT_CONFIGr(unit, port, &rval)); 33305 *enable = soc_reg_field_get(unit, GE_PORT_CONFIGr, rval, JAM_ENf); 33306 } 33307 return BCM_E_NONE; 33308 } 33309 #endif 33310 33311 *enable = 0; 33312 return BCM_E_NONE; 33313 } 33314 33315 /* 33316 * Function: 33317 * bcm_port_cable_diag 33318 * Description: 33319 * Run Cable Diagnostics on port 33320 * Parameters: 33321 * unit - Device number 33322 * port - Port number 33323 * status - (OUT) cable diag status structure 33324 * Return Value: 33325 * BCM_E_XXX 33326 * Notes: 33327 * Cable diagnostics are only supported by some phy types 33328 * (currently 5248 10/100 phy and 546x 10/100/1000 phys) 33329 */ 33330 int 33331 bcm_esw_port_cable_diag(int unit, bcm_port_t port, 33332 bcm_port_cable_diag_t *status) 33333 { 33334 int rv = BCM_E_NONE; 33335 33336 /* Make sure port module is initialized. */ 33337 PORT_INIT(unit); 33338 33339 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33340 33341 #ifdef BCM_RCPU_SUPPORT 33342 if (SOC_IS_RCPU_ONLY(unit) && IS_RCPU_PORT(unit, port)) { 33343 return BCM_E_PORT; 33344 } 33345 #endif /* BCM_RCPU_SUPPORT */ 33346 33347 #ifdef PORTMOD_SUPPORT 33348 if (SOC_USE_PORTCTRL(unit)) { 33349 return bcmi_esw_portctrl_cable_diag(unit, port, status); 33350 } else 33351 #endif /* PORTMOD_SUPPORT */ 33352 { 33353 PORT_LOCK(unit); 33354 rv = soc_phyctrl_cable_diag(unit, port, status); 33355 PORT_UNLOCK(unit); 33356 } 33357 33358 return rv; 33359 } 33360 33361 /* 33362 * Function: 33363 * bcm_esw_port_fault_get 33364 * Description: 33365 * Get link fault type 33366 * Parameters: 33367 * unit - Device number 33368 * port - Port number 33369 * flags - (OUT) flags to indicate fault type 33370 * Return Value: 33371 * BCM_E_XXX 33372 */ 33373 33374 int 33375 bcm_esw_port_fault_get(int unit, bcm_port_t port, uint32 *flags) 33376 { 33377 int rv, local_fault, remote_fault; 33378 int faults; 33379 soc_persist_t *sop = SOC_PERSIST(unit); 33380 33381 /* Make sure port module is initialized. */ 33382 PORT_INIT(unit); 33383 33384 if(bcm_common_oamp_port_enable_get(unit, port)) { 33385 LOG_ERROR(BSL_LS_BCM_PORT, 33386 (BSL_META("Error: Not permitted on OAMP port %d.n"), 33387 port)); 33388 return BCM_E_PARAM; 33389 } 33390 33391 if (SOC_PBMP_MEMBER(sop->lc_pbm_eth_buffer_mode, port)) { 33392 faults = FALSE; 33393 SOC_IF_ERROR_RETURN(soc_phyctrl_linkfault_get(unit, port, &faults)); 33394 } 33395 33396 /* Call Port Control module */ 33397 if (SOC_USE_PORTCTRL(unit)) { 33398 rv = bcmi_esw_portctrl_fault_get(unit, port, flags); 33399 if (SOC_PBMP_MEMBER(sop->lc_pbm_eth_buffer_mode, port)) { 33400 if (faults) { 33401 *flags |= faults; 33402 } 33403 } 33404 return (rv); 33405 } 33406 33407 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33408 33409 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 33410 SOC_MAC_CONTROL_FAULT_LOCAL_STATUS, &local_fault); 33411 if (rv == SOC_E_UNAVAIL) { 33412 return BCM_E_PORT; 33413 } 33414 SOC_IF_ERROR_RETURN 33415 (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 33416 SOC_MAC_CONTROL_FAULT_REMOTE_STATUS, &remote_fault)); 33417 33418 *flags = 0; 33419 if (remote_fault) { 33420 *flags |= BCM_PORT_FAULT_REMOTE; 33421 } 33422 if (local_fault) { 33423 *flags |= BCM_PORT_FAULT_LOCAL; 33424 } 33425 33426 if (SOC_PBMP_MEMBER(sop->lc_pbm_eth_buffer_mode, port)) { 33427 *flags |= faults; 33428 } 33429 33430 return BCM_E_NONE; 33431 } 33432 33433 /* 33434 * Function: 33435 * bcm_port_trunk_index_set 33436 * Description: 33437 * Set port index of a trunk for ingress port that is used to select 33438 * the egress port in the trunk. 33439 * Parameters: 33440 * unit - StrataSwitch PCI device unit number (driver internal). 33441 * port - Ingress port. 33442 * port_index - Port index of a trunk. 33443 * Returns: 33444 * BCM_E_xxxx 33445 * Note: 33446 * The psc (aka rtag) vlaue needs to be 7 (set in bcm_trunk_set()) for 33447 * a trunk in order to utilize this programmable hashing mechanism. 33448 */ 33449 33450 int 33451 bcm_esw_port_trunk_index_set(int unit, bcm_port_t port, int port_index) 33452 { 33453 #if defined(BCM_FIREBOLT_SUPPORT) 33454 uint32 val, mask = 0x7; 33455 33456 /* Make sure port module is initialized. */ 33457 PORT_INIT(unit); 33458 33459 if (soc_feature(unit, soc_feature_port_trunk_index)) { 33460 if (IS_ST_PORT(unit, port)) { 33461 if (!SOC_REG_IS_VALID(unit, IUSER_TRUNK_HASH_SELECTr)) { 33462 return BCM_E_UNAVAIL; 33463 } 33464 33465 val = 0; 33466 if (!SOC_IS_RAVEN(unit)) { 33467 mask = 0x3; 33468 } 33469 soc_reg_field_set(unit, IUSER_TRUNK_HASH_SELECTr, &val, 33470 TRUNK_CFG_VALf, port_index & mask); 33471 SOC_IF_ERROR_RETURN 33472 (WRITE_IUSER_TRUNK_HASH_SELECTr(unit, port, val)); 33473 } else if (IS_E_PORT(unit, port)) { 33474 if (!SOC_REG_IS_VALID(unit, USER_TRUNK_HASH_SELECTr)) { 33475 return BCM_E_UNAVAIL; 33476 } 33477 33478 val = 0; 33479 soc_reg_field_set(unit, USER_TRUNK_HASH_SELECTr, &val, 33480 TRUNK_CFG_VALf, port_index & mask); 33481 SOC_IF_ERROR_RETURN 33482 (WRITE_USER_TRUNK_HASH_SELECTr(unit, port, val)); 33483 } 33484 33485 return BCM_E_NONE; 33486 } 33487 #endif /* BCM_FIREBOLT_SUPPORT */ 33488 33489 return BCM_E_UNAVAIL; 33490 } 33491 33492 /* 33493 * Function: 33494 * bcm_port_trunk_index_get 33495 * Description: 33496 * Get port index of a trunk for ingress port that is used to select 33497 * the egress port in the trunk. 33498 * Parameters: 33499 * unit - StrataSwitch PCI device unit number (driver internal). 33500 * port - Ingress port. 33501 * port_index - (OUT) Port index of a trunk. 33502 * Returns: 33503 * BCM_E_xxxx 33504 */ 33505 33506 int 33507 bcm_esw_port_trunk_index_get(int unit, bcm_port_t port, int *port_index) 33508 { 33509 #if defined(BCM_FIREBOLT_SUPPORT) 33510 uint32 val; 33511 33512 /* Make sure port module is initialized. */ 33513 PORT_INIT(unit); 33514 33515 if (soc_feature(unit, soc_feature_port_trunk_index)) { 33516 if (IS_ST_PORT(unit, port)) { 33517 if (!SOC_REG_IS_VALID(unit, IUSER_TRUNK_HASH_SELECTr)) { 33518 return BCM_E_UNAVAIL; 33519 } 33520 33521 SOC_IF_ERROR_RETURN 33522 (READ_IUSER_TRUNK_HASH_SELECTr(unit, port, &val)); 33523 *port_index = soc_reg_field_get(unit, IUSER_TRUNK_HASH_SELECTr, 33524 val, TRUNK_CFG_VALf); 33525 } else if (IS_E_PORT(unit, port)) { 33526 if (!SOC_REG_IS_VALID(unit, USER_TRUNK_HASH_SELECTr)) { 33527 return BCM_E_UNAVAIL; 33528 } 33529 33530 SOC_IF_ERROR_RETURN 33531 (READ_USER_TRUNK_HASH_SELECTr(unit, port, &val)); 33532 *port_index = soc_reg_field_get(unit, USER_TRUNK_HASH_SELECTr, 33533 val, TRUNK_CFG_VALf); 33534 } 33535 33536 return BCM_E_NONE; 33537 } 33538 #endif /* BCM_FIREBOLT_SUPPORT */ 33539 33540 return BCM_E_UNAVAIL; 33541 } 33542 33543 #ifdef BCM_XGS3_SWITCH_SUPPORT 33544 33545 static soc_field_t _bcm_xgs3_priority_fields[] = { 33546 PRIORITY0_CNGf, 33547 PRIORITY1_CNGf, 33548 PRIORITY2_CNGf, 33549 PRIORITY3_CNGf, 33550 PRIORITY4_CNGf, 33551 PRIORITY5_CNGf, 33552 PRIORITY6_CNGf, 33553 PRIORITY7_CNGf, 33554 }; 33555 33556 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 33557 33558 #ifdef BCM_TRIUMPH2_SUPPORT 33559 STATIC 33560 int _bcm_esw_vp_ing_pri_cng_set(int unit, bcm_gport_t port, int untagged, 33561 int pkt_pri, int cfi, 33562 int internal_pri, bcm_color_t color) 33563 { 33564 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit)) { 33565 return _bcm_tr2_vp_ing_pri_cng_set(unit, port, untagged, 33566 pkt_pri, cfi, 33567 internal_pri, color); 33568 } 33569 return BCM_E_PORT; 33570 } 33571 33572 STATIC 33573 int _bcm_esw_vp_ing_pri_cng_get(int unit, bcm_gport_t port, int untagged, 33574 int pkt_pri, int cfi, 33575 int *internal_pri, bcm_color_t *color) 33576 { 33577 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit)) { 33578 return _bcm_tr2_vp_ing_pri_cng_get(unit, port, untagged, 33579 pkt_pri, cfi, 33580 internal_pri, color); 33581 } 33582 return BCM_E_PORT; 33583 } 33584 #endif 33585 /* 33586 * Function: 33587 * bcm_port_priority_color_set 33588 * Purpose: 33589 * Specify the color selection for the given priority. 33590 * Parameters: 33591 * unit - StrataSwitch PCI device unit number (driver internal). 33592 * port - Port to configure 33593 * prio - priority (aka 802.1p CoS) 33594 * color - color assigned to packets with indicated priority. 33595 * Returns: 33596 * BCM_E_NONE - Success. 33597 * BCM_E_XXX 33598 * Notes: 33599 * Available on XGS3 only. 33600 */ 33601 int 33602 bcm_esw_port_priority_color_set(int unit, bcm_port_t port, 33603 int prio, bcm_color_t color) 33604 { 33605 /* Make sure port module is initialized. */ 33606 PORT_INIT(unit); 33607 33608 #ifdef BCM_XGS3_SWITCH_SUPPORT 33609 if (soc_feature(unit, soc_feature_color)) { 33610 33611 VLAN_CHK_PRIO(unit, prio); 33612 33613 #if defined(BCM_TRIUMPH2_SUPPORT) 33614 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 33615 if (BCM_GPORT_IS_SET(port) && 33616 !BCM_GPORT_IS_MODPORT(port) && 33617 !BCM_GPORT_IS_LOCAL(port) && 33618 !BCM_GPORT_IS_SUBPORT_PORT(port)) { 33619 return _bcm_esw_vp_ing_pri_cng_set(unit, port, FALSE, prio, 33620 -1, -1, color); 33621 } 33622 } 33623 #endif 33624 33625 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33626 33627 #ifdef BCM_TRIUMPH2_SUPPORT 33628 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 33629 #ifdef BCM_TRIDENT3_SUPPORT 33630 if (SOC_IS_TRIDENT3X(unit)) { 33631 return bcm_td3_port_ing_pri_cng_set(unit, port, FALSE, 33632 prio, -1, -1, color); 33633 } else 33634 #endif 33635 #ifdef BCM_TRIDENT_SUPPORT 33636 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 33637 SOC_IS_TRIUMPH3(unit)) { 33638 return bcm_td_port_ing_pri_cng_set(unit, port, FALSE, 33639 prio, -1, -1, color); 33640 } else 33641 #endif /* BCM_TRIDENT_SUPPORT */ 33642 { 33643 return _bcm_tr2_port_priority_color_set(unit, port, 33644 prio, color); 33645 } 33646 } else 33647 #endif 33648 { 33649 uint32 val, oval; 33650 33651 SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, port, &val)); 33652 oval = val; 33653 soc_reg_field_set(unit, CNG_MAPr, &val, 33654 _bcm_xgs3_priority_fields[prio], 33655 _BCM_COLOR_ENCODING(unit, color)); 33656 if (oval != val) { 33657 SOC_IF_ERROR_RETURN(WRITE_CNG_MAPr(unit, port, val)); 33658 } 33659 return BCM_E_NONE; 33660 } 33661 } 33662 #endif 33663 return BCM_E_UNAVAIL; 33664 } 33665 33666 /* 33667 * Function: 33668 * bcm_port_priority_color_get 33669 * Purpose: 33670 * Get the color selection for the given priority. 33671 * Parameters: 33672 * unit - StrataSwitch PCI device unit number (driver internal). 33673 * port - Port to configure 33674 * prio - priority (aka 802.1p CoS) 33675 * color - (OUT) color assigned to packets with indicated priority. 33676 * Returns: 33677 * BCM_E_NONE - Success. 33678 * BCM_E_XXX 33679 * Notes: 33680 * Available on XGS3 only. 33681 */ 33682 int 33683 bcm_esw_port_priority_color_get(int unit, bcm_port_t port, 33684 int prio, bcm_color_t *color) 33685 { 33686 /* Make sure port module is initialized. */ 33687 PORT_INIT(unit); 33688 33689 #ifdef BCM_XGS3_SWITCH_SUPPORT 33690 if (soc_feature(unit, soc_feature_color)) { 33691 uint32 val, hw_color; 33692 cng_map_entry_t cng_map_entry; 33693 int ptr; 33694 33695 /* Input parameters check. */ 33696 if ((NULL == color)) { 33697 return (BCM_E_PARAM); 33698 } 33699 33700 VLAN_CHK_PRIO(unit, prio); 33701 33702 #if defined(BCM_TRIUMPH2_SUPPORT) 33703 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 33704 if (BCM_GPORT_IS_SET(port) && 33705 !BCM_GPORT_IS_MODPORT(port) && 33706 !BCM_GPORT_IS_LOCAL(port) && 33707 !BCM_GPORT_IS_SUBPORT_PORT(port)) { 33708 return _bcm_esw_vp_ing_pri_cng_get(unit, port, FALSE, prio, 33709 0, NULL, color); 33710 } 33711 } 33712 #endif 33713 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33714 ptr = port; 33715 33716 #ifdef BCM_TRIUMPH2_SUPPORT 33717 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 33718 #ifdef BCM_TRIDENT3_SUPPORT 33719 if (SOC_IS_TRIDENT3X(unit)) { 33720 return bcm_td3_port_ing_pri_cng_get(unit, port, FALSE, 33721 prio, 0, NULL, color); 33722 } else 33723 #endif /* BCM_TRIDENT3_SUPPORT */ 33724 #ifdef BCM_TRIDENT_SUPPORT 33725 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 33726 SOC_IS_TRIUMPH3(unit)) { 33727 return bcm_td_port_ing_pri_cng_get(unit, port, FALSE, 33728 prio, 0, NULL, color); 33729 } else 33730 #endif /* BCM_TRIDENT_SUPPORT */ 33731 { 33732 /* Get the pointer from the ING_PRI_CNG_MAP table */ 33733 port_tab_entry_t pent; 33734 BCM_IF_ERROR_RETURN 33735 (soc_mem_read(unit, PORT_TABm, MEM_BLOCK_ANY, 33736 SOC_PORT_MOD_OFFSET(unit, port), &pent)); 33737 ptr = soc_PORT_TABm_field32_get(unit, &pent, 33738 TRUST_DOT1P_PTRf); 33739 } 33740 } 33741 #endif 33742 if (SOC_MEM_IS_VALID(unit, CNG_MAPm)) { 33743 SOC_IF_ERROR_RETURN(READ_CNG_MAPm(unit, MEM_BLOCK_ANY, 33744 ptr, &cng_map_entry)); 33745 hw_color = soc_CNG_MAPm_field32_get(unit, &cng_map_entry, 33746 _bcm_xgs3_priority_fields[prio]); 33747 } else { 33748 SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, ptr, &val)); 33749 hw_color = soc_reg_field_get(unit, CNG_MAPr, val, 33750 _bcm_xgs3_priority_fields[prio]); 33751 } 33752 *color = _BCM_COLOR_DECODING(unit, hw_color); 33753 return BCM_E_NONE; 33754 } 33755 #endif 33756 return BCM_E_UNAVAIL; 33757 } 33758 33759 /* 33760 * Function: 33761 * bcm_port_cfi_color_set 33762 * Purpose: 33763 * Specify the color selection for the given CFI. 33764 * Parameters: 33765 * unit - StrataSwitch PCI device unit number (driver internal). 33766 * port - Port to configure 33767 * cfi - Canonical format indicator (TRUE/FALSE) 33768 * color - color assigned to packets with indicated CFI. 33769 * Returns: 33770 * BCM_E_NONE - Success. 33771 * BCM_E_XXX 33772 * Notes: 33773 * Available on XGS3 only. 33774 */ 33775 int 33776 bcm_esw_port_cfi_color_set(int unit, bcm_port_t port, 33777 int cfi, bcm_color_t color) 33778 { 33779 /* Make sure port module is initialized. */ 33780 PORT_INIT(unit); 33781 33782 #ifdef BCM_XGS3_SWITCH_SUPPORT 33783 if (soc_feature(unit, soc_feature_color)) { 33784 if (cfi < 0 || cfi > 1) { 33785 return BCM_E_PARAM; 33786 } 33787 33788 #if defined(BCM_TRIUMPH2_SUPPORT) 33789 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 33790 if (BCM_GPORT_IS_SET(port) && 33791 !BCM_GPORT_IS_MODPORT(port) && 33792 !BCM_GPORT_IS_LOCAL(port) && 33793 !BCM_GPORT_IS_SUBPORT_PORT(port)) { 33794 return _bcm_esw_vp_ing_pri_cng_set(unit, port, FALSE, -1, 33795 cfi, -1, color); 33796 } 33797 } 33798 #endif 33799 33800 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33801 #ifdef BCM_TRIDENT3_SUPPORT 33802 if (SOC_IS_TRIDENT3X(unit)) { 33803 return bcm_td3_port_ing_pri_cng_set(unit, port, FALSE, 33804 -1, cfi, -1, color); 33805 } else 33806 #endif 33807 #ifdef BCM_TRIDENT_SUPPORT 33808 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 33809 SOC_IS_TRIUMPH3(unit)) { 33810 return bcm_td_port_ing_pri_cng_set(unit, port, FALSE, 33811 -1, cfi, -1, color); 33812 } else 33813 #endif /* BCM_TRIDENT_SUPPORT */ 33814 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 33815 || defined (BCM_TRX_SUPPORT) 33816 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_TRX(unit) || 33817 SOC_IS_HAWKEYE(unit)) { 33818 int index, pkt_pri; 33819 uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS]; 33820 33821 sal_memset(pri_map, 0, sizeof(pri_map)); 33822 33823 #if defined(BCM_TRIUMPH2_SUPPORT) 33824 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 33825 pkt_pri = -1; 33826 return _bcm_tr2_port_vlan_priority_map_set(unit, port, pkt_pri, 33827 cfi, 33828 pkt_pri, color); 33829 } else 33830 #endif /* BCM_TRIUMPH2_SUPPORT */ 33831 { 33832 for (pkt_pri = 0; pkt_pri <= 7; pkt_pri++) { 33833 /* ING_PRI_CNG_MAP table is indexed with 33834 * port[0:4] incoming priority[2:0] incoming CFI[0] 33835 */ 33836 index = (port << 4) | (pkt_pri << 1) | cfi; 33837 if (SOC_IS_TRIDENT3X(unit)) { 33838 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, PRIf, 33839 pkt_pri); 33840 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, CNGf, 33841 _BCM_COLOR_ENCODING(unit, color)); 33842 SOC_IF_ERROR_RETURN(WRITE_PHB_MAPPING_TBL_1m(unit, 33843 MEM_BLOCK_ALL, index, &pri_map)); 33844 } else { 33845 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, PRIf, 33846 pkt_pri); 33847 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, CNGf, 33848 _BCM_COLOR_ENCODING(unit, color)); 33849 SOC_IF_ERROR_RETURN(WRITE_ING_PRI_CNG_MAPm(unit, 33850 MEM_BLOCK_ALL, index, &pri_map)); 33851 } 33852 } 33853 } 33854 } else 33855 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 33856 { 33857 uint32 val, oval; 33858 SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, port, &val)); 33859 oval = val; 33860 soc_reg_field_set(unit, CNG_MAPr, &val, 33861 cfi ? CFI1_CNGf : CFI0_CNGf, 33862 _BCM_COLOR_ENCODING(unit, color)); 33863 if (oval != val) { 33864 SOC_IF_ERROR_RETURN(WRITE_CNG_MAPr(unit, port, val)); 33865 } 33866 } 33867 return BCM_E_NONE; 33868 } 33869 #endif 33870 return BCM_E_UNAVAIL; 33871 } 33872 33873 /* 33874 * Function: 33875 * bcm_port_cfi_color_get 33876 * Purpose: 33877 * Get the color selection for the given CFI. 33878 * Parameters: 33879 * unit - StrataSwitch PCI device unit number (driver internal). 33880 * port - Port to configure 33881 * cfi - Canonical format indicator (TRUE/FALSE) 33882 * color - (OUT) color assigned to packets with indicated CFI. 33883 * Returns: 33884 * BCM_E_NONE - Success. 33885 * BCM_E_XXX 33886 * Notes: 33887 * Available on XGS3 only. 33888 */ 33889 int 33890 bcm_esw_port_cfi_color_get(int unit, bcm_port_t port, 33891 int cfi, bcm_color_t *color) 33892 { 33893 /* Make sure port module is initialized. */ 33894 PORT_INIT(unit); 33895 33896 #ifdef BCM_XGS3_SWITCH_SUPPORT 33897 if (soc_feature(unit, soc_feature_color)) { 33898 uint32 hw_color; 33899 33900 if (cfi < 0 || cfi > 1) { 33901 return BCM_E_PARAM; 33902 } 33903 33904 /* Input parameters check. */ 33905 if ((NULL == color)) { 33906 return (BCM_E_PARAM); 33907 } 33908 33909 #if defined(BCM_TRIUMPH2_SUPPORT) 33910 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 33911 if (BCM_GPORT_IS_SET(port) && 33912 !BCM_GPORT_IS_MODPORT(port) && 33913 !BCM_GPORT_IS_LOCAL(port) && 33914 !BCM_GPORT_IS_SUBPORT_PORT(port)) { 33915 return _bcm_esw_vp_ing_pri_cng_get(unit, port, FALSE, 0, 33916 cfi, NULL, color); 33917 } 33918 } 33919 #endif 33920 33921 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 33922 33923 #ifdef BCM_TRIDENT3_SUPPORT 33924 if (SOC_IS_TRIDENT3X(unit)) { 33925 return bcm_td3_port_ing_pri_cng_get(unit, port, FALSE, 0, cfi, NULL, 33926 color); 33927 } else 33928 #endif /* BCM_TRIDENT3_SUPPORT */ 33929 #ifdef BCM_TRIDENT_SUPPORT 33930 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 33931 SOC_IS_TRIUMPH3(unit)) { 33932 return bcm_td_port_ing_pri_cng_get(unit, port, FALSE, 0, cfi, NULL, 33933 color); 33934 } else 33935 #endif /* BCM_TRIDENT_SUPPORT */ 33936 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 33937 || defined(BCM_TRX_SUPPORT) 33938 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) 33939 || SOC_IS_TRX(unit) || SOC_IS_HAWKEYE(unit)) { 33940 int index; 33941 uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS]; 33942 33943 sal_memset(pri_map, 0, sizeof(pri_map)); 33944 33945 #if defined(BCM_TRIUMPH2_SUPPORT) 33946 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 33947 int pkt_pri = 0; 33948 return _bcm_tr2_port_vlan_priority_map_get(unit, port, 0, 33949 cfi, &pkt_pri, color); 33950 } else 33951 #endif /* BCM_TRIUMPH2_SUPPORT */ 33952 { 33953 /* ING_PRI_CNG_MAP table is indexed with 33954 * port[0:4] incoming priority[2:0] incoming CFI[0] 33955 */ 33956 index = (port << 4) | cfi; 33957 if (SOC_IS_TRIDENT3X(unit)) { 33958 SOC_IF_ERROR_RETURN(READ_PHB_MAPPING_TBL_1m(unit, MEM_BLOCK_ANY, 33959 index, &pri_map)); 33960 hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, 33961 &pri_map, CNGf); 33962 } else { 33963 SOC_IF_ERROR_RETURN(READ_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ANY, 33964 index, &pri_map)); 33965 hw_color = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, 33966 &pri_map, CNGf); 33967 } 33968 } 33969 } else 33970 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */ 33971 { 33972 uint32 val; 33973 33974 SOC_IF_ERROR_RETURN(READ_CNG_MAPr(unit, port, &val)); 33975 hw_color = soc_reg_field_get(unit, CNG_MAPr, val, 33976 cfi ? CFI1_CNGf : CFI0_CNGf); 33977 } 33978 *color = _BCM_COLOR_DECODING(unit, hw_color); 33979 return BCM_E_NONE; 33980 } 33981 #endif 33982 return BCM_E_UNAVAIL; 33983 } 33984 33985 /* 33986 * Function: 33987 * bcm_esw_port_vlan_priority_map_set 33988 * Description: 33989 * Define the mapping of incomming port, packet priority, and cfi bit to 33990 * switch internal priority and color. 33991 * Parameters: 33992 * unit - (IN) Device number 33993 * port - (IN) Port number 33994 * pkt_pri - (IN) Packet priority 33995 * cfi - (IN) Packet CFI 33996 * internal_pri - (IN) Internal priority 33997 * color - (IN) color 33998 * Return Value: 33999 * BCM_E_XXX 34000 * Note: 34001 * This API programs only the mapping table. 34002 */ 34003 int 34004 bcm_esw_port_vlan_priority_map_set(int unit, bcm_port_t port, int pkt_pri, 34005 int cfi, int internal_pri, bcm_color_t color) 34006 { 34007 #ifdef BCM_TRIUMPH2_SUPPORT 34008 int untagged = FALSE; 34009 #endif /* BCM_TRIUMPH2_SUPPORT */ 34010 34011 /* Make sure port module is initialized. */ 34012 PORT_INIT(unit); 34013 34014 if (!soc_feature(unit, soc_feature_color_prio_map) || 34015 soc_feature(unit, soc_feature_deprecated_api)) { 34016 return BCM_E_UNAVAIL; 34017 } 34018 34019 if (SOC_MEM_IS_VALID(unit, ING_UNTAGGED_PHBm)) { 34020 if (pkt_pri == -1 && cfi == -1) { 34021 #ifdef BCM_TRIDENT_SUPPORT 34022 untagged = TRUE; 34023 #endif /* BCM_TRIDENT_SUPPORT */ 34024 pkt_pri = 0; 34025 cfi = 0; 34026 } 34027 } 34028 34029 if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1 || internal_pri < 0 ) { 34030 return BCM_E_PARAM; 34031 } 34032 34033 if (SOC_IS_TRIDENT3X(unit)) { 34034 if (internal_pri >= (1 << soc_mem_field_length(unit, PHB_MAPPING_TBL_1m, PRIf))) { 34035 return BCM_E_PARAM; 34036 } 34037 } else { 34038 if (internal_pri >= (1 << soc_mem_field_length(unit, ING_PRI_CNG_MAPm, PRIf))) { 34039 return BCM_E_PARAM; 34040 } 34041 } 34042 34043 #if defined(BCM_TRIUMPH2_SUPPORT) 34044 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 34045 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 34046 !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) { 34047 return _bcm_esw_vp_ing_pri_cng_set(unit, port, untagged, pkt_pri, 34048 cfi, internal_pri, color); 34049 } 34050 } 34051 #endif 34052 34053 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34054 34055 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 34056 || defined(BCM_TRX_SUPPORT) 34057 #if defined(BCM_TRIUMPH2_SUPPORT) 34058 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 34059 #ifdef BCM_TRIDENT3_SUPPORT 34060 if (SOC_IS_TRIDENT3X(unit)) { 34061 return bcm_td3_port_ing_pri_cng_set(unit, port, untagged, 34062 pkt_pri, cfi, 34063 internal_pri, color); 34064 } else 34065 #endif 34066 #if defined BCM_TRIDENT_SUPPORT 34067 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 34068 SOC_IS_TRIUMPH3(unit)) { 34069 return bcm_td_port_ing_pri_cng_set(unit, port, untagged, 34070 pkt_pri, cfi, 34071 internal_pri, color); 34072 } else 34073 #endif /* BCM_TRIDENT_SUPPORT */ 34074 { 34075 return _bcm_tr2_port_vlan_priority_map_set(unit, port, pkt_pri, 34076 cfi, 34077 internal_pri, color); 34078 } 34079 } else 34080 #endif 34081 if (soc_feature(unit, soc_feature_color_prio_map)) { 34082 int index; 34083 uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS]; 34084 34085 sal_memset(pri_map, 0, sizeof(pri_map)); 34086 34087 /* ING_PRI_CNG_MAP table is indexed with 34088 * port[0:4] incoming priority[2:0] incoming CFI[0] 34089 */ 34090 index = (port << 4) | (pkt_pri << 1) | cfi; 34091 34092 if (SOC_IS_TRIDENT3X(unit)) { 34093 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, PRIf, 34094 internal_pri); 34095 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map, CNGf, 34096 _BCM_COLOR_ENCODING(unit, color)); 34097 SOC_IF_ERROR_RETURN 34098 (WRITE_PHB_MAPPING_TBL_1m(unit, MEM_BLOCK_ALL, index, &pri_map)); 34099 } else { 34100 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, PRIf, 34101 internal_pri); 34102 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map, CNGf, 34103 _BCM_COLOR_ENCODING(unit, color)); 34104 SOC_IF_ERROR_RETURN 34105 (WRITE_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ALL, index, &pri_map)); 34106 } 34107 34108 return BCM_E_NONE; 34109 } 34110 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 34111 return BCM_E_UNAVAIL; 34112 } 34113 34114 /* 34115 * Function: 34116 * bcm_esw_port_vlan_priority_map_get 34117 * Description: 34118 * Get the mapping of incomming port, packet priority, and cfi bit to 34119 * switch internal priority and color. 34120 * Parameters: 34121 * unit - (IN) Device number 34122 * port - (IN) Port number 34123 * pkt_pri - (IN) Packet priority 34124 * cfi - (IN) Packet CFI 34125 * internal_pri - (OUT) Internal priority 34126 * color - (OUT) color 34127 * Return Value: 34128 * BCM_E_XXX 34129 * Note: 34130 * This API programs only the mapping table. 34131 */ 34132 int 34133 bcm_esw_port_vlan_priority_map_get(int unit, bcm_port_t port, int pkt_pri, 34134 int cfi, int *internal_pri, 34135 bcm_color_t *color) 34136 { 34137 #if defined BCM_TRIUMPH2_SUPPORT 34138 int untagged = FALSE; 34139 #endif /* BCM_TRIUMPH2_SUPPORT */ 34140 34141 /* Make sure port module is initialized. */ 34142 PORT_INIT(unit); 34143 34144 if (!soc_feature(unit, soc_feature_color_prio_map) || 34145 soc_feature(unit, soc_feature_deprecated_api)) { 34146 return BCM_E_UNAVAIL; 34147 } 34148 34149 /* Input parameters check. */ 34150 if ((NULL == internal_pri) || (NULL == color)) { 34151 return (BCM_E_PARAM); 34152 } 34153 34154 if (SOC_MEM_IS_VALID(unit, ING_UNTAGGED_PHBm)) { 34155 if (pkt_pri == -1 && cfi == -1) { 34156 #if defined BCM_TRIDENT_SUPPORT 34157 untagged = TRUE; 34158 #endif /* BCM_TRIDENT_SUPPORT */ 34159 pkt_pri = 0; 34160 cfi = 0; 34161 } 34162 } 34163 34164 if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1) { 34165 return BCM_E_PARAM; 34166 } 34167 34168 #if defined(BCM_TRIUMPH2_SUPPORT) 34169 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 34170 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 34171 !BCM_GPORT_IS_LOCAL(port) && !BCM_GPORT_IS_SUBPORT_PORT(port)) { 34172 return _bcm_esw_vp_ing_pri_cng_get(unit, port, untagged, pkt_pri, 34173 cfi, internal_pri, color); 34174 } 34175 } 34176 #endif 34177 34178 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34179 34180 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 34181 || defined(BCM_TRX_SUPPORT) 34182 #if defined(BCM_TRIUMPH2_SUPPORT) 34183 if (soc_feature(unit, soc_feature_color_prio_map_profile)) { 34184 #ifdef BCM_TRIDENT3_SUPPORT 34185 if (SOC_IS_TRIDENT3X(unit)) { 34186 return bcm_td3_port_ing_pri_cng_get(unit, port, untagged, 34187 pkt_pri, cfi, 34188 internal_pri, color); 34189 } else 34190 #endif /* BCM_TRIDENT3_SUPPORT */ 34191 #if defined BCM_TRIDENT_SUPPORT 34192 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 34193 SOC_IS_TRIUMPH3(unit)) { 34194 return bcm_td_port_ing_pri_cng_get(unit, port, untagged, 34195 pkt_pri, cfi, 34196 internal_pri, color); 34197 } else 34198 #endif /* BCM_TRIDENT_SUPPORT */ 34199 { 34200 return _bcm_tr2_port_vlan_priority_map_get(unit, port, pkt_pri, 34201 cfi, internal_pri, 34202 color); 34203 } 34204 } else 34205 #endif 34206 if (soc_feature(unit, soc_feature_color_prio_map)) { 34207 int index, hw_color; 34208 uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS]; 34209 34210 sal_memset(pri_map, 0, sizeof(pri_map)); 34211 34212 /* ING_PRI_CNG_MAP table is indexed with 34213 * port[4:0] incoming priority[2:0] incoming CFI[0] 34214 */ 34215 index = (port << 4) | (pkt_pri << 1) | cfi; 34216 34217 LOG_INFO(BSL_LS_BCM_PORT, 34218 (BSL_META_U(unit, 34219 "bcm_esw_port_vlan_priority_map_get: u=%d p=%d index=%d\n"), 34220 unit, port, index)); 34221 34222 if (SOC_IS_TRIDENT3X(unit)) { 34223 SOC_IF_ERROR_RETURN 34224 (READ_PHB_MAPPING_TBL_1m(unit, MEM_BLOCK_ANY, index, &pri_map)); 34225 *internal_pri = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &pri_map, INT_PRIf); 34226 hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &pri_map, CNGf); 34227 } else { 34228 SOC_IF_ERROR_RETURN 34229 (READ_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ANY, index, &pri_map)); 34230 *internal_pri = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &pri_map, PRIf); 34231 hw_color = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &pri_map, CNGf); 34232 } 34233 34234 *color = _BCM_COLOR_DECODING(unit, hw_color); 34235 return BCM_E_NONE; 34236 } 34237 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 34238 return BCM_E_UNAVAIL; 34239 34240 } 34241 34242 /* 34243 * Function: 34244 * bcm_esw_port_vlan_priority_unmap_set 34245 * Description: 34246 * Define the mapping of outgoing port, internal priority, and color to 34247 * outgoing packet priority and cfi bit. 34248 * Parameters: 34249 * unit - (IN) Device number 34250 * port - (IN) Port number 34251 * internal_pri - (IN) Internal priority 34252 * color - (IN) Color 34253 * pkt_pri - (IN) Packet priority 34254 * cfi - (IN) Packet CFI 34255 * Return Value: 34256 * BCM_E_XXX 34257 * Note: 34258 * This API programs only the mapping table. 34259 */ 34260 int 34261 bcm_esw_port_vlan_priority_unmap_set(int unit, bcm_port_t port, 34262 int internal_pri, bcm_color_t color, 34263 int pkt_pri, int cfi) 34264 { 34265 /* Make sure port module is initialized. */ 34266 PORT_INIT(unit); 34267 34268 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 34269 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 34270 return BCM_E_UNAVAIL; 34271 } 34272 #endif 34273 34274 if (SOC_IS_TRIDENT3X(unit)) { 34275 return BCM_E_UNAVAIL; 34276 } 34277 34278 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34279 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 34280 || defined(BCM_TRX_SUPPORT) 34281 if (soc_feature(unit, soc_feature_color_prio_map)) { 34282 int index, int_pri_shift; 34283 uint32 pri_unmap[SOC_MAX_MEM_FIELD_WORDS]; 34284 soc_mem_t mem = EGR_PRI_CNG_MAPm; 34285 34286 int_pri_shift = SOC_IS_TRX(unit) ? 4 : 3; 34287 if ((internal_pri < 0 || internal_pri >= (1 << int_pri_shift)) || 34288 ((color != bcmColorGreen) && (color != bcmColorYellow) && 34289 (color != bcmColorRed))) { 34290 return BCM_E_PARAM; 34291 } 34292 if (pkt_pri < 0 || pkt_pri > 7 || cfi < 0 || cfi > 1) { 34293 return BCM_E_PARAM; 34294 } 34295 34296 /* EGR_PRI_CNG_MAP table is indexed with 34297 * port[4:0] priority[2:0] CNG [1:0] 34298 * port[5:0] priority[3:0] CNG [1:0] (TRX) 34299 */ 34300 index = (port << (int_pri_shift + 2)) | (internal_pri << 2) | 34301 _BCM_COLOR_ENCODING(unit, color); 34302 34303 sal_memset(pri_unmap, 0, sizeof(pri_unmap)); 34304 soc_mem_field32_set(unit, mem, &pri_unmap, PRIf, pkt_pri); 34305 soc_mem_field32_set(unit, mem, &pri_unmap, CFIf, cfi); 34306 SOC_IF_ERROR_RETURN 34307 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &pri_unmap)); 34308 34309 if ((SOC_IS_TD_TT(unit) && !SOC_IS_TOMAHAWK3(unit)) || 34310 SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) { 34311 egr_map_mh_entry_t egr_map; 34312 34313 sal_memset(&egr_map, 0, sizeof(egr_map)); 34314 index = (port << int_pri_shift) | (internal_pri) ; 34315 soc_mem_field32_set(unit, EGR_MAP_MHm, &egr_map, HG_TCf, internal_pri); 34316 SOC_IF_ERROR_RETURN(WRITE_EGR_MAP_MHm(unit, MEM_BLOCK_ALL, index, &egr_map)); 34317 } 34318 34319 return BCM_E_NONE; 34320 } 34321 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 34322 return BCM_E_UNAVAIL; 34323 } 34324 34325 /* 34326 * Function: 34327 * bcm_esw_port_vlan_priority_unmap_get 34328 * Description: 34329 * Get the mapping of outgoing port, internal priority, and color to 34330 * outgoing packet priority and cfi bit. 34331 * Parameters: 34332 * unit - (IN) Device number 34333 * port - (IN) Port number 34334 * internal_pri - (IN) Internal priority 34335 * color - (IN) Color 34336 * pkt_pri - (OUT) Packet priority 34337 * cfi - (OUT) Packet CFI 34338 * Return Value: 34339 * BCM_E_XXX 34340 * Note: 34341 * This API programs only the mapping table. 34342 */ 34343 int 34344 bcm_esw_port_vlan_priority_unmap_get(int unit, bcm_port_t port, 34345 int internal_pri, bcm_color_t color, 34346 int *pkt_pri, int *cfi) 34347 { 34348 /* Make sure port module is initialized. */ 34349 PORT_INIT(unit); 34350 34351 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 34352 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 34353 return BCM_E_UNAVAIL; 34354 } 34355 #endif 34356 34357 if (SOC_IS_TRIDENT3X(unit)) { 34358 return BCM_E_UNAVAIL; 34359 } 34360 34361 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34362 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) \ 34363 || defined(BCM_TRX_SUPPORT) 34364 if (soc_feature(unit, soc_feature_color_prio_map)) { 34365 int index, int_pri_shift; 34366 uint32 pri_unmap[SOC_MAX_MEM_FIELD_WORDS]; 34367 soc_mem_t mem = EGR_PRI_CNG_MAPm; 34368 34369 int_pri_shift = SOC_IS_TRX(unit) ? 4 : 3; 34370 if ((internal_pri < 0 || internal_pri >= (1 << int_pri_shift)) || 34371 ((color != bcmColorGreen) && (color != bcmColorYellow) && 34372 (color != bcmColorRed))) { 34373 return BCM_E_PARAM; 34374 } 34375 34376 /* EGR_PRI_CNG_MAP table is indexed with 34377 * port[4:0] priority[2:0] CNG [1:0] 34378 * port[5:0] priority[3:0] CNG [1:0] (TRX) 34379 */ 34380 index = (port << (int_pri_shift + 2)) | (internal_pri << 2) | 34381 _BCM_COLOR_ENCODING(unit, color); 34382 34383 SOC_IF_ERROR_RETURN 34384 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, pri_unmap)); 34385 *pkt_pri = soc_mem_field32_get(unit, mem, pri_unmap, PRIf); 34386 *cfi = soc_mem_field32_get(unit, mem, pri_unmap, CFIf); 34387 return BCM_E_NONE; 34388 } 34389 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 34390 return BCM_E_UNAVAIL; 34391 } 34392 34393 /* 34394 * Function: 34395 * bcm_esw_port_l3_modify_set 34396 * Description: 34397 * Enable/Disable ingress port based L3 unicast packet operations. 34398 * Parameters: 34399 * unit - Device number 34400 * port - Port number 34401 * flags - bitmap of the packet operations to be enabled or disabled. 34402 * Return Value: 34403 * BCM_E_XXX 34404 * Notes: 34405 * Available on XGS3 only. 34406 */ 34407 int 34408 bcm_esw_port_l3_modify_set(int unit, bcm_port_t port, uint32 flags) 34409 { 34410 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3) 34411 uint64 r; 34412 soc_reg_t reg; 34413 34414 /* Make sure port module is initialized. */ 34415 PORT_INIT(unit); 34416 34417 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34418 if (SOC_IS_XGS3_SWITCH(unit)) { 34419 reg = IS_ST_PORT(unit, port) ? 34420 IEGR_PORT_L3UC_MODSr : EGR_PORT_L3UC_MODSr; 34421 } else { 34422 return BCM_E_UNAVAIL; 34423 } 34424 34425 if (!SOC_REG_IS_VALID(unit, reg)) { 34426 return BCM_E_UNAVAIL; 34427 } 34428 34429 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &r)); 34430 34431 soc_reg64_field32_set(unit, reg, &r, L3_UC_SA_DISABLEf, 34432 (flags & BCM_PORT_L3_MODIFY_NO_SRCMAC) ? 1 : 0); 34433 34434 soc_reg64_field32_set(unit, reg, &r, L3_UC_DA_DISABLEf, 34435 (flags & BCM_PORT_L3_MODIFY_NO_DSTMAC) ? 1 : 0); 34436 34437 soc_reg64_field32_set(unit, reg, &r, L3_UC_TTL_DISABLEf, 34438 (flags & BCM_PORT_L3_MODIFY_NO_TTL) ? 1 : 0); 34439 34440 soc_reg64_field32_set(unit, reg, &r, L3_UC_VLAN_DISABLEf, 34441 (flags & BCM_PORT_L3_MODIFY_NO_VLAN) ? 1 : 0); 34442 34443 return soc_reg_set(unit, reg, port, 0, r); 34444 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */ 34445 return BCM_E_UNAVAIL; 34446 } 34447 34448 /* 34449 * Function: 34450 * bcm_esw_port_l3_modify_get 34451 * Description: 34452 * Get ingress port based L3 unicast packet operations status. 34453 * Parameters: 34454 * unit - Device number 34455 * port - Port number 34456 * flags - (OUT) pointer to uint32 where bitmap of the current L3 packet 34457 * operations is returned. 34458 * Return Value: 34459 * BCM_E_NONE 34460 * BCM_E_UNAVAIL - Functionality not available 34461 * Notes: 34462 * Available on XGS3 only. 34463 */ 34464 int 34465 bcm_esw_port_l3_modify_get(int unit, bcm_port_t port, uint32 *flags) 34466 { 34467 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3) 34468 uint64 r; 34469 soc_reg_t reg; 34470 34471 /* Make sure port module is initialized. */ 34472 PORT_INIT(unit); 34473 34474 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34475 if (SOC_IS_XGS3_SWITCH(unit)) { 34476 reg = IS_ST_PORT(unit, port) ? 34477 IEGR_PORT_L3UC_MODSr : EGR_PORT_L3UC_MODSr; 34478 } else { 34479 return BCM_E_UNAVAIL; 34480 } 34481 34482 if (!SOC_REG_IS_VALID(unit, reg)) { 34483 return BCM_E_UNAVAIL; 34484 } 34485 34486 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 0, &r)); 34487 34488 *flags = 0; 34489 34490 if (soc_reg64_field32_get(unit, reg, r, L3_UC_SA_DISABLEf)) { 34491 *flags |= BCM_PORT_L3_MODIFY_NO_SRCMAC; 34492 } 34493 34494 if (soc_reg64_field32_get(unit, reg, r, L3_UC_DA_DISABLEf)) { 34495 *flags |= BCM_PORT_L3_MODIFY_NO_DSTMAC; 34496 } 34497 34498 if (soc_reg64_field32_get(unit, reg, r, L3_UC_TTL_DISABLEf)) { 34499 *flags |= BCM_PORT_L3_MODIFY_NO_TTL; 34500 } 34501 34502 if (soc_reg64_field32_get(unit, reg, r, L3_UC_VLAN_DISABLEf)) { 34503 *flags |= BCM_PORT_L3_MODIFY_NO_VLAN; 34504 } 34505 34506 return BCM_E_NONE; 34507 #endif /* BCM_XGS3_SWITCH_SUPPORT && INCLUDE_L3 */ 34508 return BCM_E_UNAVAIL; 34509 } 34510 34511 /* 34512 * Function: 34513 * bcm_esw_port_ipmc_modify_set 34514 * Description: 34515 * Enable/Disable ingress port based L3 multicast packet operations. 34516 * If the reg EGR_IPMC_CFG2r does not contain DISABLE_TTL_CHECKf field, 34517 * and if flag is set , then return E_PARAM. 34518 * if flag is not set, then donot validate the field. 34519 * Parameters: 34520 * unit - Device number 34521 * port - Port number 34522 * flags - bitmap of the packet operations to be enabled or disabled. 34523 * Return Value: 34524 * BCM_E_XXX 34525 * Notes: 34526 * Available on XGS3 only. 34527 */ 34528 int 34529 bcm_esw_port_ipmc_modify_set(int unit, bcm_port_t port, uint32 flags) 34530 { 34531 #if defined(INCLUDE_L3) 34532 int field_count; 34533 soc_field_t fields[]={DISABLE_SA_REPLACEf, DISABLE_TTL_DECREMENTf, 34534 DISABLE_TTL_CHECKf}; 34535 uint32 values[]={0, 0, 0}; 34536 34537 /* Make sure port module is initialized. */ 34538 PORT_INIT(unit); 34539 34540 field_count = COUNTOF(fields); 34541 if (!soc_feature(unit, soc_feature_ip_mcast)) { 34542 return BCM_E_UNAVAIL; 34543 } 34544 34545 if (soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) { 34546 return BCM_E_UNAVAIL; 34547 } 34548 34549 if (!SOC_REG_IS_VALID(unit, EGR_IPMC_CFG2r) && 34550 !soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) { 34551 return BCM_E_UNAVAIL; 34552 } 34553 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34554 34555 #if defined(BCM_RAPTOR1_SUPPORT) 34556 if (SOC_IS_RAPTOR(unit)) { 34557 return BCM_E_UNAVAIL; 34558 } 34559 #endif /* BCM_RAPTOR1_SUPPORT */ 34560 34561 values[0] = (flags & BCM_PORT_IPMC_MODIFY_NO_SRCMAC) ? 1 : 0; 34562 values[1] = (flags & BCM_PORT_IPMC_MODIFY_NO_TTL) ? 1 : 0; 34563 values[2] = (flags & BCM_PORT_IPMC_CHECK_NO_TTL) ? 1 : 0; 34564 34565 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 34566 if (soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) { 34567 return soc_mem_fields32_modify(unit, EGR_IPMC_CFG2m, port, 34568 field_count, fields, values); 34569 } else 34570 #endif 34571 { 34572 if (values[2]) { 34573 if (!SOC_REG_FIELD_VALID(unit, EGR_IPMC_CFG2r, DISABLE_TTL_CHECKf)) { 34574 return BCM_E_PARAM; 34575 } 34576 } else { 34577 /* Donot include DISABLE_TTL_CHECKf for field validation in reg */ 34578 if (!SOC_REG_FIELD_VALID(unit, EGR_IPMC_CFG2r, DISABLE_TTL_CHECKf)) { 34579 field_count -= 1; 34580 } 34581 } 34582 34583 return soc_reg_fields32_modify(unit, EGR_IPMC_CFG2r, port, 34584 field_count, fields, values); 34585 } 34586 #else /* INCLUDE_L3 */ 34587 return (BCM_E_UNAVAIL); 34588 #endif /* INCLUDE_L3 */ 34589 } 34590 34591 /* 34592 * Function: 34593 * bcm_esw_port_ipmc_modify_get 34594 * Description: 34595 * Enable/Disable ingress port based L3 multicast packet operations. 34596 * Parameters: 34597 * unit - Device number 34598 * port - Port number 34599 * flags - (OUT) pointer to uint32 where bitmap of the current L3 packet 34600 * operations is returned. 34601 * Return Value: 34602 * BCM_E_NONE 34603 * BCM_E_UNAVAIL - Functionality not available 34604 * Notes: 34605 * Available on XGS3 only. 34606 */ 34607 int 34608 bcm_esw_port_ipmc_modify_get(int unit, bcm_port_t port, uint32 *flags) 34609 { 34610 #if defined(INCLUDE_L3) 34611 uint32 reg_val; 34612 34613 if (!soc_feature(unit, soc_feature_ip_mcast)) { 34614 return BCM_E_UNAVAIL; 34615 } 34616 34617 if (soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) { 34618 return BCM_E_UNAVAIL; 34619 } 34620 34621 if (!SOC_REG_IS_VALID(unit, EGR_IPMC_CFG2r) && 34622 !soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) { 34623 return BCM_E_UNAVAIL; 34624 } 34625 34626 #if defined(BCM_RAPTOR1_SUPPORT) 34627 if (SOC_IS_RAPTOR(unit)) { 34628 return BCM_E_UNAVAIL; 34629 } 34630 #endif /* BCM_RAPTOR1_SUPPORT */ 34631 34632 /* Make sure port module is initialized. */ 34633 PORT_INIT(unit); 34634 34635 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34636 if (NULL == flags) { 34637 return (BCM_E_PARAM); 34638 } 34639 34640 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 34641 if (soc_feature(unit, soc_feature_egr_ipmc_cfg2_is_memory)) { 34642 BCM_IF_ERROR_RETURN(READ_EGR_IPMC_CFG2m(unit, MEM_BLOCK_ANY, port, ®_val)); 34643 *flags = 0; 34644 if (soc_mem_field32_get(unit, EGR_IPMC_CFG2m, ®_val, DISABLE_SA_REPLACEf)) { 34645 *flags |= BCM_PORT_IPMC_MODIFY_NO_SRCMAC; 34646 } 34647 if (soc_mem_field32_get(unit, EGR_IPMC_CFG2m, ®_val, DISABLE_TTL_DECREMENTf)) { 34648 *flags |= BCM_PORT_IPMC_MODIFY_NO_TTL; 34649 } 34650 if (soc_mem_field32_get(unit, EGR_IPMC_CFG2m, ®_val, DISABLE_TTL_CHECKf)) { 34651 *flags |= BCM_PORT_IPMC_CHECK_NO_TTL; 34652 } 34653 } else 34654 #endif 34655 { 34656 BCM_IF_ERROR_RETURN(READ_EGR_IPMC_CFG2r(unit, port, ®_val)); 34657 34658 *flags = 0; 34659 if (soc_reg_field_get(unit, EGR_IPMC_CFG2r, reg_val, DISABLE_SA_REPLACEf)) { 34660 *flags |= BCM_PORT_IPMC_MODIFY_NO_SRCMAC; 34661 } 34662 if (soc_reg_field_get(unit, EGR_IPMC_CFG2r, reg_val, DISABLE_TTL_DECREMENTf)) { 34663 *flags |= BCM_PORT_IPMC_MODIFY_NO_TTL; 34664 } 34665 if (SOC_REG_FIELD_VALID(unit, EGR_IPMC_CFG2r, DISABLE_TTL_CHECKf)) { 34666 if (soc_reg_field_get(unit, EGR_IPMC_CFG2r, reg_val, 34667 DISABLE_TTL_CHECKf)) { 34668 *flags |= BCM_PORT_IPMC_CHECK_NO_TTL; 34669 } 34670 } 34671 } 34672 return (BCM_E_NONE); 34673 #else /* INCLUDE_L3 */ 34674 return (BCM_E_UNAVAIL); 34675 #endif /* INCLUDE_L3 */ 34676 } 34677 34678 /* 34679 * Function: 34680 * _bcm_port_force_forward_linkscan_handler 34681 * Description: 34682 * Called from linkscan handler when port toggles. 34683 * Adds/removes entry from LOCAL_SW_DISABLE_DEFAULT_PBM 34684 * Parameters: 34685 * unit - Device number 34686 * info - port info 34687 * Return Value: 34688 * BCM_E_XXX 34689 */ 34690 void 34691 _bcm_port_force_forward_linkscan_handler(int unit, 34692 bcm_port_t port, bcm_port_info_t *info) 34693 { 34694 bcm_port_t local_port; 34695 bcm_pbmp_t *sw_disable_pbmp_linkstate = 34696 p_linkstate[unit].sw_disable_pbmp_linkstate; 34697 int rv = BCM_E_NONE; 34698 34699 if (!info) { 34700 return; 34701 } 34702 34703 if (sw_disable_pbmp_linkstate == NULL) { 34704 return; 34705 } 34706 if (p_linkstate[unit].num_pbmp_entry) { 34707 PBMP_ALL_ITER(unit, local_port) { 34708 if (BCM_PBMP_MEMBER(sw_disable_pbmp_linkstate[local_port], 34709 port)) { 34710 if (info->linkstatus == BCM_PORT_LINK_STATUS_DOWN) { 34711 p_linkstate[unit].lock = 1; 34712 rv = bcm_esw_port_force_forward_mode_set(unit, local_port, 34713 port, BCM_PORT_FORCE_FORWARD_DISABLE); 34714 p_linkstate[unit].lock = 0; 34715 } else if (info->linkstatus == BCM_PORT_LINK_STATUS_UP) { 34716 p_linkstate[unit].lock = 1; 34717 rv = bcm_esw_port_force_forward_mode_set(unit, local_port, 34718 port, BCM_PORT_FORCE_FORWARD_ALL); 34719 p_linkstate[unit].lock = 0; 34720 } 34721 if (BCM_FAILURE(rv)) { 34722 LOG_WARN(BSL_LS_BCM_PORT, 34723 (BSL_META_U(unit, 34724 "bcm_esw_port_force_forward_mode_set failed for " 34725 "port %d, dest_port %d, link_state %d. rv = %d\n"), 34726 local_port, port, info->linkstatus, rv)); 34727 } 34728 } 34729 } 34730 } 34731 } 34732 34733 #if defined(BCM_TRIUMPH3_SUPPORT) 34734 /* 34735 * Function: 34736 * _bcm_port_force_forward_init 34737 * Purpose: 34738 * Initialize the port_forward entries 34739 * Parameters: 34740 * unit - SOC unit # 34741 * Returns: 34742 * BCM_E_XXX 34743 */ 34744 int 34745 _bcm_port_force_forward_init(int unit) 34746 { 34747 p_linkstate[unit].num_pbmp_entry = 0; 34748 34749 if (p_linkstate[unit].sw_disable_pbmp_linkstate != NULL) { 34750 sal_free(p_linkstate[unit].sw_disable_pbmp_linkstate); 34751 p_linkstate[unit].sw_disable_pbmp_linkstate = NULL; 34752 } 34753 34754 p_linkstate[unit].sw_disable_pbmp_linkstate = (bcm_pbmp_t*) sal_alloc( 34755 sizeof(bcm_pbmp_t) * SOC_MAX_NUM_PORTS, 34756 "SW disable pbmp linkstate"); 34757 if (p_linkstate[unit].sw_disable_pbmp_linkstate == NULL) { 34758 return BCM_E_MEMORY; 34759 } 34760 sal_memset(p_linkstate[unit].sw_disable_pbmp_linkstate, 0, 34761 sizeof(bcm_pbmp_t) * SOC_MAX_NUM_PORTS); 34762 return BCM_E_NONE; 34763 } 34764 34765 /* 34766 * Function: 34767 * _bcm_port_force_forward_deinit 34768 * Purpose: 34769 * Uninitialize the port_forward entries 34770 * Parameters: 34771 * unit - SOC unit # 34772 * Returns: 34773 * BCM_E_XXX 34774 */ 34775 int 34776 _bcm_port_force_forward_deinit(int unit) 34777 { 34778 if (p_linkstate[unit].sw_disable_pbmp_linkstate != NULL) { 34779 sal_free(p_linkstate[unit].sw_disable_pbmp_linkstate); 34780 p_linkstate[unit].sw_disable_pbmp_linkstate = NULL; 34781 p_linkstate[unit].num_pbmp_entry = 0; 34782 } 34783 return BCM_E_NONE; 34784 } 34785 34786 /* 34787 * Function: 34788 * _bcm_port_force_forward_add 34789 * Purpose: 34790 * Add/Deletes an entry into the port_forward DB. 34791 * Parameters: 34792 * unit - SOC unit # 34793 * local_port - Local port/Ingress port 34794 * egr_port - destination port. Set 0 to delete it. 34795 * Returns: 34796 * BCM_E_XXX 34797 */ 34798 int 34799 _bcm_port_force_forward_add(int unit, bcm_port_t local_port, 34800 bcm_port_t egr_port) 34801 { 34802 bcm_pbmp_t *sw_disable_pbmp_linkstate = 34803 p_linkstate[unit].sw_disable_pbmp_linkstate; 34804 if (!sw_disable_pbmp_linkstate) { 34805 return BCM_E_INTERNAL; 34806 } 34807 /* Lock is taken while calling bcm_esw_port_force_forward_mode_set 34808 * from the linkscan handler. It is not taken when called by user. 34809 * It is to ensure that only HW tables are written to and the 34810 * corresponding SW datastructure remains intact. 34811 */ 34812 if (p_linkstate[unit].lock) { 34813 return BCM_E_NONE; 34814 } 34815 BCM_PBMP_PORT_SET(sw_disable_pbmp_linkstate[local_port], egr_port); 34816 p_linkstate[unit].num_pbmp_entry++; 34817 return BCM_E_NONE; 34818 } 34819 34820 #ifdef BCM_WARM_BOOT_SUPPORT 34821 #define _BCM_PORT_WB_MAX_PBMP_V1_5 256 34822 34823 /* 34824 * Function: 34825 * _bcm_port_force_forward_sync 34826 * Purpose: 34827 * Sync port_forward DB to scache. 34828 * Parameters: 34829 * unit - Device unit number 34830 * scache_ptr - Scache pointer. 34831 * Returns: 34832 * BCM_E_XXX 34833 */ 34834 int 34835 _bcm_port_force_forward_sync(int unit, uint8 **scache_ptr) 34836 { 34837 bcm_port_t local_port, dst_port; 34838 bcm_pbmp_t *sw_disable_pbmp_linkstate = p_linkstate[unit].sw_disable_pbmp_linkstate; 34839 int port_count = 0, iter = 0; 34840 SHR_BITDCLNAME(port_bmp, _BCM_PORT_WB_MAX_PBMP_V1_5); 34841 34842 if ((scache_ptr == NULL) || (*scache_ptr == NULL)) { 34843 return BCM_E_INTERNAL; 34844 } 34845 34846 PBMP_ALL_ITER(unit, local_port) { 34847 port_count = 0; 34848 iter = 0; 34849 sal_memset(&port_bmp, 0, sizeof(port_bmp)); 34850 BCM_PBMP_COUNT(sw_disable_pbmp_linkstate[local_port], port_count); 34851 if (BCM_PBMP_NOT_NULL(sw_disable_pbmp_linkstate[local_port])) { 34852 BCM_PBMP_ITER(sw_disable_pbmp_linkstate[local_port], dst_port) { 34853 if(_SHR_BITDCLSIZE(_BCM_PORT_WB_MAX_PBMP_V1_5) < 34854 _SHR_BITDCLSIZE(dst_port)) { 34855 /* coverity[dead_error_line] */ 34856 continue; 34857 } 34858 /* coverity[overrun-local] */ 34859 SHR_BITSET(port_bmp, dst_port); 34860 iter++; 34861 if (iter >= port_count) { 34862 break; 34863 } 34864 } 34865 } 34866 sal_memcpy(*scache_ptr, port_bmp, sizeof(port_bmp)); 34867 *scache_ptr += sizeof(port_bmp); 34868 } 34869 34870 return BCM_E_NONE; 34871 } 34872 34873 /* 34874 * Function: 34875 * _bcm_port_force_forward_reinit 34876 * Purpose: 34877 * Retrieve port_forward from hardware and scache. 34878 * Parameters: 34879 * unit - Device unit number 34880 * scache_ptr - Scache pointer. 34881 * Returns: 34882 * BCM_E_XXX 34883 */ 34884 int 34885 _bcm_port_force_forward_reinit(int unit, uint8 **scache_ptr) 34886 { 34887 bcm_port_t local_port; 34888 int idx; 34889 bcm_pbmp_t *sw_disable_pbmp_linkstate = 34890 p_linkstate[unit].sw_disable_pbmp_linkstate; 34891 SHR_BITDCLNAME(port_bmp, _BCM_PORT_WB_MAX_PBMP_V1_5); 34892 34893 p_linkstate[unit].num_pbmp_entry = 0; 34894 if ((scache_ptr == NULL) || (*scache_ptr == NULL)) { 34895 return BCM_E_PARAM; 34896 } 34897 34898 sal_memset(&port_bmp, 0, sizeof(port_bmp)); 34899 sal_memset(sw_disable_pbmp_linkstate, 0, sizeof(bcm_pbmp_t)); 34900 PBMP_ALL_ITER(unit, local_port) { 34901 sal_memcpy(&port_bmp, *scache_ptr, sizeof(port_bmp)); 34902 *scache_ptr += sizeof(port_bmp); 34903 if (!SHR_BITNULL_RANGE(port_bmp, 0, _BCM_PORT_WB_MAX_PBMP_V1_5)){ 34904 int bitcount = 0; 34905 SHR_BITCOUNT_RANGE(port_bmp, bitcount, 0, _BCM_PORT_WB_MAX_PBMP_V1_5); 34906 for(idx = 0; (idx < _BCM_PORT_WB_MAX_PBMP_V1_5) && (bitcount); idx++) { 34907 if(SHR_BITGET(port_bmp, idx)) { 34908 BCM_PBMP_PORT_ADD(sw_disable_pbmp_linkstate[local_port], idx); 34909 p_linkstate[unit].num_pbmp_entry++; 34910 bitcount--; 34911 } 34912 } 34913 } 34914 } 34915 34916 return BCM_E_NONE; 34917 } 34918 34919 /* 34920 * Function: 34921 * _bcm_port_force_forward_scache_size 34922 * Purpose: 34923 * Get the size of the port_forward for scache 34924 * Parameters: 34925 * unit - Device unit number 34926 * size - size of scache 34927 * Returns: 34928 * BCM_E_XXX 34929 */ 34930 int 34931 _bcm_port_force_forward_scache_size(int unit, int *size) 34932 { 34933 int port_forward_size; 34934 int port_count = 0; 34935 bcm_port_t local_port; 34936 34937 if (!size) { 34938 return BCM_E_PARAM; 34939 } 34940 34941 /* We prefer to use a predefined size of _BCM_PORT_WB_MAX_PBMP_V1_5 34942 * for warmboot instead of bcm_pbmp_t. This is because of any future 34943 * increase in max port count for new devices which may change the 34944 * size of bcm_bcmp_t. 34945 */ 34946 PBMP_ALL_ITER(unit, local_port) { 34947 port_count++; 34948 } 34949 port_forward_size = SHR_BITALLOCSIZE(_BCM_PORT_WB_MAX_PBMP_V1_5) * port_count; 34950 34951 *size = port_forward_size; 34952 return BCM_E_NONE; 34953 } 34954 #endif /* BCM_WARM_BOOT_SUPPORT */ 34955 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/ 34956 34957 /* 34958 * Function: 34959 * bcm_port_force_forward_mode_set 34960 * Purpose: 34961 * Set egress override port mode. 34962 * Parameters: 34963 * unit - (IN) Unit number. 34964 * port - (IN) Port number 34965 * egr_port - (IN) Egress port number 34966 * flags - (IN) Force forward flags from PORT_FORCE_FORWARD_* 34967 * Returns: 34968 * BCM_E_xxx 34969 * Notes: 34970 */ 34971 int 34972 bcm_esw_port_force_forward_mode_set(int unit, bcm_port_t port, 34973 bcm_port_t egr_port, uint32 flags) 34974 { 34975 /* Make sure port module is initialized. */ 34976 PORT_INIT(unit); 34977 34978 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) \ 34979 || defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 34980 if (soc_feature(unit, soc_feature_force_forward)) { 34981 34982 int enable = FALSE; 34983 34984 if ((0 != (flags & BCM_PORT_FORCE_FORWARD_LOCAL) && 34985 !SOC_IS_TRX(unit))) { 34986 /* We don't support local only mode on pre-TRX devices */ 34987 return BCM_E_PARAM; 34988 } 34989 34990 if (0 != (flags & (BCM_PORT_FORCE_FORWARD_ALL | 34991 BCM_PORT_FORCE_FORWARD_LOCAL))) { 34992 enable = TRUE; 34993 } 34994 34995 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 34996 if (enable) { 34997 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, egr_port, 34998 &egr_port)); 34999 } 35000 35001 #if defined(BCM_TRIUMPH_SUPPORT) 35002 if (SOC_IS_TR_VL(unit)) { 35003 pbmp_t pbmp; 35004 uint64 val; 35005 int cpu_hg_index = 0; 35006 35007 COMPILER_64_SET(val, 0, 0); 35008 SOC_PBMP_CLEAR(pbmp); 35009 if (enable) { 35010 SOC_PBMP_PORT_SET(pbmp, egr_port); 35011 } 35012 if (soc_mem_is_valid(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm)) { 35013 local_sw_disable_default_pbm_entry_t entry; 35014 sal_memset(&entry, 0, sizeof(entry)); 35015 soc_mem_pbmp_field_set(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm, 35016 &entry, PORT_BITMAPf, &pbmp); 35017 BCM_IF_ERROR_RETURN 35018 (soc_mem_write(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm, 35019 MEM_BLOCK_ANY, port, &entry)); 35020 35021 cpu_hg_index = SOC_IS_KATANA2(unit) ? 35022 SOC_INFO(unit).cpu_hg_pp_port_index : 35023 SOC_INFO(unit).cpu_hg_index; 35024 if (IS_CPU_PORT(unit, port)) { 35025 BCM_IF_ERROR_RETURN 35026 (soc_mem_write(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm, 35027 MEM_BLOCK_ANY, cpu_hg_index, &entry)); 35028 } 35029 } else { 35030 #if defined(BCM_GREYHOUND2_SUPPORT) 35031 if (SOC_IS_GREYHOUND2(unit)) { 35032 uint64 val_hi, field_val; 35033 35034 COMPILER_64_SET(val_hi, 0, 0); 35035 COMPILER_64_SET(field_val, 35036 SOC_PBMP_WORD_GET(pbmp, 1), SOC_PBMP_WORD_GET(pbmp, 0)); 35037 soc_reg64_field_set(unit, LOCAL_SW_DISABLE_DEFAULT_PBM_LOr, 35038 &val, PORT_BITMAP_LOf, field_val); 35039 35040 COMPILER_64_SET(field_val, 35041 0, SOC_PBMP_WORD_GET(pbmp, 2)); 35042 soc_reg64_field_set(unit, LOCAL_SW_DISABLE_DEFAULT_PBM_HIr, 35043 &val_hi, PORT_BITMAP_LOf, field_val); 35044 35045 35046 if (IS_ST_PORT(unit, port)) { 35047 BCM_IF_ERROR_RETURN 35048 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, val)); 35049 BCM_IF_ERROR_RETURN 35050 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, val_hi)); 35051 } else { 35052 BCM_IF_ERROR_RETURN 35053 (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, val)); 35054 BCM_IF_ERROR_RETURN 35055 (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, val_hi)); 35056 if (IS_CPU_PORT(unit, port)) { 35057 BCM_IF_ERROR_RETURN 35058 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, val)); 35059 BCM_IF_ERROR_RETURN 35060 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, val_hi)); 35061 } 35062 } 35063 } else 35064 #endif /* BCM_GREYHOUND2_SUPPORT */ 35065 { 35066 soc_reg64_field32_set(unit 35067 , LOCAL_SW_DISABLE_DEFAULT_PBM_64r, 35068 &val, PORT_BITMAP_LOf, 35069 SOC_PBMP_WORD_GET(pbmp, 0)); 35070 if(!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 35071 !SOC_IS_GREYHOUND(unit)) { 35072 soc_reg64_field32_set(unit, 35073 LOCAL_SW_DISABLE_DEFAULT_PBM_64r, 35074 &val, PORT_BITMAP_HIf, 35075 SOC_PBMP_WORD_GET(pbmp, 1)); 35076 } 35077 35078 if (IS_ST_PORT(unit, port)) { 35079 BCM_IF_ERROR_RETURN 35080 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port, 35081 val)); 35082 } else { 35083 BCM_IF_ERROR_RETURN 35084 (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port, 35085 val)); 35086 if (IS_CPU_PORT(unit, port)) { 35087 BCM_IF_ERROR_RETURN 35088 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port, 35089 val)); 35090 } 35091 } 35092 } 35093 } 35094 } else 35095 #endif /* BCM_TRIUMPH_SUPPORT */ 35096 { 35097 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 35098 defined(BCM_SCORPION_SUPPORT) 35099 if ((SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || 35100 SOC_IS_SC_CQ(unit)) && IS_ST_PORT(unit, port)) { 35101 BCM_IF_ERROR_RETURN 35102 (WRITE_ILOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port, 35103 (enable) ? 1 << egr_port : 0)); 35104 } else 35105 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT || BCM_SCORPION_SUPPORT */ 35106 { 35107 BCM_IF_ERROR_RETURN 35108 (WRITE_LOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port, 35109 (enable) ? 1 << egr_port : 0)); 35110 } 35111 } 35112 35113 #if defined(BCM_TRIUMPH3_SUPPORT) 35114 if (soc_feature(unit, soc_feature_epc_linkflap_recover)) { 35115 int rv; 35116 rv = _bcm_port_force_forward_add(unit, port, 35117 (enable) ? egr_port : 0); 35118 if (BCM_FAILURE(rv)) { 35119 return rv; 35120 } 35121 } 35122 #endif /*defined(BCM_TRIUMPH3_SUPPORT)*/ 35123 35124 #if defined(BCM_TRX_SUPPORT) 35125 if (SOC_IS_TRX(unit)) { 35126 uint32 mode; 35127 35128 mode = (flags & BCM_PORT_FORCE_FORWARD_LOCAL) ? 35129 _BCM_TRX_PORT_FORCE_FORWARD_LOCAL : 35130 ((flags & BCM_PORT_FORCE_FORWARD_ALL) ? 35131 _BCM_TRX_PORT_FORCE_FORWARD_ALL : 35132 _BCM_TRX_PORT_FORCE_FORWARD_DISABLE); 35133 35134 return soc_reg_field32_modify(unit, LOCAL_SW_DISABLE_CTRLr, 35135 port, SW_MODEf, mode); 35136 } else 35137 #endif 35138 { 35139 return _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 35140 LOCAL_SW_DISABLEf, 35141 (enable) ? 1 : 0); 35142 } 35143 } 35144 #endif /* BCM_BRADLEY_SUPPORT || BCM_FIREBOLT2_SUPPORT \ 35145 || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 35146 return BCM_E_UNAVAIL; 35147 } 35148 35149 /* 35150 * Function: 35151 * bcm_port_force_forward_mode_get 35152 * Purpose: 35153 * Get egress override port. 35154 * Parameters: 35155 * unit - (IN) Unit number. 35156 * port - (IN) Port number 35157 * egr_port - (OUT) Egress port number 35158 * flags - (OUT) Force forward flags from PORT_FORCE_FORWARD_* 35159 * Returns: 35160 * BCM_E_xxx 35161 * Notes: 35162 */ 35163 int 35164 bcm_esw_port_force_forward_mode_get(int unit, bcm_port_t port, 35165 bcm_port_t *egr_port, uint32 *flags) 35166 { 35167 /* Make sure port module is initialized. */ 35168 PORT_INIT(unit); 35169 35170 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) \ 35171 || defined(BCM_TRX_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 35172 if (soc_feature(unit, soc_feature_force_forward)) { 35173 pbmp_t pbmp; 35174 uint32 egr_pbm; 35175 int ep, enabled; 35176 35177 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 35178 35179 #if defined(BCM_TRX_SUPPORT) 35180 if (SOC_IS_TRX(unit)) { 35181 uint32 val_32, mode; 35182 35183 BCM_IF_ERROR_RETURN 35184 (READ_LOCAL_SW_DISABLE_CTRLr(unit, port, &val_32)); 35185 mode = soc_reg_field_get(unit, LOCAL_SW_DISABLE_CTRLr, 35186 val_32, SW_MODEf); 35187 35188 if (_BCM_TRX_PORT_FORCE_FORWARD_LOCAL == mode) { 35189 *flags = BCM_PORT_FORCE_FORWARD_LOCAL; 35190 } else if (_BCM_TRX_PORT_FORCE_FORWARD_ALL == mode) { 35191 *flags = BCM_PORT_FORCE_FORWARD_ALL; 35192 } else { 35193 *flags = BCM_PORT_FORCE_FORWARD_DISABLE; 35194 } 35195 enabled = (BCM_PORT_FORCE_FORWARD_DISABLE != mode); 35196 } else 35197 #endif 35198 { 35199 BCM_IF_ERROR_RETURN 35200 (_bcm_esw_port_tab_get(unit, port, LOCAL_SW_DISABLEf, &enabled)); 35201 *flags = enabled ? BCM_PORT_FORCE_FORWARD_ALL : 35202 BCM_PORT_FORCE_FORWARD_DISABLE; 35203 } 35204 35205 if (enabled) { 35206 _bcm_gport_dest_t dest; 35207 bcm_module_t modid; 35208 int isGport = 0; 35209 35210 _bcm_gport_dest_t_init(&dest); 35211 #if defined(BCM_TRIUMPH_SUPPORT) 35212 if (SOC_IS_TR_VL(unit)) { 35213 uint64 val; 35214 35215 if (soc_mem_is_valid(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm)) { 35216 local_sw_disable_default_pbm_entry_t entry; 35217 BCM_IF_ERROR_RETURN 35218 (soc_mem_read(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm, 35219 MEM_BLOCK_ANY, port, &entry)); 35220 soc_mem_pbmp_field_get(unit, LOCAL_SW_DISABLE_DEFAULT_PBMm, 35221 &entry, PORT_BITMAPf, &pbmp); 35222 } else { 35223 #if defined(BCM_GREYHOUND2_SUPPORT) 35224 if (SOC_IS_GREYHOUND2(unit)) { 35225 BCM_IF_ERROR_RETURN 35226 (READ_LOCAL_SW_DISABLE_DEFAULT_PBM_LOr(unit, port, &val)); 35227 35228 egr_pbm = soc_reg64_field32_get(unit, 35229 LOCAL_SW_DISABLE_DEFAULT_PBM_LOr, 35230 val, OVER_LOf); 35231 SOC_PBMP_CLEAR(pbmp); 35232 SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm); 35233 35234 egr_pbm = soc_reg64_field32_get(unit, 35235 LOCAL_SW_DISABLE_DEFAULT_PBM_LOr, 35236 val, OVER_HIf); 35237 SOC_PBMP_WORD_SET(pbmp, 1, egr_pbm); 35238 35239 BCM_IF_ERROR_RETURN 35240 (READ_LOCAL_SW_DISABLE_DEFAULT_PBM_HIr(unit, port, &val)); 35241 35242 egr_pbm = soc_reg64_field32_get(unit, 35243 LOCAL_SW_DISABLE_DEFAULT_PBM_HIr, 35244 val, OVER_LOf); 35245 SOC_PBMP_WORD_SET(pbmp, 2, egr_pbm); 35246 } else 35247 #endif /* BCM_GREYHOUND2_SUPPORT */ 35248 { 35249 BCM_IF_ERROR_RETURN 35250 (READ_LOCAL_SW_DISABLE_DEFAULT_PBM_64r(unit, port, 35251 &val)); 35252 egr_pbm = 35253 soc_reg64_field32_get(unit, 35254 LOCAL_SW_DISABLE_DEFAULT_PBM_64r, 35255 val, PORT_BITMAP_LOf); 35256 SOC_PBMP_CLEAR(pbmp); 35257 SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm); 35258 if ((egr_pbm == 0) && 35259 (!SOC_IS_ENDURO(unit)) && (!SOC_IS_HURRICANEX(unit)) && 35260 (!SOC_IS_GREYHOUND(unit))) { 35261 egr_pbm = soc_reg64_field32_get 35262 (unit, LOCAL_SW_DISABLE_DEFAULT_PBM_64r, 35263 val, PORT_BITMAP_HIf); 35264 SOC_PBMP_WORD_SET(pbmp, 1, egr_pbm); 35265 } 35266 } 35267 } 35268 } else 35269 #endif /* BCM_TRIUMPH_SUPPORT */ 35270 if ((SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || 35271 SOC_IS_SC_CQ(unit)) && IS_ST_PORT(unit, port)) { 35272 BCM_IF_ERROR_RETURN 35273 (READ_ILOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port, &egr_pbm)); 35274 SOC_PBMP_CLEAR(pbmp); 35275 SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm); 35276 } else { 35277 BCM_IF_ERROR_RETURN 35278 (READ_LOCAL_SW_DISABLE_DEFAULT_PBMr(unit, port, &egr_pbm)); 35279 SOC_PBMP_CLEAR(pbmp); 35280 SOC_PBMP_WORD_SET(pbmp, 0, egr_pbm); 35281 } 35282 if (SOC_PBMP_IS_NULL(pbmp)) { 35283 return BCM_E_INTERNAL; 35284 } 35285 /* Convert port bitmap into port number */ 35286 SOC_PBMP_ITER(pbmp, ep) { 35287 break; 35288 } 35289 BCM_IF_ERROR_RETURN 35290 (bcm_esw_switch_control_get(unit, bcmSwitchUseGport, &isGport)); 35291 if (isGport) { 35292 /* ignore return code to suport devices w/out modid assigned */ 35293 (void)bcm_esw_stk_my_modid_get(unit, &modid); 35294 35295 if (BCM_MODID_INVALID == modid) { 35296 dest.gport_type = _SHR_GPORT_TYPE_DEVPORT; 35297 } else { 35298 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 35299 dest.modid = modid; 35300 } 35301 dest.port = ep; 35302 35303 BCM_IF_ERROR_RETURN 35304 (_bcm_esw_gport_construct(unit, &dest, &ep)); 35305 } 35306 *egr_port = ep; 35307 } 35308 return BCM_E_NONE; 35309 } 35310 #endif /* BCM_BRADLEY_SUPPORT || BCM_FIREBOLT2_SUPPORT \ 35311 || BCM_TRX_SUPPORT || BCM_RAVEN_SUPPORT */ 35312 return BCM_E_UNAVAIL; 35313 } 35314 35315 /* 35316 * Function: 35317 * bcm_esw_port_force_forward_set 35318 * Purpose: 35319 * This function allows packets to bypass the normal forwarding 35320 * logic and be sent out on a specific port instead. 35321 * Parameters: 35322 * unit - Device number 35323 * port - Port number 35324 * egr_port - Egress port number 35325 * enable - Bypass switching logic and forward to egr_port 35326 * Return Value: 35327 * BCM_E_NONE 35328 * BCM_E_UNAVAIL - Functionality not available 35329 * Notes: 35330 * All normal ingress processing (table lookups etc.) is still 35331 * performed and used for contructing the Higig header if the 35332 * forced egress port is a Higig port. 35333 */ 35334 int 35335 bcm_esw_port_force_forward_set(int unit, bcm_port_t port, 35336 bcm_port_t egr_port, int enable) 35337 { 35338 return bcm_esw_port_force_forward_mode_set(unit, port, egr_port, 35339 enable ? BCM_PORT_FORCE_FORWARD_ALL : 35340 BCM_PORT_FORCE_FORWARD_DISABLE); 35341 } 35342 35343 /* 35344 * Function: 35345 * bcm_esw_port_force_forward_get 35346 * Purpose: 35347 * Determine forced forwarding setting for a port. 35348 * Parameters: 35349 * unit - Device number 35350 * port - Port number 35351 * egr_port - (OUT) Egress port number 35352 * enabled - (OUT) Forced forwarding enabled 35353 * Return Value: 35354 * BCM_E_NONE 35355 * BCM_E_UNAVAIL - Functionality not available 35356 * Notes: 35357 * If the value of enabled is zero, the value of egr_port should 35358 * be ignored. 35359 */ 35360 int 35361 bcm_esw_port_force_forward_get(int unit, bcm_port_t port, 35362 bcm_port_t *egr_port, int *enabled) 35363 { 35364 uint32 flags; 35365 35366 /* Make sure port module is initialized. */ 35367 PORT_INIT(unit); 35368 35369 BCM_IF_ERROR_RETURN 35370 (bcm_esw_port_force_forward_mode_get(unit, port, egr_port, &flags)); 35371 35372 *enabled = (0 != (flags & (BCM_PORT_FORCE_FORWARD_ALL | 35373 BCM_PORT_FORCE_FORWARD_LOCAL))); 35374 return BCM_E_NONE; 35375 } 35376 35377 #if defined(INCLUDE_L3) 35378 /* 35379 * Function: 35380 * _bcm_esw_port_ecmp_dlb_link_status_set 35381 * Purpose: 35382 * Set ECMP DLB port link status. 35383 * Parameters: 35384 * unit - (IN) SOC unit number. 35385 * port - (IN) Port, not Gport. 35386 * status - (IN) ECMP DLB port link status. 35387 * Returns: 35388 * BCM_E_xxx 35389 */ 35390 int 35391 _bcm_esw_port_ecmp_dlb_link_status_set(int unit, bcm_port_t port, 35392 int status) 35393 { 35394 int rv = BCM_E_UNAVAIL; 35395 35396 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 35397 if (soc_feature(unit, soc_feature_ecmp_dlb_optimized)) { 35398 rv = _bcm_th2_l3_egress_ecmp_port_status_set(unit, port, status); 35399 } 35400 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */ 35401 35402 return rv; 35403 } 35404 #endif /* INCLUDE_L3 */ 35405 35406 35407 #if defined(INCLUDE_L3) 35408 /* 35409 * Function: 35410 * _bcm_esw_port_ecmp_dlb_link_status_get 35411 * Purpose: 35412 * Get ECMP DLB port link status. 35413 * Parameters: 35414 * unit - (IN) SOC unit number. 35415 * port - (IN) Port, not Gport. 35416 * status - (OUT) ECMP DLB port link status. 35417 * Returns: 35418 * BCM_E_xxx 35419 */ 35420 int 35421 _bcm_esw_port_ecmp_dlb_link_status_get(int unit, bcm_port_t port, 35422 int *status) 35423 { 35424 int rv = BCM_E_UNAVAIL; 35425 35426 if (status == NULL) { 35427 return BCM_E_PARAM; 35428 } 35429 35430 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 35431 if (soc_feature(unit, soc_feature_ecmp_dlb_optimized)) { 35432 rv = _bcm_th2_l3_egress_ecmp_port_status_get(unit, port, status); 35433 } 35434 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */ 35435 35436 return rv; 35437 } 35438 #endif /* INCLUDE_L3 */ 35439 35440 35441 35442 /* 35443 * Function: 35444 * _bcm_esw_port_err_sym_detect_set 35445 * Description: 35446 * Enable/Disable XAUI error symbol monitoring feature. 35447 * Parameters: 35448 * unit - Device number 35449 * port - Port number 35450 * enable - TRUE, enable |E| monitoring feature on the port. 35451 * FALSE, disable |E| monitoring feature on the port. 35452 * Return Value: 35453 * BCM_E_NONE 35454 * BCM_E_UNAVAIL - Functionality not available 35455 */ 35456 #ifdef BCM_XGS3_SWITCH_SUPPORT 35457 STATIC int 35458 _bcm_esw_port_err_sym_detect_set(int unit, bcm_port_t port, int enable) 35459 { 35460 int rv; 35461 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 35462 35463 LOG_INFO(BSL_LS_BCM_PORT, 35464 (BSL_META_U(unit, 35465 "_bcm_esw_port_err_sym_detect_set: u=%d p=%d enable=%d\n"), 35466 unit, port, enable)); 35467 35468 if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port) 35469 #ifdef BCM_GXPORT_SUPPORT 35470 || IS_GX_PORT(unit, port) 35471 #endif /* BCM_GXPORT_SUPPORT */ 35472 ) { 35473 PORT_LOCK(unit); 35474 rv = soc_xaui_err_sym_detect_set(unit, port, enable); 35475 PORT_UNLOCK(unit); 35476 } else { 35477 rv = BCM_E_UNAVAIL; 35478 } 35479 35480 35481 return rv; 35482 } 35483 #endif 35484 35485 /* 35486 * Function: 35487 * _bcm_esw_port_err_sym_detect_get 35488 * Description: 35489 * Get the status of XAUI error symbol monitoring feature. 35490 * Parameters: 35491 * unit - Device number 35492 * port - Port number 35493 * status - (OUT) TRUE, port is enabled, FALSE port is disabled. 35494 * Return Value: 35495 * BCM_E_NONE 35496 * BCM_E_UNAVAIL - Functionality not available 35497 */ 35498 #ifdef BCM_XGS3_SWITCH_SUPPORT 35499 STATIC int 35500 _bcm_esw_port_err_sym_detect_get(int unit, bcm_port_t port, int *status) 35501 { 35502 int rv; 35503 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 35504 35505 if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port) 35506 #ifdef BCM_GXPORT_SUPPORT 35507 || IS_GX_PORT(unit, port) 35508 #endif /* BCM_GXPORT_SUPPORT */ 35509 ) { 35510 PORT_LOCK(unit); 35511 rv = soc_xaui_err_sym_detect_get(unit, port, status); 35512 PORT_UNLOCK(unit); 35513 } else { 35514 rv = BCM_E_UNAVAIL; 35515 } 35516 35517 LOG_INFO(BSL_LS_BCM_PORT, 35518 (BSL_META_U(unit, 35519 "_bcm_esw_port_err_sym_detect_get: u=%d p=%d status=%d\n"), 35520 unit, port, *status)); 35521 35522 return rv; 35523 } 35524 #endif 35525 35526 /* 35527 * Function: 35528 * _bcm_esw_port_err_sym_count_get 35529 * Description: 35530 * Get the number of |E| symbol in XAUI lanes since last read. 35531 * The |E| symbol count is cleared on read. 35532 * Parameters: 35533 * unit - Device number 35534 * port - Port number 35535 * count - (OUT) Number of |E| error since last read. 35536 * Return Value: 35537 * BCM_E_NONE 35538 * BCM_E_UNAVAIL - Functionality not available 35539 * BCM_E_INIT - Error symbol detect feature is not enabled 35540 */ 35541 STATIC int 35542 _bcm_esw_port_err_sym_count_get(int unit, bcm_port_t port, int *count) 35543 { 35544 int rv; 35545 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 35546 35547 rv = BCM_E_UNAVAIL; 35548 35549 #ifdef BCM_XGS3_SWITCH_SUPPORT 35550 35551 if (IS_HG_PORT(unit, port) || IS_XE_PORT(unit, port) 35552 #ifdef BCM_GXPORT_SUPPORT 35553 || IS_GX_PORT(unit, port) 35554 #endif /* BCM_GXPORT_SUPPORT */ 35555 ) { 35556 PORT_LOCK(unit); 35557 rv = soc_xaui_err_sym_count(unit, port, count); 35558 PORT_UNLOCK(unit); 35559 } 35560 #endif 35561 35562 LOG_INFO(BSL_LS_BCM_PORT, 35563 (BSL_META_U(unit, 35564 "_bcm_esw_port_err_sym_count_get: u=%d p=%d count=%d\n"), 35565 unit, port, *count)); 35566 35567 return rv; 35568 } 35569 35570 STATIC int 35571 _bcm_esw_port_control_bridge_set(int unit, bcm_port_t port, int value) 35572 { 35573 int rv = BCM_E_UNAVAIL; 35574 35575 #ifdef BCM_TRIUMPH_SUPPORT 35576 if (SOC_IS_TR_VL(unit)) { 35577 bcm_pbmp_t pbmp; /* Port bitmap to update.*/ 35578 35579 if (IS_E_PORT(unit, port) 35580 || IS_CPU_PORT(unit, port) 35581 || IS_HG_PORT(unit, port)) { 35582 if (SOC_MEM_IS_VALID(unit, PORT_BRIDGE_BMAPm)) { 35583 port_bridge_bmap_entry_t entry; 35584 35585 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_BRIDGE_BMAPm, 35586 MEM_BLOCK_ANY, 0, &entry)); 35587 soc_mem_pbmp_field_get(unit, PORT_BRIDGE_BMAPm, &entry, 35588 BITMAPf, &pbmp); 35589 if (value && !SOC_PBMP_MEMBER(pbmp, port)) { 35590 SOC_PBMP_PORT_ADD(pbmp, port); 35591 } else if (!value && SOC_PBMP_MEMBER(pbmp, port)) { 35592 SOC_PBMP_PORT_REMOVE(pbmp, port); 35593 } else { 35594 return BCM_E_NONE; 35595 } 35596 soc_mem_pbmp_field_set(unit, PORT_BRIDGE_BMAPm, &entry, 35597 BITMAPf, &pbmp); 35598 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_BMAPm, 35599 MEM_BLOCK_ANY, 0, &entry)); 35600 } 35601 if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_BMAP_64r)) { 35602 uint64 buf64; /* Buffer for reg64 value. */ 35603 SOC_PBMP_CLEAR(pbmp); 35604 35605 BCM_IF_ERROR_RETURN 35606 (READ_PORT_BRIDGE_BMAP_64r(unit, &buf64)); 35607 35608 /* Set l3 port bitmap. */ 35609 SOC_PBMP_WORD_SET(pbmp, 0, 35610 soc_reg64_field32_get(unit, PORT_BRIDGE_BMAP_64r, 35611 buf64, BITMAP_LOf)); 35612 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 35613 !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) { 35614 SOC_PBMP_WORD_SET(pbmp, 1, 35615 soc_reg64_field32_get(unit, PORT_BRIDGE_BMAP_64r, 35616 buf64, BITMAP_HIf)); 35617 } 35618 35619 if (SOC_PBMP_MEMBER(pbmp, port) && value) { 35620 return BCM_E_NONE; 35621 } 35622 if (!SOC_PBMP_MEMBER(pbmp, port) && !value) { 35623 return BCM_E_NONE; 35624 } 35625 if (!SOC_PBMP_MEMBER(pbmp, port) && value) { 35626 SOC_PBMP_PORT_ADD(pbmp, port); 35627 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) { 35628 SOC_PBMP_PORT_REMOVE(pbmp, port); 35629 } 35630 35631 soc_reg64_field32_set(unit, PORT_BRIDGE_BMAP_64r, 35632 &buf64, BITMAP_LOf, 35633 SOC_PBMP_WORD_GET(pbmp, 0)); 35634 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 35635 !SOC_IS_GREYHOUND(unit)) { 35636 soc_reg64_field32_set(unit, PORT_BRIDGE_BMAP_64r, 35637 &buf64, BITMAP_HIf, 35638 SOC_PBMP_WORD_GET(pbmp, 1)); 35639 } 35640 35641 BCM_IF_ERROR_RETURN 35642 (WRITE_PORT_BRIDGE_BMAP_64r(unit, buf64)); 35643 } else if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_BMAP_LO_64r)) { 35644 /* 35645 * Both PORT_BRIDGE_BMAP_LO_64r and PORT_BRIDGE_BMAP_HI_64r 35646 * are expected been valid here. 35647 */ 35648 35649 uint64 fval64, rval64; 35650 uint32 t_port; 35651 soc_reg_t reg; 35652 pbmp_t curr_pbmp; 35653 35654 BCM_PBMP_CLEAR(curr_pbmp); 35655 COMPILER_64_ZERO(fval64); 35656 COMPILER_64_ZERO(rval64); 35657 35658 35659 if (port < 64) { 35660 reg = PORT_BRIDGE_BMAP_LO_64r; 35661 t_port = port; 35662 } else { 35663 reg = PORT_BRIDGE_BMAP_HI_64r; 35664 t_port = port - 64; 35665 } 35666 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64); 35667 if (BCM_SUCCESS(rv)) { 35668 fval64 = soc_reg64_field_get(unit, reg, 35669 rval64, BITMAPf); 35670 SOC_PBMP_WORD_SET(curr_pbmp, 0, 35671 COMPILER_64_LO(fval64)); 35672 SOC_PBMP_WORD_SET(curr_pbmp, 1, 35673 COMPILER_64_HI(fval64)); 35674 35675 if (value && !SOC_PBMP_MEMBER(curr_pbmp, t_port)) { 35676 SOC_PBMP_PORT_ADD(curr_pbmp, t_port); 35677 } else if (!value && SOC_PBMP_MEMBER(curr_pbmp, t_port)) { 35678 SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port); 35679 } else { 35680 return BCM_E_NONE; 35681 } 35682 35683 COMPILER_64_SET(fval64, 35684 SOC_PBMP_WORD_GET(curr_pbmp, 1), 35685 SOC_PBMP_WORD_GET(curr_pbmp, 0)); 35686 soc_reg64_field_set(unit, reg, &rval64, 35687 BITMAPf, fval64); 35688 rv = soc_reg_set(unit, reg, 35689 REG_PORT_ANY, 0, rval64); 35690 } 35691 } 35692 35693 } 35694 if (IS_HG_PORT(unit, port)) { 35695 35696 if (SOC_MEM_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAPm)) { 35697 port_bridge_mirror_bmap_entry_t entry; 35698 35699 SOC_IF_ERROR_RETURN(soc_mem_read(unit, PORT_BRIDGE_MIRROR_BMAPm, 35700 MEM_BLOCK_ANY, 0, &entry)); 35701 soc_mem_pbmp_field_get(unit, PORT_BRIDGE_MIRROR_BMAPm, &entry, 35702 BITMAPf, &pbmp); 35703 /* it might be different to port_tab, so don't return */ 35704 if (value && !SOC_PBMP_MEMBER(pbmp, port)) { 35705 SOC_PBMP_PORT_ADD(pbmp, port); 35706 } else if (!value && SOC_PBMP_MEMBER(pbmp, port)) { 35707 SOC_PBMP_PORT_REMOVE(pbmp, port); 35708 } 35709 soc_mem_pbmp_field_set(unit, PORT_BRIDGE_MIRROR_BMAPm, &entry, 35710 BITMAPf, &pbmp); 35711 SOC_IF_ERROR_RETURN(soc_mem_write(unit, PORT_BRIDGE_MIRROR_BMAPm, 35712 MEM_BLOCK_ANY, 0, &entry)); 35713 } 35714 35715 if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAP_64r)) { 35716 uint64 buf64; /* Buffer for reg64 value. */ 35717 SOC_PBMP_CLEAR(pbmp); 35718 35719 BCM_IF_ERROR_RETURN 35720 (READ_PORT_BRIDGE_MIRROR_BMAP_64r(unit, &buf64)); 35721 35722 /* Set port bitmap. */ 35723 SOC_PBMP_WORD_SET(pbmp, 0, 35724 soc_reg64_field32_get(unit, PORT_BRIDGE_MIRROR_BMAP_64r, 35725 buf64, BITMAP_LOf)); 35726 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 35727 !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) { 35728 SOC_PBMP_WORD_SET(pbmp, 1, 35729 soc_reg64_field32_get(unit, PORT_BRIDGE_MIRROR_BMAP_64r, 35730 buf64, BITMAP_HIf)); 35731 } 35732 35733 if (!SOC_PBMP_MEMBER(pbmp, port) && value) { 35734 SOC_PBMP_PORT_ADD(pbmp, port); 35735 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) { 35736 SOC_PBMP_PORT_REMOVE(pbmp, port); 35737 } else { 35738 return BCM_E_NONE; 35739 } 35740 35741 soc_reg64_field32_set(unit, PORT_BRIDGE_MIRROR_BMAP_64r, 35742 &buf64, BITMAP_LOf, SOC_PBMP_WORD_GET(pbmp, 0)); 35743 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 35744 !SOC_IS_GREYHOUND(unit) && !SOC_IS_GREYHOUND2(unit)) { 35745 soc_reg64_field32_set(unit, PORT_BRIDGE_MIRROR_BMAP_64r, 35746 &buf64, BITMAP_HIf, SOC_PBMP_WORD_GET(pbmp, 1)); 35747 } 35748 35749 BCM_IF_ERROR_RETURN 35750 (WRITE_PORT_BRIDGE_MIRROR_BMAP_64r(unit, buf64)); 35751 } else if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAP_LOr)) { 35752 /* 35753 * Both PORT_BRIDGE_MIRROR_BMAP_LOr and PORT_BRIDGE_MIRROR_BMAP_HIr 35754 * are expected been valid here. 35755 */ 35756 35757 uint64 fval64, rval64; 35758 uint32 t_port; 35759 soc_reg_t reg; 35760 pbmp_t curr_pbmp; 35761 35762 BCM_PBMP_CLEAR(curr_pbmp); 35763 COMPILER_64_ZERO(fval64); 35764 COMPILER_64_ZERO(rval64); 35765 35766 35767 if (port < 64) { 35768 reg = PORT_BRIDGE_MIRROR_BMAP_LOr; 35769 t_port = port; 35770 } else { 35771 reg = PORT_BRIDGE_MIRROR_BMAP_HIr; 35772 t_port = port - 64; 35773 } 35774 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64); 35775 if (BCM_SUCCESS(rv)) { 35776 fval64 = soc_reg64_field_get(unit, reg, 35777 rval64, BITMAPf); 35778 SOC_PBMP_WORD_SET(curr_pbmp, 0, 35779 COMPILER_64_LO(fval64)); 35780 SOC_PBMP_WORD_SET(curr_pbmp, 1, 35781 COMPILER_64_HI(fval64)); 35782 35783 if (value && !SOC_PBMP_MEMBER(curr_pbmp, t_port)) { 35784 SOC_PBMP_PORT_ADD(curr_pbmp, t_port); 35785 } else if (!value && SOC_PBMP_MEMBER(curr_pbmp, t_port)) { 35786 SOC_PBMP_PORT_REMOVE(curr_pbmp, t_port); 35787 } else { 35788 return BCM_E_NONE; 35789 } 35790 35791 COMPILER_64_SET(fval64, 35792 SOC_PBMP_WORD_GET(curr_pbmp, 1), 35793 SOC_PBMP_WORD_GET(curr_pbmp, 0)); 35794 soc_reg64_field_set(unit, reg, &rval64, 35795 BITMAPf, fval64); 35796 rv = soc_reg_set(unit, reg, 35797 REG_PORT_ANY, 0, rval64); 35798 } 35799 } 35800 } 35801 35802 /* Allow to set bridging on higig ports as well */ 35803 return _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 35804 PORT_BRIDGEf, (value) ? 1 : 0); 35805 } 35806 #endif /* BCM_TRIUMPH_SUPPORT */ 35807 35808 if (SOC_IS_XGS3_SWITCH(unit)) { 35809 /* Allow to set bridging on higig ports as well */ 35810 rv =_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 35811 PORT_BRIDGEf, (value) ? 1 : 0); 35812 BCM_IF_ERROR_RETURN(rv); 35813 35814 if (IS_E_PORT(unit, port) || IS_CPU_PORT(unit, port)) { 35815 35816 #if defined(BCM_RAPTOR_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 35817 defined(BCM_SCORPION_SUPPORT) 35818 if (soc_feature(unit, soc_feature_src_trunk_port_bridge)) { 35819 bcm_pbmp_t pbmp; /* Port bitmap to update.*/ 35820 uint32 port_bridge_map; 35821 #if defined (BCM_RAPTOR_SUPPORT) 35822 uint32 port_bridge_map_hi; 35823 #endif 35824 35825 SOC_PBMP_CLEAR(pbmp); 35826 BCM_IF_ERROR_RETURN 35827 (READ_PORT_BRIDGE_BMAPr(unit, &port_bridge_map)); 35828 35829 SOC_PBMP_WORD_SET(pbmp, 0, 35830 soc_reg_field_get(unit, PORT_BRIDGE_BMAPr, 35831 port_bridge_map, BITMAPf)); 35832 #if defined (BCM_RAPTOR_SUPPORT) 35833 if (soc_feature(unit, soc_feature_register_hi)) { 35834 BCM_IF_ERROR_RETURN 35835 (READ_PORT_BRIDGE_BMAP_HIr(unit, 35836 &port_bridge_map_hi)); 35837 SOC_PBMP_WORD_SET(pbmp, 1, 35838 soc_reg_field_get(unit, PORT_BRIDGE_BMAP_HIr, 35839 port_bridge_map_hi, BITMAPf)); 35840 } 35841 #endif 35842 if (!SOC_PBMP_MEMBER(pbmp, port) && value) { 35843 SOC_PBMP_PORT_ADD(pbmp, port); 35844 soc_reg_field_set(unit, PORT_BRIDGE_BMAPr, 35845 &port_bridge_map, BITMAPf, 35846 SOC_PBMP_WORD_GET(pbmp, 0)); 35847 BCM_IF_ERROR_RETURN 35848 (WRITE_PORT_BRIDGE_BMAPr(unit, port_bridge_map)); 35849 #if defined (BCM_RAPTOR_SUPPORT) 35850 35851 if (soc_feature(unit, soc_feature_register_hi)) { 35852 soc_reg_field_set(unit, PORT_BRIDGE_BMAP_HIr, 35853 &port_bridge_map_hi, BITMAPf, 35854 SOC_PBMP_WORD_GET(pbmp, 1)); 35855 BCM_IF_ERROR_RETURN 35856 (WRITE_PORT_BRIDGE_BMAP_HIr(unit, 35857 port_bridge_map_hi)); 35858 } 35859 #endif 35860 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) { 35861 SOC_PBMP_PORT_REMOVE(pbmp, port); 35862 soc_reg_field_set(unit, PORT_BRIDGE_BMAPr, 35863 &port_bridge_map, BITMAPf, 35864 SOC_PBMP_WORD_GET(pbmp, 0)); 35865 BCM_IF_ERROR_RETURN 35866 (WRITE_PORT_BRIDGE_BMAPr(unit, port_bridge_map)); 35867 #if defined (BCM_RAPTOR_SUPPORT) 35868 if (soc_feature(unit, soc_feature_register_hi)) { 35869 soc_reg_field_set(unit, PORT_BRIDGE_BMAP_HIr, 35870 &port_bridge_map_hi, BITMAPf, 35871 SOC_PBMP_WORD_GET(pbmp, 1)); 35872 BCM_IF_ERROR_RETURN 35873 (WRITE_PORT_BRIDGE_BMAP_HIr(unit, 35874 port_bridge_map_hi)); 35875 } 35876 #endif 35877 } 35878 } 35879 #endif /* BCM_RAPTOR_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 35880 35881 } else if (IS_HG_PORT(unit, port)) { 35882 #ifdef BCM_SCORPION_SUPPORT 35883 if (SOC_REG_IS_VALID(unit, PORT_BRIDGE_MIRROR_BMAPr)) { 35884 bcm_pbmp_t pbmp; /* Port bitmap to update.*/ 35885 uint32 port_bridge_mirror_map; 35886 35887 SOC_PBMP_CLEAR(pbmp); 35888 BCM_IF_ERROR_RETURN(READ_PORT_BRIDGE_MIRROR_BMAPr(unit, 35889 &port_bridge_mirror_map)); 35890 SOC_PBMP_WORD_SET(pbmp, 0, 35891 soc_reg_field_get(unit, PORT_BRIDGE_MIRROR_BMAPr, 35892 port_bridge_mirror_map, BITMAPf)); 35893 35894 if (!SOC_PBMP_MEMBER(pbmp, port) && value) { 35895 SOC_PBMP_PORT_ADD(pbmp, port); 35896 } else if (SOC_PBMP_MEMBER(pbmp, port) && !value) { 35897 SOC_PBMP_PORT_REMOVE(pbmp, port); 35898 } else { 35899 return BCM_E_NONE; 35900 } 35901 35902 soc_reg_field_set(unit, PORT_BRIDGE_MIRROR_BMAPr, 35903 &port_bridge_mirror_map, BITMAPf, 35904 SOC_PBMP_WORD_GET(pbmp, 0)); 35905 BCM_IF_ERROR_RETURN(WRITE_PORT_BRIDGE_MIRROR_BMAPr(unit, 35906 port_bridge_mirror_map)); 35907 } 35908 #endif /* BCM_SCORPION_SUPPORT */ 35909 } 35910 } 35911 return rv; 35912 } 35913 35914 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX) 35915 STATIC int 35916 _bcm_esw_port_regex_control_set(int unit, bcm_gport_t gport, 35917 int udp, int tcp, int enable) 35918 { 35919 int vp = -1; 35920 bcm_port_t local_port; 35921 source_vp_entry_t svp_entry; 35922 source_trunk_map_table_entry_t stm_entry; 35923 ft_dst_port_config_entry_t ftdcfg; 35924 bcm_module_t my_modid; 35925 int index; 35926 int rv; 35927 35928 if (!soc_feature(unit, soc_feature_regex)) { 35929 return BCM_E_UNAVAIL; 35930 } 35931 35932 enable = !!enable; 35933 35934 if (BCM_GPORT_IS_MIM_PORT(gport)) { 35935 vp = BCM_GPORT_MIM_PORT_ID_GET(gport); 35936 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 35937 return BCM_E_NOT_FOUND; 35938 } 35939 } else if (BCM_GPORT_IS_MPLS_PORT(gport)) { 35940 vp = BCM_GPORT_MPLS_PORT_ID_GET(gport); 35941 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 35942 return BCM_E_NOT_FOUND; 35943 } 35944 } else if (BCM_GPORT_IS_WLAN_PORT(gport)) { 35945 vp = BCM_GPORT_WLAN_PORT_ID_GET(gport); 35946 } 35947 35948 if (vp >= 0) { 35949 SOC_IF_ERROR_RETURN 35950 (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry)); 35951 if (tcp) { 35952 soc_SOURCE_VPm_field32_set(unit, &svp_entry, 35953 DPI_TCP_CREATE_ENf, enable); 35954 tcp = enable; 35955 } else { 35956 tcp = soc_SOURCE_VPm_field32_get(unit, &svp_entry, 35957 DPI_TCP_CREATE_ENf); 35958 } 35959 if (udp) { 35960 soc_SOURCE_VPm_field32_set(unit, &svp_entry, 35961 DPI_UDP_CREATE_ENf, enable); 35962 udp = enable; 35963 } else { 35964 udp = soc_SOURCE_VPm_field32_get(unit, &svp_entry, 35965 DPI_UDP_CREATE_ENf); 35966 } 35967 if (tcp + udp) { 35968 soc_SOURCE_VPm_field32_set(unit, &svp_entry, DPI_ENABLEf, 1); 35969 } else { 35970 soc_SOURCE_VPm_field32_set(unit, &svp_entry, DPI_ENABLEf, 0); 35971 } 35972 BCM_IF_ERROR_RETURN(WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry)); 35973 } else { 35974 BCM_IF_ERROR_RETURN( 35975 _bcm_esw_port_gport_validate(unit, gport, &local_port)); 35976 /* Port sanity check. */ 35977 if (!SOC_PORT_ADDRESSABLE(unit, local_port)) { 35978 return (BCM_E_PORT); 35979 } 35980 35981 /* Get local module id. */ 35982 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 35983 35984 soc_mem_lock(unit, SOURCE_TRUNK_MAP_TABLEm); 35985 35986 /* Calculate table index. */ 35987 rv = _bcm_esw_src_mod_port_table_index_get(unit, my_modid, 35988 local_port, &index); 35989 35990 if(BCM_FAILURE(rv)) { 35991 soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm); 35992 return rv; 35993 } 35994 35995 rv = READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, 35996 index, &stm_entry); 35997 if(BCM_FAILURE(rv)) { 35998 soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm); 35999 return rv; 36000 } 36001 36002 if (tcp) { 36003 soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, 36004 DPI_TCP_CREATE_ENf, enable); 36005 tcp = enable; 36006 } else { 36007 tcp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry, 36008 DPI_TCP_CREATE_ENf); 36009 } 36010 if (udp) { 36011 soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, 36012 DPI_UDP_CREATE_ENf, enable); 36013 udp = enable; 36014 } else { 36015 udp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry, 36016 DPI_UDP_CREATE_ENf); 36017 } 36018 if (tcp + udp) { 36019 soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, DPI_ENABLEf, 1); 36020 } else { 36021 soc_SOURCE_TRUNK_MAP_TABLEm_field32_set(unit, &stm_entry, DPI_ENABLEf, 0); 36022 } 36023 36024 rv = WRITE_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ALL, 36025 index, &stm_entry); 36026 36027 soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm); 36028 if(BCM_FAILURE(rv)) { 36029 return rv; 36030 } 36031 36032 SOC_IF_ERROR_RETURN(READ_FT_DST_PORT_CONFIGm(unit, MEM_BLOCK_ANY, 36033 local_port, &ftdcfg)); 36034 soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg, 36035 DPI_TCP_CREATE_ENf, !!tcp); 36036 soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg, 36037 DPI_UDP_CREATE_ENf, !!udp); 36038 if (tcp + udp) { 36039 soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg, DPI_ENABLEf, 1); 36040 } else { 36041 soc_FT_DST_PORT_CONFIGm_field32_set(unit, &ftdcfg, DPI_ENABLEf, 0); 36042 } 36043 SOC_IF_ERROR_RETURN(WRITE_FT_DST_PORT_CONFIGm(unit, MEM_BLOCK_ANY, 36044 local_port, &ftdcfg)); 36045 } 36046 return BCM_E_NONE; 36047 } 36048 36049 STATIC int _bcm_esw_port_regex_control_get(int unit, bcm_gport_t gport, 36050 int *udp, int *tcp, int *enable) 36051 { 36052 int vp = -1; 36053 bcm_port_t local_port; 36054 source_vp_entry_t svp_entry; 36055 source_trunk_map_table_entry_t stm_entry; 36056 ft_dst_port_config_entry_t ftdcfg; 36057 bcm_module_t my_modid; 36058 int index; 36059 36060 if (!soc_feature(unit, soc_feature_regex)) { 36061 return BCM_E_UNAVAIL; 36062 } 36063 36064 if (BCM_GPORT_IS_MIM_PORT(gport)) { 36065 vp = BCM_GPORT_MIM_PORT_ID_GET(gport); 36066 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 36067 return BCM_E_NOT_FOUND; 36068 } 36069 } else if (BCM_GPORT_IS_MPLS_PORT(gport)) { 36070 vp = BCM_GPORT_MPLS_PORT_ID_GET(gport); 36071 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 36072 return BCM_E_NOT_FOUND; 36073 } 36074 } else if (BCM_GPORT_IS_WLAN_PORT(gport)) { 36075 vp = BCM_GPORT_WLAN_PORT_ID_GET(gport); 36076 } 36077 36078 if (vp >= 0) { 36079 SOC_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry)); 36080 *tcp = soc_SOURCE_VPm_field32_get(unit, &svp_entry, DPI_TCP_CREATE_ENf); 36081 *udp = soc_SOURCE_VPm_field32_get(unit, &svp_entry, DPI_UDP_CREATE_ENf); 36082 *enable = soc_SOURCE_VPm_field32_get(unit, &svp_entry, DPI_ENABLEf); 36083 } else { 36084 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, gport, &local_port)); 36085 /* Port sanity check. */ 36086 if (!SOC_PORT_ADDRESSABLE(unit, local_port)) { 36087 return (BCM_E_PORT); 36088 } 36089 36090 /* Get local module id. */ 36091 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 36092 36093 /* Calculate table index. */ 36094 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, my_modid, 36095 local_port, &index)); 36096 36097 BCM_IF_ERROR_RETURN(READ_SOURCE_TRUNK_MAP_TABLEm(unit, MEM_BLOCK_ANY, 36098 index, &stm_entry)); 36099 *tcp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry, 36100 DPI_TCP_CREATE_ENf); 36101 *udp = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, &stm_entry, 36102 DPI_UDP_CREATE_ENf); 36103 SOC_IF_ERROR_RETURN(READ_FT_DST_PORT_CONFIGm(unit, MEM_BLOCK_ANY, 36104 local_port, &ftdcfg)); 36105 *enable = soc_FT_DST_PORT_CONFIGm_field32_get(unit, &ftdcfg, DPI_ENABLEf); 36106 } 36107 return BCM_E_NONE; 36108 } 36109 #endif 36110 36111 #if defined(BCM_SHADOW_SUPPORT) 36112 STATIC int 36113 _bcm_port_type_shadow_support (int unit, bcm_port_t port, 36114 bcm_port_control_t type) 36115 { 36116 LOG_INFO(BSL_LS_BCM_PORT, 36117 (BSL_META_U(unit, 36118 "_bcm_port_type_shadow_support : u=%d p=%d type=%d\n"), 36119 unit, port, (int)type)); 36120 36121 switch (type) 36122 { 36123 /* Shadoow supported port control types */ 36124 case bcmPortControlManagementPacketIp6Reserved: 36125 case bcmPortControlManagementPacketIp4Reserved: 36126 case bcmPortControlManagementPacketLinkConstrained: 36127 case bcmPortControlManagementPacketGarp: 36128 case bcmPortControlManagementPacketCos: 36129 case bcmPortControlManagementPacketColor: 36130 case bcmPortControlTaggedL3PacketPktPri: 36131 case bcmPortControlTaggedMPLSPacketPktPri: 36132 case bcmPortControlTaggedMPLSL3PacketPktPri: 36133 case bcmPortControlRxEnable: 36134 case bcmPortControlTxEnable: 36135 case bcmPortControlPFCEthertype: 36136 case bcmPortControlPFCOpcode: 36137 case bcmPortControlPFCReceive: 36138 case bcmPortControlPFCTransmit: 36139 case bcmPortControlPFCClasses: 36140 case bcmPortControlPFCPassFrames: 36141 case bcmPortControlPFCDestMacOui: 36142 case bcmPortControlPFCDestMacNonOui: 36143 case bcmPortControlPFCRefreshTime: 36144 case bcmPortControlPFCXOffTime: 36145 case bcmPortControlEEETransmitWakeTime: 36146 case bcmPortControlEEEReceiveWakeTime: 36147 case bcmPortControlEEETransmitSleepTime: 36148 case bcmPortControlEEEReceiveSleepTime: 36149 case bcmPortControlEEETransmitQuietTime: 36150 case bcmPortControlEEEReceiveQuietTime: 36151 case bcmPortControlEEETransmitRefreshTime: 36152 case bcmPortControlEEEEnable: 36153 case bcmPortControlEEETransmitIdleTime: 36154 case bcmPortControlEEETransmitEventCount: 36155 case bcmPortControlEEETransmitDuration: 36156 case bcmPortControlEEEReceiveEventCount: 36157 case bcmPortControlEEEReceiveDuration: 36158 case bcmPortControlEEETransmitIdleTimeHund: 36159 case bcmPortControlEEETransmitWakeTimeHund: 36160 case bcmPortControlEEETransmitMinLPITime: 36161 case bcmPortControlEEETransmitMinLPITimeHund: 36162 if (IS_IL_PORT(unit, port)) { /* No support for IL port type */ 36163 return FALSE; 36164 } 36165 /* Fall through */ 36166 case bcmPortControlPrbsMode: 36167 case bcmPortControlPrbsPolynomial: 36168 case bcmPortControlPrbsTxEnable: 36169 case bcmPortControlPrbsRxEnable: 36170 case bcmPortControlPrbsTxInvertData: 36171 case bcmPortControlPrbsRxStatus: 36172 case bcmPortControlLanes: 36173 return TRUE; 36174 36175 default: 36176 return FALSE; 36177 } 36178 } 36179 #endif /* BCM_SHADOW_SUPPORT */ 36180 36181 static int 36182 _bcm_esw_mac_rx_control(int unit, bcm_port_t port, uint8 optype, int *enable) 36183 { 36184 int rv = BCM_E_NONE; 36185 36186 if (SOC_USE_PORTCTRL(unit)) { 36187 return(bcmi_esw_portctrl_mac_rx_control(unit, port, optype, enable)); 36188 } else { 36189 PORT_LOCK(unit); 36190 if (optype) { /* get */ 36191 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 36192 SOC_MAC_CONTROL_RX_SET, enable); 36193 } else { /* set */ 36194 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 36195 SOC_MAC_CONTROL_RX_SET, *enable); 36196 } 36197 PORT_UNLOCK(unit); 36198 } 36199 return rv; 36200 } 36201 /* 36202 * Function: 36203 * bcm_esw_port_enqueue_set 36204 * Description: 36205 * This function enable and disable the enqueuing 36206 * packets on a port 36207 * Parameters: 36208 * unit - (IN) Device number 36209 * port - (IN) Port to resolve 36210 * enable - (IN) TRUE to enable enqueuing 36211 * FALSE to disable enqueuing 36212 * Return Value: 36213 * BCM_E_XXX 36214 */ 36215 36216 static int 36217 bcm_esw_port_enqueue_set(int unit, bcm_port_t port,int enable) 36218 { 36219 int rv = BCM_E_NONE; 36220 36221 /* Make sure port module is initialized. */ 36222 PORT_INIT(unit); 36223 #ifdef BCM_HELIX5_SUPPORT 36224 if (SOC_IS_HELIX5(unit)) { 36225 BCM_IF_ERROR_RETURN 36226 (_bcm_hx5_port_enqueue_set(unit, port, enable)); 36227 } else 36228 #endif 36229 #ifdef BCM_TRIDENT3_SUPPORT 36230 if (SOC_IS_TRIDENT3X(unit)) { 36231 int link; 36232 rv = bcm_esw_port_link_status_get(unit, port, &link); 36233 if (BCM_FAILURE(rv)) { 36234 return rv; 36235 } 36236 if (link == BCM_PORT_LINK_STATUS_UP) { 36237 /* FALSE to disable enqueuing and MMU cells drain */ 36238 PORT_LOCK(unit); 36239 if (SOC_USE_PORTCTRL(unit)) { 36240 rv = bcmi_esw_portctrl_mac_enable_set(unit, port, enable); 36241 } else { 36242 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, enable); 36243 } 36244 if (BCM_FAILURE(rv)) { 36245 PORT_UNLOCK(unit); 36246 return rv; 36247 } 36248 PORT_UNLOCK(unit); 36249 } 36250 } else 36251 #endif 36252 #ifdef BCM_TOMAHAWK_SUPPORT 36253 if (SOC_IS_TOMAHAWKX(unit)) { 36254 int link; 36255 rv = bcm_esw_port_link_status_get(unit, port, &link); 36256 if (BCM_FAILURE(rv)) { 36257 return rv; 36258 } 36259 if (link == BCM_PORT_LINK_STATUS_UP || SOC_FAST_REBOOT(unit)) { 36260 /* FALSE to disable enqueuing and MMU cells drain */ 36261 PORT_LOCK(unit); 36262 if (SOC_USE_PORTCTRL(unit)) { 36263 rv = bcmi_esw_portctrl_mac_enable_set(unit, port, enable); 36264 } else { 36265 rv = MAC_ENABLE_SET(PORT(unit, port).p_mac, unit, port, enable); 36266 } 36267 if (BCM_FAILURE(rv)) { 36268 PORT_UNLOCK(unit); 36269 return rv; 36270 } 36271 PORT_UNLOCK(unit); 36272 } 36273 } else 36274 #endif 36275 #ifdef BCM_MONTEREY_SUPPORT 36276 if (SOC_IS_MONTEREY(unit)) { 36277 BCM_IF_ERROR_RETURN 36278 (_bcm_mn_port_enqueue_set(unit,port,enable)); 36279 } else 36280 #endif 36281 #ifdef BCM_APACHE_SUPPORT 36282 if (SOC_IS_APACHE(unit)) { 36283 BCM_IF_ERROR_RETURN 36284 (_bcm_ap_port_enqueue_set(unit,port,enable)); 36285 } else 36286 #endif 36287 #ifdef BCM_TRIDENT2_SUPPORT 36288 if (SOC_IS_TD2_TT2(unit)) { 36289 BCM_IF_ERROR_RETURN 36290 (_bcm_td2_port_enqueue_set(unit,port,enable)); 36291 } else 36292 #endif 36293 #ifdef BCM_TRIDENT_SUPPORT 36294 if (SOC_IS_TD_TT(unit)) { 36295 BCM_IF_ERROR_RETURN 36296 (_bcm_td_port_enqueue_set(unit,port,enable)); 36297 } else 36298 #endif 36299 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) 36300 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_HELIX4(unit)) { 36301 BCM_IF_ERROR_RETURN 36302 (_bcm_tr3_port_enqueue_set(unit,port,enable)); 36303 } else 36304 #endif /* BCM_TRIUMPH3_SUPPORT */ 36305 #ifdef BCM_KATANA2_SUPPORT 36306 if (SOC_IS_KATANA2(unit)) { 36307 BCM_IF_ERROR_RETURN 36308 (_bcm_kt2_port_enqueue_set(unit,port,enable)); 36309 } else 36310 #endif 36311 { 36312 return BCM_E_UNAVAIL; 36313 } 36314 return rv; 36315 } 36316 36317 /* 36318 * Function: 36319 * bcm_esw_port_enqueue_get 36320 * Description: 36321 * This function get enqueuing state 36322 * packets on a port 36323 * Parameters: 36324 * unit - (IN) Device number 36325 * port - (IN) Port to resolve 36326 * enable - (OUT) TRUE to when enqueuing is enabled 36327 * FALSE to when enqueuing is disabled 36328 * Return Value: 36329 * BCM_E_XXX 36330 */ 36331 static int 36332 bcm_esw_port_enqueue_get(int unit, bcm_port_t port, int *enable) 36333 { 36334 int rv = BCM_E_NONE; 36335 36336 /* Make sure port module is initialized. */ 36337 PORT_INIT(unit); 36338 #ifdef BCM_HELIX5_SUPPORT 36339 if (SOC_IS_HELIX5(unit)) { 36340 BCM_IF_ERROR_RETURN 36341 (_bcm_hx5_port_enqueue_get(unit, port, enable)); 36342 } else 36343 #endif 36344 #ifdef BCM_TRIDENT3_SUPPORT 36345 if (SOC_IS_TRIDENT3X(unit)) { 36346 return BCM_E_UNAVAIL; 36347 } else 36348 #endif 36349 #ifdef BCM_TOMAHAWK_SUPPORT 36350 if (SOC_IS_TOMAHAWKX(unit)) { 36351 BCM_IF_ERROR_RETURN 36352 (_bcm_th_port_enqueue_get(unit, port, enable)); 36353 } else 36354 #endif 36355 #ifdef BCM_APACHE_SUPPORT 36356 if (SOC_IS_APACHE(unit)) { 36357 BCM_IF_ERROR_RETURN 36358 (_bcm_ap_port_enqueue_get(unit,port,enable)); 36359 } else 36360 #endif 36361 #ifdef BCM_TRIDENT2_SUPPORT 36362 if (SOC_IS_TD2_TT2(unit)) { 36363 BCM_IF_ERROR_RETURN 36364 (_bcm_td2_port_enqueue_get(unit,port,enable)); 36365 } else 36366 #endif 36367 #ifdef BCM_TRIDENT_SUPPORT 36368 if (SOC_IS_TD_TT(unit)) { 36369 BCM_IF_ERROR_RETURN 36370 (_bcm_td_port_enqueue_get(unit,port,enable)); 36371 } else 36372 #endif 36373 { 36374 return BCM_E_UNAVAIL; 36375 } 36376 return rv; 36377 } 36378 36379 /* 36380 * Function: 36381 * bcm_esw_port_drain_cells 36382 * Description:i 36383 * This function will drains the MMU cells which the port 36384 * is holding 36385 * Parameters: 36386 * unit - (IN) Device number 36387 * port - (IN) Port to resolve 36388 * value - (IN) TRUE to drain the cells 36389 * FALSE to just ignore 36390 * Return Value: 36391 * BCM_E_XXX 36392 */ 36393 static int 36394 bcm_esw_port_drain_cells(int unit, bcm_port_t port, int value) 36395 { 36396 int rv = BCM_E_NONE; 36397 36398 /* Make sure port module is initialized. */ 36399 PORT_INIT(unit); 36400 if (value == FALSE ) { 36401 return rv; 36402 } 36403 #ifdef BCM_TRIDENT3_SUPPORT 36404 if (SOC_IS_TRIDENT3X(unit)) { 36405 if (IS_CPU_PORT(unit, port)) { 36406 return BCM_E_PORT; 36407 } 36408 /* MMU cells were drained when enqueuing is disabled */ 36409 return rv; 36410 } else 36411 #endif 36412 #ifdef BCM_TOMAHAWK_SUPPORT 36413 if (SOC_IS_TOMAHAWKX(unit)) { 36414 if (IS_CPU_PORT(unit, port)) { 36415 return BCM_E_PORT; 36416 } 36417 /* MMU cells were drained when enqueuing is disabled */ 36418 return rv; 36419 36420 } else 36421 #endif 36422 #ifdef BCM_MONTEREY_SUPPORT 36423 if (SOC_IS_MONTEREY(unit)) { 36424 BCM_IF_ERROR_RETURN 36425 (bcm_monterey_port_drain_cells(unit, port)); 36426 } else 36427 #endif 36428 #ifdef BCM_APACHE_SUPPORT 36429 if (SOC_IS_APACHE(unit)) { 36430 BCM_IF_ERROR_RETURN 36431 (bcm_apache_port_drain_cells(unit, port)); 36432 } else 36433 #endif 36434 #ifdef BCM_TRIDENT2_SUPPORT 36435 if (SOC_IS_TD2_TT2(unit)) { 36436 BCM_IF_ERROR_RETURN 36437 (bcm_td2_port_drain_cells(unit, port)); 36438 } else 36439 #endif 36440 #ifdef BCM_TRIDENT_SUPPORT 36441 if (SOC_IS_TD_TT(unit)) { 36442 BCM_IF_ERROR_RETURN 36443 (bcm_td_port_drain_cells(unit, port)); 36444 } else 36445 #endif 36446 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) 36447 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_HELIX4(unit)) { 36448 BCM_IF_ERROR_RETURN 36449 (bcm_tr3_port_drain_cells(unit, port)); 36450 } else 36451 #endif /* BCM_TRIUMPH3_SUPPORT */ 36452 #ifdef BCM_KATANA2_SUPPORT 36453 if (SOC_IS_KATANA2(unit)) { 36454 BCM_IF_ERROR_RETURN 36455 (bcm_kt2_port_drain_cells(unit, port)); 36456 } else 36457 #endif 36458 36459 { 36460 return BCM_E_UNAVAIL; 36461 } 36462 return rv; 36463 } 36464 36465 /* 36466 * Function: 36467 * _bcm_esw_port_llfc_set 36468 * Description: 36469 * This function will set the LLFC_RX/TX_ENABLE field, 36470 * and LLFC_EN field can possibly be set accordingly. 36471 * Parameters: 36472 * unit - (IN) Device number 36473 * port - (IN) Port to resolve 36474 * type - (IN) Enum value of the feature 36475 * value - (IN) Value to be set 36476 * Return Value: 36477 * BCM_E_XXX 36478 */ 36479 STATIC int 36480 _bcm_esw_port_llfc_set(int unit, bcm_port_t port, bcm_port_control_t type, int value) 36481 { 36482 int rv = BCM_E_UNAVAIL; 36483 soc_reg_t port_config; 36484 int llfc_enable; 36485 #ifdef BCM_TRIDENT2_SUPPORT 36486 uint32 rval; 36487 #endif 36488 36489 if(SOC_USE_PORTCTRL(unit)) { 36490 return(bcmi_esw_portctrl_llfc_set(unit,port, type, value)); 36491 } 36492 36493 switch(type) { 36494 case bcmPortControlLLFCReceive: 36495 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 36496 case bcmPortControlSAFCReceive: 36497 #endif 36498 #if defined(BCM_XGS3_SWITCH_SUPPORT) 36499 if (SOC_IS_XGS3_SWITCH(unit)) { 36500 36501 if (!SOC_PORT_VALID(unit, port)) { 36502 return BCM_E_PORT; 36503 } 36504 36505 BCM_IF_ERROR_RETURN 36506 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 36507 SOC_MAC_CONTROL_LLFC_RX_ENABLE, value)); 36508 if (value == 0) { 36509 BCM_IF_ERROR_RETURN 36510 (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 36511 SOC_MAC_CONTROL_LLFC_TX_ENABLE, 36512 &llfc_enable)); 36513 } else { 36514 llfc_enable = TRUE; 36515 } 36516 36517 if (SOC_REG_FIELD_VALID(unit, XLPORT_CONFIGr, LLFC_ENf)) { 36518 port_config = XLPORT_CONFIGr; 36519 } else if (SOC_REG_FIELD_VALID(unit, XPORT_CONFIGr, LLFC_ENf)) { 36520 port_config = XPORT_CONFIGr; 36521 } else if (SOC_REG_FIELD_VALID(unit, PORT_CONFIGr, LLFC_ENf)) { 36522 port_config = PORT_CONFIGr; 36523 } else { 36524 port_config = INVALIDr; 36525 } 36526 36527 if (port_config != INVALIDr){ 36528 BCM_IF_ERROR_RETURN 36529 (soc_reg_field32_modify(unit, port_config, port, LLFC_ENf, 36530 llfc_enable ? 1 : 0)); 36531 } 36532 36533 rv = BCM_E_NONE; 36534 } 36535 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 36536 break; 36537 case bcmPortControlLLFCTransmit: 36538 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 36539 case bcmPortControlSAFCTransmit: 36540 #endif 36541 #if defined(BCM_XGS3_SWITCH_SUPPORT) 36542 if (SOC_IS_XGS3_SWITCH(unit)) { 36543 if (!SOC_PORT_VALID(unit, port)) { 36544 return BCM_E_PORT; 36545 } 36546 36547 BCM_IF_ERROR_RETURN 36548 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 36549 SOC_MAC_CONTROL_LLFC_TX_ENABLE, value)); 36550 if (value == 0) { 36551 BCM_IF_ERROR_RETURN 36552 (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 36553 SOC_MAC_CONTROL_LLFC_RX_ENABLE, 36554 &llfc_enable)); 36555 } else { 36556 llfc_enable = TRUE; 36557 } 36558 36559 if (SOC_REG_FIELD_VALID(unit, XLPORT_CONFIGr, LLFC_ENf)) { 36560 port_config = XLPORT_CONFIGr; 36561 } else if (SOC_REG_FIELD_VALID(unit, XPORT_CONFIGr, LLFC_ENf)) { 36562 port_config = XPORT_CONFIGr; 36563 } else if (SOC_REG_FIELD_VALID(unit, PORT_CONFIGr, LLFC_ENf)) { 36564 port_config = PORT_CONFIGr; 36565 } else { 36566 port_config = INVALIDr; 36567 } 36568 36569 if (port_config != INVALIDr){ 36570 BCM_IF_ERROR_RETURN 36571 (soc_reg_field32_modify(unit, port_config, port, LLFC_ENf, 36572 llfc_enable ? 1 : 0)); 36573 } 36574 36575 #ifdef BCM_TRIDENT2_SUPPORT 36576 if (SOC_IS_TD2_TT2(unit)) { 36577 SOC_IF_ERROR_RETURN 36578 (soc_reg32_get(unit, THDI_INPUT_PORT_XON_ENABLESr, 36579 port, 0, &rval)); 36580 36581 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 36582 PORT_PRI_XON_ENABLEf, 36583 value ? 0xffff : 0); 36584 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 36585 PORT_PAUSE_ENABLEf, value ? 0 : 1); 36586 36587 SOC_IF_ERROR_RETURN 36588 (soc_reg32_set(unit, THDI_INPUT_PORT_XON_ENABLESr, 36589 port, 0, rval)); 36590 } 36591 #endif 36592 36593 rv = BCM_E_NONE; 36594 } 36595 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 36596 break; 36597 default: 36598 break; 36599 } 36600 36601 return rv; 36602 } 36603 36604 /* 36605 * Function: 36606 * _bcm_esw_port_llfc_get 36607 * Description: 36608 * This function will get the LLFC_TX/RX_ENABLE field. 36609 * Parameters: 36610 * unit - (IN) Device number 36611 * port - (IN) Port to resolve 36612 * type - (IN) Enum value of the feature 36613 * value - (OUT) Current value of the port feature 36614 * Return Value: 36615 * BCM_E_XXX 36616 */ 36617 STATIC int 36618 _bcm_esw_port_llfc_get(int unit, bcm_port_t port, bcm_port_control_t type, int *value) 36619 { 36620 int rv = BCM_E_UNAVAIL; 36621 36622 if(SOC_USE_PORTCTRL(unit)) { 36623 return(bcmi_esw_portctrl_llfc_get(unit,port, type, value)); 36624 } 36625 36626 switch(type) { 36627 case bcmPortControlLLFCReceive: 36628 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 36629 case bcmPortControlSAFCReceive: 36630 #endif 36631 #if defined(BCM_XGS3_SWITCH_SUPPORT) 36632 if (SOC_IS_XGS3_SWITCH(unit)) { 36633 if (!SOC_PORT_VALID(unit, port)) { 36634 return BCM_E_PORT; 36635 } 36636 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 36637 SOC_MAC_CONTROL_LLFC_RX_ENABLE, value); 36638 } 36639 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 36640 break; 36641 case bcmPortControlLLFCTransmit: 36642 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 36643 case bcmPortControlSAFCTransmit: 36644 #endif 36645 #if defined(BCM_XGS3_SWITCH_SUPPORT) 36646 if (SOC_IS_XGS3_SWITCH(unit)) { 36647 if (!SOC_PORT_VALID(unit, port)) { 36648 return BCM_E_PORT; 36649 } 36650 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 36651 SOC_MAC_CONTROL_LLFC_TX_ENABLE, value); 36652 } 36653 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 36654 break; 36655 default: 36656 break; 36657 } 36658 36659 return rv; 36660 } 36661 36662 #ifdef BCM_TRIUMPH3_SUPPORT 36663 STATIC int 36664 _bcm_tr3_port_lanes_set(int unit, bcm_port_t port, int value) 36665 { 36666 int i, incr = 1, ports = 3, okay; 36667 int rv = BCM_E_NONE, rv1, old_value; 36668 int retry_count = 0, mode_change = -1; 36669 uint16 phy; 36670 uint32 flags; 36671 soc_info_t *si = &SOC_INFO(unit); 36672 int phy_port = -1; 36673 int old_port[4]; 36674 if (!SOC_PORT_VALID(unit, port)) { 36675 return BCM_E_PORT; 36676 } 36677 36678 /* coverity[overrun-local : FALSE] */ 36679 phy_port = si->port_l2p_mapping[port]; 36680 for (i = 0; i < 4; i++) { 36681 old_port[i] = si->flex_port_p2l_mapping[phy_port+i]; 36682 } 36683 36684 _reconfig: 36685 rv = soc_tr3_port_lanes_set(unit, port, value, &old_value, &mode_change); 36686 if (rv != SOC_E_NONE) { 36687 return rv; 36688 } 36689 if (value == 1) { 36690 #ifdef BCM_HELIX4_SUPPORT 36691 /* coverity[overrun-local : FALSE] */ 36692 if (SOC_IS_HELIX4(unit) && ((_tr3_port_config_id[unit] == 410) && 36693 (si->port_l2p_mapping[port] == 57 || si->port_l2p_mapping[port] == 61))){ 36694 ports = 1; 36695 }else if(SOC_IS_HELIX4(unit) && (((_tr3_port_config_id[unit] == 463) || 36696 (_tr3_port_config_id[unit] == 413)) && (si->port_l2p_mapping[port] == 57 || 36697 si->port_l2p_mapping[port] == 61))){ 36698 ports = 2; 36699 } 36700 else 36701 #endif 36702 /* coverity[overrun-local : FALSE] */ 36703 if (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) && 36704 ((_tr3_port_config_id[unit] == 112 || _tr3_port_config_id[unit] == 12) && 36705 (si->port_l2p_mapping[port] == 73 || si->port_l2p_mapping[port] == 77))) { 36706 ports = 1; 36707 } else { 36708 ports = 4; 36709 } 36710 } else if (value == 2) { 36711 #ifdef BCM_HELIX4_SUPPORT 36712 if(SOC_IS_HELIX4(unit) &&((_tr3_port_config_id[unit] == 463) || 36713 _tr3_port_config_id[unit] == 413) && (si->port_l2p_mapping[port] == 57 || 36714 si->port_l2p_mapping[port] == 61)){ 36715 ports = 1; 36716 incr = 2; 36717 } 36718 else 36719 #endif 36720 { 36721 incr = 2; 36722 } 36723 } else if (value == 4) { 36724 ports = 1; 36725 } 36726 if (value == 2 && old_value == 1) { 36727 #ifdef BCM_HELIX4_SUPPORT 36728 if(SOC_IS_HELIX4(unit) && (((_tr3_port_config_id[unit] == 463) || 36729 (_tr3_port_config_id[unit] == 413)) && (si->port_l2p_mapping[port] == 57 || 36730 si->port_l2p_mapping[port] == 61))){ 36731 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, si->port_p2l_mapping[si->port_l2p_mapping[port] + 1])); 36732 }else 36733 #endif 36734 { 36735 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 1)); 36736 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 3)); 36737 } 36738 } else if (value == 4 && old_value == 1) { 36739 if ((SOC_IS_HELIX4(unit) && (_tr3_port_config_id[unit] == 410)) || 36740 (SOC_IS_TRIUMPH3(unit) && !SOC_IS_HELIX4(unit) && 36741 (_tr3_port_config_id[unit] == 112 || _tr3_port_config_id[unit] == 12))){ 36742 if (old_port[1] > 0) { 36743 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, old_port[1])); 36744 } 36745 if (old_port[2] > 0) { 36746 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, old_port[2])); 36747 } 36748 if (old_port[3] > 0) { 36749 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, old_port[3])); 36750 } 36751 } else { 36752 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 1)); 36753 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 2)); 36754 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 3)); 36755 } 36756 } else if (value == 4 && old_value == 2) { 36757 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port + 2)); 36758 } 36759 for (i = 0; i < ports; i+=incr) { 36760 flags = 0; 36761 phy = soc_property_port_get(unit, port + i, spn_FLEX_PORT_PHY_ADDR, 0); 36762 if (!phy) { 36763 SOC_IF_ERROR_RETURN(soc_tr3_phy_addr_get(unit, port + i, &phy)); 36764 flags = _SHR_PORT_PHY_INTERNAL; 36765 } 36766 SOC_IF_ERROR_RETURN(soc_phy_cfg_addr_set(unit, port + i, flags, phy)); 36767 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port + i, &okay)); 36768 LOG_VERBOSE(BSL_LS_BCM_PORT, 36769 (BSL_META_U(unit, 36770 "Port %d probe: %d\n"), port + i, okay)); 36771 if (!okay) { 36772 return BCM_E_INTERNAL; 36773 } 36774 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port + i, TRUE)); 36775 } 36776 #ifdef BCM_WARM_BOOT_SUPPORT 36777 if (SOC_WARM_BOOT(unit)) { 36778 return rv; 36779 } 36780 #endif /* BCM_WARM_BOOT_SUPPORT */ 36781 36782 for (i = 0; i < ports; i+=incr) { 36783 if (SOC_PBMP_MEMBER(si->port.disabled_bitmap, port+i)) { 36784 continue; 36785 } 36786 rv1 = _bcm_tr3_port_ur_chk(unit, ports, port + i); 36787 if (rv1 == BCM_E_PORT) { 36788 /* Error encountered in the newly created flex ports. 36789 Lets revert back to old mode and retry if retry count not exceeded */ 36790 if (++retry_count > _BCM_TR3_PORT_UR_RETRY_MAX) { 36791 return BCM_E_INTERNAL; 36792 } 36793 rv = soc_tr3_port_lanes_set(unit, port, old_value, &old_value, &mode_change); 36794 if (rv != SOC_E_NONE) { 36795 return rv; 36796 } 36797 goto _reconfig; 36798 } 36799 if (rv1 != BCM_E_NONE) { 36800 return rv1; 36801 } 36802 } 36803 36804 /* Note: Following is currently a brute force solution */ 36805 for (i = 0; i < ports; i+=incr) { 36806 if (mode_change == BCM_PORT_ENCAP_HIGIG) { 36807 /* coverity[overrun-call : FALSE] */ 36808 BCM_IF_ERROR_RETURN 36809 (_bcm_port_encap_xport_set(unit, port + i, BCM_PORT_ENCAP_HIGIG, 36810 TRUE)); 36811 } else if (mode_change == BCM_PORT_ENCAP_IEEE) { 36812 /* coverity[overrun-call : FALSE] */ 36813 BCM_IF_ERROR_RETURN 36814 (_bcm_port_encap_xport_set(unit, port + i, BCM_PORT_ENCAP_IEEE, 36815 TRUE)); 36816 } 36817 } 36818 return rv; 36819 } 36820 36821 STATIC int 36822 _bcm_tr3_port_lanes_get(int unit, bcm_port_t port, int *value) 36823 { 36824 int rv = BCM_E_NONE; 36825 if (!SOC_PORT_VALID(unit, port)) { 36826 return BCM_E_PORT; 36827 } 36828 rv = soc_tr3_port_lanes_get(unit, port, value); 36829 return rv; 36830 } 36831 #endif /* BCM_TRIUMPH3_SUPPORT */ 36832 36833 #ifdef BCM_TRIDENT_SUPPORT 36834 STATIC int 36835 _bcm_td_port_lanes_set(int unit, bcm_port_t port, int value) 36836 { 36837 soc_info_t *si; 36838 int rv, okay, i; 36839 uint32 rval, phy_mode, core_mode; 36840 uint32 reset_status; 36841 bcm_port_t phy_port; 36842 36843 rv = READ_XLPORT_MODE_REGr(unit, port, &rval); 36844 if (BCM_SUCCESS(rv)) { 36845 phy_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, 36846 PHY_PORT_MODEf); 36847 core_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, 36848 CORE_PORT_MODEf); 36849 if (phy_mode == 0) { /* single mode */ 36850 /* Case of 40G port --> 10G XFI */ 36851 if (value == 1) { 36852 SOC_INFO(unit).port_speed_max[port]=10000; 36853 } 36854 } else if (phy_mode == 1) { /* dual mode */ 36855 if (value != 2 && value != 4) { 36856 rv = BCM_E_PARAM; 36857 } else if (value == 4) { 36858 core_mode = 0; 36859 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, CORE_PORT_MODEf, core_mode); 36860 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval)); 36861 } 36862 } else { /* phy_mode == 2 */ 36863 if (value == 4) { 36864 /* 10G XFI --> 10G XAUI or 10G XFI --> 40G */ 36865 if (core_mode == 0) { 36866 /* 10GXFI --> 40G */ 36867 SOC_INFO(unit).port_speed_max[port]=40000; 36868 } 36869 } 36870 } 36871 } 36872 if (BCM_SUCCESS(rv)) { 36873 si = &SOC_INFO(unit); 36874 phy_port = si->port_l2p_mapping[port]; 36875 for (i = 0; i < value; i++) { 36876 if ((si->port_p2l_mapping[phy_port + i]) == -1) { 36877 continue; 36878 } 36879 rv = soc_phyctrl_detach 36880 (unit, si->port_p2l_mapping[phy_port + i]); 36881 if (BCM_FAILURE(rv)) { 36882 break; 36883 } 36884 } 36885 } 36886 if (BCM_SUCCESS(rv)) { 36887 si = &SOC_INFO(unit); 36888 si->port_num_lanes[port] = value; 36889 if (BCM_SUCCESS(rv)) { 36890 rv = _bcm_port_phy_probe(unit, port, &okay); 36891 } 36892 } 36893 36894 /* Do XMAC reset when port mode is changed */ 36895 SOC_IF_ERROR_RETURN(READ_XLPORT_XMAC_CONTROLr(unit, port, &rval)); 36896 reset_status = soc_reg_field_get(unit, XLPORT_XMAC_CONTROLr, rval, XMAC_RESETf); 36897 if (reset_status != 1) { 36898 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1); 36899 SOC_IF_ERROR_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval)); 36900 sal_udelay(10); 36901 soc_reg_field_set(unit, XLPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0); 36902 SOC_IF_ERROR_RETURN(WRITE_XLPORT_XMAC_CONTROLr(unit, port, rval)); 36903 } 36904 36905 return rv; 36906 } 36907 #endif /* BCM_TRIDENT_SUPPORT */ 36908 36909 #ifdef BCM_TRIDENT2_SUPPORT 36910 STATIC int 36911 _bcm_td2_port_lanes_set(int unit, bcm_port_t port_base, int lanes) 36912 { 36913 soc_info_t *si = &SOC_INFO(unit); 36914 soc_td2_port_lanes_t lanes_ctrl; 36915 int port, i; 36916 int enable, okay; 36917 soc_control_t *soc = SOC_CONTROL(unit); 36918 36919 if(SOC_USE_PORTCTRL(unit)) { 36920 return(bcmi_esw_td2_portctrl_lanes_set(unit, port_base, lanes)); 36921 } 36922 36923 sal_memset(&lanes_ctrl, 0, sizeof(lanes_ctrl)); 36924 lanes_ctrl.port_base = port_base; 36925 lanes_ctrl.lanes = lanes; 36926 SOC_IF_ERROR_RETURN 36927 (soc_trident2_port_lanes_validate(unit, &lanes_ctrl)); 36928 36929 if (lanes_ctrl.lanes == lanes_ctrl.cur_lanes) { 36930 return BCM_E_NONE; 36931 } 36932 36933 /* All existing ports are required to be disasbled */ 36934 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port_base, &enable)); 36935 if (enable) { 36936 return BCM_E_BUSY; 36937 } 36938 if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */ 36939 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 36940 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 36941 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable)); 36942 if (enable) { 36943 return BCM_E_BUSY; 36944 } 36945 } 36946 } 36947 36948 SOC_IF_ERROR_RETURN 36949 (soc_trident2_port_lanes_set(unit, &lanes_ctrl)); 36950 36951 /* Detach PHY on all existing port(s) */ 36952 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port_base)); 36953 if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */ 36954 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 36955 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 36956 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port)); 36957 COUNTER_LOCK(unit); 36958 SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, port); 36959 COUNTER_UNLOCK(unit); 36960 } 36961 } 36962 /* Probe PHY on all port(s) after conversion */ 36963 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port_base, &okay)); 36964 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port_base, FALSE)); 36965 if (lanes_ctrl.lanes < lanes_ctrl.cur_lanes) { /* port(s) to be added */ 36966 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 36967 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 36968 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay)); 36969 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, FALSE)); 36970 COUNTER_LOCK(unit); 36971 SOC_PBMP_PORT_ADD(soc->counter_pbmp, port); 36972 COUNTER_UNLOCK(unit); 36973 } 36974 } 36975 36976 return BCM_E_NONE; 36977 } 36978 #endif /* BCM_TRIDENT2_SUPPORT */ 36979 36980 #ifdef BCM_TOMAHAWK_SUPPORT 36981 STATIC int 36982 _bcm_th_port_lanes_set(int unit, bcm_port_t port_base, int lanes) 36983 { 36984 soc_info_t *si = &SOC_INFO(unit); 36985 soc_control_t *soc = SOC_CONTROL(unit); 36986 soc_th_port_lanes_t lanes_ctrl; 36987 int port, i; 36988 int enable, okay; 36989 int speed; 36990 36991 sal_memset(&lanes_ctrl, 0, sizeof(lanes_ctrl)); 36992 lanes_ctrl.port_base = port_base; 36993 lanes_ctrl.lanes = lanes; 36994 36995 /* All existing ports are required to be disabled */ 36996 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port_base, &enable)); 36997 if (enable) { 36998 return BCM_E_PORT; 36999 } 37000 SOC_IF_ERROR_RETURN 37001 (soc_tomahawk_port_lanes_validate(unit, &lanes_ctrl)); 37002 if (lanes_ctrl.lanes == lanes_ctrl.cur_lanes) { 37003 return BCM_E_NONE; 37004 } 37005 37006 if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */ 37007 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 37008 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 37009 SOC_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &enable)); 37010 if (enable) { 37011 return BCM_E_PORT; 37012 } 37013 } 37014 } 37015 37016 SOC_IF_ERROR_RETURN 37017 (soc_tomahawk_port_lanes_set(unit, &lanes_ctrl)); 37018 SOC_IF_ERROR_RETURN 37019 (soc_tomahawk_port_lanes_consolidation(unit, &lanes_ctrl)); 37020 37021 /* Detach PHY on all existing port(s) */ 37022 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port_base)); 37023 if (lanes_ctrl.lanes > lanes_ctrl.cur_lanes) { /* port(s) to be removed */ 37024 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 37025 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 37026 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port)); 37027 COUNTER_LOCK(unit); 37028 SOC_PBMP_PORT_REMOVE(soc->counter_pbmp, port); 37029 COUNTER_UNLOCK(unit); 37030 } 37031 } 37032 37033 /* Probe PHY on all port(s) after conversion */ 37034 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port_base, &okay)); 37035 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port_base, FALSE)); 37036 if (lanes_ctrl.lanes < lanes_ctrl.cur_lanes) { /* port(s) to be added */ 37037 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 37038 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 37039 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay)); 37040 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, FALSE)); 37041 COUNTER_LOCK(unit); 37042 SOC_PBMP_PORT_ADD(soc->counter_pbmp, port); 37043 COUNTER_UNLOCK(unit); 37044 } 37045 } 37046 37047 /* Update port ASF setting to SAF */ 37048 /* Base Port */ 37049 speed = si->port_init_speed[port_base]; 37050 BCM_IF_ERROR_RETURN(soc_th_port_asf_mode_set 37051 (unit, port_base, speed, _SOC_TH_ASF_MODE_SAF)); 37052 /* Newly added ports */ 37053 if (lanes_ctrl.lanes < lanes_ctrl.cur_lanes) { /* port(s) to be added */ 37054 for (i = 0; i < lanes_ctrl.phy_ports_len; i++) { 37055 port = si->port_p2l_mapping[lanes_ctrl.phy_ports[i]]; 37056 speed = si->port_init_speed[port]; 37057 BCM_IF_ERROR_RETURN(soc_th_port_asf_mode_set 37058 (unit, port, speed, _SOC_TH_ASF_MODE_SAF)); 37059 } 37060 } 37061 37062 return BCM_E_NONE; 37063 } 37064 #endif /* BCM_TOMAHAWK_SUPPORT */ 37065 37066 #ifdef BCM_HURRICANE2_SUPPORT 37067 STATIC int 37068 _bcm_hu2_port_lanes_set(int unit, bcm_port_t port_base, int lanes) 37069 { 37070 soc_info_t *si = &SOC_INFO(unit); 37071 int cur_lanes; 37072 int port, phy_ports[3], phy_ports_len, i; 37073 int okay; 37074 37075 SOC_IF_ERROR_RETURN 37076 (soc_hurricane2_port_lanes_set(unit, port_base, lanes, &cur_lanes, 37077 phy_ports, &phy_ports_len)); 37078 if (lanes == cur_lanes) { 37079 return BCM_E_NONE; 37080 } 37081 37082 if (lanes > cur_lanes) { /* port(s) to be removed */ 37083 for (i = 0; i < phy_ports_len; i++) { 37084 port = si->port_p2l_mapping[phy_ports[i]]; 37085 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, port)); 37086 } 37087 } 37088 37089 /* The specified port */ 37090 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port_base, &okay)); 37091 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port_base, TRUE)); 37092 37093 if (lanes < cur_lanes) { /* port(s) to be added */ 37094 for (i = 0; i < phy_ports_len; i++) { 37095 port = si->port_p2l_mapping[phy_ports[i]]; 37096 BCM_IF_ERROR_RETURN(_bcm_port_probe(unit, port, &okay)); 37097 BCM_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, port, TRUE)); 37098 } 37099 } 37100 37101 return BCM_E_NONE; 37102 } 37103 #endif 37104 37105 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 37106 int 37107 _bcm_sc_tr_port_pfc_tx_set(int unit, bcm_port_t port, uint32 pri_bmp) 37108 { 37109 int pfc_enable; 37110 uint32 rval; 37111 int value, val_count = 0; 37112 soc_reg_t reg; 37113 uint32 values[2]; 37114 int chk_gx_port = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 37115 SOC_IS_VALKYRIE2(unit) || SOC_IS_SCORPION(unit)); 37116 soc_field_t fields[] = {PFC_ENABLEf, LLFC_ENf}; 37117 37118 if (!soc_feature(unit, soc_feature_priority_flow_control)) { 37119 return BCM_E_UNAVAIL; 37120 } 37121 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 37122 if (chk_gx_port && !IS_GX_PORT(unit, port)) { /* IS_GX_PORT == IS_XL_PORT */ 37123 return BCM_E_PORT; 37124 } 37125 if (pri_bmp >= (1U << 16)) { 37126 return BCM_E_PARAM; 37127 } 37128 37129 value = (pri_bmp == 0)? 0 : 1; 37130 BCM_IF_ERROR_RETURN 37131 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 37132 SOC_MAC_CONTROL_PFC_TX_ENABLE, value)); 37133 if (value == 0) { 37134 BCM_IF_ERROR_RETURN 37135 (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 37136 SOC_MAC_CONTROL_PFC_RX_ENABLE, 37137 &pfc_enable)); 37138 } else { 37139 pfc_enable = TRUE; 37140 } 37141 37142 if (!soc_feature(unit, soc_feature_mmu_config_property)) { 37143 rval = 0; 37144 if (SOC_REG_IS_VALID(unit,PORT_PRI_XON_ENABLEr)) { 37145 if (value) { 37146 soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval, 37147 PORT_PRI_XON_ENABLEf, 0xff); 37148 if (soc_reg_field_valid(unit, PORT_PRI_XON_ENABLEr, 37149 PORT_PG7PAUSE_DISABLEf)) { 37150 soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval, 37151 PORT_PG7PAUSE_DISABLEf, 1); 37152 } 37153 } 37154 BCM_IF_ERROR_RETURN 37155 (WRITE_PORT_PRI_XON_ENABLEr(unit, port, rval)); 37156 } 37157 } else if (SOC_IS_TRIDENT(unit)) { 37158 rval = 0; 37159 if (SOC_REG_IS_VALID(unit,PORT_PRI_XON_ENABLEr)) { 37160 if(value) { 37161 /* Get flow_control_enable info from mmu config 37162 * property for each priority group, and enable 37163 * generation of XON/XOFF for priority group 37164 * accordingly. */ 37165 int idx = 0, prifc_en = 0, fval = 0; 37166 char suffix; 37167 for(idx = 0; idx < 8; idx ++) { 37168 /* By default, enable generation of XON and XOFF 37169 * LLFC messages for priority 7 */ 37170 prifc_en = (idx == 7) ? 1 : 0; 37171 prifc_en = soc_property_port_obj_attr_get(unit, 37172 port, spn_BUF, spn_PRIGROUP, 37173 idx, spn_FLOW_CONTROL_ENABLE, 37174 0, &suffix, prifc_en); 37175 if(prifc_en != 0) { 37176 fval |= (1 << idx); 37177 } 37178 } 37179 soc_reg_field_set(unit, PORT_PRI_XON_ENABLEr, &rval, 37180 PORT_PRI_XON_ENABLEf, fval); 37181 } 37182 /* When disable PFC on port, generation of XON/XOFF 37183 * for all priority groups must be disabled also. */ 37184 BCM_IF_ERROR_RETURN 37185 (WRITE_PORT_PRI_XON_ENABLEr(unit, port, rval)); 37186 } 37187 } 37188 37189 /* Port config settings */ 37190 values[0] = pfc_enable ? 1 : 0; 37191 values[1] = 0; 37192 37193 if (SOC_IS_TD2_TT2(unit)) { 37194 #ifdef BCM_TOMAHAWK3_SUPPORT 37195 if(SOC_IS_TOMAHAWK3(unit)) { 37196 SOC_IF_ERROR_RETURN 37197 (bcm_th3_mmu_pfc_tx_config_set(unit, port, 37198 pfc_enable, pri_bmp)); 37199 } else 37200 #endif 37201 { 37202 SOC_IF_ERROR_RETURN 37203 (soc_reg32_get(unit, THDI_INPUT_PORT_XON_ENABLESr, 37204 port, 0, &rval)); 37205 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 37206 PORT_PRI_XON_ENABLEf, 37207 pfc_enable ? pri_bmp : 0); 37208 37209 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 37210 PORT_PAUSE_ENABLEf, pfc_enable ? 0 : 1); 37211 SOC_IF_ERROR_RETURN 37212 (soc_reg32_set(unit, THDI_INPUT_PORT_XON_ENABLESr, 37213 port, 0, rval)); 37214 } 37215 #ifdef BCM_TOMAHAWK_SUPPORT 37216 if (SOC_IS_TOMAHAWKX(unit) && IS_CL_PORT(unit, port)) { 37217 soc_info_t *si; 37218 uint64 rval64; 37219 int phy_port_base, phy_port, lane, block_idx, pipe, clport, obm; 37220 static const soc_reg_t obm_fc_config_regs[] = { 37221 IDB_OBM0_FLOW_CONTROL_CONFIGr, IDB_OBM1_FLOW_CONTROL_CONFIGr, 37222 IDB_OBM2_FLOW_CONTROL_CONFIGr, IDB_OBM3_FLOW_CONTROL_CONFIGr, 37223 IDB_OBM4_FLOW_CONTROL_CONFIGr, IDB_OBM5_FLOW_CONTROL_CONFIGr, 37224 IDB_OBM6_FLOW_CONTROL_CONFIGr, IDB_OBM7_FLOW_CONTROL_CONFIGr, 37225 #ifdef BCM_TOMAHAWK2_SUPPORT 37226 IDB_OBM8_FLOW_CONTROL_CONFIGr, IDB_OBM9_FLOW_CONTROL_CONFIGr, 37227 IDB_OBM10_FLOW_CONTROL_CONFIGr, IDB_OBM11_FLOW_CONTROL_CONFIGr, 37228 IDB_OBM12_FLOW_CONTROL_CONFIGr, IDB_OBM13_FLOW_CONTROL_CONFIGr, 37229 IDB_OBM14_FLOW_CONTROL_CONFIGr, IDB_OBM15_FLOW_CONTROL_CONFIGr 37230 #endif 37231 }; 37232 37233 COMPILER_64_ZERO(rval64); 37234 si = &SOC_INFO(unit); 37235 phy_port = si->port_l2p_mapping[port]; 37236 phy_port_base = PORT_BLOCK_BASE_PORT(port); 37237 lane = (phy_port - phy_port_base) & 3; 37238 block_idx = SOC_PORT_IDX_BLOCK(unit, phy_port_base, 0); 37239 pipe = si->port_pipe[port]; 37240 clport = SOC_BLOCK_NUMBER(unit, block_idx); 37241 if (SOC_IS_TOMAHAWK(unit)) { 37242 /* obm number is reversed (mirrored) in odd pipe */ 37243 obm = pipe & 1 ? (7- (clport & 7)) : (clport & 7); 37244 } else { 37245 obm = clport & 15; 37246 } 37247 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_config_regs[obm])[pipe]; 37248 SOC_IF_ERROR_RETURN 37249 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 37250 soc_reg64_field32_set(unit, reg, &rval64, FC_TYPEf, pfc_enable); 37251 SOC_IF_ERROR_RETURN 37252 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 37253 } 37254 #endif /* BCM_TOMAHAWK_SUPPORT */ 37255 reg = INVALIDr; 37256 } else if (SOC_IS_TD_TT(unit)) { 37257 int mmu_port; 37258 uint64 r64val; 37259 soc_info_t *si; 37260 37261 /* disable pause if pfc is enabled, vice versa */ 37262 si = &SOC_INFO(unit); 37263 mmu_port = si->port_p2m_mapping[si->port_l2p_mapping[port]]; 37264 reg = (mmu_port < 33) ? PORT_PAUSE_ENABLE0_64r : PORT_PAUSE_ENABLE1_64r; 37265 mmu_port = (mmu_port < 33) ? mmu_port : mmu_port - 33; 37266 SOC_IF_ERROR_RETURN( 37267 soc_reg_get(unit, reg, REG_PORT_ANY, 0, &r64val)); 37268 if (value) { 37269 COMPILER_64_BITCLR(r64val, mmu_port); 37270 } else { 37271 COMPILER_64_BITSET(r64val, mmu_port); 37272 } 37273 SOC_IF_ERROR_RETURN( 37274 soc_reg_set(unit, reg, REG_PORT_ANY, 0, r64val)); 37275 37276 reg = XLPORT_CONFIGr; 37277 val_count=2; 37278 } else if (SOC_IS_SHADOW(unit)) { 37279 reg = XLPORT_CONFIGr; 37280 val_count=2; 37281 } else if (SOC_IS_TRIUMPH3(unit)) { 37282 reg = PORT_CONFIGr; 37283 val_count=2; 37284 } else if (SOC_IS_SABER2(unit)) { 37285 /* No port level config required */ 37286 reg = INVALIDr; 37287 val_count = 0; 37288 } else if (SOC_IS_KATANAX(unit)) { 37289 reg = XPORT_CONFIGr; 37290 val_count=2; 37291 } else { 37292 reg = INVALIDr; 37293 } 37294 37295 if (val_count > 0) { 37296 BCM_IF_ERROR_RETURN 37297 (soc_reg_fields32_modify(unit, reg, port, 37298 COUNTOF(values), fields, values)); 37299 } else if (SOC_IS_SC_CQ(unit) || SOC_IS_TR_VL(unit)) { 37300 if (SOC_REG_IS_VALID(unit, PPFC_ENr)) { 37301 BCM_IF_ERROR_RETURN 37302 (soc_reg_field32_modify(unit, PPFC_ENr, port, 37303 PPFC_FEATURE_ENf, 37304 pfc_enable ? 1 : 0)); 37305 } 37306 if (soc_reg_field_valid(unit, XPORT_CONFIGr, PPP_ENABLEf)) { 37307 BCM_IF_ERROR_RETURN 37308 (soc_reg_field32_modify(unit, XPORT_CONFIGr, port, 37309 PPP_ENABLEf, 37310 pfc_enable ? 1 : 0)); 37311 } 37312 } 37313 37314 /* Stats enable */ 37315 BCM_IF_ERROR_RETURN 37316 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 37317 SOC_MAC_CONTROL_PFC_STATS_ENABLE, 37318 pfc_enable ? 1 : 0)); 37319 37320 return BCM_E_NONE; 37321 } 37322 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 37323 37324 37325 /* 37326 * Function: 37327 * bcm_esw_port_control_wlan_validate 37328 * Description: 37329 * Checks that port control is valid for a WLAN GPORT. 37330 * Resolves port to expected port value for the given port control type. 37331 * Parameters: 37332 * port - (IN) Port to resolve 37333 * type - (IN) Port control type 37334 * port_out - (OUT) Returns port (gport or BCM format) that 37335 * is expected for corresponding port control type. 37336 * Return Value: 37337 * BCM_E_XXX 37338 */ 37339 STATIC int 37340 bcm_esw_port_control_wlan_validate(bcm_port_t port, 37341 bcm_port_control_t type, 37342 bcm_port_t *port_out) 37343 { 37344 int rv = BCM_E_PORT; 37345 int support = FALSE; 37346 37347 switch (type) { 37348 case bcmPortControlBridge: 37349 case bcmPortControlTrunkHashSet: 37350 case bcmPortControlFabricTrunkHashSet: 37351 case bcmPortControlECMPHashSet: 37352 case bcmPortControlLoadBalanceHashSet: 37353 case bcmPortControlLoadBalancingNumber: 37354 case bcmPortControlIP4: 37355 case bcmPortControlIP6: 37356 case bcmPortControlIP4Mcast: 37357 case bcmPortControlIP6Mcast: 37358 case bcmPortControlMpls: 37359 case bcmPortControlMacInMac: 37360 case bcmPortControlSrcBmacMissToCpu: 37361 case bcmPortControlIP4McastL2: 37362 case bcmPortControlIP6McastL2: 37363 case bcmPortControlFilterLookup: 37364 case bcmPortControlFilterIngress: 37365 case bcmPortControlPreservePacketPriority: 37366 case bcmPortControlLearnClassEnable: 37367 case bcmPortControlTrustIncomingVlan: 37368 case bcmPortControlDoNotCheckVlan: 37369 case bcmPortControlIEEE8021ASEnableIngress: 37370 case bcmPortControlIpfixRate: 37371 case bcmPortControlForwardStaticL2MovePkt: 37372 case bcmPortControlTrillHashSelect: 37373 case bcmPortControlFabricSourceKnockout: 37374 case bcmPortControlL2GreEnable: 37375 case bcmPortControlL2GreTunnelbasedVpnId: 37376 case bcmPortControlL2GreDefaultTunnelEnable: 37377 case bcmPortControlVxlanEnable: 37378 case bcmPortControlVxlanTunnelbasedVnId: 37379 case bcmPortControlVxlanDefaultTunnelEnable: 37380 case bcmPortControlRegex: 37381 case bcmPortControlRegexTcp: 37382 case bcmPortControlRegexUdp: 37383 support = TRUE; 37384 break; 37385 default: 37386 support = FALSE; 37387 break; 37388 } 37389 37390 if (support) { 37391 *port_out = port; 37392 rv = BCM_E_NONE; 37393 } 37394 37395 return rv; 37396 } 37397 37398 /* 37399 * Function: 37400 * bcm_esw_port_control_proxy_validate 37401 * Description: 37402 * Checks that port control is valid for a PROXY GPORT. 37403 * Resolves port to expected port value for the given port control type. 37404 * Parameters: 37405 * unit - (IN) Device number 37406 * port - (IN) Port to resolve 37407 * type - (IN) Port control type 37408 * port_out - (OUT) Returns port (gport or BCM format) that 37409 * is expected for corresponding port control type. 37410 * Return Value: 37411 * BCM_E_XXX 37412 */ 37413 STATIC int 37414 bcm_esw_port_control_proxy_validate(int unit, bcm_port_t port, 37415 bcm_port_control_t type, 37416 bcm_port_t *port_out) 37417 { 37418 int rv = BCM_E_PORT; 37419 int support = FALSE; 37420 37421 /* Make sure port module is initialized. */ 37422 PORT_INIT(unit); 37423 37424 if (!soc_feature(unit, soc_feature_proxy_port_property)) { 37425 return BCM_E_PORT; 37426 } 37427 37428 switch(type) { 37429 case bcmPortControlBridge: 37430 case bcmPortControlTrunkHashSet: 37431 case bcmPortControlFabricTrunkHashSet: 37432 case bcmPortControlECMPHashSet: 37433 case bcmPortControlLoadBalanceHashSet: 37434 case bcmPortControlLoadBalancingNumber: 37435 case bcmPortControlIP4: 37436 case bcmPortControlIP6: 37437 case bcmPortControlIP4Mcast: 37438 case bcmPortControlIP6Mcast: 37439 case bcmPortControlMpls: 37440 case bcmPortControlMacInMac: 37441 case bcmPortControlSrcBmacMissToCpu: 37442 case bcmPortControlIP4McastL2: 37443 case bcmPortControlIP6McastL2: 37444 case bcmPortControlFilterLookup: 37445 case bcmPortControlFilterIngress: 37446 case bcmPortControlPreservePacketPriority: 37447 case bcmPortControlLearnClassEnable: 37448 case bcmPortControlTrustIncomingVlan: 37449 case bcmPortControlDoNotCheckVlan: 37450 case bcmPortControlIEEE8021ASEnableIngress: 37451 case bcmPortControlIpfixRate: 37452 case bcmPortControlOAMEnable: 37453 case bcmPortControlForwardStaticL2MovePkt: 37454 case bcmPortControlTrill: 37455 case bcmPortControlTrillAllow: 37456 case bcmPortControlNonTrillAllow: 37457 case bcmPortControlTrillCoreISISToCPU: 37458 case bcmPortControlTrillHashSelect: 37459 case bcmPortControlNivNonVntagDrop: 37460 case bcmPortControlNonEtagDrop: 37461 case bcmPortControlNivVntagDrop: 37462 case bcmPortControlEtagDrop: 37463 case bcmPortControlNivNonVntagAdd: 37464 case bcmPortControlNonEtagAdd: 37465 case bcmPortControlNivVntagIngressReplace: 37466 case bcmPortControlEtagIngressReplace: 37467 case bcmPortControlNivVntagIngressDelete: 37468 case bcmPortControlEtagIngressDelete: 37469 case bcmPortControlNivRpfCheck: 37470 case bcmPortControlExtenderRpfCheck: 37471 case bcmPortControlNivNameSpace: 37472 case bcmPortControlExtenderNameSpace: 37473 case bcmPortControlUseEtagPri: 37474 case bcmPortControlProhibitedDot1p: 37475 case bcmPortControlFabricSourceKnockout: 37476 case bcmPortControlMplsEntropyHashSet: 37477 case bcmPortControlL2GreEnable: 37478 case bcmPortControlL2GreTunnelbasedVpnId: 37479 case bcmPortControlL2GreDefaultTunnelEnable: 37480 case bcmPortControlVxlanEnable: 37481 case bcmPortControlVxlanTunnelbasedVnId: 37482 case bcmPortControlVxlanDefaultTunnelEnable: 37483 support = TRUE; 37484 break; 37485 default: 37486 support = FALSE; 37487 break; 37488 } 37489 37490 if (support) { 37491 *port_out = port; 37492 rv = BCM_E_NONE; 37493 } 37494 37495 return rv; 37496 } 37497 37498 /* 37499 * Function: 37500 * bcm_esw_port_control_scheduler_validate 37501 * Description: 37502 * Checks that port control is valid for a SCHEDULER GPORT. 37503 * Resolves port to expected port value for the given port control type. 37504 * Parameters: 37505 * unit - (IN) Device number 37506 * port - (IN) Port to resolve 37507 * type - (IN) Port control type 37508 * port_out - (OUT) Returns port (gport or BCM format) that 37509 * is expected for corresponding port control type. 37510 * Return Value: 37511 * BCM_E_XXX 37512 */ 37513 STATIC int 37514 bcm_esw_port_control_scheduler_validate(int unit, bcm_port_t port, 37515 bcm_port_control_t type, 37516 bcm_port_t *port_out) 37517 { 37518 int rv = BCM_E_PORT; 37519 int support = FALSE; 37520 37521 switch (type) { 37522 case bcmPortControlWredDropCountUpdateEnableQueueMask: 37523 case bcmPortControlWredDropCountUpdateEnableColorMask: 37524 support = TRUE; 37525 break; 37526 default: 37527 support = FALSE; 37528 break; 37529 } 37530 37531 if (support) { 37532 *port_out = port; 37533 rv = BCM_E_NONE; 37534 } 37535 37536 return rv; 37537 } 37538 37539 /* 37540 * Function: 37541 * bcm_esw_port_control_local_port_validate 37542 * Description: 37543 * Checks that port control is valid for a BCM local physical port. 37544 * Resolves port to expected port value for the given port control type. 37545 * Parameters: 37546 * unit - (IN) Device number 37547 * port - (IN) Port to resolve 37548 * type - (IN) Port control type 37549 * port_out - (OUT) Returns port (gport or BCM format) that 37550 * is expected for corresponding port control type. 37551 * Return Value: 37552 * BCM_E_XXX 37553 * 37554 * Unlike the other similar routines 37555 * (i.e. bcm_esw_port_control_wlan_support), note that the default 37556 * support is VALID and checks for INVALID types, since most 37557 * port controls are valid for this type of port. 37558 */ 37559 STATIC int 37560 bcm_esw_port_control_local_port_validate(int unit, bcm_port_t port, 37561 bcm_port_control_t type, 37562 bcm_port_t *port_out) 37563 { 37564 int rv = BCM_E_PORT; 37565 int support = TRUE; 37566 bcm_port_t local_port; 37567 37568 /* Make sure port module is initialized. */ 37569 PORT_INIT(unit); 37570 37571 /* Check for valid BCM local physical port */ 37572 BCM_IF_ERROR_RETURN 37573 (_bcm_esw_port_gport_validate(unit, port, &local_port)); 37574 37575 if (IS_ST_PORT(unit, local_port)) { 37576 switch(type) { 37577 case bcmPortControlIP4: 37578 case bcmPortControlIP6: 37579 case bcmPortControlIP4Mcast: 37580 case bcmPortControlIP6Mcast: 37581 case bcmPortControlMpls: 37582 case bcmPortControlMacInMac: 37583 case bcmPortControlIP4McastL2: 37584 case bcmPortControlIP6McastL2: 37585 case bcmPortControlIPMC4Ucast: 37586 case bcmPortControlIPMC6Ucast: 37587 support = FALSE; 37588 break; 37589 default: 37590 support = TRUE; 37591 break; 37592 } 37593 } 37594 37595 if (support) { 37596 if (!IS_E_PORT(unit, local_port)) { 37597 switch(type) { 37598 case bcmPortControlEEEEnable: 37599 case bcmPortControlEEETransmitIdleTime: 37600 case bcmPortControlEEEStatisticsClear: 37601 case bcmPortControlEEETransmitRefreshTime: 37602 case bcmPortControlEEETransmitSleepTime: 37603 case bcmPortControlEEETransmitQuietTime: 37604 case bcmPortControlEEETransmitWakeTime: 37605 case bcmPortControlEEEReceiveSleepTime: 37606 case bcmPortControlEEEReceiveQuietTime: 37607 case bcmPortControlEEEReceiveWakeTime: 37608 case bcmPortControlEEEEventCountSymmetric: 37609 case bcmPortControlEEELinkActiveDuration: 37610 case bcmPortControlEEEReceiveDuration: 37611 case bcmPortControlEEETransmitEventCount: 37612 case bcmPortControlEEETransmitDuration: 37613 case bcmPortControlEEEReceiveEventCount: 37614 support = FALSE; 37615 break; 37616 default: 37617 support = TRUE; 37618 break; 37619 } 37620 } 37621 } 37622 37623 if (support) { 37624 *port_out = local_port; 37625 rv = BCM_E_NONE; 37626 } 37627 37628 return rv; 37629 } 37630 37631 /* 37632 * Function: 37633 * bcm_esw_port_control_validate 37634 * Description: 37635 * Checks that port is valid and that control is supported 37636 * for the given port type. Resolves port to expected 37637 * port value for the given port control type. 37638 * Current valid port types are: 37639 * GPORT WLAN 37640 * GPORT PROXY 37641 * GPORT (various types) that resolves to local physical port 37642 * BCM port (non-gport) 37643 * Parameters: 37644 * unit - (IN) Device number 37645 * port - (IN) Port to resolve 37646 * type - (IN) Port control type 37647 * port_out - (OUT) Returns port (gport or BCM format) that 37648 * is expected for corresponding port control type. 37649 * Return Value: 37650 * BCM_E_XXX 37651 */ 37652 STATIC int 37653 bcm_esw_port_control_validate(int unit, bcm_port_t port, 37654 bcm_port_control_t type, 37655 bcm_port_t *port_out) 37656 { 37657 int rv = BCM_E_PORT; 37658 37659 /* Make sure port module is initialized. */ 37660 PORT_INIT(unit); 37661 37662 if (BCM_GPORT_IS_WLAN_PORT(port)) { 37663 rv = bcm_esw_port_control_wlan_validate(port, type, port_out); 37664 } else if (BCM_GPORT_IS_PROXY(port)) { 37665 rv = bcm_esw_port_control_proxy_validate(unit, port, type, port_out); 37666 } else if (BCM_GPORT_IS_SCHEDULER(port)) { 37667 rv = bcm_esw_port_control_scheduler_validate(unit, port, 37668 type, port_out); 37669 } else { 37670 rv = bcm_esw_port_control_local_port_validate(unit, port, type, 37671 port_out); 37672 } 37673 37674 return rv; 37675 } 37676 37677 37678 int 37679 _bcm_esw_port_vrf_set(int unit, bcm_port_t port, int value) 37680 { 37681 int rv = BCM_E_UNAVAIL; 37682 #if defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE_SUPPORT) 37683 if (SOC_IS_HAWKEYE(unit) || SOC_IS_HURRICANEX(unit) || 37684 !soc_feature(unit, soc_feature_l3)) { 37685 return BCM_E_UNAVAIL; 37686 } 37687 #endif /* BCM_HAWKEYE_SUPPORT || BCM_HURRICANE_SUPPORT */ 37688 if (soc_mem_field_valid(unit, PORT_TABm, VRF_IDf)) { 37689 if ((value > 0 ) && (value < SOC_VRF_MAX(unit) )) { 37690 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 37691 VRF_IDf, value); 37692 BCM_IF_ERROR_RETURN(rv); 37693 if (soc_mem_field_valid(unit, PORT_TABm, VRF_PORT_ENABLEf)) { 37694 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 37695 VRF_PORT_ENABLEf, 0x1); 37696 } 37697 } else { 37698 if (soc_mem_field_valid(unit, PORT_TABm, VRF_PORT_ENABLEf)) { 37699 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 37700 VRF_PORT_ENABLEf, 0x0); 37701 BCM_IF_ERROR_RETURN(rv); 37702 } 37703 if (soc_mem_field_valid(unit, PORT_TABm, VRF_IDf)) { 37704 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 37705 VRF_IDf, 0x0); 37706 } 37707 } 37708 } 37709 37710 #if defined(BCM_TRIUMPH_SUPPORT) 37711 else { 37712 if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, VRF_IDf)) { 37713 if ((value > 0 ) && (value < SOC_VRF_MAX(unit) )) { 37714 #if defined(BCM_KATANA2_SUPPORT) 37715 if (SOC_IS_KATANA2(unit)) { 37716 rv = _bcm_kt2_source_trunk_map_set(unit, port, 37717 VRF_IDf, value); 37718 } else 37719 #endif 37720 { 37721 rv = _bcm_trx_source_trunk_map_set(unit, port, 37722 VRF_IDf, value); 37723 } 37724 BCM_IF_ERROR_RETURN(rv); 37725 if (soc_mem_field_valid(unit, PORT_TABm, 37726 PORT_OPERATIONf) || 37727 SOC_IS_TRIDENT3X(unit)) { 37728 rv = _bcm_esw_port_tab_set(unit, port, 37729 _BCM_CPU_TABS_BOTH, 37730 PORT_OPERATIONf, 0x3); 37731 } 37732 } else { 37733 if (soc_mem_field_valid(unit, PORT_TABm, 37734 PORT_OPERATIONf) || 37735 SOC_IS_TRIDENT3X(unit)) { 37736 rv = _bcm_esw_port_tab_set(unit, port, 37737 _BCM_CPU_TABS_BOTH, 37738 PORT_OPERATIONf, 0x0); 37739 } 37740 } 37741 } 37742 } 37743 #endif /* BCM_TRIUMPH_SUPPORT */ 37744 return rv; 37745 } 37746 37747 int 37748 _bcm_esw_port_vrf_get(int unit, bcm_port_t port, int *value) 37749 { 37750 int rv = BCM_E_UNAVAIL; 37751 #if defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE_SUPPORT) 37752 if (SOC_IS_HAWKEYE(unit) || SOC_IS_HURRICANEX(unit) || 37753 !soc_feature(unit, soc_feature_l3)) { 37754 return BCM_E_UNAVAIL; 37755 } 37756 #endif /* BCM_HAWKEYE_SUPPORT || BCM_HURRICANE_SUPPORT */ 37757 if (soc_mem_field_valid(unit, PORT_TABm, VRF_PORT_ENABLEf)) { 37758 rv = _bcm_esw_port_tab_get(unit, port, VRF_PORT_ENABLEf, value); 37759 37760 if ((*value == 0x1 ) && (soc_mem_field_valid(unit, PORT_TABm, 37761 VRF_IDf ))) { 37762 rv = _bcm_esw_port_tab_get(unit, port, VRF_IDf, value); 37763 } else { 37764 *value = 0; 37765 } 37766 } else if (soc_mem_field_valid(unit, PORT_TABm, VRF_IDf)) { 37767 rv = _bcm_esw_port_tab_get(unit, port, VRF_IDf, value); 37768 } 37769 37770 #if defined(BCM_TRIUMPH_SUPPORT) 37771 else { 37772 *value = 0; 37773 if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf) || 37774 SOC_IS_TRIDENT3X(unit)) { 37775 rv = _bcm_esw_port_tab_get(unit, port, PORT_OPERATIONf, value); 37776 BCM_IF_ERROR_RETURN(rv); 37777 } 37778 if ((*value == 0x3) && 37779 (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 37780 VRF_IDf))) { 37781 #if defined(BCM_KATANA2_SUPPORT) 37782 if (SOC_IS_KATANA2(unit)) { 37783 rv = _bcm_kt2_source_trunk_map_get(unit, port, VRF_IDf, 37784 (uint32 *)value); 37785 } else 37786 #endif 37787 { 37788 rv = _bcm_trx_source_trunk_map_get(unit, port, VRF_IDf, 37789 (uint32 *)value); 37790 } 37791 } 37792 } 37793 37794 #endif /* BCM_TRIUMPH_SUPPORT */ 37795 return rv; 37796 } 37797 37798 #ifdef BCM_TRIDENT2_SUPPORT 37799 STATIC void 37800 _bcm_flex_port_phy_control_software_rx_los_get(int unit, bcm_port_t control_port) { 37801 int rv = BCM_E_NONE; 37802 bcm_pbmp_t ancillary_pbmp; 37803 bcm_port_t ancillary_port; 37804 uint32 rx_los; 37805 37806 rv = bcm_esw_port_subsidiary_ports_get(unit, control_port, &ancillary_pbmp); 37807 if (BCM_FAILURE(rv)) { 37808 return; 37809 } 37810 PBMP_ITER(ancillary_pbmp, ancillary_port) { 37811 rv = bcm_esw_port_phy_control_get(unit, ancillary_port, BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, &rx_los); 37812 if (BCM_SUCCESS(rv)) { 37813 PORT_INFO_RX_LOS_SET(unit, ancillary_port, BCM_PORT_PHY_CONTROL_SOFTWARE_RX_LOS, rx_los); 37814 } 37815 } 37816 return; 37817 } 37818 #endif 37819 37820 /* 37821 * Function: 37822 * _bcm_esw_port_eee_stat_clear 37823 * Description: 37824 * Clear EEE statistics directly by 37825 * writing EEE counter register to 0 37826 * Parameters: 37827 * unit - Device number 37828 * port - Port number 37829 * Return Value: 37830 * BCM_E_XXX 37831 */ 37832 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \ 37833 defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 37834 STATIC int 37835 _bcm_esw_port_eee_stat_clear(int unit, bcm_port_t port) 37836 { 37837 int idx; 37838 uint64 val64; 37839 soc_reg_t def_regs[] = { 37840 RX_EEE_LPI_DURATION_COUNTERr, 37841 RX_EEE_LPI_EVENT_COUNTERr, 37842 TX_EEE_LPI_DURATION_COUNTERr, 37843 TX_EEE_LPI_EVENT_COUNTERr 37844 }; 37845 soc_reg_t ge_regs[] = { 37846 GRX_EEE_LPI_DURATION_COUNTERr, 37847 GRX_EEE_LPI_EVENT_COUNTERr, 37848 GTX_EEE_LPI_DURATION_COUNTERr, 37849 GTX_EEE_LPI_EVENT_COUNTERr 37850 }; 37851 soc_reg_t *regs = def_regs; 37852 37853 COMPILER_64_ZERO(val64); 37854 37855 if (IS_GE_PORT(unit, port) && !IS_XL_PORT(unit, port)) { 37856 regs = ge_regs; 37857 } 37858 37859 for (idx = 0; idx < sizeof(def_regs) / sizeof(def_regs[0]); idx++) { 37860 SOC_IF_ERROR_RETURN(soc_counter_set(unit, port, regs[idx], 0, val64)); 37861 } 37862 37863 return BCM_E_NONE; 37864 } 37865 #endif 37866 37867 /* 37868 * Function: 37869 * bcm_esw_port_control_set 37870 * Description: 37871 * Enable/Disable specified port feature. 37872 * Parameters: 37873 * unit - Device number 37874 * port - Port number 37875 * type - Enum value of the feature 37876 * value - value to be set 37877 * Return Value: 37878 * BCM_E_NONE 37879 * BCM_E_UNAVAIL - Functionality not available 37880 */ 37881 int 37882 bcm_esw_port_control_set(int unit, bcm_port_t port, 37883 bcm_port_control_t type, int value) 37884 { 37885 int rv = BCM_E_UNAVAIL; 37886 int valid = 0; 37887 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 37888 soc_reg_t egr_port_reg; 37889 #endif 37890 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 37891 int chk_gx_port = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 37892 SOC_IS_VALKYRIE2(unit) || SOC_IS_SCORPION(unit)); 37893 #endif 37894 #if defined(BCM_GREYHOUND_SUPPORT) 37895 int cur_val = 0; 37896 #endif 37897 #if defined (BCM_METROLITE_SUPPORT) 37898 bcm_pbmp_t pbm; 37899 #endif 37900 #if defined(BCM_TOMAHAWK3_SUPPORT) 37901 int_turnaround_en_bmap_entry_t int_turnaround_en_bmap_entry; 37902 bcm_pbmp_t pbmp; 37903 #endif 37904 37905 LOG_INFO(BSL_LS_BCM_PORT, 37906 (BSL_META_U(unit, 37907 "bcm_port_control_set: u=%d p=%d rv=%d : %d\n"), 37908 unit, port, value, (int)type)); 37909 37910 /* Make sure port module is initialized. */ 37911 PORT_INIT(unit); 37912 37913 if(bcm_common_oamp_port_enable_get(unit, port) && 37914 (type != bcmPortControlSatEnable)) { 37915 /* Only bcmPortControlSatEnable is permitted on oamp port */ 37916 LOG_ERROR(BSL_LS_BCM_PORT, 37917 (BSL_META("Error: Not permitted on OAMP port %d.n"), 37918 port)); 37919 return BCM_E_PARAM; 37920 } 37921 37922 /* Call Port Control module */ 37923 if (SOC_USE_PORTCTRL(unit)) { 37924 /* 37925 * Check that port control feature is valid in Port Control. 37926 * If valid, call Port Control routine to handle feature; otherwise 37927 * continue with rest of logic. 37928 */ 37929 BCM_IF_ERROR_RETURN 37930 (bcmi_esw_portctrl_control_validate(unit, type, &valid)); 37931 if (valid) { 37932 return bcmi_esw_portctrl_control_set(unit, port, type, value); 37933 } 37934 } 37935 37936 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 37937 egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 37938 SOC_IS_VALKYRIE2(unit)|| SOC_IS_GREYHOUND(unit) || 37939 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ? 37940 EGR_PORT_64r : EGR_PORTr; 37941 #endif 37942 37943 #if defined(BCM_SHADOW_SUPPORT) 37944 if (SOC_IS_SHADOW(unit)) { 37945 /* If unsupported port control type, return unavail */ 37946 if (!_bcm_port_type_shadow_support (unit, port, type)) { 37947 return BCM_E_UNAVAIL; 37948 } 37949 } 37950 #endif /* BCM_SHADOW_SUPPORT */ 37951 37952 if (type == bcmPortControlEsmEligibility) { 37953 #ifdef BCM_TRIUMPH3_SUPPORT 37954 /* For bcmPortControlEsmEligibility, a non-local port 37955 * is accepted. For other port controls, a non-local 37956 * port is not accepted. Hence, bcmPortControlEsmEligibility 37957 * is implemented here, before the _bcm_esw_port_gport_validate 37958 * procedure below. 37959 */ 37960 return bcm_tr3_port_esm_eligible_set(unit, port, value); 37961 #endif /* BCM_TRIUMPH3_SUPPORT */ 37962 } 37963 37964 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 37965 if ( 37966 #ifdef BCM_HGPROXY_COE_SUPPORT 37967 (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 37968 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) && 37969 ((type == bcmPortControlVlanVpGroupIngress) || 37970 (type == bcmPortControlVlanVpGroupEgress))) || 37971 #endif 37972 BCM_GPORT_IS_TRUNK(port) || 37973 BCM_GPORT_IS_VLAN_PORT(port) || 37974 BCM_GPORT_IS_NIV_PORT(port) || 37975 BCM_GPORT_IS_VXLAN_PORT(port) || 37976 BCM_GPORT_IS_MIM_PORT(port) || 37977 BCM_GPORT_IS_MPLS_PORT(port) || 37978 BCM_GPORT_IS_L2GRE_PORT(port) || 37979 BCM_GPORT_IS_FLOW_PORT(port) || 37980 BCM_GPORT_IS_EXTENDER_PORT(port)) { 37981 return bcm_td_vp_control_set(unit, port, type, value); 37982 } else 37983 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 37984 #if defined(BCM_KATANA2_SUPPORT) 37985 if ((BCM_GPORT_IS_MIM_PORT(port) || BCM_GPORT_IS_MPLS_PORT(port)) 37986 && SOC_IS_KATANA2(unit)) { 37987 rv = BCM_E_NONE; 37988 } else 37989 #endif /* BCM_KATANA2_SUPPORT */ 37990 if ((BCM_GPORT_IS_LOCAL_CPU_IEEE(port)) || 37991 (BCM_GPORT_IS_LOCAL_CPU_HIGIG(port))) { 37992 rv = BCM_E_NONE; 37993 } else 37994 #ifdef BCM_HGPROXY_COE_SUPPORT 37995 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 37996 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 37997 rv = BCM_E_NONE; 37998 } else 37999 #endif 38000 { 38001 rv = bcm_esw_port_control_validate(unit, port, type, &port); 38002 } 38003 BCM_IF_ERROR_RETURN(rv); 38004 rv = BCM_E_UNAVAIL; 38005 38006 /* 38007 * At this point, 'port' can be: 38008 * GPORT WLAN 38009 * GPORT PROXY 38010 * BCM valid local port 38011 * 38012 * Some switch cases only handles 'port' in BCM port format 38013 * (non-gport). Corresponding checks must be added in those 38014 * cases to ensure that 'port' is not a gport. 38015 */ 38016 switch (type) { 38017 case bcmPortControlBridge: 38018 if (BCM_GPORT_IS_SET(port)) { 38019 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38020 PORT_BRIDGEf, value); 38021 } else { 38022 PORT_LOCK(unit); 38023 rv = _bcm_esw_port_control_bridge_set(unit, port, value); 38024 PORT_UNLOCK(unit); 38025 } 38026 break; 38027 case bcmPortControlTrunkHashSet: 38028 #if defined(BCM_TRIUMPH3_SUPPORT) 38029 if (SOC_IS_TRIUMPH3(unit)) { 38030 return BCM_E_UNAVAIL; 38031 } else 38032 #endif /* BCM_TRIUMPH3_SUPPORT */ 38033 { 38034 #if defined(BCM_BRADLEY_SUPPORT) 38035 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 38036 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38037 RTAG7_HASH_CFG_SEL_TRUNKf, 38038 (value) ? 1 : 0); 38039 } 38040 #endif /* BCM_BRADLEY_SUPPORT */ 38041 } 38042 break; 38043 case bcmPortControlFabricTrunkHashSet: 38044 #if defined(BCM_TRIUMPH3_SUPPORT) 38045 if (SOC_IS_TRIUMPH3(unit)) { 38046 return BCM_E_UNAVAIL; 38047 } else 38048 #endif /* BCM_TRIUMPH3_SUPPORT */ 38049 { 38050 #if defined(BCM_BRADLEY_SUPPORT) 38051 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 38052 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38053 RTAG7_HASH_CFG_SEL_HIGIG_TRUNKf, 38054 (value) ? 1 : 0); 38055 } 38056 #endif /* BCM_BRADLEY_SUPPORT */ 38057 } 38058 break; 38059 case bcmPortControlECMPHashSet: 38060 #if defined(BCM_TRIUMPH3_SUPPORT) 38061 if (SOC_IS_TRIUMPH3(unit)) { 38062 return BCM_E_UNAVAIL; 38063 } else 38064 #endif /* BCM_TRIUMPH3_SUPPORT */ 38065 { 38066 #if defined(BCM_BRADLEY_SUPPORT) 38067 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 38068 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38069 RTAG7_HASH_CFG_SEL_ECMPf, 38070 (value) ? 1 : 0); 38071 } 38072 #endif /* BCM_BRADLEY_SUPPORT */ 38073 } 38074 break; 38075 case bcmPortControlLoadBalanceHashSet: 38076 #if defined(BCM_TRIUMPH3_SUPPORT) 38077 if (SOC_IS_TRIUMPH3(unit)) { 38078 return BCM_E_UNAVAIL; 38079 } else 38080 #endif /* BCM_TRIUMPH3_SUPPORT */ 38081 { 38082 #if defined(BCM_BRADLEY_SUPPORT) 38083 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 38084 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38085 RTAG7_HASH_CFG_SEL_LBIDf, 38086 (value) ? 1 : 0); 38087 } 38088 #endif /* BCM_BRADLEY_SUPPORT */ 38089 } 38090 break; 38091 case bcmPortControlLoadBalancingNumber: 38092 #if defined(BCM_BRADLEY_SUPPORT) 38093 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 38094 #if defined(BCM_TOMAHAWK3_SUPPORT) 38095 if (SOC_IS_TOMAHAWK3(unit)) { 38096 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38097 RTAG7_PORT_LBNf, 38098 (value) & 0x3f); 38099 } else 38100 #endif /* BCM_TOMAHAWK3_SUPPORT */ 38101 { 38102 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38103 RTAG7_PORT_LBNf, 38104 (value) & 0xf); 38105 } 38106 } 38107 #endif /* BCM_BRADLEY_SUPPORT */ 38108 break; 38109 case bcmPortControlErrorSymbolDetect: 38110 #if defined(BCM_GREYHOUND_SUPPORT) 38111 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 38112 SOC_IS_GREYHOUND2(unit)) { 38113 rv = BCM_E_UNAVAIL; 38114 } else 38115 #endif /* BCM_GREYHOUND_SUPPORT */ 38116 { 38117 #ifdef BCM_XGS3_SWITCH_SUPPORT 38118 if (SOC_IS_XGS3_SWITCH(unit)) { 38119 rv = _bcm_esw_port_err_sym_detect_set(unit, port, value); 38120 } 38121 #endif 38122 } 38123 break; 38124 case bcmPortControlErrorSymbolCount: 38125 #if defined(BCM_GREYHOUND_SUPPORT) 38126 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 38127 SOC_IS_GREYHOUND2(unit)) { 38128 rv = BCM_E_UNAVAIL; 38129 } else 38130 #endif /* BCM_GREYHOUND_SUPPORT */ 38131 { 38132 #ifdef BCM_XGS3_SWITCH_SUPPORT 38133 if (SOC_IS_XGS3_SWITCH(unit)) { 38134 int temp = 0; 38135 /* Error symbol count is read only and cleared on read. */ 38136 rv = _bcm_esw_port_err_sym_count_get(unit, port, &temp); 38137 } 38138 #endif 38139 } 38140 break; 38141 #if defined(INCLUDE_L3) 38142 case bcmPortControlIP4: 38143 if (SOC_IS_XGS3_SWITCH(unit)) { 38144 if (BCM_GPORT_LOCAL_CPU_IEEE == port) { 38145 rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_ETHER, 38146 V4L3_ENABLEf, (value) ? 1 : 0); 38147 } else if (BCM_GPORT_LOCAL_CPU_HIGIG == port) { 38148 rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_HIGIG, 38149 V4L3_ENABLEf, (value) ? 1 : 0); 38150 } else { 38151 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38152 V4L3_ENABLEf, (value) ? 1 : 0); 38153 } 38154 38155 #if defined(BCM_TRIUMPH_SUPPORT) 38156 if (BCM_SUCCESS(rv) && 38157 soc_feature(unit, soc_feature_esm_support)) { 38158 if (SOC_IS_TRIUMPH3(unit)) { 38159 break; 38160 } 38161 if (!BCM_GPORT_IS_SET(port)) { 38162 rv = _bcm_tr_l3_enable(unit, port, 0, (value) ? 1 : 0); 38163 } 38164 } 38165 #endif /* BCM_TRIUMPH_SUPPORT */ 38166 } 38167 break; 38168 case bcmPortControlIP6: 38169 if (SOC_IS_XGS3_SWITCH(unit)) { 38170 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38171 V6L3_ENABLEf, (value) ? 1 : 0); 38172 #if defined(BCM_TRIUMPH_SUPPORT) 38173 if (BCM_SUCCESS(rv) && 38174 soc_feature(unit, soc_feature_esm_support)) { 38175 if (SOC_IS_TRIUMPH3(unit)) { 38176 break; 38177 } 38178 if (!BCM_GPORT_IS_SET(port)) { 38179 rv = _bcm_tr_l3_enable(unit, port, BCM_L3_IP6, 38180 (value) ? 1 : 0); 38181 } 38182 } 38183 #endif /* BCM_TRIUMPH_SUPPORT */ 38184 } 38185 break; 38186 case bcmPortControlIP4Mcast: 38187 if (SOC_IS_XGS3_SWITCH(unit)) { 38188 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38189 V4IPMC_ENABLEf, (value) ? 1 : 0); 38190 } 38191 break; 38192 case bcmPortControlIP6Mcast: 38193 if (SOC_IS_XGS3_SWITCH(unit)) { 38194 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38195 V6IPMC_ENABLEf, (value) ? 1 : 0); 38196 } 38197 break; 38198 case bcmPortControlIPMC4Ucast: 38199 if (soc_feature(unit, soc_feature_ipmc_unicast)) { 38200 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38201 IPMCV4_UNICAST_MACDA_ENABLEf, (value) ? 1 : 0); 38202 } 38203 break; 38204 case bcmPortControlIPMC6Ucast: 38205 if (soc_feature(unit, soc_feature_ipmc_unicast)) { 38206 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38207 IPMCV6_UNICAST_MACDA_ENABLEf, (value) ? 1 : 0); 38208 } 38209 break; 38210 case bcmPortControlMpls: 38211 #if defined(BCM_TRIUMPH_SUPPORT) 38212 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38213 MPLS_ENABLEf, (value) ? 1 : 0); 38214 #endif 38215 break; 38216 case bcmPortControlMacInMac: 38217 if (!soc_feature(unit, soc_feature_mim)) { 38218 break; 38219 } 38220 #if defined(BCM_TRIUMPH2_SUPPORT) 38221 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38222 MIM_TERM_ENABLEf, (value) ? 1 : 0); 38223 if(rv == BCM_E_NONE) { 38224 #if defined(BCM_TRIDENT3_SUPPORT) 38225 if(SOC_IS_TRIDENT3X(unit)) { 38226 int app = 0; 38227 if (0x0 != value) { 38228 app = CANCUN_APP__PORT_TABLE__MIM_MC_TERM_ENABLE; 38229 } else { 38230 app = CANCUN_APP__PORT_TABLE__MIM_MC_TERM_DISABLE; 38231 } 38232 rv = soc_cancun_app_dest_entry_set (unit, 38233 PORT_TABm, port, PORT_TYPEf, app, 0x0); 38234 if (BCM_E_NONE != rv ) { 38235 LOG_ERROR(BSL_LS_BCM_L2, 38236 (BSL_META_U(unit, 38237 "MIM_MC_TERM_ENABLE cfg error\n"))); 38238 } 38239 } else 38240 #endif 38241 { 38242 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38243 MIM_MC_TERM_ENABLEf, (value) ? 1 : 0); 38244 } 38245 } 38246 #endif 38247 break; 38248 38249 case bcmPortControlMimUcastTermEnable: 38250 if (!soc_feature(unit, soc_feature_mim)) { 38251 break; 38252 } 38253 #if defined(BCM_TRIUMPH2_SUPPORT) 38254 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38255 MIM_TERM_ENABLEf, (value) ? 1 : 0); 38256 #endif 38257 break; 38258 38259 case bcmPortControlMimMcastTermEnable: 38260 if (!soc_feature(unit, soc_feature_mim)) { 38261 break; 38262 } 38263 #if defined(BCM_TRIUMPH2_SUPPORT) 38264 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38265 MIM_MC_TERM_ENABLEf, (value) ? 1 : 0); 38266 #endif 38267 break; 38268 38269 case bcmPortControlSrcBmacMissToCpu: 38270 #ifdef BCM_TRIUMPH2_SUPPORT 38271 if (SOC_IS_TRIDENT3X(unit)) { /* see SDK-124007 */ 38272 return BCM_E_UNAVAIL; 38273 } 38274 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 38275 SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) || 38276 SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || 38277 SOC_IS_KATANA(unit)) { 38278 /* 0x2: ToCPU 0x1: Drop(default) */ 38279 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38280 CML_BMAC_NEWf, (value) ? 0x2 : 0x1); 38281 } 38282 #endif /* BCM_TRIUMPH2_SUPPORT */ 38283 break; 38284 38285 case bcmPortControlQosRemarkResolution: 38286 #ifdef BCM_TRIDENT3_SUPPORT 38287 if (SOC_IS_TRIDENT3X(unit)) { 38288 /* Two resolution supported by TD3 hardware: 38289 * 1: Serial resolution. 38290 * 3: Layered resolution. 38291 * Default is Layered resolution 38292 */ 38293 if (value == BCM_PORT_QOS_SERIAL_RESOLUTION) { 38294 value = 1; 38295 } else if (value == BCM_PORT_QOS_LAYERED_RESOLUTION) { 38296 value = 3; 38297 } else { 38298 return BCM_E_PARAM; 38299 } 38300 rv = _bcm_esw_egr_port_tab_set(unit, port, QOS_CTRL_IDf, value); 38301 } 38302 #endif /* BCM_TRIDENT3_SUPPORT */ 38303 break; 38304 38305 case bcmPortControlFabricQueue: 38306 #if defined(BCM_TRIUMPH2_SUPPORT) 38307 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 38308 #if defined(BCM_TRIDENT3_SUPPORT) 38309 if (SOC_IS_TRIDENT3X(unit) && 38310 soc_feature(unit, soc_feature_egr_lport_tab_profile)) { 38311 rv = bcm_esw_port_egr_lport_field_set( 38312 unit, port, EGR_LPORT_PROFILEm, EH_EXT_HDR_ENABLEf, 38313 (value) ? 1 : 0); 38314 BCM_IF_ERROR_RETURN(rv); 38315 } 38316 #endif 38317 if (IS_ST_PORT(unit, port)) { 38318 if (SOC_REG_FIELD_VALID(unit, EGR_PORT_64r, EH_EXT_HDR_ENABLEf)) { 38319 rv = soc_reg_field32_modify(unit, EGR_PORT_64r, port, 38320 EH_EXT_HDR_ENABLEf,(value) ? 1 : 0); 38321 } 38322 else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EH_EXT_HDR_ENABLEf)){ 38323 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 38324 EH_EXT_HDR_ENABLEf,(value) ? 1 : 0 ); 38325 } 38326 } else { 38327 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 38328 /* Allow CPU port on TD2+ to add extended header */ 38329 if (SOC_IS_TRIDENT2PLUS(unit) && IS_CPU_PORT(unit, port)) { 38330 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 38331 EH_EXT_HDR_ENABLEf,(value) ? 1 : 0 ); 38332 } 38333 #endif 38334 #if defined(BCM_TOMAHAWK_SUPPORT) 38335 if (SOC_IS_TOMAHAWKX(unit) && IS_CPU_PORT(unit, port)) { 38336 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 38337 EH_EXT_HDR_ENABLEf,(value) ? 1 : 0 ); 38338 } 38339 #endif 38340 } 38341 #endif 38342 break; 38343 #endif /* INCLUDE_L3 */ 38344 case bcmPortControlIP4McastL2: 38345 #if defined(BCM_TRX_SUPPORT) 38346 if (SOC_IS_TD2_TT2(unit) && 38347 soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 38348 IPMCV4_L2_ENABLEf)) { 38349 rv = _bcm_trx_source_trunk_map_set(unit, port, 38350 IPMCV4_L2_ENABLEf, (value) ? 1 : 0); 38351 } else { 38352 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38353 V4IPMC_L2_ENABLEf, (value) ? 1 : 0); 38354 } 38355 #endif /* BCM_TRX_SUPPORT */ 38356 break; 38357 case bcmPortControlIP6McastL2: 38358 #if defined(BCM_TRX_SUPPORT) 38359 if (SOC_IS_TD2_TT2(unit) && 38360 soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 38361 IPMCV6_L2_ENABLEf)) { 38362 rv = _bcm_trx_source_trunk_map_set(unit, port, 38363 IPMCV6_L2_ENABLEf, (value) ? 1 : 0); 38364 } else { 38365 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38366 V6IPMC_L2_ENABLEf, (value) ? 1 : 0); 38367 } 38368 #endif /* BCM_TRX_SUPPORT */ 38369 break; 38370 case bcmPortControlPassControlFrames: 38371 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 38372 #ifdef BCM_XGS3_SWITCH_SUPPORT 38373 if (SOC_IS_XGS3_SWITCH(unit) && IS_E_PORT(unit, port)) { 38374 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 38375 PASS_CONTROL_FRAMESf, 38376 (value) ? 1 : 0); 38377 } 38378 #endif 38379 #ifdef BCM_XGS_SWITCH_SUPPORT 38380 if (IS_XE_PORT(unit, port) || IS_CE_PORT(unit, port) || 38381 (IS_GE_PORT(unit, port) 38382 && soc_feature(unit, soc_feature_unified_port)) || 38383 (SOC_IS_KATANAX(unit) && IS_MXQ_PORT(unit, port))) { 38384 /* Enable Control Frames in BigMAC */ 38385 if(soc_feature(unit, soc_feature_pgw_mac_control_frame)) { 38386 uint32 rval32 = 0; 38387 PORT_LOCK(unit); 38388 rv = READ_PGW_MAC_RSV_MASKr(unit, port, &rval32); 38389 if (BCM_SUCCESS(rv)) { 38390 /* PGW_MAC_RSV_MASK: Bit 11 Control Frame recieved 38391 * Enable Control Frame : Set 0. Packet go through 38392 * Disable Control Frame : Set 1. Packet is purged. 38393 */ 38394 if(value) { 38395 rval32 &= ~(1 << 11); 38396 } else { 38397 rval32 |= (1 << 11); 38398 } 38399 rv = WRITE_PGW_MAC_RSV_MASKr(unit, port, rval32); 38400 } 38401 PORT_UNLOCK(unit); 38402 } else { 38403 PORT_LOCK(unit); 38404 38405 if (SOC_IS_SABER2(unit)) { 38406 if (IS_MXQ_PORT(unit, port)) { 38407 rv = soc_reg_field32_modify(unit, XPORT_CONFIGr, port, 38408 PASS_PAUSE_FRAMEf, value ? 1 : 0); 38409 if (rv == SOC_E_NONE) 38410 rv = soc_reg_field32_modify(unit, XPORT_CONFIGr, port, 38411 PASS_CONTROL_FRAMEf, value ? 1 : 0); 38412 } else { 38413 rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port, 38414 PASS_PAUSE_FRAMEf, value ? 1 : 0); 38415 if (rv == SOC_E_NONE) 38416 rv = soc_reg_field32_modify(unit, IECELL_CONFIGr, port, 38417 PASS_CONTROL_FRAMEf, value ? 1 : 0); 38418 } 38419 } 38420 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 38421 SOC_MAC_PASS_CONTROL_FRAME, value); 38422 PORT_UNLOCK(unit); 38423 } 38424 } 38425 #endif 38426 break; 38427 #ifdef BCM_XGS3_SWITCH_SUPPORT 38428 case bcmPortControlFilterLookup: 38429 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 38430 value = value ? 1 : 0; 38431 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38432 VFP_ENABLEf, value); 38433 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 38434 break; 38435 case bcmPortControlFilterIngress: 38436 value = value ? 1 : 0; 38437 /* Enable/disable ingress filtering. */ 38438 if (BCM_GPORT_LOCAL_CPU_IEEE == port) { 38439 rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_ETHER, 38440 FILTER_ENABLEf, value); 38441 } else if (BCM_GPORT_LOCAL_CPU_HIGIG == port) { 38442 rv = _bcm_esw_port_tab_set(unit, CMIC_PORT(unit), _BCM_CPU_TABS_HIGIG, 38443 FILTER_ENABLEf, value); 38444 } else { 38445 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38446 FILTER_ENABLEf, value); 38447 } 38448 38449 break; 38450 case bcmPortControlFilterEgress: 38451 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 38452 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 38453 value = value ? 1 : 0; 38454 /* Enable/disable egress filtering. */ 38455 if (SOC_REG_FIELD_VALID(unit, egr_port_reg, EFP_FILTER_ENABLEf)) { 38456 rv = soc_reg_field32_modify(unit, egr_port_reg, port, 38457 EFP_FILTER_ENABLEf, value); 38458 } else { 38459 rv = _bcm_esw_egr_port_tab_set(unit, port, 38460 EFP_FILTER_ENABLEf, value); 38461 } 38462 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 38463 break; 38464 case bcmPortControlFrameSpacingStretch: 38465 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 38466 rv = (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 38467 SOC_MAC_CONTROL_FRAME_SPACING_STRETCH, 38468 value)); 38469 break; 38470 case bcmPortControlPreservePacketPriority: 38471 #if ((defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT)) \ 38472 || defined(BCM_RAVEN_SUPPORT)) 38473 if (SOC_IS_TRIUMPH3(unit)) { 38474 /* Triumph3 has unity mapping to ING_OUTER_DOT1P_MAPPING_TABLE */ 38475 if (value) { 38476 /* Remap pointer to default dot1p profile */ 38477 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38478 DOT1P_REMAP_POINTERf, 0); 38479 } 38480 } else { 38481 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38482 USE_INCOMING_DOT1Pf, (value) ? 1 : 0); 38483 } 38484 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT || defined(BCM_RAVEN_SUPPORT) */ 38485 #if defined(BCM_SHADOW_SUPPORT) 38486 if (SOC_IS_SHADOW(unit)) { 38487 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 38488 rv = soc_reg_field32_modify(unit, PRIORITY_MAPPING_SELECTr, port, 38489 USE_INPUT_PRIORIYf, 1 ); 38490 } 38491 #endif 38492 break; 38493 case bcmPortControlLearnClassEnable: 38494 #if defined(BCM_TRX_SUPPORT) 38495 if (soc_feature(unit, soc_feature_class_based_learning)) { 38496 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38497 CLASS_BASED_SM_ENABLEf, value ? 1 : 0); 38498 } 38499 #endif /* BCM_TRX_SUPPORT */ 38500 break; 38501 case bcmPortControlTrustIncomingVlan: 38502 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT) 38503 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38504 TRUST_INCOMING_VIDf, (value) ? 1 : 0); 38505 #endif /* BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 38506 break; 38507 case bcmPortControlDoNotCheckVlan: 38508 #if defined(BCM_TRX_SUPPORT) 38509 #if defined(BCM_TRIDENT3_SUPPORT) 38510 if (SOC_IS_TRIDENT3X(unit)) { 38511 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38512 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 38513 BCM_IF_ERROR_RETURN(rv); 38514 } 38515 #endif 38516 if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf)) { 38517 if (CMIC_PORT(unit) == port) { 38518 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_HIGIG, 38519 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 38520 } else { 38521 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38522 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 38523 } 38524 } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 38525 DISABLE_VLAN_CHECKSf)) { 38526 #if defined(BCM_KATANA2_SUPPORT) 38527 if (SOC_IS_KATANA2(unit)) { 38528 rv = _bcm_kt2_source_trunk_map_set(unit, port, 38529 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 38530 } else 38531 #endif 38532 { 38533 rv = _bcm_trx_source_trunk_map_set(unit, port, 38534 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 38535 } 38536 } 38537 #endif /* BCM_TRX_SUPPORT */ 38538 break; 38539 case bcmPortControlDoNotCheckVlanFromCpu: 38540 #if defined(BCM_TRX_SUPPORT) 38541 #if defined(BCM_TRIDENT3_SUPPORT) 38542 if (CMIC_PORT(unit) == port) { 38543 if (SOC_IS_TRIDENT3X(unit)) { 38544 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38545 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 38546 BCM_IF_ERROR_RETURN(rv); 38547 } 38548 } 38549 #endif 38550 if (CMIC_PORT(unit) == port) { 38551 if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf)) { 38552 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 38553 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 38554 } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 38555 DISABLE_VLAN_CHECKSf)) { 38556 rv = _bcm_trx_source_trunk_map_set(unit, port, 38557 DISABLE_VLAN_CHECKSf, (value) ? 1 : 0); 38558 } 38559 } else { 38560 rv = BCM_E_PORT; 38561 } 38562 #endif /* BCM_TRX_SUPPORT */ 38563 break; 38564 case bcmPortControlIEEE8021ASEnableIngress: 38565 if (soc_feature(unit, soc_feature_rx_timestamp)) { 38566 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38567 IEEE_802_1AS_ENABLEf, (value) ? 1 : 0); 38568 } 38569 break; 38570 case bcmPortControlIEEE8021ASEnableEgress: 38571 #if defined(BCM_HAWKEYE_SUPPORT) 38572 if (SOC_IS_HAWKEYE(unit)) { 38573 rv = soc_reg_field32_modify(unit, EGR_PORTr, port, 38574 IEEE_802_1AS_ENABLEf, (value) ? 1 : 0); 38575 } 38576 #endif /* BCM_HAWKEYE_SUPPORT */ 38577 break; 38578 case bcmPortControlEgressVlanPriUsesPktPri: 38579 #if defined(BCM_TRX_SUPPORT) 38580 if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) { 38581 #if defined (BCM_HGPROXY_COE_SUPPORT) 38582 if (!(soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 38583 BCM_GPORT_IS_SUBPORT_PORT(port))) 38584 #endif 38585 { 38586 BCM_IF_ERROR_RETURN( 38587 _bcm_esw_port_gport_validate(unit, port, &port)); 38588 } 38589 #ifdef BCM_TRIDENT2PLUS_SUPPORT 38590 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 38591 if (soc_feature(unit, soc_feature_egr_all_profile)) { 38592 rv = bcm_esw_port_egr_lport_field_set(unit, 38593 port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DOT1Pf, 38594 value ? 0 : 1); 38595 } else { 38596 #if defined (BCM_HGPROXY_COE_SUPPORT) 38597 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 38598 BCM_GPORT_IS_SUBPORT_PORT(port)) { 38599 rv = bcm_esw_port_egr_lport_field_set( 38600 unit, port, EGR_VLAN_CONTROL_1m, 38601 REMARK_OUTER_DOT1Pf, value ? 0 : 1); 38602 } else 38603 #endif 38604 { 38605 rv = soc_mem_field32_modify( 38606 unit, EGR_VLAN_CONTROL_1m, port, 38607 REMARK_OUTER_DOT1Pf, value ? 0 : 1); 38608 } 38609 } 38610 } else 38611 #endif 38612 { 38613 rv = soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port, 38614 REMARK_OUTER_DOT1Pf, 38615 value ? 0 : 1); 38616 #if defined(BCM_GREYHOUND_SUPPORT) 38617 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 38618 if (BCM_FAILURE(rv)) { 38619 return rv; 38620 } 38621 /* 38622 * Make sure TREAT_PKTPRI_AS_DOT1P bit is set for 38623 * Egress VLAN internal priority mapping. 38624 */ 38625 rv = bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 38626 (unit, (value) ? 1 : -1); 38627 } 38628 #endif /* BCM_GREYHOUND_SUPPORT */ 38629 } 38630 } 38631 #endif /* BCM_TRX_SUPPORT */ 38632 break; 38633 case bcmPortControlEgressModifyDscp: 38634 #if defined(BCM_TRX_SUPPORT) 38635 if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) { 38636 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 38637 #ifdef BCM_TRIDENT2PLUS_SUPPORT 38638 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 38639 if (soc_feature(unit, soc_feature_egr_all_profile)) { 38640 rv = bcm_esw_port_egr_lport_field_set(unit, 38641 port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DSCPf, 38642 value ? 1 : 0); 38643 } else { 38644 rv = soc_mem_field32_modify(unit, 38645 EGR_VLAN_CONTROL_1m, port, REMARK_OUTER_DSCPf, 38646 value ? 1 : 0); 38647 } 38648 } else 38649 #endif 38650 { 38651 rv = soc_reg_field32_modify(unit, EGR_VLAN_CONTROL_1r, port, 38652 REMARK_OUTER_DSCPf, 38653 value ? 1 : 0); 38654 } 38655 } 38656 #endif /* BCM_TRX_SUPPORT */ 38657 break; 38658 case bcmPortControlIpfixRate: 38659 #ifdef BCM_TRIUMPH2_SUPPORT 38660 if (soc_feature(unit, soc_feature_ipfix_rate)) { 38661 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38662 IPFIX_FLOW_METER_IDf, value); 38663 } 38664 #endif /* BCM_TRIUMPH2_SUPPORT */ 38665 break; 38666 case bcmPortControlCustomerQueuing: 38667 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 38668 #ifdef BCM_ENDURO_SUPPORT 38669 if (SOC_IS_ENDURO(unit) && !IS_HG_PORT(unit, port)) { 38670 return BCM_E_UNAVAIL; 38671 } 38672 #endif 38673 #ifdef BCM_HELIX5_SUPPORT 38674 if (SOC_IS_HELIX5(unit)) { 38675 uint64 rval64, rval64_tmp, rval64_reset_tmp; 38676 soc_reg_t reg; 38677 uint32 phy_port; 38678 uint32 mmu_port; 38679 soc_info_t *si = &SOC_INFO(unit); 38680 38681 if (value < 0 || value > 1) { 38682 return BCM_E_PARAM; 38683 } 38684 38685 COMPILER_64_ZERO(rval64); 38686 COMPILER_64_ZERO(rval64_tmp); 38687 COMPILER_64_ZERO(rval64_reset_tmp); 38688 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval64); 38689 BCM_IF_ERROR_RETURN(rv); 38690 soc_reg64_field32_set(unit, ING_COS_MODEr, &rval64, COS_MODEf, 38691 value); 38692 rv = soc_reg_set(unit, ING_COS_MODEr, port, 0, rval64); 38693 BCM_IF_ERROR_RETURN(rv); 38694 38695 phy_port = si->port_l2p_mapping[port]; 38696 mmu_port = si->port_p2m_mapping[phy_port]; 38697 mmu_port &= (SOC_HX5_MMU_PORT_STRIDE - 1); 38698 38699 if (mmu_port < 16) { 38700 reg = COS_MODE_SPLIT0r; /* 2 bits per Port 0-15 */ 38701 COMPILER_64_SET(rval64_tmp, 0, (1 << (mmu_port * 2))); 38702 COMPILER_64_SET(rval64_reset_tmp, 0, (3 << (mmu_port * 2))); 38703 } else { 38704 reg = COS_MODE_64_SPLIT1r; /* 1 bit per Port 16-71 */ 38705 mmu_port -= 16; 38706 if (mmu_port < 32) { 38707 COMPILER_64_SET(rval64_tmp, 0, (1 << mmu_port)); 38708 } else { 38709 COMPILER_64_SET(rval64_tmp, (1 << (mmu_port - 32)), 0); 38710 } 38711 COMPILER_64_COPY(rval64_reset_tmp, rval64_tmp); 38712 } 38713 38714 SOC_IF_ERROR_RETURN 38715 (soc_trident3_xpe_reg_get(unit, reg, -1, si->port_pipe[port], 38716 0, &rval64)); 38717 if (value) { 38718 COMPILER_64_OR(rval64, rval64_tmp); 38719 } else { 38720 COMPILER_64_NOT(rval64_reset_tmp); 38721 COMPILER_64_AND(rval64, rval64_reset_tmp); 38722 } 38723 SOC_IF_ERROR_RETURN 38724 (soc_trident3_xpe_reg_set(unit, reg, -1, si->port_pipe[port], 38725 0, rval64)); 38726 rv = BCM_E_NONE; 38727 break; 38728 } 38729 #endif /* BCM_HELIX5_SUPPORT */ 38730 #ifdef BCM_TRIDENT3_SUPPORT 38731 if (SOC_IS_TRIDENT3X(unit)) { 38732 uint64 rval64, rval64_tmp; 38733 soc_reg_t reg; 38734 uint32 pipe_portNum; 38735 soc_info_t *si = &SOC_INFO(unit); 38736 38737 if (value < 0 || value > 1) { 38738 return BCM_E_PARAM; 38739 } 38740 38741 COMPILER_64_ZERO(rval64); 38742 COMPILER_64_ZERO(rval64_tmp); 38743 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval64); 38744 BCM_IF_ERROR_RETURN(rv); 38745 soc_reg64_field32_set(unit, ING_COS_MODEr, &rval64, COS_MODEf, 38746 value); 38747 rv = soc_reg_set(unit, ING_COS_MODEr, port, 0, rval64); 38748 BCM_IF_ERROR_RETURN(rv); 38749 38750 pipe_portNum = port % _TD3_PORTS_PER_PIPE; 38751 if (pipe_portNum < 64) { 38752 reg = COS_MODE_64_SPLIT0r; 38753 } else { 38754 reg = COS_MODE_SPLIT1r; 38755 } 38756 38757 if (pipe_portNum < 32) { 38758 COMPILER_64_SET(rval64_tmp, 0, (1 << pipe_portNum)); 38759 } else { 38760 COMPILER_64_SET(rval64_tmp, (1 << (pipe_portNum - 32)), 0); 38761 } 38762 38763 SOC_IF_ERROR_RETURN 38764 (soc_trident3_xpe_reg_get(unit, reg, -1, si->port_pipe[port], 38765 0, &rval64)); 38766 if (value) { 38767 COMPILER_64_OR(rval64, rval64_tmp); 38768 } else { 38769 COMPILER_64_NOT(rval64_tmp); 38770 COMPILER_64_AND(rval64, rval64_tmp); 38771 } 38772 38773 SOC_IF_ERROR_RETURN 38774 (soc_trident3_xpe_reg_set(unit, reg, -1, si->port_pipe[port], 38775 0, rval64)); 38776 rv = BCM_E_NONE; 38777 break; 38778 } 38779 #endif /* BCM_TRIDENT3_SUPPORT */ 38780 #ifdef BCM_TOMAHAWK_SUPPORT 38781 if (SOC_IS_TOMAHAWKX(unit)) { 38782 uint64 rval64, rval64_tmp; 38783 int pipe, phy_port, mmu_port; 38784 soc_info_t *si; 38785 38786 if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) { 38787 38788 if (value < 0 || value > 1) { 38789 return BCM_E_PARAM; 38790 } 38791 38792 COMPILER_64_ZERO(rval64); 38793 COMPILER_64_ZERO(rval64_tmp); 38794 38795 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval64); 38796 BCM_IF_ERROR_RETURN(rv); 38797 soc_reg64_field32_set(unit, ING_COS_MODEr, &rval64, COS_MODEf, 38798 value); 38799 rv = soc_reg_set(unit, ING_COS_MODEr, port, 0, rval64); 38800 BCM_IF_ERROR_RETURN(rv); 38801 38802 SOC_IF_ERROR_RETURN(soc_port_pipe_get(unit, port, &pipe)); 38803 si = &SOC_INFO(unit); 38804 phy_port = si->port_l2p_mapping[port]; 38805 mmu_port = si->port_p2m_mapping[phy_port]; 38806 mmu_port &= (SOC_TH_MMU_PORT_STRIDE - 1); 38807 38808 COMPILER_64_SET(rval64_tmp, 0, (1 << mmu_port)); 38809 COMPILER_64_ZERO(rval64); 38810 SOC_IF_ERROR_RETURN 38811 (soc_tomahawk_xpe_reg_get(unit, COS_MODE_64r, -1, pipe, 0, 38812 &rval64)); 38813 if (value) { 38814 COMPILER_64_OR(rval64, rval64_tmp); 38815 } else { 38816 COMPILER_64_NOT(rval64_tmp); 38817 COMPILER_64_AND(rval64, rval64_tmp); 38818 } 38819 38820 SOC_IF_ERROR_RETURN 38821 (soc_tomahawk_xpe_reg_set(unit, COS_MODE_64r, -1, pipe, 0, 38822 rval64)); 38823 rv = BCM_E_NONE; 38824 } 38825 break; 38826 } 38827 #endif /* BCM_TOMAHAWK_SUPPORT */ 38828 38829 #ifdef BCM_TRIDENT2_SUPPORT 38830 if (SOC_IS_TD2_TT2(unit)) { 38831 uint32 fval = 0; 38832 uint64 rval; 38833 38834 if (value <= 4) { 38835 fval = value; 38836 } 38837 38838 if (!SOC_REG_FIELD_VALID(unit, ING_COS_MODE_64r, QUEUE_MODEf)) { 38839 return BCM_E_UNAVAIL; 38840 } 38841 38842 rv = READ_ING_COS_MODE_64r(unit, port, &rval); 38843 BCM_IF_ERROR_RETURN(rv); 38844 38845 soc_reg64_field32_set(unit, ING_COS_MODE_64r, &rval, 38846 QUEUE_MODEf, fval); 38847 rv = WRITE_ING_COS_MODE_64r(unit, port, rval); 38848 break; 38849 } 38850 #endif /* BCM_TRIDENT2_SUPPORT */ 38851 #ifdef BCM_TRIUMPH2_SUPPORT 38852 if (soc_feature(unit, soc_feature_vlan_queue_map)) { 38853 uint32 fval = 0; 38854 if (SOC_IS_TRIUMPH3(unit)) { 38855 if (value <= 4) { 38856 fval = value; 38857 } 38858 } else { 38859 if (value) { 38860 fval = 3; 38861 } else { 38862 fval = 0; 38863 } 38864 } 38865 38866 rv = BCM_E_UNAVAIL; 38867 38868 if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) { 38869 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, SELECTf)) { 38870 rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port, 38871 SELECTf, fval); 38872 } 38873 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, QUEUE_MODEf)) { 38874 rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port, 38875 QUEUE_MODEf, fval); 38876 /* 0 - COS1 port COS, 1 - COS2 vlan COS */ 38877 rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port, 38878 COS_MODEf, 1); 38879 38880 } 38881 } 38882 if (SOC_REG_IS_VALID(unit, COS_MODEr)) { 38883 if (SOC_REG_FIELD_VALID(unit, COS_MODEr, SELECTf)) { 38884 rv = soc_reg_field32_modify(unit, COS_MODEr, REG_PORT_ANY, 38885 SELECTf, fval); 38886 } 38887 } 38888 38889 } 38890 #endif /* BCM_TRIUMPH2_SUPPORT */ 38891 #ifdef BCM_KATANA_SUPPORT 38892 if (SOC_IS_KATANAX(unit)) { 38893 uint32 ing_cos_mode ; 38894 uint32 rqe_cos_mode; 38895 uint32 rval = 0; 38896 /* 38897 * If custom queueing is enabled the ing_cos_mode is set to 1 but 1 is not 38898 * valid for rqe_cos_mode 38899 * setting it to 0 if the ing_cos_mode is 1. 38900 * if value is 4 that means configure service queuing only for unicast 38901 * traffic. i.e if value = 4 then ing_cos_mode = 3 and rqe_cos_mode 0 or 2. 38902 */ if (value == 4) { 38903 ing_cos_mode = 3; 38904 } else { 38905 ing_cos_mode = (value <= 3 ? value : 0); 38906 } 38907 if (IS_HG_PORT(unit, port)) { 38908 rqe_cos_mode = ((ing_cos_mode == 1) || (value == 4)) ? 2 : ing_cos_mode; 38909 } else { 38910 rqe_cos_mode = ((ing_cos_mode == 1) || (value == 4)) ? 0 : ing_cos_mode; 38911 } 38912 38913 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, COS_MODEf)) { 38914 rv = soc_reg_field32_modify(unit, ING_COS_MODEr, port, 38915 COS_MODEf, ing_cos_mode); 38916 } 38917 38918 if (SOC_IS_KATANA(unit)) { 38919 SOC_IF_ERROR_RETURN(READ_RQE_PORT_CONFIGr(unit, port, &rval)); 38920 soc_reg_field_set(unit, RQE_PORT_CONFIGr, &rval, COS_MODEf, 38921 rqe_cos_mode); 38922 SOC_IF_ERROR_RETURN(WRITE_RQE_PORT_CONFIGr(unit, port, rval)); 38923 } else { 38924 #if defined(BCM_KATANA2_SUPPORT) 38925 if (SOC_IS_KATANA2(unit)) { 38926 SOC_IF_ERROR_RETURN(READ_RQE_PP_PORT_CONFIGr(unit, port, &rval)); 38927 soc_reg_field_set(unit, RQE_PP_PORT_CONFIGr, &rval, COS_MODEf, 38928 rqe_cos_mode); 38929 SOC_IF_ERROR_RETURN(WRITE_RQE_PP_PORT_CONFIGr(unit, port, rval)); 38930 } 38931 #endif 38932 } 38933 } 38934 #endif /* BCM_KATANA_SUPPORT */ 38935 break; 38936 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 38937 38938 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT) 38939 case bcmPortControlOAMEnable: 38940 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 38941 OAM_ENABLEf, value ? 1 : 0); 38942 #if defined(BCM_KATANA2_SUPPORT) 38943 if (SOC_IS_KATANA2(unit)) { 38944 rv = _bcm_esw_egr_port_tab_set(unit, port, 38945 OAM_ENABLEf, value ? 1 : 0); 38946 } 38947 #endif 38948 break; 38949 #endif /* defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT) */ 38950 38951 #if defined(BCM_OLP_SUPPORT) 38952 case bcmPortControlOlpEnable: 38953 38954 if (soc_feature(unit, soc_feature_olp)) { 38955 ing_en_efilter_bitmap_entry_t efilter_entry; 38956 bcm_module_t module_id = 0; 38957 bcm_module_t my_modid; 38958 bcm_port_t port_id; 38959 bcm_trunk_t trunk_id = BCM_TRUNK_INVALID; 38960 int local_id; 38961 uint32 olp_enable; 38962 pbmp_t pbmp; 38963 38964 olp_enable = value ? 1 : 0; 38965 38966 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 38967 38968 if (BCM_GPORT_IS_SET(port)) { 38969 SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, &module_id, 38970 &port_id, &trunk_id, &local_id)); 38971 38972 #if defined(BCM_KATANA2_SUPPORT) 38973 if (SOC_IS_KATANA2(unit) && 38974 (BCM_GPORT_IS_SUBPORT_PORT(port)) && 38975 ((_BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) || 38976 (_BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)))) { 38977 38978 LOG_ERROR(BSL_LS_BCM_L2, 38979 (BSL_META_U(unit, 38980 "OLP is not allowed on SUBPORT. \ 38981 \n"))); 38982 return BCM_E_PARAM; 38983 } 38984 #endif 38985 } else { 38986 port_id = port; 38987 } 38988 if ((module_id == 0) || (module_id == my_modid)) { 38989 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 38990 if(SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 38991 iarb_ing_port_table_entry_t entry; 38992 port_tab_entry_t port_entry; 38993 uint64 mac; 38994 int prefix_check = 0; 38995 38996 SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PORT_TABLEm, 38997 MEM_BLOCK_ANY, port_id, &entry)); 38998 soc_IARB_ING_PORT_TABLEm_field32_set(unit, &entry, 38999 OLP_ENABLEf, olp_enable); 39000 SOC_IF_ERROR_RETURN(soc_mem_write(unit, IARB_ING_PORT_TABLEm, 39001 MEM_BLOCK_ALL, port_id, &entry)); 39002 39003 39004 /* Enable/Disable the prefix checking on the OLP port 39005 * If OLP is being enabled - Disable prefix checking 39006 * If OLP is being disabled - Enable prefix checking if it 39007 * is configured. 39008 */ 39009 prefix_check = 0; 39010 if (0 == olp_enable) { 39011 SOC_IF_ERROR_RETURN(READ_ING_OLP_CONFIG_0_64r(unit, &mac)); 39012 if (!COMPILER_64_IS_ZERO(mac)) { 39013 prefix_check = 1; 39014 } 39015 } 39016 SOC_IF_ERROR_RETURN(READ_PORT_TABm(unit, 39017 MEM_BLOCK_ANY, 39018 port_id, 39019 &port_entry)); 39020 soc_PORT_TABm_field32_set(unit, 39021 &port_entry, 39022 OLP_MAC_DA_PREFIX_CHECK_ENABLEf, 39023 prefix_check); 39024 39025 SOC_IF_ERROR_RETURN(WRITE_PORT_TABm(unit, 39026 MEM_BLOCK_ALL, 39027 port_id, 39028 &port_entry)); 39029 } else 39030 #endif 39031 { 39032 iarb_ing_physical_port_entry_t entry; 39033 ing_physical_port_table_entry_t port_entry; 39034 uint64 mac; 39035 int prefix_check = 0; 39036 39037 SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PHYSICAL_PORTm, 39038 MEM_BLOCK_ANY, port_id, &entry)); 39039 soc_IARB_ING_PHYSICAL_PORTm_field32_set(unit, &entry, 39040 OLP_ENABLEf, olp_enable); 39041 SOC_IF_ERROR_RETURN(soc_mem_write(unit, IARB_ING_PHYSICAL_PORTm, 39042 MEM_BLOCK_ALL, port_id, &entry)); 39043 39044 /* Enable/Disable the prefix checking on the OLP port 39045 * If OLP is being enabled - Disable prefix checking 39046 * If OLP is being disabled - Enable prefix checking if it 39047 * is configured. 39048 */ 39049 prefix_check = 0; 39050 if (0 == olp_enable) { 39051 SOC_IF_ERROR_RETURN(READ_ING_OLP_CONFIG_0_64r(unit, &mac)); 39052 if (!COMPILER_64_IS_ZERO(mac)) { 39053 prefix_check = 1; 39054 } 39055 } 39056 SOC_IF_ERROR_RETURN( 39057 READ_ING_PHYSICAL_PORT_TABLEm(unit, 39058 MEM_BLOCK_ANY, 39059 port_id, 39060 &port_entry)); 39061 39062 soc_ING_PHYSICAL_PORT_TABLEm_field32_set(unit, 39063 &port_entry, 39064 OLP_MAC_DA_PREFIX_CHECK_ENABLEf, 39065 prefix_check); 39066 SOC_IF_ERROR_RETURN( 39067 WRITE_ING_PHYSICAL_PORT_TABLEm(unit, 39068 MEM_BLOCK_ALL, 39069 port_id, 39070 &port_entry)); 39071 } 39072 /* Disable EFILTER */ 39073 SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm, 39074 MEM_BLOCK_ANY, 0, &efilter_entry)); 39075 soc_mem_pbmp_field_get(unit, ING_EN_EFILTER_BITMAPm, 39076 &efilter_entry, BITMAPf, &pbmp); 39077 if (olp_enable) { 39078 SOC_PBMP_PORT_REMOVE(pbmp, port_id); 39079 } else { 39080 SOC_PBMP_PORT_ADD(pbmp, port_id); 39081 } 39082 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, 39083 &efilter_entry, BITMAPf, &pbmp); 39084 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm, 39085 MEM_BLOCK_ALL, 0, &efilter_entry)); 39086 } 39087 rv = BCM_E_NONE; 39088 } 39089 break; 39090 #endif /* BCM_OLP_SUPPORT */ 39091 39092 #if defined(BCM_KATANA2_SUPPORT) || defined (BCM_APACHE_SUPPORT) 39093 case bcmPortControlPortMacOui: 39094 case bcmPortControlPortMacNonOui: 39095 39096 /* 39097 * In case of KT2, SB2 and TD2+ NONTCAM STATION related to OAM, OLP, XGS can be programmed 39098 * by either of bcm_l2_station_xxx API or bcm_switch_olp_l2_addr_xxx 39099 * 39100 * Use either of two set of APIs 39101 */ 39102 39103 if (_BCM_SWITCH_OLP_APIV(unit) == _BCM_SWITCH_OLP_L2_STATION_API) { 39104 LOG_VERBOSE(BSL_LS_BCM_L2, 39105 (BSL_META_U(unit, 39106 "use bcm_l2_station_xxx API\n"))); 39107 return BCM_E_UNAVAIL; 39108 } 39109 _BCM_SWITCH_OLP_APIV_SET(unit, _BCM_SWITCH_OLP_TRUE_API); 39110 39111 #if defined(BCM_KATANA2_SUPPORT) 39112 if (SOC_IS_KATANA2(unit) && 39113 (soc_feature(unit, soc_feature_oam) || 39114 soc_feature(unit, soc_feature_sat))) { 39115 uint32 val_lo, val_hi; 39116 uint64 mac_field; 39117 39118 PORT_LOCK(unit); 39119 39120 rv = _bcm_kt2_port_mac_get(unit, port, &mac_field); 39121 39122 if (BCM_FAILURE(rv)) { 39123 PORT_UNLOCK(unit); 39124 return (rv); 39125 } 39126 39127 COMPILER_64_TO_32_LO(val_lo, mac_field); 39128 COMPILER_64_TO_32_HI(val_hi, mac_field); 39129 39130 switch (type) { 39131 case bcmPortControlPortMacOui: 39132 val_lo = (val_lo & 0xffffff) | ((value & 0xff) << 24); 39133 val_hi = (value >> 8) & 0xffff; 39134 COMPILER_64_SET(mac_field, val_hi, val_lo); 39135 break; 39136 39137 case bcmPortControlPortMacNonOui: 39138 val_lo = (val_lo & 0xff000000) | (value & 0xffffff); 39139 COMPILER_64_SET(mac_field, val_hi, val_lo); 39140 break; 39141 39142 default: 39143 break; 39144 } 39145 39146 rv = _bcm_kt2_port_mac_set(unit, port, mac_field); 39147 PORT_UNLOCK(unit); 39148 } 39149 #endif /* BCM_KATANA2_SUPPORT */ 39150 39151 #if defined(BCM_MONTEREY_SUPPORT) 39152 if (SOC_IS_MONTEREY(unit)) { 39153 PORT_LOCK(unit); 39154 rv = _bcm_monterey_port_mac_set(unit, 39155 port, 39156 type == bcmPortControlPortMacOui, 39157 value); 39158 PORT_UNLOCK(unit); 39159 } 39160 #endif /* BCM_MONTEREY_SUPPORT */ 39161 #if defined(BCM_APACHE_SUPPORT) 39162 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 39163 PORT_LOCK(unit); 39164 rv = _bcm_apache_port_mac_set(unit, 39165 port, 39166 type == bcmPortControlPortMacOui, 39167 value); 39168 PORT_UNLOCK(unit); 39169 } 39170 #endif /* BCM_APACHE_SUPPORT */ 39171 break; 39172 #endif /* BCM_KATANA2_SUPPORT || BCM_APACHE_SUPPORT */ 39173 #ifdef BCM_TRX_SUPPORT 39174 case bcmPortControlOamLoopback: 39175 if (SOC_IS_TRX(unit) && !SOC_IS_HURRICANE(unit) 39176 && !SOC_IS_SHADOW(unit)) { 39177 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39178 39179 if (soc_reg_field_valid(unit,ING_MISC_PORT_CONFIGr, 39180 OAM_DO_NOT_MODIFYf)) { 39181 39182 rv = soc_reg_field32_modify(unit, ING_MISC_PORT_CONFIGr, port, 39183 OAM_DO_NOT_MODIFYf, value ? 1 : 0); 39184 } else { 39185 return BCM_E_UNAVAIL; 39186 } 39187 } 39188 39189 break; 39190 #endif /* BCM_TRX_SUPPORT */ 39191 39192 case bcmPortControlLanes: 39193 if (soc_feature(unit, soc_feature_flexport_no_legacy)) { 39194 return BCM_E_UNAVAIL; 39195 } 39196 #if defined(BCM_TRIUMPH2_SUPPORT) 39197 if (soc_feature(unit, soc_feature_flex_port)) { 39198 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39199 #ifdef BCM_TRIDENT_SUPPORT 39200 if (SOC_IS_TRIDENT(unit) || SOC_IS_TITAN(unit)) { 39201 bcm_port_t phy_port; 39202 int bindex; 39203 39204 if (!SOC_PORT_VALID(unit, port)) { 39205 return BCM_E_PORT; 39206 } 39207 if (value != 1 && value != 2 && value != 4) { 39208 return BCM_E_PARAM; 39209 } 39210 /* coverity[overrun-local : FALSE] */ 39211 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 39212 bindex = SOC_PORT_BINDEX(unit, phy_port); 39213 if (bindex & (value - 1)) { /* port alignment check */ 39214 return BCM_E_PARAM; 39215 } 39216 } 39217 #endif /* BCM_TRIDENT_SUPPORT */ 39218 _bcm_esw_port_mirror_lock(unit); 39219 39220 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT 39221 if (soc_feature(unit, soc_feature_xgs5_flexport_legacy_mode)) { 39222 rv = bcmi_xgs5_port_lanes_set(unit, port, value); 39223 } 39224 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */ 39225 #if defined(BCM_ENDURO_SUPPORT) 39226 if (SOC_IS_ENDURO(unit)) { 39227 rv = _bcm_en_port_lanes_set(unit, port, value); 39228 } else 39229 #endif 39230 #if defined(BCM_HURRICANE1_SUPPORT) 39231 if (SOC_IS_HURRICANE(unit)) { 39232 rv = _bcm_hu_port_lanes_set(unit, port, value); 39233 } else 39234 #endif 39235 #if defined(BCM_HURRICANE2_SUPPORT) 39236 if (SOC_IS_HURRICANE2(unit)) { 39237 rv = _bcm_hu2_port_lanes_set(unit, port, value); 39238 } else 39239 #endif 39240 #ifdef BCM_TOMAHAWK_SUPPORT 39241 if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TRIDENT3X(unit)) { 39242 /* coverity[overrun-call : FALSE] */ 39243 rv = _bcm_th_port_lanes_set(unit, port, value); 39244 } else 39245 #endif 39246 #if defined(BCM_MONTEREY_SUPPORT) 39247 if (SOC_IS_MONTEREY(unit)) { 39248 rv = bcmi_monterey_port_lanes_set(unit, port, value); 39249 } else 39250 #endif 39251 #if defined(BCM_APACHE_SUPPORT) 39252 if (SOC_IS_APACHE(unit)) { 39253 rv = bcmi_apache_port_lanes_set(unit, port, value); 39254 } else 39255 #endif 39256 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 39257 if (SOC_IS_TD2P_TT2P(unit)) { 39258 rv = bcmi_td2p_port_lanes_set(unit, port, value); 39259 } else 39260 #endif 39261 #ifdef BCM_TRIDENT2_SUPPORT 39262 if (SOC_IS_TD2_TT2(unit)) { 39263 rv = _bcm_td2_port_lanes_set(unit, port, value); 39264 _bcm_flex_port_phy_control_software_rx_los_get(unit, port); 39265 } else 39266 #endif 39267 #ifdef BCM_TRIDENT_SUPPORT 39268 if (SOC_IS_TD_TT(unit)) { 39269 /* coverity[overrun-call : FALSE] */ 39270 rv = _bcm_td_port_lanes_set(unit, port, value); 39271 } else 39272 #endif /* BCM_TRIDENT_SUPPORT */ 39273 #ifdef BCM_SHADOW_SUPPORT 39274 if (SOC_IS_SHADOW(unit)) { 39275 soc_info_t *si = NULL; 39276 int okay; 39277 int i; 39278 39279 rv = _bcm_shadow_port_lanes_set(unit, port, value); 39280 if (BCM_SUCCESS(rv)) { 39281 si = &SOC_INFO(unit); 39282 if (value == 1) { /* Probe other ports */ 39283 for (i = port; i < port+4; i++) { 39284 rv = soc_phyctrl_detach(unit, i); 39285 if (SOC_FAILURE(rv)) { 39286 _bcm_esw_port_mirror_unlock(unit); 39287 return (rv); 39288 } 39289 } 39290 for (i = port; i < port+4; i++) { 39291 /* coverity[overrun-local : FALSE] */ 39292 si->port_num_lanes[i] = value; 39293 rv = _bcm_port_probe(unit, i, &okay); 39294 } 39295 } else if (value == 4) { /* Probe other ports */ 39296 si = &SOC_INFO(unit); 39297 for (i = port; i < port+4; i++) { 39298 rv = soc_phyctrl_detach(unit, i); 39299 if (SOC_FAILURE(rv)) { 39300 _bcm_esw_port_mirror_unlock(unit); 39301 return (rv); 39302 } 39303 } 39304 /* coverity[overrun-local : FALSE] */ 39305 si->port_num_lanes[port] = value; 39306 rv = _bcm_port_probe(unit, port, &okay); 39307 } 39308 } 39309 } else 39310 #endif /* BCM_SHADOW_SUPPORT */ 39311 #ifdef BCM_TRIUMPH3_SUPPORT 39312 if (SOC_IS_TRIUMPH3(unit)) { 39313 if (!SOC_IS_HELIX4(unit) && (_tr3_port_config_id[unit] == 112 || 39314 _tr3_port_config_id[unit] == 12)&& 39315 (port == 54 || port == 55)) { 39316 return BCM_E_PARAM; 39317 } 39318 COUNTER_LOCK(unit); 39319 rv = _bcm_tr3_port_lanes_set(unit, port, value); 39320 COUNTER_UNLOCK(unit); 39321 } else 39322 #endif /* BCM_TRIUMPH3_SUPPORT */ 39323 #ifdef BCM_METROLITE_SUPPORT 39324 if (SOC_IS_METROLITE(unit)) { 39325 COUNTER_LOCK(unit); 39326 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 39327 rv = _bcm_ml_port_lanes_set(unit, port, value); 39328 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 39329 COUNTER_UNLOCK(unit); 39330 } else 39331 #endif /* BCM_METROLITE_SUPPORT */ 39332 #ifdef BCM_SABER2_SUPPORT 39333 if (SOC_IS_SABER2(unit)) { 39334 COUNTER_LOCK(unit); 39335 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 39336 rv = _bcm_sb2_port_lanes_set(unit, port, value); 39337 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 39338 COUNTER_UNLOCK(unit); 39339 } else 39340 #endif /* BCM_SABER2_SUPPORT */ 39341 #ifdef BCM_KATANA2_SUPPORT 39342 if (SOC_IS_KATANA2(unit)) { 39343 COUNTER_LOCK(unit); 39344 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 39345 rv = _bcm_kt2_port_lanes_set(unit, port, value); 39346 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 39347 COUNTER_UNLOCK(unit); 39348 } else 39349 #endif /* BCM_KATANA2_SUPPORT */ 39350 { 39351 rv = _bcm_tr2_port_lanes_set(unit, port, value); 39352 } 39353 _bcm_esw_port_mirror_unlock(unit); 39354 #ifdef BCM_METROLITE_SUPPORT 39355 if (BCM_SUCCESS(rv) && SOC_IS_METROLITE(unit)) { 39356 COUNTER_LOCK(unit); 39357 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 39358 rv = _bcm_ml_port_lanes_set_post_operation(unit, port); 39359 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 39360 COUNTER_UNLOCK(unit); 39361 } else 39362 #endif /* BCM_METROLITE_SUPPORT */ 39363 #ifdef BCM_SABER2_SUPPORT 39364 if (BCM_SUCCESS(rv) && SOC_IS_SABER2(unit)) { 39365 COUNTER_LOCK(unit); 39366 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 39367 rv = _bcm_sb2_port_lanes_set_post_operation(unit, port); 39368 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 39369 COUNTER_UNLOCK(unit); 39370 } else 39371 #endif 39372 #ifdef BCM_KATANA2_SUPPORT 39373 /* Dead Lock (with port lock) so calling separately */ 39374 if (BCM_SUCCESS(rv) && SOC_IS_KATANA2(unit)) { 39375 COUNTER_LOCK(unit); 39376 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 39377 rv = _bcm_kt2_port_lanes_set_post_operation(unit, port); 39378 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 39379 COUNTER_UNLOCK(unit); 39380 } 39381 #endif 39382 } 39383 #endif 39384 break; 39385 39386 case bcmPortControlPFCEthertype: 39387 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 39388 if (soc_feature(unit, soc_feature_priority_flow_control)) { 39389 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39390 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 39391 /* IS_GX_PORT == IS_XL_PORT */ 39392 return BCM_E_PORT; 39393 } 39394 if (value < 0 || value > 0xffff) { 39395 return BCM_E_PARAM; 39396 } 39397 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39398 SOC_MAC_CONTROL_PFC_TYPE, value); 39399 } 39400 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 39401 break; 39402 39403 case bcmPortControlPFCOpcode: 39404 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 39405 if (soc_feature(unit, soc_feature_priority_flow_control)) { 39406 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39407 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 39408 /* IS_GX_PORT == IS_XL_PORT */ 39409 return BCM_E_PORT; 39410 } 39411 if (value < 0 || value > 0xffff) { 39412 return BCM_E_PARAM; 39413 } 39414 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39415 SOC_MAC_CONTROL_PFC_OPCODE, value); 39416 } 39417 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 39418 break; 39419 39420 case bcmPortControlPFCReceive: 39421 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 39422 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39423 if (soc_feature(unit, soc_feature_priority_flow_control)) { 39424 int pfc_enable; 39425 int val_count = 0; 39426 soc_reg_t reg; 39427 uint32 values[2]; 39428 soc_field_t fields[] = {PFC_ENABLEf, LLFC_ENf}; 39429 39430 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 39431 /* IS_GX_PORT == IS_XL_PORT */ 39432 return BCM_E_PORT; 39433 } 39434 39435 BCM_IF_ERROR_RETURN 39436 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39437 SOC_MAC_CONTROL_PFC_RX_ENABLE, value)); 39438 if (value == 0) { 39439 BCM_IF_ERROR_RETURN 39440 (MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 39441 SOC_MAC_CONTROL_PFC_TX_ENABLE, 39442 &pfc_enable)); 39443 } else { 39444 pfc_enable = TRUE; 39445 } 39446 39447 if (SOC_IS_SC_CQ(unit)) { 39448 BCM_IF_ERROR_RETURN 39449 (soc_reg_field32_modify(unit, MMU_LLFC_RX_CONFIGr, 39450 port, RX_ENABLEf, value ? 1 : 0)); 39451 } 39452 39453 if (value == 0) { 39454 /* Disabling RX, flush MMU XOFF state */ 39455 BCM_IF_ERROR_RETURN 39456 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39457 SOC_MAC_CONTROL_PFC_FORCE_XON, 1)); 39458 BCM_IF_ERROR_RETURN 39459 (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39460 SOC_MAC_CONTROL_PFC_FORCE_XON, 0)); 39461 } 39462 39463 /* Port config settings */ 39464 values[0] = pfc_enable ? 1 : 0; 39465 values[1] = 0; 39466 39467 if (SOC_IS_TD2_TT2(unit)) { 39468 reg = INVALIDr; 39469 } else if (SOC_IS_TD_TT(unit) || SOC_IS_SHADOW(unit)) { 39470 reg = XLPORT_CONFIGr; 39471 val_count=2; 39472 } else if (SOC_IS_TRIUMPH3(unit)) { 39473 reg = PORT_CONFIGr; 39474 val_count=2; 39475 } else if (SOC_IS_SABER2(unit)) { 39476 /* No port level config required */ 39477 reg = INVALIDr; 39478 val_count = 0; 39479 } else if (SOC_IS_KATANAX(unit)) { 39480 reg = XPORT_CONFIGr; 39481 val_count=2; 39482 } else { 39483 reg = INVALIDr; 39484 } 39485 39486 if (val_count > 0) { 39487 BCM_IF_ERROR_RETURN 39488 (soc_reg_fields32_modify(unit, reg, port, 39489 COUNTOF(values), fields, values)); 39490 } else if (SOC_IS_TD2_TT2(unit)) { 39491 ; 39492 } else if (SOC_IS_SC_CQ(unit) || SOC_IS_TR_VL(unit)) { 39493 if (SOC_REG_IS_VALID(unit, PPFC_ENr)) { 39494 /* Feature enable */ 39495 BCM_IF_ERROR_RETURN 39496 (soc_reg_field32_modify(unit, PPFC_ENr, port, 39497 PPFC_FEATURE_ENf, 39498 pfc_enable ? 1 : 0)); 39499 } 39500 if (soc_reg_field_valid(unit, XPORT_CONFIGr, PPP_ENABLEf)) { 39501 BCM_IF_ERROR_RETURN 39502 (soc_reg_field32_modify(unit, XPORT_CONFIGr, 39503 port, PPP_ENABLEf, 39504 pfc_enable ? 1 : 0)); 39505 } 39506 } 39507 39508 /* Stats enable */ 39509 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39510 SOC_MAC_CONTROL_PFC_STATS_ENABLE, 39511 pfc_enable ? 1 : 0); 39512 39513 if (SOC_REG_IS_VALID(unit, XPORT_TO_MMU_BKPr) && pfc_enable == 0) { 39514 BCM_IF_ERROR_RETURN(WRITE_XPORT_TO_MMU_BKPr(unit, port, 0)); 39515 } 39516 } 39517 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 39518 break; 39519 39520 case bcmPortControlPFCTransmit: 39521 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 39522 if (soc_feature(unit, soc_feature_priority_flow_control)) { 39523 rv = _bcm_sc_tr_port_pfc_tx_set(unit, port, (value)? 0xffff : 0); 39524 } 39525 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 39526 break; 39527 39528 case bcmPortControlPFCClasses: 39529 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 39530 if (soc_feature(unit, soc_feature_priority_flow_control)) { 39531 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39532 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 39533 /* IS_GX_PORT == IS_XL_PORT */ 39534 return BCM_E_PORT; 39535 } 39536 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39537 SOC_MAC_CONTROL_PFC_CLASSES, value); 39538 } 39539 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 39540 break; 39541 39542 case bcmPortControlPFCPassFrames: 39543 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 39544 if (soc_feature(unit, soc_feature_priority_flow_control)) { 39545 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39546 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 39547 /* IS_GX_PORT == IS_XL_PORT */ 39548 return BCM_E_PORT; 39549 } 39550 if(soc_feature(unit, soc_feature_pgw_mac_pfc_frame)) { 39551 uint32 rval32 = 0; 39552 soc_reg_t reg = INVALIDr; 39553 if(SOC_REG_IS_VALID(unit, PGW_MAC_RSV_MASKr)) { 39554 reg = PGW_MAC_RSV_MASKr; 39555 } else if(IS_CL_PORT(unit, port) && 39556 SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) { 39557 reg = CLPORT_MAC_RSV_MASKr; 39558 } else if(IS_XL_PORT(unit, port) && 39559 SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) { 39560 reg = XLPORT_MAC_RSV_MASKr; 39561 } else { 39562 reg = INVALIDr; 39563 } 39564 39565 if (reg != INVALIDr) { 39566 PORT_LOCK(unit); 39567 rv = soc_reg32_get(unit, reg, port, 0, &rval32); 39568 if (BCM_SUCCESS(rv)) { 39569 /* xxx_MAC_RSV_MASK: Bit 18 PFC frame detected 39570 * Enable PFC Frame : Set 0. Go through 39571 * Disable PFC Frame : Set 1. Purged. 39572 */ 39573 if(value) { 39574 rval32 &= ~(1 << 18); 39575 } else { 39576 rval32 |= (1 << 18); 39577 } 39578 rv = soc_reg32_set(unit, reg, port, 0, rval32); 39579 } 39580 PORT_UNLOCK(unit); 39581 } else { 39582 rv = BCM_E_UNAVAIL; 39583 } 39584 } else { 39585 PORT_LOCK(unit); 39586 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39587 SOC_MAC_CONTROL_PFC_RX_PASS, value); 39588 PORT_UNLOCK(unit); 39589 } 39590 } 39591 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 39592 break; 39593 39594 case bcmPortControlPFCDestMacOui: 39595 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 39596 if (soc_feature(unit, soc_feature_priority_flow_control)) { 39597 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39598 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 39599 /* IS_GX_PORT == IS_XL_PORT */ 39600 return BCM_E_PORT; 39601 } 39602 if (value < 0 || value > 0xffffff) { 39603 return BCM_E_PARAM; 39604 } 39605 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39606 SOC_MAC_CONTROL_PFC_MAC_DA_OUI, value); 39607 } 39608 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 39609 break; 39610 39611 case bcmPortControlPFCDestMacNonOui: 39612 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 39613 if (soc_feature(unit, soc_feature_priority_flow_control)) { 39614 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39615 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 39616 /* IS_GX_PORT == IS_XL_PORT */ 39617 return BCM_E_PORT; 39618 } 39619 if (value < 0 || value > 0xffffff) { 39620 return BCM_E_PARAM; 39621 } 39622 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39623 SOC_MAC_CONTROL_PFC_MAC_DA_NONOUI, value); 39624 } 39625 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 39626 break; 39627 39628 case bcmPortControlPFCRefreshTime: 39629 #if defined(BCM_TRIDENT_SUPPORT)||defined(BCM_GREYHOUND_SUPPORT) 39630 if (soc_feature(unit, soc_feature_priority_flow_control)) { 39631 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39632 if (value < 0 || value > 0xffff) { 39633 return BCM_E_PARAM; 39634 } 39635 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39636 SOC_MAC_CONTROL_PFC_REFRESH_TIME, value); 39637 } 39638 #endif /* BCM_TRIDENT_SUPPORT */ 39639 break; 39640 39641 case bcmPortControlPFCXOffTime: 39642 #if defined(BCM_TRIDENT_SUPPORT)||defined(BCM_GREYHOUND_SUPPORT) 39643 if (soc_feature(unit, soc_feature_priority_flow_control)) { 39644 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 39645 if (value < 0 || value > 0xffff) { 39646 return BCM_E_PARAM; 39647 } 39648 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39649 SOC_MAC_CONTROL_PFC_XOFF_TIME, value); 39650 } 39651 #endif /* BCM_TRIDENT_SUPPORT */ 39652 break; 39653 39654 case bcmPortControlVrf: 39655 rv = _bcm_esw_port_vrf_set(unit, port, value); 39656 break; 39657 39658 case bcmPortControlL3Ingress: 39659 #if defined(BCM_TRIUMPH_SUPPORT) 39660 if (!soc_feature(unit, soc_feature_l3_ingress_interface)) { 39661 return BCM_E_UNAVAIL; 39662 } 39663 39664 if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, L3_IIFf)) { 39665 if ((value >= 1) && (value < soc_mem_index_count(unit, L3_IIFm))) { 39666 #if defined(BCM_KATANA2_SUPPORT) 39667 if (SOC_IS_KATANA2(unit)) { 39668 rv = _bcm_kt2_source_trunk_map_set(unit, port, L3_IIFf, value); 39669 } else 39670 #endif 39671 { 39672 rv = _bcm_trx_source_trunk_map_set(unit, port, L3_IIFf, value); 39673 } 39674 BCM_IF_ERROR_RETURN(rv); 39675 if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf) || 39676 SOC_IS_TRIDENT3X(unit)) { 39677 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39678 PORT_OPERATIONf, 0x2); 39679 } 39680 } else { 39681 #if defined(BCM_KATANA2_SUPPORT) 39682 if (SOC_IS_KATANA2(unit)) { 39683 rv = _bcm_kt2_source_trunk_map_set(unit, port, L3_IIFf, 0); 39684 } else 39685 #endif 39686 { 39687 rv = _bcm_trx_source_trunk_map_set(unit, port, L3_IIFf, 0); 39688 } 39689 BCM_IF_ERROR_RETURN(rv); 39690 if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf)) { 39691 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39692 PORT_OPERATIONf, 0x0); 39693 } 39694 } 39695 } 39696 #endif /* BCM_TRIUMPH_SUPPORT */ 39697 break; 39698 39699 case bcmPortControlL2Learn: 39700 #if defined(BCM_TRX_SUPPORT) 39701 if (SOC_IS_TRX(unit)) { 39702 uint32 hw_val = 0; 39703 bcm_port_cfg_t port_cfg; 39704 39705 BCM_IF_ERROR_RETURN( 39706 _bcm_trx_port_cml_flags2hw(unit, value, &hw_val)); 39707 BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg)); 39708 port_cfg.pc_cml = hw_val; 39709 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &port_cfg); 39710 } 39711 #endif /* BCM_TRX_SUPPORT */ 39712 break; 39713 39714 case bcmPortControlL2Move: 39715 #if defined(BCM_TRX_SUPPORT) 39716 if (SOC_IS_TRX(unit)) { 39717 uint32 hw_val = 0; 39718 bcm_port_cfg_t port_cfg; 39719 39720 BCM_IF_ERROR_RETURN( 39721 _bcm_trx_port_cml_flags2hw(unit, value, &hw_val)); 39722 BCM_IF_ERROR_RETURN(mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg)); 39723 port_cfg.pc_cml_move = hw_val; 39724 rv = mbcm_driver[unit]->mbcm_port_cfg_set(unit, port, &port_cfg); 39725 } 39726 #endif /* BCM_TRX_SUPPORT */ 39727 break; 39728 39729 case bcmPortControlForwardStaticL2MovePkt: 39730 #if defined(BCM_TRX_SUPPORT) 39731 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 39732 DISABLE_STATIC_MOVE_DROPf, value ? 1 : 0); 39733 #endif /* BCM_TRX_SUPPORT */ 39734 break; 39735 39736 case bcmPortControlPrbsMode: 39737 if (value != 0) { 39738 return BCM_E_PARAM; 39739 } 39740 rv = BCM_E_NONE; 39741 break; 39742 39743 case bcmPortControlPrbsPolynomial: 39744 /*prbs polynomial value check*/ 39745 if((value < BCM_PORT_PRBS_POLYNOMIAL_X7_X6_1) 39746 || (value > BCM_PORT_PRBS_POLYNOMIAL_PAM4_13Q)) 39747 { 39748 return BCM_E_PARAM; 39749 } 39750 PORT_LOCK(unit); 39751 rv = soc_phyctrl_control_set(unit, port, 39752 SOC_PHY_CONTROL_PRBS_POLYNOMIAL, value); 39753 PORT_UNLOCK(unit); 39754 break; 39755 case bcmPortControlPrbsTxEnable: 39756 PORT_LOCK(unit); 39757 rv = soc_phyctrl_control_set(unit, port, 39758 SOC_PHY_CONTROL_PRBS_TX_ENABLE, value); 39759 PORT_UNLOCK(unit); 39760 break; 39761 39762 case bcmPortControlPrbsRxEnable: 39763 PORT_LOCK(unit); 39764 rv = soc_phyctrl_control_set(unit, port, 39765 SOC_PHY_CONTROL_PRBS_RX_ENABLE, value); 39766 PORT_UNLOCK(unit); 39767 break; 39768 39769 case bcmPortControlPrbsTxInvertData: 39770 PORT_LOCK(unit); 39771 rv = soc_phyctrl_control_set(unit, port, 39772 SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA, 39773 value); 39774 PORT_UNLOCK(unit); 39775 break; 39776 39777 case bcmPortControlLinkFaultLocalEnable: 39778 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39779 SOC_MAC_CONTROL_FAULT_LOCAL_ENABLE, value); 39780 break; 39781 case bcmPortControlLinkFaultRemoteEnable: 39782 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 39783 SOC_MAC_CONTROL_FAULT_REMOTE_ENABLE, value); 39784 break; 39785 case bcmPortControlSerdesDriverTune: 39786 PORT_LOCK(unit); 39787 rv = soc_phyctrl_control_set(unit, port, 39788 SOC_PHY_CONTROL_SERDES_DRIVER_TUNE, value); 39789 PORT_UNLOCK(unit); 39790 break; 39791 case bcmPortControlLinkdownTransmit: 39792 PORT_LOCK(unit); 39793 rv = soc_phyctrl_control_set(unit, port, 39794 SOC_PHY_CONTROL_LINKDOWN_TRANSMIT, value); 39795 PORT_UNLOCK(unit); 39796 /* Most of PHYs have nothing to configure and simply return UNAVAIL*/ 39797 if ((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL)) { 39798 BCM_IF_ERROR_RETURN(_bcm_esw_link_down_tx_set(unit, port, value)); 39799 #if defined(BCM_TRIUMPH3_SUPPORT) 39800 if (SOC_REG_PORT_VALID(unit, XMAC_RX_LSS_CTRLr, port)) { 39801 rv = soc_reg_field32_modify(unit, XMAC_RX_LSS_CTRLr, 39802 port, LOCAL_FAULT_DISABLEf, (value ? 1 : 0)); 39803 } else if (SOC_REG_PORT_VALID(unit, XLMAC_RX_LSS_CTRLr, port)) { 39804 rv = soc_reg_field32_modify(unit, XLMAC_RX_LSS_CTRLr, 39805 port, LOCAL_FAULT_DISABLEf, (value ? 1 : 0)); 39806 } 39807 #endif 39808 } 39809 break; 39810 case bcmPortControlSerdesTuneMarginMode: 39811 PORT_LOCK(unit); 39812 rv = soc_phyctrl_control_set(unit, port, 39813 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_MODE, value); 39814 PORT_UNLOCK(unit); 39815 break; 39816 case bcmPortControlSerdesTuneMarginValue: 39817 PORT_LOCK(unit); 39818 rv = soc_phyctrl_control_set(unit, port, 39819 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_VALUE, value); 39820 PORT_UNLOCK(unit); 39821 break; 39822 case bcmPortControlStatOversize: 39823 rv = _bcm_esw_stat_ovr_threshold_set(unit, port, value); 39824 break; 39825 39826 case bcmPortControlStatOversizeIsError: 39827 rv = _bcm_esw_stat_ovr_error_control_set(unit, port, value); 39828 break; 39829 39830 case bcmPortControlTimestampEnable: 39831 #if defined(BCM_HAWKEYE_SUPPORT) 39832 if (SOC_IS_HAWKEYE(unit)) { 39833 uint32 rval; 39834 if (!SOC_PORT_VALID(unit, port)) { 39835 return BCM_E_PORT; 39836 } 39837 SOC_IF_ERROR_RETURN(READ_EAV_ENABLE_BMAPr(unit, &rval)); 39838 if (value) { 39839 /* coverity[BAD_SHIFT: FALSE] */ 39840 rval |= (port >= 32 ? 0 : (1 << port)); 39841 } else { 39842 /* coverity[BAD_SHIFT: FALSE] */ 39843 rval &= ~(port >= 32 ? 0 : (1 << port)); 39844 } 39845 SOC_IF_ERROR_RETURN(WRITE_EAV_ENABLE_BMAPr(unit, rval)); 39846 39847 /* Enable MMU */ 39848 SOC_IF_ERROR_RETURN(WRITE_MMUEAVENABLEr(unit, rval)); 39849 39850 /* Program EGR_PORT register */ 39851 SOC_IF_ERROR_RETURN(READ_EGR_PORTr(unit, port, &rval)); 39852 soc_reg_field_set(unit, EGR_PORTr, &rval, EAV_CAPABLEf, value); 39853 SOC_IF_ERROR_RETURN(WRITE_EGR_PORTr(unit, port, rval)); 39854 39855 rv = BCM_E_NONE; 39856 } else 39857 #endif /* BCM_HAWKEYE_SUPPORT */ 39858 if (soc_feature (unit, soc_feature_xlmac_timestamp_disable)) { 39859 if (IS_XL_PORT(unit, port)) { 39860 /* Enable/disable timesatmp on XLMAC */ 39861 uint32 rval; 39862 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, 39863 port, &rval)); 39864 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, 39865 XLMAC_TS_DISABLEf, (value) ? 0 : 1); 39866 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, 39867 port, rval)); 39868 rv = BCM_E_NONE; 39869 } 39870 } 39871 break; 39872 39873 case bcmPortControlEEEEnable: 39874 if (!SOC_PORT_VALID(unit, port)) { 39875 return BCM_E_PORT; 39876 } 39877 39878 PORT_LOCK(unit); 39879 39880 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 39881 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 39882 || defined(BCM_HURRICANE2_SUPPORT) 39883 if (soc_feature (unit, soc_feature_eee)) { 39884 int mac_val; 39885 uint32 phy_val; 39886 39887 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 39888 SOC_MAC_CONTROL_EEE_ENABLE, 39889 &mac_val) != SOC_E_UNAVAIL) && 39890 (soc_phyctrl_control_get(unit, port, 39891 BCM_PORT_PHY_CONTROL_EEE, 39892 &phy_val) != SOC_E_UNAVAIL)) { 39893 39894 /* If MAC/Switch is EEE aware (Native EEE mode is supported) 39895 * and PHY also supports Native EEE mode 39896 */ 39897 39898 /* a. Disable AutoGrEEEn mode by PHY if applicable */ 39899 rv = (soc_phyctrl_control_get(unit, port, 39900 BCM_PORT_PHY_CONTROL_EEE_AUTO, 39901 &phy_val)); 39902 39903 if ((rv != SOC_E_UNAVAIL) && (phy_val != 0)) { 39904 rv = soc_phyctrl_control_set(unit, port, 39905 BCM_PORT_PHY_CONTROL_EEE_AUTO, 39906 0); 39907 } 39908 39909 /* b. Enable/Disable Native EEE in PHY */ 39910 rv = soc_phyctrl_control_set (unit, port, 39911 BCM_PORT_PHY_CONTROL_EEE, value ? 1 : 0); 39912 39913 if (SOC_SUCCESS(rv)) { 39914 /* EEE standard compliance Work Around: 39915 * Store the software copy of eee value in eee_cfg flag 39916 */ 39917 eee_cfg[unit][port] = value; 39918 /* If (value==1), EEE will be enabled in MAC after 1 sec. 39919 * during linkscan update*/ 39920 if (value == 0) { 39921 /* Disable EEE in MAC immediately*/ 39922 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, 39923 unit, port, 39924 SOC_MAC_CONTROL_EEE_ENABLE, 0); 39925 } 39926 39927 /* Notify Int-PHY to bypass LPI for native EEE mode. 39928 * 39929 * Note : 39930 * 1. Not all internal SerDes support the setting to 39931 * enable/disable bypass LPI signal. 39932 * 2. Int-PHY to bypass LPI will sync with Ext-PHY's EEE 39933 * enabling status for Native EEE mode. 39934 */ 39935 (void)soc_phyctrl_notify(unit, port, 39936 phyEventLpiBypass, value? 1: 0); 39937 } 39938 39939 } else { 39940 /* If native EEE mode is not supported, 39941 * set PHY in AutoGrEEEn mode. 39942 */ 39943 39944 /* a. Disable Native EEE mode in PHY if applicable */ 39945 rv = (soc_phyctrl_control_get(unit, port, 39946 BCM_PORT_PHY_CONTROL_EEE, 39947 &phy_val)); 39948 39949 if ((rv != SOC_E_UNAVAIL) && (phy_val != 0)) { 39950 rv = soc_phyctrl_control_set (unit, port, 39951 BCM_PORT_PHY_CONTROL_EEE, 39952 0); 39953 } 39954 39955 /* b. Enable/Disable AutoGrEEEn in PHY. 39956 * If PHY does not support AutoGrEEEn mode, 39957 * rv will be assigned SOC_E_UNAVAIL. 39958 */ 39959 rv = soc_phyctrl_control_set (unit, port, 39960 BCM_PORT_PHY_CONTROL_EEE_AUTO, 39961 value ? 1 : 0); 39962 if (SOC_SUCCESS(rv)) { 39963 eee_cfg[unit][port] = value; 39964 } 39965 } 39966 } else 39967 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 39968 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 39969 39970 { 39971 /* For legacy devices that don't support native EEE, 39972 * set PHY in AutoGrEEEn mode. 39973 */ 39974 uint32 phy_val; 39975 39976 /* a. Disable Native EEE mode in PHY if applicable */ 39977 rv = (soc_phyctrl_control_get(unit, port, 39978 BCM_PORT_PHY_CONTROL_EEE, 39979 &phy_val)); 39980 39981 if ((rv != SOC_E_UNAVAIL) && (phy_val != 0)) { 39982 rv = soc_phyctrl_control_set (unit, port, 39983 BCM_PORT_PHY_CONTROL_EEE, 0); 39984 } 39985 39986 /* b. Enable/Disable AutoGrEEEn in PHY. 39987 * If PHY does not support AutoGrEEEn mode, 39988 * rv will be assigned BCM_E_UNAVAIL. 39989 */ 39990 rv = soc_phyctrl_control_set (unit, port, 39991 BCM_PORT_PHY_CONTROL_EEE_AUTO, 39992 value ? 1 : 0); 39993 } 39994 39995 PORT_UNLOCK(unit); 39996 39997 break; 39998 39999 case bcmPortControlEEEStatisticsClear: 40000 if (!SOC_PORT_VALID(unit, port)) { 40001 return BCM_E_PORT; 40002 } 40003 if (!IS_E_PORT(unit, port)) { 40004 return BCM_E_UNAVAIL; 40005 } 40006 40007 PORT_LOCK(unit); 40008 40009 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) ||\ 40010 defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 40011 if (soc_feature(unit, soc_feature_eee)) { 40012 uint32 val = 0; 40013 uint64 val64; 40014 int mac_val; 40015 uint32 phy_val; 40016 40017 COMPILER_64_ZERO(val64); 40018 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 40019 SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) 40020 != SOC_E_UNAVAIL) && 40021 (soc_phyctrl_control_get(unit, port, 40022 BCM_PORT_PHY_CONTROL_EEE, &phy_val) 40023 != SOC_E_UNAVAIL)) { 40024 40025 if (soc_feature(unit, soc_feature_eee_stat_clear_directly) || 40026 SOC_IS_TD2_TT2(unit)) { 40027 rv = _bcm_esw_port_eee_stat_clear(unit, port); 40028 40029 PORT_UNLOCK (unit); 40030 break; 40031 } 40032 40033 /* MAC/Switch is EEE aware (Native EEE mode is supported) */ 40034 if (soc_feature(unit, soc_feature_unified_port)) { 40035 if (SOC_REG_IS_VALID(unit,PORT_XGXS_COUNTER_MODEr)) { 40036 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40037 (READ_PORT_XGXS_COUNTER_MODEr(unit, port, &val)); 40038 soc_reg_field_set(unit, PORT_XGXS_COUNTER_MODEr, &val, 40039 CNT_MODEf, 0); 40040 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40041 (WRITE_PORT_XGXS_COUNTER_MODEr(unit, port, val)); 40042 } 40043 } else { 40044 if (SOC_REG_IS_VALID(unit,GE0_EEE_CONFIGr)) { 40045 /*set counter rollover bit to 0*/ 40046 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 40047 READ_GE0_EEE_CONFIGr(unit, port, &val)); 40048 soc_reg_field_set(unit, GE0_EEE_CONFIGr, &val, 40049 COUNTER_ROLLOVERf, 0); 40050 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40051 (WRITE_GE0_EEE_CONFIGr(unit, port, val)); 40052 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40053 (WRITE_GE1_EEE_CONFIGr(unit, port, val)); 40054 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40055 (WRITE_GE2_EEE_CONFIGr(unit, port, val)); 40056 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40057 (WRITE_GE3_EEE_CONFIGr(unit, port, val)); 40058 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40059 (WRITE_GE4_EEE_CONFIGr(unit, port, val)); 40060 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40061 (WRITE_GE5_EEE_CONFIGr(unit, port, val)); 40062 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40063 (WRITE_GE6_EEE_CONFIGr(unit, port, val)); 40064 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40065 (WRITE_GE7_EEE_CONFIGr(unit, port, val)); 40066 } 40067 } 40068 40069 /*Read counters to clear them*/ 40070 if (IS_GE_PORT(unit, port) && !IS_XL_PORT(unit, port) && 40071 (SOC_IS_HURRICANE2(unit) || SOC_IS_HURRICANE3(unit) || 40072 SOC_IS_GREYHOUND(unit))) { 40073 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40074 (READ_GRX_EEE_LPI_DURATION_COUNTERr(unit, port, &val)); 40075 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40076 (READ_GRX_EEE_LPI_EVENT_COUNTERr(unit, port, &val)); 40077 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40078 (READ_GTX_EEE_LPI_DURATION_COUNTERr(unit, port, &val)); 40079 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40080 (READ_GTX_EEE_LPI_EVENT_COUNTERr(unit, port, &val)); 40081 #ifdef BCM_GREYHOUND2_SUPPORT 40082 } else if (SOC_IS_GREYHOUND2(unit)) { 40083 40084 if (IS_CL_PORT(unit, port)) { 40085 /* for port with CLMAC */ 40086 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40087 (READ_CLMIB_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 40088 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40089 (READ_CLMIB_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 40090 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40091 (READ_CLMIB_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 40092 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40093 (READ_CLMIB_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 40094 } else if (IS_XL_PORT(unit, port)) { 40095 /* for port with XLMAC */ 40096 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40097 (READ_XLMIB_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 40098 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40099 (READ_XLMIB_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 40100 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40101 (READ_XLMIB_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 40102 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40103 (READ_XLMIB_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 40104 40105 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40106 (READ_XLPMIB_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 40107 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40108 (READ_XLPMIB_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 40109 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40110 (READ_XLPMIB_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 40111 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40112 (READ_XLPMIB_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 40113 } else { 40114 /* for port with UniMAC */ 40115 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40116 (READ_GRX_EEE_LPI_DURATION_COUNTERr(unit, port, &val)); 40117 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40118 (READ_GRX_EEE_LPI_EVENT_COUNTERr(unit, port, &val)); 40119 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40120 (READ_GTX_EEE_LPI_DURATION_COUNTERr(unit, port, &val)); 40121 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40122 (READ_GTX_EEE_LPI_EVENT_COUNTERr(unit, port, &val)); 40123 } 40124 #endif 40125 } else { 40126 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40127 (READ_RX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 40128 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40129 (READ_RX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 40130 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40131 (READ_TX_EEE_LPI_DURATION_COUNTERr(unit, port, &val64)); 40132 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40133 (READ_TX_EEE_LPI_EVENT_COUNTERr(unit, port, &val64)); 40134 } 40135 40136 /*set counter rollover bit to 1*/ 40137 if (soc_feature(unit, soc_feature_unified_port)) { 40138 if (SOC_REG_IS_VALID(unit,PORT_XGXS_COUNTER_MODEr)) { 40139 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40140 (READ_PORT_XGXS_COUNTER_MODEr(unit, port, &val)); 40141 soc_reg_field_set(unit, PORT_XGXS_COUNTER_MODEr, &val, 40142 CNT_MODEf, 1); 40143 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40144 (WRITE_PORT_XGXS_COUNTER_MODEr(unit, port, val)); 40145 } 40146 } else { 40147 if (SOC_REG_IS_VALID(unit,GE0_EEE_CONFIGr)) { 40148 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 40149 READ_GE0_EEE_CONFIGr(unit, port, &val)); 40150 soc_reg_field_set(unit, GE0_EEE_CONFIGr, &val, 40151 COUNTER_ROLLOVERf, 1); 40152 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40153 (WRITE_GE0_EEE_CONFIGr(unit, port, val)); 40154 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40155 (WRITE_GE1_EEE_CONFIGr(unit, port, val)); 40156 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40157 (WRITE_GE2_EEE_CONFIGr(unit, port, val)); 40158 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40159 (WRITE_GE3_EEE_CONFIGr(unit, port, val)); 40160 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40161 (WRITE_GE4_EEE_CONFIGr(unit, port, val)); 40162 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40163 (WRITE_GE5_EEE_CONFIGr(unit, port, val)); 40164 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40165 (WRITE_GE6_EEE_CONFIGr(unit, port, val)); 40166 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 40167 (WRITE_GE7_EEE_CONFIGr(unit, port, val)); 40168 } 40169 } 40170 rv = BCM_E_NONE; 40171 } else { 40172 /* native EEE mode is not supported, */ 40173 rv = soc_phyctrl_control_set 40174 (unit, port, 40175 BCM_PORT_PHY_CONTROL_EEE_STATISTICS_CLEAR, value); 40176 } 40177 } else 40178 #endif /* BCM_HURRICANE_SUPPORT || BCM_TRIDENT_SUPPORT 40179 || BCM_HAWKEYE_SUPPORT*/ 40180 { 40181 /* On legacy devices that don't support native EEE, 40182 * get counter value from PHY. If PHY does not support 40183 * EEE counters, rv will be assigned BCM_E_UNAVAIL. 40184 */ 40185 rv = soc_phyctrl_control_set 40186 (unit, port, 40187 BCM_PORT_PHY_CONTROL_EEE_STATISTICS_CLEAR, value); 40188 } 40189 PORT_UNLOCK (unit); 40190 break; 40191 40192 40193 /********************** EEE Mode Overview ************************ 40194 * |DET| | WT | 40195 * Signalling |idles| |------------------------------| | idles | 40196 * from Tx MAC | or | | Low Power Idle (LPI) |idles| or | 40197 * to local PHY |data | |------------------------------| | data | 40198 * * * 40199 * * * 40200 * * -------LPI state------------* 40201 * Local PHY | | | | | | | | | | 40202 * signaling | Active|Ts| Tq |Tr| Tq |Tr| Tq |Tw |Active | 40203 * on MDI | | | | | | | | | | 40204 * *------------------------------* 40205 * * * 40206 * * * 40207 * Signaling | idles |-------------------------------|id| PHY is | 40208 * from LP PHY | or | Low Power Idle (LPI) |le| ready | 40209 * to Rx MAC | data |-------------------------------|s | for data | 40210 * 40211 * where DET = Delay Entry Timer WT = Tx MAC Wake Timer 40212 */ 40213 case bcmPortControlEEETransmitIdleTime: 40214 /* DET = Time (in microsecs) for which condition to move to LPI state 40215 * is satisfied, at the end of which MAC TX transitions to LPI state */ 40216 if (!SOC_PORT_VALID(unit, port)) { 40217 return BCM_E_PORT; 40218 } 40219 40220 PORT_LOCK(unit); 40221 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 40222 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 40223 || defined (BCM_HURRICANE2_SUPPORT) 40224 if (soc_feature (unit, soc_feature_eee)) { 40225 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40226 SOC_MAC_CONTROL_EEE_TX_IDLE_TIME, value); 40227 } else 40228 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 40229 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 40230 { 40231 rv = BCM_E_UNAVAIL; 40232 } 40233 PORT_UNLOCK(unit); 40234 break; 40235 40236 case bcmPortControlEEETransmitRefreshTime: 40237 if (!SOC_PORT_VALID(unit, port)) { 40238 return BCM_E_PORT; 40239 } 40240 40241 PORT_LOCK(unit); 40242 rv = soc_phyctrl_control_set(unit, port, 40243 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_REFRESH_TIME, value); 40244 PORT_UNLOCK (unit); 40245 break; 40246 40247 case bcmPortControlEEETransmitSleepTime: 40248 if (!SOC_PORT_VALID(unit, port)) { 40249 return BCM_E_PORT; 40250 } 40251 PORT_LOCK (unit); 40252 rv = soc_phyctrl_control_set(unit, port, 40253 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_SLEEP_TIME, value); 40254 PORT_UNLOCK (unit); 40255 break; 40256 40257 case bcmPortControlEEETransmitQuietTime: 40258 if (!SOC_PORT_VALID(unit, port)) { 40259 return BCM_E_PORT; 40260 } 40261 PORT_LOCK(unit); 40262 rv = soc_phyctrl_control_set(unit, port, 40263 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_QUIET_TIME, value); 40264 PORT_UNLOCK (unit); 40265 break; 40266 40267 case bcmPortControlEEETransmitWakeTime: 40268 /* Time(in microsecs) to wait before transmitter can leave LPI State*/ 40269 if (!SOC_PORT_VALID(unit, port)) { 40270 return BCM_E_PORT; 40271 } 40272 40273 PORT_LOCK (unit); 40274 40275 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 40276 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 40277 || defined(BCM_HURRICANE2_SUPPORT) 40278 if (soc_feature (unit, soc_feature_eee)) { 40279 rv = MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 40280 SOC_MAC_CONTROL_EEE_TX_WAKE_TIME, value); 40281 } 40282 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || BCM_TRIDENT_SUPPORT || 40283 BCM_SHADOW_SUPPORT */ 40284 40285 PORT_UNLOCK (unit); 40286 break; 40287 40288 case bcmPortControlEEEReceiveSleepTime: 40289 if (!SOC_PORT_VALID(unit, port)) { 40290 return BCM_E_PORT; 40291 } 40292 PORT_LOCK (unit); 40293 rv = soc_phyctrl_control_set(unit, port, 40294 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_SLEEP_TIME, value); 40295 PORT_UNLOCK (unit); 40296 break; 40297 40298 case bcmPortControlEEEReceiveQuietTime: 40299 if (!SOC_PORT_VALID(unit, port)) { 40300 return BCM_E_PORT; 40301 } 40302 PORT_LOCK(unit); 40303 rv = soc_phyctrl_control_set(unit, port, 40304 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_QUIET_TIME, value); 40305 PORT_UNLOCK(unit); 40306 break; 40307 40308 case bcmPortControlEEEReceiveWakeTime: 40309 if (!SOC_PORT_VALID(unit, port)) { 40310 return BCM_E_PORT; 40311 } 40312 if (!IS_E_PORT(unit, port)) { 40313 return BCM_E_UNAVAIL; 40314 } 40315 PORT_LOCK(unit); 40316 40317 rv = soc_phyctrl_control_set (unit, port, 40318 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_WAKE_TIME, value); 40319 PORT_UNLOCK(unit); 40320 break; 40321 40322 case bcmPortControlEEEEventCountSymmetric: 40323 if (!SOC_PORT_VALID(unit, port)) { 40324 return BCM_E_PORT; 40325 } 40326 if (!IS_E_PORT(unit, port)) { 40327 return BCM_E_UNAVAIL; 40328 } 40329 #if defined(BCM_HURRICANE2_SUPPORT) 40330 if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 40331 SOC_IS_GREYHOUND2(unit)) { 40332 soc_reg_t reg; 40333 40334 if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) { 40335 reg = IS_XL_PORT(unit, port) ? XLPORT_EEE_COUNTER_MODEr : 40336 CLPORT_EEE_COUNTER_MODEr; 40337 40338 if (SOC_REG_FIELD_VALID(unit, reg, MODE_BITf)) { 40339 rv = soc_reg_field32_modify(unit, reg, port, 40340 MODE_BITf, (value) ? 1 : 0); 40341 } else { 40342 return BCM_E_INTERNAL; 40343 } 40344 } else { 40345 return BCM_E_PORT; 40346 } 40347 } else 40348 #endif 40349 { 40350 #if defined(BCM_TRIUMPH3_SUPPORT) 40351 if (SOC_REG_FIELD_VALID(unit, PORT_EEE_COUNTER_MODEr, MODE_BITf)) { 40352 rv = soc_reg_field32_modify(unit, PORT_EEE_COUNTER_MODEr, port, 40353 MODE_BITf, (value) ? 1 : 0); 40354 } 40355 #endif 40356 } 40357 break; 40358 40359 case bcmPortControlEEELinkActiveDuration: 40360 if (!SOC_PORT_VALID(unit, port)) { 40361 return BCM_E_PORT; 40362 } 40363 if (!IS_E_PORT(unit, port)) { 40364 return BCM_E_UNAVAIL; 40365 } 40366 #if defined(BCM_HURRICANE2_SUPPORT) 40367 if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || 40368 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 40369 soc_reg_t reg; 40370 40371 if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) { 40372 reg = IS_XL_PORT(unit, port) ? XLMAC_EEE_1_SEC_LINK_STATUS_TIMERr : 40373 CLMAC_EEE_1_SEC_LINK_STATUS_TIMERr; 40374 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) { 40375 if (value >= (1 << soc_reg_field_length(unit, 40376 reg, 40377 ONE_SECOND_TIMERf))) { 40378 return BCM_E_PARAM; 40379 } 40380 rv = soc_reg_field32_modify(unit, 40381 reg, 40382 port, 40383 ONE_SECOND_TIMERf, 40384 value); 40385 } 40386 } else { 40387 return BCM_E_PORT; 40388 } 40389 } else 40390 #endif 40391 { 40392 #if defined(BCM_TRIUMPH3_SUPPORT) 40393 { 40394 soc_reg_t reg; 40395 40396 reg = IS_C_PORT(unit, port) ? 40397 CMAC_EEE_1_SEC_LINK_STATUS_TIMERr : 40398 XMAC_EEE_1_SEC_LINK_STATUS_TIMERr; 40399 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) { 40400 if (value >= (1 << soc_reg_field_length(unit, reg, 40401 ONE_SECOND_TIMERf))) { 40402 return BCM_E_PARAM; 40403 } 40404 rv = soc_reg_field32_modify(unit, reg, port, 40405 ONE_SECOND_TIMERf, value); 40406 } 40407 } 40408 #endif 40409 } 40410 break; 40411 40412 case bcmPortControlRemoteCpuEnable: 40413 if (soc_feature(unit, soc_feature_rcpu_1)) { 40414 bcm_pbmp_t pbmp; 40415 uint32 rval; 40416 40417 rval = 0; 40418 if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTSr)) { 40419 READ_CMIC_PKT_PORTSr(unit, &rval); 40420 } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_0r)) { 40421 READ_CMIC_PKT_PORTS_0r(unit, &rval); 40422 } 40423 SOC_PBMP_WORD_SET(pbmp, 0, rval); 40424 if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HIr)) { 40425 READ_CMIC_PKT_PORTS_HIr(unit, &rval); 40426 SOC_PBMP_WORD_SET(pbmp, 1, rval); 40427 } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_1r)) { 40428 READ_CMIC_PKT_PORTS_1r(unit, &rval); 40429 SOC_PBMP_WORD_SET(pbmp, 1, rval); 40430 } 40431 40432 if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HI_2r)) { 40433 READ_CMIC_PKT_PORTS_HI_2r(unit, &rval); 40434 SOC_PBMP_WORD_SET(pbmp, 2, rval); 40435 } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_2r)) { 40436 READ_CMIC_PKT_PORTS_2r(unit, &rval); 40437 SOC_PBMP_WORD_SET(pbmp, 2, rval); 40438 } 40439 40440 if (value) { 40441 SOC_PBMP_PORT_ADD(pbmp, port); 40442 } else { 40443 SOC_PBMP_PORT_REMOVE(pbmp, port); 40444 } 40445 rval = 0; 40446 40447 if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTSr)) { 40448 soc_reg_field_set(unit, CMIC_PKT_PORTSr, &rval, PORTSf, 40449 SOC_PBMP_WORD_GET(pbmp, 0)); 40450 (void) WRITE_CMIC_PKT_PORTSr(unit, rval); 40451 } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_0r)) { 40452 soc_reg_field_set(unit, CMIC_PKT_PORTS_0r, &rval, PORTSf, 40453 SOC_PBMP_WORD_GET(pbmp, 0)); 40454 (void) WRITE_CMIC_PKT_PORTS_0r(unit, rval); 40455 } 40456 40457 if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HIr)) { 40458 rval = 0; 40459 soc_reg_field_set(unit, CMIC_PKT_PORTS_HIr, &rval, PORTS_HIf, 40460 SOC_PBMP_WORD_GET(pbmp, 1)); 40461 (void) WRITE_CMIC_PKT_PORTS_HIr(unit, rval); 40462 } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_1r)) { 40463 rval = 0; 40464 soc_reg_field_set(unit, CMIC_PKT_PORTS_1r, &rval, PORTS_HIf, 40465 SOC_PBMP_WORD_GET(pbmp, 1)); 40466 (void) WRITE_CMIC_PKT_PORTS_1r(unit, rval); 40467 } 40468 40469 if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_HI_2r)) { 40470 rval = 0; 40471 soc_reg_field_set(unit, CMIC_PKT_PORTS_HI_2r, &rval, PORTS_HIf, 40472 SOC_PBMP_WORD_GET(pbmp, 2)); 40473 (void) WRITE_CMIC_PKT_PORTS_HI_2r(unit, rval); 40474 } else if (SOC_REG_IS_VALID(unit, CMIC_PKT_PORTS_2r)) { 40475 rval = 0; 40476 soc_reg_field_set(unit, CMIC_PKT_PORTS_2r, &rval, PORTS_HIf, 40477 SOC_PBMP_WORD_GET(pbmp, 2)); 40478 (void) WRITE_CMIC_PKT_PORTS_2r(unit, rval); 40479 } 40480 40481 rv = BCM_E_NONE; 40482 } else { 40483 rv = BCM_E_UNAVAIL; 40484 } 40485 break; 40486 40487 case bcmPortControlRemoteCpuTcMapping: 40488 if (soc_feature(unit, soc_feature_rcpu_tc_mapping)) { 40489 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40490 REMOTE_CPU_ENf, (value) ? 1 : 0); 40491 /* If BCM port, then set property in LPORT table too */ 40492 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 40493 rv = bcm_esw_port_lport_field_set(unit, port, 40494 LPORT_PROFILE_LPORT_TAB, 40495 REMOTE_CPU_ENf, 40496 (value) ? 1 : 0); 40497 } 40498 } else { 40499 rv = BCM_E_UNAVAIL; 40500 } 40501 break; 40502 40503 case bcmPortControlTrill: 40504 #if defined(BCM_TRIDENT_SUPPORT) 40505 if (soc_feature(unit, soc_feature_trill)) { 40506 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40507 TRILL_ENABLEf, (value) ? 1 : 0); 40508 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 40509 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, TRILL_ENABLEf)) { 40510 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 40511 TRILL_ENABLEf, 40512 (value) ? 1 : 0); 40513 } 40514 } 40515 } 40516 #endif /* BCM_TRIDENT_SUPPORT */ 40517 break; 40518 40519 case bcmPortControlTrillAllow: 40520 #if defined(BCM_TRIDENT_SUPPORT) 40521 if (soc_feature(unit, soc_feature_trill)) { 40522 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40523 ALLOW_TRILL_FRAMESf, 40524 (value) ? 1 : 0); 40525 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 40526 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 40527 ALLOW_TRILL_FRAMESf)) { 40528 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 40529 ALLOW_TRILL_FRAMESf, 40530 (value) ? 1 : 0); 40531 } 40532 } 40533 } 40534 #endif /* BCM_TRIDENT_SUPPORT */ 40535 break; 40536 40537 case bcmPortControlNonTrillAllow: 40538 #if defined(BCM_TRIDENT_SUPPORT) 40539 if (soc_feature(unit, soc_feature_trill)) { 40540 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40541 ALLOW_NON_TRILL_FRAMESf, 40542 (value) ? 1 : 0); 40543 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 40544 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 40545 ALLOW_NON_TRILL_FRAMESf)) { 40546 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 40547 ALLOW_NON_TRILL_FRAMESf, 40548 (value) ? 1 : 0); 40549 } 40550 } 40551 } 40552 #endif /* BCM_TRIDENT_SUPPORT */ 40553 break; 40554 40555 case bcmPortControlTrillCoreISISToCPU: 40556 #if defined(BCM_TRIDENT_SUPPORT) 40557 if (soc_feature(unit, soc_feature_trill)) { 40558 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40559 COPY_CORE_IS_IS_TO_CPUf, 40560 (value) ? 1 : 0); 40561 } 40562 #endif /* BCM_TRIDENT_SUPPORT */ 40563 break; 40564 40565 case bcmPortControlTrillHashSelect: 40566 #if defined(BCM_TRIUMPH3_SUPPORT) 40567 if (SOC_IS_TRIUMPH3(unit)) { 40568 return BCM_E_UNAVAIL; 40569 } else 40570 #endif /* BCM_TRIUMPH3_SUPPORT */ 40571 { 40572 #if defined(BCM_TRIDENT_SUPPORT) 40573 if (soc_feature(unit, soc_feature_trill)) { 40574 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40575 RTAG7_HASH_CFG_SEL_TRILL_ECMPf, (value) ? 1 : 0); 40576 } 40577 #endif /* BCM_TRIDENT_SUPPORT */ 40578 } 40579 break; 40580 40581 case bcmPortControlNivAccessVirtualInterfaceId: 40582 case bcmPortControlExtendedPortVid: 40583 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40584 if (soc_feature(unit, soc_feature_niv) || 40585 soc_feature(unit, soc_feature_port_extension)) { 40586 int mod_port_index; 40587 40588 if ((value < 0) || (value > 0xfff)) { 40589 return BCM_E_PARAM; 40590 } 40591 BCM_IF_ERROR_RETURN( 40592 _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40593 NIV_VIF_IDf, value)); 40594 BCM_IF_ERROR_RETURN( 40595 _bcm_esw_src_mod_port_table_index_get_from_port( 40596 unit, port, &mod_port_index)); 40597 SOC_IF_ERROR_RETURN( 40598 soc_mem_field32_modify(unit, EGR_GPP_ATTRIBUTESm, mod_port_index, 40599 SRC_NIV_VIF_IDf, value)); 40600 40601 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 40602 SOC_IS_GREYHOUND2(unit)) { 40603 uint64 val64; 40604 40605 rv = READ_EGR_PORT_64r(unit, port, &val64); 40606 if (BCM_SUCCESS(rv)) { 40607 soc_reg64_field32_set(unit, EGR_PORT_64r, 40608 &val64, 40609 NIV_VIF_IDf, value); 40610 } 40611 rv = WRITE_EGR_PORT_64r(unit, port, val64); 40612 } else { 40613 rv = _bcm_esw_egr_port_tab_set(unit, port, NIV_VIF_IDf, value); 40614 } 40615 } 40616 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 40617 break; 40618 40619 case bcmPortControlNivNonVntagDrop: 40620 case bcmPortControlNonEtagDrop: 40621 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40622 if (soc_feature(unit, soc_feature_niv) || 40623 soc_feature(unit, soc_feature_port_extension)) { 40624 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40625 DISCARD_IF_VNTAG_NOT_PRESENTf, (value) ? 1 : 0); 40626 } 40627 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT*/ 40628 break; 40629 40630 case bcmPortControlNivVntagDrop: 40631 case bcmPortControlEtagDrop: 40632 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40633 if (soc_feature(unit, soc_feature_niv) || 40634 soc_feature(unit, soc_feature_port_extension)) { 40635 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40636 DISCARD_IF_VNTAG_PRESENTf, (value) ? 1 : 0); 40637 } 40638 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 40639 break; 40640 40641 case bcmPortControlSubportPktTagDrop: 40642 #if defined(BCM_KATANA2_SUPPORT) 40643 if (soc_feature(unit, soc_feature_lltag)) { 40644 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40645 DISCARD_IF_LLTAG_PRESENTf, (value) ? 1 : 0); 40646 } 40647 #endif /* BCM_KATANA2_SUPPORT */ 40648 break; 40649 40650 case bcmPortControlNoSubportPktTagDrop: 40651 #if defined(BCM_KATANA2_SUPPORT) 40652 if (soc_feature(unit, soc_feature_lltag)) { 40653 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40654 DISCARD_IF_LLTAG_NOT_PRESENTf, (value) ? 1 : 0); 40655 } 40656 #endif /* BCM_KATANA2_SUPPORT */ 40657 break; 40658 40659 case bcmPortControlNivNonVntagAdd: 40660 case bcmPortControlNonEtagAdd: 40661 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40662 if (soc_feature(unit, soc_feature_niv) || 40663 soc_feature(unit, soc_feature_port_extension)) { 40664 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40665 VNTAG_ACTIONS_IF_NOT_PRESENTf, 40666 (value) ? 40667 ((type == bcmPortControlNonEtagAdd) ? 2 : VNTAG_ADD) : 40668 VNTAG_NOOP); 40669 } 40670 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 40671 break; 40672 40673 case bcmPortControlNivVntagIngressReplace: 40674 case bcmPortControlEtagIngressReplace: 40675 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40676 if (soc_feature(unit, soc_feature_niv) || 40677 soc_feature(unit, soc_feature_port_extension)) { 40678 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40679 VNTAG_ACTIONS_IF_PRESENTf, 40680 (value) ? VNTAG_REPLACE : VNTAG_NOOP); 40681 } 40682 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 40683 break; 40684 40685 case bcmPortControlNivVntagEgressReplace: 40686 case bcmPortControlEtagEgressReplace: 40687 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40688 if (soc_feature(unit, soc_feature_niv) || 40689 soc_feature(unit, soc_feature_port_extension)) { 40690 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 40691 SOC_IS_GREYHOUND2(unit)) { 40692 uint64 val64; 40693 40694 if (type == bcmPortControlEtagEgressReplace) { 40695 return BCM_E_UNAVAIL; 40696 } 40697 40698 rv = READ_EGR_PORT_64r(unit, port, &val64); 40699 if (BCM_SUCCESS(rv)) { 40700 soc_reg64_field32_set(unit, EGR_PORT_64r, 40701 &val64, 40702 VNTAG_ACTIONS_IF_PRESENTf, 40703 (value) ? VNTAG_REPLACE : VNTAG_NOOP); 40704 } 40705 rv = WRITE_EGR_PORT_64r(unit, port, val64); 40706 } else { 40707 rv = _bcm_esw_egr_port_tab_set( 40708 unit, port, VNTAG_ACTIONS_IF_PRESENTf, 40709 (value) ? VNTAG_REPLACE : VNTAG_NOOP); 40710 } 40711 } 40712 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 40713 break; 40714 40715 case bcmPortControlNivVntagIngressDelete: 40716 case bcmPortControlEtagIngressDelete: 40717 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40718 if (soc_feature(unit, soc_feature_niv) || 40719 soc_feature(unit, soc_feature_port_extension)) { 40720 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40721 VNTAG_ACTIONS_IF_PRESENTf, 40722 (value) ? VNTAG_DELETE : VNTAG_NOOP); 40723 } 40724 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 40725 break; 40726 40727 case bcmPortControlNivVntagEgressDelete: 40728 case bcmPortControlEtagEgressDelete: 40729 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40730 if (soc_feature(unit, soc_feature_niv) || 40731 soc_feature(unit, soc_feature_port_extension)) { 40732 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 40733 SOC_IS_GREYHOUND2(unit)) { 40734 uint64 val64; 40735 rv = READ_EGR_PORT_64r(unit, port, &val64); 40736 if (BCM_SUCCESS(rv)) { 40737 soc_reg64_field32_set(unit, EGR_PORT_64r, 40738 &val64, 40739 VNTAG_ACTIONS_IF_PRESENTf, 40740 (value) ? VNTAG_DELETE : VNTAG_NOOP); 40741 } 40742 rv = WRITE_EGR_PORT_64r(unit, port, val64); 40743 } else { 40744 rv = _bcm_esw_egr_port_tab_set( 40745 unit, port, VNTAG_ACTIONS_IF_PRESENTf, 40746 (value) ? VNTAG_DELETE: VNTAG_NOOP); 40747 } 40748 } 40749 #endif /* BCM_TRIDENT_SUPPORT || BCM_GREYHOUND_SUPPORT */ 40750 break; 40751 40752 case bcmPortControlNivRpfCheck: 40753 case bcmPortControlExtenderRpfCheck: 40754 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40755 if (soc_feature(unit, soc_feature_niv) || 40756 soc_feature(unit, soc_feature_port_extension)) { 40757 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40758 NIV_RPF_CHECK_ENABLEf, (value) ? 1 : 0); 40759 } 40760 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 40761 break; 40762 40763 case bcmPortControlNivSourceKnockout: 40764 case bcmPortControlExtenderSourceKnockout: 40765 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40766 if (soc_feature(unit, soc_feature_niv) || 40767 soc_feature(unit, soc_feature_port_extension)) { 40768 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 40769 SOC_IS_GREYHOUND2(unit)) { 40770 uint64 val64; 40771 rv = READ_EGR_PORT_64r(unit, port, &val64); 40772 if (BCM_SUCCESS(rv)) { 40773 soc_reg64_field32_set(unit, EGR_PORT_64r, 40774 &val64, 40775 NIV_PRUNE_ENABLEf, 40776 (value) ? 1 : 0); 40777 } 40778 rv = WRITE_EGR_PORT_64r(unit, port, val64); 40779 } else { 40780 rv = _bcm_esw_egr_port_tab_set(unit, port, NIV_PRUNE_ENABLEf, 40781 (value) ? 1 : 0); 40782 } 40783 } 40784 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 40785 break; 40786 40787 case bcmPortControlNivForwardPort: 40788 case bcmPortControlExtenderForwardPort: 40789 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40790 if (soc_feature(unit, soc_feature_niv) || 40791 soc_feature(unit, soc_feature_port_extension)) { 40792 int mod_port_index; 40793 bcm_module_t mod_out; 40794 bcm_port_t port_out; 40795 bcm_trunk_t trunk_out; 40796 int id_out; 40797 int tx_dest_port; 40798 40799 if (value == -1) { 40800 BCM_IF_ERROR_RETURN 40801 (_bcm_esw_port_tab_set(unit, port, 40802 _BCM_CPU_TABS_ETHER, 40803 NIV_UPLINK_PORTf, 1)); 40804 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 40805 SOC_IS_GREYHOUND2(unit)) { 40806 uint64 val64; 40807 rv = READ_EGR_PORT_64r(unit, port, &val64); 40808 if (BCM_SUCCESS(rv)) { 40809 soc_reg64_field32_set(unit, EGR_PORT_64r, 40810 &val64, 40811 NIV_UPLINK_PORTf, 1); 40812 } 40813 rv = WRITE_EGR_PORT_64r(unit, port, val64); 40814 } else { 40815 BCM_IF_ERROR_RETURN( 40816 _bcm_esw_egr_port_tab_set(unit, port, 40817 NIV_UPLINK_PORTf, 1)); 40818 BCM_IF_ERROR_RETURN( 40819 _bcm_esw_src_mod_port_table_index_get_from_port( 40820 unit, port, &mod_port_index)); 40821 SOC_IF_ERROR_RETURN( 40822 soc_mem_field32_modify(unit, EGR_GPP_ATTRIBUTESm, 40823 mod_port_index, 40824 SRC_IS_NIV_UPLINK_PORTf, 1)); 40825 } 40826 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40827 NIV_VIF_LOOKUP_ENABLEf, 1); 40828 } else { 40829 BCM_IF_ERROR_RETURN 40830 (_bcm_esw_gport_resolve(unit, value, &mod_out, &port_out, 40831 &trunk_out, &id_out)); 40832 if (id_out != -1) { 40833 return BCM_E_PARAM; 40834 } 40835 40836 if (soc_feature(unit, soc_feature_generic_dest)) { 40837 uint32 dval; 40838 if (trunk_out != -1) { 40839 dval = _soc_mem_dest_value_construct(unit, 40840 SOC_MEM_FIF_DEST_LAG, trunk_out); 40841 } else { 40842 dval = _soc_mem_dest_value_construct(unit, 40843 SOC_MEM_FIF_DEST_DGPP, 40844 mod_out << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS | port_out); 40845 } 40846 BCM_IF_ERROR_RETURN 40847 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40848 DESTINATIONf, dval)); 40849 } else { 40850 if (trunk_out != -1) { 40851 tx_dest_port = (1 << SOC_TRUNK_BIT_POS(unit)) + trunk_out; 40852 } else { 40853 #if defined(BCM_METROLITE_SUPPORT) 40854 /* Metrolite DGLP still uses 7 bits for ports like saber2 */ 40855 if (SOC_IS_METROLITE(unit)) { 40856 tx_dest_port = ((mod_out << 7) | (port_out)); 40857 } else 40858 #endif 40859 tx_dest_port = mod_out * (SOC_PORT_ADDR_MAX(unit) + 1) + 40860 port_out; 40861 } 40862 40863 BCM_IF_ERROR_RETURN 40864 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40865 TX_DEST_PORTf, tx_dest_port)); 40866 } 40867 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40868 TX_DEST_PORT_ENABLEf, 1); 40869 } 40870 } 40871 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 40872 break; 40873 40874 case bcmPortControlNivType: 40875 if (soc_feature(unit, soc_feature_niv)) { 40876 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 40877 SOC_IS_GREYHOUND2(unit)) { 40878 #if defined(BCM_GREYHOUND_SUPPORT) 40879 rv = bcm_gh_port_niv_type_set(unit, port, value); 40880 #endif /* BCM_GREYHOUND_SUPPORT */ 40881 } else { 40882 #if defined(BCM_TRIDENT_SUPPORT) 40883 rv = bcm_td_port_niv_type_set(unit, port, value); 40884 #endif /* BCM_TRIDENT_SUPPORT */ 40885 } 40886 } 40887 break; 40888 40889 case bcmPortControlExtenderType: 40890 if (soc_feature(unit, soc_feature_port_extension)) { 40891 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 40892 SOC_IS_GREYHOUND2(unit)) { 40893 #if defined(BCM_GREYHOUND_SUPPORT) 40894 rv = bcm_gh_port_extender_type_set(unit, port, value); 40895 #endif /* BCM_GREYHOUND_SUPPORT */ 40896 } else { 40897 #if defined(BCM_TRIUMPH3_SUPPORT) 40898 rv = bcm_tr3_port_extender_type_set(unit, port, value); 40899 #endif /* BCM_TRIUMPH3_SUPPORT */ 40900 } 40901 } 40902 break; 40903 40904 case bcmPortControlNivNameSpace: 40905 case bcmPortControlExtenderNameSpace: 40906 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40907 if (soc_feature(unit, soc_feature_niv) || 40908 soc_feature(unit, soc_feature_port_extension)) { 40909 if ((value < 0) || (value > 0xfff)) { 40910 return BCM_E_PARAM; 40911 } 40912 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40913 NIV_NAMESPACEf, value); 40914 } 40915 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 40916 break; 40917 40918 case bcmPortControlEtagPcpDeSelect: 40919 #if defined(INCLUDE_L3) 40920 if (soc_feature(unit, soc_feature_port_extension)) { 40921 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 40922 SOC_IS_GREYHOUND2(unit)) { 40923 #if defined(BCM_GREYHOUND_SUPPORT) 40924 rv = bcm_gh_port_etag_pcp_de_source_set(unit, port, value); 40925 #endif /* BCM_GREYHOUND_SUPPORT */ 40926 } else { 40927 #if defined(BCM_TRIUMPH3_SUPPORT) 40928 rv = bcm_tr3_port_etag_pcp_de_source_set(unit, port, value); 40929 #endif /* BCM_TRIUMPH3_SUPPORT */ 40930 } 40931 } 40932 #endif /* INCLUDE_L3 */ 40933 break; 40934 40935 case bcmPortControlEtagPcp: 40936 #if defined(BCM_TRIUMPH3_SUPPORT) 40937 if (soc_feature(unit, soc_feature_port_extension)) { 40938 if ((value < 0) || (value > 7)) { 40939 return BCM_E_PARAM; 40940 } 40941 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, ETAG_PCPf)) { 40942 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 40943 EGR_ING_PORTm, port, 40944 ETAG_PCPf, value)); 40945 } 40946 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40947 ETAG_PCPf, value); 40948 } 40949 #endif /* BCM_TRIUMPH3_SUPPORT */ 40950 #if defined(BCM_GREYHOUND_SUPPORT) 40951 if (soc_feature(unit, soc_feature_port_extension)) { 40952 if ((value < 0) || (value > 7)) { 40953 return BCM_E_PARAM; 40954 } 40955 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40956 ETAG_PCPf, value); 40957 } 40958 #endif /* BCM_GREYHOUND_SUPPORT */ 40959 break; 40960 40961 case bcmPortControlEtagDe: 40962 #if defined(BCM_TRIUMPH3_SUPPORT) 40963 if (soc_feature(unit, soc_feature_port_extension)) { 40964 if ((value < 0) || (value > 1)) { 40965 return BCM_E_PARAM; 40966 } 40967 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, ETAG_DEf)) { 40968 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 40969 EGR_ING_PORTm, port, 40970 ETAG_DEf, value)); 40971 } 40972 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40973 ETAG_DEf, value); 40974 } 40975 #endif /* BCM_TRIUMPH3_SUPPORT */ 40976 #if defined(BCM_GREYHOUND_SUPPORT) 40977 if (soc_feature(unit, soc_feature_port_extension)) { 40978 if ((value < 0) || (value > 1)) { 40979 return BCM_E_PARAM; 40980 } 40981 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40982 ETAG_DEf, value); 40983 } 40984 #endif /* BCM_GREYHOUND_SUPPORT */ 40985 break; 40986 40987 case bcmPortControlUseEtagPri: 40988 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 40989 if (soc_feature(unit, soc_feature_port_extension)) { 40990 if ((value < 0) || (value > 1)) { 40991 return BCM_E_PARAM; 40992 } 40993 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 40994 PHB_FROM_ETAGf, value); 40995 #if defined(BCM_GREYHOUND_SUPPORT) 40996 if(soc_feature(unit,soc_feature_pktpri_as_dot1p)){ 40997 if (BCM_FAILURE(rv)) { 40998 return rv; 40999 } 41000 /* 41001 * Make sure TREAT_PKTPRI_AS_DOT1P bit is set for 41002 * ETAG internal priority mapping. 41003 */ 41004 rv = bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 41005 (unit, (value) ? 1 : -1); 41006 } 41007 #endif /* BCM_GREYHOUND_SUPPORT */ 41008 } 41009 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */ 41010 break; 41011 41012 case bcmPortControlUseSubportPktTagPri: 41013 #if defined(BCM_KATANA2_SUPPORT) 41014 if (soc_feature(unit, soc_feature_lltag)) { 41015 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41016 PHB_FROM_LLTAGf, value); 41017 } 41018 #endif /* BCM_KATANA2_SUPPORT */ 41019 break; 41020 41021 case bcmPortControlProhibitedDot1p: 41022 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 41023 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41024 PROHIBITED_DOT1Pf, value); 41025 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 41026 break; 41027 41028 case bcmPortControlFabricSourceKnockout: 41029 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, REMOVE_HG_HDR_SRC_PORTf) || 41030 SOC_IS_TRIDENT3X(unit)) { 41031 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41032 REMOVE_HG_HDR_SRC_PORTf, (value) ? 1 : 0); 41033 41034 if (!SOC_IS_TOMAHAWK3(unit)) { 41035 /* If BCM port, then set property in LPORT table too */ 41036 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 41037 rv = bcm_esw_port_lport_field_set(unit, port, 41038 LPORT_PROFILE_LPORT_TAB, 41039 ALLOW_SRC_MODf, value); 41040 } 41041 } 41042 } 41043 break; 41044 case bcmPortControlRxEnable: 41045 rv = _bcm_esw_mac_rx_control(unit, port, 0, &value); 41046 break; 41047 case bcmPortControlTxEnable: 41048 41049 if (SOC_REG_IS_VALID(unit, COSMASKr)) { 41050 /* Use egress scheduling control if available */ 41051 uint32 val; 41052 if (value > 0) { 41053 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) { 41054 /* Port tx was never stopped */ 41055 rv = BCM_E_NONE; 41056 break; 41057 } 41058 /* Restore values */ 41059 val = PORT(unit, port).cosmask; 41060 rv = soc_reg_field32_modify(unit, COSMASKr, port, 41061 COSMASKf, val); 41062 /* clear flag */ 41063 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX; 41064 } else { 41065 uint32 rval; 41066 /* Read and save current values */ 41067 SOC_IF_ERROR_RETURN(READ_COSMASKr(unit, port, &rval)); 41068 PORT(unit, port).cosmask = soc_reg_field_get(unit, COSMASKr, 41069 rval, COSMASKf); 41070 /* set flag */ 41071 PORT(unit, port).flags |= _PORT_INFO_STOP_TX; 41072 /* Disable Tx */ 41073 val = (1 << soc_reg_field_length(unit, COSMASKr, 41074 COSMASKf)) - 1; 41075 rv = soc_reg_field32_modify(unit, COSMASKr, port, 41076 COSMASKf, val); 41077 } 41078 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) 41079 } else if (SOC_IS_HELIX4(unit) || SOC_IS_TRIUMPH3(unit)) { 41080 rv = BCM_E_NONE; 41081 if (value > 0 ) { 41082 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) { 41083 /* Port tx already enabled */ 41084 break; 41085 } 41086 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX; 41087 BCM_IF_ERROR_RETURN(_bcm_tr3_port_tx_set(unit, port, 1)); 41088 } else { 41089 if ((PORT(unit, port).flags & _PORT_INFO_STOP_TX)) { 41090 /* Port tx already disabled */ 41091 break; 41092 } 41093 PORT(unit, port).flags |= _PORT_INFO_STOP_TX; 41094 BCM_IF_ERROR_RETURN(_bcm_tr3_port_tx_set(unit, port, 0)); 41095 } 41096 break; 41097 #endif 41098 } else if ((SOC_REG_IS_VALID(unit, EGRMETERINGCONFIGr)) || 41099 (SOC_REG_IS_VALID(unit, EGRMETERINGBUCKETr))) { /* Use egress metering control if available */ 41100 uint32 rval1 = 0, rval2 = 0; 41101 if (value > 0 ) { 41102 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) { 41103 /* Port tx was never stopped */ 41104 break; 41105 } 41106 /* Restore values */ 41107 BCM_IF_ERROR_RETURN(READ_EGRMETERINGCONFIGr(unit, port, 41108 &rval1)); 41109 BCM_IF_ERROR_RETURN(READ_EGRMETERINGBUCKETr(unit, port, 41110 &rval2)); 41111 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1, 41112 REFRESHf, PORT(unit, port).m_info.refresh); 41113 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1, 41114 THD_SELf, PORT(unit, port).m_info.threshold); 41115 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2, 41116 BUCKETf, PORT(unit, port).m_info.bucket); 41117 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2, 41118 IN_PROFILE_FLAGf, 41119 PORT(unit, port).m_info.in_profile); 41120 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGCONFIGr(unit, port, 41121 rval1)); 41122 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGBUCKETr(unit, port, 41123 rval2)); 41124 /* clear flag */ 41125 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX; 41126 rv = BCM_E_NONE; 41127 41128 } else { 41129 /* Read and save current values */ 41130 BCM_IF_ERROR_RETURN(READ_EGRMETERINGCONFIGr(unit, port, 41131 &rval1)); 41132 PORT(unit, port).m_info.refresh = 41133 soc_reg_field_get(unit, EGRMETERINGCONFIGr, rval1, 41134 REFRESHf); 41135 PORT(unit, port).m_info.threshold = 41136 soc_reg_field_get(unit, EGRMETERINGCONFIGr, rval1, 41137 THD_SELf); 41138 BCM_IF_ERROR_RETURN(READ_EGRMETERINGBUCKETr(unit, port, 41139 &rval2)); 41140 PORT(unit, port).m_info.bucket = 41141 soc_reg_field_get(unit, EGRMETERINGBUCKETr, rval2, 41142 BUCKETf); 41143 PORT(unit, port).m_info.in_profile = 41144 soc_reg_field_get(unit, EGRMETERINGBUCKETr, rval2, 41145 IN_PROFILE_FLAGf); 41146 /* set flag */ 41147 PORT(unit, port).flags |= _PORT_INFO_STOP_TX; 41148 /* Disable Tx */ 41149 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1, 41150 REFRESHf, 0); 41151 soc_reg_field_set(unit, EGRMETERINGCONFIGr, &rval1, 41152 THD_SELf, 1); 41153 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2, 41154 BUCKETf, 0x100000); 41155 soc_reg_field_set(unit, EGRMETERINGBUCKETr, &rval2, 41156 IN_PROFILE_FLAGf, 1); 41157 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGCONFIGr(unit, port, 41158 rval1)); 41159 BCM_IF_ERROR_RETURN(WRITE_EGRMETERINGBUCKETr(unit, port, 41160 rval2)); 41161 rv = BCM_E_NONE; 41162 } 41163 } else { 41164 int (*port_tx_enable_set) (int, soc_port_t, int); 41165 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 41166 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TRIDENT2(unit)) { 41167 port_tx_enable_set = soc_td2_port_traffic_egr_enable_set; 41168 } else 41169 #endif 41170 #if defined(BCM_TRIDENT3_SUPPORT) 41171 if (SOC_IS_TRIDENT3X(unit)) { 41172 port_tx_enable_set = soc_td3_port_traffic_egr_enable_set; 41173 } else 41174 #endif 41175 #if defined(BCM_MONTEREY_SUPPORT) 41176 if (SOC_IS_MONTEREY(unit)) { 41177 port_tx_enable_set = soc_monterey_port_traffic_egr_enable_set; 41178 } else 41179 #endif 41180 #if defined(BCM_APACHE_SUPPORT) 41181 if (SOC_IS_APACHE(unit)) { 41182 port_tx_enable_set = soc_apache_port_traffic_egr_enable_set; 41183 } else 41184 #endif 41185 #if defined(BCM_TOMAHAWK_SUPPORT) 41186 if (SOC_IS_TOMAHAWKX(unit)) { 41187 port_tx_enable_set = soc_tomahawk_port_traffic_egr_enable_set; 41188 } else 41189 #endif 41190 { 41191 port_tx_enable_set = NULL; 41192 } 41193 if (port_tx_enable_set != NULL ) { 41194 rv = BCM_E_NONE; 41195 if (value > 0 ) { 41196 if (!(PORT(unit, port).flags & _PORT_INFO_STOP_TX)) { 41197 /* Port tx was never stopped */ 41198 break; 41199 } 41200 PORT(unit, port).flags &= ~_PORT_INFO_STOP_TX; 41201 BCM_IF_ERROR_RETURN(((*port_tx_enable_set)(unit, port, 1))); 41202 } else { 41203 if ((PORT(unit, port).flags & _PORT_INFO_STOP_TX)) { 41204 /* Port tx alrady enabled */ 41205 break; 41206 } 41207 PORT(unit, port).flags |= _PORT_INFO_STOP_TX; 41208 BCM_IF_ERROR_RETURN(((*port_tx_enable_set)(unit, port, 0))); 41209 } 41210 break; 41211 } else { 41212 rv = BCM_E_UNAVAIL; 41213 } 41214 } 41215 break; 41216 case bcmPortControlMplsEntropyHashSet: 41217 #if defined(BCM_TRIUMPH3_SUPPORT) 41218 if (SOC_IS_TRIUMPH3(unit)) { 41219 return BCM_E_UNAVAIL; 41220 } else 41221 #endif /* BCM_TRIUMPH3_SUPPORT */ 41222 #if defined(BCM_KATANA2_SUPPORT) 41223 if (SOC_IS_KATANA2(unit)) { 41224 return BCM_E_UNAVAIL; 41225 } else 41226 #endif /* BCM_KATANA2_SUPPORT */ 41227 { 41228 #if defined(BCM_KATANA_SUPPORT) 41229 if (soc_feature(unit, soc_feature_mpls)) { 41230 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41231 RTAG7_HASH_CFG_SEL_ENTROPY_LABELf, 41232 (value) ? 1 : 0); 41233 } 41234 #endif /* BCM_KATANA_SUPPORT */ 41235 } 41236 break; 41237 41238 case bcmPortControlL2GreEnable: 41239 #if defined(BCM_TRIUMPH3_SUPPORT) 41240 if (soc_feature(unit, soc_feature_l2gre) 41241 #if defined(BCM_TRIDENT3_SUPPORT) 41242 || soc_feature(unit, soc_feature_flex_flow) 41243 #endif 41244 ) { 41245 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41246 L2GRE_TERMINATION_ALLOWEDf, 41247 (value) ? 1 : 0); 41248 } 41249 #endif /* BCM_TRIUMPH3_SUPPORT */ 41250 break; 41251 41252 case bcmPortControlL2GreTunnelbasedVpnId: 41253 #if defined(BCM_TRIUMPH3_SUPPORT) 41254 if (soc_feature(unit, soc_feature_l2gre) 41255 #if defined(BCM_TRIDENT3_SUPPORT) 41256 || soc_feature(unit, soc_feature_flex_flow) 41257 #endif 41258 ) { 41259 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41260 L2GRE_VPNID_LOOKUP_KEY_TYPEf, 41261 (value) ? 1 : 0); 41262 41263 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 41264 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 41265 L2GRE_VFI_LOOKUP_KEY_TYPEf)) { 41266 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 41267 L2GRE_VFI_LOOKUP_KEY_TYPEf, 41268 (value) ? 1 : 0); 41269 } 41270 } 41271 } 41272 #endif /* BCM_TRIUMPH3_SUPPORT */ 41273 break; 41274 41275 case bcmPortControlL2GreDefaultTunnelEnable: 41276 #if defined(BCM_TRIUMPH3_SUPPORT) 41277 if (soc_feature(unit, soc_feature_l2gre) 41278 #if defined(BCM_TRIDENT3_SUPPORT) 41279 || soc_feature(unit, soc_feature_flex_flow) 41280 #endif 41281 ) { 41282 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41283 L2GRE_DEFAULT_SVP_ENABLEf, 41284 (value) ? 1 : 0); 41285 } 41286 #endif /* BCM_TRIUMPH3_SUPPORT */ 41287 break; 41288 41289 case bcmPortControlVxlanEnable: 41290 #if defined(BCM_TRIDENT2_SUPPORT) 41291 if ((soc_feature(unit, soc_feature_vxlan)) || 41292 (soc_feature(unit, soc_feature_flex_flow))) { 41293 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41294 VXLAN_TERMINATION_ALLOWEDf, 41295 (value) ? 1 : 0); 41296 } 41297 #endif /* BCM_TRIDENT2_SUPPORT */ 41298 break; 41299 41300 case bcmPortControlVxlanTunnelbasedVnId: 41301 #if defined(BCM_TRIDENT2_SUPPORT) 41302 if ((soc_feature(unit, soc_feature_vxlan)) || 41303 (soc_feature(unit, soc_feature_flex_flow))) { 41304 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41305 VXLAN_VN_ID_LOOKUP_KEY_TYPEf, 41306 (value) ? 1 : 0); 41307 if (BCM_SUCCESS(rv) && !BCM_GPORT_IS_SET(port)) { 41308 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 41309 VXLAN_VFI_LOOKUP_KEY_TYPEf)) { 41310 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 41311 VXLAN_VFI_LOOKUP_KEY_TYPEf, 41312 (value) ? 1 : 0); 41313 } 41314 } 41315 #if defined(BCM_TRIDENT3_SUPPORT) && defined(CANCUN_SUPPORT) 41316 if (BCM_SUCCESS(rv) && SOC_IS_TRIDENT3X(unit)) { 41317 rv = _bcm_esw_td3_port_cmh_ctrl_set(unit, port, type, value); 41318 } 41319 #endif 41320 } 41321 #endif /* BCM_TRIDENT2_SUPPORT */ 41322 break; 41323 case bcmPortControlVxlanVpnAssignmentCriteria: 41324 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 41325 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 41326 if ((value < bcmPortVxlanVpnAssignOnVnid) 41327 || (value > bcmPortVxlanVpnAssignOnVnidOuterVlanSrcIp)) { 41328 return BCM_E_PARAM; 41329 } 41330 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41331 VXLAN_VN_ID_LOOKUP_KEY_TYPEf, value); 41332 } 41333 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 41334 break; 41335 case bcmPortControlVxlanTerminationMatchCriteria: 41336 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 41337 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 41338 if ((value < bcmPortVxlanTerminationMatchDstIp) 41339 || (value > bcmPortVxlanTerminationMatchOuterVlanDstIp)) { 41340 return BCM_E_PARAM; 41341 } 41342 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41343 VXLAN_TERMINATION_LOOKUP_TYPEf, value); 41344 } 41345 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 41346 break; 41347 case bcmPortControlVxlanGportAssignmentCriteria: 41348 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 41349 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 41350 if ((value < bcmPortVxlanGportAssignOnSrcIp) 41351 || (value > bcmPortVxlanGportAssignOnOuterVlanSrcIp)) { 41352 return BCM_E_PARAM; 41353 } 41354 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41355 VXLAN_SVP_ASSIGNMENT_KEY_TYPEf, value); 41356 } 41357 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 41358 break; 41359 case bcmPortControlVxlanDefaultTunnelEnable: 41360 #if defined(BCM_TRIDENT2_SUPPORT) 41361 if ((soc_feature(unit, soc_feature_vxlan)) || 41362 (soc_feature(unit, soc_feature_flex_flow))) { 41363 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 41364 VXLAN_DEFAULT_SVP_ENABLEf, 41365 (value) ? 1 : 0); 41366 } 41367 #endif /* BCM_TRIDENT2_SUPPORT */ 41368 break; 41369 41370 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX) 41371 case bcmPortControlRegex: 41372 if (!SOC_IS_TRIUMPH3(unit)) { 41373 return BCM_E_UNAVAIL; 41374 } 41375 rv = _bcm_esw_port_regex_control_set(unit, port, 1, 1, !!value); 41376 break; 41377 case bcmPortControlRegexTcp: 41378 if (!SOC_IS_TRIUMPH3(unit)) { 41379 return BCM_E_UNAVAIL; 41380 } 41381 rv = _bcm_esw_port_regex_control_set(unit, port, 0, 1, !!value); 41382 break; 41383 case bcmPortControlRegexUdp: 41384 if (!SOC_IS_TRIUMPH3(unit)) { 41385 return BCM_E_UNAVAIL; 41386 } 41387 rv = _bcm_esw_port_regex_control_set(unit, port, 1, 0, !!value); 41388 break; 41389 #endif 41390 #ifdef BCM_SHADOW_SUPPORT 41391 case bcmPortControlManagementPacketIp6Reserved: 41392 if (!SOC_IS_SHADOW(unit)) { 41393 return BCM_E_UNAVAIL; 41394 } 41395 PORT_LOCK(unit); 41396 if (value == 0) { 41397 /* Clear the MGMT Frame classification */ 41398 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 41399 IPV6_RESVf, 0); 41400 } else { 41401 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 41402 IPV6_RESVf, 1); 41403 } 41404 PORT_UNLOCK(unit); 41405 break; 41406 case bcmPortControlManagementPacketIp4Reserved: 41407 if (!SOC_IS_SHADOW(unit)) { 41408 return BCM_E_UNAVAIL; 41409 } 41410 PORT_LOCK(unit); 41411 if (value == 0) { 41412 /* Clear the MGMT Frame classification */ 41413 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 41414 IPV6_RESVf, 0); 41415 } else { 41416 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 41417 IPV4_RESVf, 1); 41418 } 41419 PORT_UNLOCK(unit); 41420 break; 41421 case bcmPortControlManagementPacketLinkConstrained: 41422 if (!SOC_IS_SHADOW(unit)) { 41423 return BCM_E_UNAVAIL; 41424 } 41425 PORT_LOCK(unit); 41426 if (value == 0) { 41427 /* Clear the MGMT Frame classification */ 41428 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 41429 LINK_CONSTf, 0); 41430 } else { 41431 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 41432 LINK_CONSTf, 1); 41433 } 41434 PORT_UNLOCK(unit); 41435 break; 41436 case bcmPortControlManagementPacketGarp: 41437 if (!SOC_IS_SHADOW(unit)) { 41438 return BCM_E_UNAVAIL; 41439 } 41440 PORT_LOCK(unit); 41441 if (value == 0) { 41442 /* Clear the MGMT Frame classification */ 41443 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 41444 DOT1D_GARPf, 0); 41445 } else { 41446 rv = soc_reg_field32_modify(unit, MGMT_FRAME_ENABLEr, port, 41447 DOT1D_GARPf, 1); 41448 } 41449 PORT_UNLOCK(unit); 41450 break; 41451 case bcmPortControlManagementPacketCos: 41452 if (!SOC_IS_SHADOW(unit)) { 41453 return BCM_E_UNAVAIL; 41454 } 41455 PORT_LOCK(unit); 41456 if ((value >= 0) && (value <= 7)) { 41457 /* Clear the MGMT Frame classification */ 41458 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 41459 MGMT_FRAME_COSf, value); 41460 } else { 41461 rv = BCM_E_PARAM; 41462 } 41463 PORT_UNLOCK(unit); 41464 break; 41465 case bcmPortControlManagementPacketColor: 41466 rv = BCM_E_UNAVAIL; 41467 break; 41468 case bcmPortControlTaggedL3PacketPktPri: 41469 if (!SOC_IS_SHADOW(unit)) { 41470 return BCM_E_UNAVAIL; 41471 } 41472 PORT_LOCK(unit); 41473 switch ((bcm_port_cos_remap_t)value) { 41474 case BCM_PORT_COS_REMAP_VLAN_PRI: 41475 /* Clear the MGMT Frame classification */ 41476 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 41477 SELECT5f, 0); 41478 break; 41479 case BCM_PORT_COS_REMAP_DSCP: 41480 /* Clear the MGMT Frame classification */ 41481 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 41482 SELECT5f, 2); 41483 break; 41484 default: 41485 rv = BCM_E_PARAM; 41486 } 41487 PORT_UNLOCK(unit); 41488 break; 41489 case bcmPortControlTaggedMPLSPacketPktPri: 41490 if (!SOC_IS_SHADOW(unit)) { 41491 return BCM_E_UNAVAIL; 41492 } 41493 PORT_LOCK(unit); 41494 switch ((bcm_port_cos_remap_t)value) { 41495 case BCM_PORT_COS_REMAP_VLAN_PRI: 41496 /* Clear the MGMT Frame classification */ 41497 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 41498 SELECT3f, 0); 41499 break; 41500 case BCM_PORT_COS_REMAP_EXP: 41501 /* Clear the MGMT Frame classification */ 41502 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 41503 SELECT3f, 1); 41504 break; 41505 default: 41506 rv = BCM_E_PARAM; 41507 } 41508 PORT_UNLOCK(unit); 41509 break; 41510 case bcmPortControlTaggedMPLSL3PacketPktPri: 41511 if (!SOC_IS_SHADOW(unit)) { 41512 return BCM_E_UNAVAIL; 41513 } 41514 PORT_LOCK(unit); 41515 switch(value) { 41516 case BCM_PORT_COS_REMAP_VLAN_PRI: 41517 /* Clear the MGMT Frame classification */ 41518 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 41519 SELECT7f, 0); 41520 break; 41521 case BCM_PORT_COS_REMAP_DSCP: 41522 /* Clear the MGMT Frame classification */ 41523 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 41524 SELECT7f, 2); 41525 break; 41526 case BCM_PORT_COS_REMAP_EXP: 41527 /* Clear the MGMT Frame classification */ 41528 rv = soc_reg_field32_modify(unit, COSDP_REMAP_CONTROLr, port, 41529 SELECT7f, 1); 41530 break; 41531 default: 41532 rv = BCM_E_PARAM; 41533 } 41534 PORT_UNLOCK(unit); 41535 break; 41536 41537 #endif 41538 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 41539 case bcmPortControlFieldEgressClassSelect: 41540 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 41541 if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) { 41542 rv = _bcm_td2p_port_control_egress_class_select_set(unit, port, value); 41543 } else 41544 #endif 41545 { 41546 rv = _bcm_trx_port_control_egress_class_select_set(unit, port, value); 41547 } 41548 break; 41549 #endif 41550 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 41551 case bcmPortControlFieldHiGigClassSelect: 41552 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 41553 if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) { 41554 rv = _bcm_td2p_port_control_higig_class_select_set(unit, port, value); 41555 } else 41556 #endif 41557 { 41558 rv = _bcm_trx_port_control_higig_class_select_set(unit, port, value); 41559 } 41560 break; 41561 #endif 41562 case bcmPortControlSubportTagEnable: 41563 41564 #if defined (BCM_HGPROXY_COE_SUPPORT) 41565 if(soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 41566 rv = bcmi_xgs5_port_control_subtag_status_set(unit, port, value); 41567 } 41568 #endif 41569 #if defined (BCM_KATANA2_SUPPORT) 41570 if (soc_feature(unit, soc_feature_subtag_coe)) { 41571 if (SOC_IS_KATANA2(unit)) { 41572 rv = bcm_kt2_port_control_subtag_status_set(unit, port, value); 41573 } 41574 #if defined (BCM_METROLITE_SUPPORT) 41575 /*In Metrolite physical port PP port is [re]used for the subports 41576 * to achieve the MAX number of streams.*/ 41577 if((soc_feature(unit, soc_feature_discontinuous_pp_port)) && (rv == BCM_E_NONE)){ 41578 BCM_PBMP_CLEAR(pbm); 41579 BCM_PBMP_PORT_ADD(pbm, port); 41580 if(value){ 41581 bcm_esw_vlan_port_remove(unit, BCM_VLAN_DEFAULT, pbm); 41582 }else{ 41583 bcm_esw_vlan_port_add(unit, BCM_VLAN_DEFAULT, pbm, pbm); 41584 } 41585 } 41586 #endif 41587 } 41588 #endif 41589 break; 41590 41591 case bcmPortControlLinkPhyEnable: 41592 #if defined (BCM_KATANA2_SUPPORT) 41593 if (soc_feature(unit, soc_feature_linkphy_coe)) { 41594 if (SOC_IS_KATANA2(unit)) { 41595 rv = bcm_kt2_port_control_linkphy_status_set(unit, port, value); 41596 } 41597 #if defined (BCM_METROLITE_SUPPORT) 41598 /*In Metrolite physical port PP port is [re]used for the subports 41599 * to achieve the MAX number of streams.*/ 41600 if((soc_feature(unit, soc_feature_discontinuous_pp_port)) && (rv == BCM_E_NONE)){ 41601 BCM_PBMP_CLEAR(pbm); 41602 BCM_PBMP_PORT_ADD(pbm, port); 41603 if(value){ 41604 bcm_esw_vlan_port_remove(unit, BCM_VLAN_DEFAULT, pbm); 41605 }else{ 41606 bcm_esw_vlan_port_add(unit, BCM_VLAN_DEFAULT, pbm, pbm); 41607 } 41608 } 41609 #endif 41610 } 41611 #endif 41612 break; 41613 41614 #if defined(BCM_TRIDENT2_SUPPORT) 41615 41616 case bcmPortControlFcoeRouteEnable: 41617 if (soc_feature(unit, soc_feature_fcoe)) { 41618 #ifdef BCM_TRIDENT3_SUPPORT 41619 if (SOC_IS_TRIDENT3X(unit)) { 41620 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41621 FCOE_ROUTE_ENABLEf, 41622 (value) ? 1 : 0); 41623 if ((rv == BCM_E_NONE) && 41624 SOC_MEM_IS_VALID(unit, EGR_PORTm) && 41625 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_ROUTE_ENABLEf)) { 41626 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 41627 FCOE_ROUTE_ENABLEf, 41628 (value) ? 1 : 0); 41629 } 41630 } else 41631 #endif 41632 { 41633 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_ROUTE_ENABLEf)) { 41634 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41635 FCOE_ROUTE_ENABLEf, 41636 (value) ? 1 : 0); 41637 } 41638 if ((rv == BCM_E_NONE) && 41639 SOC_MEM_IS_VALID(unit, EGR_PORTm) && 41640 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_ROUTE_ENABLEf)) { 41641 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 41642 FCOE_ROUTE_ENABLEf, 41643 (value) ? 1 : 0); 41644 } 41645 } 41646 } 41647 break; 41648 41649 case bcmPortControlFcoeVftEnable: 41650 if (soc_feature(unit, soc_feature_fcoe)) { 41651 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VFT_ENABLEf)) { 41652 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41653 FCOE_VFT_ENABLEf, (value) ? 1 : 0); 41654 } 41655 } 41656 break; 41657 41658 case bcmPortControlFcoeZoneCheckEnable: 41659 if (soc_feature(unit, soc_feature_fcoe)) { 41660 if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, 41661 FCOE_ZONE_CHECK_ENABLEf))) { 41662 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41663 FCOE_ZONE_CHECK_ENABLEf, 41664 (value) ? 1 : 0); 41665 } 41666 } 41667 break; 41668 41669 case bcmPortControlFcoeSourceBindCheckEnable: 41670 if (soc_feature(unit, soc_feature_fcoe)) { 41671 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, 41672 FCOE_SRC_BIND_CHECK_ENABLEf)) { 41673 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41674 FCOE_SRC_BIND_CHECK_ENABLEf, 41675 (value) ? 1 : 0); 41676 } 41677 } 41678 break; 41679 41680 case bcmPortControlFcoeFpmaPrefixCheckEnable: 41681 if (soc_feature(unit, soc_feature_fcoe)) { 41682 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, 41683 FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf)) { 41684 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41685 FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf, 41686 (value) ? 1 : 0); 41687 } 41688 } 41689 break; 41690 41691 case bcmPortControlFcoeDoNotLearn: 41692 if (soc_feature(unit, soc_feature_fcoe)) { 41693 if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_DO_NOT_LEARNf))) { 41694 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41695 FCOE_DO_NOT_LEARNf, 41696 (value) ? 1 : 0); 41697 } 41698 } 41699 break; 41700 41701 case bcmPortControlFcoeNetworkPort: 41702 if (soc_feature(unit, soc_feature_fcoe)) { 41703 if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_NETWORK_PORTf))) { 41704 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41705 FCOE_NETWORK_PORTf, 41706 (value) ? 1 : 0); 41707 } 41708 } 41709 break; 41710 41711 case bcmPortControlFcoeFabricSel: 41712 if (soc_feature(unit, soc_feature_fcoe)) { 41713 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_SELf)) { 41714 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41715 FCOE_FABRIC_SELf, value); 41716 } 41717 } 41718 break; 41719 41720 case bcmPortControlFcoeFabricId: 41721 if (soc_feature(unit, soc_feature_fcoe)) { 41722 #ifdef BCM_TRIDENT3_SUPPORT 41723 if (SOC_IS_TRIDENT3X(unit)) { 41724 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41725 FCOE_FABRIC_IDf, value); 41726 } else 41727 #endif 41728 { 41729 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_IDf)) { 41730 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41731 FCOE_FABRIC_IDf, value); 41732 } 41733 } 41734 } 41735 break; 41736 41737 case bcmPortControlFcoeFabricPri: 41738 if (soc_feature(unit, soc_feature_fcoe)) { 41739 #ifdef BCM_TRIDENT3_SUPPORT 41740 if (SOC_IS_TRIDENT3X(unit)) { 41741 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41742 FCOE_FABRIC_PRIf, value); 41743 } else 41744 #endif 41745 { 41746 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_PRIf)) { 41747 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41748 FCOE_FABRIC_PRIf, value); 41749 } 41750 } 41751 } 41752 break; 41753 41754 case bcmPortControlFcoeFcCrcAction: 41755 if (soc_feature(unit, soc_feature_fcoe)) { 41756 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, 41757 FCOE_FC_CRC_ACTIONf)) { 41758 /* 2 bits but only 0,1 are valid */ 41759 rv = soc_mem_field32_modify(unit, EGR_ING_PORTm, port, 41760 FCOE_FC_CRC_ACTIONf, value); 41761 } 41762 } 41763 break; 41764 41765 case bcmPortControlFcoeFcCrcRecompute: 41766 if (soc_feature(unit, soc_feature_fcoe)) { 41767 if (SOC_MEM_IS_VALID(unit, EGR_PORTm) && 41768 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 41769 FCOE_FC_CRC_RECOMPUTEf)) { 41770 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 41771 FCOE_FC_CRC_RECOMPUTEf, value); 41772 } 41773 } 41774 break; 41775 41776 case bcmPortControlFcoeFcEofIgnore: 41777 if (soc_feature(unit, soc_feature_fcoe)) { 41778 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, 41779 FCOE_FC_EOF_IGNOREf)) { 41780 rv = soc_mem_field32_modify(unit, EGR_ING_PORTm, port, 41781 FCOE_FC_EOF_IGNOREf, 41782 (value) ? 1 : 0); 41783 } 41784 } 41785 break; 41786 41787 case bcmPortControlFcoeTranslateKeyFirst: 41788 case bcmPortControlFcoeTranslateKeySecond: 41789 if (soc_feature(unit, soc_feature_fcoe)) { 41790 41791 /* first, translate value to HW value */ 41792 int key_type = 0; 41793 int key_type_value; 41794 int use_port = 0; 41795 41796 switch (value) { 41797 case bcmFcoeVsanTranslateKeyPortDouble: 41798 use_port = 1; /* fall thru */ 41799 case bcmFcoeVsanTranslateKeyDouble: 41800 key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID; 41801 break; 41802 case bcmFcoeVsanTranslateKeyPortOuterTag: 41803 use_port = 1; /* fall thru */ 41804 case bcmFcoeVsanTranslateKeyOuterTag: 41805 key_type = VLXLT_HASH_KEY_TYPE_OTAG; 41806 break; 41807 case bcmFcoeVsanTranslateKeyPortInnerTag: 41808 use_port = 1; /* fall thru */ 41809 case bcmFcoeVsanTranslateKeyInnerTag: 41810 key_type = VLXLT_HASH_KEY_TYPE_ITAG; 41811 break; 41812 case bcmFcoeVsanTranslateKeyPortOuter: 41813 use_port = 1; /* fall thru */ 41814 case bcmFcoeVsanTranslateKeyOuter: 41815 key_type = VLXLT_HASH_KEY_TYPE_OVID; 41816 break; 41817 case bcmFcoeVsanTranslateKeyPortInner: 41818 use_port = 1; /* fall thru */ 41819 case bcmFcoeVsanTranslateKeyInner: 41820 key_type = VLXLT_HASH_KEY_TYPE_IVID; 41821 break; 41822 case bcmFcoeVsanTranslateKeyPortOuterPri: 41823 use_port = 1; /* fall thru */ 41824 case bcmFcoeVsanTranslateKeyOuterPri: 41825 key_type = VLXLT_HASH_KEY_TYPE_PRI_CFI; 41826 break; 41827 case bcmFcoeVsanTranslateKeyPortDoubleVsan: 41828 use_port = 1; /* fall thru */ 41829 case bcmFcoeVsanTranslateKeyDoubleVsan: 41830 key_type = VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN; 41831 break; 41832 case bcmFcoeVsanTranslateKeyPortInnerVsan: 41833 use_port = 1; /* fall thru */ 41834 case bcmFcoeVsanTranslateKeyInnerVsan: 41835 key_type = VLXLT_HASH_KEY_TYPE_IVID_VSAN; 41836 break; 41837 case bcmFcoeVsanTranslateKeyPortOuterVsan: 41838 use_port = 1; /* fall thru */ 41839 case bcmFcoeVsanTranslateKeyOuterVsan: 41840 key_type = VLXLT_HASH_KEY_TYPE_OVID_VSAN; 41841 break; 41842 default: 41843 return BCM_E_PARAM; 41844 } 41845 41846 BCM_IF_ERROR_RETURN( 41847 _bcm_esw_vlan_xlate_key_type_value_get(unit, key_type, 41848 &key_type_value)); 41849 41850 if (type == bcmPortControlFcoeTranslateKeyFirst) { 41851 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_1f)) { 41852 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41853 FCOE_VT_KEY_TYPE_1f, 41854 key_type_value); 41855 } 41856 if (BCM_SUCCESS(rv)) { 41857 rv = _bcm_esw_port_config_set(unit, port, 41858 _bcmPortVTKeyPortFirst, 41859 use_port); 41860 } 41861 } else { 41862 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_2f)) { 41863 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 41864 FCOE_VT_KEY_TYPE_2f, 41865 key_type_value); 41866 } 41867 if (BCM_SUCCESS(rv)) { 41868 rv = _bcm_esw_port_config_set(unit, port, 41869 _bcmPortVTKeyPortSecond, 41870 use_port); 41871 } 41872 } 41873 } 41874 break; 41875 41876 case bcmPortControlFcoeTranslateKeyFirstEgress: 41877 case bcmPortControlFcoeTranslateKeySecondEgress: 41878 if (soc_feature(unit, soc_feature_fcoe)) { 41879 41880 /* first, translate value to HW value */ 41881 int key_type_value = 0; 41882 41883 switch (value) { 41884 case bcmFcoeVsanTranslateKeyEgressDoubleVsan: 41885 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN; 41886 break; 41887 case bcmFcoeVsanTranslateKeyEgressVsan: 41888 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_VSAN; 41889 break; 41890 case bcmFcoeVsanTranslateKeyEgressInnerVsan: 41891 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID_VSAN; 41892 break; 41893 case bcmFcoeVsanTranslateKeyEgressOuterVsan: 41894 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_OVID_VSAN; 41895 break; 41896 case bcmFcoeVsanTranslateKeyEgressDouble: 41897 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID; 41898 break; 41899 case bcmFcoeVsanTranslateKeyEgressInner: 41900 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_IVID; 41901 break; 41902 case bcmFcoeVsanTranslateKeyEgressOuter: 41903 key_type_value = EGR_VLXLT_HASH_KEY_TYPE_OVID; 41904 break; 41905 default: 41906 return BCM_E_PARAM; 41907 } 41908 41909 if (type == bcmPortControlFcoeTranslateKeyFirstEgress) { 41910 if (SOC_IS_TRIDENT3X(unit) || 41911 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_1f)) { 41912 rv = _bcm_esw_egr_port_tab_set(unit, port, 41913 FCOE_VT_LOOKUP_1f, 41914 key_type_value); 41915 } 41916 } else { 41917 if (SOC_IS_TRIDENT3X(unit) || 41918 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_2f)) { 41919 rv = _bcm_esw_egr_port_tab_set(unit, port, 41920 FCOE_VT_LOOKUP_2f, 41921 key_type_value); 41922 } 41923 } 41924 } 41925 break; 41926 41927 #endif /* TRIDENT2 */ 41928 case bcmPortControlEEEMode: 41929 if (soc_feature(unit, soc_feature_eee_bb_mode)) { 41930 uint32 rval = 0; 41931 uint32 fval = 0; 41932 uint32 temp = 0; 41933 if (soc_feature (unit, soc_feature_high_portcount_register)) { 41934 soc_reg_t eee_bb_reg; 41935 int phy_port; 41936 int mmu_port; 41937 int offset; 41938 41939 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 41940 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 41941 if (mmu_port < 32) { 41942 eee_bb_reg = EEE_BB_ENABLE_0r; 41943 offset = mmu_port; 41944 } else if ((mmu_port >=32) && (mmu_port < 64)) { 41945 eee_bb_reg = EEE_BB_ENABLE_1r; 41946 offset = mmu_port - 32; 41947 } else { /* mmu_port >= 64 */ 41948 eee_bb_reg = EEE_BB_ENABLE_2r; 41949 offset = mmu_port - 64; 41950 } 41951 temp = (1 << offset); 41952 BCM_IF_ERROR_RETURN( 41953 soc_reg32_get(unit, eee_bb_reg, REG_PORT_ANY, 0, &rval)); 41954 fval = soc_reg_field_get(unit, eee_bb_reg, rval, 41955 EEE_BB_ENABLEf); 41956 if (value == bcmPortEEEBurstAndBatchMode) { 41957 fval |= temp; 41958 } else if (value == bcmPortEEENativeMode) { 41959 fval &= ~temp; 41960 } else { 41961 return BCM_E_PARAM; 41962 } 41963 rv = soc_reg_field32_modify(unit, eee_bb_reg, REG_PORT_ANY, 41964 EEE_BB_ENABLEf, 41965 fval); 41966 } else { 41967 temp = (1 << port); 41968 temp >>= 2; 41969 READ_EEE_BB_ENABLEr(unit, &rval); 41970 fval = soc_reg_field_get(unit, EEE_BB_ENABLEr, rval, 41971 EEE_BB_ENABLEf); 41972 if (value == bcmPortEEEBurstAndBatchMode) { 41973 fval |= temp; 41974 } else if (value == bcmPortEEENativeMode) { 41975 fval &= ~temp; 41976 } else { 41977 return BCM_E_PARAM; 41978 } 41979 rv = soc_reg_field32_modify(unit, EEE_BB_ENABLEr, REG_PORT_ANY, 41980 EEE_BB_ENABLEf, 41981 fval); 41982 } 41983 } 41984 break; 41985 #ifdef BCM_GREYHOUND_SUPPORT 41986 case bcmPortControlWredDropCountUpdateEnableQueueMask: 41987 if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) { 41988 #if defined(BCM_GREYHOUND2_SUPPORT) 41989 if (SOC_IS_GREYHOUND2(unit)) { 41990 rv = bcmi_gh2_cosq_wred_port_control_set(unit, port, type, 41991 value); 41992 } else 41993 #endif /* BCM_GREYHOUND2_SUPPORT */ 41994 { 41995 rv = soc_reg_field32_modify(unit, WRED_DROP_CTR_CONFIGr, 41996 port, QUEUE_MASKf, value); 41997 } 41998 } 41999 break; 42000 case bcmPortControlWredDropCountUpdateEnableColorMask: 42001 if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) { 42002 /* parameter checking */ 42003 if (value & ~((0x1 << bcmColorGreen) | 42004 (0x1 << bcmColorYellow) | 42005 (0x1 << bcmColorRed))) { 42006 return BCM_E_PARAM; 42007 } 42008 #if defined(BCM_GREYHOUND2_SUPPORT) 42009 if (SOC_IS_GREYHOUND2(unit)) { 42010 rv = bcmi_gh2_cosq_wred_port_control_set(unit, port, type, 42011 value); 42012 } else 42013 #endif /* BCM_GREYHOUND2_SUPPORT */ 42014 { 42015 cur_val = 0; 42016 if (value & (0x1 << bcmColorGreen)) { 42017 cur_val |= 0x4; 42018 } 42019 if (value & (0x1 << bcmColorYellow)) { 42020 cur_val |= 0x2; 42021 } 42022 if (value & (0x1 << bcmColorRed)) { 42023 cur_val |= 0x1; 42024 } 42025 rv = soc_reg_field32_modify(unit, WRED_DROP_CTR_CONFIGr, 42026 port, COLOR_MASKf, cur_val); 42027 } 42028 } 42029 break; 42030 #endif /* BCM_GREYHOUND_SUPPORT */ 42031 #ifdef BCM_TRIDENT2_SUPPORT 42032 case bcmPortControlProbeSerdesReset: 42033 if (SOC_IS_TD2_TT2(unit)) { 42034 PORT_LOCK(unit); 42035 if (value) { 42036 PORT(unit, port).flags |= _PORT_INFO_PROBE_RESET_SERDES; 42037 } else { 42038 PORT(unit, port).flags &= ~_PORT_INFO_PROBE_RESET_SERDES; 42039 } 42040 PORT_UNLOCK(unit); 42041 rv = BCM_E_NONE; 42042 } 42043 break; 42044 #endif /* BCM_TRIDENT2_SUPPORT */ 42045 case bcmPortControlMmuDrain: 42046 rv = bcm_esw_port_drain_cells(unit, port, value); 42047 break; 42048 case bcmPortControlMmuTrafficEnable: 42049 rv = bcm_esw_port_enqueue_set(unit, port, value); 42050 break; 42051 case bcmPortControlRxFastLOS: 42052 rv = _bcm_esw_link_fast_set(unit, port, value); 42053 break; 42054 case bcmPortControlStatCollectionEnable: 42055 if (!SOC_PORT_VALID(unit, port)) { 42056 return BCM_E_PORT; 42057 } 42058 rv = soc_counter_port_collect_enable_set(unit, port, value); 42059 break; 42060 case bcmPortControlLLFCReceive: 42061 case bcmPortControlLLFCTransmit: 42062 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 42063 case bcmPortControlSAFCReceive: 42064 case bcmPortControlSAFCTransmit: 42065 #endif 42066 rv = _bcm_esw_port_llfc_set(unit, port, type, value); 42067 break; 42068 case bcmPortControlTrunkLoadBalancingRandomizer: 42069 #ifdef BCM_TOMAHAWK_SUPPORT 42070 if (soc_feature(unit, soc_feature_randomized_load_balance)) { 42071 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42072 OFFSET_TRUNK_RANDOM_LBf, value); 42073 } 42074 #endif /* BCM_TOMAHAWK_SUPPORT */ 42075 break; 42076 case bcmPortControlECMPLevel1LoadBalancingRandomizer: 42077 #ifdef BCM_TOMAHAWK_SUPPORT 42078 if (soc_feature(unit, soc_feature_ecmp_random)) { 42079 if ((value < 0) || (value > 15)) { 42080 return BCM_E_PARAM; 42081 } 42082 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42083 OFFSET_ECMP_RANDOM_LBf, value); 42084 } 42085 #endif /* BCM_TOMAHAWK_SUPPORT */ 42086 break; 42087 case bcmPortControlECMPLevel2LoadBalancingRandomizer: 42088 #ifdef BCM_TOMAHAWK_SUPPORT 42089 if (soc_feature(unit, soc_feature_ecmp_random)) { 42090 if ((value < 0) || (value > 15)) { 42091 return BCM_E_PARAM; 42092 } 42093 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 42094 OFFSET_ECMP_LEVEL2_RANDOM_LBf, 42095 value); 42096 } 42097 #endif /* BCM_TOMAHAWK_SUPPORT */ 42098 break; 42099 case bcmPortControlMcastGroupRemap: 42100 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, NETWORK_PORTf)) { 42101 rv = soc_mem_field32_modify(unit, SOURCE_VPm, port, 42102 NETWORK_PORTf, value ? 1 : 0); 42103 } 42104 break; 42105 case bcmPortControlOOBFCTxReportIngEnable: 42106 if (soc_feature(unit, soc_feature_oob_fc)) { 42107 #ifdef BCM_TOMAHAWK_SUPPORT 42108 if (SOC_IS_TOMAHAWKX(unit)) { 42109 rv = _bcm_th_oob_fc_tx_port_control_set(unit, port, value, 0); 42110 } 42111 #endif 42112 #ifdef BCM_KATANA2_SUPPORT 42113 if (SOC_IS_KATANA2(unit)) { 42114 rv = _bcm_kt2_oob_fc_tx_port_control_set(unit, port, value, 0); 42115 } 42116 #endif 42117 #ifdef BCM_TRIDENT3_SUPPORT 42118 if (SOC_IS_TRIDENT3X(unit)) { 42119 rv = _bcm_td3_oob_fc_tx_port_control_set(unit, port, value, 0); 42120 } 42121 #endif 42122 #ifdef BCM_APACHE_SUPPORT 42123 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 42124 rv = _bcm_ap_oob_fc_tx_port_control_set(unit, port, value, 0); 42125 } 42126 #endif 42127 } 42128 break; 42129 case bcmPortControlOOBFCTxReportEgrEnable: 42130 if (soc_feature(unit, soc_feature_oob_fc)) { 42131 #ifdef BCM_TOMAHAWK_SUPPORT 42132 if (SOC_IS_TOMAHAWKX(unit)) { 42133 rv = _bcm_th_oob_fc_tx_port_control_set(unit, port, value, 1); 42134 } 42135 #endif 42136 #ifdef BCM_APACHE_SUPPORT 42137 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 42138 rv = _bcm_ap_oob_fc_tx_port_control_set(unit, port, value, 1); 42139 } 42140 #endif 42141 #ifdef BCM_KATANA2_SUPPORT 42142 if (SOC_IS_KATANA2(unit)) { 42143 rv = _bcm_kt2_oob_fc_tx_port_control_set(unit, port, value, 1); 42144 } 42145 #endif 42146 #ifdef BCM_TRIDENT3_SUPPORT 42147 if (SOC_IS_TRIDENT3X(unit)) { 42148 rv = _bcm_th_oob_fc_tx_port_control_set(unit, port, value, 1); 42149 } 42150 #endif 42151 } 42152 break; 42153 42154 case bcmPortControlSubportTagSize: 42155 #ifdef BCM_HGPROXY_COE_SUPPORT 42156 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 42157 DESTINATION_SUBPORT_TAG_TYPEf)) { 42158 42159 int local_port = 0; 42160 if (BCM_GPORT_IS_SET(port)) { 42161 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 42162 } else { 42163 if(!SOC_PORT_VALID(unit, port)) { 42164 return BCM_E_PORT; 42165 } else { 42166 local_port = port; 42167 } 42168 } 42169 42170 /* Setting of tag_type to 8Byte is not supported currently, 42171 hence return error if 'value' is non-zero */ 42172 if(value) { 42173 return BCM_E_UNAVAIL; 42174 } 42175 42176 rv = soc_mem_field32_modify(unit, EGR_PORTm, local_port, 42177 DESTINATION_SUBPORT_TAG_TYPEf, value ? 1 : 0); 42178 } 42179 if (SOC_IS_TRIDENT3X(unit)) { 42180 if (value) { 42181 return BCM_E_UNAVAIL; 42182 } 42183 else { 42184 return BCM_E_NONE; 42185 } 42186 } 42187 #endif 42188 break; 42189 42190 case bcmPortControlSystemPortOverride: 42191 #ifdef BCM_HGPROXY_COE_SUPPORT 42192 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, VT_SYS_PORT_OVERRIDEf)) { 42193 rv = bcmi_xgs5_subport_subtag_port_override_set(unit, port, value); 42194 } 42195 #endif 42196 break; 42197 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 42198 case bcmPortControlSampleIngressDest: 42199 if(soc_feature(unit, soc_feature_sflow_ing_mem)) { 42200 sflow_ing_data_source_entry_t sflow_entry; 42201 uint32 field_values[2] = {0, 0}; 42202 if ((value < 0) || (value > 3)) { 42203 return BCM_E_PARAM; 42204 } 42205 42206 if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_CPU) == 42207 BCM_PORT_CONTROL_SAMPLE_DEST_CPU) { 42208 field_values[0] = 1; 42209 } 42210 if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) == 42211 BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) { 42212 field_values[1] = 1; 42213 } 42214 42215 BCM_IF_ERROR_RETURN 42216 (READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 42217 &sflow_entry)); 42218 soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry, 42219 CPUf, &field_values[0]); 42220 soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry, 42221 MIRRORf, &field_values[1]); 42222 BCM_IF_ERROR_RETURN 42223 (WRITE_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 42224 &sflow_entry)); 42225 rv = BCM_E_NONE; 42226 } 42227 break; 42228 case bcmPortControlSampleFlexDest: 42229 if(soc_feature(unit, soc_feature_sflow_flex)) { 42230 sflow_ing_flex_data_source_entry_t sflow_entry; 42231 uint32 field_values[2] = {0, 0}; 42232 if ((value < 0) || (value > 3)) { 42233 return BCM_E_PARAM; 42234 } 42235 42236 if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_CPU) == 42237 BCM_PORT_CONTROL_SAMPLE_DEST_CPU) { 42238 field_values[0] = 1; 42239 } 42240 if ((value & BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) == 42241 BCM_PORT_CONTROL_SAMPLE_DEST_MIRROR) { 42242 field_values[1] = 1; 42243 } 42244 42245 BCM_IF_ERROR_RETURN 42246 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 42247 &sflow_entry)); 42248 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry, 42249 CPUf, &field_values[0]); 42250 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry, 42251 MIRRORf, &field_values[1]); 42252 BCM_IF_ERROR_RETURN 42253 (WRITE_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 42254 &sflow_entry)); 42255 rv = BCM_E_NONE; 42256 } 42257 break; 42258 case bcmPortControlSampleFlexRate: 42259 if(soc_feature(unit, soc_feature_sflow_flex)) { 42260 uint32 values[2] = {0, 0}; 42261 sflow_ing_flex_data_source_entry_t sflow_entry; 42262 soc_counter_non_dma_t *non_dma = NULL; 42263 soc_control_t *soc; 42264 uint32 count = 0, subset_ct = 0; 42265 42266 if (value < 0) { 42267 return BCM_E_PARAM; 42268 } 42269 /* Set sampling threshold */ 42270 if (value > 0) { 42271 /* Enable sFlow */ 42272 values[0] = 1; 42273 42274 /* Set sampling threshold */ 42275 if (value == 1) { 42276 /* Needs special handling to avoid register overflow */ 42277 values[1] = (1 << (SFLOW_RANGE_MAX(unit))) - 1; 42278 } else { 42279 /* Calculate threshold based on sampling rate */ 42280 values[1] = (1 << (SFLOW_RANGE_MAX(unit))) / value; 42281 } 42282 } 42283 42284 /* Update Flex rate limiting data table. */ 42285 BCM_IF_ERROR_RETURN 42286 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 42287 &sflow_entry)); 42288 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry, 42289 ENABLEf, &values[0]); 42290 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_set(unit, &sflow_entry, 42291 THRESHOLDf, &values[1]); 42292 BCM_IF_ERROR_RETURN 42293 (WRITE_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 42294 &sflow_entry)); 42295 42296 /* Enable counter thread for Flex sFlow samplers */ 42297 if (values[0] == 1) { 42298 soc = SOC_CONTROL(unit); 42299 non_dma = &soc->counter_non_dma[ 42300 SOC_COUNTER_NON_DMA_SFLOW_FLEX_PKT - 42301 SOC_COUNTER_NON_DMA_START]; 42302 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 42303 /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */ 42304 subset_ct = non_dma->extra_ctr_ct << 1; 42305 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 42306 non_dma = non_dma->extra_ctrs; 42307 42308 do { 42309 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 42310 /* BYTE_CTRf not currently supported */ 42311 count += 2; 42312 non_dma += 2; 42313 } while ((count < subset_ct)); 42314 } 42315 } 42316 rv = BCM_E_NONE; 42317 } 42318 break; 42319 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */ 42320 #ifdef BCM_XGS3_SWITCH_SUPPORT 42321 case bcmPortControlSampleIngressEnable: 42322 if (SOC_IS_XGS3_SWITCH(unit)) { 42323 uint32 regval = 0; 42324 uint32 field_enable = 0; 42325 #ifdef BCM_TOMAHAWK_SUPPORT 42326 sflow_ing_data_source_entry_t sflow_entry; 42327 soc_counter_non_dma_t *non_dma = NULL; 42328 soc_control_t *soc; 42329 uint32 count = 0, subset_ct = 0; 42330 #endif /* BCM_TOMAHAWK_SUPPORT */ 42331 42332 field_enable = value ? 1 : 0; 42333 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 42334 /* Update Ingress rate limiting data table. */ 42335 if(soc_feature(unit, soc_feature_sflow_ing_mem)) { 42336 BCM_IF_ERROR_RETURN( 42337 READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 42338 &sflow_entry)); 42339 soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry, ENABLEf, 42340 &field_enable); 42341 42342 BCM_IF_ERROR_RETURN( 42343 WRITE_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 42344 &sflow_entry)); 42345 42346 /* Enable counter thread for Ingress sFlow samplers */ 42347 if (field_enable) { 42348 soc = SOC_CONTROL(unit); 42349 non_dma = &soc->counter_non_dma[SOC_COUNTER_NON_DMA_SFLOW_ING_PKT - 42350 SOC_COUNTER_NON_DMA_START]; 42351 if (!(non_dma->flags & _SOC_COUNTER_NON_DMA_VALID)) { 42352 /* Do PACKET_CTRf and BYTE_CTRf sequentially. Hence 2x loop */ 42353 subset_ct = non_dma->extra_ctr_ct << 1; 42354 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 42355 non_dma = non_dma->extra_ctrs; 42356 42357 do { 42358 non_dma->flags |= _SOC_COUNTER_NON_DMA_VALID; 42359 /* BYTE_CTRf not currently supported */ 42360 count += 2; 42361 non_dma += 2; 42362 } while ((count < subset_ct)); 42363 } 42364 } 42365 rv = BCM_E_NONE; 42366 } else 42367 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */ 42368 { 42369 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) { 42370 return BCM_E_UNAVAIL; 42371 } 42372 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, ®val)); 42373 soc_reg_field_set(unit, SFLOW_ING_THRESHOLDr, ®val, 42374 ENABLEf, field_enable); 42375 42376 BCM_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, regval)); 42377 rv = BCM_E_NONE; 42378 } 42379 } else { 42380 rv = BCM_E_UNAVAIL; 42381 } 42382 break; 42383 case bcmPortControlSampleEgressEnable: 42384 if (SOC_IS_XGS3_SWITCH(unit)) { 42385 uint32 regval = 0; 42386 uint32 field_enable = 0; 42387 42388 if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) { 42389 return BCM_E_UNAVAIL; 42390 } 42391 BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, ®val)); 42392 42393 field_enable = value ? 1 : 0; 42394 soc_reg_field_set(unit, SFLOW_EGR_THRESHOLDr, ®val, 42395 ENABLEf, field_enable); 42396 42397 BCM_IF_ERROR_RETURN(WRITE_SFLOW_EGR_THRESHOLDr(unit, port, regval)); 42398 rv = BCM_E_NONE; 42399 } else { 42400 rv = BCM_E_UNAVAIL; 42401 } 42402 break; 42403 case bcmPortControlSampleIngressRate: 42404 if (SOC_IS_XGS3_SWITCH(unit)) { 42405 uint32 field_value = 0; 42406 uint32 regval = 0; 42407 #ifdef BCM_TOMAHAWK_SUPPORT 42408 sflow_ing_data_source_entry_t sflow_entry; 42409 #endif /* BCM_TOMAHAWK_SUPPORT */ 42410 42411 42412 /* rate - (IN)Every 1/rate a packet will be sampled 42413 * 1 indicating sample all. 42414 * 0 indicating sample none.*/ 42415 if (value > 0) { 42416 /* Set sampling threshold */ 42417 if (value == 1) { 42418 /* Needs special handling to avoid register overflow */ 42419 field_value = (1 << (SFLOW_RANGE_MAX(unit))) - 1; 42420 } else if (value <= ((1 << (SFLOW_RANGE_MAX(unit))) - 1)) { 42421 /* Calculate threshold based on sampling rate */ 42422 field_value = (1 << (SFLOW_RANGE_MAX(unit))) / value; 42423 } else { 42424 return BCM_E_PARAM; 42425 } 42426 42427 /* 42428 * For early sFlow implementations the 16-bit threshold value 42429 * is compared to bits [23:8] of the sFlow random number. 42430 */ 42431 if (soc_feature(unit, soc_feature_sample_offset8)) { 42432 field_value >>= 8; 42433 } 42434 42435 /* Cut the value in case 16 bit threshold can not accomodate it. */ 42436 if (soc_feature(unit, soc_feature_sample_thresh16)) { 42437 if (field_value >= (1 << 16)) { 42438 field_value = (1 << 16) - 1; 42439 } 42440 } 42441 } 42442 42443 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 42444 /* Update Ingress rate limiting data table. */ 42445 if(soc_feature(unit, soc_feature_sflow_ing_mem)) { 42446 BCM_IF_ERROR_RETURN( 42447 READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 42448 &sflow_entry)); 42449 soc_SFLOW_ING_DATA_SOURCEm_field_set(unit, &sflow_entry, THRESHOLDf, 42450 &field_value); 42451 42452 BCM_IF_ERROR_RETURN( 42453 WRITE_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 42454 &sflow_entry)); 42455 42456 rv = BCM_E_NONE; 42457 } else 42458 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */ 42459 { 42460 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) { 42461 return BCM_E_UNAVAIL; 42462 } 42463 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, ®val)); 42464 soc_reg_field_set(unit, SFLOW_ING_THRESHOLDr, ®val, 42465 THRESHOLDf, field_value); 42466 42467 BCM_IF_ERROR_RETURN(WRITE_SFLOW_ING_THRESHOLDr(unit, port, regval)); 42468 rv = BCM_E_NONE; 42469 } 42470 } else { 42471 rv = BCM_E_UNAVAIL; 42472 } 42473 break; 42474 case bcmPortControlSampleEgressRate: 42475 if (SOC_IS_XGS3_SWITCH(unit)) { 42476 uint32 field_value = 0, regval = 0; 42477 42478 /* rate - (IN)Every 1/rate a packet will be sampled 42479 * 1 indicating sample all. 42480 * 0 indicating sample none.*/ 42481 if (value > 0) { 42482 /* Set sampling threshold */ 42483 if (value == 1) { 42484 /* Needs special handling to avoid register overflow */ 42485 field_value = (1 << (SFLOW_RANGE_MAX(unit))) - 1; 42486 } else if (value <= ((1 << (SFLOW_RANGE_MAX(unit))) - 1)) { 42487 /* Calculate threshold based on sampling rate */ 42488 field_value = (1 << (SFLOW_RANGE_MAX(unit))) / value; 42489 } else { 42490 return BCM_E_PARAM; 42491 } 42492 42493 /* 42494 * For early sFlow implementations the 16-bit threshold value 42495 * is compared to bits [23:8] of the sFlow random number. 42496 */ 42497 if (soc_feature(unit, soc_feature_sample_offset8)) { 42498 field_value >>= 8; 42499 } 42500 42501 /* Cut the value in case 16 bit threshold can not accomodate it. */ 42502 if (soc_feature(unit, soc_feature_sample_thresh16)) { 42503 if (field_value >= (1 << 16)) { 42504 field_value = (1 << 16) - 1; 42505 } 42506 } 42507 } 42508 42509 if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) { 42510 return BCM_E_UNAVAIL; 42511 } 42512 42513 BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, ®val)); 42514 soc_reg_field_set(unit, SFLOW_EGR_THRESHOLDr, ®val, 42515 THRESHOLDf, field_value); 42516 42517 BCM_IF_ERROR_RETURN(WRITE_SFLOW_EGR_THRESHOLDr(unit, port, regval)); 42518 rv = BCM_E_NONE; 42519 } else { 42520 rv = BCM_E_UNAVAIL; 42521 } 42522 break; 42523 #endif 42524 case bcmPortControlExternalBufferEnable: 42525 #if defined(BCM_KATANA2_SUPPORT) 42526 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_ddr3)) { 42527 rv = _bcm_kt2_cosq_port_ext_buf_set(unit, port, value); 42528 } 42529 #endif 42530 break; 42531 #ifdef BCM_HURRICANE3_SUPPORT 42532 case bcmPortControlTrustMimlPri: 42533 if (soc_feature(unit, soc_feature_miml)) { 42534 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42535 USE_MIML_PCP_FOR_PRIf, value ? 1 : 0); 42536 if (soc_feature(unit, soc_feature_pktpri_as_dot1p)) { 42537 if (BCM_FAILURE(rv)) { 42538 return rv; 42539 } 42540 /* 42541 * Make sure TREAT_PKTPRI_AS_DOT1P bit is set for 42542 * MiML internal priority mapping. 42543 */ 42544 rv = bcmi_esw_port_treat_pktpri_as_dot1p_ref_cnt_update 42545 (unit, (value) ? 1 : -1); 42546 } 42547 } 42548 break; 42549 case bcmPortControlTrustCustomHeaderPri: 42550 if (soc_feature(unit, soc_feature_custom_header)) { 42551 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42552 USE_CUSTOM_HEADER_FOR_PRIf, 42553 value ? 1 : 0); 42554 } 42555 break; 42556 case bcmPortControlCustomHeaderEncapEnable: 42557 if (soc_feature(unit, soc_feature_custom_header)) { 42558 uint64 val64; 42559 42560 rv = READ_EGR_PORT_64r(unit, port, &val64); 42561 if (BCM_SUCCESS(rv)) { 42562 soc_reg64_field32_set(unit, EGR_PORT_64r, 42563 &val64, 42564 CUSTOM_HEADER_ENABLEf, value ? 1 : 0); 42565 } 42566 42567 rv = WRITE_EGR_PORT_64r(unit, port, val64); 42568 } 42569 break; 42570 #endif /* BCM_HURRICANE3_SUPPORT */ 42571 #if defined(BCM_SABER2_SUPPORT) 42572 case bcmPortControlSatEnable: 42573 PORT_LOCK(unit); 42574 if (SOC_IS_SABER2(unit)) { 42575 COUNTER_LOCK(unit); 42576 SOC_L2_DEL_SYNC_LOCK(SOC_CONTROL(unit)); 42577 rv = _bcm_sb2_port_oamp_enable(unit, port, value); 42578 COUNTER_UNLOCK(unit); 42579 SOC_L2_DEL_SYNC_UNLOCK(SOC_CONTROL(unit)); 42580 } else { 42581 rv = BCM_E_UNAVAIL; 42582 } 42583 PORT_UNLOCK(unit); 42584 break; 42585 #endif 42586 case bcmPortControl1588P2PDelay: 42587 { 42588 int p_speed=0; 42589 rv = bcm_esw_port_speed_get(unit, port, &p_speed); 42590 if (BCM_FAILURE(rv)) { 42591 rv = BCM_E_FAIL; 42592 } 42593 PORT(unit, port).link_delay_offset = value; 42594 rv = _bcm_esw_port_link_delay_update(unit, port, p_speed); 42595 } 42596 break; 42597 case bcmPortControlPacketTimeStampInsertRx: 42598 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 42599 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 42600 if (soc_feature(unit, soc_feature_timestamp)) { 42601 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 42602 BCM_IF_ERROR_RETURN( 42603 _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42604 INSERT_RX_TIMESTAMPf, value ? 1 : 0)); 42605 rv = BCM_E_NONE; 42606 } 42607 break; 42608 #endif 42609 case bcmPortControlPacketTimeStampInsertTx: 42610 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 42611 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 42612 if (soc_feature(unit, soc_feature_timestamp)) { 42613 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 42614 SOC_IF_ERROR_RETURN( 42615 soc_reg_field32_modify(unit, EGR_TS_CONTROLr, port, 42616 INSERT_TX_TIMESTAMPf, value ? 1 : 0)); 42617 rv = BCM_E_NONE; 42618 } 42619 break; 42620 #endif 42621 case bcmPortControlPacketTimeStampSrcPortInsertCancel: 42622 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 42623 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 42624 if (soc_feature(unit, soc_feature_timestamp)) { 42625 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 42626 BCM_IF_ERROR_RETURN( 42627 _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 42628 DISABLE_TIMESTAMPINGf, value ? 1 : 0)); 42629 rv = BCM_E_NONE; 42630 } 42631 break; 42632 #endif 42633 case bcmPortControlPacketTimeStampDestPortInsertCancel: 42634 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 42635 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 42636 if (soc_feature(unit, soc_feature_timestamp)) { 42637 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 42638 SOC_IF_ERROR_RETURN( 42639 soc_reg_field32_modify(unit, EGR_TS_CONTROLr, port, 42640 DISABLE_TIMESTAMPINGf, value ? 1 : 0)); 42641 rv = BCM_E_NONE; 42642 } 42643 break; 42644 #endif 42645 case bcmPortControlPacketTimeStampRxId: 42646 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 42647 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 42648 if (soc_feature(unit, soc_feature_timestamp)) { 42649 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 42650 if ((value < 0) || (value >= 0x7FFFFF)) { 42651 return BCM_E_PARAM; 42652 } 42653 if (SOC_REG_IS_VALID(unit,EGR_TS_ING_PORT_MAPr)) { 42654 SOC_IF_ERROR_RETURN( 42655 soc_reg_field32_modify(unit, EGR_TS_ING_PORT_MAPr, 42656 port, TS_RX_ORIGIN_IDf, value)); 42657 } else { 42658 SOC_IF_ERROR_RETURN( 42659 soc_mem_field32_modify(unit, EGR_TS_ING_PORT_MAPm, 42660 port, TS_RX_ORIGIN_IDf, value)); 42661 } 42662 rv = BCM_E_NONE; 42663 } 42664 #endif 42665 break; 42666 case bcmPortControlPacketTimeStampTxId: 42667 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 42668 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 42669 if (soc_feature(unit, soc_feature_timestamp)) { 42670 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 42671 if ((value < 0) || (value >= 0x7FFFFF)) { 42672 return BCM_E_PARAM; 42673 } 42674 if (soc_reg_field_valid(unit, EGR_TS_CONTROL_2r, TS_TX_ORIGIN_IDf)) 42675 { 42676 rv = soc_reg_field32_modify(unit, EGR_TS_CONTROL_2r, 42677 port, TS_TX_ORIGIN_IDf, value); 42678 } else { 42679 rv = soc_reg_field32_modify(unit, EGR_TS_CONTROLr, 42680 port, TS_TX_ORIGIN_IDf, value); 42681 } 42682 } 42683 #endif 42684 break; 42685 case bcmPortControlPacketTimeStampByteMeterAdjust: 42686 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 42687 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 42688 if (soc_feature(unit, soc_feature_timestamp) && !SOC_IS_TOMAHAWK3(unit)) 42689 { 42690 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 42691 rv = soc_reg_field32_modify(unit, EGR_TS_CONTROLr, port, 42692 TS_ADJUST_METERSf, (value) ? 1 : 0); 42693 } 42694 #endif 42695 break; 42696 case bcmPortControlE2EFCTransmitEnable: 42697 if (soc_feature(unit, soc_feature_e2efc)) { 42698 uint64 val; 42699 #if defined(BCM_KATANA2_SUPPORT) 42700 uint32 val32; 42701 #endif 42702 if (!IS_HG_PORT(unit, port)) { 42703 LOG_ERROR( 42704 BSL_LS_BCM_PORT, 42705 (BSL_META_U(unit, 42706 "Error: unit %d port %d is not a Higig port. " 42707 "E2EFC messages can only be transmitted to " 42708 "or received from Higig ports.\n"), 42709 unit, port)); 42710 return BCM_E_PARAM; 42711 } 42712 #if defined(BCM_KATANA2_SUPPORT) 42713 if (SOC_IS_KATANA2(unit)) { 42714 val32 = value ? 1: 0; 42715 rv = WRITE_E2EFC_IBP_ENr(unit, val32); 42716 } else 42717 #endif 42718 if (IS_XL_PORT(unit, port)) { 42719 BCM_IF_ERROR_RETURN(READ_XLMAC_E2E_CTRLr(unit, port, &val)); 42720 soc_reg64_field32_set(unit, XLMAC_E2E_CTRLr, 42721 &val, E2E_ENABLEf, value ? 1 : 0); 42722 rv = WRITE_XLMAC_E2E_CTRLr(unit, port, val); 42723 } else if (IS_CL_PORT(unit, port)) { 42724 BCM_IF_ERROR_RETURN(READ_CLMAC_E2E_CTRLr(unit, port, &val)); 42725 soc_reg64_field32_set(unit, CLMAC_E2E_CTRLr, 42726 &val, E2E_ENABLEf, value ? 1 : 0); 42727 rv = WRITE_CLMAC_E2E_CTRLr(unit, port, val); 42728 } else { 42729 return BCM_E_PARAM; 42730 } 42731 } 42732 break; 42733 case bcmPortControlE2EFCReceiveEnable: 42734 if (soc_feature(unit, soc_feature_e2efc)) { 42735 uint32 val; 42736 42737 BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val)); 42738 soc_reg_field_set(unit, IE2E_CONTROLr, 42739 &val, IBP_ENABLEf, value ? 1 : 0); 42740 rv = WRITE_IE2E_CONTROLr(unit, port, val); 42741 } 42742 break; 42743 case bcmPortControlE2EFCCopyToCpuEnable: 42744 if (soc_feature(unit, soc_feature_e2efc)) { 42745 uint32 val; 42746 42747 BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val)); 42748 soc_reg_field_set(unit, IE2E_CONTROLr, 42749 &val, IBP_TOCPUf, value ? 1 : 0); 42750 rv = WRITE_IE2E_CONTROLr(unit, port, val); 42751 } 42752 break; 42753 /* Higher 3 bytes of Destination MAC address */ 42754 case bcmPortControlE2EFCDestMacOui: 42755 if (soc_feature(unit, soc_feature_e2efc)) { 42756 uint32 val_lo, val_hi; 42757 uint64 val_64, data_0; 42758 #if defined(BCM_KATANA2_SUPPORT) 42759 uint32 val; 42760 #endif 42761 soc_reg_t reg; 42762 42763 if (!IS_HG_PORT(unit, port)) { 42764 LOG_ERROR( 42765 BSL_LS_BCM_PORT, 42766 (BSL_META_U(unit, 42767 "Error: unit %d port %d is not a Higig port. " 42768 "E2EFC messages can only be transmitted to " 42769 "or received from Higig ports.\n"), 42770 unit, port)); 42771 return BCM_E_PARAM; 42772 } 42773 #if defined(BCM_KATANA2_SUPPORT) 42774 if (SOC_IS_KATANA2(unit)) { 42775 #if defined(BCM_SABER2_SUPPORT) 42776 if (SOC_IS_SABER2(unit)) { 42777 /* Do nothing */ 42778 } else 42779 #endif /* BCM_SABER2_SUPPORT */ 42780 { 42781 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val)); 42782 val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f); 42783 val_hi = (val_hi & 0xff) | ((value & 0xffffff) << 8); 42784 soc_reg_field_set(unit, XIBP_D0r, &val, DATA_BYTES_0_3f, val_hi); 42785 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D0r, port, 0, val)); 42786 rv = BCM_E_NONE; 42787 break; 42788 } 42789 } 42790 #endif /* BCM_KATANA2_SUPPORT */ 42791 if (IS_XL_PORT(unit, port)) { 42792 reg = XLMAC_E2EFC_DATA_HDR_0r; 42793 } else if (IS_CL_PORT(unit, port)) { 42794 reg = CLMAC_E2EFC_DATA_HDR_0r; 42795 } else { 42796 return BCM_E_PARAM; 42797 } 42798 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 42799 0, &val_64)); 42800 data_0 = soc_reg64_field_get(unit, reg, 42801 val_64, E2EFC_DATA_HDR_0f); 42802 COMPILER_64_TO_32_LO(val_lo, data_0); 42803 COMPILER_64_TO_32_HI(val_hi, data_0); 42804 val_hi = (val_hi & 0xff) | ((value & 0xffffff) << 8); 42805 COMPILER_64_SET(data_0, val_hi, val_lo); 42806 soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_0f, 42807 data_0); 42808 rv = soc_reg64_set(unit, reg, port, 0, val_64); 42809 } 42810 break; 42811 /* Lower 3 bytes of Destination MAC address */ 42812 case bcmPortControlE2EFCDestMacNonOui: 42813 if (soc_feature(unit, soc_feature_e2efc)) { 42814 uint32 val_lo, val_hi; 42815 uint64 val_64, data_0; 42816 soc_reg_t reg; 42817 #if defined(BCM_KATANA2_SUPPORT) 42818 uint32 val; 42819 #endif 42820 42821 if (!IS_HG_PORT(unit, port)) { 42822 LOG_ERROR( 42823 BSL_LS_BCM_PORT, 42824 (BSL_META_U(unit, 42825 "Error: unit %d port %d is not a Higig port. " 42826 "E2EFC messages can only be transmitted to " 42827 "or received from Higig ports.\n"), 42828 unit, port)); 42829 return BCM_E_PARAM; 42830 } 42831 #if defined(BCM_KATANA2_SUPPORT) 42832 if (SOC_IS_KATANA2(unit)) { 42833 #if defined(BCM_SABER2_SUPPORT) 42834 if (SOC_IS_SABER2(unit)) { 42835 /* Do nothing */ 42836 } else 42837 #endif /* BCM_SABER2_SUPPORT */ 42838 { 42839 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val)); 42840 val_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f); 42841 val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16); 42842 soc_reg_field_set(unit, XIBP_D1r, &val, DATA_BYTES_4_7f, val_lo); 42843 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D1r, port, 0, val)); 42844 42845 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val)); 42846 val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f); 42847 val_hi = (val_hi & 0xffffff00) | ((value >> 16) & 0xff); 42848 soc_reg_field_set(unit, XIBP_D0r, &val, DATA_BYTES_0_3f, val_hi); 42849 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D0r, port, 0, val)); 42850 rv = BCM_E_NONE; 42851 break; 42852 } 42853 } 42854 #endif /* BCM_KATANA2_SUPPORT */ 42855 if (IS_XL_PORT(unit, port)) { 42856 reg = XLMAC_E2EFC_DATA_HDR_0r; 42857 } else if (IS_CL_PORT(unit, port)) { 42858 reg = CLMAC_E2EFC_DATA_HDR_0r; 42859 } else { 42860 return BCM_E_PARAM; 42861 } 42862 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 42863 0, &val_64)); 42864 data_0 = soc_reg64_field_get(unit, reg, 42865 val_64, E2EFC_DATA_HDR_0f); 42866 COMPILER_64_TO_32_LO(val_lo, data_0); 42867 COMPILER_64_TO_32_HI(val_hi, data_0); 42868 val_hi = (val_hi & 0xffffff00) | ((value >> 16) & 0xff); 42869 val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16); 42870 COMPILER_64_SET(data_0, val_hi, val_lo); 42871 soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_0f, 42872 data_0); 42873 rv = soc_reg64_set(unit, reg, port, 0, val_64); 42874 } 42875 break; 42876 /* Higher 3 bytes of Source MAC address */ 42877 case bcmPortControlE2EFCSrcMacOui: 42878 if (soc_feature(unit, soc_feature_e2efc)) { 42879 uint32 val_lo, val_hi; 42880 uint64 val_64, data_1, data_0; 42881 soc_reg_t reg_1, reg_0; 42882 #if defined(BCM_KATANA2_SUPPORT) 42883 uint32 val; 42884 #endif 42885 if (!IS_HG_PORT(unit, port)) { 42886 LOG_ERROR( 42887 BSL_LS_BCM_PORT, 42888 (BSL_META_U(unit, 42889 "Error: unit %d port %d is not a Higig port. " 42890 "E2EFC messages can only be transmitted to " 42891 "or received from Higig ports.\n"), 42892 unit, port)); 42893 return BCM_E_PARAM; 42894 } 42895 #if defined(BCM_KATANA2_SUPPORT) 42896 if (SOC_IS_KATANA2(unit)) { 42897 #if defined(BCM_SABER2_SUPPORT) 42898 if (SOC_IS_SABER2(unit)) { 42899 /* Do nothing */ 42900 } else 42901 #endif /* BCM_SABER2_SUPPORT */ 42902 { 42903 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val)); 42904 val_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f); 42905 val_lo = (val_lo & 0xffff0000) | ((value >> 8) & 0xffff); 42906 soc_reg_field_set(unit, XIBP_D1r, &val, DATA_BYTES_4_7f, val_lo); 42907 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D1r, port, 0, val)); 42908 42909 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val)); 42910 val_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f); 42911 val_hi = (val_hi & 0xffffff) | ((value & 0xff) << 24); 42912 soc_reg_field_set(unit, XIBP_D2r, &val, DATA_BYTES_8_11f, val_hi); 42913 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D2r, port, 0, val)); 42914 rv = BCM_E_NONE; 42915 break; 42916 } 42917 } 42918 #endif /* BCM_KATANA2_SUPPORT */ 42919 if (IS_XL_PORT(unit, port)) { 42920 reg_1 = XLMAC_E2EFC_DATA_HDR_1r; 42921 reg_0 = XLMAC_E2EFC_DATA_HDR_0r; 42922 } else if (IS_CL_PORT(unit, port)) { 42923 reg_1 = CLMAC_E2EFC_DATA_HDR_1r; 42924 reg_0 = CLMAC_E2EFC_DATA_HDR_0r; 42925 } else { 42926 return BCM_E_PARAM; 42927 } 42928 42929 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_1, port, 42930 0, &val_64)); 42931 data_1 = soc_reg64_field_get(unit, reg_1, 42932 val_64, E2EFC_DATA_HDR_1f); 42933 COMPILER_64_TO_32_LO(val_lo, data_1); 42934 COMPILER_64_TO_32_HI(val_hi, data_1); 42935 val_hi = (val_hi & 0xffffff) | ((value & 0xff) << 24); 42936 COMPILER_64_SET(data_1, val_hi, val_lo); 42937 soc_reg64_field_set(unit, reg_1, &val_64, E2EFC_DATA_HDR_1f, 42938 data_1); 42939 BCM_IF_ERROR_RETURN(soc_reg64_set(unit, reg_1, port, 0, val_64)); 42940 /* SA MAC setting across 2 registers */ 42941 COMPILER_64_ZERO(val_64); 42942 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_0, port, 42943 0, &val_64)); 42944 data_0 = soc_reg64_field_get(unit, reg_0, 42945 val_64, E2EFC_DATA_HDR_0f); 42946 COMPILER_64_TO_32_LO(val_lo, data_0); 42947 COMPILER_64_TO_32_HI(val_hi, data_0); 42948 val_lo = (val_lo & 0xffff0000) | ((value >> 8) & 0xffff); 42949 COMPILER_64_SET(data_0, val_hi, val_lo); 42950 soc_reg64_field_set(unit, reg_0, &val_64, E2EFC_DATA_HDR_0f, 42951 data_0); 42952 rv = soc_reg64_set(unit, reg_0, port, 0, val_64); 42953 } 42954 break; 42955 /* Lower 3 bytes of Source MAC address */ 42956 case bcmPortControlE2EFCSrcMacNonOui: 42957 if (soc_feature(unit, soc_feature_e2efc)) { 42958 uint32 val_lo, val_hi; 42959 uint64 val_64, data_1; 42960 soc_reg_t reg; 42961 #if defined(BCM_KATANA2_SUPPORT) 42962 uint32 val; 42963 #endif 42964 if (!IS_HG_PORT(unit, port)) { 42965 LOG_ERROR( 42966 BSL_LS_BCM_PORT, 42967 (BSL_META_U(unit, 42968 "Error: unit %d port %d is not a Higig port. " 42969 "E2EFC messages can only be transmitted to " 42970 "or received from Higig ports.\n"), 42971 unit, port)); 42972 return BCM_E_PARAM; 42973 } 42974 #if defined(BCM_KATANA2_SUPPORT) 42975 if (SOC_IS_KATANA2(unit)) { 42976 #if defined(BCM_SABER2_SUPPORT) 42977 if (SOC_IS_SABER2(unit)) { 42978 /* Do nothing */ 42979 } else 42980 #endif /* BCM_SABER2_SUPPORT */ 42981 { 42982 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val)); 42983 val_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f); 42984 val_hi = (val_hi & 0xff000000) | (value & 0xffffff); 42985 soc_reg_field_set(unit, XIBP_D2r, &val, DATA_BYTES_8_11f, val_hi); 42986 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D2r, port, 0, val)); 42987 rv = BCM_E_NONE; 42988 break; 42989 } 42990 } 42991 #endif /* BCM_KATANA2_SUPPORT */ 42992 if (IS_XL_PORT(unit, port)) { 42993 reg = XLMAC_E2EFC_DATA_HDR_1r; 42994 } else if (IS_CL_PORT(unit, port)) { 42995 reg = CLMAC_E2EFC_DATA_HDR_1r; 42996 } else { 42997 return BCM_E_PARAM; 42998 } 42999 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 43000 0, &val_64)); 43001 data_1 = soc_reg64_field_get(unit, reg, 43002 val_64, E2EFC_DATA_HDR_1f); 43003 COMPILER_64_TO_32_LO(val_lo, data_1); 43004 COMPILER_64_TO_32_HI(val_hi, data_1); 43005 val_hi = (val_hi & 0xff000000) | (value & 0xffffff); 43006 COMPILER_64_SET(data_1, val_hi, val_lo); 43007 soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_1f, 43008 data_1); 43009 43010 rv = soc_reg64_set(unit, reg, port, 0, val_64); 43011 } 43012 break; 43013 case bcmPortControlE2EFCEtherType: 43014 if (soc_feature(unit, soc_feature_e2efc)) { 43015 uint32 val_lo, val_hi; 43016 uint64 val_64, data_1; 43017 soc_reg_t reg; 43018 #if defined(BCM_KATANA2_SUPPORT) 43019 uint32 val; 43020 #endif 43021 if (!IS_HG_PORT(unit, port)) { 43022 LOG_ERROR( 43023 BSL_LS_BCM_PORT, 43024 (BSL_META_U(unit, 43025 "Error: unit %d port %d is not a Higig port. " 43026 "E2EFC messages can only be transmitted to " 43027 "or received from Higig ports.\n"), 43028 unit, port)); 43029 return BCM_E_PARAM; 43030 } 43031 #if defined(BCM_KATANA2_SUPPORT) 43032 if (SOC_IS_KATANA2(unit)) { 43033 #if defined(BCM_SABER2_SUPPORT) 43034 if (SOC_IS_SABER2(unit)) { 43035 /* Do nothing */ 43036 } else 43037 #endif /* BCM_SABER2_SUPPORT */ 43038 { 43039 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val)); 43040 val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f); 43041 val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16); 43042 soc_reg_field_set(unit, XIBP_D3r, &val, D_BYTES_12_15f, val_lo); 43043 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D3r, port, 0, val)); 43044 rv = BCM_E_NONE; 43045 break; 43046 } 43047 } 43048 #endif /* BCM_KATANA2_SUPPORT */ 43049 if (IS_XL_PORT(unit, port)) { 43050 reg = XLMAC_E2EFC_DATA_HDR_1r; 43051 } else if (IS_CL_PORT(unit, port)) { 43052 reg = CLMAC_E2EFC_DATA_HDR_1r; 43053 } else { 43054 return BCM_E_PARAM; 43055 } 43056 43057 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 43058 0, &val_64)); 43059 data_1 = soc_reg64_field_get(unit, reg, 43060 val_64, E2EFC_DATA_HDR_1f); 43061 COMPILER_64_TO_32_LO(val_lo, data_1); 43062 COMPILER_64_TO_32_HI(val_hi, data_1); 43063 val_lo = (val_lo & 0xffff) | ((value & 0xffff) << 16); 43064 COMPILER_64_SET(data_1, val_hi, val_lo); 43065 soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_1f, 43066 data_1); 43067 rv = soc_reg64_set(unit, reg, port, 0, val_64); 43068 } 43069 break; 43070 case bcmPortControlE2EFCOpcode: 43071 if (soc_feature(unit, soc_feature_e2efc)) { 43072 uint32 val_lo, val_hi; 43073 uint64 val_64, data_1; 43074 soc_reg_t reg; 43075 #if defined(BCM_KATANA2_SUPPORT) 43076 uint32 val; 43077 #endif 43078 43079 if (!IS_HG_PORT(unit, port)) { 43080 LOG_ERROR( 43081 BSL_LS_BCM_PORT, 43082 (BSL_META_U(unit, 43083 "Error: unit %d port %d is not a Higig port. " 43084 "E2EFC messages can only be transmitted to " 43085 "or received from Higig ports.\n"), 43086 unit, port)); 43087 return BCM_E_PARAM; 43088 } 43089 #if defined(BCM_KATANA2_SUPPORT) 43090 if (SOC_IS_KATANA2(unit)) { 43091 #if defined(BCM_SABER2_SUPPORT) 43092 if (SOC_IS_SABER2(unit)) { 43093 /* Do nothing */ 43094 } else 43095 #endif /* BCM_SABER2_SUPPORT */ 43096 { 43097 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val)); 43098 val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f); 43099 val_lo = (val_lo & 0xffff0000) | (value & 0xffff); 43100 soc_reg_field_set(unit, XIBP_D3r, &val, D_BYTES_12_15f, val_lo); 43101 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_D3r, port, 0, val)); 43102 rv = BCM_E_NONE; 43103 break; 43104 } 43105 } 43106 #endif /* BCM_KATANA2_SUPPORT */ 43107 if (IS_XL_PORT(unit, port)) { 43108 reg = XLMAC_E2EFC_DATA_HDR_1r; 43109 } else if (IS_CL_PORT(unit, port)) { 43110 reg = CLMAC_E2EFC_DATA_HDR_1r; 43111 } else { 43112 return BCM_E_PARAM; 43113 } 43114 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, 43115 0, &val_64)); 43116 data_1 = soc_reg64_field_get(unit, reg, 43117 val_64, E2EFC_DATA_HDR_1f); 43118 COMPILER_64_TO_32_LO(val_lo, data_1); 43119 COMPILER_64_TO_32_HI(val_hi, data_1); 43120 val_lo = (val_lo & 0xffff0000) | (value & 0xffff); 43121 COMPILER_64_SET(data_1, val_hi, val_lo); 43122 soc_reg64_field_set(unit, reg, &val_64, E2EFC_DATA_HDR_1f, 43123 data_1); 43124 rv = soc_reg64_set(unit, reg, port, 0, val_64); 43125 } 43126 break; 43127 case bcmPortControlResetSerdes: 43128 43129 43130 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TOMAHAWKPLUS_SUPPORT) 43131 if (SOC_IS_TOMAHAWK(unit) || SOC_IS_TOMAHAWKPLUS(unit)) { 43132 rv = soc_th_reset_serdes(unit, port, value); 43133 43134 } else 43135 #endif 43136 43137 #if defined(BCM_HURRICANE3_SUPPORT) 43138 if (SOC_IS_HURRICANE3(unit)) { 43139 rv = soc_hurricane3_tsc_core_reset(unit, port, value); 43140 } else 43141 #endif 43142 { 43143 rv = BCM_E_UNAVAIL; 43144 } 43145 break; 43146 case bcmPortControlIntEnable: 43147 #if defined(BCM_TOMAHAWK3_SUPPORT) 43148 if (soc_feature(unit, soc_feature_inband_network_telemetry)) { 43149 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, INT_ENABLEf, value); 43150 } 43151 #endif 43152 break; 43153 case bcmPortControlIntTurnaround: 43154 #if defined(BCM_TOMAHAWK3_SUPPORT) 43155 if (soc_feature(unit, soc_feature_inband_network_telemetry)) { 43156 SOC_IF_ERROR_RETURN 43157 (READ_INT_TURNAROUND_EN_BMAPm(unit, MEM_BLOCK_ANY, 0, 43158 &int_turnaround_en_bmap_entry)); 43159 soc_mem_pbmp_field_get(unit, INT_TURNAROUND_EN_BMAPm, 43160 &int_turnaround_en_bmap_entry, PORT_BITMAPf, &pbmp); 43161 if (value) 43162 SOC_PBMP_PORT_ADD(pbmp, port); 43163 else 43164 SOC_PBMP_PORT_REMOVE(pbmp, port); 43165 43166 soc_mem_pbmp_field_set(unit, INT_TURNAROUND_EN_BMAPm, 43167 &int_turnaround_en_bmap_entry, PORT_BITMAPf, &pbmp); 43168 SOC_IF_ERROR_RETURN 43169 (WRITE_INT_TURNAROUND_EN_BMAPm(unit, MEM_BLOCK_ANY, 0, 43170 &int_turnaround_en_bmap_entry)); 43171 } 43172 #endif 43173 break; 43174 case bcmPortControlObmClassifierPriority: 43175 case bcmPortControlObmClassifierEnableDscp: 43176 case bcmPortControlObmClassifierEnableMpls: 43177 case bcmPortControlObmClassifierEnableEtag: 43178 case bcmPortControlObmClassifierEtagEthertype: 43179 case bcmPortControlObmClassifierVntagEthertype: 43180 43181 #if defined(BCM_MONTEREY_SUPPORT) 43182 if (SOC_IS_MONTEREY(unit)) { 43183 rv = bcm_mn_obm_classifier_port_control_set(unit, port, type, value); 43184 } else 43185 #endif 43186 #if defined(BCM_APACHE_SUPPORT) 43187 if (SOC_IS_APACHE(unit)) { 43188 rv = bcm_apache_obm_classifier_port_control_set(unit, port, type, value); 43189 } else 43190 #endif 43191 { 43192 rv = BCM_E_UNAVAIL; 43193 } 43194 break; 43195 case bcmPortControlObmClassifierInternal: 43196 #if defined(BCM_MONTEREY_SUPPORT) 43197 if (SOC_IS_MONTEREY(unit)) { 43198 rv = bcm_mn_obm_classifier_port_control_set(unit, port, type, value); 43199 } else 43200 #endif 43201 { 43202 rv = BCM_E_UNAVAIL; 43203 } 43204 break; 43205 43206 case bcmPortControlWirelessCosMapSelect: 43207 #if defined(BCM_HELIX5_SUPPORT) 43208 if (SOC_IS_HELIX5(unit)) { 43209 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, 43210 WIRED_WIRELESSf, (value) ? 1 : 0); 43211 } else 43212 #endif 43213 { 43214 rv = BCM_E_UNAVAIL; 43215 } 43216 break; 43217 43218 case bcmPortControlHiGigCosSelect: 43219 #if defined(BCM_HELIX5_SUPPORT) 43220 if (SOC_IS_HELIX5(unit)) { 43221 rv = bcm_hx5_hgcos_select_port_control_set(unit, port, type, value); 43222 } else 43223 #endif 43224 { 43225 rv = BCM_E_UNAVAIL; 43226 } 43227 break; 43228 case bcmPortControlInternalLoopback: 43229 #ifdef BCM_TRIDENT3_SUPPORT 43230 if (SOC_IS_TRIDENT3X(unit)) { 43231 rv = bcmi_td3_port_internal_loopback_set(unit,port,value); 43232 43233 } else 43234 #endif 43235 { 43236 rv = BCM_E_UNAVAIL; 43237 } 43238 break; 43239 #ifdef BCM_MONTEREY_SUPPORT 43240 case bcmPortControlObmInterruptTypeDropPreempt : 43241 case bcmPortControlObmInterruptTypeOverflowPreempt : 43242 case bcmPortControlObmInterruptTypeDropExpress : 43243 case bcmPortControlObmInterruptTypeOverflowExpress : 43244 if (SOC_IS_MONTEREY(unit)) { 43245 rv = bcm_mn_obm_interrupt_port_control_set(unit, port, type, value); 43246 43247 } else 43248 #endif 43249 { 43250 rv = BCM_E_UNAVAIL; 43251 } 43252 break; 43253 default: 43254 break; 43255 } 43256 return rv; 43257 } 43258 43259 43260 /* 43261 * Function: 43262 * bcm_esw_port_control_get 43263 * Description: 43264 * Get the status of specified port feature. 43265 * Parameters: 43266 * unit - Device number 43267 * port - Port number 43268 * type - Enum value of the feature 43269 * value - (OUT) Current value of the port feature 43270 * Return Value: 43271 * BCM_E_NONE 43272 * BCM_E_UNAVAIL - Functionality not available 43273 */ 43274 int 43275 bcm_esw_port_control_get(int unit, bcm_port_t port, 43276 bcm_port_control_t type, int *value) 43277 { 43278 int rv = BCM_E_UNAVAIL; 43279 int valid = 0; 43280 #if defined(BCM_SHADOW_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 43281 uint32 val = 0; 43282 #endif /* BCM_SHADOW_SUPPORT || BCM_GREYHOUND_SUPPORT */ 43283 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 43284 int chk_gx_port = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 43285 SOC_IS_VALKYRIE2(unit) || SOC_IS_SCORPION(unit)); 43286 #endif 43287 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX) 43288 int udp; 43289 int tcp; 43290 int enable; 43291 #endif 43292 source_vp_entry_t svp_entry; 43293 #if defined(BCM_TOMAHAWK3_SUPPORT) 43294 int_turnaround_en_bmap_entry_t int_turnaround_en_bmap_entry; 43295 bcm_pbmp_t pbmp; 43296 #endif 43297 if (value == NULL) { 43298 return BCM_E_PARAM; 43299 } 43300 43301 /* Make sure port module is initialized. */ 43302 PORT_INIT(unit); 43303 43304 if(bcm_common_oamp_port_enable_get(unit, port) && 43305 (type != bcmPortControlSatEnable)) { 43306 LOG_ERROR(BSL_LS_BCM_PORT, 43307 (BSL_META("Error: Not permitted on OAMP port %d.n"), 43308 port)); 43309 return BCM_E_PARAM; 43310 } 43311 43312 /* Call Port Control module */ 43313 if (SOC_USE_PORTCTRL(unit)) { 43314 /* 43315 * Check that port control feature is valid in Port Control. 43316 * If valid, call Port Control routine to handle feature; otherwise 43317 * continue with rest of logic. 43318 */ 43319 BCM_IF_ERROR_RETURN 43320 (bcmi_esw_portctrl_control_validate(unit, type, &valid)); 43321 if (valid) { 43322 return bcmi_esw_portctrl_control_get(unit, port, type, value); 43323 } 43324 } 43325 43326 #if defined(BCM_SHADOW_SUPPORT) 43327 if (SOC_IS_SHADOW(unit)) { 43328 /* If unsupported port control type, return unavail */ 43329 if (!_bcm_port_type_shadow_support (unit, port, type)) { 43330 return BCM_E_UNAVAIL; 43331 } 43332 } 43333 #endif /* BCM_SHADOW_SUPPORT */ 43334 43335 if (type == bcmPortControlEsmEligibility) { 43336 #ifdef BCM_TRIUMPH3_SUPPORT 43337 /* For bcmPortControlEsmEligibility, a non-local port 43338 * is accepted. For other port controls, a non-local 43339 * port is not accepted. Hence, bcmPortControlEsmEligibility 43340 * is implemented here, before the _bcm_esw_port_gport_validate 43341 * procedure below. 43342 */ 43343 return bcm_tr3_port_esm_eligible_get(unit, port, value); 43344 #endif /* BCM_TRIUMPH3_SUPPORT */ 43345 } 43346 43347 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 43348 if ( 43349 #ifdef BCM_HGPROXY_COE_SUPPORT 43350 (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 43351 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) && 43352 ((type == bcmPortControlVlanVpGroupIngress) || 43353 (type == bcmPortControlVlanVpGroupEgress))) || 43354 #endif 43355 BCM_GPORT_IS_TRUNK(port) || 43356 BCM_GPORT_IS_VLAN_PORT(port) || 43357 BCM_GPORT_IS_NIV_PORT(port) || 43358 BCM_GPORT_IS_VXLAN_PORT(port) || 43359 BCM_GPORT_IS_MIM_PORT(port) || 43360 BCM_GPORT_IS_MPLS_PORT(port) || 43361 BCM_GPORT_IS_L2GRE_PORT(port) || 43362 BCM_GPORT_IS_FLOW_PORT(port) || 43363 BCM_GPORT_IS_EXTENDER_PORT(port)) { 43364 return bcm_td_vp_control_get(unit, port, type, value); 43365 } else 43366 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 43367 #if defined(BCM_KATANA2_SUPPORT) 43368 if (((BCM_GPORT_IS_MIM_PORT(port)) || 43369 (BCM_GPORT_IS_MPLS_PORT(port))) && SOC_IS_KATANA2(unit)) { 43370 rv = BCM_E_NONE; 43371 } else 43372 #endif /* BCM_KATANA2_SUPPORT */ 43373 if ((BCM_GPORT_IS_LOCAL_CPU_IEEE(port)) || 43374 (BCM_GPORT_IS_LOCAL_CPU_HIGIG(port))) { 43375 rv = BCM_E_NONE; 43376 } else 43377 #ifdef BCM_HGPROXY_COE_SUPPORT 43378 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 43379 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 43380 rv = BCM_E_NONE; 43381 } else 43382 #endif 43383 { 43384 rv = bcm_esw_port_control_validate(unit, port, type, &port); 43385 } 43386 BCM_IF_ERROR_RETURN(rv); 43387 rv = BCM_E_UNAVAIL; 43388 43389 /* 43390 * At this point, 'port' can be: 43391 * GPORT WLAN 43392 * GPORT PROXY 43393 * BCM valid local port 43394 * 43395 * Some switch cases only handles 'port' in BCM port format 43396 * (non-gport). Corresponding checks must be added in those 43397 * cases to ensure that 'port' is not a gport. 43398 */ 43399 switch (type) { 43400 case bcmPortControlBridge: 43401 if (SOC_IS_XGS3_SWITCH(unit)) { 43402 rv = _bcm_esw_port_tab_get(unit, port, PORT_BRIDGEf, value); 43403 } 43404 break; 43405 case bcmPortControlTrunkHashSet: 43406 #if defined(BCM_TRIUMPH3_SUPPORT) 43407 if (SOC_IS_TRIUMPH3(unit)) { 43408 return BCM_E_UNAVAIL; 43409 } else 43410 #endif /* BCM_TRIUMPH3_SUPPORT */ 43411 { 43412 #if defined(BCM_BRADLEY_SUPPORT) 43413 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 43414 rv = _bcm_esw_port_tab_get(unit, port, 43415 RTAG7_HASH_CFG_SEL_TRUNKf, value); 43416 } 43417 #endif /* BCM_BRADLEY_SUPPORT */ 43418 } 43419 break; 43420 case bcmPortControlFabricTrunkHashSet: 43421 #if defined(BCM_TRIUMPH3_SUPPORT) 43422 if (SOC_IS_TRIUMPH3(unit)) { 43423 return BCM_E_UNAVAIL; 43424 } else 43425 #endif /* BCM_TRIUMPH3_SUPPORT */ 43426 { 43427 #if defined(BCM_BRADLEY_SUPPORT) 43428 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 43429 rv = _bcm_esw_port_tab_get(unit, port, 43430 RTAG7_HASH_CFG_SEL_HIGIG_TRUNKf, 43431 value); 43432 } 43433 #endif /* BCM_BRADLEY_SUPPORT */ 43434 } 43435 break; 43436 case bcmPortControlECMPHashSet: 43437 #if defined(BCM_TRIUMPH3_SUPPORT) 43438 if (SOC_IS_TRIUMPH3(unit)) { 43439 return BCM_E_UNAVAIL; 43440 } else 43441 #endif /* BCM_TRIUMPH3_SUPPORT */ 43442 { 43443 #if defined(BCM_BRADLEY_SUPPORT) 43444 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 43445 rv = _bcm_esw_port_tab_get(unit, port, 43446 RTAG7_HASH_CFG_SEL_ECMPf, value); 43447 } 43448 #endif /* BCM_BRADLEY_SUPPORT */ 43449 } 43450 break; 43451 case bcmPortControlLoadBalanceHashSet: 43452 #if defined(BCM_TRIUMPH3_SUPPORT) 43453 if (SOC_IS_TRIUMPH3(unit)) { 43454 return BCM_E_UNAVAIL; 43455 } else 43456 #endif /* BCM_TRIUMPH3_SUPPORT */ 43457 { 43458 #if defined(BCM_BRADLEY_SUPPORT) 43459 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 43460 rv = _bcm_esw_port_tab_get(unit, port, 43461 RTAG7_HASH_CFG_SEL_LBIDf, value); 43462 } 43463 #endif /* BCM_BRADLEY_SUPPORT */ 43464 } 43465 break; 43466 case bcmPortControlLoadBalancingNumber: 43467 #if defined(BCM_BRADLEY_SUPPORT) 43468 if (SOC_IS_HBX(unit) || SOC_IS_TRX(unit)) { 43469 rv = _bcm_esw_port_tab_get(unit, port, 43470 RTAG7_PORT_LBNf, value); 43471 } 43472 #endif /* BCM_BRADLEY_SUPPORT */ 43473 break; 43474 case bcmPortControlErrorSymbolDetect: 43475 #if defined(BCM_GREYHOUND_SUPPORT) 43476 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 43477 SOC_IS_GREYHOUND2(unit)) { 43478 rv = BCM_E_UNAVAIL; 43479 } else 43480 #endif /* BCM_GREYHOUND_SUPPORT */ 43481 { 43482 #ifdef BCM_XGS3_SWITCH_SUPPORT 43483 if (SOC_IS_XGS3_SWITCH(unit)) { 43484 rv = _bcm_esw_port_err_sym_detect_get(unit, port, value); 43485 } 43486 #endif 43487 } 43488 break; 43489 case bcmPortControlErrorSymbolCount: 43490 #if defined(BCM_GREYHOUND_SUPPORT) 43491 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 43492 SOC_IS_GREYHOUND2(unit)) { 43493 rv = BCM_E_UNAVAIL; 43494 } else 43495 #endif /* BCM_GREYHOUND_SUPPORT */ 43496 { 43497 #ifdef BCM_XGS3_SWITCH_SUPPORT 43498 if (SOC_IS_XGS3_SWITCH(unit)) { 43499 rv = _bcm_esw_port_err_sym_count_get(unit, port, value); 43500 } 43501 #endif 43502 } 43503 break; 43504 case bcmPortControlIP4: 43505 if (SOC_IS_XGS3_SWITCH(unit)) { 43506 #if defined(BCM_TRX_SUPPORT) 43507 if (BCM_GPORT_LOCAL_CPU_HIGIG == port) { 43508 rv = _bcm_esw_iport_tab_get(unit, CMIC_PORT(unit), V4L3_ENABLEf, value); 43509 } else 43510 #endif 43511 { 43512 rv = _bcm_esw_port_tab_get(unit, port, V4L3_ENABLEf, value); 43513 } 43514 } 43515 break; 43516 case bcmPortControlIP6: 43517 if (SOC_IS_XGS3_SWITCH(unit)) { 43518 rv = _bcm_esw_port_tab_get(unit, port, V6L3_ENABLEf, value); 43519 } 43520 break; 43521 case bcmPortControlIP4Mcast: 43522 if (SOC_IS_XGS3_SWITCH(unit)) { 43523 rv = _bcm_esw_port_tab_get(unit, port, V4IPMC_ENABLEf, value); 43524 } 43525 break; 43526 case bcmPortControlIP6Mcast: 43527 if (SOC_IS_XGS3_SWITCH(unit)) { 43528 rv = _bcm_esw_port_tab_get(unit, port, V6IPMC_ENABLEf, value); 43529 } 43530 break; 43531 case bcmPortControlIPMC4Ucast: 43532 if (soc_feature(unit, soc_feature_ipmc_unicast)) { 43533 rv = _bcm_esw_port_tab_get(unit, port, 43534 IPMCV4_UNICAST_MACDA_ENABLEf, value); 43535 } 43536 break; 43537 case bcmPortControlIPMC6Ucast: 43538 if (soc_feature(unit, soc_feature_ipmc_unicast)) { 43539 rv = _bcm_esw_port_tab_get(unit, port, 43540 IPMCV6_UNICAST_MACDA_ENABLEf, value); 43541 } 43542 break; 43543 case bcmPortControlIP4McastL2: 43544 #if defined(BCM_TRX_SUPPORT) 43545 if (SOC_IS_XGS3_SWITCH(unit)) { 43546 if (SOC_IS_TD2_TT2(unit) && 43547 soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 43548 IPMCV4_L2_ENABLEf)) { 43549 rv = _bcm_trx_source_trunk_map_get(unit, port, 43550 IPMCV4_L2_ENABLEf, (uint32 *)value); 43551 } else { 43552 rv = _bcm_esw_port_tab_get(unit, port, V4IPMC_L2_ENABLEf, value); 43553 } 43554 } 43555 #endif /* BCM_TRX_SUPPORT */ 43556 break; 43557 case bcmPortControlIP6McastL2: 43558 #ifdef BCM_TRX_SUPPORT 43559 if (SOC_IS_XGS3_SWITCH(unit)) { 43560 if (SOC_IS_TD2_TT2(unit) && 43561 soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 43562 IPMCV6_L2_ENABLEf)) { 43563 rv = _bcm_trx_source_trunk_map_get(unit, port, 43564 IPMCV6_L2_ENABLEf, (uint32 *)value); 43565 } else { 43566 rv = _bcm_esw_port_tab_get(unit, port, V6IPMC_L2_ENABLEf, value); 43567 } 43568 } 43569 #endif 43570 break; 43571 43572 case bcmPortControlMpls: 43573 #if defined(BCM_TRIUMPH_SUPPORT) 43574 if (SOC_IS_XGS3_SWITCH(unit)) { 43575 rv = _bcm_esw_port_tab_get(unit, port, MPLS_ENABLEf, value); 43576 } 43577 #endif 43578 break; 43579 43580 case bcmPortControlMacInMac: 43581 #if defined(BCM_TRIUMPH2_SUPPORT) 43582 if (SOC_IS_XGS3_SWITCH(unit) && soc_feature(unit, soc_feature_mim)) { 43583 rv = _bcm_esw_port_tab_get(unit, port, MIM_TERM_ENABLEf, value); 43584 } 43585 #endif 43586 break; 43587 43588 case bcmPortControlMimUcastTermEnable: 43589 #if defined(BCM_TRIUMPH2_SUPPORT) 43590 if (SOC_IS_XGS3_SWITCH(unit) && soc_feature(unit, soc_feature_mim)) { 43591 rv = _bcm_esw_port_tab_get(unit, port, MIM_TERM_ENABLEf, value); 43592 } 43593 #endif 43594 break; 43595 43596 case bcmPortControlMimMcastTermEnable: 43597 #if defined(BCM_TRIUMPH2_SUPPORT) 43598 if (SOC_IS_XGS3_SWITCH(unit) && soc_feature(unit, soc_feature_mim)) { 43599 rv = _bcm_esw_port_tab_get(unit, port, MIM_MC_TERM_ENABLEf, value); 43600 } 43601 #endif 43602 break; 43603 43604 case bcmPortControlSrcBmacMissToCpu: 43605 #ifdef BCM_TRIUMPH2_SUPPORT 43606 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 43607 SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) || 43608 SOC_IS_TD_TT(unit) || SOC_IS_TRIUMPH3(unit) || SOC_IS_KATANA(unit)) { 43609 /* 0x2: ToCPU 0x1: Drop(default) */ 43610 rv = _bcm_esw_port_tab_get(unit, port, CML_BMAC_NEWf, value); 43611 *value = (*value == 0x2) ? TRUE : FALSE; 43612 } 43613 #endif /* BCM_TRIUMPH2_SUPPORT */ 43614 break; 43615 43616 case bcmPortControlQosRemarkResolution: 43617 #ifdef BCM_TRIDENT3_SUPPORT 43618 if (SOC_IS_TRIDENT3X(unit)) { 43619 rv = _bcm_esw_egr_port_tab_get(unit, port, QOS_CTRL_IDf, value); 43620 /* TD3 only supports 2 of the 4 valid hardware configurations for now. 43621 * 1: Serial resolution. 43622 * 3: Layered resolution. 43623 * Other value: Invalid. 43624 */ 43625 if (rv == BCM_E_NONE) { 43626 if (*value == 1) { 43627 *value = BCM_PORT_QOS_SERIAL_RESOLUTION; 43628 } else if (*value == 3) { 43629 *value = BCM_PORT_QOS_LAYERED_RESOLUTION; 43630 } else { 43631 return BCM_E_PARAM; 43632 } 43633 } 43634 } 43635 #endif /* BCM_TRIDENT3_SUPPORT */ 43636 break; 43637 43638 case bcmPortControlFabricQueue: 43639 #if defined(BCM_TRIUMPH2_SUPPORT) 43640 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43641 if (IS_ST_PORT(unit, port)) { 43642 if (SOC_REG_FIELD_VALID(unit, EGR_PORT_64r, EH_EXT_HDR_ENABLEf)) { 43643 uint64 egr_val64; 43644 rv = READ_EGR_PORT_64r(unit, port, &egr_val64); 43645 if (BCM_SUCCESS(rv)) { 43646 *value = soc_reg64_field32_get(unit, EGR_PORT_64r, 43647 egr_val64, EH_EXT_HDR_ENABLEf); 43648 } 43649 } 43650 else if(SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EH_EXT_HDR_ENABLEf)){ 43651 egr_port_entry_t entry; 43652 rv = soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ANY, port, 43653 &entry); 43654 if (BCM_SUCCESS(rv)) { 43655 *value = soc_mem_field32_get(unit, EGR_PORTm, &entry, 43656 EH_EXT_HDR_ENABLEf); 43657 } 43658 } 43659 } else { 43660 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 43661 /* Allow CPU port on TD2+ to add extended header */ 43662 if (SOC_IS_TRIDENT2PLUS(unit) && IS_CPU_PORT(unit, port)) { 43663 egr_port_entry_t entry; 43664 rv = soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ANY, port, 43665 &entry); 43666 if (BCM_SUCCESS(rv)) { 43667 *value = soc_mem_field32_get(unit, EGR_PORTm, &entry, 43668 EH_EXT_HDR_ENABLEf); 43669 } 43670 } 43671 #endif 43672 #if defined(BCM_TOMAHAWK_SUPPORT) 43673 if (SOC_IS_TOMAHAWKX(unit) && IS_CPU_PORT(unit, port)) { 43674 egr_port_entry_t entry; 43675 rv = soc_mem_read(unit, EGR_PORTm, MEM_BLOCK_ANY, port, &entry); 43676 if (BCM_SUCCESS(rv)) { 43677 *value = soc_mem_field32_get(unit, EGR_PORTm, &entry, 43678 EH_EXT_HDR_ENABLEf); 43679 } 43680 } 43681 #endif 43682 } 43683 #if defined(BCM_TRIDENT3_SUPPORT) 43684 if (SOC_IS_TRIDENT3X(unit) && 43685 soc_feature(unit, soc_feature_egr_lport_tab_profile)) { 43686 uint32 lport_idx; 43687 egr_port_entry_t entry; 43688 egr_lport_profile_entry_t lport_entry; 43689 43690 BCM_IF_ERROR_RETURN(READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, &entry)); 43691 lport_idx = soc_mem_field32_get(unit, EGR_PORTm, &entry, 43692 EGR_LPORT_PROFILE_IDXf); 43693 rv = (READ_EGR_LPORT_PROFILEm(unit, MEM_BLOCK_ANY, 43694 lport_idx, &lport_entry)); 43695 if (BCM_SUCCESS(rv)) { 43696 *value = soc_mem_field32_get(unit, EGR_LPORT_PROFILEm, &lport_entry, 43697 EH_EXT_HDR_ENABLEf); 43698 } 43699 } 43700 #endif 43701 #endif 43702 break; 43703 case bcmPortControlPassControlFrames: 43704 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43705 #ifdef BCM_XGS_SWITCH_SUPPORT 43706 if (IS_XE_PORT(unit, port) || IS_CE_PORT(unit, port) || 43707 (IS_GE_PORT(unit, port) 43708 && soc_feature(unit, soc_feature_unified_port)) || 43709 (SOC_IS_KATANAX(unit) && IS_MXQ_PORT(unit, port))) { 43710 if(soc_feature(unit, soc_feature_pgw_mac_control_frame)) { 43711 uint32 rval32 = 0; 43712 rv = READ_PGW_MAC_RSV_MASKr(unit, port, &rval32); 43713 if (BCM_SUCCESS(rv)) { 43714 /* PGW_MAC_RSV_MASK: Bit 11 Control Frame recieved 43715 * the bit value needs to be reversed 43716 */ 43717 *value = ((rval32 & 0x800) >> 11) ? 0 : 1 ; 43718 } 43719 } else { 43720 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 43721 SOC_MAC_PASS_CONTROL_FRAME, value); 43722 } 43723 } 43724 #endif 43725 break; 43726 #ifdef BCM_XGS3_SWITCH_SUPPORT 43727 case bcmPortControlFilterLookup: 43728 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 43729 rv = _bcm_esw_port_tab_get(unit, port, VFP_ENABLEf, value); 43730 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 43731 break; 43732 case bcmPortControlFilterIngress: 43733 #if defined(BCM_TRX_SUPPORT) 43734 if (BCM_GPORT_LOCAL_CPU_HIGIG == port) { 43735 rv = _bcm_esw_iport_tab_get(unit, CMIC_PORT(unit), FILTER_ENABLEf, value); 43736 } else 43737 #endif 43738 if (BCM_GPORT_LOCAL_CPU_IEEE == port) { 43739 rv = _bcm_esw_port_tab_get(unit, CMIC_PORT(unit), FILTER_ENABLEf, value); 43740 } else { 43741 rv = _bcm_esw_port_tab_get(unit, port, FILTER_ENABLEf, value); 43742 } 43743 break; 43744 case bcmPortControlFilterEgress: 43745 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 43746 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43747 if (SOC_REG_FIELD_VALID(unit, EGR_PORTr, EFP_FILTER_ENABLEf)) { 43748 uint32 egr_val; 43749 43750 rv = READ_EGR_PORTr(unit, port, &egr_val); 43751 if (BCM_SUCCESS(rv)) { 43752 *value = soc_reg_field_get(unit, EGR_PORTr, egr_val, 43753 EFP_FILTER_ENABLEf); 43754 } 43755 } else if (SOC_REG_FIELD_VALID(unit, EGR_PORT_64r, 43756 EFP_FILTER_ENABLEf)) { 43757 uint64 egr_val64; 43758 43759 rv = READ_EGR_PORT_64r(unit, port, &egr_val64); 43760 if (BCM_SUCCESS(rv)) { 43761 *value = soc_reg64_field32_get(unit, EGR_PORT_64r, 43762 egr_val64, 43763 EFP_FILTER_ENABLEf); 43764 } 43765 } else { 43766 rv = _bcm_esw_egr_port_tab_get(unit, port, EFP_FILTER_ENABLEf, value); 43767 43768 } 43769 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 43770 break; 43771 case bcmPortControlFrameSpacingStretch: 43772 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43773 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 43774 SOC_MAC_CONTROL_FRAME_SPACING_STRETCH, value); 43775 break; 43776 case bcmPortControlPreservePacketPriority: 43777 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 43778 if (SOC_IS_TRIUMPH3(unit)) { 43779 /* Triumph3 has unity mapping to ING_OUTER_DOT1P_MAPPING_TABLE */ 43780 rv = _bcm_esw_port_tab_get(unit, port, 43781 DOT1P_REMAP_POINTERf, value); 43782 if (BCM_SUCCESS(rv)) { 43783 /* True if pointed to default dot1p profile */ 43784 *value = (*value) ? 0 : 1; 43785 } 43786 } else { 43787 rv = _bcm_esw_port_tab_get(unit, port, USE_INCOMING_DOT1Pf, value); 43788 } 43789 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 43790 break; 43791 case bcmPortControlLearnClassEnable: 43792 #if defined(BCM_TRX_SUPPORT) 43793 if (soc_feature(unit, soc_feature_class_based_learning)) { 43794 rv = _bcm_esw_port_tab_get(unit, port, CLASS_BASED_SM_ENABLEf, 43795 value); 43796 } 43797 #endif /* BCM_TRX_SUPPORT */ 43798 break; 43799 case bcmPortControlTrustIncomingVlan: 43800 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_TRX_SUPPORT) 43801 rv = _bcm_esw_port_tab_get(unit, port, TRUST_INCOMING_VIDf, value); 43802 #endif /* BCM_RAVEN_SUPPORT || BCM_TRX_SUPPORT */ 43803 break; 43804 case bcmPortControlDoNotCheckVlan: 43805 #if defined(BCM_TRX_SUPPORT) 43806 if (!SOC_IS_SHADOW(unit)) { 43807 #if defined(BCM_TRIDENT3_SUPPORT) 43808 if (SOC_IS_TRIDENT3X(unit)) { 43809 rv = _bcm_esw_port_tab_get(unit, port, 43810 DISABLE_VLAN_CHECKSf, value); 43811 } else 43812 #endif 43813 if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf)) { 43814 if (CMIC_PORT(unit) == port) { 43815 rv = _bcm_esw_iport_tab_get(unit, port, 43816 DISABLE_VLAN_CHECKSf, value); 43817 } else { 43818 rv = _bcm_esw_port_tab_get(unit, port, 43819 DISABLE_VLAN_CHECKSf, value); 43820 } 43821 } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 43822 DISABLE_VLAN_CHECKSf)) { 43823 #if defined(BCM_KATANA2_SUPPORT) 43824 if (SOC_IS_KATANA2(unit)) { 43825 rv = _bcm_kt2_source_trunk_map_get(unit, port, 43826 DISABLE_VLAN_CHECKSf, (uint32 *)value); 43827 } else 43828 #endif 43829 { 43830 rv = _bcm_trx_source_trunk_map_get(unit, port, 43831 DISABLE_VLAN_CHECKSf, (uint32 *)value); 43832 } 43833 } 43834 } 43835 #endif /* BCM_TRX_SUPPORT */ 43836 break; 43837 case bcmPortControlDoNotCheckVlanFromCpu: 43838 #if defined(BCM_TRX_SUPPORT) 43839 if (!SOC_IS_SHADOW(unit)) { 43840 if (CMIC_PORT(unit) == port) { 43841 if (soc_mem_field_valid(unit, PORT_TABm, DISABLE_VLAN_CHECKSf) || 43842 SOC_IS_TRIDENT3X(unit)) { 43843 rv = _bcm_esw_port_tab_get(unit, port, 43844 DISABLE_VLAN_CHECKSf, value); 43845 } else if (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 43846 DISABLE_VLAN_CHECKSf)) { 43847 rv = _bcm_trx_source_trunk_map_get(unit, port, 43848 DISABLE_VLAN_CHECKSf, (uint32 *)value); 43849 } 43850 } else { 43851 rv = BCM_E_PORT; 43852 } 43853 } 43854 #endif /* BCM_TRX_SUPPORT */ 43855 break; 43856 case bcmPortControlIEEE8021ASEnableIngress: 43857 #if defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_ENDURO_SUPPORT) 43858 if (soc_feature(unit, soc_feature_rx_timestamp)) { 43859 rv = _bcm_esw_port_tab_get(unit, port, 43860 IEEE_802_1AS_ENABLEf, value); 43861 } 43862 #endif /* BCM_HAWKEYE_SUPPORT */ 43863 break; 43864 case bcmPortControlIEEE8021ASEnableEgress: 43865 #if defined(BCM_HAWKEYE_SUPPORT) 43866 if (SOC_IS_HAWKEYE(unit)) { 43867 uint32 egr_val; 43868 43869 rv = READ_EGR_PORTr(unit, port, &egr_val); 43870 if (BCM_SUCCESS(rv)) { 43871 *value = soc_reg_field_get(unit, EGR_PORTr, egr_val, 43872 IEEE_802_1AS_ENABLEf); 43873 } 43874 } 43875 #endif /* BCM_HAWKEYE_SUPPORT */ 43876 break; 43877 case bcmPortControlEgressVlanPriUsesPktPri: 43878 #if defined(BCM_TRX_SUPPORT) 43879 #if defined (BCM_HGPROXY_COE_SUPPORT) 43880 if (!(soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 43881 BCM_GPORT_IS_SUBPORT_PORT(port))) 43882 #endif 43883 { 43884 BCM_IF_ERROR_RETURN( 43885 _bcm_esw_port_gport_validate(unit, port, &port)); 43886 } 43887 if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) { 43888 uint32 val; 43889 #ifdef BCM_TRIDENT2PLUS_SUPPORT 43890 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 43891 if (soc_feature(unit, soc_feature_egr_all_profile)) { 43892 rv = bcm_esw_port_egr_lport_field_get(unit, 43893 port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DOT1Pf, 43894 (uint32 *)value); 43895 *value = *value ? 0 : 1; 43896 } else { 43897 #if defined (BCM_HGPROXY_COE_SUPPORT) 43898 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 43899 BCM_GPORT_IS_SUBPORT_PORT(port)) { 43900 rv = bcm_esw_port_egr_lport_field_get( 43901 unit, port, EGR_VLAN_CONTROL_1m, 43902 REMARK_OUTER_DOT1Pf, (uint32 *)value); 43903 *value = *value ? 0 : 1; 43904 } else 43905 #endif 43906 { 43907 egr_vlan_control_1_entry_t entry; 43908 rv = READ_EGR_VLAN_CONTROL_1m( 43909 unit, MEM_BLOCK_ANY, port, &entry); 43910 if (BCM_SUCCESS(rv)) { 43911 *value = soc_EGR_VLAN_CONTROL_1m_field32_get( 43912 unit, &entry, 43913 REMARK_OUTER_DOT1Pf) ? 0 : 1; 43914 } 43915 } 43916 } 43917 } else 43918 #endif 43919 { 43920 rv = READ_EGR_VLAN_CONTROL_1r(unit, port, &val); 43921 if (BCM_SUCCESS(rv)) { 43922 *value = (soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, val, 43923 REMARK_OUTER_DOT1Pf)) ? 0 : 1; 43924 } 43925 } 43926 } 43927 #endif /* BCM_TRX_SUPPORT */ 43928 break; 43929 case bcmPortControlEgressModifyDscp: 43930 #if defined(BCM_TRX_SUPPORT) 43931 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43932 if (SOC_IS_TRX(unit) && !SOC_IS_SHADOW(unit)) { 43933 uint32 val; 43934 #ifdef BCM_TRIDENT2PLUS_SUPPORT 43935 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 43936 if (soc_feature(unit, soc_feature_egr_all_profile)) { 43937 rv = bcm_esw_port_egr_lport_field_get(unit, 43938 port, EGR_VLAN_CONTROL_1m, REMARK_OUTER_DSCPf, 43939 (uint32 *)value); 43940 *value = *value ? 1 : 0; 43941 } else { 43942 egr_vlan_control_1_entry_t entry; 43943 rv = READ_EGR_VLAN_CONTROL_1m(unit, MEM_BLOCK_ANY, port, &entry); 43944 if (BCM_SUCCESS(rv)) { 43945 *value = soc_EGR_VLAN_CONTROL_1m_field32_get(unit, &entry, 43946 REMARK_OUTER_DSCPf) ? 1 : 0; 43947 } 43948 } 43949 } else 43950 #endif 43951 { 43952 rv = READ_EGR_VLAN_CONTROL_1r(unit, port, &val); 43953 if (BCM_SUCCESS(rv)) { 43954 *value = (soc_reg_field_get(unit, EGR_VLAN_CONTROL_1r, val, 43955 REMARK_OUTER_DSCPf)) ? 1 : 0; 43956 } 43957 } 43958 } 43959 #endif /* BCM_TRX_SUPPORT */ 43960 break; 43961 case bcmPortControlIpfixRate: 43962 #ifdef BCM_TRIUMPH2_SUPPORT 43963 if (soc_feature(unit, soc_feature_ipfix_rate)) { 43964 rv = _bcm_esw_port_tab_get(unit, port, IPFIX_FLOW_METER_IDf, 43965 value); 43966 } 43967 #endif /* BCM_TRIUMPH2_SUPPORT */ 43968 break; 43969 case bcmPortControlCustomerQueuing: 43970 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 43971 #ifdef BCM_ENDURO_SUPPORT 43972 if (SOC_IS_ENDURO(unit) && !IS_HG_PORT(unit, port)) { 43973 return BCM_E_UNAVAIL; 43974 } 43975 #endif 43976 #ifdef BCM_KATANA_SUPPORT 43977 if (SOC_IS_KATANAX(unit)) { 43978 uint32 rval, ing_cos_mode, rqe_cos_mode; 43979 BCM_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &rval)); 43980 ing_cos_mode = soc_reg_field_get(unit, ING_COS_MODEr, rval, COS_MODEf); 43981 if (SOC_IS_KATANA(unit)) { 43982 SOC_IF_ERROR_RETURN(READ_RQE_PORT_CONFIGr(unit, port, &rval)); 43983 rqe_cos_mode = soc_reg_field_get(unit, RQE_PORT_CONFIGr, rval, COS_MODEf); 43984 } else { 43985 SOC_IF_ERROR_RETURN(READ_RQE_PP_PORT_CONFIGr(unit, port, &rval)); 43986 rqe_cos_mode = soc_reg_field_get(unit, RQE_PP_PORT_CONFIGr, rval, COS_MODEf); 43987 } 43988 if ((ing_cos_mode != rqe_cos_mode) && (ing_cos_mode != 1)) { 43989 *value = 4; 43990 } else { 43991 *value = ing_cos_mode; 43992 } 43993 rv = BCM_E_NONE; 43994 break; 43995 } 43996 #endif /* BCM_KATANA_SUPPORT */ 43997 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 43998 if ((SOC_IS_TRIDENT3X(unit)) || (SOC_IS_TOMAHAWKX(unit))) { 43999 uint64 rval1; 44000 if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) { 44001 rv = soc_reg_get(unit, ING_COS_MODEr, port, 0, &rval1); 44002 BCM_IF_ERROR_RETURN(rv); 44003 *value = soc_reg64_field32_get(unit, ING_COS_MODEr, rval1, 44004 COS_MODEf); 44005 } 44006 break; 44007 } 44008 #endif /* BCM_TRIDENT3_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 44009 #ifdef BCM_TRIDENT2_SUPPORT 44010 if (SOC_IS_TD2_TT2(unit)) { 44011 uint64 rval; 44012 rv = READ_ING_COS_MODE_64r(unit, port, &rval); 44013 BCM_IF_ERROR_RETURN(rv); 44014 44015 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODE_64r, QUEUE_MODEf)) { 44016 *value = soc_reg64_field32_get(unit, ING_COS_MODE_64r, rval, 44017 QUEUE_MODEf); 44018 break; 44019 } 44020 } 44021 #endif /* BCM_TRIDENT2_SUPPORT */ 44022 #ifdef BCM_TRIUMPH2_SUPPORT 44023 if (soc_feature(unit, soc_feature_vlan_queue_map)) { 44024 uint32 rval; 44025 soc_field_t field; 44026 if (SOC_REG_IS_VALID(unit, ING_COS_MODEr)) { 44027 rv = READ_ING_COS_MODEr(unit, port, &rval); 44028 if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, SELECTf)) { 44029 field = SELECTf; 44030 } else if (SOC_REG_FIELD_VALID(unit, ING_COS_MODEr, 44031 QUEUE_MODEf)) { 44032 field = QUEUE_MODEf; 44033 } else { 44034 rv = BCM_E_UNAVAIL; 44035 break; 44036 } 44037 if (SOC_IS_TRIUMPH3(unit)) { 44038 *value = soc_reg_field_get(unit, ING_COS_MODEr, rval, field); 44039 } else { 44040 if (soc_reg_field_get(unit, ING_COS_MODEr, rval, field) 44041 == 3) { 44042 *value = 1; 44043 } else { 44044 *value = 0; 44045 } 44046 } 44047 } 44048 } 44049 #endif /* BCM_TRIUMPH2_SUPPORT */ 44050 break; 44051 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 44052 44053 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT) 44054 case bcmPortControlOAMEnable: 44055 rv = _bcm_esw_port_tab_get(unit, port, OAM_ENABLEf, value); 44056 break; 44057 #endif /* defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_APOLLO_SUPPORT) */ 44058 44059 #if defined (BCM_OLP_SUPPORT) 44060 case bcmPortControlOlpEnable: 44061 if (soc_feature(unit, soc_feature_olp)) { 44062 bcm_module_t module_id = 0; 44063 bcm_module_t my_modid; 44064 bcm_port_t port_id; 44065 bcm_trunk_t trunk_id = BCM_TRUNK_INVALID; 44066 int local_id; 44067 44068 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 44069 44070 if (BCM_GPORT_IS_SET(port)) { 44071 SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, &module_id, 44072 &port_id, &trunk_id, &local_id)); 44073 44074 #if defined(BCM_KATANA2_SUPPORT) 44075 if (SOC_IS_KATANA2(unit) && 44076 (BCM_GPORT_IS_SUBPORT_PORT(port)) && 44077 ((_BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) || 44078 (_BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port)))) { 44079 44080 LOG_ERROR(BSL_LS_BCM_L2, 44081 (BSL_META_U(unit, 44082 "OLP is not allowed on SUBPORT. \ 44083 \n"))); 44084 return BCM_E_PARAM; 44085 } 44086 #endif 44087 } else { 44088 port_id = port; 44089 } 44090 if ((module_id == 0) || (module_id == my_modid)) { 44091 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 44092 if(SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 44093 iarb_ing_port_table_entry_t entry; 44094 44095 SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PORT_TABLEm, 44096 MEM_BLOCK_ANY, port_id, &entry)); 44097 *value = soc_IARB_ING_PORT_TABLEm_field32_get(unit, 44098 &entry, OLP_ENABLEf); 44099 44100 } else 44101 #endif 44102 { 44103 iarb_ing_physical_port_entry_t entry; 44104 SOC_IF_ERROR_RETURN(soc_mem_read(unit, IARB_ING_PHYSICAL_PORTm, 44105 MEM_BLOCK_ANY, port_id, &entry)); 44106 *value = soc_IARB_ING_PHYSICAL_PORTm_field32_get(unit, 44107 &entry, OLP_ENABLEf); 44108 } 44109 } 44110 rv = BCM_E_NONE; 44111 } 44112 break; 44113 #endif /* BCM_OLP_SUPPORT*/ 44114 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_APACHE_SUPPORT) 44115 44116 case bcmPortControlPortMacOui: 44117 case bcmPortControlPortMacNonOui: 44118 44119 /* 44120 * In case of KT2, SB2 and TD2+ NONTCAM STATION related to OAM, OLP, XGS can be programmed 44121 * by either of bcm_l2_station_xxx API or bcm_switch_olp_l2_addr_xxx 44122 * 44123 * Use either of two set of APIs 44124 */ 44125 44126 if (_BCM_SWITCH_OLP_APIV(unit) == _BCM_SWITCH_OLP_L2_STATION_API) { 44127 LOG_VERBOSE(BSL_LS_BCM_L2, 44128 (BSL_META_U(unit, 44129 "use bcm_l2_station_xxx API\n"))); 44130 return BCM_E_UNAVAIL; 44131 } 44132 _BCM_SWITCH_OLP_APIV_SET(unit, _BCM_SWITCH_OLP_TRUE_API); 44133 44134 #if defined(BCM_KATANA2_SUPPORT) 44135 if (SOC_IS_KATANA2(unit) && 44136 (soc_feature(unit, soc_feature_oam) || 44137 soc_feature(unit, soc_feature_sat))) { 44138 44139 uint32 val_lo, val_hi; 44140 uint64 mac_field; 44141 44142 PORT_LOCK(unit); 44143 44144 rv = _bcm_kt2_port_mac_get(unit, port, &mac_field); 44145 if (BCM_FAILURE(rv)) { 44146 PORT_UNLOCK(unit); 44147 return (rv); 44148 } 44149 COMPILER_64_TO_32_LO(val_lo, mac_field); 44150 COMPILER_64_TO_32_HI(val_hi, mac_field); 44151 44152 switch (type) { 44153 case bcmPortControlPortMacOui: 44154 *value = 0xffffff & ((val_hi << 8) | ((val_lo >> 24) & 0xff)); 44155 break; 44156 44157 case bcmPortControlPortMacNonOui: 44158 *value = (val_lo & 0xffffff); 44159 break; 44160 default: 44161 break; 44162 } 44163 PORT_UNLOCK(unit); 44164 44165 rv = BCM_E_NONE; 44166 } 44167 #endif /* BCM_KATANA2_SUPPORT */ 44168 44169 #if defined(BCM_MONTEREY_SUPPORT) 44170 if (SOC_IS_MONTEREY(unit)) { 44171 uint32 mac; 44172 44173 PORT_LOCK(unit); 44174 rv = _bcm_monterey_port_mac_get(unit, 44175 port, 44176 type == bcmPortControlPortMacOui, 44177 &mac); 44178 PORT_UNLOCK(unit); 44179 44180 *value = mac; 44181 } 44182 #endif 44183 #if defined(BCM_APACHE_SUPPORT) 44184 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 44185 uint32 mac; 44186 44187 PORT_LOCK(unit); 44188 rv = _bcm_apache_port_mac_get(unit, 44189 port, 44190 type == bcmPortControlPortMacOui, 44191 &mac); 44192 PORT_UNLOCK(unit); 44193 44194 *value = mac; 44195 } 44196 #endif /* BCM_APACHE_SUPPORT */ 44197 break; 44198 #endif /* BCM_KATANA2_SUPPORT || BCM_APACHE_SUPPORT*/ 44199 44200 #ifdef BCM_TRX_SUPPORT 44201 case bcmPortControlOamLoopback: 44202 if (SOC_IS_TRX(unit) && !SOC_IS_HURRICANE(unit) 44203 && !SOC_IS_SHADOW(unit)) 44204 { 44205 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44206 if (soc_reg_field_valid(unit,ING_MISC_PORT_CONFIGr, 44207 OAM_DO_NOT_MODIFYf)) { 44208 uint32 reg_value; 44209 44210 rv = READ_ING_MISC_PORT_CONFIGr(unit, port, ®_value); 44211 44212 if (SOC_SUCCESS(rv)) { 44213 *value = soc_reg_field_get(unit, ING_MISC_PORT_CONFIGr, 44214 reg_value, OAM_DO_NOT_MODIFYf); 44215 } 44216 } else { 44217 return BCM_E_UNAVAIL; 44218 } 44219 } 44220 44221 break; 44222 #endif /* BCM_TRX_SUPPORT */ 44223 44224 case bcmPortControlLanes: 44225 if (soc_feature(unit, soc_feature_flexport_no_legacy)) { 44226 return BCM_E_UNAVAIL; 44227 } 44228 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44229 #if defined(BCM_TRIUMPH2_SUPPORT) 44230 if (soc_feature(unit, soc_feature_flex_port)) { 44231 #ifdef BCM_XGS5_SWITCH_PORT_SUPPORT 44232 if (soc_feature(unit, soc_feature_xgs5_flexport_legacy_mode)) { 44233 rv = bcmi_xgs5_port_lanes_get(unit, port, value); 44234 } else 44235 #endif /* BCM_XGS5_SWITCH_PORT_SUPPORT */ 44236 #if defined(BCM_ENDURO_SUPPORT) 44237 if (SOC_IS_ENDURO(unit)) { 44238 rv = _bcm_en_port_lanes_get(unit, port, value); 44239 } else 44240 #endif 44241 #if defined(BCM_HURRICANE1_SUPPORT) 44242 if (SOC_IS_HURRICANE(unit)) { 44243 rv = _bcm_hu_port_lanes_get(unit, port, value); 44244 } else 44245 #endif 44246 #if defined(BCM_HURRICANE2_SUPPORT) 44247 if (SOC_IS_HURRICANE2(unit)) { 44248 rv = soc_hurricane2_port_lanes_get(unit, port, value); 44249 } else 44250 #endif 44251 #if defined(BCM_MONTEREY_SUPPORT) 44252 if (SOC_IS_MONTEREY(unit)) { 44253 rv = bcmi_monterey_port_lanes_get(unit, port, value); 44254 } else 44255 #endif 44256 #if defined(BCM_APACHE_SUPPORT) 44257 if (SOC_IS_APACHE(unit)) { 44258 rv = bcmi_apache_port_lanes_get(unit, port, value); 44259 } else 44260 #endif 44261 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 44262 if (SOC_IS_TD2P_TT2P(unit)) { 44263 rv = bcmi_td2p_port_lanes_get(unit, port, value); 44264 } else 44265 #endif 44266 #if defined(BCM_TRIDENT2_SUPPORT) 44267 if (SOC_IS_TD2_TT2(unit)) { 44268 rv = soc_trident2_port_lanes_get(unit, port, value); 44269 } else 44270 #endif /* BCM_TRIDENT2_SUPPORT */ 44271 #ifdef BCM_TRIDENT_SUPPORT 44272 if (SOC_IS_TD_TT(unit)) { 44273 if (!SOC_PORT_VALID(unit, port)) { 44274 return BCM_E_PORT; 44275 } 44276 /* coverity[overrun-local : FALSE] */ 44277 *value = SOC_INFO(unit).port_num_lanes[port]; 44278 rv = BCM_E_NONE; 44279 } else 44280 #endif /* BCM_TRIDENT_SUPPORT */ 44281 #ifdef BCM_SHADOW_SUPPORT 44282 if (SOC_IS_SHADOW(unit)) { 44283 if (!SOC_PORT_VALID(unit, port)) { 44284 return BCM_E_PORT; 44285 } 44286 /* coverity[overrun-local : FALSE] */ 44287 *value = SOC_INFO(unit).port_num_lanes[port]; 44288 rv = BCM_E_NONE; 44289 } else 44290 #endif /* BCM_SHADOW_SUPPORT */ 44291 #ifdef BCM_TRIUMPH3_SUPPORT 44292 if (SOC_IS_TRIUMPH3(unit)) { 44293 rv = _bcm_tr3_port_lanes_get(unit, port, value); 44294 } else 44295 #endif /* BCM_TRIUMPH3_SUPPORT */ 44296 #ifdef BCM_METROLITE_SUPPORT 44297 if (SOC_IS_METROLITE(unit)) { 44298 rv = _bcm_ml_port_lanes_get(unit, port, value); 44299 } else 44300 #endif /* BCM_METROLITE_SUPPORT */ 44301 #ifdef BCM_SABER2_SUPPORT 44302 if (SOC_IS_SABER2(unit)) { 44303 rv = _bcm_sb2_port_lanes_get(unit, port, value); 44304 } else 44305 #endif /* BCM_SABER2_SUPPORT */ 44306 #ifdef BCM_KATANA2_SUPPORT 44307 if (SOC_IS_KATANA2(unit)) { 44308 rv = _bcm_kt2_port_lanes_get(unit, port, value); 44309 } else 44310 #endif /* BCM_KATANA2_SUPPORT */ 44311 { 44312 rv = _bcm_tr2_port_lanes_get(unit, port, value); 44313 } 44314 } 44315 #endif 44316 break; 44317 case bcmPortControlPFCEthertype: 44318 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 44319 if (soc_feature(unit, soc_feature_priority_flow_control)) { 44320 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44321 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 44322 /* IS_GX_PORT == IS_XL_PORT */ 44323 return BCM_E_PORT; 44324 } 44325 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44326 SOC_MAC_CONTROL_PFC_TYPE, value); 44327 } 44328 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 44329 break; 44330 case bcmPortControlPFCOpcode: 44331 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 44332 if (soc_feature(unit, soc_feature_priority_flow_control)) { 44333 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44334 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 44335 /* IS_GX_PORT == IS_XL_PORT */ 44336 return BCM_E_PORT; 44337 } 44338 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44339 SOC_MAC_CONTROL_PFC_OPCODE, value); 44340 } 44341 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 44342 break; 44343 case bcmPortControlPFCReceive: 44344 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 44345 if (soc_feature(unit, soc_feature_priority_flow_control)) { 44346 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44347 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 44348 /* IS_GX_PORT == IS_XL_PORT */ 44349 return BCM_E_PORT; 44350 } 44351 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44352 SOC_MAC_CONTROL_PFC_RX_ENABLE, value); 44353 } 44354 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 44355 break; 44356 case bcmPortControlPFCTransmit: 44357 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 44358 if (soc_feature(unit, soc_feature_priority_flow_control)) { 44359 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44360 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 44361 /* IS_GX_PORT == IS_XL_PORT */ 44362 return BCM_E_PORT; 44363 } 44364 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44365 SOC_MAC_CONTROL_PFC_TX_ENABLE, value); 44366 } 44367 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 44368 break; 44369 case bcmPortControlPFCClasses: 44370 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 44371 if (soc_feature(unit, soc_feature_priority_flow_control)) { 44372 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44373 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 44374 /* IS_GX_PORT == IS_XL_PORT */ 44375 return BCM_E_PORT; 44376 } 44377 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44378 SOC_MAC_CONTROL_PFC_CLASSES, value); 44379 } 44380 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 44381 break; 44382 case bcmPortControlPFCPassFrames: 44383 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 44384 if (soc_feature(unit, soc_feature_priority_flow_control)) { 44385 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44386 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 44387 /* IS_GX_PORT == IS_XL_PORT */ 44388 return BCM_E_PORT; 44389 } 44390 44391 if(soc_feature(unit, soc_feature_pgw_mac_pfc_frame)) { 44392 uint32 rval32 = 0; 44393 soc_reg_t reg = INVALIDr; 44394 if(SOC_REG_IS_VALID(unit, PGW_MAC_RSV_MASKr)) { 44395 reg = PGW_MAC_RSV_MASKr; 44396 } else if(IS_CL_PORT(unit, port) && 44397 SOC_REG_IS_VALID(unit, CLPORT_MAC_RSV_MASKr)) { 44398 reg = CLPORT_MAC_RSV_MASKr; 44399 } else if(IS_XL_PORT(unit, port) && 44400 SOC_REG_IS_VALID(unit, XLPORT_MAC_RSV_MASKr)) { 44401 reg = XLPORT_MAC_RSV_MASKr; 44402 } else { 44403 reg = INVALIDr; 44404 } 44405 44406 if (reg != INVALIDr) { 44407 rv = soc_reg32_get(unit, reg, port, 0, &rval32); 44408 if (BCM_SUCCESS(rv)) { 44409 /* xxx_MAC_RSV_MASK: Bit 18 PFC frame detected 44410 * the bit value needs to be reversed 44411 */ 44412 *value = ((rval32 & 0x40000) >> 18) ? 0 : 1 ; 44413 } 44414 } else { 44415 rv = BCM_E_UNAVAIL; 44416 } 44417 } else { 44418 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44419 SOC_MAC_CONTROL_PFC_RX_PASS, value); 44420 } 44421 } 44422 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 44423 break; 44424 44425 case bcmPortControlPFCDestMacOui: 44426 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 44427 if (soc_feature(unit, soc_feature_priority_flow_control)) { 44428 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44429 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 44430 /* IS_GX_PORT == IS_XL_PORT */ 44431 return BCM_E_PORT; 44432 } 44433 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44434 SOC_MAC_CONTROL_PFC_MAC_DA_OUI, value); 44435 } 44436 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 44437 break; 44438 44439 case bcmPortControlPFCDestMacNonOui: 44440 #if defined(BCM_SCORPION_SUPPORT) || defined(BCM_TRIUMPH2_SUPPORT) 44441 if (soc_feature(unit, soc_feature_priority_flow_control)) { 44442 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44443 if (chk_gx_port && !IS_GX_PORT(unit, port)) { 44444 /* IS_GX_PORT == IS_XL_PORT */ 44445 return BCM_E_PORT; 44446 } 44447 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44448 SOC_MAC_CONTROL_PFC_MAC_DA_NONOUI, value); 44449 } 44450 #endif /* BCM_SCORPION_SUPPORT || BCM_TRIUMPH2_SUPPORT */ 44451 break; 44452 44453 case bcmPortControlPFCRefreshTime: 44454 #if defined(BCM_TRIDENT_SUPPORT)|defined(BCM_GREYHOUND_SUPPORT) 44455 if (soc_feature(unit, soc_feature_priority_flow_control)) { 44456 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44457 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44458 SOC_MAC_CONTROL_PFC_REFRESH_TIME, value); 44459 } 44460 #endif /* BCM_TRIDENT_SUPPORT */ 44461 break; 44462 44463 case bcmPortControlPFCXOffTime: 44464 #if defined(BCM_TRIDENT_SUPPORT)||defined(BCM_GREYHOUND_SUPPORT) 44465 if (soc_feature(unit, soc_feature_priority_flow_control)) { 44466 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 44467 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44468 SOC_MAC_CONTROL_PFC_XOFF_TIME, value); 44469 } 44470 #endif /* BCM_TRIDENT_SUPPORT */ 44471 break; 44472 44473 case bcmPortControlVrf: 44474 rv = _bcm_esw_port_vrf_get(unit, port, value); 44475 break; 44476 44477 case bcmPortControlL3Ingress: 44478 #if defined(BCM_TRIUMPH_SUPPORT) 44479 { 44480 if (!soc_feature(unit, soc_feature_l3_ingress_interface)) { 44481 return BCM_E_UNAVAIL; 44482 } 44483 44484 *value = 0; 44485 if (soc_mem_field_valid(unit, PORT_TABm, PORT_OPERATIONf) || 44486 SOC_IS_TRIDENT3X(unit)) { 44487 rv = _bcm_esw_port_tab_get(unit, port, PORT_OPERATIONf, value); 44488 BCM_IF_ERROR_RETURN(rv); 44489 if ((*value == 0x2) && 44490 (soc_mem_field_valid(unit, SOURCE_TRUNK_MAP_TABLEm, 44491 L3_IIFf)) ) { 44492 #if defined(BCM_KATANA2_SUPPORT) 44493 if (SOC_IS_KATANA2(unit)) { 44494 rv = _bcm_kt2_source_trunk_map_get(unit, port, L3_IIFf, 44495 (uint32 *)value); 44496 } else 44497 #endif 44498 { 44499 rv = _bcm_trx_source_trunk_map_get(unit, port, L3_IIFf, 44500 (uint32 *)value); 44501 } 44502 } 44503 } 44504 } 44505 #endif /* BCM_TRIUMPH_SUPPORT */ 44506 break; 44507 44508 case bcmPortControlL2Learn: 44509 #if defined(BCM_TRX_SUPPORT) 44510 if (SOC_IS_TRX(unit)) { 44511 bcm_port_cfg_t port_cfg; 44512 44513 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg); 44514 if (BCM_SUCCESS(rv)) { 44515 rv = _bcm_trx_port_cml_hw2flags(unit, port_cfg.pc_cml, 44516 (uint32 *)value); 44517 } 44518 } 44519 #endif /* BCM_TRX_SUPPORT */ 44520 break; 44521 44522 case bcmPortControlL2Move: 44523 #if defined(BCM_TRX_SUPPORT) 44524 if (SOC_IS_TRX(unit)) { 44525 bcm_port_cfg_t port_cfg; 44526 44527 rv = mbcm_driver[unit]->mbcm_port_cfg_get(unit, port, &port_cfg); 44528 if (BCM_SUCCESS(rv)) { 44529 rv = _bcm_trx_port_cml_hw2flags(unit, port_cfg.pc_cml_move, 44530 (uint32 *)value); 44531 } 44532 } 44533 #endif /* BCM_TRX_SUPPORT */ 44534 break; 44535 44536 case bcmPortControlForwardStaticL2MovePkt: 44537 #if defined(BCM_TRX_SUPPORT) 44538 rv = _bcm_esw_port_tab_get(unit, port, DISABLE_STATIC_MOVE_DROPf, 44539 value); 44540 #endif /* BCM_TRX_SUPPORT */ 44541 break; 44542 44543 case bcmPortControlPrbsRxStatus: 44544 PORT_LOCK(unit); 44545 rv = soc_phyctrl_control_get(unit, port, 44546 SOC_PHY_CONTROL_PRBS_RX_STATUS, 44547 (uint32 *)value); 44548 PORT_UNLOCK(unit); 44549 break; 44550 case bcmPortControlLinkFaultLocalEnable: 44551 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44552 SOC_MAC_CONTROL_FAULT_LOCAL_ENABLE, value); 44553 break; 44554 case bcmPortControlLinkFaultRemoteEnable: 44555 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44556 SOC_MAC_CONTROL_FAULT_REMOTE_ENABLE, value); 44557 break; 44558 case bcmPortControlLinkFaultLocal: 44559 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44560 SOC_MAC_CONTROL_FAULT_LOCAL_STATUS, value); 44561 break; 44562 case bcmPortControlLinkFaultRemote: 44563 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44564 SOC_MAC_CONTROL_FAULT_REMOTE_STATUS, value); 44565 break; 44566 case bcmPortControlTimestampTransmit: 44567 #if defined(BCM_TIMESYNC_SUPPORT) 44568 if (soc_feature(unit, soc_feature_timesync_support)) { 44569 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44570 SOC_MAC_CONTROL_TIMESTAMP_TRANSMIT, value); 44571 } else 44572 #endif /* BCM_TIMESYNC_SUPPORT */ 44573 { 44574 return BCM_E_UNAVAIL; 44575 } 44576 break; 44577 case bcmPortControlTimestampEnable: 44578 #if defined(BCM_HAWKEYE_SUPPORT) 44579 if (SOC_IS_HAWKEYE(unit)) { 44580 uint32 rval; 44581 if (!SOC_PORT_VALID(unit, port)) { 44582 return BCM_E_PORT; 44583 } 44584 SOC_IF_ERROR_RETURN(READ_EAV_ENABLE_BMAPr(unit, &rval)); 44585 if ( port < 32 ) { 44586 *value = (rval & (1 << port)) ? TRUE:FALSE; 44587 } else { 44588 *value = FALSE; 44589 } 44590 rv = BCM_E_NONE; 44591 } else 44592 #endif /* BCM_HAWKEYE_SUPPORT */ 44593 if (soc_feature (unit, soc_feature_xlmac_timestamp_disable)) { 44594 if (IS_XL_PORT(unit, port)) { 44595 int tmp; 44596 uint32 rval; 44597 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, 44598 port, &rval)); 44599 tmp = soc_reg_field_get(unit, XLPORT_MAC_CONTROLr, 44600 rval, XLMAC_TS_DISABLEf); 44601 if (tmp) { 44602 *value = FALSE; 44603 } else { 44604 *value = TRUE; 44605 } 44606 rv = BCM_E_NONE; 44607 } 44608 } 44609 break; 44610 case bcmPortControlSerdesDriverEqualizationTuneStatusFarEnd: 44611 PORT_LOCK(unit); 44612 rv = soc_phyctrl_control_get(unit, port, 44613 SOC_PHY_CONTROL_SERDES_DRIVER_EQUALIZATION_TUNE_STATUS_FAR_END, 44614 (uint32 *)value); 44615 PORT_UNLOCK(unit); 44616 break; 44617 case bcmPortControlLinkdownTransmit: 44618 PORT_LOCK(unit); 44619 rv = soc_phyctrl_control_get(unit, port, 44620 SOC_PHY_CONTROL_LINKDOWN_TRANSMIT, 44621 (uint32 *)value); 44622 PORT_UNLOCK(unit); 44623 /* Most of PHYs have nothing to configure and simply return UNAVAIL*/ 44624 if ((rv == SOC_E_NONE) || (rv == SOC_E_UNAVAIL)) { 44625 rv = _bcm_esw_link_down_tx_get(unit, port, value); 44626 } 44627 break; 44628 case bcmPortControlSerdesTuneMarginMode: 44629 PORT_LOCK(unit); 44630 rv = soc_phyctrl_control_get(unit, port, 44631 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_MODE, 44632 (uint32 *)value); 44633 PORT_UNLOCK(unit); 44634 break; 44635 case bcmPortControlSerdesTuneMarginValue: 44636 PORT_LOCK(unit); 44637 rv = soc_phyctrl_control_get(unit, port, 44638 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_VALUE, 44639 (uint32 *)value); 44640 PORT_UNLOCK(unit); 44641 break; 44642 case bcmPortControlSerdesTuneMarginMax: 44643 PORT_LOCK(unit); 44644 rv = soc_phyctrl_control_get(unit, port, 44645 SOC_PHY_CONTROL_SERDES_TUNE_MARGIN_MAX, 44646 (uint32 *)value); 44647 PORT_UNLOCK(unit); 44648 break; 44649 case bcmPortControlStatOversize: 44650 rv = _bcm_esw_stat_ovr_threshold_get(unit, port, value); 44651 break; 44652 44653 case bcmPortControlStatOversizeIsError: 44654 rv = _bcm_esw_stat_ovr_error_control_get(unit, port, value); 44655 break; 44656 44657 case bcmPortControlEEEEnable: 44658 if (!SOC_PORT_VALID(unit, port)) { 44659 return BCM_E_PORT; 44660 } 44661 44662 PORT_LOCK(unit); 44663 44664 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 44665 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 44666 || defined(BCM_HURRICANE2_SUPPORT) 44667 44668 if (soc_feature(unit, soc_feature_eee)) { 44669 *value = eee_cfg[unit][port]; 44670 rv = BCM_E_NONE; 44671 } else 44672 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPORT || 44673 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 44674 44675 { 44676 uint32 eeenative, eeeauto; 44677 int rv1 = BCM_E_UNAVAIL, rv2 = BCM_E_UNAVAIL; 44678 44679 rv = BCM_E_NONE; 44680 44681 if ((rv1 = soc_phyctrl_control_get(unit, port, 44682 BCM_PORT_PHY_CONTROL_EEE, &eeenative)) != 44683 SOC_E_UNAVAIL) { 44684 *value = eeenative; 44685 } 44686 44687 if ((rv2 = soc_phyctrl_control_get(unit, port, 44688 BCM_PORT_PHY_CONTROL_EEE_AUTO, &eeeauto)) != 44689 SOC_E_UNAVAIL) { 44690 *value = eeeauto; 44691 } 44692 44693 /* If neither Native EEE nor AutoGrEEEn mode is supported */ 44694 if ((rv1 == SOC_E_UNAVAIL) && (rv2 == SOC_E_UNAVAIL)) { 44695 rv = BCM_E_UNAVAIL; 44696 } 44697 44698 /* If both Native EEE and AutoGrEEEn mode are supported */ 44699 if ((rv1 != SOC_E_UNAVAIL) && (rv2 != SOC_E_UNAVAIL)) { 44700 *value = eeenative ? (eeeauto ? 0 : 1) : (eeeauto ? 1 : 0); 44701 } 44702 } 44703 44704 PORT_UNLOCK (unit); 44705 44706 break; 44707 44708 /********************** EEE Mode Overview ************************ 44709 * |DET| | WT | 44710 * Signalling |idles| |------------------------------| | idles | 44711 * from Tx MAC | or | | Low Power Idle (LPI) |idles| or | 44712 * to local PHY |data | |------------------------------| | data | 44713 * * * 44714 * * * 44715 * * -------LPI state------------* 44716 * Local PHY | | | | | | | | | | 44717 * signaling | Active|Ts| Tq |Tr| Tq |Tr| Tq |Tw |Active | 44718 * on MDI | | | | | | | | | | 44719 * *------------------------------* 44720 * * * 44721 * * * 44722 * Signaling | idles |-------------------------------|id| PHY is | 44723 * from LP PHY | or | Low Power Idle (LPI) |le| ready | 44724 * to Rx MAC | data |-------------------------------|s | for data | 44725 * 44726 * where DET = Delay Entry Timer WT = MAC Wake Timer 44727 */ 44728 case bcmPortControlEEETransmitIdleTime: 44729 /* DET = Time (in microsecs) for which condition to move to LPI state 44730 * is satisfied, at the end of which MAC TX transitions to LPI state */ 44731 if (!SOC_PORT_VALID(unit, port)) { 44732 return BCM_E_PORT; 44733 } 44734 44735 PORT_LOCK(unit); 44736 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 44737 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 44738 || defined(BCM_HURRICANE2_SUPPORT) 44739 if (soc_feature (unit, soc_feature_eee)) { 44740 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44741 SOC_MAC_CONTROL_EEE_TX_IDLE_TIME, value); 44742 } else 44743 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 44744 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 44745 { 44746 rv = BCM_E_UNAVAIL; 44747 } 44748 PORT_UNLOCK(unit); 44749 break; 44750 44751 case bcmPortControlEEETransmitEventCount: 44752 /* Number of time MAC TX enters LPI state for 44753 * a given measurement interval*/ 44754 if (!SOC_PORT_VALID(unit, port)) { 44755 return BCM_E_PORT; 44756 } 44757 44758 PORT_LOCK(unit); 44759 44760 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 44761 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 44762 || defined(BCM_HURRICANE2_SUPPORT) 44763 if (soc_feature(unit, soc_feature_eee)) { 44764 int mac_val; 44765 uint32 phy_val; 44766 uint64 rval64, rval64_2nd; 44767 soc_reg_t reg, reg_2nd = INVALIDr; 44768 44769 COMPILER_64_ZERO(rval64); 44770 COMPILER_64_ZERO(rval64_2nd); 44771 44772 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44773 SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) && 44774 (soc_phyctrl_control_get(unit, port, 44775 BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) { 44776 /* If MAC/Switch is EEE aware (Native EEE mode is supported) 44777 * and PHY also supports Native mode 44778 */ 44779 44780 /* On Katana TX/RX register are swapped */ 44781 reg = (SOC_IS_KATANAX(unit)) ? RX_EEE_LPI_EVENT_COUNTERr : 44782 ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ? 44783 GTX_EEE_LPI_EVENT_COUNTERr : 44784 TX_EEE_LPI_EVENT_COUNTERr); 44785 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) { 44786 if (IS_XL_PORT(unit, port)){ 44787 reg = TX_EEE_LPI_EVENT_COUNTERr; 44788 } else { 44789 reg = GTX_EEE_LPI_EVENT_COUNTERr; 44790 } 44791 } else if (SOC_IS_GREYHOUND2(unit)) { 44792 if (IS_CL_PORT(unit, port)){ 44793 reg = CLMIB_TX_EEE_LPI_EVENT_COUNTERr; 44794 } else if (IS_XL_PORT(unit, port)) { 44795 reg = XLMIB_TX_EEE_LPI_EVENT_COUNTERr; 44796 reg_2nd = XLPMIB_TX_EEE_LPI_EVENT_COUNTERr; 44797 } else { 44798 reg = GTX_EEE_LPI_EVENT_COUNTERr; 44799 } 44800 } 44801 44802 rv = soc_reg_get(unit, reg, port, 0, &rval64); 44803 44804 if (BCM_SUCCESS(rv)) { 44805 *value = COMPILER_64_LO(rval64); 44806 } 44807 44808 if (SOC_REG_IS_VALID(unit, reg_2nd)) { 44809 rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd); 44810 44811 if (BCM_SUCCESS(rv)) { 44812 *value += COMPILER_64_LO(rval64_2nd); 44813 } 44814 } 44815 } else { 44816 /* Get counter value from PHY. If PHY does not support 44817 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 44818 */ 44819 rv = soc_phyctrl_control_get(unit, port, 44820 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_EVENTS, &phy_val); 44821 if (SOC_SUCCESS(rv)) { 44822 *value = phy_val; 44823 } 44824 } 44825 } else 44826 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 44827 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 44828 44829 { 44830 /* On legacy devices that don't support native EEE, 44831 * get counter value from PHY. If PHY does not support 44832 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 44833 */ 44834 uint32 phy_val; 44835 rv = soc_phyctrl_control_get(unit, port, 44836 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_EVENTS, &phy_val); 44837 if (SOC_SUCCESS(rv)) { 44838 *value = phy_val; 44839 } 44840 } 44841 44842 PORT_UNLOCK (unit); 44843 44844 break; 44845 44846 case bcmPortControlEEETransmitDuration: 44847 /* Time in (microsecs) for which MAC TX enters LPI state 44848 * during a measurement interval*/ 44849 if (!SOC_PORT_VALID(unit, port)) { 44850 return BCM_E_PORT; 44851 } 44852 44853 PORT_LOCK(unit); 44854 44855 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 44856 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 44857 || defined(BCM_HURRICANE2_SUPPORT) 44858 if (soc_feature(unit, soc_feature_eee)) { 44859 int mac_val; 44860 uint32 phy_val; 44861 uint64 rval64, rval64_2nd; 44862 soc_reg_t reg, reg_2nd = INVALIDr; 44863 44864 COMPILER_64_ZERO(rval64); 44865 COMPILER_64_ZERO(rval64_2nd); 44866 44867 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44868 SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) && 44869 (soc_phyctrl_control_get(unit, port, 44870 BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) { 44871 /* If MAC/Switch is EEE aware (Native EEE mode is supported) 44872 * and PHY also supports Native mode 44873 */ 44874 /* On Katana TX/RX register are swapped */ 44875 reg = (SOC_IS_KATANAX(unit)) ? RX_EEE_LPI_DURATION_COUNTERr : 44876 ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ? 44877 GTX_EEE_LPI_DURATION_COUNTERr : 44878 TX_EEE_LPI_DURATION_COUNTERr); 44879 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) { 44880 if (IS_XL_PORT(unit, port)) { 44881 reg = TX_EEE_LPI_DURATION_COUNTERr; 44882 } else { 44883 reg = GTX_EEE_LPI_DURATION_COUNTERr; 44884 } 44885 } else if (SOC_IS_GREYHOUND2(unit)) { 44886 if (IS_CL_PORT(unit, port)){ 44887 reg = CLMIB_TX_EEE_LPI_DURATION_COUNTERr; 44888 } else if (IS_XL_PORT(unit, port)) { 44889 reg = XLMIB_TX_EEE_LPI_DURATION_COUNTERr; 44890 reg_2nd = XLPMIB_TX_EEE_LPI_DURATION_COUNTERr; 44891 } else { 44892 reg = GTX_EEE_LPI_DURATION_COUNTERr; 44893 } 44894 } 44895 44896 rv = soc_reg_get(unit, reg, port, 0, &rval64); 44897 44898 if (BCM_SUCCESS(rv)) { 44899 *value = COMPILER_64_LO(rval64); 44900 } 44901 44902 if (SOC_REG_IS_VALID(unit, reg_2nd)) { 44903 rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd); 44904 if (BCM_SUCCESS(rv)) { 44905 /* add the 2nd register */ 44906 *value += COMPILER_64_LO(rval64_2nd); 44907 } 44908 } 44909 } else { 44910 /* Get counter value from PHY. If PHY does not support 44911 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 44912 */ 44913 rv = soc_phyctrl_control_get(unit, port, 44914 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_DURATION, &phy_val); 44915 if (SOC_SUCCESS(rv)) { 44916 *value = phy_val; 44917 } 44918 } 44919 } else 44920 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 44921 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 44922 { 44923 /* On legacy devices that don't support native EEE, 44924 * get counter value from PHY. If PHY does not support 44925 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 44926 */ 44927 uint32 phy_val; 44928 rv = soc_phyctrl_control_get(unit, port, 44929 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_DURATION, &phy_val); 44930 if (SOC_SUCCESS(rv)) { 44931 *value = phy_val; 44932 } 44933 } 44934 44935 PORT_UNLOCK (unit); 44936 break; 44937 44938 case bcmPortControlEEEReceiveEventCount: 44939 /* Number of time MAC RX enters LPI state for 44940 * a given measurement interval */ 44941 if (!SOC_PORT_VALID(unit, port)) { 44942 return BCM_E_PORT; 44943 } 44944 44945 PORT_LOCK(unit); 44946 44947 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 44948 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_SHADOW_SUPPORT) \ 44949 || defined(BCM_HURRICANE2_SUPPORT) 44950 if (soc_feature(unit, soc_feature_eee)) { 44951 int mac_val; 44952 uint32 phy_val; 44953 uint64 rval64, rval64_2nd; 44954 soc_reg_t reg, reg_2nd = INVALIDr; 44955 44956 COMPILER_64_ZERO(rval64); 44957 COMPILER_64_ZERO(rval64_2nd); 44958 44959 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 44960 SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) && 44961 (soc_phyctrl_control_get(unit, port, 44962 BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) { 44963 /* If MAC/Switch is EEE aware (Native EEE mode is supported) 44964 * and PHY also supports Native mode 44965 */ 44966 /* On Katana TX/RX register are swapped */ 44967 reg = (SOC_IS_KATANAX(unit)) ? TX_EEE_LPI_EVENT_COUNTERr : 44968 ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ? 44969 GRX_EEE_LPI_EVENT_COUNTERr : 44970 RX_EEE_LPI_EVENT_COUNTERr); 44971 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) { 44972 if (IS_XL_PORT(unit, port)) { 44973 reg = RX_EEE_LPI_EVENT_COUNTERr; 44974 } else { 44975 reg = GRX_EEE_LPI_EVENT_COUNTERr; 44976 } 44977 } else if (SOC_IS_GREYHOUND2(unit)) { 44978 if (IS_CL_PORT(unit, port)){ 44979 reg = CLMIB_RX_EEE_LPI_EVENT_COUNTERr; 44980 } else if (IS_XL_PORT(unit, port)) { 44981 reg = XLMIB_RX_EEE_LPI_EVENT_COUNTERr; 44982 reg_2nd = XLPMIB_RX_EEE_LPI_EVENT_COUNTERr; 44983 } else { 44984 reg = GRX_EEE_LPI_EVENT_COUNTERr; 44985 } 44986 } 44987 44988 rv = soc_reg_get(unit, reg, port, 0, &rval64); 44989 44990 if (BCM_SUCCESS(rv)) { 44991 *value = COMPILER_64_LO(rval64); 44992 } 44993 44994 if (SOC_REG_IS_VALID(unit, reg_2nd)) { 44995 rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd); 44996 if (BCM_SUCCESS(rv)) { 44997 /* add the 2nd register */ 44998 *value += COMPILER_64_LO(rval64_2nd); 44999 } 45000 } 45001 } else { 45002 /* Get counter value from PHY. If PHY does not support 45003 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 45004 */ 45005 rv = soc_phyctrl_control_get(unit, port, 45006 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_EVENTS, &phy_val); 45007 if (SOC_SUCCESS(rv)) { 45008 *value = phy_val; 45009 } 45010 } 45011 } else 45012 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 45013 BCM_TRIDENT_SUPPORT || BCM_SHADOW_SUPPORT */ 45014 { 45015 /* On legacy devices that don't support native EEE, 45016 * get counter value from PHY. If PHY does not support 45017 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 45018 */ 45019 uint32 phy_val; 45020 rv = soc_phyctrl_control_get(unit, port, 45021 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_EVENTS, &phy_val); 45022 if (SOC_SUCCESS(rv)) { 45023 *value = phy_val; 45024 } 45025 } 45026 45027 PORT_UNLOCK (unit); 45028 break; 45029 45030 case bcmPortControlEEEReceiveDuration: 45031 /* Time in (microsecs) for which MAC RX enters LPI state 45032 * during a measurement interval*/ 45033 if (!SOC_PORT_VALID(unit, port)) { 45034 return BCM_E_PORT; 45035 } 45036 if (!IS_E_PORT(unit, port)) { 45037 return BCM_E_UNAVAIL; 45038 } 45039 45040 PORT_LOCK(unit); 45041 45042 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 45043 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 45044 if (soc_feature(unit, soc_feature_eee)) { 45045 int mac_val; 45046 uint32 phy_val; 45047 uint64 rval64, rval64_2nd; 45048 soc_reg_t reg, reg_2nd = INVALIDr; 45049 45050 COMPILER_64_ZERO(rval64); 45051 COMPILER_64_ZERO(rval64_2nd); 45052 45053 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45054 SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) && 45055 (soc_phyctrl_control_get(unit, port, 45056 BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) { 45057 /* If MAC/Switch is EEE aware (Native EEE mode is supported) 45058 * and PHY also supports Native mode 45059 */ 45060 /* On Katana TX/RX register are swapped */ 45061 reg = (SOC_IS_KATANAX(unit)) ? TX_EEE_LPI_DURATION_COUNTERr : 45062 ((SOC_IS_HURRICANE2(unit) && IS_GE_PORT(unit, port)) ? 45063 GRX_EEE_LPI_DURATION_COUNTERr : 45064 RX_EEE_LPI_DURATION_COUNTERr); 45065 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) { 45066 if (IS_XL_PORT(unit, port)) { 45067 reg = RX_EEE_LPI_DURATION_COUNTERr; 45068 } else { 45069 reg = GRX_EEE_LPI_DURATION_COUNTERr; 45070 } 45071 } else if (SOC_IS_GREYHOUND2(unit)) { 45072 if (IS_CL_PORT(unit, port)){ 45073 reg = CLMIB_RX_EEE_LPI_DURATION_COUNTERr; 45074 } else if (IS_XL_PORT(unit, port)) { 45075 reg = XLMIB_RX_EEE_LPI_DURATION_COUNTERr; 45076 reg_2nd = XLPMIB_RX_EEE_LPI_DURATION_COUNTERr; 45077 } else { 45078 reg = GRX_EEE_LPI_DURATION_COUNTERr; 45079 } 45080 } 45081 45082 rv = soc_reg_get(unit, reg, port, 0, &rval64); 45083 45084 if (BCM_SUCCESS(rv)) { 45085 *value = COMPILER_64_LO(rval64); 45086 } 45087 45088 if (SOC_REG_IS_VALID(unit, reg_2nd)) { 45089 rv = soc_reg_get(unit, reg_2nd, port, 0, &rval64_2nd); 45090 if (BCM_SUCCESS(rv)) { 45091 /* add the 2nd register */ 45092 *value += COMPILER_64_LO(rval64_2nd); 45093 } 45094 } 45095 } else { 45096 /* Get counter value from PHY. If PHY does not support 45097 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 45098 */ 45099 rv = soc_phyctrl_control_get(unit, port, 45100 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_DURATION, &phy_val); 45101 if (SOC_SUCCESS(rv)) { 45102 *value = phy_val; 45103 } 45104 } 45105 } else 45106 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 45107 BCM_TRIDENT_SUPPORT */ 45108 { 45109 /* On legacy devices that don't support native EEE, 45110 * get counter value from PHY. If PHY does not support 45111 * EEE counters, rv will be assigned SOC_E_UNAVAIL. 45112 */ 45113 uint32 phy_val; 45114 rv = soc_phyctrl_control_get(unit, port, 45115 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_DURATION, &phy_val); 45116 if (SOC_SUCCESS(rv)) { 45117 *value = phy_val; 45118 } 45119 } 45120 45121 PORT_UNLOCK (unit); 45122 break; 45123 45124 case bcmPortControlEEETransmitRefreshTime: 45125 if (!SOC_PORT_VALID(unit, port)) { 45126 return BCM_E_PORT; 45127 } 45128 if (!IS_E_PORT(unit, port)) { 45129 return BCM_E_UNAVAIL; 45130 } 45131 PORT_LOCK(unit); 45132 rv = soc_phyctrl_control_get(unit, port, 45133 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_REFRESH_TIME, 45134 (uint32 *)value); 45135 PORT_UNLOCK (unit); 45136 break; 45137 45138 case bcmPortControlEEETransmitSleepTime: 45139 if (!SOC_PORT_VALID(unit, port)) { 45140 return BCM_E_PORT; 45141 } 45142 if (!IS_E_PORT(unit, port)) { 45143 return BCM_E_UNAVAIL; 45144 } 45145 PORT_LOCK(unit); 45146 rv = soc_phyctrl_control_get(unit, port, 45147 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_SLEEP_TIME, (uint32 *)value); 45148 PORT_UNLOCK (unit); 45149 break; 45150 45151 case bcmPortControlEEETransmitQuietTime: 45152 if (!SOC_PORT_VALID(unit, port)) { 45153 return BCM_E_PORT; 45154 } 45155 if (!IS_E_PORT(unit, port)) { 45156 return BCM_E_UNAVAIL; 45157 } 45158 PORT_LOCK(unit); 45159 rv = soc_phyctrl_control_get(unit, port, 45160 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_QUIET_TIME, (uint32 *)value); 45161 PORT_UNLOCK (unit); 45162 break; 45163 45164 case bcmPortControlEEETransmitWakeTime: 45165 /* Time(in microsecs) to wait before transmitter can leave LPI State*/ 45166 if (!SOC_PORT_VALID(unit, port)) { 45167 return BCM_E_PORT; 45168 } 45169 if (!IS_E_PORT(unit, port)) { 45170 return BCM_E_UNAVAIL; 45171 } 45172 45173 PORT_LOCK(unit); 45174 45175 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_HAWKEYE_SUPPORT) \ 45176 || defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE2_SUPPORT) 45177 if (soc_feature(unit, soc_feature_eee)) { 45178 int mac_val; 45179 uint32 phy_val; 45180 45181 if ((MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45182 SOC_MAC_CONTROL_EEE_ENABLE, &mac_val) != SOC_E_UNAVAIL) && 45183 (soc_phyctrl_control_get(unit, port, 45184 BCM_PORT_PHY_CONTROL_EEE, &phy_val) != SOC_E_UNAVAIL)) { 45185 /* If MAC/Switch is EEE aware (Native EEE mode is supported) 45186 * and PHY also supports Native mode 45187 */ 45188 rv = MAC_CONTROL_GET(PORT(unit, port).p_mac, unit, port, 45189 SOC_MAC_CONTROL_EEE_TX_WAKE_TIME, value); 45190 45191 } else { 45192 /* Get timer value from PHY. If PHY does not support 45193 * EEE timers, rv will be assigned SOC_E_UNAVAIL. 45194 */ 45195 rv = soc_phyctrl_control_get(unit, port, 45196 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_WAKE_TIME, &phy_val); 45197 if (SOC_SUCCESS(rv)) { 45198 *value = phy_val; 45199 } 45200 } 45201 } else 45202 #endif /* BCM_HURRICANE_SUPPORT || BCM_HAWKEYE_SUPPORT || 45203 BCM_TRIDENT_SUPPORT */ 45204 { 45205 /* On legacy devices that don't support native EEE, 45206 * get timer value from PHY. If PHY does not support 45207 * EEE timers, rv will be assigned SOC_E_UNAVAIL. 45208 */ 45209 uint32 phy_val; 45210 rv = soc_phyctrl_control_get(unit, port, 45211 BCM_PORT_PHY_CONTROL_EEE_TRANSMIT_WAKE_TIME, &phy_val); 45212 if (SOC_SUCCESS(rv)) { 45213 *value = phy_val; 45214 } 45215 } 45216 45217 PORT_UNLOCK (unit); 45218 break; 45219 45220 case bcmPortControlEEEReceiveSleepTime: 45221 if (!SOC_PORT_VALID(unit, port)) { 45222 return BCM_E_PORT; 45223 } 45224 if (!IS_E_PORT(unit, port)) { 45225 return BCM_E_UNAVAIL; 45226 } 45227 PORT_LOCK(unit); 45228 rv = soc_phyctrl_control_get(unit, port, 45229 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_SLEEP_TIME, (uint32 *)value); 45230 PORT_UNLOCK (unit); 45231 break; 45232 45233 case bcmPortControlEEEReceiveQuietTime: 45234 if (!SOC_PORT_VALID(unit, port)) { 45235 return BCM_E_PORT; 45236 } 45237 if (!IS_E_PORT(unit, port)) { 45238 return BCM_E_UNAVAIL; 45239 } 45240 PORT_LOCK(unit); 45241 rv = soc_phyctrl_control_get(unit, port, 45242 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_QUIET_TIME, (uint32 *)value); 45243 PORT_UNLOCK (unit); 45244 break; 45245 45246 case bcmPortControlEEEReceiveWakeTime: 45247 if (!SOC_PORT_VALID(unit, port)) { 45248 return BCM_E_PORT; 45249 } 45250 if (!IS_E_PORT(unit, port)) { 45251 return BCM_E_UNAVAIL; 45252 } 45253 PORT_LOCK(unit); 45254 rv = soc_phyctrl_control_get(unit, port, 45255 BCM_PORT_PHY_CONTROL_EEE_RECEIVE_WAKE_TIME, (uint32 *)value); 45256 PORT_UNLOCK (unit); 45257 break; 45258 45259 case bcmPortControlEEEEventCountSymmetric: 45260 if (!SOC_PORT_VALID(unit, port)) { 45261 return BCM_E_PORT; 45262 } 45263 if (!IS_E_PORT(unit, port)) { 45264 return BCM_E_UNAVAIL; 45265 } 45266 #if defined(BCM_HURRICANE2_SUPPORT) 45267 if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || 45268 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 45269 uint32 reg_value; 45270 soc_reg_t reg; 45271 if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) { 45272 reg = IS_XL_PORT(unit, port) ? XLPORT_EEE_COUNTER_MODEr : 45273 CLPORT_EEE_COUNTER_MODEr; 45274 45275 if (SOC_REG_FIELD_VALID(unit, reg, MODE_BITf)) { 45276 rv = soc_reg32_get(unit, reg, port, 0, ®_value); 45277 if (SOC_SUCCESS(rv)) { 45278 *value = soc_reg_field_get(unit, reg, 45279 reg_value, MODE_BITf); 45280 } 45281 } else { 45282 return BCM_E_INTERNAL; 45283 } 45284 } else { 45285 return BCM_E_PORT; 45286 } 45287 } else 45288 #endif 45289 { 45290 #if defined(BCM_TRIUMPH3_SUPPORT) 45291 if (SOC_REG_FIELD_VALID(unit, PORT_EEE_COUNTER_MODEr, MODE_BITf)) { 45292 uint32 reg_value; 45293 45294 rv = READ_PORT_EEE_COUNTER_MODEr(unit, port, ®_value); 45295 45296 if (SOC_SUCCESS(rv)) { 45297 *value = soc_reg_field_get(unit, PORT_EEE_COUNTER_MODEr, 45298 reg_value, MODE_BITf); 45299 } 45300 } 45301 #endif 45302 } 45303 break; 45304 45305 case bcmPortControlEEELinkActiveDuration: 45306 if (!SOC_PORT_VALID(unit, port)) { 45307 return BCM_E_PORT; 45308 } 45309 if (!IS_E_PORT(unit, port)) { 45310 return BCM_E_UNAVAIL; 45311 } 45312 #if defined(BCM_HURRICANE2_SUPPORT) 45313 if (SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND(unit) || 45314 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 45315 soc_reg_t reg; 45316 45317 if (IS_XL_PORT(unit, port) || IS_CL_PORT(unit, port)) { 45318 45319 reg = IS_XL_PORT(unit, port) ? 45320 XLMAC_EEE_1_SEC_LINK_STATUS_TIMERr : 45321 CLMAC_EEE_1_SEC_LINK_STATUS_TIMERr; 45322 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) { 45323 uint64 reg_value; 45324 45325 rv = soc_reg_get(unit, reg, port, 0, ®_value); 45326 if (SOC_SUCCESS(rv)) { 45327 *value = soc_reg64_field32_get(unit, 45328 reg, reg_value, 45329 ONE_SECOND_TIMERf); 45330 } 45331 } 45332 } else { 45333 return BCM_E_PORT; 45334 } 45335 } else 45336 #endif 45337 { 45338 #if defined(BCM_TRIUMPH3_SUPPORT) 45339 { 45340 soc_reg_t reg; 45341 45342 reg = IS_C_PORT(unit, port) ? 45343 CMAC_EEE_1_SEC_LINK_STATUS_TIMERr : 45344 XMAC_EEE_1_SEC_LINK_STATUS_TIMERr; 45345 if (SOC_REG_FIELD_VALID(unit, reg, ONE_SECOND_TIMERf)) { 45346 uint64 reg_value; 45347 45348 rv = soc_reg_get(unit, reg, port, 0, ®_value); 45349 if (SOC_SUCCESS(rv)) { 45350 *value = soc_reg64_field32_get(unit, reg, reg_value, 45351 ONE_SECOND_TIMERf); 45352 } 45353 } 45354 } 45355 #endif 45356 } 45357 break; 45358 45359 case bcmPortControlRemoteCpuTcMapping: 45360 if (soc_feature(unit, soc_feature_rcpu_tc_mapping)) { 45361 rv = _bcm_esw_port_tab_get(unit, port, REMOTE_CPU_ENf, value); 45362 } else { 45363 rv = BCM_E_UNAVAIL; 45364 } 45365 break; 45366 45367 case bcmPortControlTrill: 45368 #if defined(BCM_TRIDENT_SUPPORT) 45369 if (soc_feature(unit, soc_feature_trill)) { 45370 rv = _bcm_esw_port_tab_get(unit, port, TRILL_ENABLEf, value); 45371 } 45372 #endif /* BCM_TRIDENT_SUPPORT */ 45373 break; 45374 45375 case bcmPortControlTrillAllow: 45376 #if defined(BCM_TRIDENT_SUPPORT) 45377 if (soc_feature(unit, soc_feature_trill)) { 45378 rv = _bcm_esw_port_tab_get(unit, port, 45379 ALLOW_TRILL_FRAMESf, value); 45380 } 45381 #endif /* BCM_TRIDENT_SUPPORT */ 45382 break; 45383 45384 case bcmPortControlNonTrillAllow: 45385 #if defined(BCM_TRIDENT_SUPPORT) 45386 if (soc_feature(unit, soc_feature_trill)) { 45387 rv = _bcm_esw_port_tab_get(unit, port, 45388 ALLOW_NON_TRILL_FRAMESf, value); 45389 } 45390 #endif /* BCM_TRIDENT_SUPPORT */ 45391 break; 45392 45393 case bcmPortControlTrillCoreISISToCPU: 45394 #if defined(BCM_TRIDENT_SUPPORT) 45395 if (soc_feature(unit, soc_feature_trill)) { 45396 rv = _bcm_esw_port_tab_get(unit, port, 45397 COPY_CORE_IS_IS_TO_CPUf, value); 45398 } 45399 #endif /* BCM_TRIDENT_SUPPORT */ 45400 break; 45401 45402 case bcmPortControlTrillHashSelect: 45403 #if defined(BCM_TRIDENT_SUPPORT) 45404 if (soc_feature(unit, soc_feature_trill)) { 45405 rv = _bcm_esw_port_tab_get(unit, port, 45406 RTAG7_HASH_CFG_SEL_TRILL_ECMPf, value); 45407 } 45408 #endif /* BCM_TRIDENT_SUPPORT */ 45409 break; 45410 45411 case bcmPortControlNivAccessVirtualInterfaceId: 45412 case bcmPortControlExtendedPortVid: 45413 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45414 if (soc_feature(unit, soc_feature_niv) || 45415 soc_feature(unit, soc_feature_port_extension)) { 45416 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 45417 SOC_IS_GREYHOUND2(unit)) { 45418 uint64 val64; 45419 rv = READ_EGR_PORT_64r(unit, port, &val64); 45420 if (BCM_SUCCESS(rv)) { 45421 *value = soc_reg64_field32_get(unit, EGR_PORT_64r, 45422 val64, NIV_VIF_IDf); 45423 } 45424 } else { 45425 rv = _bcm_esw_port_tab_get(unit, port, NIV_VIF_IDf, value); 45426 } 45427 } 45428 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45429 break; 45430 45431 case bcmPortControlNivNonVntagDrop: 45432 case bcmPortControlNonEtagDrop: 45433 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45434 if (soc_feature(unit, soc_feature_niv) || 45435 soc_feature(unit, soc_feature_port_extension)) { 45436 rv = _bcm_esw_port_tab_get(unit, port, 45437 DISCARD_IF_VNTAG_NOT_PRESENTf, value); 45438 } 45439 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45440 break; 45441 45442 case bcmPortControlNivVntagDrop: 45443 case bcmPortControlEtagDrop: 45444 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45445 if (soc_feature(unit, soc_feature_niv) || 45446 soc_feature(unit, soc_feature_port_extension)) { 45447 rv = _bcm_esw_port_tab_get(unit, port, 45448 DISCARD_IF_VNTAG_PRESENTf, value); 45449 } 45450 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45451 break; 45452 45453 case bcmPortControlSubportPktTagDrop: 45454 #if defined(BCM_KATANA2_SUPPORT) 45455 if (soc_feature(unit, soc_feature_lltag)) { 45456 rv = _bcm_esw_port_tab_get(unit, port, 45457 DISCARD_IF_LLTAG_PRESENTf, value); 45458 } 45459 #endif /* BCM_KATANA2_SUPPORT */ 45460 break; 45461 45462 case bcmPortControlNoSubportPktTagDrop: 45463 #if defined(BCM_KATANA2_SUPPORT) 45464 if (soc_feature(unit, soc_feature_lltag)) { 45465 rv = _bcm_esw_port_tab_get(unit, port, 45466 DISCARD_IF_LLTAG_NOT_PRESENTf, value); 45467 } 45468 #endif /* BCM_KATANA2_SUPPORT */ 45469 break; 45470 45471 case bcmPortControlNivNonVntagAdd: 45472 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45473 if (soc_feature(unit, soc_feature_niv)) { 45474 int vntag_action; 45475 rv = _bcm_esw_port_tab_get(unit, port, 45476 VNTAG_ACTIONS_IF_NOT_PRESENTf, 45477 &vntag_action); 45478 if (BCM_SUCCESS(rv)) { 45479 *value = (vntag_action == VNTAG_ADD) ? TRUE : FALSE; 45480 } 45481 } 45482 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45483 break; 45484 45485 case bcmPortControlNonEtagAdd: 45486 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45487 if (soc_feature(unit, soc_feature_port_extension)) { 45488 int etag_action; 45489 rv = _bcm_esw_port_tab_get(unit, port, 45490 VNTAG_ACTIONS_IF_NOT_PRESENTf, 45491 &etag_action); 45492 if (BCM_SUCCESS(rv)) { 45493 *value = (etag_action == 2) ? TRUE : FALSE; 45494 } 45495 } 45496 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45497 break; 45498 45499 case bcmPortControlNivVntagIngressReplace: 45500 case bcmPortControlEtagIngressReplace: 45501 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45502 if (soc_feature(unit, soc_feature_niv) || 45503 soc_feature(unit, soc_feature_port_extension)) { 45504 int vntag_action; 45505 rv = _bcm_esw_port_tab_get(unit, port, 45506 VNTAG_ACTIONS_IF_PRESENTf, 45507 &vntag_action); 45508 if (BCM_SUCCESS(rv)) { 45509 *value = (vntag_action == VNTAG_REPLACE) ? TRUE : FALSE; 45510 } 45511 } 45512 #endif /* BCM_TRIDENT_SUPPORT ||BCM_GREYHOUND_SUPPORT */ 45513 break; 45514 45515 case bcmPortControlNivVntagEgressReplace: 45516 case bcmPortControlEtagEgressReplace: 45517 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45518 if (soc_feature(unit, soc_feature_niv) || 45519 soc_feature(unit, soc_feature_port_extension)) { 45520 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 45521 SOC_IS_GREYHOUND2(unit)) { 45522 uint64 val64; 45523 int vntag_action; 45524 45525 if (type == bcmPortControlEtagEgressReplace) { 45526 return BCM_E_UNAVAIL; 45527 } 45528 45529 rv = READ_EGR_PORT_64r(unit, port, &val64); 45530 if (BCM_SUCCESS(rv)) { 45531 vntag_action = soc_reg64_field32_get(unit, EGR_PORT_64r, 45532 val64, VNTAG_ACTIONS_IF_PRESENTf); 45533 *value = (vntag_action == VNTAG_REPLACE) ? TRUE : FALSE; 45534 } 45535 } else { 45536 int vntag_action; 45537 rv = _bcm_esw_egr_port_tab_get(unit, port, 45538 VNTAG_ACTIONS_IF_PRESENTf, 45539 &vntag_action); 45540 if (BCM_SUCCESS(rv)) { 45541 *value = (vntag_action == VNTAG_REPLACE) ? TRUE : FALSE; 45542 } 45543 } 45544 } 45545 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45546 break; 45547 45548 case bcmPortControlNivVntagIngressDelete: 45549 case bcmPortControlEtagIngressDelete: 45550 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45551 if (soc_feature(unit, soc_feature_niv) || 45552 soc_feature(unit, soc_feature_port_extension)) { 45553 int vntag_action; 45554 rv = _bcm_esw_port_tab_get(unit, port, 45555 VNTAG_ACTIONS_IF_PRESENTf, 45556 &vntag_action); 45557 if (BCM_SUCCESS(rv)) { 45558 *value = (vntag_action == VNTAG_DELETE) ? TRUE : FALSE; 45559 } 45560 } 45561 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45562 break; 45563 45564 case bcmPortControlNivVntagEgressDelete: 45565 case bcmPortControlEtagEgressDelete: 45566 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45567 if (soc_feature(unit, soc_feature_niv) || 45568 soc_feature(unit, soc_feature_port_extension)) { 45569 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 45570 SOC_IS_GREYHOUND2(unit)) { 45571 uint64 val64; 45572 int vntag_action; 45573 rv = READ_EGR_PORT_64r(unit, port, &val64); 45574 if (BCM_SUCCESS(rv)) { 45575 vntag_action = soc_reg64_field32_get(unit, EGR_PORT_64r, 45576 val64, VNTAG_ACTIONS_IF_PRESENTf); 45577 *value = (vntag_action == VNTAG_DELETE) ? TRUE : FALSE; 45578 } 45579 } else { 45580 int vntag_action; 45581 rv = _bcm_esw_egr_port_tab_get(unit, port, 45582 VNTAG_ACTIONS_IF_PRESENTf, 45583 &vntag_action); 45584 if (BCM_SUCCESS(rv)) { 45585 *value = (vntag_action == VNTAG_DELETE) ? TRUE : FALSE; 45586 } 45587 } 45588 } 45589 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45590 break; 45591 45592 case bcmPortControlNivRpfCheck: 45593 case bcmPortControlExtenderRpfCheck: 45594 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45595 if (soc_feature(unit, soc_feature_niv) || 45596 soc_feature(unit, soc_feature_port_extension)) { 45597 rv = _bcm_esw_port_tab_get(unit, port, 45598 NIV_RPF_CHECK_ENABLEf, value); 45599 } 45600 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45601 break; 45602 45603 case bcmPortControlNivSourceKnockout: 45604 case bcmPortControlExtenderSourceKnockout: 45605 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45606 if (soc_feature(unit, soc_feature_niv) || 45607 soc_feature(unit, soc_feature_port_extension)) { 45608 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 45609 SOC_IS_GREYHOUND2(unit)) { 45610 uint64 val64; 45611 rv = READ_EGR_PORT_64r(unit, port, &val64); 45612 if (BCM_SUCCESS(rv)) { 45613 *value = soc_reg64_field32_get(unit, EGR_PORT_64r, 45614 val64, NIV_PRUNE_ENABLEf); 45615 } 45616 } else { 45617 rv = _bcm_esw_egr_port_tab_get(unit, port, 45618 NIV_PRUNE_ENABLEf, value); 45619 } 45620 } 45621 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45622 break; 45623 45624 case bcmPortControlNivForwardPort: 45625 case bcmPortControlExtenderForwardPort: 45626 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45627 if (soc_feature(unit, soc_feature_niv) || 45628 soc_feature(unit, soc_feature_port_extension)) { 45629 int is_niv_uplink; 45630 int tx_dest_port; 45631 _bcm_gport_dest_t dest; 45632 45633 BCM_IF_ERROR_RETURN 45634 (_bcm_esw_port_tab_get(unit, port, 45635 NIV_UPLINK_PORTf, &is_niv_uplink)); 45636 if (is_niv_uplink) { 45637 *value = -1; 45638 } else { 45639 if (soc_feature(unit, soc_feature_generic_dest)) { 45640 uint32 dt, dval; 45641 BCM_IF_ERROR_RETURN 45642 (_bcm_esw_port_tab_get(unit, port, DESTINATIONf, 45643 &tx_dest_port)); 45644 _soc_mem_dest_value_resolve(unit, tx_dest_port, &dt, &dval); 45645 if (dt == SOC_MEM_FIF_DEST_LAG) { 45646 dest.tgid = dval; 45647 dest.gport_type = _SHR_GPORT_TYPE_TRUNK; 45648 } else { 45649 dest.port = dval & SOC_MEM_FIF_DGPP_PORT_MASK; 45650 dest.modid = (dval & SOC_MEM_FIF_DGPP_MOD_ID_MASK) >> 45651 SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS; 45652 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 45653 } 45654 } else { 45655 BCM_IF_ERROR_RETURN 45656 (_bcm_esw_port_tab_get(unit, port, 45657 TX_DEST_PORTf, &tx_dest_port)); 45658 if ((tx_dest_port >> SOC_TRUNK_BIT_POS(unit)) & 0x1) { 45659 dest.tgid = tx_dest_port - (1 << SOC_TRUNK_BIT_POS(unit)); 45660 dest.gport_type = _SHR_GPORT_TYPE_TRUNK; 45661 } else { 45662 #if defined(BCM_METROLITE_SUPPORT) 45663 /* Metrolite DGLP still uses 7 bits for port like saber 2 */ 45664 if (SOC_IS_METROLITE(unit)) { 45665 dest.port = tx_dest_port & 0x7f; 45666 dest.modid =( tx_dest_port & 0xff10) >> 7; 45667 } else 45668 #endif 45669 { 45670 dest.port = tx_dest_port & SOC_PORT_ADDR_MAX(unit); 45671 dest.modid = (tx_dest_port - dest.port) / 45672 (SOC_PORT_ADDR_MAX(unit) + 1); 45673 } 45674 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 45675 } 45676 } 45677 BCM_IF_ERROR_RETURN 45678 (_bcm_esw_gport_construct(unit, &dest, value)); 45679 } 45680 rv = BCM_E_NONE; 45681 } 45682 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45683 break; 45684 45685 case bcmPortControlNivType: 45686 if (soc_feature(unit, soc_feature_niv)) { 45687 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 45688 SOC_IS_GREYHOUND2(unit)) { 45689 #if defined(BCM_GREYHOUND_SUPPORT) 45690 rv = bcm_gh_port_niv_type_get(unit, port, value); 45691 #endif /* BCM_GREYHOUND_SUPPORT */ 45692 } else { 45693 #if defined(BCM_TRIDENT_SUPPORT) 45694 rv = bcm_td_port_niv_type_get(unit, port, value); 45695 #endif /* BCM_TRIDENT_SUPPORT */ 45696 } 45697 } 45698 break; 45699 45700 case bcmPortControlExtenderType: 45701 if (soc_feature(unit, soc_feature_port_extension)) { 45702 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 45703 SOC_IS_GREYHOUND2(unit)) { 45704 #if defined(BCM_GREYHOUND_SUPPORT) 45705 rv = bcm_gh_port_extender_type_get(unit, port, value); 45706 #endif /* BCM_GREYHOUND_SUPPORT */ 45707 } else { 45708 #if defined(BCM_TRIUMPH3_SUPPORT) 45709 rv = bcm_tr3_port_extender_type_get(unit, port, value); 45710 #endif /* BCM_TRIUMPH3_SUPPORT */ 45711 } 45712 } 45713 break; 45714 45715 case bcmPortControlNivNameSpace: 45716 case bcmPortControlExtenderNameSpace: 45717 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45718 if (soc_feature(unit, soc_feature_niv) || 45719 soc_feature(unit, soc_feature_port_extension)) { 45720 rv = _bcm_esw_port_tab_get(unit, port, NIV_NAMESPACEf, value); 45721 } 45722 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45723 break; 45724 45725 case bcmPortControlEtagPcpDeSelect: 45726 #if defined(INCLUDE_L3) 45727 if (soc_feature(unit, soc_feature_port_extension)) { 45728 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 45729 SOC_IS_GREYHOUND2(unit)) { 45730 #if defined(BCM_GREYHOUND_SUPPORT) 45731 rv = bcm_gh_port_etag_pcp_de_source_get(unit, port, value); 45732 #endif /* BCM_GREYHOUND_SUPPORT */ 45733 } else { 45734 #if defined(BCM_TRIUMPH3_SUPPORT) 45735 rv = bcm_tr3_port_etag_pcp_de_source_get(unit, port, value); 45736 #endif /* BCM_TRIUMPH3_SUPPORT */ 45737 } 45738 } 45739 #endif /* INCLUDE_L3 */ 45740 break; 45741 45742 case bcmPortControlEtagPcp: 45743 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45744 if (soc_feature(unit, soc_feature_port_extension)) { 45745 rv = _bcm_esw_port_tab_get(unit, port, ETAG_PCPf, value); 45746 } 45747 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45748 break; 45749 45750 case bcmPortControlEtagDe: 45751 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45752 if (soc_feature(unit, soc_feature_port_extension)) { 45753 rv = _bcm_esw_port_tab_get(unit, port, ETAG_DEf, value); 45754 } 45755 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45756 break; 45757 45758 case bcmPortControlUseEtagPri: 45759 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45760 if (soc_feature(unit, soc_feature_port_extension)) { 45761 rv = _bcm_esw_port_tab_get(unit, port, PHB_FROM_ETAGf, value); 45762 } 45763 #endif /* BCM_TRIUMPH3_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45764 break; 45765 45766 case bcmPortControlUseSubportPktTagPri: 45767 #if defined(BCM_KATANA2_SUPPORT) 45768 if (soc_feature(unit, soc_feature_lltag)) { 45769 rv = _bcm_esw_port_tab_get(unit, port, PHB_FROM_LLTAGf, value); 45770 } 45771 #endif /* BCM_KATANA2_SUPPORT */ 45772 break; 45773 45774 case bcmPortControlProhibitedDot1p: 45775 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND_SUPPORT) 45776 rv = _bcm_esw_port_tab_get(unit, port, PROHIBITED_DOT1Pf, value); 45777 #endif /* BCM_TRIDENT_SUPPORT||BCM_GREYHOUND_SUPPORT */ 45778 break; 45779 45780 case bcmPortControlFabricSourceKnockout: 45781 rv = _bcm_esw_port_tab_get(unit, port, REMOVE_HG_HDR_SRC_PORTf, 45782 value); 45783 break; 45784 45785 case bcmPortControlPrbsPolynomial: 45786 rv = soc_phyctrl_control_get(unit, port, 45787 SOC_PHY_CONTROL_PRBS_POLYNOMIAL, 45788 (uint32 *)value); 45789 break; 45790 case bcmPortControlPrbsTxEnable: 45791 rv = soc_phyctrl_control_get(unit, port, 45792 SOC_PHY_CONTROL_PRBS_TX_ENABLE, 45793 (uint32 *)value); 45794 break; 45795 45796 case bcmPortControlPrbsRxEnable: 45797 rv = soc_phyctrl_control_get(unit, port, 45798 SOC_PHY_CONTROL_PRBS_RX_ENABLE, 45799 (uint32 *)value); 45800 break; 45801 45802 case bcmPortControlPrbsTxInvertData: 45803 rv = soc_phyctrl_control_get(unit, port, 45804 SOC_PHY_CONTROL_PRBS_TX_INVERT_DATA, 45805 (uint32 *)value); 45806 break; 45807 45808 case bcmPortControlRxEnable: 45809 rv = _bcm_esw_mac_rx_control(unit, port, 1, value); 45810 break; 45811 case bcmPortControlTxEnable: 45812 if (SOC_REG_IS_VALID(unit, COSMASKr) || 45813 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 45814 /* Trident2plus/Trident2 uses soc_td2_port_traffic_egr_enable_set */ 45815 SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_TRIDENT2(unit) || 45816 #endif 45817 #ifdef BCM_APACHE_SUPPORT 45818 SOC_IS_APACHE(unit) || 45819 #endif 45820 #ifdef BCM_TRIDENT3_SUPPORT 45821 SOC_IS_TRIDENT3X(unit) || 45822 #endif 45823 #ifdef BCM_TOMAHAWK_SUPPORT 45824 SOC_IS_TOMAHAWKX(unit) || 45825 #endif 45826 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_HELIX4_SUPPORT) 45827 (SOC_IS_HELIX4(unit) || SOC_IS_TRIUMPH3(unit)) || 45828 #endif 45829 (SOC_REG_IS_VALID(unit, EGRMETERINGCONFIGr) && 45830 SOC_REG_IS_VALID(unit, EGRMETERINGBUCKETr))) { 45831 *value = 1; 45832 if (PORT(unit, port).flags & _PORT_INFO_STOP_TX) { 45833 *value = 0; 45834 } 45835 rv = SOC_E_NONE; 45836 } 45837 break; 45838 45839 case bcmPortControlL2GreEnable: 45840 #if defined(BCM_TRIUMPH3_SUPPORT) 45841 if (soc_feature(unit, soc_feature_l2gre) 45842 #if defined(BCM_TRIDENT3_SUPPORT) 45843 || soc_feature(unit, soc_feature_flex_flow) 45844 #endif 45845 ) { 45846 rv = _bcm_esw_port_tab_get(unit, port, 45847 L2GRE_TERMINATION_ALLOWEDf, value); 45848 } 45849 #endif /* BCM_TRIUMPH3_SUPPORT */ 45850 break; 45851 45852 case bcmPortControlL2GreTunnelbasedVpnId: 45853 #if defined(BCM_TRIUMPH3_SUPPORT) 45854 if (soc_feature(unit, soc_feature_l2gre) 45855 #if defined(BCM_TRIDENT3_SUPPORT) 45856 || soc_feature(unit, soc_feature_flex_flow) 45857 #endif 45858 ) { 45859 rv = _bcm_esw_port_tab_get(unit, port, 45860 L2GRE_VPNID_LOOKUP_KEY_TYPEf, value); 45861 } 45862 #endif /* BCM_TRIUMPH3_SUPPORT */ 45863 break; 45864 45865 case bcmPortControlL2GreDefaultTunnelEnable: 45866 #if defined(BCM_TRIUMPH3_SUPPORT) 45867 if (soc_feature(unit, soc_feature_l2gre) 45868 #if defined(BCM_TRIDENT3_SUPPORT) 45869 || soc_feature(unit, soc_feature_flex_flow) 45870 #endif 45871 ) { 45872 rv = _bcm_esw_port_tab_get(unit, port, 45873 L2GRE_DEFAULT_SVP_ENABLEf, value); 45874 } 45875 #endif /* BCM_TRIUMPH3_SUPPORT */ 45876 45877 break; 45878 45879 case bcmPortControlVxlanEnable: 45880 #if defined(BCM_TRIDENT2_SUPPORT) 45881 if ((soc_feature(unit, soc_feature_vxlan)) || 45882 (soc_feature(unit, soc_feature_flex_flow))) { 45883 rv = _bcm_esw_port_tab_get(unit, port, 45884 VXLAN_TERMINATION_ALLOWEDf, value); 45885 } 45886 #endif /* BCM_TRIDENT2_SUPPORT */ 45887 break; 45888 45889 case bcmPortControlVxlanTunnelbasedVnId: 45890 #if defined(BCM_TRIDENT2_SUPPORT) 45891 if ((soc_feature(unit, soc_feature_vxlan)) || 45892 (soc_feature(unit, soc_feature_flex_flow))) { 45893 rv = _bcm_esw_port_tab_get(unit, port, 45894 VXLAN_VN_ID_LOOKUP_KEY_TYPEf, value); 45895 } 45896 #endif /* BCM_TRIDENT2_SUPPORT */ 45897 break; 45898 case bcmPortControlVxlanVpnAssignmentCriteria: 45899 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 45900 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 45901 rv = _bcm_esw_port_tab_get(unit, port, 45902 VXLAN_VN_ID_LOOKUP_KEY_TYPEf, value); 45903 } 45904 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 45905 break; 45906 case bcmPortControlVxlanTerminationMatchCriteria: 45907 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 45908 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 45909 rv = _bcm_esw_port_tab_get(unit, port, 45910 VXLAN_TERMINATION_LOOKUP_TYPEf, value); 45911 } 45912 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 45913 break; 45914 case bcmPortControlVxlanGportAssignmentCriteria: 45915 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 45916 if (soc_feature(unit, soc_feature_vrf_aware_vxlan_termination)) { 45917 rv = _bcm_esw_port_tab_get(unit, port, 45918 VXLAN_SVP_ASSIGNMENT_KEY_TYPEf, value); 45919 } 45920 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 45921 break; 45922 case bcmPortControlVxlanDefaultTunnelEnable: 45923 #if defined(BCM_TRIDENT2_SUPPORT) 45924 if ((soc_feature(unit, soc_feature_vxlan)) || 45925 (soc_feature(unit, soc_feature_flex_flow))) { 45926 rv = _bcm_esw_port_tab_get(unit, port, 45927 VXLAN_DEFAULT_SVP_ENABLEf, value); 45928 } 45929 #endif /* BCM_TRIDENT2_SUPPORT */ 45930 break; 45931 45932 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_REGEX) 45933 case bcmPortControlRegex: 45934 rv = _bcm_esw_port_regex_control_get(unit, port, &udp, &tcp, &enable); 45935 if (enable != 0) { 45936 *value = 1; 45937 } else { 45938 *value = 0; 45939 } 45940 break; 45941 case bcmPortControlRegexTcp: 45942 rv = _bcm_esw_port_regex_control_get(unit, port, &udp, &tcp, &enable); 45943 if (tcp != 0) { 45944 *value = 1; 45945 } else { 45946 *value = 0; 45947 } 45948 break; 45949 case bcmPortControlRegexUdp: 45950 rv = _bcm_esw_port_regex_control_get(unit, port, &udp, &tcp, &enable); 45951 if (udp != 0) { 45952 *value = 1; 45953 } else { 45954 *value = 0; 45955 } 45956 break; 45957 #endif 45958 45959 case bcmPortControlMplsEntropyHashSet: 45960 #if defined(BCM_KATANA2_SUPPORT) 45961 if (SOC_IS_KATANA2(unit)) { 45962 return BCM_E_UNAVAIL; 45963 } else 45964 #endif /* BCM_KATANA2_SUPPORT */ 45965 { 45966 #if defined(BCM_KATANA_SUPPORT) 45967 if (soc_feature(unit, soc_feature_mpls)) { 45968 rv = _bcm_esw_port_tab_get(unit, port, 45969 RTAG7_HASH_CFG_SEL_ENTROPY_LABELf, 45970 value); 45971 } 45972 #endif /* BCM_KATANA_SUPPORT */ 45973 } 45974 break; 45975 45976 #ifdef BCM_SHADOW_SUPPORT 45977 case bcmPortControlManagementPacketIp6Reserved: 45978 if (!SOC_IS_SHADOW(unit)) { 45979 return BCM_E_UNAVAIL; 45980 } 45981 PORT_LOCK(unit); 45982 rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val); 45983 if (BCM_SUCCESS(rv)) { 45984 *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr, 45985 val, IPV6_RESVf); 45986 } 45987 PORT_UNLOCK(unit); 45988 break; 45989 case bcmPortControlManagementPacketIp4Reserved: 45990 if (!SOC_IS_SHADOW(unit)) { 45991 return BCM_E_UNAVAIL; 45992 } 45993 PORT_LOCK(unit); 45994 rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val); 45995 if (BCM_SUCCESS(rv)) { 45996 *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr, 45997 val, IPV4_RESVf); 45998 } 45999 PORT_UNLOCK(unit); 46000 break; 46001 case bcmPortControlManagementPacketLinkConstrained: 46002 if (!SOC_IS_SHADOW(unit)) { 46003 return BCM_E_UNAVAIL; 46004 } 46005 PORT_LOCK(unit); 46006 rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val); 46007 if (BCM_SUCCESS(rv)) { 46008 *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr, 46009 val, LINK_CONSTf); 46010 } 46011 PORT_UNLOCK(unit); 46012 break; 46013 case bcmPortControlManagementPacketGarp: 46014 if (!SOC_IS_SHADOW(unit)) { 46015 return BCM_E_UNAVAIL; 46016 } 46017 PORT_LOCK(unit); 46018 rv = READ_MGMT_FRAME_ENABLEr(unit, port, &val); 46019 if (BCM_SUCCESS(rv)) { 46020 *value = soc_reg_field_get(unit, MGMT_FRAME_ENABLEr, 46021 val, DOT1D_GARPf); 46022 } 46023 PORT_UNLOCK(unit); 46024 break; 46025 case bcmPortControlManagementPacketCos: 46026 if (!SOC_IS_SHADOW(unit)) { 46027 return BCM_E_UNAVAIL; 46028 } 46029 PORT_LOCK(unit); 46030 rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val); 46031 if (BCM_SUCCESS(rv)) { 46032 *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr, 46033 val, MGMT_FRAME_COSf); 46034 } 46035 PORT_UNLOCK(unit); 46036 break; 46037 case bcmPortControlManagementPacketColor: 46038 rv = BCM_E_UNAVAIL; 46039 break; 46040 case bcmPortControlTaggedL3PacketPktPri: 46041 if (!SOC_IS_SHADOW(unit)) { 46042 return BCM_E_UNAVAIL; 46043 } 46044 PORT_LOCK(unit); 46045 rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val); 46046 if (BCM_SUCCESS(rv)) { 46047 *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr, 46048 val, SELECT5f); 46049 switch (*value) { 46050 case 0: 46051 *value = BCM_PORT_COS_REMAP_DSCP; 46052 break; 46053 case 1: 46054 *value = BCM_PORT_COS_REMAP_EXP; 46055 break; 46056 case 2: 46057 *value = BCM_PORT_COS_REMAP_VLAN_PRI; 46058 break; 46059 default: 46060 *value = BCM_PORT_COS_REMAP_VLAN_PRI; 46061 } 46062 } 46063 PORT_UNLOCK(unit); 46064 break; 46065 case bcmPortControlTaggedMPLSPacketPktPri: 46066 if (!SOC_IS_SHADOW(unit)) { 46067 return BCM_E_UNAVAIL; 46068 } 46069 PORT_LOCK(unit); 46070 rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val); 46071 if (BCM_SUCCESS(rv)) { 46072 *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr, 46073 val, SELECT3f); 46074 switch (*value) { 46075 case 0: 46076 *value = BCM_PORT_COS_REMAP_DSCP; 46077 break; 46078 case 1: 46079 *value = BCM_PORT_COS_REMAP_EXP; 46080 break; 46081 case 2: 46082 *value = BCM_PORT_COS_REMAP_VLAN_PRI; 46083 break; 46084 default: 46085 *value = BCM_PORT_COS_REMAP_VLAN_PRI; 46086 } 46087 } 46088 PORT_UNLOCK(unit); 46089 break; 46090 case bcmPortControlTaggedMPLSL3PacketPktPri: 46091 if (!SOC_IS_SHADOW(unit)) { 46092 return BCM_E_UNAVAIL; 46093 } 46094 PORT_LOCK(unit); 46095 rv = READ_COSDP_REMAP_CONTROLr(unit, port, &val); 46096 if (BCM_SUCCESS(rv)) { 46097 *value = soc_reg_field_get(unit, COSDP_REMAP_CONTROLr, 46098 val, SELECT7f); 46099 switch (*value) { 46100 case 0: 46101 *value = BCM_PORT_COS_REMAP_DSCP; 46102 break; 46103 case 1: 46104 *value = BCM_PORT_COS_REMAP_EXP; 46105 break; 46106 case 2: 46107 *value = BCM_PORT_COS_REMAP_VLAN_PRI; 46108 break; 46109 default: 46110 *value = BCM_PORT_COS_REMAP_VLAN_PRI; 46111 } 46112 } 46113 PORT_UNLOCK(unit); 46114 break; 46115 #endif 46116 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 46117 case bcmPortControlFieldEgressClassSelect: 46118 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 46119 if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) { 46120 rv = _bcm_td2p_port_control_egress_class_select_get(unit, port, 46121 (uint32 *)value); 46122 } else 46123 #endif 46124 { 46125 rv = _bcm_trx_port_control_egress_class_select_get(unit, port, 46126 (uint32 *)value); 46127 } 46128 break; 46129 #endif 46130 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 46131 case bcmPortControlFieldHiGigClassSelect: 46132 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 46133 if (soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) { 46134 rv = _bcm_td2p_port_control_higig_class_select_get(unit, port, 46135 (uint32 *)value); 46136 } else 46137 #endif 46138 { 46139 rv = _bcm_trx_port_control_higig_class_select_get(unit, port, 46140 (uint32 *)value); 46141 } 46142 break; 46143 #endif 46144 case bcmPortControlSubportTagEnable: 46145 #if defined (BCM_HGPROXY_COE_SUPPORT) 46146 if(soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 46147 rv = bcmi_xgs5_port_control_subtag_status_get(unit, port, value); 46148 } 46149 #endif 46150 #if defined (BCM_KATANA2_SUPPORT) 46151 if (soc_feature(unit, soc_feature_subtag_coe)) { 46152 if (SOC_IS_KATANA2(unit)) { 46153 rv = bcm_kt2_port_control_subtag_status_get(unit, port, value); 46154 } 46155 } 46156 #endif 46157 break; 46158 46159 46160 case bcmPortControlLinkPhyEnable: 46161 #if defined (BCM_KATANA2_SUPPORT) 46162 if (soc_feature(unit, soc_feature_linkphy_coe)) { 46163 if (SOC_IS_KATANA2(unit)) { 46164 rv = bcm_kt2_port_control_linkphy_status_get(unit, port, value); 46165 } 46166 } 46167 #endif 46168 break; 46169 46170 #if defined(BCM_TRIDENT2_SUPPORT) 46171 46172 case bcmPortControlFcoeRouteEnable: 46173 if (soc_feature(unit, soc_feature_fcoe)) { 46174 #ifdef BCM_TRIDENT3_SUPPORT 46175 if (SOC_IS_TRIDENT3X(unit)) { 46176 rv = _bcm_esw_port_tab_get(unit, port, 46177 FCOE_ROUTE_ENABLEf, value); 46178 } else 46179 #endif 46180 { 46181 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_ROUTE_ENABLEf)) { 46182 rv = _bcm_esw_port_tab_get(unit, port, 46183 FCOE_ROUTE_ENABLEf, value); 46184 } 46185 } 46186 } 46187 break; 46188 46189 case bcmPortControlFcoeVftEnable: 46190 if (soc_feature(unit, soc_feature_fcoe)) { 46191 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VFT_ENABLEf)) { 46192 rv = _bcm_esw_port_tab_get(unit, port, 46193 FCOE_VFT_ENABLEf, value); 46194 } 46195 } 46196 break; 46197 46198 case bcmPortControlFcoeZoneCheckEnable: 46199 if (soc_feature(unit, soc_feature_fcoe)) { 46200 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, 46201 FCOE_ZONE_CHECK_ENABLEf)) { 46202 rv = _bcm_esw_port_tab_get(unit, port, 46203 FCOE_ZONE_CHECK_ENABLEf, value); 46204 } 46205 } 46206 break; 46207 46208 case bcmPortControlFcoeSourceBindCheckEnable: 46209 if (soc_feature(unit, soc_feature_fcoe)) { 46210 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, 46211 FCOE_SRC_BIND_CHECK_ENABLEf)) { 46212 rv = _bcm_esw_port_tab_get(unit, port, 46213 FCOE_SRC_BIND_CHECK_ENABLEf, 46214 value); 46215 } 46216 } 46217 break; 46218 46219 case bcmPortControlFcoeFpmaPrefixCheckEnable: 46220 if (soc_feature(unit, soc_feature_fcoe)) { 46221 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, 46222 FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf)) { 46223 rv = _bcm_esw_port_tab_get(unit, port, 46224 FCOE_SRC_FPMA_PREFIX_CHECK_ENABLEf, 46225 value); 46226 } 46227 } 46228 break; 46229 46230 case bcmPortControlFcoeDoNotLearn: 46231 if (soc_feature(unit, soc_feature_fcoe)) { 46232 if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_DO_NOT_LEARNf))) { 46233 rv = _bcm_esw_port_tab_get(unit, port, 46234 FCOE_DO_NOT_LEARNf, value); 46235 } 46236 } 46237 break; 46238 46239 case bcmPortControlFcoeNetworkPort: 46240 if (soc_feature(unit, soc_feature_fcoe)) { 46241 if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_NETWORK_PORTf))) { 46242 rv = _bcm_esw_port_tab_get(unit, port, 46243 FCOE_NETWORK_PORTf, value); 46244 } 46245 } 46246 break; 46247 46248 case bcmPortControlFcoeFabricSel: 46249 if (soc_feature(unit, soc_feature_fcoe)) { 46250 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_SELf)) { 46251 rv = _bcm_esw_port_tab_get(unit, port, 46252 FCOE_FABRIC_SELf, value); 46253 } 46254 } 46255 break; 46256 46257 case bcmPortControlFcoeFabricId: 46258 if (soc_feature(unit, soc_feature_fcoe)) { 46259 #ifdef BCM_TRIDENT3_SUPPORT 46260 if (SOC_IS_TRIDENT3X(unit)) { 46261 rv = _bcm_esw_port_tab_get(unit, port, 46262 FCOE_FABRIC_IDf, value); 46263 } else 46264 #endif 46265 { 46266 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_IDf)) { 46267 rv = _bcm_esw_port_tab_get(unit, port, 46268 FCOE_FABRIC_IDf, value); 46269 } 46270 } 46271 } 46272 break; 46273 46274 case bcmPortControlFcoeFabricPri: 46275 if (soc_feature(unit, soc_feature_fcoe)) { 46276 #ifdef BCM_TRIDENT3_SUPPORT 46277 if (SOC_IS_TRIDENT3X(unit)) { 46278 rv = _bcm_esw_port_tab_get(unit, port, 46279 FCOE_FABRIC_PRIf, value); 46280 } else 46281 #endif 46282 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_FABRIC_PRIf)) { 46283 rv = _bcm_esw_port_tab_get(unit, port, 46284 FCOE_FABRIC_PRIf, value); 46285 } 46286 } 46287 break; 46288 46289 case bcmPortControlFcoeFcCrcAction: 46290 if (soc_feature(unit, soc_feature_fcoe)) { 46291 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, 46292 FCOE_FC_CRC_ACTIONf)) { 46293 egr_ing_port_entry_t egr_ing_port_entry; 46294 46295 rv = READ_EGR_ING_PORTm(unit, MEM_BLOCK_ANY, port, 46296 &egr_ing_port_entry); 46297 if (BCM_SUCCESS(rv)) { 46298 *value = soc_mem_field32_get(unit, EGR_ING_PORTm, 46299 &egr_ing_port_entry, 46300 FCOE_FC_CRC_ACTIONf); 46301 } 46302 } 46303 } 46304 break; 46305 46306 case bcmPortControlFcoeFcCrcRecompute: 46307 if (soc_feature(unit, soc_feature_fcoe)) { 46308 if (SOC_MEM_IS_VALID(unit, EGR_PORTm) && 46309 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 46310 FCOE_FC_CRC_RECOMPUTEf)) { 46311 egr_port_entry_t egr_port_entry; 46312 46313 rv = READ_EGR_PORTm(unit, MEM_BLOCK_ANY, port, 46314 &egr_port_entry); 46315 if (BCM_SUCCESS(rv)) { 46316 *value = soc_mem_field32_get(unit, EGR_PORTm, 46317 &egr_port_entry, 46318 FCOE_FC_CRC_RECOMPUTEf); 46319 } 46320 } 46321 } 46322 break; 46323 46324 case bcmPortControlFcoeFcEofIgnore: 46325 if (soc_feature(unit, soc_feature_fcoe)) { 46326 if (SOC_MEM_FIELD_VALID(unit, EGR_ING_PORTm, 46327 FCOE_FC_EOF_IGNOREf)) { 46328 egr_ing_port_entry_t egr_ing_port_entry; 46329 46330 rv = READ_EGR_ING_PORTm(unit, MEM_BLOCK_ANY, port, 46331 &egr_ing_port_entry); 46332 if (BCM_SUCCESS(rv)) { 46333 *value = soc_mem_field32_get(unit, EGR_ING_PORTm, 46334 &egr_ing_port_entry, 46335 FCOE_FC_EOF_IGNOREf); 46336 } 46337 } 46338 } 46339 break; 46340 46341 case bcmPortControlFcoeTranslateKeyFirst: 46342 case bcmPortControlFcoeTranslateKeySecond: 46343 if (soc_feature(unit, soc_feature_fcoe)) { 46344 int reg_val; 46345 int key_type; 46346 int use_port = 0; 46347 int vt_port_type; 46348 46349 if (type == bcmPortControlFcoeTranslateKeyFirst) { 46350 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_1f)) { 46351 rv = _bcm_esw_port_tab_get(unit, port, 46352 FCOE_VT_KEY_TYPE_1f, ®_val); 46353 } 46354 46355 if (BCM_SUCCESS(rv)) { 46356 rv = _bcm_esw_port_config_get(unit, port, 46357 _bcmPortVTKeyPortFirst, 46358 &vt_port_type); 46359 if (BCM_SUCCESS(rv)) { 46360 if (vt_port_type != 0) { 46361 use_port = 1; 46362 } 46363 } 46364 } 46365 } else { 46366 if (SOC_IS_TRIDENT3X(unit) || SOC_MEM_FIELD_VALID(unit, PORT_TABm, FCOE_VT_KEY_TYPE_2f)) { 46367 rv = _bcm_esw_port_tab_get(unit, port, 46368 FCOE_VT_KEY_TYPE_2f, ®_val); 46369 } 46370 if (BCM_SUCCESS(rv)) { 46371 rv = _bcm_esw_port_config_get(unit, port, 46372 _bcmPortVTKeyPortSecond, 46373 &vt_port_type); 46374 if (BCM_SUCCESS(rv)) { 46375 if (vt_port_type != 0) { 46376 use_port = 1; 46377 } 46378 } 46379 } 46380 } 46381 46382 if (BCM_SUCCESS(rv)) { 46383 /* convert register value to common key type */ 46384 rv = _bcm_esw_vlan_xlate_key_type_get(unit, reg_val, &key_type); 46385 if (!BCM_SUCCESS(rv)) { 46386 break; 46387 } 46388 46389 /* convert common key type value to 46390 bcm_fcoe_vsan_translate_key_t */ 46391 switch (key_type) { 46392 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 46393 if (use_port) { 46394 *value = bcmFcoeVsanTranslateKeyPortDouble; 46395 } else { 46396 *value = bcmFcoeVsanTranslateKeyDouble; 46397 } 46398 break; 46399 case VLXLT_HASH_KEY_TYPE_OTAG: 46400 if (use_port) { 46401 *value = bcmFcoeVsanTranslateKeyPortOuterTag; 46402 } else { 46403 *value = bcmFcoeVsanTranslateKeyOuterTag; 46404 } 46405 break; 46406 case VLXLT_HASH_KEY_TYPE_ITAG: 46407 if (use_port) { 46408 *value = bcmFcoeVsanTranslateKeyPortInnerTag; 46409 } else { 46410 *value = bcmFcoeVsanTranslateKeyInnerTag; 46411 } 46412 break; 46413 case VLXLT_HASH_KEY_TYPE_OVID: 46414 if (use_port) { 46415 *value = bcmFcoeVsanTranslateKeyPortOuter; 46416 } else { 46417 *value = bcmFcoeVsanTranslateKeyOuter; 46418 } 46419 break; 46420 case VLXLT_HASH_KEY_TYPE_IVID: 46421 if (use_port) { 46422 *value = bcmFcoeVsanTranslateKeyPortInner; 46423 } else { 46424 *value = bcmFcoeVsanTranslateKeyInner; 46425 } 46426 break; 46427 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 46428 if (use_port) { 46429 *value = bcmFcoeVsanTranslateKeyPortOuterPri; 46430 } else { 46431 *value = bcmFcoeVsanTranslateKeyOuterPri; 46432 } 46433 break; 46434 case VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN: 46435 if (use_port) { 46436 *value = bcmFcoeVsanTranslateKeyPortDoubleVsan; 46437 } else { 46438 *value = bcmFcoeVsanTranslateKeyDoubleVsan; 46439 } 46440 break; 46441 case VLXLT_HASH_KEY_TYPE_IVID_VSAN: 46442 if (use_port) { 46443 *value = bcmFcoeVsanTranslateKeyPortInnerVsan; 46444 } else { 46445 *value = bcmFcoeVsanTranslateKeyInnerVsan; 46446 } 46447 break; 46448 case VLXLT_HASH_KEY_TYPE_OVID_VSAN: 46449 if (use_port) { 46450 *value = bcmFcoeVsanTranslateKeyPortOuterVsan; 46451 } else { 46452 *value = bcmFcoeVsanTranslateKeyOuterVsan; 46453 } 46454 break; 46455 default: 46456 *value = bcmFcoeVsanTranslateKeyInvalid; 46457 break; 46458 } 46459 } 46460 } else { 46461 rv = BCM_E_UNAVAIL; 46462 } 46463 break; 46464 46465 case bcmPortControlFcoeTranslateKeyFirstEgress: 46466 case bcmPortControlFcoeTranslateKeySecondEgress: 46467 if (soc_feature(unit, soc_feature_fcoe)) { 46468 int key_type = -1; 46469 46470 if (type == bcmPortControlFcoeTranslateKeyFirstEgress) { 46471 if (SOC_IS_TRIDENT3X(unit) || 46472 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_1f)) { 46473 rv = _bcm_esw_egr_port_tab_get(unit, port, 46474 FCOE_VT_LOOKUP_1f, 46475 &key_type); 46476 } 46477 } else { 46478 if (SOC_IS_TRIDENT3X(unit) || 46479 SOC_MEM_FIELD_VALID(unit, EGR_PORTm, FCOE_VT_LOOKUP_2f)) { 46480 rv = _bcm_esw_egr_port_tab_get(unit, port, 46481 FCOE_VT_LOOKUP_2f, 46482 &key_type); 46483 } 46484 } 46485 46486 if (BCM_SUCCESS(rv)) { 46487 /* convert common key type value to 46488 bcm_fcoe_vsan_translate_key_egress_t */ 46489 switch (key_type) { 46490 case EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID_VSAN: 46491 *value = bcmFcoeVsanTranslateKeyEgressDoubleVsan; 46492 break; 46493 case EGR_VLXLT_HASH_KEY_TYPE_VSAN: 46494 *value = bcmFcoeVsanTranslateKeyEgressVsan; 46495 break; 46496 case EGR_VLXLT_HASH_KEY_TYPE_IVID_VSAN: 46497 *value = bcmFcoeVsanTranslateKeyEgressInnerVsan; 46498 break; 46499 case EGR_VLXLT_HASH_KEY_TYPE_OVID_VSAN: 46500 *value = bcmFcoeVsanTranslateKeyEgressOuterVsan; 46501 break; 46502 case EGR_VLXLT_HASH_KEY_TYPE_IVID_OVID: 46503 *value = bcmFcoeVsanTranslateKeyEgressDouble; 46504 break; 46505 case EGR_VLXLT_HASH_KEY_TYPE_IVID: 46506 *value = bcmFcoeVsanTranslateKeyEgressInner; 46507 break; 46508 case EGR_VLXLT_HASH_KEY_TYPE_OVID: 46509 *value = bcmFcoeVsanTranslateKeyEgressOuter; 46510 break; 46511 default: 46512 *value = bcmFcoeVsanTranslateKeyEgressInvalid; 46513 break; 46514 } 46515 } 46516 } else { 46517 rv = BCM_E_UNAVAIL; 46518 } 46519 break; 46520 46521 #endif /* BCM_TRIDENT2_SUPPORT */ 46522 case bcmPortControlEEEMode: 46523 if (soc_feature(unit, soc_feature_eee_bb_mode)) { 46524 uint32 fval = 0; 46525 uint32 rval = 0; 46526 uint32 temp = 0; 46527 if (soc_feature (unit, soc_feature_high_portcount_register)) { 46528 soc_reg_t eee_bb_reg; 46529 int phy_port; 46530 int mmu_port; 46531 int offset; 46532 46533 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 46534 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 46535 if (mmu_port < 32) { 46536 eee_bb_reg = EEE_BB_ENABLE_0r; 46537 offset = mmu_port; 46538 } else if ((mmu_port >=32) && (mmu_port < 64)) { 46539 eee_bb_reg = EEE_BB_ENABLE_1r; 46540 offset = mmu_port - 32; 46541 } else { /* mmu_port >= 64 */ 46542 eee_bb_reg = EEE_BB_ENABLE_2r; 46543 offset = mmu_port - 64; 46544 } 46545 temp = (1 << offset); 46546 BCM_IF_ERROR_RETURN( 46547 soc_reg32_get(unit, eee_bb_reg, REG_PORT_ANY, 0, &rval)); 46548 fval = soc_reg_field_get(unit, eee_bb_reg, rval, 46549 EEE_BB_ENABLEf); 46550 *value = (fval & temp) ? \ 46551 bcmPortEEEBurstAndBatchMode:bcmPortEEENativeMode; 46552 } else { 46553 temp = (1 << port); 46554 temp >>= 2; 46555 rv = READ_EEE_BB_ENABLEr(unit, &rval); 46556 if (BCM_SUCCESS(rv)) { 46557 fval = soc_reg_field_get(unit, EEE_BB_ENABLEr, rval, 46558 EEE_BB_ENABLEf); 46559 *value = (fval & temp) ? \ 46560 bcmPortEEEBurstAndBatchMode:bcmPortEEENativeMode; 46561 } 46562 } 46563 } 46564 break; 46565 #ifdef BCM_GREYHOUND_SUPPORT 46566 case bcmPortControlWredDropCountUpdateEnableQueueMask: 46567 if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) { 46568 #if defined(BCM_GREYHOUND2_SUPPORT) 46569 if (SOC_IS_GREYHOUND2(unit)) { 46570 rv = bcmi_gh2_cosq_wred_port_control_get(unit, port, type, 46571 value); 46572 } else 46573 #endif /* BCM_GREYHOUND2_SUPPORT */ 46574 { 46575 rv = READ_WRED_DROP_CTR_CONFIGr(unit, port, &val); 46576 *value = soc_reg_field_get(unit, WRED_DROP_CTR_CONFIGr, 46577 val, QUEUE_MASKf); 46578 } 46579 } 46580 break; 46581 case bcmPortControlWredDropCountUpdateEnableColorMask: 46582 if (soc_feature(unit, soc_feature_wred_drop_counter_per_port)) { 46583 #if defined(BCM_GREYHOUND2_SUPPORT) 46584 if (SOC_IS_GREYHOUND2(unit)) { 46585 rv = bcmi_gh2_cosq_wred_port_control_get(unit, port, type, 46586 value); 46587 } else 46588 #endif /* BCM_GREYHOUND2_SUPPORT */ 46589 { 46590 uint32 fld_val; 46591 rv = READ_WRED_DROP_CTR_CONFIGr(unit, port, &val); 46592 if (BCM_SUCCESS(rv)) { 46593 fld_val = soc_reg_field_get(unit, WRED_DROP_CTR_CONFIGr, 46594 val, COLOR_MASKf); 46595 *value = 0; 46596 if (fld_val & 0x4) { 46597 *value |= (0x1 << bcmColorGreen); 46598 } 46599 if (fld_val & 0x2) { 46600 *value |= (0x1 << bcmColorYellow); 46601 } 46602 if (fld_val & 0x1) { 46603 *value |= (0x1 << bcmColorRed); 46604 } 46605 } 46606 } 46607 } 46608 break; 46609 #endif /* BCM_GREYHOUND_SUPPORT */ 46610 #ifdef BCM_TRIDENT2_SUPPORT 46611 case bcmPortControlProbeSerdesReset: 46612 if (SOC_IS_TD2_TT2(unit)) { 46613 *value = 46614 PORT(unit, port).flags & _PORT_INFO_PROBE_RESET_SERDES ? 46615 1 : 0; 46616 rv = BCM_E_NONE; 46617 } 46618 break; 46619 #endif /* BCM_TRIDENT2_SUPPORT */ 46620 case bcmPortControlMmuTrafficEnable: 46621 rv = bcm_esw_port_enqueue_get(unit, port, value); 46622 break; 46623 case bcmPortControlRxFastLOS: 46624 rv = _bcm_esw_link_fast_get(unit, port, value); 46625 break; 46626 case bcmPortControlLLFCReceive: 46627 case bcmPortControlLLFCTransmit: 46628 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 46629 case bcmPortControlSAFCReceive: 46630 case bcmPortControlSAFCTransmit: 46631 #endif 46632 rv = _bcm_esw_port_llfc_get(unit, port, type, value); 46633 break; 46634 case bcmPortControlTrunkLoadBalancingRandomizer: 46635 #ifdef BCM_TOMAHAWK_SUPPORT 46636 if (soc_feature(unit, soc_feature_randomized_load_balance)) { 46637 rv = _bcm_esw_port_tab_get(unit, port, 46638 OFFSET_TRUNK_RANDOM_LBf, value); 46639 } 46640 #endif /* BCM_TOMAHAWK_SUPPORT */ 46641 break; 46642 case bcmPortControlECMPLevel1LoadBalancingRandomizer: 46643 #ifdef BCM_TOMAHAWK_SUPPORT 46644 if (soc_feature(unit, soc_feature_ecmp_random)) { 46645 rv = _bcm_esw_port_tab_get(unit, port, 46646 OFFSET_ECMP_RANDOM_LBf , value); 46647 } 46648 #endif /* BCM_TOMAHAWK_SUPPORT */ 46649 break; 46650 case bcmPortControlECMPLevel2LoadBalancingRandomizer: 46651 #ifdef BCM_TOMAHAWK_SUPPORT 46652 if (soc_feature(unit, soc_feature_ecmp_random)) { 46653 rv = _bcm_esw_port_tab_get(unit, port, 46654 OFFSET_ECMP_LEVEL2_RANDOM_LBf, 46655 value); 46656 } 46657 #endif /* BCM_TOMAHAWK_SUPPORT */ 46658 break; 46659 case bcmPortControlMcastGroupRemap: 46660 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, NETWORK_PORTf)) { 46661 SOC_IF_ERROR_RETURN 46662 (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, port, &svp_entry)); 46663 *value = soc_SOURCE_VPm_field32_get(unit, &svp_entry, 46664 NETWORK_PORTf); 46665 rv = BCM_E_NONE; 46666 } 46667 break; 46668 case bcmPortControlOOBFCTxReportIngEnable: 46669 if (soc_feature(unit, soc_feature_oob_fc)) { 46670 #ifdef BCM_TOMAHAWK_SUPPORT 46671 if (SOC_IS_TOMAHAWKX(unit)) { 46672 rv = _bcm_th_oob_fc_tx_port_control_get(unit, port, value, 0); 46673 } 46674 #endif 46675 #ifdef BCM_KATANA2_SUPPORT 46676 if (SOC_IS_KATANA2(unit)) { 46677 rv = _bcm_kt2_oob_fc_tx_port_control_get(unit, port, value, 0); 46678 } 46679 #endif 46680 #ifdef BCM_TRIDENT3_SUPPORT 46681 if (SOC_IS_TRIDENT3X(unit)) { 46682 rv = _bcm_td3_oob_fc_tx_port_control_get(unit, port, value, 0); 46683 } 46684 #endif 46685 #ifdef BCM_APACHE_SUPPORT 46686 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 46687 rv = _bcm_ap_oob_fc_tx_port_control_get(unit, port, value, 0); 46688 } 46689 #endif 46690 } 46691 break; 46692 case bcmPortControlOOBFCTxReportEgrEnable: 46693 if (soc_feature(unit, soc_feature_oob_fc)) { 46694 #ifdef BCM_TOMAHAWK_SUPPORT 46695 if (SOC_IS_TOMAHAWKX(unit)) { 46696 rv = _bcm_th_oob_fc_tx_port_control_get(unit, port, value, 1); 46697 } 46698 #endif 46699 #ifdef BCM_APACHE_SUPPORT 46700 if (SOC_IS_APACHE(unit) && !SOC_IS_MONTEREY(unit)) { 46701 rv = _bcm_ap_oob_fc_tx_port_control_get(unit, port, value, 1); 46702 } 46703 #endif 46704 #ifdef BCM_KATANA2_SUPPORT 46705 if (SOC_IS_KATANA2(unit)) { 46706 rv = _bcm_kt2_oob_fc_tx_port_control_get(unit, port, value, 1); 46707 } 46708 #endif 46709 #ifdef BCM_TRIDENT3_SUPPORT 46710 if (SOC_IS_TRIDENT3X(unit)) { 46711 rv = _bcm_td3_oob_fc_tx_port_control_get(unit, port, value, 1); 46712 } 46713 #endif 46714 } 46715 break; 46716 46717 case bcmPortControlSubportTagSize: 46718 #ifdef BCM_HGPROXY_COE_SUPPORT 46719 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 46720 DESTINATION_SUBPORT_TAG_TYPEf)) { 46721 46722 int local_port = 0; 46723 egr_port_entry_t egr_port_entry; 46724 if (BCM_GPORT_IS_SET(port)) { 46725 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 46726 } else { 46727 if(!SOC_PORT_VALID(unit, port)) { 46728 return BCM_E_PORT; 46729 } else { 46730 local_port = port; 46731 } 46732 } 46733 46734 SOC_IF_ERROR_RETURN 46735 (READ_EGR_PORTm(unit, MEM_BLOCK_ANY, local_port, &egr_port_entry)); 46736 *value = soc_EGR_PORTm_field32_get(unit, &egr_port_entry, 46737 DESTINATION_SUBPORT_TAG_TYPEf); 46738 rv = BCM_E_NONE; 46739 } 46740 if (SOC_IS_TRIDENT3X(unit)) { 46741 *value = 0; 46742 rv = BCM_E_NONE; 46743 } 46744 #endif 46745 break; 46746 46747 case bcmPortControlSystemPortOverride: 46748 #ifdef BCM_HGPROXY_COE_SUPPORT 46749 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, 46750 VT_SYS_PORT_OVERRIDEf)) { 46751 46752 rv = bcmi_xgs5_subport_subtag_port_override_get(unit, port, 46753 value); 46754 } 46755 #endif 46756 break; 46757 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 46758 case bcmPortControlSampleIngressDest: 46759 if(soc_feature(unit, soc_feature_sflow_ing_mem)) { 46760 sflow_ing_data_source_entry_t sflow_entry; 46761 uint32 field_values[2] = {0, 0}; 46762 BCM_IF_ERROR_RETURN 46763 (READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 46764 &sflow_entry)); 46765 soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry, 46766 CPUf, &field_values[0]); 46767 soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry, 46768 MIRRORf, &field_values[1]); 46769 *value = field_values[0] | (field_values[1] << 1); 46770 rv = BCM_E_NONE; 46771 } 46772 break; 46773 case bcmPortControlSampleFlexDest: 46774 if(soc_feature(unit, soc_feature_sflow_flex)) { 46775 sflow_ing_flex_data_source_entry_t sflow_entry; 46776 uint32 field_values[2] = {0, 0}; 46777 BCM_IF_ERROR_RETURN 46778 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 46779 &sflow_entry)); 46780 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry, 46781 CPUf, &field_values[0]); 46782 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry, 46783 MIRRORf, &field_values[1]); 46784 *value = field_values[0] | (field_values[1] << 1); 46785 rv = BCM_E_NONE; 46786 } 46787 break; 46788 case bcmPortControlSampleFlexRate: 46789 if(soc_feature(unit, soc_feature_sflow_flex)) { 46790 sflow_ing_flex_data_source_entry_t sflow_entry; 46791 uint32 field_enable, field_thresh; 46792 46793 /* Read ENABLE and THRESHOLD fields from flex rate data table */ 46794 BCM_IF_ERROR_RETURN 46795 (READ_SFLOW_ING_FLEX_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 46796 &sflow_entry)); 46797 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry, 46798 ENABLEf, &field_enable); 46799 soc_SFLOW_ING_FLEX_DATA_SOURCEm_field_get(unit, &sflow_entry, 46800 THRESHOLDf, 46801 &field_thresh); 46802 46803 if (field_enable) { 46804 if (field_thresh) { 46805 *value = (1 << (SFLOW_RANGE_MAX(unit))) / field_thresh; 46806 } else { 46807 *value = 1 << (SFLOW_RANGE_MAX(unit)); 46808 } 46809 } else { 46810 *value = 0; 46811 if (field_thresh) { 46812 return BCM_E_INTERNAL; 46813 } 46814 } 46815 rv = BCM_E_NONE; 46816 } 46817 break; 46818 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */ 46819 #ifdef BCM_XGS3_SWITCH_SUPPORT 46820 case bcmPortControlSampleIngressEnable: 46821 if (SOC_IS_XGS3_SWITCH(unit)) { 46822 uint32 regval = 0; 46823 uint32 field_enable = 0; 46824 #ifdef BCM_TOMAHAWK_SUPPORT 46825 sflow_ing_data_source_entry_t sflow_entry; 46826 #endif /* BCM_TOMAHAWK_SUPPORT */ 46827 46828 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 46829 if (soc_feature(unit, soc_feature_sflow_ing_mem)) { 46830 BCM_IF_ERROR_RETURN( 46831 READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 46832 &sflow_entry)); 46833 46834 soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry, ENABLEf, 46835 &field_enable); 46836 } else 46837 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */ 46838 { 46839 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) { 46840 return BCM_E_UNAVAIL; 46841 } 46842 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, ®val)); 46843 field_enable = soc_reg_field_get(unit, SFLOW_ING_THRESHOLDr, regval, 46844 ENABLEf); 46845 } 46846 46847 *value = field_enable ? 1 : 0; 46848 rv = BCM_E_NONE; 46849 } else { 46850 rv = BCM_E_UNAVAIL; 46851 } 46852 break; 46853 case bcmPortControlSampleEgressEnable: 46854 if (SOC_IS_XGS3_SWITCH(unit)) { 46855 uint32 regval = 0; 46856 uint32 field_enable = 0; 46857 46858 if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) { 46859 return BCM_E_UNAVAIL; 46860 } 46861 BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, ®val)); 46862 field_enable = soc_reg_field_get(unit, SFLOW_EGR_THRESHOLDr, regval, 46863 ENABLEf); 46864 46865 *value = field_enable ? 1 : 0; 46866 rv = BCM_E_NONE; 46867 } else { 46868 rv = BCM_E_UNAVAIL; 46869 } 46870 break; 46871 case bcmPortControlSampleIngressRate: 46872 if (SOC_IS_XGS3_SWITCH(unit)) { 46873 uint32 regval = 0; 46874 uint32 field_value; 46875 #ifdef BCM_TOMAHAWK_SUPPORT 46876 sflow_ing_data_source_entry_t sflow_entry; 46877 #endif /* BCM_TOMAHAWK_SUPPORT */ 46878 46879 #if defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 46880 if (soc_feature(unit, soc_feature_sflow_ing_mem)) { 46881 BCM_IF_ERROR_RETURN( 46882 READ_SFLOW_ING_DATA_SOURCEm(unit, MEM_BLOCK_ANY, port, 46883 &sflow_entry)); 46884 46885 soc_SFLOW_ING_DATA_SOURCEm_field_get(unit, &sflow_entry, THRESHOLDf, 46886 &field_value); 46887 } else 46888 #endif /* BCM_TOMAHAWK_SUPPORT || BCM_TRIDENT3_SUPPORT */ 46889 { 46890 if (!SOC_REG_IS_VALID(unit, SFLOW_ING_THRESHOLDr)) { 46891 return BCM_E_UNAVAIL; 46892 } 46893 BCM_IF_ERROR_RETURN(READ_SFLOW_ING_THRESHOLDr(unit, port, ®val)); 46894 46895 field_value = soc_reg_field_get(unit, SFLOW_ING_THRESHOLDr, 46896 regval, THRESHOLDf); 46897 } 46898 46899 /* 46900 * For early sFlow implementations the 16-bit threshold value 46901 * is compared to bits [23:8] of the sFlow random number. 46902 */ 46903 if (soc_feature(unit, soc_feature_sample_offset8)) { 46904 field_value <<= 8; 46905 } 46906 46907 if (field_value) { 46908 *value = (1 << (SFLOW_RANGE_MAX(unit))) / field_value; 46909 } else { 46910 *value = 0; 46911 } 46912 rv = BCM_E_NONE; 46913 } else { 46914 rv = BCM_E_UNAVAIL; 46915 } 46916 break; 46917 case bcmPortControlSampleEgressRate: 46918 if (SOC_IS_XGS3_SWITCH(unit)) { 46919 uint32 regval; 46920 uint32 field_value; 46921 46922 if (!SOC_REG_IS_VALID(unit, SFLOW_EGR_THRESHOLDr)) { 46923 return BCM_E_UNAVAIL; 46924 } 46925 BCM_IF_ERROR_RETURN(READ_SFLOW_EGR_THRESHOLDr(unit, port, ®val)); 46926 46927 field_value = soc_reg_field_get(unit, SFLOW_EGR_THRESHOLDr, 46928 regval, THRESHOLDf); 46929 46930 /* 46931 * For early sFlow implementations the 16-bit threshold value 46932 * is compared to bits [23:8] of the sFlow random number. 46933 */ 46934 if (soc_feature(unit, soc_feature_sample_offset8)) { 46935 field_value <<= 8; 46936 } 46937 46938 if (field_value) { 46939 *value = (1 << (SFLOW_RANGE_MAX(unit))) / field_value; 46940 } else { 46941 *value = 0; 46942 } 46943 rv = BCM_E_NONE; 46944 } else { 46945 rv = BCM_E_UNAVAIL; 46946 } 46947 break; 46948 #endif 46949 case bcmPortControlExternalBufferEnable: 46950 #if defined(BCM_KATANA2_SUPPORT) 46951 if (SOC_IS_KATANA2(unit) && soc_feature(unit, soc_feature_ddr3)) { 46952 rv = _bcm_kt2_cosq_port_ext_buf_get(unit, port, value); 46953 } 46954 #endif 46955 break; 46956 #ifdef BCM_HURRICANE3_SUPPORT 46957 case bcmPortControlTrustMimlPri: 46958 if (soc_feature(unit, soc_feature_miml)) { 46959 rv = _bcm_esw_port_tab_get(unit, port, 46960 USE_MIML_PCP_FOR_PRIf, value); 46961 } 46962 break; 46963 case bcmPortControlTrustCustomHeaderPri: 46964 if (soc_feature(unit, soc_feature_custom_header)) { 46965 rv = _bcm_esw_port_tab_get(unit, port, 46966 USE_CUSTOM_HEADER_FOR_PRIf, value); 46967 } 46968 break; 46969 case bcmPortControlCustomHeaderEncapEnable: 46970 if (soc_feature(unit, soc_feature_custom_header)) { 46971 uint64 val64; 46972 46973 rv = READ_EGR_PORT_64r(unit, port, &val64); 46974 if (BCM_SUCCESS(rv)) { 46975 *value = soc_reg64_field32_get(unit, EGR_PORT_64r, 46976 val64, CUSTOM_HEADER_ENABLEf); 46977 } 46978 } 46979 break; 46980 #endif /* BCM_HURRICANE3_SUPPORT */ 46981 case bcmPortControl1588P2PDelay: 46982 { 46983 uint32 link_delay; 46984 int mac_rx_latency = 0; 46985 int speed; 46986 rv = bcm_esw_port_speed_get(unit, port, &speed); 46987 soc_property_port_get(unit, port, 46988 spn_LINK_DELAY(speed), mac_rx_latency); 46989 46990 if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAYr, port)) { 46991 soc_reg32_get(unit, EGR_1588_LINK_DELAYr, 46992 port, LINK_DELAYf, &link_delay); 46993 *value = link_delay - mac_rx_latency; 46994 rv = BCM_E_NONE; 46995 } else if (SOC_REG_PORT_VALID(unit, EGR_1588_LINK_DELAY_64r, port)) { 46996 soc_reg_above_64_field32_read(unit, EGR_1588_LINK_DELAY_64r, 46997 port, 0, LINK_DELAYf, &link_delay); 46998 *value = link_delay - mac_rx_latency; 46999 rv = BCM_E_NONE; 47000 } else { 47001 rv = BCM_E_UNAVAIL; 47002 /* No LINK_DELAY register, so no-op */ 47003 } 47004 } 47005 break; 47006 case bcmPortControlPacketTimeStampInsertRx: 47007 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 47008 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 47009 if (soc_feature(unit, soc_feature_timestamp)) { 47010 int ing_insert; 47011 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 47012 47013 BCM_IF_ERROR_RETURN( 47014 _bcm_esw_port_tab_get(unit, port, INSERT_RX_TIMESTAMPf, 47015 &ing_insert)); 47016 *value = ing_insert; 47017 rv = BCM_E_NONE; 47018 } 47019 #endif 47020 break; 47021 case bcmPortControlPacketTimeStampInsertTx: 47022 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 47023 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 47024 if (soc_feature(unit, soc_feature_timestamp)) { 47025 uint32 regval; 47026 uint32 egr_insert; 47027 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 47028 47029 BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, ®val)); 47030 egr_insert = soc_reg_field_get(unit, EGR_TS_CONTROLr, regval, 47031 INSERT_TX_TIMESTAMPf); 47032 *value = (int)egr_insert; 47033 rv = BCM_E_NONE; 47034 } 47035 #endif 47036 break; 47037 case bcmPortControlPacketTimeStampSrcPortInsertCancel: 47038 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 47039 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 47040 if (soc_feature(unit, soc_feature_timestamp)) { 47041 int ing_disable; 47042 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 47043 47044 BCM_IF_ERROR_RETURN( 47045 _bcm_esw_port_tab_get(unit, port, DISABLE_TIMESTAMPINGf, 47046 &ing_disable)); 47047 *value = ing_disable; 47048 rv = BCM_E_NONE; 47049 } 47050 #endif 47051 break; 47052 case bcmPortControlPacketTimeStampDestPortInsertCancel: 47053 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 47054 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 47055 if (soc_feature(unit, soc_feature_timestamp)) { 47056 uint32 regval; 47057 uint32 egr_disable; 47058 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 47059 47060 BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, ®val)); 47061 egr_disable = soc_reg_field_get(unit, EGR_TS_CONTROLr, regval, 47062 DISABLE_TIMESTAMPINGf); 47063 *value = (int)egr_disable; 47064 rv = BCM_E_NONE; 47065 } 47066 #endif 47067 break; 47068 case bcmPortControlPacketTimeStampRxId: 47069 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 47070 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 47071 if (soc_feature(unit, soc_feature_timestamp)) { 47072 uint32 regval; 47073 egr_ts_ing_port_map_entry_t egr_ts_entry; 47074 uint32 id; 47075 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 47076 if (SOC_REG_IS_VALID(unit, EGR_TS_ING_PORT_MAPr)) { 47077 BCM_IF_ERROR_RETURN(READ_EGR_TS_ING_PORT_MAPr(unit, port, ®val)); 47078 id = soc_reg_field_get(unit, EGR_TS_ING_PORT_MAPr, regval, 47079 TS_RX_ORIGIN_IDf); 47080 *value = (int)id; 47081 } else { 47082 47083 BCM_IF_ERROR_RETURN( 47084 READ_EGR_TS_ING_PORT_MAPm(unit, MEM_BLOCK_ANY, port, &egr_ts_entry)); 47085 soc_EGR_TS_ING_PORT_MAPm_field_get(unit, &egr_ts_entry, TS_RX_ORIGIN_IDf, 47086 ®val); 47087 *value = (int)regval; 47088 47089 } 47090 rv = BCM_E_NONE; 47091 } 47092 #endif 47093 break; 47094 case bcmPortControlPacketTimeStampTxId: 47095 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 47096 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 47097 if (soc_feature(unit, soc_feature_timestamp)) { 47098 uint32 regval; 47099 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 47100 47101 if (soc_reg_field_valid(unit, EGR_TS_CONTROL_2r, TS_TX_ORIGIN_IDf)) 47102 { 47103 BCM_IF_ERROR_RETURN( 47104 READ_EGR_TS_CONTROL_2r(unit, port, ®val)); 47105 *value = soc_reg_field_get( 47106 unit, EGR_TS_CONTROL_2r, regval, TS_TX_ORIGIN_IDf); 47107 } else { 47108 BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, ®val)); 47109 *value = soc_reg_field_get( 47110 unit, EGR_TS_CONTROLr, regval, TS_TX_ORIGIN_IDf); 47111 } 47112 rv = BCM_E_NONE; 47113 } 47114 #endif 47115 break; 47116 case bcmPortControlPacketTimeStampByteMeterAdjust: 47117 #if defined(BCM_TOMAHAWK2_SUPPORT) || \ 47118 defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 47119 if (soc_feature(unit, soc_feature_timestamp) && !SOC_IS_TOMAHAWK3(unit)) 47120 { 47121 uint32 regval; 47122 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 47123 47124 BCM_IF_ERROR_RETURN(READ_EGR_TS_CONTROLr(unit, port, ®val)); 47125 *value = soc_reg_field_get(unit, EGR_TS_CONTROLr, regval, 47126 TS_ADJUST_METERSf); 47127 rv = BCM_E_NONE; 47128 } 47129 #endif 47130 break; 47131 case bcmPortControlE2EFCTransmitEnable: 47132 if (soc_feature(unit, soc_feature_e2efc)) { 47133 uint32 fval; 47134 uint64 val; 47135 47136 if (!IS_HG_PORT(unit, port)) { 47137 LOG_ERROR( 47138 BSL_LS_BCM_PORT, 47139 (BSL_META_U(unit, 47140 "Error: unit %d port %d is not a Higig port. " 47141 "E2EFC messages can only be transmitted to " 47142 "or received from Higig ports.\n"), 47143 unit, port)); 47144 return BCM_E_PARAM; 47145 } 47146 #if defined(BCM_KATANA2_SUPPORT) 47147 if (SOC_IS_KATANA2(unit)) { 47148 BCM_IF_ERROR_RETURN(READ_E2EFC_IBP_ENr(unit, &fval)); 47149 *value = fval; 47150 } else 47151 #endif 47152 if (IS_XL_PORT(unit, port)) { 47153 BCM_IF_ERROR_RETURN(READ_XLMAC_E2E_CTRLr(unit, port, &val)); 47154 fval = soc_reg64_field32_get(unit, XLMAC_E2E_CTRLr, 47155 val, E2E_ENABLEf); 47156 *value = fval; 47157 } else if (IS_CL_PORT(unit, port)) { 47158 BCM_IF_ERROR_RETURN(READ_CLMAC_E2E_CTRLr(unit, port, &val)); 47159 fval = soc_reg64_field32_get(unit, CLMAC_E2E_CTRLr, 47160 val, E2E_ENABLEf); 47161 *value = fval; 47162 } else { 47163 return BCM_E_PARAM; 47164 } 47165 47166 rv = BCM_E_NONE; 47167 } 47168 break; 47169 case bcmPortControlE2EFCReceiveEnable: 47170 if (soc_feature(unit, soc_feature_e2efc)) { 47171 uint32 val, fval; 47172 47173 BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val)); 47174 fval = soc_reg_field_get(unit, IE2E_CONTROLr, 47175 val, IBP_ENABLEf); 47176 *value = fval; 47177 rv = BCM_E_NONE; 47178 } 47179 break; 47180 case bcmPortControlE2EFCCopyToCpuEnable: 47181 if (soc_feature(unit, soc_feature_e2efc)) { 47182 uint32 val, fval; 47183 47184 BCM_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, &val)); 47185 fval = soc_reg_field_get(unit, IE2E_CONTROLr, 47186 val, IBP_TOCPUf); 47187 *value = fval; 47188 rv = BCM_E_NONE; 47189 } 47190 break; 47191 /* Higher 3 bytes of Destination MAC address */ 47192 case bcmPortControlE2EFCDestMacOui: 47193 if (soc_feature(unit, soc_feature_e2efc)) { 47194 uint32 val_hi; 47195 uint64 val_64, data_0; 47196 soc_reg_t reg; 47197 #if defined(BCM_KATANA2_SUPPORT) 47198 uint32 val; 47199 #endif 47200 if (!IS_HG_PORT(unit, port)) { 47201 LOG_ERROR( 47202 BSL_LS_BCM_PORT, 47203 (BSL_META_U(unit, 47204 "Error: unit %d port %d is not a Higig port. " 47205 "E2EFC messages can only be transmitted to " 47206 "or received from Higig ports.\n"), 47207 unit, port)); 47208 return BCM_E_PARAM; 47209 } 47210 #if defined(BCM_KATANA2_SUPPORT) 47211 if (SOC_IS_KATANA2(unit)) { 47212 #if defined(BCM_SABER2_SUPPORT) 47213 if (SOC_IS_SABER2(unit)) { 47214 /* Do nothing */ 47215 } else 47216 #endif /* BCM_SABER2_SUPPORT */ 47217 { 47218 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val)); 47219 val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f); 47220 *value = (val_hi >> 8) & 0xffffff; 47221 rv = BCM_E_NONE; 47222 break; 47223 } 47224 } 47225 #endif /* BCM_KATANA2_SUPPORT */ 47226 if (IS_XL_PORT(unit, port)) { 47227 reg = XLMAC_E2EFC_DATA_HDR_0r; 47228 } else if (IS_CL_PORT(unit, port)) { 47229 reg = CLMAC_E2EFC_DATA_HDR_0r; 47230 } else { 47231 return BCM_E_PARAM; 47232 } 47233 47234 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, 47235 port, 0, &val_64)); 47236 data_0 = soc_reg64_field_get(unit, reg, 47237 val_64, E2EFC_DATA_HDR_0f); 47238 COMPILER_64_TO_32_HI(val_hi, data_0); 47239 *value = (val_hi >> 8) & 0xffffff; 47240 rv = BCM_E_NONE; 47241 } 47242 break; 47243 /* Lower 3 bytes of Destination MAC address */ 47244 case bcmPortControlE2EFCDestMacNonOui: 47245 if (soc_feature(unit, soc_feature_e2efc)) { 47246 uint32 val_lo, val_hi; 47247 uint64 val_64, data_0; 47248 soc_reg_t reg; 47249 #if defined(BCM_KATANA2_SUPPORT) 47250 uint32 val; 47251 #endif 47252 if (!IS_HG_PORT(unit, port)) { 47253 LOG_ERROR( 47254 BSL_LS_BCM_PORT, 47255 (BSL_META_U(unit, 47256 "Error: unit %d port %d is not a Higig port. " 47257 "E2EFC messages can only be transmitted to " 47258 "or received from Higig ports.\n"), 47259 unit, port)); 47260 return BCM_E_PARAM; 47261 } 47262 #if defined(BCM_KATANA2_SUPPORT) 47263 if (SOC_IS_KATANA2(unit)) { 47264 #if defined(BCM_SABER2_SUPPORT) 47265 if (SOC_IS_SABER2(unit)) { 47266 /* Do nothing */ 47267 } else 47268 #endif /* BCM_SABER2_SUPPORT */ 47269 { 47270 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D0r, port, 0, &val)); 47271 val_hi = soc_reg_field_get(unit, XIBP_D0r, val, DATA_BYTES_0_3f); 47272 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val)); 47273 val_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f); 47274 *value = ((val_hi & 0xff) << 16) | ((val_lo >> 16) & 0xffff); 47275 rv = BCM_E_NONE; 47276 break; 47277 } 47278 } 47279 #endif /* BCM_KATANA2_SUPPORT */ 47280 if (IS_XL_PORT(unit, port)) { 47281 reg = XLMAC_E2EFC_DATA_HDR_0r; 47282 } else if (IS_CL_PORT(unit, port)) { 47283 reg = CLMAC_E2EFC_DATA_HDR_0r; 47284 } else { 47285 return BCM_E_PARAM; 47286 } 47287 47288 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, 47289 port, 0, &val_64)); 47290 data_0 = soc_reg64_field_get(unit, reg, 47291 val_64, E2EFC_DATA_HDR_0f); 47292 COMPILER_64_TO_32_LO(val_lo, data_0); 47293 COMPILER_64_TO_32_HI(val_hi, data_0); 47294 *value = ((val_hi & 0xff) << 16) | ((val_lo >> 16) & 0xffff); 47295 rv = BCM_E_NONE; 47296 } 47297 break; 47298 /* Higher 3 bytes of Source MAC address */ 47299 case bcmPortControlE2EFCSrcMacOui: 47300 if (soc_feature(unit, soc_feature_e2efc)) { 47301 uint32 val_0_lo, val_1_hi; 47302 uint64 val_64, data_1, data_0; 47303 soc_reg_t reg_0, reg_1; 47304 #if defined(BCM_KATANA2_SUPPORT) 47305 uint32 val; 47306 #endif 47307 if (!IS_HG_PORT(unit, port)) { 47308 LOG_ERROR( 47309 BSL_LS_BCM_PORT, 47310 (BSL_META_U(unit, 47311 "Error: unit %d port %d is not a Higig port. " 47312 "E2EFC messages can only be transmitted to " 47313 "or received from Higig ports.\n"), 47314 unit, port)); 47315 return BCM_E_PARAM; 47316 } 47317 #if defined(BCM_KATANA2_SUPPORT) 47318 if (SOC_IS_KATANA2(unit)) { 47319 #if defined(BCM_SABER2_SUPPORT) 47320 if (SOC_IS_SABER2(unit)) { 47321 /* Do nothing */ 47322 } else 47323 #endif /* BCM_SABER2_SUPPORT */ 47324 { 47325 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D1r, port, 0, &val)); 47326 val_0_lo = soc_reg_field_get(unit, XIBP_D1r, val, DATA_BYTES_4_7f); 47327 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val)); 47328 val_1_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f); 47329 *value = ((val_1_hi >> 24) & 0xff) | ((val_0_lo & 0xffff) << 8); 47330 rv = BCM_E_NONE; 47331 break; 47332 } 47333 } 47334 #endif /* BCM_KATANA2_SUPPORT */ 47335 if (IS_XL_PORT(unit, port)) { 47336 reg_0 = XLMAC_E2EFC_DATA_HDR_0r; 47337 reg_1 = XLMAC_E2EFC_DATA_HDR_1r; 47338 } else if (IS_CL_PORT(unit, port)) { 47339 reg_0 = CLMAC_E2EFC_DATA_HDR_0r; 47340 reg_1 = CLMAC_E2EFC_DATA_HDR_1r; 47341 } else { 47342 return BCM_E_PARAM; 47343 } 47344 47345 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_1, 47346 port, 0, &val_64)); 47347 data_1 = soc_reg64_field_get(unit, reg_1, 47348 val_64, E2EFC_DATA_HDR_1f); 47349 COMPILER_64_TO_32_HI(val_1_hi, data_1); 47350 /* SA MAC setting across 2 registers */ 47351 COMPILER_64_ZERO(val_64); 47352 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg_0, 47353 port, 0, &val_64)); 47354 data_0 = soc_reg64_field_get(unit, reg_0, 47355 val_64, E2EFC_DATA_HDR_0f); 47356 COMPILER_64_TO_32_LO(val_0_lo, data_0); 47357 *value = ((val_1_hi >> 24) & 0xff) | ((val_0_lo & 0xffff) << 8); 47358 rv = BCM_E_NONE; 47359 } 47360 break; 47361 /* Lower 3 bytes of Source MAC address */ 47362 case bcmPortControlE2EFCSrcMacNonOui: 47363 if (soc_feature(unit, soc_feature_e2efc)) { 47364 uint32 val_hi; 47365 uint64 val_64, data_1; 47366 soc_reg_t reg; 47367 #if defined(BCM_KATANA2_SUPPORT) 47368 uint32 val; 47369 #endif 47370 if (!IS_HG_PORT(unit, port)) { 47371 LOG_ERROR( 47372 BSL_LS_BCM_PORT, 47373 (BSL_META_U(unit, 47374 "Error: unit %d port %d is not a Higig port. " 47375 "E2EFC messages can only be transmitted to " 47376 "or received from Higig ports.\n"), 47377 unit, port)); 47378 return BCM_E_PARAM; 47379 } 47380 #if defined(BCM_KATANA2_SUPPORT) 47381 if (SOC_IS_KATANA2(unit)) { 47382 #if defined(BCM_SABER2_SUPPORT) 47383 if (SOC_IS_SABER2(unit)) { 47384 /* Do nothing */ 47385 } else 47386 #endif /* BCM_SABER2_SUPPORT */ 47387 { 47388 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D2r, port, 0, &val)); 47389 val_hi = soc_reg_field_get(unit, XIBP_D2r, val, DATA_BYTES_8_11f); 47390 *value = val_hi & 0xffffff; 47391 rv = BCM_E_NONE; 47392 break; 47393 } 47394 } 47395 #endif /* BCM_KATANA2_SUPPORT */ 47396 47397 if (IS_XL_PORT(unit, port)) { 47398 reg = XLMAC_E2EFC_DATA_HDR_1r; 47399 } else if (IS_CL_PORT(unit, port)) { 47400 reg = CLMAC_E2EFC_DATA_HDR_1r; 47401 } else { 47402 return BCM_E_PARAM; 47403 } 47404 47405 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, 47406 port, 0, &val_64)); 47407 data_1 = soc_reg64_field_get(unit, reg, 47408 val_64, E2EFC_DATA_HDR_1f); 47409 COMPILER_64_TO_32_HI(val_hi, data_1); 47410 *value = val_hi & 0xffffff; 47411 rv = BCM_E_NONE; 47412 } 47413 break; 47414 case bcmPortControlE2EFCEtherType: 47415 if (soc_feature(unit, soc_feature_e2efc)) { 47416 uint32 val_lo; 47417 uint64 val_64, data_1; 47418 soc_reg_t reg; 47419 #if defined(BCM_KATANA2_SUPPORT) 47420 uint32 val; 47421 #endif 47422 if (!IS_HG_PORT(unit, port)) { 47423 LOG_ERROR( 47424 BSL_LS_BCM_PORT, 47425 (BSL_META_U(unit, 47426 "Error: unit %d port %d is not a Higig port. " 47427 "E2EFC messages can only be transmitted to " 47428 "or received from Higig ports.\n"), 47429 unit, port)); 47430 return BCM_E_PARAM; 47431 } 47432 #if defined(BCM_KATANA2_SUPPORT) 47433 if (SOC_IS_KATANA2(unit)) { 47434 #if defined(BCM_SABER2_SUPPORT) 47435 if (SOC_IS_SABER2(unit)) { 47436 /* Do nothing */ 47437 } else 47438 #endif /* BCM_SABER2_SUPPORT */ 47439 { 47440 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val)); 47441 val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f); 47442 *value = (val_lo >> 16) & 0xffff; 47443 rv = BCM_E_NONE; 47444 break; 47445 } 47446 } 47447 #endif /* BCM_KATANA2_SUPPORT */ 47448 if (IS_XL_PORT(unit, port)) { 47449 reg = XLMAC_E2EFC_DATA_HDR_1r; 47450 } else if (IS_CL_PORT(unit, port)) { 47451 reg = CLMAC_E2EFC_DATA_HDR_1r; 47452 } else { 47453 return BCM_E_PARAM; 47454 } 47455 47456 BCM_IF_ERROR_RETURN( 47457 soc_reg_get(unit, reg, port, 0, &val_64)); 47458 data_1 = soc_reg64_field_get(unit, reg, 47459 val_64, E2EFC_DATA_HDR_1f); 47460 COMPILER_64_TO_32_LO(val_lo, data_1); 47461 *value = (val_lo >> 16) & 0xffff; 47462 rv = BCM_E_NONE; 47463 } 47464 break; 47465 case bcmPortControlE2EFCOpcode: 47466 if (soc_feature(unit, soc_feature_e2efc)) { 47467 uint32 val_lo; 47468 uint64 val_64, data_1; 47469 soc_reg_t reg; 47470 #if defined(BCM_KATANA2_SUPPORT) 47471 uint32 val; 47472 #endif 47473 if (!IS_HG_PORT(unit, port)) { 47474 LOG_ERROR( 47475 BSL_LS_BCM_PORT, 47476 (BSL_META_U(unit, 47477 "Error: unit %d port %d is not a Higig port. " 47478 "E2EFC messages can only be transmitted to " 47479 "or received from Higig ports.\n"), 47480 unit, port)); 47481 return BCM_E_PARAM; 47482 } 47483 #if defined(BCM_KATANA2_SUPPORT) 47484 if (SOC_IS_KATANA2(unit)) { 47485 #if defined(BCM_SABER2_SUPPORT) 47486 if (SOC_IS_SABER2(unit)) { 47487 /* Do nothing */ 47488 } else 47489 #endif /* BCM_SABER2_SUPPORT */ 47490 { 47491 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_D3r, port, 0, &val)); 47492 val_lo = soc_reg_field_get(unit, XIBP_D3r, val, D_BYTES_12_15f); 47493 *value = val_lo & 0xffff; 47494 rv = BCM_E_NONE; 47495 break; 47496 } 47497 } 47498 #endif /* BCM_KATANA2_SUPPORT */ 47499 if (IS_XL_PORT(unit, port)) { 47500 reg = XLMAC_E2EFC_DATA_HDR_1r; 47501 } else if (IS_CL_PORT(unit, port)) { 47502 reg = CLMAC_E2EFC_DATA_HDR_1r; 47503 } else { 47504 return BCM_E_PARAM; 47505 } 47506 47507 BCM_IF_ERROR_RETURN(soc_reg_get(unit, reg, 47508 port, 0, &val_64)); 47509 data_1 = soc_reg64_field_get(unit, reg, 47510 val_64, E2EFC_DATA_HDR_1f); 47511 COMPILER_64_TO_32_LO(val_lo, data_1); 47512 *value = val_lo & 0xffff; 47513 rv = BCM_E_NONE; 47514 } 47515 break; 47516 case bcmPortControlIntEnable: 47517 #if defined(BCM_TOMAHAWK3_SUPPORT) 47518 if (soc_feature(unit, soc_feature_inband_network_telemetry)) { 47519 rv = _bcm_esw_port_tab_get(unit, port, INT_ENABLEf, value); 47520 } 47521 #endif 47522 break; 47523 case bcmPortControlIntTurnaround: 47524 #if defined(BCM_TOMAHAWK3_SUPPORT) 47525 if (soc_feature(unit, soc_feature_inband_network_telemetry)) { 47526 SOC_IF_ERROR_RETURN 47527 (READ_INT_TURNAROUND_EN_BMAPm(unit, MEM_BLOCK_ANY, 0, 47528 &int_turnaround_en_bmap_entry)); 47529 soc_mem_pbmp_field_get(unit, INT_TURNAROUND_EN_BMAPm, 47530 &int_turnaround_en_bmap_entry, PORT_BITMAPf, &pbmp); 47531 *value = 0; 47532 if (SOC_PBMP_MEMBER(pbmp, port)) 47533 *value = 1; 47534 } 47535 #endif 47536 break; 47537 case bcmPortControlObmClassifierPriority: 47538 case bcmPortControlObmClassifierEnableDscp: 47539 case bcmPortControlObmClassifierEnableMpls: 47540 case bcmPortControlObmClassifierEnableEtag: 47541 case bcmPortControlObmClassifierEtagEthertype: 47542 case bcmPortControlObmClassifierVntagEthertype: 47543 47544 #if defined(BCM_MONTEREY_SUPPORT) 47545 if (SOC_IS_MONTEREY(unit)) { 47546 rv = bcm_mn_obm_classifier_port_control_get(unit, port, type, value); 47547 } else 47548 #endif 47549 #if defined(BCM_APACHE_SUPPORT) 47550 if (SOC_IS_APACHE(unit)) { 47551 rv = bcm_apache_obm_classifier_port_control_get(unit, port, type, value); 47552 } else 47553 #endif 47554 { 47555 rv = BCM_E_UNAVAIL; 47556 } 47557 break; 47558 case bcmPortControlObmClassifierInternal: 47559 #if defined(BCM_MONTEREY_SUPPORT) 47560 if (SOC_IS_MONTEREY(unit)) { 47561 rv = bcm_mn_obm_classifier_port_control_get(unit, port, type, value); 47562 } else 47563 #endif 47564 { 47565 rv = BCM_E_UNAVAIL; 47566 } 47567 break; 47568 47569 case bcmPortControlWirelessCosMapSelect: 47570 #if defined(BCM_HELIX5_SUPPORT) 47571 if (SOC_IS_HELIX5(unit)) { 47572 rv = _bcm_esw_port_tab_get(unit, port, WIRED_WIRELESSf, value); 47573 } else 47574 #endif 47575 { 47576 rv = BCM_E_UNAVAIL; 47577 } 47578 break; 47579 47580 case bcmPortControlHiGigCosSelect: 47581 #if defined(BCM_HELIX5_SUPPORT) 47582 if (SOC_IS_HELIX5(unit)) { 47583 rv = bcm_hx5_hgcos_select_port_control_get(unit, port, type, value); 47584 } else 47585 #endif 47586 { 47587 rv = BCM_E_UNAVAIL; 47588 } 47589 break; 47590 #ifdef BCM_MONTEREY_SUPPORT 47591 case bcmPortControlObmInterruptTypeDropPreempt : 47592 case bcmPortControlObmInterruptTypeOverflowPreempt : 47593 case bcmPortControlObmInterruptTypeDropExpress : 47594 case bcmPortControlObmInterruptTypeOverflowExpress : 47595 if (SOC_IS_MONTEREY(unit)) { 47596 rv = bcm_mn_obm_interrupt_port_control_get(unit, port, type, value); 47597 47598 }else 47599 #endif 47600 { 47601 rv = BCM_E_UNAVAIL; 47602 } 47603 break; 47604 default: 47605 break; 47606 } 47607 47608 if (BCM_SUCCESS(rv)) { 47609 LOG_INFO(BSL_LS_BCM_PORT, 47610 (BSL_META_U(unit, 47611 "bcm_port_control_get: u=%d p=%d v=%d\n"), 47612 unit, port, *value)); 47613 } else { 47614 /* On error, the value is not guaranteed valid */ 47615 LOG_INFO(BSL_LS_BCM_PORT, 47616 (BSL_META_U(unit, 47617 "bcm_port_control_get failure: u=%d p=%d: %s\n"), 47618 unit, port, bcm_errmsg(rv))); 47619 } 47620 47621 return rv; 47622 } 47623 47624 /* 47625 * Function: 47626 * bcm_esw_port_mac_failover_notify 47627 * Description: 47628 * disable RX routine on MAC 47629 * note: omitting XLMAC since it should not be disabled during failover 47630 * Parameters: 47631 * unit - Device number 47632 * port - Port number 47633 * Return Value: 47634 * BCM_E_NONE 47635 * BCM_E_UNAVAIL - Functionality not available 47636 */ 47637 int 47638 _bcm_esw_port_mac_failover_notify(int unit, bcm_port_t port) 47639 { 47640 int rv = BCM_E_NONE; 47641 47642 if (!SOC_USE_PORTCTRL(unit)) { 47643 /* disable RX for MAC and XMAC controller. 47644 for TD2, lag failover has been implemented within XLMAC; 47645 thus, XLMAC rx should not be disabled during failover */ 47646 PORT_LOCK(unit); 47647 rv = (MAC_CONTROL_SET(PORT(unit, port).p_mac, unit, port, 47648 SOC_MAC_CONTROL_FAILOVER_RX_SET, FALSE)); 47649 PORT_UNLOCK(unit); 47650 } 47651 return rv; 47652 } 47653 47654 47655 /* 47656 * Function: 47657 * _bcm_esw_port_policer_get 47658 * Purpose: 47659 * Internal function to Retrieve the Policer ID accociated 47660 * with specified physical port. 47661 * Parameters: 47662 * Unit - (IN) unit number 47663 * port - (IN) Port Number 47664 * policer_id - (OUT) policer Id 47665 * Returns: 47666 * BCM_E_XXX 47667 */ 47668 int _bcm_esw_port_policer_get( 47669 int unit, 47670 bcm_port_t port, 47671 bcm_policer_t *policer_id) 47672 { 47673 int rv = BCM_E_NONE; 47674 47675 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 47676 defined(BCM_GREYHOUND2_SUPPORT) 47677 int index = 0; 47678 int offset_mode = 0; 47679 47680 BCM_IF_ERROR_RETURN 47681 (_bcm_esw_port_config_get(unit, port, 47682 _bcmPortSvcMeterIndex, &index)); 47683 BCM_IF_ERROR_RETURN 47684 (_bcm_esw_port_config_get(unit, port, 47685 _bcmPortSvcMeterOffsetMode, &offset_mode)); 47686 _bcm_esw_get_policer_id_from_index_offset(unit, index, 47687 offset_mode, policer_id); 47688 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 47689 BCM_GREYHOUND2_SUPPORT */ 47690 return rv; 47691 } 47692 47693 /* 47694 * Function: 47695 * bcm_esw_port_policer_get 47696 * Purpose: 47697 * Retrieve the Policer ID accociated for the specified physical port. 47698 * Parameters: 47699 * Unit - (IN) unit number 47700 * port - (IN) Port Number 47701 * policer_id - (OUT) policer Id 47702 * Returns: 47703 * BCM_E_XXX 47704 */ 47705 int bcm_esw_port_policer_get( 47706 int unit, 47707 bcm_port_t port, 47708 bcm_policer_t *policer_id) 47709 { 47710 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 47711 defined(BCM_GREYHOUND2_SUPPORT) 47712 int rv = BCM_E_NONE; 47713 47714 /* Make sure port module is initialized. */ 47715 PORT_INIT(unit); 47716 if (!soc_feature(unit, soc_feature_global_meter)) { 47717 return BCM_E_UNAVAIL; 47718 } 47719 BCM_IF_ERROR_RETURN(_check_global_meter_init(unit)); 47720 rv = _bcm_esw_port_gport_validate(unit, port, &port); 47721 BCM_IF_ERROR_RETURN(rv); 47722 rv = _bcm_esw_port_policer_get(unit, port, policer_id); 47723 return rv; 47724 #else /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 47725 BCM_GREYHOUND2_SUPPORT */ 47726 return BCM_E_UNAVAIL; 47727 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 47728 BCM_GREYHOUND2_SUPPORT */ 47729 } 47730 47731 #if defined(BCM_GLOBAL_METER_V2_SUPPORT) 47732 /* 47733 * Function: 47734 * bcmi_esw_port_policer_set 47735 * Purpose: 47736 * Set the Policer ID accociated for the specified physical port. 47737 * Parameters: 47738 * Unit - (IN) unit number 47739 * port - (IN) Port Number 47740 * policer_id - (IN) policer Id 47741 * Returns: 47742 * BCM_E_XXX 47743 */ 47744 STATIC int 47745 bcmi_esw_port_policer_set( 47746 int unit, 47747 bcm_port_t port, 47748 bcm_policer_t policer_id) 47749 { 47750 int rv = BCM_E_UNAVAIL; 47751 #if defined(BCM_GREYHOUND2_SUPPORT) 47752 int index = 0; 47753 int offset_mode = 0; 47754 bcm_policer_t current_policer_id = 0; 47755 47756 if (SOC_IS_GREYHOUND2(unit)) { 47757 /* Make sure port module is initialized. */ 47758 PORT_INIT(unit); 47759 if (!soc_feature(unit, soc_feature_global_meter)) { 47760 return BCM_E_UNAVAIL; 47761 } 47762 BCM_IF_ERROR_RETURN(_check_global_meter_init(unit)); 47763 rv = _bcm_esw_port_gport_validate(unit, port, &port); 47764 BCM_IF_ERROR_RETURN(rv); 47765 /* validate policer id */ 47766 rv = _bcm_esw_policer_validate(unit, &policer_id); 47767 if (BCM_FAILURE(rv)) { 47768 LOG_VERBOSE(BSL_LS_BCM_PORT, 47769 (BSL_META_U(unit, 47770 "Invalid policer id passed: %x \n"), 47771 policer_id)); 47772 return (rv); 47773 } 47774 /* get the policer id that is currently configured */ 47775 rv = _bcm_esw_port_policer_get(unit, port, ¤t_policer_id); 47776 if (BCM_FAILURE(rv)) { 47777 LOG_VERBOSE(BSL_LS_BCM_PORT, 47778 (BSL_META_U(unit, 47779 "Unabel to get the current policer configured \n"))); 47780 return (rv); 47781 } 47782 47783 /* Set policer id */ 47784 BCM_IF_ERROR_RETURN( 47785 _bcm_esw_get_policer_table_index(unit, policer_id, &index)); 47786 BCM_IF_ERROR_RETURN( 47787 _bcm_esw_policer_offset_mode_get(unit, policer_id, &offset_mode)); 47788 47789 BCM_IF_ERROR_RETURN( 47790 _bcm_esw_port_config_set( 47791 unit, port, _bcmPortSvcMeterIndex, index)); 47792 BCM_IF_ERROR_RETURN( 47793 _bcm_esw_port_config_set( 47794 unit, port, _bcmPortSvcMeterOffsetMode, offset_mode)); 47795 47796 /* increment new set policer ref_cnt */ 47797 rv = _bcm_esw_policer_increment_ref_count(unit, policer_id); 47798 BCM_IF_ERROR_RETURN(rv); 47799 47800 /* decrement current hw policer ref_cnt */ 47801 rv = _bcm_esw_policer_validate(unit, ¤t_policer_id); 47802 47803 /* Don't need to handle fail case since existed index could be 0 */ 47804 if (BCM_SUCCESS(rv)) { 47805 rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer_id); 47806 BCM_IF_ERROR_RETURN(rv); 47807 } 47808 47809 rv = BCM_E_NONE; 47810 } 47811 #endif /* BCM_GREYHOUND2_SUPPORT */ 47812 return rv; 47813 } 47814 47815 #endif /* BCM_GLOBAL_METER_V2_SUPPORT */ 47816 47817 /* 47818 * Function: 47819 * bcm_esw_port_policer_set 47820 * Purpose: 47821 * Set the Policer ID accociated for the specified physical port. 47822 * Parameters: 47823 * Unit - (IN) unit number 47824 * port - (IN) Port Number 47825 * policer_id - (IN) policer Id 47826 * Returns: 47827 * BCM_E_XXX 47828 */ 47829 int bcm_esw_port_policer_set( 47830 int unit, 47831 bcm_port_t port, 47832 bcm_policer_t policer) 47833 { 47834 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 47835 defined(BCM_APACHE_SUPPORT)) 47836 int rv = BCM_E_NONE; 47837 int index=0; 47838 int offset_mode=0; 47839 bcm_policer_t current_policer = 0; 47840 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 47841 BCM_APACHE_SUPPORT */ 47842 47843 #if defined(BCM_GLOBAL_METER_V2_SUPPORT) 47844 if (soc_feature(unit, soc_feature_global_meter_v2)) { 47845 return bcmi_esw_port_policer_set(unit, port, policer); 47846 } 47847 #endif /* BCM_GLOBAL_METER_V2_SUPPORT */ 47848 47849 #if (defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 47850 defined(BCM_APACHE_SUPPORT)) 47851 47852 /* Make sure port module is initialized. */ 47853 PORT_INIT(unit); 47854 if (!soc_feature(unit, soc_feature_global_meter)) { 47855 return BCM_E_UNAVAIL; 47856 } 47857 BCM_IF_ERROR_RETURN(_check_global_meter_init(unit)); 47858 rv = _bcm_esw_port_gport_validate(unit, port, &port); 47859 BCM_IF_ERROR_RETURN(rv); 47860 /* validate policer id */ 47861 rv = _bcm_esw_policer_validate(unit, &policer); 47862 if (BCM_FAILURE(rv)) { 47863 LOG_VERBOSE(BSL_LS_BCM_PORT, 47864 (BSL_META_U(unit, 47865 "Invalid policer id passed: %x \n"), 47866 policer)); 47867 return (rv); 47868 } 47869 /* get the policer id that is currently configured */ 47870 rv = _bcm_esw_port_policer_get(unit, port, ¤t_policer); 47871 if (BCM_FAILURE(rv)) { 47872 LOG_VERBOSE(BSL_LS_BCM_PORT, 47873 (BSL_META_U(unit, 47874 "Unabel to get the current policer configured \n"))); 47875 return (rv); 47876 } 47877 rv = BCM_E_UNAVAIL; 47878 /* Set policer id */ 47879 _bcm_esw_get_policer_table_index(unit, policer, &index); 47880 offset_mode = (((policer) & BCM_POLICER_GLOBAL_METER_MODE_MASK) >> 47881 BCM_POLICER_GLOBAL_METER_MODE_SHIFT); 47882 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) { 47883 if ((offset_mode == 0) && (policer != 0)) { 47884 /* 47885 * Not a Global meter policer, 47886 * policer zero is used to detach already configured policer 47887 */ 47888 return (BCM_E_PARAM); 47889 } 47890 } 47891 if (offset_mode >= 1) { 47892 offset_mode = offset_mode - 1; 47893 } 47894 if (index >= soc_mem_index_count(unit,SVM_METER_TABLEm)) { 47895 LOG_VERBOSE(BSL_LS_BCM_PORT, 47896 (BSL_META_U(unit, 47897 "Invalid table index\n"))); 47898 return BCM_E_PARAM; 47899 } 47900 if (offset_mode >= (soc_mem_index_count(unit,SVM_OFFSET_TABLEm) >> 47901 BCM_POLICER_SVC_METER_OFFSET_TABLE_KEY_SIZE)) { 47902 LOG_VERBOSE(BSL_LS_BCM_PORT, 47903 (BSL_META_U(unit, 47904 "Invalid offset mode\n"))); 47905 return BCM_E_PARAM; 47906 } 47907 BCM_IF_ERROR_RETURN( 47908 _bcm_esw_port_config_set(unit, port, 47909 _bcmPortSvcMeterIndex, index)); 47910 BCM_IF_ERROR_RETURN( 47911 _bcm_esw_port_config_set(unit, port, 47912 _bcmPortSvcMeterOffsetMode, offset_mode)); 47913 /* decrement current policer if any */ 47914 if ((current_policer & BCM_POLICER_GLOBAL_METER_INDEX_MASK) > 0) { 47915 rv = _bcm_esw_policer_decrement_ref_count(unit, current_policer); 47916 BCM_IF_ERROR_RETURN(rv); 47917 } 47918 /* increment policer reference count */ 47919 if ((policer & BCM_POLICER_GLOBAL_METER_INDEX_MASK) > 0 ) { 47920 rv = _bcm_esw_policer_increment_ref_count(unit, policer); 47921 BCM_IF_ERROR_RETURN(rv); 47922 } 47923 return rv; 47924 #else /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 47925 BCM_APACHE_SUPPORT */ 47926 return BCM_E_UNAVAIL; 47927 #endif 47928 } 47929 47930 /* 47931 * Function: 47932 * bcm_port_vlan_inner_tag_set 47933 * Purpose: 47934 * Set the inner tag to be added to the packet. 47935 * Parameters: 47936 * unit - (IN) BCM unit. 47937 * port - (IN) Port number. 47938 * inner_tag - (IN) Inner tag. 47939 * Priority[15:13] CFI[12] VLAN ID [11:0] 47940 * Returns: 47941 * BCM_E_XXX 47942 */ 47943 int 47944 bcm_esw_port_vlan_inner_tag_set(int unit, bcm_port_t port, uint16 inner_tag) 47945 { 47946 int rv; 47947 47948 /* Make sure port module is initialized. */ 47949 PORT_INIT(unit); 47950 47951 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 47952 47953 rv = BCM_E_UNAVAIL; 47954 47955 #ifdef BCM_TRX_SUPPORT 47956 if (SOC_IS_TRX(unit)) { 47957 bcm_vlan_action_set_t action; 47958 47959 if (!soc_feature(unit, soc_feature_vlan_action)) { 47960 return BCM_E_UNAVAIL; 47961 } 47962 47963 PORT_LOCK(unit); 47964 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 47965 (_bcm_trx_vlan_port_default_action_get(unit, port, &action)); 47966 action.new_inner_vlan = BCM_VLAN_CTRL_ID(inner_tag); 47967 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 47968 if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 47969 rv =_bcm_trx_vlan_port_default_action_profile_set(unit, port, &action); 47970 } else 47971 #endif 47972 { 47973 rv = _bcm_trx_vlan_port_default_action_set(unit, port, &action); 47974 } 47975 PORT_UNLOCK(unit); 47976 return rv; 47977 } 47978 #endif 47979 47980 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 47981 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 47982 PORT_LOCK(unit); 47983 47984 rv = soc_reg_field32_modify(unit, EGR_SRC_PORTr, port, 47985 INNER_TAGf, inner_tag); 47986 PORT_UNLOCK(unit); 47987 } 47988 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */ 47989 47990 return rv; 47991 } 47992 47993 /* 47994 * Function: 47995 * bcm_port_vlan_inner_tag_get 47996 * Purpose: 47997 * Get the inner tag to be added to the packet. 47998 * Parameters: 47999 * unit - (IN) BCM unit. 48000 * port - (IN) Port number. 48001 * inner_tag - (OUT) Inner tag. 48002 * Priority[15:13] CFI[12] VLAN ID [11:0] 48003 * Returns: 48004 * BCM_E_XXX 48005 */ 48006 int 48007 bcm_esw_port_vlan_inner_tag_get(int unit, bcm_port_t port, uint16 *inner_tag) 48008 { 48009 int rv; 48010 48011 /* Make sure port module is initialized. */ 48012 PORT_INIT(unit); 48013 48014 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 48015 48016 rv = BCM_E_UNAVAIL; 48017 48018 #ifdef BCM_TRX_SUPPORT 48019 if (SOC_IS_TRX(unit)) { 48020 bcm_vlan_action_set_t action; 48021 48022 if (!soc_feature(unit, soc_feature_vlan_action)) { 48023 return BCM_E_UNAVAIL; 48024 } 48025 48026 PORT_LOCK(unit); 48027 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK 48028 (_bcm_trx_vlan_port_default_action_get(unit, port, &action)); 48029 *inner_tag = action.new_inner_vlan; 48030 PORT_UNLOCK(unit); 48031 return BCM_E_NONE; 48032 } 48033 #endif 48034 48035 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_RAVEN_SUPPORT) 48036 if (SOC_IS_FIREBOLT2(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 48037 uint32 value; 48038 48039 rv = READ_EGR_SRC_PORTr(unit, port, &value); 48040 *inner_tag = soc_reg_field_get(unit, EGR_SRC_PORTr, value, 48041 INNER_TAGf); 48042 } 48043 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_RAVEN_SUPPORT */ 48044 return rv; 48045 } 48046 48047 #if defined(INCLUDE_L3) && defined(BCM_TRIDENT_SUPPORT) 48048 STATIC int 48049 _bcm_esw_port_vp_type_id_get(int unit, bcm_port_t port, 48050 _bcm_vp_type_e *vp_type, int *vp) 48051 { 48052 *vp = -1; 48053 *vp_type = _bcmVpTypeAny; 48054 48055 if (BCM_GPORT_IS_MIM_PORT(port) && soc_feature(unit, soc_feature_mim)) { 48056 *vp_type = _bcmVpTypeMim; 48057 *vp = BCM_GPORT_MIM_PORT_ID_GET(port); 48058 } else if (BCM_GPORT_IS_TRILL_PORT(port) && soc_feature(unit, soc_feature_trill)) { 48059 *vp_type = _bcmVpTypeTrill; 48060 *vp = BCM_GPORT_TRILL_PORT_ID_GET(port); 48061 } else if (BCM_GPORT_IS_VXLAN_PORT(port) && soc_feature(unit, soc_feature_vxlan)) { 48062 *vp_type = _bcmVpTypeVxlan; 48063 *vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 48064 } else if (BCM_GPORT_IS_MPLS_PORT(port) && soc_feature(unit, soc_feature_mpls)) { 48065 *vp_type = _bcmVpTypeMpls; 48066 *vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 48067 } else if (BCM_GPORT_IS_EXTENDER_PORT(port) && soc_feature(unit, soc_feature_port_extension)) { 48068 *vp_type = _bcmVpTypeExtender; 48069 *vp = BCM_GPORT_EXTENDER_PORT_ID_GET(port); 48070 } else if (BCM_GPORT_IS_WLAN_PORT(port) && soc_feature(unit, soc_feature_wlan)) { 48071 *vp_type = _bcmVpTypeWlan; 48072 *vp = BCM_GPORT_WLAN_PORT_ID_GET(port); 48073 } else if (BCM_GPORT_IS_NIV_PORT(port) && soc_feature(unit, soc_feature_niv)) { 48074 *vp_type = _bcmVpTypeNiv; 48075 *vp = BCM_GPORT_NIV_PORT_ID_GET(port); 48076 } else if (BCM_GPORT_IS_VLAN_PORT(port) && soc_feature(unit, soc_feature_vlan_vp)) { 48077 *vp_type = _bcmVpTypeVlan; 48078 *vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 48079 } else if (BCM_GPORT_IS_L2GRE_PORT(port) && soc_feature(unit, soc_feature_l2gre)) { 48080 *vp_type = _bcmVpTypeL2Gre; 48081 *vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 48082 } else if (BCM_GPORT_IS_FLOW_PORT(port) && soc_feature(unit, soc_feature_flex_flow)) { 48083 *vp_type = _bcmVpTypeFlow; 48084 *vp = BCM_GPORT_FLOW_PORT_ID_GET(port); 48085 } else if (BCM_GPORT_IS_TRUNK(port) && soc_feature(unit, soc_feature_vp_lag)) { 48086 *vp_type = _bcmVpTypeVpLag; 48087 BCM_IF_ERROR_RETURN( 48088 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port), 48089 vp)); 48090 } 48091 return BCM_E_NONE; 48092 } 48093 #endif 48094 48095 /* 48096 * Function : 48097 * bcm_port_class_set 48098 * Description : 48099 * Set the ports class ID. Ports with the 48100 * same class ID can be treated as a group in 48101 * field processing and VLAN translation. 48102 * Parameters : 48103 * (IN) unit - BCM device number 48104 * (IN) port - Device or logical port number 48105 * (IN) pclass - Classification type 48106 * (IN) pclass_id - New class ID of the port. 48107 * Returns : 48108 * BCM_E_NONE - Success 48109 * BCM_E_XXX - Failed 48110 */ 48111 int 48112 bcm_esw_port_class_set(int unit, bcm_port_t port, 48113 bcm_port_class_t pclass, uint32 pclass_id) 48114 { 48115 int rv = BCM_E_UNAVAIL; 48116 bcm_port_t port_out = port; 48117 #if defined(BCM_TOMAHAWK_SUPPORT) 48118 soc_mem_t port_mem = PORT_TABm; 48119 #endif 48120 48121 /* Make sure port module is initialized. */ 48122 PORT_INIT(unit); 48123 48124 #if defined(INCLUDE_L3) 48125 #if defined(BCM_TRIDENT_SUPPORT) 48126 if (BCM_GPORT_IS_SET(port)) { 48127 int vp; 48128 _bcm_vp_type_e vp_type; 48129 BCM_IF_ERROR_RETURN(_bcm_esw_port_vp_type_id_get(unit, port, 48130 &vp_type, &vp)); 48131 switch (pclass) { 48132 case bcmPortClassFieldIngress: 48133 if (vp_type == _bcmVpTypeMim || vp_type == _bcmVpTypeTrill || 48134 vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeMpls || 48135 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeWlan || 48136 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeVlan || 48137 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeVpLag || 48138 vp_type == _bcmVpTypeFlow){ 48139 48140 if (!_bcm_vp_used_get(unit, vp, vp_type)) { 48141 return BCM_E_PORT; 48142 } 48143 rv = soc_mem_field32_modify(unit, SOURCE_VPm, vp, CLASS_IDf, pclass_id); 48144 return rv; 48145 } 48146 break; 48147 case bcmPortClassVlanTranslateEgress: 48148 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 48149 /* class_id of DVP used in egress VLAN translation */ 48150 /* class_id of DVP used in egress VLAN translation */ 48151 if ((vp_type == _bcmVpTypeVxlan) || (vp_type == _bcmVpTypeMim) || 48152 (vp_type == _bcmVpTypeMpls) || (vp_type == _bcmVpTypeL2Gre) || 48153 (vp_type == _bcmVpTypeFlow) ) { 48154 int network_port; 48155 source_vp_entry_t svp; 48156 _bcm_vp_info_t vp_info; 48157 48158 if (!_bcm_vp_used_get(unit, vp, vp_type)) { 48159 return BCM_E_PORT; 48160 } 48161 BCM_IF_ERROR_RETURN (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 48162 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 48163 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 48164 network_port = TRUE; 48165 } else { 48166 network_port = FALSE; 48167 } 48168 48169 if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, 48170 VT_DVP_GROUP_IDf) 48171 #if defined(BCM_TRIDENT3_SUPPORT) 48172 || (SOC_IS_TRIDENT3X(unit) && SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, 48173 COMMON__VT_DVP_GROUP_IDf)) 48174 #endif 48175 ) { 48176 if ((network_port) && (vp_type == _bcmVpTypeVxlan)) { 48177 rv = soc_mem_field32_modify(unit, EGR_DVP_ATTRIBUTEm, vp, 48178 VXLAN__VT_DVP_GROUP_IDf, pclass_id); 48179 } else if ((network_port) && (vp_type == _bcmVpTypeL2Gre)) { 48180 rv = soc_mem_field32_modify(unit, EGR_DVP_ATTRIBUTEm, vp, 48181 L2GRE__VT_DVP_GROUP_IDf, pclass_id); 48182 } else { 48183 rv = soc_mem_field32_modify(unit, EGR_DVP_ATTRIBUTEm, vp, 48184 COMMON__VT_DVP_GROUP_IDf, pclass_id); 48185 } 48186 } else { 48187 return BCM_E_UNAVAIL; 48188 } 48189 return rv; 48190 } 48191 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 48192 break; 48193 #if defined(BCM_TOMAHAWK_SUPPORT) 48194 case bcmPortClassFieldIngressSourceGport: 48195 if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 48196 return BCM_E_UNAVAIL; 48197 } 48198 if (pclass_id > 33) { 48199 return BCM_E_PARAM; 48200 } 48201 if (vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeVlan || 48202 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeVpLag || 48203 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeMpls || 48204 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeMim || 48205 vp_type == _bcmVpTypeFlow) { 48206 if (!_bcm_vp_used_get(unit, vp, vp_type)) { 48207 return BCM_E_PORT; 48208 } 48209 rv = soc_mem_field32_modify(unit, SOURCE_VPm, vp, 48210 IPBM_INDEXf, pclass_id); 48211 return rv; 48212 } 48213 break; 48214 #endif /* BCM_TOMAHAWK_SUPPORT */ 48215 48216 default: 48217 break; 48218 } 48219 } 48220 #endif /* BCM_TRIDENT_SUPPORT*/ 48221 #endif /* INCLUDE_L3 */ 48222 48223 #ifdef BCM_XGS3_SWITCH_SUPPORT 48224 if (SOC_IS_XGS3_SWITCH(unit)) { 48225 #if defined(BCM_TOMAHAWK_SUPPORT) 48226 bcm_module_t mod; 48227 bcm_trunk_t tid_out; 48228 int id_out; 48229 int index; 48230 #endif /* BCM_TOMAHAWK_SUPPORT */ 48231 switch (pclass) { 48232 case bcmPortClassFieldIngressSystemPort: 48233 #if defined(BCM_TOMAHAWK_SUPPORT) 48234 if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 48235 return BCM_E_UNAVAIL; 48236 } 48237 if (pclass_id > 33) { 48238 #if defined(BCM_TRIDENT3_SUPPORT) 48239 if (!SOC_IS_TRIDENT3X(unit) || 48240 soc_feature(unit, soc_feature_ifp_no_inports_support)) 48241 #endif 48242 return BCM_E_PARAM; 48243 } 48244 if (BCM_GPORT_IS_SET(port)) { 48245 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 48246 &mod, &port_out, &tid_out, &id_out)); 48247 if (-1 != tid_out || -1 != id_out) { 48248 return BCM_E_PORT; 48249 } 48250 } else { 48251 if (!SOC_PORT_VALID(unit, port)) { 48252 return BCM_E_PORT; 48253 } 48254 port_out = port; 48255 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod)); 48256 } 48257 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, 48258 mod, port_out, &index)); 48259 #if defined(BCM_TRIDENT3_SUPPORT) 48260 if (SOC_IS_TRIDENT3X(unit) && 48261 !soc_feature(unit, soc_feature_ifp_no_inports_support)) { 48262 rv = bcm_td3_port_ipbm_opaque_set(unit, index, pclass_id); 48263 return rv; 48264 } 48265 #endif 48266 rv = soc_mem_field32_modify(unit, SOURCE_TRUNK_MAP_TABLEm, index, 48267 IPBM_INDEXf, pclass_id); 48268 return rv; 48269 #endif /* BCM_TOMAHAWK_SUPPORT */ 48270 break; 48271 default: 48272 break; 48273 } 48274 } 48275 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 48276 /* 48277 * Skip port validation if soc_feature_shg_support_remote_port 48278 * is true and ptype is bcmPortClassFieldIngress. 48279 */ 48280 if (!(soc_feature(unit, soc_feature_shg_support_remote_port) && 48281 (pclass == bcmPortClassFieldIngress))) { 48282 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port_out)); 48283 } 48284 48285 48286 #ifdef BCM_XGS3_SWITCH_SUPPORT 48287 if (SOC_IS_XGS3_SWITCH(unit)) { 48288 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 48289 int port_class_id; 48290 soc_reg_t egr_port_reg; 48291 egr_port_reg = (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 48292 SOC_IS_VALKYRIE2(unit) || SOC_IS_GREYHOUND(unit) || 48293 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) ? 48294 EGR_PORT_64r : EGR_PORTr; 48295 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */ 48296 48297 switch (pclass) { 48298 case bcmPortClassFieldIngressGroupSel: 48299 #if defined(BCM_TOMAHAWK_SUPPORT) 48300 if (SOC_IS_TRIDENT3X(unit)) { 48301 port_mem = LPORT_TABm; 48302 } 48303 if (soc_mem_field_valid(unit, port_mem, IFP_KEY_SEL_CLASS_IDf)) { 48304 rv = soc_mem_field_pbmp_fit(unit, port_mem, 48305 IFP_KEY_SEL_CLASS_IDf, &pclass_id); 48306 if (rv == BCM_E_NONE) { 48307 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48308 IFP_KEY_SEL_CLASS_IDf, pclass_id); 48309 } 48310 } 48311 #endif 48312 break; 48313 case bcmPortClassFieldLookup: 48314 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 48315 if (soc_mem_field_valid(unit, PORT_TABm, VFP_PORT_GROUP_IDf) || 48316 SOC_IS_TRIDENT3X(unit)) { 48317 /* Intentional use of var pclass_id, to be filled here */ 48318 if (soc_mem_field_valid(unit, PORT_TABm, VFP_PORT_GROUP_IDf)) { 48319 /* coverity [callee_ptr_arith] */ 48320 rv = soc_mem_field_pbmp_fit(unit, PORT_TABm, 48321 VFP_PORT_GROUP_IDf, &pclass_id); 48322 } else if (SOC_IS_TRIDENT3X(unit)) { 48323 rv = soc_mem_field_pbmp_fit(unit, LPORT_TABm, 48324 VFP_PORT_GROUP_IDf, &pclass_id); 48325 } 48326 if (rv == BCM_E_NONE) { 48327 port_class_id = (int) pclass_id; 48328 rv = _bcm_esw_port_tab_set(unit, port, 48329 _BCM_CPU_TABS_BOTH, 48330 VFP_PORT_GROUP_IDf, 48331 port_class_id); 48332 } 48333 } 48334 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */ 48335 #if defined(BCM_TRX_SUPPORT) 48336 if ((SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 48337 VFP_PORT_GROUP_IDf)) && 48338 (BCM_SUCCESS(rv))) { 48339 #if defined(BCM_KATANA2_SUPPORT) 48340 if (SOC_IS_KATANA2(unit)) { 48341 rv = _bcm_kt2_source_trunk_map_set(unit, port_out, 48342 VFP_PORT_GROUP_IDf, 48343 pclass_id); 48344 } else 48345 #endif 48346 { 48347 rv = _bcm_trx_source_trunk_map_set(unit, port, 48348 VFP_PORT_GROUP_IDf, 48349 pclass_id); 48350 } 48351 } 48352 #endif /* BCM_TRX_SUPPORT */ 48353 break; 48354 case bcmPortClassVlanTranslateIngress: 48355 #if defined(BCM_TRIDENT2_SUPPORT) 48356 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, PORT_GROUPf)) { 48357 rv = _bcm_trx_source_trunk_map_set(unit, port, 48358 PORT_GROUPf, pclass_id); 48359 } 48360 #endif /* BCM_TRIDENT2_SUPPORT */ 48361 break; 48362 case bcmPortClassFieldIngress: 48363 #if defined(BCM_TRX_SUPPORT) 48364 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, CLASS_IDf)) { 48365 #if defined(BCM_KATANA2_SUPPORT) 48366 if (SOC_IS_KATANA2(unit)) { 48367 rv = _bcm_kt2_source_trunk_map_set(unit, port_out, 48368 CLASS_IDf, pclass_id); 48369 } else 48370 #endif 48371 { 48372 rv = _bcm_trx_source_trunk_map_set(unit, port, 48373 CLASS_IDf, pclass_id); 48374 } 48375 } 48376 #endif /* BCM_TRX_SUPPORT */ 48377 break; 48378 case bcmPortClassFieldEgress: 48379 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 48380 if (soc_reg_field_valid(unit, egr_port_reg, EGR_PORT_GROUP_IDf)) { 48381 rv = soc_reg_field32_modify(unit, egr_port_reg, port_out, 48382 EGR_PORT_GROUP_IDf, pclass_id); 48383 } 48384 #ifdef BCM_TRIDENT_SUPPORT 48385 else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EGR_PORT_GROUP_IDf) || 48386 SOC_IS_TRIDENT3X(unit)) { 48387 rv = _bcm_esw_egr_port_tab_set(unit, port, 48388 EGR_PORT_GROUP_IDf, pclass_id); 48389 } 48390 #endif /* BCM_TRIDENT_SUPPORT */ 48391 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */ 48392 break; 48393 case bcmPortClassVlanTranslateEgress: 48394 #if defined(BCM_TRX_SUPPORT) 48395 if (soc_reg_field_valid(unit, egr_port_reg, VT_PORT_GROUP_IDf)) { 48396 soc_control_t *sc = SOC_CONTROL(unit); 48397 48398 if (sc->soc_flags & SOC_F_PORT_CLASS_BLOCKED) { 48399 return BCM_E_CONFIG; 48400 } 48401 rv = soc_reg_field32_modify(unit, egr_port_reg, port_out, 48402 VT_PORT_GROUP_IDf, pclass_id); 48403 if (BCM_SUCCESS(rv)) { 48404 /* Once port class is changed system will not allow */ 48405 /* To use bcm_vlan_translate_egress */ 48406 sc->soc_flags |= SOC_F_XLATE_EGR_BLOCKED; 48407 } 48408 } 48409 #ifdef BCM_TRIDENT_SUPPORT 48410 else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, VT_PORT_GROUP_IDf) || 48411 SOC_IS_TRIDENT3X(unit)) { 48412 rv = _bcm_esw_egr_port_tab_set(unit, port, 48413 VT_PORT_GROUP_IDf, pclass_id); 48414 } 48415 #endif /* BCM_TRIDENT_SUPPORT */ 48416 #endif /* BCM_TRX_SUPPORT */ 48417 break; 48418 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 48419 case bcmPortClassEgress: 48420 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, CLASS_IDf) || 48421 SOC_IS_TRIDENT3X(unit)) { 48422 rv = _bcm_esw_egr_port_tab_set(unit, port, 48423 CLASS_IDf, pclass_id); 48424 } 48425 break; 48426 #endif 48427 #if defined(BCM_TOMAHAWK_SUPPORT) 48428 case bcmPortClassFieldIngressDevicePort: 48429 if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 48430 return BCM_E_UNAVAIL; 48431 } 48432 if (pclass_id > 33) { 48433 return BCM_E_PARAM; 48434 } 48435 48436 if (BCM_GPORT_IS_SET(port)) { 48437 bcm_module_t mod; 48438 bcm_trunk_t tid_out; 48439 int id_out; 48440 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 48441 &mod, &port_out, &tid_out, &id_out)); 48442 if (-1 != tid_out || -1 != id_out) { 48443 return BCM_E_PORT; 48444 } 48445 } else { 48446 if (!SOC_PORT_VALID(unit, port)) { 48447 return BCM_E_PORT; 48448 } 48449 } 48450 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48451 PORT_IPBM_INDEXf, pclass_id); 48452 break; 48453 #endif /* BCM_TOMAHAWK_SUPPORT */ 48454 default: 48455 rv = BCM_E_PARAM; 48456 } 48457 } 48458 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 48459 48460 return rv; 48461 } 48462 48463 /* 48464 * Function : 48465 * bcm_port_class_get 48466 * Description : 48467 * Get the ports class ID. Ports with the 48468 * same class ID can be treated as a group in 48469 * field processing and VLAN translation. 48470 * Parameters : 48471 * (IN) unit - BCM device number 48472 * (IN) port - Device or logical port number 48473 * (IN) pclass - Classification type 48474 * (OUT) pclass_id - New class ID of the port. 48475 * Returns : 48476 * BCM_E_NONE - Success 48477 * BCM_E_XXX - Failed 48478 */ 48479 int 48480 bcm_esw_port_class_get(int unit, bcm_port_t port, 48481 bcm_port_class_t pclass, uint32 *pclass_id) 48482 { 48483 int rv = BCM_E_UNAVAIL; 48484 bcm_port_t port_out = port; 48485 48486 /* Make sure port module is initialized. */ 48487 PORT_INIT(unit); 48488 48489 #if defined(INCLUDE_L3) 48490 #if defined(BCM_TRIDENT_SUPPORT) 48491 if (BCM_GPORT_IS_SET(port)) { 48492 int vp; 48493 _bcm_vp_type_e vp_type; 48494 source_vp_entry_t entry; 48495 BCM_IF_ERROR_RETURN(_bcm_esw_port_vp_type_id_get(unit, port, 48496 &vp_type, &vp)); 48497 switch (pclass) { 48498 case bcmPortClassFieldIngress: 48499 if (vp_type == _bcmVpTypeMim || vp_type == _bcmVpTypeTrill || 48500 vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeMpls || 48501 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeWlan || 48502 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeVlan || 48503 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeVpLag || 48504 vp_type == _bcmVpTypeFlow){ 48505 48506 if (!_bcm_vp_used_get(unit, vp, vp_type)) { 48507 return BCM_E_PORT; 48508 } 48509 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &entry); 48510 if (BCM_SUCCESS(rv)) { 48511 *pclass_id = soc_mem_field32_get(unit, SOURCE_VPm, 48512 &entry, CLASS_IDf); 48513 } 48514 return rv; 48515 } 48516 break; 48517 case bcmPortClassVlanTranslateEgress: 48518 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 48519 /* class_id of DVP used in egress VLAN translation */ 48520 if ((vp_type == _bcmVpTypeVxlan) || (vp_type == _bcmVpTypeMim) || 48521 (vp_type == _bcmVpTypeMpls) || (vp_type == _bcmVpTypeL2Gre)) { 48522 int network_port; 48523 egr_dvp_attribute_entry_t dvp_entry; 48524 _bcm_vp_info_t vp_info; 48525 48526 if (!_bcm_vp_used_get(unit, vp, vp_type)) { 48527 return BCM_E_PORT; 48528 } 48529 48530 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 48531 if (vp_info.flags & _BCM_VP_INFO_NETWORK_PORT) { 48532 network_port = TRUE; 48533 } else { 48534 network_port = FALSE; 48535 } 48536 48537 if (SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, 48538 VT_DVP_GROUP_IDf) 48539 #if defined(BCM_TRIDENT3_SUPPORT) 48540 || (SOC_IS_TRIDENT3X(unit) && SOC_MEM_FIELD_VALID(unit, EGR_DVP_ATTRIBUTEm, 48541 COMMON__VT_DVP_GROUP_IDf)) 48542 #endif 48543 ) { 48544 rv = READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY, 48545 vp, &dvp_entry); 48546 if (BCM_SUCCESS(rv)) { 48547 if ((network_port) && (vp_type == _bcmVpTypeVxlan)) { 48548 *pclass_id = soc_mem_field32_get 48549 (unit, EGR_DVP_ATTRIBUTEm, &dvp_entry, 48550 VXLAN__VT_DVP_GROUP_IDf); 48551 } else if ((network_port) && (vp_type == _bcmVpTypeL2Gre)) { 48552 *pclass_id = soc_mem_field32_get 48553 (unit, EGR_DVP_ATTRIBUTEm, &dvp_entry, 48554 L2GRE__VT_DVP_GROUP_IDf); 48555 } else { 48556 *pclass_id = soc_mem_field32_get 48557 (unit, EGR_DVP_ATTRIBUTEm, &dvp_entry, 48558 COMMON__VT_DVP_GROUP_IDf); 48559 } 48560 } 48561 } else { 48562 return BCM_E_UNAVAIL; 48563 } 48564 return rv; 48565 } 48566 48567 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 48568 break; 48569 #if defined(BCM_TOMAHAWK_SUPPORT) 48570 case bcmPortClassFieldIngressSourceGport: 48571 if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 48572 return BCM_E_UNAVAIL; 48573 } 48574 if (vp_type == _bcmVpTypeVxlan || vp_type == _bcmVpTypeVlan || 48575 vp_type == _bcmVpTypeExtender || vp_type == _bcmVpTypeVpLag || 48576 vp_type == _bcmVpTypeNiv || vp_type == _bcmVpTypeMpls || 48577 vp_type == _bcmVpTypeL2Gre || vp_type == _bcmVpTypeMim || 48578 vp_type == _bcmVpTypeFlow) { 48579 if (!_bcm_vp_used_get(unit, vp, vp_type)) { 48580 return BCM_E_PORT; 48581 } 48582 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &entry); 48583 if (BCM_SUCCESS(rv)) { 48584 *pclass_id = soc_mem_field32_get(unit, SOURCE_VPm, 48585 &entry, IPBM_INDEXf); 48586 } 48587 return rv; 48588 } 48589 break; 48590 #endif /* BCM_TOMAHAWK_SUPPORT */ 48591 default: 48592 break; 48593 } 48594 } 48595 #endif /* BCM_TRIDENT_SUPPORT */ 48596 #endif /* INCLUDE_L3 */ 48597 #ifdef BCM_XGS3_SWITCH_SUPPORT 48598 if (SOC_IS_XGS3_SWITCH(unit)) { 48599 #if defined(BCM_TOMAHAWK_SUPPORT) 48600 source_trunk_map_table_entry_t entry; 48601 bcm_module_t mod; 48602 bcm_trunk_t tid_out; 48603 int id_out; 48604 int index; 48605 #endif /* BCM_TOMAHAWK_SUPPORT */ 48606 48607 switch (pclass) { 48608 case bcmPortClassFieldIngressSystemPort: 48609 #if defined(BCM_TOMAHAWK_SUPPORT) 48610 if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 48611 return BCM_E_UNAVAIL; 48612 } 48613 if (BCM_GPORT_IS_SET(port)) { 48614 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 48615 &mod, &port_out, &tid_out, &id_out)); 48616 if (-1 != tid_out || -1 != id_out) { 48617 return BCM_E_PORT; 48618 } 48619 } else { 48620 if (!SOC_PORT_VALID(unit, port)) { 48621 return BCM_E_PORT; 48622 } 48623 port_out = port; 48624 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mod)); 48625 } 48626 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, 48627 mod, port_out, &index)); 48628 #if defined(BCM_TRIDENT3_SUPPORT) 48629 if (SOC_IS_TRIDENT3X(unit) && 48630 !soc_feature(unit, soc_feature_ifp_no_inports_support)){ 48631 rv = bcm_td3_port_ipbm_opaque_get(unit, index, pclass_id); 48632 return rv; 48633 } 48634 #endif 48635 SOC_IF_ERROR_RETURN(soc_mem_read(unit, SOURCE_TRUNK_MAP_TABLEm, 48636 MEM_BLOCK_ANY, index, &entry)); 48637 *pclass_id = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, 48638 &entry, IPBM_INDEXf); 48639 return BCM_E_NONE; 48640 #endif /* BCM_TOMAHAWK_SUPPORT */ 48641 break; 48642 default: 48643 break; 48644 } 48645 } 48646 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 48647 /* 48648 * Skip port validation if soc_feature_shg_support_remote_port 48649 * is true and ptype is bcmPortClassFieldIngress. 48650 */ 48651 if (!(soc_feature(unit, soc_feature_shg_support_remote_port) && 48652 (pclass == bcmPortClassFieldIngress))) { 48653 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port_out)); 48654 } 48655 48656 if (NULL == pclass_id) { 48657 return BCM_E_PARAM; 48658 } 48659 48660 #ifdef BCM_XGS3_SWITCH_SUPPORT 48661 if (SOC_IS_XGS3_SWITCH(unit)) { 48662 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 48663 uint32 reg_val; 48664 uint64 reg_val64; 48665 int port_class_id; 48666 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 48667 switch (pclass) { 48668 case bcmPortClassFieldIngressGroupSel: 48669 #if defined(BCM_TOMAHAWK_SUPPORT) 48670 rv = _bcm_esw_port_tab_get(unit, port, IFP_KEY_SEL_CLASS_IDf, 48671 (int32*) pclass_id); 48672 #endif 48673 break; 48674 48675 case bcmPortClassFieldLookup: 48676 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 48677 if (soc_mem_field_valid(unit, PORT_TABm, VFP_PORT_GROUP_IDf) || 48678 SOC_IS_TRIDENT3X(unit)) { 48679 rv = _bcm_esw_port_tab_get(unit, port, VFP_PORT_GROUP_IDf, 48680 &port_class_id); 48681 *pclass_id = (uint32) port_class_id; 48682 } 48683 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */ 48684 break; 48685 case bcmPortClassVlanTranslateIngress: 48686 #if defined(BCM_TRIDENT2_SUPPORT) 48687 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, PORT_GROUPf)) { 48688 rv = _bcm_trx_source_trunk_map_get(unit, port, 48689 PORT_GROUPf, pclass_id); 48690 } 48691 #endif /* BCM_TRIDENT2_SUPPORT */ 48692 break; 48693 case bcmPortClassFieldIngress: 48694 #if defined(BCM_TRX_SUPPORT) 48695 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, CLASS_IDf)) { 48696 #if defined(BCM_KATANA2_SUPPORT) 48697 if (SOC_IS_KATANA2(unit)) { 48698 rv = _bcm_kt2_source_trunk_map_get(unit, port_out, 48699 CLASS_IDf, pclass_id); 48700 } else 48701 #endif 48702 { 48703 rv = _bcm_trx_source_trunk_map_get(unit, port, 48704 CLASS_IDf, pclass_id); 48705 } 48706 } 48707 #endif /* BCM_TRX_SUPPORT */ 48708 break; 48709 case bcmPortClassFieldEgress: 48710 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 48711 if (soc_reg_field_valid(unit, EGR_PORT_64r, EGR_PORT_GROUP_IDf)) { 48712 rv = READ_EGR_PORT_64r(unit, port_out, ®_val64); 48713 if (BCM_SUCCESS(rv)) { 48714 *pclass_id = soc_reg64_field32_get(unit, EGR_PORT_64r, 48715 reg_val64, EGR_PORT_GROUP_IDf); 48716 } 48717 } else if (soc_reg_field_valid(unit, EGR_PORTr, EGR_PORT_GROUP_IDf)) { 48718 rv = READ_EGR_PORTr(unit, port_out, ®_val); 48719 if (BCM_SUCCESS(rv)) { 48720 *pclass_id = soc_reg_field_get(unit, EGR_PORTr, 48721 reg_val, EGR_PORT_GROUP_IDf); 48722 } 48723 } 48724 #ifdef BCM_TRIDENT_SUPPORT 48725 else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, EGR_PORT_GROUP_IDf) || 48726 SOC_IS_TRIDENT3X(unit)) { 48727 rv = _bcm_esw_egr_port_tab_get(unit, port, EGR_PORT_GROUP_IDf, 48728 (int *)pclass_id); 48729 48730 } 48731 #endif /* BCM_TRIDENT_SUPPORT */ 48732 #endif /* BCM_FIREBOLT_SUPPORT || BCM_TRX_SUPPORT */ 48733 break; 48734 case bcmPortClassVlanTranslateEgress: 48735 #if defined(BCM_TRX_SUPPORT) 48736 if (soc_reg_field_valid(unit, EGR_PORT_64r, VT_PORT_GROUP_IDf)) { 48737 if (SOC_REG_IS_VALID(unit, EGR_PORT_64r)) { 48738 rv = READ_EGR_PORT_64r(unit, port_out, ®_val64); 48739 if (BCM_SUCCESS(rv)) { 48740 *pclass_id = soc_reg64_field32_get(unit, EGR_PORT_64r, 48741 reg_val64, VT_PORT_GROUP_IDf); 48742 } 48743 } 48744 } else if (soc_reg_field_valid(unit, EGR_PORTr, VT_PORT_GROUP_IDf)) { 48745 rv = READ_EGR_PORTr(unit, port_out, ®_val); 48746 if (BCM_SUCCESS(rv)) { 48747 *pclass_id = soc_reg_field_get(unit, EGR_PORTr, 48748 reg_val, VT_PORT_GROUP_IDf); 48749 } 48750 } 48751 #ifdef BCM_TRIDENT_SUPPORT 48752 else if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, VT_PORT_GROUP_IDf) || 48753 SOC_IS_TRIDENT3X(unit)) { 48754 rv = _bcm_esw_egr_port_tab_get(unit, port, VT_PORT_GROUP_IDf, 48755 (int *)pclass_id); 48756 } 48757 #endif /* BCM_TRIDENT_SUPPORT */ 48758 #endif /* BCM_TRX_SUPPORT */ 48759 break; 48760 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 48761 case bcmPortClassEgress: 48762 if (SOC_MEM_FIELD_VALID(unit, EGR_PORTm, CLASS_IDf) || 48763 SOC_IS_TRIDENT3X(unit)) { 48764 rv = _bcm_esw_egr_port_tab_get(unit, port, CLASS_IDf, 48765 (int *)pclass_id); 48766 } 48767 break; 48768 #endif 48769 #if defined(BCM_TOMAHAWK_SUPPORT) 48770 case bcmPortClassFieldIngressDevicePort: 48771 if (!soc_feature(unit, soc_feature_multi_pipe_mapped_ports)) { 48772 return BCM_E_UNAVAIL; 48773 } 48774 rv = _bcm_esw_port_tab_get(unit, port, PORT_IPBM_INDEXf, 48775 &port_class_id); 48776 if (BCM_SUCCESS(rv)) { 48777 *pclass_id = (uint32) port_class_id; 48778 } 48779 break; 48780 #endif /* BCM_TOMAHAWK_SUPPORT */ 48781 48782 default: 48783 rv = BCM_E_PARAM; 48784 } 48785 } 48786 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 48787 48788 return rv; 48789 } 48790 48791 48792 /* 48793 * Function : _bcm_esw_port_config_set 48794 * Description : Internal function to set port configuration. 48795 * Parameters : (IN)unit - BCM device number. 48796 * (IN)port - Port number (see Notes for valid port formats). 48797 * (IN)type - Port property. 48798 * (IN)value - New property value. 48799 * Returns : BCM_E_XXX 48800 * Notes: 48801 * Current valid port types are: 48802 * GPORT PROXY 48803 * GPORT SUBPORT 48804 * GPORT (various types) that resolves to local physical port 48805 * BCM port (non-gport), local physical port 48806 */ 48807 int 48808 _bcm_esw_port_config_set(int unit, bcm_port_t port, 48809 _bcm_port_config_t type, int value) 48810 { 48811 int rv = BCM_E_UNAVAIL; /* Operation return status. */ 48812 48813 #ifdef BCM_HGPROXY_COE_SUPPORT 48814 if (BCM_GPORT_IS_SET(port) && 48815 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) && 48816 soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 48817 /* Don't resolve port */ 48818 } else 48819 #endif 48820 if (BCM_GPORT_IS_PROXY(port)) { 48821 /* Don't resolve port */ 48822 } else { 48823 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 48824 } 48825 48826 48827 PORT_LOCK(unit); 48828 48829 switch (type) { 48830 case _bcmPortL3UrpfMode: 48831 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 48832 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48833 URPF_MODEf, value); 48834 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 48835 break; 48836 case _bcmPortL3UrpfDefaultRoute: 48837 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 48838 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48839 URPF_DEFAULTROUTECHECKf, 48840 (value) ? 0 : 1); 48841 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 48842 break; 48843 case _bcmPortVlanTranslate: 48844 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48845 VT_ENABLEf, value); 48846 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 48847 defined(BCM_KATANA2_SUPPORT) 48848 if ((SOC_IS_TRIUMPH3(unit) || 48849 SOC_IS_TD2_TT2(unit) || 48850 SOC_IS_KATANA2(unit)) && (rv == SOC_E_NONE)) { 48851 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48852 VT_PORT_TYPE_SELECTf, value); 48853 if (rv == SOC_E_NONE) { 48854 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48855 VT_PORT_TYPE_SELECT_2f, value); 48856 } 48857 } else 48858 #endif 48859 { 48860 #if defined(BCM_TRX_SUPPORT) 48861 if (SOC_IS_TRX(unit) && (rv == SOC_E_NONE)) { 48862 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48863 VT_KEY_TYPE_USE_GLPf, value); 48864 if (rv == SOC_E_NONE) { 48865 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48866 VT_KEY_TYPE_2_USE_GLPf, value); 48867 } 48868 } 48869 #endif 48870 } 48871 break; 48872 case _bcmPortVlanPrecedence: 48873 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48874 VLAN_PRECEDENCEf, value); 48875 break; 48876 case _bcmPortVTMissDrop: 48877 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48878 VT_MISS_DROPf, value); 48879 break; 48880 case _bcmPortLookupMACEnable: 48881 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48882 MAC_BASED_VID_ENABLEf, value); 48883 break; 48884 case _bcmPortLookupIPEnable: 48885 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48886 SUBNET_BASED_VID_ENABLEf, 48887 value); 48888 break; 48889 case _bcmPortUseInnerPri: 48890 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 48891 defined(BCM_TRX_SUPPORT) 48892 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48893 USE_INNER_PRIf, value); 48894 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 48895 break; 48896 case _bcmPortUseOuterPri: 48897 #if defined(BCM_TRX_SUPPORT) 48898 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48899 TRUST_OUTER_DOT1Pf, value); 48900 #endif /* BCM_TRX_SUPPORT */ 48901 break; 48902 case _bcmPortVerifyOuterTpid: 48903 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 48904 defined(BCM_TRX_SUPPORT) 48905 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48906 OUTER_TPID_VERIFYf, value); 48907 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 48908 break; 48909 case _bcmPortVTKeyTypeFirst: 48910 #if defined(BCM_TRX_SUPPORT) 48911 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48912 VT_KEY_TYPEf, value); 48913 #endif /* BCM_TRX_SUPPORT */ 48914 break; 48915 case _bcmPortVTKeyPortFirst: 48916 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 48917 defined(BCM_KATANA2_SUPPORT) 48918 if (SOC_IS_TRIUMPH3(unit) || 48919 SOC_IS_TD2_TT2(unit) || 48920 SOC_IS_KATANA2(unit)) { 48921 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48922 VT_PORT_TYPE_SELECTf, value); 48923 } else 48924 #endif 48925 { 48926 #if defined(BCM_TRX_SUPPORT) 48927 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48928 VT_KEY_TYPE_USE_GLPf, value); 48929 #endif /* BCM_TRX_SUPPORT */ 48930 } 48931 break; 48932 case _bcmPortVTKeyTypeSecond: 48933 #if defined(BCM_TRX_SUPPORT) 48934 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48935 VT_KEY_TYPE_2f, value); 48936 #endif /* BCM_TRX_SUPPORT */ 48937 break; 48938 case _bcmPortVTKeyPortSecond: 48939 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 48940 defined(BCM_KATANA2_SUPPORT) 48941 if (SOC_IS_TRIUMPH3(unit) || 48942 SOC_IS_TD2_TT2(unit) || 48943 SOC_IS_KATANA2(unit)) { 48944 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48945 VT_PORT_TYPE_SELECT_2f, value); 48946 } else 48947 #endif 48948 { 48949 #if defined(BCM_TRX_SUPPORT) 48950 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48951 VT_KEY_TYPE_2_USE_GLPf, value); 48952 #endif /* BCM_TRX_SUPPORT */ 48953 } 48954 break; 48955 case _bcmPortIpmcV4Enable: 48956 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48957 V4IPMC_ENABLEf, value); 48958 break; 48959 case _bcmPortIpmcV6Enable: 48960 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48961 V6IPMC_ENABLEf, value); 48962 break; 48963 case _bcmPortIpmcVlanKey: 48964 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48965 IPMC_DO_VLANf, value); 48966 break; 48967 case _bcmPortCfiAsCng: 48968 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48969 CFI_AS_CNGf, value); 48970 break; 48971 case _bcmPortNni: 48972 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48973 NNI_PORTf, value); 48974 break; 48975 case _bcmPortHigigTrunkId: 48976 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT) 48977 if (value < 0) { 48978 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48979 HIGIG_TRUNKf, 0); 48980 if (BCM_SUCCESS(rv)) { 48981 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48982 HIGIG_TRUNK_IDf, 0); 48983 } 48984 } else { 48985 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48986 HIGIG_TRUNK_IDf, value); 48987 if (BCM_SUCCESS(rv)) { 48988 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48989 HIGIG_TRUNKf, 1); 48990 } 48991 } 48992 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */ 48993 break; 48994 case _bcmPortModuleLoopback: 48995 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 48996 ALLOW_SRC_MODf, value); 48997 break; 48998 case _bcmPortOuterTpidEnables: 48999 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 49000 defined(BCM_TRX_SUPPORT) 49001 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 49002 OUTER_TPID_ENABLEf)) { 49003 #ifdef BCM_TRX_SUPPORT 49004 rv = _bcm_trx_source_trunk_map_set(unit, port, OUTER_TPID_ENABLEf, 49005 (uint32)value); 49006 #endif 49007 } else { 49008 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 49009 OUTER_TPID_ENABLEf, value); 49010 } 49011 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 49012 break; 49013 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 49014 defined(BCM_GREYHOUND2_SUPPORT) 49015 case _bcmPortSvcMeterIndex: 49016 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || \ 49017 SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) { 49018 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 49019 SVC_METER_INDEXf, value); 49020 } 49021 break; 49022 case _bcmPortSvcMeterOffsetMode: 49023 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || \ 49024 SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) { 49025 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 49026 SVC_METER_OFFSET_MODEf, value); 49027 } 49028 break; 49029 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 49030 BCM_GREYHOUND2_SUPPORT */ 49031 #if defined(BCM_KATANA2_SUPPORT) 49032 case _bcmPortOamUseXlatedInnerVlan: 49033 if (SOC_IS_KATANA2(unit)) { 49034 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 49035 OAM_CVLAN_MEP_AFTER_VXLTf, value); 49036 rv = _bcm_esw_egr_port_tab_set(unit, port, 49037 OAM_CVLAN_MEP_AFTER_VXLTf, value); 49038 } 49039 break; 49040 #endif /* BCM_KATANA2_SUPPORT */ 49041 default: 49042 rv = BCM_E_INTERNAL; 49043 } 49044 49045 PORT_UNLOCK(unit); 49046 return (rv); 49047 } 49048 49049 /* 49050 * Function : _bcm_esw_port_config_get 49051 * Description : Internal function to get port configuration. 49052 * Parameters : (IN)unit - BCM device number. 49053 * (IN)port - Port number. 49054 * (IN)type - Port property. 49055 * (OUT)value -Port property value. 49056 * Returns : BCM_E_XXX 49057 * Notes: 49058 * Current valid port types are: 49059 * GPORT PROXY 49060 * GPORT SUBPORT 49061 * GPORT (various types) that resolves to local physical port 49062 * BCM port (non-gport), local physical port 49063 */ 49064 int 49065 _bcm_esw_port_config_get(int unit, bcm_port_t port, 49066 _bcm_port_config_t type, int *value) 49067 { 49068 int rv = BCM_E_UNAVAIL; /* Operation return status. */ 49069 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 49070 int tmp_value; /* Temporary value. */ 49071 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 49072 49073 #ifdef BCM_HGPROXY_COE_SUPPORT 49074 if (BCM_GPORT_IS_SET(port) && 49075 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) && 49076 soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 49077 /* Don't resolve port */ 49078 } else 49079 #endif 49080 if (BCM_GPORT_IS_PROXY(port)) { 49081 /* Don't resolve port */ 49082 } else { 49083 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 49084 } 49085 49086 PORT_LOCK(unit); 49087 49088 switch (type) { 49089 case _bcmPortL3UrpfMode: 49090 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 49091 rv = _bcm_esw_port_tab_get(unit, port, URPF_MODEf, value); 49092 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 49093 break; 49094 case _bcmPortL3UrpfDefaultRoute: 49095 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) 49096 rv = _bcm_esw_port_tab_get(unit, port, URPF_DEFAULTROUTECHECKf, 49097 &tmp_value); 49098 *value = (tmp_value) ? FALSE : TRUE; 49099 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 49100 break; 49101 case _bcmPortVlanTranslate: 49102 rv = _bcm_esw_port_tab_get(unit, port, VT_ENABLEf, value); 49103 break; 49104 case _bcmPortVlanPrecedence: 49105 rv = _bcm_esw_port_tab_get(unit, port, VLAN_PRECEDENCEf, value); 49106 break; 49107 case _bcmPortVTMissDrop: 49108 rv = _bcm_esw_port_tab_get(unit, port, VT_MISS_DROPf, value); 49109 break; 49110 case _bcmPortLookupMACEnable: 49111 rv = _bcm_esw_port_tab_get(unit, port, MAC_BASED_VID_ENABLEf, value); 49112 break; 49113 case _bcmPortLookupIPEnable: 49114 rv = _bcm_esw_port_tab_get(unit, port, SUBNET_BASED_VID_ENABLEf, 49115 value); 49116 break; 49117 case _bcmPortUseInnerPri: 49118 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 49119 defined(BCM_TRX_SUPPORT) 49120 rv = _bcm_esw_port_tab_get(unit, port, USE_INNER_PRIf, value); 49121 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 49122 break; 49123 case _bcmPortUseOuterPri: 49124 #if defined(BCM_TRX_SUPPORT) 49125 rv = _bcm_esw_port_tab_get(unit, port, TRUST_OUTER_DOT1Pf, value); 49126 #endif /* BCM_TRX_SUPPORT */ 49127 break; 49128 case _bcmPortVerifyOuterTpid: 49129 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 49130 defined(BCM_TRX_SUPPORT) 49131 rv = _bcm_esw_port_tab_get(unit, port, OUTER_TPID_VERIFYf, value); 49132 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 49133 break; 49134 case _bcmPortVTKeyTypeFirst: 49135 #if defined(BCM_TRX_SUPPORT) 49136 rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPEf, value); 49137 #endif /* BCM_TRX_SUPPORT */ 49138 break; 49139 case _bcmPortVTKeyPortFirst: 49140 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 49141 defined(BCM_KATANA2_SUPPORT) 49142 if (SOC_IS_TRIUMPH3(unit) || 49143 SOC_IS_TD2_TT2(unit) || 49144 SOC_IS_KATANA2(unit)) { 49145 rv = _bcm_esw_port_tab_get(unit, port, 49146 VT_PORT_TYPE_SELECTf, value); 49147 } else 49148 #endif 49149 { 49150 #if defined(BCM_TRX_SUPPORT) 49151 rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPE_USE_GLPf, value); 49152 #endif /* BCM_TRX_SUPPORT */ 49153 } 49154 break; 49155 case _bcmPortVTKeyTypeSecond: 49156 #if defined(BCM_TRX_SUPPORT) 49157 rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPE_2f, value); 49158 #endif /* BCM_TRX_SUPPORT */ 49159 break; 49160 case _bcmPortVTKeyPortSecond: 49161 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 49162 defined(BCM_KATANA2_SUPPORT) 49163 if (SOC_IS_TRIUMPH3(unit) || 49164 SOC_IS_TD2_TT2(unit) || 49165 SOC_IS_KATANA2(unit)) { 49166 rv = _bcm_esw_port_tab_get(unit, port, 49167 VT_PORT_TYPE_SELECT_2f, value); 49168 } else 49169 #endif 49170 { 49171 #if defined(BCM_TRX_SUPPORT) 49172 rv = _bcm_esw_port_tab_get(unit, port, VT_KEY_TYPE_2_USE_GLPf, value); 49173 #endif /* BCM_TRX_SUPPORT */ 49174 } 49175 break; 49176 case _bcmPortIpmcV4Enable: 49177 rv = _bcm_esw_port_tab_get(unit, port, V4IPMC_ENABLEf, value); 49178 break; 49179 case _bcmPortIpmcV6Enable: 49180 rv = _bcm_esw_port_tab_get(unit, port, V6IPMC_ENABLEf, value); 49181 break; 49182 case _bcmPortIpmcVlanKey: 49183 rv = _bcm_esw_port_tab_get(unit, port, IPMC_DO_VLANf, value); 49184 break; 49185 case _bcmPortCfiAsCng: 49186 rv = _bcm_esw_port_tab_get(unit, port, CFI_AS_CNGf, value); 49187 break; 49188 case _bcmPortNni: 49189 rv = _bcm_esw_port_tab_get(unit, port, NNI_PORTf, value); 49190 break; 49191 case _bcmPortHigigTrunkId: 49192 #if defined(BCM_BRADLEY_SUPPORT) || defined(BCM_TRX_SUPPORT) 49193 rv = _bcm_esw_port_tab_get(unit, port, HIGIG_TRUNKf, value); 49194 if (BCM_SUCCESS(rv)) { 49195 if (*value == 0) { 49196 *value = -1; 49197 } else { 49198 rv = _bcm_esw_port_tab_get(unit, port, 49199 HIGIG_TRUNK_IDf, value); 49200 } 49201 } 49202 #endif /* BCM_BRADLEY_SUPPORT || BCM_TRX_SUPPORT */ 49203 break; 49204 case _bcmPortModuleLoopback: 49205 rv = _bcm_esw_port_tab_get(unit, port, ALLOW_SRC_MODf, value); 49206 break; 49207 case _bcmPortOuterTpidEnables: 49208 #if defined(BCM_RAVEN_SUPPORT) || defined(BCM_FIREBOLT2_SUPPORT) || \ 49209 defined(BCM_TRX_SUPPORT) 49210 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 49211 OUTER_TPID_ENABLEf)) { 49212 #ifdef BCM_TRX_SUPPORT 49213 rv = _bcm_trx_source_trunk_map_get(unit, port, OUTER_TPID_ENABLEf, 49214 (uint32 *)value); 49215 #endif 49216 } else { 49217 rv = _bcm_esw_port_tab_get(unit, port, OUTER_TPID_ENABLEf, value); 49218 } 49219 #endif /* BCM_RAVEN_SUPPORT || BCM_FIREBOLT2_SUPPORT || BCM_TRX_SUPPORT */ 49220 break; 49221 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 49222 defined(BCM_GREYHOUND2_SUPPORT) 49223 case _bcmPortSvcMeterIndex: 49224 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) \ 49225 || SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) { 49226 rv = _bcm_esw_port_tab_get(unit, port, SVC_METER_INDEXf, value); 49227 } 49228 break; 49229 case _bcmPortSvcMeterOffsetMode: 49230 if (SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) \ 49231 || SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) { 49232 rv = _bcm_esw_port_tab_get(unit, port, SVC_METER_OFFSET_MODEf, value); 49233 } 49234 break; 49235 #endif /* BCM_KATANA_SUPPORT || BCM_TRIUMPH3_SUPPORT || 49236 BCM_GREYHOUND2_SUPPORT */ 49237 #if defined(BCM_KATANA2_SUPPORT) 49238 case _bcmPortOamUseXlatedInnerVlan: 49239 if (SOC_IS_KATANA2(unit)) { 49240 rv = _bcm_esw_port_tab_get(unit, port, OAM_CVLAN_MEP_AFTER_VXLTf, 49241 value); 49242 } 49243 break; 49244 #endif /* BCM_KATANA2_SUPPORT */ 49245 default: 49246 rv = BCM_E_INTERNAL; 49247 } 49248 PORT_UNLOCK(unit); 49249 return (rv); 49250 } 49251 49252 /* 49253 * Function: 49254 * bcm_port_force_vlan_set 49255 * Description: 49256 * To set the force vlan attribute of a port 49257 * Parameters: 49258 * unit device number 49259 * port port number 49260 * vlan vlan identifier 49261 * (0 - 4095) - use this VLAN id if egress packet is tagged 49262 * pkt_prio egress packet priority (-1, 0..7) 49263 * any negative priority value disable the priority 49264 * override if the egress packet is tagged 49265 * flags bit fields 49266 * BCM_PORT_FORCE_VLAN_ENABLE - enable force vlan on this 49267 * port 49268 * BCM_PORT_FORCE_VLAN_UNTAG - egress untagged when force 49269 * vlan is enabled on this port 49270 * 49271 * Return: 49272 * BCM_E_NONE 49273 * BCM_E_UNIT 49274 * BCM_E_PORT 49275 * BCM_E_PARAM 49276 * BCM_E_UNAVAIL 49277 * BCM_E_XXX 49278 */ 49279 int 49280 bcm_esw_port_force_vlan_set(int unit, bcm_port_t port, bcm_vlan_t vlan, 49281 int pkt_prio, uint32 flags) 49282 { 49283 int rv = BCM_E_UNAVAIL; 49284 49285 /* Make sure port module is initialized. */ 49286 PORT_INIT(unit); 49287 49288 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 49289 if (BCM_GPORT_IS_VLAN_PORT(port) || 49290 BCM_GPORT_IS_NIV_PORT(port) || 49291 BCM_GPORT_IS_EXTENDER_PORT(port)) { 49292 return bcm_td_vp_force_vlan_set(unit, port, vlan, flags); 49293 } 49294 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 49295 49296 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 49297 #if defined(BCM_TRX_SUPPORT) 49298 if (SOC_REG_FIELD_VALID(unit, EGR_PVLAN_EPORT_CONTROLr, PVLAN_UNTAGf)) { 49299 rv = _bcm_trx_port_force_vlan_set(unit, port, vlan, pkt_prio, flags); 49300 } 49301 #endif /* defined(BCM_TRX_SUPPORT) */ 49302 49303 return rv; 49304 } 49305 49306 /* 49307 * Function: 49308 * bcm_port_force_vlan_get 49309 * Description: 49310 * To get the force vlan attribute of a port 49311 * Parameters: 49312 * unit device number 49313 N_UNTAGf* port port number 49314 * vlan pointer to vlan identifier 49315 * (0 - 4095) - use this VLAN id if egress packet is tagged 49316 * valid only when BCM_PORT_FORCE_VLAN_ENABLE is set and 49317 * BCM_PORT_FORCE_VLAN_UNTAG is clear 49318 * pkt_prio egress packet priority (-1, 0 - 7) 49319 * valid only when BCM_PORT_FORCE_VLAN_ENABLE is set and 49320 * BCM_PORT_FORCE_VLAN_UNTAG is clear 49321 * flags bit fields 49322 * BCM_PORT_FORCE_VLAN_ENABLE - enable force vlan on this 49323 * port 49324 * BCM_PORT_FORCE_VLAN_UNTAG - egress untagged when force 49325 * vlan is enabled on this port 49326 * 49327 * Return: 49328 * BCM_E_XXX 49329 */ 49330 int 49331 bcm_esw_port_force_vlan_get(int unit, bcm_port_t port, bcm_vlan_t *vlan, 49332 int *pkt_prio, uint32 *flags) 49333 { 49334 int rv = BCM_E_UNAVAIL; 49335 49336 /* Make sure port module is initialized. */ 49337 PORT_INIT(unit); 49338 49339 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 49340 if (BCM_GPORT_IS_VLAN_PORT(port) || 49341 BCM_GPORT_IS_NIV_PORT(port) || 49342 BCM_GPORT_IS_EXTENDER_PORT(port)) { 49343 return bcm_td_vp_force_vlan_get(unit, port, vlan, flags); 49344 } 49345 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 49346 49347 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 49348 49349 #if defined(BCM_TRX_SUPPORT) 49350 if (SOC_REG_FIELD_VALID(unit, EGR_PVLAN_EPORT_CONTROLr, PVLAN_UNTAGf)) { 49351 rv = _bcm_trx_port_force_vlan_get(unit, port, vlan, pkt_prio, flags); 49352 } 49353 #endif /* defined(BCM_TRX_SUPPORT) */ 49354 49355 return rv; 49356 } 49357 49358 /* 49359 * Function: 49360 * bcm_port_phy_control_set 49361 * Description: 49362 * Set PHY specific properties 49363 * Parameters: 49364 * unit device number 49365 * port port number 49366 * type configuration type 49367 * value new value for the configuration 49368 * Return: 49369 * BCM_E_XXX 49370 */ 49371 int 49372 bcm_esw_port_phy_control_set(int unit, bcm_port_t port, 49373 bcm_port_phy_control_t type, uint32 value) 49374 { 49375 int rv; 49376 bcm_port_t local_port = 0; 49377 int phy_lane = -1; 49378 int phyn = 0, sys_side = 0; 49379 49380 /* Make sure port module is initialized. */ 49381 PORT_INIT(unit); 49382 49383 if (SOC_USE_PORTCTRL(unit)) { 49384 BCM_IF_ERROR_RETURN 49385 (bcmi_esw_portctrl_phy_control_set(unit, port, type, value)); 49386 #ifdef BCM_TOMAHAWK_SUPPORT 49387 /* If FEC/CL91/CL108 is enabled/disabled on the 25/27/50/53G ports, we will need to update ASF parameters */ 49388 if (SOC_IS_TOMAHAWKX(unit)) { 49389 if ((type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL91) 49390 || (type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL108)) { 49391 bcm_port_info_t port_info; 49392 49393 bcm_port_info_t_init(&port_info); 49394 BCM_IF_ERROR_RETURN(bcm_esw_port_info_get(unit, port, &port_info)); 49395 49396 if ((port_info.speed == 25000) || (port_info.speed == 27000) || 49397 (port_info.speed == 50000) || (port_info.speed == 53000) || 49398 (port_info.speed == 100000) || (port_info.speed == 106000)){ 49399 int mode; 49400 49401 BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_get(unit, port, &mode)); 49402 BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_set(unit, port, mode)); 49403 } 49404 } 49405 } 49406 #endif 49407 return BCM_E_NONE; 49408 } 49409 49410 if(BCM_PHY_GPORT_IS_PHYN(port)) { 49411 local_port = BCM_PHY_GPORT_PHYN_PORT_PORT_GET(port); 49412 phyn = BCM_PHY_GPORT_PHYN_PORT_PHYN_GET(port); 49413 phy_lane = -1; 49414 } else if(BCM_PHY_GPORT_IS_PHYN_LANE(port)) { 49415 local_port = BCM_PHY_GPORT_PHYN_LANE_PORT_PORT_GET(port); 49416 phyn = BCM_PHY_GPORT_PHYN_LANE_PORT_PHYN_GET(port); 49417 phy_lane = BCM_PHY_GPORT_PHYN_LANE_PORT_LANE_GET(port); 49418 } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE(port)) { 49419 local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PORT_GET(port); 49420 phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PHYN_GET(port); 49421 sys_side = TRUE; 49422 phy_lane = -1; 49423 } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE_LANE(port)) { 49424 local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PORT_GET(port); 49425 phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PHYN_GET(port); 49426 phy_lane = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_LANE_GET(port); 49427 sys_side = TRUE; 49428 } else if (BCM_PHY_GPORT_IS_LANE(port)) { 49429 local_port = BCM_PHY_GPORT_LANE_PORT_PORT_GET(port); 49430 phy_lane = BCM_PHY_GPORT_LANE_PORT_LANE_GET(port); 49431 } else { 49432 BCM_IF_ERROR_RETURN 49433 (_bcm_esw_port_gport_validate(unit, port, &local_port)); 49434 49435 PORT_LOCK(unit); 49436 rv = soc_phyctrl_control_set(unit, local_port, (soc_phy_control_t) type, value); 49437 if (BCM_SUCCESS(rv)) { 49438 PORT_INFO_RX_LOS_SET(unit, local_port, type, value); 49439 } 49440 PORT_UNLOCK(unit); 49441 49442 #ifdef BCM_TOMAHAWK_SUPPORT 49443 /* If FEC/CL91/CL108 is enabled/disabled on the 25/27/50/53G ports, we will need to update ASF parameters */ 49444 if (SOC_IS_TOMAHAWKX(unit)) { 49445 if ((type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL91) 49446 || (type == _SHR_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL108)) { 49447 bcm_port_info_t port_info; 49448 49449 bcm_port_info_t_init(&port_info); 49450 BCM_IF_ERROR_RETURN(bcm_esw_port_info_get(unit, port, &port_info)); 49451 49452 if ((port_info.speed == 25000) || (port_info.speed == 27000) || 49453 (port_info.speed == 50000) || (port_info.speed == 53000) || 49454 (port_info.speed == 100000) || (port_info.speed == 106000)){ 49455 int mode; 49456 49457 BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_get(unit, port, &mode)); 49458 BCM_IF_ERROR_RETURN(bcm_esw_port_asf_mode_set(unit, port, mode)); 49459 } 49460 } 49461 } 49462 #endif 49463 return rv; 49464 } 49465 49466 if (!SOC_PORT_VALID(unit, local_port)) { 49467 return BCM_E_PORT; 49468 } 49469 49470 PORT_LOCK(unit); 49471 rv = soc_phyctrl_redirect_control_set(unit, local_port, phyn, phy_lane, 49472 sys_side, (soc_phy_control_t) type, value); 49473 if (BCM_SUCCESS(rv)) { 49474 PORT_INFO_RX_LOS_SET(unit, local_port, type, value); 49475 } 49476 PORT_UNLOCK(unit); 49477 49478 return rv; 49479 } 49480 49481 /* 49482 * Function: 49483 * bcm_esw_port_phy_control_get 49484 * Description: 49485 * Set PHY specific properties 49486 * Parameters: 49487 * unit device number 49488 * port port number 49489 * type configuration type 49490 * value value for the configuration 49491 * Return: 49492 * BCM_E_XXX 49493 */ 49494 int 49495 bcm_esw_port_phy_control_get(int unit, bcm_port_t port, 49496 bcm_port_phy_control_t type, uint32 *value) 49497 { 49498 int rv; 49499 bcm_port_t local_port; 49500 int phy_lane = -1; 49501 int phyn = 0, sys_side = 0; 49502 49503 if (NULL == value) { 49504 return BCM_E_PARAM; 49505 } 49506 49507 /* Make sure port module is initialized. */ 49508 PORT_INIT(unit); 49509 49510 if (SOC_USE_PORTCTRL(unit)) { 49511 return bcmi_esw_portctrl_phy_control_get(unit, port, type, value); 49512 } 49513 49514 if(BCM_PHY_GPORT_IS_PHYN(port)) { 49515 local_port = BCM_PHY_GPORT_PHYN_PORT_PORT_GET(port); 49516 phyn = BCM_PHY_GPORT_PHYN_PORT_PHYN_GET(port); 49517 phy_lane = -1; 49518 } else if(BCM_PHY_GPORT_IS_PHYN_LANE(port)) { 49519 local_port = BCM_PHY_GPORT_PHYN_LANE_PORT_PORT_GET(port); 49520 phyn = BCM_PHY_GPORT_PHYN_LANE_PORT_PHYN_GET(port); 49521 phy_lane = BCM_PHY_GPORT_PHYN_LANE_PORT_LANE_GET(port); 49522 } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE(port)) { 49523 local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PORT_GET(port); 49524 phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PHYN_GET(port); 49525 sys_side = TRUE; 49526 phy_lane = -1; 49527 } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE_LANE(port)) { 49528 local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PORT_GET(port); 49529 phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PHYN_GET(port); 49530 phy_lane = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_LANE_GET(port); 49531 sys_side = TRUE; 49532 } else if (BCM_PHY_GPORT_IS_LANE(port)) { 49533 local_port = BCM_PHY_GPORT_LANE_PORT_PORT_GET(port); 49534 phy_lane = BCM_PHY_GPORT_LANE_PORT_LANE_GET(port); 49535 } else { 49536 BCM_IF_ERROR_RETURN 49537 (_bcm_esw_port_gport_validate(unit, port, &port)); 49538 49539 PORT_LOCK(unit); 49540 rv = soc_phyctrl_control_get(unit, port, (soc_phy_control_t) type, value); 49541 PORT_UNLOCK(unit); 49542 return rv; 49543 } 49544 49545 if (!SOC_PORT_VALID(unit, local_port)) { 49546 return BCM_E_PORT; 49547 } 49548 49549 PORT_LOCK(unit); 49550 rv = soc_phyctrl_redirect_control_get(unit, local_port, phyn, phy_lane, 49551 sys_side, (soc_phy_control_t) type, value); 49552 PORT_UNLOCK(unit); 49553 49554 return rv; 49555 } 49556 49557 /* 49558 * Function: 49559 * bcm_esw_port_phy_firmware_set 49560 * Purpose: 49561 * Write the firmware to the PHY device's non-volatile storage. 49562 * Parameters: 49563 * unit - (IN) Unit number. 49564 * port - (IN) Port number 49565 * flags - (IN) PHY spcific flags, such as BCM_PORT_PHY_INTERNAL 49566 * offset - (IN) Offset to the firmware data array 49567 * array - (IN) The firmware data array 49568 * length - (IN) The length of the firmware data array 49569 * Returns: 49570 * BCM_E_XXX 49571 * Notes: 49572 */ 49573 int 49574 bcm_esw_port_phy_firmware_set(int unit, bcm_port_t port, uint32 flags, 49575 int offset, uint8 *array, int length) 49576 { 49577 int rv; 49578 49579 /* Make sure port module is initialized. */ 49580 PORT_INIT(unit); 49581 49582 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 49583 49584 PORT_LOCK(unit); 49585 rv = soc_phyctrl_firmware_set(unit, port, flags,offset,array,length); 49586 PORT_UNLOCK(unit); 49587 49588 return rv; 49589 } 49590 49591 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 49592 /* 49593 * Function : _bcm_esw_port_subport_index_get 49594 * Description : Get the subport index for the specified mod port. 49595 * 49596 * Parameters : (IN) unit - BCM device number 49597 * (IN) modport - GPORT ID 49598 * (OUT) subport_index - subport index 49599 * Returns : BCM_E_XXX 49600 */ 49601 int 49602 _bcm_esw_port_subport_index_get(int unit, bcm_gport_t modport, 49603 int *subport_index) 49604 { 49605 int id_out = 0; 49606 bcm_module_t mod_out = 0; 49607 bcm_port_t port_out = 0; 49608 bcm_trunk_t tgid_out = 0; 49609 int base_index = 0; 49610 int result = FALSE; 49611 modid_base_ptr_entry_t modid_base_entry; 49612 soc_info_t *si = &SOC_INFO(unit); 49613 int i = 0, valid = 0, modid = 0; 49614 49615 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, modport, 49616 &mod_out, &port_out, &tgid_out, &id_out)); 49617 if ((-1 != tgid_out) || (-1 != id_out)) { 49618 return BCM_E_PARAM; 49619 } 49620 49621 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 49622 for (i = 0; i < si->num_modules; i++) { 49623 if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] 49624 == mod_out) { 49625 BCM_IF_ERROR_RETURN( 49626 _bcm_esw_stk_get_mod_config_by_type(unit, 49627 BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid, 49628 &base_index)); 49629 if ((valid == 1) && (modid == mod_out)) { 49630 if (port_out > 49631 src_modid_base_index_bk[unit]->num_ports[modid]) { 49632 return BCM_E_PARAM; 49633 } 49634 *subport_index = base_index + port_out; 49635 return BCM_E_NONE; 49636 } 49637 } 49638 } 49639 } 49640 49641 /* Check modport in one of additional module */ 49642 BCM_IF_ERROR_RETURN ( 49643 _bcm_esw_my_modid_additional_check(unit, mod_out, &result)); 49644 if(result == FALSE) { 49645 return BCM_E_PORT; 49646 } 49647 MODULE_ID_LOWER_6_BITS(mod_out); /* lower 6 bit */ 49648 SOC_IF_ERROR_RETURN( 49649 READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_out, 49650 &modid_base_entry)); 49651 base_index = soc_MODID_BASE_PTRm_field32_get( 49652 unit, &modid_base_entry, MODID_BASEf); 49653 *subport_index = base_index; /* the index is indicated by module base ptr */ 49654 49655 return BCM_E_NONE; 49656 } 49657 49658 /* 49659 * Function : _bcm_esw_modport_local_get 49660 * Description : Get the physical port for the specified mod port. 49661 * 49662 * Parameters : (IN) unit - BCM device number 49663 * (IN) modport - Gport number 49664 * (OUT) local_port - port number 49665 * 49666 * Returns : BCM_E_XXX 49667 */ 49668 int _bcm_esw_modport_local_get(int unit, bcm_gport_t modport, bcm_port_t *local_port) 49669 { 49670 int subport_index = 0; 49671 modport_map_subport_entry_t modport_map_subport_entry; 49672 49673 /* Make sure port module is initialized. */ 49674 PORT_INIT(unit); 49675 49676 /* Parameter check */ 49677 if (!BCM_GPORT_IS_MODPORT(modport)) { 49678 return BCM_E_PARAM; 49679 } 49680 49681 if(local_port == NULL) { 49682 return BCM_E_PARAM; 49683 } 49684 49685 SOC_IF_ERROR_RETURN( 49686 _bcm_esw_port_subport_index_get(unit, modport, &subport_index)); 49687 49688 SOC_IF_ERROR_RETURN( 49689 READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index, 49690 &modport_map_subport_entry)); 49691 *local_port = soc_MODPORT_MAP_SUBPORTm_field32_get( 49692 unit, &modport_map_subport_entry, DESTf); 49693 49694 return BCM_E_NONE; 49695 } 49696 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 49697 49698 /* 49699 * Function : bcm_esw_port_local_get 49700 * Description : Get the local port from the given GPORT ID. 49701 * 49702 * Parameters : (IN) unit - BCM device number 49703 * (IN) gport - global port identifier 49704 * (OUT) local_port - local port encoded in gport 49705 * Returns : BCM_E_XXX 49706 */ 49707 int 49708 bcm_esw_port_local_get(int unit, bcm_gport_t gport, bcm_port_t *local_port) 49709 { 49710 bcm_module_t my_mod, encap_mod; 49711 bcm_port_t encap_port; 49712 int num_modid, isLocal = 0; 49713 soc_info_t *si = &SOC_INFO(unit); 49714 49715 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 49716 int rv = BCM_E_NONE; 49717 #endif 49718 49719 #if defined(BCM_KATANA2_SUPPORT) 49720 bcm_trunk_t trunk_id = BCM_TRUNK_INVALID; 49721 int id = -1; 49722 int pp_port = 0; 49723 int min_pp_port = SOC_INFO(unit).pp_port_index_min; 49724 int max_pp_port = SOC_INFO(unit).pp_port_index_max; 49725 #endif /* BCM_KATANA2_SUPPORT */ 49726 49727 /* Make sure port module is initialized. */ 49728 PORT_INIT(unit); 49729 49730 BCM_IF_ERROR_RETURN(bcm_esw_stk_modid_count(unit, &num_modid)); 49731 if ((!num_modid) && !BCM_GPORT_IS_DEVPORT(gport) ){ 49732 /* Only devport gport can be supported on device with no modid */ 49733 return BCM_E_UNAVAIL; 49734 } 49735 49736 if (BCM_GPORT_IS_LOCAL(gport)) { 49737 *local_port = BCM_GPORT_LOCAL_GET(gport); 49738 } else if (BCM_GPORT_IS_LOCAL_CPU(gport)) { 49739 *local_port = CMIC_PORT(unit); 49740 } else if (BCM_GPORT_IS_DEVPORT(gport)) { 49741 *local_port = BCM_GPORT_DEVPORT_PORT_GET(gport); 49742 if (unit != BCM_GPORT_DEVPORT_DEVID_GET(gport)) { 49743 return BCM_E_PORT; 49744 } 49745 } else if (BCM_GPORT_IS_MODPORT(gport) || BCM_GPORT_IS_PROXY(gport)) { 49746 BCM_IF_ERROR_RETURN( 49747 bcm_esw_stk_my_modid_get(unit, &my_mod)); 49748 49749 if (BCM_GPORT_IS_MODPORT(gport)) { 49750 encap_mod = BCM_GPORT_MODPORT_MODID_GET(gport); 49751 encap_port = BCM_GPORT_MODPORT_PORT_GET(gport); 49752 } else { 49753 encap_mod = BCM_GPORT_PROXY_MODID_GET(gport); 49754 encap_port = BCM_GPORT_PROXY_PORT_GET(gport); 49755 } 49756 49757 if (encap_mod == my_mod){ 49758 *local_port = encap_port; 49759 } else if ((num_modid > 1) && 49760 !si->coe_stacking_mode) { 49761 BCM_IF_ERROR_RETURN( 49762 _bcm_esw_modid_is_local(unit, encap_mod, &isLocal)); 49763 if (isLocal) { 49764 #if defined(BCM_TOMAHAWK_SUPPORT) 49765 /* Call asymmetric dual modid unmapping function */ 49766 if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) { 49767 BCM_IF_ERROR_RETURN ( 49768 _bcm_esw_stk_asymmetric_dual_modmap_map(unit, 49769 BCM_STK_MODMAP_SET, &encap_mod, &encap_port)); 49770 *local_port = encap_port; 49771 } else 49772 #endif /* BCM_TOMAHAWK_SUPPORT */ 49773 { 49774 *local_port = encap_port + 49775 (encap_mod - my_mod) * (SOC_MODPORT_MAX(unit) + 1); 49776 } 49777 } else { 49778 return BCM_E_PORT; 49779 } 49780 } else { 49781 49782 #if defined(BCM_KATANA2_SUPPORT) 49783 if (soc_feature(unit, soc_feature_linkphy_coe) || 49784 soc_feature(unit, soc_feature_subtag_coe)) { 49785 if (_bcm_kt2_mod_is_coe_mod_check(unit, encap_mod) == BCM_E_NONE) { 49786 BCM_IF_ERROR_RETURN( 49787 _bcm_kt2_modport_to_pp_port_get(unit, 49788 encap_mod, encap_port, &pp_port)); 49789 #if defined BCM_METROLITE_SUPPORT 49790 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 49791 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 49792 *local_port = pp_port; 49793 return BCM_E_NONE; 49794 } 49795 } else 49796 #endif 49797 { 49798 if ((pp_port >= min_pp_port) && (pp_port <= max_pp_port)) { 49799 *local_port = pp_port; 49800 return BCM_E_NONE; 49801 } 49802 } 49803 } 49804 } else 49805 #endif 49806 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 49807 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 49808 _bcm_xgs5_subport_coe_mod_port_local(unit, encap_mod, encap_port)) { 49809 BCM_IF_ERROR_RETURN( 49810 _bcmi_coe_subport_mod_port_physical_port_get(unit, encap_mod, 49811 encap_port, local_port)); 49812 } 49813 /* Call modport to local function */ 49814 else if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 49815 BCM_IF_ERROR_RETURN ( 49816 _bcm_esw_modport_local_get(unit, gport, &encap_port)); 49817 *local_port = encap_port; 49818 } else 49819 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 49820 { 49821 return BCM_E_PORT; 49822 } 49823 } 49824 if (soc_feature(unit, soc_feature_sysport_remap)) { 49825 BCM_XLATE_SYSPORT_S2P(unit, local_port); 49826 } 49827 if (!SOC_PORT_VALID(unit, *local_port)) { 49828 return BCM_E_PORT; 49829 } 49830 } else if (BCM_GPORT_IS_SUBPORT_PORT(gport)) { 49831 49832 #if defined(BCM_HGPROXY_COE_SUPPORT) 49833 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 49834 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) { 49835 return _bcmi_coe_subport_physical_port_get(unit, gport, local_port); 49836 } else 49837 #endif /* BCM_HGPROXY_COE_SUPPORT */ 49838 #if defined(BCM_KATANA2_SUPPORT) 49839 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, gport)) { 49840 pp_port = BCM_GPORT_SUBPORT_PORT_GET(gport); 49841 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_mod)); 49842 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, gport, &encap_mod, 49843 &encap_port, &trunk_id, &id)); 49844 if (_bcm_kt2_mod_is_coe_mod_check(unit, encap_mod) == BCM_E_NONE) { 49845 #if defined BCM_METROLITE_SUPPORT 49846 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 49847 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 49848 *local_port = pp_port; 49849 return BCM_E_NONE; 49850 } 49851 } else 49852 #endif 49853 { 49854 if ((pp_port >= min_pp_port) && (pp_port <= max_pp_port)) { 49855 *local_port = pp_port; 49856 return BCM_E_NONE; 49857 } 49858 } 49859 } 49860 } 49861 #endif 49862 return BCM_E_PORT; 49863 } else if (BCM_GPORT_IS_VLAN_PORT(gport)) { 49864 *local_port = BCM_GPORT_VLAN_PORT_ID_GET(gport); 49865 } else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 49866 *local_port = BCM_GPORT_EXTENDER_PORT_ID_GET(gport); 49867 } else if (BCM_GPORT_IS_NIV_PORT(gport)) { 49868 *local_port = BCM_GPORT_NIV_PORT_ID_GET(gport); 49869 } else if (BCM_GPORT_IS_VXLAN_PORT(gport)) { 49870 *local_port = BCM_GPORT_VXLAN_PORT_ID_GET(gport); 49871 } else if (BCM_GPORT_IS_FLOW_PORT(gport)) { 49872 *local_port = BCM_GPORT_FLOW_PORT_ID_GET(gport); 49873 } else if (BCM_GPORT_IS_L2GRE_PORT(gport)) { 49874 *local_port = BCM_GPORT_L2GRE_PORT_ID_GET(gport); 49875 } else if (BCM_GPORT_IS_MIM_PORT(gport)) { 49876 *local_port = BCM_GPORT_MIM_PORT_ID_GET(gport); 49877 } else if (BCM_GPORT_IS_MPLS_PORT(gport)) { 49878 *local_port = BCM_GPORT_MPLS_PORT_ID_GET(gport); 49879 } else if (BCM_GPORT_IS_TRUNK(gport)) { 49880 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 49881 if (soc_feature(unit, soc_feature_vp_lag)) { 49882 rv = _bcm_esw_trunk_tid_to_vp_lag_vp(unit, 49883 BCM_GPORT_TRUNK_GET(gport),local_port); 49884 return (rv != BCM_E_NONE) ? BCM_E_PORT : BCM_E_NONE; 49885 } 49886 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 49887 return BCM_E_PORT; 49888 } else if (BCM_GPORT_IS_VP_GROUP(gport)) { 49889 *local_port = BCM_GPORT_VP_GROUP_GET(gport); 49890 } else { 49891 return BCM_E_PORT; 49892 } 49893 49894 return BCM_E_NONE; 49895 } 49896 49897 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 49898 49899 /* 49900 * Function : _bcm_esw_modid_is_coe_mod 49901 * Description : Identifies if given modid is a CoE module 49902 * 49903 * Parameters : (IN) unit - BCM device number 49904 * (IN) modnd - Module ID 49905 * Returns : BCM_E_NONE, if it is a CoE Module 49906 * BCM_E_NOT_FOUND, if it is not a CoE Module 49907 */ 49908 49909 int 49910 _bcm_esw_modid_is_coe_mod(int unit, bcm_module_t modid) 49911 { 49912 bcm_stk_modid_config_t mod_cfg; 49913 mod_cfg.modid = modid; 49914 49915 mod_cfg.modid_type = bcmStkModidTypeCoe; 49916 49917 /* Also check if this is one of the CoE modules */ 49918 return bcm_esw_stk_modid_config_get(unit, &mod_cfg); 49919 } 49920 #endif 49921 49922 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 49923 /* 49924 * Function : _bcm_esw_modid_is_multi_nexthop_mod 49925 * Description : Identifies if given modid is a Multi Next Hop module 49926 * 49927 * Parameters : (IN) unit - BCM device number 49928 * (IN) modnd - Module ID 49929 * Returns : BCM_E_NONE, if it is a Multi Next Hop Module 49930 * BCM_E_NOT_FOUND, if it is not a Multi Next Hop Module 49931 */ 49932 49933 int 49934 _bcm_esw_modid_is_multi_nexthop_mod(int unit, bcm_module_t modid) 49935 { 49936 bcm_stk_modid_config_t mod_cfg; 49937 49938 if ((modid < 0) || (modid > SOC_MODID_MAX(unit))) { 49939 return BCM_E_PARAM; 49940 } 49941 mod_cfg.modid = modid; 49942 mod_cfg.modid_type = bcmStkModidTypeMultiNextHops; 49943 49944 /* Also check if this is one of the Multi Next Hop modules */ 49945 return bcm_esw_stk_modid_config_get(unit, &mod_cfg); 49946 } 49947 49948 /* 49949 * Function : _bcm_esw_is_multi_nexthop_mod_port 49950 * Description : Identifies if given modid is a Multi Next Hop module port 49951 * 49952 * Parameters : (IN) unit - BCM device number 49953 * (IN) modid - Mod Id value 49954 * (IN) port - Port Id value 49955 * Returns : TRUE if is Multi Next Hop module port, FALSE otherwise 49956 */ 49957 int 49958 _bcm_esw_is_multi_nexthop_mod_port(int unit, bcm_module_t modid, 49959 bcm_port_t port) 49960 { 49961 int rv = BCM_E_NONE; 49962 int result = FALSE; 49963 49964 if(_bcm_esw_modid_is_multi_nexthop_mod(unit, modid) == BCM_E_NONE) { 49965 if (port <= src_modid_base_index_bk[unit]->num_ports[modid]) { 49966 return TRUE; 49967 } 49968 } else { 49969 rv = _bcm_esw_my_modid_additional_check(unit, modid, &result); 49970 if (BCM_FAILURE(rv)) { 49971 return FALSE; 49972 } 49973 return result; 49974 } 49975 return FALSE; 49976 } 49977 #endif 49978 49979 /* 49980 * Function : _bcm_esw_modid_is_local 49981 * Description : Identifies if given modid is local on a given unit 49982 * 49983 * Parameters : (IN) unit - BCM device number 49984 * (IN) modnd - Module ID 49985 * (OUT) result - TRUE if modid is local, FALSE otherwise 49986 * Returns : BCM_E_XXX 49987 */ 49988 int 49989 _bcm_esw_modid_is_local(int unit, bcm_module_t modid, int *result) 49990 { 49991 bcm_module_t mymodid; 49992 int rv; 49993 soc_info_t *si=&SOC_INFO(unit); 49994 49995 /* Input parameters check. */ 49996 if (NULL == result) { 49997 return (BCM_E_PARAM); 49998 } 49999 50000 COMPILER_REFERENCE(si); 50001 50002 /* Get local module id. */ 50003 rv = bcm_esw_stk_my_modid_get(unit, &mymodid); 50004 if (BCM_E_UNAVAIL == rv) { 50005 if (BCM_MODID_INVALID == modid) { 50006 *result = TRUE; 50007 } else { 50008 #if defined(BCM_HGPROXY_COE_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 50009 /* If hg_proxy or if (subtag/linkPhy-Coe && stacking-mode) 50010 check the local modid */ 50011 if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 50012 ((soc_feature(unit, soc_feature_subtag_coe) || 50013 (soc_feature(unit, soc_feature_linkphy_coe))) && 50014 si->coe_stacking_mode)) && 50015 (_bcm_esw_modid_is_coe_mod(unit, modid) == BCM_E_NONE)) { 50016 *result = TRUE; 50017 } else 50018 #endif 50019 { 50020 *result = FALSE; 50021 } 50022 } 50023 return (BCM_E_NONE); 50024 } 50025 50026 if (mymodid == modid) { 50027 *result = TRUE; 50028 } else if ((modid > mymodid) && (modid < mymodid + NUM_MODID(unit))) { 50029 *result = TRUE; 50030 } 50031 #if defined(BCM_HGPROXY_COE_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 50032 /* If hg_proxy or if (subtag/linkPhy-Coe && stacking-mode) 50033 check the local modid */ 50034 else if ((soc_feature(unit, soc_feature_hgproxy_subtag_coe) || 50035 ((soc_feature(unit, soc_feature_subtag_coe) || 50036 (soc_feature(unit, soc_feature_linkphy_coe))) && 50037 si->coe_stacking_mode)) && 50038 (_bcm_esw_modid_is_coe_mod(unit, modid) == BCM_E_NONE)) { 50039 *result = TRUE; 50040 } 50041 #endif /* BCM_HGPROXY_COE_SUPPORT || BCM_KATANA2_SUPPORT */ 50042 else { 50043 *result = FALSE; 50044 } 50045 50046 return (BCM_E_NONE); 50047 } 50048 50049 50050 /* 50051 * Function : _bcm_gport_modport_hw2api_map 50052 * Description : Remaps module and port from HW space to API space 50053 * 50054 * Parameters : (IN) unit - BCM device number 50055 * (IN) mod_in - Module ID to map 50056 * (IN) port_in - Physical port to map 50057 * (OUT) mod_out - Module ID after mapping 50058 * (OUT) port_out - Port number after mapping 50059 * Returns : BCM_E_XXX 50060 * Notes : If mod_out == NULL then port_out will be local physical port. 50061 */ 50062 int 50063 _bcm_gport_modport_hw2api_map(int unit, bcm_module_t mod_in, bcm_port_t port_in, 50064 bcm_module_t *mod_out, bcm_port_t *port_out) 50065 { 50066 if (port_out == NULL) { 50067 return (BCM_E_PARAM); 50068 } 50069 50070 if (NUM_MODID(unit) == 1) { /* HW device has single modid */ 50071 if (mod_out != NULL) { 50072 *mod_out = mod_in; 50073 } 50074 *port_out = port_in; 50075 50076 return (BCM_E_NONE); 50077 } 50078 /* Here only for devices with multiple modid NUM_MODID(unit) > 1 */ 50079 if (mod_out == NULL) { /* physical port requested */ 50080 int isLocal = 0; 50081 bcm_module_t mymodid; 50082 BCM_IF_ERROR_RETURN( 50083 _bcm_esw_modid_is_local(unit, mod_in, &isLocal)); 50084 if (isLocal != TRUE) { 50085 return (BCM_E_PARAM); 50086 } 50087 BCM_IF_ERROR_RETURN (bcm_esw_stk_my_modid_get(unit, &mymodid)); 50088 50089 #if defined(BCM_TOMAHAWK_SUPPORT) 50090 /* Call asymmetric dual modid unmapping function */ 50091 if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) { 50092 BCM_IF_ERROR_RETURN ( 50093 _bcm_esw_stk_asymmetric_dual_modmap_map(unit, 50094 BCM_STK_MODMAP_SET, &mod_in, &port_in)); 50095 *port_out = port_in; 50096 } else 50097 #endif /* BCM_TOMAHAWK_SUPPORT */ 50098 { 50099 *port_out = port_in + 50100 (mod_in - mymodid) * (SOC_MODPORT_MAX(unit) + 1); 50101 } 50102 } else { /* NUM_MODID(unit) > 1 and not local physical port */ 50103 #if defined(BCM_TOMAHAWK_SUPPORT) 50104 /* Call asymmetric dual modid mapping function */ 50105 if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) { 50106 BCM_IF_ERROR_RETURN ( 50107 _bcm_esw_stk_asymmetric_dual_modmap_map(unit, 50108 BCM_STK_MODMAP_GET, &mod_in, &port_in)); 50109 *mod_out = mod_in; 50110 *port_out = port_in; 50111 } else 50112 #endif /* BCM_TOMAHAWK_SUPPORT */ 50113 { 50114 *port_out = port_in % (SOC_MODPORT_MAX(unit) + 1); 50115 *mod_out = mod_in + port_in / (SOC_MODPORT_MAX(unit) + 1); 50116 } 50117 } 50118 50119 return (BCM_E_NONE); 50120 } 50121 50122 /* 50123 * Function : bcm_port_gport_get 50124 * Description : Get the GPORT ID for the specified physical port. 50125 * 50126 * Parameters : (IN) unit - BCM device number 50127 * (IN) port - Port number 50128 * (OUT) gport - GPORT ID 50129 * Returns : BCM_E_XXX 50130 * Notes: 50131 * Always returns a MODPORT gport or an error. 50132 */ 50133 int 50134 bcm_esw_port_gport_get(int unit, bcm_port_t port, bcm_gport_t *gport) 50135 { 50136 int rv; 50137 _bcm_gport_dest_t dest; 50138 50139 /* Make sure port module is initialized. */ 50140 PORT_INIT(unit); 50141 50142 _bcm_gport_dest_t_init(&dest); 50143 50144 PORT_PARAM_CHECK(unit, port); 50145 50146 rv = bcm_esw_stk_my_modid_get(unit, &dest.modid); 50147 50148 if (BCM_FAILURE(rv)) { 50149 return BCM_E_UNAVAIL; 50150 } 50151 50152 if (soc_feature(unit, soc_feature_sysport_remap)) { 50153 BCM_XLATE_SYSPORT_P2S(unit, &port); 50154 } 50155 50156 dest.port = port; 50157 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 50158 50159 /* In this case we can safely assume that a port is in hw format */ 50160 /* since it is a physical port number */ 50161 BCM_IF_ERROR_RETURN 50162 (_bcm_gport_modport_hw2api_map(unit, dest.modid, dest.port, 50163 &(dest.modid), &(dest.port))); 50164 50165 return _bcm_esw_gport_construct(unit, &dest, gport); 50166 } 50167 50168 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 50169 /* 50170 * Function : bcm_port_gport_add 50171 * Description : Add the GPORT ID for the specified physical port. 50172 * 50173 * Parameters : (IN) unit - BCM device number 50174 * (IN) local_port - Port number 50175 * (IN) modport - GPORT ID 50176 * Returns : BCM_E_XXX 50177 */ 50178 int 50179 _bcm_esw_port_gport_add(int unit, bcm_port_t local_port, 50180 bcm_gport_t modport) 50181 { 50182 int subport_index = 0; 50183 bcm_port_t old_local_port = 0; 50184 modport_map_subport_entry_t modport_map_subport_entry; 50185 50186 /* Make sure port module is initialized. */ 50187 PORT_INIT(unit); 50188 50189 /* Parameter check */ 50190 PORT_PARAM_CHECK(unit, local_port); 50191 if (!BCM_GPORT_IS_MODPORT(modport)) { 50192 return BCM_E_PARAM; 50193 } 50194 50195 SOC_IF_ERROR_RETURN( 50196 _bcm_esw_port_subport_index_get(unit, modport, &subport_index)); 50197 50198 SOC_IF_ERROR_RETURN 50199 (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index, 50200 &modport_map_subport_entry)); 50201 old_local_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 50202 &modport_map_subport_entry, DESTf); 50203 if(old_local_port == local_port) { 50204 return BCM_E_NONE; 50205 } 50206 if(old_local_port) { 50207 return BCM_E_RESOURCE; 50208 } 50209 50210 soc_MODPORT_MAP_SUBPORTm_field32_set (unit, 50211 &modport_map_subport_entry, DESTf, local_port); 50212 soc_MODPORT_MAP_SUBPORTm_field32_set (unit, 50213 &modport_map_subport_entry, ISTRUNKf, 0); 50214 soc_MODPORT_MAP_SUBPORTm_field32_set (unit, 50215 &modport_map_subport_entry, ENABLEf, 1); 50216 SOC_IF_ERROR_RETURN 50217 (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index, 50218 &modport_map_subport_entry)); 50219 50220 return BCM_E_NONE; 50221 } 50222 50223 /* 50224 * Function : bcm_port_gport_get_all 50225 * Description : Get all the extra GPORT ID for the specified physical port. 50226 * 50227 * Parameters : (IN) unit - BCM device number 50228 * (IN) local_port - Port number 50229 * (IN) modport_max - size of gport array 50230 * (OUT) gport_array - Gport number 50231 * (OUT) count - GPORT count 50232 * Returns : BCM_E_XXX 50233 * Notes: 50234 * Always returns MODPORT gports or an error. 50235 */ 50236 int _bcm_esw_port_gport_get_all(int unit, bcm_port_t local_port, int size, 50237 bcm_gport_t *gport_array, int *count) 50238 { 50239 int rv = BCM_E_NONE; 50240 int mod_idx = 0; 50241 int port_idx = 0; 50242 int base_index = 0; 50243 bcm_gport_t modport = 0; 50244 _bcm_gport_dest_t dest; 50245 bcm_port_t egress_port = 0; 50246 bcm_stk_modid_config_t mod_cfg; 50247 modid_base_ptr_entry_t modid_base_entry; 50248 modport_map_subport_entry_t modport_map_subport_entry; 50249 soc_info_t *si = &SOC_INFO(unit); 50250 int i = 0, valid = 0, modid = 0, n_ports = 0; 50251 50252 /* Make sure port module is initialized. */ 50253 PORT_INIT(unit); 50254 50255 /* Parameter check */ 50256 PORT_PARAM_CHECK(unit, local_port); 50257 if (size < 0 || count == NULL) { 50258 return BCM_E_PARAM; 50259 } 50260 50261 if ((size > 0) && gport_array == NULL) { 50262 return BCM_E_PARAM; 50263 } 50264 50265 mod_cfg.modid_type = bcmStkModidTypeMultiNextHops; 50266 mod_cfg.modid = BCM_MODID_INVALID; 50267 BCM_IF_ERROR_RETURN(bcm_esw_stk_modid_config_get(unit, &mod_cfg)); 50268 50269 *count = 0; 50270 if (size == 0) { 50271 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 50272 for (i = 0; i < si->num_modules; i++) { 50273 if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] == 50274 BCM_MODID_INVALID) { 50275 continue; 50276 } 50277 BCM_IF_ERROR_RETURN( 50278 _bcm_esw_stk_get_mod_config_by_type(unit, 50279 BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid, 50280 &base_index)); 50281 if (valid == 0) { 50282 continue; 50283 } 50284 n_ports = src_modid_base_index_bk[unit]->num_ports[modid]; 50285 for (port_idx = base_index; port_idx < base_index + n_ports; 50286 port_idx++) { 50287 SOC_IF_ERROR_RETURN 50288 (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx, 50289 &modport_map_subport_entry)); 50290 /* Check if index is used. */ 50291 egress_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 50292 &modport_map_subport_entry, DESTf); 50293 if(egress_port == local_port) {/* Entry found. */ 50294 (*count)++; 50295 } 50296 } 50297 } 50298 } 50299 50300 for (mod_idx = mod_cfg.modid; mod_idx < mod_cfg.modid + mod_cfg.num_mods; 50301 mod_idx ++) { 50302 MODULE_ID_LOWER_6_BITS(mod_idx); /* lower 6 bit */ 50303 SOC_IF_ERROR_RETURN( 50304 READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_idx, 50305 &modid_base_entry)); 50306 base_index = 50307 soc_MODID_BASE_PTRm_field32_get(unit, &modid_base_entry, 50308 MODID_BASEf); 50309 SOC_IF_ERROR_RETURN( 50310 READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, base_index, 50311 &modport_map_subport_entry)); 50312 /* Check if index is used. */ 50313 egress_port = 50314 soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 50315 &modport_map_subport_entry, DESTf); 50316 if (egress_port == local_port) {/* Entry found. */ 50317 (*count)++; 50318 } 50319 } 50320 return BCM_E_NONE; 50321 } 50322 50323 _bcm_gport_dest_t_init(&dest); 50324 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 50325 for (i = 0; i < si->num_modules; i++) { 50326 if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] == 50327 BCM_MODID_INVALID) { 50328 continue; 50329 } 50330 BCM_IF_ERROR_RETURN( 50331 _bcm_esw_stk_get_mod_config_by_type(unit, 50332 BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid, 50333 &base_index)); 50334 if (valid == 0) { 50335 continue; 50336 } 50337 n_ports = src_modid_base_index_bk[unit]->num_ports[modid]; 50338 for (port_idx = base_index; port_idx < base_index + n_ports; 50339 port_idx++) { 50340 if ((*count) < size) { 50341 SOC_IF_ERROR_RETURN 50342 (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx, 50343 &modport_map_subport_entry)); 50344 /* Check if index is used. */ 50345 egress_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 50346 &modport_map_subport_entry, DESTf); 50347 if (egress_port == local_port) { 50348 /* Entry found. */ 50349 dest.port = port_idx - base_index; 50350 dest.modid = modid; 50351 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 50352 rv = _bcm_esw_gport_construct(unit, &dest, &modport); 50353 gport_array[(*count)++] = modport; 50354 } 50355 } 50356 } 50357 } 50358 } 50359 50360 for (mod_idx = mod_cfg.modid; mod_idx < mod_cfg.modid + mod_cfg.num_mods; 50361 mod_idx ++) { 50362 MODULE_ID_LOWER_6_BITS(mod_idx); /* lower 6 bit */ 50363 SOC_IF_ERROR_RETURN 50364 (READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_idx, &modid_base_entry)); 50365 base_index = soc_MODID_BASE_PTRm_field32_get(unit, 50366 &modid_base_entry, MODID_BASEf); 50367 if ((*count) < size) { 50368 SOC_IF_ERROR_RETURN( 50369 READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, base_index, 50370 &modport_map_subport_entry)); 50371 /* Check if index is used. */ 50372 egress_port = 50373 soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 50374 &modport_map_subport_entry, DESTf); 50375 if (egress_port == local_port) { 50376 /* Entry found. */ 50377 dest.port = BCM_PORT_INVALID; 50378 dest.modid = mod_idx; 50379 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 50380 rv = _bcm_esw_gport_construct(unit, &dest, &modport); 50381 gport_array[(*count)++] = modport; 50382 } 50383 } 50384 } 50385 50386 return rv; 50387 } 50388 50389 /* 50390 * Function : bcm_port_gport_delete 50391 * Description : Delete the mapping of the specified GPORT. 50392 * 50393 * Parameters : (IN) unit - BCM device number 50394 * (IN) modport - GPORT ID 50395 * Returns : BCM_E_XXX 50396 */ 50397 int 50398 _bcm_esw_port_gport_delete(int unit, bcm_port_t local_port, bcm_gport_t modport) 50399 { 50400 int subport_index = 0; 50401 modport_map_subport_entry_t modport_map_subport_entry; 50402 50403 /* Make sure port module is initialized. */ 50404 PORT_INIT(unit); 50405 50406 /* Parameter check */ 50407 PORT_PARAM_CHECK(unit, local_port); 50408 if (!BCM_GPORT_IS_MODPORT(modport)) { 50409 return BCM_E_PARAM; 50410 } 50411 50412 SOC_IF_ERROR_RETURN( 50413 _bcm_esw_port_subport_index_get(unit, modport, &subport_index)); 50414 50415 SOC_IF_ERROR_RETURN 50416 (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index, 50417 &modport_map_subport_entry)); 50418 soc_MODPORT_MAP_SUBPORTm_field32_set(unit, 50419 &modport_map_subport_entry, DESTf, 0); 50420 soc_MODPORT_MAP_SUBPORTm_field32_set (unit, 50421 &modport_map_subport_entry, ISTRUNKf, 0); 50422 soc_MODPORT_MAP_SUBPORTm_field32_set (unit, 50423 &modport_map_subport_entry, ENABLEf, 0); 50424 SOC_IF_ERROR_RETURN 50425 (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, subport_index, 50426 &modport_map_subport_entry)); 50427 50428 return BCM_E_NONE; 50429 } 50430 50431 /* 50432 * Function : bcm_port_gport_delete_all 50433 * Description : Delete all the extra mapping of the specified physical port. 50434 * 50435 * Parameters : (IN) unit - BCM device number 50436 * (IN) local_port - PORT ID 50437 * Returns : BCM_E_XXX 50438 */ 50439 int 50440 _bcm_esw_port_gport_delete_all(int unit, bcm_port_t local_port) 50441 { 50442 int mod_idx = 0; 50443 int port_idx = 0; 50444 int base_index = 0; 50445 bcm_port_t egress_port = 0; 50446 bcm_stk_modid_config_t mod_cfg; 50447 modid_base_ptr_entry_t modid_base_entry; 50448 modport_map_subport_entry_t modport_map_subport_entry; 50449 soc_info_t *si = &SOC_INFO(unit); 50450 int i = 0, valid = 0, modid = 0, n_ports = 0; 50451 50452 /* Make sure port module is initialized. */ 50453 PORT_INIT(unit); 50454 50455 /* Parameter check */ 50456 PORT_PARAM_CHECK(unit, local_port); 50457 50458 mod_cfg.modid_type = bcmStkModidTypeMultiNextHops; 50459 mod_cfg.modid = BCM_MODID_INVALID; 50460 BCM_IF_ERROR_RETURN( 50461 bcm_esw_stk_modid_config_get(unit, &mod_cfg)); 50462 50463 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 50464 for (i = 0; i < si->num_modules; i++) { 50465 if (src_modid_base_index_bk[unit]->multi_nexthop_module_id_list[i] == 50466 BCM_MODID_INVALID) { 50467 continue; 50468 } 50469 BCM_IF_ERROR_RETURN( 50470 _bcm_esw_stk_get_mod_config_by_type(unit, 50471 BCM_MODID_TYPE_MULTI_NEXT_HOPS, i + 1, &modid, &valid, 50472 &base_index)); 50473 if (valid == 0) { 50474 continue; 50475 } 50476 n_ports = src_modid_base_index_bk[unit]->num_ports[modid]; 50477 for (port_idx = base_index; port_idx < base_index + n_ports; 50478 port_idx++) { 50479 SOC_IF_ERROR_RETURN 50480 (READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx, 50481 &modport_map_subport_entry)); 50482 /* Check if index is used. */ 50483 egress_port = soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 50484 &modport_map_subport_entry, DESTf); 50485 if(egress_port == local_port) { 50486 /* Entry found. */ 50487 soc_MODPORT_MAP_SUBPORTm_field32_set( 50488 unit, &modport_map_subport_entry, DESTf, 0); 50489 soc_MODPORT_MAP_SUBPORTm_field32_set( 50490 unit, &modport_map_subport_entry, ENABLEf, 0); 50491 SOC_IF_ERROR_RETURN 50492 (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx, 50493 &modport_map_subport_entry)); 50494 } 50495 } 50496 } 50497 } 50498 50499 for (mod_idx = mod_cfg.modid; mod_idx < mod_cfg.modid + mod_cfg.num_mods; 50500 mod_idx ++) { 50501 MODULE_ID_LOWER_6_BITS(mod_idx); /* lower 6 bit */ 50502 SOC_IF_ERROR_RETURN 50503 (READ_MODID_BASE_PTRm(unit, MEM_BLOCK_ANY, mod_idx, &modid_base_entry)); 50504 base_index = soc_MODID_BASE_PTRm_field32_get(unit, 50505 &modid_base_entry, MODID_BASEf); 50506 SOC_IF_ERROR_RETURN( 50507 READ_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, base_index, 50508 &modport_map_subport_entry)); 50509 /* Check if index is used. */ 50510 egress_port = 50511 soc_MODPORT_MAP_SUBPORTm_field32_get(unit, 50512 &modport_map_subport_entry, DESTf); 50513 if (egress_port == local_port) { 50514 /* Entry found. */ 50515 soc_MODPORT_MAP_SUBPORTm_field32_set( 50516 unit, &modport_map_subport_entry, DESTf, 0); 50517 soc_MODPORT_MAP_SUBPORTm_field32_set( 50518 unit, &modport_map_subport_entry, ENABLEf, 0); 50519 SOC_IF_ERROR_RETURN( 50520 WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ANY, port_idx, 50521 &modport_map_subport_entry)); 50522 } 50523 } 50524 50525 return BCM_E_NONE; 50526 } 50527 50528 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 50529 50530 /* 50531 * Function : bcm_port_gport_add 50532 * Description : Add the GPORT ID for the specified physical port. 50533 * 50534 * Parameters : (IN) unit - BCM device number 50535 * (IN) local_port - Port number 50536 * (IN) modport - GPORT ID 50537 * Returns : BCM_E_XXX 50538 */ 50539 int 50540 bcm_esw_port_gport_add(int unit, bcm_port_t local_port, 50541 bcm_gport_t modport) 50542 { 50543 int rv = BCM_E_UNAVAIL; 50544 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 50545 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 50546 rv = _bcm_esw_port_gport_add(unit, local_port, modport); 50547 } 50548 #endif 50549 return rv; 50550 } 50551 50552 /* 50553 * Function : bcm_port_gport_get_all 50554 * Description : Get all the extra GPORT ID for the specified physical port. 50555 * 50556 * Parameters : (IN) unit - BCM device number 50557 * (IN) local_port - Port number 50558 * (IN) modport_max - size of gport array 50559 * (OUT) gport_array - Gport number 50560 * (OUT) count - GPORT count 50561 * Returns : BCM_E_XXX 50562 * Notes: 50563 */ 50564 int bcm_esw_port_gport_get_all(int unit, bcm_port_t local_port, int size, 50565 bcm_gport_t *gport_array, int *count) 50566 { 50567 int rv = BCM_E_UNAVAIL; 50568 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 50569 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 50570 if (size < 0 || count == NULL) { 50571 return BCM_E_PARAM; 50572 } 50573 50574 if ((size > 0) && gport_array == NULL) { 50575 return BCM_E_PARAM; 50576 } 50577 50578 rv = _bcm_esw_port_gport_get_all(unit, local_port, size, gport_array, count); 50579 } 50580 #endif 50581 return rv; 50582 } 50583 50584 /* 50585 * Function : bcm_port_gport_delete 50586 * Description : Delete the mapping of the specified GPORT. 50587 * 50588 * Parameters : (IN) unit - BCM device number 50589 * (IN) modport - GPORT ID 50590 * Returns : BCM_E_XXX 50591 */ 50592 int 50593 bcm_esw_port_gport_delete(int unit, bcm_port_t local_port, bcm_gport_t modport) 50594 { 50595 int rv = BCM_E_UNAVAIL; 50596 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 50597 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 50598 rv = _bcm_esw_port_gport_delete(unit, local_port, modport); 50599 } 50600 #endif 50601 return rv; 50602 } 50603 50604 /* 50605 * Function : bcm_port_gport_delete_all 50606 * Description : Delete all the extra mapping of the specified physical port. 50607 * 50608 * Parameters : (IN) unit - BCM device number 50609 * (IN) local_port - PORT ID 50610 * Returns : BCM_E_XXX 50611 */ 50612 int 50613 bcm_esw_port_gport_delete_all(int unit, bcm_port_t local_port) 50614 { 50615 int rv = BCM_E_UNAVAIL; 50616 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 50617 if (soc_feature(unit, soc_feature_multi_next_hops_on_port)) { 50618 rv = _bcm_esw_port_gport_delete_all(unit, local_port); 50619 } 50620 #endif 50621 return rv; 50622 } 50623 50624 /* 50625 * Function: 50626 * bcm_esw_port_gport_is_free 50627 * Purpose: 50628 * Request if the given gport value is available on the device 50629 * Parameters: 50630 * unit - (IN) Unit number. 50631 * gport - (IN) GPORT ID. 50632 * Returns: 50633 * BCM_E_NONE - gport is valid and available on the device 50634 * BCM_E_EXISTS - gport is valid but already in use 50635 * on this device 50636 * BCM_E_PARAM - gport is not valid on this device 50637 * BCM_E_UNAVAIL - Feature unavailable 50638 * Notes: 50639 */ 50640 int 50641 bcm_esw_port_gport_is_free(int unit, bcm_gport_t gport) 50642 { 50643 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 50644 int rv = BCM_E_PARAM; 50645 int vp = 0, vp_idx, rv_vp = 0, is_vp = FALSE; 50646 int vp_count = 1; /* Required consecutive VP's */ 50647 50648 /* Make sure port module is initialized. */ 50649 PORT_INIT(unit); 50650 50651 if (!soc_mem_is_valid(unit, SOURCE_VPm)) { 50652 /* No virtual ports at this time. */ 50653 return BCM_E_UNAVAIL; 50654 } 50655 50656 #if defined(BCM_MPLS_SUPPORT) 50657 if (BCM_GPORT_IS_MPLS_PORT(gport) && 50658 soc_feature(unit, soc_feature_mpls)) { 50659 is_vp = TRUE; 50660 vp = BCM_GPORT_MPLS_PORT_ID_GET(gport); 50661 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 50662 rv_vp = -1; 50663 } else { 50664 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeMpls); 50665 } 50666 } else 50667 #endif /* BCM_MPLS_SUPPORT */ 50668 if (BCM_GPORT_IS_MIM_PORT(gport) && 50669 soc_feature(unit, soc_feature_mim)) { 50670 is_vp = TRUE; 50671 vp = BCM_GPORT_MIM_PORT_ID_GET(gport); 50672 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 50673 rv_vp = -1; 50674 } else { 50675 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeMim); 50676 } 50677 } else if (BCM_GPORT_IS_L2GRE_PORT(gport) && 50678 soc_feature(unit, soc_feature_l2gre)) { 50679 is_vp = TRUE; 50680 vp = BCM_GPORT_L2GRE_PORT_ID_GET(gport); 50681 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 50682 rv_vp = -1; 50683 } else { 50684 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre); 50685 } 50686 } else if (BCM_GPORT_IS_VXLAN_PORT(gport) && 50687 soc_feature(unit, soc_feature_vxlan)) { 50688 is_vp = TRUE; 50689 vp = BCM_GPORT_VXLAN_PORT_ID_GET(gport); 50690 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 50691 rv_vp = -1; 50692 } else { 50693 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan); 50694 } 50695 } else if (BCM_GPORT_IS_FLOW_PORT(gport) && 50696 soc_feature(unit, soc_feature_flex_flow)) { 50697 is_vp = TRUE; 50698 vp = BCM_GPORT_FLOW_PORT_ID_GET(gport); 50699 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 50700 rv_vp = -1; 50701 } else { 50702 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeFlow); 50703 } 50704 } else if (BCM_GPORT_IS_WLAN_PORT(gport) && 50705 soc_feature(unit, soc_feature_wlan)) { 50706 is_vp = TRUE; 50707 vp = BCM_GPORT_WLAN_PORT_ID_GET(gport); 50708 if (SOC_MEM_IS_VALID(unit, WLAN_SVP_TABLEm)) { 50709 if (vp > soc_mem_index_count(unit, WLAN_SVP_TABLEm)) { 50710 rv_vp = -1; 50711 } else { 50712 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeWlan); 50713 } 50714 50715 } else if (SOC_MEM_IS_VALID(unit, SOURCE_VP_ATTRIBUTES_2m)) { 50716 if (vp > soc_mem_index_count(unit, SOURCE_VP_ATTRIBUTES_2m)) { 50717 rv_vp = -1; 50718 } else { 50719 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeWlan); 50720 } 50721 } else { 50722 rv_vp = -1; 50723 } 50724 } else if (BCM_GPORT_IS_TRILL_PORT(gport) && 50725 soc_feature(unit, soc_feature_trill)) { 50726 is_vp = TRUE; 50727 vp = BCM_GPORT_TRILL_PORT_ID_GET(gport); 50728 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 50729 rv_vp = -1; 50730 } else { 50731 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeTrill); 50732 } 50733 } else if (BCM_GPORT_IS_VLAN_PORT(gport) && 50734 soc_feature(unit, soc_feature_vlan_vp)) { 50735 is_vp = TRUE; 50736 vp = BCM_GPORT_VLAN_PORT_ID_GET(gport); 50737 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 50738 rv_vp = -1; 50739 } else { 50740 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeVlan); 50741 } 50742 } else if (BCM_GPORT_IS_NIV_PORT(gport) && 50743 soc_feature(unit, soc_feature_niv)) { 50744 is_vp = TRUE; 50745 vp = BCM_GPORT_NIV_PORT_ID_GET(gport); 50746 if (vp > soc_mem_index_count(unit, SOURCE_VPm)) { 50747 rv_vp = -1; 50748 } else { 50749 rv_vp = _bcm_vp_used_get(unit, vp, _bcmVpTypeNiv); 50750 } 50751 } 50752 #if defined(BCM_TRIUMPH2_SUPPORT) 50753 else if ((BCM_GPORT_IS_SUBPORT_GROUP(gport) || 50754 BCM_GPORT_IS_SUBPORT_PORT(gport)) && 50755 soc_feature(unit, soc_feature_subport_enhanced)) { 50756 /* No TR/SC support for now */ 50757 rv_vp = _bcm_tr2_subport_gport_used(unit, gport); 50758 if (BCM_E_NOT_FOUND == rv_vp) { 50759 rv = BCM_E_NONE; 50760 /* Now we need to check if the VP is in use by something else, 50761 * using the logic below. */ 50762 is_vp = TRUE; 50763 rv_vp = 0; 50764 if (BCM_GPORT_IS_SUBPORT_GROUP(gport)) { 50765 vp = BCM_GPORT_SUBPORT_GROUP_GET(gport); 50766 vp = (vp / 8) * 8; 50767 vp_count = 8; 50768 } else { 50769 vp = BCM_GPORT_SUBPORT_PORT_GET(gport); 50770 } 50771 } else if (BCM_E_NONE == rv_vp) { 50772 rv = BCM_E_EXISTS; 50773 } else { 50774 rv = rv_vp; 50775 } 50776 } 50777 #endif /* BCM_TRIUMPH2_SUPPORT */ 50778 50779 if (is_vp) { 50780 if (0 == rv_vp) { 50781 /* Double-check no other protocol is using this VP */ 50782 for (vp_idx = 0; vp_idx < vp_count; vp_idx++) { 50783 rv_vp = _bcm_vp_used_get(unit, vp + vp_idx, _bcmVpTypeAny); 50784 if (0 == rv_vp) { 50785 rv = BCM_E_NONE; 50786 } else { 50787 rv = BCM_E_EXISTS; 50788 break; 50789 } 50790 } 50791 } else if (-1 != rv_vp) { 50792 rv = BCM_E_EXISTS; 50793 } /* else parameter error */ 50794 } 50795 /* subport */ 50796 50797 return rv; 50798 #else 50799 return BCM_E_UNAVAIL; 50800 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 50801 } 50802 50803 /* 50804 * Function: 50805 * bcm_esw_port_gport_free_range_get 50806 * Purpose: 50807 * Retrieve the minimum and maximum unallocated gport values for 50808 * a given gport type. 50809 * Parameters: 50810 * unit - (IN) Unit number. 50811 * gport_type - (IN) One of BCM_GPORT_TYPE_* or BCM_GPORT_*_PORT values. 50812 * gport_min - (OUT) Minimum available gport value of type gport_type 50813 * gport_max - (OUT) Maximum available gport value of type gport_type 50814 * Returns: 50815 * BCM_E_NONE - Valid gports range of requested type returned 50816 * BCM_E_NOT_FOUND - No available gports of this type 50817 * BCM_E_PARAM - Gport type is not valid on this device 50818 * BCM_E_UNAVAIL - Feature unavailable 50819 * Notes: 50820 */ 50821 int 50822 bcm_esw_port_gport_free_range_get(int unit, uint32 gport_type, 50823 bcm_gport_t *gport_min, 50824 bcm_gport_t *gport_max) 50825 { 50826 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 50827 bcm_gport_t dev_min, dev_max, gport, free_min, free_max; 50828 int rv = BCM_E_PARAM; 50829 int svp_max; 50830 50831 /* Make sure port module is initialized. */ 50832 PORT_INIT(unit); 50833 50834 if (soc_mem_is_valid(unit, SOURCE_VPm)) { 50835 svp_max = soc_mem_index_max(unit, SOURCE_VPm); 50836 } else { 50837 /* No virtual ports at this time. */ 50838 return BCM_E_UNAVAIL; 50839 } 50840 50841 switch (gport_type) { 50842 case BCM_GPORT_MPLS_PORT: 50843 BCM_GPORT_MPLS_PORT_ID_SET(dev_min, 0); 50844 BCM_GPORT_MPLS_PORT_ID_SET(dev_max, svp_max); 50845 break; 50846 case BCM_GPORT_MIM_PORT: 50847 BCM_GPORT_MIM_PORT_ID_SET(dev_min, 0); 50848 BCM_GPORT_MIM_PORT_ID_SET(dev_max, svp_max); 50849 break; 50850 case BCM_GPORT_L2GRE_PORT: 50851 BCM_GPORT_L2GRE_PORT_ID_SET(dev_min, 0); 50852 BCM_GPORT_L2GRE_PORT_ID_SET(dev_max, svp_max); 50853 break; 50854 case BCM_GPORT_VXLAN_PORT: 50855 BCM_GPORT_VXLAN_PORT_ID_SET(dev_min, 0); 50856 BCM_GPORT_VXLAN_PORT_ID_SET(dev_max, svp_max); 50857 break; 50858 case BCM_GPORT_WLAN_PORT: 50859 BCM_GPORT_WLAN_PORT_ID_SET(dev_min, 0); 50860 BCM_GPORT_WLAN_PORT_ID_SET(dev_max, svp_max); 50861 break; 50862 case BCM_GPORT_TRILL_PORT: 50863 BCM_GPORT_TRILL_PORT_ID_SET(dev_min, 0); 50864 BCM_GPORT_TRILL_PORT_ID_SET(dev_max, svp_max); 50865 break; 50866 case BCM_GPORT_VLAN_PORT: 50867 BCM_GPORT_VLAN_PORT_ID_SET(dev_min, 0); 50868 BCM_GPORT_VLAN_PORT_ID_SET(dev_max, svp_max); 50869 break; 50870 case BCM_GPORT_NIV_PORT: 50871 BCM_GPORT_NIV_PORT_ID_SET(dev_min, 0); 50872 BCM_GPORT_NIV_PORT_ID_SET(dev_max, svp_max); 50873 break; 50874 case BCM_GPORT_SUBPORT_GROUP: 50875 BCM_GPORT_SUBPORT_GROUP_SET(dev_min, 0); 50876 BCM_GPORT_SUBPORT_GROUP_SET(dev_max, svp_max); 50877 break; 50878 case BCM_GPORT_SUBPORT_PORT: 50879 BCM_GPORT_SUBPORT_PORT_SET(dev_min, 0); 50880 BCM_GPORT_SUBPORT_PORT_SET(dev_max, svp_max); 50881 break; 50882 default: 50883 /* Not a supported gport type at this time */ 50884 return rv; 50885 } 50886 50887 free_min = free_max = 0; /* Invalid multicast group */ 50888 for (gport = dev_min; gport <= dev_max; gport++) { 50889 rv = bcm_esw_port_gport_is_free(unit, gport); 50890 if (BCM_SUCCESS(rv)) { 50891 if (0 == free_min) { 50892 free_min = gport; 50893 } 50894 free_max = gport; 50895 } else if (BCM_E_EXISTS == rv) { 50896 /* Nothing to do but clear the error */ 50897 rv = BCM_E_NONE; 50898 } else if (BCM_E_PARAM == rv) { 50899 /* Range is less than expected, stop iterating */ 50900 rv = BCM_E_NONE; 50901 break; 50902 } else { 50903 /* Real error, return */ 50904 break; 50905 } 50906 } 50907 50908 if (BCM_SUCCESS(rv)) { 50909 if (0 == free_min) { 50910 /* No available groups of this type */ 50911 return BCM_E_NOT_FOUND; 50912 } else { 50913 /* Copy the results */ 50914 *gport_min = free_min; 50915 *gport_max = free_max; 50916 } 50917 } 50918 50919 return rv; 50920 50921 #else 50922 return BCM_E_UNAVAIL; 50923 #endif /* BCM_TRIUMPH_SUPPORT && INCLUDE_L3 */ 50924 } 50925 50926 #if defined(BCM_TRIUMPH2_SUPPORT) 50927 int 50928 _bcm_esw_port_flex_stat_index_set(int unit, bcm_gport_t port, int fs_idx, 50929 uint32 flags) 50930 { 50931 bcm_port_t loc_port; 50932 int rv; 50933 50934 rv = bcm_esw_port_local_get(unit, port, &loc_port); 50935 if (BCM_FAILURE(rv)) { 50936 return BCM_E_NOT_FOUND; /* Local port disabled */ 50937 } 50938 50939 PORT_LOCK(unit); /* Keep port tables in sync */ 50940 rv = BCM_E_NONE; 50941 if (flags & _BCM_FLEX_STAT_HW_INGRESS) { 50942 rv = soc_mem_field32_modify(unit, PORT_TABm, loc_port, VINTF_CTR_IDXf, 50943 fs_idx); 50944 } 50945 50946 if (flags & _BCM_FLEX_STAT_HW_EGRESS) { 50947 if (BCM_SUCCESS(rv)) { 50948 #ifdef BCM_TRIDENT_SUPPORT 50949 if (SOC_IS_TD_TT(unit)) { 50950 rv = soc_mem_field32_modify(unit, EGR_PORTm, loc_port, 50951 VINTF_CTR_IDXf, fs_idx); 50952 } else 50953 #endif /* BCM_TRIDENT_SUPPORT */ 50954 { 50955 rv = soc_reg_field32_modify(unit, EGR_PORT_64r, loc_port, 50956 VINTF_CTR_IDXf, fs_idx); 50957 } 50958 } 50959 } 50960 PORT_UNLOCK(unit); 50961 return rv; 50962 } 50963 50964 STATIC int 50965 _bcm_esw_port_stat_param_verify(int unit, bcm_gport_t port) 50966 { 50967 int vp; 50968 50969 if (BCM_GPORT_IS_MPLS_PORT(port)) { 50970 #if defined(BCM_MPLS_SUPPORT) && defined(INCLUDE_L3) 50971 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 50972 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 50973 return BCM_E_PARAM; 50974 } 50975 #endif 50976 } else if (BCM_GPORT_IS_NIV_PORT(port)) { 50977 #if defined(BCM_MPLS_SUPPORT) && defined(INCLUDE_L3) 50978 vp = BCM_GPORT_NIV_PORT_ID_GET(port); 50979 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) { 50980 return BCM_E_PARAM; 50981 } 50982 #endif 50983 } else if (BCM_GPORT_IS_SUBPORT_GROUP(port) || 50984 BCM_GPORT_IS_SUBPORT_PORT(port)) { 50985 50986 #if defined(BCM_HGPROXY_COE_SUPPORT) 50987 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 50988 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 50989 return bcm_esw_port_local_get(unit, port, &vp); 50990 } 50991 #endif 50992 #if defined(BCM_KATANA2_SUPPORT) 50993 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)){ 50994 return bcm_esw_port_local_get(unit, port, &vp); 50995 } 50996 #endif 50997 #if defined(INCLUDE_L3) 50998 if (BCM_FAILURE(_bcm_tr2_subport_gport_used(unit, port))) { 50999 return BCM_E_PARAM; 51000 } 51001 } else if (BCM_GPORT_IS_MIM_PORT(port)) { 51002 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 51003 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 51004 return BCM_E_PARAM; 51005 } 51006 } else if (BCM_GPORT_IS_WLAN_PORT(port)) { 51007 vp = BCM_GPORT_WLAN_PORT_ID_GET(port); 51008 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) { 51009 return BCM_E_PARAM; 51010 } 51011 #endif 51012 } else { 51013 BCM_IF_ERROR_RETURN( 51014 bcm_esw_port_local_get(unit, port, &vp)); 51015 } 51016 51017 return BCM_E_NONE; 51018 } 51019 STATIC int 51020 _bcm_esw_port_stat_param_valid(int unit, bcm_gport_t port) 51021 { 51022 PORT_INIT(unit); 51023 51024 if (!soc_feature(unit, soc_feature_gport_service_counters)) { 51025 return BCM_E_UNAVAIL; 51026 } 51027 return _bcm_esw_port_stat_param_verify(unit, port); 51028 } 51029 51030 STATIC _bcm_flex_stat_t 51031 _bcm_esw_port_stat_to_flex_stat(bcm_port_stat_t stat) 51032 { 51033 _bcm_flex_stat_t flex_stat; 51034 51035 switch (stat) { 51036 case bcmPortStatIngressPackets: 51037 flex_stat = _bcmFlexStatIngressPackets; 51038 break; 51039 case bcmPortStatIngressBytes: 51040 flex_stat = _bcmFlexStatIngressBytes; 51041 break; 51042 case bcmPortStatEgressPackets: 51043 flex_stat = _bcmFlexStatEgressPackets; 51044 break; 51045 case bcmPortStatEgressBytes: 51046 flex_stat = _bcmFlexStatEgressBytes; 51047 break; 51048 default: 51049 flex_stat = _bcmFlexStatNum; 51050 } 51051 51052 return flex_stat; 51053 } 51054 51055 /* Requires "idx" variable */ 51056 #define BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr) \ 51057 for (idx = 0; idx < nstat; idx++) { \ 51058 if (NULL == value_arr + idx) { \ 51059 return (BCM_E_PARAM); \ 51060 } \ 51061 } 51062 51063 STATIC int 51064 _bcm_port_stat_array_convert(int unit, int nstat, bcm_port_stat_t *stat_arr, 51065 _bcm_flex_stat_t *fs_arr) 51066 { 51067 int idx; 51068 51069 if ((nstat <= 0) || (nstat > _bcmFlexStatNum)) { 51070 return BCM_E_PARAM; 51071 } 51072 if ((NULL == stat_arr) || (NULL == fs_arr)) { 51073 return (BCM_E_PARAM); 51074 } 51075 51076 for (idx = 0; idx < nstat; idx++) { 51077 fs_arr[idx] = _bcm_esw_port_stat_to_flex_stat(stat_arr[idx]); 51078 } 51079 return BCM_E_NONE; 51080 } 51081 #endif /* BCM_TRIUMPH2_SUPPORT */ 51082 51083 /* 51084 * Function: 51085 * bcm_esw_port_stat_enable_set 51086 * Purpose: 51087 * Enable/disable packet and byte counters for the selected 51088 * gport. 51089 * Parameters: 51090 * unit - (IN) Unit number. 51091 * port - (IN) GPORT ID 51092 * enable - (IN) Non-zero to enable counter collection, zero to disable. 51093 * Returns: 51094 * BCM_E_XXX 51095 * Notes: 51096 */ 51097 int 51098 bcm_esw_port_stat_enable_set(int unit, bcm_gport_t port, int enable) 51099 { 51100 #if defined(BCM_TRIUMPH2_SUPPORT) 51101 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 51102 uint32 num_of_tables=0; 51103 uint32 num_stat_counter_ids=0; 51104 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 51105 bcm_stat_object_t object=bcmStatObjectIngPort; 51106 uint32 stat_counter_id[ 51107 BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]={0}; 51108 uint32 num_entries=0; 51109 int index=0; 51110 51111 #endif 51112 51113 /* Make sure port module is initialized. */ 51114 PORT_INIT(unit); 51115 51116 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 51117 BCM_IF_ERROR_RETURN 51118 (_bcm_esw_port_stat_param_valid(unit, port)); 51119 return _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeGport, 51120 _bcm_esw_port_flex_stat_hw_index_set, 51121 NULL, port, enable,0); 51122 } 51123 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 51124 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 51125 unit,port,&num_of_tables,&table_info[0])); 51126 if (enable ) { 51127 for(index=0;index < num_of_tables ;index++) { 51128 if(table_info[index].direction == bcmStatFlexDirectionIngress) { 51129 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_ingress_object( 51130 unit,table_info[index].table, 51131 table_info[index].index,NULL,&object)); 51132 } else { 51133 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_egress_object( 51134 unit,table_info[index].table, 51135 table_info[index].index,NULL,&object)); 51136 } 51137 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_create( 51138 unit,object,bcmStatGroupModeSingle, 51139 &stat_counter_id[table_info[index].direction], 51140 &num_entries)); 51141 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_attach( 51142 unit,port, 51143 stat_counter_id[table_info[index].direction])); 51144 } 51145 return BCM_E_NONE; 51146 } else { 51147 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_counter_id( 51148 unit, num_of_tables,&table_info[0], 51149 &num_stat_counter_ids,&stat_counter_id[0])); 51150 if ((stat_counter_id[bcmStatFlexDirectionIngress] == 0) && 51151 (stat_counter_id[bcmStatFlexDirectionEgress] == 0)) { 51152 return BCM_E_PARAM; 51153 } 51154 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_detach(unit,port)); 51155 if (stat_counter_id[bcmStatFlexDirectionIngress] != 0) { 51156 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 51157 unit, 51158 stat_counter_id[bcmStatFlexDirectionIngress])); 51159 } 51160 if (stat_counter_id[bcmStatFlexDirectionEgress] != 0) { 51161 BCM_IF_ERROR_RETURN(bcm_esw_stat_group_destroy( 51162 unit, 51163 stat_counter_id[bcmStatFlexDirectionEgress])); 51164 } 51165 return BCM_E_NONE; 51166 } 51167 #else 51168 return BCM_E_UNAVAIL; 51169 #endif 51170 #else 51171 return BCM_E_UNAVAIL; 51172 #endif 51173 } 51174 51175 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 51176 /* 51177 * Function: 51178 * _bcm_esw_port_stat_get_table_info 51179 * Description: 51180 * Provides relevant flex table information(table-name,index with 51181 * direction) for given gport. 51182 * 51183 * Parameters: 51184 * unit - (IN) unit number 51185 * port - (IN) GPORT ID 51186 * num_of_tables - (OUT) Number of flex counter tables 51187 * table_info - (OUT) Flex counter tables information 51188 * 51189 * Return Value: 51190 * BCM_E_XXX 51191 * Notes: 51192 */ 51193 STATIC 51194 bcm_error_t _bcm_esw_port_stat_get_table_info( 51195 int unit, 51196 bcm_gport_t port, 51197 uint32 *num_of_tables, 51198 bcm_stat_flex_table_info_t *table_info) 51199 { 51200 #if defined(INCLUDE_L3) 51201 int vp=0; 51202 int rv=0; 51203 int nh_index=0; 51204 int vp_base=0; 51205 int vt_index =-1; 51206 bcm_vlan_t ovid = 0; 51207 uint32 port_class = 0; 51208 bcm_port_t egress_port = 0; 51209 ing_l3_next_hop_entry_t ing_nh={{0}}; 51210 egr_vlan_xlate_entry_t egr_vent={{0}}; 51211 ing_dvp_table_entry_t dvp={{0}}; 51212 egr_l3_next_hop_entry_t egr_nh={{0}}; 51213 source_vp_entry_t svp; 51214 int l3_idx=0; 51215 egr_l3_intf_entry_t l3_intf; 51216 51217 #endif 51218 bcm_port_t loc_port=0; 51219 51220 (*num_of_tables) = 0; 51221 51222 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 51223 return BCM_E_UNAVAIL; 51224 } 51225 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_param_verify(unit, port)); 51226 if (BCM_GPORT_IS_MPLS_PORT(port) || 51227 BCM_GPORT_IS_NIV_PORT(port)) { 51228 #if defined(BCM_MPLS_SUPPORT) && defined(INCLUDE_L3) 51229 if (BCM_GPORT_IS_MPLS_PORT(port)) { 51230 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 51231 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 51232 return BCM_E_NOT_FOUND; 51233 } 51234 } 51235 if (BCM_GPORT_IS_NIV_PORT(port)) { 51236 vp = BCM_GPORT_NIV_PORT_ID_GET(port); 51237 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) { 51238 return BCM_E_NOT_FOUND; 51239 } 51240 } 51241 51242 /* Ingress Side */ 51243 table_info[*num_of_tables].table=SOURCE_VPm; 51244 table_info[*num_of_tables].index=vp; 51245 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 51246 (*num_of_tables)++; 51247 /* Egress Side */ 51248 if (BCM_SUCCESS(READ_ING_DVP_TABLEm(unit, MEM_BLOCK_ANY, vp, &dvp))) { 51249 nh_index = soc_mem_field32_get(unit, ING_DVP_TABLEm, &dvp, 51250 NEXT_HOP_INDEXf); 51251 if (BCM_SUCCESS(soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 51252 nh_index,&egr_nh))) { 51253 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm; 51254 table_info[*num_of_tables].index=nh_index; 51255 table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress; 51256 (*num_of_tables)++; 51257 } 51258 } 51259 return BCM_E_NONE; 51260 #endif/* BCM_MPLS_SUPPORT && INCLUDE_L3*/ 51261 } else if (BCM_GPORT_IS_SUBPORT_GROUP(port) || 51262 BCM_GPORT_IS_SUBPORT_PORT(port)) { 51263 51264 51265 #if defined(BCM_HGPROXY_COE_SUPPORT) 51266 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 51267 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 51268 51269 if(BCM_FAILURE(bcm_esw_port_local_get(unit, port, &loc_port))) { 51270 return BCM_E_NOT_FOUND; /* Local port disabled */ 51271 } 51272 table_info[*num_of_tables].table = PORT_TABm; 51273 table_info[*num_of_tables].index =loc_port; 51274 table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress; 51275 (*num_of_tables)++; 51276 table_info[*num_of_tables].table = EGR_PORTm; 51277 table_info[*num_of_tables].index = loc_port; 51278 table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress; 51279 (*num_of_tables)++; 51280 return BCM_E_NONE; 51281 } 51282 #endif 51283 #if defined(BCM_KATANA2_SUPPORT) 51284 if (_BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)){ 51285 if(BCM_FAILURE(bcm_esw_port_local_get(unit, port, &loc_port))) { 51286 return BCM_E_NOT_FOUND; /* Local port disabled */ 51287 } 51288 table_info[*num_of_tables].table = PORT_TABm; 51289 table_info[*num_of_tables].index =loc_port; 51290 table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress; 51291 (*num_of_tables)++; 51292 table_info[*num_of_tables].table = EGR_PORTm; 51293 table_info[*num_of_tables].index = loc_port; 51294 table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress; 51295 (*num_of_tables)++; 51296 return BCM_E_NONE; 51297 } 51298 #endif /* BCM_KATANA2_SUPPORT */ 51299 #if defined(INCLUDE_L3) 51300 if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 51301 l3_idx = BCM_GPORT_SUBPORT_PORT_GET(port) & 0xfff; 51302 BCM_IF_ERROR_RETURN(soc_mem_read( 51303 unit, EGR_L3_INTFm, MEM_BLOCK_ALL, 51304 l3_idx, &l3_intf)); 51305 vp = soc_mem_field32_get(unit,EGR_L3_INTFm, &l3_intf, IVIDf); 51306 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm( 51307 unit,MEM_BLOCK_ALL,vp,&svp)); 51308 vp_base = soc_SOURCE_VPm_field32_get(unit, &svp, DVPf); 51309 /* vp = BCM_GPORT_SUBPORT_PORT_GET(port); */ 51310 /* Get the base group VP */ 51311 /* vp_base = vp & ~(0x7); */ 51312 /* Get the group's next-hop index */ 51313 BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm( 51314 unit, MEM_BLOCK_ALL, vp_base, &dvp)); 51315 nh_index = soc_ING_DVP_TABLEm_field32_get( 51316 unit, &dvp, NEXT_HOP_INDEXf); 51317 /*Get the group's OVID from the group's egress NextHopEntry*/ 51318 BCM_IF_ERROR_RETURN(soc_mem_read( 51319 unit, EGR_L3_NEXT_HOPm, 51320 MEM_BLOCK_ALL, nh_index, &egr_nh)); 51321 ovid = soc_mem_field32_get( 51322 unit, EGR_L3_NEXT_HOPm, &egr_nh, OVIDf); 51323 /* Get the egress port class */ 51324 BCM_IF_ERROR_RETURN (soc_mem_read( 51325 unit, ING_L3_NEXT_HOPm, 51326 MEM_BLOCK_ANY,nh_index, &ing_nh)); 51327 if (!soc_ING_L3_NEXT_HOPm_field32_get(unit, &ing_nh, Tf)) { 51328 egress_port = soc_ING_L3_NEXT_HOPm_field32_get( 51329 unit, &ing_nh, PORT_NUMf); 51330 BCM_IF_ERROR_RETURN(bcm_esw_port_class_get( 51331 unit, egress_port, 51332 bcmPortClassVlanTranslateEgress, 51333 &port_class)); 51334 } 51335 sal_memset(&egr_vent, 0, sizeof(egr_vent)); 51336 soc_EGR_VLAN_XLATEm_field32_set(unit, &egr_vent, VALIDf, 1); 51337 soc_EGR_VLAN_XLATEm_field32_set(unit, &egr_vent, OVIDf,ovid); 51338 if (soc_feature(unit, soc_feature_subport_enhanced)) { 51339 soc_EGR_VLAN_XLATEm_field32_set(unit,&egr_vent,IVIDf,vp); 51340 } 51341 soc_EGR_VLAN_XLATEm_field32_set( 51342 unit,&egr_vent,ENTRY_TYPEf, 0x01); 51343 soc_EGR_VLAN_XLATEm_field32_set( 51344 unit,&egr_vent,PORT_GROUP_IDf,port_class); 51345 MEM_LOCK(unit, EGR_VLAN_XLATEm); 51346 rv = soc_mem_search(unit,EGR_VLAN_XLATEm,MEM_BLOCK_ALL, 51347 &vt_index, &egr_vent, &egr_vent, 0); 51348 if (rv < 0) { 51349 MEM_UNLOCK(unit, EGR_VLAN_XLATEm); 51350 return rv; 51351 } 51352 rv = soc_mem_write(unit, EGR_VLAN_XLATEm, 51353 MEM_BLOCK_ALL, vt_index,&egr_vent); 51354 if (BCM_FAILURE(rv)) { 51355 MEM_UNLOCK(unit, EGR_VLAN_XLATEm); 51356 return rv; 51357 } 51358 table_info[*num_of_tables].table= EGR_VLAN_XLATEm; 51359 table_info[*num_of_tables].index=vt_index; 51360 table_info[*num_of_tables].direction= 51361 bcmStatFlexDirectionEgress; 51362 (*num_of_tables)++; 51363 MEM_UNLOCK(unit, EGR_VLAN_XLATEm); 51364 return BCM_E_NONE; 51365 } else { /*BCM_GPORT_IS_SUBPORT_GROUP(port) */ 51366 #if defined(BCM_TRIUMPH2_SUPPORT) 51367 vp_base = BCM_GPORT_SUBPORT_GROUP_GET(port); 51368 BCM_IF_ERROR_RETURN(_bcm_tr2_subport_gport_used(unit,port)); 51369 table_info[*num_of_tables].table= SOURCE_VPm; 51370 table_info[*num_of_tables].index=vp_base; 51371 table_info[*num_of_tables].direction= 51372 bcmStatFlexDirectionIngress; 51373 (*num_of_tables)++; 51374 return BCM_E_NONE; 51375 #endif 51376 } 51377 } else if (BCM_GPORT_IS_MIM_PORT(port)) { 51378 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 51379 /*MIM_LOCK(unit); */ 51380 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 51381 /*MIM_UNLOCK(unit); */ 51382 return BCM_E_NOT_FOUND; 51383 } 51384 /* Ingress side */ 51385 table_info[*num_of_tables].table= SOURCE_VPm; 51386 table_info[*num_of_tables].index=vp; 51387 table_info[*num_of_tables].direction= 51388 bcmStatFlexDirectionIngress; 51389 (*num_of_tables)++; 51390 /* Egress side */ 51391 if (BCM_SUCCESS(READ_ING_DVP_TABLEm( 51392 unit, MEM_BLOCK_ANY, vp, &dvp))) { 51393 nh_index = soc_mem_field32_get(unit, ING_DVP_TABLEm, &dvp, 51394 NEXT_HOP_INDEXf); 51395 if (BCM_SUCCESS(soc_mem_read( 51396 unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 51397 nh_index,&egr_nh))) { 51398 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm; 51399 table_info[*num_of_tables].index=nh_index; 51400 table_info[*num_of_tables].direction= 51401 bcmStatFlexDirectionEgress; 51402 (*num_of_tables)++; 51403 } 51404 } 51405 return BCM_E_NONE; 51406 } else if (BCM_GPORT_IS_WLAN_PORT(port)) { 51407 vp = BCM_GPORT_WLAN_PORT_ID_GET(port); 51408 /*WLAN_LOCK(unit); */ 51409 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) { 51410 /*WLAN_UNLOCK(unit); */ 51411 return BCM_E_NOT_FOUND; 51412 } 51413 /*Ingress Side */ 51414 table_info[*num_of_tables].table= SOURCE_VPm; 51415 table_info[*num_of_tables].index=vp; 51416 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 51417 (*num_of_tables)++; 51418 BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm( 51419 unit, MEM_BLOCK_ANY, vp, &dvp)); 51420 nh_index = soc_ING_DVP_TABLEm_field32_get( 51421 unit, &dvp, NEXT_HOP_INDEXf); 51422 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm; 51423 table_info[*num_of_tables].index=nh_index; 51424 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress; 51425 (*num_of_tables)++; 51426 return BCM_E_NONE; 51427 } else if (BCM_GPORT_IS_VLAN_PORT(port)) { 51428 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 51429 51430 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan))) { 51431 return BCM_E_NOT_FOUND; 51432 } 51433 51434 /*Ingress Side */ 51435 table_info[*num_of_tables].table= SOURCE_VPm; 51436 table_info[*num_of_tables].index=vp; 51437 table_info[*num_of_tables].direction=bcmStatFlexDirectionIngress; 51438 (*num_of_tables)++; 51439 BCM_IF_ERROR_RETURN(READ_ING_DVP_TABLEm( 51440 unit, MEM_BLOCK_ANY, vp, &dvp)); 51441 nh_index = soc_ING_DVP_TABLEm_field32_get( 51442 unit, &dvp, NEXT_HOP_INDEXf); 51443 table_info[*num_of_tables].table= EGR_L3_NEXT_HOPm; 51444 table_info[*num_of_tables].index=nh_index; 51445 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress; 51446 (*num_of_tables)++; 51447 return BCM_E_NONE; 51448 #endif 51449 } else { 51450 if(BCM_FAILURE(bcm_esw_port_local_get(unit, port, &loc_port))) { 51451 return BCM_E_NOT_FOUND; /* Local port disabled */ 51452 } 51453 /*PORT_LOCK(unit); */ 51454 #if defined(BCM_TRIDENT3_SUPPORT) 51455 if (SOC_IS_TRIDENT3X(unit)) { 51456 table_info[*num_of_tables].table = LPORT_TABm; 51457 table_info[*num_of_tables].index = loc_port; 51458 table_info[*num_of_tables].direction = bcmStatFlexDirectionIngress; 51459 (*num_of_tables)++; 51460 if (soc_mem_field_valid(unit, EGR_PORTm, EGR_LPORT_PROFILE_IDXf) && 51461 soc_mem_is_valid(unit, EGR_LPORT_PROFILEm)) { 51462 table_info[*num_of_tables].table = EGR_LPORT_PROFILEm; 51463 table_info[*num_of_tables].index = loc_port; 51464 table_info[*num_of_tables].direction = bcmStatFlexDirectionEgress; 51465 (*num_of_tables)++; 51466 } else { 51467 return BCM_E_NOT_FOUND; 51468 } 51469 } else 51470 #endif 51471 { 51472 table_info[*num_of_tables].table= PORT_TABm; 51473 table_info[*num_of_tables].index=loc_port; 51474 table_info[*num_of_tables].direction= bcmStatFlexDirectionIngress; 51475 (*num_of_tables)++; 51476 table_info[*num_of_tables].table= EGR_PORTm; 51477 table_info[*num_of_tables].index=loc_port; 51478 table_info[*num_of_tables].direction=bcmStatFlexDirectionEgress; 51479 (*num_of_tables)++; 51480 } 51481 return BCM_E_NONE; 51482 } 51483 return BCM_E_NOT_FOUND; 51484 } 51485 #endif 51486 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 51487 /* 51488 * Function: 51489 * _bcm_esw_port_stat_attach 51490 * Description: 51491 * Attach counter entries to the given GPORT 51492 * 51493 * Parameters: 51494 * unit - (IN) unit number 51495 * port - (IN) GPORT ID 51496 * stat_counter_id - (IN) Stat Counter ID. 51497 * 51498 * Return Value: 51499 * BCM_E_XXX 51500 * Notes: 51501 */ 51502 int _bcm_esw_port_stat_attach( 51503 int unit, 51504 bcm_gport_t port, 51505 uint32 stat_counter_id) 51506 { 51507 soc_mem_t table=0; 51508 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 51509 uint32 pool_number=0; 51510 uint32 base_index=0; 51511 bcm_stat_flex_mode_t offset_mode=0; 51512 bcm_stat_object_t object=bcmStatObjectIngPort; 51513 bcm_stat_group_mode_t group_mode= bcmStatGroupModeSingle; 51514 uint32 count=0; 51515 uint32 actual_num_tables=0; 51516 uint32 num_of_tables=0; 51517 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 51518 uint8 skip_table_check = 0; 51519 51520 _bcm_esw_stat_get_counter_id_info( 51521 unit, stat_counter_id, 51522 &group_mode,&object,&offset_mode,&pool_number,&base_index); 51523 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_object(unit,object,&direction)); 51524 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit,group_mode)); 51525 BCM_IF_ERROR_RETURN(_bcm_esw_stat_flex_get_table_info( 51526 unit,object,1,&actual_num_tables,&table,&direction)); 51527 51528 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 51529 unit, port,&num_of_tables,&table_info[0])); 51530 skip_table_check = soc_property_get(unit, spn_FLEX_STAT_SHARE_ENABLE, 0); 51531 for (count=0; count < num_of_tables ; count++) { 51532 if ( (table_info[count].direction == direction) && 51533 ((table_info[count].table == table) || (skip_table_check)) ) { 51534 if(direction == bcmStatFlexDirectionIngress) { 51535 return _bcm_esw_stat_flex_attach_ingress_table_counters( 51536 unit, 51537 table_info[count].table, 51538 table_info[count].index, 51539 offset_mode, 51540 base_index, 51541 pool_number); 51542 } else { 51543 return _bcm_esw_stat_flex_attach_egress_table_counters( 51544 unit, 51545 table_info[count].table, 51546 table_info[count].index, 51547 0, 51548 offset_mode, 51549 base_index, 51550 pool_number); 51551 } 51552 } 51553 } 51554 return BCM_E_NOT_FOUND; 51555 } 51556 #endif 51557 51558 /* 51559 * Function: 51560 * bcm_esw_port_stat_attach 51561 * Description: 51562 * Attach counter entries to the given GPORT 51563 * 51564 * Parameters: 51565 * unit - (IN) unit number 51566 * port - (IN) GPORT ID 51567 * stat_counter_id - (IN) Stat Counter ID. 51568 * 51569 * Return Value: 51570 * BCM_E_XXX 51571 * Notes: 51572 */ 51573 int bcm_esw_port_stat_attach( 51574 int unit, 51575 bcm_gport_t port, 51576 uint32 stat_counter_id) 51577 { 51578 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 51579 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 51580 return _bcm_esw_port_stat_attach(unit,port,stat_counter_id); 51581 } else 51582 #endif 51583 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 51584 if (soc_feature(unit,soc_feature_gport_service_counters)) { 51585 _bcm_flex_stat_type_t fs_type; 51586 uint32 fs_inx; 51587 uint32 flag; 51588 int rv; 51589 51590 fs_type = _BCM_FLEX_STAT_TYPE(stat_counter_id); 51591 fs_inx = _BCM_FLEX_STAT_COUNT_INX(stat_counter_id); 51592 51593 if (!((fs_type == _bcmFlexStatTypeGport || 51594 fs_type == _bcmFlexStatTypeEgressGport) && fs_inx)) { 51595 return BCM_E_PARAM; 51596 } 51597 BCM_IF_ERROR_RETURN 51598 (_bcm_esw_port_stat_param_valid(unit, port)); 51599 51600 flag = fs_type==_bcmFlexStatTypeGport? _BCM_FLEX_STAT_HW_INGRESS: 51601 _BCM_FLEX_STAT_HW_EGRESS; 51602 51603 rv = _bcm_esw_flex_stat_enable_set(unit, fs_type, 51604 _bcm_esw_port_flex_stat_hw_index_set, 51605 INT_TO_PTR(flag), 51606 port, TRUE,fs_inx); 51607 return rv; 51608 } else 51609 #endif 51610 { 51611 return BCM_E_UNAVAIL; 51612 } 51613 } 51614 51615 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 51616 /* 51617 * Function: 51618 * _bcm_esw_port_stat_detach 51619 * Description: 51620 * Detach counter entries to the given GPORT 51621 * 51622 * Parameters: 51623 * unit - (IN) unit number 51624 * port - (IN) GPORT ID 51625 * 51626 * Return Value: 51627 * BCM_E_XXX 51628 * Notes: 51629 */ 51630 int _bcm_esw_port_stat_detach( 51631 int unit, 51632 bcm_gport_t port) 51633 { 51634 uint32 count=0; 51635 uint32 num_of_tables=0; 51636 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 51637 bcm_error_t rv = BCM_E_NONE; 51638 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 51639 51640 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 51641 unit, port,&num_of_tables,&table_info[0])); 51642 51643 for (count=0; count < num_of_tables ; count++) { 51644 if (table_info[count].direction == bcmStatFlexDirectionIngress) { 51645 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 51646 unit, 51647 table_info[count].table, 51648 table_info[count].index); 51649 if (BCM_E_NONE != rv && 51650 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 51651 err_code[bcmStatFlexDirectionIngress] = rv; 51652 } 51653 } else { 51654 rv = _bcm_esw_stat_flex_detach_egress_table_counters( 51655 unit, 51656 0, 51657 table_info[count].table, 51658 table_info[count].index); 51659 if (BCM_E_NONE != rv && 51660 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) { 51661 err_code[bcmStatFlexDirectionEgress] = rv; 51662 } 51663 } 51664 } 51665 51666 BCM_STAT_FLEX_DETACH_RETURN(err_code) 51667 } 51668 51669 /* 51670 * Function: 51671 * _bcm_esw_port_stat_detach_with_id 51672 * Description: 51673 * Detach counter entries to the given GPORT with a given stat counter id 51674 * 51675 * Parameters: 51676 * unit - (IN) unit number 51677 * port - (IN) GPORT ID 51678 * stat_counter_id - (IN) Stat Counter ID 51679 * 51680 * Return Value: 51681 * BCM_E_XXX 51682 * Notes: 51683 */ 51684 bcm_error_t _bcm_esw_port_stat_detach_with_id( 51685 int unit, 51686 bcm_gport_t port, 51687 uint32 stat_counter_id) 51688 { 51689 uint32 count=0; 51690 uint32 num_of_tables=0; 51691 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 51692 bcm_error_t rv = BCM_E_NONE; 51693 bcm_error_t err_code[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION] = {BCM_E_NONE}; 51694 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 51695 uint32 pool_number=0; 51696 uint32 base_index=0; 51697 bcm_stat_flex_mode_t offset_mode=0; 51698 bcm_stat_object_t object=bcmStatObjectIngPort; 51699 bcm_stat_group_mode_t group_mode= bcmStatGroupModeSingle; 51700 uint32 actual_num_tables=0; 51701 soc_mem_t table=0; 51702 51703 _bcm_esw_stat_get_counter_id_info(unit, stat_counter_id, &group_mode, &object, 51704 &offset_mode, &pool_number, &base_index); 51705 BCM_IF_ERROR_RETURN 51706 (_bcm_esw_stat_validate_object(unit, object, &direction)); 51707 BCM_IF_ERROR_RETURN(_bcm_esw_stat_validate_group(unit, group_mode)); 51708 BCM_IF_ERROR_RETURN 51709 (_bcm_esw_stat_flex_get_table_info(unit, object, 1, &actual_num_tables, 51710 &table, &direction)); 51711 51712 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 51713 unit, port,&num_of_tables,&table_info[0])); 51714 51715 for (count=0; count < num_of_tables ; count++) { 51716 if((table_info[count].direction == direction) && 51717 (table_info[count].table == table)) { 51718 if(direction == bcmStatFlexDirectionIngress) { 51719 rv = _bcm_esw_stat_flex_detach_ingress_table_counters( 51720 unit, 51721 table_info[count].table, 51722 table_info[count].index); 51723 if (BCM_E_NONE != rv && 51724 BCM_E_NONE == err_code[bcmStatFlexDirectionIngress]) { 51725 err_code[bcmStatFlexDirectionIngress] = rv; 51726 } 51727 } else { 51728 rv = _bcm_esw_stat_flex_detach_egress_table_counters( 51729 unit, 51730 0, 51731 table_info[count].table, 51732 table_info[count].index); 51733 if (BCM_E_NONE != rv && 51734 BCM_E_NONE == err_code[bcmStatFlexDirectionEgress]) { 51735 err_code[bcmStatFlexDirectionEgress] = rv; 51736 } 51737 } 51738 } 51739 } 51740 51741 BCM_STAT_FLEX_DETACH_RETURN(err_code) 51742 } 51743 #endif 51744 51745 /* 51746 * Function: 51747 * bcm_esw_port_stat_detach 51748 * Description: 51749 * Detach counter entries to the given GPORT 51750 * 51751 * Parameters: 51752 * unit - (IN) unit number 51753 * port - (IN) GPORT ID 51754 * 51755 * Return Value: 51756 * BCM_E_XXX 51757 * Notes: 51758 */ 51759 int bcm_esw_port_stat_detach( 51760 int unit, 51761 bcm_gport_t port) 51762 { 51763 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 51764 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 51765 return _bcm_esw_port_stat_detach(unit,port); 51766 } else 51767 #endif 51768 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 51769 if (soc_feature(unit,soc_feature_gport_service_counters)) { 51770 uint32 flag; 51771 int rv; 51772 int rv1; 51773 51774 BCM_IF_ERROR_RETURN 51775 (_bcm_esw_port_stat_param_valid(unit, port)); 51776 51777 /* no count_id, detach all counters associated with this port.*/ 51778 flag= _BCM_FLEX_STAT_HW_INGRESS; 51779 rv = _bcm_esw_flex_stat_enable_set(unit, _bcmFlexStatTypeGport, 51780 _bcm_esw_port_flex_stat_hw_index_set, 51781 INT_TO_PTR(flag), 51782 port, FALSE,1); 51783 flag= _BCM_FLEX_STAT_HW_EGRESS; 51784 rv1 = _bcm_esw_flex_stat_enable_set(unit, 51785 _bcmFlexStatTypeEgressGport, 51786 _bcm_esw_port_flex_stat_hw_index_set, 51787 INT_TO_PTR(flag), 51788 port, FALSE,1); 51789 if (BCM_SUCCESS(rv) && BCM_SUCCESS(rv1)) { 51790 return BCM_E_NONE; 51791 } else { 51792 return BCM_E_NOT_FOUND; 51793 } 51794 } else 51795 #endif 51796 { 51797 return BCM_E_UNAVAIL; 51798 } 51799 } 51800 51801 /* 51802 * Function: 51803 * bcm_esw_port_stat_detach_with_id 51804 * Description: 51805 * Detach counter entries to the given GPORT with a given stat counter id 51806 * 51807 * Parameters: 51808 * unit - (IN) unit number 51809 * port - (IN) GPORT ID 51810 * stat_counter_id - (IN) Stat Counter ID 51811 * 51812 * Return Value: 51813 * BCM_E_XXX 51814 * Notes: 51815 */ 51816 bcm_error_t bcm_esw_port_stat_detach_with_id( 51817 int unit, 51818 bcm_gport_t port, 51819 uint32 stat_counter_id) 51820 { 51821 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 51822 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 51823 return _bcm_esw_port_stat_detach_with_id(unit, port, stat_counter_id); 51824 } else 51825 #endif 51826 { 51827 return BCM_E_UNAVAIL; 51828 } 51829 } 51830 51831 51832 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 51833 /* 51834 * Function: 51835 * _bcm_esw_port_stat_counter_get 51836 * Description: 51837 * retrieve set of counter statistic values for the given GPORT 51838 * if sync_mode is set, sync the sw accumulated count 51839 * with hw count value first, else return sw count. 51840 * 51841 * Parameters: 51842 * unit - (IN) unit number 51843 * port - (IN) GPORT ID 51844 * stat - (IN) Type of the counter to retrieve 51845 * I.e. ingress/egress byte/packet) 51846 * num_entries - (IN) Number of counter Entries 51847 * counter_indexes - (IN) Pointer to Counter indexes entries 51848 * counter_values - (OUT) Pointer to counter values 51849 * 51850 * Return Value: 51851 * BCM_E_XXX 51852 * Notes: 51853 */ 51854 int _bcm_esw_port_stat_counter_get( 51855 int unit, 51856 int sync_mode, 51857 bcm_gport_t port, 51858 bcm_port_stat_t stat, 51859 uint32 num_entries, 51860 uint32 *counter_indexes, 51861 bcm_stat_value_t *counter_values) 51862 { 51863 uint32 table_count=0; 51864 uint32 index_count=0; 51865 uint32 num_of_tables=0; 51866 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 51867 uint32 byte_flag=0; 51868 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 51869 51870 if ((stat == bcmPortStatIngressPackets) || 51871 (stat == bcmPortStatIngressBytes)) { 51872 direction = bcmStatFlexDirectionIngress; 51873 } else { 51874 direction = bcmStatFlexDirectionEgress; 51875 } 51876 if ((stat == bcmPortStatIngressPackets) || 51877 (stat == bcmPortStatEgressPackets)) { 51878 byte_flag=0; 51879 } else { 51880 byte_flag=1; 51881 } 51882 51883 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 51884 unit, port,&num_of_tables,&table_info[0])); 51885 51886 for (table_count=0; table_count < num_of_tables ; table_count++) { 51887 if (table_info[table_count].direction == direction) { 51888 for (index_count=0; index_count < num_entries ; index_count++) { 51889 /*ctr_offset_info.offset_index = counter_indexes[index_count];*/ 51890 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_get( 51891 unit, sync_mode, 51892 table_info[table_count].index, 51893 table_info[table_count].table, 51894 0, 51895 byte_flag, 51896 counter_indexes[index_count], 51897 &counter_values[index_count])); 51898 } 51899 } 51900 } 51901 return BCM_E_NONE; 51902 } 51903 #endif 51904 51905 /* 51906 * Function: 51907 * _bcm_esw_port_flex_stat_counter_get 51908 * Description: 51909 * retrieve set of counter statistic values for the given GPORT 51910 * if sync_mode is set, sync the sw accumulated count 51911 * with hw count value first, else return sw count. 51912 * Parameters: 51913 * unit - (IN) unit number 51914 * sync_mode - (IN) hwcount is to be synced to sw count 51915 * port - (IN) GPORT ID 51916 * stat - (IN) Type of the counter to retrieve 51917 * I.e. ingress/egress byte/packet) 51918 * num_entries - (IN) Number of counter Entries 51919 * counter_indexes - (IN) Pointer to Counter indexes entries 51920 * counter_values - (OUT) Pointer to counter values 51921 * 51922 * Return Value: 51923 * BCM_E_XXX 51924 * Notes: 51925 */ 51926 int _bcm_esw_port_flex_stat_counter_get(int unit, 51927 int sync_mode, 51928 bcm_gport_t port, 51929 bcm_port_stat_t stat, 51930 uint32 num_entries, 51931 uint32 *counter_indexes, 51932 bcm_stat_value_t *counter_values) 51933 { 51934 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 51935 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 51936 return _bcm_esw_port_stat_counter_get(unit, sync_mode, port, stat, 51937 num_entries, counter_indexes, 51938 counter_values); 51939 } else 51940 #endif 51941 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 51942 if (soc_feature(unit,soc_feature_gport_service_counters)) { 51943 uint64 val; 51944 int rv = BCM_E_NONE; 51945 51946 rv = _bcm_esw_flex_stat_get(unit, sync_mode, 51947 ((stat == bcmPortStatIngressPackets) || 51948 (stat == bcmPortStatIngressBytes)) ? 51949 _bcmFlexStatTypeGport:_bcmFlexStatTypeEgressGport, 51950 port, 51951 _bcm_esw_port_stat_to_flex_stat(stat), &val); 51952 51953 if ((stat == bcmPortStatIngressPackets) || 51954 (stat == bcmPortStatEgressPackets)) { 51955 counter_values->packets = COMPILER_64_LO(val); 51956 } else { 51957 COMPILER_64_SET(counter_values->bytes, 51958 COMPILER_64_HI(val), 51959 COMPILER_64_LO(val)); 51960 } 51961 return rv; 51962 51963 } else 51964 #endif 51965 { 51966 return BCM_E_UNAVAIL; 51967 } 51968 51969 } 51970 51971 51972 /* 51973 * Function: 51974 * bcm_esw_port_stat_counter_get 51975 * Description: 51976 * retrieve set of counter statistic values for the given GPORT 51977 * Parameters: 51978 * unit - (IN) unit number 51979 * port - (IN) GPORT ID 51980 * stat - (IN) Type of the counter to retrieve 51981 * I.e. ingress/egress byte/packet) 51982 * num_entries - (IN) Number of counter Entries 51983 * counter_indexes - (IN) Pointer to Counter indexes entries 51984 * counter_values - (OUT) Pointer to counter values 51985 * 51986 * Return Value: 51987 * BCM_E_XXX 51988 * Notes: 51989 */ 51990 51991 int bcm_esw_port_stat_counter_get(int unit, 51992 bcm_gport_t port, 51993 bcm_port_stat_t stat, 51994 uint32 num_entries, 51995 uint32 *counter_indexes, 51996 bcm_stat_value_t *counter_values) 51997 { 51998 int rv = BCM_E_UNAVAIL; 51999 52000 rv = _bcm_esw_port_flex_stat_counter_get(unit, 0, port, stat, num_entries, 52001 counter_indexes, counter_values); 52002 52003 return rv; 52004 } 52005 52006 52007 /* 52008 * Function: 52009 * bcm_esw_port_stat_counter_sync_get 52010 * Description: 52011 * retrieve set of counter statistic values for the given GPORT 52012 * sw accumulated counters synced with hw count. 52013 * Parameters: 52014 * unit - (IN) unit number 52015 * port - (IN) GPORT ID 52016 * stat - (IN) Type of the counter to retrieve 52017 * I.e. ingress/egress byte/packet) 52018 * num_entries - (IN) Number of counter Entries 52019 * counter_indexes - (IN) Pointer to Counter indexes entries 52020 * counter_values - (OUT) Pointer to counter values 52021 * 52022 * Return Value: 52023 * BCM_E_XXX 52024 * Notes: 52025 */ 52026 52027 int bcm_esw_port_stat_counter_sync_get(int unit, 52028 bcm_gport_t port, 52029 bcm_port_stat_t stat, 52030 uint32 num_entries, 52031 uint32 *counter_indexes, 52032 bcm_stat_value_t *counter_values) 52033 { 52034 int rv = BCM_E_UNAVAIL; 52035 52036 rv = _bcm_esw_port_flex_stat_counter_get(unit, 1, port, stat, num_entries, 52037 counter_indexes, counter_values); 52038 52039 return rv; 52040 } 52041 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52042 /* 52043 * Function: 52044 * _bcm_esw_port_stat_counter_set 52045 * Description: 52046 * set counter statistic values for the given GPORT 52047 * 52048 * Parameters: 52049 * unit - (IN) unit number 52050 * port - (IN) GPORT ID 52051 * stat - (IN) Type of the counter to retrieve 52052 * I.e. ingress/egress byte/packet) 52053 * num_entries - (IN) Number of counter Entries 52054 * counter_indexes - (IN) Pointer to Counter indexes entries 52055 * counter_values - (IN) Pointer to counter values 52056 * 52057 * Return Value: 52058 * BCM_E_XXX 52059 * Notes: 52060 */ 52061 int _bcm_esw_port_stat_counter_set( 52062 int unit, 52063 bcm_gport_t port, 52064 bcm_port_stat_t stat, 52065 uint32 num_entries, 52066 uint32 *counter_indexes, 52067 bcm_stat_value_t *counter_values) 52068 { 52069 uint32 table_count=0; 52070 uint32 index_count=0; 52071 uint32 num_of_tables=0; 52072 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 52073 uint32 byte_flag=0; 52074 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 52075 52076 if ((stat == bcmPortStatIngressPackets) || 52077 (stat == bcmPortStatIngressBytes)) { 52078 direction = bcmStatFlexDirectionIngress; 52079 } else { 52080 direction = bcmStatFlexDirectionEgress; 52081 } 52082 if ((stat == bcmPortStatIngressPackets) || 52083 (stat == bcmPortStatEgressPackets)) { 52084 byte_flag=0; 52085 } else { 52086 byte_flag=1; 52087 } 52088 52089 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 52090 unit, port,&num_of_tables,&table_info[0])); 52091 52092 for (table_count=0; table_count < num_of_tables ; table_count++) { 52093 if (table_info[table_count].direction == direction) { 52094 for (index_count=0; index_count < num_entries ; index_count++) { 52095 BCM_IF_ERROR_RETURN(_bcm_esw_stat_counter_set( 52096 unit, 52097 table_info[table_count].index, 52098 table_info[table_count].table, 52099 0, 52100 byte_flag, 52101 counter_indexes[index_count], 52102 &counter_values[index_count])); 52103 } 52104 } 52105 } 52106 return BCM_E_NONE; 52107 } 52108 #endif 52109 /* 52110 * Function: 52111 * bcm_esw_port_stat_counter_set 52112 * Description: 52113 * set counter statistic values for the given GPORT 52114 * 52115 * Parameters: 52116 * unit - (IN) unit number 52117 * port - (IN) GPORT ID 52118 * stat - (IN) Type of the counter to retrieve 52119 * I.e. ingress/egress byte/packet) 52120 * num_entries - (IN) Number of counter Entries 52121 * counter_indexes - (IN) Pointer to Counter indexes entries 52122 * counter_values - (IN) Pointer to counter values 52123 * 52124 * Return Value: 52125 * BCM_E_XXX 52126 * Notes: 52127 */ 52128 int bcm_esw_port_stat_counter_set( 52129 int unit, 52130 bcm_gport_t port, 52131 bcm_port_stat_t stat, 52132 uint32 num_entries, 52133 uint32 *counter_indexes, 52134 bcm_stat_value_t *counter_values) 52135 { 52136 /* Make sure port module is initialized. */ 52137 PORT_INIT(unit); 52138 52139 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52140 if (soc_feature(unit,soc_feature_advanced_flex_counter)) { 52141 return _bcm_esw_port_stat_counter_set(unit,port,stat, 52142 num_entries,counter_indexes,counter_values); 52143 } else 52144 #endif 52145 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) 52146 if (soc_feature(unit,soc_feature_gport_service_counters)) { 52147 uint64 val; 52148 int rv = BCM_E_NONE; 52149 52150 if ((stat == bcmPortStatIngressPackets) || 52151 (stat == bcmPortStatEgressPackets)) { 52152 COMPILER_64_SET(val,0,counter_values->packets); 52153 } else { 52154 COMPILER_64_SET(val, 52155 COMPILER_64_HI(counter_values->bytes), 52156 COMPILER_64_LO(counter_values->bytes)); 52157 } 52158 rv = _bcm_esw_flex_stat_set(unit, 52159 ((stat == bcmPortStatIngressPackets) || 52160 (stat == bcmPortStatIngressBytes)) ? 52161 _bcmFlexStatTypeGport:_bcmFlexStatTypeEgressGport, 52162 port, 52163 _bcm_esw_port_stat_to_flex_stat(stat), val); 52164 52165 return rv; 52166 52167 } else 52168 #endif 52169 { 52170 return BCM_E_UNAVAIL; 52171 } 52172 } 52173 /* 52174 * Function: 52175 * bcm_esw_port_stat_id_get 52176 * Description: 52177 * Get stat counter id associated with given gport 52178 * 52179 * Parameters: 52180 * unit - (IN) unit number 52181 * port - (IN) GPORT ID 52182 * stat - (IN) Type of the counter to retrieve 52183 * I.e. ingress/egress byte/packet) 52184 * Stat_counter_id - (OUT) Stat Counter ID 52185 * Return Value: 52186 * BCM_E_XXX 52187 * Notes: 52188 */ 52189 int bcm_esw_port_stat_id_get( 52190 int unit, 52191 bcm_gport_t port, 52192 bcm_port_stat_t stat, 52193 uint32 *stat_counter_id) 52194 { 52195 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52196 bcm_stat_flex_direction_t direction=bcmStatFlexDirectionIngress; 52197 uint32 num_of_tables=0; 52198 bcm_stat_flex_table_info_t table_info[BCM_STAT_FLEX_COUNTER_MAX_DIRECTION]; 52199 uint32 index=0; 52200 uint32 num_stat_counter_ids=0; 52201 52202 /* Make sure port module is initialized. */ 52203 PORT_INIT(unit); 52204 52205 if ((stat == bcmPortStatIngressPackets) || 52206 (stat == bcmPortStatIngressBytes)) { 52207 direction = bcmStatFlexDirectionIngress; 52208 } else { 52209 direction = bcmStatFlexDirectionEgress; 52210 } 52211 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_get_table_info( 52212 unit,port,&num_of_tables,&table_info[0])); 52213 for (index=0; index < num_of_tables ; index++) { 52214 if (table_info[index].direction == direction) 52215 return _bcm_esw_stat_flex_get_counter_id( 52216 unit, 1, &table_info[index], 52217 &num_stat_counter_ids,stat_counter_id); 52218 } 52219 return BCM_E_NOT_FOUND; 52220 #else 52221 return BCM_E_UNAVAIL; 52222 #endif 52223 } 52224 52225 52226 /* 52227 * Function: 52228 * _bcm_esw_port_stat_get 52229 * Purpose: 52230 * Get 64-bit counter value for specified port statistic type. 52231 * if sync_mode is set, sync the sw accumulated count 52232 * with hw count value first, else return sw count. 52233 * Parameters: 52234 * unit - (IN) Unit number. 52235 * sync_mode - (IN) hwcount is to be synced to sw count 52236 * port - (IN) GPORT ID 52237 * stat - (IN) Type of the counter to retrieve. 52238 * val - (OUT) Pointer to a counter value. 52239 * Returns: 52240 * BCM_E_XXX 52241 * Notes: 52242 */ 52243 int 52244 _bcm_esw_port_stat_get(int unit, int sync_mode, bcm_gport_t port, 52245 bcm_port_stat_t stat, uint64 *val) 52246 { 52247 #if defined(BCM_TRIUMPH2_SUPPORT) 52248 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52249 uint32 counter_indexes=0; 52250 bcm_stat_value_t counter_values={0}; 52251 #endif 52252 52253 /* Make sure port module is initialized. */ 52254 PORT_INIT(unit); 52255 52256 #if defined(BCM_PREEMPTION_SUPPORT) 52257 if (soc_feature(unit, soc_feature_preemption_cnt)) { 52258 bcm_port_t local_port; 52259 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 52260 return bcmi_esw_preemption_counter_get(unit, sync_mode, local_port, 52261 stat, val); 52262 } 52263 #endif /* BCM_PREEMPTION_SUPPORT */ 52264 52265 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 52266 BCM_IF_ERROR_RETURN 52267 (_bcm_esw_port_stat_param_valid(unit, port)); 52268 return _bcm_esw_flex_stat_get(unit, sync_mode, _bcmFlexStatTypeGport, port, 52269 _bcm_esw_port_stat_to_flex_stat(stat), val); 52270 } 52271 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52272 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_counter_get(unit, sync_mode, port, 52273 stat, 1, &counter_indexes, 52274 &counter_values)); 52275 if ((stat == bcmPortStatIngressPackets) || 52276 (stat == bcmPortStatEgressPackets)) { 52277 COMPILER_64_SET(*val, 52278 COMPILER_64_HI(counter_values.packets64), 52279 COMPILER_64_LO(counter_values.packets64)); 52280 } else { 52281 COMPILER_64_SET(*val, 52282 COMPILER_64_HI(counter_values.bytes), 52283 COMPILER_64_LO(counter_values.bytes)); 52284 } 52285 return BCM_E_NONE; 52286 #else 52287 return BCM_E_UNAVAIL; 52288 #endif 52289 #else 52290 return BCM_E_UNAVAIL; 52291 #endif 52292 } 52293 52294 52295 /* 52296 * Function: 52297 * bcm_esw_port_stat_get 52298 * Purpose: 52299 * Get 64-bit counter value for specified port statistic type. 52300 * Parameters: 52301 * unit - (IN) Unit number. 52302 * port - (IN) GPORT ID 52303 * stat - (IN) Type of the counter to retrieve. 52304 * val - (OUT) Pointer to a counter value. 52305 * Returns: 52306 * BCM_E_XXX 52307 * Notes: 52308 */ 52309 int 52310 bcm_esw_port_stat_get(int unit, bcm_gport_t port, bcm_port_stat_t stat, 52311 uint64 *val) 52312 { 52313 int rv = BCM_E_UNAVAIL; 52314 52315 rv = _bcm_esw_port_stat_get(unit, 0, port, stat, val); 52316 52317 return rv; 52318 } 52319 52320 52321 /* 52322 * Function: 52323 * bcm_esw_port_stat_sync_get 52324 * Purpose: 52325 * Get 64-bit counter value for specified port statistic type. 52326 * sw accumulated counters synced with hw count. 52327 * Parameters: 52328 * unit - (IN) Unit number. 52329 * port - (IN) GPORT ID 52330 * stat - (IN) Type of the counter to retrieve. 52331 * val - (OUT) Pointer to a counter value. 52332 * Returns: 52333 * BCM_E_XXX 52334 * Notes: 52335 */ 52336 int 52337 bcm_esw_port_stat_sync_get(int unit, bcm_gport_t port, bcm_port_stat_t stat, 52338 uint64 *val) 52339 { 52340 int rv = BCM_E_UNAVAIL; 52341 52342 rv = _bcm_esw_port_stat_get(unit, 1, port, stat, val); 52343 52344 return rv; 52345 } 52346 52347 /* 52348 * Function: 52349 * _bcm_esw_port_stat_get32 52350 * Purpose: 52351 * Get lower 32-bit counter value for specified port statistic 52352 * type. 52353 * if sync_mode is set, sync the sw accumulated count 52354 * with hw count value first, else return sw count. 52355 * Parameters: 52356 * unit - (IN) Unit number. 52357 * sync_mode - (IN) hwcount is to be synced to sw count 52358 * port - (IN) GPORT ID 52359 * stat - (IN) Type of the counter to retrieve. 52360 * val - (OUT) Pointer to a counter value. 52361 * Returns: 52362 * BCM_E_XXX 52363 * Notes: 52364 */ 52365 int 52366 _bcm_esw_port_stat_get32(int unit, int sync_mode, bcm_gport_t port, 52367 bcm_port_stat_t stat, uint32 *val) 52368 { 52369 #if defined(BCM_TRIUMPH2_SUPPORT) 52370 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52371 uint32 counter_indexes=0; 52372 bcm_stat_value_t counter_values={0}; 52373 #endif 52374 52375 /* Make sure port module is initialized. */ 52376 PORT_INIT(unit); 52377 52378 #if defined(BCM_PREEMPTION_SUPPORT) 52379 if (soc_feature(unit, soc_feature_preemption_cnt)) { 52380 bcm_port_t local_port; 52381 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 52382 return bcmi_esw_preemption_counter_get32(unit, sync_mode, local_port, 52383 stat, val); 52384 } 52385 #endif /* BCM_PREEMPTION_SUPPORT */ 52386 52387 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 52388 BCM_IF_ERROR_RETURN 52389 (_bcm_esw_port_stat_param_valid(unit, port)); 52390 return _bcm_esw_flex_stat_get32(unit, sync_mode, 52391 _bcmFlexStatTypeGport, port, 52392 _bcm_esw_port_stat_to_flex_stat(stat), val); 52393 } 52394 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52395 BCM_IF_ERROR_RETURN(_bcm_esw_port_stat_counter_get(unit, sync_mode, 52396 port, stat, 1, 52397 &counter_indexes, 52398 &counter_values)); 52399 if ((stat == bcmPortStatIngressPackets) || 52400 (stat == bcmPortStatEgressPackets)) { 52401 *val = counter_values.packets; 52402 } else { 52403 /* Ignoring Hi bytes value */ 52404 *val = COMPILER_64_LO(counter_values.bytes); 52405 } 52406 return BCM_E_NONE; 52407 #else 52408 return BCM_E_UNAVAIL; 52409 #endif 52410 #else 52411 return BCM_E_UNAVAIL; 52412 #endif 52413 } 52414 52415 52416 /* 52417 * Function: 52418 * bcm_esw_port_stat_get32 52419 * Purpose: 52420 * Get lower 32-bit counter value for specified port statistic 52421 * type. 52422 * Parameters: 52423 * unit - (IN) Unit number. 52424 * port - (IN) GPORT ID 52425 * stat - (IN) Type of the counter to retrieve. 52426 * val - (OUT) Pointer to a counter value. 52427 * Returns: 52428 * BCM_E_XXX 52429 * Notes: 52430 */ 52431 int 52432 bcm_esw_port_stat_get32(int unit, bcm_gport_t port, 52433 bcm_port_stat_t stat, uint32 *val) 52434 { 52435 int rv = BCM_E_UNAVAIL; 52436 52437 rv = _bcm_esw_port_stat_get32(unit, 0, port, stat, val); 52438 52439 return rv; 52440 52441 } 52442 52443 52444 /* 52445 * Function: 52446 * bcm_esw_port_stat_sync_get32 52447 * Purpose: 52448 * Get lower 32-bit counter value for specified port statistic 52449 * type. sw accumulated counters synced with hw count. 52450 * Parameters: 52451 * unit - (IN) Unit number. 52452 * port - (IN) GPORT ID 52453 * stat - (IN) Type of the counter to retrieve. 52454 * val - (OUT) Pointer to a counter value. 52455 * Returns: 52456 * BCM_E_XXX 52457 * Notes: 52458 */ 52459 int 52460 bcm_esw_port_stat_sync_get32(int unit, bcm_gport_t port, 52461 bcm_port_stat_t stat, uint32 *val) 52462 { 52463 int rv = BCM_E_UNAVAIL; 52464 52465 rv = _bcm_esw_port_stat_get32(unit, 1, port, stat, val); 52466 52467 return rv; 52468 } 52469 52470 /* 52471 * Function: 52472 * bcm_esw_port_stat_set 52473 * Purpose: 52474 * Set 64-bit counter value for specified port statistic type. 52475 * Parameters: 52476 * unit - (IN) Unit number. 52477 * port - (IN) GPORT ID 52478 * stat - (IN) Type of the counter to retrieve. 52479 * val - (IN) New counter value. 52480 * Returns: 52481 * BCM_E_XXX 52482 * Notes: 52483 */ 52484 int 52485 bcm_esw_port_stat_set(int unit, bcm_gport_t port, bcm_port_stat_t stat, 52486 uint64 val) 52487 { 52488 #if defined(BCM_TRIUMPH2_SUPPORT) 52489 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52490 uint32 counter_indexes=0; 52491 bcm_stat_value_t counter_values={0}; 52492 #endif 52493 52494 /* Make sure port module is initialized. */ 52495 PORT_INIT(unit); 52496 52497 #if defined(BCM_PREEMPTION_SUPPORT) 52498 if (soc_feature(unit, soc_feature_preemption_cnt)) { 52499 bcm_port_t local_port; 52500 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 52501 return bcmi_esw_preemption_counter_set(unit, local_port, 52502 stat, val); 52503 } 52504 #endif /* BCM_PREEMPTION_SUPPORT */ 52505 52506 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 52507 BCM_IF_ERROR_RETURN 52508 (_bcm_esw_port_stat_param_valid(unit, port)); 52509 return _bcm_esw_flex_stat_set(unit, _bcmFlexStatTypeGport, port, 52510 _bcm_esw_port_stat_to_flex_stat(stat), val); 52511 } 52512 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52513 if ((stat == bcmPortStatIngressPackets) || 52514 (stat == bcmPortStatEgressPackets)) { 52515 counter_values.packets = COMPILER_64_LO(val); 52516 } else { 52517 COMPILER_64_SET(counter_values.bytes, 52518 COMPILER_64_HI(val), 52519 COMPILER_64_LO(val)); 52520 } 52521 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set( 52522 unit,port,stat, 1, &counter_indexes, &counter_values)); 52523 return BCM_E_NONE; 52524 #else 52525 return BCM_E_UNAVAIL; 52526 #endif 52527 #else 52528 return BCM_E_UNAVAIL; 52529 #endif 52530 } 52531 52532 /* 52533 * Function: 52534 * bcm_esw_port_stat_set32 52535 * Purpose: 52536 * Set lower 32-bit counter value for specified port statistic 52537 * type. 52538 * Parameters: 52539 * unit - (IN) Unit number. 52540 * port - (IN) GPORT ID 52541 * stat - (IN) Type of the counter to retrieve. 52542 * val - (IN) New counter value. 52543 * Returns: 52544 * BCM_E_XXX 52545 * Notes: 52546 */ 52547 int 52548 bcm_esw_port_stat_set32(int unit, bcm_gport_t port, 52549 bcm_port_stat_t stat, uint32 val) 52550 { 52551 #if defined(BCM_TRIUMPH2_SUPPORT) 52552 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52553 uint32 counter_indexes=0; 52554 bcm_stat_value_t counter_values={0}; 52555 #endif 52556 52557 /* Make sure port module is initialized. */ 52558 PORT_INIT(unit); 52559 52560 #if defined(BCM_PREEMPTION_SUPPORT) 52561 if (soc_feature(unit, soc_feature_preemption_cnt)) { 52562 bcm_port_t local_port; 52563 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 52564 return bcmi_esw_preemption_counter_set32(unit, local_port, 52565 stat, val); 52566 } 52567 #endif /* BCM_PREEMPTION_SUPPORT */ 52568 52569 52570 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 52571 BCM_IF_ERROR_RETURN 52572 (_bcm_esw_port_stat_param_valid(unit, port)); 52573 return _bcm_esw_flex_stat_set32(unit, _bcmFlexStatTypeGport, port, 52574 _bcm_esw_port_stat_to_flex_stat(stat), val); 52575 } 52576 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52577 if ((stat == bcmPortStatIngressPackets) || 52578 (stat == bcmPortStatEgressPackets)) { 52579 counter_values.packets = val; 52580 } else { 52581 /* Ignoring high value */ 52582 COMPILER_64_SET(counter_values.bytes,0,val); 52583 } 52584 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set( 52585 unit,port,stat, 1, &counter_indexes, &counter_values)); 52586 return BCM_E_NONE; 52587 #else 52588 return BCM_E_UNAVAIL; 52589 #endif 52590 #else 52591 return BCM_E_UNAVAIL; 52592 #endif 52593 } 52594 52595 /* 52596 * Function: 52597 * bcm_esw_port_stat_multi_get 52598 * Purpose: 52599 * Get 64-bit counter value for multiple port statistic types. 52600 * Parameters: 52601 * unit - (IN) Unit number. 52602 * port - (IN) GPORT ID 52603 * nstat - (IN) Number of elements in stat array 52604 * stat_arr - (IN) Collected statistics descriptors array 52605 * value_arr - (OUT) Collected counters values 52606 * Returns: 52607 * BCM_E_XXX 52608 * Notes: 52609 */ 52610 int 52611 bcm_esw_port_stat_multi_get(int unit, bcm_gport_t port, int nstat, 52612 bcm_port_stat_t *stat_arr, 52613 uint64 *value_arr) 52614 { 52615 #if defined(BCM_TRIUMPH2_SUPPORT) 52616 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 52617 int idx; 52618 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52619 uint32 counter_indexes=0; 52620 bcm_stat_value_t counter_values={0}; 52621 #endif 52622 52623 /* Make sure port module is initialized. */ 52624 PORT_INIT(unit); 52625 52626 #if defined(BCM_PREEMPTION_SUPPORT) 52627 if (soc_feature(unit, soc_feature_preemption_cnt)) { 52628 bcm_port_t local_port; 52629 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 52630 return bcmi_esw_preemption_counter_multi_get(unit, 0, local_port, nstat, 52631 stat_arr, value_arr); 52632 } 52633 #endif /* BCM_PREEMPTION_SUPPORT */ 52634 52635 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 52636 BCM_IF_ERROR_RETURN 52637 (_bcm_esw_port_stat_param_valid(unit, port)); 52638 BCM_IF_ERROR_RETURN 52639 (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr)); 52640 BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr); 52641 52642 return _bcm_esw_flex_stat_multi_get(unit, _bcmFlexStatTypeGport, port, 52643 nstat, fs_arr, value_arr); 52644 } 52645 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52646 for (idx=0;idx < nstat ; idx ++) { 52647 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_get( 52648 unit, port, stat_arr[idx], 52649 1, &counter_indexes, &counter_values)); 52650 if ((stat_arr[idx] == bcmPortStatIngressPackets) || 52651 (stat_arr[idx] == bcmPortStatEgressPackets)) { 52652 COMPILER_64_SET(value_arr[idx], 52653 COMPILER_64_HI(counter_values.packets64), 52654 COMPILER_64_LO(counter_values.packets64)); 52655 } else { 52656 COMPILER_64_SET(value_arr[idx], 52657 COMPILER_64_HI(counter_values.bytes), 52658 COMPILER_64_LO(counter_values.bytes)); 52659 } 52660 } 52661 return BCM_E_NONE; 52662 #else 52663 return BCM_E_UNAVAIL; 52664 #endif 52665 #else 52666 return BCM_E_UNAVAIL; 52667 #endif 52668 } 52669 52670 /* 52671 * Function: 52672 * bcm_esw_port_stat_multi_get32 52673 * Purpose: 52674 * Get lower 32-bit counter value for multiple port statistic 52675 * types. 52676 * Parameters: 52677 * unit - (IN) Unit number. 52678 * port - (IN) GPORT ID 52679 * nstat - (IN) Number of elements in stat array 52680 * stat_arr - (IN) Collected statistics descriptors array 52681 * value_arr - (OUT) Collected counters values 52682 * Returns: 52683 * BCM_E_XXX 52684 * Notes: 52685 */ 52686 int 52687 bcm_esw_port_stat_multi_get32(int unit, bcm_gport_t port, int nstat, 52688 bcm_port_stat_t *stat_arr, 52689 uint32 *value_arr) 52690 { 52691 #if defined(BCM_TRIUMPH2_SUPPORT) 52692 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 52693 int idx; 52694 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52695 uint32 counter_indexes=0; 52696 bcm_stat_value_t counter_values={0}; 52697 #endif 52698 52699 /* Make sure port module is initialized. */ 52700 PORT_INIT(unit); 52701 52702 #if defined(BCM_PREEMPTION_SUPPORT) 52703 if (soc_feature(unit, soc_feature_preemption_cnt)) { 52704 bcm_port_t local_port; 52705 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 52706 return bcmi_esw_preemption_counter_multi_get32(unit, 0, local_port, nstat, 52707 stat_arr, value_arr); 52708 } 52709 #endif /* BCM_PREEMPTION_SUPPORT */ 52710 52711 52712 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 52713 BCM_IF_ERROR_RETURN 52714 (_bcm_esw_port_stat_param_valid(unit, port)); 52715 BCM_IF_ERROR_RETURN 52716 (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr)); 52717 BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr); 52718 52719 return _bcm_esw_flex_stat_multi_get32(unit, _bcmFlexStatTypeGport, port, 52720 nstat, fs_arr, value_arr); 52721 } 52722 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52723 for (idx=0;idx < nstat ; idx ++) { 52724 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_get( 52725 unit, port, stat_arr[idx], 52726 1, &counter_indexes, &counter_values)); 52727 if ((stat_arr[idx] == bcmPortStatIngressPackets) || 52728 (stat_arr[idx] == bcmPortStatEgressPackets)) { 52729 value_arr[idx] = counter_values.packets; 52730 } else { 52731 value_arr[idx] = COMPILER_64_LO(counter_values.bytes); 52732 } 52733 } 52734 return BCM_E_NONE; 52735 #else 52736 return BCM_E_UNAVAIL; 52737 #endif 52738 #else 52739 return BCM_E_UNAVAIL; 52740 #endif 52741 } 52742 52743 /* 52744 * Function: 52745 * bcm_esw_port_stat_multi_set 52746 * Purpose: 52747 * Set 64-bit counter value for multiple port statistic types. 52748 * Parameters: 52749 * unit - (IN) Unit number. 52750 * port - (IN) GPORT ID 52751 * nstat - (IN) Number of elements in stat array 52752 * stat_arr - (IN) New statistics descriptors array 52753 * value_arr - (IN) New counters values 52754 * Returns: 52755 * BCM_E_XXX 52756 * Notes: 52757 */ 52758 int 52759 bcm_esw_port_stat_multi_set(int unit, bcm_gport_t port, int nstat, 52760 bcm_port_stat_t *stat_arr, 52761 uint64 *value_arr) 52762 { 52763 #if defined(BCM_TRIUMPH2_SUPPORT) 52764 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 52765 int idx; 52766 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52767 uint32 counter_indexes=0; 52768 bcm_stat_value_t counter_values={0}; 52769 #endif 52770 52771 /* Make sure port module is initialized. */ 52772 PORT_INIT(unit); 52773 52774 #if defined(BCM_PREEMPTION_SUPPORT) 52775 if (soc_feature(unit, soc_feature_preemption_cnt)) { 52776 bcm_port_t local_port; 52777 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 52778 return bcmi_esw_preemption_counter_multi_set(unit, local_port, nstat, 52779 stat_arr, value_arr); 52780 } 52781 #endif /* BCM_PREEMPTION_SUPPORT */ 52782 52783 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 52784 BCM_IF_ERROR_RETURN 52785 (_bcm_esw_port_stat_param_valid(unit, port)); 52786 BCM_IF_ERROR_RETURN 52787 (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr)); 52788 BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr); 52789 52790 return _bcm_esw_flex_stat_multi_set(unit, _bcmFlexStatTypeGport, port, 52791 nstat, fs_arr, value_arr); 52792 } 52793 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52794 for (idx=0;idx < nstat ; idx ++) { 52795 if ((stat_arr[idx] == bcmPortStatIngressPackets) || 52796 (stat_arr[idx] == bcmPortStatEgressPackets)) { 52797 counter_values.packets = COMPILER_64_LO(value_arr[idx]); 52798 } else { 52799 COMPILER_64_SET(counter_values.bytes, 52800 COMPILER_64_HI(value_arr[idx]), 52801 COMPILER_64_LO(value_arr[idx])); 52802 } 52803 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set( 52804 unit, port, stat_arr[idx], 52805 1, &counter_indexes, &counter_values)); 52806 } 52807 return BCM_E_NONE; 52808 #else 52809 return BCM_E_UNAVAIL; 52810 #endif 52811 #else 52812 return BCM_E_UNAVAIL; 52813 #endif 52814 } 52815 52816 /* 52817 * Function: 52818 * bcm_esw_port_stat_multi_set32 52819 * Purpose: 52820 * Set lower 32-bit counter value for multiple port statistic 52821 * types. 52822 * Parameters: 52823 * unit - (IN) Unit number. 52824 * port - (IN) GPORT ID 52825 * nstat - (IN) Number of elements in stat array 52826 * stat_arr - (IN) New statistics descriptors array 52827 * value_arr - (IN) New counters values 52828 * Returns: 52829 * BCM_E_XXX 52830 * Notes: 52831 */ 52832 int 52833 bcm_esw_port_stat_multi_set32(int unit, bcm_gport_t port, int nstat, 52834 bcm_port_stat_t *stat_arr, 52835 uint32 *value_arr) 52836 { 52837 #if defined(BCM_TRIUMPH2_SUPPORT) 52838 _bcm_flex_stat_t fs_arr[_bcmFlexStatNum]; /* Normalize stats */ 52839 int idx; 52840 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52841 uint32 counter_indexes=0; 52842 bcm_stat_value_t counter_values={0}; 52843 #endif 52844 52845 /* Make sure port module is initialized. */ 52846 PORT_INIT(unit); 52847 52848 #if defined(BCM_PREEMPTION_SUPPORT) 52849 if (soc_feature(unit, soc_feature_preemption_cnt)) { 52850 bcm_port_t local_port; 52851 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &local_port)); 52852 return bcmi_esw_preemption_counter_multi_set32(unit, local_port, nstat, 52853 stat_arr, value_arr); 52854 } 52855 #endif /* BCM_PREEMPTION_SUPPORT */ 52856 52857 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 52858 BCM_IF_ERROR_RETURN 52859 (_bcm_esw_port_stat_param_valid(unit, port)); 52860 BCM_IF_ERROR_RETURN 52861 (_bcm_port_stat_array_convert(unit, nstat, stat_arr, fs_arr)); 52862 BCM_PORT_VALUE_ARRAY_VALID(unit, nstat, value_arr); 52863 52864 return _bcm_esw_flex_stat_multi_set32(unit, _bcmFlexStatTypeGport, port, 52865 nstat, fs_arr, value_arr); 52866 } 52867 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 52868 for (idx=0;idx < nstat ; idx ++) { 52869 if ((stat_arr[idx] == bcmPortStatIngressPackets) || 52870 (stat_arr[idx] == bcmPortStatEgressPackets)) { 52871 counter_values.packets = value_arr[idx]; 52872 } else { 52873 COMPILER_64_SET(counter_values.bytes,0,value_arr[idx]); 52874 } 52875 BCM_IF_ERROR_RETURN(bcm_esw_port_stat_counter_set( 52876 unit, port, stat_arr[idx], 52877 1, &counter_indexes, &counter_values)); 52878 } 52879 return BCM_E_NONE; 52880 #else 52881 return BCM_E_UNAVAIL; 52882 #endif 52883 #else 52884 return BCM_E_UNAVAIL; 52885 #endif 52886 } 52887 52888 /* 52889 * Function : _bcm_gport_dest_t_init 52890 * Description : Initialize gport_dest structure 52891 * Parameters : (IN/OUT) gport_dest - Structure to initialize 52892 * Returns : None 52893 */ 52894 52895 void 52896 _bcm_gport_dest_t_init(_bcm_gport_dest_t *gport_dest) 52897 { 52898 sal_memset(gport_dest, 0, sizeof (_bcm_gport_dest_t)); 52899 } 52900 52901 52902 /* 52903 * Function : _bcm_esw_gport_construct 52904 * Description : Internal function to construct a gport from 52905 * given parameters 52906 * Parameters : (IN) unit - BCM device number 52907 * (IN) gport_dest - Structure that contains destination 52908 * to encode into a gport 52909 * (OUT) gport - Global port identifier 52910 * Returns : BCM_E_XXX 52911 * Notes : The modid and port are translated from the 52912 * local modid/port space to application space 52913 */ 52914 int 52915 _bcm_esw_gport_construct(int unit, _bcm_gport_dest_t *gport_dest, bcm_gport_t *gport) 52916 { 52917 52918 bcm_gport_t l_gport = 0; 52919 bcm_module_t mod_out; 52920 bcm_port_t port_out; 52921 52922 if ((NULL == gport_dest) || (NULL == gport) ){ 52923 return BCM_E_PARAM; 52924 } 52925 52926 switch (gport_dest->gport_type) { 52927 case _SHR_GPORT_TYPE_TRUNK: 52928 SOC_GPORT_TRUNK_SET(l_gport, gport_dest->tgid); 52929 break; 52930 case _SHR_GPORT_TYPE_LOCAL_CPU: 52931 l_gport = BCM_GPORT_LOCAL_CPU; 52932 break; 52933 case _SHR_GPORT_TYPE_BLACK_HOLE: 52934 l_gport = BCM_GPORT_BLACK_HOLE; 52935 break; 52936 case _SHR_GPORT_TYPE_LOCAL: 52937 SOC_GPORT_LOCAL_SET(l_gport, gport_dest->port); 52938 break; 52939 case _SHR_GPORT_TYPE_SUBPORT_GROUP: 52940 SOC_GPORT_SUBPORT_GROUP_SET(l_gport, gport_dest->subport_id); 52941 break; 52942 case _SHR_GPORT_TYPE_MPLS_PORT: 52943 BCM_GPORT_MPLS_PORT_ID_SET(l_gport, gport_dest->mpls_id); 52944 break; 52945 case _SHR_GPORT_TYPE_MIM_PORT: 52946 BCM_GPORT_MIM_PORT_ID_SET(l_gport, gport_dest->mim_id); 52947 break; 52948 case _SHR_GPORT_TYPE_WLAN_PORT: 52949 BCM_GPORT_WLAN_PORT_ID_SET(l_gport, gport_dest->wlan_id); 52950 break; 52951 case _SHR_GPORT_TYPE_TRILL_PORT: 52952 BCM_GPORT_TRILL_PORT_ID_SET(l_gport, gport_dest->trill_id); 52953 break; 52954 case _SHR_GPORT_TYPE_NIV_PORT: 52955 BCM_GPORT_NIV_PORT_ID_SET(l_gport, gport_dest->niv_id); 52956 break; 52957 case _SHR_GPORT_TYPE_L2GRE_PORT: 52958 BCM_GPORT_L2GRE_PORT_ID_SET(l_gport, gport_dest->l2gre_id); 52959 break; 52960 case _SHR_GPORT_TYPE_VXLAN_PORT: 52961 BCM_GPORT_VXLAN_PORT_ID_SET(l_gport, gport_dest->vxlan_id); 52962 break; 52963 case _SHR_GPORT_TYPE_FLOW_PORT: 52964 BCM_GPORT_FLOW_PORT_ID_SET(l_gport, gport_dest->flow_id); 52965 break; 52966 case _SHR_GPORT_TYPE_VLAN_PORT: 52967 BCM_GPORT_VLAN_PORT_ID_SET(l_gport, gport_dest->vlan_vp_id); 52968 break; 52969 case _SHR_GPORT_TYPE_EXTENDER_PORT: 52970 BCM_GPORT_EXTENDER_PORT_ID_SET(l_gport, gport_dest->extender_id); 52971 break; 52972 case _SHR_GPORT_TYPE_DEVPORT: 52973 BCM_GPORT_DEVPORT_SET(l_gport, unit, gport_dest->port); 52974 break; 52975 case _SHR_GPORT_TYPE_MODPORT: 52976 BCM_IF_ERROR_RETURN ( 52977 _bcm_gport_modport_hw2api_map(unit, gport_dest->modid, 52978 gport_dest->port, &mod_out, 52979 &port_out)); 52980 SOC_GPORT_MODPORT_SET(l_gport, mod_out, port_out); 52981 break; 52982 default: 52983 return BCM_E_PARAM; 52984 } 52985 52986 *gport = l_gport; 52987 return BCM_E_NONE; 52988 } 52989 52990 /* 52991 * Function : _bcm_esw_gport_resolve 52992 * Description : Internal function to get modid, port, and trunk_id 52993 * from a bcm_gport_t (global port) 52994 * Parameters : (IN) unit - BCM device number 52995 * (IN) gport - Global port identifier 52996 * (OUT) modid - Module ID 52997 * (OUT) port - Port number 52998 * (OUT) trunk_id - Trunk ID 52999 * (OUT) id - HW ID 53000 * Returns : BCM_E_XXX 53001 * Notes : The modid and port are translated from the 53002 * application space to local modid/port space if applicable, 53003 * on units without modid (Fabric) modid will be -1 and port 53004 * will be a local physical port. 53005 */ 53006 int 53007 _bcm_esw_gport_resolve(int unit, bcm_gport_t gport, 53008 bcm_module_t *modid, bcm_port_t *port, 53009 bcm_trunk_t *trunk_id, int *id) 53010 { 53011 int local_id, rv = BCM_E_NONE; 53012 bcm_module_t mod_in, local_modid; 53013 bcm_port_t port_in, local_port; 53014 bcm_trunk_t local_tgid; 53015 #ifdef BCM_KATANA_SUPPORT 53016 int extended_queue_id = 0; 53017 #endif 53018 53019 local_modid = -1; 53020 local_port = -1; 53021 local_id = -1; 53022 local_tgid = BCM_TRUNK_INVALID; 53023 53024 if (BCM_GPORT_IS_TRUNK(gport)) { 53025 local_tgid = SOC_GPORT_TRUNK_GET(gport); 53026 } else if (BCM_GPORT_IS_LOCAL_CPU(gport)) { 53027 rv = bcm_esw_stk_my_modid_get(unit, &local_modid); 53028 if (BCM_FAILURE(rv) && !SOC_IS_XGS_FABRIC(unit)) { 53029 return rv; 53030 } 53031 local_port = CMIC_PORT(unit); 53032 } else if (BCM_GPORT_IS_LOCAL(gport)) { 53033 BCM_IF_ERROR_RETURN 53034 (bcm_esw_stk_my_modid_get(unit, &local_modid)); 53035 local_port = SOC_GPORT_LOCAL_GET(gport); 53036 if (soc_feature(unit, soc_feature_sysport_remap)) { 53037 BCM_XLATE_SYSPORT_P2S(unit, &local_port); 53038 } 53039 if (!SOC_PORT_ADDRESSABLE(unit, local_port)) { 53040 return BCM_E_PORT; 53041 } 53042 } else if (BCM_GPORT_IS_DEVPORT(gport)) { 53043 rv = bcm_esw_stk_my_modid_get(unit, &local_modid); 53044 if (BCM_FAILURE(rv)) { 53045 if (!SOC_IS_XGS_FABRIC(unit)) { 53046 return rv; 53047 } 53048 } 53049 if (unit != SOC_GPORT_DEVPORT_DEVID_GET(gport)) { 53050 return BCM_E_PORT; 53051 } 53052 local_port = SOC_GPORT_DEVPORT_PORT_GET(gport); 53053 53054 if (!SOC_PORT_ADDRESSABLE(unit, local_port)) { 53055 return BCM_E_PORT; 53056 } 53057 } else if (BCM_GPORT_IS_MODPORT(gport)) { 53058 mod_in = SOC_GPORT_MODPORT_MODID_GET(gport); 53059 port_in = SOC_GPORT_MODPORT_PORT_GET(gport); 53060 53061 if (NUM_MODID(unit) > 1) { 53062 #if defined(BCM_TOMAHAWK_SUPPORT) 53063 /* Call asymmetric dual modid unmapping function */ 53064 if (soc_feature(unit, soc_feature_asymmetric_dual_modid)) { 53065 BCM_IF_ERROR_RETURN ( 53066 _bcm_esw_stk_asymmetric_dual_modmap_map(unit, 53067 BCM_STK_MODMAP_GET, &mod_in, &port_in)); 53068 } else 53069 #endif /* BCM_TOMAHAWK_SUPPORT */ 53070 if ((NUM_MODID(unit) > 1) && (port_in > SOC_INFO(unit).modport_max)) { 53071 mod_in = mod_in + 1; 53072 port_in = port_in - (SOC_INFO(unit).modport_max + 1); 53073 } 53074 } 53075 PORT_DUALMODID_VALID(unit, port_in); 53076 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET, 53077 mod_in, port_in, &local_modid, &local_port); 53078 53079 if (!SOC_MODID_ADDRESSABLE(unit, local_modid)) { 53080 return BCM_E_BADID; 53081 } 53082 if (!SOC_PORT_ADDRESSABLE(unit, local_port)) { 53083 return BCM_E_PORT; 53084 } 53085 } else if (BCM_GPORT_IS_PROXY(gport)) { 53086 mod_in = BCM_GPORT_PROXY_MODID_GET(gport); 53087 port_in = BCM_GPORT_PROXY_PORT_GET(gport); 53088 PORT_DUALMODID_VALID(unit, port_in); 53089 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET, 53090 mod_in, port_in, &local_modid, &local_port); 53091 53092 if (!SOC_MODID_ADDRESSABLE(unit, local_modid)) { 53093 return BCM_E_BADID; 53094 } 53095 if (!SOC_PORT_ADDRESSABLE(unit, local_port)) { 53096 return BCM_E_PORT; 53097 } 53098 } 53099 #if defined(BCM_TRIUMPH_SUPPORT) && defined(BCM_MPLS_SUPPORT) && \ 53100 defined(INCLUDE_L3) 53101 else if (BCM_GPORT_IS_MPLS_PORT(gport)) { 53102 if (SOC_IS_TR_VL(unit)) { 53103 rv = _bcm_tr_mpls_port_resolve(unit, gport, &local_modid, 53104 &local_port, &local_tgid, 53105 &local_id); 53106 } 53107 } 53108 #endif 53109 #if ((defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT)) \ 53110 && defined(INCLUDE_L3)) 53111 else if (BCM_GPORT_IS_MIM_PORT(gport)) { 53112 if (soc_feature(unit, soc_feature_mim)) { 53113 rv = _bcm_tr2_mim_port_resolve(unit, gport, &local_modid, 53114 &local_port, &local_tgid, 53115 &local_id); 53116 } 53117 } else if (BCM_GPORT_IS_WLAN_PORT(gport)) { 53118 if (soc_feature(unit, soc_feature_wlan)) { 53119 #if defined(BCM_TRIUMPH3_SUPPORT) 53120 if (SOC_IS_TRIUMPH3(unit)) { 53121 rv = _bcm_tr3_wlan_port_resolve(unit, gport, &local_modid, 53122 &local_port, &local_tgid, 53123 &local_id); 53124 } else 53125 #endif /* BCM_TRIUMPH3_SUPPORT */ 53126 { 53127 rv = _bcm_tr2_wlan_port_resolve(unit, gport, &local_modid, 53128 &local_port, &local_tgid, 53129 &local_id); 53130 } 53131 } 53132 } 53133 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 53134 #if defined (BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 53135 else if (BCM_GPORT_IS_L2GRE_PORT(gport)) { 53136 if (soc_feature(unit, soc_feature_l2gre)) { 53137 rv = _bcm_tr3_l2gre_port_resolve(unit, gport, -1, &local_modid, 53138 &local_port, &local_tgid, 53139 &local_id); 53140 } 53141 } 53142 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 53143 #if defined (BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 53144 else if (BCM_GPORT_IS_VXLAN_PORT(gport)) { 53145 if (soc_feature(unit, soc_feature_vxlan)) { 53146 rv = _bcm_td2_vxlan_port_resolve(unit, gport, -1, &local_modid, 53147 &local_port, &local_tgid, 53148 &local_id); 53149 } 53150 } 53151 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 53152 #if defined (BCM_GREYHOUND2_SUPPORT) && defined(INCLUDE_L3) 53153 else if (BCM_GPORT_IS_VXLAN_PORT(gport)) { 53154 if (soc_feature(unit, soc_feature_vxlan_lite)) { 53155 rv = bcmi_gh2_vxlan_port_resolve(unit, gport, -1, &local_modid, 53156 &local_port, &local_tgid, 53157 &local_id); 53158 } 53159 } 53160 #endif /* BCM_GREYHOUND2_SUPPORT && INCLUDE_L3 */ 53161 #if defined (BCM_TRIDENT3_SUPPORT) && defined(INCLUDE_L3) 53162 else if (BCM_GPORT_IS_FLOW_PORT(gport)) { 53163 if (soc_feature(unit, soc_feature_flex_flow)) { 53164 rv = _bcm_td3_flow_port_resolve(unit, gport, -1, &local_modid, 53165 &local_port, &local_tgid, 53166 &local_id); 53167 } 53168 } 53169 #endif /* BCM_TRIDENT3_SUPPORT && INCLUDE_L3 */ 53170 #if defined (BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 53171 else if (BCM_GPORT_IS_TRILL_PORT(gport)) { 53172 if (soc_feature(unit, soc_feature_trill)) { 53173 rv = _bcm_td_trill_port_resolve(unit, gport, -1, &local_modid, 53174 &local_port, &local_tgid, 53175 &local_id); 53176 } 53177 } 53178 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 53179 #if defined (BCM_TRX_SUPPORT) && defined(INCLUDE_L3) 53180 else if (BCM_GPORT_IS_SUBPORT_GROUP(gport)) { 53181 if (SOC_IS_TRX(unit)) { 53182 53183 #if defined (BCM_HGPROXY_COE_SUPPORT) 53184 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 53185 rv = _bcmi_xgs5_subport_group_resolve(unit, gport, &local_modid, 53186 &local_port, &local_tgid, 53187 &local_id); 53188 } else 53189 #endif /* defined (BCM_HGPROXY_COE_SUPPORT) */ 53190 53191 #if defined (BCM_KATANA2_SUPPORT) 53192 if (SOC_IS_KATANA2(unit)) { 53193 rv = bcm_kt2_subport_group_resolve(unit, gport, &local_modid, 53194 &local_port, &local_tgid, 53195 &local_id); 53196 } else 53197 #endif /* defined (BCM_KATANA2_SUPPORT) */ 53198 if (soc_feature(unit, soc_feature_subport_enhanced)) { 53199 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 53200 rv = _bcm_tr2_subport_group_resolve(unit, gport, &local_modid, 53201 &local_port, &local_tgid, 53202 &local_id); 53203 #endif /* defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) */ 53204 } else if (soc_feature(unit, soc_feature_subport)) { 53205 rv = _bcm_tr_subport_group_resolve(unit, gport, &local_modid, 53206 &local_port, &local_tgid, 53207 &local_id); 53208 } 53209 } 53210 } else if (BCM_GPORT_IS_SUBPORT_PORT(gport)) { 53211 if (SOC_IS_TRX(unit)) { 53212 53213 #if defined (BCM_HGPROXY_COE_SUPPORT) 53214 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 53215 rv = _bcm_xgs5_subport_port_resolve(unit, gport, &local_modid, 53216 &local_port, &local_tgid, 53217 &local_id); 53218 } else 53219 #endif /* defined (BCM_HGPROXY_COE_SUPPORT) */ 53220 53221 #if defined (BCM_KATANA2_SUPPORT) 53222 if (SOC_IS_KATANA2(unit)) { 53223 53224 rv = bcm_kt2_subport_port_resolve(unit, gport, &local_modid, 53225 &local_port, &local_tgid, 53226 &local_id); 53227 } else 53228 #endif /* defined (BCM_KATANA2_SUPPORT) */ 53229 if (soc_feature(unit, soc_feature_subport_enhanced)) { 53230 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 53231 rv = _bcm_tr2_subport_port_resolve(unit, gport, &local_modid, 53232 &local_port, &local_tgid, 53233 &local_id); 53234 #endif /* defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) */ 53235 } else if (soc_feature(unit, soc_feature_subport)) { 53236 rv = _bcm_tr_subport_port_resolve(unit, gport, &local_modid, 53237 &local_port, &local_tgid, 53238 &local_id); 53239 } 53240 } 53241 } 53242 #endif /* BCM_TRX_SUPPORT && INCLUDE_L3 */ 53243 #ifdef BCM_TRIUMPH_SUPPORT 53244 else if (BCM_GPORT_IS_SCHEDULER(gport)) { 53245 #if defined (BCM_TOMAHAWK3_SUPPORT) 53246 if (SOC_IS_TOMAHAWK3(unit)) { 53247 rv = _bcm_th3_cosq_port_resolve(unit, gport, &local_modid, 53248 &local_port, &local_tgid, 53249 &local_id, NULL); 53250 } else 53251 #endif /* BCM_TOMAHAWK3_SUPPORT */ 53252 #if defined (BCM_TOMAHAWK_SUPPORT) 53253 if (SOC_IS_TOMAHAWKX(unit)) { 53254 rv = _bcm_th_cosq_port_resolve(unit, gport, &local_modid, 53255 &local_port, &local_tgid, 53256 &local_id, NULL); 53257 } else 53258 #endif /* BCM_TOMAHAWK_SUPPORT */ 53259 #ifdef BCM_HELIX5_SUPPORT 53260 if (SOC_IS_HELIX5(unit)) { 53261 rv = _bcm_hx5_cosq_port_resolve(unit, gport, &local_modid, 53262 &local_port, &local_tgid, 53263 &local_id, NULL); 53264 } else 53265 #endif /* BCM_HELIX5_SUPPORT */ 53266 #if defined (BCM_MONTEREY_SUPPORT) 53267 if (SOC_IS_MONTEREY(unit)) { 53268 rv = _bcm_mn_cosq_port_resolve(unit, gport, &local_modid, 53269 &local_port, &local_tgid, 53270 &local_id, NULL); 53271 } else 53272 #endif 53273 #ifdef BCM_TRIDENT3_SUPPORT 53274 if (SOC_IS_TRIDENT3X(unit)) { 53275 rv = _bcm_td3_cosq_port_resolve(unit, gport, &local_modid, 53276 &local_port, &local_tgid, 53277 &local_id, NULL); 53278 } else 53279 #endif /* BCM_TRIDENT3_SUPPORT */ 53280 #if defined (BCM_APACHE_SUPPORT) 53281 if (SOC_IS_APACHE(unit)) { 53282 rv = _bcm_ap_cosq_port_resolve(unit, gport, &local_modid, 53283 &local_port, &local_tgid, 53284 &local_id, NULL); 53285 } else 53286 #endif 53287 #if defined (BCM_TRIDENT2_SUPPORT) 53288 if (SOC_IS_TD2_TT2(unit)) { 53289 rv = _bcm_td2_cosq_port_resolve(unit, gport, &local_modid, 53290 &local_port, &local_tgid, 53291 &local_id, NULL); 53292 } else 53293 #endif /* BCM_TRIDENT2_SUPPORT */ 53294 #if defined (BCM_TRIDENT_SUPPORT) 53295 if (SOC_IS_TD_TT(unit)) { 53296 rv = _bcm_td_cosq_port_resolve(unit, gport, &local_modid, 53297 &local_port, &local_tgid, 53298 &local_id); 53299 } else 53300 #endif /* BCM_TRIDENT_SUPPORT */ 53301 #if defined (BCM_TRIUMPH3_SUPPORT) 53302 if (SOC_IS_TRIUMPH3(unit)) { 53303 rv = _bcm_tr3_cosq_port_resolve(unit, gport, &local_modid, 53304 &local_port, &local_tgid, 53305 &local_id, NULL); 53306 } else 53307 #endif /* BCM_TRIUMPH3_SUPPORT */ 53308 #if defined (BCM_TRIUMPH2_SUPPORT) 53309 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 53310 SOC_IS_VALKYRIE2(unit)) { 53311 rv = _bcm_tr2_cosq_port_resolve(unit, gport, &local_modid, 53312 &local_port, &local_tgid, 53313 &local_id); 53314 } else 53315 #endif /* BCM_TRIUMPH2_SUPPORT */ 53316 #if defined (BCM_GREYHOUND2_SUPPORT) 53317 if (SOC_IS_GREYHOUND2(unit)) { 53318 rv = bcmi_gh2_cosq_port_resolve(unit, gport, &local_modid, 53319 &local_port, &local_tgid, 53320 &local_id); 53321 } else 53322 #endif /* BCM_GREYHOUND2_SUPPORT */ 53323 if (SOC_IS_TR_VL(unit)) { 53324 rv = _bcm_tr_cosq_port_resolve(unit, gport, &local_modid, 53325 &local_port, &local_tgid, 53326 &local_id); 53327 } 53328 } 53329 #endif /* BCM_TRIUMPH_SUPPORT */ 53330 #ifdef BCM_KATANA_SUPPORT 53331 else if ((SOC_IS_KATANAX(unit)) && 53332 ((BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport)) || 53333 (BCM_GPORT_IS_UCAST_SUBSCRIBER_QUEUE_GROUP(gport)) || 53334 (BCM_GPORT_IS_MCAST_SUBSCRIBER_QUEUE_GROUP(gport)))) { 53335 if (soc_feature(unit, soc_feature_extended_queueing)) { 53336 #if defined(BCM_KATANA2_SUPPORT) 53337 if (SOC_IS_KATANA2(unit)) { 53338 rv = _bcm_kt2_cosq_port_resolve(unit, gport, &local_modid, 53339 &local_port, &local_tgid, 53340 &local_id, &extended_queue_id); 53341 } else 53342 #endif 53343 if (SOC_IS_KATANA(unit)){ 53344 rv = _bcm_kt_cosq_port_resolve(unit, gport, &local_modid, 53345 &local_port, &local_tgid, 53346 &local_id, &extended_queue_id); 53347 } 53348 local_tgid = extended_queue_id; 53349 } 53350 } 53351 #endif /* BCM_KATANA_SUPPORT */ 53352 53353 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 53354 defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 53355 else if (BCM_GPORT_IS_UCAST_QUEUE_GROUP(gport) || 53356 BCM_GPORT_IS_MCAST_QUEUE_GROUP(gport)) { 53357 #if defined (BCM_TOMAHAWK3_SUPPORT) 53358 if (SOC_IS_TOMAHAWK3(unit)) { 53359 rv = _bcm_th3_cosq_port_resolve(unit, gport, &local_modid, 53360 &local_port, &local_tgid, 53361 &local_id, NULL); 53362 } else 53363 #endif /* BCM_TOMAHAWK3_SUPPORT */ 53364 #if defined (BCM_TOMAHAWK_SUPPORT) 53365 if (SOC_IS_TOMAHAWKX(unit)) { 53366 rv = _bcm_th_cosq_port_resolve(unit, gport, &local_modid, 53367 &local_port, &local_tgid, 53368 &local_id, NULL); 53369 } else 53370 #endif /* BCM_TOMAHAWK_SUPPORT */ 53371 #ifdef BCM_HELIX5_SUPPORT 53372 if (SOC_IS_HELIX5(unit)) { 53373 rv = _bcm_hx5_cosq_port_resolve(unit, gport, &local_modid, 53374 &local_port, &local_tgid, 53375 &local_id, NULL); 53376 } else 53377 #endif /* BCM_HELIX5_SUPPORT */ 53378 #if defined (BCM_MONTEREY_SUPPORT) 53379 if (SOC_IS_MONTEREY(unit)) { 53380 rv = _bcm_mn_cosq_port_resolve(unit, gport, &local_modid, 53381 &local_port, &local_tgid, 53382 &local_id, NULL); 53383 } else 53384 #endif 53385 53386 #ifdef BCM_TRIDENT3_SUPPORT 53387 if (SOC_IS_TRIDENT3X(unit)) { 53388 rv = _bcm_td3_cosq_port_resolve(unit, gport, &local_modid, 53389 &local_port, &local_tgid, 53390 &local_id, NULL); 53391 } else 53392 #endif /* BCM_TRIDENT3_SUPPORT */ 53393 #if defined(BCM_APACHE_SUPPORT) 53394 if (SOC_IS_APACHE(unit)) { 53395 rv = _bcm_ap_cosq_port_resolve(unit, gport, &local_modid, 53396 &local_port, &local_tgid, 53397 &local_id, NULL); 53398 } else 53399 #endif /* BCM_APACHE_SUPPORT */ 53400 #if defined(BCM_TRIDENT2_SUPPORT) 53401 if (SOC_IS_TD2_TT2(unit)) { 53402 rv = _bcm_td2_cosq_port_resolve(unit, gport, &local_modid, 53403 &local_port, &local_tgid, 53404 &local_id, NULL); 53405 } else 53406 #endif /* BCM_TRIDENT2_SUPPORT */ 53407 #if defined(BCM_TRIDENT_SUPPORT) 53408 if (SOC_IS_TD_TT(unit)) { 53409 rv = _bcm_td_cosq_port_resolve(unit, gport, &local_modid, 53410 &local_port, &local_tgid, 53411 &local_id); 53412 } else 53413 #endif /* BCM_TRIDENT_SUPPORT */ 53414 #if defined(BCM_TRIUMPH3_SUPPORT) 53415 if (SOC_IS_TRIUMPH3(unit)) { 53416 rv = _bcm_tr3_cosq_port_resolve(unit, gport, &local_modid, 53417 &local_port, &local_tgid, 53418 &local_id, NULL); 53419 } else 53420 #endif 53421 #if defined (BCM_GREYHOUND2_SUPPORT) 53422 if (SOC_IS_GREYHOUND2(unit)) { 53423 rv = bcmi_gh2_cosq_port_resolve(unit, gport, &local_modid, 53424 &local_port, &local_tgid, 53425 &local_id); 53426 } else 53427 #endif /* BCM_GREYHOUND2_SUPPORT */ 53428 { 53429 return BCM_E_UNAVAIL; 53430 } 53431 } 53432 #endif /* BCM_TRIDENT_SUPPORT || BCM_TRIUMPH3_SUPPORT */ 53433 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 53434 else if (BCM_GPORT_IS_VLAN_PORT(gport)) { 53435 if (soc_feature(unit, soc_feature_vlan_vp)) { 53436 #if defined(BCM_ENDURO_SUPPORT) 53437 if (SOC_IS_ENDURO(unit)) { 53438 rv = _bcm_enduro_vlan_port_resolve(unit, gport, &local_modid, 53439 &local_port, &local_tgid, 53440 &local_id); 53441 } else 53442 #endif /* BCM_ENDURO_SUPPORT */ 53443 { 53444 rv = _bcm_tr2_vlan_port_resolve(unit, gport, &local_modid, 53445 &local_port, &local_tgid, 53446 &local_id); 53447 } 53448 } 53449 } 53450 #endif /* BCM_TRIUMPH2_SUPPORT && INCLUDE_L3 */ 53451 #if defined(BCM_TRIDENT_SUPPORT) && defined(INCLUDE_L3) 53452 else if (BCM_GPORT_IS_NIV_PORT(gport)) { 53453 if (soc_feature(unit, soc_feature_niv)) { 53454 rv = _bcm_trident_niv_port_resolve(unit, gport, &local_modid, 53455 &local_port, &local_tgid, 53456 &local_id); 53457 } 53458 } 53459 #endif /* BCM_TRIDENT_SUPPORT && INCLUDE_L3 */ 53460 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 53461 else if (BCM_GPORT_IS_EXTENDER_PORT(gport)) { 53462 if (soc_feature(unit, soc_feature_port_extension)) { 53463 rv = _bcm_tr3_extender_port_resolve(unit, gport, &local_modid, 53464 &local_port, &local_tgid, 53465 &local_id); 53466 } 53467 } 53468 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 53469 else if (BCM_GPORT_IS_BLACK_HOLE(gport)) { 53470 local_modid = BCM_MODID_INVALID; 53471 local_tgid = BCM_TRUNK_INVALID; 53472 local_port = BCM_GPORT_INVALID; 53473 local_id = -1; 53474 rv = BCM_E_NONE; 53475 } 53476 else { 53477 /* BCM_GPORT_INVALID should return an error */ 53478 return BCM_E_PORT; 53479 } 53480 *modid = local_modid; 53481 *port = local_port; 53482 *trunk_id = local_tgid; 53483 *id = local_id; 53484 return (rv); 53485 } 53486 53487 /* 53488 * Function : _bcm_esw_port_is_local_subport 53489 * Description : Internal function to check whehter a gport or (mod,port) 53490 * is local subport. 53491 * Parameters : (IN) unit - BCM device number 53492 * (IN) gport - Global port identifier 53493 * (IN) modid - Module ID 53494 * (IN) port - Port number 53495 * (OUT) is_local_subport - True/False 53496 * (OUT) phy_port - physical port of subport 53497 * Returns : BCM_E_XXX 53498 * Note: all gport, modid, port parameters are required. 53499 */ 53500 int 53501 _bcm_esw_port_is_local_subport(int unit, bcm_gport_t gport, 53502 bcm_module_t modid, bcm_port_t port, 53503 int *is_local_subport, bcm_port_t *phy_port) 53504 { 53505 #if defined(BCM_KATANA2_SUPPORT) 53506 int pp_port; 53507 int min_subport = SOC_INFO(unit).pp_port_index_min; 53508 int max_subport = SOC_INFO(unit).pp_port_index_max; 53509 #endif 53510 53511 if ((is_local_subport == NULL) || (phy_port == NULL)) { 53512 return BCM_E_PARAM; 53513 } 53514 53515 *is_local_subport = FALSE; 53516 53517 #if defined(BCM_HGPROXY_COE_SUPPORT) 53518 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 53519 BCM_GPORT_IS_SET(gport) && 53520 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) { 53521 53522 if(_bcm_xgs5_subport_coe_gport_local(unit, gport)) { 53523 *is_local_subport = TRUE; 53524 } 53525 53526 if (*is_local_subport == FALSE) { 53527 return BCM_E_PORT; 53528 } 53529 53530 BCM_IF_ERROR_RETURN( 53531 _bcmi_coe_subport_physical_port_get(unit, gport, phy_port)); 53532 } else if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 53533 _bcm_xgs5_subport_coe_mod_port_local(unit, modid, port)) { 53534 *is_local_subport = TRUE; 53535 BCM_IF_ERROR_RETURN( 53536 _bcmi_coe_subport_mod_port_physical_port_get( 53537 unit, modid, port, phy_port)); 53538 } else 53539 #endif 53540 53541 #if defined(BCM_KATANA2_SUPPORT) 53542 if (soc_feature(unit, soc_feature_linkphy_coe) || 53543 soc_feature(unit, soc_feature_subtag_coe)) { 53544 if (BCM_GPORT_IS_SET(gport) && 53545 _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, gport)) { 53546 pp_port = BCM_GPORT_SUBPORT_PORT_GET(gport); 53547 if ((_bcm_kt2_mod_is_coe_mod_check(unit, modid) == BCM_E_NONE) || 53548 (soc_feature(unit, soc_feature_general_cascade) && 53549 SOC_PBMP_MEMBER(SOC_INFO(unit).general_pp_port_pbm, pp_port))) { 53550 #if defined BCM_METROLITE_SUPPORT 53551 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 53552 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 53553 *is_local_subport = TRUE; 53554 *phy_port = pp_port; 53555 } 53556 } else 53557 #endif 53558 { 53559 if ((pp_port >= min_subport) && 53560 (pp_port <= max_subport)) { 53561 *is_local_subport = TRUE; 53562 *phy_port = pp_port; 53563 } 53564 } 53565 } 53566 if (*is_local_subport == FALSE) { 53567 return BCM_E_PORT; 53568 } 53569 } 53570 } else 53571 #endif 53572 { 53573 return BCM_E_NONE; 53574 } 53575 53576 return BCM_E_NONE; 53577 } 53578 53579 /* 53580 * Function: 53581 * _bcm_esw_port_gport_get_from_modport 53582 * Purpose: 53583 * Get a gport for all port. 53584 * For non-COE port, it returns modport gport. 53585 * For COE subport, it returns Coe subport gport. 53586 * Parameters: 53587 * unit - (IN) Unit number. 53588 * modid - (IN) Module id. 53589 * port - (IN) Port id. 53590 * Returns: 53591 * gport 53592 * Notes: 53593 */ 53594 bcm_gport_t 53595 _bcm_esw_port_gport_get_from_modport(int unit, bcm_module_t modid, bcm_port_t port) 53596 { 53597 bcm_gport_t gport; 53598 53599 #if defined(BCM_HGPROXY_COE_SUPPORT) 53600 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 53601 _bcm_xgs5_subport_coe_mod_port_local(unit, modid, port)) { 53602 _BCM_SUBPORT_COE_PORT_ID_SET(gport, modid, port); 53603 _BCM_SUBPORT_COE_PORT_TYPE_SET(gport,_BCM_SUBPORT_COE_TYPE_SUBTAG); 53604 } else 53605 #endif 53606 { 53607 BCM_GPORT_MODPORT_SET(gport, modid, port); 53608 } 53609 53610 return gport; 53611 } 53612 53613 /* Check if a given port is a valid controlling port for the Flex-port 53614 feature. 53615 */ 53616 53617 unsigned 53618 _bcm_esw_valid_flex_port_controlling_port(int unit, bcm_port_t port) 53619 { 53620 uint16 dev_id; 53621 uint8 rev_id; 53622 53623 if (!SOC_PORT_VALID(unit, port)) return (FALSE); 53624 53625 soc_cm_get_id(unit, &dev_id, &rev_id); 53626 53627 if (dev_id == BCM56636_DEVICE_ID) { 53628 /* Device is a BCM56636 */ 53629 53630 /* Only valid controlling ports are 42 and 50 53631 (ports 30, 34 and 38 come up in gigE, and 53632 therefore are not valid Flex-port controlling ports). 53633 */ 53634 53635 if (port != 42 && port != 50) return (FALSE); 53636 } else 53637 #if defined(BCM_METROLITE_SUPPORT) 53638 if (SOC_IS_METROLITE(unit)) { 53639 if ((port != 1) && (port != 5) && (port != 9)) { 53640 return (FALSE); 53641 } 53642 } else 53643 #endif 53644 #if defined(BCM_SABER2_SUPPORT) 53645 if (SOC_IS_SABER2(unit)) { 53646 if ((port != 1) && (port != 5) && (port != 9) 53647 && (port != 13) && (port != 17) && (port != 21) 53648 && (port != 25)) { 53649 return (FALSE); 53650 } 53651 } else 53652 #endif 53653 #if defined(BCM_KATANA2_SUPPORT) 53654 if (SOC_IS_KATANA2(unit)) { 53655 if ((port != 1) && (port != 5) && (port != 9) 53656 && (port != 13) && (port != 17) && (port != 21) 53657 && (port != 25) && (port != 26) && (port != 27) 53658 && (port != 28)) { 53659 return (FALSE); 53660 } 53661 } else 53662 #endif 53663 { 53664 if ((port != 30) && (port != 34) && (port != 38) 53665 && (port != 42) && (port != 46) && (port != 50)) { 53666 return (FALSE); 53667 } 53668 } 53669 return (TRUE); 53670 } 53671 53672 53673 /* 53674 * Function: 53675 * bcm_port_subsidiary_ports_get 53676 * Purpose: 53677 * Given a controlling port, this API returns the set of ancillary ports 53678 * belonging to the group (port block) that can be configured to operate 53679 * either as a single high-speed port or multiple GE ports. If the input 53680 * port is not a controlling port, BCM_E_PORT error will be returned. 53681 * Parameters: 53682 * unit - (IN) Unit number. 53683 * port - (IN) Port 53684 * pbmp - (OUT) Ports associated with the hot-swap group 53685 * Returns: 53686 * BCM_E_XXX 53687 * Notes: 53688 */ 53689 int 53690 bcm_esw_port_subsidiary_ports_get(int unit, bcm_port_t port, bcm_pbmp_t *pbmp) 53691 { 53692 int rv = BCM_E_UNAVAIL; 53693 53694 /* Make sure port module is initialized. */ 53695 PORT_INIT(unit); 53696 53697 if (!soc_feature(unit, soc_feature_flex_port)) { 53698 return BCM_E_UNAVAIL; 53699 } 53700 53701 #if defined(BCM_TRIDENT3_SUPPORT) 53702 if (SOC_IS_TRIDENT3X(unit)) { 53703 return (soc_td3_subsidiary_ports_get(unit, port, pbmp)); 53704 } 53705 #endif 53706 #if defined(BCM_TOMAHAWK_SUPPORT) 53707 if (SOC_IS_TOMAHAWKX(unit)) { 53708 return (soc_th_subsidiary_ports_get(unit, port, pbmp)); 53709 } 53710 #endif 53711 #if defined(BCM_MONTEREY_SUPPORT) 53712 if (SOC_IS_MONTEREY(unit)) { 53713 return (soc_monterey_subsidiary_ports_get(unit, port, pbmp)); 53714 } 53715 #endif 53716 #if defined(BCM_APACHE_SUPPORT) 53717 if (SOC_IS_APACHE(unit)) { 53718 return (soc_apache_subsidiary_ports_get(unit, port, pbmp)); 53719 } 53720 #endif 53721 #ifdef BCM_TRIDENT2PLUS_SUPPORT 53722 if (SOC_IS_TRIDENT2PLUS(unit)) { 53723 return(soc_td2p_subsidiary_ports_get(unit, port, pbmp)); 53724 } 53725 #endif 53726 53727 #if defined(BCM_TRIDENT2_SUPPORT) 53728 if (SOC_IS_TD2_TT2(unit)) { 53729 soc_info_t *si = &SOC_INFO(unit); 53730 int i, port_num_lanes_max; 53731 int phy_port, phy_port_base, port_base, lp; 53732 bcm_pbmp_t pbm; 53733 53734 if (!SOC_PORT_VALID(unit, port)) { 53735 return BCM_E_PORT; 53736 } 53737 /* coverity[overrun-local : FALSE] */ 53738 phy_port = si->port_l2p_mapping[port]; 53739 if (phy_port == -1) { 53740 return BCM_E_PORT; 53741 } 53742 53743 phy_port_base = (phy_port & ~0x3) + 1; 53744 if (phy_port != phy_port_base) { 53745 return BCM_E_PORT; 53746 } 53747 53748 port_base = si->port_p2l_mapping[phy_port_base]; 53749 53750 if (si->port_speed_max[port_base] > 20000) { 53751 port_num_lanes_max = 4; 53752 } else if (si->port_speed_max[port_base] > 10000) { 53753 port_num_lanes_max = 2; 53754 } else { 53755 port_num_lanes_max = 1; 53756 } 53757 53758 BCM_PBMP_CLEAR(pbm); 53759 /* Get the subsidiary ports bitmap */ 53760 for (i = 1; i < port_num_lanes_max; i++) { 53761 lp = si->port_p2l_mapping[phy_port_base + i]; 53762 if (lp != -1 53763 && BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), lp)) { 53764 BCM_PBMP_PORT_ADD(pbm, lp); 53765 } 53766 } 53767 53768 if (BCM_PBMP_IS_NULL(pbm)) { /* No Subsidiary ports */ 53769 return BCM_E_PORT; 53770 } 53771 53772 /* Add base port to subsidiary ports bitmap */ 53773 BCM_PBMP_PORT_ADD(pbm, port_base); 53774 BCM_PBMP_ASSIGN(*pbmp, pbm); 53775 53776 rv = BCM_E_NONE; 53777 } 53778 #endif /* BCM_TRIDENT2_SUPPORT */ 53779 53780 #if defined(BCM_TRIUMPH3_SUPPORT) 53781 if (SOC_IS_TRIUMPH3(unit)) { 53782 soc_info_t *si = &SOC_INFO(unit); 53783 int i, phy_port, phy_port_base, lp; 53784 bcm_pbmp_t pbm; 53785 53786 BCM_PBMP_CLEAR(pbm); 53787 53788 if ( !(IS_XW_PORT(unit,port) || IS_CL_PORT(unit, port) || IS_XT_PORT(unit,port)) || 53789 !_bcm_tr3_port_is_control_port(unit, port) || !soc_tr3_port_is_flex_port(unit, port)) { 53790 return BCM_E_PORT; 53791 } 53792 /* coverity[overrun-local : FALSE] */ 53793 phy_port = si->port_l2p_mapping[port]; 53794 if (phy_port == -1) { 53795 return BCM_E_PORT; 53796 } 53797 phy_port_base = (phy_port & ~0x3) + 1; 53798 if (phy_port != phy_port_base) { 53799 return BCM_E_PORT; 53800 } 53801 BCM_PBMP_CLEAR(pbm); 53802 for (i = 0; i < _SOC_TR3_LANES_PER_PHY; i++) { 53803 /* coverity[overrun-local : FALSE] */ 53804 lp = si->port_p2l_mapping[phy_port_base + i]; 53805 if (lp != -1 && 53806 (si->port_speed_max[lp] != 0) && 53807 BCM_PBMP_MEMBER(PBMP_PORT_ALL(unit), lp)) { 53808 BCM_PBMP_PORT_ADD(pbm, lp); 53809 } 53810 } 53811 53812 53813 BCM_PBMP_ASSIGN(*pbmp, pbm); 53814 return BCM_E_NONE; 53815 } 53816 #endif /* BCM_TRIUMPH3_SUPPORT */ 53817 53818 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 53819 if (!SOC_IS_ENDURO(unit) && !SOC_IS_HURRICANEX(unit) && 53820 !SOC_IS_TD_TT(unit)) { 53821 int i; 53822 53823 if (!_bcm_esw_valid_flex_port_controlling_port(unit, port)) { 53824 return (BCM_E_PORT); 53825 } 53826 53827 BCM_PBMP_CLEAR(*pbmp); 53828 if ((SOC_IS_KATANA2(unit)) && (!SOC_IS_SABER2(unit))) { 53829 if (port == 25) { 53830 BCM_PBMP_PORT_ADD(*pbmp, 25); 53831 for (i = 0; i < 3; i++) { 53832 if(SOC_PORT_VALID(unit, 35 + i)) { 53833 BCM_PBMP_PORT_ADD(*pbmp, 35 + i); 53834 } 53835 } 53836 return (BCM_E_NONE); 53837 } else if (port == 26) { 53838 BCM_PBMP_PORT_ADD(*pbmp, 26); 53839 for (i = 0; i < 3; i++) { 53840 if(SOC_PORT_VALID(unit, 38 + i)) { 53841 BCM_PBMP_PORT_ADD(*pbmp, 38 + i); 53842 } 53843 } 53844 return (BCM_E_NONE); 53845 } else if (port == 27) { 53846 BCM_PBMP_PORT_ADD(*pbmp, 27); 53847 for (i = 0; i < 3; i++) { 53848 if(SOC_PORT_VALID(unit, 32 + i)) { 53849 BCM_PBMP_PORT_ADD(*pbmp, 32 + i); 53850 } 53851 } 53852 return (BCM_E_NONE); 53853 } 53854 } 53855 53856 for (i = 0; i < 4; i++) { 53857 /* coverity[overrun-local : FALSE] */ 53858 if (SOC_PORT_VALID(unit, port + i)) { 53859 BCM_PBMP_PORT_ADD(*pbmp, port + i); 53860 } 53861 } 53862 rv = BCM_E_NONE; 53863 } 53864 #endif 53865 53866 return rv; 53867 } 53868 53869 /* 53870 * Function: 53871 * _bcm_esw_port_e2ecc_hg_pbm_convert 53872 * Purpose: 53873 * Convert Higig port to E2ECC Higig port bitmap. 53874 * Parameters: 53875 * port - (IN) Higig port number. 53876 * converted_hg_pbm - (OUT) Converted Higig port bitmap. 53877 * Returns: 53878 * BCM_E_xxx 53879 */ 53880 STATIC int 53881 _bcm_esw_port_e2ecc_hg_pbm_convert(bcm_port_t port, uint32 *converted_hg_pbm) 53882 { 53883 int hg_pbm_index; 53884 53885 /* In Triumph2, the mapping between HG_PBM[9:0] and physical port number is: 53886 * 53887 * HG_PBM index: | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 53888 * Physical Port: | 50 | 46 | 42 | 38 | 34 | 30 | 29 | 28 | 27 | 26 | 53889 */ 53890 switch (port) 53891 { 53892 case 26: 53893 case 27: 53894 case 28: 53895 case 29: 53896 case 30: 53897 hg_pbm_index = port - 26; 53898 break; 53899 case 34: 53900 case 38: 53901 case 42: 53902 case 46: 53903 case 50: 53904 hg_pbm_index = 5 + (port - 34) / 4; 53905 break; 53906 default: 53907 LOG_ERROR(BSL_LS_BCM_PORT, 53908 (BSL_META("Error: Port %d is an invalid Higig port"), port)); 53909 return BCM_E_PARAM; 53910 } 53911 53912 *converted_hg_pbm = (1 << hg_pbm_index); 53913 53914 return BCM_E_NONE; 53915 } 53916 53917 STATIC int 53918 _bcm_esw_port_drop_status_enable_set(int unit, bcm_port_t port, int enable) 53919 { 53920 uint32 rval; 53921 int idx; 53922 53923 #if defined(BCM_MONTEREY_SUPPORT) 53924 if (SOC_IS_MONTEREY(unit)) { 53925 return bcm_mn_cosq_drop_status_enable_set(unit, port, enable); 53926 } 53927 #endif /* BCM_TRIDENT2_SUPPORT */ 53928 #if defined(BCM_APACHE_SUPPORT) 53929 if (SOC_IS_APACHE(unit)) { 53930 return bcm_ap_cosq_drop_status_enable_set(unit, port, enable); 53931 } 53932 #endif /* BCM_TRIDENT2_SUPPORT */ 53933 #if defined(BCM_TRIDENT2_SUPPORT) 53934 if (SOC_IS_TD2_TT2(unit)) { 53935 return bcm_td2_cosq_drop_status_enable_set(unit, port, enable); 53936 } 53937 #endif /* BCM_TRIDENT2_SUPPORT */ 53938 53939 #if defined(BCM_TRIDENT_SUPPORT) 53940 if (SOC_IS_TD_TT(unit)) { 53941 return bcm_td_cosq_drop_status_enable_set(unit, port, enable); 53942 } 53943 #endif /* BCM_TRIDENT_SUPPORT */ 53944 53945 #if defined(BCM_TRIUMPH3_SUPPORT) 53946 if (SOC_IS_TRIUMPH3(unit)) { 53947 return bcm_tr3_cosq_drop_status_enable_set(unit, port, enable); 53948 } 53949 #endif /* BCM_TRIUMPH3_SUPPORT */ 53950 53951 #if defined(BCM_KATANA_SUPPORT) 53952 if (SOC_IS_KATANA(unit)) { 53953 return bcm_kt_cosq_drop_status_enable_set(unit, port, enable); 53954 } 53955 #endif /* BCM_KATANA_SUPPORT */ 53956 #if defined(BCM_KATANA2_SUPPORT) 53957 if (SOC_IS_KATANA2(unit)) { 53958 return bcm_kt2_cosq_drop_status_enable_set(unit, port, enable); 53959 } 53960 #endif /* BCM_KATANA2_SUPPORT */ 53961 #if defined(BCM_HURRICANE3_SUPPORT) 53962 if (SOC_IS_HURRICANE3(unit)) { 53963 return bcm_hr3_cosq_drop_status_enable_set(unit, port, enable); 53964 } 53965 #endif /* BCM_HURRICANE3_SUPPORT */ 53966 #if defined(BCM_GREYHOUND2_SUPPORT) 53967 if (SOC_IS_GREYHOUND2(unit)) { 53968 return bcmi_gh2_cosq_drop_status_enable_set(unit, port, enable); 53969 } 53970 #endif /* BCM_GREYHOUND2_SUPPORT */ 53971 53972 for (idx = 0; idx < 8; idx++) { 53973 if (SOC_IS_SC_CQ(unit)) { 53974 SOC_IF_ERROR_RETURN(READ_OP_QUEUE_CONFIGr(unit, port, idx, &rval)); 53975 soc_reg_field_set(unit, OP_QUEUE_CONFIGr, &rval, 53976 Q_E2E_DS_ENABLEf, enable ? 1 : 0); 53977 SOC_IF_ERROR_RETURN(WRITE_OP_QUEUE_CONFIGr(unit, port, idx, rval)); 53978 } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 53979 SOC_IS_VALKYRIE2(unit)) { 53980 SOC_IF_ERROR_RETURN 53981 (READ_OP_QUEUE_CONFIG1_CELLr(unit, port, idx, &rval)); 53982 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_CELLr, &rval, 53983 Q_E2E_DS_EN_CELLf, enable ? 1 : 0); 53984 SOC_IF_ERROR_RETURN 53985 (WRITE_OP_QUEUE_CONFIG1_CELLr(unit, port, idx, rval)); 53986 53987 SOC_IF_ERROR_RETURN 53988 (READ_OP_QUEUE_CONFIG1_PACKETr(unit, port, idx, &rval)); 53989 soc_reg_field_set(unit, OP_QUEUE_CONFIG1_PACKETr, &rval, 53990 Q_E2E_DS_EN_PACKETf, enable ? 1 : 0); 53991 SOC_IF_ERROR_RETURN 53992 (WRITE_OP_QUEUE_CONFIG1_PACKETr(unit, port, idx, rval)); 53993 } 53994 } 53995 53996 SOC_IF_ERROR_RETURN(READ_OP_THR_CONFIGr(unit, &rval)); 53997 soc_reg_field_set(unit, OP_THR_CONFIGr, &rval, EARLY_E2E_SELECTf, 53998 enable ? 1 : 0); 53999 SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, rval)); 54000 54001 return BCM_E_NONE; 54002 } 54003 54004 /* 54005 * Function: 54006 * _bcm_esw_port_e2e_tx_enable_set 54007 * Purpose: 54008 * Set E2E Tx Enable 54009 * Parameters: 54010 * unit - (IN) SOC unit number. 54011 * port - (IN) Port number. 54012 * enable - (IN) Whether to enable or disable 54013 * Returns: 54014 * BCM_E_xxx 54015 */ 54016 STATIC int 54017 _bcm_esw_port_e2e_tx_enable_set(int unit, bcm_port_t port, int enable) 54018 { 54019 uint64 rval64; 54020 54021 if (SOC_USE_PORTCTRL(unit)) { 54022 return bcmi_esw_portctrl_e2e_tx_enable_set(unit, port, enable); 54023 } 54024 54025 if (IS_CL_PORT(unit, port)) { 54026 SOC_IF_ERROR_RETURN(READ_CLMAC_E2E_CTRLr(unit, port, &rval64)); 54027 soc_reg64_field32_set(unit, CLMAC_E2E_CTRLr, &rval64, 54028 E2E_ENABLEf, enable); 54029 SOC_IF_ERROR_RETURN(WRITE_CLMAC_E2E_CTRLr(unit, port, rval64)); 54030 } else { 54031 SOC_IF_ERROR_RETURN(READ_XLMAC_E2E_CTRLr(unit, port, &rval64)); 54032 soc_reg64_field32_set(unit, XLMAC_E2E_CTRLr, &rval64, 54033 E2E_ENABLEf, enable); 54034 SOC_IF_ERROR_RETURN(WRITE_XLMAC_E2E_CTRLr(unit, port, rval64)); 54035 } 54036 return BCM_E_NONE; 54037 } 54038 54039 /* 54040 * Function: 54041 * _bcm_esw_port_e2ecc_tx 54042 * Purpose: 54043 * Configure E2ECC message transmission. 54044 * Parameters: 54045 * unit - (IN) Unit number. 54046 * port - (IN) Local port number. 54047 * config - (IN) Congestion configuration. 54048 * Returns: 54049 * BCM_E_xxx 54050 */ 54051 STATIC int 54052 _bcm_esw_port_e2ecc_tx(int unit, bcm_port_t port, 54053 bcm_port_congestion_config_t *config) 54054 { 54055 uint32 regval; 54056 uint32 hg_pbm, converted_hg_pbm, new_hg_pbm; 54057 int value_a, value_b; 54058 int time_unit_sel, time_units; 54059 int src_modid, src_pid; 54060 soc_higig_e2ecc_hdr_t e2ecc_hdr; 54061 int blk, blk_num = -1, bindex = 0; 54062 if (config->flags & BCM_PORT_CONGESTION_CONFIG_TX) { 54063 /* If BCM_PORT_CONGESTION_CONFIG_TX flag is set, enable E2ECC transmission. */ 54064 54065 /* Set chip-wide E2ECC enable bit */ 54066 if (SOC_IS_SC_CQ(unit)) { 54067 SOC_IF_ERROR_RETURN(READ_E2E_HOL_ENr(unit, ®val)); 54068 if (soc_reg_field_get(unit, E2E_HOL_ENr, regval, ENf) == 0) { 54069 soc_reg_field_set(unit, E2E_HOL_ENr, ®val, ENf, 1); 54070 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_ENr(unit, regval)); 54071 } 54072 } else { 54073 SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_ENr(unit, ®val)); 54074 if (soc_reg_field_get(unit, E2ECC_HOL_ENr, regval, ENf) == 0) { 54075 soc_reg_field_set(unit, E2ECC_HOL_ENr, ®val, ENf, 1); 54076 SOC_IF_ERROR_RETURN(WRITE_E2ECC_HOL_ENr(unit, regval)); 54077 } 54078 } 54079 54080 54081 /* In Trident E2E_HOL_ENf is not present. MMY E2ECC_HOL_EN is used */ 54082 /* (Checked with Architecture) */ 54083 if (soc_reg_field_valid(unit, XPORT_CONFIGr, E2E_HOL_ENf)) { 54084 /* Set per-port E2ECC TX enable bit */ 54085 SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, ®val)); 54086 if (soc_reg_field_get(unit, XPORT_CONFIGr, 54087 regval, E2E_HOL_ENf) == 0) { 54088 soc_reg_field_set(unit, XPORT_CONFIGr, ®val, 54089 E2E_HOL_ENf, 1); 54090 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, regval)); 54091 } 54092 } 54093 54094 if (soc_reg_field_valid(unit, XPORT_MODE_REGr, E2E_HOL_ENf)) { 54095 /* Set per-port E2ECC TX enable bit */ 54096 SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, ®val)); 54097 if (soc_reg_field_get(unit, XPORT_MODE_REGr, 54098 regval, E2E_HOL_ENf) == 0) { 54099 soc_reg_field_set(unit, XPORT_MODE_REGr, ®val, 54100 E2E_HOL_ENf, 1); 54101 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, regval)); 54102 } 54103 } 54104 54105 /* Set per-queue E2ECC enable bits */ 54106 BCM_IF_ERROR_RETURN 54107 (_bcm_esw_port_drop_status_enable_set(unit, port, TRUE)); 54108 54109 /* Set the Higig port bitmap used to transmit E2ECC messages */ 54110 if (SOC_IS_SC_CQ(unit)) { 54111 SOC_IF_ERROR_RETURN(READ_E2E_HOL_PBMr(unit, ®val)); 54112 hg_pbm = soc_reg_field_get(unit, E2E_HOL_PBMr, regval, PORT_BITMAPf); 54113 54114 converted_hg_pbm = 1 << port; 54115 54116 if (!(hg_pbm & converted_hg_pbm)) { 54117 new_hg_pbm = hg_pbm | converted_hg_pbm; 54118 soc_reg_field_set(unit, E2E_HOL_PBMr, ®val, PORT_BITMAPf, new_hg_pbm); 54119 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_PBMr(unit, regval)); 54120 } 54121 } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 54122 SOC_IS_VALKYRIE2(unit)) { 54123 SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_PBMr(unit, ®val)); 54124 hg_pbm = soc_reg_field_get(unit, E2ECC_HOL_PBMr, regval, HG_PBMf); 54125 54126 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hg_pbm_convert(port, &converted_hg_pbm)); 54127 54128 if (!(hg_pbm & converted_hg_pbm)) { 54129 new_hg_pbm = hg_pbm | converted_hg_pbm; 54130 soc_reg_field_set(unit, E2ECC_HOL_PBMr, ®val, HG_PBMf, new_hg_pbm); 54131 SOC_IF_ERROR_RETURN(WRITE_E2ECC_HOL_PBMr(unit, regval)); 54132 } 54133 } else { /* TD_TT, KATANAX, TR3 */ 54134 if (soc_feature(unit, soc_feature_logical_port_num)) { 54135 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[port]); 54136 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[port]); 54137 } else{ 54138 blk = SOC_PORT_BLOCK(unit, port); 54139 bindex = SOC_PORT_BINDEX(unit, port); 54140 } 54141 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 54142 if (SOC_IS_TRIDENT2X(unit)) { 54143 blk_num = SOC_INFO(unit).port_serdes[port]; 54144 } else 54145 #endif 54146 { 54147 blk_num = SOC_BLOCK_INFO(unit, blk).number; 54148 } 54149 /* In TR3 E2ECC is implemented only in blocks CL, XL1 */ 54150 if (!SOC_IS_TRIUMPH3(unit) || (IS_CL_PORT(unit, port) || (blk == 13))) { 54151 if (SOC_IS_TRIUMPH3(unit)) { 54152 if (IS_CL_PORT(unit, port)) { 54153 blk_num = (blk_num ? 4 + bindex/4 : bindex/4); 54154 bindex = bindex%4; 54155 } else { 54156 blk_num = 3; 54157 } 54158 } 54159 #if defined(BCM_KATANA2_SUPPORT) 54160 if (SOC_IS_KATANA2(unit)) { 54161 /* In KT2 E2ECC is implemented only in blocks 6..9 */ 54162 blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ; 54163 } 54164 #endif 54165 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num, 54166 ®val)); 54167 if (!(regval & (1 << bindex))) { 54168 new_hg_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval, 54169 TX_ENABLE_BMPf); 54170 /* new_hg_pbm &= ~(1 << bindex); */ 54171 new_hg_pbm |= (1 << bindex); 54172 soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, ®val, 54173 TX_ENABLE_BMPf, new_hg_pbm); 54174 SOC_IF_ERROR_RETURN 54175 (WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, regval)); 54176 } 54177 } 54178 54179 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 54180 if (SOC_IS_TD2_TT2(unit)) { 54181 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1)); 54182 54183 /* DMVOQ congestion bytes max length is 64 bytes, 54184 As a result 54185 DMVOQ feature can support upto 64 ports*/ 54186 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_PORTS_NUMr(unit, ®val)); 54187 soc_reg_field_set(unit, E2ECC_TX_PORTS_NUMr, ®val, 54188 TX_PORTS_NUMf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ); 54189 SOC_IF_ERROR_RETURN(WRITE_E2ECC_TX_PORTS_NUMr(unit, regval)); 54190 54191 /* By default congestion states of 4 cos values are transmitted 54192 inorder to transmit the congestion state for all the 54193 8 cos values 54194 if num_coq > 8 following configuration is done */ 54195 if (!SOC_IS_TRIUMPH3(unit) && !SOC_IS_MONTEREY(unit) && NUM_COS(unit) >= 8) { 54196 uint64 rval64 ; 54197 uint64 fval64; 54198 COMPILER_64_ZERO(fval64); 54199 COMPILER_64_SET(fval64, 0xffffffff, 0xffffffff); 54200 soc_reg64_field_set(unit, OOBFC_ENG_PORT_QSEL0_64r , 54201 &rval64, 54202 ENG_PORT_QSELf, fval64); 54203 SOC_IF_ERROR_RETURN(WRITE_OOBFC_ENG_PORT_QSEL0_64r(unit, 54204 rval64)); 54205 } 54206 } 54207 #endif 54208 #if defined(BCM_HURRICANE3_SUPPORT) 54209 if (SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 54210 uint32 max_bitmap; 54211 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_PORTS_NUMr(unit, ®val)); 54212 /* max Congestion bitmap number of E2ECC message */ 54213 if (SOC_IS_HURRICANE3(unit)) { 54214 max_bitmap = 36; 54215 } else { /* GREYHOUND2 */ 54216 max_bitmap = 64; 54217 } 54218 soc_reg_field_set(unit, E2ECC_TX_PORTS_NUMr, ®val, 54219 TX_PORTS_NUMf, max_bitmap); 54220 SOC_IF_ERROR_RETURN(WRITE_E2ECC_TX_PORTS_NUMr(unit, regval)); 54221 54222 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1)); 54223 } 54224 #endif 54225 54226 if (SOC_IS_KATANAX(unit)) { 54227 SOC_IF_ERROR_RETURN(READ_OP_THR_CONFIGr(unit, ®val)); 54228 soc_reg_field_set(unit, OP_THR_CONFIGr, ®val, E2ECC_HOL_ENf, 1); 54229 SOC_IF_ERROR_RETURN(WRITE_OP_THR_CONFIGr(unit, regval)); 54230 if (SOC_IS_SABER2(unit)) { 54231 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 1)); 54232 } 54233 } 54234 } 54235 54236 /* Configuring the E2ECC min timer so that during congestion, back-to-back 54237 * E2ECC messages are generated as fast as hardware allows. 54238 */ 54239 if (SOC_IS_SC_CQ(unit)) { 54240 54241 SOC_IF_ERROR_RETURN(READ_E2E_MIN_TX_TIMERr(unit, ®val)); 54242 if (soc_reg_field_get(unit, E2E_MIN_TX_TIMERr, regval, TIMERf) != 0) { 54243 soc_reg_field_set(unit, E2E_MIN_TX_TIMERr, ®val, TIMERf, 0); 54244 soc_reg_field_set(unit, E2E_MIN_TX_TIMERr, ®val, LGf, 0); 54245 SOC_IF_ERROR_RETURN(WRITE_E2E_MIN_TX_TIMERr(unit, regval)); 54246 } 54247 } else { 54248 SOC_IF_ERROR_RETURN(READ_E2ECC_MIN_TX_TIMERr(unit, ®val)); 54249 if (soc_reg_field_get(unit, E2ECC_MIN_TX_TIMERr, regval, TIMERf) != 0) { 54250 soc_reg_field_set(unit, E2ECC_MIN_TX_TIMERr, ®val, TIMERf, 0); 54251 soc_reg_field_set(unit, E2ECC_MIN_TX_TIMERr, ®val, LGf, 0); 54252 SOC_IF_ERROR_RETURN(WRITE_E2ECC_MIN_TX_TIMERr(unit, regval)); 54253 } 54254 } 54255 54256 /* In the absence of congestion, an E2ECC message is still generated to refresh 54257 * congestion status when the E2ECC max timer expires. This timer is specified 54258 * in units of 250ns or 25us, and up to 1023 time units can be specified. 54259 * The selection of time unit and the number of time units is computed as follows: 54260 * 54261 * Let E2ECC message refresh rate = N messages/sec, and N != 0, 54262 * then A = # of 250ns time units = 1 sec / N / 250ns = 4000000 / N, 54263 * and B = # of 25us time units = 1 sec / N / 25us = 40000 / N = A / 100. 54264 * 54265 * If A < 1, configure the minimum allowed timer value: time unit = 250ns, 54266 * # of time units = 1. 54267 * 54268 * If A is between 1 and 1023, configure the timer as: time unit = 250ns, 54269 * # of time units = A. 54270 * 54271 * If A > 1023 and B <= 1023, configure the timer as: time unit = 25us, 54272 * # of time units = B. 54273 * 54274 * If B > 1023, configure the maximum allowed timer value: time unit = 25us, 54275 * # of time units = 1023. 54276 * 54277 * Note: If N = 0, # of time units will be set to 0, and E2ECC message refresh 54278 * is effectively disabled. E2ECC message will be generated only when 54279 * there is a change in congestion status. 54280 */ 54281 54282 if (config->packets_per_sec == 0) { 54283 time_unit_sel = 0; 54284 time_units = 0; 54285 } else { 54286 value_a = 4000000 / config->packets_per_sec; 54287 value_b = value_a / 100; 54288 if (value_a < 1) { 54289 time_unit_sel = 0; 54290 time_units = 1; 54291 } else if (value_a <= 1023) { 54292 time_unit_sel = 0; 54293 time_units = value_a; 54294 } else if ((value_a > 1023) && (value_b <= 1023)) { 54295 time_unit_sel = 1; 54296 time_units = value_b; 54297 } else { /* value_b > 1023 */ 54298 time_unit_sel = 1; 54299 time_units = 1023; 54300 } 54301 } 54302 54303 if (SOC_IS_SC_CQ(unit)) { 54304 SOC_IF_ERROR_RETURN(READ_E2E_MAX_TX_TIMERr(unit, ®val)); 54305 soc_reg_field_set(unit, E2E_MAX_TX_TIMERr, ®val, LGf, 54306 time_unit_sel); 54307 soc_reg_field_set(unit, E2E_MAX_TX_TIMERr, ®val, TIMERf, 54308 time_units); 54309 SOC_IF_ERROR_RETURN(WRITE_E2E_MAX_TX_TIMERr(unit, regval)); 54310 } else { 54311 SOC_IF_ERROR_RETURN(READ_E2ECC_MAX_TX_TIMERr(unit, ®val)); 54312 soc_reg_field_set(unit, E2ECC_MAX_TX_TIMERr, ®val, LGf, 54313 time_unit_sel); 54314 soc_reg_field_set(unit, E2ECC_MAX_TX_TIMERr, ®val, TIMERf, 54315 time_units); 54316 SOC_IF_ERROR_RETURN(WRITE_E2ECC_MAX_TX_TIMERr(unit, regval)); 54317 } 54318 54319 /* Configure per-port E2ECC message header */ 54320 54321 if (BCM_GPORT_IS_MODPORT(config->src_port)) { 54322 src_modid = BCM_GPORT_MODPORT_MODID_GET(config->src_port); 54323 src_pid = BCM_GPORT_MODPORT_PORT_GET(config->src_port); 54324 } else { 54325 LOG_ERROR(BSL_LS_BCM_PORT, 54326 (BSL_META_U(unit, 54327 "Error: src_port %d is not of type modid:port.\n"), config->src_port)); 54328 return BCM_E_PARAM; 54329 } 54330 54331 sal_memset(&e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t)); 54332 54333 e2ecc_hdr.overlay1.words[0] = 54334 (SOC_HIGIG_START << 24) | /* K.SOP[7:0] */ 54335 (((1 << 4) | (config->traffic_class & 0x0F)) << 16) | /* MC and TC[3:0] */ 54336 (config->multicast_id & 0xFFFF); /* MGID[15:0] */ 54337 54338 e2ecc_hdr.overlay1.words[1] = 54339 ((src_modid & 0xFF) << 24) | /* SRC_MODID[7:0] */ 54340 ((src_pid & 0xFF) << 16) | /* SRC_PID[7:0] */ 54341 ((config->color & 0x03) << 6); /* DP[1:0] */ 54342 54343 /* e2ecc_hdr.overlay1.words[2] is all zeroes. */ 54344 54345 if (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL) { 54346 /* In case of DMVOQ, we are sending opcode as Multicast 54347 so that packet is accepted at different modules */ 54348 e2ecc_hdr.overlay1.words[3] = 54349 ((config->pri & 0x07) << 29) | /* VID_HIGH[7:5] */ 54350 ((config->cfi & 0x01) << 28) | /* VID_HIGH[4] */ 54351 ((config->vlan & 0xfff) << 16) | /* VID_HIGH[3:0], VID_LOW[7:0] */ 54352 ((SOC_HIGIG_OP_MC & 0x07) << 8); /* OPCODE[2:0] */ 54353 } else { 54354 e2ecc_hdr.overlay1.words[3] = 54355 ((config->pri & 0x07) << 29) | /* VID_HIGH[7:5] */ 54356 ((config->cfi & 0x01) << 28) | /* VID_HIGH[4] */ 54357 ((config->vlan & 0xfff) << 16) | /* VID_HIGH[3:0], VID_LOW[7:0] */ 54358 ((SOC_HIGIG_OP_BC & 0x07) << 8); /* OPCODE[2:0] */ 54359 } 54360 54361 e2ecc_hdr.overlay1.words[4] = 54362 (config->dest_mac[0] << 24) | /* MAC-DA[47:40] */ 54363 (config->dest_mac[1] << 16) | /* MAC-DA[39:32] */ 54364 (config->dest_mac[2] << 8) | /* MAC-DA[31:24] */ 54365 (config->dest_mac[3]); /* MAC-DA[23:16] */ 54366 54367 e2ecc_hdr.overlay1.words[5] = 54368 (config->dest_mac[4] << 24) | /* MAC-DA[15:8] */ 54369 (config->dest_mac[5] << 16) | /* MAC-DA[7:0] */ 54370 (config->src_mac[0] << 8) | /* MAC-SA[47:40] */ 54371 (config->src_mac[1]); /* MAC-SA[39:32] */ 54372 54373 e2ecc_hdr.overlay1.words[6] = 54374 (config->src_mac[2] << 24) | /* MAC-SA[31:24] */ 54375 (config->src_mac[3] << 16) | /* MAC-SA[23:16] */ 54376 (config->src_mac[4] << 8) | /* MAC-SA[15:8] */ 54377 (config->src_mac[5]); /* MAC-SA[7:0] */ 54378 54379 e2ecc_hdr.overlay1.words[7] = 54380 ((config->ethertype & 0xFFFF) << 16) | /* Ethertype[15:0] */ 54381 (config->opcode & 0xFFFF); /* Opcode[7:0] */ 54382 54383 BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hdr_set(unit, port, &e2ecc_hdr)); 54384 54385 /* Enable QE interop mode */ 54386 if (SOC_IS_SC_CQ(unit)) { 54387 SOC_IF_ERROR_RETURN(READ_GLOBAL_SHARED_FILL_STATE_CONFIGr(unit, ®val)); 54388 if (soc_reg_field_get(unit, GLOBAL_SHARED_FILL_STATE_CONFIGr, regval, 54389 GLOBAL_SHARED_FILL_STATE_ENf) == 0) { 54390 soc_reg_field_set(unit, GLOBAL_SHARED_FILL_STATE_CONFIGr, ®val, 54391 GLOBAL_SHARED_FILL_STATE_ENf, 1); 54392 SOC_IF_ERROR_RETURN(WRITE_GLOBAL_SHARED_FILL_STATE_CONFIGr(unit, regval)); 54393 } 54394 } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit)) { 54395 SOC_IF_ERROR_RETURN(READ_QE_INTEROP_CONFIGr(unit, ®val)); 54396 if (soc_reg_field_get(unit, QE_INTEROP_CONFIGr, regval, QE_INTEROP_ENf) == 0) { 54397 soc_reg_field_set(unit, QE_INTEROP_CONFIGr, ®val, QE_INTEROP_ENf, 1); 54398 SOC_IF_ERROR_RETURN(WRITE_QE_INTEROP_CONFIGr(unit, regval)); 54399 } 54400 } else if (SOC_IS_TD2_TT2(unit)) { 54401 SOC_IF_ERROR_RETURN 54402 (soc_reg_field32_modify(unit, 54403 INTFO_E2ECC_POOL_STATE_REPORT_ENABLEr, 54404 REG_PORT_ANY, ENf, 1)); 54405 } else if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit)) { 54406 SOC_IF_ERROR_RETURN(READ_THDO_INTEROP_CONFIGr(unit, ®val)); 54407 if (soc_reg_field_get(unit, THDO_INTEROP_CONFIGr, regval, 54408 GLOBAL_CNG_STATE_REPORT_ENABLEf) == 0) { 54409 soc_reg_field_set(unit, THDO_INTEROP_CONFIGr, ®val, 54410 GLOBAL_CNG_STATE_REPORT_ENABLEf, 1); 54411 SOC_IF_ERROR_RETURN(WRITE_THDO_INTEROP_CONFIGr(unit, regval)); 54412 } 54413 } 54414 54415 } else { 54416 /* If BCM_PORT_CONGESTION_CONFIG_TX flag is not set, disable E2ECC transmission. */ 54417 54418 if (soc_reg_field_valid(unit, XPORT_CONFIGr, E2E_HOL_ENf)) { 54419 /* Clear per-port E2ECC TX enable bit */ 54420 SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, ®val)); 54421 if (soc_reg_field_get(unit, XPORT_CONFIGr, regval, E2E_HOL_ENf) == 1) { 54422 soc_reg_field_set(unit, XPORT_CONFIGr, ®val, E2E_HOL_ENf, 0); 54423 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, port, regval)); 54424 } 54425 } 54426 54427 if (soc_reg_field_valid(unit, XPORT_MODE_REGr, E2E_HOL_ENf)) { 54428 /* Clear per-port E2ECC TX enable bit */ 54429 SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, ®val)); 54430 if (soc_reg_field_get(unit, XPORT_MODE_REGr, regval, E2E_HOL_ENf) == 1) { 54431 soc_reg_field_set(unit, XPORT_MODE_REGr, ®val, E2E_HOL_ENf, 0); 54432 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, regval)); 54433 } 54434 } 54435 54436 /* Clear per-queue E2ECC enable bits */ 54437 BCM_IF_ERROR_RETURN 54438 (_bcm_esw_port_drop_status_enable_set(unit, port, FALSE)); 54439 54440 /* Clear the bit corresponding to the given Higig port in the Higig port bitmap 54441 * used to transmit E2ECC messages 54442 */ 54443 if (SOC_IS_SC_CQ(unit)) { 54444 SOC_IF_ERROR_RETURN(READ_E2E_HOL_PBMr(unit, ®val)); 54445 hg_pbm = soc_reg_field_get(unit, E2E_HOL_PBMr, regval, PORT_BITMAPf); 54446 54447 converted_hg_pbm = 1 << port; 54448 54449 if (hg_pbm & converted_hg_pbm) { 54450 new_hg_pbm = hg_pbm & ~converted_hg_pbm; 54451 soc_reg_field_set(unit, E2E_HOL_PBMr, ®val, PORT_BITMAPf, new_hg_pbm); 54452 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_PBMr(unit, regval)); 54453 } 54454 } else if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || SOC_IS_VALKYRIE2(unit)) { 54455 SOC_IF_ERROR_RETURN(READ_E2ECC_HOL_PBMr(unit, ®val)); 54456 hg_pbm = soc_reg_field_get(unit, E2ECC_HOL_PBMr, regval, HG_PBMf); 54457 54458 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hg_pbm_convert(port, &converted_hg_pbm)); 54459 54460 if (hg_pbm & converted_hg_pbm) { 54461 new_hg_pbm = hg_pbm & ~converted_hg_pbm; 54462 soc_reg_field_set(unit, E2ECC_HOL_PBMr, ®val, HG_PBMf, new_hg_pbm); 54463 SOC_IF_ERROR_RETURN(WRITE_E2ECC_HOL_PBMr(unit, regval)); 54464 } 54465 } else if (SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 54466 SOC_IS_TRIUMPH3(unit) || SOC_IS_HURRICANE3(unit) || 54467 SOC_IS_GREYHOUND2(unit)) { 54468 if (soc_feature(unit, soc_feature_logical_port_num)) { 54469 blk = SOC_PORT_BLOCK(unit, SOC_INFO(unit).port_l2p_mapping[port]); 54470 bindex = SOC_PORT_BINDEX(unit, SOC_INFO(unit).port_l2p_mapping[port]); 54471 } else{ 54472 blk = SOC_PORT_BLOCK(unit, port); 54473 bindex = SOC_PORT_BINDEX(unit, port); 54474 } 54475 #if defined(BCM_APACHE_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 54476 if (SOC_IS_TRIDENT2X(unit)) { 54477 blk_num = SOC_INFO(unit).port_serdes[port]; 54478 } else 54479 #endif 54480 { 54481 blk_num = SOC_BLOCK_INFO(unit, blk).number; 54482 } 54483 /* In TR3 E2ECC is implemented only in blocks CL, XL1 */ 54484 if (!SOC_IS_TRIUMPH3(unit) || (IS_CL_PORT(unit, port) || (blk == 13))) { 54485 if (SOC_IS_TRIUMPH3(unit)) { 54486 if (IS_CL_PORT(unit, port)) { 54487 blk_num = (blk_num ? 4 + bindex/4 : bindex/4); 54488 bindex = bindex%4; 54489 } else { 54490 blk_num = 3; 54491 } 54492 } 54493 #if defined(BCM_KATANA2_SUPPORT) 54494 if (SOC_IS_KATANA2(unit)) { 54495 /* In KT2 E2ECC is implemented only in blocks 6..9 */ 54496 blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ; 54497 if (SOC_IS_SABER2(unit)) { 54498 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 0)); 54499 } 54500 } 54501 #endif 54502 SOC_IF_ERROR_RETURN(READ_E2ECC_TX_ENABLE_BMPr(unit, blk_num, 54503 ®val)); 54504 if (regval & (1 << bindex)) { 54505 new_hg_pbm = soc_reg_field_get(unit, E2ECC_TX_ENABLE_BMPr, regval, 54506 TX_ENABLE_BMPf); 54507 new_hg_pbm &= ~(1 << bindex); 54508 soc_reg_field_set(unit, E2ECC_TX_ENABLE_BMPr, ®val, 54509 TX_ENABLE_BMPf, new_hg_pbm); 54510 SOC_IF_ERROR_RETURN 54511 (WRITE_E2ECC_TX_ENABLE_BMPr(unit, blk_num, regval)); 54512 } 54513 } 54514 54515 if (SOC_IS_TD2_TT2(unit) || SOC_IS_HURRICANE3(unit) || 54516 SOC_IS_GREYHOUND2(unit)) { 54517 SOC_IF_ERROR_RETURN(_bcm_esw_port_e2e_tx_enable_set(unit, port, 0)); 54518 } 54519 } 54520 54521 /* Clear per-port registers holding the E2ECC message header */ 54522 sal_memset(&e2ecc_hdr, 0, sizeof(soc_higig_e2ecc_hdr_t)); 54523 BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_hdr_set(unit, port, &e2ecc_hdr)); 54524 } 54525 54526 return BCM_E_NONE; 54527 } 54528 54529 /* 54530 * Function: 54531 * _bcm_esw_port_e2ecc_rx 54532 * Purpose: 54533 * Configure E2ECC message reception. 54534 * Parameters: 54535 * unit - (IN) Unit number. 54536 * port - (IN) Local port number. 54537 * config - (IN) Congestion configuration. 54538 * Returns: 54539 * BCM_E_xxx 54540 */ 54541 STATIC int 54542 _bcm_esw_port_e2ecc_rx(int unit, bcm_port_t port, 54543 bcm_port_congestion_config_t *config) 54544 { 54545 uint32 regval; 54546 uint64 regval64; 54547 uint32 field_val; 54548 54549 if (config->flags & BCM_PORT_CONGESTION_CONFIG_RX) { 54550 /* If BCM_PORT_CONGESTION_CONFIG_RX flag is set, enable E2ECC reception. */ 54551 54552 /* Make sure chip-wide E2ECC reception disable bit is cleared */ 54553 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, ®val64)); 54554 if (soc_reg64_field32_get(unit, ING_CONFIG_64r, regval64, 54555 DISABLE_E2E_HOL_CHECKf) == 1) { 54556 soc_reg64_field32_set(unit, ING_CONFIG_64r, ®val64, 54557 DISABLE_E2E_HOL_CHECKf, 0); 54558 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, regval64)); 54559 } 54560 54561 /* Set per-port E2ECC RX enable bit */ 54562 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 54563 if (soc_reg_field_get(unit, IE2E_CONTROLr, regval, 54564 HOL_ENABLEf) == 0) { 54565 soc_reg_field_set(unit, IE2E_CONTROLr, ®val, HOL_ENABLEf, 1); 54566 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval)); 54567 } 54568 54569 /* Configure E2ECC receive MAC-DA, Length/Type, and Opcode */ 54570 54571 field_val = (config->dest_mac[0] << 8) | /* MAC-DA[47:40] */ 54572 (config->dest_mac[1]); /* MAC-DA[39:32] */ 54573 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_MSr(unit, ®val)); 54574 soc_reg_field_set(unit, E2E_HOL_RX_DA_MSr, ®val, DAf, field_val); 54575 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_DA_MSr(unit, regval)); 54576 54577 field_val = (config->dest_mac[2] << 24) | /* MAC-DA[31:24] */ 54578 (config->dest_mac[3] << 16) | /* MAC-DA[23:16] */ 54579 (config->dest_mac[4] << 8) | /* MAC-DA[15:8] */ 54580 (config->dest_mac[5]); /* MAC-DA[7:0] */ 54581 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_DA_LSr(unit, ®val)); 54582 soc_reg_field_set(unit, E2E_HOL_RX_DA_LSr, ®val, DAf, field_val); 54583 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_DA_LSr(unit, regval)); 54584 54585 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_LENGTH_TYPEr(unit, ®val)); 54586 soc_reg_field_set(unit, E2E_HOL_RX_LENGTH_TYPEr, ®val, LENGTH_TYPEf, config->ethertype); 54587 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_LENGTH_TYPEr(unit, regval)); 54588 54589 SOC_IF_ERROR_RETURN(READ_E2E_HOL_RX_OPCODEr(unit, ®val)); 54590 soc_reg_field_set(unit, E2E_HOL_RX_OPCODEr, ®val, OPCODEf, config->opcode); 54591 SOC_IF_ERROR_RETURN(WRITE_E2E_HOL_RX_OPCODEr(unit, regval)); 54592 54593 } else { 54594 /* If BCM_PORT_CONGESTION_CONFIG_RX flag is not set, disable E2ECC reception. */ 54595 54596 /* Clear per-port E2ECC RX enable bit */ 54597 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 54598 if (soc_reg_field_get(unit, IE2E_CONTROLr, regval, HOL_ENABLEf) == 1) { 54599 soc_reg_field_set(unit, IE2E_CONTROLr, ®val, HOL_ENABLEf, 0); 54600 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval)); 54601 } 54602 } 54603 54604 return BCM_E_NONE; 54605 } 54606 54607 STATIC int 54608 _bcm_tr3_port_hcfc(int unit, bcm_port_t port, 54609 bcm_port_congestion_config_t *config) 54610 { 54611 #if defined(BCM_TRIUMPH3_SUPPORT) 54612 soc_reg_t reg; 54613 int enable; 54614 uint32 rval; 54615 uint64 rval64, fval64, tmp; 54616 54617 enable = config->flags & BCM_PORT_CONGESTION_CONFIG_TX ? 1 : 0; 54618 BCM_IF_ERROR_RETURN 54619 (_bcm_esw_port_drop_status_enable_set(unit, port, enable)); 54620 54621 /* Configure egress status reporting */ 54622 reg = OOBFC_ENG_PORT_EN_64r; 54623 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 54624 fval64 = soc_reg64_field_get(unit, reg, rval64, ENG_PORT_ENf); 54625 COMPILER_64_SET(tmp, 0, 1); 54626 COMPILER_64_SHL(tmp, port); 54627 COMPILER_64_AND(fval64, tmp); 54628 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 54629 54630 SOC_IF_ERROR_RETURN(READ_OOBFC_GCSr(unit, &rval)); 54631 soc_reg_field_set(unit, OOBFC_GCSr, &rval, GCS_ENf, 0); 54632 SOC_IF_ERROR_RETURN(WRITE_OOBFC_GCSr(unit, rval)); 54633 54634 return BCM_E_NONE; 54635 #else 54636 return BCM_E_UNAVAIL; 54637 #endif 54638 } 54639 54640 54641 /* 54642 * Function: 54643 * _bcm_esw_port_hcfc_tx 54644 * Purpose: 54645 * configure the port hcfc egress status to enable 54646 * Parameters: 54647 * unit - (IN) Unit number. 54648 * port - (IN) Port number 54649 * config - (IN) Configuration 54650 * Returns: 54651 * BCM_E_xxx 54652 * Notes: 54653 */ 54654 STATIC int 54655 _bcm_esw_port_hcfc_tx(int unit, bcm_port_t port, 54656 bcm_port_congestion_config_t *config) 54657 { 54658 soc_reg_t reg, reg0, reg1; 54659 int enable, len; 54660 uint64 rval64, fval64; 54661 uint32 fval_hi, fval_lo; 54662 54663 if (!SOC_PORT_VALID(unit, port)) { 54664 return BCM_E_PORT; 54665 } 54666 54667 if (SOC_REG_IS_VALID(unit, OOBFC_ENG_PORT_EN0_64r)) { 54668 reg0 = OOBFC_ENG_PORT_EN0_64r; 54669 reg1 = OOBFC_ENG_PORT_EN1_64r; 54670 } else { 54671 reg0 = OOBFC_ENG_PORT_EN_0_64r; 54672 reg1 = OOBFC_ENG_PORT_EN_1_64r; 54673 } 54674 if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) { 54675 return BCM_E_PORT; 54676 } 54677 54678 /* Configure egress status reporting */ 54679 len = soc_reg_field_length(unit, reg0, ENG_PORT_ENf); 54680 if (len < 1) { 54681 return BCM_E_PORT; 54682 } 54683 if (port < len) { /* First half of logical ports (not mmu port) */ 54684 reg = reg0; 54685 } else { /* Second half of logical ports (not mmu port) */ 54686 reg = reg1; 54687 } 54688 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 54689 fval64 = soc_reg64_field_get(unit, reg, rval64, ENG_PORT_ENf); 54690 fval_hi = COMPILER_64_HI(fval64); 54691 fval_lo = COMPILER_64_LO(fval64); 54692 enable = config->flags & BCM_PORT_CONGESTION_CONFIG_TX ? 1 : 0; 54693 if (enable) { 54694 if (port < len) { 54695 if (port < 32) { 54696 fval_lo |= (1 << port); 54697 } else { 54698 /* coverity[large_shift : FALSE] */ 54699 fval_hi |= (1 << (port - 32)); 54700 } 54701 } else { 54702 int port_offset = port - len; 54703 if ( port_offset < 32 ) { 54704 fval_lo |= (1 << port_offset); 54705 } else { 54706 fval_hi |= (1 << (port_offset - 32)); 54707 } 54708 } 54709 } else { 54710 if (port < len) { 54711 if (port < 32) { 54712 fval_lo &= ~(1 << port); 54713 } else { 54714 /* coverity[large_shift : FALSE] */ 54715 fval_hi &= ~(1 << (port - 32)); 54716 } 54717 } else { 54718 int port_offset = port - len; 54719 if ( port_offset < 32 ) { 54720 fval_lo &= ~(1 << port_offset); 54721 } else { 54722 fval_hi &= ~(1 << (port_offset - 32)); 54723 } 54724 } 54725 } 54726 COMPILER_64_SET(fval64, fval_hi, fval_lo); 54727 soc_reg64_field_set(unit, reg, &rval64, ENG_PORT_ENf, fval64); 54728 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 54729 54730 return BCM_E_NONE; 54731 } 54732 54733 /* 54734 * Function: 54735 * _bcm_esw_port_hcfc_rx 54736 * Purpose: 54737 * configure the port hcfc ingress status to enable 54738 * Parameters: 54739 * unit - (IN) Unit number. 54740 * port - (IN) Port number 54741 * config - (IN) Configuration 54742 * Returns: 54743 * BCM_E_xxx 54744 * Notes: 54745 */ 54746 STATIC int 54747 _bcm_esw_port_hcfc_rx(int unit, bcm_port_t port, 54748 bcm_port_congestion_config_t *config) 54749 { 54750 soc_reg_t reg, reg0, reg1; 54751 int enable, len; 54752 uint64 rval64, fval64; 54753 uint32 fval_hi, fval_lo; 54754 54755 if (!SOC_PORT_VALID(unit, port)) { 54756 return BCM_E_PORT; 54757 } 54758 54759 if (SOC_REG_IS_VALID(unit, OOBFC_ING_PORT_EN0_64r)) { 54760 reg0 = OOBFC_ING_PORT_EN0_64r; 54761 reg1 = OOBFC_ING_PORT_EN1_64r; 54762 } else { 54763 reg0 = OOBFC_ING_PORT_EN_0_64r; 54764 reg1 = OOBFC_ING_PORT_EN_1_64r; 54765 } 54766 if (!(SOC_REG_IS_VALID(unit, reg0)) || !(SOC_REG_IS_VALID(unit, reg1))) { 54767 return BCM_E_PORT; 54768 } 54769 54770 /* Configure ingress status reporting */ 54771 len = soc_reg_field_length(unit, reg0, ING_PORT_ENf); 54772 if (len < 1) { 54773 return BCM_E_PORT; 54774 } 54775 if (port < len) { /* First half of logical ports (not mmu port) */ 54776 reg = reg0; 54777 } else { /* Second half of logical ports (not mmu port) */ 54778 reg = reg1; 54779 } 54780 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 54781 fval64 = soc_reg64_field_get(unit, reg, rval64, ING_PORT_ENf); 54782 fval_hi = COMPILER_64_HI(fval64); 54783 fval_lo = COMPILER_64_LO(fval64); 54784 54785 enable = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0; 54786 if (enable) { 54787 if (port < len) { 54788 if (port < 32) { 54789 fval_lo |= (1 << port); 54790 } else { 54791 /* coverity[large_shift : FALSE] */ 54792 fval_hi |= (1 << (port - 32)); 54793 } 54794 } else { 54795 int port_offset = port - len; 54796 if ( port_offset < 32 ) { 54797 fval_lo |= (1 << port_offset); 54798 } else { 54799 fval_hi |= (1 << (port_offset - 32)); 54800 } 54801 } 54802 } else { 54803 if (port < len) { 54804 if (port < 32) { 54805 fval_lo &= ~(1 << port); 54806 } else { 54807 /* coverity[large_shift : FALSE] */ 54808 fval_hi &= ~(1 << (port - 32)); 54809 } 54810 } else { 54811 int port_offset = port - len; 54812 if ( port_offset < 32 ) { 54813 fval_lo &= ~(1 << port_offset); 54814 } else { 54815 fval_hi &= ~(1 << (port_offset - 32)); 54816 } 54817 } 54818 } 54819 COMPILER_64_SET(fval64, fval_hi, fval_lo); 54820 soc_reg64_field_set(unit, reg, &rval64, ING_PORT_ENf, fval64); 54821 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 54822 54823 return BCM_E_NONE; 54824 } 54825 54826 54827 STATIC int 54828 _bcm_esw_port_hcfc(int unit, bcm_port_t port, 54829 bcm_port_congestion_config_t *config) 54830 { 54831 int enable; 54832 uint32 rval; 54833 54834 enable = config->flags & BCM_PORT_CONGESTION_CONFIG_TX ? 1 : 0; 54835 BCM_IF_ERROR_RETURN 54836 (_bcm_esw_port_drop_status_enable_set(unit, port, enable)); 54837 54838 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_tx(unit, port, config)); 54839 54840 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc_rx(unit, port, config)); 54841 54842 SOC_IF_ERROR_RETURN(READ_OOBFC_GCSr(unit, &rval)); 54843 soc_reg_field_set(unit, OOBFC_GCSr, &rval, GCS_ENf, 0); 54844 SOC_IF_ERROR_RETURN(WRITE_OOBFC_GCSr(unit, rval)); 54845 54846 return BCM_E_NONE; 54847 } 54848 54849 #ifdef BCM_KATANA2_SUPPORT 54850 STATIC int 54851 _bcm_esw_port_coe_e2ecc(int unit, bcm_port_t port, 54852 bcm_port_congestion_config_t *config) 54853 { 54854 54855 uint32 regval = 0; 54856 int en; 54857 int e2ecc_strict = -1; 54858 uint32 field_val; 54859 int index; 54860 mmu_intfi_st_trans_tbl_entry_t st_trans_entry; 54861 uint16 dev_id; 54862 uint8 rev_id; 54863 54864 soc_cm_get_id(unit, &dev_id, &rev_id); 54865 54866 en = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0; 54867 54868 if ((config->flags & 54869 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE)) { 54870 e2ecc_strict = 0; 54871 } else if (config->flags & 54872 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) { 54873 e2ecc_strict = 1; 54874 } else { 54875 return BCM_E_PARAM; 54876 } 54877 if ((rev_id == BCM56450_A0_REV_ID) && (!SOC_IS_SABER2(unit))) { 54878 if (e2ecc_strict) { 54879 /* E2ECC STRICT mode only valid for BCM56450_B0 onwards 54880 */ 54881 return BCM_E_UNAVAIL; 54882 } 54883 } else if ((rev_id >= BCM56450_B0_REV_ID) || SOC_IS_SABER2(unit)) { 54884 /* setting of strict/flex mode is valid only when flow control is 54885 * enabled 54886 */ 54887 e2ecc_strict = (en ? e2ecc_strict : 0); 54888 SOC_IF_ERROR_RETURN( 54889 READ_COE_FLOW_CONTROL_CONFIGr (unit, port, ®val)); 54890 /* Enable the Flow control and E2ECC mode 54891 * 1. When there is enable request 54892 * 2. When flow control is already enabled 54893 * and there is change in E2ECC_mode from 54894 * strict to flex or vice versa 54895 */ 54896 if ((en != soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr, 54897 regval, FLOW_CONTROL_FORMATf)) || 54898 (en && (soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr, 54899 regval, FLOW_CONTROL_FORMATf) == 1) && 54900 (e2ecc_strict != soc_reg_field_get(unit, COE_FLOW_CONTROL_CONFIGr, 54901 regval, E2ECC_MODEf)))) { 54902 soc_reg_field_set(unit, COE_FLOW_CONTROL_CONFIGr, ®val, 54903 FLOW_CONTROL_FORMATf, en); 54904 soc_reg_field_set(unit, COE_FLOW_CONTROL_CONFIGr, ®val, 54905 E2ECC_MODEf, e2ecc_strict); 54906 SOC_IF_ERROR_RETURN( 54907 WRITE_COE_FLOW_CONTROL_CONFIGr (unit, port, regval)); 54908 } 54909 } 54910 54911 if (en) { 54912 /* Configure E2ECC-FC receive MAC-DA, Length/Type, and Opcode */ 54913 field_val = (config->dest_mac[0] << 8) | /* MAC-DA[47:40] */ 54914 (config->dest_mac[1]); /* MAC-DA[39:32] */ 54915 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_MSr(unit, ®val)); 54916 soc_reg_field_set(unit, ING_VOQFC_MACDA_MSr, ®val, DAf, field_val); 54917 SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_MSr(unit, regval)); 54918 54919 field_val = (config->dest_mac[2] << 24) | /* MAC-DA[31:24] */ 54920 (config->dest_mac[3] << 16) | /* MAC-DA[23:16] */ 54921 (config->dest_mac[4] << 8) | /* MAC-DA[15:8] */ 54922 (config->dest_mac[5]); /* MAC-DA[7:0] */ 54923 54924 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_LSr(unit, ®val)); 54925 soc_reg_field_set(unit, ING_VOQFC_MACDA_LSr, ®val, DAf, field_val); 54926 SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_LSr(unit, regval)); 54927 54928 54929 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, ®val)); 54930 soc_reg_field_set(unit, ING_VOQFC_IDr, ®val, 54931 LENGTH_TYPEf, config->ethertype); 54932 54933 soc_reg_field_set(unit, ING_VOQFC_IDr, ®val, 54934 OPCODEf, config->opcode); 54935 SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_IDr(unit, regval)); 54936 54937 /* 54938 * Hardcoding the MMU_INTFI_ST_TRANS_TBL so the 54939 * congestion data is written as it is 54940 * in FC_ST_TABLE 54941 */ 54942 54943 for (index=0 ; index < soc_mem_index_count(unit, 54944 MMU_INTFI_ST_TRANS_TBLm); index++) { 54945 SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm( 54946 unit, MEM_BLOCK_ALL,index, 54947 &st_trans_entry)); 54948 soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm, 54949 &st_trans_entry, FC_ST_XLATEf,index%256); 54950 SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm( 54951 unit, MEM_BLOCK_ALL, index, 54952 &st_trans_entry)); 54953 } 54954 54955 /* 54956 * Hardcoding FC_WIDTH to 3 so that 8 bits are read at time 54957 */ 54958 SOC_IF_ERROR_RETURN 54959 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 54960 FC_WIDTHf, 3)); 54961 /* 54962 * In case of COE E2ECC merger block should be disabled 54963 */ 54964 54965 SOC_IF_ERROR_RETURN 54966 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 54967 MERGE_ENf, 0)); 54968 /* 54969 * Hardcode the INTFI_MAP_L0/L1/L2_TBL_ADDR, 54970 * so that state machine reads 54971 * all the L1,L2,L3 Nodes in a cycle 54972 */ 54973 54974 54975 SOC_IF_ERROR_RETURN 54976 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 54977 FC_MAP_TBL_ADDR_ENf, 0)); 54978 SOC_IF_ERROR_RETURN 54979 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 54980 FC_MAP_TBL_START_ADDRf, 0)); 54981 if (SOC_IS_SABER2(unit)) { 54982 #ifdef BCM_METROLITE_SUPPORT 54983 if (SOC_IS_METROLITE(unit)) { 54984 SOC_IF_ERROR_RETURN 54985 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 54986 FC_MAP_TBL_END_ADDRf, 0x1f)); 54987 } else 54988 #endif 54989 SOC_IF_ERROR_RETURN 54990 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 54991 FC_MAP_TBL_END_ADDRf, 0x3f)); 54992 } else { 54993 SOC_IF_ERROR_RETURN 54994 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 54995 FC_MAP_TBL_END_ADDRf, 0xff)); 54996 } 54997 SOC_IF_ERROR_RETURN 54998 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 54999 FC_MAP_TBL_ADDR_ENf, 0)); 55000 SOC_IF_ERROR_RETURN 55001 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 55002 FC_MAP_TBL_START_ADDRf, 0)); 55003 if (SOC_IS_SABER2(unit)) { 55004 #ifdef BCM_METROLITE_SUPPORT 55005 if (SOC_IS_METROLITE(unit)) { 55006 SOC_IF_ERROR_RETURN 55007 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 55008 FC_MAP_TBL_END_ADDRf, 0x7)); 55009 } else 55010 #endif 55011 SOC_IF_ERROR_RETURN 55012 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 55013 FC_MAP_TBL_END_ADDRf, 0xf)); 55014 } else { 55015 SOC_IF_ERROR_RETURN 55016 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 55017 FC_MAP_TBL_END_ADDRf, 0x3f)); 55018 } 55019 SOC_IF_ERROR_RETURN 55020 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 55021 FC_MAP_TBL_ADDR_ENf, 0)); 55022 SOC_IF_ERROR_RETURN 55023 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 55024 FC_MAP_TBL_START_ADDRf, 0)); 55025 if (SOC_IS_SABER2(unit)) { 55026 #ifdef BCM_METROLITE_SUPPORT 55027 if (SOC_IS_METROLITE(unit)) { 55028 SOC_IF_ERROR_RETURN 55029 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 55030 FC_MAP_TBL_END_ADDRf, 0x3)); 55031 } else 55032 #endif 55033 SOC_IF_ERROR_RETURN 55034 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 55035 FC_MAP_TBL_END_ADDRf, 0x7)); 55036 } else { 55037 SOC_IF_ERROR_RETURN 55038 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 55039 FC_MAP_TBL_END_ADDRf, 0x1f)); 55040 } 55041 55042 if (e2ecc_strict == 0) { 55043 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 55044 if (en != soc_reg_field_get(unit, IE2E_CONTROLr, regval, 55045 VOQFC_ENABLEf)) { 55046 soc_reg_field_set(unit, IE2E_CONTROLr, ®val, 55047 VOQFC_ENABLEf, en); 55048 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval)); 55049 } 55050 } else { 55051 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 55052 if (soc_reg_field_get(unit, IE2E_CONTROLr, regval, 55053 VOQFC_ENABLEf)) { 55054 soc_reg_field_set(unit, IE2E_CONTROLr, ®val, 55055 VOQFC_ENABLEf, 0); 55056 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval)); 55057 } 55058 } 55059 } else { 55060 if (e2ecc_strict == 0) { 55061 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 55062 if (soc_reg_field_get(unit, IE2E_CONTROLr, regval, 55063 VOQFC_ENABLEf)) { 55064 soc_reg_field_set(unit, IE2E_CONTROLr, ®val, 55065 VOQFC_ENABLEf, 0); 55066 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval)); 55067 } 55068 } 55069 } 55070 55071 return BCM_E_NONE; 55072 } 55073 #endif 55074 55075 /* 55076 * Function: 55077 * _bcm_esw_port_dmvoqfc_rx 55078 * Purpose: 55079 * Configure VOQFC message reception. 55080 * Parameters: 55081 * unit - (IN) Unit number. 55082 * port - (IN) Local port number. 55083 * config - (IN) Congestion configuration. 55084 * Returns: 55085 * BCM_E_xxx 55086 */ 55087 STATIC int 55088 _bcm_esw_port_dmvoqfc_rx(int unit, bcm_port_t port, 55089 bcm_port_congestion_config_t *config) 55090 { 55091 uint32 regval; 55092 uint32 field_val; 55093 int en, cos_mode; 55094 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \ 55095 defined(BCM_TRIUMPH3_SUPPORT) 55096 int index; 55097 #endif 55098 #if defined(BCM_TRIDENT2_SUPPORT) 55099 uint64 rval; 55100 #endif 55101 #if defined(BCM_TRIUMPH3_SUPPORT) 55102 uint32 rval1; 55103 mmu_intfi_st_trans_tbl_entry_t st_trans_entry; 55104 #endif 55105 55106 en = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0; 55107 cos_mode = config->flags & BCM_PORT_CONGESTION_CONFIG_RX ? 1 : 0; 55108 SOC_IF_ERROR_RETURN(READ_IE2E_CONTROLr(unit, port, ®val)); 55109 if (en != soc_reg_field_get(unit, IE2E_CONTROLr, regval, 55110 VOQFC_ENABLEf)) { 55111 soc_reg_field_set(unit, IE2E_CONTROLr, ®val, VOQFC_ENABLEf, en); 55112 SOC_IF_ERROR_RETURN(WRITE_IE2E_CONTROLr(unit, port, regval)); 55113 } 55114 #ifdef BCM_TRIDENT2_SUPPORT 55115 if (SOC_IS_TD2_TT2(unit)) { 55116 SOC_IF_ERROR_RETURN(READ_ING_COS_MODE_64r(unit, port, &rval)); 55117 if (cos_mode != soc_reg64_field32_get(unit, ING_COS_MODE_64r, rval, 55118 QUEUE_MODEf)) { 55119 soc_reg64_field32_set(unit, ING_COS_MODE_64r, &rval, QUEUE_MODEf, cos_mode); 55120 SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODE_64r(unit, port, rval)); 55121 } 55122 /* 55123 * FC_WIDTH is set to 2 so that 4 bits of i 55124 * congestion data is read on each cycle 55125 */ 55126 SOC_IF_ERROR_RETURN 55127 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 55128 FC_WIDTHf, 2)); 55129 /* 55130 * MERGE_EN is set to 1, to merge the congestion state 55131 * received from different ports of the same module 55132 */ 55133 55134 SOC_IF_ERROR_RETURN 55135 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 55136 MERGE_ENf, 1)); 55137 /* MODE_SEL is set to 1 to specify the message is of type 55138 * DMVOQ 55139 */ 55140 SOC_IF_ERROR_RETURN 55141 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 55142 MODE_SELf, 1)); 55143 #ifdef BCM_APACHE_SUPPORT 55144 if (SOC_IS_APACHE(unit)) { 55145 if (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL) { 55146 /* 55147 * MERGE_EN is set to 0, in case of DPVOQ. 55148 */ 55149 55150 SOC_IF_ERROR_RETURN 55151 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 55152 MERGE_ENf, 0)); 55153 /* MODE_SEL is set to 0 to specify the message is of type 55154 * DPVOQ 55155 */ 55156 SOC_IF_ERROR_RETURN 55157 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 55158 MODE_SELf, 0)); 55159 } 55160 } 55161 #endif 55162 /* DMVOQ congestion bytes max length is 64 bytes, 55163 * as a result 55164 * DMVOQ feature can support upto 64 ports 55165 */ 55166 55167 for (index = 0 ; index < SOC_REG_NUMELS(unit, CONGESTION_STATE_BYTESr) 55168 ; index++) { 55169 soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, ®val, 55170 DATAf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ); 55171 SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit, 55172 index, regval)); 55173 } 55174 55175 } else 55176 #endif 55177 #ifdef BCM_KATANA2_SUPPORT 55178 if (SOC_IS_KATANA2(unit)) { 55179 SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, ®val)); 55180 if (cos_mode != soc_reg_field_get(unit, ING_COS_MODEr, regval, 55181 COS_MODEf)) { 55182 soc_reg_field_set(unit, ING_COS_MODEr, ®val, COS_MODEf, cos_mode); 55183 SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, regval)); 55184 } 55185 55186 /* 55187 * Hardcoding FC_WIDTH to 3 so that 8 bits are read at time 55188 */ 55189 SOC_IF_ERROR_RETURN 55190 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 55191 FC_WIDTHf, 3)); 55192 if (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL) { 55193 /* 55194 * In case of DMVOQ we need to merge all the congestion bytes 55195 * of the ports so enabling MERGE_EN 55196 */ 55197 55198 SOC_IF_ERROR_RETURN 55199 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 55200 MERGE_ENf, 1)); 55201 } 55202 /* 55203 * Hardcode the INTFI_MAP_L0/L1/L2_TBL_ADDR, 55204 * so that state machine reads 55205 * all the L1,L2,L3 Nodes in a cycle 55206 */ 55207 55208 SOC_IF_ERROR_RETURN 55209 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 55210 FC_MAP_TBL_ADDR_ENf, 0)); 55211 SOC_IF_ERROR_RETURN 55212 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 55213 FC_MAP_TBL_START_ADDRf, 0)); 55214 SOC_IF_ERROR_RETURN 55215 (soc_reg_field32_modify(unit, INTFI_MAP_L2_TBL_ADDRr, REG_PORT_ANY, 55216 FC_MAP_TBL_END_ADDRf, 55217 ((soc_mem_index_count(unit, LLS_L2_PARENTm)) / 16) - 1)); 55218 SOC_IF_ERROR_RETURN 55219 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 55220 FC_MAP_TBL_ADDR_ENf, 0)); 55221 SOC_IF_ERROR_RETURN 55222 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 55223 FC_MAP_TBL_START_ADDRf, 0)); 55224 SOC_IF_ERROR_RETURN 55225 (soc_reg_field32_modify(unit, INTFI_MAP_L1_TBL_ADDRr, REG_PORT_ANY, 55226 FC_MAP_TBL_END_ADDRf, 55227 ((soc_mem_index_count(unit, LLS_L1_PARENTm)) / 16) - 1 )); 55228 SOC_IF_ERROR_RETURN 55229 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 55230 FC_MAP_TBL_ADDR_ENf, 0)); 55231 SOC_IF_ERROR_RETURN 55232 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 55233 FC_MAP_TBL_START_ADDRf, 0)); 55234 SOC_IF_ERROR_RETURN 55235 (soc_reg_field32_modify(unit, INTFI_MAP_L0_TBL_ADDRr, REG_PORT_ANY, 55236 FC_MAP_TBL_END_ADDRf, 55237 ((soc_mem_index_count(unit, LLS_L0_PARENTm)) / 55238 (SOC_IS_METROLITE(unit) ? 32: 16)) - 1)); 55239 55240 /* Though the number of ports supported in KT2 is 41, we're setting the 55241 max to 64 to support stacked systems. */ 55242 for (index = 0 ; index < SOC_REG_NUMELS(unit, CONGESTION_STATE_BYTESr) 55243 ; index++) { 55244 soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, ®val, 55245 DATAf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ); 55246 SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit, 55247 index, regval)); 55248 } 55249 55250 } else 55251 #endif 55252 #ifdef BCM_TRIUMPH3_SUPPORT 55253 if (SOC_IS_TRIUMPH3(unit)) { 55254 SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, &rval1)); 55255 if (cos_mode != soc_reg_field_get(unit, ING_COS_MODEr, rval1, 55256 QUEUE_MODEf)) { 55257 soc_reg_field_set(unit, ING_COS_MODEr, &rval1, QUEUE_MODEf, cos_mode); 55258 SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, rval1)); 55259 } 55260 /* 55261 * Hardcoding the MMU_INTFI_ST_TRANS_TBL so the 55262 * congestion data is written as it is 55263 * in FC_ST_TABLE, This we are doing so that 55264 * congestion data is updated as it is how 55265 * it recevied 55266 */ 55267 55268 for (index=0 ; index < soc_mem_index_count(unit, 55269 MMU_INTFI_ST_TRANS_TBLm); index++) { 55270 SOC_IF_ERROR_RETURN(READ_MMU_INTFI_ST_TRANS_TBLm( 55271 unit, MEM_BLOCK_ALL,index, 55272 &st_trans_entry)); 55273 soc_mem_field32_set(unit, MMU_INTFI_ST_TRANS_TBLm, 55274 &st_trans_entry, FC_ST_XLATEf,index%16); 55275 SOC_IF_ERROR_RETURN(WRITE_MMU_INTFI_ST_TRANS_TBLm( 55276 unit, MEM_BLOCK_ALL, index, 55277 &st_trans_entry)); 55278 } 55279 /* 55280 * FC_WIDTH is set to 2 so that 4 bits of i 55281 * congestion data is read on each cycle 55282 */ 55283 SOC_IF_ERROR_RETURN 55284 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 55285 FC_WIDTHf, 2)); 55286 /* 55287 * MERGE_EN is set to 1, to merge the congestion state 55288 * received from different ports of the same module 55289 */ 55290 55291 SOC_IF_ERROR_RETURN 55292 (soc_reg_field32_modify(unit, INTFI_CFGr, REG_PORT_ANY, 55293 MERGE_ENf, 1)); 55294 /* DMVOQ congestion bytes max length is 64 bytes, 55295 * as a result 55296 * DMVOQ feature can support upto 64 ports 55297 */ 55298 55299 for (index = 0; index < SOC_REG_NUMELS(unit, CONGESTION_STATE_BYTESr) 55300 ; index++) { 55301 soc_reg_field_set(unit, CONGESTION_STATE_BYTESr, ®val, 55302 DATAf, BCM_MAX_PORTS_SUPPORT_FOR_DMVOQ); 55303 SOC_IF_ERROR_RETURN(WRITE_CONGESTION_STATE_BYTESr(unit, 55304 index, regval)); 55305 } 55306 55307 } else 55308 #endif 55309 { 55310 SOC_IF_ERROR_RETURN(READ_ING_COS_MODEr(unit, port, ®val)); 55311 if (cos_mode != soc_reg_field_get(unit, ING_COS_MODEr, regval, 55312 QUEUE_MODEf)) { 55313 soc_reg_field_set(unit, ING_COS_MODEr, ®val, QUEUE_MODEf, cos_mode); 55314 SOC_IF_ERROR_RETURN(WRITE_ING_COS_MODEr(unit, port, regval)); 55315 } 55316 } 55317 55318 if (en) { 55319 /* Configure DMVOQFC receive MAC-DA, Length/Type, and Opcode */ 55320 field_val = (config->dest_mac[0] << 8) | /* MAC-DA[47:40] */ 55321 (config->dest_mac[1]); /* MAC-DA[39:32] */ 55322 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_MSr(unit, ®val)); 55323 soc_reg_field_set(unit, ING_VOQFC_MACDA_MSr, ®val, DAf, field_val); 55324 SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_MSr(unit, regval)); 55325 55326 field_val = (config->dest_mac[2] << 24) | /* MAC-DA[31:24] */ 55327 (config->dest_mac[3] << 16) | /* MAC-DA[23:16] */ 55328 (config->dest_mac[4] << 8) | /* MAC-DA[15:8] */ 55329 (config->dest_mac[5]); /* MAC-DA[7:0] */ 55330 55331 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_MACDA_LSr(unit, ®val)); 55332 soc_reg_field_set(unit, ING_VOQFC_MACDA_LSr, ®val, DAf, field_val); 55333 SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_MACDA_LSr(unit, regval)); 55334 55335 55336 SOC_IF_ERROR_RETURN(READ_ING_VOQFC_IDr(unit, ®val)); 55337 soc_reg_field_set(unit, ING_VOQFC_IDr, ®val, 55338 LENGTH_TYPEf, config->ethertype); 55339 55340 soc_reg_field_set(unit, ING_VOQFC_IDr, ®val, OPCODEf, config->opcode); 55341 SOC_IF_ERROR_RETURN(WRITE_ING_VOQFC_IDr(unit, regval)); 55342 } 55343 55344 return BCM_E_NONE; 55345 } 55346 /* 55347 * Function: 55348 * _bcm_esw_port_dmvoqfc_tx 55349 * Purpose: 55350 * Configure VOQFC message reception. 55351 * Parameters: 55352 * unit - (IN) Unit number. 55353 * port - (IN) Local port number. 55354 * config - (IN) Congestion configuration. 55355 * Returns: 55356 * BCM_E_xxx 55357 */ 55358 STATIC int 55359 _bcm_esw_port_dmvoqfc_tx(int unit, bcm_port_t port, 55360 bcm_port_congestion_config_t *config) 55361 { 55362 /* 55363 * Trident/Titan VOQFC message generation is same as E2ECC, except for 55364 * ethertype and opcode. 55365 */ 55366 if (SOC_IS_TD_TT(unit) || SOC_IS_KATANA2(unit) 55367 || SOC_IS_TD2_TT2(unit) || SOC_IS_TRIUMPH3(unit)) { 55368 BCM_IF_ERROR_RETURN(_bcm_esw_port_e2ecc_tx(unit, port, config)); 55369 return BCM_E_NONE; 55370 } 55371 55372 return BCM_E_UNAVAIL; 55373 } 55374 55375 /* 55376 * Function: 55377 * bcm_port_congestion_config_set 55378 * Purpose: 55379 * Set end-to-end congestion control. 55380 * Parameters: 55381 * unit - (IN) Unit number. 55382 * port - (IN) Gport number. 55383 * config - (IN) Structure containing the congestion configuration. 55384 * Returns: 55385 * BCM_E_xxx 55386 */ 55387 int 55388 bcm_esw_port_congestion_config_set(int unit, bcm_gport_t port, 55389 bcm_port_congestion_config_t *config) 55390 { 55391 bcm_port_t local_port; 55392 55393 /* Make sure port module is initialized. */ 55394 PORT_INIT(unit); 55395 55396 if (soc_feature(unit, soc_feature_e2ecc)) { 55397 /* Check for parameters */ 55398 55399 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &local_port)); 55400 55401 if (!IS_HG_PORT(unit, local_port)) { 55402 if(SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 55403 SOC_IS_APACHE(unit) ) { 55404 if ((config->flags & 55405 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) || 55406 (config->flags & 55407 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) || 55408 (config->flags & 55409 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) 55410 { 55411 if (!IS_SUBTAG_PORT(unit, local_port)) { 55412 LOG_ERROR(BSL_LS_BCM_PORT, 55413 (BSL_META_U(unit, 55414 "E2ECC COE is applicable on subports only." 55415 "Port %d is not a subport.\n"), 55416 local_port)); 55417 return BCM_E_PORT; 55418 } 55419 } else if ((config->flags & 55420 BCM_PORT_CONGESTION_CONFIG_TX) && 55421 (config->flags & 55422 BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL)) { 55423 if ((IS_GE_PORT(unit, local_port)) || 55424 (IS_XE_PORT(unit, local_port))) { 55425 /* Set per-queue E2ECC enable bits */ 55426 BCM_IF_ERROR_RETURN 55427 (_bcm_esw_port_drop_status_enable_set(unit, 55428 port, TRUE)); 55429 /* Make sure port module is initialized. */ 55430 PORT_INIT(unit); 55431 55432 /* Lock is needed to modify bcm_port_info */ 55433 PORT_LOCK(unit); 55434 55435 /* Allocate per-port congestion configuration state on demand */ 55436 if (PORT(unit, local_port).e2ecc_config == NULL) { 55437 PORT(unit, local_port).e2ecc_config = sal_alloc(sizeof(bcm_port_congestion_config_t), 55438 "bcm_port_congestion_config"); 55439 if (PORT(unit, local_port).e2ecc_config == NULL) { 55440 LOG_ERROR(BSL_LS_BCM_PORT, 55441 (BSL_META_U(unit, 55442 "Error: unable to allocate memory for bcm_port_congestion_config.\n"))); 55443 PORT_UNLOCK(unit); 55444 return BCM_E_MEMORY; 55445 } 55446 } 55447 55448 /* Store E2ECC configuration */ 55449 *(PORT(unit, local_port).e2ecc_config) = *(config); 55450 55451 PORT_UNLOCK(unit); 55452 return BCM_E_NONE; 55453 } 55454 LOG_ERROR(BSL_LS_BCM_PORT, 55455 (BSL_META_U(unit, 55456 "Applicable on Ge/Xe only " 55457 "for enabling dmvoq transmitting only.\n "))); 55458 return BCM_E_PARAM; 55459 } else { 55460 if (((SOC_IS_TRIDENT2PLUS(unit)) || SOC_IS_APACHE(unit)) && 55461 (config->flags & BCM_PORT_CONGESTION_CONFIG_HCFC)) { 55462 LOG_ERROR(BSL_LS_BCM_PORT, 55463 (BSL_META_U(unit, 55464 "Error: unit %d port %d is not a Higig port. " 55465 "E2ECC messages can only be transmitted to " 55466 "or received from Higig ports.\n"), 55467 unit, local_port)); 55468 return BCM_E_PARAM; 55469 } 55470 } 55471 } else { 55472 LOG_ERROR(BSL_LS_BCM_PORT, 55473 (BSL_META_U(unit, 55474 "Error: unit %d port %d is not a Higig port. " 55475 "E2ECC messages can only be transmitted to or received from " 55476 "Higig ports.\n"), unit, local_port)); 55477 return BCM_E_PARAM; 55478 } 55479 } 55480 55481 if (config == NULL) { 55482 return BCM_E_PARAM; 55483 } 55484 55485 if (!((config->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC) || 55486 (config->flags & BCM_PORT_CONGESTION_CONFIG_HCFC) || 55487 (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL) || 55488 (config->flags & BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL) || 55489 (config->flags & BCM_PORT_CONGESTION_CONFIG_MAX_SPLIT4) || 55490 (config->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) || 55491 (config->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) || 55492 (config->flags & BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE))) { 55493 return BCM_E_PARAM; 55494 } 55495 55496 if (config->packets_per_sec < 0) { 55497 return BCM_E_PARAM; 55498 } 55499 55500 switch (config->flags & 55501 (BCM_PORT_CONGESTION_CONFIG_E2ECC | 55502 BCM_PORT_CONGESTION_CONFIG_HCFC | 55503 BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL | 55504 BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL | 55505 BCM_PORT_CONGESTION_CONFIG_MAX_SPLIT4 | 55506 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE | 55507 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE | 55508 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) { 55509 case BCM_PORT_CONGESTION_CONFIG_E2ECC: 55510 case BCM_PORT_CONGESTION_CONFIG_MAX_SPLIT4: 55511 /* Handle E2ECC message transmission */ 55512 BCM_IF_ERROR_RETURN 55513 (_bcm_esw_port_e2ecc_tx(unit, local_port, config)); 55514 55515 /* Handle E2ECC message reception */ 55516 BCM_IF_ERROR_RETURN 55517 (_bcm_esw_port_e2ecc_rx(unit, local_port, config)); 55518 break; 55519 55520 case BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE: 55521 case BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE: 55522 case BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE: 55523 /* COE flow control using E2ECC messages 55524 * KT2 supports E2E-CC message reception on 55525 * COE ports. 55526 */ 55527 #ifdef BCM_KATANA2_SUPPORT 55528 if (SOC_IS_KATANA2(unit)) { 55529 BCM_IF_ERROR_RETURN 55530 (_bcm_esw_port_coe_e2ecc(unit, local_port, config)); 55531 55532 } 55533 #endif 55534 55535 55536 55537 /* COE flow control using E2ECC messages 55538 * TD2+ supports E2E-CC message reception on 55539 * COE ports, only in STRICT mode. 55540 */ 55541 #ifdef BCM_TRIDENT2PLUS_SUPPORT 55542 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 55543 if (((config->flags & 55544 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) || 55545 (config->flags & 55546 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) && 55547 (config->flags & 55548 BCM_PORT_CONGESTION_CONFIG_RX)) 55549 { 55550 BCM_IF_ERROR_RETURN 55551 (bcm_td2p_port_coe_e2ecc(unit, local_port, config)); 55552 } else { 55553 return BCM_E_PARAM; 55554 } 55555 55556 } 55557 #endif 55558 break; 55559 55560 case BCM_PORT_CONGESTION_CONFIG_HCFC: 55561 if (SOC_IS_TRIUMPH3(unit)) { 55562 BCM_IF_ERROR_RETURN(_bcm_tr3_port_hcfc(unit, local_port, config)); 55563 } else { 55564 BCM_IF_ERROR_RETURN(_bcm_esw_port_hcfc(unit, local_port, config)); 55565 } 55566 break; 55567 55568 case BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL: 55569 if ((!SOC_IS_TD_TT(unit)) && (!SOC_IS_KATANA2(unit)) && 55570 (!SOC_IS_TD2_TT2(unit)) && (!SOC_IS_TRIUMPH3(unit))) { 55571 return BCM_E_PARAM; 55572 } 55573 55574 /* Handle VOQFC message reception */ 55575 BCM_IF_ERROR_RETURN 55576 (_bcm_esw_port_dmvoqfc_rx(unit, local_port, config)); 55577 55578 /* Handle E2ECC message transmission */ 55579 BCM_IF_ERROR_RETURN 55580 (_bcm_esw_port_dmvoqfc_tx(unit, local_port, config)); 55581 break; 55582 case BCM_PORT_CONGESTION_CONFIG_DESTMODPORT_FLOW_CONTROL: 55583 if (!SOC_IS_KATANA2(unit) && !(SOC_IS_APACHE(unit))) { 55584 return BCM_E_PARAM; 55585 } 55586 55587 /* Handle VOQFC message reception */ 55588 BCM_IF_ERROR_RETURN 55589 (_bcm_esw_port_dmvoqfc_rx(unit, local_port, config)); 55590 55591 /* Handle E2ECC message transmission */ 55592 BCM_IF_ERROR_RETURN 55593 (_bcm_esw_port_dmvoqfc_tx(unit, local_port, config)); 55594 break; 55595 default: 55596 return BCM_E_PARAM; 55597 } 55598 /* Make sure port module is initialized. */ 55599 PORT_INIT(unit); 55600 55601 /* Lock is needed to modify bcm_port_info */ 55602 PORT_LOCK(unit); 55603 55604 /* Allocate per-port congestion configuration state on demand */ 55605 if (PORT(unit, local_port).e2ecc_config == NULL) { 55606 PORT(unit, local_port).e2ecc_config = sal_alloc(sizeof(bcm_port_congestion_config_t), 55607 "bcm_port_congestion_config"); 55608 if (PORT(unit, local_port).e2ecc_config == NULL) { 55609 LOG_ERROR(BSL_LS_BCM_PORT, 55610 (BSL_META_U(unit, 55611 "Error: unable to allocate memory for bcm_port_congestion_config.\n"))); 55612 PORT_UNLOCK(unit); 55613 return BCM_E_MEMORY; 55614 } 55615 } 55616 55617 /* Store E2ECC configuration */ 55618 *(PORT(unit, local_port).e2ecc_config) = *(config); 55619 55620 PORT_UNLOCK(unit); 55621 55622 55623 return BCM_E_NONE; 55624 } else { 55625 return BCM_E_UNAVAIL; 55626 } 55627 55628 } 55629 55630 /* 55631 * Function: 55632 * bcm_port_congestion_config_get 55633 * Purpose: 55634 * Get end-to-end congestion control configuration. 55635 * Parameters: 55636 * unit - (IN) Unit number. 55637 * port - (IN) Gport number. 55638 * config - (OUT) Structure containing the congestion configuration. 55639 * Returns: 55640 * BCM_E_xxx 55641 */ 55642 55643 int 55644 bcm_esw_port_congestion_config_get(int unit, bcm_gport_t port, 55645 bcm_port_congestion_config_t *config) 55646 { 55647 bcm_port_t local_port; 55648 55649 /* Make sure port module is initialized. */ 55650 PORT_INIT(unit); 55651 55652 if (soc_feature(unit, soc_feature_e2ecc)) { 55653 /* Check for parameters */ 55654 55655 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &local_port)); 55656 if (!IS_HG_PORT(unit, local_port)) { 55657 if (SOC_IS_KATANA2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 55658 SOC_IS_APACHE(unit)) { 55659 if ((config->flags & 55660 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) || 55661 (config->flags & 55662 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) || 55663 (config->flags & 55664 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) { 55665 if (!IS_SUBTAG_PORT(unit, local_port)) { 55666 LOG_ERROR( 55667 BSL_LS_BCM_PORT, 55668 (BSL_META_U(unit, 55669 "Error: unit %d port %d is not a Higig " 55670 "port or Subtag port. E2ECC messages " 55671 "can be transmitted to or received from " 55672 "Higig ports or can be received on " 55673 "Subtag port.\n"), 55674 unit, local_port)); 55675 return BCM_E_PORT; 55676 } 55677 if ((SOC_IS_TRIDENT2PLUS(unit)|| SOC_IS_APACHE(unit)) && 55678 ((config->flags & 55679 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE))) { 55680 return BCM_E_PARAM; 55681 55682 } else if ((SOC_IS_TRIDENT2PLUS(unit)|| SOC_IS_APACHE(unit)) && 55683 ((config->flags & 55684 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) || 55685 (config->flags & 55686 BCM_PORT_CONGESTION_CONFIG_VLAN_PAUSE_COE)) && 55687 (config->flags & 55688 BCM_PORT_CONGESTION_CONFIG_TX)) { 55689 return BCM_E_PARAM; 55690 } 55691 } else if ((config->flags & 55692 BCM_PORT_CONGESTION_CONFIG_TX) && 55693 (config->flags & 55694 BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL)) { 55695 if (!(IS_GE_PORT(unit, local_port)) && 55696 !(IS_XE_PORT(unit, local_port))) { 55697 LOG_ERROR( 55698 BSL_LS_BCM_PORT, 55699 (BSL_META_U(unit, 55700 "Applicable on Ge/Xe only for enabling " 55701 "dmvoq transmitting only.\n "))); 55702 return BCM_E_PARAM; 55703 } 55704 } else if ((SOC_IS_TRIDENT2PLUS(unit)|| SOC_IS_APACHE(unit)) && 55705 (config->flags & BCM_PORT_CONGESTION_CONFIG_HCFC)) { 55706 LOG_ERROR( 55707 BSL_LS_BCM_PORT, 55708 (BSL_META_U(unit, 55709 "Error: unit %d port %d is not a Higig port. " 55710 "E2ECC messages can only be transmitted to " 55711 "or received from Higig ports.\n"), 55712 unit, local_port)); 55713 return BCM_E_PARAM; 55714 } 55715 } else { 55716 LOG_ERROR( 55717 BSL_LS_BCM_PORT, 55718 (BSL_META_U(unit, 55719 "Error: unit %d port %d is not a Higig port. " 55720 "E2ECC messages can only be transmitted to " 55721 "or received from Higig ports.\n"), 55722 unit, local_port)); 55723 return BCM_E_PARAM; 55724 } 55725 } 55726 if (config == NULL) { 55727 return BCM_E_PARAM; 55728 } 55729 55730 /* Make sure port module is initialized. */ 55731 PORT_INIT(unit); 55732 55733 if (PORT(unit, local_port).e2ecc_config == NULL) { 55734 LOG_ERROR(BSL_LS_BCM_PORT, 55735 (BSL_META_U(unit, 55736 "Error: Port %d bcm_port_congestion_config was not set.\n"), 55737 local_port)); 55738 return BCM_E_NOT_FOUND; 55739 } 55740 55741 /* Retrieve E2ECC configuration */ 55742 *config = *(PORT(unit, local_port).e2ecc_config); 55743 55744 return BCM_E_NONE; 55745 55746 } else { 55747 return BCM_E_UNAVAIL; 55748 } 55749 } 55750 55751 /* 55752 * Function: 55753 * bcm_port_match_add 55754 * Purpose: 55755 * Add a match to an existing port 55756 * Parameters: 55757 * unit - (IN) Unit number. 55758 * port - (IN) Port or gport 55759 * match - (IN) Match criteria 55760 * Returns: 55761 * BCM_E_xxx 55762 * Notes: 55763 */ 55764 int 55765 bcm_esw_port_match_add( 55766 int unit, 55767 bcm_gport_t port, 55768 bcm_port_match_info_t *match) 55769 { 55770 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 55771 int vp=0, rv = BCM_E_NONE; 55772 bcm_gport_t gp = 0; 55773 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_MPLS_SUPPORT) 55774 _bcm_vp_info_t vp_info; 55775 #endif 55776 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 55777 bcm_vxlan_port_t vxlan_port; 55778 bcm_l2gre_port_t l2gre_port; 55779 #endif 55780 int existing_updated = 0; 55781 #if defined(BCM_TRIDENT3_SUPPORT) 55782 bcm_mirror_destination_t mirror_dest; 55783 uint32 cancun_ver; 55784 #endif /* BCM_TRIDENT3_SUPPORT */ 55785 #if defined(BCM_TRX_SUPPORT) 55786 bcm_vlan_match_info_t vlan_match_info; 55787 #endif 55788 if (match == NULL) { 55789 return BCM_E_PARAM; 55790 } 55791 55792 /* Make sure port module is initialized. */ 55793 PORT_INIT(unit); 55794 55795 if (BCM_GPORT_IS_MIM_PORT(port)) { 55796 #if defined(BCM_TRIUMPH2_SUPPORT) 55797 if (!soc_feature(unit, soc_feature_mim)) { 55798 return BCM_E_UNAVAIL; 55799 } 55800 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 55801 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 55802 return BCM_E_NOT_FOUND; 55803 } 55804 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 55805 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 55806 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_port_phys_gport_get(unit, vp, &gp)); 55807 } 55808 #endif 55809 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 55810 if (!soc_feature(unit, soc_feature_mpls)) { 55811 return BCM_E_UNAVAIL; 55812 } 55813 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 55814 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 55815 return BCM_E_NOT_FOUND; 55816 } 55817 #if defined(BCM_MPLS_SUPPORT) 55818 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 55819 if ((vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 55820 if (!soc_feature(unit, soc_feature_vp_sharing)) { 55821 return BCM_E_UNAVAIL; 55822 } 55823 } else { 55824 BCM_IF_ERROR_RETURN(bcm_tr_mpls_port_phys_gport_get(unit, vp, &gp)); 55825 } 55826 #endif 55827 } else 55828 #if defined(BCM_TRIDENT2_SUPPORT) 55829 if (BCM_GPORT_IS_TRUNK(port)) { 55830 if (!soc_feature(unit, soc_feature_vp_lag)) { 55831 return BCM_E_UNAVAIL; 55832 } 55833 BCM_IF_ERROR_RETURN( 55834 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port), 55835 &vp)); 55836 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 55837 return BCM_E_NOT_FOUND; 55838 } 55839 if (match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID && 55840 match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN) { 55841 return BCM_E_PARAM; 55842 } 55843 } else 55844 #endif /* BCM_TRIDENT2_SUPPORT */ 55845 #if defined(BCM_TRIDENT2_SUPPORT) 55846 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 55847 if (!soc_feature(unit, soc_feature_vxlan)) { 55848 return BCM_E_UNAVAIL; 55849 } 55850 if (match->match == BCM_PORT_MATCH_PORT 55851 || match->match == BCM_PORT_MATCH_PORT_VLAN_RANGE 55852 || match->match == BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE 55853 || match->match == BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE 55854 ) { 55855 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 55856 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) { 55857 return BCM_E_NOT_FOUND; 55858 } 55859 } else { 55860 if (!soc_feature(unit, soc_feature_vp_sharing)) { 55861 return BCM_E_UNAVAIL; 55862 } 55863 55864 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 55865 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 55866 55867 if (vp_info.vp_type != _bcmVpTypeVxlan) { 55868 return BCM_E_PARAM; 55869 } 55870 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 55871 return BCM_E_PARAM; 55872 } 55873 55874 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_vpn_is_valid(unit, match->vpn)); 55875 } 55876 } else 55877 #endif 55878 #if defined(BCM_TRIDENT2_SUPPORT) 55879 if (BCM_GPORT_IS_L2GRE_PORT(port)) { 55880 if (!soc_feature(unit, soc_feature_l2gre)) { 55881 return BCM_E_UNAVAIL; 55882 } 55883 if (match->match == BCM_PORT_MATCH_PORT) { 55884 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 55885 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre))) { 55886 return BCM_E_NOT_FOUND; 55887 } 55888 } else { 55889 if (!soc_feature(unit, soc_feature_vp_sharing)) { 55890 return BCM_E_UNAVAIL; 55891 } 55892 55893 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 55894 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 55895 55896 if (vp_info.vp_type != _bcmVpTypeL2Gre) { 55897 return BCM_E_PARAM; 55898 } 55899 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 55900 return BCM_E_PARAM; 55901 } 55902 55903 BCM_IF_ERROR_RETURN(_bcm_tr3_l2gre_vpn_is_valid(unit, match->vpn)); 55904 } 55905 } else 55906 #endif 55907 55908 55909 #if defined(BCM_TRIUMPH2_SUPPORT) 55910 if (BCM_GPORT_IS_VLAN_PORT(port)) { 55911 if (!soc_feature(unit, soc_feature_lltag)) { 55912 return BCM_E_UNAVAIL; 55913 } 55914 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 55915 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan))) { 55916 return BCM_E_NOT_FOUND; 55917 } 55918 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_port_phys_gport_get(unit, vp, &gp)); 55919 } else 55920 #endif 55921 #if defined(BCM_TRIDENT_SUPPORT) 55922 if (BCM_GPORT_IS_NIV_PORT(port)) { 55923 if (!soc_feature(unit, soc_feature_niv)) { 55924 return BCM_E_UNAVAIL; 55925 } 55926 vp = BCM_GPORT_NIV_PORT_ID_GET(port); 55927 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv))) { 55928 return BCM_E_PARAM; 55929 } 55930 } else 55931 #endif /* BCM_TRIDENT_SUPPORT */ 55932 #if defined(BCM_TRIDENT3_SUPPORT) 55933 if (BCM_GPORT_IS_MIRROR(port)) { 55934 if (!soc_feature(unit, soc_feature_mirror_encap_profile)) { 55935 return BCM_E_UNAVAIL; 55936 } 55937 if ((match->match == BCM_PORT_MATCH_PORT_VLAN) || 55938 (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) || 55939 (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) { 55940 55941 SOC_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver)); 55942 if (SOC_IS_TRIDENT3(unit) && 55943 SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) { 55944 if ((match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) || 55945 (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) { 55946 LOG_ERROR(BSL_LS_BCM_PORT, 55947 (BSL_META_U(unit, 55948 "BCM_PORT_MATCH_PORT_I2E_CLASS match criteria \ 55949 not supported in Cancun 5.1.8 release\n"))); 55950 return BCM_E_UNAVAIL; 55951 } 55952 } else { 55953 if (match->match == BCM_PORT_MATCH_PORT_VLAN) { 55954 LOG_ERROR(BSL_LS_BCM_PORT, 55955 (BSL_META_U(unit, 55956 "BCM_PORT_MATCH_PORT_VLAN match criteria \ 55957 not supported after Cancun 5.1.8 release\n"))); 55958 return BCM_E_UNAVAIL; 55959 } 55960 55961 /* check if max I2E class_id */ 55962 if (match->match_vlan > _BCM_I2E_CLASS_ID_MAX) { 55963 LOG_ERROR(BSL_LS_BCM_PORT, 55964 (BSL_META_U(unit, " %d exceeds I2E class_id max %d\n"), 55965 match->match_vlan,_BCM_I2E_CLASS_ID_MAX)); 55966 return BCM_E_PARAM; 55967 } 55968 } 55969 55970 bcm_mirror_destination_t_init(&mirror_dest); 55971 BCM_IF_ERROR_RETURN(bcm_esw_mirror_destination_get(unit, port, 55972 &mirror_dest)); 55973 if (mirror_dest.flags & BCM_MIRROR_DEST_FIELD) { 55974 return BCM_E_PARAM; 55975 } 55976 } else { 55977 return BCM_E_PARAM; 55978 } 55979 } else 55980 #endif /* BCM_TRIDENT3_SUPPORT */ 55981 { 55982 return BCM_E_PORT; 55983 } 55984 55985 switch (match->match) { 55986 case BCM_PORT_MATCH_NONE: 55987 rv = BCM_E_NONE; 55988 break; 55989 #if defined(BCM_TRIDENT2_SUPPORT) 55990 case BCM_PORT_MATCH_PORT: 55991 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 55992 bcm_vxlan_port_t_init(&vxlan_port); 55993 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT; 55994 vxlan_port.vxlan_port_id = port; 55995 vxlan_port.match_port = match->port; 55996 BCM_IF_ERROR_RETURN( 55997 _bcm_td2_vxlan_match_add(unit, &vxlan_port, vp, 0)); 55998 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 55999 bcm_l2gre_port_t_init(&l2gre_port); 56000 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT; 56001 l2gre_port.l2gre_port_id = port; 56002 l2gre_port.match_port = match->port; 56003 BCM_IF_ERROR_RETURN( 56004 bcm_td2_l2gre_match_add(unit, &l2gre_port, vp, 0)); 56005 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 56006 #if defined(BCM_MPLS_SUPPORT) 56007 bcm_mpls_port_t mpls_port; 56008 bcm_mpls_port_t_init(&mpls_port); 56009 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT; 56010 mpls_port.mpls_port_id = port; 56011 mpls_port.port = match->port; 56012 BCM_IF_ERROR_RETURN( 56013 _bcm_tr_mpls_match_add(unit, &mpls_port, vp, 0, TRUE)); 56014 #endif 56015 } else { 56016 rv = BCM_E_PARAM; 56017 } 56018 break; 56019 #endif 56020 56021 case BCM_PORT_MATCH_PORT_I2E_CLASS: 56022 case BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE: 56023 #if defined(BCM_TRIDENT3_SUPPORT) 56024 if (BCM_GPORT_IS_MIRROR(port)) { 56025 rv = _bcm_mirror_port_match_add(unit, &mirror_dest, match->port, 56026 match->match_vlan, match->match); 56027 } else 56028 #endif 56029 { 56030 rv = BCM_E_UNAVAIL; 56031 } 56032 break; 56033 56034 case BCM_PORT_MATCH_PORT_VLAN: 56035 #if defined(BCM_TRIDENT3_SUPPORT) 56036 if (BCM_GPORT_IS_MIRROR(port)) { 56037 rv = _bcm_mirror_port_match_add(unit, &mirror_dest, match->port, 56038 match->match_vlan, match->match); 56039 break; 56040 } else 56041 #endif /* BCM_TRIDENT3_SUPPORT */ 56042 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 56043 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 56044 /* match_info translation to vxlan_port */ 56045 bcm_vxlan_port_t_init(&vxlan_port); 56046 VLAN_CHK_ID(unit, match->match_vlan); 56047 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN; 56048 vxlan_port.match_vlan = match->match_vlan; 56049 vxlan_port.vxlan_port_id = port; 56050 vxlan_port.match_port = match->port; 56051 56052 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit, 56053 &vxlan_port, vp, match->vpn)); 56054 break; 56055 } else if (BCM_GPORT_IS_MIM_PORT(port) && 56056 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56057 bcm_mim_port_t mim_port; 56058 bcm_mim_port_t_init(&mim_port); 56059 VLAN_CHK_ID(unit, match->match_vlan); 56060 mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN; 56061 mim_port.match_vlan = match->match_vlan; 56062 mim_port.mim_port_id = port; 56063 mim_port.port = match->port; 56064 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_add(unit, 56065 &mim_port, vp, match->vpn)); 56066 break; 56067 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 56068 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56069 bcm_mpls_port_t mpls_port; 56070 bcm_mpls_port_t_init(&mpls_port); 56071 VLAN_CHK_ID(unit, match->match_vlan); 56072 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN; 56073 mpls_port.match_vlan = match->match_vlan; 56074 mpls_port.mpls_port_id = port; 56075 mpls_port.port = match->port; 56076 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit, 56077 &mpls_port, vp, match->vpn, TRUE)); 56078 break; 56079 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 56080 /* match_info translation to L2GRE_port */ 56081 bcm_l2gre_port_t_init(&l2gre_port); 56082 VLAN_CHK_ID(unit, match->match_vlan); 56083 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN; 56084 l2gre_port.match_vlan = match->match_vlan; 56085 l2gre_port.l2gre_port_id = port; 56086 l2gre_port.match_port = match->port; 56087 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit, 56088 &l2gre_port, vp, match->vpn)); 56089 break; 56090 } 56091 #endif 56092 56093 /* Add an entry in the VLAN_XLATE table */ 56094 /* Tag actions need to be adjusted by calling the 56095 bcm_vlan_translate_action_add API for the entry we are creating */ 56096 VLAN_CHK_ID(unit, match->match_vlan); 56097 if (BCM_GPORT_IS_MODPORT(match->port) || 56098 BCM_GPORT_IS_TRUNK(match->port)) { 56099 /* Use the port from bcm_port_match_info_t instead of the physical 56100 port from the VP */ 56101 gp = match->port; 56102 } 56103 56104 rv = _bcm_tr_vlan_translate_vp_add(unit, gp, 56105 bcmVlanTranslateKeyPortOuter, 56106 match->match_vlan, 56107 BCM_VLAN_INVALID, 56108 vp, match->action, 56109 &existing_updated); 56110 if (BCM_GPORT_IS_MIM_PORT(port)) { 56111 #if defined(BCM_TRIUMPH2_SUPPORT) 56112 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 56113 #endif 56114 } else if (BCM_GPORT_IS_MPLS_PORT(port) && !existing_updated) { 56115 #if defined(BCM_MPLS_SUPPORT) 56116 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1); 56117 #endif 56118 } 56119 break; 56120 56121 case BCM_PORT_MATCH_PORT_INNER_VLAN: 56122 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 56123 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 56124 bcm_vxlan_port_t_init(&vxlan_port); 56125 VLAN_CHK_ID(unit, match->match_inner_vlan); 56126 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_INNER_VLAN; 56127 vxlan_port.match_inner_vlan = match->match_inner_vlan; 56128 vxlan_port.vxlan_port_id = port; 56129 vxlan_port.match_port = match->port; 56130 56131 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit, 56132 &vxlan_port, vp, match->vpn)); 56133 break; 56134 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 56135 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56136 bcm_mpls_port_t mpls_port; 56137 bcm_mpls_port_t_init(&mpls_port); 56138 VLAN_CHK_ID(unit, match->match_inner_vlan); 56139 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_INNER_VLAN; 56140 mpls_port.match_inner_vlan = match->match_inner_vlan; 56141 mpls_port.mpls_port_id = port; 56142 mpls_port.port = match->port; 56143 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit, 56144 &mpls_port, vp, match->vpn, TRUE)); 56145 break; 56146 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 56147 /* match_info translation to L2GRE_port */ 56148 bcm_l2gre_port_t_init(&l2gre_port); 56149 VLAN_CHK_ID(unit, match->match_vlan); 56150 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN; 56151 l2gre_port.match_inner_vlan = match->match_inner_vlan; 56152 l2gre_port.l2gre_port_id = port; 56153 l2gre_port.match_port = match->port; 56154 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit, 56155 &l2gre_port, vp, match->vpn)); 56156 break; 56157 } 56158 #endif 56159 /* Add an entry in the VLAN_XLATE table */ 56160 /* Tag actions need to be adjusted by calling the 56161 * bcm_vlan_translate_action_add API for the entry we are creating */ 56162 VLAN_CHK_ID(unit, match->match_inner_vlan); 56163 if (BCM_GPORT_IS_MODPORT(match->port) || 56164 BCM_GPORT_IS_TRUNK(match->port)) { 56165 /* Use the port from bcm_port_match_info_t instead of the physical 56166 port from the VP */ 56167 gp = match->port; 56168 } 56169 56170 rv = _bcm_tr_vlan_translate_vp_add(unit, gp, 56171 bcmVlanTranslateKeyPortInner, 56172 BCM_VLAN_INVALID, 56173 match->match_inner_vlan, 56174 vp, match->action, 56175 &existing_updated); 56176 break; 56177 56178 case BCM_PORT_MATCH_PORT_VLAN16: 56179 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 56180 if (BCM_GPORT_IS_VXLAN_PORT(port) && 56181 ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) { 56182 bcm_vxlan_port_t_init(&vxlan_port); 56183 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI; 56184 vxlan_port.match_vlan = match->match_vlan; 56185 vxlan_port.vxlan_port_id = port; 56186 vxlan_port.match_port = match->port; 56187 56188 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit, 56189 &vxlan_port, vp, match->vpn)); 56190 break; 56191 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 56192 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT) && 56193 ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) { 56194 bcm_mpls_port_t mpls_port; 56195 bcm_mpls_port_t_init(&mpls_port); 56196 mpls_port.criteria = BCM_MPLS_PORT_MATCH_VLAN_PRI; 56197 mpls_port.match_vlan = match->match_vlan; 56198 mpls_port.mpls_port_id = port; 56199 mpls_port.port = match->port; 56200 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit, 56201 &mpls_port, vp, match->vpn, TRUE)); 56202 break; 56203 } else if (BCM_GPORT_IS_L2GRE_PORT(port) && 56204 ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) { 56205 /* match_info translation to L2GRE_port */ 56206 bcm_l2gre_port_t_init(&l2gre_port); 56207 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_VLAN_PRI; 56208 l2gre_port.match_vlan = match->match_vlan; 56209 l2gre_port.l2gre_port_id = port; 56210 l2gre_port.match_port = match->port; 56211 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit, 56212 &l2gre_port, vp, match->vpn)); 56213 break; 56214 } 56215 #endif 56216 /* Add an entry in the VLAN_XLATE table */ 56217 /* Tag actions need to be adjusted by calling the 56218 bcm_vlan_translate_action_add API for the entry we are creating */ 56219 if (BCM_GPORT_IS_MODPORT(match->port) || 56220 BCM_GPORT_IS_TRUNK(match->port)) { 56221 /* Use the port from bcm_port_match_info_t instead of the physical 56222 port from the VP */ 56223 gp = match->port; 56224 } 56225 56226 /* allow 16 bit VLAN id */ 56227 rv = _bcm_tr_vlan_translate_vp_add(unit, gp, 56228 bcmVlanTranslateKeyPortOuterTag, 56229 match->match_vlan, 56230 BCM_VLAN_INVALID, 56231 vp, match->action, 56232 &existing_updated); 56233 if (BCM_GPORT_IS_MIM_PORT(port)) { 56234 #if defined(BCM_TRIUMPH2_SUPPORT) 56235 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 56236 #endif 56237 } else if (BCM_GPORT_IS_MPLS_PORT(port) && !existing_updated) { 56238 #if defined(BCM_MPLS_SUPPORT) 56239 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1); 56240 #endif 56241 } 56242 break; 56243 56244 56245 case BCM_PORT_MATCH_PORT_VLAN_STACKED: 56246 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 56247 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 56248 /* match_info translation to vxlan_port */ 56249 bcm_vxlan_port_t_init(&vxlan_port); 56250 VLAN_CHK_ID(unit, match->match_vlan); 56251 VLAN_CHK_ID(unit, match->match_inner_vlan); 56252 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN_STACKED; 56253 vxlan_port.match_vlan = match->match_vlan; 56254 vxlan_port.match_inner_vlan = match->match_inner_vlan; 56255 vxlan_port.vxlan_port_id = port; 56256 vxlan_port.match_port = match->port; 56257 56258 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_add(unit, 56259 &vxlan_port, vp, match->vpn)); 56260 break; 56261 } else if (BCM_GPORT_IS_MIM_PORT(port) && 56262 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56263 bcm_mim_port_t mim_port; 56264 bcm_mim_port_t_init(&mim_port); 56265 VLAN_CHK_ID(unit, match->match_vlan); 56266 VLAN_CHK_ID(unit, match->match_inner_vlan); 56267 mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN_STACKED; 56268 mim_port.match_vlan = match->match_vlan; 56269 mim_port.match_inner_vlan = match->match_inner_vlan; 56270 mim_port.mim_port_id = port; 56271 mim_port.port = match->port; 56272 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_add(unit, 56273 &mim_port, vp, match->vpn)); 56274 break; 56275 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 56276 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56277 bcm_mpls_port_t mpls_port; 56278 bcm_mpls_port_t_init(&mpls_port); 56279 VLAN_CHK_ID(unit, match->match_vlan); 56280 VLAN_CHK_ID(unit, match->match_inner_vlan); 56281 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN_STACKED; 56282 mpls_port.match_vlan = match->match_vlan; 56283 mpls_port.match_inner_vlan = match->match_inner_vlan; 56284 mpls_port.mpls_port_id = port; 56285 mpls_port.port = match->port; 56286 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_add(unit, 56287 &mpls_port, vp, match->vpn, TRUE)); 56288 break; 56289 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 56290 /* match_info translation to L2GRE_port */ 56291 bcm_l2gre_port_t_init(&l2gre_port); 56292 VLAN_CHK_ID(unit, match->match_vlan); 56293 VLAN_CHK_ID(unit, match->match_inner_vlan); 56294 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED; 56295 l2gre_port.match_vlan = match->match_vlan; 56296 l2gre_port.match_inner_vlan = match->match_inner_vlan; 56297 l2gre_port.l2gre_port_id = port; 56298 l2gre_port.match_port = match->port; 56299 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_add(unit, 56300 &l2gre_port, vp, match->vpn)); 56301 break; 56302 } 56303 #endif 56304 56305 /* Add an entry in the VLAN_XLATE table */ 56306 /* Tag actions need to be adjusted by calling the 56307 bcm_vlan_translate_action_add API for the entry we are creating */ 56308 VLAN_CHK_ID(unit, match->match_vlan); 56309 VLAN_CHK_ID(unit, match->match_inner_vlan); 56310 if (BCM_GPORT_IS_MODPORT(match->port) || 56311 BCM_GPORT_IS_TRUNK(match->port)) { 56312 /* Use the port from bcm_port_match_info_t instead of the physical 56313 port from the VP */ 56314 gp = match->port; 56315 } 56316 rv = _bcm_tr_vlan_translate_vp_add(unit, gp, 56317 bcmVlanTranslateKeyPortDouble, 56318 match->match_vlan, 56319 match->match_inner_vlan, 56320 vp, match->action, 56321 &existing_updated); 56322 if (BCM_GPORT_IS_MIM_PORT(port)) { 56323 #if defined(BCM_TRIUMPH2_SUPPORT) 56324 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 56325 #endif 56326 } else if (BCM_GPORT_IS_MPLS_PORT(port) && !existing_updated) { 56327 #if defined(BCM_MPLS_SUPPORT) 56328 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1); 56329 #endif 56330 } 56331 break; 56332 case BCM_PORT_MATCH_PORT_VLAN_RANGE: 56333 #if defined(BCM_TRIUMPH2_SUPPORT) 56334 /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */ 56335 /* Tag actions need to be adjusted by calling the 56336 bcm_vlan_translate_action_add API for the entry we are creating */ 56337 VLAN_CHK_ID(unit, match->match_vlan); 56338 VLAN_CHK_ID(unit, match->match_vlan_max); 56339 if (BCM_GPORT_IS_MODPORT(match->port) || 56340 BCM_GPORT_IS_TRUNK(match->port)) { 56341 /* Use the port from bcm_port_match_info_t instead of the physical 56342 port from the VP */ 56343 gp = match->port; 56344 } 56345 56346 rv = _bcm_tr2_vlan_translate_range_vp_add(unit, gp, 56347 match->match_vlan, 56348 match->match_vlan_max, 56349 BCM_VLAN_INVALID, 56350 BCM_VLAN_INVALID, 56351 vp, match->action); 56352 if (BCM_SUCCESS(rv)) { 56353 if (BCM_GPORT_IS_MIM_PORT(port)) { 56354 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 56355 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 56356 #if defined(BCM_MPLS_SUPPORT) 56357 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1); 56358 #endif 56359 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 56360 #if defined(BCM_TRIDENT2_SUPPORT) 56361 bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1); 56362 #endif 56363 } 56364 } 56365 #endif 56366 break; 56367 case BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE: 56368 #if defined(BCM_TRIUMPH2_SUPPORT) 56369 if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) { 56370 return BCM_E_UNAVAIL; 56371 } 56372 /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */ 56373 /* Tag actions need to be adjusted by calling the 56374 bcm_vlan_translate_action_add API for the entry we are creating */ 56375 VLAN_CHK_ID(unit, match->match_inner_vlan); 56376 VLAN_CHK_ID(unit, match->match_inner_vlan_max); 56377 if (BCM_GPORT_IS_MODPORT(match->port) || 56378 BCM_GPORT_IS_TRUNK(match->port)) { 56379 /* Use the port from bcm_port_match_info_t instead of the physical 56380 port from the VP */ 56381 gp = match->port; 56382 } 56383 56384 rv = _bcm_tr2_vlan_translate_range_vp_add(unit, gp, 56385 BCM_VLAN_INVALID, 56386 BCM_VLAN_INVALID, 56387 match->match_inner_vlan, 56388 match->match_inner_vlan_max, 56389 vp, match->action); 56390 if (BCM_SUCCESS(rv)) { 56391 if (BCM_GPORT_IS_MIM_PORT(port)) { 56392 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 56393 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 56394 #if defined(BCM_MPLS_SUPPORT) 56395 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1); 56396 #endif 56397 } 56398 } 56399 #endif 56400 break; 56401 case BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE: 56402 #if defined(BCM_TRIUMPH2_SUPPORT) 56403 if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) { 56404 return BCM_E_UNAVAIL; 56405 } 56406 /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */ 56407 /* Tag actions need to be adjusted by calling the 56408 bcm_vlan_translate_action_add API for the entry we are creating */ 56409 VLAN_CHK_ID(unit, match->match_vlan); 56410 VLAN_CHK_ID(unit, match->match_vlan_max); 56411 VLAN_CHK_ID(unit, match->match_inner_vlan); 56412 VLAN_CHK_ID(unit, match->match_inner_vlan_max); 56413 if (BCM_GPORT_IS_MODPORT(match->port) || 56414 BCM_GPORT_IS_TRUNK(match->port)) { 56415 /* Use the port from bcm_port_match_info_t instead of the physical 56416 port from the VP */ 56417 gp = match->port; 56418 } 56419 56420 rv = _bcm_tr2_vlan_translate_range_vp_add(unit, gp, 56421 match->match_vlan, 56422 match->match_vlan_max, 56423 match->match_inner_vlan, 56424 match->match_inner_vlan_max, 56425 vp, match->action); 56426 if (BCM_SUCCESS(rv)) { 56427 if (BCM_GPORT_IS_MIM_PORT(port)) { 56428 _bcm_tr2_mim_port_match_count_adjust(unit, vp, 1); 56429 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 56430 #if defined(BCM_MPLS_SUPPORT) 56431 bcm_tr_mpls_port_match_count_adjust(unit, vp, 1); 56432 #endif 56433 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 56434 #if defined(BCM_TRIDENT2_SUPPORT) 56435 bcm_td2_vxlan_port_match_count_adjust(unit, vp, 1); 56436 #endif 56437 } 56438 } 56439 #endif 56440 break; 56441 56442 #if defined(BCM_TRIUMPH3_SUPPORT) 56443 case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID: 56444 case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN: 56445 rv = _bcm_esw_extender_port_match_add(unit, match->port, 56446 match->extended_port_vid, 56447 match->match_vlan, vp); 56448 break; 56449 #endif 56450 56451 #ifdef BCM_TRIUMPH2_SUPPORT 56452 case BCM_PORT_MATCH_PORT_PON_TUNNEL: 56453 case BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN: 56454 case BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN: 56455 if (!BCM_GPORT_IS_VLAN_PORT(port)) { 56456 return BCM_E_UNAVAIL; 56457 } 56458 if (BCM_GPORT_IS_MODPORT(match->port) || 56459 BCM_GPORT_IS_TRUNK(match->port)) { 56460 if (match->port != gp) { 56461 return BCM_E_PORT; 56462 } 56463 } else if (BCM_GPORT_IS_LOCAL(match->port)) { 56464 bcm_module_t modid; 56465 bcm_trunk_t trunk_id; 56466 bcm_port_t port_num; 56467 bcm_gport_t modport; 56468 int id; 56469 56470 BCM_IF_ERROR_RETURN (_bcm_esw_gport_resolve(unit, 56471 match->port, &modid, &port_num, &trunk_id, &id)); 56472 if (trunk_id != BCM_TRUNK_INVALID) { 56473 BCM_GPORT_TRUNK_SET(modport, trunk_id); 56474 } else { 56475 BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, 56476 BCM_STK_MODMAP_GET, modid, port_num, &modid, &port_num)); 56477 BCM_GPORT_MODPORT_SET(modport, modid, port_num); 56478 } 56479 56480 if (modport != gp) { 56481 return BCM_E_PORT; 56482 } 56483 }else { 56484 return BCM_E_PORT; 56485 } 56486 56487 VLAN_CHK_ID(unit, match->match_pon_tunnel); 56488 if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL) { 56489 rv = _bcm_tr_lltag_vlan_translate_vp_add(unit, gp, bcmVlanTranslateKeyPortPonTunnel, 56490 match->match_pon_tunnel, 56491 BCM_VLAN_INVALID, 56492 vp, 56493 match->action); 56494 } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN) { 56495 VLAN_CHK_ID(unit, match->match_vlan); 56496 rv = _bcm_tr_lltag_vlan_translate_vp_add(unit, gp, bcmVlanTranslateKeyPortPonTunnelOuter, 56497 match->match_pon_tunnel, 56498 match->match_vlan, 56499 vp, 56500 match->action); 56501 } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN) { 56502 VLAN_CHK_ID(unit, match->match_inner_vlan); 56503 rv = _bcm_tr_lltag_vlan_translate_vp_add(unit, gp, bcmVlanTranslateKeyPortPonTunnelInner, 56504 match->match_pon_tunnel, 56505 match->match_inner_vlan, 56506 vp, 56507 match->action); 56508 } 56509 56510 if (BCM_FAILURE(rv)) { 56511 return rv; 56512 } 56513 56514 bcm_tr2_vlan_port_match_count_adjust(unit, vp, 1); 56515 break; 56516 #endif 56517 #if defined(BCM_TRIDENT_SUPPORT) 56518 case BCM_PORT_MATCH_PORT_NIV_PORT_VIF: 56519 case BCM_PORT_MATCH_PORT_NIV_PORT_VIF_VLAN: 56520 rv = _bcm_trident_niv_match_add(unit, match->port, 56521 match->niv_port_vif, 56522 match->match_vlan, vp); 56523 break; 56524 #endif /* BCM_TRIDENT_SUPPORT */ 56525 #if defined(BCM_TRX_SUPPORT) 56526 case BCM_PORT_MATCH_MAC_PORT: 56527 case BCM_PORT_MATCH_MAC_PORT_CLASS: 56528 bcm_vlan_match_info_t_init(&vlan_match_info); 56529 if (match->match == BCM_PORT_MATCH_MAC_PORT) { 56530 vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT; 56531 vlan_match_info.port = match->port; 56532 } else if (match->match == BCM_PORT_MATCH_MAC_PORT_CLASS) { 56533 vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT_CLASS; 56534 vlan_match_info.port_class = match->port_class; 56535 } 56536 sal_memcpy(vlan_match_info.src_mac, 56537 match->src_mac, sizeof (bcm_mac_t)); 56538 rv = _bcm_trx_vlan_match_action_add(unit, 0, 56539 port, &vlan_match_info, match->action); 56540 break; 56541 #endif 56542 default: 56543 rv = BCM_E_PARAM; 56544 break; 56545 } 56546 return rv; 56547 #else 56548 return BCM_E_UNAVAIL; 56549 #endif 56550 } 56551 56552 /* 56553 * Function: 56554 * bcm_port_match_delete 56555 * Purpose: 56556 * Remove a match from an existing port 56557 * Parameters: 56558 * unit - (IN) Unit number. 56559 * port - (IN) Port or gport 56560 * match - (IN) Match criteria 56561 * Returns: 56562 * BCM_E_xxx 56563 * Notes: 56564 */ 56565 int 56566 bcm_esw_port_match_delete( 56567 int unit, 56568 bcm_gport_t port, 56569 bcm_port_match_info_t *match) 56570 { 56571 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 56572 int vp=0, rv = BCM_E_NONE; 56573 bcm_gport_t gp = 0; 56574 #if defined(BCM_TRIUMPH2_SUPPORT) || defined(BCM_MPLS_SUPPORT) 56575 _bcm_vp_info_t vp_info; 56576 #endif 56577 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 56578 bcm_vxlan_port_t vxlan_port; 56579 bcm_l2gre_port_t l2gre_port; 56580 #endif 56581 #if defined(BCM_TRIDENT3_SUPPORT) 56582 bcm_mirror_destination_t mirror_dest; 56583 uint32 cancun_ver; 56584 #endif /* BCM_TRIDENT3_SUPPORT */ 56585 #if defined(BCM_TRX_SUPPORT) 56586 bcm_vlan_match_info_t vlan_match_info; 56587 #endif 56588 56589 if (match == NULL) { 56590 return BCM_E_PARAM; 56591 } 56592 /* Make sure port module is initialized. */ 56593 PORT_INIT(unit); 56594 56595 if (BCM_GPORT_IS_MIM_PORT(port)) { 56596 #if defined(BCM_TRIUMPH2_SUPPORT) 56597 if (!soc_feature(unit, soc_feature_mim)) { 56598 return BCM_E_UNAVAIL; 56599 } 56600 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 56601 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 56602 return BCM_E_NOT_FOUND; 56603 } 56604 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 56605 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56606 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_port_phys_gport_get(unit, vp, &gp)); 56607 } 56608 #endif 56609 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 56610 if (!soc_feature(unit, soc_feature_mpls)) { 56611 return BCM_E_UNAVAIL; 56612 } 56613 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 56614 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 56615 return BCM_E_NOT_FOUND; 56616 } 56617 #if defined(BCM_MPLS_SUPPORT) 56618 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 56619 if ((vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56620 if (!soc_feature(unit, soc_feature_vp_sharing)) { 56621 return BCM_E_UNAVAIL; 56622 } 56623 } else { 56624 BCM_IF_ERROR_RETURN(bcm_tr_mpls_port_phys_gport_get(unit, vp, &gp)); 56625 } 56626 #endif 56627 } else 56628 #if defined(BCM_TRIDENT2_SUPPORT) 56629 if (BCM_GPORT_IS_TRUNK(port)) { 56630 if (!soc_feature(unit, soc_feature_vp_lag)) { 56631 return BCM_E_UNAVAIL; 56632 } 56633 BCM_IF_ERROR_RETURN( 56634 _bcm_esw_trunk_tid_to_vp_lag_vp(unit, BCM_GPORT_TRUNK_GET(port), 56635 &vp)); 56636 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVpLag)) { 56637 return BCM_E_NOT_FOUND; 56638 } 56639 if (match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID && 56640 match->match != BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN) { 56641 return BCM_E_PARAM; 56642 } 56643 } else 56644 #endif /* BCM_TRIDENT2_SUPPORT */ 56645 #if defined(BCM_TRIDENT2_SUPPORT) 56646 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 56647 if (!soc_feature(unit, soc_feature_vxlan)) { 56648 return BCM_E_UNAVAIL; 56649 } 56650 if (match->match == BCM_PORT_MATCH_PORT 56651 || match->match == BCM_PORT_MATCH_PORT_VLAN_RANGE 56652 || match->match == BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE 56653 || match->match == BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE 56654 ) { 56655 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 56656 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) { 56657 return BCM_E_NOT_FOUND; 56658 } 56659 } else { 56660 if (!soc_feature(unit, soc_feature_vp_sharing)) { 56661 return BCM_E_UNAVAIL; 56662 } 56663 56664 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 56665 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 56666 if (vp_info.vp_type != _bcmVpTypeVxlan) { 56667 return BCM_E_PARAM; 56668 } 56669 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56670 return BCM_E_PARAM; 56671 } 56672 } 56673 } else 56674 #endif 56675 #if defined(BCM_TRIDENT2_SUPPORT) 56676 if (BCM_GPORT_IS_L2GRE_PORT(port)) { 56677 if (!soc_feature(unit, soc_feature_l2gre)) { 56678 return BCM_E_UNAVAIL; 56679 } 56680 if (match->match == BCM_PORT_MATCH_PORT) { 56681 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 56682 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre))) { 56683 return BCM_E_NOT_FOUND; 56684 } 56685 } else { 56686 if (!soc_feature(unit, soc_feature_vp_sharing)) { 56687 return BCM_E_UNAVAIL; 56688 } 56689 56690 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 56691 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 56692 56693 if (vp_info.vp_type != _bcmVpTypeL2Gre) { 56694 return BCM_E_PARAM; 56695 } 56696 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56697 return BCM_E_PARAM; 56698 } 56699 } 56700 } else 56701 #endif 56702 56703 #if defined(BCM_TRIUMPH2_SUPPORT) 56704 if (BCM_GPORT_IS_VLAN_PORT(port)) { 56705 if (!soc_feature(unit, soc_feature_lltag)) { 56706 return BCM_E_UNAVAIL; 56707 } 56708 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 56709 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan))) { 56710 return BCM_E_NOT_FOUND; 56711 } 56712 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_port_phys_gport_get(unit, vp, &gp)); 56713 } else 56714 #endif 56715 #if defined(BCM_TRIDENT_SUPPORT) 56716 if (BCM_GPORT_IS_NIV_PORT(port)) { 56717 if (!soc_feature(unit, soc_feature_niv)) { 56718 return BCM_E_UNAVAIL; 56719 } 56720 vp = BCM_GPORT_NIV_PORT_ID_GET(port); 56721 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv))) { 56722 return BCM_E_PARAM; 56723 } 56724 } else 56725 #endif /* BCM_TRIDENT_SUPPORT */ 56726 #if defined(BCM_TRIDENT3_SUPPORT) 56727 if (BCM_GPORT_IS_MIRROR(port)) { 56728 if (!soc_feature(unit, soc_feature_mirror_encap_profile)) { 56729 return BCM_E_UNAVAIL; 56730 } 56731 if ((match->match == BCM_PORT_MATCH_PORT_VLAN) || 56732 (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) || 56733 (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) { 56734 56735 SOC_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver)); 56736 if (SOC_IS_TRIDENT3(unit) && 56737 SOC_CANCUN_VERSION_5_2_UNDER_SERIES(cancun_ver)) { 56738 if ((match->match == BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE) || 56739 (match->match == BCM_PORT_MATCH_PORT_I2E_CLASS)) { 56740 LOG_ERROR(BSL_LS_BCM_PORT, 56741 (BSL_META_U(unit, 56742 "BCM_PORT_MATCH_PORT_I2E_CLASS match criteria \ 56743 not supported in Cancun 5.1.8 release\n"))); 56744 return BCM_E_UNAVAIL; 56745 } 56746 } else { 56747 if (match->match == BCM_PORT_MATCH_PORT_VLAN) { 56748 LOG_ERROR(BSL_LS_BCM_PORT, 56749 (BSL_META_U(unit, 56750 "BCM_PORT_MATCH_PORT_VLAN match criteria \ 56751 not supported after Cancun 5.1.8 release\n"))); 56752 return BCM_E_UNAVAIL; 56753 } 56754 } 56755 56756 bcm_mirror_destination_t_init(&mirror_dest); 56757 BCM_IF_ERROR_RETURN(bcm_esw_mirror_destination_get(unit, port, 56758 &mirror_dest)); 56759 if (mirror_dest.flags & BCM_MIRROR_DEST_FIELD) { 56760 return BCM_E_PARAM; 56761 } 56762 } else { 56763 return BCM_E_PARAM; 56764 } 56765 } else 56766 #endif /* BCM_TRIDENT3_SUPPORT */ 56767 { 56768 return BCM_E_PORT; 56769 } 56770 56771 switch (match->match) { 56772 case BCM_PORT_MATCH_NONE: 56773 rv = BCM_E_NONE; 56774 break; 56775 #if defined(BCM_TRIDENT2_SUPPORT) 56776 case BCM_PORT_MATCH_PORT: 56777 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 56778 bcm_vxlan_port_t_init(&vxlan_port); 56779 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT; 56780 vxlan_port.vxlan_port_id = port; 56781 vxlan_port.match_port = match->port; 56782 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0)); 56783 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 56784 #if defined(BCM_MPLS_SUPPORT) 56785 bcm_mpls_port_t mpls_port; 56786 bcm_mpls_port_t_init(&mpls_port); 56787 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT; 56788 mpls_port.mpls_port_id = port; 56789 mpls_port.port = match->port; 56790 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit, vp, &mpls_port, TRUE)); 56791 #endif 56792 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 56793 bcm_l2gre_port_t_init(&l2gre_port); 56794 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT; 56795 l2gre_port.l2gre_port_id = port; 56796 l2gre_port.match_port = match->port; 56797 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp, &l2gre_port)); 56798 } else { 56799 rv = BCM_E_PARAM; 56800 } 56801 break; 56802 #endif 56803 56804 case BCM_PORT_MATCH_PORT_I2E_CLASS: 56805 case BCM_PORT_MATCH_PORT_I2E_CLASS_IFP_TYPE: 56806 #if defined(BCM_TRIDENT3_SUPPORT) 56807 if (BCM_GPORT_IS_MIRROR(port)) { 56808 rv = _bcm_mirror_port_match_delete(unit, &mirror_dest, match->port, 56809 match->match_vlan, match->match); 56810 } else 56811 #endif 56812 { 56813 rv = BCM_E_UNAVAIL; 56814 } 56815 break; 56816 56817 case BCM_PORT_MATCH_PORT_VLAN: 56818 #if defined(BCM_TRIDENT3_SUPPORT) 56819 if (BCM_GPORT_IS_MIRROR(port)) { 56820 rv = _bcm_mirror_port_match_delete(unit, &mirror_dest, match->port, 56821 match->match_vlan, match->match); 56822 break; 56823 } else 56824 #endif /* BCM_TRIDENT3_SUPPORT */ 56825 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 56826 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 56827 /* match_info translation to vxlan_port */ 56828 bcm_vxlan_port_t_init(&vxlan_port); 56829 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN; 56830 vxlan_port.match_vlan = match->match_vlan; 56831 vxlan_port.vxlan_port_id = port; 56832 vxlan_port.match_port = match->port; 56833 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0)); 56834 break; 56835 } else if (BCM_GPORT_IS_MIM_PORT(port) && 56836 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56837 bcm_mim_port_t mim_port; 56838 bcm_mim_port_t_init(&mim_port); 56839 VLAN_CHK_ID(unit, match->match_vlan); 56840 mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN; 56841 mim_port.match_vlan = match->match_vlan; 56842 mim_port.mim_port_id = port; 56843 mim_port.port = match->port; 56844 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_delete(unit, 56845 vp, mim_port)); 56846 break; 56847 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 56848 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56849 bcm_mpls_port_t mpls_port; 56850 bcm_mpls_port_t_init(&mpls_port); 56851 VLAN_CHK_ID(unit, match->match_vlan); 56852 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN; 56853 mpls_port.match_vlan = match->match_vlan; 56854 mpls_port.mpls_port_id = port; 56855 mpls_port.port = match->port; 56856 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit, 56857 vp, &mpls_port, 0)); 56858 break; 56859 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 56860 /* match_info translation to L2GRE_port */ 56861 bcm_l2gre_port_t_init(&l2gre_port); 56862 VLAN_CHK_ID(unit, match->match_vlan); 56863 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN; 56864 l2gre_port.match_vlan = match->match_vlan; 56865 l2gre_port.l2gre_port_id = port; 56866 l2gre_port.match_port = match->port; 56867 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit,vp, 56868 &l2gre_port)); 56869 break; 56870 } 56871 #endif 56872 56873 /* Add an entry in the VLAN_XLATE table */ 56874 /* Tag actions need to be adjusted by calling the 56875 bcm_vlan_translate_action_add API for the entry we are creating */ 56876 VLAN_CHK_ID(unit, match->match_vlan); 56877 if (BCM_GPORT_IS_MODPORT(match->port) || 56878 BCM_GPORT_IS_TRUNK(match->port)) { 56879 /* Use the port from bcm_port_match_info_t instead of the physical 56880 port from the VP */ 56881 gp = match->port; 56882 } 56883 rv = _bcm_tr_vlan_translate_vp_delete(unit, gp, 56884 bcmVlanTranslateKeyPortOuter, 56885 match->match_vlan, 56886 BCM_VLAN_INVALID, 56887 vp); 56888 56889 if (BCM_GPORT_IS_MIM_PORT(port)) { 56890 #if defined(BCM_TRIUMPH2_SUPPORT) 56891 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 56892 #endif 56893 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 56894 #if defined(BCM_MPLS_SUPPORT) 56895 bcm_tr_mpls_port_match_count_adjust(unit, vp, -1); 56896 #endif 56897 } 56898 break; 56899 56900 case BCM_PORT_MATCH_PORT_INNER_VLAN: 56901 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 56902 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 56903 bcm_vxlan_port_t_init(&vxlan_port); 56904 VLAN_CHK_ID(unit, match->match_inner_vlan); 56905 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_INNER_VLAN; 56906 vxlan_port.match_inner_vlan = match->match_inner_vlan; 56907 vxlan_port.vxlan_port_id = port; 56908 vxlan_port.match_port = match->port; 56909 56910 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0)); 56911 break; 56912 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 56913 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56914 bcm_mpls_port_t mpls_port; 56915 bcm_mpls_port_t_init(&mpls_port); 56916 VLAN_CHK_ID(unit, match->match_inner_vlan); 56917 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_INNER_VLAN; 56918 mpls_port.match_inner_vlan = match->match_inner_vlan; 56919 mpls_port.mpls_port_id = port; 56920 mpls_port.port = match->port; 56921 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit, 56922 vp, &mpls_port, 0)); 56923 break; 56924 } else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 56925 /* match_info translation to L2GRE_port */ 56926 bcm_l2gre_port_t_init(&l2gre_port); 56927 VLAN_CHK_ID(unit, match->match_inner_vlan); 56928 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_INNER_VLAN; 56929 l2gre_port.match_inner_vlan = match->match_inner_vlan; 56930 l2gre_port.l2gre_port_id = port; 56931 l2gre_port.match_port = match->port; 56932 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp, 56933 &l2gre_port)); 56934 break; 56935 } 56936 #endif 56937 /* Add an entry in the VLAN_XLATE table */ 56938 /* Tag actions need to be adjusted by calling the 56939 * bcm_vlan_translate_action_add API for the entry we are creating */ 56940 VLAN_CHK_ID(unit, match->match_inner_vlan); 56941 if (BCM_GPORT_IS_MODPORT(match->port) || 56942 BCM_GPORT_IS_TRUNK(match->port)) { 56943 /* Use the port from bcm_port_match_info_t instead of the physical 56944 port from the VP */ 56945 gp = match->port; 56946 } 56947 56948 rv = _bcm_tr_vlan_translate_vp_delete(unit, gp, 56949 bcmVlanTranslateKeyPortInner, 56950 BCM_VLAN_INVALID, 56951 match->match_inner_vlan, 56952 vp); 56953 break; 56954 56955 case BCM_PORT_MATCH_PORT_VLAN16: 56956 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 56957 if (BCM_GPORT_IS_VXLAN_PORT(port) && 56958 ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) { 56959 bcm_vxlan_port_t_init(&vxlan_port); 56960 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI; 56961 vxlan_port.match_vlan = match->match_vlan; 56962 vxlan_port.vxlan_port_id = port; 56963 vxlan_port.match_port = match->port; 56964 56965 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0)); 56966 break; 56967 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 56968 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 56969 bcm_mpls_port_t mpls_port; 56970 bcm_mpls_port_t_init(&mpls_port); 56971 mpls_port.criteria = BCM_MPLS_PORT_MATCH_VLAN_PRI; 56972 mpls_port.match_vlan = match->match_vlan; 56973 mpls_port.mpls_port_id = port; 56974 mpls_port.port = match->port; 56975 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit, 56976 vp, &mpls_port, 0)); 56977 break; 56978 } else if (BCM_GPORT_IS_L2GRE_PORT(port) && 56979 ((match->match_vlan & 0xfff) == BCM_VLAN_NONE)) { 56980 /* match_info translation to L2GRE_port */ 56981 bcm_l2gre_port_t_init(&l2gre_port); 56982 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_VLAN_PRI; 56983 l2gre_port.match_vlan = match->match_vlan; 56984 l2gre_port.l2gre_port_id = port; 56985 l2gre_port.match_port = match->port; 56986 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp, 56987 &l2gre_port)); 56988 break; 56989 } 56990 #endif 56991 /* Add an entry in the VLAN_XLATE table */ 56992 /* Tag actions need to be adjusted by calling the 56993 bcm_vlan_translate_action_add API for the entry we are creating */ 56994 if (BCM_GPORT_IS_MODPORT(match->port) || 56995 BCM_GPORT_IS_TRUNK(match->port)) { 56996 /* Use the port from bcm_port_match_info_t instead of the physical 56997 port from the VP */ 56998 gp = match->port; 56999 } 57000 /* allow 16 bit VLAN id */ 57001 rv = _bcm_tr_vlan_translate_vp_delete(unit, gp, 57002 bcmVlanTranslateKeyPortOuterTag, 57003 match->match_vlan, 57004 BCM_VLAN_INVALID, 57005 vp); 57006 57007 if (BCM_GPORT_IS_MIM_PORT(port)) { 57008 #if defined(BCM_TRIUMPH2_SUPPORT) 57009 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 57010 #endif 57011 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 57012 #if defined(BCM_MPLS_SUPPORT) 57013 bcm_tr_mpls_port_match_count_adjust(unit, vp, -1); 57014 #endif 57015 } 57016 break; 57017 case BCM_PORT_MATCH_PORT_VLAN_STACKED: 57018 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 57019 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 57020 /* match_info translation to vxlan_port */ 57021 bcm_vxlan_port_t_init(&vxlan_port); 57022 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_PORT_VLAN_STACKED; 57023 vxlan_port.match_vlan = match->match_vlan; 57024 vxlan_port.match_inner_vlan = match->match_inner_vlan; 57025 vxlan_port.vxlan_port_id = port; 57026 vxlan_port.match_port = match->port; 57027 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0)); 57028 break; 57029 } else if (BCM_GPORT_IS_MIM_PORT(port) && 57030 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57031 bcm_mim_port_t mim_port; 57032 bcm_mim_port_t_init(&mim_port); 57033 VLAN_CHK_ID(unit, match->match_vlan); 57034 VLAN_CHK_ID(unit, match->match_inner_vlan); 57035 mim_port.criteria = BCM_MIM_PORT_MATCH_PORT_VLAN_STACKED; 57036 mim_port.match_vlan = match->match_vlan; 57037 mim_port.match_inner_vlan = match->match_inner_vlan; 57038 mim_port.mim_port_id = port; 57039 mim_port.port = match->port; 57040 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_match_delete(unit, 57041 vp, mim_port)); 57042 break; 57043 } else if (BCM_GPORT_IS_MPLS_PORT(port) && 57044 (vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57045 bcm_mpls_port_t mpls_port; 57046 bcm_mpls_port_t_init(&mpls_port); 57047 VLAN_CHK_ID(unit, match->match_vlan); 57048 VLAN_CHK_ID(unit, match->match_inner_vlan); 57049 mpls_port.criteria = BCM_MPLS_PORT_MATCH_PORT_VLAN_STACKED; 57050 mpls_port.match_vlan = match->match_vlan; 57051 mpls_port.match_inner_vlan = match->match_inner_vlan; 57052 mpls_port.mpls_port_id = port; 57053 mpls_port.port = match->port; 57054 BCM_IF_ERROR_RETURN(_bcm_tr_mpls_match_delete(unit, 57055 vp, &mpls_port, 0)); 57056 break; 57057 }else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 57058 /* match_info translation to L2GRE_port */ 57059 bcm_l2gre_port_t_init(&l2gre_port); 57060 l2gre_port.criteria = BCM_L2GRE_PORT_MATCH_PORT_VLAN_STACKED; 57061 l2gre_port.match_vlan = match->match_vlan; 57062 l2gre_port.match_inner_vlan = match->match_inner_vlan; 57063 l2gre_port.l2gre_port_id = port; 57064 l2gre_port.match_port = match->port; 57065 BCM_IF_ERROR_RETURN(bcm_td2_l2gre_match_delete(unit, vp, 57066 &l2gre_port)); 57067 break; 57068 } 57069 #endif 57070 /* Add an entry in the VLAN_XLATE table */ 57071 /* Tag actions need to be adjusted by calling the 57072 bcm_vlan_translate_action_add API for the entry we are creating */ 57073 VLAN_CHK_ID(unit, match->match_vlan); 57074 VLAN_CHK_ID(unit, match->match_inner_vlan); 57075 if (BCM_GPORT_IS_MODPORT(match->port) || 57076 BCM_GPORT_IS_TRUNK(match->port)) { 57077 /* Use the port from bcm_port_match_info_t instead of the physical 57078 port from the VP */ 57079 gp = match->port; 57080 } 57081 rv = _bcm_tr_vlan_translate_vp_delete(unit, gp, 57082 bcmVlanTranslateKeyPortDouble, 57083 match->match_vlan, 57084 match->match_inner_vlan, 57085 vp); 57086 57087 if (BCM_GPORT_IS_MIM_PORT(port)) { 57088 #if defined(BCM_TRIUMPH2_SUPPORT) 57089 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 57090 #endif 57091 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 57092 #if defined(BCM_MPLS_SUPPORT) 57093 bcm_tr_mpls_port_match_count_adjust(unit, vp, -1); 57094 #endif 57095 } 57096 break; 57097 case BCM_PORT_MATCH_PORT_VLAN_RANGE: 57098 #if defined(BCM_TRIUMPH2_SUPPORT) 57099 /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */ 57100 /* Tag actions need to be adjusted by calling the 57101 bcm_vlan_translate_action_add API for the entry we are creating */ 57102 VLAN_CHK_ID(unit, match->match_vlan); 57103 VLAN_CHK_ID(unit, match->match_vlan_max); 57104 if (BCM_GPORT_IS_MODPORT(match->port) || 57105 BCM_GPORT_IS_TRUNK(match->port)) { 57106 /* Use the port from bcm_port_match_info_t instead of the physical 57107 port from the VP */ 57108 gp = match->port; 57109 } 57110 rv = _bcm_tr2_vlan_translate_range_vp_delete(unit, gp, 57111 match->match_vlan, 57112 match->match_vlan_max, 57113 BCM_VLAN_INVALID, 57114 BCM_VLAN_INVALID, 57115 vp); 57116 if (BCM_GPORT_IS_MIM_PORT(port)) { 57117 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 57118 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 57119 #if defined(BCM_MPLS_SUPPORT) 57120 bcm_tr_mpls_port_match_count_adjust(unit, vp, -1); 57121 #endif 57122 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 57123 #if defined(BCM_TRIDENT2_SUPPORT) 57124 bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1); 57125 #endif 57126 } 57127 #endif 57128 break; 57129 case BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE: 57130 #if defined(BCM_TRIUMPH2_SUPPORT) 57131 if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) { 57132 return BCM_E_UNAVAIL; 57133 } 57134 /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */ 57135 /* Tag actions need to be adjusted by calling the 57136 bcm_vlan_translate_action_add API for the entry we are creating */ 57137 VLAN_CHK_ID(unit, match->match_inner_vlan); 57138 VLAN_CHK_ID(unit, match->match_inner_vlan_max); 57139 if (BCM_GPORT_IS_MODPORT(match->port) || 57140 BCM_GPORT_IS_TRUNK(match->port)) { 57141 /* Use the port from bcm_port_match_info_t instead of the physical 57142 port from the VP */ 57143 gp = match->port; 57144 } 57145 rv = _bcm_tr2_vlan_translate_range_vp_delete(unit, gp, 57146 BCM_VLAN_INVALID, 57147 BCM_VLAN_INVALID, 57148 match->match_inner_vlan, 57149 match->match_inner_vlan_max, 57150 vp); 57151 if (BCM_GPORT_IS_MIM_PORT(port)) { 57152 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 57153 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 57154 #if defined(BCM_MPLS_SUPPORT) 57155 bcm_tr_mpls_port_match_count_adjust(unit, vp, -1); 57156 #endif 57157 } 57158 #endif 57159 break; 57160 case BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE: 57161 #if defined(BCM_TRIUMPH2_SUPPORT) 57162 if (!soc_feature(unit, soc_feature_inner_vlan_range_check)) { 57163 return BCM_E_UNAVAIL; 57164 } 57165 /* Add entries in the ING_VLAN_RANGE and VLAN_XLATE tables */ 57166 /* Tag actions need to be adjusted by calling the 57167 bcm_vlan_translate_action_add API for the entry we are creating */ 57168 VLAN_CHK_ID(unit, match->match_vlan); 57169 VLAN_CHK_ID(unit, match->match_vlan_max); 57170 VLAN_CHK_ID(unit, match->match_inner_vlan); 57171 VLAN_CHK_ID(unit, match->match_inner_vlan_max); 57172 if (BCM_GPORT_IS_MODPORT(match->port) || 57173 BCM_GPORT_IS_TRUNK(match->port)) { 57174 /* Use the port from bcm_port_match_info_t instead of the physical 57175 port from the VP */ 57176 gp = match->port; 57177 } 57178 rv = _bcm_tr2_vlan_translate_range_vp_delete(unit, gp, 57179 match->match_vlan, 57180 match->match_vlan_max, 57181 match->match_inner_vlan, 57182 match->match_inner_vlan_max, 57183 vp); 57184 if (BCM_GPORT_IS_MIM_PORT(port)) { 57185 _bcm_tr2_mim_port_match_count_adjust(unit, vp, -1); 57186 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 57187 #if defined(BCM_MPLS_SUPPORT) 57188 bcm_tr_mpls_port_match_count_adjust(unit, vp, -1); 57189 #endif 57190 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 57191 #if defined(BCM_TRIDENT2_SUPPORT) 57192 bcm_td2_vxlan_port_match_count_adjust(unit, vp, -1); 57193 #endif 57194 } 57195 #endif 57196 break; 57197 57198 #if defined(BCM_TRIUMPH3_SUPPORT) 57199 case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID: 57200 case BCM_PORT_MATCH_PORT_EXTENDED_PORT_VID_VLAN: 57201 rv = _bcm_esw_extender_port_match_delete(unit, match->port, 57202 match->extended_port_vid, 57203 match->match_vlan, vp); 57204 break; 57205 #endif 57206 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 57207 case BCM_PORT_MATCH_PORT_PCP_VLAN: 57208 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 57209 /* match_info translation to vxlan_port */ 57210 bcm_vxlan_port_t_init(&vxlan_port); 57211 VLAN_CHK_ID(unit, match->match_vlan); 57212 if ((match->match_vlan & 0x0fff) != 0) { 57213 return BCM_E_UNAVAIL; 57214 } 57215 vxlan_port.criteria = BCM_VXLAN_PORT_MATCH_VLAN_PRI; 57216 vxlan_port.match_vlan = (match->match_vlan & 0xf000); 57217 vxlan_port.vxlan_port_id = port; 57218 vxlan_port.match_port = match->port; 57219 BCM_IF_ERROR_RETURN(_bcm_td2_vxlan_match_delete(unit, vp, vxlan_port, 0)); 57220 break; 57221 } else { 57222 rv = BCM_E_PARAM; 57223 } 57224 break; 57225 #endif 57226 #ifdef BCM_TRIUMPH2_SUPPORT 57227 case BCM_PORT_MATCH_PORT_PON_TUNNEL: 57228 case BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN: 57229 case BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN: 57230 if (!BCM_GPORT_IS_VLAN_PORT(port)) { 57231 return BCM_E_UNAVAIL; 57232 } 57233 if (match->port != gp) { 57234 return BCM_E_PORT; 57235 } 57236 57237 VLAN_CHK_ID(unit, match->match_pon_tunnel); 57238 if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL) { 57239 rv = _bcm_tr_lltag_vlan_translate_vp_delete(unit, gp, bcmVlanTranslateKeyPortPonTunnel, 57240 match->match_pon_tunnel, 57241 BCM_VLAN_INVALID, 57242 vp); 57243 } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN) { 57244 VLAN_CHK_ID(unit, match->match_vlan); 57245 rv = _bcm_tr_lltag_vlan_translate_vp_delete(unit, gp, bcmVlanTranslateKeyPortPonTunnelOuter, 57246 match->match_pon_tunnel, 57247 match->match_vlan, 57248 vp); 57249 } else if (match->match == BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN) { 57250 VLAN_CHK_ID(unit, match->match_pon_tunnel); 57251 rv = _bcm_tr_lltag_vlan_translate_vp_delete(unit, gp, bcmVlanTranslateKeyPortPonTunnelInner, 57252 match->match_pon_tunnel, 57253 match->match_inner_vlan, 57254 vp); 57255 } 57256 57257 if (BCM_FAILURE(rv)) { 57258 return rv; 57259 } 57260 57261 bcm_tr2_vlan_port_match_count_adjust(unit, vp, -1); 57262 break; 57263 #endif 57264 #if defined(BCM_TRIDENT_SUPPORT) 57265 case BCM_PORT_MATCH_PORT_NIV_PORT_VIF: 57266 case BCM_PORT_MATCH_PORT_NIV_PORT_VIF_VLAN: 57267 rv = _bcm_trident_niv_match_delete(unit, match->port, 57268 match->niv_port_vif, 57269 match->match_vlan, NULL); 57270 break; 57271 #endif /* BCM_TRIDENT_SUPPORT */ 57272 #if defined(BCM_TRX_SUPPORT) 57273 case BCM_PORT_MATCH_MAC_PORT: 57274 case BCM_PORT_MATCH_MAC_PORT_CLASS: 57275 bcm_vlan_match_info_t_init(&vlan_match_info); 57276 if (match->match == BCM_PORT_MATCH_MAC_PORT) { 57277 vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT; 57278 vlan_match_info.port = match->port; 57279 } else if (match->match == BCM_PORT_MATCH_MAC_PORT_CLASS) { 57280 vlan_match_info.match = BCM_VLAN_MATCH_MAC_PORT_CLASS; 57281 vlan_match_info.port_class = match->port_class; 57282 } 57283 sal_memcpy(vlan_match_info.src_mac, 57284 match->src_mac, sizeof (bcm_mac_t)); 57285 rv = _bcm_trx_vlan_match_action_delete(unit, 57286 port, &vlan_match_info); 57287 break; 57288 #endif 57289 default: 57290 rv = BCM_E_PARAM; 57291 break; 57292 } 57293 return rv; 57294 #else 57295 return BCM_E_UNAVAIL; 57296 #endif 57297 } 57298 57299 /* 57300 * Function: 57301 * bcm_port_match_replace 57302 * Purpose: 57303 * Replace an old match with a new one for an existing port 57304 * Parameters: 57305 * unit - (IN) Unit number. 57306 * port - (IN) Port or gport 57307 * old_match - (IN) Old match criteria 57308 * new_match - (IN) New match criteria 57309 * Returns: 57310 * BCM_E_xxx 57311 * Notes: 57312 */ 57313 int 57314 bcm_esw_port_match_replace( 57315 int unit, 57316 bcm_gport_t port, 57317 bcm_port_match_info_t *old_match, 57318 bcm_port_match_info_t *new_match) 57319 { 57320 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 57321 int rv = BCM_E_NONE; 57322 /* Make sure port module is initialized. */ 57323 PORT_INIT(unit); 57324 rv = bcm_esw_port_match_delete(unit, port, old_match); 57325 if (BCM_SUCCESS(rv)) { 57326 rv = bcm_esw_port_match_add(unit, port, new_match); 57327 } 57328 return rv; 57329 #else 57330 return BCM_E_UNAVAIL; 57331 #endif 57332 } 57333 57334 extern void 57335 _bcm_trx_vlan_range_profile_entry_get(int unit, bcm_vlan_t *min_vlan, 57336 bcm_vlan_t *max_vlan, uint32 index); 57337 57338 int _bcm_esw_port_vp_gport_check(bcm_gport_t port, 57339 int vp) 57340 { 57341 int matched = 0; 57342 if (BCM_GPORT_IS_MIM_PORT(port)) { 57343 if (vp == BCM_GPORT_MIM_PORT_ID_GET(port)) { 57344 matched = 1; 57345 } 57346 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 57347 if (vp == BCM_GPORT_MPLS_PORT_ID_GET(port)) { 57348 matched = 1; 57349 } 57350 } 57351 #if defined(BCM_TRIDENT2_SUPPORT) 57352 else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 57353 if (vp == BCM_GPORT_VXLAN_PORT_ID_GET(port)) { 57354 matched = 1; 57355 } 57356 } 57357 #endif 57358 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 57359 else if (BCM_GPORT_IS_L2GRE_PORT(port)) { 57360 if (vp == BCM_GPORT_L2GRE_PORT_ID_GET(port)) { 57361 matched = 1; 57362 } 57363 } 57364 #endif 57365 #if defined(BCM_TRIUMPH2_SUPPORT) 57366 else if(BCM_GPORT_IS_VLAN_PORT(port)) { 57367 if (vp == BCM_GPORT_VLAN_PORT_ID_GET(port)) { 57368 matched = 1; 57369 } 57370 } 57371 #endif 57372 return matched; 57373 } 57374 /* 57375 * Function: 57376 * bcm_port_match_multi_get 57377 * Purpose: 57378 * Get all the matches for an existing port 57379 * Parameters: 57380 * unit - (IN) Unit number. 57381 * port - (IN) Port or gport 57382 * size - (IN) Number of elements in match array 57383 * match_array - (OUT) Match array 57384 * count - (OUT) Match count 57385 * Returns: 57386 * BCM_E_xxx 57387 * Notes: 57388 */ 57389 int 57390 bcm_esw_port_match_multi_get( 57391 int unit, 57392 bcm_gport_t port, 57393 int size, 57394 bcm_port_match_info_t *match_array, 57395 int *count) 57396 { 57397 #if defined(BCM_TRIUMPH2_SUPPORT) && defined(INCLUDE_L3) 57398 int id, vp, prof_idx, i, j, index_min, index_max, ctr, rv = BCM_E_NONE; 57399 int stm_idx = 0; 57400 int key_type_value = 0, key_type = 0; 57401 uint32 matched; 57402 uint8 *vlan_xlate_buf = NULL; /* VLAN_XLATE DMA buffer */ 57403 uint8 *source_trunk_map_buf = NULL; /* SOURCE_TRUNK_MAP DMA buffer */ 57404 source_trunk_map_table_entry_t *source_trunk_map; 57405 bcm_gport_t gp; 57406 bcm_vlan_t min_vlan[8], max_vlan[8]; 57407 bcm_module_t mod_out, mod_in; 57408 bcm_port_t port_out, port_in; 57409 bcm_trunk_t trunk_id; 57410 int mpls_action; 57411 soc_mem_t mem; 57412 #if defined(BCM_TRIUMPH3_SUPPORT) 57413 vlan_xlate_entry_t vent; 57414 #endif 57415 bcm_vlan_action_set_t *action; 57416 int profile_idx; 57417 void *entry; 57418 57419 bcm_trunk_member_t *member_array = NULL; 57420 57421 /* Parameter checks */ 57422 if ((size < 0) || (count == NULL)) { 57423 return BCM_E_PARAM; 57424 } 57425 if ((size > 0) && (match_array == NULL)) { 57426 return BCM_E_PARAM; 57427 } 57428 57429 /* Make sure port module is initialized. */ 57430 PORT_INIT(unit); 57431 57432 if (BCM_GPORT_IS_MIM_PORT(port)) { 57433 if (!soc_feature(unit, soc_feature_mim)) { 57434 return BCM_E_UNAVAIL; 57435 } 57436 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 57437 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 57438 return BCM_E_NOT_FOUND; 57439 } 57440 BCM_IF_ERROR_RETURN(_bcm_tr2_mim_port_phys_gport_get(unit, vp, &gp)); 57441 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 57442 if (!soc_feature(unit, soc_feature_mpls)) { 57443 return BCM_E_UNAVAIL; 57444 } 57445 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 57446 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 57447 return BCM_E_NOT_FOUND; 57448 } 57449 #if defined(BCM_MPLS_SUPPORT) 57450 BCM_IF_ERROR_RETURN(bcm_tr_mpls_port_phys_gport_get(unit, vp, &gp)); 57451 #endif 57452 57453 } else 57454 #if defined(BCM_TRIDENT2_SUPPORT) 57455 if (BCM_GPORT_IS_TRUNK(port)) { 57456 if (!soc_feature(unit, soc_feature_vp_lag)) { 57457 return BCM_E_UNAVAIL; 57458 } 57459 return _bcm_esw_trunk_match_multi_get(unit, BCM_GPORT_TRUNK_GET(port), 57460 size, match_array, count); 57461 } else 57462 #endif /* BCM_TRIDENT2_SUPPORT */ 57463 #if defined(BCM_TRIDENT2_SUPPORT) 57464 if (BCM_GPORT_IS_VXLAN_PORT(port)) { 57465 57466 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 57467 if (!(_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan))) { 57468 return BCM_E_NOT_FOUND; 57469 } 57470 57471 BCM_GPORT_VXLAN_PORT_ID_SET(gp,vp); 57472 } else 57473 #endif 57474 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 57475 if (BCM_GPORT_IS_L2GRE_PORT(port)) { 57476 _bcm_vp_info_t vp_info; 57477 57478 if (!soc_feature(unit, soc_feature_vp_sharing)) { 57479 return BCM_E_UNAVAIL; 57480 } 57481 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 57482 57483 BCM_IF_ERROR_RETURN(_bcm_vp_info_get(unit, vp, &vp_info)); 57484 if (!(vp_info.flags & _BCM_VP_INFO_SHARED_PORT)) { 57485 return BCM_E_NOT_FOUND; 57486 } 57487 57488 BCM_GPORT_L2GRE_PORT_ID_SET(gp,vp); 57489 } else 57490 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 57491 #if defined(BCM_TRIUMPH2_SUPPORT) 57492 if (BCM_GPORT_IS_VLAN_PORT(port)) { 57493 if (!soc_feature(unit, soc_feature_lltag)) { 57494 return BCM_E_UNAVAIL; 57495 } 57496 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 57497 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 57498 return BCM_E_NOT_FOUND; 57499 } 57500 BCM_IF_ERROR_RETURN(bcm_tr2_vlan_port_phys_gport_get(unit, vp, &gp)); 57501 } else 57502 #endif 57503 #if defined(BCM_TRIDENT_SUPPORT) 57504 if (BCM_GPORT_IS_NIV_PORT(port)) { 57505 if (!soc_feature(unit, soc_feature_niv)) { 57506 return BCM_E_UNAVAIL; 57507 } 57508 return _bcm_td_port_vif_match_multi_get(unit, port, 57509 size, match_array, count); 57510 } else 57511 #endif /* BCM_TRIDENT_SUPPORT */ 57512 #if defined(BCM_TRIDENT3_SUPPORT) 57513 if (BCM_GPORT_IS_MIRROR(port)) { 57514 if (!soc_feature(unit, soc_feature_mirror_encap_profile)) { 57515 return BCM_E_UNAVAIL; 57516 } 57517 return _bcm_mirror_port_match_multi_get(unit, port, size, match_array, 57518 count); 57519 } else 57520 #endif /* BCM_TRIDENT3_SUPPORT */ 57521 { 57522 return BCM_E_PORT; 57523 } 57524 57525 rv = _bcm_esw_gport_resolve(unit, gp, &mod_out, &port_out, &trunk_id, &id); 57526 if (BCM_FAILURE(rv)) { 57527 goto cleanup; 57528 } 57529 #if defined(BCM_TRIUMPH3_SUPPORT) 57530 if (SOC_IS_TRIUMPH3(unit)) { 57531 mem = VLAN_XLATE_EXTDm; 57532 } else 57533 #endif 57534 #if defined(BCM_TRIDENT3_SUPPORT) 57535 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 57536 mem = VLAN_XLATE_1_DOUBLEm; 57537 } else 57538 #endif 57539 { 57540 mem = VLAN_XLATEm; 57541 } 57542 57543 /* DMA the relevant tables for traversal */ 57544 vlan_xlate_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem), 57545 "VLAN_XLATE buffer"); 57546 if (NULL == vlan_xlate_buf) { 57547 rv = BCM_E_MEMORY; 57548 goto cleanup; 57549 } 57550 57551 index_min = soc_mem_index_min(unit, mem); 57552 index_max = soc_mem_index_max(unit, mem); 57553 if ((rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 57554 index_min, index_max, 57555 vlan_xlate_buf)) < 0 ) { 57556 goto cleanup; 57557 } 57558 source_trunk_map_buf = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES 57559 (unit, SOURCE_TRUNK_MAP_TABLEm), 57560 "SOURCE_TRUNK_MAP_TABLE buffer"); 57561 if (NULL == source_trunk_map_buf) { 57562 rv = BCM_E_MEMORY; 57563 goto cleanup; 57564 } 57565 index_min = soc_mem_index_min(unit, SOURCE_TRUNK_MAP_TABLEm); 57566 index_max = soc_mem_index_max(unit, SOURCE_TRUNK_MAP_TABLEm); 57567 if ((rv = soc_mem_read_range(unit, SOURCE_TRUNK_MAP_TABLEm, MEM_BLOCK_ANY, 57568 index_min, index_max, 57569 source_trunk_map_buf)) < 0 ) { 57570 goto cleanup; 57571 } 57572 57573 ctr = 0; 57574 /* Get all VLAN_XLATE matches */ 57575 index_min = soc_mem_index_min(unit, mem); 57576 index_max = soc_mem_index_max(unit, mem); 57577 for (i = index_min; i <= index_max; i++) { 57578 if ((size != 0) && (size <= ctr)) { 57579 break; 57580 } 57581 if (SOC_IS_TRIUMPH3(unit)) { 57582 mem = VLAN_XLATE_EXTDm; 57583 } 57584 entry = soc_mem_table_idx_to_pointer 57585 (unit, mem, void *, vlan_xlate_buf, i); 57586 #if defined(BCM_TRIUMPH3_SUPPORT) 57587 if (SOC_IS_TRIUMPH3(unit)) { 57588 int key_type; 57589 57590 /* double wide entry should always start at double wide boundary */ 57591 key_type = soc_mem_field32_get(unit, mem, entry, KEY_TYPE_0f); 57592 57593 /* if key type is odd number, then it is double wide entry */ 57594 if (!(key_type & 1)) { 57595 continue; 57596 } 57597 mpls_action = soc_mem_field32_get(unit, mem, entry, MPLS_ACTIONf); 57598 vp = soc_mem_field32_get(unit, mem, entry, SOURCE_VPf); 57599 sal_memset(&vent, 0, sizeof(vent)); 57600 rv = _bcm_tr3_vxlate_extd2vxlate(unit, (vlan_xlate_extd_entry_t *)entry, &vent, 0); 57601 if (rv != BCM_E_NONE) { 57602 goto cleanup; 57603 } 57604 entry = &vent; 57605 mem = VLAN_XLATEm; 57606 } else 57607 #endif /* BCM_TRIUMPH3_SUPPORT */ 57608 { 57609 mpls_action = soc_mem_field32_get(unit, mem, entry, MPLS_ACTIONf); 57610 vp = soc_mem_field32_get(unit, mem, entry, SOURCE_VPf); 57611 } 57612 57613 #if defined(BCM_TRIDENT3_SUPPORT) 57614 if (SOC_MEM_IS_VALID(unit, VLAN_XLATE_1_DOUBLEm)) { 57615 if (soc_mem_field32_get(unit, mem, entry, BASE_VALID_0f) != 3) { 57616 continue; 57617 } 57618 if (soc_mem_field32_get(unit, mem, entry, BASE_VALID_1f) != 7) { 57619 continue; 57620 } 57621 } 57622 #endif 57623 57624 if (SOC_MEM_FIELD_VALID(unit, mem, VALIDf)) { 57625 if (soc_mem_field32_get(unit, mem, entry, VALIDf) == 0) { 57626 continue; 57627 } 57628 } 57629 57630 if (!(mpls_action & 0x1)) { 57631 continue; /* Entry is not for an SVP */ 57632 } 57633 57634 key_type_value = (int)soc_mem_field32_get(unit, mem, entry, KEY_TYPEf); 57635 57636 rv = _bcm_esw_vlan_xlate_key_type_get(unit,key_type_value,&key_type); 57637 if (rv != BCM_E_NONE) { 57638 goto cleanup; 57639 } 57640 57641 matched = _bcm_esw_port_vp_gport_check(port, vp); 57642 57643 if (matched) { 57644 soc_field_t field; 57645 int port_count; 57646 int tid; 57647 int gport_id; 57648 int outer_vlan_range_found = 0, inner_vlan_range_found = 0; 57649 ctr++; 57650 if (size >= ctr) { 57651 switch (key_type) { 57652 case VLXLT_HASH_KEY_TYPE_OVID: 57653 match_array->match = BCM_PORT_MATCH_PORT_VLAN; 57654 match_array->match_vlan = 57655 soc_mem_field32_get(unit, mem, entry, XLATE__OVIDf); 57656 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 57657 if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) { 57658 if (soc_feature(unit, soc_feature_vfi_zero_invalid) && 57659 (soc_mem_field32_get(unit, mem, entry, XLATE__VFIf)) == 0) { 57660 match_array->vpn = 0; 57661 } else { 57662 _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI, 57663 soc_mem_field32_get(unit, mem, entry, XLATE__VFIf)); 57664 } 57665 } else { 57666 match_array->vpn = 0; 57667 } 57668 #endif 57669 /* Check if this match is a VLAN range match */ 57670 if (BCM_TRUNK_INVALID != trunk_id) { 57671 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, 57672 &port_count); 57673 if (BCM_FAILURE(rv)) { 57674 goto cleanup; 57675 } 57676 57677 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count, 57678 "trunk member array"); 57679 if (member_array == NULL) { 57680 rv = BCM_E_MEMORY; 57681 goto cleanup; 57682 } 57683 sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count); 57684 57685 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count, 57686 member_array, &port_count); 57687 if (BCM_FAILURE(rv)) { 57688 goto cleanup; 57689 } 57690 57691 rv = _bcm_esw_gport_resolve(unit, member_array[0].gport, 57692 &mod_out, &port_out, &tid, &gport_id); 57693 if (BCM_FAILURE(rv)) { 57694 goto cleanup; 57695 } 57696 57697 } 57698 rv = _bcm_esw_src_mod_port_table_index_get( 57699 unit, mod_out, port_out, &stm_idx); 57700 if (BCM_FAILURE(rv)) { 57701 goto cleanup; 57702 } 57703 57704 source_trunk_map = soc_mem_table_idx_to_pointer 57705 (unit, SOURCE_TRUNK_MAP_TABLEm, 57706 source_trunk_map_table_entry_t *, 57707 source_trunk_map_buf, stm_idx); 57708 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 57709 OUTER_VLAN_RANGE_IDXf)) { 57710 field = OUTER_VLAN_RANGE_IDXf; 57711 } else { 57712 field = VLAN_RANGE_IDXf; 57713 } 57714 prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, 57715 source_trunk_map, field); 57716 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, 57717 max_vlan, prof_idx); 57718 for (j = 0; j < 8; j++) { 57719 if (min_vlan[j] == match_array->match_vlan) { 57720 match_array->match_vlan_max = max_vlan[j]; 57721 match_array->match = 57722 BCM_PORT_MATCH_PORT_VLAN_RANGE; 57723 break; /* Found a VLAN range match */ 57724 } 57725 } 57726 if (j == 8) { 57727 match_array->match = BCM_PORT_MATCH_PORT_VLAN; 57728 } 57729 if (soc_mem_field32_get(unit, mem, entry, XLATE__Tf)) { 57730 trunk_id = soc_mem_field32_get(unit, mem, entry, XLATE__TGIDf); 57731 BCM_GPORT_TRUNK_SET(gp, trunk_id); 57732 } else { 57733 mod_in = soc_mem_field32_get(unit, mem, entry, XLATE__MODULE_IDf); 57734 port_in = soc_mem_field32_get(unit, mem, entry, XLATE__PORT_NUMf); 57735 57736 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 57737 mod_in, port_in, &mod_out, &port_out); 57738 BCM_GPORT_MODPORT_SET(gp, mod_out, port_out); 57739 } 57740 match_array->port = gp; 57741 match_array++; 57742 break; 57743 case VLXLT_HASH_KEY_TYPE_IVID: 57744 match_array->match = BCM_PORT_MATCH_PORT_INNER_VLAN; 57745 match_array->match_inner_vlan = 57746 soc_mem_field32_get(unit, mem, entry, XLATE__IVIDf); 57747 57748 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 57749 if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) { 57750 if (soc_feature(unit, soc_feature_vfi_zero_invalid) && 57751 (soc_mem_field32_get(unit, mem, entry, XLATE__VFIf) == 0)) { 57752 57753 match_array->vpn = 0; 57754 } else { 57755 _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI, 57756 soc_mem_field32_get(unit, mem, entry, XLATE__VFIf)); 57757 57758 } 57759 } else { 57760 match_array->vpn = 0; 57761 } 57762 #endif 57763 /* Check if this match is a VLAN range match */ 57764 if (BCM_TRUNK_INVALID != trunk_id) { 57765 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, 57766 &port_count); 57767 if (BCM_FAILURE(rv)) { 57768 goto cleanup; 57769 } 57770 57771 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count, 57772 "trunk member array"); 57773 if (member_array == NULL) { 57774 rv = BCM_E_MEMORY; 57775 goto cleanup; 57776 } 57777 sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count); 57778 57779 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count, 57780 member_array, &port_count); 57781 if (BCM_FAILURE(rv)) { 57782 goto cleanup; 57783 } 57784 57785 rv = _bcm_esw_gport_resolve(unit, member_array[0].gport, 57786 &mod_out, &port_out, &tid, &gport_id); 57787 if (BCM_FAILURE(rv)) { 57788 goto cleanup; 57789 } 57790 57791 } 57792 57793 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 57794 INNER_VLAN_RANGE_IDXf)) { 57795 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 57796 if (soc_feature(unit, soc_feature_src_modid_base_index)) { 57797 int is_local; 57798 bcm_module_t modid = mod_out; 57799 57800 rv = _bcm_esw_stk_modmap_map( 57801 unit, BCM_STK_MODMAP_SET, modid, -1, 57802 &mod_out, NULL); 57803 if (BCM_SUCCESS(rv)) { 57804 rv = _bcm_esw_modid_is_local(unit, mod_out, 57805 &is_local); 57806 } 57807 if (BCM_SUCCESS(rv)) { 57808 rv = _bcm_esw_src_modid_base_index_get( 57809 unit, modid, is_local, &stm_idx); 57810 } 57811 if (BCM_FAILURE(rv)) { 57812 goto cleanup; 57813 } 57814 stm_idx += port_out; 57815 } else 57816 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */ 57817 { 57818 stm_idx = (mod_out * (SOC_PORT_ADDR_MAX(unit) + 1)) 57819 + port_out; 57820 } 57821 source_trunk_map = 57822 soc_mem_table_idx_to_pointer(unit, SOURCE_TRUNK_MAP_TABLEm, 57823 source_trunk_map_table_entry_t *, 57824 source_trunk_map_buf, 57825 stm_idx); 57826 field = INNER_VLAN_RANGE_IDXf; 57827 prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, 57828 source_trunk_map, field); 57829 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, 57830 max_vlan, prof_idx); 57831 for (j = 0; j < 8; j++) { 57832 if (min_vlan[j] == match_array->match_inner_vlan) { 57833 match_array->match_inner_vlan_max = max_vlan[j]; 57834 match_array->match = 57835 BCM_PORT_MATCH_PORT_INNER_VLAN_RANGE; 57836 break; /* Found a VLAN range match */ 57837 } 57838 } 57839 } 57840 if (soc_mem_field32_get(unit, mem, entry, XLATE__Tf)) { 57841 trunk_id = soc_mem_field32_get(unit, mem, entry, XLATE__TGIDf); 57842 BCM_GPORT_TRUNK_SET(gp, trunk_id); 57843 } else { 57844 mod_in = soc_mem_field32_get(unit, mem, entry, XLATE__MODULE_IDf); 57845 port_in = soc_mem_field32_get(unit, mem, entry, XLATE__PORT_NUMf); 57846 57847 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 57848 mod_in, port_in, &mod_out, &port_out); 57849 BCM_GPORT_MODPORT_SET(gp, mod_out, port_out); 57850 } 57851 match_array->port = gp; 57852 match_array++; 57853 break; 57854 case VLXLT_HASH_KEY_TYPE_PRI_CFI: 57855 match_array->match = BCM_PORT_MATCH_PORT_VLAN16; 57856 match_array->match_vlan = 57857 soc_mem_field32_get(unit, mem, entry, OTAGf); 57858 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 57859 if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) { 57860 if (soc_feature(unit, soc_feature_vfi_zero_invalid) && 57861 (soc_mem_field32_get(unit, mem, entry, VFIf) == 0)) { 57862 match_array->vpn = 0; 57863 } else { 57864 _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI, 57865 soc_mem_field32_get(unit, mem, entry, VFIf)); 57866 } 57867 } else { 57868 match_array->vpn = 0; 57869 } 57870 #endif 57871 if (soc_mem_field32_get(unit, mem, entry, Tf)) { 57872 trunk_id = soc_mem_field32_get(unit, mem, entry, TGIDf); 57873 BCM_GPORT_TRUNK_SET(gp, trunk_id); 57874 } else { 57875 mod_in = soc_mem_field32_get(unit, mem, entry, MODULE_IDf); 57876 port_in = soc_mem_field32_get(unit, mem, entry, PORT_NUMf); 57877 57878 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 57879 mod_in, port_in, &mod_out, &port_out); 57880 BCM_GPORT_MODPORT_SET(gp, mod_out, port_out); 57881 } 57882 match_array->port = gp; 57883 match_array++; 57884 break; 57885 case VLXLT_HASH_KEY_TYPE_IVID_OVID: 57886 match_array->match = BCM_PORT_MATCH_PORT_VLAN_STACKED; 57887 match_array->match_vlan = 57888 soc_mem_field32_get(unit, mem, entry, OVIDf); 57889 match_array->match_inner_vlan = 57890 soc_mem_field32_get(unit, mem, entry, IVIDf); 57891 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 57892 if (SOC_MEM_FIELD_VALID(unit, mem, VFIf)) { 57893 if (soc_feature(unit, soc_feature_vfi_zero_invalid) && 57894 (soc_mem_field32_get(unit, mem, entry, VFIf) == 0)) { 57895 match_array->vpn = 0; 57896 } else { 57897 _BCM_VXLAN_VPN_SET(match_array->vpn, _BCM_VPN_TYPE_VFI, 57898 soc_mem_field32_get(unit, mem, entry, VFIf)); 57899 } 57900 } else { 57901 match_array->vpn = 0; 57902 } 57903 #endif 57904 57905 /* Check if this match is a VLAN range match */ 57906 if (BCM_TRUNK_INVALID != trunk_id) { 57907 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, 0, NULL, 57908 &port_count); 57909 if (BCM_FAILURE(rv)) { 57910 goto cleanup; 57911 } 57912 57913 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * port_count, 57914 "trunk member array"); 57915 if (member_array == NULL) { 57916 rv = BCM_E_MEMORY; 57917 goto cleanup; 57918 } 57919 sal_memset(member_array, 0, sizeof(bcm_trunk_member_t) * port_count); 57920 57921 rv = bcm_esw_trunk_get(unit, trunk_id, NULL, port_count, 57922 member_array, &port_count); 57923 if (BCM_FAILURE(rv)) { 57924 goto cleanup; 57925 } 57926 57927 rv = _bcm_esw_gport_resolve(unit, member_array[0].gport, 57928 &mod_out, &port_out, &tid, &gport_id); 57929 if (BCM_FAILURE(rv)) { 57930 goto cleanup; 57931 } 57932 57933 } 57934 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 57935 OUTER_VLAN_RANGE_IDXf)) { 57936 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 57937 if (soc_feature(unit, soc_feature_src_modid_base_index)) { 57938 int is_local; 57939 bcm_module_t modid = mod_out; 57940 57941 rv = _bcm_esw_stk_modmap_map( 57942 unit, BCM_STK_MODMAP_SET, modid, -1, 57943 &mod_out, NULL); 57944 if (BCM_SUCCESS(rv)) { 57945 rv = _bcm_esw_modid_is_local(unit, mod_out, 57946 &is_local); 57947 } 57948 if (BCM_SUCCESS(rv)) { 57949 rv = _bcm_esw_src_modid_base_index_get( 57950 unit, modid, is_local, &stm_idx); 57951 } 57952 if (BCM_FAILURE(rv)) { 57953 goto cleanup; 57954 } 57955 stm_idx += port_out; 57956 } else 57957 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */ 57958 { 57959 stm_idx = (mod_out * (SOC_PORT_ADDR_MAX(unit) + 1)) 57960 + port_out; 57961 } 57962 source_trunk_map = 57963 soc_mem_table_idx_to_pointer(unit, SOURCE_TRUNK_MAP_TABLEm, 57964 source_trunk_map_table_entry_t *, 57965 source_trunk_map_buf, 57966 stm_idx); 57967 field = OUTER_VLAN_RANGE_IDXf; 57968 prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, 57969 source_trunk_map, field); 57970 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, 57971 max_vlan, prof_idx); 57972 for (j = 0; j < 8; j++) { 57973 if (min_vlan[j] == match_array->match_vlan) { 57974 match_array->match_vlan_max = max_vlan[j]; 57975 outer_vlan_range_found = 1; 57976 break; /* Found a VLAN range match */ 57977 } 57978 } 57979 } 57980 57981 if (SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, 57982 INNER_VLAN_RANGE_IDXf)) { 57983 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 57984 if (soc_feature(unit, soc_feature_src_modid_base_index)) { 57985 int is_local; 57986 bcm_module_t modid = mod_out; 57987 57988 rv = _bcm_esw_stk_modmap_map( 57989 unit, BCM_STK_MODMAP_SET, modid, -1, 57990 &mod_out, NULL); 57991 if (BCM_SUCCESS(rv)) { 57992 rv = _bcm_esw_modid_is_local(unit, mod_out, 57993 &is_local); 57994 } 57995 if (BCM_SUCCESS(rv)) { 57996 rv = _bcm_esw_src_modid_base_index_get( 57997 unit, modid, is_local, &stm_idx); 57998 } 57999 if (BCM_FAILURE(rv)) { 58000 goto cleanup; 58001 } 58002 stm_idx += port_out; 58003 } else 58004 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */ 58005 { 58006 stm_idx = (mod_out * (SOC_PORT_ADDR_MAX(unit) + 1)) 58007 + port_out; 58008 } 58009 source_trunk_map = 58010 soc_mem_table_idx_to_pointer(unit, SOURCE_TRUNK_MAP_TABLEm, 58011 source_trunk_map_table_entry_t *, 58012 source_trunk_map_buf, 58013 stm_idx); 58014 field = INNER_VLAN_RANGE_IDXf; 58015 prof_idx = soc_SOURCE_TRUNK_MAP_TABLEm_field32_get(unit, 58016 source_trunk_map, field); 58017 _bcm_trx_vlan_range_profile_entry_get(unit, min_vlan, 58018 max_vlan, prof_idx); 58019 for (j = 0; j < 8; j++) { 58020 if (min_vlan[j] == match_array->match_inner_vlan) { 58021 match_array->match_inner_vlan_max = max_vlan[j]; 58022 inner_vlan_range_found = 1; 58023 break; /* Found a VLAN range match */ 58024 } 58025 } 58026 } 58027 if (inner_vlan_range_found && outer_vlan_range_found) { 58028 match_array->match = BCM_PORT_MATCH_PORT_VLAN_STACKED_RANGE; 58029 } 58030 58031 if (soc_mem_field32_get(unit, mem, entry, Tf)) { 58032 trunk_id = soc_mem_field32_get(unit, mem, entry, TGIDf); 58033 BCM_GPORT_TRUNK_SET(gp, trunk_id); 58034 } else { 58035 mod_in = soc_mem_field32_get(unit, mem, entry, MODULE_IDf); 58036 port_in = soc_mem_field32_get(unit, mem, entry, PORT_NUMf); 58037 58038 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 58039 mod_in, port_in, &mod_out, &port_out); 58040 BCM_GPORT_MODPORT_SET(gp, mod_out, port_out); 58041 } 58042 match_array->port = gp; 58043 match_array++; 58044 break; 58045 #if defined (BCM_TRIUMPH2_SUPPORT) 58046 case VLXLT_HASH_KEY_TYPE_LLVID: 58047 case VLXLT_HASH_KEY_TYPE_LLVID_OVID: 58048 case VLXLT_HASK_KEY_TYPE_LLVID_IVID: 58049 if (key_type == VLXLT_HASH_KEY_TYPE_LLVID) { 58050 match_array->match = BCM_PORT_MATCH_PORT_PON_TUNNEL; 58051 } else if (key_type == VLXLT_HASH_KEY_TYPE_LLVID_OVID) { 58052 match_array->match = BCM_PORT_MATCH_PORT_PON_TUNNEL_VLAN; 58053 } else { 58054 match_array->match = BCM_PORT_MATCH_PORT_PON_TUNNEL_INNER_VLAN; 58055 } 58056 58057 match_array->match_pon_tunnel = 58058 soc_mem_field32_get(unit, mem, entry, LLTAG__LLVIDf); 58059 match_array->match_inner_vlan = 58060 soc_mem_field32_get(unit, mem, entry, LLTAG__IVIDf); 58061 match_array->match_vlan = 58062 soc_mem_field32_get(unit, mem, entry, LLTAG__OVIDf); 58063 58064 if (soc_mem_field32_get(unit, mem, entry, Tf)) { 58065 trunk_id = soc_mem_field32_get(unit, mem, entry, TGIDf); 58066 BCM_GPORT_TRUNK_SET(gp, trunk_id); 58067 } else { 58068 mod_in = soc_mem_field32_get(unit, mem, entry, MODULE_IDf); 58069 port_in = soc_mem_field32_get(unit, mem, entry, PORT_NUMf); 58070 58071 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 58072 mod_in, port_in, &mod_out, &port_out); 58073 BCM_GPORT_MODPORT_SET(gp, mod_out, port_out); 58074 } 58075 58076 if (match_array->action != NULL) { 58077 action = match_array->action; 58078 action->new_outer_vlan = 58079 soc_mem_field32_get(unit, mem, entry, NEW_OVIDf); 58080 action->new_inner_vlan = 58081 soc_mem_field32_get(unit, mem, entry, NEW_IVIDf); 58082 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 58083 action->priority = 58084 soc_mem_field32_get(unit, mem, entry, NEW_OPRIf); 58085 action->new_outer_cfi = 58086 soc_mem_field32_get(unit, mem, entry, NEW_OCFIf); 58087 action->new_inner_pkt_prio = 58088 soc_mem_field32_get(unit, mem, entry, NEW_IPRIf); 58089 action->new_inner_cfi = 58090 soc_mem_field32_get(unit, mem, entry, NEW_ICFIf); 58091 } 58092 profile_idx = soc_mem_field32_get(unit, mem, entry, TAG_ACTION_PROFILE_PTRf); 58093 _bcm_trx_vlan_action_profile_entry_get(unit, action, profile_idx); 58094 } 58095 match_array->port = gp; 58096 match_array++; 58097 break; 58098 #endif 58099 default: 58100 break; 58101 } 58102 } 58103 } 58104 } 58105 58106 #if defined(BCM_TRX_SUPPORT) 58107 /* Get the list from VLAN_MACm */ 58108 if (BCM_SUCCESS(rv)) { 58109 rv = _bcm_vlan_match_action_multi_get(unit, 58110 port, size, match_array, ctr, &ctr); 58111 } 58112 #endif 58113 58114 *count = ctr; 58115 58116 cleanup: 58117 if (vlan_xlate_buf) { 58118 soc_cm_sfree(unit, vlan_xlate_buf); 58119 } 58120 if (source_trunk_map_buf) { 58121 soc_cm_sfree(unit, source_trunk_map_buf); 58122 } 58123 if (member_array) { 58124 sal_free(member_array); 58125 } 58126 return rv; 58127 #else 58128 return BCM_E_UNAVAIL; 58129 #endif 58130 } 58131 58132 /* 58133 * Function: 58134 * bcm_port_match_set 58135 * Purpose: 58136 * Assign a set of matches to an existing port 58137 * Parameters: 58138 * unit - (IN) Unit number. 58139 * port - (IN) Port or gport 58140 * size - (IN) Number of elements in match array 58141 * match_array - (IN) Match array 58142 * Returns: 58143 * BCM_E_xxx 58144 * Notes: 58145 */ 58146 int 58147 bcm_esw_port_match_set( 58148 int unit, 58149 bcm_gport_t port, 58150 int size, 58151 bcm_port_match_info_t *match_array) 58152 { 58153 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 58154 int i, rv = BCM_E_NONE; 58155 if ((size <= 0) || (match_array == NULL)) { 58156 return BCM_E_PARAM; 58157 } 58158 58159 /* Make sure port module is initialized. */ 58160 PORT_INIT(unit); 58161 58162 /* Add every single match */ 58163 for (i = 0; i < size; i++) { 58164 rv = bcm_esw_port_match_add(unit, port, match_array + i); 58165 if (BCM_FAILURE(rv)) { 58166 return rv; 58167 } 58168 } 58169 return rv; 58170 #else 58171 return BCM_E_UNAVAIL; 58172 #endif 58173 } 58174 58175 /* 58176 * Function: 58177 * bcm_port_match_delete_all 58178 * Purpose: 58179 * Delete all matches for an existing port 58180 * Parameters: 58181 * unit - (IN) Unit number. 58182 * port - (IN) Port or gport 58183 * Returns: 58184 * BCM_E_xxx 58185 * Notes: 58186 */ 58187 int 58188 bcm_esw_port_match_delete_all( 58189 int unit, 58190 bcm_gport_t port) 58191 { 58192 #if defined(BCM_TRIUMPH_SUPPORT) && defined(INCLUDE_L3) 58193 int i, size, count, rv = BCM_E_NONE; 58194 bcm_port_match_info_t *match_array = NULL; 58195 58196 /* Make sure port module is initialized. */ 58197 PORT_INIT(unit); 58198 58199 /* First get number of entries */ 58200 rv = bcm_esw_port_match_multi_get(unit, port, 0, match_array, &count); 58201 if (BCM_FAILURE(rv) || (count == 0)) { 58202 return rv; 58203 } 58204 match_array = sal_alloc(sizeof(bcm_port_match_info_t) * count, 58205 "match_array"); 58206 if (match_array == NULL) { 58207 return BCM_E_MEMORY; 58208 } 58209 sal_memset(match_array, 0, sizeof(bcm_port_match_info_t) * count); 58210 58211 /* Get all matches */ 58212 size = count; 58213 rv = bcm_esw_port_match_multi_get(unit, port, size, match_array, &count); 58214 if (BCM_FAILURE(rv)) { 58215 sal_free(match_array); 58216 return rv; 58217 } 58218 58219 /* Delete every single match */ 58220 for (i = 0; i < count; i++) { 58221 rv = bcm_esw_port_match_delete(unit, port, match_array + i); 58222 if (BCM_FAILURE(rv)) { 58223 sal_free(match_array); 58224 return rv; 58225 } 58226 } 58227 sal_free(match_array); 58228 return rv; 58229 #else 58230 return BCM_E_UNAVAIL; 58231 #endif 58232 } 58233 58234 int 58235 bcmi_esw_port_eee_cfg_get(int unit, bcm_port_t port, int *value) 58236 { 58237 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \ 58238 defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) || \ 58239 defined(BCM_HURRICANE2_SUPPORT) 58240 if ((port < 0) || (port >= SOC_MAX_NUM_PORTS)) { 58241 return BCM_E_PORT; 58242 } 58243 58244 *value = eee_cfg[unit][port]; 58245 58246 return BCM_E_NONE; 58247 #else 58248 return BCM_E_UNAVAIL; 58249 #endif 58250 } 58251 58252 58253 58254 /* 58255 * Function: 58256 * bcm_esw_port_timesync_config_get 58257 * Purpose: 58258 * Delete all matches for an existing port 58259 * Parameters: 58260 * unit - (IN) Unit number. 58261 * port - (IN) Port 58262 * conf - (IN) Configuration 58263 * Returns: 58264 * BCM_E_xxx 58265 * Notes: 58266 */ 58267 58268 int 58269 bcm_esw_port_timesync_config_get(int unit, bcm_port_t port, int array_size, 58270 bcm_port_timesync_config_t *config_array, 58271 int *array_count) 58272 { 58273 int rv; 58274 int is_remote_port = FALSE; 58275 58276 /* Make sure port module is initialized. */ 58277 PORT_INIT(unit); 58278 58279 if (SOC_IS_TRIDENT3X(unit) && BCM_GPORT_IS_PROXY(port)) { 58280 if (bcm_esw_port_local_get(unit, port, &port) != BCM_E_NONE) { 58281 /* the port is remote mod port */ 58282 is_remote_port = TRUE; 58283 } 58284 } 58285 58286 if (!is_remote_port) { 58287 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58288 } 58289 58290 COMPILER_REFERENCE(array_size); 58291 COMPILER_REFERENCE(config_array); 58292 COMPILER_REFERENCE(array_count); 58293 58294 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \ 58295 defined(BCM_TIMESYNC_V3_SUPPORT)|| defined(BCM_SABER2_SUPPORT) || \ 58296 defined(BCM_APACHE_SUPPORT) 58297 /* 58298 * Internal timesync function handles port lock and retrieves 58299 * timesync config profiles 58300 */ 58301 if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) || 58302 SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 58303 SOC_IS_APACHE(unit)) && 58304 (soc_feature(unit,soc_feature_timesync_support))) { 58305 rv = _bcm_esw_port_timesync_config_get(unit, port, array_size, 58306 config_array, array_count, is_remote_port); 58307 } else 58308 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || 58309 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */ 58310 { 58311 rv = BCM_E_UNAVAIL; 58312 } 58313 58314 return rv; 58315 } 58316 58317 /* 58318 * Function: 58319 * bcm_esw_port_timesync_config_set 58320 * Purpose: 58321 * Set Timesync Configuration profiles for the port 58322 * Parameters: 58323 * unit - (IN) bcm device 58324 * port - (IN) port 58325 * config_count - (IN)Count of timesync profile 58326 * *config_array - (IN/OUT) Pointer to array of timesync profiles 58327 * Returns: 58328 * BCM_E_xxx 58329 * Notes: 58330 */ 58331 int 58332 bcm_esw_port_timesync_config_set(int unit, bcm_port_t port, int config_count, 58333 bcm_port_timesync_config_t *config_array) 58334 { 58335 int rv; 58336 int is_remote_port = FALSE; 58337 58338 /* Make sure port module is initialized. */ 58339 PORT_INIT(unit); 58340 58341 if (SOC_IS_TRIDENT3X(unit) && BCM_GPORT_IS_PROXY(port)) { 58342 if (bcm_esw_port_local_get(unit, port, &port) != BCM_E_NONE) { 58343 int cnt; 58344 bcm_port_timesync_config_t *ts_config; 58345 is_remote_port = TRUE; 58346 for (cnt = 0; cnt < config_count; cnt++) 58347 { 58348 ts_config = (bcm_port_timesync_config_t*) (config_array + cnt); 58349 /* the params can't be configured on remote logical port */ 58350 if (ts_config->flags & BCM_PORT_TIMESYNC_ONE_STEP_TIMESTAMP || 58351 ts_config->flags & BCM_PORT_TIMESYNC_TWO_STEP_TIMESTAMP || 58352 ts_config->flags & BCM_PORT_TIMESYNC_TIMESTAMP_CFUPDATE_ALL || 58353 ts_config->pkt_drop & BCM_PORT_TIMESYNC_PKT_INVALID) { 58354 return BCM_E_PORT; 58355 } 58356 } 58357 } 58358 } 58359 58360 if (!is_remote_port) { 58361 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58362 } 58363 58364 COMPILER_REFERENCE(config_count); 58365 COMPILER_REFERENCE(config_array); 58366 58367 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || \ 58368 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) || \ 58369 defined(BCM_APACHE_SUPPORT) 58370 /* 58371 * Internal timesync function handles port lock and adds 58372 * timesync config profiles 58373 */ 58374 if ((soc_feature(unit, soc_feature_timesync_v3) || SOC_IS_TRIUMPH3(unit) || 58375 SOC_IS_KATANAX(unit)|| SOC_IS_TD2_TT2(unit) || SOC_IS_SABER2(unit) || 58376 SOC_IS_APACHE(unit)) && 58377 (soc_feature(unit,soc_feature_timesync_support))) { 58378 rv = _bcm_esw_port_timesync_config_set(unit, port, config_count, 58379 config_array, is_remote_port); 58380 } else 58381 #endif /* defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA_SUPPORT) || 58382 defined(BCM_TIMESYNC_V3_SUPPORT) || defined(BCM_SABER2_SUPPORT) */ 58383 { 58384 rv = BCM_E_UNAVAIL; 58385 } 58386 58387 return rv; 58388 } 58389 58390 /* 58391 * Function: 58392 * bcm_esw_port_timesync_tx_timestamp_and_seqid_get 58393 * Purpose: 58394 * Retrives two-step PTP timestamp and seqid from MAC FIFO after packet TX 58395 * Parameters: 58396 * unit - (IN) Unit number. 58397 * port - (IN) Port 58398 * conf - (IN) Configuration 58399 * Returns: 58400 * BCM_E_xxx 58401 * Notes: 58402 */ 58403 58404 int 58405 bcm_esw_port_timesync_tx_info_get(int unit, bcm_port_t port, 58406 bcm_port_timesync_tx_info_t *tx_info) 58407 { 58408 int rv; 58409 58410 /* Make sure port module is initialized. */ 58411 PORT_INIT(unit); 58412 58413 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58414 58415 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) \ 58416 || defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) \ 58417 || defined(BCM_SABER2_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) 58418 /* 58419 * Internal timesync function handles port lock and retrieves 58420 * timesync config profiles 58421 */ 58422 if (((SOC_IS_TD2_TT2(unit)) || SOC_IS_HURRICANE3(unit) || SOC_IS_SABER2(unit) || SOC_IS_TRIDENT2(unit)) && 58423 (soc_feature(unit,soc_feature_timesync_support))) { 58424 if (SOC_USE_PORTCTRL(unit)) { 58425 rv = _bcm_esw_port_timesync_tx_info_get(unit, port, tx_info); 58426 } else { 58427 soc_port_timesync_tx_info_t info; 58428 sal_memset(&info, 0, sizeof(soc_port_timesync_tx_info_t)); 58429 58430 PORT_LOCK(unit) 58431 rv = MAC_TIMESYNC_TX_INFO_GET(PORT(unit, port).p_mac, unit, port, &info); 58432 PORT_UNLOCK(unit); 58433 COMPILER_64_SET(tx_info->timestamp, info.timestamps_in_fifo_hi, info.timestamps_in_fifo); 58434 tx_info->sequence_id = info.sequence_id; 58435 } 58436 } else 58437 #endif /* defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 58438 || defined(BCM_TOMAHAWK2_SUPPORT) */ 58439 { 58440 rv = BCM_E_UNAVAIL; 58441 } 58442 58443 return rv; 58444 } 58445 58446 /* 58447 * Function: 58448 * bcm_esw_port_timestamp_adjust_get 58449 * Purpose: 58450 * get OSTS,TSTS timestamp adjust based on current speed 58451 * Parameters: 58452 * unit - (IN) Unit number. 58453 * port - (IN) Port 58454 * ts_adjust - (OUT) configuration for tsts,osts timestamp adjustment. 58455 * Returns: 58456 * BCM_E_xxx 58457 * Notes: 58458 */ 58459 int 58460 bcm_esw_port_timestamp_adjust_get(int unit, bcm_port_t port, 58461 bcm_port_timestamp_adjust_t *ts_adjust) 58462 { 58463 int rv; 58464 58465 /* Make sure port module is initialized. */ 58466 PORT_INIT(unit); 58467 58468 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58469 58470 #ifdef PORTMOD_SUPPORT 58471 if (SOC_USE_PORTCTRL(unit)) { 58472 PORT_LOCK(unit); 58473 rv = bcmi_esw_portctrl_timestamp_adjust_get(unit, port, ts_adjust); 58474 PORT_UNLOCK(unit); 58475 } else 58476 #endif /* PORTMOD_SUPPORT */ 58477 { 58478 rv = BCM_E_UNAVAIL; 58479 } 58480 58481 return rv; 58482 58483 } 58484 58485 /* 58486 * Function: 58487 * bcm_esw_port_timestamp_adjust_set 58488 * Purpose: 58489 * set OSTS,TSTS timestamp adjust based on speed 58490 * Parameters: 58491 * unit - (IN) Unit number. 58492 * port - (IN) Port. 58493 * ts_adjust - (IN) configuration for tsts,osts timestamp adjust. 58494 * Returns: 58495 * BCM_E_xxx 58496 * Notes: 58497 */ 58498 int 58499 bcm_esw_port_timestamp_adjust_set(int unit, bcm_port_t port, 58500 bcm_port_timestamp_adjust_t *ts_adjust) 58501 { 58502 int rv; 58503 /* Make sure port module is initialized. */ 58504 PORT_INIT(unit); 58505 58506 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58507 58508 #ifdef PORTMOD_SUPPORT 58509 if (SOC_USE_PORTCTRL(unit)) { 58510 PORT_LOCK(unit); 58511 rv = bcmi_esw_portctrl_timestamp_adjust_set(unit, port, ts_adjust); 58512 PORT_UNLOCK(unit); 58513 } else 58514 #endif /* PORTMOD_SUPPORT */ 58515 { 58516 rv = BCM_E_UNAVAIL; 58517 } 58518 58519 return rv; 58520 58521 } 58522 58523 /* 58524 * Function: 58525 * bcm_esw_port_phy_timesync_config_set 58526 * Purpose: 58527 * Delete all matches for an existing port 58528 * Parameters: 58529 * unit - (IN) Unit number. 58530 * port - (IN) Port 58531 * conf - (IN) Configuration 58532 * Returns: 58533 * BCM_E_xxx 58534 * Notes: 58535 */ 58536 int 58537 bcm_esw_port_phy_timesync_config_set(int unit, bcm_port_t port, 58538 bcm_port_phy_timesync_config_t *conf) 58539 { 58540 int rv; 58541 /* Make sure port module is initialized. */ 58542 PORT_INIT(unit); 58543 58544 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58545 58546 #ifdef PORTMOD_SUPPORT 58547 if (SOC_USE_PORTCTRL(unit)) { 58548 PORT_LOCK(unit); 58549 rv = soc_portctrl_phy_timesync_config_set(unit, port, 58550 (soc_port_phy_timesync_config_t *)conf); 58551 PORT_UNLOCK(unit); 58552 } else 58553 #endif /* PORTMOD_SUPPORT */ 58554 { 58555 PORT_LOCK(unit); 58556 rv = soc_port_phy_timesync_config_set(unit, port, 58557 (soc_port_phy_timesync_config_t *)conf); 58558 PORT_UNLOCK(unit); 58559 } 58560 58561 return rv; 58562 } 58563 58564 /* 58565 * Function: 58566 * bcm_esw_port_phy_timesync_config_get 58567 * Purpose: 58568 * Delete all matches for an existing port 58569 * Parameters: 58570 * unit - (IN) Unit number. 58571 * port - (IN) Port 58572 * conf - (OUT) Configuration 58573 * Returns: 58574 * BCM_E_xxx 58575 * Notes: 58576 */ 58577 int 58578 bcm_esw_port_phy_timesync_config_get(int unit, bcm_port_t port, 58579 bcm_port_phy_timesync_config_t *conf) 58580 { 58581 int rv; 58582 58583 /* Make sure port module is initialized. */ 58584 PORT_INIT(unit); 58585 58586 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58587 58588 #ifdef PORTMOD_SUPPORT 58589 if (SOC_USE_PORTCTRL(unit)) { 58590 PORT_LOCK(unit); 58591 rv = soc_portctrl_phy_timesync_config_get(unit, port, 58592 (soc_port_phy_timesync_config_t *)conf); 58593 PORT_UNLOCK(unit); 58594 } else 58595 #endif /* PORTMOD_SUPPORT */ 58596 { 58597 PORT_LOCK(unit); 58598 rv = soc_port_phy_timesync_config_get(unit, port, 58599 (soc_port_phy_timesync_config_t *)conf); 58600 PORT_UNLOCK(unit); 58601 } 58602 58603 return rv; 58604 } 58605 58606 /* 58607 * Function: 58608 * bcm_esw_port_control_phy_timesync_set 58609 * Purpose: 58610 * Delete all matches for an existing port 58611 * Parameters: 58612 * unit - (IN) Unit number. 58613 * port - (IN) Port 58614 * type - (IN) Operation 58615 * value- (IN) Arg to operation 58616 * Returns: 58617 * BCM_E_xxx 58618 * Notes: 58619 */ 58620 int 58621 bcm_esw_port_control_phy_timesync_set(int unit, bcm_port_t port, 58622 bcm_port_control_phy_timesync_t type, 58623 uint64 value) 58624 { 58625 int rv; 58626 58627 /* Make sure port module is initialized. */ 58628 PORT_INIT(unit); 58629 58630 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58631 58632 #ifdef PORTMOD_SUPPORT 58633 if (SOC_USE_PORTCTRL(unit)) { 58634 PORT_LOCK(unit); 58635 rv = soc_portctrl_control_phy_timesync_set(unit, port, type, value); 58636 PORT_UNLOCK(unit); 58637 } else 58638 #endif /* PORTMOD_SUPPORT */ 58639 { 58640 PORT_LOCK(unit); 58641 rv = soc_port_control_phy_timesync_set(unit, port, type, value); 58642 PORT_UNLOCK(unit); 58643 } 58644 58645 return rv; 58646 } 58647 58648 /* 58649 * Function: 58650 * bcm_esw_port_control_phy_timesync_get 58651 * Purpose: 58652 * Delete all matches for an existing port 58653 * Parameters: 58654 * unit - (IN) Unit number. 58655 * port - (IN) Port 58656 * type - (IN) Operation 58657 * value- (OUT) Pointer to arg for operation 58658 * Returns: 58659 * BCM_E_xxx 58660 * Notes: 58661 */ 58662 int 58663 bcm_esw_port_control_phy_timesync_get(int unit, bcm_port_t port, 58664 bcm_port_control_phy_timesync_t type, 58665 uint64 *value) 58666 { 58667 int rv; 58668 58669 /* Make sure port module is initialized. */ 58670 PORT_INIT(unit); 58671 58672 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58673 58674 #ifdef PORTMOD_SUPPORT 58675 if (SOC_USE_PORTCTRL(unit)) { 58676 PORT_LOCK(unit); 58677 rv = soc_portctrl_control_phy_timesync_get(unit, port, type, value); 58678 PORT_UNLOCK(unit); 58679 } else 58680 #endif /* PORTMOD_SUPPORT */ 58681 { 58682 PORT_LOCK(unit); 58683 rv = soc_port_control_phy_timesync_get(unit, port, type, value); 58684 PORT_UNLOCK(unit); 58685 } 58686 58687 return rv; 58688 } 58689 58690 /* 58691 * Function: 58692 * bcm_esw_port_phy_timesync_enhanced_capture_get 58693 * Purpose: 58694 * Delete all matches for an existing port 58695 * Parameters: 58696 * unit - (IN) Unit number. 58697 * port - (IN) Port 58698 * value - (OUT) Configuration 58699 * Returns: 58700 * BCM_E_xxx 58701 * Notes: 58702 */ 58703 int 58704 bcm_esw_port_phy_timesync_enhanced_capture_get(int unit, bcm_port_t port, 58705 bcm_port_phy_timesync_enhanced_capture_t *value) 58706 { 58707 int rv; 58708 /* Make sure port module is initialized. */ 58709 PORT_INIT(unit); 58710 58711 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58712 58713 PORT_LOCK(unit); 58714 rv = soc_port_phy_timesync_enhanced_capture_get(unit, port, 58715 (soc_port_phy_timesync_enhanced_capture_t *)value); 58716 PORT_UNLOCK(unit); 58717 58718 return rv; 58719 } 58720 58721 /* bcm_port_config_phy_oam_set */ 58722 int bcm_esw_port_config_phy_oam_set(int unit, bcm_port_t port, 58723 bcm_port_config_phy_oam_t *conf){ 58724 int rv; 58725 58726 /* Make sure port module is initialized. */ 58727 PORT_INIT(unit); 58728 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58729 58730 #ifdef PORTMOD_SUPPORT 58731 if (SOC_USE_PORTCTRL(unit)) { 58732 rv = BCM_E_UNAVAIL; 58733 } else 58734 #endif /* PORTMOD_SUPPORT */ 58735 { 58736 58737 PORT_LOCK(unit); 58738 rv = soc_port_config_phy_oam_set(unit, port, 58739 (soc_port_config_phy_oam_t *)conf); 58740 PORT_UNLOCK(unit); 58741 } 58742 58743 return rv; 58744 } 58745 58746 /* bcm_port_config_phy_oam_get */ 58747 int bcm_esw_port_config_phy_oam_get(int unit, bcm_port_t port, 58748 bcm_port_config_phy_oam_t *conf){ 58749 int rv; 58750 58751 /* Make sure port module is initialized. */ 58752 PORT_INIT(unit); 58753 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58754 58755 #ifdef PORTMOD_SUPPORT 58756 if (SOC_USE_PORTCTRL(unit)) { 58757 rv = BCM_E_UNAVAIL; 58758 } else 58759 #endif /* PORTMOD_SUPPORT */ 58760 { 58761 PORT_LOCK(unit); 58762 rv = soc_port_config_phy_oam_get(unit, port, 58763 (soc_port_config_phy_oam_t *)conf); 58764 PORT_UNLOCK(unit); 58765 } 58766 58767 return rv; 58768 } 58769 58770 /* bcm_port_control_phy_oam_set */ 58771 int bcm_esw_port_control_phy_oam_set(int unit, bcm_port_t port, 58772 bcm_port_control_phy_oam_t type, 58773 uint64 value){ 58774 int rv; 58775 58776 /* Make sure port module is initialized. */ 58777 PORT_INIT(unit); 58778 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58779 58780 #ifdef PORTMOD_SUPPORT 58781 if (SOC_USE_PORTCTRL(unit)) { 58782 rv = BCM_E_UNAVAIL; 58783 } else 58784 #endif /* PORTMOD_SUPPORT */ 58785 { 58786 PORT_LOCK(unit); 58787 rv = soc_port_control_phy_oam_set(unit, port,type, value); 58788 PORT_UNLOCK(unit); 58789 } 58790 58791 return rv; 58792 } 58793 58794 /* bcm_port_control_phy_oam_get */ 58795 int bcm_esw_port_control_phy_oam_get(int unit, bcm_port_t port, 58796 bcm_port_control_phy_oam_t type, 58797 uint64 *value){ 58798 int rv; 58799 58800 /* Make sure port module is initialized. */ 58801 PORT_INIT(unit); 58802 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 58803 58804 #ifdef PORTMOD_SUPPORT 58805 if (SOC_USE_PORTCTRL(unit)) { 58806 rv = BCM_E_UNAVAIL; 58807 } else 58808 #endif /* PORTMOD_SUPPORT */ 58809 { 58810 PORT_LOCK(unit); 58811 rv = soc_port_control_phy_oam_get(unit, port,type, value); 58812 PORT_UNLOCK(unit); 58813 } 58814 58815 return rv; 58816 } 58817 58818 /* 58819 * Function: 58820 * bcm_esw_port_tpid_get_all 58821 * Purpose: 58822 * Get a list of tpids and associated color selections for a given port 58823 * Parameters: 58824 * unit - (IN) Unit number. 58825 * port - (IN) Port 58826 * size - (IN) number of elements of the next two array parameters 58827 *tpid_array - (OUT) buffer array to hold a list of retrieved tpids 58828 *color_array - (OUT) buffer array to hold a list of retrieved color selections 58829 * count - (OUT) actual number of tpids retrieved. 58830 * Returns: 58831 * BCM_E_xxx 58832 */ 58833 int 58834 bcm_esw_port_tpid_get_all(int unit, bcm_port_t port, 58835 int size, /* number of elements of the arrays */ 58836 uint16 *tpid_array, /* buffer array to hold a list of retrieved tpids */ 58837 int *color_array, /* buffer array to hold a list of retrieved colors */ 58838 int *count) /* actual number of tpids retrieved. */ 58839 { 58840 int rv = BCM_E_UNAVAIL; 58841 bcm_module_t mod_out; 58842 bcm_port_t port_out; 58843 bcm_trunk_t tgid_out; 58844 int id_out; 58845 int is_local = 0; 58846 58847 /* safety check */ 58848 if (size < 0 || count == NULL) { 58849 return BCM_E_PARAM; 58850 } 58851 if ((size > 0) && (tpid_array == NULL || color_array == NULL)) { 58852 return BCM_E_PARAM; 58853 } 58854 58855 *count = 0; 58856 58857 /* Make sure port module is initialized. */ 58858 PORT_INIT(unit); 58859 if (BCM_GPORT_IS_SET(port)) { 58860 /* Handle virtual ports separetly */ 58861 if (BCM_GPORT_IS_MPLS_PORT(port) || 58862 BCM_GPORT_IS_MIM_PORT(port) || 58863 BCM_GPORT_IS_TRILL_PORT(port) || 58864 BCM_GPORT_IS_VXLAN_PORT(port) || 58865 BCM_GPORT_IS_VLAN_PORT(port)) { 58866 58867 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 58868 #if defined(BCM_TRX_SUPPORT) 58869 PORT_LOCK(unit); 58870 rv = _bcm_trx_vp_tpid_get_all(unit, port, size, 58871 tpid_array, color_array,count); 58872 PORT_UNLOCK(unit); 58873 #endif 58874 } 58875 return rv; 58876 } else { 58877 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, 58878 &mod_out, &port_out, &tgid_out, &id_out)); 58879 if ((-1 != tgid_out) || (-1 != id_out)) { 58880 return BCM_E_PARAM; 58881 } 58882 58883 BCM_IF_ERROR_RETURN 58884 (_bcm_esw_modid_is_local(unit, mod_out, &is_local)); 58885 if (!is_local) { 58886 return BCM_E_PORT; 58887 } else { 58888 BCM_IF_ERROR_RETURN( 58889 bcm_esw_port_local_get(unit, port, &port)); 58890 } 58891 } 58892 58893 } else if (!SOC_PORT_VALID(unit, port)) { 58894 return BCM_E_PORT; 58895 } 58896 58897 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRX_SUPPORT) \ 58898 || defined(BCM_RAVEN_SUPPORT) 58899 if (soc_feature(unit, soc_feature_vlan_ctrl)) { 58900 PORT_LOCK(unit); 58901 rv = _bcm_fb2_port_tpid_get_all(unit, port, size,tpid_array, 58902 color_array, count); 58903 PORT_UNLOCK(unit); 58904 } 58905 #endif 58906 return (rv); 58907 } 58908 void bcm_esw_kt2_port_lock(int unit) 58909 { 58910 PORT_LOCK(unit); 58911 } 58912 void bcm_esw_kt2_port_unlock(int unit) 58913 { 58914 PORT_UNLOCK(unit); 58915 } 58916 58917 #ifdef BCM_WARM_BOOT_SUPPORT 58918 int 58919 _bcm_port_cleanup(int unit) 58920 { 58921 #if defined(BCM_FIREBOLT_SUPPORT) 58922 if (SOC_IS_FB_FX_HX(unit)) { 58923 bcm_port_t port; 58924 58925 for (port = 0; port < SOC_MAX_NUM_PORTS; port++) { 58926 if (PORT(unit, port).p_vd_pbvl != NULL) { 58927 sal_free(PORT(unit, port).p_vd_pbvl); 58928 PORT(unit, port).p_vd_pbvl = NULL; 58929 } 58930 58931 if (PORT(unit, port).e2ecc_config != NULL) { 58932 sal_free(PORT(unit, port).e2ecc_config); 58933 PORT(unit, port).e2ecc_config = NULL; 58934 } 58935 } 58936 58937 if (bcm_port_info[unit] != NULL) { 58938 sal_free(bcm_port_info[unit]); 58939 bcm_port_info[unit] = NULL; 58940 } 58941 } 58942 #endif /* BCM_FIREBOLT_SUPPORT */ 58943 58944 return BCM_E_NONE; 58945 } 58946 #endif /* BCM_WARM_BOOT_SUPPORT */ 58947 58948 #ifndef BCM_SW_STATE_DUMP_DISABLE 58949 /* 58950 * Function: 58951 * _bcm_port_sw_dump 58952 * Purpose: 58953 * Displays port information maintained by software. 58954 * Parameters: 58955 * unit - Device unit number 58956 * Returns: 58957 * None 58958 * Note: 58959 * Skip following structure fields: p_phy, p_mac 58960 */ 58961 void 58962 _bcm_port_sw_dump(int unit) 58963 { 58964 _bcm_port_info_t *info; 58965 int i, j; 58966 int idxmax, entries, max_num_ports = 0; 58967 bcm_port_t port; 58968 bcm_pbmp_t all_pbmp; 58969 58970 info = bcm_port_info[unit]; 58971 idxmax = soc_mem_index_max(unit, VLAN_PROTOCOLm) + 1; 58972 entries = (idxmax + (_BCM_PORT_VD_PBVL_ESIZE - 1)) / _BCM_PORT_VD_PBVL_ESIZE; 58973 58974 max_num_ports = SOC_MAX_NUM_PORTS; 58975 58976 SOC_PBMP_CLEAR(all_pbmp); 58977 SOC_PBMP_ASSIGN(all_pbmp, PBMP_ALL(unit)); 58978 58979 #ifdef BCM_KATANA2_SUPPORT 58980 if (soc_feature(unit, soc_feature_linkphy_coe) || 58981 soc_feature(unit, soc_feature_subtag_coe)) { 58982 _bcm_kt2_subport_pbmp_update (unit, &all_pbmp); 58983 if (SOC_INFO(unit).linkphy_enabled || 58984 SOC_INFO(unit).subtag_enabled) { 58985 max_num_ports = SOC_MAX_NUM_PP_PORTS; 58986 } 58987 } 58988 #endif 58989 58990 58991 LOG_CLI((BSL_META_U(unit, 58992 "\nSW Information Port - Unit %d\n"), unit)); 58993 58994 if (info != NULL) { 58995 for (i = 0; i < max_num_ports; i++) { 58996 LOG_CLI((BSL_META_U(unit, 58997 " Port %2d : "), i)); 58998 LOG_CLI((BSL_META_U(unit, 58999 " MAC driver - %s\n"), 59000 ((SOC_PORT_VALID(unit, i)) && (info[i].p_mac != NULL)) ? 59001 (info[i].p_mac)->drv_name : "none")); 59002 LOG_CLI((BSL_META_U(unit, 59003 " Untagged priority - %d\n"), 59004 info[i].p_ut_prio)); 59005 LOG_CLI((BSL_META_U(unit, 59006 " Double-tag mode - "))); 59007 if (0 != info[i].dtag_mode) { 59008 if (0 != (info[i].dtag_mode & 59009 BCM_PORT_DTAG_MODE_INTERNAL)) { 59010 LOG_CLI((BSL_META_U(unit, 59011 " Internal"))); 59012 } 59013 if (0 != (info[i].dtag_mode & 59014 BCM_PORT_DTAG_MODE_EXTERNAL)) { 59015 LOG_CLI((BSL_META_U(unit, 59016 " External"))); 59017 } 59018 if (0 != (info[i].dtag_mode & 59019 BCM_PORT_DTAG_ADD_EXTERNAL_TAG)) { 59020 LOG_CLI((BSL_META_U(unit, 59021 " AddTag"))); 59022 } 59023 if (0 != (info[i].dtag_mode & 59024 BCM_PORT_DTAG_REMOVE_EXTERNAL_TAG)) { 59025 LOG_CLI((BSL_META_U(unit, 59026 " RemoveTag"))); 59027 } 59028 } else { 59029 LOG_CLI((BSL_META_U(unit, 59030 " None"))); 59031 } 59032 LOG_CLI((BSL_META_U(unit, 59033 "\n"))); 59034 LOG_CLI((BSL_META_U(unit, 59035 " VLAN_PROTOCOL_DATA index - %d\n"), 59036 info[i].vlan_prot_ptr)); 59037 LOG_CLI((BSL_META_U(unit, 59038 " Number of VPs - %d\n"), 59039 info[i].vp_count)); 59040 } 59041 59042 LOG_CLI((BSL_META_U(unit, 59043 "\n"))); 59044 59045 LOG_CLI((BSL_META_U(unit, 59046 " Protocol based VLAN - \n"))); 59047 LOG_CLI((BSL_META_U(unit, 59048 " Total Entries : %d\n"), entries)); 59049 59050 PBMP_ITER(all_pbmp, port) { 59051 LOG_CLI((BSL_META_U(unit, 59052 " Port %2d : "), port)); 59053 if (info[port].p_vd_pbvl == NULL) { 59054 LOG_CLI((BSL_META_U(unit, 59055 "\n"))); 59056 continue; 59057 } 59058 59059 for (j = 0; j < entries; j++) { 59060 if ((j > 0) && !(j % 10)) { 59061 LOG_CLI((BSL_META_U(unit, 59062 "\n "))); 59063 } 59064 LOG_CLI((BSL_META_U(unit, 59065 " 0x%2.2x"), info[port].p_vd_pbvl[j])); 59066 } 59067 LOG_CLI((BSL_META_U(unit, 59068 "\n"))); 59069 } 59070 59071 if (soc_feature(unit, soc_feature_e2ecc)) { 59072 bcm_port_congestion_config_t *e2ep; 59073 59074 LOG_CLI((BSL_META_U(unit, 59075 "\n"))); 59076 LOG_CLI((BSL_META_U(unit, 59077 " E2E Congestion Control - \n"))); 59078 PBMP_ALL_ITER(unit, port) { 59079 e2ep = info[port].e2ecc_config; 59080 if (NULL == e2ep) { 59081 continue; 59082 } 59083 59084 if ((0 == (e2ep->flags & (BCM_PORT_CONGESTION_CONFIG_E2ECC | 59085 BCM_PORT_CONGESTION_CONFIG_DESTMOD_FLOW_CONTROL | 59086 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE | 59087 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE)))) { 59088 continue; 59089 } 59090 59091 LOG_CLI((BSL_META_U(unit, 59092 "\n Port : %d\n"), port)); 59093 if ((e2ep->flags & 59094 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) || 59095 (e2ep->flags & 59096 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE)) { 59097 LOG_CLI((BSL_META_U(unit, 59098 " E2ECC COE Flags: %s %s \n"), 59099 (e2ep->flags & 59100 BCM_PORT_CONGESTION_CONFIG_RX) ? 59101 "RX" : "", 59102 ((e2ep->flags & 59103 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_FLEX_MODE) ? 59104 "FLEX mode": 59105 (e2ep->flags & 59106 BCM_PORT_CONGESTION_CONFIG_E2ECC_COE_STRICT_MODE) ? 59107 "STRICT mode" : ""))) ; 59108 } else { 59109 LOG_CLI((BSL_META_U(unit, 59110 " Flags : %s %s %s\n"), 59111 (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_E2ECC) ? 59112 "E2ECC" : "DestMod Flow control", 59113 (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_TX) ? 59114 "TX" : "", 59115 (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_RX) ? 59116 "RX" : "")); 59117 } 59118 59119 if (e2ep->flags & BCM_PORT_CONGESTION_CONFIG_TX) { 59120 LOG_CLI((BSL_META_U(unit, 59121 " Port bits : 0x%02x\n"), 59122 e2ep->port_bits)); 59123 LOG_CLI((BSL_META_U(unit, 59124 " Packets/sec : %d\n"), 59125 e2ep->packets_per_sec)); 59126 LOG_CLI((BSL_META_U(unit, 59127 " Source gport : 0x%08x\n"), 59128 e2ep->src_port)); 59129 LOG_CLI((BSL_META_U(unit, 59130 " Multicast ID : 0x%04x\n"), 59131 e2ep->multicast_id)); 59132 LOG_CLI((BSL_META_U(unit, 59133 " Traffic class : %d\n"), 59134 e2ep->traffic_class)); 59135 LOG_CLI((BSL_META_U(unit, 59136 " Color : %d\n"), 59137 e2ep->color)); 59138 LOG_CLI((BSL_META_U(unit, 59139 " Source MAC : 0x%02x%02x%02x%02x%02x%02x\n"), 59140 e2ep->src_mac[0], e2ep->src_mac[1], 59141 e2ep->src_mac[2], e2ep->src_mac[3], 59142 e2ep->src_mac[4], e2ep->src_mac[5])); 59143 } 59144 59145 LOG_CLI((BSL_META_U(unit, 59146 " Destination MAC : " 59147 "0x%02x%02x%02x%02x%02x%02x\n"), 59148 e2ep->dest_mac[0], e2ep->dest_mac[1], 59149 e2ep->dest_mac[2], e2ep->dest_mac[3], 59150 e2ep->dest_mac[4], e2ep->dest_mac[5])); 59151 LOG_CLI((BSL_META_U(unit, 59152 " Ethertype : 0x%04x\n"), 59153 e2ep->ethertype)); 59154 LOG_CLI((BSL_META_U(unit, 59155 " Opcode : 0x%04x\n"), 59156 e2ep->opcode)); 59157 } 59158 } 59159 59160 #ifdef BCM_TRIUMPH2_SUPPORT 59161 if (soc_feature(unit, soc_feature_src_modid_blk_profile)) { 59162 59163 LOG_CLI((BSL_META_U(unit, 59164 "\n"))); 59165 LOG_CLI((BSL_META_U(unit, 59166 " Source Modid Egress Blocking Profiles - \n"))); 59167 PBMP_ITER(all_pbmp, port) { 59168 if (-1 == PORT_SRC_MOD_EGR_PROF_PTR(unit, port)) { 59169 continue; 59170 } 59171 LOG_CLI((BSL_META_U(unit, 59172 " Port %2d : "), port)); 59173 LOG_CLI((BSL_META_U(unit, 59174 "Profile index %d\n"), 59175 PORT_SRC_MOD_EGR_PROF_PTR(unit, port))); 59176 } 59177 /* Display those entries with reference count > 0 */ 59178 if (PORT_SRC_MOD_EGR_PROFILE(unit) != NULL) { 59179 int i; 59180 int num_entries; 59181 int ref_count; 59182 int entries_per_set; 59183 int modid_count; 59184 uint32 index; 59185 pbmp_t sme_pbmp; 59186 src_modid_egress_entry_t *entry_p; 59187 char sme_pfm[SOC_PBMP_FMT_LEN]; 59188 59189 num_entries = soc_mem_index_count(unit, 59190 PORT_SRC_MOD_EGR_PROFILE(unit)->tables[0].mem); 59191 LOG_CLI((BSL_META_U(unit, 59192 " Source Modid Egress Profile\n"))); 59193 LOG_CLI((BSL_META_U(unit, 59194 " Number of entries: %d\n"), num_entries)); 59195 LOG_CLI((BSL_META_U(unit, 59196 " Index RefCount EntriesPerSet - " 59197 "PortBlockMaskBitmap\n"))); 59198 59199 modid_count = SOC_MODID_MAX(unit) + 1; 59200 for (index = 0; index < num_entries; index += modid_count) { 59201 if (SOC_FAILURE(soc_profile_mem_ref_count_get(unit, 59202 PORT_SRC_MOD_EGR_PROFILE(unit), 59203 index, &ref_count))) { 59204 break; 59205 } 59206 59207 if (ref_count <= 0) { 59208 continue; 59209 } 59210 59211 for (i = 0; i < modid_count; i++) { 59212 entries_per_set = 59213 PORT_SRC_MOD_EGR_PROFILE(unit)->tables[0].\ 59214 entries[index+i].entries_per_set; 59215 entry_p = SOC_PROFILE_MEM_ENTRY(unit, 59216 PORT_SRC_MOD_EGR_PROFILE(unit), 59217 src_modid_egress_entry_t *, 59218 index + i); 59219 soc_mem_pbmp_field_get(unit, SRC_MODID_EGRESSm, 59220 entry_p, 59221 PORT_BLOCK_MASK_BITMAPf, 59222 &sme_pbmp); 59223 59224 if (BCM_PBMP_NOT_NULL(sme_pbmp)) { 59225 LOG_CLI((BSL_META_U(unit, 59226 " %5d %8d %13d "), 59227 index + i, ref_count, 59228 entries_per_set)); 59229 LOG_CLI((BSL_META_U(unit, 59230 "%s\n"), 59231 SOC_PBMP_FMT(sme_pbmp, sme_pfm))); 59232 } 59233 } 59234 } 59235 } 59236 } 59237 #endif /* BCM_TRIUMPH2_SUPPORT */ 59238 } 59239 59240 LOG_CLI((BSL_META_U(unit, 59241 "\n"))); 59242 59243 return; 59244 } 59245 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 59246 59247 59248 /* 59249 * Function: 59250 * _bcm_esw_port_gport_phyn_validate 59251 * Purpose: 59252 * Validate PHY specific gport 59253 * Parameters: 59254 * unit - (IN) Unit number. 59255 * port - (IN) Port number. 59256 * local_port - (OUT) Local Port number. 59257 * phyn - (OUT) Phy number 59258 * phy_lane - (OUT) Lane number 59259 * sys_side - (OUT) System side(1)or line side(0). 59260 * Returns: 59261 * BCM_E_XXX 59262 */ 59263 59264 int 59265 _bcm_esw_port_gport_phyn_validate(int unit, bcm_port_t port, 59266 bcm_port_t *local_port, int *phyn, 59267 int *phy_lane, int *sys_side) 59268 { 59269 /* Validate input arguments */ 59270 if (local_port == NULL || phy_lane == NULL || 59271 phyn == NULL || sys_side == NULL) { 59272 return BCM_E_PARAM; 59273 } 59274 59275 if (BCM_PHY_GPORT_IS_PHYN(port)) { 59276 *local_port = BCM_PHY_GPORT_PHYN_PORT_PORT_GET(port); 59277 *phyn = BCM_PHY_GPORT_PHYN_PORT_PHYN_GET(port); 59278 *phy_lane = -1; 59279 } else if(BCM_PHY_GPORT_IS_PHYN_LANE(port)) { 59280 *local_port = BCM_PHY_GPORT_PHYN_LANE_PORT_PORT_GET(port); 59281 *phyn = BCM_PHY_GPORT_PHYN_LANE_PORT_PHYN_GET(port); 59282 *phy_lane = BCM_PHY_GPORT_PHYN_LANE_PORT_LANE_GET(port); 59283 } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE(port)) { 59284 *local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PORT_GET(port); 59285 *phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_PORT_PHYN_GET(port); 59286 *sys_side = TRUE; 59287 *phy_lane = -1; 59288 } else if(BCM_PHY_GPORT_IS_PHYN_SYS_SIDE_LANE(port)) { 59289 *local_port = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PORT_GET(port); 59290 *phyn = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_PHYN_GET(port); 59291 *phy_lane = BCM_PHY_GPORT_PHYN_SYS_SIDE_LANE_PORT_LANE_GET(port); 59292 *sys_side = TRUE; 59293 } else if (BCM_PHY_GPORT_IS_LANE(port)) { 59294 *local_port = BCM_PHY_GPORT_LANE_PORT_PORT_GET(port); 59295 *phy_lane = BCM_PHY_GPORT_LANE_PORT_LANE_GET(port); 59296 } else { 59297 *local_port = -1; 59298 return BCM_E_NONE; 59299 } 59300 59301 if (!SOC_PORT_VALID(unit, *local_port)) { 59302 return BCM_E_PORT; 59303 } 59304 59305 return BCM_E_NONE; 59306 } 59307 59308 /** 59309 * Function: 59310 * _bcm_esw_link_force_for_disabled_loopback_port 59311 * Purpose: 59312 * Force linkscan's current link status on for a disabled port 59313 * which is configured to MAC loopback. 59314 * Parameters: 59315 * unit - (IN) Unit number. 59316 * Returns: 59317 * BCM_E_xxx 59318 * Notes: 59319 */ 59320 int 59321 _bcm_esw_link_force_for_disabled_loopback_port(int unit) 59322 { 59323 bcm_port_t port; 59324 int loopback; 59325 int enable; 59326 bcm_pbmp_t pbmp; 59327 59328 SOC_PBMP_ASSIGN(pbmp, PBMP_E_ALL(unit)); 59329 #if defined(BCM_SABER2_SUPPORT) 59330 if(SOC_IS_SABER2(unit)){ 59331 /* 59332 * During warmboot init, the oamp port is not removed 59333 * from ethernet bitmaps till sat is initialized. 59334 * So manually removing it here. 59335 */ 59336 int oamp_enable; 59337 (void)bcm_sb2_sat_oamp_enable_get(unit, &oamp_enable); 59338 /* Skip OAMP port for saber2 device */ 59339 if(oamp_enable) { 59340 SOC_PBMP_PORT_REMOVE(pbmp, 59341 _BCM_SB2_SAT_OAMP_PHY_PORT_NUMBER); 59342 } 59343 } 59344 #endif 59345 59346 PBMP_ITER(pbmp,port) { 59347 BCM_IF_ERROR_RETURN( 59348 bcm_esw_port_loopback_get(unit, port, &loopback)); 59349 BCM_IF_ERROR_RETURN( 59350 bcm_esw_port_enable_get(unit, port, &enable)); 59351 if ((loopback == BCM_PORT_LOOPBACK_MAC) && (enable == FALSE)) { 59352 BCM_IF_ERROR_RETURN 59353 (_bcm_esw_link_force(unit, 0 /*flags*/, port, TRUE, TRUE)); 59354 } 59355 } 59356 59357 return BCM_E_NONE; 59358 } 59359 59360 #ifdef BCM_MAVERICK2_SUPPORT 59361 /** 59362 * Function: 59363 * _bcm_esw_mv2_asf_init 59364 * Purpose: 59365 * Initialize ASF subsystem and configure all the applicable ports 59366 * to the specified forwarding mode 59367 * Parameters: 59368 * unit - (IN) Unit number. 59369 * mode - (IN) forwarding mode 59370 * Returns: 59371 * BCM_E_xxx 59372 */ 59373 STATIC int 59374 _bcm_esw_mv2_asf_init( 59375 int unit, 59376 soc_mv2_asf_mode_e asf_mode) 59377 { 59378 bcm_port_t port; 59379 int speed; 59380 soc_info_t *si; 59381 59382 if (!(si = &SOC_INFO(unit))) { 59383 return BCM_E_INTERNAL; 59384 } 59385 59386 BCM_IF_ERROR_RETURN(soc_mv2_asf_init_start(unit)); 59387 59388 PBMP_ALL_ITER(unit, port) { 59389 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 59390 continue; 59391 } 59392 speed = si->port_init_speed[port]; 59393 if (speed == 0) { 59394 BCM_IF_ERROR_RETURN( 59395 bcm_esw_port_speed_get(unit, port, &speed)); 59396 } 59397 BCM_IF_ERROR_RETURN( 59398 soc_mv2_port_asf_init(unit, port, speed, asf_mode)); 59399 } 59400 BCM_IF_ERROR_RETURN(soc_mv2_asf_init_done(unit)); 59401 59402 return BCM_E_NONE; 59403 } 59404 59405 STATIC int 59406 _bcm_esw_mv2_port_asf_mode_set( 59407 int unit, 59408 bcm_port_t port, 59409 int mode) 59410 { 59411 int rv = BCM_E_NONE, speed; 59412 soc_info_t *si; 59413 int txp = 0, rxp = 0; 59414 pbmp_t *pause_bmp; 59415 59416 if (!(si = &SOC_INFO(unit))) { 59417 return SOC_E_INTERNAL; 59418 } 59419 59420 pause_bmp = soc_mv2_port_asf_pause_bpmp_get(unit); 59421 if (pause_bmp == NULL) { 59422 return BCM_E_INTERNAL; 59423 } 59424 59425 /* Update Pause for ASF mode */ 59426 if (_SOC_MV2_ASF_MODE_SAF != mode) { 59427 /* Disable rx pause for cut through */ 59428 BCM_IF_ERROR_RETURN 59429 (bcm_esw_port_pause_get(unit, port, &txp, &rxp)); 59430 59431 if (rxp) { 59432 SOC_PBMP_PORT_ADD((*pause_bmp), port); 59433 } 59434 BCM_IF_ERROR_RETURN 59435 (bcm_esw_port_pause_set(unit, port, txp, 0)); 59436 59437 } 59438 59439 speed = si->port_init_speed[port]; 59440 if (speed == 0) { 59441 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed)); 59442 } 59443 PORT_LOCK(unit); 59444 rv = soc_mv2_port_asf_mode_set(unit, port, speed, mode); 59445 PORT_UNLOCK(unit); 59446 59447 /* Update Pause for ASF mode */ 59448 if (((rv != SOC_E_NONE) && (_SOC_MV2_ASF_MODE_SAF != mode)) || 59449 ((rv == SOC_E_NONE) && (_SOC_MV2_ASF_MODE_SAF == mode))) { 59450 /* restore pause */ 59451 if (SOC_PBMP_MEMBER((*pause_bmp), port)) { 59452 BCM_IF_ERROR_RETURN 59453 (bcm_esw_port_pause_get(unit, port, &txp, &rxp)); 59454 BCM_IF_ERROR_RETURN 59455 (bcm_esw_port_pause_set(unit, port, txp, 1)); 59456 SOC_PBMP_PORT_REMOVE((*pause_bmp), port); 59457 } 59458 } 59459 59460 return rv; 59461 } 59462 #endif 59463 59464 #ifdef BCM_TRIDENT3_SUPPORT 59465 /** 59466 * Function: 59467 * _bcm_esw_td3_asf_init 59468 * Purpose: 59469 * Initialize ASF subsystem and configure all the applicable ports 59470 * to the specified forwarding mode 59471 * Parameters: 59472 * unit - (IN) Unit number. 59473 * mode - (IN) forwarding mode 59474 * Returns: 59475 * BCM_E_xxx 59476 */ 59477 STATIC int 59478 _bcm_esw_td3_asf_init( 59479 int unit, 59480 soc_td3_asf_mode_e asf_mode) 59481 { 59482 bcm_port_t port; 59483 int speed; 59484 soc_info_t *si; 59485 59486 if (!(si = &SOC_INFO(unit))) { 59487 return BCM_E_INTERNAL; 59488 } 59489 59490 BCM_IF_ERROR_RETURN(soc_td3_asf_init_start(unit)); 59491 59492 PBMP_ALL_ITER(unit, port) { 59493 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 59494 continue; 59495 } 59496 speed = si->port_init_speed[port]; 59497 if (speed == 0) { 59498 BCM_IF_ERROR_RETURN( 59499 bcm_esw_port_speed_get(unit, port, &speed)); 59500 } 59501 BCM_IF_ERROR_RETURN( 59502 soc_td3_port_asf_init(unit, port, speed, asf_mode)); 59503 } 59504 BCM_IF_ERROR_RETURN(soc_td3_asf_init_done(unit)); 59505 59506 return BCM_E_NONE; 59507 } 59508 59509 STATIC int 59510 _bcm_esw_td3_port_asf_mode_set( 59511 int unit, 59512 bcm_port_t port, 59513 int mode) 59514 { 59515 int rv = BCM_E_NONE, speed; 59516 soc_info_t *si; 59517 int txp = 0, rxp = 0; 59518 pbmp_t *pause_bmp; 59519 59520 if (!(si = &SOC_INFO(unit))) { 59521 return SOC_E_INTERNAL; 59522 } 59523 59524 pause_bmp = soc_td3_port_asf_pause_bpmp_get(unit); 59525 if (pause_bmp == NULL) { 59526 return BCM_E_INTERNAL; 59527 } 59528 59529 /* Update Pause for ASF mode */ 59530 if (_SOC_TD3_ASF_MODE_SAF != mode) { 59531 /* Disable rx pause for cut through */ 59532 BCM_IF_ERROR_RETURN 59533 (bcm_esw_port_pause_get(unit, port, &txp, &rxp)); 59534 59535 if (rxp) { 59536 SOC_PBMP_PORT_ADD((*pause_bmp), port); 59537 } 59538 BCM_IF_ERROR_RETURN 59539 (bcm_esw_port_pause_set(unit, port, txp, 0)); 59540 59541 } 59542 59543 speed = si->port_init_speed[port]; 59544 if (speed == 0) { 59545 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed)); 59546 } 59547 PORT_LOCK(unit); 59548 rv = soc_td3_port_asf_mode_set(unit, port, speed, mode); 59549 PORT_UNLOCK(unit); 59550 59551 /* Update Pause for ASF mode */ 59552 if (((rv != SOC_E_NONE) && (_SOC_TD3_ASF_MODE_SAF != mode)) || 59553 ((rv == SOC_E_NONE) && (_SOC_TD3_ASF_MODE_SAF == mode))) { 59554 /* restore pause */ 59555 if (SOC_PBMP_MEMBER((*pause_bmp), port)) { 59556 BCM_IF_ERROR_RETURN 59557 (bcm_esw_port_pause_get(unit, port, &txp, &rxp)); 59558 BCM_IF_ERROR_RETURN 59559 (bcm_esw_port_pause_set(unit, port, txp, 1)); 59560 SOC_PBMP_PORT_REMOVE((*pause_bmp), port); 59561 } 59562 } 59563 59564 return rv; 59565 } 59566 #endif 59567 59568 #if defined(BCM_TOMAHAWK_SUPPORT) 59569 /* ASF (Cut-thru Forwarding) */ 59570 59571 /** 59572 * Function: 59573 * _bcm_esw_asf_init 59574 * Purpose: 59575 * Initialize ASF subsystem and configure all the applicable ports 59576 * to the specified forwarding mode 59577 * Parameters: 59578 * unit - (IN) Unit number. 59579 * mode - (IN) forwarding mode 59580 * Returns: 59581 * BCM_E_xxx 59582 */ 59583 STATIC int 59584 _bcm_esw_asf_init( 59585 int unit, 59586 soc_th_asf_mode_e asf_mode) 59587 { 59588 bcm_port_t port; 59589 int speed; 59590 soc_info_t *si; 59591 59592 if (!(si = &SOC_INFO(unit))) { 59593 return SOC_E_INTERNAL; 59594 } 59595 59596 if (!soc_feature(unit, soc_feature_asf_multimode)) { 59597 return BCM_E_UNAVAIL; 59598 } 59599 59600 #ifdef BCM_WARM_BOOT_SUPPORT 59601 if (SOC_WARM_BOOT(unit)) { 59602 /* WB recovery happens in _bcm_esw_port_wb_recover context */ 59603 return BCM_E_NONE; 59604 } 59605 #endif /* BCM_WARM_BOOT_SUPPORT */ 59606 59607 #ifdef BCM_TOMAHAWK3_SUPPORT 59608 if (SOC_IS_TOMAHAWK3(unit)) { 59609 return soc_th3_asf_init(unit); 59610 } else 59611 #endif 59612 { 59613 BCM_IF_ERROR_RETURN(soc_th_asf_init_start(unit)); 59614 59615 PBMP_ALL_ITER(unit, port) { 59616 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 59617 continue; 59618 } 59619 speed = si->port_init_speed[port]; 59620 BCM_IF_ERROR_RETURN( 59621 soc_th_port_asf_init(unit, port, speed, asf_mode)); 59622 } 59623 BCM_IF_ERROR_RETURN(soc_th_asf_init_done(unit)); 59624 } 59625 59626 return BCM_E_NONE; 59627 } 59628 59629 /** 59630 * Function: 59631 * _bcm_esw_asf_deinit 59632 * Purpose: 59633 * Deinitialize ASF subsystem and release ASF internal structures 59634 * Parameters: 59635 * unit - (IN) Unit number. 59636 * Returns: 59637 * BCM_E_xxx 59638 */ 59639 STATIC int 59640 _bcm_esw_asf_deinit(int unit) 59641 { 59642 #ifdef BCM_TRIDENT3_SUPPORT 59643 if (SOC_IS_TRIDENT3X(unit)) { 59644 return soc_td3_asf_deinit(unit); 59645 } else 59646 #endif 59647 #ifdef BCM_TOMAHAWK3_SUPPORT 59648 if (SOC_IS_TOMAHAWK3(unit)) { 59649 return soc_th3_asf_deinit(unit); 59650 } else 59651 #endif 59652 { 59653 if (SOC_IS_TOMAHAWKX(unit)) { 59654 return soc_th_asf_deinit(unit); 59655 } 59656 } 59657 59658 return BCM_E_NONE; 59659 } 59660 59661 #ifdef BCM_WARM_BOOT_SUPPORT 59662 /** 59663 * Function: 59664 * bcm_esw_asf_wb_memsz_get 59665 * Purpose: 59666 * Returns the WB Memory requirement from ASF subsystem 59667 * Parameters: 59668 * unit - (IN) Unit number 59669 * mem_sz - (OUT) WB Memory required in bytes 59670 * Returns: 59671 * BCM_E_xxx 59672 */ 59673 STATIC int 59674 _bcm_esw_asf_wb_memsz_get( 59675 int unit, 59676 OUT uint32* const mem_sz, 59677 uint16 scache_ver) 59678 { 59679 int rv; 59680 59681 if (soc_feature(unit, soc_feature_asf_multimode)) { 59682 #ifdef BCM_MAVERICK2_SUPPORT 59683 if (SOC_IS_MAVERICK2(unit)) { 59684 rv = soc_mv2_asf_wb_memsz_get(unit, mem_sz, scache_ver); 59685 } else 59686 #endif 59687 #ifdef BCM_TRIDENT3_SUPPORT 59688 if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_MAVERICK2(unit)) { 59689 rv = soc_td3_asf_wb_memsz_get(unit, mem_sz, scache_ver); 59690 } else 59691 #endif 59692 #ifdef BCM_TOMAHAWK3_SUPPORT 59693 if (SOC_IS_TOMAHAWK3(unit)) { 59694 rv = soc_th3_asf_wb_memsz_get(unit, mem_sz, scache_ver); 59695 } else 59696 #endif 59697 if (SOC_IS_TOMAHAWKX(unit)) { 59698 rv = soc_th_asf_wb_memsz_get(unit, mem_sz, scache_ver); 59699 } else { 59700 *mem_sz = 0; 59701 rv = BCM_E_NONE; 59702 } 59703 } else { 59704 *mem_sz = 0; 59705 rv = BCM_E_NONE; 59706 } 59707 59708 return rv; 59709 } 59710 59711 /** 59712 * Function: 59713 * _bcm_esw_asf_wb_sync 59714 * Purpose: 59715 * ASF Warmboot Sync 59716 * Parameters: 59717 * unit - (IN) Unit number 59718 * wb_data - (IN/OUT) ptr to ASF WB data area 59719 * Returns: 59720 * BCM_E_xxx 59721 */ 59722 STATIC int 59723 _bcm_esw_asf_wb_sync( 59724 int unit, 59725 IN_OUT uint8* wb_data) 59726 { 59727 int rv; 59728 59729 if (soc_feature(unit, soc_feature_asf_multimode)) { 59730 #ifdef BCM_MAVERICK2_SUPPORT 59731 if (SOC_IS_MAVERICK2(unit)) { 59732 rv = soc_mv2_asf_wb_sync(unit, wb_data); 59733 } else 59734 #endif 59735 #ifdef BCM_TRIDENT3_SUPPORT 59736 if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_MAVERICK2(unit)) { 59737 rv = soc_td3_asf_wb_sync(unit, wb_data); 59738 } else 59739 #endif 59740 #ifdef BCM_TOMAHAWK3_SUPPORT 59741 if (SOC_IS_TOMAHAWK3(unit)) { 59742 rv = soc_th3_asf_wb_sync(unit, wb_data); 59743 } else 59744 #endif 59745 59746 if (SOC_IS_TOMAHAWKX(unit)) { 59747 rv = soc_th_asf_wb_sync(unit, wb_data); 59748 } else { 59749 rv = BCM_E_NONE; 59750 } 59751 } else { 59752 rv = BCM_E_NONE; 59753 } 59754 59755 return rv; 59756 } 59757 59758 /** 59759 * Function: 59760 * _bcm_esw_asf_wb_recover 59761 * Purpose: 59762 * ASF Warmboot Recovery 59763 * Parameters: 59764 * unit - (IN) Unit number 59765 * wb_data - (IN) pointer to ASF WB data area 59766 * Returns: 59767 * BCM_E_xxx 59768 */ 59769 STATIC int 59770 _bcm_esw_asf_wb_recover( 59771 int unit, 59772 uint8* const wb_data, 59773 uint16 scache_ver) 59774 { 59775 int rv; 59776 59777 if (soc_feature(unit, soc_feature_asf_multimode)) { 59778 #ifdef BCM_MAVERICK2_SUPPORT 59779 if (SOC_IS_MAVERICK2(unit)) { 59780 rv = soc_mv2_asf_wb_recover(unit, wb_data, scache_ver); 59781 } else 59782 #endif 59783 #ifdef BCM_TRIDENT3_SUPPORT 59784 if (SOC_IS_TRIDENT3X(unit) && !SOC_IS_MAVERICK2(unit)) { 59785 rv = soc_td3_asf_wb_recover(unit, wb_data, scache_ver); 59786 } else 59787 #endif 59788 #ifdef BCM_TOMAHAWK3_SUPPORT 59789 if (SOC_IS_TOMAHAWK3(unit)) { 59790 rv = soc_th3_asf_wb_recover(unit, wb_data, scache_ver); 59791 } else 59792 #endif 59793 59794 if (SOC_IS_TOMAHAWKX(unit)) { 59795 rv = soc_th_asf_wb_recover(unit, wb_data, scache_ver); 59796 } else { 59797 rv = BCM_E_NONE; 59798 } 59799 } else { 59800 rv = BCM_E_NONE; 59801 } 59802 59803 return rv; 59804 } 59805 #endif /* BCM_WARMBOOT_SUPPORT */ 59806 59807 /** 59808 * Function: 59809 * bcm_esw_port_asf_mode_get 59810 * Purpose: 59811 * Returns the forwarding mode configured on the specified port 59812 * Parameters: 59813 * unit - (IN) Unit number 59814 * port - (IN) Logical port 59815 * mode - (OUT) SAF/ASF mode configured on the port 59816 * 0=SAF, 1=ASF(Same Speed), 2=ASF(Slow to Fast) 59817 * 3=ASF (Fast to Slow) 59818 * Returns: 59819 * BCM_E_xxx 59820 */ 59821 int 59822 bcm_esw_port_asf_mode_get( 59823 int unit, 59824 bcm_port_t port, 59825 OUT int* const mode) 59826 { 59827 int rv = BCM_E_UNAVAIL, speed; 59828 soc_info_t *si; 59829 59830 if (!(si = &SOC_INFO(unit))) { 59831 return SOC_E_INTERNAL; 59832 } 59833 59834 /* Make sure port module is initialized. */ 59835 PORT_INIT(unit); 59836 if (!soc_feature(unit, soc_feature_asf_multimode)) { 59837 return BCM_E_UNAVAIL; 59838 } 59839 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 59840 speed = si->port_init_speed[port]; 59841 59842 PORT_LOCK(unit); 59843 #ifdef BCM_MAVERICK2_SUPPORT 59844 if (SOC_IS_MAVERICK2(unit)) { 59845 rv = soc_mv2_port_asf_mode_get(unit, port, speed, 59846 (soc_mv2_asf_mode_e *) mode ); 59847 } else 59848 #endif 59849 #ifdef BCM_TRIDENT3_SUPPORT 59850 if (SOC_IS_TRIDENT3X(unit)) { 59851 rv = soc_td3_port_asf_mode_get(unit, port, speed, 59852 (soc_td3_asf_mode_e *) mode); 59853 } else 59854 #endif 59855 59856 #ifdef BCM_TOMAHAWK3_SUPPORT 59857 if (SOC_IS_TOMAHAWK3(unit)) { 59858 rv = soc_th3_port_asf_mode_get(unit, port, speed, 59859 (soc_th3_asf_mode_t *) mode); 59860 } else 59861 #endif 59862 if (SOC_IS_TOMAHAWKX(unit)) { 59863 rv = soc_th_port_asf_mode_get(unit, port, speed, 59864 (soc_th_asf_mode_e *) mode); 59865 } 59866 PORT_UNLOCK(unit); 59867 59868 return rv; 59869 } 59870 59871 /** 59872 * Function: 59873 * bcm_esw_port_asf_mode_set 59874 * Purpose: 59875 * Configure specified SAF/ASF mode on the given port 59876 * Parameters: 59877 * unit - (IN) Unit number 59878 * port - (IN) Logical port 59879 * mode - (IN) Forwarding mode to be configured on the port 59880 * 0=SAF, 1=ASF(Same Speed), 2=ASF(Slow to Fast) 59881 * 3=ASF (Fast to Slow) 59882 * Returns: 59883 * BCM_E_xxx 59884 */ 59885 int 59886 bcm_esw_port_asf_mode_set( 59887 int unit, 59888 bcm_port_t port, 59889 int mode) 59890 { 59891 int rv = BCM_E_UNAVAIL, speed = 0; 59892 soc_info_t *si; 59893 #if defined(BCM_TOMAHAWK2_SUPPORT) 59894 int txp = 0, rxp = 0; 59895 pbmp_t *pause_bmp = NULL; 59896 #endif /* BCM_TOMAHAWK2_SUPPORT */ 59897 59898 if (!(si = &SOC_INFO(unit))) { 59899 return SOC_E_INTERNAL; 59900 } 59901 59902 /* Make sure port module is initialized. */ 59903 PORT_INIT(unit); 59904 if (!soc_feature(unit, soc_feature_asf_multimode)) { 59905 return BCM_E_UNAVAIL; 59906 } 59907 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 59908 59909 #if defined(BCM_TOMAHAWK2_SUPPORT) 59910 /* Update Pause for ASF mode */ 59911 if (SOC_IS_TOMAHAWK2(unit)) { 59912 pause_bmp = soc_th_port_asf_pause_bpmp_get(unit); 59913 if (pause_bmp == NULL) { 59914 return BCM_E_INTERNAL; 59915 } 59916 59917 if (_SOC_TH_ASF_MODE_SAF != mode) { 59918 /* Disable rx pause for cut through */ 59919 BCM_IF_ERROR_RETURN 59920 (bcm_esw_port_pause_get(unit, port, &txp, &rxp)); 59921 59922 if (rxp) { 59923 SOC_PBMP_PORT_ADD((*pause_bmp), port); 59924 } 59925 BCM_IF_ERROR_RETURN 59926 (bcm_esw_port_pause_set(unit, port, txp, 0)); 59927 } 59928 } 59929 #endif /* BCM_TOMAHAWK2_SUPPORT */ 59930 59931 #ifdef BCM_MAVERICK2_SUPPORT 59932 if (SOC_IS_MAVERICK2(unit)) { 59933 rv = _bcm_esw_mv2_port_asf_mode_set(unit, port, mode); 59934 } else 59935 #endif 59936 #ifdef BCM_TRIDENT3_SUPPORT 59937 if (SOC_IS_TRIDENT3X(unit)) { 59938 rv = _bcm_esw_td3_port_asf_mode_set(unit, port, mode); 59939 } else 59940 #endif 59941 #ifdef BCM_TOMAHAWK3_SUPPORT 59942 if(SOC_IS_TOMAHAWK3(unit)) { 59943 if (mode >= 2) { 59944 return BCM_E_PARAM; 59945 } 59946 speed = si->port_init_speed[port]; 59947 PORT_LOCK(unit); 59948 rv = soc_th3_port_asf_mode_set(unit, port, speed, mode); 59949 PORT_UNLOCK(unit); 59950 } else 59951 #endif 59952 { 59953 speed = si->port_init_speed[port]; 59954 PORT_LOCK(unit); 59955 rv = soc_th_port_asf_mode_set(unit, port, speed, mode); 59956 PORT_UNLOCK(unit); 59957 } 59958 59959 #if defined(BCM_TOMAHAWK2_SUPPORT) 59960 /* Update Pause for ASF mode */ 59961 if (SOC_IS_TOMAHAWK2(unit)) { 59962 if (_SOC_TH_ASF_MODE_SAF == mode) { /* SAF */ 59963 /* restore pause */ 59964 if (SOC_PBMP_MEMBER((*pause_bmp), port)) { 59965 BCM_IF_ERROR_RETURN 59966 (bcm_esw_port_pause_get(unit, port, &txp, &rxp)); 59967 BCM_IF_ERROR_RETURN 59968 (bcm_esw_port_pause_set(unit, port, txp, 1)); 59969 SOC_PBMP_PORT_REMOVE((*pause_bmp), port); 59970 } 59971 } 59972 } 59973 #endif /* BCM_TOMAHAWK2_SUPPORT */ 59974 59975 return rv; 59976 } 59977 59978 /** 59979 * Function: 59980 * bcm_esw_asf_diag 59981 * Purpose: 59982 * Dump all ASF configurations specific to the unit 59983 * Parameters: 59984 * unit - (IN) Unit number 59985 * Returns: 59986 * BCM_E_xxx 59987 */ 59988 int 59989 bcm_esw_asf_diag(int unit) 59990 { 59991 /* Make sure port module is initialized. */ 59992 PORT_INIT(unit); 59993 if (!soc_feature(unit, soc_feature_asf_multimode)) { 59994 return BCM_E_UNAVAIL; 59995 } 59996 59997 #ifdef BCM_MAVERICK2_SUPPORT 59998 if (SOC_IS_MAVERICK2(unit)) { 59999 return soc_mv2_asf_config_dump(unit); 60000 } else 60001 #endif 60002 #ifdef BCM_TRIDENT3_SUPPORT 60003 if (SOC_IS_TRIDENT3X(unit)) { 60004 return soc_td3_asf_config_dump(unit); 60005 } else 60006 #endif 60007 #ifdef BCM_TOMAHAWK3_SUPPORT 60008 if(SOC_IS_TOMAHAWK3(unit)) { 60009 return soc_th3_asf_config_dump(unit); 60010 } else 60011 #endif 60012 if (SOC_IS_TOMAHAWKX(unit)) { 60013 return soc_th_asf_config_dump(unit); 60014 } 60015 60016 return BCM_E_UNAVAIL; 60017 } 60018 60019 /** 60020 * Function: 60021 * bcm_esw_port_asf_show 60022 * Purpose: 60023 * Display formatted ASF information for a port 60024 * Parameters: 60025 * unit - (IN) Unit number 60026 * port - (IN) Logical port 60027 * Returns: 60028 * BCM_E_xxx 60029 */ 60030 int 60031 bcm_esw_port_asf_show( 60032 int unit, 60033 bcm_port_t port) 60034 { 60035 int speed; 60036 soc_info_t *si; 60037 60038 if (!(si = &SOC_INFO(unit))) { 60039 return SOC_E_INTERNAL; 60040 } 60041 60042 /* Make sure port module is initialized. */ 60043 PORT_INIT(unit); 60044 if (!soc_feature(unit, soc_feature_asf_multimode)) { 60045 return BCM_E_UNAVAIL; 60046 } 60047 if(!SOC_IS_TOMAHAWK3(unit)) { 60048 60049 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed)); 60050 } else { 60051 speed = si->port_init_speed[port]; 60052 } 60053 #ifdef BCM_MAVERICK2_SUPPORT 60054 if (SOC_IS_MAVERICK2(unit)) { 60055 return soc_mv2_port_asf_show(unit, port, speed); 60056 } else 60057 #endif 60058 #ifdef BCM_TRIDENT3_SUPPORT 60059 if (SOC_IS_TRIDENT3X(unit)) { 60060 return soc_td3_port_asf_show(unit, port, speed); 60061 } else 60062 #endif 60063 #ifdef BCM_TOMAHAWK3_SUPPORT 60064 if(SOC_IS_TOMAHAWK3(unit)) { 60065 return soc_th3_port_asf_show(unit, port, speed); 60066 } else 60067 #endif 60068 if (SOC_IS_TOMAHAWKX(unit)) { 60069 return soc_th_port_asf_show(unit, port, speed); 60070 } 60071 60072 return BCM_E_UNAVAIL; 60073 } 60074 60075 /** 60076 * Function: 60077 * bcm_esw_port_asf_diag 60078 * Purpose: 60079 * Dump all related ASF configurations for the given port 60080 * Parameters: 60081 * unit - (IN) Unit number 60082 * port - (IN) Logical port 60083 * Returns: 60084 * BCM_E_xxx 60085 */ 60086 int 60087 bcm_esw_port_asf_diag( 60088 int unit, 60089 bcm_port_t port) 60090 { 60091 int speed; 60092 soc_info_t *si; 60093 60094 if (!(si = &SOC_INFO(unit))) { 60095 return SOC_E_INTERNAL; 60096 } 60097 60098 /* Make sure port module is initialized. */ 60099 PORT_INIT(unit); 60100 if (!soc_feature(unit, soc_feature_asf_multimode)) { 60101 return BCM_E_UNAVAIL; 60102 } 60103 if(!SOC_IS_TOMAHAWK3(unit)) { 60104 60105 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get(unit, port, &speed)); 60106 } else { 60107 speed = si->port_init_speed[port]; 60108 } 60109 #ifdef BCM_MAVERICK2_SUPPORT 60110 if (SOC_IS_MAVERICK2(unit)) { 60111 return soc_mv2_port_asf_config_dump(unit, port, speed); 60112 } else 60113 #endif 60114 #ifdef BCM_TRIDENT3_SUPPORT 60115 if (SOC_IS_TRIDENT3X(unit)) { 60116 return soc_td3_port_asf_config_dump(unit, port, speed); 60117 } else 60118 #endif 60119 #ifdef BCM_TOMAHAWK3_SUPPORT 60120 if (SOC_IS_TOMAHAWK3(unit)) { 60121 return soc_th3_port_asf_config_dump(unit, port, speed); 60122 } else 60123 #endif 60124 if (SOC_IS_TOMAHAWKX(unit)) { 60125 return soc_th_port_asf_config_dump(unit, port, speed); 60126 } 60127 60128 return BCM_E_UNAVAIL; 60129 } 60130 #endif /* BCM_TOMAHAWK_SUPPORT */ 60131 60132 /** 60133 * Function : 60134 * _bcm_esw_port_sw_info_display 60135 * Purpose: 60136 * To display status of port related software structures 60137 * Parameters: 60138 * unit - (IN) Unit number 60139 * port - (IN) Port number 60140 * Returns : 60141 * BCM_E_xxxx 60142 * Note: 60143 * Implementation currently limited to KATANA2 and SABER2 ONLY 60144 */ 60145 int 60146 _bcm_esw_port_sw_info_display(int unit, bcm_port_t port) 60147 { 60148 #ifdef BCM_METROLITE_SUPPORT 60149 if (SOC_IS_METROLITE(unit)) { 60150 BCM_IF_ERROR_RETURN(_bcm_ml_port_sw_info_display(unit, port)); 60151 } else 60152 #endif 60153 #ifdef BCM_SABER2_SUPPORT 60154 if (SOC_IS_SABER2(unit)) { 60155 BCM_IF_ERROR_RETURN(_bcm_sb2_port_sw_info_display(unit, port)); 60156 } else 60157 #endif 60158 #ifdef BCM_KATANA2_SUPPORT 60159 if (SOC_IS_KATANA2(unit)) { 60160 BCM_IF_ERROR_RETURN(_bcm_kt2_port_sw_info_display(unit, port)); 60161 } else 60162 #endif 60163 { 60164 LOG_ERROR(BSL_LS_BCM_PORT, 60165 (BSL_META_U(unit, 60166 "_bcm_esw_port_sw_info_display \ 60167 implementation not implemented\n"))); 60168 return SOC_E_UNIT; 60169 } 60170 60171 return BCM_E_NONE; 60172 } 60173 60174 /** 60175 * Function : 60176 * _bcm_esw_port_hw_info_display 60177 * Purpose: 60178 * To display status of port related harware registers. 60179 * Parameters: 60180 * unit - (IN) Unit number. 60181 * port - (IN) Port number 60182 * Returns: 60183 * BCM_E_xxxx 60184 * Notes: 60185 * Implementation currently limited to KATANA2 and SABER2 ONLY 60186 */ 60187 int 60188 _bcm_esw_port_hw_info_display(int unit, bcm_port_t port) 60189 { 60190 #ifdef BCM_METROLITE_SUPPORT 60191 if (SOC_IS_METROLITE(unit)) { 60192 BCM_IF_ERROR_RETURN(_bcm_ml_port_hw_info_display(unit, port)); 60193 } else 60194 #endif 60195 #ifdef BCM_SABER2_SUPPORT 60196 if (SOC_IS_SABER2(unit)) { 60197 BCM_IF_ERROR_RETURN(_bcm_sb2_port_hw_info_display(unit, port)); 60198 } else 60199 #endif 60200 #ifdef BCM_KATANA2_SUPPORT 60201 if (SOC_IS_KATANA2(unit)) { 60202 BCM_IF_ERROR_RETURN(_bcm_kt2_port_hw_info_display(unit, port)); 60203 } else 60204 #endif 60205 { 60206 LOG_ERROR(BSL_LS_BCM_PORT, 60207 (BSL_META_U(unit, 60208 "_bcm_esw_port_hw_info_display \ 60209 implementation not implemented\n"))); 60210 return SOC_E_UNIT; 60211 } 60212 60213 return BCM_E_NONE; 60214 } 60215 60216 60217 /* 60218 * Function: 60219 * bcm_esw_port_resource_set 60220 * Purpose: 60221 * Modify the following port resources: 60222 * - Logical to physical port mapping 60223 * - Speed 60224 * - Number of PHY lanes 60225 * - Encapsulation mode 60226 * Parameters: 60227 * unit - (IN) Unit number. 60228 * port - (IN) Logical port. 60229 * resource - (IN) Port resource configuration. 60230 * Returns: 60231 * BCM_E_XXX 60232 */ 60233 int 60234 bcm_esw_port_resource_set(int unit, 60235 bcm_gport_t port, bcm_port_resource_t *resource) 60236 { 60237 int rv = BCM_E_UNAVAIL; 60238 60239 PORT_INIT(unit); 60240 60241 PORT_LOCK(unit); 60242 60243 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 60244 if (BCM_ESW_PORT_DRV(unit)->resource_set != NULL) { 60245 rv = BCM_ESW_PORT_DRV(unit)->resource_set(unit, port, resource); 60246 } 60247 } 60248 60249 if (BCM_SUCCESS(rv) && (BCM_ESW_PORT_DRV(unit)->resource_status_update != NULL)) { 60250 BCM_ESW_PORT_DRV(unit)->resource_status_update(unit, 1, resource); 60251 } 60252 60253 PORT_UNLOCK(unit); 60254 60255 return rv; 60256 } 60257 60258 60259 /* 60260 * Function: 60261 * bcm_esw_port_resource_get 60262 * Purpose: 60263 * Get the port resource configuration for the specified logical port. 60264 * Parameters: 60265 * unit - (IN) Unit number. 60266 * port - (IN) Logical port. 60267 * resource - (OUT) Returns port resource information. 60268 * Returns: 60269 * BCM_E_XXX 60270 */ 60271 int 60272 bcm_esw_port_resource_get(int unit, 60273 bcm_gport_t port, bcm_port_resource_t *resource) 60274 { 60275 int rv = BCM_E_UNAVAIL; 60276 60277 PORT_INIT(unit); 60278 60279 PORT_LOCK(unit); 60280 60281 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 60282 if (BCM_ESW_PORT_DRV(unit)->resource_get != NULL) { 60283 rv = BCM_ESW_PORT_DRV(unit)->resource_get(unit, port, resource); 60284 } 60285 } 60286 60287 PORT_UNLOCK(unit); 60288 60289 return rv; 60290 } 60291 60292 /* 60293 * Function: 60294 * bcm_esw_port_resource_multi_set 60295 * Purpose: 60296 * Modify the following port resources: 60297 * - Logical to physical port mapping 60298 * - Speedu 60299 * - Number of PHY lanes 60300 * - Encapsulation mode 60301 * Parameters: 60302 * unit - (IN) Unit number. 60303 * nport - (IN) Number of elements in array resource. 60304 * resource - (IN) Port resource configuration array. 60305 * Returns: 60306 * BCM_E_XXX 60307 */ 60308 int 60309 bcm_esw_port_resource_multi_set(int unit, 60310 int nport, bcm_port_resource_t *resource) 60311 { 60312 int rv = BCM_E_UNAVAIL; 60313 60314 PORT_INIT(unit); 60315 60316 PORT_LOCK(unit); 60317 60318 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 60319 if (BCM_ESW_PORT_DRV(unit)->resource_multi_set != NULL) { 60320 rv = BCM_ESW_PORT_DRV(unit)->resource_multi_set(unit, nport, 60321 resource); 60322 } 60323 } 60324 60325 if (BCM_SUCCESS(rv) && (BCM_ESW_PORT_DRV(unit)->resource_status_update != NULL)) { 60326 BCM_ESW_PORT_DRV(unit)->resource_status_update(unit, nport, resource); 60327 } 60328 60329 PORT_UNLOCK(unit); 60330 60331 return rv; 60332 } 60333 /* 60334 * Function: 60335 * bcm_esw_port_resource_speed_config_validate 60336 * Purpose: 60337 * Validate the resource configuration 60338 * Parameters: 60339 * unit - (IN) Unit number. 60340 * resource - (IN) Port resource information. 60341 * pbmp - (OUT) Returns the affected sister ports 60342 * Returns: 60343 * BCM_E_NONE - Config is honred without affecting sister ports 60344 * BCM_E_PARAM - Config will affect sister ports in pbmp 60345 */ 60346 int 60347 bcm_esw_port_resource_speed_config_validate(int unit, 60348 bcm_port_resource_t *resource, bcm_pbmp_t *pbmp) 60349 { 60350 int rv = BCM_E_UNAVAIL; 60351 60352 /* Make sure port module is initialized. */ 60353 PORT_INIT(unit); 60354 60355 /* Call Port Control module */ 60356 if (SOC_USE_PORTCTRL(unit)) { 60357 rv = bcmi_esw_portctrl_resource_speed_config_validate(unit, 60358 resource, pbmp); 60359 } 60360 60361 return rv; 60362 } 60363 60364 /* 60365 * Function: 60366 * bcm_esw_port_resource_speed_get 60367 * Purpose: 60368 * Get the speed port resource configuration for the specified logical 60369 * port. 60370 * Parameters: 60371 * unit - (IN) Unit number. 60372 * port - (IN) Logical port. 60373 * resource - (OUT) Returns port resource information. 60374 * Returns: 60375 * BCM_E_XXX 60376 */ 60377 int 60378 bcm_esw_port_resource_speed_get(int unit, 60379 bcm_gport_t port, bcm_port_resource_t *resource) 60380 { 60381 int rv = BCM_E_UNAVAIL; 60382 60383 rv = bcm_esw_port_resource_get(unit, port, resource); 60384 60385 return rv; 60386 } 60387 60388 /* 60389 * Function: 60390 * bcm_esw_port_resource_speed_set 60391 * Purpose: 60392 * Modify the following port resources: 60393 * - Speed 60394 * Note: The parameter for this function will be used to derive the 60395 * associated physical port 60396 * Parameters: 60397 * unit - (IN) Unit number. 60398 * gport - (IN) Logical Port. 60399 * resource - (IN) Port resource configuration array. 60400 * Returns: 60401 * BCM_E_XXX 60402 */ 60403 int 60404 bcm_esw_port_resource_speed_set(int unit, 60405 bcm_gport_t port, bcm_port_resource_t *resource) 60406 { 60407 int rv = BCM_E_UNAVAIL; 60408 int lport; 60409 60410 if (NULL == resource) { 60411 return BCM_E_PARAM; 60412 } 60413 60414 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &lport)); 60415 60416 /* Use the passed in logical port to be consistent with port_speed_set */ 60417 resource->port = lport; 60418 60419 rv = bcm_esw_port_resource_speed_multi_set(unit, 1, resource); 60420 60421 return rv; 60422 } 60423 60424 /* 60425 * Function: 60426 * bcm_esw_port_resource_speed_multi_set 60427 * Purpose: 60428 * Modify the following port resources: 60429 * - Speed 60430 * Parameters: 60431 * unit - (IN) Unit number. 60432 * nport - (IN) Number of elements in array resource. 60433 * resource - (IN) Port resource configuration array. 60434 * Returns: 60435 * BCM_E_XXX 60436 */ 60437 int 60438 bcm_esw_port_resource_speed_multi_set(int unit, 60439 int nport, bcm_port_resource_t *resource) 60440 { 60441 int i, max_speed; 60442 pbmp_t pbm; 60443 int *enable; 60444 int rv = BCM_E_UNAVAIL; 60445 60446 60447 PORT_INIT(unit); 60448 60449 /* Do this check because we don't want to allocate 4 billion ints 60450 * if there's bad input 60451 */ 60452 if ((nport < 0) || (nport > SOC_MAX_NUM_PORTS)) { 60453 return BCM_E_PARAM; 60454 } 60455 60456 if (resource == NULL) { 60457 return BCM_E_PARAM; 60458 } 60459 60460 enable = sal_alloc(nport * sizeof(int), "port enable array"); 60461 if (NULL == enable) { 60462 return BCM_E_MEMORY; 60463 } 60464 60465 /* Iterate through each entry and do some sanity checks */ 60466 for (i = 0; i < nport; i++) { 60467 rv = (_bcm_esw_port_gport_validate(unit, 60468 resource[i].port, &resource[i].port)); 60469 if(!BCM_SUCCESS(rv)) { 60470 goto speed_multi_cleanup; 60471 } 60472 60473 rv = (bcm_esw_port_speed_max(unit,resource[i].port, &max_speed)); 60474 if(!BCM_SUCCESS(rv)) { 60475 goto speed_multi_cleanup; 60476 } 60477 60478 60479 if ((resource[i].speed < 0) || (resource[i].speed > max_speed)) { 60480 if ((resource[i].speed > max_speed) && 60481 !soc_feature(unit, soc_feature_flexport_based_speed_set)) 60482 rv = BCM_E_PARAM; 60483 if(!BCM_SUCCESS(rv)) { 60484 goto speed_multi_cleanup; 60485 } 60486 } 60487 60488 /* 60489 * When performing flexport based speed changes, disable port 60490 * first prior to affecting speed change, but keep track of whether 60491 * the port was enabled 60492 */ 60493 if (soc_feature(unit, soc_feature_flexport_based_speed_set) && 60494 !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), resource[i].port) && 60495 !SOC_USE_PORTCTRL(unit)) { 60496 rv = (bcm_esw_port_enable_get(unit, 60497 resource[i].port, &enable[i])); 60498 if(!BCM_SUCCESS(rv)) { 60499 goto speed_multi_cleanup; 60500 } 60501 60502 if (TRUE == enable[i]) { 60503 rv = (bcm_esw_port_enable_set(unit, resource[i].port, FALSE)); 60504 if(!BCM_SUCCESS(rv)) { 60505 goto speed_multi_cleanup; 60506 } 60507 60508 } 60509 } 60510 60511 } 60512 PORT_LOCK(unit); 60513 rv = bcmi_esw_portctrl_speed_multi_set(unit, nport, resource); 60514 PORT_UNLOCK(unit); 60515 if(!BCM_SUCCESS(rv)) { 60516 goto speed_multi_cleanup; 60517 } 60518 60519 for (i = 0; i < nport; i++) { 60520 /* 60521 * Restore port's enable state based on what was read prior 60522 * to setting speed 60523 */ 60524 if (soc_feature(unit, soc_feature_flexport_based_speed_set) && 60525 !SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), resource[i].port) && 60526 !SOC_USE_PORTCTRL(unit)) { 60527 if (TRUE == enable[i]) { 60528 rv = bcm_esw_port_enable_set(unit, resource[i].port, TRUE); 60529 if(!BCM_SUCCESS(rv)) { 60530 goto speed_multi_cleanup; 60531 } 60532 } 60533 } 60534 60535 if (BCM_SUCCESS(rv) && !SAL_BOOT_SIMULATION) { 60536 SOC_PBMP_CLEAR(pbm); 60537 SOC_PBMP_PORT_ADD(pbm, resource[i].port); 60538 (void)bcm_esw_link_change(unit, pbm); 60539 } 60540 60541 rv = _bcm_esw_port_link_delay_update(unit, resource[i].port, 60542 resource[i].speed); 60543 if(!BCM_SUCCESS(rv)) { 60544 goto speed_multi_cleanup; 60545 } 60546 } 60547 60548 60549 speed_multi_cleanup: 60550 if (NULL != enable) { 60551 sal_free(enable); 60552 } 60553 60554 return rv; 60555 } 60556 /* 60557 * Function: 60558 * bcm_esw_port_resource_traverse 60559 * Purpose: 60560 * Iterates over the port resource configurations on a given 60561 * unit and calls user-provided callback for every entry. 60562 * Parameters: 60563 * unit - (IN) Unit number. 60564 * trav_fn - (IN) Callback function to execute. 60565 * user_data - (IN) Pointer to any user data. 60566 * Returns: 60567 * BCM_E_XXX 60568 */ 60569 int 60570 bcm_esw_port_resource_traverse(int unit, 60571 bcm_port_resource_traverse_cb trav_fn, 60572 void *user_data) 60573 { 60574 int rv = BCM_E_UNAVAIL; 60575 60576 PORT_INIT(unit); 60577 60578 PORT_LOCK(unit); 60579 60580 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 60581 if (BCM_ESW_PORT_DRV(unit)->resource_traverse != NULL) { 60582 rv = BCM_ESW_PORT_DRV(unit)->resource_traverse(unit, trav_fn, 60583 user_data); 60584 } 60585 } 60586 60587 PORT_UNLOCK(unit); 60588 60589 return rv; 60590 } 60591 60592 /* 60593 * Function: 60594 * bcm_esw_port_priority_group_mapping_set 60595 * Purpose: 60596 * Assign a Priority Group for the input priority. 60597 * Parameters: 60598 * unit - (IN) device id. 60599 * gport - (IN) generic port. 60600 * prio - (IN) input priority. 60601 * priority_group - (IN) priority group ID that the input priority mapped to. 60602 * Returns: 60603 * BCM_E_XXX 60604 */ 60605 int 60606 bcm_esw_port_priority_group_mapping_set(int unit, bcm_gport_t gport, int prio, int priority_group) 60607 { 60608 int rv = BCM_E_UNAVAIL; 60609 60610 PORT_INIT(unit); 60611 if (soc_feature(unit, soc_feature_priority_flow_control)) { 60612 #ifdef BCM_SABER2_SUPPORT 60613 if (SOC_IS_SABER2(unit)) { 60614 return (bcm_kt2_port_priority_group_mapping_set(unit, gport, prio, priority_group)); 60615 } 60616 #endif 60617 #if defined(BCM_GREYHOUND_SUPPORT) 60618 if (soc_feature(unit, soc_feature_gh_style_pfc_config)) { 60619 return (bcm_gh_port_priority_group_mapping_set(unit, gport, prio, priority_group)); 60620 } 60621 #endif /* BCM_GREYHOUND_SUPPORT */ 60622 #if defined(BCM_TRIDENT3_SUPPORT) 60623 if (SOC_IS_TRIDENT3X(unit)) { 60624 return (bcm_td3_port_priority_group_mapping_set(unit, gport, prio, 60625 priority_group)); 60626 } 60627 #endif /* BCM_TRIDENT3_SUPPORT */ 60628 #if defined(BCM_TRIDENT2_SUPPORT) 60629 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 60630 SOC_IS_TITAN2X(unit)) { 60631 return (bcm_td2_port_priority_group_mapping_set(unit, gport, prio, 60632 priority_group)); 60633 } 60634 #endif /* BCM_TRIDENT2_SUPPORT */ 60635 #if defined(BCM_TOMAHAWK3_SUPPORT) 60636 if (SOC_IS_TOMAHAWK3(unit)) { 60637 return BCM_E_UNAVAIL; 60638 } 60639 #endif /* BCM_TOMAHAWK3_SUPPORT */ 60640 #if defined(BCM_TOMAHAWK_SUPPORT) 60641 if (SOC_IS_TOMAHAWKX(unit)) { 60642 return (bcm_th_port_priority_group_mapping_set(unit, gport, prio, 60643 priority_group)); 60644 } 60645 #endif /* BCM_TOMAHAWK_SUPPORT */ 60646 #if defined(BCM_APACHE_SUPPORT) 60647 if (SOC_IS_APACHE(unit)){ 60648 return (bcm_ap_port_priority_group_mapping_set(unit, gport, prio, 60649 priority_group)); 60650 } 60651 #endif 60652 } 60653 return rv; 60654 } 60655 60656 /* 60657 * Function: 60658 * bcm_esw_port_priority_group_mapping_get 60659 * Purpose: 60660 * Get the assigned Priority Group ID of the input priority. 60661 * Parameters: 60662 * unit - (IN) device id. 60663 * gport - (IN) generic port. 60664 * prio - (IN) input priority. 60665 * priority_group - (OUT) priority group ID that the input priority mapped to. 60666 * Returns: 60667 * BCM_E_XXX 60668 */ 60669 int 60670 bcm_esw_port_priority_group_mapping_get(int unit, bcm_gport_t gport, int prio, int *priority_group) 60671 { 60672 int rv = BCM_E_UNAVAIL; 60673 60674 PORT_INIT(unit); 60675 if (soc_feature(unit, soc_feature_priority_flow_control)) { 60676 #ifdef BCM_SABER2_SUPPORT 60677 if (SOC_IS_SABER2(unit)) { 60678 return (bcm_kt2_port_priority_group_mapping_get(unit, gport, prio, priority_group)); 60679 } 60680 #endif 60681 60682 #if defined(BCM_GREYHOUND_SUPPORT) 60683 if (soc_feature(unit, soc_feature_gh_style_pfc_config)) { 60684 return (bcm_gh_port_priority_group_mapping_get(unit, gport, prio, priority_group)); 60685 } 60686 #endif /* BCM_GREYHOUND_SUPPORT */ 60687 #if defined(BCM_TRIDENT3_SUPPORT) 60688 if (SOC_IS_TRIDENT3X(unit)) { 60689 return (bcm_td3_port_priority_group_mapping_get(unit, gport, prio, 60690 priority_group)); 60691 } 60692 #endif /* BCM_TRIDENT3_SUPPORT */ 60693 #if defined(BCM_TRIDENT2_SUPPORT) 60694 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 60695 SOC_IS_TITAN2X(unit)) { 60696 return (bcm_td2_port_priority_group_mapping_get(unit, gport, prio, 60697 priority_group)); 60698 } 60699 #endif /* BCM_TRIDENT2_SUPPORT */ 60700 #if defined(BCM_TOMAHAWK3_SUPPORT) 60701 if (SOC_IS_TOMAHAWK3(unit)) { 60702 return BCM_E_UNAVAIL; 60703 } 60704 #endif /* BCM_TOMAHAWK3_SUPPORT */ 60705 #if defined(BCM_TOMAHAWK_SUPPORT) 60706 if (SOC_IS_TOMAHAWKX(unit)) { 60707 return (bcm_th_port_priority_group_mapping_get(unit, gport, prio, 60708 priority_group)); 60709 } 60710 #endif /* BCM_TOMAHAWK_SUPPORT */ 60711 #if defined(BCM_APACHE_SUPPORT) 60712 if (SOC_IS_APACHE(unit)) { 60713 return (bcm_ap_port_priority_group_mapping_get(unit, gport, prio, 60714 priority_group)); 60715 } 60716 #endif 60717 } 60718 return rv; 60719 } 60720 60721 /* 60722 * Function: 60723 * bcm_esw_port_priority_group_config_set 60724 * Purpose: 60725 * Set the port priority group configuration. 60726 * Parameters: 60727 * unit - (IN) device id. 60728 * gport - (IN) generic port. 60729 * priority_group - (IN) priority group id. 60730 * prigrp_config - (IN) structure describes port priority group configuration. 60731 * Returns: 60732 * BCM_E_XXX 60733 */ 60734 int 60735 bcm_esw_port_priority_group_config_set(int unit, bcm_gport_t gport, int priority_group, bcm_port_priority_group_config_t *prigrp_config) 60736 { 60737 int rv = BCM_E_UNAVAIL; 60738 60739 PORT_INIT(unit); 60740 if (soc_feature(unit, soc_feature_priority_flow_control)) { 60741 #if defined(BCM_GREYHOUND_SUPPORT) 60742 if (soc_feature(unit, soc_feature_gh_style_pfc_config)) { 60743 return (bcm_gh_port_priority_group_config_set(unit, gport, priority_group, prigrp_config)); 60744 } 60745 #endif /* BCM_GREYHOUND_SUPPORT */ 60746 #if defined(BCM_TRIDENT3_SUPPORT) 60747 if (SOC_IS_TRIDENT3X(unit)) { 60748 return (bcm_td3_port_priority_group_config_set(unit, gport, 60749 priority_group, prigrp_config)); 60750 } 60751 #endif /* BCM_TRIDENT3_SUPPORT */ 60752 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 60753 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 60754 SOC_IS_TITAN2X(unit) || SOC_IS_MONTEREY(unit) || 60755 SOC_IS_APACHE(unit)) { 60756 if (SOC_USE_PORTCTRL(unit)) { 60757 return bcmi_esw_portctrl_priority_group_config_set(unit, gport, 60758 priority_group, prigrp_config); 60759 } 60760 return (bcm_td2_port_priority_group_config_set(unit, gport, 60761 priority_group, prigrp_config)); 60762 } 60763 #endif /* BCM_TRIDENT2_SUPPORT */ 60764 #if defined(BCM_TOMAHAWK_SUPPORT) 60765 if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) { 60766 return (bcm_th_port_priority_group_config_set(unit, gport, 60767 priority_group, prigrp_config)); 60768 } 60769 #endif /* BCM_TOMAHAWK_SUPPORT */ 60770 60771 #if defined(BCM_TOMAHAWK3_SUPPORT) 60772 if(SOC_IS_TOMAHAWK3(unit)) { 60773 return (bcm_th3_port_priority_group_config_set(unit, gport, 60774 priority_group, prigrp_config)); 60775 } 60776 #endif 60777 60778 } 60779 return rv; 60780 } 60781 60782 /* 60783 * Function: 60784 * bcm_esw_port_priority_group_config_get 60785 * Purpose: 60786 * Get the port priority group configuration. 60787 * Parameters: 60788 * unit - (IN) device id. 60789 * gport - (IN) generic port. 60790 * priority_group - (IN) priority group id. 60791 * prigrp_config - (OUT) structure describes port priority group configuration. 60792 * Returns: 60793 * BCM_E_XXX 60794 */ 60795 int 60796 bcm_esw_port_priority_group_config_get(int unit, bcm_gport_t gport, int priority_group, bcm_port_priority_group_config_t *prigrp_config) 60797 { 60798 int rv = BCM_E_UNAVAIL; 60799 60800 PORT_INIT(unit); 60801 if (soc_feature(unit, soc_feature_priority_flow_control)) { 60802 #if defined(BCM_GREYHOUND_SUPPORT) 60803 if (soc_feature(unit, soc_feature_gh_style_pfc_config)) { 60804 return (bcm_gh_port_priority_group_config_get(unit, gport, priority_group, prigrp_config)); 60805 } 60806 #endif /* BCM_GREYHOUND_SUPPORT */ 60807 #if defined(BCM_TRIDENT3_SUPPORT) 60808 if (SOC_IS_TRIDENT3X(unit)) { 60809 return (bcm_td3_port_priority_group_config_get(unit, gport, 60810 priority_group, prigrp_config)); 60811 } 60812 #endif /* BCM_TRIDENT3_SUPPORT */ 60813 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_MONTEREY_SUPPORT) 60814 if (SOC_IS_TRIDENT2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 60815 SOC_IS_TITAN2X(unit) || SOC_IS_MONTEREY(unit) || 60816 SOC_IS_APACHE(unit)) { 60817 return (bcm_td2_port_priority_group_config_get(unit, gport, 60818 priority_group, prigrp_config)); 60819 } 60820 #endif /* BCM_TRIDENT2_SUPPORT */ 60821 60822 #if defined(BCM_TOMAHAWK3_SUPPORT) 60823 if (SOC_IS_TOMAHAWK3(unit)) { 60824 return (bcm_th3_port_priority_group_config_get(unit, gport, 60825 priority_group, prigrp_config)); 60826 } 60827 #endif /* BCM_TOMAHAWK3_SUPPORT */ 60828 60829 #if defined(BCM_TOMAHAWK_SUPPORT) 60830 if (SOC_IS_TOMAHAWKX(unit)) { 60831 return (bcm_th_port_priority_group_config_get(unit, gport, 60832 priority_group, prigrp_config)); 60833 } 60834 #endif /* BCM_TOMAHAWK_SUPPORT */ 60835 60836 } 60837 return rv; 60838 } 60839 60840 /* 60841 * Function: 60842 * bcm_esw_port_redirect_config_t_init 60843 * Purpose: 60844 * Initialize the redirection config structure 60845 * Parameters: 60846 * redirect_config - (IN) Pointer to the redirection config structure 60847 * Returns: 60848 * None 60849 */ 60850 void bcm_esw_port_redirect_config_t_init( 60851 bcm_port_redirect_config_t *redirect_config) 60852 { 60853 return; 60854 } 60855 60856 /* 60857 * Function: 60858 * bcm_esw_port_redirect_set 60859 * Purpose: 60860 * Configure the redirection data 60861 * Parameters: 60862 * unit - (IN) device id. 60863 * port - (IN) Port number. 60864 * redirect_config - (IN) Pointer to the redirection config structure 60865 * Returns: 60866 * None 60867 */ 60868 int 60869 bcm_esw_port_redirect_config_set(int unit, int port, 60870 bcm_port_redirect_config_t *redirect_config) 60871 { 60872 int rv = BCM_E_UNAVAIL; 60873 60874 PORT_INIT(unit); 60875 60876 PORT_LOCK(unit); 60877 60878 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 60879 if (BCM_ESW_PORT_DRV(unit)->port_redirect_set != NULL) { 60880 rv = BCM_ESW_PORT_DRV(unit)->port_redirect_set(unit, port, 60881 redirect_config); 60882 } 60883 } 60884 60885 PORT_UNLOCK(unit); 60886 60887 return rv; 60888 } 60889 60890 60891 /* 60892 * Function: 60893 * bcm_esw_port_redirect_get 60894 * Purpose: 60895 * Configure the redirection data 60896 * Parameters: 60897 * unit - (IN) device id. 60898 * port - (IN) Port number. 60899 * redirect_config - (IN) Pointer to the redirection config structure 60900 * Returns: 60901 * None 60902 */ 60903 int 60904 bcm_esw_port_redirect_config_get(int unit, int port, 60905 bcm_port_redirect_config_t *redirect_config) 60906 { 60907 int rv = BCM_E_UNAVAIL; 60908 60909 PORT_INIT(unit); 60910 60911 PORT_LOCK(unit); 60912 60913 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 60914 if (BCM_ESW_PORT_DRV(unit)->port_redirect_get != NULL) { 60915 rv = BCM_ESW_PORT_DRV(unit)->port_redirect_get(unit, port, 60916 redirect_config); 60917 } 60918 } 60919 60920 PORT_UNLOCK(unit); 60921 60922 return rv; 60923 } 60924 60925 /* 60926 * Function : _bcm_esw_glp_bits_pos 60927 * Description : Internal function to get modid, port, and trunk_id 60928 * from a glp 60929 * Parameters : (IN) unit - BCM device number 60930 * (OUT) trunk_pos - Trunk ID position 60931 * (OUT) max_modid - Max module ID bits 60932 * (OUT) modid_pos - Module ID position 60933 * (OUT) max_port - Max port addr bits 60934 * Returns : BCM_E_XXX 60935 * Notes : The trunkid, modid and port are used for 16 bits {T, MODID[7:0], PORT[7:0]}, 60936 * get qualifiers for GLP related fields in FP_TCAM 60937 */ 60938 static int 60939 _bcm_esw_glp_bits_pos(int unit, 60940 uint8 *trunk_pos, uint8 *max_modid, 60941 uint8 *modid_pos, uint8 *max_port) 60942 { 60943 if ((NULL == trunk_pos) || (NULL == max_modid) || (NULL == modid_pos) || 60944 (NULL == max_port)) { 60945 return BCM_E_PARAM; 60946 } 60947 60948 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT) || \ 60949 defined(BCM_TITAN_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \ 60950 defined(BCM_TITAN2_SUPPORT) || defined(BCM_TRIDENT2_SUPPORT) || \ 60951 defined(BCM_HELIX4_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) || \ 60952 defined(BCM_SABER2_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) || \ 60953 defined(BCM_APACHE_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 60954 if(SOC_IS_KATANA(unit) || SOC_IS_KATANA2(unit) || 60955 SOC_IS_TITAN(unit) || SOC_IS_TRIDENT(unit) || 60956 SOC_IS_TITAN2(unit) || SOC_IS_TRIDENT2(unit) || 60957 SOC_IS_HELIX4(unit) || SOC_IS_TRIUMPH3(unit) || 60958 SOC_IS_SABER2(unit) || SOC_IS_TRIDENT2PLUS(unit) || 60959 SOC_IS_APACHE(unit) || SOC_IS_GREYHOUND2(unit)) { 60960 *trunk_pos = 15; 60961 *max_modid = 0xff; 60962 *modid_pos = 7; 60963 *max_port = 0x7f; 60964 } else 60965 #endif 60966 #if defined(BCM_TOMAHAWK_SUPPORT) 60967 if (SOC_IS_TOMAHAWKX(unit)) { 60968 *trunk_pos = 16; 60969 *max_modid = 0xff; 60970 *modid_pos = 8; 60971 *max_port = 0xff; 60972 } else 60973 #endif 60974 #if defined(BCM_CONQUEROR_SUPPORT) || defined(BCM_SCORPION_SUPPORT) || \ 60975 defined(BCM_SHADOW_SUPPORT) 60976 if (SOC_IS_CONQUEROR(unit) || SOC_IS_SCORPION(unit) || 60977 SOC_IS_SHADOW(unit)) { 60978 *trunk_pos = 14; 60979 *max_modid = 0xff; 60980 *modid_pos = 6; 60981 *max_port = 0x3f; 60982 } else 60983 #endif 60984 #if defined(BCM_RAPTOR_SUPPORT) || defined(BCM_RAVEN_SUPPORT) || \ 60985 defined(BCM_HAWKEYE_SUPPORT) 60986 if (SOC_IS_RAPTOR(unit) || SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit)) { 60987 *trunk_pos = 0; 60988 *max_modid = 0x0; 60989 *modid_pos = 6; 60990 *max_port = 0x3f; 60991 } else 60992 #endif 60993 { 60994 *trunk_pos = 13; 60995 *max_modid = 0x7f; 60996 *modid_pos = 6; 60997 *max_port = 0x3f; 60998 } 60999 61000 return BCM_E_NONE; 61001 } 61002 61003 /* 61004 * Function : _bcm_esw_glp_construct 61005 * Description : Internal function to set GLP port 61006 * from modid, port, and trunk_id 61007 * Parameters : (IN) unit - BCM device number 61008 * (IN) modid - Module ID 61009 * (IN) port - Port number 61010 * (IN) trunk_id - Trunk ID 61011 * (OUT) glp - is trunk + modid + port num 61012 * Returns : BCM_E_XXX 61013 * Notes : The trunkid, modid and port are used for 16 bits {T, MODID[7:0], PORT[7:0]}, 61014 * set qualifiers for GLP related fields in FP_TCAM 61015 */ 61016 int 61017 _bcm_esw_glp_construct(int unit, bcm_trunk_t trunk_id, 61018 bcm_module_t modid, bcm_port_t port, 61019 bcm_gport_t *glp) 61020 { 61021 uint8 trunk_pos = 0; 61022 uint8 max_modid = 0; 61023 uint8 modid_pos = 0; 61024 uint8 max_port = 0; 61025 61026 if (NULL == glp) { 61027 return BCM_E_PARAM; 61028 } 61029 61030 BCM_IF_ERROR_RETURN 61031 (_bcm_esw_glp_bits_pos(unit, 61032 &trunk_pos, &max_modid, 61033 &modid_pos, &max_port)); 61034 61035 if (trunk_id != BCM_TRUNK_INVALID) { 61036 *glp = ((1 << trunk_pos) | trunk_id); 61037 } else { 61038 *glp = (((modid & max_modid) << modid_pos) | 61039 (port & max_port)); 61040 } 61041 61042 return BCM_E_NONE; 61043 } 61044 61045 /* 61046 * Function : _bcm_esw_glp_resolve 61047 * Description : Internal function to get modid, port, and trunk_id 61048 * from a glp 61049 * Parameters : (IN) unit - BCM device number 61050 * (IN) glp - trunk + modid + port num 61051 * (OUT) modid - Module ID 61052 * (OUT) port - Port number 61053 * (OUT) trunk_id - Trunk ID 61054 * Returns : BCM_E_XXX 61055 * Notes : The trunkid, modid and port are used for 16 bits {T, MODID[7:0], PORT[7:0]}, 61056 * get qualifiers for GLP related fields in FP_TCAM 61057 */ 61058 int 61059 _bcm_esw_glp_resolve(int unit, bcm_trunk_t *trunk_id, 61060 bcm_module_t *modid, bcm_port_t *port, 61061 bcm_gport_t glp) 61062 { 61063 uint8 trunk_pos = 0; 61064 uint8 max_modid = 0; 61065 uint8 modid_pos = 0; 61066 uint8 max_port = 0; 61067 61068 if ((NULL == trunk_id) || (NULL == modid) || (NULL == port)){ 61069 return BCM_E_PARAM; 61070 } 61071 61072 BCM_IF_ERROR_RETURN 61073 (_bcm_esw_glp_bits_pos(unit, 61074 &trunk_pos, &max_modid, 61075 &modid_pos, &max_port)); 61076 61077 if (glp & (1 << trunk_pos)) { 61078 *trunk_id = (glp & ~(1 << trunk_pos)); 61079 } else { 61080 *port = (glp & max_port); 61081 *modid = ((glp >> modid_pos) & max_modid); 61082 } 61083 61084 return BCM_E_NONE; 61085 } 61086 61087 /* 61088 * Function : _bcm_esw_gport_to_glp 61089 * Description : Internal function to set GLP port from gport 61090 * Parameters : (IN) unit - BCM device number 61091 * (IN) gport - trunk + modid + port num 61092 * (OUT) glp - trunk + modid + port num 61093 * Returns : BCM_E_XXX 61094 * Notes : The glport as Eg: 16 bits {T, MODID[7:0], PORT[7:0]}, 61095 * get qualifiers for GLP related fields in FP_TCAM 61096 */ 61097 int 61098 _bcm_esw_gport_to_glp(int unit, bcm_gport_t gport, bcm_gport_t *glp) 61099 { 61100 bcm_trunk_t trunk_id; 61101 bcm_module_t mod_id; 61102 bcm_port_t port; 61103 int local_id; 61104 61105 if (BCM_GPORT_IS_SET(gport)) { 61106 SOC_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, gport, &mod_id, 61107 &port, &trunk_id, &local_id)); 61108 61109 BCM_IF_ERROR_RETURN 61110 (_bcm_esw_glp_construct(unit, 61111 trunk_id, mod_id, 61112 port, glp)); 61113 return BCM_E_NONE; 61114 } 61115 61116 return BCM_E_PARAM; 61117 } 61118 61119 /* 61120 * Function: 61121 * bcmi_esw_port_eee_cfg_get 61122 * Purpose: 61123 * Set the eee_cfg value for given port. 61124 * Parameters: 61125 * unit - (IN) Unit number. 61126 * port - (IN) Logical port, BCM format. 61127 * value - (IN) Value to set. 61128 * Returns: 61129 * BCM_E_XXX 61130 * Notes: 61131 */ 61132 int 61133 bcmi_esw_port_eee_cfg_set(int unit, bcm_port_t port, int value) 61134 { 61135 #if defined(BCM_HURRICANE_SUPPORT) || defined(BCM_TRIDENT_SUPPORT) || \ 61136 defined(BCM_HAWKEYE_SUPPORT) || defined(BCM_SHADOW_SUPPORT) || \ 61137 defined(BCM_HURRICANE2_SUPPORT) 61138 if ((port < 0) || (port >= SOC_MAX_NUM_PORTS)) { 61139 return BCM_E_PORT; 61140 } 61141 61142 eee_cfg[unit][port] = value; 61143 61144 return BCM_E_NONE; 61145 #else 61146 return BCM_E_UNAVAIL; 61147 #endif 61148 } 61149 61150 61151 /* 61152 * Function: 61153 * bcmi_esw_port_egr_prof_ptr_set 61154 * Purpose: 61155 * Set the port_src_mod_egr_prof_ptr value for given port. 61156 * Parameters: 61157 * unit - (IN) Unit number. 61158 * port - (IN) Logical port, BCM format. 61159 * egr_prof_ptr - (IN) Value to set. 61160 * Returns: 61161 * BCM_E_XXX 61162 * Notes: 61163 */ 61164 int 61165 bcmi_esw_port_egr_prof_ptr_set(int unit, bcm_port_t port, int value) 61166 { 61167 #ifdef BCM_TRIUMPH2_SUPPORT 61168 if ((port < 0) || (port >= SOC_MAX_NUM_PORTS)) { 61169 return BCM_E_PORT; 61170 } 61171 61172 PORT_SRC_MOD_EGR_PROF_PTR(unit, port) = value; 61173 61174 return BCM_E_NONE; 61175 #else 61176 return BCM_E_UNAVAIL; 61177 #endif /* BCM_TRIUMPH2_SUPPORT */ 61178 } 61179 61180 61181 /* 61182 * Function: 61183 * bcmi_port_force_lb_set 61184 * Purpose: 61185 * Force port into internal loopback accroding to bond options. 61186 * Parameters: 61187 * unit - (IN) Unit number. 61188 * port - (IN) Logical port, BCM format. 61189 * egr_prof_ptr - (IN) Value to set. 61190 * Returns: 61191 * BCM_E_XXX 61192 * Notes: 61193 */ 61194 int 61195 bcmi_port_force_lb_set(int unit) 61196 { 61197 int rv = BCM_E_UNAVAIL; 61198 61199 PORT_INIT(unit); 61200 61201 PORT_LOCK(unit); 61202 61203 if (BCM_ESW_PORT_DRV(unit)!= NULL) { 61204 if (BCM_ESW_PORT_DRV(unit)->force_lb_set != NULL) { 61205 rv = BCM_ESW_PORT_DRV(unit)->force_lb_set(unit); 61206 } 61207 } 61208 61209 PORT_UNLOCK(unit); 61210 61211 return rv; 61212 } 61213 61214 /* 61215 * Function: 61216 * bcm_esw_port_preemption_control_set 61217 * Purpose: 61218 * Set various configurations for Preemption. 61219 * Parameters: 61220 * unit - (IN) Unit number. 61221 * gport - (IN) gport id 61222 * type - (IN) preemption control type defined in bcm_port_preempt_control_t 61223 * arg - (IN) the preemption control value 61224 * Returns: 61225 * BCM_E_XXX 61226 * Notes: 61227 */ 61228 int 61229 bcm_esw_port_preemption_control_set(int unit, bcm_gport_t gport, 61230 bcm_port_preempt_control_t type, 61231 uint32 arg) 61232 { 61233 PORT_INIT(unit); 61234 61235 #if defined(BCM_PREEMPTION_SUPPORT) 61236 if (soc_feature(unit, soc_feature_preemption)) { 61237 bcm_port_t local_port; 61238 uint32 preempt_support; 61239 #ifdef BCM_MONTEREY_SUPPORT 61240 int link = BCM_PORT_LINK_STATUS_DOWN; 61241 #endif 61242 61243 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port)); 61244 if(!SOC_PBMP_MEMBER(PBMP_E_ALL(unit), local_port)) { 61245 /* hg port does not support preemption */ 61246 BCM_IF_ERROR_RETURN(BCM_E_UNAVAIL); 61247 } 61248 #ifdef BCM_MONTEREY_SUPPORT 61249 if (SOC_IS_MONTEREY(unit)) { 61250 if ((type == bcmPortPreemptControlVerifyTime) || 61251 (type == bcmPortPreemptControlVerifyAttempts) || 61252 (type == bcmPortPreemptControlVerifyEnable)) { 61253 return BCM_E_UNAVAIL; 61254 } 61255 if (type == bcmPortPreemptControlPreemptionSupport) { 61256 /* Intentionally supreesing return type to avoid unrelated error */ 61257 (void)_bcm_esw_link_get(unit, local_port, &link); 61258 if (!arg && (link == BCM_PORT_LINK_STATUS_UP)) { 61259 return BCM_E_CONFIG; 61260 } 61261 } 61262 } 61263 #endif /* BCM_MONTEREY_SUPPORT */ 61264 PORT_LOCK(unit); 61265 switch (type) { 61266 /* only need set mac-related */ 61267 case bcmPortPreemptControlEnableTx: 61268 case bcmPortPreemptControlVerifyEnable: 61269 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61270 bcmi_esw_preemption_capability_get(unit, 61271 local_port, 61272 &preempt_support)); 61273 if (0 == preempt_support) { 61274 /* need to enable preempt ability on this port first */ 61275 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM); 61276 } 61277 /* fall-through */ 61278 case bcmPortPreemptControlVerifyTime: 61279 case bcmPortPreemptControlVerifyAttempts: 61280 case bcmPortPreemptControlNonFinalFragSizeRx: 61281 case bcmPortPreemptControlFinalFragSizeRx: 61282 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61283 bcmi_esw_preemption_mac_config_set(unit, 61284 local_port, 61285 type, arg)); 61286 break; 61287 /* only need setup chip-related */ 61288 case bcmPortPreemptControlNonFinalFragSizeTx: 61289 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61290 bcmi_esw_preemption_frag_config_tx_set(unit, 61291 local_port, 0, 61292 arg)); 61293 break; 61294 case bcmPortPreemptControlFinalFragSizeTx: 61295 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61296 bcmi_esw_preemption_frag_config_tx_set(unit, 61297 local_port, 1, 61298 arg)); 61299 break; 61300 case bcmPortPreemptControlHoldReqCntMode: 61301 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61302 bcmi_esw_preemption_hold_request_mode_set(unit, 61303 local_port, 61304 arg)); 61305 break; 61306 case bcmPortPreemptControlQueueBitmap: 61307 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61308 bcmi_esw_preemption_queue_bitmap_set(unit, 61309 local_port, 61310 arg)); 61311 break; 61312 case bcmPortPreemptControlPreemptionSupport: 61313 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61314 bcmi_esw_preemption_capability_set(unit, 61315 local_port, 61316 arg)); 61317 break; 61318 default: 61319 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM); 61320 61321 } 61322 PORT_UNLOCK(unit); 61323 return BCM_E_NONE; 61324 } else 61325 #endif /* BCM_PREEMPTION_SUPPORT */ 61326 { 61327 return BCM_E_UNAVAIL; 61328 } 61329 } 61330 61331 61332 /* 61333 * Function: 61334 * bcmi_esw_port_mac_type_get 61335 * Purpose: 61336 * Get mactype for a given logical port 61337 * Parameters: 61338 * unit - (IN) Unit number. 61339 * lport - (IN) logical port 61340 * type - (OUT) mac type defined in bcmi_port_mac_type_t 61341 * Returns: 61342 * BCM_E_XXX 61343 * Notes: 61344 */ 61345 int bcmi_esw_port_mac_type_get(int unit, bcm_port_t lport, 61346 bcmi_port_mac_type_t *type) { 61347 #if defined(BCM_GREYHOUND2_SUPPORT) 61348 if(SOC_IS_GREYHOUND2(unit)) { 61349 return bcmi_gh2_port_mac_type_get(unit, lport, type); 61350 } else 61351 #endif /* BCM_GREYHOUND2_SUPPORT */ 61352 { 61353 if (NULL == type) { 61354 return SOC_E_PARAM; 61355 } 61356 *type = bcmiPortMacTypePortmode; 61357 } 61358 return BCM_E_NONE; 61359 } 61360 61361 /* 61362 * Function: 61363 * bcm_esw_port_preemption_control_get 61364 * Purpose: 61365 * Get various configurations for Preemption. 61366 * Parameters: 61367 * unit - (IN) Unit number. 61368 * gport - (IN) gport id 61369 * type - (IN) preemption control type defined in bcm_port_preempt_control_t 61370 * arg - (OUT) the preemption control value 61371 * Returns: 61372 * BCM_E_XXX 61373 * Notes: 61374 */ 61375 int 61376 bcm_esw_port_preemption_control_get(int unit, bcm_gport_t gport, 61377 bcm_port_preempt_control_t type, 61378 uint32 *arg) 61379 { 61380 PORT_INIT(unit); 61381 61382 #if defined(BCM_PREEMPTION_SUPPORT) 61383 if (soc_feature(unit, soc_feature_preemption)) { 61384 bcm_port_t local_port; 61385 61386 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port)); 61387 if(!SOC_PBMP_MEMBER(PBMP_E_ALL(unit), local_port)) { 61388 /* hg port does not support preemption */ 61389 BCM_IF_ERROR_RETURN(BCM_E_UNAVAIL); 61390 } 61391 #ifdef BCM_MONTEREY_SUPPORT 61392 if (SOC_IS_MONTEREY(unit)) { 61393 if ((type == bcmPortPreemptControlVerifyTime) || 61394 (type == bcmPortPreemptControlVerifyAttempts) || 61395 (type == bcmPortPreemptControlVerifyEnable)) { 61396 return BCM_E_UNAVAIL; 61397 } 61398 } 61399 #endif /* BCM_MONTEREY_SUPPORT */ 61400 PORT_LOCK(unit); 61401 switch (type) { 61402 /* mac-related */ 61403 case bcmPortPreemptControlEnableTx: 61404 case bcmPortPreemptControlVerifyEnable: 61405 case bcmPortPreemptControlVerifyTime: 61406 case bcmPortPreemptControlVerifyAttempts: 61407 case bcmPortPreemptControlNonFinalFragSizeRx: 61408 case bcmPortPreemptControlFinalFragSizeRx: 61409 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61410 bcmi_esw_preemption_mac_config_get(unit, 61411 local_port, 61412 type, arg)); 61413 break; 61414 /* chip-related */ 61415 case bcmPortPreemptControlNonFinalFragSizeTx: 61416 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61417 bcmi_esw_preemption_frag_config_tx_get(unit, 61418 local_port, 0, 61419 arg)); 61420 break; 61421 case bcmPortPreemptControlFinalFragSizeTx: 61422 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61423 bcmi_esw_preemption_frag_config_tx_get(unit, 61424 local_port, 1, 61425 arg)); 61426 break; 61427 case bcmPortPreemptControlHoldReqCntMode: 61428 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61429 bcmi_esw_preemption_hold_request_mode_get(unit, 61430 local_port, 61431 arg)); 61432 break; 61433 case bcmPortPreemptControlQueueBitmap: 61434 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61435 bcmi_esw_preemption_queue_bitmap_get(unit, 61436 local_port, 61437 arg)); 61438 break; 61439 case bcmPortPreemptControlPreemptionSupport: 61440 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61441 bcmi_esw_preemption_capability_get(unit, 61442 local_port, 61443 arg)); 61444 break; 61445 default: 61446 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM); 61447 61448 } 61449 PORT_UNLOCK(unit); 61450 return BCM_E_NONE; 61451 } else 61452 #endif /* BCM_PREEMPTION_SUPPORT */ 61453 { 61454 return BCM_E_UNAVAIL; 61455 } 61456 } 61457 61458 61459 /* 61460 * Function: 61461 * bcm_esw_port_preemption_status_get 61462 * Purpose: 61463 * Get the specified preemption status. 61464 * Parameters: 61465 * unit - (IN) Unit number. 61466 * gport - (IN) gport id 61467 * type - (IN) preemption status type defined in bcm_port_preempt_status_t 61468 * status - (OUT) the preemption status 61469 * For bcmPortPreemptStatusTx type, the status value 61470 * defined in bcm_port_preempt_status_tx_t. 61471 * For bcmPortPreemptStatusVerify type, the status value 61472 * defined in bcm_port_preempt_status_verify_t. 61473 * Returns: 61474 * BCM_E_XXX 61475 * Notes: 61476 */ 61477 int bcm_esw_port_preemption_status_get(int unit, bcm_gport_t gport, 61478 bcm_port_preempt_status_t type, 61479 uint32 *status) 61480 { 61481 PORT_INIT(unit); 61482 61483 #if defined(BCM_PREEMPTION_SUPPORT) 61484 if (soc_feature(unit, soc_feature_preemption)) { 61485 bcm_port_t local_port; 61486 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, gport, &local_port)); 61487 PORT_LOCK(unit); 61488 switch (type) { 61489 case bcmPortPreemptStatusTx: 61490 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61491 bcmi_esw_preemption_status_tx_get(unit, local_port, 61492 status)); 61493 break; 61494 case bcmPortPreemptStatusVerify: 61495 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK( 61496 bcmi_esw_preemption_status_verify_get(unit, local_port, 61497 status)); 61498 break; 61499 default: 61500 _BCM_PORT_IF_ERROR_RETURN_WITH_UNLOCK(BCM_E_PARAM); 61501 } 61502 PORT_UNLOCK(unit); 61503 return BCM_E_NONE; 61504 } else 61505 #endif /* BCM_PREEMPTION_SUPPORT */ 61506 { 61507 return BCM_E_UNAVAIL; 61508 } 61509 } 61510 61511 /* 61512 * Description: 61513 * Enable and configure the remote module to apply E2EFC mechanism. 61514 * Or disable it. 61515 * Parameter: 61516 * unit - (IN) unit number 61517 * remote_module - (IN) remote module id 61518 * mode - (IN) selected mode 61519 * enable - (IN) enable or disable selection 61520 * e2efc_rmod_cfg - (IN) structure containing the configuration. 61521 * Ignored when enable = 0. 61522 */ 61523 int 61524 bcm_esw_port_e2efc_remote_module_enable_set( 61525 int unit, 61526 bcm_module_t remote_module, 61527 bcm_port_e2efc_mode_t mode, 61528 int enable, 61529 bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg) 61530 { 61531 if (e2efc_rmod_cfg == NULL) { 61532 return BCM_E_UNAVAIL; 61533 } 61534 61535 if (soc_feature(unit, soc_feature_e2efc)) { 61536 #if defined(BCM_GREYHOUND2_SUPPORT) 61537 if (SOC_IS_GREYHOUND2(unit)) { 61538 return bcmi_gh2_port_e2efc_remote_module_enable_set(unit, 61539 remote_module, mode, enable, e2efc_rmod_cfg); 61540 } 61541 #endif /* BCM_GREYHOUND2_SUPPORT */ 61542 61543 #if defined(BCM_KATANA2_SUPPORT) 61544 if (SOC_IS_KATANA2(unit)) { 61545 return bcmi_kt2_port_e2efc_remote_module_enable_set(unit, 61546 remote_module, mode, enable, e2efc_rmod_cfg); 61547 } 61548 #endif /* BCM_KATANA2_SUPPORT */ 61549 } 61550 61551 return BCM_E_UNAVAIL; 61552 } 61553 61554 /* 61555 * Description: 61556 * Get the enable mode and configuration of the remote module that 61557 * applies E2EFC mechanism. 61558 * Parameter: 61559 * unit - (IN) unit number 61560 * remote_module - (IN) remote module id 61561 * mode - (IN) selected mode 61562 * enable - (OUT) enable or disable selection 61563 * e2efc_rmod_cfg - (OUT) structure containing the configuration. 61564 * Only valid if the remote module is enabled. 61565 */ 61566 int 61567 bcm_esw_port_e2efc_remote_module_enable_get( 61568 int unit, 61569 bcm_module_t remote_module, 61570 bcm_port_e2efc_mode_t mode, 61571 int *enable, 61572 bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg) 61573 { 61574 61575 if (e2efc_rmod_cfg == NULL || enable == NULL) { 61576 return BCM_E_UNAVAIL; 61577 } 61578 61579 if (soc_feature(unit, soc_feature_e2efc)) { 61580 #if defined(BCM_GREYHOUND2_SUPPORT) 61581 if (SOC_IS_GREYHOUND2(unit)) { 61582 return bcmi_gh2_port_e2efc_remote_module_enable_get(unit, 61583 remote_module, mode, enable, e2efc_rmod_cfg); 61584 } 61585 #endif /* BCM_GREYHOUND2_SUPPORT */ 61586 61587 #if defined(BCM_KATANA2_SUPPORT) 61588 if (SOC_IS_KATANA2(unit)) { 61589 return bcmi_kt2_port_e2efc_remote_module_enable_get(unit, 61590 remote_module, mode, enable, e2efc_rmod_cfg); 61591 } 61592 #endif /* BCM_KATANA2_SUPPORT */ 61593 } 61594 61595 return BCM_E_UNAVAIL; 61596 } 61597 61598 /* 61599 * Description: 61600 * Traverse enabled remote modules that apply E2EFC mechanism. 61601 * Parameter: 61602 * unit - (IN) unit number 61603 * cb - (IN) call back function to execute 61604 * user_data - (IN) pointer to user data 61605 */ 61606 int 61607 bcm_esw_port_e2efc_remote_module_traverse( 61608 int unit, 61609 bcm_port_e2efc_remote_module_traverse_cb cb, 61610 void *user_data) 61611 { 61612 if ( user_data == NULL || cb == NULL) { 61613 return BCM_E_PARAM; 61614 } 61615 61616 if (soc_feature(unit, soc_feature_e2efc)) { 61617 #if defined(BCM_GREYHOUND2_SUPPORT) 61618 if (SOC_IS_GREYHOUND2(unit)) { 61619 return bcmi_gh2_port_e2efc_remote_module_traverse(unit, cb, 61620 user_data); 61621 } 61622 #endif /* BCM_GREYHOUND2_SUPPORT */ 61623 61624 #if defined(BCM_KATANA2_SUPPORT) 61625 if (SOC_IS_KATANA2(unit)) { 61626 return bcmi_kt2_port_e2efc_remote_module_traverse(unit, cb, 61627 user_data); 61628 } 61629 #endif /* BCM_KATANA2_SUPPORT */ 61630 } 61631 return BCM_E_UNAVAIL; 61632 } 61633 61634 /* 61635 * Description: 61636 * Add remote module-port and set configuration. 61637 * Return a handle id for the bcm_port_e2efc_remote_port_xxx APIs. 61638 * The API of remote module-port configuration is only for E2EFC 61639 * transmission. 61640 * Parameter: 61641 * unit - (IN) unit number 61642 * e2efc_rport_cfg - (IN) structure containing the configuration 61643 * rport_handle_id - (OUT) remote port handle id, to be used for the rest 61644 * of bcm_port_e2efc_remote_port_xxx APIs 61645 */ 61646 int 61647 bcm_esw_port_e2efc_remote_port_add( 61648 int unit, 61649 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg, 61650 int *rport_handle_id) 61651 { 61652 if (e2efc_rport_cfg == NULL || rport_handle_id == NULL) { 61653 return BCM_E_UNAVAIL; 61654 } 61655 if (soc_feature(unit, soc_feature_e2efc)) { 61656 #if defined(BCM_GREYHOUND2_SUPPORT) 61657 if (SOC_IS_GREYHOUND2(unit)) { 61658 return bcmi_gh2_port_e2efc_remote_port_add(unit, e2efc_rport_cfg, 61659 rport_handle_id); 61660 } 61661 #endif /* BCM_GREYHOUND2_SUPPORT */ 61662 61663 #if defined(BCM_KATANA2_SUPPORT) 61664 if (SOC_IS_KATANA2(unit)) { 61665 return bcmi_kt2_port_e2efc_remote_port_add(unit, e2efc_rport_cfg, 61666 rport_handle_id); 61667 } 61668 #endif /* BCM_KATANA2_SUPPORT */ 61669 } 61670 return BCM_E_UNAVAIL; 61671 } 61672 61673 /* 61674 * Description: 61675 * Set (modify) configuration of the remote port. 61676 * Parameter: 61677 * unit - (IN) unit number 61678 * rport_handle_id - (IN) remote port handle id 61679 * e2efc_rport_cfg - (IN) structure containing the configuration 61680 */ 61681 int 61682 bcm_esw_port_e2efc_remote_port_set( 61683 int unit, 61684 int rport_handle_id, 61685 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg) 61686 { 61687 if (e2efc_rport_cfg == NULL) { 61688 return BCM_E_UNAVAIL; 61689 } 61690 if (soc_feature(unit, soc_feature_e2efc)) { 61691 #if defined(BCM_GREYHOUND2_SUPPORT) 61692 if (SOC_IS_GREYHOUND2(unit)) { 61693 return bcmi_gh2_port_e2efc_remote_port_set(unit, rport_handle_id, 61694 e2efc_rport_cfg); 61695 } 61696 #endif /* BCM_GREYHOUND2_SUPPORT */ 61697 61698 #if defined(BCM_KATANA2_SUPPORT) 61699 if (SOC_IS_KATANA2(unit)) { 61700 return bcmi_kt2_port_e2efc_remote_port_set(unit, rport_handle_id, 61701 e2efc_rport_cfg); 61702 } 61703 #endif /* BCM_KATANA2_SUPPORT */ 61704 } 61705 return BCM_E_UNAVAIL; 61706 } 61707 61708 /* 61709 * Description: 61710 * Get configuration of the remote port. 61711 * Return the remote module, remote port and configuration of the 61712 * handle id. 61713 * Parameter: 61714 * unit - (IN) unit number 61715 * rport_handle_id - (IN) remote port handle id 61716 * e2efc_rport_cfg - (OUT) structure containing the configuration 61717 */ 61718 int 61719 bcm_esw_port_e2efc_remote_port_get( 61720 int unit, 61721 int rport_handle_id, 61722 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg) 61723 { 61724 if (e2efc_rport_cfg == NULL) { 61725 return BCM_E_UNAVAIL; 61726 } 61727 if (soc_feature(unit, soc_feature_e2efc)) { 61728 #if defined(BCM_GREYHOUND2_SUPPORT) 61729 if (SOC_IS_GREYHOUND2(unit)) { 61730 return bcmi_gh2_port_e2efc_remote_port_get(unit, rport_handle_id, 61731 e2efc_rport_cfg); 61732 } 61733 #endif /* BCM_GREYHOUND2_SUPPORT */ 61734 61735 #if defined(BCM_KATANA2_SUPPORT) 61736 if (SOC_IS_KATANA2(unit)) { 61737 return bcmi_kt2_port_e2efc_remote_port_get(unit, rport_handle_id, 61738 e2efc_rport_cfg); 61739 } 61740 #endif /* BCM_KATANA2_SUPPORT */ 61741 } 61742 return BCM_E_UNAVAIL; 61743 } 61744 61745 /* 61746 * Description: 61747 * Delete remote port. 61748 * Parameter: 61749 * unit - (IN) unit number 61750 * rport_handle_id - (IN) remote port handle id 61751 */ 61752 int 61753 bcm_esw_port_e2efc_remote_port_delete( 61754 int unit, 61755 int rport_handle_id) 61756 { 61757 61758 if (soc_feature(unit, soc_feature_e2efc)) { 61759 #if defined(BCM_GREYHOUND2_SUPPORT) 61760 if (SOC_IS_GREYHOUND2(unit)) { 61761 return bcmi_gh2_port_e2efc_remote_port_delete(unit, 61762 rport_handle_id); 61763 } 61764 #endif /* BCM_GREYHOUND2_SUPPORT */ 61765 61766 #if defined(BCM_KATANA2_SUPPORT) 61767 if (SOC_IS_KATANA2(unit)) { 61768 return bcmi_kt2_port_e2efc_remote_port_delete(unit, 61769 rport_handle_id); 61770 } 61771 #endif /* BCM_KATANA2_SUPPORT */ 61772 } 61773 return BCM_E_UNAVAIL; 61774 } 61775 61776 /* 61777 * Description: 61778 * Traverse remote ports. 61779 * Parameter: 61780 * unit - (IN) unit number 61781 * cb - (IN) call back function to execute 61782 * user_data - (IN) pointer to user data 61783 */ 61784 int 61785 bcm_esw_port_e2efc_remote_port_traverse( 61786 int unit, 61787 bcm_port_e2efc_remote_port_traverse_cb cb, 61788 void *user_data) 61789 { 61790 if ( user_data == NULL || cb == NULL) { 61791 return BCM_E_PARAM; 61792 } 61793 61794 if (soc_feature(unit, soc_feature_e2efc)) { 61795 #if defined(BCM_GREYHOUND2_SUPPORT) 61796 if (SOC_IS_GREYHOUND2(unit)) { 61797 return bcmi_gh2_port_e2efc_remote_port_traverse(unit, cb, 61798 user_data); 61799 } 61800 #endif /* BCM_GREYHOUND2_SUPPORT */ 61801 61802 #if defined(BCM_KATANA2_SUPPORT) 61803 if (SOC_IS_KATANA2(unit)) { 61804 return bcmi_kt2_port_e2efc_remote_port_traverse(unit, cb, 61805 user_data); 61806 } 61807 #endif /* BCM_KATANA2_SUPPORT */ 61808 } 61809 return BCM_E_UNAVAIL; 61810 } 61811 61812 #ifdef SW_AUTONEG_SUPPORT 61813 /* 61814 * Function : _bcm_esw_port_notify_link_down_evt 61815 * Description : Notify Link_Down event to SW AN SM. 61816 * Parameters : (IN) unit - BCM device number 61817 * (IN) port - Port number 61818 * Returns : BCM_E_XXX 61819 */ 61820 int 61821 _bcm_esw_port_notify_link_down_evt(int unit, bcm_port_t port) 61822 { 61823 int an_mode = 0; 61824 int an_enabled = 0; 61825 int rv = BCM_E_NONE; 61826 61827 if (soc_feature(unit, soc_feature_sw_autoneg)) { 61828 /* if the link is down notify the SW AN thread 61829 * to restart AN if AN is enabled for the port 61830 */ 61831 an_mode = soc_property_port_get(unit, port, 61832 spn_PHY_AN_C73, an_mode); 61833 61834 /* phy_an_c73 value of 3 indicated MSA AN mode */ 61835 if ((an_mode == SW_AN_MODE_CL73_MSA) || 61836 (an_mode == SW_AN_MODE_MSA_ONLY)) { 61837 61838 61839 rv = bcm_esw_port_autoneg_get(unit, port , &an_enabled); 61840 if (BCM_FAILURE(rv)) { 61841 LOG_WARN(BSL_LS_BCM_PORT, 61842 (BSL_META_U(unit, 61843 "u=%d p=%d AUTONEG GET FALSE rv=%d\n"), 61844 unit, port, rv)); 61845 PORT_UNLOCK(unit); 61846 return rv; 61847 } 61848 61849 if (an_enabled) { 61850 /* notify the SW AN thread of link down event */ 61851 rv = bcm_sw_an_post_event(unit, port, BCM_PORT_SW_AN_EVENT_AN_LINK_DOWN); 61852 } 61853 61854 if (BCM_FAILURE(rv)) { 61855 LOG_WARN(BSL_LS_BCM_PORT, 61856 (BSL_META_U(unit, 61857 "u=%d p=%d SW AN POST EVENT FAILED rv=%d\n"), 61858 unit, port, rv)); 61859 } 61860 } 61861 } 61862 return BCM_E_NONE; 61863 } 61864 #endif 61865 61866 61867 /* 61868 * Function: 61869 * bcm_esw_port_phy_tx_set 61870 * Purpose: 61871 * Set port phy tx properties 61872 * Parameters: 61873 * unit - StrataSwitch Unit #. 61874 * port - StrataSwitch port #. 61875 * tx - tx properties 61876 * Returns: 61877 * BCM_E_NONE 61878 * BCM_E_XXX 61879 */ 61880 int 61881 bcm_esw_port_phy_tx_set(int unit, bcm_port_t port, bcm_port_phy_tx_t *tx) { 61882 int rv = BCM_E_UNAVAIL; 61883 61884 if (NULL == tx) { 61885 return BCM_E_PARAM; 61886 } 61887 61888 /* Make sure port module is initialized. */ 61889 PORT_INIT(unit); 61890 61891 if (SOC_IS_TOMAHAWK3(unit)) { 61892 /* Call Port Control module */ 61893 if (SOC_USE_PORTCTRL(unit)) { 61894 rv = bcmi_esw_portctrl_phy_tx_set(unit, port, tx); 61895 } 61896 } 61897 61898 return rv; 61899 } 61900 61901 /* 61902 * Function: 61903 * bcm_esw_port_phy_tx_get 61904 * Purpose: 61905 * Get port phy tx properties 61906 * Parameters: 61907 * unit - StrataSwitch Unit #. 61908 * port - StrataSwitch port #. 61909 * tx - tx properties 61910 * Returns: 61911 * BCM_E_NONE 61912 * BCM_E_XXX 61913 */ 61914 int 61915 bcm_esw_port_phy_tx_get(int unit, bcm_port_t port, bcm_port_phy_tx_t *tx) { 61916 int rv = BCM_E_UNAVAIL; 61917 61918 if (NULL == tx) { 61919 return BCM_E_PARAM; 61920 } 61921 61922 /* Make sure port module is initialized. */ 61923 PORT_INIT(unit); 61924 61925 if (SOC_IS_TOMAHAWK3(unit)) { 61926 /* Call Port Control module */ 61927 if (SOC_USE_PORTCTRL(unit)) { 61928 rv = bcmi_esw_portctrl_phy_tx_get(unit, port, tx); 61929 } 61930 } 61931 61932 return rv; 61933 } 61934 61935 /* 61936 * Function: 61937 * bcm_esw_port_rlm_config_set 61938 * Purpose: 61939 * Set port rlm config properties 61940 * Parameters: 61941 * unit - (IN) StrataSwitch Unit #. 61942 * port - (IN) StrataSwitch port #. 61943 * rlm_config - (IN) rlm properties 61944 * enable - (IN) enable or disable rlm 61945 * Returns: 61946 * BCM_E_NONE 61947 * BCM_E_XXX 61948 */ 61949 int 61950 bcm_esw_port_rlm_config_set(int unit, bcm_port_t port, 61951 bcm_port_rlm_config_t *rlm_config, int enable) { 61952 int rv = BCM_E_UNAVAIL; 61953 int port_enabled = 0; 61954 int link; 61955 61956 if (NULL == rlm_config) { 61957 return BCM_E_PARAM; 61958 } 61959 61960 /* Make sure port module is initialized. */ 61961 PORT_INIT(unit); 61962 61963 /* Check for valid port */ 61964 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 61965 61966 if (!enable) { 61967 /* need to disable the port first if disable RLM */ 61968 rv = bcm_esw_port_enable_set(unit, port, 0); 61969 } else { 61970 /*next check if the port is enabled */ 61971 rv = bcm_esw_port_enable_get(unit, port, &port_enabled); 61972 if (!port_enabled) { 61973 LOG_ERROR(BSL_LS_BCM_PORT, 61974 (BSL_META_U(unit, 61975 "port %d is not enabled \n"), port)); 61976 return BCM_E_CONFIG; 61977 } 61978 61979 /* check link status */ 61980 SOC_IF_ERROR_RETURN 61981 (bcm_esw_port_link_status_get(unit, port, &link)); 61982 if (FALSE == link) { 61983 LOG_ERROR(BSL_LS_BCM_PORT, 61984 (BSL_META_U(unit, 61985 "port %d link is not up \n"), port)); 61986 return BCM_E_CONFIG; 61987 } 61988 } 61989 61990 if (SOC_IS_TOMAHAWK3(unit)) { 61991 /* Call Port Control module */ 61992 if (SOC_USE_PORTCTRL(unit)) { 61993 rv = bcmi_esw_portctrl_rlm_config_set(unit, 61994 port, 61995 rlm_config, 61996 enable); 61997 } 61998 } 61999 62000 if (!enable) { 62001 /* need to re-enable the port after RLM is disabled */ 62002 rv = bcm_esw_port_enable_set(unit, port, 1); 62003 } 62004 62005 return rv; 62006 } 62007 62008 /* 62009 * Function: 62010 * bcm_esw_port_rlm_config_get 62011 * Purpose: 62012 * Get port phy tx properties 62013 * Parameters: 62014 * unit - (IN) StrataSwitch Unit #. 62015 * port - (IN) StrataSwitch port #. 62016 * rlm_config - (OUT) rlm config properties 62017 * enable - (OUT) enable/disable 62018 * Returns: 62019 * BCM_E_NONE 62020 * BCM_E_XXX 62021 */ 62022 int 62023 bcm_esw_port_rlm_config_get(int unit, bcm_port_t port, 62024 bcm_port_rlm_config_t *rlm_config, int *enable) { 62025 int rv = BCM_E_UNAVAIL; 62026 62027 if (NULL == rlm_config) { 62028 return BCM_E_PARAM; 62029 } 62030 62031 /* Make sure port module is initialized. */ 62032 PORT_INIT(unit); 62033 62034 /* Check for valid port */ 62035 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 62036 62037 if (SOC_IS_TOMAHAWK3(unit)) { 62038 /* Call Port Control module */ 62039 if (SOC_USE_PORTCTRL(unit)) { 62040 rv = bcmi_esw_portctrl_rlm_config_get(unit, 62041 port, 62042 rlm_config, 62043 enable); 62044 } 62045 } 62046 62047 return rv; 62048 } 62049 /* 62050 * Function: 62051 * bcm_esw_port_rlm_status_get 62052 * Purpose: 62053 * Get port rlm status 62054 * Parameters: 62055 * unit - (IN) StrataSwitch Unit #. 62056 * port - (IN) StrataSwitch port #. 62057 * rlm_status - (OUT) rlm config properties 62058 * Returns: 62059 * BCM_E_NONE 62060 * BCM_E_XXX 62061 */ 62062 int 62063 bcm_esw_port_rlm_status_get(int unit, bcm_port_t port, 62064 bcm_port_rlm_status_t *rlm_status) { 62065 int rv = BCM_E_UNAVAIL; 62066 62067 if (NULL == rlm_status) { 62068 return BCM_E_PARAM; 62069 } 62070 62071 /* Make sure port module is initialized. */ 62072 PORT_INIT(unit); 62073 62074 /* Check for valid port */ 62075 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate(unit, port, &port)); 62076 62077 if (SOC_IS_TOMAHAWK3(unit)) { 62078 /* Call Port Control module */ 62079 if (SOC_USE_PORTCTRL(unit)) { 62080 rv = bcmi_esw_portctrl_rlm_status_get(unit, 62081 port, 62082 rlm_status); 62083 } 62084 } 62085 62086 return rv; 62087 }