port.c (68803B)
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 15 #include <sal/core/time.h> 16 #include <shared/bsl.h> 17 #include <bcm/port.h> 18 #include <bcm/tx.h> 19 #include <bcm/error.h> 20 #include <bcm_int/esw/stack.h> 21 #include <bcm_int/esw/katana2.h> 22 #include <bcm_int/esw/metrolite.h> 23 #include <bcm_int/esw/cosq.h> 24 25 #include <soc/katana2.h> 26 #include <soc/metrolite.h> 27 #include <soc/phyreg.h> 28 #include <soc/ll.h> 29 #include <soc/types.h> 30 #if defined(BCM_METROLITE_SUPPORT) 31 #include <bcm_int/esw_dispatch.h> 32 #endif 33 34 static uint32 ml_port_lanes_unchanged; 35 static uint32 new_tdm[ML_TDM_MAX_SIZE] = {0}; 36 extern int block_ml_max_startaddr[ML_MAX_BLOCKS]; 37 extern int block_ml_max_endaddr[ML_MAX_BLOCKS]; 38 extern ml_port_to_block_subports_t *ml_port_to_block_subports[SOC_MAX_NUM_DEVICES]; 39 extern ml_speed_t *bcm56270_speed[SOC_MAX_NUM_DEVICES]; 40 41 #define ML_SPEED_MODE_LINK_1G 2 42 #define ML_SPEED_MODE_LINK_2G5 3 43 #define ML_SPEED_MODE_LINK_10G_PLUS 4 44 45 int 46 _bcm_ml_port_sw_info_display(int unit, bcm_port_t port) { 47 48 int rv = 0; 49 soc_info_t *si = &SOC_INFO(unit); 50 int lanes = 0; 51 uint8 block; 52 int enable; 53 int speed; 54 int link; 55 int autoneg; 56 int discard_mode; 57 int loopback_mode; 58 int master_mode; 59 int encap_mode = BCM_PORT_ENCAP_COUNT; 60 char *discard[] = {"NONE", "ALL", "UNTAG", "TAG"}; 61 char *loopback[] = {"NONE", "MAC", "PHY", "RMT", "C57"}; 62 char *master[] = {"SLAVE", "MASTER", "AUTO", "NONE"}; 63 char *encap[] = {"IEEE", "HIGIG", "B5632", "HIGIG2", "HIGIG-Lite"}; 64 65 rv += (_bcm_ml_port_lanes_get(unit, port, &lanes)); 66 rv += (soc_metrolite_get_port_block(unit,port,&block)); 67 rv += (bcm_esw_port_enable_get(unit, port, &enable)); 68 rv += (bcm_esw_port_autoneg_get(unit, port, &autoneg)); 69 rv += (bcm_esw_port_speed_get(unit, port, &speed)); 70 rv += (bcm_esw_port_link_status_get(unit, port, &link)); 71 rv += (bcm_esw_port_discard_get(unit, port, &discard_mode)); 72 rv += (bcm_esw_port_loopback_get(unit, port, &loopback_mode)); 73 rv += (bcm_esw_port_master_get(unit, port, &master_mode)); 74 rv += (bcm_esw_port_encap_get(unit, port, &encap_mode)); 75 76 if (rv < 0) { 77 LOG_CLI((BSL_META_U(unit, "\n\n Some parameters not set properly !!"))); 78 } 79 LOG_CLI((BSL_META_U(unit, "\n\n SOFTWARE PORT CONFIGURATION :\n"))); 80 LOG_CLI((BSL_META_U(unit, "------------------------------------"))); 81 LOG_CLI((BSL_META_U(unit, "\n Port Name\t\t:\t%s"),si->port_name[port])); 82 LOG_CLI((BSL_META_U(unit, "\n Block ID\t\t:\t%d"), block)); 83 LOG_CLI((BSL_META_U(unit, "\n Lane Number\t\t:\t%d "),lanes)); 84 LOG_CLI((BSL_META_U(unit, "\n Current Speed\t\t:\t%d"), speed)); 85 LOG_CLI((BSL_META_U(unit, "\n Max speed\t\t:\t%d"),si->port_speed_max[port])); 86 LOG_CLI((BSL_META_U(unit, "\n Speed\t\t\t:\t%d"),((* 87 ml_port_speeds[unit])[block][lanes-1]))); 88 LOG_CLI((BSL_META_U(unit, "\n Port status \t\t:\t%s"),(enable ? "ENABLED" : "DISABLED"))); 89 LOG_CLI((BSL_META_U(unit, "\n Link status\t\t:\t%s"),(link ? "UP" : "DOWN"))); 90 LOG_CLI((BSL_META_U(unit, "\n Autoneg status\t\t:\t%s"),(autoneg ? "TRUE" : "FALSE"))); 91 LOG_CLI((BSL_META_U(unit, "\n Discard Type\t\t:\t%s"),(discard_mode <= 3 ? discard[discard_mode] : "INVALID"))); 92 LOG_CLI((BSL_META_U(unit, "\n Loopback Mode\t\t:\t%s"),(loopback_mode <= 4 ? loopback[loopback_mode] : "INVALID"))); 93 LOG_CLI((BSL_META_U(unit, "\n Master Status\t\t:\t%s"),(master_mode <= 3 ? master[master_mode] : "INVALID"))); 94 LOG_CLI((BSL_META_U(unit, "\n Encapsulation \t\t:\t%s"),(encap_mode <= 4 ? encap[encap_mode] : "INVALID"))); 95 LOG_CLI((BSL_META_U(unit, "\n\n*********************************************** \n\n"))); 96 97 return BCM_E_NONE; 98 99 } 100 101 int 102 _bcm_ml_port_hw_info_display(int unit, bcm_port_t port) { 103 104 uint32 rval = 0; 105 uint64 rval_64; 106 int lanes = 0; 107 uint8 mxqblock; 108 int port0, port1, port2, port3; 109 int higig, higig2; 110 int core_mode, phy_mode; 111 int tx_en, rx_en, ipg_check_disable, lpbk_leak; 112 int soft_reset, rs_soft_reset, sw_link, link_status_select; 113 int hdr_mode, sop_crc, speed_mode; 114 int port_enable; 115 egr_enable_entry_t egr_en; 116 117 char *phy[] = {"Single", "Dual", "Quad"}; 118 char *core[] = {"Single", "Dual", "Quad"}; 119 char *enable[] = {"DISABLED", "ENABLED"}; 120 char *active[] = {"INACTIVE", "ACTIVE"}; 121 char *link_sel[] = {"SOFTWARE", "STRAP-PIN"}; 122 char *hdr[] = {"IEEE", "HG+", "HG2", "CLH", "SCH", "SOP ONLY IEEE"}; 123 char *speed[] = {"10Mpbps", "100Mbps", "1Gbps", "2.5Gbps", ">=10Gbps"}; 124 125 BCM_IF_ERROR_RETURN(_bcm_ml_port_lanes_get(unit, port, &lanes)); 126 BCM_IF_ERROR_RETURN(soc_metrolite_get_port_block(unit, port, &mxqblock)); 127 128 LOG_CLI((BSL_META_U(unit, "\n\n HARDWARE PORT CONFIGURATION : \n"))); 129 LOG_CLI((BSL_META_U(unit, "--------------------------------------\n"))); 130 131 /* XPORT_MODE_REG */ 132 if (SOC_REG_PORT_VALID(unit, XPORT_MODE_REGr, port)) { 133 SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &rval)); 134 phy_mode = soc_reg_field_get(unit, XPORT_MODE_REGr, rval, PHY_PORT_MODEf); 135 LOG_CLI((BSL_META_U(unit, "\n XPORT MODE "))); 136 LOG_CLI((BSL_META_U(unit, "\n Phy Mode\t:\t%s"), phy[phy_mode])); 137 } 138 139 /* XLPORT_MODE_REG */ 140 if (SOC_REG_PORT_VALID(unit, XLPORT_MODE_REGr, port)) { 141 SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port, &rval)); 142 core_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, 143 XPORT0_CORE_PORT_MODEf); 144 phy_mode = soc_reg_field_get(unit, XLPORT_MODE_REGr, rval, 145 XPORT0_PHY_PORT_MODEf); 146 LOG_CLI((BSL_META_U(unit, "\n XPORT MODE "))); 147 LOG_CLI((BSL_META_U(unit, "\n Core Mode\t:\t%s"), core[core_mode])); 148 LOG_CLI((BSL_META_U(unit, "\n Phy Mode\t:\t%s"), phy[phy_mode])); 149 } 150 151 /* XPORT_PORT_ENABLE */ 152 if (SOC_REG_PORT_VALID(unit, XPORT_PORT_ENABLEr, port)) { 153 SOC_IF_ERROR_RETURN(READ_XPORT_PORT_ENABLEr(unit, port, &rval)); 154 port0 = soc_reg_field_get(unit, XPORT_PORT_ENABLEr, rval, PORT0f); 155 port1 = soc_reg_field_get(unit, XPORT_PORT_ENABLEr, rval, PORT1f); 156 port2 = soc_reg_field_get(unit, XPORT_PORT_ENABLEr, rval, PORT2f); 157 port3 = soc_reg_field_get(unit, XPORT_PORT_ENABLEr, rval, PORT3f); 158 LOG_CLI((BSL_META_U(unit, "\n\n XPORT PORT ENABLE "))); 159 LOG_CLI((BSL_META_U(unit, "\n MxQBlock\t:\t%d\n Port0\t\t:\t%s\n Port1\t\t:\t%s" 160 "\n Port2\t\t:\t%s\n Port3\t\t:\t%s"), mxqblock, \ 161 enable[port0], enable[port1], enable[port2], enable[port3])); 162 } 163 164 /* XLPORT_ENABLE_REG */ 165 if (SOC_REG_PORT_VALID(unit, XLPORT_ENABLE_REGr, port)) { 166 SOC_IF_ERROR_RETURN(READ_XLPORT_ENABLE_REGr(unit, port, &rval)); 167 port0 = soc_reg_field_get(unit, XLPORT_ENABLE_REGr, rval, PORT0f); 168 port1 = soc_reg_field_get(unit, XLPORT_ENABLE_REGr, rval, PORT1f); 169 port2 = soc_reg_field_get(unit, XLPORT_ENABLE_REGr, rval, PORT2f); 170 port3 = soc_reg_field_get(unit, XLPORT_ENABLE_REGr, rval, PORT3f); 171 LOG_CLI((BSL_META_U(unit, "\n\n XLPORT PORT ENABLE "))); 172 LOG_CLI((BSL_META_U(unit, "\n MxQBlock\t:\t%d\n Port0\t\t:\t%s\n Port1\t\t:\t%s" 173 "\n Port2\t\t:\t%s\n Port3\t\t:\t%s"), mxqblock, \ 174 enable[port0], enable[port1], enable[port2], enable[port3])); 175 } 176 177 /* XPORT_CONFIG */ 178 if (SOC_REG_PORT_VALID(unit, XPORT_CONFIGr, port)) { 179 SOC_IF_ERROR_RETURN(READ_XPORT_CONFIGr(unit, port, &rval)); 180 higig = soc_reg_field_get(unit, XPORT_CONFIGr, rval, HIGIG_MODEf); 181 higig2 = soc_reg_field_get(unit, XPORT_CONFIGr, rval, HIGIG2_MODEf); 182 LOG_CLI((BSL_META_U(unit, "\n\n XPORT CONFIG "))); 183 LOG_CLI((BSL_META_U(unit, "\n HiGig\t\t:\t%s"), enable[higig])); 184 LOG_CLI((BSL_META_U(unit, "\n HiGig2\t\t:\t%s"), enable[higig2])); 185 } 186 187 /* XLPORT_CONFIG */ 188 if (SOC_REG_PORT_VALID(unit, XLPORT_CONFIGr, port)) { 189 SOC_IF_ERROR_RETURN(READ_XLPORT_CONFIGr(unit, port, &rval)); 190 higig = soc_reg_field_get(unit, XLPORT_CONFIGr, rval, HIGIG_MODEf); 191 higig2 = soc_reg_field_get(unit, XLPORT_CONFIGr, rval, HIGIG2_MODEf); 192 LOG_CLI((BSL_META_U(unit, "\n\n XLPORT CONFIG "))); 193 LOG_CLI((BSL_META_U(unit, "\n HiGig\t\t:\t%s"), enable[higig])); 194 LOG_CLI((BSL_META_U(unit, "\n HiGig2\t\t:\t%s"), enable[higig2])); 195 } 196 197 /* XLMAC_CTRL */ 198 SOC_IF_ERROR_RETURN(READ_XLMAC_CTRLr(unit, port, &rval_64)); 199 tx_en = soc_reg64_field32_get(unit, XLMAC_CTRLr, rval_64, TX_ENf); 200 rx_en = soc_reg64_field32_get(unit, XLMAC_CTRLr, rval_64, RX_ENf); 201 soft_reset = soc_reg64_field32_get(unit, XLMAC_CTRLr, rval_64, SOFT_RESETf); 202 rs_soft_reset = soc_reg64_field32_get(unit, XLMAC_CTRLr, rval_64, RS_SOFT_RESETf); 203 lpbk_leak = soc_reg64_field32_get(unit, XLMAC_CTRLr, rval_64, LOCAL_LPBK_LEAK_ENBf); 204 sw_link = soc_reg64_field32_get(unit, XLMAC_CTRLr, rval_64, SW_LINK_STATUSf); 205 link_status_select = soc_reg64_field32_get(unit, XLMAC_CTRLr, rval_64, 206 LINK_STATUS_SELECTf); 207 ipg_check_disable = soc_reg64_field32_get(unit, XLMAC_CTRLr, rval_64, 208 XGMII_IPG_CHECK_DISABLEf); 209 LOG_CLI((BSL_META_U(unit, "\n\n XMAC CTRL"))); 210 LOG_CLI((BSL_META_U(unit, "\n Tx\t \t\t:\t%s"), enable[tx_en])); 211 LOG_CLI((BSL_META_U(unit, "\n Rx \t\t\t:\t%s"), enable[rx_en])); 212 LOG_CLI((BSL_META_U(unit, "\n Soft Reset\t\t:\t%s"),enable[soft_reset])); 213 LOG_CLI((BSL_META_U(unit, "\n RS Soft Reset\t\t:\t%s"), enable[rs_soft_reset])); 214 LOG_CLI((BSL_META_U(unit, "\n RS Soft Reset\t\t:\t%s"), enable[rs_soft_reset])); 215 LOG_CLI((BSL_META_U(unit, "\n Lpbk Leak(Local)\t:\t%s"), enable[lpbk_leak])); 216 LOG_CLI((BSL_META_U(unit, "\n SW Link Status\t\t:\t%s"), active[sw_link])); 217 LOG_CLI((BSL_META_U(unit, "\n Link Status Select\t:\t%s"), link_sel[link_status_select])); 218 LOG_CLI((BSL_META_U(unit, "\n ipg check disable\t:\t%s"), enable[ipg_check_disable])); 219 220 /* XLMAC_MODE*/ 221 SOC_IF_ERROR_RETURN(READ_XLMAC_MODEr(unit, port, &rval_64)); 222 hdr_mode = soc_reg64_field32_get(unit, XLMAC_MODEr, rval_64, HDR_MODEf); 223 sop_crc = soc_reg64_field32_get(unit, XLMAC_MODEr, rval_64, NO_SOP_FOR_CRC_HGf); 224 speed_mode = soc_reg64_field32_get(unit, XLMAC_MODEr, rval_64, SPEED_MODEf); 225 LOG_CLI((BSL_META_U(unit, "\n\n XMAC MODE"))); 226 LOG_CLI((BSL_META_U(unit, "\n Header Mode\t\t:\t%s"),hdr[hdr_mode])); 227 LOG_CLI((BSL_META_U(unit, "\n SOP for CRC in HG\t:\t%s"), 228 (sop_crc ? "EXCLUDE" : "INCLUDE"))); 229 LOG_CLI((BSL_META_U(unit, "\n Speed Mode\t\t:\t%s"), speed[speed_mode])); 230 231 /* EGR_ENABLE */ 232 SOC_IF_ERROR_RETURN(READ_EGR_ENABLEm(unit, SOC_BLOCK_ANY, port, &egr_en)); 233 port_enable = soc_EGR_ENABLEm_field32_get(unit, &egr_en, PRT_ENABLEf); 234 LOG_CLI((BSL_META_U(unit, "\n\n EGR ENABLE"))); 235 LOG_CLI((BSL_META_U(unit, "\n Port\t\t:\t%s\n\n"),enable[port_enable])); 236 237 return BCM_E_NONE; 238 239 } 240 241 int 242 bcm_ml_flexio_pbmp_update(int unit, bcm_pbmp_t *pbmp) 243 { 244 bcm_port_t blk_port; 245 int blk, blk_idx; 246 bcm_port_t first_port; 247 248 if (NULL == pbmp) { 249 return BCM_E_PORT; 250 } 251 252 for (blk = 0; blk < ML_MAX_BLOCKS; blk++) { 253 254 /* If the first port is invalid, then skip the block */ 255 first_port = (*ml_block_ports[unit])[blk][0]; 256 if (!SOC_PORT_VALID(unit, first_port)) { 257 continue; 258 } 259 260 if (blk == 0) { 261 /* Add the port at index 1, 2, & 3 to gven pbmp and update the 262 * port_type so that it is treated as valid port 263 */ 264 for (blk_idx = 0; 265 blk_idx < ML_MAX_PORTS_PER_BLOCK; blk_idx++) { 266 267 blk_port = (*ml_block_ports[unit])[blk][blk_idx]; 268 if ((blk_port < SOC_INFO(unit).lb_port) && (!SOC_PBMP_MEMBER(SOC_INFO(unit).subtag_pp_port_pbm, blk_port)) && 269 (!SOC_PBMP_MEMBER(SOC_INFO(unit).linkphy_pp_port_pbm, blk_port))) { 270 BCM_PBMP_PORT_ADD(*pbmp, blk_port); 271 SOC_PORT_TYPE(unit, blk_port) = SOC_BLK_MXQPORT; 272 } 273 274 } /* for blk_idx */ 275 } else{ 276 277 for (blk_idx = 0; 278 blk_idx < ML_MAX_PORTS_PER_BLOCK; blk_idx++) { 279 280 blk_port = (*ml_block_ports[unit])[blk][blk_idx]; 281 if ((blk_port < SOC_INFO(unit).lb_port) && (!SOC_PBMP_MEMBER(SOC_INFO(unit).subtag_pp_port_pbm, blk_port)) && 282 (!SOC_PBMP_MEMBER(SOC_INFO(unit).linkphy_pp_port_pbm, blk_port))) { 283 BCM_PBMP_PORT_ADD(*pbmp, blk_port); 284 SOC_PORT_TYPE(unit, blk_port) = SOC_BLK_XLPORT; 285 } 286 287 } /* for blk_idx */ 288 } /* if SOC_PORT_TYPE */ 289 } /* For blk */ 290 291 return BCM_E_NONE; 292 } 293 294 /* 295 * Feature implementation is based on KT2 approach. 296 * So changing the lanes convention as per the implementation. 297 * lanes = 4 --> 4 active ports in the port block.(Eg : 4 ge ports) 298 * lanes = 1 --> 1 active port in the port block.(Eg : 1 xe port) 299 */ 300 int 301 _bcm_ml_lanes_convention(int *lanes) { 302 303 switch(*lanes) { 304 case 1 : *lanes = 4; 305 break; 306 case 2 : *lanes = 2; 307 break; 308 case 4 : *lanes = 1; 309 break; 310 default : return BCM_E_PARAM; 311 } 312 return BCM_E_NONE; 313 } 314 315 int 316 _bcm_ml_port_lanes_set_post_operation(int unit, bcm_port_t port) 317 { 318 soc_error_t rv = BCM_E_NONE; 319 uint8 loop = 0; 320 uint8 block = 0; 321 uint8 block_port = 0; 322 int mode = 0; 323 int new_lanes = 0; 324 int port_enable = 0; 325 int speed=0, max_speed=0; 326 327 if (ml_port_lanes_unchanged) { 328 return BCM_E_NONE; 329 } 330 331 SOC_IF_ERROR_RETURN(soc_metrolite_get_port_block( 332 unit, port, &block)); 333 SOC_IF_ERROR_RETURN(_bcm_ml_port_lanes_get( 334 unit, port,&new_lanes)); 335 BCM_IF_ERROR_RETURN(_bcm_ml_lanes_convention(&new_lanes)); 336 337 #ifdef BCM_PORT_DEFAULT_DISABLE 338 port_enable = FALSE; 339 #else 340 port_enable = TRUE; 341 #endif /* BCM_PORT_DEFAULT_DISABLE */ 342 343 for (loop = 0;loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 344 block_port=(*ml_block_ports[unit])[block][loop]; 345 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 346 BCM_IF_ERROR_RETURN(bcm_esw_port_enable_set(unit, 347 block_port, port_enable)); 348 349 speed = (*ml_port_speeds[unit])[block][new_lanes-1]; 350 351 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_max(unit, 352 block_port, &max_speed)); 353 speed = speed > max_speed ? max_speed : speed; 354 rv = bcm_esw_port_speed_set(unit, block_port, speed); 355 SOC_IF_ERROR_RETURN(rv); 356 357 SOC_IF_ERROR_RETURN(bcm_esw_linkscan_mode_get( 358 unit, block_port, &mode)); 359 360 if (mode == BCM_LINKSCAN_MODE_NONE) { 361 BCM_IF_ERROR_RETURN(bcm_esw_linkscan_mode_set( 362 unit, block_port, BCM_LINKSCAN_MODE_SW)); 363 } 364 365 BCM_IF_ERROR_RETURN(bcm_esw_port_learn_set(unit, 366 block_port, 367 BCM_PORT_LEARN_ARL | BCM_PORT_LEARN_FWD)); 368 BCM_IF_ERROR_RETURN(bcm_esw_port_stp_set( 369 unit, block_port, BCM_STG_STP_FORWARD)); 370 371 BCM_IF_ERROR_RETURN(bcm_esw_port_loopback_set(unit, 372 block_port, BCM_PORT_LOOPBACK_NONE)); 373 } /* if SOC_PBMP_MEMBER */ 374 } /* For loop */ 375 376 return BCM_E_NONE; 377 } 378 379 void soc_ml_port_bitmap_add(int unit,soc_port_t port,int block, 380 int speed, int new_lanes) { 381 int blk=0; 382 soc_info_t *si = &SOC_INFO(unit); 383 soc_pbmp_t my_pbmp_xport_xe; 384 soc_pbmp_t my_pbmp_xport_ge; 385 386 blk = SOC_DRIVER(unit)->port_info[port].blk; 387 SOC_PBMP_PORT_ADD(si->block_bitmap[blk],port); 388 389 if (block == 0) { 390 /* mxq ports */ 391 392 if (speed == 10000) { 393 SOC_PBMP_PORT_ADD(si->xe.bitmap, port); 394 SOC_PBMP_PORT_REMOVE(si->xe.disabled_bitmap, port); 395 } else { 396 SOC_PBMP_PORT_ADD(si->ge.bitmap, port); 397 SOC_PBMP_PORT_REMOVE(si->ge.disabled_bitmap, port); 398 } 399 SOC_PBMP_PORT_ADD(si->ether.bitmap, port); 400 SOC_PBMP_PORT_REMOVE(si->ether.disabled_bitmap, port); 401 402 SOC_PBMP_PORT_ADD(si->mxq.bitmap, port); 403 SOC_PBMP_PORT_REMOVE(si->mxq.disabled_bitmap, port); 404 405 SOC_PBMP_PORT_ADD(si->port.bitmap, port); 406 SOC_PBMP_PORT_REMOVE(si->port.disabled_bitmap, port); 407 408 SOC_PBMP_PORT_ADD(si->all.bitmap, port); 409 SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, port); 410 411 SOC_PORT_TYPE(unit,port)= SOC_BLK_MXQPORT; 412 si->port_speed_max[port] = speed; 413 414 } else if (block >= 1) { 415 /* xl ports */ 416 417 SOC_PBMP_CLEAR(my_pbmp_xport_xe); 418 SOC_PBMP_CLEAR(my_pbmp_xport_ge); 419 420 my_pbmp_xport_xe = soc_property_get_pbmp_default(unit, spn_PBMP_XPORT_XE, 421 my_pbmp_xport_xe); 422 my_pbmp_xport_ge = soc_property_get_pbmp_default(unit, spn_PBMP_XPORT_GE, 423 my_pbmp_xport_ge); 424 425 si->port_speed_max[port] = speed; 426 SOC_PBMP_PORT_ADD(si->xl.bitmap, port); 427 SOC_PBMP_PORT_REMOVE(si->xl.disabled_bitmap, port); 428 429 /* On XL port speed 2.5G can mean pbmp_xport_ge config or HGL port */ 430 if (SOC_PBMP_MEMBER(my_pbmp_xport_ge, port)) { 431 SOC_PBMP_PORT_ADD(si->ge.bitmap, port); 432 SOC_PBMP_PORT_REMOVE(si->ge.disabled_bitmap, port); 433 si->port_speed_max[port] = 2500; 434 } else if (SOC_PBMP_MEMBER(my_pbmp_xport_xe, port)) { 435 SOC_PBMP_PORT_ADD(si->xe.bitmap, port); 436 SOC_PBMP_PORT_REMOVE(si->xe.disabled_bitmap, port); 437 si->port_speed_max[port] = 10000; 438 } else { 439 if (speed <=2500) { 440 SOC_PBMP_PORT_ADD(si->ge.bitmap, port); 441 SOC_PBMP_PORT_REMOVE(si->ge.disabled_bitmap, port); 442 } else if (speed <= 10000) { 443 SOC_PBMP_PORT_ADD(si->xe.bitmap, port); 444 SOC_PBMP_PORT_REMOVE(si->xe.disabled_bitmap, port); 445 } else { 446 SOC_PBMP_PORT_ADD(si->hg.bitmap, port); 447 SOC_PBMP_PORT_ADD(si->st.bitmap, port); 448 SOC_PBMP_PORT_REMOVE(si->hg.disabled_bitmap, port); 449 SOC_PBMP_PORT_REMOVE(si->st.disabled_bitmap, port); 450 } 451 } 452 453 SOC_PBMP_PORT_ADD(si->ether.bitmap, port); 454 SOC_PBMP_PORT_REMOVE(si->ether.disabled_bitmap, port); 455 456 SOC_PBMP_PORT_ADD(si->port.bitmap, port); 457 SOC_PBMP_PORT_REMOVE(si->port.disabled_bitmap, port); 458 459 SOC_PBMP_PORT_ADD(si->all.bitmap, port); 460 SOC_PBMP_PORT_REMOVE(si->all.disabled_bitmap, port); 461 462 SOC_PORT_TYPE(unit,port)=SOC_BLK_XLPORT; 463 } 464 } 465 466 int _bcm_ml_update_port_mode(int unit,uint8 port,int speed) { 467 uint32 rval; 468 uint8 block; 469 bcmMxqPhyPortMode_t phy_mode = -1; 470 bcmXlCorePortMode_t core_mode_xl = -1; 471 bcmXlPhyPortMode_t phy_mode_xl = -1; 472 473 SOC_IF_ERROR_RETURN(soc_metrolite_get_port_block( 474 unit, port, &block)); 475 476 if(IS_MXQ_PORT(unit, port)) { 477 SOC_IF_ERROR_RETURN(soc_metrolite_get_mxq_phy_port_mode( 478 unit, port, speed, &phy_mode)); 479 if(phy_mode == -1) { 480 return BCM_E_FAIL; 481 } 482 } 483 if (SOC_REG_PORT_VALID(unit, XPORT_MODE_REGr, port)) { 484 SOC_IF_ERROR_RETURN(READ_XPORT_MODE_REGr(unit, port, &rval)); 485 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, PHY_PORT_MODEf, phy_mode); 486 soc_reg_field_set(unit, XPORT_MODE_REGr, &rval, 487 PORT_GMII_MII_ENABLEf, (speed >= 10000) ? 0 : 1); 488 SOC_IF_ERROR_RETURN(WRITE_XPORT_MODE_REGr(unit, port, rval)); 489 } 490 491 if(IS_XL_PORT(unit, port)) { 492 SOC_IF_ERROR_RETURN(soc_metrolite_get_xl_phy_core_port_mode(unit, port, 493 &phy_mode_xl, &core_mode_xl)); 494 if((phy_mode_xl == -1) || (core_mode_xl == -1)){ 495 return BCM_E_FAIL; 496 } 497 } 498 if (SOC_REG_PORT_VALID(unit, XLPORT_MODE_REGr, port)) { 499 SOC_IF_ERROR_RETURN(READ_XLPORT_MODE_REGr(unit, port, &rval)); 500 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, 501 EGR_1588_TIMESTAMPING_CMIC_48_ENf, 1); 502 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, 503 XPORT0_CORE_PORT_MODEf,core_mode_xl); 504 soc_reg_field_set(unit, XLPORT_MODE_REGr, &rval, 505 XPORT0_PHY_PORT_MODEf, phy_mode_xl); 506 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MODE_REGr(unit, port, rval)); 507 } 508 509 return BCM_E_NONE; 510 } 511 512 soc_error_t soc_ml_port_detach(int unit,uint8 block_port) { 513 soc_linkscan_pause(unit); 514 515 SOC_IF_ERROR_CLEAN_RETURN((soc_phyctrl_enable_set(unit, block_port, 1)), 516 soc_linkscan_continue(unit)); 517 518 SOC_IF_ERROR_CLEAN_RETURN((soc_phyctrl_detach(unit, block_port)), 519 soc_linkscan_continue(unit)); 520 521 PHY_FLAGS_CLR_ALL(unit, block_port); 522 523 soc_linkscan_continue(unit); 524 return BCM_E_NONE; 525 } 526 527 soc_error_t soc_ml_port_attach( 528 int unit, uint8 block, uint8 block_port ) { 529 uint16 phy_addr=0; 530 uint16 phy_addr_int=0; 531 int okay = 0; 532 uint64 rval64; 533 534 soc_linkscan_pause(unit); 535 536 _ml_phy_addr_default(unit, block_port, 537 &phy_addr, &phy_addr_int); 538 SOC_IF_ERROR_RETURN 539 (soc_phy_cfg_addr_set(unit,block_port,0, phy_addr)); 540 SOC_IF_ERROR_RETURN 541 (soc_phy_cfg_addr_set(unit,block_port,SOC_PHY_INTERNAL, 542 phy_addr_int)); 543 PHY_ADDR(unit, block_port) = phy_addr; 544 PHY_ADDR_INT(unit, block_port) = phy_addr_int; 545 546 SOC_IF_ERROR_RETURN(_bcm_port_probe(unit, block_port, &okay)); 547 if (!okay) { 548 soc_linkscan_continue(unit); 549 return BCM_E_INTERNAL; 550 } 551 552 SOC_IF_ERROR_RETURN(_bcm_port_mode_setup(unit, block_port, FALSE)); 553 554 /* _bcm_port_probe() sets the encap only on MAC and not on PHY. 555 * Resetting the mac encap to allow 556 * bcm_esw_port_encap() function to set encap on both MAC and PHY 557 */ 558 if (IS_HG_PORT(unit, block_port)) { 559 SOC_IF_ERROR_RETURN(READ_XLMAC_MODEr(unit,block_port, &rval64)); 560 soc_reg64_field32_set(unit, XLMAC_MODEr, &rval64, HDR_MODEf, 0); 561 SOC_IF_ERROR_RETURN(WRITE_XLMAC_MODEr(unit,block_port, rval64)); 562 bcm_esw_port_encap_set(unit, block_port, BCM_PORT_ENCAP_HIGIG); 563 } else { 564 SOC_IF_ERROR_RETURN(READ_XLMAC_MODEr(unit,block_port, &rval64)); 565 soc_reg64_field32_set(unit, XLMAC_MODEr, &rval64, HDR_MODEf, 1); 566 SOC_IF_ERROR_RETURN(WRITE_XLMAC_MODEr(unit,block_port, rval64)); 567 bcm_esw_port_encap_set(unit, block_port, BCM_PORT_ENCAP_IEEE); 568 } 569 570 soc_linkscan_continue(unit); 571 return BCM_E_NONE; 572 } 573 574 int _bcm_ml_port_lanes_set(int unit, bcm_port_t port, int lanes) 575 { 576 uint32 start_addr = 0; 577 uint32 end_addr = 0; 578 soc_pbmp_t link_pbmp; 579 uint32 time_multiplier = 1; 580 uint64 rval64; 581 uint32 rval = 0, rval1 = 0; 582 uint32 cell_cnt = 0; 583 uint32 try = 0, try_count = 0; 584 soc_timeout_t to = {0}; 585 sal_usecs_t timeout_usec = 100000; 586 int min_polls = 100; 587 uint32 pfc_enable = 0; 588 uint8 old_ports[][ML_MAX_PORTS_PER_BLOCK]= 589 {{1,0,0,0},{1,0,3,0},{0,0,0,0},{1,2,3,4}}; 590 uint8 new_ports[][ML_MAX_PORTS_PER_BLOCK]= 591 {{1,0,0,0},{1,0,3,0},{0,0,0,0},{1,2,3,4}}; 592 uint8 new_port_mode[5]={0,1,2,0,3}; 593 soc_info_t *si = &SOC_INFO(unit); 594 uint8 block = 0; 595 uint8 block_port = 0, first_port = 0; 596 uint8 try_loop = 0; 597 uint8 loop = 0; 598 int old_lanes = 0; 599 int new_lanes; 600 int config_lanes = lanes; 601 soc_field_t port_intf_reset_fld[] = { 602 XQ1_PORT_INTF_RESETf, XQ2_PORT_INTF_RESETf, 603 XQ3_PORT_INTF_RESETf, XQ4_PORT_INTF_RESETf, 604 XQ5_PORT_INTF_RESETf, XQ6_PORT_INTF_RESETf, 605 XQ7_PORT_INTF_RESETf, XQ8_PORT_INTF_RESETf}; 606 soc_field_t mmu_intf_reset_fld[] = { 607 XQ1_MMU_INTF_RESETf, XQ2_MMU_INTF_RESETf, 608 XQ3_MMU_INTF_RESETf, XQ4_MMU_INTF_RESETf, 609 XQ5_MMU_INTF_RESETf, XQ6_MMU_INTF_RESETf, 610 XQ7_MMU_INTF_RESETf, XQ8_MMU_INTF_RESETf}; 611 soc_field_t new_port_mode_fld[] = { 612 XQ1_NEW_PORT_MODEf, XQ2_NEW_PORT_MODEf, 613 XQ3_NEW_PORT_MODEf, XQ4_NEW_PORT_MODEf, 614 XQ5_NEW_PORT_MODEf, XQ6_NEW_PORT_MODEf, 615 XQ7_NEW_PORT_MODEf, XQ8_NEW_PORT_MODEf}; 616 uint8 speed_value = 0; 617 int port_speed = 0; 618 uint8 tdm_ports[4] = {0}; 619 uint8 index = 0; 620 uint32 pos = 0; 621 #if defined(METROLITE_DEBUG) 622 char config_str[80]; 623 uint8 lane_incr[ML_MAX_PORTS_PER_BLOCK]={4,2,0,1}; 624 int auto_portgroup = 0; 625 int portgroup = 0; 626 #endif 627 soc_field_t port_enable_field[ML_MAX_PORTS_PER_BLOCK]= 628 {PORT0f, PORT1f, PORT2f , PORT3f}; 629 int port_enable = 0; 630 egr_enable_entry_t egr_enable_entry = {{0}}; 631 int length_check; 632 uint64 xlmac_ctrl; 633 epc_link_bmap_entry_t epc_link_bmap_entry = {{0}}; 634 txlp_port_addr_map_table_entry_t txlp_port_addr_map_table_entry={{0}}; 635 uint64 ctr_val; 636 int cfg_num = 0; 637 ml_port_lanes_unchanged = FALSE; 638 639 /* Check input port is valid. */ 640 if (!SOC_PORT_VALID(unit, port)) { 641 return BCM_E_PORT; 642 } 643 644 if (SAL_BOOT_QUICKTURN) { 645 time_multiplier = 1000; 646 } 647 648 /* Retreive internal cfg num */ 649 BCM_IF_ERROR_RETURN(_soc_metrolite_get_cfg_num(unit, 0, &cfg_num)); 650 651 /* Check metrolite config not supporting flex operation. */ 652 if ((cfg_num == (BCM56272_DEVICE_ID_OFFSET_CFG + 1)) || 653 (cfg_num == (BCM56272_DEVICE_ID_OFFSET_CFG + 2))) { 654 LOG_DEBUG(BSL_LS_BCM_PORT, 655 (BSL_META_U(unit, 656 "Flex Operation not supported on unit %d: Int cfg %d\n"), 657 unit, cfg_num)); 658 return BCM_E_UNAVAIL; 659 } 660 661 /* Change lanes convention. */ 662 BCM_IF_ERROR_RETURN(_bcm_ml_lanes_convention(&lanes)); 663 new_lanes = lanes; 664 665 /* Check lanes parameter. */ 666 if (IS_MXQ_PORT(unit, port)) { 667 if ((new_lanes != 1) && (new_lanes != 4)) { 668 return BCM_E_PARAM; 669 } 670 } else if(IS_XL_PORT(unit, port)) { 671 if ((new_lanes != 1) && (new_lanes != 2) && (new_lanes != 4)) { 672 return BCM_E_PARAM; 673 } 674 if ((new_lanes == 2) && (port >= 9 && port <= 12) && 675 (cfg_num == (BCM56271_DEVICE_ID_OFFSET_CFG + 1))) { 676 return BCM_E_PARAM; 677 } 678 if ((new_lanes == 4) && 679 (cfg_num == (BCM56271_DEVICE_ID_OFFSET_CFG + 2))) { 680 return BCM_E_PARAM; 681 } 682 } 683 684 /* Get previous lanes set on port. */ 685 SOC_IF_ERROR_RETURN(soc_metrolite_get_port_block(unit, 686 port,&block)); 687 SOC_IF_ERROR_RETURN(_bcm_ml_port_lanes_get(unit, 688 port,&old_lanes)); 689 BCM_IF_ERROR_RETURN(_bcm_ml_lanes_convention(&old_lanes)); 690 691 /* Lanes are same, nothing to do. */ 692 if(old_lanes == new_lanes) { 693 ml_port_lanes_unchanged = TRUE; 694 return BCM_E_NONE; 695 } 696 697 /* Flex cannot be performed on linkphy or coe enabled ports. */ 698 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 699 if ((IS_LP_PORT(unit, (*ml_block_ports[unit])[block][loop])) || 700 (IS_SUBTAG_PORT(unit, (*ml_block_ports[unit])[block][loop]))) { 701 LOG_CLI((BSL_META_U(unit, 702 "HotSwap is not supported for \ 703 Subport Coe/LinkPhy Ports\n Disable CoE and \ 704 run the API again.\n"))); 705 return BCM_E_PARAM; 706 } 707 } 708 709 if (new_lanes == 1) { 710 if(!(IS_XL_PORT(unit, port))) { 711 tdm_ports[0] = (*ml_block_ports[unit])[block][0]; 712 tdm_ports[1] = (*ml_block_ports[unit])[block][0]; 713 tdm_ports[2] = (*ml_block_ports[unit])[block][0]; 714 tdm_ports[3] = (*ml_block_ports[unit])[block][0]; 715 } 716 } 717 718 if (new_lanes == 2) { 719 if(!(IS_XL_PORT(unit, port))) { 720 tdm_ports[0] = (*ml_block_ports[unit])[block][0]; 721 tdm_ports[1] = (*ml_block_ports[unit])[block][2]; 722 tdm_ports[2] = (*ml_block_ports[unit])[block][0]; 723 tdm_ports[3] = (*ml_block_ports[unit])[block][2]; 724 } 725 } 726 727 if (new_lanes == 4) { 728 tdm_ports[0] = (*ml_block_ports[unit])[block][0]; 729 tdm_ports[1] = (*ml_block_ports[unit])[block][1]; 730 tdm_ports[2] = (*ml_block_ports[unit])[block][2]; 731 tdm_ports[3] = (*ml_block_ports[unit])[block][3]; 732 } 733 734 sal_memcpy(&new_tdm[0],&ml_current_tdm[0], 735 ml_current_tdm_size *sizeof(ml_current_tdm[0])); 736 737 if(!(IS_XL_PORT(unit, port))) { 738 for (index=0,loop=0; loop < ml_tdm_pos_info[block].total_slots; loop++) { 739 pos = ml_tdm_pos_info[block].pos[loop]; 740 new_tdm[pos]=tdm_ports[index]; 741 index = (index + 1) % 4 ; 742 } 743 } 744 745 746 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 747 block_port=(*ml_block_ports[unit])[block][loop]; 748 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 749 /* 1. Stop linkscan on the port */ 750 bcm_esw_kt2_port_unlock(unit); 751 BCM_IF_ERROR_RETURN(bcm_esw_linkscan_mode_set( 752 unit, block_port, BCM_LINKSCAN_MODE_NONE)); 753 bcm_esw_kt2_port_lock(unit); 754 755 /* 2. To stop the incoming traffic, disable XLMAC Rx */ 756 SOC_IF_ERROR_RETURN(READ_XLMAC_CTRLr( 757 unit, block_port, &xlmac_ctrl)); 758 soc_reg64_field32_set(unit, XLMAC_CTRLr, &xlmac_ctrl, TX_ENf, 1); 759 soc_reg64_field32_set(unit, XLMAC_CTRLr, &xlmac_ctrl, RX_ENf, 0); 760 SOC_IF_ERROR_RETURN(WRITE_XLMAC_CTRLr( 761 unit, block_port, xlmac_ctrl)); 762 sal_udelay((10*time_multiplier)); 763 } 764 } 765 766 sal_udelay((10 * time_multiplier)); 767 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 768 block_port=(*ml_block_ports[unit])[block][loop]; 769 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 770 /* serdes requires autoneg to be False before flex operation */ 771 BCM_IF_ERROR_RETURN(bcm_esw_port_autoneg_set(unit, block_port,FALSE)); 772 /* 3. Brings the port down. */ 773 BCM_IF_ERROR_RETURN(READ_EPC_LINK_BMAPm( 774 unit, MEM_BLOCK_ANY, 0, &epc_link_bmap_entry)); 775 soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, 776 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 777 BCM_PBMP_PORT_REMOVE(link_pbmp,block_port); 778 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, 779 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 780 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm( 781 unit, MEM_BLOCK_ALL, 0, &epc_link_bmap_entry)); 782 } 783 } 784 785 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 786 block_port=(*ml_block_ports[unit])[block][loop]; 787 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 788 789 #ifdef PORT_FLUSH_DEBUG 790 /* 4. Issues MMU port flush command */ 791 /* PortFlushing creating some issue with L0 node movement. 792 * So moving to Q Flush. 793 */ 794 BCM_IF_ERROR_RETURN(READ_TOQ_FLUSH0r(unit, &flush_reg)); 795 soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, 796 FLUSH_ACTIVEf,1); 797 /* PORT FLUSHING not QUEUE FLUSHING */ 798 soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, FLUSH_TYPEf,1); 799 soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, FLUSH_NUMf,1); 800 soc_reg_field_set(unit, TOQ_FLUSH0r, &flush_reg, 801 FLUSH_ID0f, block_port); 802 BCM_IF_ERROR_RETURN(WRITE_TOQ_FLUSH0r(unit, flush_reg)); 803 #endif 804 805 806 /* 5. Save the current configuration of PAUSE/PFC flow control */ 807 BCM_IF_ERROR_RETURN(bcm_esw_port_speed_get( 808 unit, block_port, &port_speed)); 809 if (!(SAL_BOOT_BCMSIM || SAL_BOOT_PLISIM)) { 810 if (port_speed == 10000) { 811 BCM_IF_ERROR_RETURN(READ_XPORT_TO_MMU_BKPr( 812 unit, block, &pfc_enable)); 813 BCM_IF_ERROR_RETURN(WRITE_XPORT_TO_MMU_BKPr( 814 unit, block, 0)); 815 } 816 } 817 818 /* 6. flushes any pending egress packets in MXQPORT */ 819 if (SOC_REG_PORT_VALID(unit, IECELL_TXFIFO_PKT_DROP_CTLr, block_port)) { 820 READ_IECELL_TXFIFO_PKT_DROP_CTLr(unit, block_port, &rval); 821 soc_reg_field_set(unit, IECELL_TXFIFO_PKT_DROP_CTLr, &rval, 822 DROP_ENf, 1); 823 WRITE_IECELL_TXFIFO_PKT_DROP_CTLr(unit, block_port, rval); 824 } 825 826 if (SOC_REG_PORT_VALID(unit, XP_TXFIFO_PKT_DROP_CTLr, block_port)) { 827 READ_XP_TXFIFO_PKT_DROP_CTLr(unit, block_port, &rval); 828 soc_reg_field_set(unit, XP_TXFIFO_PKT_DROP_CTLr, &rval, 829 DROP_ENf, 1); 830 WRITE_XP_TXFIFO_PKT_DROP_CTLr(unit, block_port, rval); 831 } 832 833 #ifndef PORT_FLUSH_DEBUG 834 BCM_IF_ERROR_RETURN(bcm_kt2_cosq_port_flush( 835 unit, block_port, bcmCosqFlushTypeQueue)); 836 #endif 837 838 #ifdef PORT_FLUSH_DEBUG 839 /* 7. Waits until all egress port packets are drained. */ 840 try_count=0; 841 if ((SAL_BOOT_BCMSIM || SAL_BOOT_PLISIM)) { 842 BCM_IF_ERROR_RETURN(READ_TOQ_FLUSH0r(unit, &rval)); 843 soc_reg_field_set(unit, TOQ_FLUSH0r, &rval, FLUSH_ACTIVEf, 0); 844 BCM_IF_ERROR_RETURN(WRITE_TOQ_FLUSH0r(unit, rval)); 845 } 846 847 do { 848 soc_timeout_init(&to, timeout_usec, min_polls); 849 if(soc_timeout_check(&to)) { 850 LOG_ERROR(BSL_LS_BCM_PORT, 851 (BSL_META_U(unit, 852 "%s:%d:TimeOut InternalError\n"), 853 FUNCTION_NAME(),__LINE__)); 854 return BCM_E_INTERNAL; 855 } 856 try_count++; 857 BCM_IF_ERROR_RETURN(READ_TOQ_FLUSH0r(unit, &rval)); 858 if (soc_reg_field_get( 859 unit, TOQ_FLUSH0r, rval, FLUSH_ACTIVEf) == 0) { 860 break; 861 } 862 } while (try_count != 3); 863 864 if (try_count == 3) { 865 return BCM_E_TIMEOUT; 866 } 867 #endif 868 869 try_count=0; 870 if ((SAL_BOOT_BCMSIM || SAL_BOOT_PLISIM)) { 871 if (SOC_REG_PORT_VALID(unit, XP_TXFIFO_CELL_CNTr, block_port)) { 872 BCM_IF_ERROR_RETURN(READ_XP_TXFIFO_CELL_CNTr( 873 unit, block_port, &rval)); 874 soc_reg_field_set(unit, XP_TXFIFO_CELL_CNTr, 875 &rval, CELL_CNTf, 0); 876 BCM_IF_ERROR_RETURN(WRITE_XP_TXFIFO_CELL_CNTr( 877 unit, block_port, rval)); 878 } 879 880 if (SOC_REG_PORT_VALID(unit, IECELL_TXFIFO_CELL_CNTr, block_port)) { 881 BCM_IF_ERROR_RETURN(READ_IECELL_TXFIFO_CELL_CNTr( 882 unit, block_port, &rval)); 883 soc_reg_field_set(unit, IECELL_TXFIFO_CELL_CNTr, 884 &rval, CELL_CNTf, 0); 885 BCM_IF_ERROR_RETURN(WRITE_IECELL_TXFIFO_CELL_CNTr( 886 unit, block_port, rval)); 887 } 888 889 } 890 soc_timeout_init(&to, timeout_usec, min_polls); 891 for (try=0; try<100 && try_count < 10 ; try++) { 892 if(soc_timeout_check(&to)) { 893 LOG_ERROR(BSL_LS_BCM_PORT, 894 (BSL_META_U(unit, 895 "%s:%d:TimeOut InternalError\n"), 896 FUNCTION_NAME(),__LINE__)); 897 return BCM_E_INTERNAL; 898 } 899 900 BCM_IF_ERROR_RETURN(READ_XP_TXFIFO_CELL_CNTr ( 901 unit,block_port, &rval)); 902 cell_cnt=soc_reg_field_get(unit, XP_TXFIFO_CELL_CNTr, 903 rval, CELL_CNTf); 904 if (cell_cnt == 0) { 905 try_count++; 906 break; 907 } 908 } 909 910 if (try == 100) { 911 return BCM_E_TIMEOUT; 912 } 913 } 914 } 915 916 /* Disable port before detaching phy */ 917 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 918 block_port=(*ml_block_ports[unit])[block][loop]; 919 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 920 BCM_IF_ERROR_RETURN( 921 bcm_esw_port_enable_set(unit, block_port, 0)); 922 } 923 } 924 925 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 926 block_port=(*ml_block_ports[unit])[block][loop]; 927 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 928 929 /* 8. Powerdown Vipercore/Eaglecore serdes */ 930 if (SOC_REG_PORT_VALID(unit, XPORT_XGXS_CTRLr, block_port)) { 931 SOC_IF_ERROR_RETURN(READ_XPORT_XGXS_CTRLr(unit, block_port, &rval)); 932 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, 933 IDDQf,1); 934 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, 935 PWRDWNf,1); 936 WRITE_XPORT_XGXS_CTRLr(unit, block_port,rval); 937 } 938 939 940 if (SOC_REG_PORT_VALID(unit, XLPORT_XGXS0_CTRL_REGr, block_port)) { 941 SOC_IF_ERROR_RETURN(READ_XLPORT_XGXS0_CTRL_REGr(unit, 942 block_port, &rval)); 943 soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, 944 PWRDWNf, 1); 945 SOC_IF_ERROR_RETURN(WRITE_XLPORT_XGXS0_CTRL_REGr(unit, 946 block_port, rval)); 947 } 948 949 /* 9. Disable egress cell request generation. */ 950 if(block > 0) { 951 sal_memset(&egr_enable_entry, 0, sizeof(egr_enable_entry_t)); 952 soc_mem_field32_set(unit, EGR_ENABLEm, &egr_enable_entry, PRT_ENABLEf, 0); 953 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, block_port, 954 &egr_enable_entry)); 955 } else { 956 SOC_IF_ERROR_RETURN(READ_TXLP_PORT_ENABLEr(unit, port, 957 &rval)); 958 port_enable = soc_reg_field_get(unit, TXLP_PORT_ENABLEr, rval, 959 PORT_ENABLEf); 960 port_enable &= ~(1 << (loop)); 961 soc_reg_field_set(unit, TXLP_PORT_ENABLEr, &rval, 962 PORT_ENABLEf, port_enable); 963 BCM_IF_ERROR_RETURN(WRITE_TXLP_PORT_ENABLEr(unit, port, rval)); 964 } 965 966 /* 10. disable the MXQPORT flush. */ 967 if (SOC_REG_PORT_VALID(unit, XP_TXFIFO_PKT_DROP_CTLr, block_port)) { 968 READ_XP_TXFIFO_PKT_DROP_CTLr(unit, block_port,&rval); 969 soc_reg_field_set(unit, XP_TXFIFO_PKT_DROP_CTLr, &rval, 970 DROP_ENf,0); 971 WRITE_XP_TXFIFO_PKT_DROP_CTLr(unit, block_port,rval); 972 } 973 974 if (SOC_REG_PORT_VALID(unit, IECELL_TXFIFO_PKT_DROP_CTLr, block_port)) { 975 READ_IECELL_TXFIFO_PKT_DROP_CTLr(unit, block_port,&rval); 976 soc_reg_field_set(unit, IECELL_TXFIFO_PKT_DROP_CTLr, &rval, 977 DROP_ENf,0); 978 WRITE_IECELL_TXFIFO_PKT_DROP_CTLr(unit, block_port,rval); 979 } 980 /* 11. Restore PFC */ 981 if (!(SAL_BOOT_BCMSIM || SAL_BOOT_PLISIM)) { 982 if (port_speed >= 10000) { 983 BCM_IF_ERROR_RETURN(WRITE_XPORT_TO_MMU_BKPr( 984 unit, block, pfc_enable)); 985 } 986 } 987 /* PLEASE NOTE THAT PORT IS STILL DOWN */ 988 989 } /* If SOC_PBMP_MEMBER */ 990 } /* for loop */ 991 992 /* Update local pbmp's */ 993 soc_linkscan_pause(unit); 994 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 995 block_port=(*ml_block_ports[unit])[block][loop]; 996 if ((old_ports[old_lanes-1][loop] == 0) && 997 (new_ports[new_lanes-1][loop] == 0)) { 998 /* Either not used */ 999 continue; 1000 } 1001 1002 si->port_speed_max[block_port]=(*ml_port_speeds[unit])[block] 1003 [new_lanes-1]; 1004 1005 if (old_ports[old_lanes-1][loop] == new_ports[new_lanes-1][loop] ) { 1006 /* same port was used so only speed change */ 1007 soc_katana2_pbmp_remove(unit,block_port); 1008 soc_ml_port_bitmap_add(unit,block_port,block, 1009 si->port_speed_max[block_port], new_lanes); 1010 } 1011 if (old_ports[old_lanes-1][loop] > new_ports[new_lanes-1][loop]) { 1012 /* This port is not applicable so remove it from pbmp list */ 1013 soc_katana2_pbmp_remove(unit,block_port); 1014 continue; 1015 } 1016 if (new_ports[new_lanes-1][loop] > old_ports[old_lanes-1][loop]) { 1017 /* This port is new so add it in pbmp list first */ 1018 soc_ml_port_bitmap_add(unit,block_port, block, 1019 si->port_speed_max[block_port], new_lanes); 1020 } 1021 BCM_IF_ERROR_RETURN(bcm_katana2_cosq_reconfigure_flexio(unit, block_port, config_lanes)); 1022 } 1023 soc_katana2_pbmp_all_resync(unit) ; 1024 soc_esw_dport_init(unit); 1025 soc_linkscan_continue(unit); 1026 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1027 block_port=(*ml_block_ports[unit])[block][loop]; 1028 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1029 SOC_IF_ERROR_RETURN(_soc_ml_mmu_reconfigure(unit, block_port)); 1030 } 1031 } 1032 /* ReConfigure H/W */ 1033 /* 1. Soft-reset relevant MXQPORT(s) */ 1034 if (block < 1) { 1035 soc_metrolite_block_reset(unit, block, 0); 1036 } 1037 1038 /* ReConfigure TDM */ 1039 soc_metrolite_reconfigure_tdm(unit, ml_current_tdm_size, new_tdm); 1040 sal_memcpy(&ml_current_tdm[0],&new_tdm[0], 1041 ml_current_tdm_size *sizeof(ml_current_tdm[0])); 1042 1043 /* WORK-AROUND for port-flushing i.e. need to repeat below step twice */ 1044 for (try_loop = 0; try_loop < 2; try_loop++) { 1045 /* EP Reset */ 1046 if ((SAL_BOOT_BCMSIM || SAL_BOOT_PLISIM)) { 1047 BCM_IF_ERROR_RETURN(WRITE_DYNAMIC_PORT_RECFG_VECTOR_CFGr( 1048 unit, 0)); 1049 } 1050 1051 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1052 block_port=(*ml_block_ports[unit])[block][loop]; 1053 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1054 rval1 |= (1 << block_port); 1055 } 1056 } 1057 1058 BCM_IF_ERROR_RETURN(WRITE_DYNAMIC_PORT_RECFG_VECTOR_CFGr( 1059 unit, rval1)); 1060 1061 if ((SAL_BOOT_BCMSIM || SAL_BOOT_PLISIM)) { 1062 BCM_IF_ERROR_RETURN(WRITE_DYNAMIC_PORT_RECFG_VECTOR_CFGr( 1063 unit, 0)); 1064 } 1065 1066 try_count = 0; 1067 do { 1068 soc_timeout_init(&to, timeout_usec, min_polls); 1069 if(soc_timeout_check(&to)) { 1070 LOG_ERROR(BSL_LS_BCM_PORT, 1071 (BSL_META_U(unit, 1072 "%s:%d:TimeOut InternalError\n"), 1073 FUNCTION_NAME(),__LINE__)); 1074 return BCM_E_INTERNAL; 1075 } 1076 try_count++; 1077 1078 BCM_IF_ERROR_RETURN(READ_DYNAMIC_PORT_RECFG_VECTOR_CFGr( 1079 unit, &rval1)); 1080 if (rval1 == 0 ) { 1081 break; 1082 } 1083 } while (try_count != 3); 1084 1085 if (try_count == 3) { 1086 return BCM_E_TIMEOUT; 1087 } 1088 1089 sal_usleep(1000); 1090 } /* for try_loop */ 1091 1092 if (block >= 1) { 1093 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1094 READ_EDATABUF_DBG_PORT_INTF_RESETr(unit, &rval); 1095 soc_reg_field_set(unit, EDATABUF_DBG_PORT_INTF_RESETr, 1096 &rval, port_intf_reset_fld[(4*block) + loop - 4], 1); 1097 WRITE_EDATABUF_DBG_PORT_INTF_RESETr(unit, rval); 1098 READ_EDATABUF_DBG_MMU_INTF_RESETr(unit, &rval); 1099 soc_reg_field_set(unit, EDATABUF_DBG_MMU_INTF_RESETr, 1100 &rval, mmu_intf_reset_fld[(4*block) + loop - 4], 1); 1101 soc_reg_field_set(unit, EDATABUF_DBG_MMU_INTF_RESETr, 1102 &rval, new_port_mode_fld[(4*block) + loop - 4], 1103 new_port_mode[new_lanes]); 1104 WRITE_EDATABUF_DBG_MMU_INTF_RESETr(unit, rval); 1105 } 1106 } else if (block == 0){ 1107 WRITE_TXLP_PORT_CREDIT_RESETr(unit, port,0xf); 1108 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1109 sal_memset(&txlp_port_addr_map_table_entry,0, 1110 sizeof(txlp_port_addr_map_table_entry_t)); 1111 block_port=(*ml_block_ports[unit])[block][loop]; 1112 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1113 1114 if (si->port_speed_max[port] <= 2500) { 1115 end_addr = start_addr + (( 8 * 4) - 1); /* 8 cells */ 1116 } else if(si->port_speed_max[port] <= 10000) { 1117 end_addr = start_addr + (( 16 * 4) - 1); 1118 } else { 1119 return BCM_E_PARAM; 1120 } 1121 1122 soc_TXLP_PORT_ADDR_MAP_TABLEm_field_set(unit, 1123 &txlp_port_addr_map_table_entry,START_ADDRf,&start_addr); 1124 soc_TXLP_PORT_ADDR_MAP_TABLEm_field_set(unit, 1125 &txlp_port_addr_map_table_entry,END_ADDRf,&end_addr); 1126 start_addr = end_addr+1; 1127 } 1128 1129 BCM_IF_ERROR_RETURN(WRITE_TXLP_PORT_ADDR_MAP_TABLEm( 1130 unit,SOC_INFO(unit).txlp_block[block], 1131 loop, &txlp_port_addr_map_table_entry)); 1132 } /* for loop */ 1133 } /* if else block != 0 */ 1134 1135 /* Begin: Link up sequence */ 1136 sal_udelay((10*time_multiplier)); 1137 1138 /* 1. Bring edatabuf port and mmu intf out of reset */ 1139 if(block >= 1) { 1140 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1141 READ_EDATABUF_DBG_PORT_INTF_RESETr(unit, &rval); 1142 soc_reg_field_set(unit, EDATABUF_DBG_PORT_INTF_RESETr, 1143 &rval, port_intf_reset_fld[(4*block) + loop - 4], 0); 1144 WRITE_EDATABUF_DBG_PORT_INTF_RESETr(unit, rval); 1145 READ_EDATABUF_DBG_MMU_INTF_RESETr(unit, &rval); 1146 soc_reg_field_set(unit, EDATABUF_DBG_MMU_INTF_RESETr, 1147 &rval, mmu_intf_reset_fld[(4*block) + loop - 4], 0); 1148 WRITE_EDATABUF_DBG_MMU_INTF_RESETr(unit, rval); 1149 } 1150 } 1151 1152 if (block == 0) { 1153 WRITE_TXLP_PORT_CREDIT_RESETr(unit, port,0); 1154 } 1155 1156 /* 2. Enable port */ 1157 BCM_IF_ERROR_RETURN(READ_EPC_LINK_BMAPm( 1158 unit, MEM_BLOCK_ANY, 0, &epc_link_bmap_entry)); 1159 soc_mem_pbmp_field_get(unit, EPC_LINK_BMAPm, 1160 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 1161 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1162 block_port=(*ml_block_ports[unit])[block][loop]; 1163 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1164 BCM_PBMP_PORT_ADD(link_pbmp,block_port); 1165 } 1166 } 1167 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, 1168 &epc_link_bmap_entry, PORT_BITMAPf,&link_pbmp); 1169 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm( 1170 unit, MEM_BLOCK_ALL, 0, &epc_link_bmap_entry)); 1171 1172 sal_udelay((10*time_multiplier)); 1173 1174 /* Bring out of reset */ 1175 if (block < 1) { 1176 soc_metrolite_block_reset(unit, block, 1); 1177 } 1178 1179 first_port = (*ml_block_ports[unit])[block][0]; 1180 if (SOC_REG_PORT_VALID(unit, XLPORT_XGXS0_CTRL_REGr, first_port)) { 1181 SOC_IF_ERROR_RETURN(READ_XLPORT_XGXS0_CTRL_REGr(unit, first_port, &rval)); 1182 1183 soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, PWRDWNf, 0); 1184 SOC_IF_ERROR_RETURN(WRITE_XLPORT_XGXS0_CTRL_REGr(unit, first_port, rval)); 1185 1186 soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, IDDQf, 0); 1187 SOC_IF_ERROR_RETURN(WRITE_XLPORT_XGXS0_CTRL_REGr(unit, first_port, rval)); 1188 1189 soc_reg_field_set(unit, XLPORT_XGXS0_CTRL_REGr, &rval, RSTB_HWf, 1); 1190 SOC_IF_ERROR_RETURN(WRITE_XLPORT_XGXS0_CTRL_REGr(unit, first_port, rval)); 1191 1192 } else if (SOC_REG_PORT_VALID(unit, XPORT_XGXS_CTRLr, first_port)) { 1193 SOC_IF_ERROR_RETURN(READ_XPORT_XGXS_CTRLr(unit, first_port, &rval)); 1194 1195 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, PWRDWNf, 0); 1196 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr(unit, first_port, rval)); 1197 1198 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, IDDQf, 0); 1199 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr(unit, first_port, rval)); 1200 1201 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, RSTB_HWf, 1); 1202 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr(unit, first_port, rval)); 1203 1204 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, RSTB_MDIOREGSf, 1); 1205 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr(unit, first_port, rval)); 1206 1207 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, RSTB_PLLf, 1); 1208 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr(unit, first_port, rval)); 1209 1210 for (loop=0;loop<ML_MAX_PORTS_PER_BLOCK;loop++) { 1211 block_port=(*ml_block_ports[unit])[block][loop]; 1212 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1213 SOC_IF_ERROR_RETURN(READ_XPORT_XGXS_CTRLr( 1214 unit, block_port, &rval)); 1215 if (si->port_speed_max[block_port] > 2500) { 1216 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, 1217 TXD10G_FIFO_RSTBf, 1); 1218 } else { 1219 soc_reg_field_set(unit, XPORT_XGXS_CTRLr, &rval, 1220 TXD10G_FIFO_RSTBf,0); 1221 } 1222 soc_reg_field_set(unit,XPORT_XGXS_CTRLr, &rval, 1223 TXD1G_FIFO_RSTBf, 0xF); 1224 SOC_IF_ERROR_RETURN(WRITE_XPORT_XGXS_CTRLr( 1225 unit,block_port, rval)); 1226 } 1227 } 1228 } 1229 1230 if (block >= 1) { 1231 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1232 block_port=(*ml_block_ports[unit])[block][loop]; 1233 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1234 if(SOC_REG_PORT_VALID(unit, XLPORT_MAC_CONTROLr, block_port)) { 1235 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_CONTROLr(unit, block_port, &rval)); 1236 1237 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 1); 1238 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, block_port, rval)); 1239 1240 sal_usleep(1000); 1241 soc_reg_field_set(unit, XLPORT_MAC_CONTROLr, &rval, XMAC0_RESETf, 0); 1242 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_CONTROLr(unit, block_port, rval)); 1243 } 1244 } 1245 } 1246 1247 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1248 block_port=(*ml_block_ports[unit])[block][loop]; 1249 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1250 if (SOC_REG_PORT_VALID(unit, IECELL_CONFIGr, block_port)) { 1251 SOC_IF_ERROR_RETURN(READ_IECELL_CONFIGr(unit, block_port, &rval)); 1252 1253 soc_reg_field_set(unit, IECELL_CONFIGr, &rval, SOFT_RESETf, 1); 1254 SOC_IF_ERROR_RETURN(WRITE_IECELL_CONFIGr(unit, block_port, rval)); 1255 1256 sal_usleep(1000); 1257 soc_reg_field_set(unit, IECELL_CONFIGr, &rval, SOFT_RESETf, 0); 1258 SOC_IF_ERROR_RETURN(WRITE_IECELL_CONFIGr(unit, block_port, rval)); 1259 } 1260 } 1261 } 1262 } 1263 1264 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1265 block_port=(*ml_block_ports[unit])[block][loop]; 1266 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1267 BCM_IF_ERROR_RETURN(_bcm_ml_update_port_mode( 1268 unit,block_port, 1269 si->port_speed_max[block_port])); 1270 break; 1271 } 1272 } 1273 1274 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1275 block_port=(*ml_block_ports[unit])[block][loop]; 1276 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1277 if(SOC_REG_PORT_VALID(unit, XPORT_XMAC_CONTROLr, block_port)) { 1278 SOC_IF_ERROR_RETURN(READ_XPORT_XMAC_CONTROLr(unit, block_port, &rval)); 1279 soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 1); 1280 SOC_IF_ERROR_RETURN(WRITE_XPORT_XMAC_CONTROLr(unit, block_port, rval)); 1281 } 1282 } 1283 } 1284 sal_udelay(10); 1285 1286 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1287 block_port=(*ml_block_ports[unit])[block][loop]; 1288 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1289 if(SOC_REG_PORT_VALID(unit, XPORT_XMAC_CONTROLr, block_port)) { 1290 SOC_IF_ERROR_RETURN(READ_XPORT_XMAC_CONTROLr(unit, block_port, &rval)); 1291 soc_reg_field_set(unit, XPORT_XMAC_CONTROLr, &rval, XMAC_RESETf, 0); 1292 SOC_IF_ERROR_RETURN(WRITE_XPORT_XMAC_CONTROLr(unit, block_port, rval)); 1293 } 1294 } 1295 } 1296 1297 length_check = soc_property_get(unit, spn_MAC_LENGTH_CHECK_ENABLE, 0); 1298 1299 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1300 block_port=(*ml_block_ports[unit])[block][loop]; 1301 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1302 if(SOC_REG_PORT_VALID(unit, MAC_RSV_MASKr, block_port)) { 1303 SOC_IF_ERROR_RETURN(READ_MAC_RSV_MASKr(unit, block_port, &rval)); 1304 1305 if (length_check) { 1306 rval |= 0x20; /* set bit 5 to enable frame length check */ 1307 } else { 1308 rval &= ~0x20; /* clear bit 5 to disable frame length check */ 1309 } 1310 SOC_IF_ERROR_RETURN(WRITE_MAC_RSV_MASKr(unit,block_port, rval)); 1311 } /* SOC_REG_PORT_VALID MAC_RSV_MASK */ 1312 1313 if(SOC_REG_PORT_VALID(unit, XLPORT_MAC_RSV_MASKr, block_port)) { 1314 SOC_IF_ERROR_RETURN(READ_XLPORT_MAC_RSV_MASKr(unit, 1315 block_port, &rval)); 1316 1317 if (IS_ST_PORT(unit, block_port)) { 1318 /* No frame length for stack */ 1319 soc_reg_field_set(unit, XLPORT_MAC_RSV_MASKr, 1320 &rval, MASKf, 0x58); 1321 } else { 1322 if (length_check) { 1323 rval |= 0x20; /* set bit 5 to enable frame length check */ 1324 } else { 1325 rval &= ~0x20; /* clear bit 5 to disable frame length check */ 1326 } 1327 } 1328 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MAC_RSV_MASKr(unit, 1329 block_port, rval)); 1330 } /* SOC_REG_PORT_VALID MAC_RSV_MASK */ 1331 } /* if SOC_PBMP_MEMBER */ 1332 } /* for loop */ 1333 1334 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1335 block_port=(*ml_block_ports[unit])[block][loop]; 1336 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1337 1338 if (SOC_REG_PORT_VALID(unit, XPORT_MIB_RESETr, block_port)) { 1339 SOC_IF_ERROR_RETURN(WRITE_XPORT_MIB_RESETr(unit, block_port, 0xf)); 1340 sal_usleep(1000); 1341 SOC_IF_ERROR_RETURN(WRITE_XPORT_MIB_RESETr(unit, block_port, 0x0)); 1342 } 1343 1344 if (SOC_REG_PORT_VALID(unit, XLPORT_MIB_RESETr, block_port)) { 1345 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, block_port, 0xf)); 1346 sal_usleep(1000); 1347 SOC_IF_ERROR_RETURN(WRITE_XLPORT_MIB_RESETr(unit, block_port, 0x0)); 1348 } 1349 } 1350 } 1351 1352 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1353 block_port=(*ml_block_ports[unit])[block][loop]; 1354 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1355 if (SOC_REG_PORT_VALID(unit, XLMAC_MODEr, block_port)) { 1356 SOC_IF_ERROR_RETURN(READ_XLMAC_MODEr(unit,block_port, 1357 &rval64)); 1358 if (si->port_speed_max[block_port] == 1000) { 1359 speed_value = ML_SPEED_MODE_LINK_1G; 1360 } else if (si->port_speed_max[block_port] == 2500) { 1361 speed_value = ML_SPEED_MODE_LINK_2G5; 1362 } else { 1363 speed_value = ML_SPEED_MODE_LINK_10G_PLUS; 1364 } 1365 1366 soc_reg64_field32_set(unit, XLMAC_MODEr, &rval64, 1367 SPEED_MODEf,speed_value); 1368 if (IS_ST_PORT(unit, block_port)) { 1369 soc_reg64_field32_set(unit, XLMAC_MODEr, &rval64, 1370 HDR_MODEf, 2); 1371 } else { 1372 soc_reg64_field32_set(unit, XLMAC_MODEr, &rval64, 1373 HDR_MODEf, 0); 1374 } 1375 SOC_IF_ERROR_RETURN(WRITE_XLMAC_MODEr(unit,block_port, 1376 rval64)); 1377 } /* if SOC_REG_PORT_VALID XLMAC_MODE */ 1378 } /* if SOC_PBMP_MEMBER block_port */ 1379 } /* for loop */ 1380 1381 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1382 block_port=(*ml_block_ports[unit])[block][loop]; 1383 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1384 if (SOC_REG_PORT_VALID(unit, XLMAC_RX_CTRLr, block_port)) { 1385 SOC_IF_ERROR_RETURN(READ_XLMAC_RX_CTRLr( 1386 unit,block_port, &rval64)); 1387 if (IS_ST_PORT(unit, block_port)) { 1388 soc_reg64_field32_set(unit, XLMAC_RX_CTRLr, &rval64, 1389 RUNT_THRESHOLDf, 76); 1390 } else { 1391 soc_reg64_field32_set(unit, XLMAC_RX_CTRLr, &rval64, 1392 RUNT_THRESHOLDf, 64); 1393 } 1394 soc_reg64_field32_set(unit, XLMAC_RX_CTRLr, &rval64, 1395 STRIP_CRCf, 0); 1396 SOC_IF_ERROR_RETURN(WRITE_XLMAC_RX_CTRLr( 1397 unit,block_port, rval64)); 1398 } /* if SOC_REG_PORT_VALID XLMAC_RX_CTRL */ 1399 } /* if SOC_PBMP_MEMBER block_port */ 1400 } /* for loop */ 1401 1402 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1403 block_port=(*ml_block_ports[unit])[block][loop]; 1404 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1405 if (SOC_REG_PORT_VALID(unit, XLMAC_TX_CTRLr, block_port)) { 1406 SOC_IF_ERROR_RETURN(READ_XLMAC_TX_CTRLr( 1407 unit, block_port, &rval64)); 1408 soc_reg64_field32_set(unit, XLMAC_TX_CTRLr, &rval64, 1409 CRC_MODEf,3); 1410 SOC_IF_ERROR_RETURN(WRITE_XLMAC_TX_CTRLr( 1411 unit,block_port, rval64)); 1412 } /* if SOC_REG_PORT_VALID XLMAC_TX_CTRL */ 1413 } /* if SOC_PBMP_MEMBER block_port */ 1414 } /* for loop */ 1415 1416 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1417 block_port=(*ml_block_ports[unit])[block][loop]; 1418 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1419 if (SOC_REG_PORT_VALID(unit, XLMAC_RX_MAX_SIZEr, block_port)) { 1420 SOC_IF_ERROR_RETURN(READ_XLMAC_RX_MAX_SIZEr( 1421 unit,block_port, &rval64)); 1422 soc_reg64_field32_set(unit, XLMAC_RX_MAX_SIZEr, &rval64, 1423 RX_MAX_SIZEf,(12*1024)); 1424 SOC_IF_ERROR_RETURN(WRITE_XLMAC_RX_MAX_SIZEr( 1425 unit,block_port, rval64)); 1426 } /* if SOC_REG_PORT_VALID XLMAC_RX_MAX_SIZE */ 1427 } /* if SOC_PBMP_MEMBER block_port */ 1428 } /* for loop */ 1429 1430 if (SOC_REG_PORT_VALID(unit, XLPORT_ECC_CONTROLr, port)) { 1431 SOC_IF_ERROR_RETURN(READ_XLPORT_ECC_CONTROLr(unit, port, &rval)); 1432 soc_reg_field_set(unit, XLPORT_ECC_CONTROLr, &rval, 1433 MIB_TSC_MEM_ENf, 1); 1434 SOC_IF_ERROR_RETURN(WRITE_XLPORT_ECC_CONTROLr(unit, port, rval)); 1435 } 1436 1437 /* detach phy from old port */ 1438 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1439 block_port=(*ml_block_ports[unit])[block][loop]; 1440 if ((old_ports[old_lanes-1][loop] == 0) && 1441 (new_ports[new_lanes-1][loop] == 0)) { 1442 continue; 1443 } 1444 if (old_ports[old_lanes-1][loop] == new_ports[new_lanes-1][loop] ) { 1445 /* same port was used so only speed change */ 1446 SOC_IF_ERROR_RETURN(soc_ml_port_detach(unit,block_port)); 1447 } 1448 if (old_ports[old_lanes-1][loop] > new_ports[new_lanes-1][loop]) { 1449 /* This port is not applicable so remove it from pbmp list */ 1450 SOC_IF_ERROR_RETURN(soc_ml_port_detach(unit,block_port)); 1451 continue; 1452 } 1453 if (new_ports[new_lanes-1][loop] > old_ports[old_lanes-1][loop]) { 1454 /* This port is new continue */ 1455 continue; 1456 } 1457 } 1458 1459 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1460 block_port=(*ml_block_ports[unit])[block][loop]; 1461 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1462 1463 if (SOC_REG_PORT_VALID(unit, XPORT_PORT_ENABLEr, block_port)) { 1464 SOC_IF_ERROR_RETURN(READ_XPORT_PORT_ENABLEr(unit, block_port, 1465 &rval)); 1466 soc_reg_field_set(unit, XPORT_PORT_ENABLEr, &rval, 1467 port_enable_field[loop], 1); 1468 SOC_IF_ERROR_RETURN(WRITE_XPORT_PORT_ENABLEr(unit, block_port, 1469 rval)); 1470 } 1471 1472 if (SOC_REG_PORT_VALID(unit, XLPORT_ENABLE_REGr, block_port)) { 1473 SOC_IF_ERROR_RETURN(READ_XLPORT_ENABLE_REGr(unit, block_port, 1474 &rval)); 1475 soc_reg_field_set(unit, XLPORT_ENABLE_REGr, &rval, 1476 port_enable_field[loop], 1); 1477 SOC_IF_ERROR_RETURN(WRITE_XLPORT_ENABLE_REGr(unit, block_port, 1478 rval)); 1479 } 1480 1481 }/* if SOC_PBMP_MEMBER block_port */ 1482 } /* for loop */ 1483 1484 sal_udelay((10*time_multiplier)); 1485 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1486 block_port=(*ml_block_ports[unit])[block][loop]; 1487 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1488 BCM_IF_ERROR_RETURN(soc_mac_xl.md_enable_set( 1489 unit, block_port, TRUE)); 1490 } /* if SOC_PBMP_MEMBER block_port */ 1491 } /* for loop */ 1492 1493 if (SOC_REG_PORT_VALID(unit, THDO_PORT_DISABLE_CFG1r, port)) { 1494 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1495 block_port=(*ml_block_ports[unit])[block][loop]; 1496 SOC_IF_ERROR_RETURN(READ_THDO_PORT_DISABLE_CFG1r(unit,&rval)); 1497 1498 soc_reg_field_set(unit, THDO_PORT_DISABLE_CFG1r, &rval, 1499 PORT_WRf,1); 1500 soc_reg_field_set(unit, THDO_PORT_DISABLE_CFG1r, &rval, 1501 PORT_WR_TYPEf,0); 1502 soc_reg_field_set(unit, THDO_PORT_DISABLE_CFG1r, &rval, 1503 PORT_IDf,block_port); 1504 SOC_IF_ERROR_RETURN(WRITE_THDO_PORT_DISABLE_CFG1r(unit,rval)); 1505 1506 sal_udelay(10*time_multiplier); 1507 1508 if ((SAL_BOOT_BCMSIM || SAL_BOOT_PLISIM)) { 1509 soc_reg_field_set(unit, THDO_PORT_DISABLE_CFG1r, &rval, 1510 PORT_WRf,0); 1511 SOC_IF_ERROR_RETURN(WRITE_THDO_PORT_DISABLE_CFG1r( 1512 unit,rval)); 1513 } 1514 SOC_IF_ERROR_RETURN(READ_THDO_PORT_DISABLE_CFG1r(unit,&rval)); 1515 1516 if (soc_reg_field_get(unit, THDO_PORT_DISABLE_CFG1r, rval, 1517 PORT_WRf) != 0) { 1518 return BCM_E_TIMEOUT; 1519 } 1520 } /* for loop */ 1521 } /* if SOC_REG_PORT_VALID THDO_PORT_DISABLE_CFG1 */ 1522 1523 sal_udelay((10*time_multiplier)); 1524 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1525 block_port=(*ml_block_ports[unit])[block][loop]; 1526 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1527 if(block > 0) { 1528 sal_memset(&egr_enable_entry, 0, sizeof(egr_enable_entry_t)); 1529 soc_mem_field32_set(unit, EGR_ENABLEm, &egr_enable_entry, PRT_ENABLEf, 1); 1530 SOC_IF_ERROR_RETURN(WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, block_port, 1531 &egr_enable_entry)); 1532 } else { 1533 SOC_IF_ERROR_RETURN(READ_TXLP_PORT_ENABLEr( 1534 unit, port, &rval)); 1535 port_enable = soc_reg_field_get(unit, TXLP_PORT_ENABLEr, 1536 rval, PORT_ENABLEf); 1537 port_enable |= ( 1<< ((*ml_port_to_block_subports[unit]) 1538 [block_port-1])); 1539 soc_reg_field_set(unit, TXLP_PORT_ENABLEr, 1540 &rval, PORT_ENABLEf, port_enable); 1541 SOC_IF_ERROR_RETURN(WRITE_TXLP_PORT_ENABLEr( 1542 unit, port, rval)); 1543 } 1544 } 1545 } 1546 1547 /* Update port_num_lanes in soc_info_config */ 1548 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1549 block_port=(*ml_block_ports[unit])[block][loop]; 1550 if (!SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1551 /* Not a valid port. So set num_lanes to 0 */ 1552 si->port_num_lanes[block_port] = 0; 1553 si->port_speed_max[block_port] = 0; 1554 sal_snprintf(si->port_name[block_port], sizeof(si->port_name[block_port]), 1555 "?%d", block_port); 1556 } 1557 } 1558 1559 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1560 block_port=(*ml_block_ports[unit])[block][loop]; 1561 if ((old_ports[old_lanes-1][loop] == 0) && 1562 (new_ports[new_lanes-1][loop] == 0)) { 1563 continue; 1564 } 1565 if (old_ports[old_lanes-1][loop] == new_ports[new_lanes-1][loop] ) { 1566 /* same port was used so only speed change */ 1567 SOC_IF_ERROR_RETURN(soc_ml_port_attach( 1568 unit,block ,block_port)); 1569 } 1570 if (old_ports[old_lanes-1][loop] > new_ports[new_lanes-1][loop]) { 1571 /* This port is not applicable so remove it from pbmp list */ 1572 continue; 1573 } 1574 if (new_ports[new_lanes-1][loop] > old_ports[old_lanes-1][loop]) { 1575 /* This port is new so add it in pbmp list first */ 1576 SOC_IF_ERROR_RETURN(soc_ml_port_attach( 1577 unit,block ,block_port)); 1578 } 1579 } 1580 1581 /* Clear counters for the new ports */ 1582 SOC_PBMP_CLEAR(link_pbmp); 1583 for (loop = 0; loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1584 block_port=(*ml_block_ports[unit])[block][loop]; 1585 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), block_port)) { 1586 BCM_PBMP_PORT_ADD(link_pbmp,block_port); 1587 } 1588 } 1589 1590 COMPILER_64_ZERO(ctr_val); 1591 BCM_IF_ERROR_RETURN(soc_counter_set_by_port(unit, link_pbmp, ctr_val)); 1592 1593 /* End: Link up sequence */ 1594 1595 return BCM_E_NONE; 1596 } 1597 1598 int 1599 _bcm_ml_port_lanes_get(int unit, bcm_port_t port, int *active_lanes) 1600 { 1601 uint8 loop=0, block=0; 1602 int lanes = 0; 1603 1604 SOC_IF_ERROR_RETURN(soc_metrolite_get_port_block(unit, 1605 port, &block)); 1606 1607 for (loop = 0;loop < ML_MAX_PORTS_PER_BLOCK; loop++) { 1608 if (SOC_PBMP_MEMBER((PBMP_ALL(unit)), 1609 (*ml_block_ports[unit])[block][loop])) { 1610 lanes++; 1611 } 1612 } 1613 1614 /* active_lanes refer to the number of active lanes per port. */ 1615 /* lanes refer to number of valid lanes in the port block. */ 1616 switch (lanes) { 1617 case 1 : *active_lanes = 4; 1618 break; 1619 case 2 : *active_lanes = 2; 1620 break; 1621 case 4 : *active_lanes = 1; 1622 break; 1623 default : return BCM_E_INTERNAL; 1624 } 1625 1626 return BCM_E_NONE; 1627 }