port.c (181686B)
1 /* 2 * 3 * 4 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 5 * 6 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 7 */ 8 9 10 #include <soc/defs.h> 11 #include <soc/debug.h> 12 #include <soc/drv.h> 13 #include <soc/mem.h> 14 #include <soc/cmic.h> 15 16 #include <sal/core/time.h> 17 #include <shared/bsl.h> 18 #include <bcm/port.h> 19 #include <bcm/tx.h> 20 #include <bcm/error.h> 21 #include <bcm_int/esw/stack.h> 22 #include <bcm_int/esw/katana2.h> 23 #include <bcm_int/esw/cosq.h> 24 25 #include <soc/katana2.h> 26 #include <soc/phyreg.h> 27 28 #if defined(BCM_SABER2_SUPPORT) 29 #include <soc/saber2.h> 30 #include <bcm_int/esw/saber2.h> 31 #endif 32 33 #if defined(BCM_METROLITE_SUPPORT) 34 #include <soc/metrolite.h> 35 #include <bcm_int/esw/metrolite.h> 36 #endif 37 38 #if defined(BCM_KATANA2_SUPPORT) 39 #include <bcm_int/esw_dispatch.h> 40 #include <bcm_int/esw/katana.h> 41 #include <bcm_int/esw/katana2.h> 42 #include <bcm_int/esw/virtual.h> 43 #include <soc/macutil.h> 44 #include <bcm_int/esw/port.h> 45 #include <bcm_int/esw/xgs5.h> 46 47 #if defined(BCM_SABER2_SUPPORT) 48 #include <soc/saber2.h> 49 #endif 50 #include <bcm_int/esw/portctrl.h> 51 52 static uint32 new_tdm[256] = {0}; 53 extern int mxqblock_max_startaddr[KT2_MAX_MXQBLOCKS]; 54 extern int mxqblock_max_endaddr[KT2_MAX_MXQBLOCKS]; 55 extern int 56 bcm_katana2_cosq_reconfigure_flexio(int unit, bcm_port_t port, int lanes); 57 extern int soc_kt_port_flush(int unit, int port, int enable); 58 extern int _soc_katana2_mmu_init_helper_dyn(int unit, int port, int ext_mem_enable); 59 extern int _bcm_saber2_mmu_init_helper_dyn(int unit, int port, int ext_mem_enable); 60 /* 61 * Function Vector 62 */ 63 static bcm_esw_port_drv_t bcm_katana2_port_drv = { 64 /* fn_drv_init */ bcmi_katana2_port_fn_drv_init, 65 /* resource_set */ NULL, 66 /* resource_get */ NULL, 67 /* resource_multi_set */ NULL, 68 /* resource_speed_set */ NULL, 69 /* resource_traverse */ NULL, 70 /* port_redirect_set */ bcmi_xgs5_port_redirect_config_set, 71 /* port_redirect_get */ bcmi_xgs5_port_redirect_config_get, 72 /* port_enable_set */ NULL 73 }; 74 75 /* 76 * Device Specific HW Tables 77 */ 78 79 /* Egr port table */ 80 static bcmi_xgs5_port_redirection_egr_port_table_t 81 bcmi_katana2_port_redirection_egr_port_table = { 82 /* mem */ EGR_PORTm, 83 /* dest_type */ REDIRECTION_TYPEf, 84 /* dest_value */ REDIRECTION_DESTINATIONf, 85 /* drop_original */ DROP_ORIGINAL_COPYf, 86 /* pkt_priority */ REDIRECT_INT_PRIf, 87 /* pkt_change_priority */ REDIRECT_INT_PRI_SELf, 88 /* pkt_color */ REDIRECT_DROP_PRECEDENCEf, 89 /* strength */ INVALIDf, 90 /* buffer_priority */ INVALIDf, 91 /* action */ INVALIDf, 92 /* redir_pkt_source */ INVALIDf, 93 /* redir_pkt_truncate */ INVALIDf 94 }; 95 96 97 /* HW Definitions */ 98 static bcmi_xgs5_port_hw_defs_t bcmi_katana2_port_hw_defs; 99 100 /* 101 * Function: 102 * bcmi_katana2_port_fn_drv_init 103 * Purpose: 104 * Initialize the Port function driver. 105 * Parameters: 106 * unit - (IN) Unit number. 107 * Returns: 108 * BCM_E_xxx 109 * Notes: 110 */ 111 int 112 bcmi_katana2_port_fn_drv_init(int unit) 113 { 114 /* HW Definition Tables */ 115 sal_memset(&bcmi_katana2_port_hw_defs, 0, 116 sizeof(bcmi_katana2_port_hw_defs)); 117 bcmi_katana2_port_hw_defs.egr_port = 118 &bcmi_katana2_port_redirection_egr_port_table; 119 120 /* Initialize Common XGS5 Port module */ 121 BCM_IF_ERROR_RETURN 122 (bcmi_xgs5_port_fn_drv_init(unit, &bcm_katana2_port_drv, NULL, 123 &bcmi_katana2_port_hw_defs)); 124 125 return BCM_E_NONE; 126 } 127 128 /* 129 * Function: 130 * _bcm_kt2_port_cfg_init 131 * Purpose: 132 * Initialize port configuration according to Initial System 133 * Configuration (see init.c) 134 * Parameters: 135 * unit - (IN)StrataSwitch unit number. 136 * port - (IN)Port number. 137 * vlan_data - (IN)Initial VLAN data information 138 * Returns: 139 * BCM_E_XXX 140 */ 141 int 142 _bcm_kt2_port_cfg_init(int unit, bcm_port_t port, bcm_vlan_data_t *vlan_data) 143 { 144 port_tab_entry_t ptab; /* Port table entry. */ 145 soc_field_t field_ids[SOC_MAX_MEM_FIELD_WORDS]; 146 uint32 field_values[SOC_MAX_MEM_FIELD_WORDS]; 147 uint32 cascaded_type = 0, port_type = 0; 148 int field_count = 0; 149 int key_type_value = 0; 150 bcm_pbmp_t port_pbmp; 151 bcm_port_t max_ports = KT2_MAX_LOGICAL_PORTS; 152 153 #if defined(BCM_METROLITE_SUPPORT) 154 if (SOC_IS_METROLITE(unit)) { 155 max_ports = ML_MAX_LOGICAL_PORTS; 156 } else 157 #endif 158 #if defined(BCM_SABER2_SUPPORT) 159 if(SOC_IS_SABER2(unit)) { 160 max_ports = SB2_MAX_LOGICAL_PORTS; 161 } 162 #endif 163 164 if (port < max_ports) { 165 if (IS_ST_PORT(unit, port)) { 166 port_type = KT2_PORT_TYPE_HIGIG; 167 } else if (IS_LB_PORT(unit, port)) { 168 port_type = KT2_PORT_TYPE_LOOPBACK; 169 } else if (IS_LP_PORT(unit, port)) { 170 port_type = KT2_PORT_TYPE_CASCADED; 171 cascaded_type = KT2_CASCADED_TYPE_LINKPHY; 172 } else if (IS_SUBTAG_PORT(unit, port)) { 173 port_type = KT2_PORT_TYPE_CASCADED; 174 cascaded_type = KT2_CASCADED_TYPE_SUBTAG; 175 } else { 176 port_type = KT2_PORT_TYPE_ETHERNET; 177 } 178 179 BCM_IF_ERROR_RETURN(soc_mem_field32_modify( 180 unit, ING_PHYSICAL_PORT_TABLEm, port, 181 PORT_TYPEf,port_type)); 182 BCM_IF_ERROR_RETURN(soc_mem_field32_modify( 183 unit, ING_PHYSICAL_PORT_TABLEm, port, 184 CASCADED_PORT_TYPEf, cascaded_type)); 185 BCM_IF_ERROR_RETURN(soc_mem_field32_modify( 186 unit, EGR_PHYSICAL_PORTm, port, 187 PORT_TYPEf,port_type)); 188 BCM_IF_ERROR_RETURN(soc_mem_field32_modify( 189 unit, ING_PHYSICAL_PORT_TABLEm, port, 190 CASCADED_PORT_TYPEf, cascaded_type)); 191 192 if (IS_CPU_PORT(unit,port)) { 193 if (SOC_INFO(unit).cpu_hg_index != -1) { 194 BCM_IF_ERROR_RETURN(soc_mem_field32_modify( 195 unit, ING_PHYSICAL_PORT_TABLEm, 196 SOC_INFO(unit).cpu_hg_index, PORT_TYPEf, 1)); 197 BCM_IF_ERROR_RETURN(soc_mem_field32_modify( 198 unit, EGR_PHYSICAL_PORTm, SOC_INFO(unit).cpu_hg_index, 199 PORT_TYPEf, 1)); 200 } 201 } 202 203 204 /* ingress physical port to pp_port mapping */ 205 if (port_type != KT2_PORT_TYPE_CASCADED) { 206 BCM_IF_ERROR_RETURN(soc_mem_field32_modify( 207 unit, ING_PHYSICAL_PORT_TABLEm, port, PP_PORTf, port)); 208 } else { 209 BCM_IF_ERROR_RETURN(soc_mem_field32_modify( 210 unit, ING_PHYSICAL_PORT_TABLEm, port, PP_PORTf, 211 ((1 << soc_mem_field_length(unit, ING_PHYSICAL_PORT_TABLEm, PP_PORTf)) - 1))); 212 } 213 214 /* pp_port to egress physical port mapping */ 215 BCM_IF_ERROR_RETURN(soc_mem_field32_modify( 216 unit, PP_PORT_TO_PHYSICAL_PORT_MAPm, port, DESTINATIONf,port)); 217 } 218 219 field_ids[field_count] = EN_EFILTERf; 220 field_values[field_count] = 1; 221 field_count ++; 222 223 /* Initialize egress vlan translation port class with identity mapping */ 224 BCM_PBMP_CLEAR(port_pbmp); 225 BCM_PBMP_ASSIGN(port_pbmp, PBMP_PORT_ALL(unit)); 226 if (soc_feature(unit, soc_feature_flex_port)) { 227 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update(unit, &port_pbmp)); 228 } 229 230 field_ids[field_count] = VT_PORT_GROUP_IDf; 231 field_values[field_count] = 232 SOC_PBMP_MEMBER(port_pbmp, port) ? port : 0; 233 field_count++; 234 235 /* For some devices, directed mirroring will always be 1 */ 236 if (soc_feature(unit, soc_feature_directed_mirror_only)) { 237 field_ids[field_count] = EM_SRCMOD_CHANGEf; 238 field_values[field_count] = 1; 239 field_count++; 240 } 241 242 if (SOC_MEM_IS_VALID(unit, EGR_PORTm)) { 243 BCM_IF_ERROR_RETURN 244 (soc_mem_fields32_modify(unit, EGR_PORTm, port, field_count, 245 field_ids, field_values)); 246 } 247 248 /* Write PORT_TABm memory */ 249 sal_memcpy(&ptab, soc_mem_entry_null(unit, PORT_TABm), sizeof (ptab)); 250 251 /* Set default vlan id(pvid) for port. */ 252 soc_PORT_TABm_field32_set(unit, &ptab, PORT_VIDf, vlan_data->vlan_tag); 253 254 /* Switching VLAN. */ 255 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, OUTER_TPIDf)) { 256 soc_PORT_TABm_field32_set(unit, &ptab, OUTER_TPIDf, 0x8100); 257 } 258 259 /* Enable mac based vlan classification. */ 260 soc_PORT_TABm_field32_set(unit, &ptab, MAC_BASED_VID_ENABLEf, 1); 261 262 /* Enable subned based vlan classification. */ 263 soc_PORT_TABm_field32_set(unit, &ptab, SUBNET_BASED_VID_ENABLEf, 1); 264 265 266 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, TRUST_INCOMING_VIDf)) { 267 soc_PORT_TABm_field32_set(unit, &ptab, TRUST_INCOMING_VIDf, 1); 268 269 /* Set identify mapping for pri/cfi re-mapping */ 270 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, PRI_MAPPINGf)) { 271 soc_PORT_TABm_field32_set(unit, &ptab, PRI_MAPPINGf, 0xfac688); 272 soc_PORT_TABm_field32_set(unit, &ptab, CFI_0_MAPPINGf, 0); 273 soc_PORT_TABm_field32_set(unit, &ptab, CFI_1_MAPPINGf, 1); 274 } 275 276 /* Set identify mapping for ipri/icfi re-mapping */ 277 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, IPRI_MAPPINGf)) { 278 soc_PORT_TABm_field32_set(unit, &ptab, IPRI_MAPPINGf, 0xfac688); 279 soc_PORT_TABm_field32_set(unit, &ptab, ICFI_0_MAPPINGf, 0); 280 soc_PORT_TABm_field32_set(unit, &ptab, ICFI_1_MAPPINGf, 1); 281 } 282 283 /* Set the CML to PVP_CML_SWITCH by default (hw learn and forward) */ 284 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, CML_FLAGS_NEWf)) { 285 soc_PORT_TABm_field32_set(unit, &ptab, CML_FLAGS_NEWf, 0x8); 286 soc_PORT_TABm_field32_set(unit, &ptab, CML_FLAGS_MOVEf, 0x8); 287 } 288 /* Set first VLAN_XLATE key-type to {outer,port}. 289 * Set second VLAN_XLATE key-type to {inner,port}. 290 */ 291 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, VT_KEY_TYPEf)) { 292 BCM_IF_ERROR_RETURN 293 (_bcm_esw_pt_vtkey_type_value_get(unit, 294 KT2_VLXLT_HASH_KEY_TYPE_OVID,&key_type_value)); 295 soc_PORT_TABm_field32_set(unit, &ptab, VT_KEY_TYPEf, 296 key_type_value); 297 BCM_IF_ERROR_RETURN 298 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 299 VT_KEY_TYPEf, key_type_value)); 300 } 301 302 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, VT_KEY_TYPE_USE_GLPf)) { 303 soc_PORT_TABm_field32_set(unit, &ptab, VT_KEY_TYPE_USE_GLPf, 1); 304 BCM_IF_ERROR_RETURN 305 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 306 VT_KEY_TYPE_USE_GLPf, 1)); 307 } 308 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, VT_PORT_TYPE_SELECTf)) { 309 soc_PORT_TABm_field32_set(unit, &ptab, VT_PORT_TYPE_SELECTf, 1); 310 BCM_IF_ERROR_RETURN 311 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 312 VT_PORT_TYPE_SELECTf, 1)); 313 } 314 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, VT_KEY_TYPE_2f)) { 315 BCM_IF_ERROR_RETURN 316 (_bcm_esw_pt_vtkey_type_value_get(unit, 317 KT2_VLXLT_HASH_KEY_TYPE_IVID,&key_type_value)); 318 soc_PORT_TABm_field32_set(unit, &ptab, VT_KEY_TYPE_2f, 319 key_type_value); 320 BCM_IF_ERROR_RETURN 321 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 322 VT_KEY_TYPE_2f, key_type_value)); 323 324 } 325 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, VT_KEY_TYPE_2_USE_GLPf)) { 326 soc_PORT_TABm_field32_set(unit, &ptab, VT_KEY_TYPE_2_USE_GLPf, 1); 327 BCM_IF_ERROR_RETURN 328 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 329 VT_KEY_TYPE_2_USE_GLPf, 1)); 330 } 331 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, VT_PORT_TYPE_SELECT_2f)) { 332 soc_PORT_TABm_field32_set(unit, &ptab, VT_PORT_TYPE_SELECT_2f, 1); 333 BCM_IF_ERROR_RETURN 334 (_bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 335 VT_PORT_TYPE_SELECT_2f, 1)); 336 } 337 338 /* Trust the outer tag pri/cfi (to be backwards compatible) */ 339 if (SOC_MEM_FIELD_VALID(unit, PORT_TABm, TRUST_OUTER_DOT1Pf)) { 340 soc_PORT_TABm_field32_set(unit, &ptab, TRUST_OUTER_DOT1Pf, 1); 341 } 342 } 343 344 BCM_IF_ERROR_RETURN(BCM_XGS3_MEM_WRITE(unit, PORT_TABm, port, &ptab)); 345 346 return (BCM_E_NONE); 347 } 348 349 int 350 bcm_kt2_port_cfg_init(int unit, bcm_port_t port, bcm_vlan_data_t *vlan_data) 351 { 352 #ifdef BCM_KATANA2_SUPPORT 353 if(SOC_IS_KATANA2(unit)) { 354 return _bcm_kt2_port_cfg_init(unit, port, vlan_data); 355 } 356 #endif /* BCM_KATANA2_SUPPORT */ 357 return (BCM_E_NONE); 358 } 359 360 int 361 _bcm_kt2_port_sw_info_display(int unit, bcm_port_t port) { 362 363 int rv = 0; 364 soc_info_t *si = &SOC_INFO(unit); 365 int lanes; 366 uint8 mxqblock; 367 int enable; 368 int speed; 369 int link; 370 int autoneg; 371 int discard_mode; 372 int loopback_mode; 373 int master_mode; 374 int encap_mode = BCM_PORT_ENCAP_COUNT; 375 char *discard[] = {"NONE", "ALL", "UNTAG", "TAG"}; 376 char *loopback[] = {"NONE", "MAC", "PHY", "RMT", "C57"}; 377 char *master[] = {"SLAVE", "MASTER", "AUTO", "NONE"}; 378 char *encap[] = {"IEEE", "HIGIG", "B5632", "HIGIG2", "HIGIG-Lite"}; 379 380 rv += (_bcm_kt2_port_lanes_get(unit, port, &lanes)); 381 rv += (soc_katana2_get_port_mxqblock(unit,port,&mxqblock)); 382 rv += (bcm_esw_port_enable_get(unit, port, &enable)); 383 rv += (bcm_esw_port_autoneg_get(unit, port, &autoneg)); 384 rv += (bcm_esw_port_speed_get(unit, port, &speed)); 385 rv += (bcm_esw_port_link_status_get(unit, port, &link)); 386 rv += (bcm_esw_port_discard_get(unit, port, &discard_mode)); 387 rv += (bcm_esw_port_loopback_get(unit, port, &loopback_mode)); 388 rv += (bcm_esw_port_master_get(unit, port, &master_mode)); 389 rv += (bcm_esw_port_encap_get(unit, port, &encap_mode)); 390 391 if (rv < 0) { 392 LOG_CLI((BSL_META_U(unit, "\n\n Some parameters not set properly !!"))); 393 } 394 LOG_CLI((BSL_META_U(unit, "\n\n SOFTWARE PORT CONFIGURATION :\n"))); 395 LOG_CLI((BSL_META_U(unit, "------------------------------------"))); 396 LOG_CLI((BSL_META_U(unit, "\n Port Name\t\t:\t%s"),si->port_name[port])); 397 LOG_CLI((BSL_META_U(unit, "\n MxQBlock ID\t\t:\t%d"), mxqblock)); 398 LOG_CLI((BSL_META_U(unit, "\n Lane Number\t\t:\t%d "),lanes)); 399 LOG_CLI((BSL_META_U(unit, "\n Current Speed\t\t:\t%d"), speed)); 400 LOG_CLI((BSL_META_U(unit, "\n Max speed\t\t:\t%d"),si->port_speed_max[port])); 401 LOG_CLI((BSL_META_U(unit, "\n MxQSpeed\t\t:\t%d"),((*mxqspeeds[unit])[mxqblock][lanes-1]))); 402 LOG_CLI((BSL_META_U(unit, "\n Port status \t\t:\t%s"),(enable ? "ENABLED" : "DISABLED"))); 403 LOG_CLI((BSL_META_U(unit, "\n Link status\t\t:\t%s"),(link ? "UP" : "DOWN"))); 404 LOG_CLI((BSL_META_U(unit, "\n Autoneg status\t\t:\t%s"),(autoneg ? "TRUE" : "FALSE"))); 405 LOG_CLI((BSL_META_U(unit, "\n Discard Type\t\t:\t%s"),(discard_mode <= 3 ? discard[discard_mode] : "INVALID"))); 406 LOG_CLI((BSL_META_U(unit, "\n Loopback Mode\t\t:\t%s"),(loopback_mode <= 4 ? loopback[loopback_mode] : "INVALID"))); 407 LOG_CLI((BSL_META_U(unit, "\n Master Status\t\t:\t%s"),(master_mode <= 3 ? master[master_mode] : "INVALID"))); 408 LOG_CLI((BSL_META_U(unit, "\n Encapsulation \t\t:\t%s"),(encap_mode <= 4 ? encap[encap_mode] : "INVALID"))); 409 LOG_CLI((BSL_META_U(unit, "\n\n***********************************************\n\n"))); 410 411 return 0; 412 413 } 414 415 int 416 _bcm_kt2_port_hw_info_display(int unit, bcm_port_t port) { 417 418 uint32 rval = 0; 419 uint64 rval_64; 420 uint8 mxq_port = port; 421 int lanes = 0; 422 uint8 mxqblock; 423 int port0, port1, port2, port3; 424 int higig, higig2, xpause, pfc, drain, llfc; 425 int core_mode, phy_mode; 426 int tx_en, rx_en, line_lpbk, core_lpbk, line_rm_lpbk, core_rm_lpbk; 427 int lpbk_leak, rm_lpbk_leak; 428 int soft_reset, rs_soft_reset, sw_link, link_status_select; 429 int hdr_mode, sop_crc, speed_mode; 430 int port_enable; 431 egr_enable_entry_t egr_en; 432 433 char *phy[] = {"Single", "Dual", "Quad"}; 434 char *core[] = {"Single", "Dual", "Quad"}; 435 char *enable[] = {"DISABLED", "ENABLED"}; 436 char *active[] = {"INACTIVE", "ACTIVE"}; 437 char *link_sel[] = {"SOFTWARE", "STRAP-PIN"}; 438 char *hdr[] = {"IEEE", "HG+", "HG2", "CLH", "SCH", "SOP ONLY IEEE"}; 439 char *speed[] = {"10Mpbps", "100Mbps", "1Gbps", "2.5Gbps", ">=10Gbps"}; 440 441 BCM_IF_ERROR_RETURN(_bcm_kt2_port_lanes_get(unit, port, &lanes)); 442 BCM_IF_ERROR_RETURN(soc_katana2_get_port_mxqblock(unit, port, &mxqblock)); 443 444 LOG_CLI((BSL_META_U(unit, "\n\n HARDWARE PORT CONFIGURATION : \n"))); 445 LOG_CLI((BSL_META_U(unit, "--------------------------------------\n"))); 446 447 /* XPORT_MODE_REG */ 448 SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &rval)); 449 core_mode = soc_reg_field_get(unit, XPORT_MODE_REGr, rval, CORE_PORT_MODEf); 450 phy_mode = soc_reg_field_get(unit, XPORT_MODE_REGr, rval, PHY_PORT_MODEf); 451 LOG_CLI((BSL_META_U(unit, "\n XPORT MODE "))); 452 LOG_CLI((BSL_META_U(unit, "\n Core Mode\t:\t%s"), core[core_mode])); 453 LOG_CLI((BSL_META_U(unit, "\n Phy Mode\t:\t%s"), phy[phy_mode])); 454 455 /* XPORT PORT ENABLE */ 456 SOC_IF_ERROR_RETURN(READ_XPORT_PORT_ENABLEr(unit, port, &rval)); 457 port0 = soc_reg_field_get(unit, XPORT_PORT_ENABLEr, rval, PORT0f); 458 port1 = soc_reg_field_get(unit, XPORT_PORT_ENABLEr, rval, PORT1f); 459 port2 = soc_reg_field_get(unit, XPORT_PORT_ENABLEr, rval, PORT2f); 460 port3 = soc_reg_field_get(unit, XPORT_PORT_ENABLEr, rval, PORT3f); 461 LOG_CLI((BSL_META_U(unit, "\n\n XPORT PORT ENABLE "))); 462 LOG_CLI((BSL_META_U(unit, "\n MxQBlock\t:\t%d\n Port0\t\t:\t%s\n Port1\t\t:\t%s" 463 "\n Port2\t\t:\t%s\n Port3\t\t:\t%s"), mxqblock, \ 464 enable[port0], enable[port1], enable[port2], enable[port3])); 465 466 467 /* XPORT CONFIG */ 468 SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, &rval)); 469 higig = soc_reg_field_get(unit, XPORT_CONFIGr, rval, HIGIG_MODEf); 470 higig2 = soc_reg_field_get(unit, XPORT_CONFIGr, rval, HIGIG2_MODEf); 471 xpause = soc_reg_field_get(unit, XPORT_CONFIGr, rval, XPAUSE_ENf); 472 pfc = soc_reg_field_get(unit, XPORT_CONFIGr, rval, PFC_ENABLEf); 473 drain = soc_reg_field_get(unit, XPORT_CONFIGr, rval, DRAIN_CONDITION_ENABLEf); 474 llfc = soc_reg_field_get(unit, XPORT_CONFIGr, rval, LLFC_ENf); 475 LOG_CLI((BSL_META_U(unit, "\n\n XPORT CONFIG "))); 476 LOG_CLI((BSL_META_U(unit, "\n HiGig\t\t:\t%s"), enable[higig])); 477 LOG_CLI((BSL_META_U(unit, "\n HiGig2\t\t:\t%s"), enable[higig2])); 478 LOG_CLI((BSL_META_U(unit, "\n XPause\t\t:\t%s"), enable[xpause])); 479 LOG_CLI((BSL_META_U(unit, "\n Priority FC\t:\t%s"), enable[pfc])); 480 LOG_CLI((BSL_META_U(unit, "\n Drain Cndtn\t:\t%s"), enable[drain])); 481 LOG_CLI((BSL_META_U(unit, "\n Link Level FC\t:\t%s\n\n"), enable[llfc])); 482 483 /* XMAC CTRL */ 484 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr(unit, mxq_port, &rval_64)); 485 tx_en = soc_reg64_field32_get(unit, XMAC_CTRLr, rval_64, TX_ENf); 486 rx_en = soc_reg64_field32_get(unit, XMAC_CTRLr, rval_64, RX_ENf); 487 line_lpbk = soc_reg64_field32_get(unit, XMAC_CTRLr, rval_64, LINE_LOCAL_LPBKf); 488 core_lpbk = soc_reg64_field32_get(unit, XMAC_CTRLr, rval_64, CORE_LOCAL_LPBKf); 489 line_rm_lpbk = soc_reg64_field32_get(unit, XMAC_CTRLr, rval_64, LINE_REMOTE_LPBKf); 490 core_rm_lpbk = soc_reg64_field32_get(unit, XMAC_CTRLr, rval_64, CORE_REMOTE_LPBKf); 491 soft_reset = soc_reg64_field32_get(unit, XMAC_CTRLr, rval_64, SOFT_RESETf); 492 rs_soft_reset = soc_reg64_field32_get(unit, XMAC_CTRLr, rval_64, RS_SOFT_RESETf); 493 lpbk_leak = soc_reg64_field32_get(unit, XMAC_CTRLr, rval_64, LOCAL_LPBK_LEAK_ENBf); 494 rm_lpbk_leak = soc_reg64_field32_get(unit, XMAC_CTRLr, rval_64, REMOTE_LPBK_LEAK_ENBf); 495 sw_link = soc_reg64_field32_get(unit, XMAC_CTRLr, rval_64, SW_LINK_STATUSf); 496 link_status_select = soc_reg64_field32_get(unit, XMAC_CTRLr, rval_64, LINK_STATUS_SELECTf); 497 LOG_CLI((BSL_META_U(unit, "\n\n XMAC CTRL"))); 498 LOG_CLI((BSL_META_U(unit, "\n Tx\t \t\t:\t%s"), enable[tx_en])); 499 LOG_CLI((BSL_META_U(unit, "\n Rx \t\t\t:\t%s"), enable[rx_en])); 500 LOG_CLI((BSL_META_U(unit, "\n Soft Reset\t\t:\t%s"),enable[soft_reset])); 501 LOG_CLI((BSL_META_U(unit, "\n RS Soft Reset\t\t:\t%s"), enable[rs_soft_reset])); 502 LOG_CLI((BSL_META_U(unit, "\n Line Lpbk(Local)\t:\t%s"), enable[line_lpbk])); 503 LOG_CLI((BSL_META_U(unit, "\n Core Lpbk(Local)\t:\t%s"), enable[core_lpbk])); 504 LOG_CLI((BSL_META_U(unit, "\n Line Lpbk(Remote)\t:\t%s"), enable[line_rm_lpbk])); 505 LOG_CLI((BSL_META_U(unit, "\n Core Lpbk(Remote)\t:\t%s"), enable[core_rm_lpbk])); 506 LOG_CLI((BSL_META_U(unit, "\n Lpbk Leak(Local)\t:\t%s"), enable[lpbk_leak])); 507 LOG_CLI((BSL_META_U(unit, "\n Lpbk Leak(Remote)\t:\t%s"), enable[rm_lpbk_leak])); 508 LOG_CLI((BSL_META_U(unit, "\n SW Link Status\t\t:\t%s"), active[sw_link])); 509 LOG_CLI((BSL_META_U(unit, "\n Link Status Select\t:\t%s"), link_sel[link_status_select])); 510 511 512 /* XMAC MODE */ 513 SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit, mxq_port, &rval_64)); 514 hdr_mode = soc_reg64_field32_get(unit, XMAC_MODEr, rval_64, HDR_MODEf); 515 sop_crc = soc_reg64_field32_get(unit, XMAC_MODEr, rval_64, NO_SOP_FOR_CRC_HGf); 516 speed_mode = soc_reg64_field32_get(unit, XMAC_MODEr, rval_64, SPEED_MODEf); 517 LOG_CLI((BSL_META_U(unit, "\n\n XMAC MODE"))); 518 LOG_CLI((BSL_META_U(unit, "\n Header Mode\t\t:\t%s"),hdr[hdr_mode])); 519 LOG_CLI((BSL_META_U(unit, "\n SOP for CRC in HG\t:\t%s"), (sop_crc ? "EXCLUDE" : "INCLUDE"))); 520 LOG_CLI((BSL_META_U(unit, "\n Speed Mode\t\t:\t%s"), speed[speed_mode])); 521 522 523 /* EGR ENABLE */ 524 SOC_IF_ERROR_RETURN(READ_EGR_ENABLEm(unit, SOC_BLOCK_ANY, port, &egr_en)); 525 port_enable = soc_EGR_ENABLEm_field32_get(unit, &egr_en, PRT_ENABLEf); 526 LOG_CLI((BSL_META_U(unit, "\n\n EGR ENABLE"))); 527 LOG_CLI((BSL_META_U(unit, "\n Port\t\t:\t%s"),enable[port_enable])); 528 529 530 531 LOG_CLI((BSL_META_U(unit, "\n\n***************************************************************************************\n"))); 532 LOG_CLI((BSL_META_U(unit, " NOTE : You can run the following TR Loopback tests to verify sanity of port\n"))); 533 LOG_CLI((BSL_META_U(unit, " PHY:\n tr 19 pbm=%d\n"),port)); 534 LOG_CLI((BSL_META_U(unit, " MAC:\n tr 18 pbm=%d\n"),port)); 535 LOG_CLI((BSL_META_U(unit, "*******************************************************************************************\n\n"))); 536 LOG_CLI((BSL_META_U(unit, "Basic Port Status :\n\n"))); 537 538 return 0; 539 540 541 } 542 543 int 544 _bcm_kt2_port_lanes_set_post_operation(int unit, bcm_port_t port) 545 { 546 soc_error_t rv = SOC_E_NONE; 547 #if 0 548 uint32 rval = 0; 549 #endif 550 uint8 loop = 0; 551 uint8 mxqblock = 0; 552 uint8 mxqblock_port = 0; 553 int mode = 0; 554 int new_lanes = 0; 555 int speed=0, max_speed=0; 556 int port_enable = 0; 557 egr_enable_entry_t egr_enable_entry = {{0}}; 558 #if 0 559 soc_timeout_t to = {0}; 560 sal_usecs_t timeout_usec = 100000; /* 100ms */ 561 int min_polls = 100; 562 #endif 563 564 sal_memset(&egr_enable_entry, 0, sizeof(egr_enable_entry_t)); 565 soc_mem_field32_set(unit, EGR_ENABLEm, &egr_enable_entry, PRT_ENABLEf, 1); 566 567 SOC_IF_ERROR_RETURN(soc_katana2_get_port_mxqblock( 568 unit,port,&mxqblock)); 569 SOC_IF_ERROR_RETURN(_bcm_kt2_port_lanes_get( 570 unit,port,&new_lanes)); 571 572 #if 0 573 /* Bring-out of Soft-reset relevant MXQPORT(s) */ 574 /* Delay of 100ms */ 575 soc_timeout_init(&to, timeout_usec, min_polls); 576 if(soc_timeout_check(&to)) { 577 LOG_ERROR(BSL_LS_BCM_PORT, 578 (BSL_META_U(unit, 579 "_bcm_kt2_port_lanes_set_post_operation:TimeOut InternalError\n"))); 580 return SOC_E_INTERNAL; 581 } 582 soc_katana2_mxqblock_reset(unit, mxqblock, 1); 583 #endif 584 585 #ifdef BCM_PORT_DEFAULT_DISABLE 586 port_enable = FALSE; 587 #else 588 port_enable = TRUE; 589 #endif /* BCM_PORT_DEFAULT_DISABLE */ 590 591 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 592 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 593 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 594 /* Configuring default settings */ 595 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit,mxqblock_port,port_enable)); 596 BCM_IF_ERROR_RETURN(bcm_esw_port_loopback_set(unit, mxqblock_port, 597 BCM_PORT_LOOPBACK_NONE)); 598 kt2_tdm_update_flag=0; 599 speed = (*mxqspeeds[unit])[mxqblock][new_lanes-1]; 600 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_max(unit, mxqblock_port, 601 &max_speed)); 602 speed = speed > max_speed ? max_speed : speed; 603 rv = bcm_esw_port_speed_set(unit, mxqblock_port , 604 speed); 605 kt2_tdm_update_flag=1; 606 SOC_IF_ERROR_RETURN(rv); 607 SOC_IF_ERROR_RETURN(bcm_esw_linkscan_mode_get( 608 unit, mxqblock_port, &mode)); 609 if (mode == BCM_LINKSCAN_MODE_NONE) { 610 BCM_IF_ERROR_RETURN(bcm_esw_linkscan_mode_set( 611 unit,mxqblock_port,BCM_LINKSCAN_MODE_SW)); 612 } 613 614 BCM_IF_ERROR_RETURN(bcm_esw_port_learn_set(unit, mxqblock_port, 615 BCM_PORT_LEARN_ARL | BCM_PORT_LEARN_FWD)); 616 BCM_IF_ERROR_RETURN(bcm_esw_port_stp_set( 617 unit, mxqblock_port, BCM_STG_STP_FORWARD)); 618 #if 0 619 BCM_IF_ERROR_RETURN(soc_mem_write( 620 unit, EGR_ENABLEm, MEM_BLOCK_ALL, 621 mxqblock_port, &egr_enable_entry)); 622 /* 6. PowerDown MXQBlock/WarpCore */ 623 READ_XPORT_XGXS_CTRLr(unit, mxqblock_port,&rval); 624 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, 625 PWRDWNf,0); 626 WRITE_XPORT_XGXS_CTRLr(unit, mxqblock_port,rval); 627 #endif 628 } 629 } 630 return SOC_E_NONE; 631 } 632 static 633 void soc_katana2_pbmp_one_resync(int unit,soc_ptype_t *ptype) 634 { 635 soc_port_t it_port = 0 ; 636 637 ptype->num = 0; \ 638 ptype->min = ptype->max = -1; 639 640 PBMP_ITER(ptype->bitmap, it_port) { 641 ptype->port[ptype->num++] = it_port; 642 if (ptype->min < 0) { \ 643 ptype->min = it_port; 644 } 645 if (it_port > ptype->max) { 646 ptype->max = it_port; 647 } 648 } 649 } 650 651 void soc_katana2_pbmp_all_resync(int unit) 652 { 653 soc_info_t *si = &SOC_INFO(unit); 654 soc_katana2_pbmp_one_resync(unit,&si->xe); 655 soc_katana2_pbmp_one_resync(unit,&si->ether); 656 soc_katana2_pbmp_one_resync(unit,&si->mxq); 657 soc_katana2_pbmp_one_resync(unit,&si->port); 658 soc_katana2_pbmp_one_resync(unit,&si->all); 659 soc_katana2_pbmp_one_resync(unit,&si->ge); 660 soc_katana2_pbmp_one_resync(unit,&si->hg); 661 soc_katana2_pbmp_one_resync(unit,&si->st); 662 } 663 664 void soc_katana2_pbmp_remove(int unit,soc_port_t port) 665 { 666 int blk = 0; 667 soc_info_t *si = &SOC_INFO(unit); 668 669 blk = SOC_DRIVER(unit)->port_info[port].blk; 670 SOC_PBMP_PORT_REMOVE(si->block_bitmap[blk],port); 671 672 SOC_PBMP_PORT_REMOVE(si->xe.bitmap, port); 673 SOC_PBMP_PORT_ADD(si->xe.disabled_bitmap, port); 674 675 SOC_PBMP_PORT_REMOVE(si->ether.bitmap, port); 676 SOC_PBMP_PORT_ADD(si->ether.disabled_bitmap, port); 677 678 SOC_PBMP_PORT_REMOVE(si->mxq.bitmap, port); 679 SOC_PBMP_PORT_ADD(si->mxq.disabled_bitmap, port); 680 681 SOC_PBMP_PORT_REMOVE(si->port.bitmap, port); 682 SOC_PBMP_PORT_ADD(si->port.disabled_bitmap, port); 683 684 SOC_PBMP_PORT_REMOVE(si->all.bitmap, port); 685 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port); 686 687 SOC_PBMP_PORT_REMOVE(si->ge.bitmap, port); 688 SOC_PBMP_PORT_ADD(si->ge.disabled_bitmap, port); 689 690 SOC_PBMP_PORT_REMOVE(si->hg.bitmap, port); 691 SOC_PBMP_PORT_ADD(si->hg.disabled_bitmap, port); 692 693 SOC_PBMP_PORT_REMOVE(si->st.bitmap, port); 694 SOC_PBMP_PORT_ADD(si->st.disabled_bitmap, port); 695 696 } 697 static 698 void soc_katana2_pbmp_add(int unit,soc_port_t port,int mxqblock,int speed) { 699 int blk=0; 700 soc_info_t *si = &SOC_INFO(unit); 701 soc_pbmp_t my_pbmp_xport_xe; 702 703 blk = SOC_DRIVER(unit)->port_info[port].blk; 704 SOC_PBMP_PORT_ADD(si->block_bitmap[blk],port); 705 706 707 if ((mxqblock >=0) && (mxqblock <= 5)) { 708 if (speed == 10000) { 709 SOC_PBMP_PORT_ADD(si->xe.bitmap, port); 710 SOC_PBMP_PORT_REMOVE(si->xe.disabled_bitmap, port); 711 } else { 712 SOC_PBMP_PORT_ADD(si->ge.bitmap, port); 713 SOC_PBMP_PORT_REMOVE(si->ge.disabled_bitmap, port); 714 } 715 SOC_PBMP_PORT_ADD(si->ether.bitmap, port); 716 SOC_PBMP_PORT_REMOVE(si->ether.disabled_bitmap, port); 717 718 SOC_PBMP_PORT_ADD(si->mxq.bitmap, port); 719 SOC_PBMP_PORT_REMOVE(si->mxq.disabled_bitmap, port); 720 721 SOC_PBMP_PORT_ADD(si->port.bitmap, port); 722 SOC_PBMP_PORT_REMOVE(si->port.disabled_bitmap, port); 723 724 SOC_PBMP_PORT_ADD(si->all.bitmap, port); 725 SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, port); 726 } 727 if ((mxqblock >=6) && (mxqblock <= 9)) { 728 SOC_PBMP_CLEAR(my_pbmp_xport_xe); 729 my_pbmp_xport_xe = soc_property_get_pbmp_default(unit, 730 spn_PBMP_XPORT_XE, 731 my_pbmp_xport_xe); 732 if (speed >= 13000) { 733 if (SOC_PBMP_MEMBER(my_pbmp_xport_xe, port)) { 734 SOC_PBMP_PORT_ADD(si->xe.bitmap, port); 735 SOC_PBMP_PORT_REMOVE(si->xe.disabled_bitmap, port); 736 } else { 737 SOC_PBMP_PORT_ADD(si->hg.bitmap, port); 738 SOC_PBMP_PORT_ADD(si->st.bitmap, port); 739 SOC_PBMP_PORT_REMOVE(si->hg.disabled_bitmap, port); 740 SOC_PBMP_PORT_REMOVE(si->st.disabled_bitmap, port); 741 } 742 } else if (speed == 10000) { 743 SOC_PBMP_PORT_ADD(si->xe.bitmap, port); 744 SOC_PBMP_PORT_REMOVE(si->xe.disabled_bitmap, port); 745 } else { 746 SOC_PBMP_PORT_ADD(si->ge.bitmap, port); 747 SOC_PBMP_PORT_REMOVE(si->ge.disabled_bitmap, port); 748 } 749 SOC_PBMP_PORT_ADD(si->ether.bitmap, port); 750 SOC_PBMP_PORT_REMOVE(si->ether.disabled_bitmap, port); 751 752 SOC_PBMP_PORT_ADD(si->mxq.bitmap, port); 753 SOC_PBMP_PORT_REMOVE(si->mxq.disabled_bitmap, port); 754 755 SOC_PBMP_PORT_ADD(si->port.bitmap, port); 756 SOC_PBMP_PORT_REMOVE(si->port.disabled_bitmap, port); 757 SOC_PBMP_PORT_ADD(si->all.bitmap, port); 758 SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, port); 759 } 760 SOC_PORT_TYPE(unit,port)=SOC_BLK_MXQPORT; 761 si->port_speed_max[port] = speed; 762 if (port == KT2_OLP_PORT) { 763 if (SOC_DRIVER(unit)->port_info[KT2_OLP_PORT].bindex != 3) { 764 SOC_DRIVER(unit)->port_info[KT2_OLP_PORT].bindex = 3; 765 SOC_DRIVER(unit)->port_info[KT2_OLP_PORT].blk = SOC_DRIVER(unit)->port_info[26].blk; 766 } 767 } 768 } 769 770 static 771 soc_error_t soc_katana2_port_attach( 772 int unit,uint8 mxqblock ,uint8 mxqblock_port) 773 { 774 uint16 phy_addr=0; 775 uint16 phy_addr_int=0; 776 int okay; 777 bcm_error_t rv = SOC_E_NONE; 778 779 soc_linkscan_pause(unit); 780 _katana2_phy_addr_default(unit, mxqblock_port, 781 &phy_addr, &phy_addr_int); 782 SOC_IF_ERROR_RETURN 783 (soc_phy_cfg_addr_set(unit,mxqblock_port,0, phy_addr)); 784 SOC_IF_ERROR_RETURN 785 (soc_phy_cfg_addr_set(unit,mxqblock_port,SOC_PHY_INTERNAL, 786 phy_addr_int)); 787 PHY_ADDR(unit, mxqblock_port) = phy_addr; 788 PHY_ADDR_INT(unit, mxqblock_port) = phy_addr_int; 789 SOC_IF_ERROR_RETURN(_bcm_port_probe(unit, mxqblock_port, &okay)); 790 if (!okay) { 791 soc_linkscan_continue(unit); 792 return SOC_E_INTERNAL; 793 } 794 SOC_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, mxqblock_port, FALSE)); 795 if (IS_HG_PORT(unit, mxqblock_port)) { 796 bcm_esw_port_encap_set(unit,mxqblock_port,BCM_PORT_ENCAP_HIGIG); 797 /* Set the settings specific to HiGig port. 798 * update_port_mode is set to FALSE since port mode update was 799 * already done as part of flex port sequence. Also, port mode 800 * should be updated only when mxqblock is in hard reset(XMAC_RESET=1) 801 * or else we would be having issue in cell count requests in EP. 802 */ 803 _bcm_port_encap_xport_set(unit,mxqblock_port,BCM_PORT_ENCAP_HIGIG, 804 FALSE); 805 } else { 806 bcm_esw_port_encap_set(unit,mxqblock_port,BCM_PORT_ENCAP_IEEE); 807 /* Set the settings specific to HiGig port. 808 * update_port_mode is set to FALSE since port mode update was 809 * already done as part of flex port sequence. Also, port mode 810 * should be updated only when mxqblock is in hard reset(XMAC_RESET=1) 811 * or else we would be having issue in cell count requests in EP. 812 */ 813 _bcm_port_encap_xport_set(unit,mxqblock_port,BCM_PORT_ENCAP_IEEE, 814 FALSE); 815 } 816 rv = bcm_esw_port_enable_set(unit,mxqblock_port,1); 817 if (BCM_FAILURE(rv)) { 818 LOG_ERROR(BSL_LS_BCM_PORT, 819 (BSL_META_U(unit, 820 "Port enable set failed for port[%d]\n"), mxqblock_port)); 821 } 822 rv = _soc_linkscan_hw_port_init(unit, mxqblock_port); 823 soc_linkscan_continue(unit); 824 return rv; 825 } 826 static 827 soc_error_t soc_katana2_port_detach(int unit,uint8 mxqblock_port) 828 { 829 bcm_error_t rv = SOC_E_NONE; 830 831 soc_linkscan_pause(unit); 832 /* Enabling port before detaching as Flex-IO Unicore GE ports when 833 * disabled, not being reset when combined back to XE. This was causing 834 * Link up issues at the SERDES level */ 835 SOC_IF_ERROR_RETURN(soc_phyctrl_enable_set(unit, mxqblock_port, 1)); 836 SOC_IF_ERROR_RETURN(soc_phyctrl_detach(unit, mxqblock_port)); 837 PHY_FLAGS_CLR_ALL(unit, mxqblock_port); 838 839 if (SOC_PBMP_MEMBER(PBMP_PORT_ALL(unit), mxqblock_port)) { 840 rv = bcm_esw_port_enable_set(unit,mxqblock_port,0); 841 if (BCM_FAILURE(rv)) { 842 LOG_ERROR(BSL_LS_BCM_PORT, 843 (BSL_META_U(unit, 844 "Port enable set failed for port[%d]\n"), 845 mxqblock_port)); 846 } 847 } 848 soc_linkscan_continue(unit); 849 return rv; 850 } 851 int _bcm_kt2_update_port_mode(int unit,uint8 port,int speed) 852 { 853 uint32 rval = 0; 854 uint32 phy_mode = 0; 855 uint32 core_mode = 0; 856 uint32 wc_10g_21g_sel = 0; 857 uint8 mxqblock = 0; 858 bcmMxqConnection_t connection_mode; 859 860 SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &rval)); 861 SOC_IF_ERROR_RETURN(soc_katana2_get_phy_port_mode( 862 unit, port, speed, &phy_mode)); 863 SOC_IF_ERROR_RETURN(soc_katana2_get_core_port_mode( 864 unit, port, &core_mode)); 865 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, CORE_PORT_MODEf, core_mode); 866 SOC_IF_ERROR_RETURN(soc_katana2_get_port_mxqblock( unit,port,&mxqblock)); 867 if ((mxqblock == 8) || (mxqblock == 9)) { 868 if ((speed == 10000) || (speed == 21000)) { 869 wc_10g_21g_sel = 1; 870 } 871 } 872 if ((mxqblock == 6) || (mxqblock == 7)) { 873 if (speed == 10000) { 874 SOC_IF_ERROR_RETURN(soc_katana2_get_phy_connection_mode( 875 unit,port, mxqblock,&connection_mode)); 876 /* XFI Mode */ 877 if (connection_mode == bcmMqxConnectionWarpCore) { 878 wc_10g_21g_sel = 1; 879 } 880 } 881 } 882 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, 883 WC_10G_21G_SELf, wc_10g_21g_sel); 884 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, PHY_PORT_MODEf, phy_mode); 885 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, 886 PORT_GMII_MII_ENABLEf, (speed >= 10000) ? 0 : 1); 887 /* WORK AROUND: KATANA2-1698 888 RTL PORT: Hotswap from quad port mode to dual port mode fails 889 occasionally. */ 890 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, CORE_PORT_MODEf, 891 bcmMxqCorePortModeSingle); 892 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, rval)); 893 sal_udelay(100); 894 895 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, CORE_PORT_MODEf, 896 core_mode); 897 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, rval)); 898 return BCM_E_NONE; 899 } 900 901 int __bcm_kt2_port_lanes_set(int unit, bcm_port_t port, int lanes) 902 { 903 uint64 xmac_ctrl; 904 uint32 port_enable=0; 905 int length_check = 0; 906 epc_link_bmap_entry_t epc_link_bmap_entry={{0}}; 907 txlp_port_addr_map_table_entry_t txlp_port_addr_map_table_entry={{0}}; 908 soc_field_t port_enable_field[KT2_MAX_MXQPORTS_PER_BLOCK]= 909 {PORT0f, PORT1f, PORT2f , PORT3f}; 910 911 uint32 start_addr=0; 912 uint32 end_addr=0; 913 soc_pbmp_t link_pbmp; 914 /* uint32 flush_reg=0; */ 915 uint32 time_multiplier=1; 916 uint64 rval64 ; 917 uint32 rval = 0; 918 uint32 rval1 = 0; 919 uint32 rval2 = 0; 920 egr_enable_entry_t egr_enable_entry = {{0}}; 921 uint32 cell_cnt = 0; 922 uint32 try = 0; 923 uint32 try_count = 0; 924 soc_timeout_t to = {0}; 925 sal_usecs_t timeout_usec = 100000; 926 int min_polls = 100; 927 uint32 pfc_enable=0; 928 int pfc_index=0; 929 uint8 old_ports[][KT2_MAX_MXQPORTS_PER_BLOCK]= 930 {{1,0,0,0},{1,0,3,0},{0,0,0,0},{1,2,3,4}}; 931 uint8 new_ports[][KT2_MAX_MXQPORTS_PER_BLOCK]= 932 {{1,0,0,0},{1,0,3,0},{0,0,0,0},{1,2,3,4}}; 933 uint8 new_port_mode[5]={0,1,2,0,3}; 934 uint32 top_misc_control_1_val = 0; 935 soc_field_t wc_xfi_mode_sel_fld[] = 936 {WC0_8_XFI_MODE_SELf,WC1_8_XFI_MODE_SELf}; 937 soc_info_t *si = &SOC_INFO(unit); 938 uint8 mxqblock = 0; 939 uint8 mxqblock_port = 0; 940 uint8 try_loop = 0; 941 uint8 loop = 0; 942 int old_lanes = 0; 943 int new_lanes = lanes; 944 uint8 xfi_mode[2] = {0,0}; 945 /* uint8 old_xfi_mode[2] = {0,0}; */ 946 soc_field_t port_intf_reset_fld[] = { 947 XQ0_PORT_INTF_RESETf, XQ1_PORT_INTF_RESETf, 948 XQ2_PORT_INTF_RESETf, XQ3_PORT_INTF_RESETf, 949 XQ4_PORT_INTF_RESETf, XQ5_PORT_INTF_RESETf, 950 XQ6_PORT_INTF_RESETf, XQ7_PORT_INTF_RESETf}; 951 soc_field_t mmu_intf_reset_fld[] = { 952 XQ0_MMU_INTF_RESETf, XQ1_MMU_INTF_RESETf, 953 XQ2_MMU_INTF_RESETf, XQ3_MMU_INTF_RESETf, 954 XQ4_MMU_INTF_RESETf, XQ5_MMU_INTF_RESETf, 955 XQ6_MMU_INTF_RESETf, XQ7_MMU_INTF_RESETf}; 956 soc_field_t new_port_mode_fld[] = { 957 XQ0_NEW_PORT_MODEf, XQ1_NEW_PORT_MODEf, 958 XQ2_NEW_PORT_MODEf, XQ3_NEW_PORT_MODEf, 959 XQ4_NEW_PORT_MODEf, XQ5_NEW_PORT_MODEf, 960 XQ6_NEW_PORT_MODEf, XQ7_NEW_PORT_MODEf}; 961 uint8 required_tdm_slots = 0; 962 uint8 available_tdm_slots = 0; 963 uint8 speed_index = 0; 964 uint8 speed_value = 0; 965 int port_speed = 0; 966 uint8 tdm_ports[4] = {0}; 967 uint8 index = 0; 968 uint32 pos = 0; 969 uint32 egr_fifo_depth = 0; 970 /* int cfg_num = 0; */ 971 int mxqblock_max_nxtaddr; 972 int init_mode = 0; 973 int threshold, padding = 0; 974 int blk = 0; 975 976 if (!SOC_PORT_VALID(unit, port)) { 977 return BCM_E_PORT; 978 } 979 if (SAL_BOOT_QUICKTURN) { 980 time_multiplier=1000; 981 } 982 983 if ((new_lanes != 1) && (new_lanes != 2) && (new_lanes != 4)) { 984 return BCM_E_PARAM; 985 } 986 987 /* cfg_num = soc_property_get(unit, spn_BCM5645X_CONFIG, 0); */ 988 989 if (SOC_PORT_TYPE(unit,port) != SOC_BLK_MXQPORT) { 990 return SOC_E_CONFIG; 991 } 992 SOC_IF_ERROR_RETURN(soc_katana2_get_port_mxqblock( 993 unit,port,&mxqblock)); 994 SOC_IF_ERROR_RETURN(_bcm_kt2_port_lanes_get( 995 unit,port,&old_lanes)); 996 if(old_lanes == new_lanes) { 997 LOG_CLI((BSL_META_U(unit, "Port is already in %d lane mode \n "), 998 old_lanes)); 999 return SOC_E_NONE; 1000 } 1001 1002 if ((mxqblock == 8) || (mxqblock == 9)) { 1003 if (soc_mem_config_set == NULL) { 1004 LOG_CLI((BSL_META_U(unit, 1005 "ATTN:Auto PortGroup Config setting not possible \n"))); 1006 } 1007 } 1008 if (SOC_INFO(unit).olp_port[0]) { 1009 if (port == KT2_OLP_PORT) { 1010 LOG_CLI((BSL_META_U(unit, 1011 "HotSwap is not supported for OLP port \n"))); 1012 return BCM_E_PARAM; 1013 } 1014 } 1015 if (mxqblock == 7 ) { 1016 if (SOC_INFO(unit).olp_port[0]) { 1017 LOG_CLI((BSL_META_U(unit, 1018 "OLP port is being used so cannot hotswap on MXQ7\n"))); 1019 return BCM_E_PARAM; 1020 } 1021 } 1022 if ((mxqblock==8) || (mxqblock==9)) { 1023 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1024 if (IS_LP_PORT(unit, (*kt2_mxqblock_ports[unit])[mxqblock][loop])) { 1025 LOG_CLI((BSL_META_U(unit, 1026 "HotSwap is not supported for LinkPhy Ports\n"))); 1027 return BCM_E_PARAM; 1028 } 1029 } 1030 } 1031 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1032 if (IS_SUBTAG_PORT(unit, (*kt2_mxqblock_ports[unit])[mxqblock][loop])) { 1033 LOG_CLI((BSL_META_U(unit, 1034 "HotSwap is not supported for SubTag/COE Ports\n"))); 1035 return BCM_E_PARAM; 1036 } 1037 } 1038 if ((mxqblock >= 6 ) && (mxqblock <= 9)) { 1039 SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROL_1r( 1040 unit,&top_misc_control_1_val)); 1041 if ((mxqblock == 6) || (mxqblock == 8)) { 1042 xfi_mode[0]= soc_reg_field_get(unit, TOP_MISC_CONTROL_1r, 1043 top_misc_control_1_val, 1044 wc_xfi_mode_sel_fld[0]); 1045 } 1046 if (xfi_mode[0]) { 1047 LOG_CLI((BSL_META_U(unit, 1048 "XFI Mode enabled. Hot Swapping not possible \n"))); 1049 return SOC_E_UNAVAIL; 1050 } 1051 if ((mxqblock == 7) || (mxqblock == 9)) { 1052 xfi_mode[1]= soc_reg_field_get(unit, TOP_MISC_CONTROL_1r, 1053 top_misc_control_1_val, 1054 wc_xfi_mode_sel_fld[1]); 1055 } 1056 if (xfi_mode[1]) { 1057 LOG_CLI((BSL_META_U(unit, 1058 "XFI Mode enabled. Hot Swapping not possible \n"))); 1059 return SOC_E_UNAVAIL; 1060 } 1061 } 1062 1063 /* 1064 if ((new_lanes==4)&& ((mxqblock==8) || (mxqblock==9))) { 1065 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1066 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), 1067 (*kt2_mxqblock_ports[unit])[mxqblock-2][loop])) { 1068 LOG_CLI((BSL_META_U(unit, 1069 "MXQBlock%d being used so" 1070 " WC cannot be used in XFI mode \n"),mxqblock-2)); 1071 return SOC_E_CONFIG; 1072 } 1073 } 1074 xfi_mode[mxqblock-8]=1; 1075 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1076 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), 1077 (*kt2_mxqblock_ports[unit])[mxqblock][loop])) { 1078 if (!SOC_PBMP_MEMBER((PBMP_XE_ALL(unit)), 1079 (*kt2_mxqblock_ports[unit])[mxqblock][loop])) { 1080 xfi_mode[mxqblock-8]=0; 1081 break; 1082 } 1083 } 1084 } 1085 if (xfi_mode[mxqblock-8] == 1) { 1086 LOG_CLI((BSL_META_U(unit, 1087 "NEW XFI MODE ON \n"))); 1088 } 1089 } 1090 if ((mxqblock==8) || (mxqblock==9)) { 1091 old_xfi_mode[mxqblock-8]=1; 1092 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1093 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), 1094 (*kt2_mxqblock_ports[unit])[mxqblock][loop])) { 1095 if (!SOC_PBMP_MEMBER((PBMP_XE_ALL(unit)), 1096 (*kt2_mxqblock_ports[unit])[mxqblock][loop])) { 1097 old_xfi_mode[mxqblock-8]=0; 1098 break; 1099 } 1100 } 1101 } 1102 if (old_xfi_mode[mxqblock-8] == 1) { 1103 LOG_CLI((BSL_META_U(unit, 1104 "OLD XFI MODE ON \n"))); 1105 } 1106 } 1107 */ 1108 switch((*mxqspeeds[unit])[mxqblock][new_lanes-1]) { 1109 case 1000: speed_index=0;break; 1110 case 2500: speed_index=2;break; 1111 case 10000: speed_index=3;break; 1112 case 13000: speed_index=4;break; 1113 case 20000: 1114 case 21000: speed_index=6;break; 1115 default: return SOC_E_CONFIG; 1116 } 1117 required_tdm_slots = kt2_current_tdm_cycles_info[speed_index]. 1118 min_tdm_cycles * new_lanes; 1119 available_tdm_slots = kt2_tdm_pos_info[mxqblock].total_slots; 1120 /* 1121 if (((mxqblock==8) || (mxqblock==9)) && (xfi_mode[mxqblock-8]==1)) { 1122 available_tdm_slots += kt2_tdm_pos_info[mxqblock-2].total_slots; 1123 } 1124 */ 1125 if (required_tdm_slots > available_tdm_slots) { 1126 LOG_CLI((BSL_META_U(unit, 1127 "TDM feasibility failed required_tdm_slots:%d >" 1128 "available_tdm_slots:%d \n"), required_tdm_slots, 1129 available_tdm_slots)); 1130 return SOC_E_CONFIG; 1131 } 1132 if (new_lanes == 1) { 1133 /* 1134 if (((mxqblock==8) || (mxqblock==9)) && (old_xfi_mode[mxqblock-8]==1)) { 1135 tdm_ports[0]=(*kt2_mxqblock_ports[unit])[mxqblock][0]; 1136 tdm_ports[1]=KT2_IDLE; 1137 tdm_ports[2]=(*kt2_mxqblock_ports[unit])[mxqblock][0]; 1138 tdm_ports[3]=KT2_IDLE; 1139 } else */ { 1140 tdm_ports[0]=(*kt2_mxqblock_ports[unit])[mxqblock][0]; 1141 tdm_ports[1]=(*kt2_mxqblock_ports[unit])[mxqblock][0]; 1142 tdm_ports[2]=(*kt2_mxqblock_ports[unit])[mxqblock][0]; 1143 tdm_ports[3]=(*kt2_mxqblock_ports[unit])[mxqblock][0]; 1144 } 1145 } 1146 if (new_lanes == 2) { 1147 /* 1148 if (((mxqblock==8) || (mxqblock==9)) && (old_xfi_mode[mxqblock-8]==1)) { 1149 tdm_ports[0]=(*kt2_mxqblock_ports[unit])[mxqblock][0]; 1150 tdm_ports[1]=(*kt2_mxqblock_ports[unit])[mxqblock][2]; 1151 tdm_ports[2]=(*kt2_mxqblock_ports[unit])[mxqblock][0]; 1152 tdm_ports[3]=(*kt2_mxqblock_ports[unit])[mxqblock][2]; 1153 } else */ { 1154 tdm_ports[0]=(*kt2_mxqblock_ports[unit])[mxqblock][0]; 1155 tdm_ports[1]=(*kt2_mxqblock_ports[unit])[mxqblock][2]; 1156 tdm_ports[2]=(*kt2_mxqblock_ports[unit])[mxqblock][0]; 1157 tdm_ports[3]=(*kt2_mxqblock_ports[unit])[mxqblock][2]; 1158 } 1159 } 1160 if (new_lanes == 4) { 1161 /* 1162 if (((mxqblock==8) || (mxqblock==9)) && (xfi_mode[mxqblock-8]==1)) { 1163 tdm_ports[0]=(*kt2_mxqblock_ports[unit])[mxqblock-2][0]; 1164 tdm_ports[1]=(*kt2_mxqblock_ports[unit])[mxqblock-2][2]; 1165 tdm_ports[2]=(*kt2_mxqblock_ports[unit])[mxqblock][0]; 1166 tdm_ports[3]=(*kt2_mxqblock_ports[unit])[mxqblock][2]; 1167 } else */ { 1168 tdm_ports[0]=(*kt2_mxqblock_ports[unit])[mxqblock][0]; 1169 tdm_ports[1]=(*kt2_mxqblock_ports[unit])[mxqblock][1]; 1170 tdm_ports[2]=(*kt2_mxqblock_ports[unit])[mxqblock][2]; 1171 tdm_ports[3]=(*kt2_mxqblock_ports[unit])[mxqblock][3]; 1172 } 1173 } 1174 sal_memcpy(&new_tdm[0],&kt2_current_tdm[0], 1175 kt2_current_tdm_size *sizeof(kt2_current_tdm[0])); 1176 /* 1177 if (((mxqblock==8) || (mxqblock==9)) && (xfi_mode[mxqblock-8]==1)) { 1178 index=0; 1179 for (loop=0; loop < kt2_tdm_pos_info[mxqblock-2].total_slots; loop++) { 1180 pos = kt2_tdm_pos_info[mxqblock-2].pos[loop]; 1181 new_tdm[pos]=tdm_ports[index]; 1182 index = (index + 1) %2; 1183 } 1184 for (loop=0; loop < kt2_tdm_pos_info[mxqblock].total_slots; loop++) { 1185 pos = kt2_tdm_pos_info[mxqblock].pos[loop]; 1186 new_tdm[pos]=tdm_ports[index+2]; 1187 index = (index + 1) %2; 1188 } 1189 1190 } else */ { 1191 for (index=0,loop=0; loop < kt2_tdm_pos_info[mxqblock].total_slots; loop++) { 1192 pos = kt2_tdm_pos_info[mxqblock].pos[loop]; 1193 new_tdm[pos]=tdm_ports[index]; 1194 index = (index + 1) % 4 ; 1195 } 1196 } 1197 /* 1198 if (((mxqblock==8) || (mxqblock==9)) && (old_xfi_mode[mxqblock-8]==1)) { 1199 for (loop=0;loop < kt2_tdm_pos_info[mxqblock-2].total_slots; loop++) { 1200 pos = kt2_tdm_pos_info[mxqblock-2].pos[loop]; 1201 new_tdm[pos]=KT2_IDLE; 1202 } 1203 } 1204 if (((mxqblock==8) || (mxqblock==9)) && (xfi_mode[mxqblock-8]==1)) { 1205 index=0; 1206 for (loop=0; loop < kt2_tdm_pos_info[mxqblock-2].total_slots; loop++) { 1207 pos = kt2_tdm_pos_info[mxqblock-2].pos[loop]; 1208 new_tdm[pos]= (*kt2_mxqblock_ports[unit])[mxqblock-2][index]; 1209 index = (index + 2) %4; 1210 } 1211 } 1212 */ 1213 /* 1214 kt2_tdm_display(new_tdm,kt2_current_tdm_size, 1215 bcm56450_tdm_info[cfg_num].row, 1216 bcm56450_tdm_info[cfg_num].col); 1217 */ 1218 1219 /* Stop Counter Thread for time-being */ 1220 /* SOC_IF_ERROR_RETURN(soc_counter_stop(unit)); */ 1221 1222 sal_memset(&egr_enable_entry, 0, sizeof(egr_enable_entry_t)); 1223 soc_mem_field32_set(unit, EGR_ENABLEm, &egr_enable_entry, PRT_ENABLEf, 0); 1224 BCM_IF_ERROR_RETURN(bcm_esw_linkscan_mode_get(unit, port, &init_mode)); 1225 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1226 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1227 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1228 /* 1. START: Stop LinkScanning for ports on which flex operation 1229 * will be performed. This has to be done before performing MMU 1230 * Queue flush on each flex port to avoid incorrect updation 1231 * of EPC_LINK_BMAP during PHY-MAC sync that happens during link 1232 * scan mode set */ 1233 bcm_esw_kt2_port_unlock(unit); 1234 BCM_IF_ERROR_RETURN(bcm_esw_linkscan_mode_set( 1235 unit, mxqblock_port, BCM_LINKSCAN_MODE_NONE)); 1236 bcm_esw_kt2_port_lock(unit); 1237 } 1238 } 1239 1240 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1241 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1242 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1243 /* 2. To stop the incoming traffic, disables XMAC in ingress(Rx) 1244 direction. This can be done by disabling RxEn bit in 1245 XMAC_Ctrl register in MAC XMAC_Ctrl.<old_port>.RxEn= 0 */ 1246 1247 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr( 1248 unit, mxqblock_port, &xmac_ctrl)); 1249 soc_reg64_field32_set(unit, XMAC_CTRLr, &xmac_ctrl, TX_ENf, 1); 1250 soc_reg64_field32_set(unit, XMAC_CTRLr, &xmac_ctrl, RX_ENf, 0); 1251 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr( 1252 unit, mxqblock_port, xmac_ctrl)); 1253 sal_udelay((10*time_multiplier)); 1254 /* After disabling XMAC receive path, reset the MAC logic by 1255 * setting SOFT_RESET=1 in XMAC_CTRL 1256 * Without the XMAC soft reset only setting XMAC RXEn =0 1257 * is not taking effect as port flush timeout is seen 1258 * for bidirectional traffic, when all ports in same block 1259 * are transmitting and receiving. 1260 * XMAC disable follows this sequence during MAC disable 1261 */ 1262 1263 soc_reg64_field32_set(unit, XMAC_CTRLr, &xmac_ctrl, 1264 SOFT_RESETf, 1); 1265 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr( 1266 unit, mxqblock_port, xmac_ctrl)); 1267 sal_udelay((10*time_multiplier)); 1268 1269 1270 /* 3. Brings the port down. This is done by programming 1271 EPC_LINK_BMAP[x] = 0; (x: port number) 1272 1273 This register resides in Sw2 block of ingress pipeline, by 1274 disabling this bit software will block all the new packets 1275 pertaining to this port from entering MMU except for packets 1276 utilizing the extended queueing mechanism which may still 1277 be passed to the MMU. 1278 1279 Reset appropriate EPC_LINK_BMAP:PORT_BITMAP */ 1280 1281 BCM_IF_ERROR_RETURN(READ_EPC_LINK_BMAPm( 1282 unit, MEM_BLOCK_ANY, 0, &epc_link_bmap_entry)); 1283 soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, 1284 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 1285 BCM_PBMP_PORT_REMOVE(link_pbmp,mxqblock_port); 1286 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, 1287 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 1288 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm( 1289 unit, MEM_BLOCK_ALL, 0, &epc_link_bmap_entry)); 1290 1291 /* -------------------------------------------------------------------------- */ 1292 /* PortFlushing creating some issue with L0 node movement so moving to Q Flush*/ 1293 /* -------------------------------------------------------------------------- */ 1294 #ifdef PORT_FLUSH_DEBUG 1295 /* 4. Issues MMU port flush command 1296 Software issues MMU port flush command (up to 4 ports can be 1297 flushed in one command). MMU will drop any further enqueue 1298 requests for queues within this port and will indicate port 1299 flush command complete when all ports specified in the command 1300 have drained all their packets from the MMU */ 1301 1302 BCM_IF_ERROR_RETURN(READ_TOQ_FLUSH0r(unit, &flush_reg)); 1303 soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, 1304 FLUSH_ACTIVEf,1); 1305 /* PORT FLUSHING not QUEUE FLUSHING */ 1306 soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, FLUSH_TYPEf,1); 1307 soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, FLUSH_NUMf,1); 1308 soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, FLUSH_EXTERNALf, 1309 (IS_EXT_MEM_PORT(unit, mxqblock_port) ? 1 : 0)); 1310 soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, 1311 FLUSH_ID0f, mxqblock_port); 1312 BCM_IF_ERROR_RETURN(WRITE_TOQ_FLUSH0r(unit, flush_reg)); 1313 #endif 1314 1315 1316 /* 5. Saves the current configuration of PAUSE/PFC flow control 1317 Then disables the PFC flow control to ensure all pending 1318 packets can flow through MMU. 1319 This can be done by programming the following register in 1320 MMU for the relevant port: 1321 XPORT_TO_MMU_BKP.PRI15_0_BKP = 16d0; */ 1322 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get( 1323 unit, mxqblock_port, &port_speed)); 1324 if (port_speed >= 10000) { 1325 if ((mxqblock >= 6) && (mxqblock <= 9)) { 1326 switch(mxqblock_port) { 1327 case 25: pfc_index=6;break; 1328 case 36: pfc_index=7;break; 1329 case 26: pfc_index=8;break; 1330 case 39: pfc_index=9;break; 1331 case 27: pfc_index=10;break; 1332 case 33: pfc_index=11;break; 1333 case 28: pfc_index=12;break; 1334 case 30: pfc_index=13;break; 1335 default: return BCM_E_INTERNAL; 1336 } 1337 } else { 1338 pfc_index=mxqblock; 1339 } 1340 BCM_IF_ERROR_RETURN(READ_XPORT_TO_MMU_BKPr( 1341 unit, pfc_index, &pfc_enable)); 1342 BCM_IF_ERROR_RETURN(WRITE_XPORT_TO_MMU_BKPr( 1343 unit, pfc_index, 0)); 1344 } 1345 1346 /* 6. flushes any pending egress packets in MXQPORT, in this 1347 scenario MMU sends out the packets but they are dropped in 1348 the MXQPORT, hence the packets are drained out of MMU but 1349 are not sent out of the chip. This is done by programming 1350 the following: XP_TXFIFO_PKT_DROP_CTL.DROP_EN = 1b1; */ 1351 1352 READ_XP_TXFIFO_PKT_DROP_CTLr(unit, mxqblock_port,&rval); 1353 soc_reg_field_set(unit, XP_TXFIFO_PKT_DROP_CTLr, &rval, 1354 DROP_ENf,1); 1355 WRITE_XP_TXFIFO_PKT_DROP_CTLr(unit, mxqblock_port,rval); 1356 1357 #ifndef PORT_FLUSH_DEBUG 1358 /* Drain cells in mmu/port before cells entering TX FIFO */ 1359 SOC_IF_ERROR_RETURN(soc_mmu_flush_enable(unit, mxqblock_port, TRUE)); 1360 1361 #endif 1362 1363 /* ------------------------------------------------- */ 1364 /* No more PortFlushing so Confirmation not required */ 1365 /* ------------------------------------------------- */ 1366 #ifdef PORT_FLUSH_DEBUG 1367 1368 /* 7. Waits until all egress port packets are drained. 1369 This is done by making sure MMU is empty for cells destined 1370 for this port and MXQPORT FIFO is empty and no packets are 1371 being sent to MAC. This is done by checking the following 1372 i. MMU Port Flush command has completed by polling 1373 TOQ_FLUSH0.flush_active == 0 1374 ii.XP_TXFIFO_CELL_CNT.CELL_CNT == 0 1375 1376 SW will have to poll for cell_cnt to be 0 for a few hundred 1377 clocks prior to concluding port TX flush completion */ 1378 1379 try_count=0; 1380 if (SAL_BOOT_SIMULATION) { 1381 BCM_IF_ERROR_RETURN(READ_TOQ_FLUSH0r(unit, &rval)); 1382 soc_reg_field_set(unit, TOQ_FLUSH0r, &rval, FLUSH_ACTIVEf, 0); 1383 BCM_IF_ERROR_RETURN(WRITE_TOQ_FLUSH0r(unit, rval)); 1384 } 1385 do { 1386 soc_timeout_init(&to, timeout_usec, min_polls); 1387 if(soc_timeout_check(&to)) { 1388 LOG_ERROR(BSL_LS_BCM_PORT, 1389 (BSL_META_U(unit, 1390 "TimeOut InternalError\n"))); 1391 return BCM_E_INTERNAL; 1392 } 1393 try_count++; 1394 BCM_IF_ERROR_RETURN(READ_TOQ_FLUSH0r(unit, &rval)); 1395 if (soc_reg_field_get( 1396 unit, TOQ_FLUSH0r, rval, FLUSH_ACTIVEf) == 0) { 1397 break; 1398 } 1399 } while (try_count != 3); 1400 if (try_count == 3) { 1401 return BCM_E_TIMEOUT; 1402 } 1403 #endif 1404 try_count=0; 1405 if (SAL_BOOT_SIMULATION) { 1406 BCM_IF_ERROR_RETURN(READ_XP_TXFIFO_CELL_CNTr( 1407 unit, mxqblock_port, &rval)); 1408 soc_reg_field_set(unit, XP_TXFIFO_CELL_CNTr, 1409 &rval, CELL_CNTf, 0); 1410 BCM_IF_ERROR_RETURN(WRITE_XP_TXFIFO_CELL_CNTr( 1411 unit, mxqblock_port, rval)); 1412 } 1413 soc_timeout_init(&to, timeout_usec, min_polls); 1414 for (try=0; try<100 && try_count < 10 ; try++) { 1415 if(soc_timeout_check(&to)) { 1416 LOG_ERROR(BSL_LS_BCM_PORT, 1417 (BSL_META_U(unit, 1418 "TimeOut InternalError\n"))); 1419 return SOC_E_INTERNAL; 1420 } 1421 BCM_IF_ERROR_RETURN(READ_XP_TXFIFO_CELL_CNTr ( 1422 unit,mxqblock_port, &rval)); 1423 cell_cnt=soc_reg_field_get(unit, XP_TXFIFO_CELL_CNTr, 1424 rval, CELL_CNTf); 1425 if (cell_cnt == 0) { 1426 try_count++; 1427 break; 1428 } 1429 } 1430 if (try == 100) { 1431 return SOC_E_TIMEOUT; 1432 } 1433 1434 /*8. Since we have blocked ingress traffic and outgoing packets 1435 have been dropped in MXQPORT, it is safe to powerdown 1436 Unicore/Warpcore serdes. This is done by programming the 1437 following:XPORT_XGXS_CTRL.Pwrdwn = 1 */ 1438 /* READ_XPORT_XGXS_CTRLr(unit, mxqblock_port,&rval); */ 1439 rval = 0; 1440 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, 1441 LCREF_ENf,1); 1442 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, 1443 IDDQf,1); 1444 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, 1445 PWRDWNf,1); 1446 WRITE_XPORT_XGXS_CTRLr(unit, mxqblock_port,rval); 1447 1448 /*9 Disable the egress cell request generation; this will make 1449 sure that egress does not send any request to MMU. 1450 This is done by clearing EGR_ENABLE(for EDB) /port_enable 1451 (for TXLP) register in Egress */ 1452 /* soc_mem_field32_set(unit, EGR_ENABLEm, 1453 &egr_enable_entry, PRT_ENABLEf, 0); */ 1454 if (mxqblock <= 7) { 1455 BCM_IF_ERROR_RETURN(soc_mem_write( 1456 unit, EGR_ENABLEm, MEM_BLOCK_ALL, 1457 mxqblock_port, &egr_enable_entry)); 1458 } else { 1459 SOC_IF_ERROR_RETURN(READ_TXLP_PORT_ENABLEr( 1460 unit, port, &rval)); 1461 port_enable = soc_reg_field_get(unit, TXLP_PORT_ENABLEr, 1462 rval, PORT_ENABLEf); 1463 port_enable &= ~(1 << (loop)); 1464 soc_reg_field_set(unit, TXLP_PORT_ENABLEr, 1465 &rval, PORT_ENABLEf, port_enable); 1466 BCM_IF_ERROR_RETURN(WRITE_TXLP_PORT_ENABLEr( 1467 unit, port, rval)); 1468 } 1469 1470 /*10. At this point, the link is down and all pending packets are 1471 drained. The software then disables the MXQPORT flush. 1472 This is done by programming the followings: 1473 XP_TXFIFO_PKT_DROP_CTL.DROP_EN */ 1474 READ_XP_TXFIFO_PKT_DROP_CTLr(unit, mxqblock_port,&rval); 1475 soc_reg_field_set(unit, XP_TXFIFO_PKT_DROP_CTLr, &rval, 1476 DROP_ENf,0); 1477 WRITE_XP_TXFIFO_PKT_DROP_CTLr(unit, mxqblock_port,rval); 1478 1479 /* 11. Restore PFC */ 1480 if (port_speed >= 10000) { 1481 BCM_IF_ERROR_RETURN(WRITE_XPORT_TO_MMU_BKPr( 1482 unit, pfc_index, pfc_enable)); 1483 } 1484 /* PLEASE NOTE THAT PORT IS STILL DOWN */ 1485 1486 } 1487 } 1488 /* ReConfigure H/W */ 1489 /* 1. Soft-reset relevant MXQPORT(s) */ 1490 soc_katana2_mxqblock_reset(unit, mxqblock, 0); 1491 if ((mxqblock==8) || (mxqblock==9)) { 1492 if (xfi_mode[mxqblock-8]==1) { 1493 soc_katana2_mxqblock_reset(unit, mxqblock-2, 0); 1494 } 1495 } 1496 1497 /* ReConfigure TDM */ 1498 soc_katana2_reconfigure_tdm(unit,kt2_current_tdm_size,new_tdm); 1499 sal_memcpy(&kt2_current_tdm[0],&new_tdm[0], 1500 kt2_current_tdm_size *sizeof(kt2_current_tdm[0])); 1501 1502 /* Update local pbmp's */ 1503 soc_linkscan_pause(unit); 1504 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1505 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1506 if ((old_ports[old_lanes-1][loop] == 0) && 1507 (new_ports[new_lanes-1][loop] == 0)) { 1508 /* Eithere not used */ 1509 continue; 1510 } 1511 si->port_speed_max[mxqblock_port]=(*mxqspeeds[unit])[mxqblock] 1512 [new_lanes-1]; 1513 if (old_ports[old_lanes-1][loop] == new_ports[new_lanes-1][loop] ) { 1514 /* same port was used so only speed change */ 1515 soc_katana2_pbmp_remove(unit,mxqblock_port); 1516 soc_katana2_pbmp_add(unit,mxqblock_port,mxqblock, 1517 si->port_speed_max[mxqblock_port]); 1518 } 1519 if (old_ports[old_lanes-1][loop] > new_ports[new_lanes-1][loop]) { 1520 /* This port is not applicable so remove it from pbmp list */ 1521 soc_katana2_pbmp_remove(unit,mxqblock_port); 1522 continue; 1523 } 1524 if (new_ports[new_lanes-1][loop] > old_ports[old_lanes-1][loop]) { 1525 /* This port is new so add it in pbmp list first */ 1526 soc_katana2_pbmp_add(unit,mxqblock_port, mxqblock, 1527 si->port_speed_max[mxqblock_port]); 1528 } 1529 BCM_IF_ERROR_RETURN(bcm_katana2_cosq_reconfigure_flexio(unit, mxqblock_port, 0)); 1530 } 1531 if (((mxqblock==8) || (mxqblock==9)) && ((lanes==2)||(lanes==4))) { 1532 if (soc_kt2_linkphy_port_reg_blk_idx_get(unit, port, 1533 SOC_BLK_TXLP, &blk, NULL) == SOC_E_NONE) { 1534 /* Is a TXLP Port */ 1535 si->block_valid[blk] += 1; 1536 if (si->block_port[blk] < 0) { 1537 si->block_port[blk] = port; 1538 } 1539 if (lanes==2) { 1540 SOC_PBMP_PORT_ADD(si->block_bitmap[blk], (*kt2_mxqblock_ports[unit])[mxqblock][2]); 1541 } else if (lanes==4) { 1542 SOC_PBMP_PORT_ADD(si->block_bitmap[blk], (*kt2_mxqblock_ports[unit])[mxqblock][1]); 1543 SOC_PBMP_PORT_ADD(si->block_bitmap[blk], (*kt2_mxqblock_ports[unit])[mxqblock][2]); 1544 SOC_PBMP_PORT_ADD(si->block_bitmap[blk], (*kt2_mxqblock_ports[unit])[mxqblock][3]); 1545 } 1546 } 1547 if (soc_kt2_linkphy_port_reg_blk_idx_get(unit, port, 1548 SOC_BLK_RXLP, &blk, NULL) == SOC_E_NONE) { 1549 /* Is a RXLP Port */ 1550 si->block_valid[blk] += 1; 1551 if (si->block_port[blk] < 0) { 1552 si->block_port[blk] = port; 1553 } 1554 if (lanes==2) { 1555 SOC_PBMP_PORT_ADD(si->block_bitmap[blk], (*kt2_mxqblock_ports[unit])[mxqblock][2]); 1556 } else if (lanes==4) { 1557 SOC_PBMP_PORT_ADD(si->block_bitmap[blk], (*kt2_mxqblock_ports[unit])[mxqblock][1]); 1558 SOC_PBMP_PORT_ADD(si->block_bitmap[blk], (*kt2_mxqblock_ports[unit])[mxqblock][2]); 1559 SOC_PBMP_PORT_ADD(si->block_bitmap[blk], (*kt2_mxqblock_ports[unit])[mxqblock][3]); 1560 } 1561 } 1562 } 1563 soc_katana2_pbmp_all_resync(unit) ; 1564 soc_esw_dport_init(unit); 1565 soc_linkscan_continue(unit); 1566 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1567 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1568 SOC_IF_ERROR_RETURN(_soc_katana2_mmu_reconfigure(unit, mxqblock_port)); 1569 } 1570 1571 mxqblock_max_nxtaddr = mxqblock_max_startaddr[mxqblock]; 1572 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1573 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1574 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1575 BCM_IF_ERROR_RETURN(READ_DEQ_EFIFO_CFGr(unit,mxqblock_port,&rval)); 1576 if (si->port_speed_max[mxqblock_port] <= 1000) { 1577 egr_fifo_depth = (IS_EXT_MEM_PORT(unit, mxqblock_port)) ? 10 : 2; 1578 threshold = (IS_EXT_MEM_PORT(unit, mxqblock_port)) ? 8 : 0; 1579 padding = 10 - egr_fifo_depth; 1580 }else if (si->port_speed_max[mxqblock_port] <= 2500) { 1581 egr_fifo_depth = (IS_EXT_MEM_PORT(unit, mxqblock_port)) ? 14 : 2; 1582 threshold = (IS_EXT_MEM_PORT(unit, mxqblock_port)) ? 12 : 0; 1583 padding = 14 - egr_fifo_depth; 1584 } else if (si->port_speed_max[mxqblock_port] <= 13000) { 1585 egr_fifo_depth = (IS_EXT_MEM_PORT(unit, mxqblock_port)) ? 56 : 10; 1586 threshold = (IS_EXT_MEM_PORT(unit, mxqblock_port)) ? 49 : 0; 1587 padding = 56 - egr_fifo_depth; 1588 } else { 1589 egr_fifo_depth = (IS_EXT_MEM_PORT(unit, mxqblock_port)) ? 112 : 16; 1590 threshold = (IS_EXT_MEM_PORT(unit, mxqblock_port)) ? 85 : 0; 1591 padding = 112 - egr_fifo_depth; 1592 } 1593 soc_reg_field_set(unit, DEQ_EFIFO_CFGr, &rval, 1594 EGRESS_FIFO_START_ADDRESSf, 1595 mxqblock_max_nxtaddr); 1596 if ((mxqblock_max_nxtaddr + (egr_fifo_depth + padding)) > mxqblock_max_endaddr[mxqblock]) { 1597 egr_fifo_depth = (mxqblock_max_endaddr[mxqblock] - 1598 mxqblock_max_nxtaddr)+1; 1599 mxqblock_max_nxtaddr = mxqblock_max_endaddr[mxqblock]; 1600 } else { 1601 mxqblock_max_nxtaddr += egr_fifo_depth + padding; 1602 } 1603 if (egr_fifo_depth == 1) { 1604 LOG_CLI((BSL_META_U(unit, 1605 "WARN: EGR_FIFO_DEPTH IS ZERO for port=%d\n"), 1606 mxqblock_port)); 1607 } 1608 if ((IS_EXT_MEM_PORT(unit, mxqblock_port)) && !(PBMP_MEMBER(si->linkphy_pbm, mxqblock_port))) { 1609 soc_reg_field_set(unit, DEQ_EFIFO_CFGr, &rval, 1610 EGRESS_FIFO_XMIT_OVERSPEED_RATE_LIMITERf, 1); 1611 } else { 1612 soc_reg_field_set(unit, DEQ_EFIFO_CFGr, &rval, 1613 EGRESS_FIFO_XMIT_OVERSPEED_RATE_LIMITERf, 0); 1614 } 1615 soc_reg_field_set(unit, DEQ_EFIFO_CFGr, &rval, 1616 EGRESS_FIFO_DEPTHf, egr_fifo_depth); 1617 soc_reg_field_set(unit, DEQ_EFIFO_CFGr, &rval, 1618 EGRESS_FIFO_XMIT_THRESHOLDf, threshold); 1619 BCM_IF_ERROR_RETURN(WRITE_DEQ_EFIFO_CFGr( 1620 unit,mxqblock_port,rval)); 1621 } 1622 } 1623 1624 /* WORK-AROUND for port-flushing i.e. need to repeat below step twice */ 1625 for (try_loop = 0; try_loop < 2; try_loop++) { 1626 /* EP Reset */ 1627 if (SAL_BOOT_SIMULATION) { 1628 BCM_IF_ERROR_RETURN(WRITE_DYNAMIC_PORT_RECFG_VECTOR_CFG_31_00r( 1629 unit, 0)); 1630 BCM_IF_ERROR_RETURN(WRITE_DYNAMIC_PORT_RECFG_VECTOR_CFG_41_32r( 1631 unit, 0)); 1632 } 1633 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1634 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1635 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1636 if (mxqblock_port <= 31) { 1637 rval1 |= (1 << mxqblock_port); 1638 } else { 1639 rval2 |= (1 << (mxqblock_port-32)); 1640 } 1641 } 1642 } 1643 BCM_IF_ERROR_RETURN(WRITE_DYNAMIC_PORT_RECFG_VECTOR_CFG_31_00r( 1644 unit, rval1)); 1645 BCM_IF_ERROR_RETURN(WRITE_DYNAMIC_PORT_RECFG_VECTOR_CFG_41_32r( 1646 unit, rval2)); 1647 if (SAL_BOOT_SIMULATION) { 1648 BCM_IF_ERROR_RETURN(WRITE_DYNAMIC_PORT_RECFG_VECTOR_CFG_31_00r( 1649 unit, 0)); 1650 BCM_IF_ERROR_RETURN(WRITE_DYNAMIC_PORT_RECFG_VECTOR_CFG_41_32r( 1651 unit, 0)); 1652 } 1653 try_count = 0; 1654 do { 1655 soc_timeout_init(&to, timeout_usec, min_polls); 1656 if(soc_timeout_check(&to)) { 1657 LOG_ERROR(BSL_LS_BCM_PORT, 1658 (BSL_META_U(unit, 1659 "TimeOut InternalError\n"))); 1660 return BCM_E_INTERNAL; 1661 } 1662 try_count++; 1663 BCM_IF_ERROR_RETURN(READ_DYNAMIC_PORT_RECFG_VECTOR_CFG_31_00r( 1664 unit, &rval1)); 1665 BCM_IF_ERROR_RETURN(READ_DYNAMIC_PORT_RECFG_VECTOR_CFG_41_32r( 1666 unit, &rval2)); 1667 if ((rval1 == 0) && (rval2 == 0)) { 1668 break; 1669 } 1670 } while (try_count != 3); 1671 if (try_count == 3) { 1672 return BCM_E_TIMEOUT; 1673 } 1674 } 1675 1676 if (mxqblock <= 7) { 1677 READ_EDATABUF_DBG_PORT_INTF_RESETr(unit, &rval); 1678 soc_reg_field_set(unit, EDATABUF_DBG_PORT_INTF_RESETr, 1679 &rval, port_intf_reset_fld[mxqblock], 1); 1680 WRITE_EDATABUF_DBG_PORT_INTF_RESETr(unit, rval); 1681 READ_EDATABUF_DBG_MMU_INTF_RESETr(unit, &rval); 1682 soc_reg_field_set(unit, EDATABUF_DBG_MMU_INTF_RESETr, 1683 &rval, mmu_intf_reset_fld[mxqblock], 1); 1684 soc_reg_field_set(unit, EDATABUF_DBG_MMU_INTF_RESETr, 1685 &rval, new_port_mode_fld[mxqblock], 1686 new_port_mode[new_lanes]); 1687 WRITE_EDATABUF_DBG_MMU_INTF_RESETr(unit, rval); 1688 } 1689 /* mxqblock_port=port; */ 1690 if ((mxqblock >= 8) && (mxqblock <= 9)) { 1691 WRITE_TXLP_PORT_CREDIT_RESETr(unit, port,0xf); 1692 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1693 sal_memset(&txlp_port_addr_map_table_entry,0, 1694 sizeof(txlp_port_addr_map_table_entry_t)); 1695 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1696 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1697 /* 5. As each cell-occupies "4" lines in buffer, [end-start+1] must be a integral 1698 multiple of "4". */ 1699 if (si->port_speed_max[mxqblock_port] <= 2500) { 1700 end_addr = start_addr + (( 6 * 4) - 1); /* 6 Cells */ 1701 } else if (si->port_speed_max[mxqblock_port] <= 10000) { 1702 end_addr = start_addr + ((12 * 4) - 1); /* 12 Cells */ 1703 } else if (si->port_speed_max[mxqblock_port] <= 13000) { 1704 end_addr = start_addr + ((16 * 4) - 1); /* 16 Cells */ 1705 } else if (si->port_speed_max[mxqblock_port] <= 21000) { 1706 end_addr = start_addr + ((20 * 4) - 1); /* 20 Cells */ 1707 } 1708 soc_TXLP_PORT_ADDR_MAP_TABLEm_field_set(unit, 1709 &txlp_port_addr_map_table_entry,START_ADDRf,&start_addr); 1710 soc_TXLP_PORT_ADDR_MAP_TABLEm_field_set(unit, 1711 &txlp_port_addr_map_table_entry,END_ADDRf,&end_addr); 1712 start_addr = end_addr+1; 1713 } 1714 BCM_IF_ERROR_RETURN(WRITE_TXLP_PORT_ADDR_MAP_TABLEm( 1715 unit,SOC_INFO(unit).txlp_block[mxqblock-8], 1716 loop, &txlp_port_addr_map_table_entry)); 1717 } 1718 } 1719 1720 1721 /* Begin: Link up sequence */ 1722 sal_udelay((10*time_multiplier)); 1723 /* 1 */ 1724 if (mxqblock <= 7) { 1725 READ_EDATABUF_DBG_PORT_INTF_RESETr(unit, &rval); 1726 soc_reg_field_set(unit, EDATABUF_DBG_PORT_INTF_RESETr, 1727 &rval, port_intf_reset_fld[mxqblock], 0); 1728 WRITE_EDATABUF_DBG_PORT_INTF_RESETr(unit, rval); 1729 READ_EDATABUF_DBG_MMU_INTF_RESETr(unit, &rval); 1730 soc_reg_field_set(unit, EDATABUF_DBG_MMU_INTF_RESETr, 1731 &rval, mmu_intf_reset_fld[mxqblock], 0); 1732 WRITE_EDATABUF_DBG_MMU_INTF_RESETr(unit, rval); 1733 } 1734 /* mxqblock_port=port; */ 1735 if ((mxqblock >= 8) && (mxqblock <= 9)) { 1736 WRITE_TXLP_PORT_CREDIT_RESETr(unit, port,0); 1737 } 1738 /* 2 */ 1739 BCM_IF_ERROR_RETURN(READ_EPC_LINK_BMAPm( 1740 unit, MEM_BLOCK_ANY, 0, &epc_link_bmap_entry)); 1741 soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, 1742 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 1743 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1744 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1745 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1746 BCM_PBMP_PORT_ADD(link_pbmp,mxqblock_port); 1747 } 1748 } 1749 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, 1750 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 1751 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm( 1752 unit, MEM_BLOCK_ALL, 0, &epc_link_bmap_entry)); 1753 1754 /* Bring out of reset */ 1755 soc_katana2_mxqblock_reset(unit, mxqblock, 1); 1756 1757 /* XFI Mode ??? */ 1758 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1759 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1760 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1761 BCM_IF_ERROR_RETURN(_bcm_kt2_update_port_mode( 1762 unit,mxqblock_port, 1763 si->port_speed_max[mxqblock_port])); 1764 break; 1765 } 1766 } 1767 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1768 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1769 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1770 SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, mxqblock_port,&rval)); 1771 if (((si->port_speed_max[mxqblock_port]) >= 13000) && 1772 ((si->port_speed_max[mxqblock_port]) != 20000)) { 1773 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf,1); 1774 if (soc_feature(unit, soc_feature_higig2) && IS_HL_PORT(unit,port)) { 1775 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, 1776 HIGIG2_MODEf,1); 1777 } 1778 } else { 1779 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG_MODEf,0); 1780 soc_reg_field_set(unit, XPORT_CONFIGr, &rval, HIGIG2_MODEf,0); 1781 } 1782 SOC_IF_ERROR_RETURN(WRITE_XPORT_CONFIGr(unit, mxqblock_port,rval)); 1783 } 1784 } 1785 /* mxqblock_port=port; */ 1786 SOC_IF_ERROR_RETURN(WRITE_XPORT_XMAC_CONTROLr(unit, port, 0)); 1787 1788 length_check = soc_property_get(unit, spn_MAC_LENGTH_CHECK_ENABLE, 0); 1789 1790 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1791 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1792 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1793 SOC_IF_ERROR_RETURN(READ_MAC_RSV_MASKr(unit,mxqblock_port, &rval)); 1794 if (length_check) { 1795 rval |= 0x20; /* set bit 5 to enable frame length check */ 1796 } else { 1797 rval &= ~0x20; /* clear bit 5 to disable frame length check */ 1798 } 1799 SOC_IF_ERROR_RETURN(WRITE_MAC_RSV_MASKr(unit,mxqblock_port, rval)); 1800 } 1801 } 1802 1803 /* mxqblock_port=port; */ 1804 SOC_IF_ERROR_RETURN(WRITE_XPORT_MIB_RESETr(unit,port, 0xf)); 1805 SOC_IF_ERROR_RETURN(WRITE_XPORT_MIB_RESETr(unit,port, 0x0)); 1806 1807 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1808 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1809 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1810 SOC_IF_ERROR_RETURN(READ_XMAC_MODEr(unit,mxqblock_port, &rval64)); 1811 if (si->port_speed_max[mxqblock_port] == 1000) { 1812 speed_value = 2; 1813 } else if (si->port_speed_max[mxqblock_port] == 2500) { 1814 speed_value = 3; 1815 } else { 1816 speed_value = 4; 1817 } 1818 soc_reg64_field32_set(unit, XMAC_MODEr, &rval64, 1819 SPEED_MODEf,speed_value); 1820 if (si->port_speed_max[mxqblock_port] <= 10000) { 1821 soc_reg64_field32_set(unit, XMAC_MODEr, &rval64,HDR_MODEf,0); 1822 } else { 1823 soc_reg64_field32_set(unit, XMAC_MODEr, &rval64,HDR_MODEf,2); 1824 } 1825 SOC_IF_ERROR_RETURN(WRITE_XMAC_MODEr(unit,mxqblock_port, rval64)); 1826 } 1827 } 1828 1829 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1830 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1831 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1832 SOC_IF_ERROR_RETURN(READ_XMAC_RX_CTRLr( 1833 unit,mxqblock_port, &rval64)); 1834 if (si->port_speed_max[mxqblock_port] <= 10000) { 1835 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64, 1836 RUNT_THRESHOLDf, 64); 1837 } else { 1838 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64, 1839 RUNT_THRESHOLDf, 76); 1840 } 1841 soc_reg64_field32_set(unit, XMAC_RX_CTRLr, &rval64, STRIP_CRCf, 0); 1842 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_CTRLr( 1843 unit,mxqblock_port, rval64)); 1844 } 1845 } 1846 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1847 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1848 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1849 SOC_IF_ERROR_RETURN(READ_XMAC_TX_CTRLr( 1850 unit,mxqblock_port, &rval64)); 1851 if (si->port_speed_max[mxqblock_port] < 2500) { 1852 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, 1853 TX_64BYTE_BUFFER_ENf,1); 1854 } else { 1855 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, 1856 TX_64BYTE_BUFFER_ENf,0); 1857 } 1858 soc_reg64_field32_set(unit, XMAC_TX_CTRLr, &rval64, CRC_MODEf,3); 1859 SOC_IF_ERROR_RETURN(WRITE_XMAC_TX_CTRLr( 1860 unit,mxqblock_port, rval64)); 1861 } 1862 } 1863 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1864 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1865 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1866 SOC_IF_ERROR_RETURN(READ_XMAC_RX_MAX_SIZEr( 1867 unit,mxqblock_port, &rval64)); 1868 soc_reg64_field32_set(unit, XMAC_RX_MAX_SIZEr, &rval64, 1869 RX_MAX_SIZEf,(12*1024)); 1870 SOC_IF_ERROR_RETURN(WRITE_XMAC_RX_MAX_SIZEr( 1871 unit,mxqblock_port, rval64)); 1872 } 1873 } 1874 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1875 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1876 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1877 SOC_IF_ERROR_RETURN(READ_XMAC_CTRLr( 1878 unit,mxqblock_port, &rval64)); 1879 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, SOFT_RESETf,0); 1880 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, TX_ENf,1); 1881 soc_reg64_field32_set(unit, XMAC_CTRLr, &rval64, RX_ENf,1); 1882 SOC_IF_ERROR_RETURN(WRITE_XMAC_CTRLr( 1883 unit,mxqblock_port, rval64)); 1884 } 1885 } 1886 1887 /* mxqblock_port=port; */ 1888 SOC_IF_ERROR_RETURN(WRITE_XPORT_ECC_CONTROLr(unit,port, 0xf)); 1889 1890 SOC_IF_ERROR_RETURN(READ_XPORT_PORT_ENABLEr(unit,port, &rval)); 1891 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1892 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1893 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1894 soc_reg_field_set(unit, XPORT_PORT_ENABLEr, &rval, 1895 port_enable_field[(*kt2_port_to_mxqblock_subports[unit]) 1896 [mxqblock_port-1]],1); 1897 } 1898 } 1899 /* mxqblock_port=port; */ 1900 SOC_IF_ERROR_RETURN(WRITE_XPORT_PORT_ENABLEr(unit,port, rval)); 1901 1902 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1903 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1904 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1905 SOC_IF_ERROR_RETURN(READ_THDO_PORT_DISABLE_CFG1r(unit,&rval)); 1906 soc_reg_field_set(unit, THDO_PORT_DISABLE_CFG1r, &rval, 1907 PORT_WRf,1); 1908 soc_reg_field_set(unit, THDO_PORT_DISABLE_CFG1r, &rval, 1909 PORT_WR_TYPEf,0); 1910 soc_reg_field_set(unit, THDO_PORT_DISABLE_CFG1r, &rval, 1911 PORT_IDf,mxqblock_port); 1912 SOC_IF_ERROR_RETURN(WRITE_THDO_PORT_DISABLE_CFG1r(unit,rval)); 1913 sal_udelay(10*time_multiplier); 1914 if ((SAL_BOOT_BCMSIM || SAL_BOOT_PLISIM)) { 1915 soc_reg_field_set(unit, THDO_PORT_DISABLE_CFG1r, &rval, 1916 PORT_WRf,0); 1917 SOC_IF_ERROR_RETURN(WRITE_THDO_PORT_DISABLE_CFG1r( 1918 unit,rval)); 1919 } 1920 SOC_IF_ERROR_RETURN(READ_THDO_PORT_DISABLE_CFG1r(unit,&rval)); 1921 if (soc_reg_field_get(unit, THDO_PORT_DISABLE_CFG1r, rval, 1922 PORT_WRf) != 0) { 1923 return BCM_E_TIMEOUT; 1924 } 1925 } 1926 } 1927 /* mxqblock_port=port; */ 1928 SOC_IF_ERROR_RETURN(READ_XPORT_XGXS_CTRLr(unit,port,&rval)); 1929 soc_reg_field_set(unit,XPORT_XGXS_CTRLr,&rval,PWRDWNf,0); 1930 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr(unit,port,rval)); 1931 1932 SOC_IF_ERROR_RETURN(READ_XPORT_XGXS_CTRLr(unit,port,&rval)); 1933 soc_reg_field_set(unit,XPORT_XGXS_CTRLr,&rval,IDDQf,0); 1934 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr(unit,port,rval)); 1935 1936 SOC_IF_ERROR_RETURN(READ_XPORT_XGXS_CTRLr(unit,port,&rval)); 1937 soc_reg_field_set(unit,XPORT_XGXS_CTRLr,&rval,REFSELf,0); 1938 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr(unit,port,rval)); 1939 1940 SOC_IF_ERROR_RETURN(READ_XPORT_XGXS_CTRLr(unit,port,&rval)); 1941 soc_reg_field_set(unit,XPORT_XGXS_CTRLr,&rval,REFDIVf,0); 1942 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr(unit,port,rval)); 1943 1944 SOC_IF_ERROR_RETURN(READ_XPORT_XGXS_CTRLr(unit,port,&rval)); 1945 soc_reg_field_set(unit,XPORT_XGXS_CTRLr,&rval,RSTB_HWf,1); 1946 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr(unit,port,rval)); 1947 1948 SOC_IF_ERROR_RETURN(READ_XPORT_XGXS_CTRLr(unit,port,&rval)); 1949 soc_reg_field_set(unit,XPORT_XGXS_CTRLr,&rval,RSTB_MDIOREGSf,1); 1950 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr(unit,port,rval)); 1951 1952 SOC_IF_ERROR_RETURN(READ_XPORT_XGXS_CTRLr(unit,port,&rval)); 1953 soc_reg_field_set(unit,XPORT_XGXS_CTRLr,&rval,RSTB_PLLf,1); 1954 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr(unit,port,rval)); 1955 1956 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1957 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1958 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1959 SOC_IF_ERROR_RETURN(READ_XPORT_XGXS_CTRLr( 1960 unit,mxqblock_port,&rval)); 1961 if (si->port_speed_max[mxqblock_port] > 2500) { 1962 soc_reg_field_set(unit,XPORT_XGXS_CTRLr,&rval, 1963 TXD10G_FIFO_RSTBf,1); 1964 } else { 1965 soc_reg_field_set(unit,XPORT_XGXS_CTRLr,&rval, 1966 TXD10G_FIFO_RSTBf,0); 1967 } 1968 soc_reg_field_set(unit,XPORT_XGXS_CTRLr,&rval, 1969 TXD1G_FIFO_RSTBf,0xF); 1970 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr( 1971 unit,mxqblock_port,rval)); 1972 } 1973 } 1974 1975 /* Txd10g_FIFO_RstB_DXGXS1 ?? */ 1976 1977 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 1978 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 1979 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 1980 if (mxqblock <= 7 ) { 1981 sal_memset(&egr_enable_entry, 0, sizeof(egr_enable_entry_t)); 1982 soc_mem_field32_set(unit, EGR_ENABLEm, 1983 &egr_enable_entry,PRT_ENABLEf, 1); 1984 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, 1985 mxqblock_port, &egr_enable_entry)); 1986 } else { 1987 SOC_IF_ERROR_RETURN(READ_TXLP_PORT_ENABLEr( 1988 unit, port, &rval)); 1989 port_enable = soc_reg_field_get(unit, TXLP_PORT_ENABLEr, 1990 rval, PORT_ENABLEf); 1991 port_enable |= (1<< ((*kt2_port_to_mxqblock_subports[unit]) 1992 [mxqblock_port-1])); 1993 soc_reg_field_set(unit, TXLP_PORT_ENABLEr, 1994 &rval, PORT_ENABLEf, port_enable); 1995 SOC_IF_ERROR_RETURN(WRITE_TXLP_PORT_ENABLEr( 1996 unit, port, rval)); 1997 } 1998 } 1999 } 2000 2001 /* End: Link up sequence */ 2002 2003 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 2004 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 2005 if ((old_ports[old_lanes-1][loop] == 0) && 2006 (new_ports[new_lanes-1][loop] == 0)) { 2007 /* Eithere not used */ 2008 continue; 2009 } 2010 if (old_ports[old_lanes-1][loop] == new_ports[new_lanes-1][loop] ) { 2011 /* same port was used so only speed change */ 2012 SOC_IF_ERROR_RETURN(soc_katana2_port_detach(unit,mxqblock_port)); 2013 } 2014 if (old_ports[old_lanes-1][loop] > new_ports[new_lanes-1][loop]) { 2015 /* This port is not applicable so remove it from pbmp list */ 2016 SOC_IF_ERROR_RETURN(soc_katana2_port_detach(unit,mxqblock_port)); 2017 continue; 2018 } 2019 if (new_ports[new_lanes-1][loop] > old_ports[old_lanes-1][loop]) { 2020 /* This port is new continue */ 2021 continue; 2022 } 2023 } 2024 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 2025 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 2026 if ((old_ports[old_lanes-1][loop] == 0) && 2027 (new_ports[new_lanes-1][loop] == 0)) { 2028 /* Eithere not used */ 2029 continue; 2030 } 2031 if (old_ports[old_lanes-1][loop] == new_ports[new_lanes-1][loop] ) { 2032 /* same port was used so only speed change */ 2033 SOC_IF_ERROR_RETURN(soc_katana2_port_attach( 2034 unit,mxqblock ,mxqblock_port)); 2035 } 2036 if (old_ports[old_lanes-1][loop] > new_ports[new_lanes-1][loop]) { 2037 /* This port is not applicable so remove it from pbmp list */ 2038 continue; 2039 } 2040 if (new_ports[new_lanes-1][loop] > old_ports[old_lanes-1][loop]) { 2041 /* This port is new so add it in pbmp list first */ 2042 SOC_IF_ERROR_RETURN(soc_katana2_port_attach( 2043 unit,mxqblock ,mxqblock_port)); 2044 } 2045 } 2046 2047 /* Special Treatment */ 2048 /* 2049 if ((mxqblock==8) || (mxqblock==9)) { 2050 if (xfi_mode[mxqblock-8]==1) { 2051 LOG_CLI((BSL_META_U(unit, 2052 "4xXFI Mode used for mxqblock:%d\n"),mxqblock)); 2053 } 2054 SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROL_1r( 2055 unit,&top_misc_control_1_val)); 2056 soc_reg_field_set(unit, TOP_MISC_CONTROL_1r, 2057 &top_misc_control_1_val, 2058 wc_xfi_mode_sel_fld[mxqblock-8],xfi_mode[mxqblock-8]); 2059 SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROL_1r( 2060 unit,top_misc_control_1_val)); 2061 } 2062 */ 2063 2064 /* 1. Bring-out of Soft-reset XFI mode related MXQPORT(s) */ 2065 /* 2066 if ((mxqblock==8) || (mxqblock==9)) { 2067 if (xfi_mode[mxqblock-8]==1) { 2068 soc_timeout_init(&to, timeout_usec, min_polls); 2069 if(soc_timeout_check(&to)) { 2070 LOG_ERROR(BSL_LS_BCM_PORT, 2071 (BSL_META_U(unit, 2072 "_bcm_kt2_port_lanes_set:TimeOut InternalError\n"))); 2073 return SOC_E_INTERNAL; 2074 } 2075 soc_katana2_mxqblock_reset(unit, mxqblock-2, 1); 2076 } 2077 } 2078 */ 2079 #ifdef BCM_WARM_BOOT_SUPPORT 2080 SOC_CONTROL_LOCK(unit); 2081 SOC_CONTROL(unit)->scache_dirty = 1; 2082 SOC_CONTROL_UNLOCK(unit); 2083 #endif 2084 2085 return SOC_E_NONE; 2086 2087 } 2088 int _bcm_kt2_cosq_port_ext_buf_set(int unit, bcm_port_t port, int enable) 2089 { 2090 int mxqblock_port_enable[KT2_MAX_MXQPORTS_PER_BLOCK]; 2091 epc_link_bmap_entry_t epc_link_bmap_entry; 2092 soc_pbmp_t link_pbmp, link_pbmp_bkp; 2093 uint8 mxqblock; 2094 uint8 mxqblock_port; 2095 uint8 loop; 2096 pbmp_t ext_pbmp; 2097 2098 #if defined(BCM_SABER2_SUPPORT) 2099 int okay = 0; 2100 uint64 xlmac_ctrl; 2101 #endif 2102 2103 ext_pbmp = soc_property_get_pbmp(unit, spn_PBMP_EXT_MEM, 0); 2104 if (soc_feature(unit, soc_feature_mmu_packing)) { 2105 if (!SOC_PBMP_MEMBER(ext_pbmp, port)){ 2106 return BCM_E_PORT; 2107 } 2108 } 2109 2110 2111 /* Validation on Availability of External Mem */ 2112 if (SOC_DDR3_NUM_MEMORIES(unit) == 0) { 2113 if (enable) { 2114 LOG_ERROR(BSL_LS_BCM_PORT, 2115 (BSL_META_U(unit, 2116 "_bcm_kt2_cosq_port_ext_buf_set:External Memory Not Available\n"))); 2117 return BCM_E_RESOURCE; 2118 } 2119 return BCM_E_NONE; 2120 } 2121 2122 /* Disable the port to flush the queues */ 2123 #if defined(BCM_SABER2_SUPPORT) 2124 if (SOC_IS_SABER2(unit) && (IS_XL_PORT(unit, port))) { 2125 2126 /* Stop the incoming traffic, disable XLMAC Rx */ 2127 SOC_IF_ERROR_RETURN(READ_XLMAC_CTRLr( 2128 unit, port, &xlmac_ctrl)); 2129 soc_reg64_field32_set(unit, XLMAC_CTRLr, &xlmac_ctrl, TX_ENf, 1); 2130 soc_reg64_field32_set(unit, XLMAC_CTRLr, &xlmac_ctrl, RX_ENf, 0); 2131 SOC_IF_ERROR_RETURN(WRITE_XLMAC_CTRLr( 2132 unit, port, xlmac_ctrl)); 2133 sal_udelay(10); 2134 2135 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, port, &okay)); 2136 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, 0)); 2137 2138 /* Remove the port from EPC_LINK_BMAP to avoid packets getting queued 2139 * while switching between buffers */ 2140 BCM_IF_ERROR_RETURN(READ_EPC_LINK_BMAPm( 2141 unit, MEM_BLOCK_ANY, 0, &epc_link_bmap_entry)); 2142 soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, 2143 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 2144 BCM_PBMP_PORT_REMOVE(link_pbmp,port); 2145 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, 2146 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 2147 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm( 2148 unit, MEM_BLOCK_ALL, 0, &epc_link_bmap_entry)); 2149 } else 2150 #endif 2151 { 2152 #if defined(BCM_SABER2_SUPPORT) 2153 if(SOC_IS_SABER2(unit)) { 2154 SOC_IF_ERROR_RETURN(soc_saber2_get_port_block( 2155 unit,port,&mxqblock)); 2156 } else 2157 #endif 2158 { 2159 SOC_IF_ERROR_RETURN(soc_katana2_get_port_mxqblock( 2160 unit,port,&mxqblock)); 2161 } 2162 2163 SOC_IF_ERROR_RETURN(READ_EPC_LINK_BMAPm( 2164 unit, MEM_BLOCK_ANY, 0, &epc_link_bmap_entry)); 2165 soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, 2166 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 2167 SOC_PBMP_ASSIGN(link_pbmp_bkp, link_pbmp); 2168 2169 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 2170 #if defined(BCM_SABER2_SUPPORT) 2171 if(SOC_IS_SABER2(unit)) { 2172 mxqblock_port=(*sb2_block_ports[unit])[mxqblock][loop]; 2173 } else 2174 #endif 2175 { 2176 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 2177 } 2178 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 2179 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_get(unit, mxqblock_port, 2180 &mxqblock_port_enable[loop])); 2181 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, mxqblock_port, 2182 0)); 2183 /* Remove the port from EPC_LINK_BMAP to avoid packets getting 2184 * queued while switching between buffers */ 2185 BCM_PBMP_PORT_REMOVE(link_pbmp, mxqblock_port); 2186 2187 } 2188 } 2189 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, 2190 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 2191 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm( 2192 unit, MEM_BLOCK_ALL, 0, &epc_link_bmap_entry)); 2193 } 2194 sal_usleep(200000); 2195 /* Perform Buffer switching */ 2196 #if defined(BCM_SABER2_SUPPORT) 2197 if(SOC_IS_SABER2(unit)) { 2198 SOC_IF_ERROR_RETURN(_bcm_saber2_mmu_init_helper_dyn(unit, port, enable)); 2199 } else 2200 #endif 2201 { 2202 SOC_IF_ERROR_RETURN(_soc_katana2_mmu_init_helper_dyn(unit, port, enable)); 2203 } 2204 sal_usleep(200000); 2205 #if defined(BCM_SABER2_SUPPORT) 2206 if (SOC_IS_SABER2(unit) && (IS_XL_PORT(unit, port))) { 2207 /* Restore EPC_LINK_BMAP with the port */ 2208 BCM_IF_ERROR_RETURN(READ_EPC_LINK_BMAPm( 2209 unit, MEM_BLOCK_ANY, 0, &epc_link_bmap_entry)); 2210 soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, 2211 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 2212 BCM_PBMP_PORT_ADD(link_pbmp,port); 2213 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, 2214 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 2215 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm( 2216 unit, MEM_BLOCK_ALL, 0, &epc_link_bmap_entry)); 2217 sal_usleep(200000); 2218 2219 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, port, okay)); 2220 } else 2221 #endif 2222 { 2223 /* Restore EPC_LINK_BMAP with the port */ 2224 SOC_IF_ERROR_RETURN(READ_EPC_LINK_BMAPm( 2225 unit, MEM_BLOCK_ANY, 0, &epc_link_bmap_entry)); 2226 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, 2227 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp_bkp); 2228 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm( 2229 unit, MEM_BLOCK_ALL, 0, &epc_link_bmap_entry)); 2230 sal_usleep(200000); 2231 2232 for (loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK;loop++) { 2233 #if defined(BCM_SABER2_SUPPORT) 2234 if(SOC_IS_SABER2(unit)) { 2235 mxqblock_port=(*sb2_block_ports[unit])[mxqblock][loop]; 2236 } else 2237 #endif 2238 { 2239 mxqblock_port=(*kt2_mxqblock_ports[unit])[mxqblock][loop]; 2240 } 2241 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), mxqblock_port)) { 2242 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, mxqblock_port, 2243 mxqblock_port_enable[loop])); 2244 } 2245 } 2246 } 2247 return BCM_E_NONE; 2248 } 2249 2250 int _bcm_kt2_cosq_port_ext_buf_get(int unit, bcm_port_t port, int *enable) 2251 { 2252 *enable = 0; 2253 if (SOC_PBMP_MEMBER(PBMP_EXT_MEM (unit), port)) { 2254 *enable = 1; 2255 } 2256 return BCM_E_NONE; 2257 2258 } 2259 int _bcm_kt2_port_lanes_set(int unit, bcm_port_t port, int lanes) 2260 { 2261 int rv; 2262 soc_flex_io_operation_status_set(unit, 1); 2263 rv = __bcm_kt2_port_lanes_set(unit, port, lanes); 2264 soc_flex_io_operation_status_set(unit, 0); 2265 return rv; 2266 } 2267 int 2268 _bcm_kt2_port_lanes_get(int unit, bcm_port_t port, int *lanes) 2269 { 2270 uint8 loop=0; 2271 uint8 mxqblock=0; 2272 2273 *lanes=0; 2274 SOC_IF_ERROR_RETURN(soc_katana2_get_port_mxqblock( 2275 unit,port,&mxqblock)); 2276 for(loop=0;loop<KT2_MAX_MXQPORTS_PER_BLOCK; loop++) { 2277 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), 2278 (*kt2_mxqblock_ports[unit])[mxqblock][loop])) { 2279 (*lanes)++; 2280 } 2281 } 2282 return SOC_E_NONE; 2283 } 2284 2285 int 2286 _bcm_kt2_port_control_oam_loopkup_with_dvp_set(int unit, bcm_port_t port, 2287 int val) 2288 { 2289 #if defined(INCLUDE_L3) 2290 int vp = 0; 2291 egr_dvp_attribute_entry_t dvp_entry; 2292 /* From the gport get VP index */ 2293 if (BCM_GPORT_IS_MIM_PORT(port)) { 2294 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 2295 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 2296 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 2297 } else if (BCM_GPORT_IS_VLAN_PORT(port)) { 2298 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 2299 } else { 2300 return BCM_E_PORT; 2301 } 2302 2303 /* Set OAM_KEY3 in EGR_DVP_ATTRIBUTE table entry */ 2304 SOC_IF_ERROR_RETURN 2305 (READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry)); 2306 soc_EGR_DVP_ATTRIBUTEm_field32_set(unit, &dvp_entry, 2307 OAM_KEY3f, val ? 1 : 0); 2308 SOC_IF_ERROR_RETURN 2309 (WRITE_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ALL, vp, &dvp_entry)); 2310 return BCM_E_NONE; 2311 #endif 2312 return BCM_E_NONE; 2313 } 2314 2315 int 2316 _bcm_kt2_port_control_oam_loopkup_with_dvp_get(int unit, bcm_port_t port, 2317 int *val) 2318 { 2319 #if defined(INCLUDE_L3) 2320 int vp = 0; 2321 egr_dvp_attribute_entry_t dvp_entry; 2322 /* From the gport get VP index */ 2323 if (BCM_GPORT_IS_MIM_PORT(port)) { 2324 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 2325 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 2326 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 2327 } else if (BCM_GPORT_IS_VLAN_PORT(port)) { 2328 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 2329 } else { 2330 return BCM_E_PORT; 2331 } 2332 SOC_IF_ERROR_RETURN 2333 (READ_EGR_DVP_ATTRIBUTEm(unit, MEM_BLOCK_ANY, vp, &dvp_entry)); 2334 *val = soc_EGR_DVP_ATTRIBUTEm_field32_get(unit, &dvp_entry, 2335 OAM_KEY3f); 2336 #endif 2337 return BCM_E_NONE; 2338 } 2339 2340 soc_field_t 2341 modid_valid_field[KT2_MAX_MODIDS_PER_TRANSLATION_TABLE] = 2342 { MODID_0_VALIDf, 2343 MODID_1_VALIDf, 2344 MODID_2_VALIDf, 2345 MODID_3_VALIDf}; 2346 soc_field_t 2347 modid_field[KT2_MAX_MODIDS_PER_TRANSLATION_TABLE] = 2348 { MODID_0f, 2349 MODID_1f, 2350 MODID_2f, 2351 MODID_3f }; 2352 soc_field_t 2353 modid_base_port_ptr_field[KT2_MAX_MODIDS_PER_TRANSLATION_TABLE] = 2354 { MODID_0_BASE_PP_PORTf , 2355 MODID_1_BASE_PP_PORTf , 2356 MODID_2_BASE_PP_PORTf , 2357 MODID_3_BASE_PP_PORTf } ; 2358 soc_mem_t 2359 pp_port_gpp_translation_table[KT2_MAX_PP_PORT_GPP_TRANSLATION_TABLES + 2360 KT2_MAX_EGR_PP_PORT_GPP_TRANSLATION_TABLES] = 2361 { PP_PORT_GPP_TRANSLATION_1m, 2362 PP_PORT_GPP_TRANSLATION_2m, 2363 PP_PORT_GPP_TRANSLATION_3m, 2364 PP_PORT_GPP_TRANSLATION_4m, 2365 EGR_PP_PORT_GPP_TRANSLATION_1m, 2366 EGR_PP_PORT_GPP_TRANSLATION_2m}; 2367 2368 /* 2369 * Function: 2370 * bcm_kt2_modid_set_all 2371 * Purpose: 2372 * Update all the moduleids, valid bits and corresponding port base 2373 * pointers in the appropriates tables as per Katana2 2374 * Parameters: 2375 * unit - (IN)StrataSwitch unit number. 2376 * my_mod_list - (IN) list of module ID's 2377 * my_mod_valid_list - (IN) list of Valid bits corresponding to Module ID 2378 * base_ptr_list - (IN) list of port base ptr corresponding to 2379 * ModuleID 2380 * Returns: 2381 * BCM_E_XXX 2382 */ 2383 2384 int 2385 bcm_kt2_modid_set_all(int unit, 2386 int *my_modid_list, int *my_modid_valid_list , 2387 int *base_port_ptr_list) 2388 { 2389 int loop = 0; 2390 int index = 0; 2391 2392 for (index = 0 ; index < ( KT2_MAX_PP_PORT_GPP_TRANSLATION_TABLES 2393 + KT2_MAX_EGR_PP_PORT_GPP_TRANSLATION_TABLES ) ; index++) { 2394 for (loop = 0 ; loop < KT2_MAX_MODIDS_PER_TRANSLATION_TABLE; loop++) { 2395 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 2396 pp_port_gpp_translation_table[index], 2397 0, modid_valid_field[loop], 2398 my_modid_valid_list[loop])); 2399 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 2400 pp_port_gpp_translation_table[index], 2401 0, modid_field[loop], 2402 my_modid_list[loop])); 2403 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 2404 pp_port_gpp_translation_table[index], 0, 2405 modid_base_port_ptr_field[loop], 2406 base_port_ptr_list[loop])); 2407 2408 } 2409 } 2410 return BCM_E_NONE; 2411 } 2412 2413 2414 /* 2415 * Function: 2416 * bcm_kt2_modid_set 2417 * Purpose: 2418 * Update a given entry with the moduleid, valid bits corresponding port 2419 * base pointers in the appropriates tables as per Katana2 2420 * Parameters: 2421 * unit - (IN)StrataSwitch unit number. 2422 * mod_index - (IN) Index of the module we are setting up 2423 * modid_ - (IN) Module ID 2424 * modid_valid - (IN) Valid bit 2425 * base_port_ptr - (IN) Port base pointer 2426 * Returns: 2427 * BCM_E_XXX 2428 */ 2429 int 2430 bcm_kt2_modid_set(int unit, int mod_index, int modid, 2431 int modid_valid, int base_port_ptr) 2432 { 2433 int num_tables = 0; 2434 2435 /* Sanity check the 'mod_index' value, first index reserved 2436 for front panel ports */ 2437 if((mod_index < _BCMI_KATANA2_MODULE_2) || 2438 (mod_index > (KT2_MAX_MODIDS_PER_TRANSLATION_TABLE-1))) { 2439 return BCM_E_PARAM; 2440 } 2441 2442 /* Loop through relevant tables and set up the entry */ 2443 for (num_tables = 0; num_tables < ( KT2_MAX_PP_PORT_GPP_TRANSLATION_TABLES 2444 + KT2_MAX_EGR_PP_PORT_GPP_TRANSLATION_TABLES); num_tables++) { 2445 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 2446 pp_port_gpp_translation_table[num_tables], 2447 0, modid_valid_field[mod_index], modid_valid)); 2448 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 2449 pp_port_gpp_translation_table[num_tables], 2450 0, modid_field[mod_index], modid)); 2451 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, 2452 pp_port_gpp_translation_table[num_tables], 0, 2453 modid_base_port_ptr_field[mod_index], 2454 base_port_ptr)); 2455 2456 } 2457 2458 return BCM_E_NONE; 2459 } 2460 2461 /* 2462 * Function: 2463 * bcm_kt2_modid_get_all 2464 * Purpose: 2465 * Get the moduleids, valid bits and corresponding port base pointers 2466 * Parameters: 2467 * unit - (IN) unit number. 2468 * my_mod_list - (OUT) list of module ID's 2469 * my_mod_valid_list - (OUT) list of Valid bits corresponding to Module ID 2470 * base_ptr_list - (OUT) list of port base ptr corresponding to 2471 * ModuleID 2472 * Returns: 2473 * BCM_E_XXX 2474 */ 2475 2476 int 2477 bcm_kt2_modid_get_all(int unit, 2478 int *my_modid_list, int *my_modid_valid_list , 2479 int *base_port_ptr_list) 2480 { 2481 int loop = 0; 2482 soc_mem_t mem = pp_port_gpp_translation_table[0]; 2483 uint32 hw_buf[SOC_MAX_MEM_FIELD_WORDS]; /* hw entry buffer. */ 2484 2485 sal_memset(hw_buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 2486 2487 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 0, hw_buf)); 2488 2489 for (loop = 0 ; loop < KT2_MAX_MODIDS_PER_TRANSLATION_TABLE; loop++) { 2490 my_modid_valid_list[loop] = soc_mem_field32_get(unit, mem, hw_buf, 2491 modid_valid_field[loop]); 2492 my_modid_list[loop] = soc_mem_field32_get(unit, mem, hw_buf, 2493 modid_field[loop]); 2494 base_port_ptr_list[loop] = soc_mem_field32_get(unit, mem, hw_buf, 2495 modid_base_port_ptr_field[loop]); 2496 } 2497 return BCM_E_NONE; 2498 } 2499 2500 /* 2501 * Function: 2502 * bcm_kt2_modid_get 2503 * Purpose: 2504 * Get the module-id, valid bit and corresponding port base pointer for 2505 * a given module index 2506 * Parameters: 2507 * unit - (IN) unit number. 2508 * mod_index - (IN) Module index to retrieve 2509 * modid - (OUT) Module ID correspoding to mod_index 2510 * mod_valid - (OUT) Valid bits corresponding to mod_index 2511 * base_port_ptr - (OUT) Port base ptr corresponding to mod_index 2512 * Returns: 2513 * BCM_E_XXX 2514 */ 2515 2516 int 2517 bcm_kt2_modid_get(int unit, int mod_index, int *modid, int *modid_valid, 2518 int *base_port_ptr) 2519 { 2520 soc_mem_t mem = pp_port_gpp_translation_table[0]; 2521 uint32 hw_buf[SOC_MAX_MEM_FIELD_WORDS]; /* hw entry buffer. */ 2522 2523 /* Sanity check the 'mod_index' value, first index (_BCMI_KATANA2_MODULE_1) 2524 reserved for front panel ports */ 2525 if((mod_index < _BCMI_KATANA2_MODULE_2) || 2526 (mod_index > (KT2_MAX_MODIDS_PER_TRANSLATION_TABLE-1))) { 2527 return BCM_E_PARAM; 2528 } 2529 2530 sal_memset(hw_buf, 0, SOC_MAX_MEM_FIELD_WORDS * sizeof(uint32)); 2531 2532 BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, 0, hw_buf)); 2533 2534 *modid = soc_mem_field32_get(unit, mem, hw_buf, 2535 modid_valid_field[mod_index]); 2536 *modid_valid = soc_mem_field32_get(unit, mem, hw_buf, 2537 modid_field[mod_index]); 2538 *base_port_ptr = soc_mem_field32_get(unit, mem, hw_buf, 2539 modid_base_port_ptr_field[mod_index]); 2540 2541 return BCM_E_NONE; 2542 } 2543 2544 /* 2545 * Function: 2546 * _bcm_kt2_port_gport_validate 2547 * Description: 2548 * Helper funtion to validate port/gport parameter 2549 * Parameters: 2550 * unit - (IN) BCM device number 2551 * port_in - (IN) Port / Gport to validate 2552 * port_out - (OUT) Port number if valid. 2553 * Return Value: 2554 * BCM_E_NONE - Port OK 2555 * BCM_E_PORT - Port Invalid 2556 */ 2557 int 2558 _bcm_kt2_port_gport_validate(int unit, bcm_port_t port_in, 2559 bcm_port_t *port_out) 2560 { 2561 if (BCM_GPORT_IS_SET(port_in)) { 2562 if (BCM_GPORT_IS_SUBPORT_PORT(port_in)) { 2563 if (_BCM_KT2_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port_in) || 2564 _BCM_KT2_GPORT_IS_LINKPHY_SUBPORT_PORT(unit, port_in) || 2565 _BCM_KT2_GPORT_IS_GENERAL_SUBPORT_PORT(unit, port_in)) { 2566 *port_out = _BCM_KT2_SUBPORT_PORT_ID_GET(port_in); 2567 } else { 2568 return BCM_E_PORT; 2569 } 2570 } else { 2571 BCM_IF_ERROR_RETURN( 2572 bcm_esw_port_local_get(unit, port_in, port_out)); 2573 } 2574 } else if (SOC_PORT_VALID(unit, port_in)) { 2575 *port_out = port_in; 2576 } else { 2577 return BCM_E_PORT; 2578 } 2579 2580 return BCM_E_NONE; 2581 2582 } 2583 2584 /* 2585 * Function: 2586 * _bcm_kt2_pp_port_to_modport_get 2587 * Description: 2588 * given a PP_PORT return the modid and port 2589 * Parameters: 2590 * unit - (IN) BCM device number 2591 * pp_port - (IN) pp_port / Gport 2592 * modid - (OUT) Module ID 2593 * port - (OUT) Port number if valid. 2594 * Return Value: 2595 * BCM_E_XXX 2596 */ 2597 int 2598 _bcm_kt2_pp_port_to_modport_get(int unit, bcm_port_t pp_port, int *modid, 2599 bcm_port_t *port) 2600 { 2601 int my_modid_list[KT2_MAX_MODIDS_PER_TRANSLATION_TABLE] = {0}; 2602 int my_modid_valid[KT2_MAX_MODIDS_PER_TRANSLATION_TABLE] = {0}; 2603 int my_modport_base_ptr[KT2_MAX_MODIDS_PER_TRANSLATION_TABLE] = {0}; 2604 2605 *modid = -1; 2606 *port = -1; 2607 2608 BCM_IF_ERROR_RETURN(_bcm_kt2_port_gport_validate(unit, pp_port, &pp_port)); 2609 2610 BCM_IF_ERROR_RETURN( 2611 bcm_kt2_modid_get_all(unit, my_modid_list, my_modid_valid, 2612 my_modport_base_ptr)); 2613 2614 if (my_modid_valid[3] && (pp_port >= my_modport_base_ptr[3])) { 2615 *modid = my_modid_list[3]; 2616 *port = pp_port - my_modport_base_ptr[3]; 2617 } else if (my_modid_valid[2] && (pp_port >= my_modport_base_ptr[2])) { 2618 *modid = my_modid_list[2]; 2619 *port = pp_port - my_modport_base_ptr[2]; 2620 } else if (my_modid_valid[1] && (pp_port >= my_modport_base_ptr[1])) { 2621 *modid = my_modid_list[1]; 2622 *port = pp_port - my_modport_base_ptr[1]; 2623 } else { 2624 *modid = my_modid_list[0]; 2625 *port = pp_port - my_modport_base_ptr[0]; 2626 } 2627 return BCM_E_NONE; 2628 2629 } 2630 2631 /* 2632 * Function: 2633 * _bcm_kt2_modport_to_pp_port_get 2634 * Description: 2635 * given a modid and port return the pp_port number 2636 * Parameters: 2637 * unit - (IN) BCM device number 2638 * modid - (IN) Module ID 2639 * port - (IN) Port number if valid. 2640 * pp_port - (OUT) pp_port / Gport 2641 * Return Value: 2642 * BCM_E_XXX 2643 */ 2644 int 2645 _bcm_kt2_modport_to_pp_port_get(int unit, int modid, bcm_port_t port, 2646 bcm_port_t *pp_port) 2647 { 2648 int my_modid_list[KT2_MAX_MODIDS_PER_TRANSLATION_TABLE] = {0}; 2649 int my_modid_valid[KT2_MAX_MODIDS_PER_TRANSLATION_TABLE] = {0}; 2650 int my_modport_base_ptr[KT2_MAX_MODIDS_PER_TRANSLATION_TABLE] = {0}; 2651 2652 *pp_port = -1; 2653 2654 if ((modid > SOC_INFO(unit).modid_max) || 2655 (port > SOC_INFO(unit).port_addr_max)) { 2656 return BCM_E_PARAM; 2657 } 2658 2659 BCM_IF_ERROR_RETURN( 2660 bcm_kt2_modid_get_all(unit, my_modid_list, my_modid_valid, 2661 my_modport_base_ptr)); 2662 2663 if (my_modid_valid[0] && (modid == my_modid_list[0])) { 2664 *pp_port = my_modport_base_ptr[0] + port; 2665 } else if (my_modid_valid[1] && (modid == my_modid_list[1])) { 2666 *pp_port = my_modport_base_ptr[1] + port; 2667 } else if(my_modid_valid[2] && (modid == my_modid_list[2])) { 2668 *pp_port = my_modport_base_ptr[2] + port; 2669 } else { 2670 *pp_port = my_modport_base_ptr[3] + port; 2671 } 2672 return BCM_E_NONE; 2673 2674 } 2675 2676 /* 2677 * Function: 2678 * _bcm_kt2_mod_is_coe_mod_check 2679 * Description: 2680 * Given a modid, check if it is a CoE modid 2681 * Parameters: 2682 * unit - (IN) BCM device number 2683 * modid - (IN) Module ID 2684 * Return Value: 2685 * BCM_E_NONE if it is a CoE mod, BCM_E_NOT_FOUND otherwise 2686 * a specific BCM_E_XXXX for other general cases 2687 */ 2688 int 2689 _bcm_kt2_mod_is_coe_mod_check(int unit, int modid) 2690 { 2691 soc_info_t *si=&SOC_INFO(unit); 2692 bcm_module_t my_modid; 2693 2694 /* If the device is running in the stacking mode, check that 2695 the module is one of the CoE modules created, else just 2696 check that it is one greater than the 'local_modid', which 2697 was the earlier implementation */ 2698 if(si->coe_stacking_mode) { 2699 return _bcm_stk_aux_mod_valid(unit, BCM_MODID_TYPE_COE, modid); 2700 } else { 2701 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 2702 #if defined BCM_METROLITE_SUPPORT 2703 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 2704 if(modid == (my_modid)) { 2705 return BCM_E_NONE; 2706 } 2707 } else 2708 #endif 2709 { 2710 /* Return BCM_E_NONE to indicate the mod was found */ 2711 if(modid == (my_modid + 1)) { 2712 return BCM_E_NONE; 2713 } 2714 } 2715 } 2716 2717 /* Return UNAVAIL by default*/ 2718 return BCM_E_NOT_FOUND; 2719 } 2720 2721 /* 2722 * Function: 2723 * _bcm_kt2_port_mac_set 2724 * Description: 2725 * configure port table mac address 2726 * Parameters: 2727 * unit - (IN) BCM device number 2728 * port - (IN) Port number if valid. 2729 * port_mac - (IN) 64 bit mac address 2730 * Return Value: 2731 * BCM_E_XXX 2732 */ 2733 int 2734 _bcm_kt2_port_mac_set(int unit, bcm_port_t port, uint64 port_mac) 2735 { 2736 int index; /* Entry index. */ 2737 bcm_module_t module_id; /* Module ID */ 2738 bcm_port_t port_id; /* Port ID. */ 2739 bcm_trunk_t trunk_id; /* Trunk ID. */ 2740 int local_id; /* Hardware ID. */ 2741 port_tab_entry_t ptab; 2742 egr_port_entry_t egr_port_entry; 2743 int rv; 2744 2745 /* Get index to PORT table from source port */ 2746 if (BCM_GPORT_IS_SET(port)) { 2747 rv = _bcm_esw_gport_resolve(unit, port, &module_id, 2748 &port_id, &trunk_id, &local_id); 2749 if (BCM_FAILURE(rv)) { 2750 return (rv); 2751 } 2752 rv = _bcm_kt2_modport_to_pp_port_get(unit, module_id, port_id, 2753 &index); 2754 if (BCM_FAILURE(rv)) { 2755 return (rv); 2756 } 2757 } else { 2758 index = port; 2759 } 2760 /* Set MAC address in Port table */ 2761 SOC_IF_ERROR_RETURN( 2762 READ_PORT_TABm(unit, MEM_BLOCK_ANY, index, &ptab)); 2763 2764 soc_mem_field64_set(unit, PORT_TABm, &ptab, MAC_ADDRESSf, port_mac); 2765 2766 SOC_IF_ERROR_RETURN( WRITE_PORT_TABm(unit,MEM_BLOCK_ALL, index, &ptab)); 2767 2768 SOC_IF_ERROR_RETURN(READ_EGR_PORTm(unit, MEM_BLOCK_ANY, index, 2769 &egr_port_entry)); 2770 2771 soc_mem_field64_set(unit, EGR_PORTm, &egr_port_entry, 2772 MAC_ADDRESSf, port_mac); 2773 SOC_IF_ERROR_RETURN( 2774 WRITE_EGR_PORTm(unit, MEM_BLOCK_ALL, index, &egr_port_entry)); 2775 2776 if (SOC_IS_SABER2(unit) && soc_feature(unit, soc_feature_sat) && 2777 soc_property_get(unit, spn_SAT_ENABLE, 0)) { 2778 2779 egr_sat_config_mac_sa_entry_t sat_cfg_entry; 2780 2781 SOC_IF_ERROR_RETURN( 2782 READ_EGR_SAT_CONFIG_MAC_SAm(unit, MEM_BLOCK_ANY, index, &sat_cfg_entry)); 2783 2784 soc_mem_field64_set(unit, EGR_SAT_CONFIG_MAC_SAm, &sat_cfg_entry, MAC_ADDRESSf, port_mac); 2785 2786 SOC_IF_ERROR_RETURN( 2787 WRITE_EGR_SAT_CONFIG_MAC_SAm(unit, MEM_BLOCK_ALL, index, &sat_cfg_entry)); 2788 } 2789 return BCM_E_NONE; 2790 } 2791 2792 /* 2793 * Function: 2794 * _bcm_kt2_port_mac_get 2795 * Description: 2796 * configure port table mac address 2797 * Parameters: 2798 * unit - (IN) BCM device number 2799 * port - (IN) Port number if valid. 2800 * port_mac - (OUT) 64 bit mac address 2801 * Return Value: 2802 * BCM_E_XXX 2803 */ 2804 int 2805 _bcm_kt2_port_mac_get(int unit, bcm_port_t port, uint64 *port_mac) 2806 { 2807 port_tab_entry_t ptab; 2808 int index; /* Entry index. */ 2809 bcm_module_t module_id; /* Module ID */ 2810 bcm_port_t port_id; /* Port ID. */ 2811 bcm_trunk_t trunk_id; /* Trunk ID. */ 2812 int local_id; /* Hardware ID. */ 2813 int rv; 2814 2815 /* Get index to PORT table from source port */ 2816 if (BCM_GPORT_IS_SET(port)) { 2817 rv = _bcm_esw_gport_resolve(unit, port, &module_id, 2818 &port_id, &trunk_id, &local_id); 2819 if (BCM_FAILURE(rv)) { 2820 return (rv); 2821 } 2822 rv = _bcm_kt2_modport_to_pp_port_get(unit, module_id, port_id, 2823 &index); 2824 if (BCM_FAILURE(rv)) { 2825 return (rv); 2826 } 2827 } else { 2828 index = port; 2829 } 2830 2831 SOC_IF_ERROR_RETURN( 2832 READ_PORT_TABm(unit, MEM_BLOCK_ANY, index, &ptab)); 2833 2834 soc_mem_field64_get(unit, PORT_TABm, &ptab, MAC_ADDRESSf, port_mac); 2835 2836 return BCM_E_NONE; 2837 } 2838 2839 /* 2840 * Function: 2841 * _bcm_kt2_subport_pbmp_update 2842 * Description: 2843 * given a pbmp, add linkphy/subtag pp_port pbmp and 2844 * remove linkphy/subtag port pbmp 2845 * Parameters: 2846 * unit - (IN) BCM device number 2847 * pbmp - (IN/OUT) port bit map 2848 */ 2849 2850 void 2851 _bcm_kt2_subport_pbmp_update(int unit, bcm_pbmp_t *pbmp) 2852 { 2853 BCM_PBMP_OR(*pbmp, SOC_INFO(unit).linkphy_pp_port_pbm); 2854 BCM_PBMP_OR(*pbmp, SOC_INFO(unit).subtag_pp_port_pbm); 2855 BCM_PBMP_OR(*pbmp, SOC_INFO(unit).general_pp_port_pbm); 2856 return; 2857 } 2858 2859 /* 2860 * Function: 2861 * _bcm_kt2_flexio_pbmp_update 2862 * Description: 2863 * given a pbmp, add flexio pbmp 2864 * Parameters: 2865 * unit - (IN) BCM device number 2866 * pbmp - (IN/OUT) port bit map 2867 */ 2868 2869 int 2870 bcm_kt2_flexio_pbmp_update(int unit, bcm_pbmp_t *pbmp) 2871 { 2872 bcm_port_t first_port, mxqblk_port; 2873 int mxqblk, blk_idx; 2874 2875 if (NULL == pbmp) { 2876 return BCM_E_PORT; 2877 } 2878 for (mxqblk = 0; mxqblk < (KT2_MAX_MXQBLOCKS - 1); mxqblk++) { 2879 /* Get first port in each MXQ block */ 2880 first_port = (*kt2_mxqblock_ports[unit])[mxqblk][0]; 2881 if (SOC_PORT_TYPE(unit, first_port) == SOC_BLK_MXQPORT) { 2882 /* Add the mxqport at index 1, 2, & 3 to gven pbmp and update the 2883 * port_type so that it is treated as valid port*/ 2884 for (blk_idx = 1; blk_idx < KT2_MAX_MXQPORTS_PER_BLOCK; blk_idx++) { 2885 mxqblk_port = (*kt2_mxqblock_ports[unit])[mxqblk][blk_idx]; 2886 if (mxqblk_port < SOC_INFO(unit).lb_port) { 2887 BCM_PBMP_PORT_ADD(*pbmp, mxqblk_port); 2888 SOC_PORT_TYPE(unit, mxqblk_port) = SOC_BLK_MXQPORT; 2889 } 2890 } 2891 } 2892 } 2893 return BCM_E_NONE; 2894 } 2895 2896 int 2897 _bcm_kt2_flexio_pbmp_update(int unit, bcm_pbmp_t *pbmp) 2898 { 2899 2900 #if defined(BCM_METROLITE_SUPPORT) 2901 if(SOC_IS_METROLITE(unit)) { 2902 BCM_IF_ERROR_RETURN(bcm_ml_flexio_pbmp_update(unit, pbmp)); 2903 } else 2904 #endif 2905 #if defined(BCM_SABER2_SUPPORT) 2906 if(SOC_IS_SABER2(unit)) { 2907 BCM_IF_ERROR_RETURN(bcm_sb2_flexio_pbmp_update(unit, pbmp)); 2908 } else 2909 #endif 2910 if (SOC_IS_KATANA2(unit)) { 2911 BCM_IF_ERROR_RETURN(bcm_kt2_flexio_pbmp_update(unit, pbmp)); 2912 } 2913 return SOC_E_NONE; 2914 } 2915 2916 /* 2917 * Function: 2918 * _bcm_kt2_source_trunk_map_set 2919 * Description: 2920 * Helper funtion to modify fields in SOURCE_TRUNK_MAP memory. 2921 * Parameters: 2922 * unit - Device number 2923 * port - Port number 2924 * field - Field name within SOURCE_TRUNK_MAP table entry 2925 * value - new field value 2926 * Return Value: 2927 * BCM_E_XXX 2928 */ 2929 2930 int 2931 _bcm_kt2_source_trunk_map_set(int unit, bcm_port_t port, 2932 soc_field_t field, uint32 value) 2933 { 2934 bcm_module_t modid; 2935 int index; 2936 2937 BCM_IF_ERROR_RETURN( 2938 _bcm_kt2_pp_port_to_modport_get(unit, port, &modid, &port)); 2939 2940 /* Port sanity check. */ 2941 if (!SOC_PORT_ADDRESSABLE(unit, port)) { 2942 return (BCM_E_PORT); 2943 } 2944 2945 /* Calculate table index. */ 2946 BCM_IF_ERROR_RETURN( 2947 _bcm_esw_src_mod_port_table_index_get(unit, modid, port, &index)); 2948 2949 return soc_mem_field32_modify(unit, 2950 SOURCE_TRUNK_MAP_TABLEm, index, field, value); 2951 2952 } 2953 2954 /* 2955 * Function: 2956 * _bcm_kt2_source_trunk_map_get 2957 * Description: 2958 * Helper funtion to get fields in SOURCE_TRUNK_MAP memory. 2959 * Parameters: 2960 * unit - Device number 2961 * port - Port number 2962 * field - Field name within SOURCE_TRUNK_MAP table entry 2963 * value - New field value 2964 * Return Value: 2965 * BCM_E_XXX 2966 */ 2967 2968 int 2969 _bcm_kt2_source_trunk_map_get(int unit, bcm_port_t port, 2970 soc_field_t field, uint32 *value) 2971 { 2972 uint32 buf[SOC_MAX_MEM_FIELD_WORDS]; 2973 bcm_module_t modid; 2974 int index; 2975 2976 /* Input parameters check */ 2977 if (NULL == value) { 2978 return (BCM_E_PARAM); 2979 } 2980 2981 /* Memory field is valid check. */ 2982 if (!SOC_MEM_FIELD_VALID(unit, SOURCE_TRUNK_MAP_TABLEm, field)) { 2983 return (BCM_E_UNAVAIL); 2984 } 2985 2986 BCM_IF_ERROR_RETURN( 2987 _bcm_kt2_pp_port_to_modport_get(unit, port, &modid, &port)); 2988 2989 /* Port sanity check. */ 2990 if (!SOC_PORT_ADDRESSABLE(unit, port)) { 2991 return (BCM_E_PORT); 2992 } 2993 2994 /* Get table index. */ 2995 BCM_IF_ERROR_RETURN( 2996 _bcm_esw_src_mod_port_table_index_get(unit, modid, port, &index)); 2997 2998 if ((index > soc_mem_index_max(unit, SOURCE_TRUNK_MAP_TABLEm)) || 2999 (index < soc_mem_index_min(unit, SOURCE_TRUNK_MAP_TABLEm))) { 3000 return (BCM_E_INTERNAL); 3001 } 3002 3003 /* Read table entry. */ 3004 BCM_IF_ERROR_RETURN 3005 (soc_mem_read(unit, SOURCE_TRUNK_MAP_TABLEm, MEM_BLOCK_ANY, index, buf)); 3006 3007 /* Read requested field value. */ 3008 *value = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, buf, field); 3009 3010 return (BCM_E_NONE); 3011 3012 } 3013 3014 /* 3015 * Function: 3016 * _bcm_kt2_trunk_table_read 3017 * Purpose: 3018 * Read trunk table entry and parse it to common 3019 * (bcm_port_cfg_t) structure. 3020 * Parameters: 3021 * unit - (IN)SOC unit number. 3022 * port - (IN)Port number. 3023 * tid - (OUT)Trunk group ID. 3024 * Returns: 3025 * BCM_E_XXX 3026 */ 3027 int 3028 _bcm_kt2_trunk_table_read(int unit, bcm_port_t port, int *tid) 3029 { 3030 int modid; 3031 int src_trk_idx = 0; /*Source Trunk table index.*/ 3032 source_trunk_map_table_entry_t trunk_map_entry;/*Trunk table entry buffer.*/ 3033 3034 BCM_IF_ERROR_RETURN( 3035 _bcm_kt2_pp_port_to_modport_get(unit, port, &modid, &port)); 3036 3037 /* Port sanity check. */ 3038 if (!SOC_PORT_ADDRESSABLE(unit, port)) { 3039 return (BCM_E_PORT); 3040 } 3041 3042 /* Get index to source trunk map table */ 3043 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, modid, 3044 port, &src_trk_idx)); 3045 3046 /* Read source trunk map table. */ 3047 SOC_IF_ERROR_RETURN (BCM_XGS3_MEM_READ(unit, SOURCE_TRUNK_MAP_TABLEm, 3048 src_trk_idx, &trunk_map_entry)); 3049 3050 /* Get trunk group id. */ 3051 *tid = 0; 3052 if (1 == soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 3053 &trunk_map_entry, PORT_TYPEf)) { 3054 *tid = soc_mem_field32_get(unit, SOURCE_TRUNK_MAP_TABLEm, 3055 &trunk_map_entry, TGIDf); 3056 } 3057 3058 return (BCM_E_NONE); 3059 } 3060 3061 /* 3062 * Function: 3063 * _bcm_kt2_trunk_table_write 3064 * Purpose: 3065 * Write trunk table entry. 3066 * Parameters: 3067 * unit - (IN)SOC unit number. 3068 * port - (IN)Port number. 3069 * tid - (IN)Trunk group ID. 3070 * Returns: 3071 * BCM_E_XXX 3072 */ 3073 int 3074 _bcm_kt2_trunk_table_write(int unit, bcm_port_t port, int tid) 3075 { 3076 int rv; 3077 int tgid; 3078 int port_type; 3079 int modid; 3080 int src_trk_idx = 0; /*Source Trunk table index.*/ 3081 source_trunk_map_table_entry_t trunk_map_entry;/*Trunk table entry buffer.*/ 3082 3083 if (tid != BCM_TRUNK_INVALID) { 3084 tgid = tid; 3085 port_type = 1; 3086 } else { 3087 tgid = 0; 3088 port_type = 0; 3089 } 3090 3091 BCM_IF_ERROR_RETURN( 3092 _bcm_kt2_pp_port_to_modport_get(unit, port, &modid, &port)); 3093 3094 /* Port sanity check. */ 3095 if (!SOC_PORT_ADDRESSABLE(unit, port)) { 3096 return (BCM_E_PORT); 3097 } 3098 3099 /* Get index to source trunk map table */ 3100 BCM_IF_ERROR_RETURN(_bcm_esw_src_mod_port_table_index_get(unit, modid, 3101 port, &src_trk_idx)); 3102 3103 soc_mem_lock(unit, SOURCE_TRUNK_MAP_TABLEm); 3104 3105 /* Read source trunk map table. */ 3106 rv = BCM_XGS3_MEM_READ(unit, SOURCE_TRUNK_MAP_TABLEm, 3107 src_trk_idx, &trunk_map_entry); 3108 if (BCM_FAILURE(rv)) { 3109 soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm); 3110 return rv; 3111 } 3112 3113 /* Set trunk group id. */ 3114 soc_mem_field32_set(unit, SOURCE_TRUNK_MAP_TABLEm, &trunk_map_entry, 3115 TGIDf, tgid); 3116 3117 /* Set port is part of trunk flag. */ 3118 soc_mem_field32_set(unit, SOURCE_TRUNK_MAP_TABLEm, &trunk_map_entry, 3119 PORT_TYPEf, port_type); 3120 3121 /* Write entry to hw. */ 3122 rv = BCM_XGS3_MEM_WRITE(unit, SOURCE_TRUNK_MAP_TABLEm, 3123 src_trk_idx, &trunk_map_entry); 3124 3125 soc_mem_unlock(unit, SOURCE_TRUNK_MAP_TABLEm); 3126 3127 return rv; 3128 } 3129 3130 /* 3131 * Function: 3132 * bcm_kt2_port_drain_cells 3133 * Purpose: 3134 * To drain cells associated to the port. 3135 * Parameters: 3136 * unit - (IN) unit number 3137 * port - (IN) Port 3138 * Returns: 3139 * BCM_E_XXX 3140 */ 3141 int bcm_kt2_port_drain_cells(int unit, int port) 3142 { 3143 mac_driver_t *macd; 3144 int rv = BCM_E_NONE; 3145 3146 /* Call Port Control module */ 3147 if (SOC_USE_PORTCTRL(unit)) { 3148 return bcmi_esw_portctrl_egress_queue_drain(unit, port); 3149 } 3150 3151 PORT_LOCK(unit); 3152 rv = soc_mac_probe(unit, port, &macd); 3153 3154 if (BCM_SUCCESS(rv)) { 3155 rv = MAC_CONTROL_SET(macd, unit, port, SOC_MAC_CONTROL_EGRESS_DRAIN, 1); 3156 3157 } 3158 PORT_UNLOCK(unit); 3159 return rv; 3160 } 3161 3162 /************ E2EFC CODE START *************************/ 3163 3164 #define E2EFC_REMOTE_MODE_VALID(_m_) \ 3165 do { \ 3166 if ((_m_) != bcmPortE2efcModeTx && (_m_) != bcmPortE2efcModeRx) { \ 3167 return BCM_E_UNAVAIL; \ 3168 } \ 3169 } while (0) 3170 #define KT2_BYTE2CELL(_a_) ((_a_ + 192) / 192) 3171 3172 #define KT2_CELL2BYTE(_a_) ((_a_) * 192) 3173 3174 #define KT2_E2EFC_PBM2BINDEX(_a_) \ 3175 do { \ 3176 switch (_a_) \ 3177 { \ 3178 case 1: \ 3179 (_a_) = 1; \ 3180 break; \ 3181 case 2: \ 3182 (_a_) = 2; \ 3183 break; \ 3184 case 4: \ 3185 (_a_) = 3; \ 3186 break; \ 3187 case 8: \ 3188 (_a_) = 4; \ 3189 break; \ 3190 default: \ 3191 return BCM_E_PARAM; \ 3192 } \ 3193 } while (0) 3194 3195 #define KT2_E2EFC_RMOD_NUM 4 3196 #define KT2_E2EFC_MODULE_HDR_LEN 2 3197 #define KT2_PORT_BLOCK_ENT_NUM 4 3198 #define KT2_PORT_BLOCK_INIT_NUM 6 3199 3200 STATIC const soc_field_t e2efc_rmod_id_field[KT2_E2EFC_RMOD_NUM] = { 3201 RMOD_ID0f, RMOD_ID1f, RMOD_ID2f, RMOD_ID3f}; 3202 STATIC const soc_reg_t 3203 e2efc_rmod_id_reg[bcmPortE2efcModeCount][KT2_E2EFC_RMOD_NUM] = { 3204 {E2EFC_TX_RMODID_0r, E2EFC_TX_RMODID_0r, 3205 E2EFC_TX_RMODID_1r, E2EFC_TX_RMODID_1r}, 3206 {E2EFC_RX_RMODID_0r, E2EFC_RX_RMODID_0r, 3207 E2EFC_RX_RMODID_1r, E2EFC_RX_RMODID_1r}}; 3208 STATIC const soc_field_t e2efc_rmod_enabled[KT2_E2EFC_RMOD_NUM] = { 3209 V0f, V1f, V2f, V3f}; 3210 3211 STATIC const soc_reg_t 3212 e2efc_module_hdr_reg[KT2_E2EFC_MODULE_HDR_LEN] = 3213 {XLMAC_E2EFC_MODULE_HDR_0r, XLMAC_E2EFC_MODULE_HDR_1r}; 3214 3215 STATIC int 3216 kt2_e2efc_remote_port_num(int unit) 3217 { 3218 #if defined(BCM_SABER2_SUPPORT) 3219 if (SOC_IS_SABER2(unit)) { 3220 return 24; 3221 } 3222 #endif 3223 return 48; 3224 } 3225 3226 /* 3227 * Description: 3228 * Enable and configure the remote module to apply E2EFC mechanism. 3229 * Or disable it. 3230 * Parameter: 3231 * unit - (IN) unit number 3232 * remote_module - (IN) remote module id 3233 * mode - (IN) selected mode 3234 * enable - (IN) enable or disable selection 3235 * e2efc_rmod_cfg - (IN) structure containing the configuration. 3236 * Ignored when enable = 0. 3237 */ 3238 int 3239 bcmi_kt2_port_e2efc_remote_module_enable_set( 3240 int unit, 3241 bcm_module_t remote_module, 3242 bcm_port_e2efc_mode_t mode, 3243 int enable, 3244 bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg) 3245 { 3246 bcm_port_t local_port; 3247 uint32 val; 3248 bcm_module_t remote_module_clear = 0; 3249 int modid, i, blk, bindex, blk_num, port_mode; 3250 3251 /* XLMAC Related Parameters */ 3252 uint32 hdr_0_lo, hdr_0_hi, hdr_1_lo, hdr_1_hi; 3253 uint32 src_mod, dest_mod, src_port; 3254 int time_unit_sel, time_units, value_a, value_b; 3255 uint32 val_min, val_max, new_pbm = 0; 3256 #if defined(BCM_SABER2_SUPPORT) 3257 uint64 val_64; 3258 int hdr_0 = 0, hdr_1 = 1; 3259 #endif 3260 3261 E2EFC_REMOTE_MODE_VALID(mode); 3262 /* Check the remote module id is in the valid range or not */ 3263 if (!SOC_MODID_ADDRESSABLE(unit, remote_module)) { 3264 LOG_ERROR(BSL_LS_BCM_PORT, 3265 (BSL_META_U(unit, 3266 "Invalid remote module ID.\n"))); 3267 return BCM_E_BADID; 3268 } 3269 3270 if (e2efc_rmod_cfg == NULL) { 3271 LOG_ERROR(BSL_LS_BCM_PORT, 3272 (BSL_META_U(unit, 3273 "Null Remote Module Configuration.\n"))); 3274 return BCM_E_PARAM; 3275 } 3276 3277 /* Check the logical port is in the right range */ 3278 if (e2efc_rmod_cfg->local_port < 0 || 3279 e2efc_rmod_cfg->local_port >= MAX_PORT(unit)) { 3280 LOG_ERROR(BSL_LS_BCM_PORT, 3281 (BSL_META_U(unit, 3282 "Invalid Port Range. Should be >= 0 && < %d\n"), 3283 MAX_PORT(unit))); 3284 return BCM_E_PARAM; 3285 } 3286 3287 if (enable == 1) { 3288 /* Search whether the existing remote module ID exist */ 3289 for (i = 0; i < KT2_E2EFC_RMOD_NUM; i++) { 3290 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_reg[mode][i], 3291 REG_PORT_ANY, 0, &val)); 3292 if (remote_module == (soc_reg_field_get( 3293 unit, e2efc_rmod_id_reg[mode][i], val, 3294 e2efc_rmod_id_field[i]))) { 3295 LOG_ERROR(BSL_LS_BCM_PORT, 3296 (BSL_META_U(unit, 3297 "Remote Module ID already exists.\n"))); 3298 return BCM_E_EXISTS; 3299 } 3300 } 3301 /* Traverse 4 remote module id and setup the one that is not enabled */ 3302 modid = -1; 3303 for (i = 0; i < KT2_E2EFC_RMOD_NUM; i++) { 3304 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_reg[mode][i], 3305 REG_PORT_ANY, 0, &val)); 3306 if (!(soc_reg_field_get(unit, e2efc_rmod_id_reg[mode][i], val, 3307 e2efc_rmod_enabled[i]))) { 3308 soc_reg_field_set(unit, e2efc_rmod_id_reg[mode][i], &val, 3309 e2efc_rmod_id_field[i], remote_module); 3310 soc_reg_field_set(unit, e2efc_rmod_id_reg[mode][i], &val, 3311 e2efc_rmod_enabled[i], enable); 3312 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, 3313 e2efc_rmod_id_reg[mode][i], 3314 REG_PORT_ANY, 0, val)); 3315 modid = i; 3316 break; 3317 } 3318 } 3319 if (modid == -1 ) { 3320 LOG_ERROR(BSL_LS_BCM_PORT, 3321 (BSL_META_U(unit, 3322 "E2EFC No Available Remote.Module to Setup" 3323 "Maximun 4 Remote Module only.\n"))); 3324 return BCM_E_FULL; 3325 } 3326 /* Set up Higig Port and Port Speed Information */ 3327 if (mode == bcmPortE2efcModeTx) { 3328 /* Higig port setting */ 3329 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate( 3330 unit, e2efc_rmod_cfg->local_port, 3331 &local_port)); 3332 if (!IS_HG_PORT(unit, local_port)) { 3333 LOG_ERROR( 3334 BSL_LS_BCM_PORT, 3335 (BSL_META_U(unit, 3336 "Error: unit %d port %d is not a Higig port. " 3337 "E2EFC messages can only be transmitted to " 3338 "or received from Higig ports.\n"), 3339 unit, local_port)); 3340 return BCM_E_PARAM; 3341 3342 } 3343 /* Register E2EFC_RMOD_CFG fill in */ 3344 3345 blk = SOC_PORT_BLOCK(unit, local_port); 3346 bindex = SOC_PORT_BINDEX(unit, local_port); 3347 3348 blk_num = SOC_BLOCK_INFO(unit, blk).number; 3349 3350 blk_num = (blk_num >= 6) ? (blk_num - 6) : blk_num ; 3351 3352 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_RMOD_CFGr, 3353 REG_PORT_ANY, modid, &val)); 3354 if (soc_reg_field_valid(unit, E2EFC_RMOD_CFGr, PORT_GRP_IDf)) { 3355 soc_reg_field_set(unit, E2EFC_RMOD_CFGr, &val, 3356 PORT_GRP_IDf, blk_num); 3357 } 3358 new_pbm |= (1 << bindex); 3359 soc_reg_field_set(unit, E2EFC_RMOD_CFGr, &val, 3360 TX_ENABLE_BMPf, new_pbm); 3361 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_RMOD_CFGr, 3362 REG_PORT_ANY, modid, val)); 3363 /* XLMAC Module Header Set up */ 3364 bcm_esw_port_encap_get(unit, local_port, &port_mode); 3365 /* Higig2 Mode */ 3366 bcm_esw_stk_my_modid_get(unit, (int *)&src_mod); 3367 if (port_mode == BCM_PORT_ENCAP_HIGIG2) { 3368 /* default setting K.SOP = 0xfb, MCST = 0(unicast)*/ 3369 hdr_0_hi = 0xfb00000; 3370 dest_mod = (remote_module & 0xff) << 8; 3371 hdr_0_hi = hdr_0_hi | dest_mod; 3372 hdr_0_lo = 0x00000000; 3373 src_mod = (src_mod & 0xff) << 24; 3374 src_port = (local_port & 0xff) << 16; 3375 hdr_0_lo = hdr_0_lo | src_mod | src_port; 3376 } else { 3377 /* Higig Mode */ 3378 /* default setting K.SOP = 0xfb, HGI = 8, VID = 1 */ 3379 hdr_0_hi = 0xfb800001; 3380 src_mod = (src_mod & 0x2f) << 27; 3381 dest_mod = remote_module & 0xff; 3382 /* default setting OPCODE = 1, COS = 7 */ 3383 hdr_0_lo = 0x01000701 | src_mod | dest_mod; 3384 } 3385 3386 if (!IS_XL_PORT(unit, local_port)) { 3387 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_MH0r, local_port, 0, &val)); 3388 soc_reg_field_set(unit, XIBP_MH0r, &val, MH_BYTES_0_3f, hdr_0_lo); 3389 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_MH0r, local_port, 0, val)); 3390 3391 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_MH1r, local_port, 0, &val)); 3392 soc_reg_field_set(unit, XIBP_MH1r, &val, MH_BYTES_4_7f, hdr_0_hi); 3393 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_MH1r, local_port, 0, val)); 3394 } 3395 #if defined(BCM_SABER2_SUPPORT) 3396 if(SOC_IS_SABER2(unit)) { 3397 BCM_IF_ERROR_RETURN( 3398 soc_reg64_get(unit, e2efc_module_hdr_reg[hdr_0], 3399 local_port, 0, &val_64)); 3400 soc_reg64_field32_set(unit, e2efc_module_hdr_reg[hdr_0], 3401 &val_64, E2EFC_MODULE_HDR_0_LOf, hdr_0_lo); 3402 soc_reg64_field32_set(unit, e2efc_module_hdr_reg[hdr_0], 3403 &val_64, E2EFC_MODULE_HDR_0_HIf, hdr_0_hi); 3404 BCM_IF_ERROR_RETURN( 3405 soc_reg64_set(unit, e2efc_module_hdr_reg[hdr_0], 3406 local_port, 0, val_64)); 3407 } 3408 #endif 3409 if (port_mode == BCM_PORT_ENCAP_HIGIG2) { 3410 /* default setting vlan = 1, opcode = 1 */ 3411 hdr_1_lo = 0x00010100; 3412 hdr_1_hi = 0x00000000; 3413 } else { 3414 hdr_1_lo = 0x00000000; 3415 hdr_1_hi = 0x00000000; 3416 } 3417 #if defined(BCM_SABER2_SUPPORT) 3418 if(SOC_IS_SABER2(unit)) { 3419 BCM_IF_ERROR_RETURN( 3420 soc_reg64_get(unit, e2efc_module_hdr_reg[hdr_1], 3421 local_port, 0, &val_64)); 3422 soc_reg64_field32_set(unit, e2efc_module_hdr_reg[hdr_1], 3423 &val_64, E2EFC_MODULE_HDR_1_LOf, hdr_1_lo); 3424 soc_reg64_field32_set(unit, e2efc_module_hdr_reg[hdr_1], 3425 &val_64, E2EFC_MODULE_HDR_1_HIf, 3426 hdr_1_hi); 3427 BCM_IF_ERROR_RETURN( 3428 soc_reg64_set(unit, e2efc_module_hdr_reg[hdr_1], 3429 local_port, 0, val_64)); 3430 } else 3431 #endif 3432 { 3433 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_MH2r, local_port, 0, &val)); 3434 soc_reg_field_set(unit, XIBP_MH2r, &val, MH_BYTES_8_11f, hdr_1_lo); 3435 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_MH2r, local_port, 0, val)); 3436 3437 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, XIBP_MH3r, local_port, 0, &val)); 3438 soc_reg_field_set(unit, XIBP_MH3r, &val, MH_BYTES_12_15f, hdr_1_hi); 3439 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, XIBP_MH3r, local_port, 0, val)); 3440 } 3441 /* In the absence of congestion, an E2EFC message is still 3442 * generated to refresh congestion status when the E2EFC max 3443 * timer expires. This timer is specified in units of 250ns or 3444 * 25us, and up to 1023 time units can be specified. 3445 * The selection of time unit and the number of time units 3446 * is computed as follows: 3447 * 3448 * Let E2EFC message refresh rate = N messages/sec, and N != 0, 3449 * A = # of 250ns time units = 1 sec / N / 250ns = 4000000 / N, 3450 * B = # of 25us time units = 1 sec / N / 25us = 3451 * 40000 / N = A / 100. 3452 * 3453 * If A < 1, configure the minimum allowed timer value: 3454 * time unit = 250ns, # of time units = 1. 3455 * 3456 * If A is between 1 and 1023, configure the timer as: 3457 * time unit = 250ns, # of time units = A. 3458 * 3459 * If A > 1023 and B <= 1023, configure the timer as: 3460 * time unit = 25us, # of time units = B. 3461 * 3462 * If B > 1023, configure the maximum allowed timer value: 3463 * time unit = 25us, # of time units = 1023. 3464 * 3465 * Note: If N = 0, # of time units will be set to 0, and E2EFC 3466 * message refresh is effectively disabled. E2ECC message 3467 * will be generated only when there is a change in congestion 3468 * status. 3469 */ 3470 3471 if (e2efc_rmod_cfg->pkt_per_second == 0) { 3472 time_unit_sel = 0; 3473 time_units = 0; 3474 } else { 3475 value_a = 4000000 / e2efc_rmod_cfg->pkt_per_second; 3476 value_b = value_a / 100; 3477 if (value_a < 1) { 3478 time_unit_sel = 0; 3479 time_units = 1; 3480 } else if (value_a <= 1023) { 3481 time_unit_sel = 0; 3482 time_units = value_a; 3483 } else if ((value_a > 1023) && (value_b <= 1023)) { 3484 time_unit_sel = 1; 3485 time_units = value_b; 3486 } else { /* value_b > 1023 */ 3487 time_unit_sel = 1; 3488 time_units = 1023; 3489 } 3490 } 3491 /* E2EFC meesage trasmit period setup */ 3492 /* For Min TX Timer */ 3493 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_MIN_TX_TIMERr, 3494 REG_PORT_ANY, modid, &val_min)); 3495 soc_reg_field_set(unit, E2EFC_MIN_TX_TIMERr, &val_min, 3496 LGf, time_unit_sel); 3497 soc_reg_field_set(unit, E2EFC_MIN_TX_TIMERr, &val_min, 3498 TIMERf, time_units); 3499 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_MIN_TX_TIMERr, 3500 REG_PORT_ANY, modid, val_min)); 3501 /* For Max TX Timer */ 3502 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_MAX_TX_TIMERr, 3503 REG_PORT_ANY, modid, &val_max)); 3504 soc_reg_field_set(unit, E2EFC_MAX_TX_TIMERr, &val_max, 3505 LGf, time_unit_sel); 3506 soc_reg_field_set(unit, E2EFC_MAX_TX_TIMERr, &val_max, 3507 TIMERf, time_units); 3508 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_MAX_TX_TIMERr, 3509 REG_PORT_ANY, modid, val_max)); 3510 } else { 3511 LOG_VERBOSE(BSL_LS_BCM_PORT, 3512 (BSL_META_U(unit, 3513 "E2EFC RX mode not allowed to configure timer" 3514 " and XLMAC and HG port setup.\n"))); 3515 } 3516 } else { 3517 /* Traverse 4 rmod id and clear the one that match rmod id */ 3518 modid = -1; 3519 for (i = 0; i < KT2_E2EFC_RMOD_NUM; i++) { 3520 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_reg[mode][i], 3521 REG_PORT_ANY, 0, &val)); 3522 if (remote_module == (soc_reg_field_get( 3523 unit, e2efc_rmod_id_reg[mode][i], val, 3524 e2efc_rmod_id_field[i]))) { 3525 soc_reg_field_set(unit, e2efc_rmod_id_reg[mode][i], &val, 3526 e2efc_rmod_id_field[i], remote_module_clear); 3527 soc_reg_field_set(unit, e2efc_rmod_id_reg[mode][i], &val, 3528 e2efc_rmod_enabled[i], 0); 3529 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, 3530 e2efc_rmod_id_reg[mode][i], 3531 REG_PORT_ANY, 0, val)); 3532 modid = i; 3533 break; 3534 } 3535 } 3536 if (modid == -1 ) { 3537 LOG_ERROR(BSL_LS_BCM_PORT, 3538 (BSL_META_U(unit, 3539 "E2EFC No Existing Remote.Module to Clear" 3540 "Maximun 4 Remote Module only.\n"))); 3541 return BCM_E_NOT_FOUND; 3542 } 3543 } 3544 3545 return BCM_E_NONE; 3546 } 3547 3548 3549 /* 3550 * Description: 3551 * Get the enable mode and configuration of the remote module that 3552 * applies E2EFC mechanism. 3553 * Parameter: 3554 * unit - (IN) unit number 3555 * remote_module - (IN) remote module id 3556 * mode - (IN) selected mode 3557 * enable - (OUT) enable or disable selection 3558 * e2efc_rmod_cfg - (OUT) structure containing the configuration. 3559 * Only valid if the remote module is enabled. 3560 */ 3561 int 3562 bcmi_kt2_port_e2efc_remote_module_enable_get( 3563 int unit, 3564 bcm_module_t remote_module, 3565 bcm_port_e2efc_mode_t mode, 3566 int *enable, 3567 bcm_port_e2efc_remote_module_config_t *e2efc_rmod_cfg) 3568 { 3569 uint32 val, val_p, val_t; 3570 int i, time_unit_sel, time_units; 3571 int blk_num, pbm, phy_port = 0, log_port = 0; 3572 3573 E2EFC_REMOTE_MODE_VALID(mode); 3574 3575 /* Check the remote module id is in the valid range or not */ 3576 if (!SOC_MODID_ADDRESSABLE(unit, remote_module)) { 3577 LOG_ERROR(BSL_LS_BCM_PORT, 3578 (BSL_META_U(unit, 3579 "Invalid remote module ID.\n"))); 3580 return BCM_E_BADID; 3581 } 3582 3583 if (enable == NULL || e2efc_rmod_cfg == NULL) { 3584 return BCM_E_PARAM; 3585 } 3586 3587 /* Check the logical port is in the right range */ 3588 if (e2efc_rmod_cfg->local_port < 0 || 3589 e2efc_rmod_cfg->local_port >= MAX_PORT(unit)) { 3590 LOG_ERROR(BSL_LS_BCM_PORT, 3591 (BSL_META_U(unit, 3592 "Invalid Port Range. Should be >= 0 && < %d\n"), 3593 MAX_PORT(unit))); 3594 return BCM_E_PARAM; 3595 } 3596 3597 /* if the matched rmod id is not found then the "enable" is zero */ 3598 *enable = 0; 3599 /* 3600 * Only Mode TX has the bcm_port_e2efc_remote_module_config_t 3601 * configuration, so if mode == RX, the get API will check whether the 3602 * remote_module exists and return enable value. 3603 */ 3604 /* Traverse 4 rmod id and search the one that match rmod id */ 3605 for (i = 0; i < KT2_E2EFC_RMOD_NUM; i++) { 3606 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_reg[mode][i], 3607 REG_PORT_ANY, 0, &val)); 3608 if (remote_module == (soc_reg_field_get(unit, 3609 e2efc_rmod_id_reg[mode][i], val, 3610 e2efc_rmod_id_field[i]))) { 3611 if (mode == bcmPortE2efcModeTx) { 3612 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_RMOD_CFGr, 3613 REG_PORT_ANY, i, &val_p)); 3614 if (soc_reg_field_valid(unit, E2EFC_RMOD_CFGr, PORT_GRP_IDf)) { 3615 3616 blk_num = soc_reg_field_get(unit, E2EFC_RMOD_CFGr, val_p, 3617 PORT_GRP_IDf); 3618 } else { 3619 blk_num = 0; 3620 } 3621 pbm = soc_reg_field_get(unit, E2EFC_RMOD_CFGr, val_p, 3622 TX_ENABLE_BMPf); 3623 KT2_E2EFC_PBM2BINDEX(pbm); 3624 phy_port = (blk_num * KT2_PORT_BLOCK_ENT_NUM) + pbm 3625 + KT2_PORT_BLOCK_INIT_NUM; 3626 log_port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 3627 e2efc_rmod_cfg->local_port = log_port; 3628 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_MIN_TX_TIMERr, 3629 REG_PORT_ANY, i, &val_t)); 3630 time_unit_sel = 3631 soc_reg_field_get(unit, E2EFC_MIN_TX_TIMERr, 3632 val_t, LGf); 3633 time_units = 3634 soc_reg_field_get(unit, E2EFC_MIN_TX_TIMERr, 3635 val_t, TIMERf); 3636 if (time_units == 0) { 3637 e2efc_rmod_cfg->pkt_per_second = 0; 3638 } else if (time_unit_sel == 1) { 3639 /* pkt_per_second = 1 / 25us / time_units */ 3640 e2efc_rmod_cfg->pkt_per_second = 40000 / time_units; 3641 } else { 3642 /* pkt_per_second = 1 / 250ns / time_units */ 3643 e2efc_rmod_cfg->pkt_per_second = 4000000 / time_units; 3644 } 3645 } 3646 *enable = 1; 3647 break; 3648 } 3649 } 3650 return BCM_E_NONE; 3651 } 3652 3653 /* helper function to search the remote module pointer */ 3654 int 3655 bcmi_kt2_e2efc_remote_module_ptr_get( 3656 int unit, 3657 bcm_module_t remote_module, 3658 int *module_ptr) 3659 { 3660 int i, ptr; 3661 uint32 val; 3662 bcm_port_e2efc_mode_t mode = bcmPortE2efcModeTx; 3663 3664 if (module_ptr == NULL) { 3665 return BCM_E_PARAM; 3666 } 3667 /* Check the remote module id is in the valid range or not */ 3668 if (!SOC_MODID_ADDRESSABLE(unit, remote_module)) { 3669 LOG_ERROR(BSL_LS_BCM_PORT, 3670 (BSL_META_U(unit, 3671 "Invalid remote module ID.\n"))); 3672 return BCM_E_BADID; 3673 } 3674 3675 ptr = -1; 3676 for (i = 0; i < KT2_E2EFC_RMOD_NUM; i++) { 3677 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_reg[mode][i], 3678 REG_PORT_ANY, 0, &val)); 3679 if (remote_module == (soc_reg_field_get( 3680 unit, e2efc_rmod_id_reg[mode][i], val, 3681 e2efc_rmod_id_field[i]))) { 3682 ptr = i; 3683 break; 3684 } 3685 } 3686 if (ptr == -1) { 3687 LOG_ERROR(BSL_LS_BCM_PORT, 3688 (BSL_META_U(unit, 3689 "Remote module ID not found.\n"))); 3690 return BCM_E_NOT_FOUND; 3691 } else { 3692 *module_ptr = ptr; 3693 } 3694 return BCM_E_NONE; 3695 } 3696 3697 /* helper function to search the remote module id */ 3698 int 3699 bcmi_kt2_e2efc_remote_module_id_get( 3700 int unit, 3701 int module_ptr, 3702 bcm_module_t *remote_module) 3703 { 3704 uint32 val; 3705 bcm_port_e2efc_mode_t mode = bcmPortE2efcModeTx; 3706 3707 if (remote_module == NULL) { 3708 return BCM_E_PARAM; 3709 } 3710 3711 if (module_ptr < 0 || module_ptr >= KT2_E2EFC_RMOD_NUM) { 3712 LOG_ERROR(BSL_LS_BCM_PORT, 3713 (BSL_META_U(unit, 3714 "Invalid remote module pointer. Should be 0~3.\n"))); 3715 return BCM_E_PARAM; 3716 } 3717 3718 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, e2efc_rmod_id_reg[mode][module_ptr], 3719 REG_PORT_ANY, 0, &val)); 3720 /* the remote moduel is enabled */ 3721 if (soc_reg_field_get(unit, 3722 e2efc_rmod_id_reg[mode][module_ptr], val, 3723 e2efc_rmod_enabled[module_ptr])) { 3724 *remote_module = (soc_reg_field_get( 3725 unit, e2efc_rmod_id_reg[mode][module_ptr], val, 3726 e2efc_rmod_id_field[module_ptr])); 3727 } else { 3728 return BCM_E_FAIL; 3729 } 3730 3731 return BCM_E_NONE; 3732 } 3733 3734 /* helper function to init E2EFC remote port */ 3735 int 3736 bcmi_kt2_port_e2efc_remote_port_init(int unit) 3737 { 3738 int i; 3739 uint32 val; 3740 3741 for (i = 0; i < kt2_e2efc_remote_port_num(unit); i++) { 3742 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr, 3743 REG_PORT_ANY, i, &val)); 3744 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val, Vf, 0); 3745 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_ATTRr, 3746 REG_PORT_ANY, i, val)); 3747 } 3748 3749 return BCM_E_NONE; 3750 } 3751 /* Helper function to configure thresholds. */ 3752 STATIC int 3753 bcmi_kt2_port_e2efc_configure_thresholds(int unit, int rport_handle_id, 3754 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg) 3755 { 3756 uint32 val_off, val_on, val_drop; 3757 int set, reset, drop; 3758 3759 switch(e2efc_rport_cfg->e2efc_resource_type) { 3760 case BCM_E2EFC_RESOURCE_TYPE_INT_MEM: 3761 set = KT2_BYTE2CELL(e2efc_rport_cfg->xoff_threshold_bytes); 3762 reset = KT2_BYTE2CELL(e2efc_rport_cfg->xon_threshold_bytes); 3763 drop = KT2_BYTE2CELL(e2efc_rport_cfg->drop_threshold_bytes); 3764 3765 BCM_IF_ERROR_RETURN(READ_E2EFCINT_CNT_SET_LIMITr(unit, rport_handle_id, &val_off)); 3766 soc_reg_field_set(unit, E2EFCINT_CNT_SET_LIMITr, &val_off, SET_LIMITf, set); 3767 BCM_IF_ERROR_RETURN(WRITE_E2EFCINT_CNT_SET_LIMITr(unit, rport_handle_id, val_off)); 3768 3769 BCM_IF_ERROR_RETURN(READ_E2EFCINT_CNT_RESET_LIMITr(unit, rport_handle_id, &val_on)); 3770 soc_reg_field_set(unit, E2EFCINT_CNT_RESET_LIMITr, &val_on, RESET_LIMITf, reset); 3771 BCM_IF_ERROR_RETURN(WRITE_E2EFCINT_CNT_RESET_LIMITr(unit, rport_handle_id, val_on)); 3772 3773 BCM_IF_ERROR_RETURN(READ_E2EFCINT_CNT_DISC_LIMITr(unit, rport_handle_id, &val_drop)); 3774 soc_reg_field_set(unit, E2EFCINT_CNT_DISC_LIMITr, &val_drop, DISC_LIMITf, drop); 3775 BCM_IF_ERROR_RETURN(WRITE_E2EFCINT_CNT_DISC_LIMITr(unit, rport_handle_id, val_drop)); 3776 break; 3777 case BCM_E2EFC_RESOURCE_TYPE_QEN: 3778 set = e2efc_rport_cfg->xoff_threshold_packets; 3779 reset = e2efc_rport_cfg->xon_threshold_packets; 3780 drop = e2efc_rport_cfg->drop_threshold_packets; 3781 3782 BCM_IF_ERROR_RETURN(READ_E2EFCQEN_CNT_SET_LIMITr(unit, rport_handle_id, &val_off)); 3783 soc_reg_field_set(unit, E2EFCQEN_CNT_SET_LIMITr, &val_off, SET_LIMITf, set); 3784 BCM_IF_ERROR_RETURN(WRITE_E2EFCQEN_CNT_SET_LIMITr(unit, rport_handle_id, val_off)); 3785 3786 BCM_IF_ERROR_RETURN(READ_E2EFCQEN_CNT_RESET_LIMITr(unit, rport_handle_id, &val_on)); 3787 soc_reg_field_set(unit, E2EFCQEN_CNT_RESET_LIMITr, &val_on, RESET_LIMITf, reset); 3788 BCM_IF_ERROR_RETURN(WRITE_E2EFCQEN_CNT_RESET_LIMITr(unit, rport_handle_id, val_on)); 3789 3790 BCM_IF_ERROR_RETURN(READ_E2EFCQEN_CNT_DISC_LIMITr(unit, rport_handle_id, &val_drop)); 3791 soc_reg_field_set(unit, E2EFCQEN_CNT_DISC_LIMITr, &val_drop, DISC_LIMITf, drop); 3792 BCM_IF_ERROR_RETURN(WRITE_E2EFCQEN_CNT_DISC_LIMITr(unit, rport_handle_id, val_drop)); 3793 break; 3794 case BCM_E2EFC_RESOURCE_TYPE_RQE: 3795 set = e2efc_rport_cfg->xoff_threshold_packets; 3796 reset = e2efc_rport_cfg->xon_threshold_packets; 3797 drop = e2efc_rport_cfg->drop_threshold_packets; 3798 3799 BCM_IF_ERROR_RETURN(READ_E2EFCRQE_CNT_SET_LIMITr(unit, rport_handle_id, &val_off)); 3800 soc_reg_field_set(unit, E2EFCRQE_CNT_SET_LIMITr, &val_off, SET_LIMITf, set); 3801 BCM_IF_ERROR_RETURN(WRITE_E2EFCRQE_CNT_SET_LIMITr(unit, rport_handle_id, val_off)); 3802 3803 BCM_IF_ERROR_RETURN(READ_E2EFCRQE_CNT_RESET_LIMITr(unit, rport_handle_id, &val_on)); 3804 soc_reg_field_set(unit, E2EFCRQE_CNT_RESET_LIMITr, &val_on, RESET_LIMITf, reset); 3805 BCM_IF_ERROR_RETURN(WRITE_E2EFCRQE_CNT_RESET_LIMITr(unit, rport_handle_id, val_on)); 3806 3807 BCM_IF_ERROR_RETURN(READ_E2EFCRQE_CNT_DISC_LIMITr(unit, rport_handle_id, &val_drop)); 3808 soc_reg_field_set(unit, E2EFCRQE_CNT_DISC_LIMITr, &val_drop, DISC_LIMITf, drop); 3809 BCM_IF_ERROR_RETURN(WRITE_E2EFCRQE_CNT_DISC_LIMITr(unit, rport_handle_id, val_drop)); 3810 break; 3811 case BCM_E2EFC_RESOURCE_TYPE_EXT_MEM: 3812 #if defined(BCM_METROLITE_SUPPORT) 3813 if (SOC_IS_METROLITE(unit)) { 3814 return BCM_E_PARAM; 3815 } 3816 #endif 3817 set = KT2_BYTE2CELL(e2efc_rport_cfg->xoff_threshold_bytes); 3818 reset = KT2_BYTE2CELL(e2efc_rport_cfg->xon_threshold_bytes); 3819 drop = KT2_BYTE2CELL(e2efc_rport_cfg->drop_threshold_bytes); 3820 3821 BCM_IF_ERROR_RETURN(READ_E2EFCEXT_CNT_SET_LIMITr(unit, rport_handle_id, &val_off)); 3822 soc_reg_field_set(unit, E2EFCEXT_CNT_SET_LIMITr, &val_off, SET_LIMITf, set); 3823 BCM_IF_ERROR_RETURN(WRITE_E2EFCEXT_CNT_SET_LIMITr(unit, rport_handle_id, val_off)); 3824 3825 BCM_IF_ERROR_RETURN(READ_E2EFCEXT_CNT_RESET_LIMITr(unit, rport_handle_id, &val_on)); 3826 soc_reg_field_set(unit, E2EFCEXT_CNT_RESET_LIMITr, &val_on, RESET_LIMITf, reset); 3827 BCM_IF_ERROR_RETURN(WRITE_E2EFCEXT_CNT_RESET_LIMITr(unit, rport_handle_id, val_on)); 3828 3829 BCM_IF_ERROR_RETURN(READ_E2EFCEXT_CNT_DISC_LIMITr(unit, rport_handle_id, &val_drop)); 3830 soc_reg_field_set(unit, E2EFCEXT_CNT_DISC_LIMITr, &val_drop, DISC_LIMITf, drop); 3831 BCM_IF_ERROR_RETURN(WRITE_E2EFCEXT_CNT_DISC_LIMITr(unit, rport_handle_id, val_drop)); 3832 break; 3833 case BCM_E2EFC_RESOURCE_TYPE_EMA: 3834 #if defined(BCM_METROLITE_SUPPORT) 3835 if (SOC_IS_METROLITE(unit)) { 3836 return BCM_E_PARAM; 3837 } 3838 #endif 3839 set = KT2_BYTE2CELL(e2efc_rport_cfg->xoff_threshold_bytes); 3840 reset = KT2_BYTE2CELL(e2efc_rport_cfg->xon_threshold_bytes); 3841 drop = KT2_BYTE2CELL(e2efc_rport_cfg->drop_threshold_bytes); 3842 3843 BCM_IF_ERROR_RETURN(READ_E2EFCEMA_CNT_SET_LIMITr(unit, rport_handle_id, &val_off)); 3844 soc_reg_field_set(unit, E2EFCEMA_CNT_SET_LIMITr, &val_off, SET_LIMITf, set); 3845 BCM_IF_ERROR_RETURN(WRITE_E2EFCEMA_CNT_SET_LIMITr(unit, rport_handle_id, val_off)); 3846 3847 BCM_IF_ERROR_RETURN(READ_E2EFCEMA_CNT_RESET_LIMITr(unit, rport_handle_id, &val_on)); 3848 soc_reg_field_set(unit, E2EFCEMA_CNT_RESET_LIMITr, &val_on, RESET_LIMITf, reset); 3849 BCM_IF_ERROR_RETURN(WRITE_E2EFCEMA_CNT_RESET_LIMITr(unit, rport_handle_id, val_on)); 3850 3851 BCM_IF_ERROR_RETURN(READ_E2EFCEMA_CNT_DISC_LIMITr(unit, rport_handle_id, &val_drop)); 3852 soc_reg_field_set(unit, E2EFCEMA_CNT_DISC_LIMITr, &val_drop, DISC_LIMITf, drop); 3853 BCM_IF_ERROR_RETURN(WRITE_E2EFCEMA_CNT_DISC_LIMITr(unit, rport_handle_id, val_drop)); 3854 break; 3855 default: 3856 return BCM_E_PARAM; 3857 } 3858 return BCM_E_NONE; 3859 } 3860 3861 /* Helper function to get thresholds. */ 3862 STATIC int 3863 bcmi_kt2_port_e2efc_get_thresholds(int unit, int rport_handle_id, 3864 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg) 3865 { 3866 uint32 val_off, val_on, val_drop; 3867 int set, reset, drop; 3868 3869 switch(e2efc_rport_cfg->e2efc_resource_type) { 3870 case BCM_E2EFC_RESOURCE_TYPE_INT_MEM: 3871 BCM_IF_ERROR_RETURN(READ_E2EFCINT_CNT_SET_LIMITr(unit, rport_handle_id, &val_off)); 3872 set = soc_reg_field_get(unit, E2EFCINT_CNT_SET_LIMITr, val_off, SET_LIMITf); 3873 BCM_IF_ERROR_RETURN(READ_E2EFCINT_CNT_RESET_LIMITr(unit, rport_handle_id, &val_on)); 3874 reset = soc_reg_field_get(unit, E2EFCINT_CNT_RESET_LIMITr, val_on, RESET_LIMITf); 3875 BCM_IF_ERROR_RETURN(READ_E2EFCINT_CNT_DISC_LIMITr(unit, rport_handle_id, &val_drop)); 3876 drop = soc_reg_field_get(unit, E2EFCINT_CNT_DISC_LIMITr, val_drop, DISC_LIMITf); 3877 3878 e2efc_rport_cfg->xoff_threshold_bytes = KT2_CELL2BYTE(set); 3879 e2efc_rport_cfg->xon_threshold_bytes = KT2_CELL2BYTE(reset); 3880 e2efc_rport_cfg->drop_threshold_bytes = KT2_CELL2BYTE(drop); 3881 break; 3882 case BCM_E2EFC_RESOURCE_TYPE_QEN: 3883 BCM_IF_ERROR_RETURN(READ_E2EFCQEN_CNT_SET_LIMITr(unit, rport_handle_id, &val_off)); 3884 set = soc_reg_field_get(unit, E2EFCQEN_CNT_SET_LIMITr, val_off, SET_LIMITf); 3885 BCM_IF_ERROR_RETURN(READ_E2EFCQEN_CNT_RESET_LIMITr(unit, rport_handle_id, &val_on)); 3886 reset = soc_reg_field_get(unit, E2EFCQEN_CNT_RESET_LIMITr, val_on, RESET_LIMITf); 3887 BCM_IF_ERROR_RETURN(READ_E2EFCQEN_CNT_DISC_LIMITr(unit, rport_handle_id, &val_drop)); 3888 drop = soc_reg_field_get(unit, E2EFCQEN_CNT_DISC_LIMITr, val_drop, DISC_LIMITf); 3889 3890 e2efc_rport_cfg->xoff_threshold_packets = set; 3891 e2efc_rport_cfg->xon_threshold_packets = reset; 3892 e2efc_rport_cfg->drop_threshold_packets = drop; 3893 break; 3894 case BCM_E2EFC_RESOURCE_TYPE_RQE: 3895 BCM_IF_ERROR_RETURN(READ_E2EFCRQE_CNT_SET_LIMITr(unit, rport_handle_id, &val_off)); 3896 set = soc_reg_field_get(unit, E2EFCRQE_CNT_SET_LIMITr, val_off, SET_LIMITf); 3897 BCM_IF_ERROR_RETURN(READ_E2EFCRQE_CNT_RESET_LIMITr(unit, rport_handle_id, &val_on)); 3898 reset = soc_reg_field_get(unit, E2EFCRQE_CNT_RESET_LIMITr, val_on, RESET_LIMITf); 3899 BCM_IF_ERROR_RETURN(READ_E2EFCRQE_CNT_DISC_LIMITr(unit, rport_handle_id, &val_drop)); 3900 drop = soc_reg_field_get(unit, E2EFCRQE_CNT_DISC_LIMITr, val_drop, DISC_LIMITf); 3901 3902 e2efc_rport_cfg->xoff_threshold_packets = set; 3903 e2efc_rport_cfg->xon_threshold_packets = reset; 3904 e2efc_rport_cfg->drop_threshold_packets = drop; 3905 break; 3906 case BCM_E2EFC_RESOURCE_TYPE_EXT_MEM: 3907 #if defined(BCM_METROLITE_SUPPORT) 3908 if (SOC_IS_METROLITE(unit)) { 3909 return BCM_E_PARAM; 3910 } 3911 #endif 3912 3913 BCM_IF_ERROR_RETURN(READ_E2EFCEXT_CNT_SET_LIMITr(unit, rport_handle_id, &val_off)); 3914 set = soc_reg_field_get(unit, E2EFCEXT_CNT_SET_LIMITr, val_off, SET_LIMITf); 3915 BCM_IF_ERROR_RETURN(READ_E2EFCEXT_CNT_RESET_LIMITr(unit, rport_handle_id, &val_on)); 3916 reset = soc_reg_field_get(unit, E2EFCEXT_CNT_RESET_LIMITr, val_on, RESET_LIMITf); 3917 BCM_IF_ERROR_RETURN(READ_E2EFCEXT_CNT_DISC_LIMITr(unit, rport_handle_id, &val_drop)); 3918 drop = soc_reg_field_get(unit, E2EFCEXT_CNT_DISC_LIMITr, val_drop, DISC_LIMITf); 3919 3920 e2efc_rport_cfg->xoff_threshold_bytes = KT2_CELL2BYTE(set); 3921 e2efc_rport_cfg->xon_threshold_bytes = KT2_CELL2BYTE(reset); 3922 e2efc_rport_cfg->drop_threshold_bytes = KT2_CELL2BYTE(drop); 3923 break; 3924 case BCM_E2EFC_RESOURCE_TYPE_EMA: 3925 #if defined(BCM_METROLITE_SUPPORT) 3926 if (SOC_IS_METROLITE(unit)) { 3927 return BCM_E_PARAM; 3928 } 3929 #endif 3930 BCM_IF_ERROR_RETURN(READ_E2EFCEMA_CNT_SET_LIMITr(unit, rport_handle_id, &val_off)); 3931 set = soc_reg_field_get(unit, E2EFCEMA_CNT_SET_LIMITr, val_off, SET_LIMITf); 3932 BCM_IF_ERROR_RETURN(READ_E2EFCEMA_CNT_RESET_LIMITr(unit, rport_handle_id, &val_on)); 3933 reset = soc_reg_field_get(unit, E2EFCEMA_CNT_RESET_LIMITr, val_on, RESET_LIMITf); 3934 BCM_IF_ERROR_RETURN(READ_E2EFCEMA_CNT_DISC_LIMITr(unit, rport_handle_id, &val_drop)); 3935 drop = soc_reg_field_get(unit, E2EFCEMA_CNT_DISC_LIMITr, val_drop, DISC_LIMITf); 3936 3937 e2efc_rport_cfg->xoff_threshold_bytes = KT2_CELL2BYTE(set); 3938 e2efc_rport_cfg->xon_threshold_bytes = KT2_CELL2BYTE(reset); 3939 e2efc_rport_cfg->drop_threshold_bytes = KT2_CELL2BYTE(drop); 3940 break; 3941 default: 3942 break; 3943 } 3944 return BCM_E_NONE; 3945 } 3946 3947 /* 3948 * Description: 3949 * Add remote module-port and set configuration. 3950 * Return a handle id for the bcm_port_e2efc_remote_port_xxx APIs. 3951 * The API of remote module-port configuration is only for E2EFC 3952 * transmission. 3953 * Parameter: 3954 * unit - (IN) unit number 3955 * e2efc_rport_cfg - (IN) structure containing the configuration 3956 * rport_handle_id - (OUT) remote port handle id, to be used for the rest 3957 * of bcm_port_e2efc_remote_port_xxx APIs 3958 */ 3959 int 3960 bcmi_kt2_port_e2efc_remote_port_add( 3961 int unit, 3962 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg, 3963 int *rport_handle_id) 3964 { 3965 uint32 val_p; 3966 int i, enable, rmod_ptr; 3967 3968 if (e2efc_rport_cfg == NULL || rport_handle_id == NULL) { 3969 return BCM_E_PARAM; 3970 } 3971 3972 /* Check the logical port is in the right range */ 3973 if (e2efc_rport_cfg->remote_port < 0 || 3974 e2efc_rport_cfg->remote_port >= MAX_PORT(unit)) { 3975 LOG_ERROR(BSL_LS_BCM_PORT, 3976 (BSL_META_U(unit, 3977 "Invalid Port Range. Should be >= 0 && < %d\n"), 3978 MAX_PORT(unit))); 3979 return BCM_E_PARAM; 3980 } 3981 3982 /* Checking if the duplicated Counter is being set */ 3983 for (i = 0; i < kt2_e2efc_remote_port_num(unit); i++) { 3984 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr, 3985 REG_PORT_ANY, i, &val_p)); 3986 if ((soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val_p, Vf))) { 3987 if(bcmi_kt2_e2efc_remote_module_ptr_get( 3988 unit, e2efc_rport_cfg->remote_module, 3989 &rmod_ptr) == BCM_E_NONE) { 3990 if (e2efc_rport_cfg->remote_port == 3991 (soc_reg_field_get(unit, E2EFC_CNT_ATTRr, 3992 val_p, RMT_SRC_PORT_IDf))) { 3993 LOG_ERROR(BSL_LS_BCM_PORT, 3994 (BSL_META_U(unit, 3995 "Each remote source port should be" 3996 " mapped to only one counter.\n"))); 3997 return BCM_E_FULL; 3998 } 3999 } 4000 } 4001 } 4002 4003 enable = 0; 4004 for (i = 0; i < kt2_e2efc_remote_port_num(unit); i++) { 4005 /* check whether the E2EFC_CNT_ATTRr Vf is enabled */ 4006 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr, 4007 REG_PORT_ANY, i, &val_p)); 4008 if (!(soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val_p, Vf))) { 4009 /* Setting remote port, module id and enable counter */ 4010 enable = 1; 4011 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, Vf, enable); 4012 BCM_IF_ERROR_RETURN( 4013 bcmi_kt2_e2efc_remote_module_ptr_get( 4014 unit, e2efc_rport_cfg->remote_module, &rmod_ptr)); 4015 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, 4016 RMOD_PTRf, rmod_ptr); 4017 4018 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, 4019 RMT_SRC_PORT_IDf, e2efc_rport_cfg->remote_port); 4020 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_ATTRr, 4021 REG_PORT_ANY, i, val_p)); 4022 BCM_IF_ERROR_RETURN(bcmi_kt2_port_e2efc_configure_thresholds(unit, 4023 i, e2efc_rport_cfg)); 4024 break; 4025 } 4026 } 4027 if (enable == 0) { 4028 LOG_ERROR(BSL_LS_BCM_PORT, 4029 (BSL_META_U(unit, 4030 "Can't Port Config Because the 48 entries is all full"))); 4031 return BCM_E_FULL; 4032 } 4033 *rport_handle_id = i; 4034 4035 return BCM_E_NONE; 4036 } 4037 4038 /* 4039 * Description: 4040 * Set (modify) configuration of the remote port. 4041 * Parameter: 4042 * unit - (IN) unit number 4043 * rport_handle_id - (IN) remote port handle id 4044 * e2efc_rport_cfg - (IN) structure containing the configuration 4045 */ 4046 int 4047 bcmi_kt2_port_e2efc_remote_port_set( 4048 int unit, 4049 int rport_handle_id, 4050 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg) 4051 { 4052 uint32 val_p; 4053 int rmod_ptr; 4054 4055 /* check whehter the handle id is valid */ 4056 if ( rport_handle_id < 0 || rport_handle_id >= kt2_e2efc_remote_port_num(unit)) { 4057 LOG_ERROR(BSL_LS_BCM_PORT, 4058 (BSL_META_U(unit, 4059 "Invalid Hadle ID.\n"))); 4060 return BCM_E_PARAM; 4061 } 4062 4063 if (e2efc_rport_cfg == NULL) { 4064 return BCM_E_PARAM; 4065 } 4066 4067 /* Check the logical port is in the right range */ 4068 if (e2efc_rport_cfg->remote_port < 0 || 4069 e2efc_rport_cfg->remote_port >= MAX_PORT(unit)) { 4070 LOG_ERROR(BSL_LS_BCM_PORT, 4071 (BSL_META_U(unit, 4072 "Invalid Port Range. Should be >= 0 && < %d\n"), 4073 MAX_PORT(unit))); 4074 return BCM_E_PARAM; 4075 } 4076 /* check whether the parameter is added or not */ 4077 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, 4078 E2EFC_CNT_ATTRr, 4079 REG_PORT_ANY, rport_handle_id, &val_p)); 4080 if (!(soc_reg_field_get(unit, E2EFC_CNT_ATTRr, 4081 val_p, Vf))) { 4082 LOG_ERROR(BSL_LS_BCM_PORT, 4083 (BSL_META_U(unit, 4084 "The port config is not added, thus can't set"))); 4085 return BCM_E_PARAM; 4086 } 4087 4088 /* Setting remote port and module id */ 4089 BCM_IF_ERROR_RETURN( 4090 bcmi_kt2_e2efc_remote_module_ptr_get( 4091 unit, e2efc_rport_cfg->remote_module, &rmod_ptr)); 4092 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, RMOD_PTRf, rmod_ptr); 4093 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, 4094 RMT_SRC_PORT_IDf, e2efc_rport_cfg->remote_port); 4095 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_ATTRr, REG_PORT_ANY, 4096 rport_handle_id, val_p)); 4097 BCM_IF_ERROR_RETURN(bcmi_kt2_port_e2efc_configure_thresholds( 4098 unit, rport_handle_id, 4099 e2efc_rport_cfg)); 4100 return BCM_E_NONE; 4101 } 4102 4103 4104 /* 4105 * Description: 4106 * Get configuration of the remote port. 4107 * Return the remote module, remote port and configuration of the 4108 * handle id. 4109 * Parameter: 4110 * unit - (IN) unit number 4111 * rport_handle_id - (IN) remote port handle id 4112 * e2efc_rport_cfg - (OUT) structure containing the configuration 4113 */ 4114 int 4115 bcmi_kt2_port_e2efc_remote_port_get( 4116 int unit, 4117 int rport_handle_id, 4118 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg) 4119 { 4120 uint32 val_p; 4121 int rmod_ptr, rmod_id; 4122 4123 if (e2efc_rport_cfg == NULL) { 4124 return BCM_E_PARAM; 4125 } 4126 4127 /* check whehter the handle id is valid */ 4128 if ( rport_handle_id < 0 || rport_handle_id >= kt2_e2efc_remote_port_num(unit)) { 4129 LOG_ERROR(BSL_LS_BCM_PORT, 4130 (BSL_META_U(unit, 4131 "Invalid Hadle ID.\n"))); 4132 return BCM_E_PARAM; 4133 } 4134 /* check whether the parameter is added or not */ 4135 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, 4136 E2EFC_CNT_ATTRr, 4137 REG_PORT_ANY, rport_handle_id, &val_p)); 4138 if (!(soc_reg_field_get(unit, E2EFC_CNT_ATTRr, 4139 val_p, Vf))) { 4140 LOG_ERROR(BSL_LS_BCM_PORT, 4141 (BSL_META_U(unit, 4142 "The port config is not added, thus can't get"))); 4143 return BCM_E_NOT_FOUND; 4144 } 4145 4146 /* Getting remote port and module id */ 4147 rmod_ptr = soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val_p, RMOD_PTRf); 4148 BCM_IF_ERROR_RETURN( 4149 bcmi_kt2_e2efc_remote_module_id_get(unit, rmod_ptr, &rmod_id)); 4150 e2efc_rport_cfg->remote_module = rmod_id; 4151 e2efc_rport_cfg->remote_port = 4152 soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val_p, 4153 RMT_SRC_PORT_IDf); 4154 BCM_IF_ERROR_RETURN(bcmi_kt2_port_e2efc_get_thresholds(unit,rport_handle_id, 4155 e2efc_rport_cfg)); 4156 return BCM_E_NONE; 4157 } 4158 4159 4160 /* 4161 * Description: 4162 * Delete remote port. 4163 * Parameter: 4164 * unit - (IN) unit number 4165 * rport_handle_id - (IN) remote port handle id 4166 */ 4167 int 4168 bcmi_kt2_port_e2efc_remote_port_delete( 4169 int unit, 4170 int rport_handle_id) 4171 { 4172 uint32 val_p; 4173 uint32 clear = 0x00000000; 4174 bcm_port_e2efc_remote_port_config_t e2efc_rport_cfg_s; 4175 bcm_port_e2efc_remote_port_config_t *e2efc_rport_cfg = &e2efc_rport_cfg_s; 4176 4177 /* check whehter the handle id is valid */ 4178 if ( rport_handle_id < 0 || rport_handle_id >= kt2_e2efc_remote_port_num(unit)) { 4179 LOG_ERROR(BSL_LS_BCM_PORT, 4180 (BSL_META_U(unit, 4181 "Invalid Hadle ID.\n"))); 4182 return BCM_E_PARAM; 4183 } 4184 /* check whether the parameter is added or not */ 4185 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr, 4186 REG_PORT_ANY, rport_handle_id, &val_p)); 4187 if (!(soc_reg_field_get(unit, E2EFC_CNT_ATTRr, 4188 val_p, Vf))) { 4189 LOG_ERROR(BSL_LS_BCM_PORT, 4190 (BSL_META_U(unit, 4191 "The port config is not added, thus can't delete"))); 4192 return BCM_E_NOT_FOUND; 4193 } 4194 4195 /* Set to zero remote port and module id */ 4196 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, 4197 Vf, clear); 4198 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, 4199 RMOD_PTRf, clear); 4200 soc_reg_field_set(unit, E2EFC_CNT_ATTRr, &val_p, 4201 RMT_SRC_PORT_IDf, clear); 4202 BCM_IF_ERROR_RETURN(soc_reg32_set(unit, E2EFC_CNT_ATTRr, 4203 REG_PORT_ANY, rport_handle_id, val_p)); 4204 4205 e2efc_rport_cfg->xoff_threshold_bytes = 0; 4206 e2efc_rport_cfg->xon_threshold_bytes = 0; 4207 e2efc_rport_cfg->drop_threshold_bytes = 0; 4208 e2efc_rport_cfg->xoff_threshold_packets = 0; 4209 e2efc_rport_cfg->xon_threshold_packets = 0; 4210 e2efc_rport_cfg->drop_threshold_packets = 0; 4211 4212 e2efc_rport_cfg->e2efc_resource_type = BCM_E2EFC_RESOURCE_TYPE_INT_MEM; 4213 BCM_IF_ERROR_RETURN(bcmi_kt2_port_e2efc_configure_thresholds(unit, 4214 rport_handle_id, e2efc_rport_cfg)); 4215 4216 e2efc_rport_cfg->e2efc_resource_type = BCM_E2EFC_RESOURCE_TYPE_QEN; 4217 BCM_IF_ERROR_RETURN(bcmi_kt2_port_e2efc_configure_thresholds(unit, 4218 rport_handle_id, e2efc_rport_cfg)); 4219 4220 e2efc_rport_cfg->e2efc_resource_type = BCM_E2EFC_RESOURCE_TYPE_RQE; 4221 BCM_IF_ERROR_RETURN(bcmi_kt2_port_e2efc_configure_thresholds(unit, 4222 rport_handle_id, e2efc_rport_cfg)); 4223 #if defined(BCM_METROLITE_SUPPORT) 4224 if (SOC_IS_METROLITE(unit)) { 4225 return BCM_E_NONE; 4226 } 4227 #endif 4228 e2efc_rport_cfg->e2efc_resource_type = BCM_E2EFC_RESOURCE_TYPE_EXT_MEM; 4229 BCM_IF_ERROR_RETURN(bcmi_kt2_port_e2efc_configure_thresholds(unit, 4230 rport_handle_id, e2efc_rport_cfg)); 4231 4232 e2efc_rport_cfg->e2efc_resource_type = BCM_E2EFC_RESOURCE_TYPE_EMA; 4233 BCM_IF_ERROR_RETURN(bcmi_kt2_port_e2efc_configure_thresholds(unit, 4234 rport_handle_id, e2efc_rport_cfg)); 4235 return BCM_E_NONE; 4236 } 4237 /* 4238 * Description: 4239 * Traverse enabled remote modules that apply E2EFC mechanism. 4240 * Parameter: 4241 * unit - (IN) unit number 4242 * cb - (IN) call back function to execute 4243 * user_data - (IN) pointer to user data 4244 */ 4245 int 4246 bcmi_kt2_port_e2efc_remote_module_traverse( 4247 int unit, 4248 bcm_port_e2efc_remote_module_traverse_cb cb, 4249 void *user_data) 4250 { 4251 int i, rv, rmod_id; 4252 bcm_port_e2efc_mode_t mode; 4253 uint32 val; 4254 4255 for (i = 0; i < KT2_E2EFC_RMOD_NUM; i++) { 4256 for (mode = bcmPortE2efcModeTx; mode < bcmPortE2efcModeCount; mode++) { 4257 soc_reg32_get(unit, e2efc_rmod_id_reg[mode][i], 4258 REG_PORT_ANY, 0, &val); 4259 if (soc_reg_field_get(unit, e2efc_rmod_id_reg[mode][i], 4260 val, e2efc_rmod_enabled[i])) { 4261 rmod_id = soc_reg_field_get(unit, e2efc_rmod_id_reg[mode][i], 4262 val, e2efc_rmod_id_field[i]); 4263 rv = cb(unit, rmod_id, mode, user_data); 4264 if (rv != BCM_E_NONE) { 4265 return rv; 4266 } 4267 } 4268 } 4269 } 4270 return BCM_E_NONE; 4271 } 4272 4273 /* 4274 * Description: 4275 * Traverse remote ports. 4276 * Parameter: 4277 * unit - (IN) unit number 4278 * cb - (IN) call back function to execute 4279 * user_data - (IN) pointer to user data 4280 */ 4281 int 4282 bcmi_kt2_port_e2efc_remote_port_traverse( 4283 int unit, 4284 bcm_port_e2efc_remote_port_traverse_cb cb, 4285 void *user_data) 4286 { 4287 int i, rv; 4288 uint32 val; 4289 4290 for (i = 0; i < kt2_e2efc_remote_port_num(unit); i++) { 4291 /* check whether the E2EFC_CNT_ATTRr Vf is enabled */ 4292 BCM_IF_ERROR_RETURN(soc_reg32_get(unit, E2EFC_CNT_ATTRr, 4293 REG_PORT_ANY, i, &val)); 4294 if (soc_reg_field_get(unit, E2EFC_CNT_ATTRr, val, Vf)) { 4295 rv = cb(unit, i, user_data); 4296 if (rv != BCM_E_NONE) { 4297 return rv; 4298 } 4299 } 4300 } 4301 4302 return BCM_E_NONE; 4303 } 4304 /* 4305 * Function: 4306 * bcm_kt2_switch_control_set 4307 * Description: 4308 * Specify general switch behaviors. 4309 * Parameters: 4310 * unit - Device unit number 4311 * type - The desired configuration parameter to modify 4312 * arg - The value with which to set the parameter 4313 * Returns: 4314 * BCM_E_xxx 4315 * Notes: 4316 * For behaviors which are port-specific, all non-stack ports 4317 * will be set. 4318 */ 4319 4320 int 4321 bcm_kt2_switch_control_set(int unit, 4322 bcm_switch_control_t type, 4323 int arg) 4324 { 4325 switch (type) { 4326 case bcmSwitchE2EFCReceiveDestMacOui: 4327 if (soc_feature(unit, soc_feature_e2efc)) { 4328 uint32 val, fval; 4329 SOC_IF_ERROR_RETURN(READ_E2E_IBP_RX_DA_LSr(unit, &val)); 4330 fval = soc_reg_field_get(unit, E2E_IBP_RX_DA_LSr, 4331 val, DAf); 4332 fval = (fval & 0xffffff) | (arg & 0xff) << 24; 4333 soc_reg_field_set(unit, E2E_IBP_RX_DA_LSr, 4334 &val, DAf, fval); 4335 SOC_IF_ERROR_RETURN(WRITE_E2E_IBP_RX_DA_LSr(unit, val)); 4336 SOC_IF_ERROR_RETURN(READ_E2E_IBP_RX_DA_MSr(unit, &val)); 4337 fval = (arg >> 8) & 0xffff; 4338 soc_reg_field_set(unit, E2E_IBP_RX_DA_MSr, 4339 &val, DAf, fval); 4340 SOC_IF_ERROR_RETURN(WRITE_E2E_IBP_RX_DA_MSr(unit, val)); 4341 return BCM_E_NONE; 4342 } 4343 break; 4344 case bcmSwitchE2EFCReceiveDestMacNonOui: 4345 if (soc_feature(unit, soc_feature_e2efc)) { 4346 uint32 val, fval; 4347 SOC_IF_ERROR_RETURN(READ_E2E_IBP_RX_DA_LSr(unit, &val)); 4348 fval = soc_reg_field_get(unit, E2E_IBP_RX_DA_LSr, 4349 val, DAf); 4350 fval = (fval & 0xff000000) | (arg & 0xffffff); 4351 soc_reg_field_set(unit, E2E_IBP_RX_DA_LSr, 4352 &val, DAf, fval); 4353 SOC_IF_ERROR_RETURN(WRITE_E2E_IBP_RX_DA_LSr(unit, val)); 4354 return BCM_E_NONE; 4355 } 4356 break; 4357 case bcmSwitchE2EFCReceiveEtherType: 4358 if (soc_feature(unit, soc_feature_e2efc)) { 4359 uint32 val; 4360 SOC_IF_ERROR_RETURN(READ_E2E_IBP_RX_LENGTH_TYPEr(unit, &val)); 4361 arg = (arg & 0xffff); 4362 soc_reg_field_set(unit, E2E_IBP_RX_LENGTH_TYPEr, 4363 &val, LENGTH_TYPEf, arg); 4364 SOC_IF_ERROR_RETURN(WRITE_E2E_IBP_RX_LENGTH_TYPEr(unit, val)); 4365 return BCM_E_NONE; 4366 } 4367 break; 4368 case bcmSwitchE2EFCReceiveOpcode: 4369 if (soc_feature(unit, soc_feature_e2efc)) { 4370 uint32 val; 4371 SOC_IF_ERROR_RETURN(READ_E2E_IBP_RX_OPCODEr(unit, &val)); 4372 arg = (arg & 0xffff); 4373 soc_reg_field_set(unit, E2E_IBP_RX_OPCODEr, 4374 &val, OPCODEf, arg); 4375 SOC_IF_ERROR_RETURN(WRITE_E2E_IBP_RX_OPCODEr(unit, val)); 4376 return BCM_E_NONE; 4377 } 4378 break; 4379 default: 4380 break; 4381 } 4382 return BCM_E_PARAM; 4383 } 4384 /* 4385 * Function: 4386 * bcm_kt2_switch_control_get 4387 * Description: 4388 * Retrieve general switch behaviors. 4389 * Parameters: 4390 * unit - Device unit number 4391 * type - The desired configuration parameter to retrieve. 4392 * arg - Pointer to where the retrieved value will be written. 4393 * Returns: 4394 * BCM_E_xxx 4395 * Notes: 4396 * For behaviors which are port-specific, retrieves the setting 4397 * for one port arbitrarily chosen from those which support the 4398 * setting and are non-stack. 4399 */ 4400 4401 int 4402 bcm_kt2_switch_control_get(int unit, 4403 bcm_switch_control_t type, 4404 int *arg) 4405 { 4406 if (arg == NULL) { 4407 return BCM_E_PARAM; 4408 } 4409 4410 switch (type) { 4411 case bcmSwitchE2EFCReceiveDestMacOui: 4412 if (soc_feature(unit, soc_feature_e2efc)) { 4413 uint32 val, f_lo, f_hi; 4414 SOC_IF_ERROR_RETURN(READ_E2E_IBP_RX_DA_LSr(unit, &val)); 4415 f_lo = soc_reg_field_get(unit, E2E_IBP_RX_DA_LSr, 4416 val, DAf); 4417 SOC_IF_ERROR_RETURN(READ_E2E_IBP_RX_DA_MSr(unit, &val)); 4418 f_hi = soc_reg_field_get(unit, E2E_IBP_RX_DA_MSr, 4419 val, DAf); 4420 *arg = (f_hi & 0xffff) << 8 | ((f_lo >> 24) & 0xff); 4421 return BCM_E_NONE; 4422 } 4423 break; 4424 case bcmSwitchE2EFCReceiveDestMacNonOui: 4425 if (soc_feature(unit, soc_feature_e2efc)) { 4426 uint32 val, fval; 4427 SOC_IF_ERROR_RETURN(READ_E2E_IBP_RX_DA_LSr(unit, &val)); 4428 fval = soc_reg_field_get(unit, E2E_IBP_RX_DA_LSr, 4429 val, DAf); 4430 *arg = fval & 0Xffffff; 4431 return BCM_E_NONE; 4432 } 4433 break; 4434 case bcmSwitchE2EFCReceiveEtherType: 4435 if (soc_feature(unit, soc_feature_e2efc)) { 4436 uint32 val, fval; 4437 SOC_IF_ERROR_RETURN(READ_E2E_IBP_RX_LENGTH_TYPEr(unit, &val)); 4438 fval = soc_reg_field_get(unit, E2E_IBP_RX_LENGTH_TYPEr, 4439 val, LENGTH_TYPEf); 4440 *arg = fval & 0xffff; 4441 return BCM_E_NONE; 4442 } 4443 break; 4444 case bcmSwitchE2EFCReceiveOpcode: 4445 if (soc_feature(unit, soc_feature_e2efc)) { 4446 uint32 val, fval; 4447 SOC_IF_ERROR_RETURN(READ_E2E_IBP_RX_OPCODEr(unit, &val)); 4448 fval = soc_reg_field_get(unit, E2E_IBP_RX_OPCODEr, 4449 val, OPCODEf); 4450 *arg = fval & 0xffff; 4451 return BCM_E_NONE; 4452 } 4453 break; 4454 4455 4456 default: 4457 break; 4458 } 4459 return BCM_E_PARAM; 4460 } 4461 /************ E2EFC CODE END *************************/ 4462 #endif /* BCM_KATANA2_SUPPORT */