port.c (41647B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: port.c 8 * Purpose: Port driver. 9 */ 10 11 #include <soc/defs.h> 12 13 #if defined(BCM_TOMAHAWK3_SUPPORT) 14 #include <soc/tomahawk.h> 15 #include <soc/tomahawk3.h> 16 #include <bcm_int/esw/xgs5.h> 17 #include <bcm_int/esw/portctrl.h> 18 #include <bcm_int/esw/tomahawk.h> 19 #include <bcm_int/esw/trident.h> 20 #include <bcm_int/esw/tomahawk3.h> 21 #include <soc/flexport/tomahawk3_flexport.h> 22 23 /* 24 * Function Vector 25 */ 26 static bcm_esw_port_drv_t bcm_th3_port_drv = { 27 /* fn_drv_init */ bcmi_th3_port_fn_drv_init, 28 /* resource_set */ bcmi_xgs5_port_resource_set, 29 /* resource_get */ bcmi_xgs5_port_resource_get, 30 /* resource_multi_set */ bcmi_xgs5_port_resource_multi_set, 31 /* resource_speed_set */ bcmi_xgs5_port_speed_set, 32 /* resource_traverse */ bcmi_xgs5_port_resource_traverse, 33 /* port_redirect_set */ NULL, 34 /* port_redirect_get */ NULL, 35 /* port_enable_set */ bcmi_xgs5_port_enable_set, 36 /* encap_speed_check */ bcmi_xgs5_port_encap_speed_check, 37 /* force_lb_set */ NULL, 38 /* force_lb_check */ NULL, 39 /* resource_status_update */ bcmi_xgs5_port_resource_status_update, 40 /* port_resource_speed_multi_set */ bcmi_xgs5_port_resource_speed_multi_set, 41 /* device_speed_check */ bcmi_th3_device_speed_check, 42 }; 43 44 /* Device programming routines */ 45 static bcmi_xgs5_port_func_t bcmi_th3_port_calls = { 46 /* reconfigure_ports */ bcmi_tomahawk3_reconfigure_ports, 47 /* soc_resource_init */ bcmi_th3_port_soc_resource_init, 48 /* port_resource_validate */ bcmi_th3_port_resource_validate, 49 /* pre_flexport_tdm */ bcmi_th3_pre_flexport_tdm, 50 /* post_flexport_tdm */ NULL, 51 /* port_macro_update */ bcmi_th3_cdport_update, 52 /* port_enable */ bcmi_th3_port_enable, 53 /* port_disable */ bcmi_th3_port_disable, 54 /* no_tdm_speed_update */ bcmi_th3_port_speed_1g_update, 55 /* speed_ability_get */ bcmi_th3_speed_ability_get, 56 }; 57 58 static bcmi_xgs5_dev_info_t *bcmi_th3_dev_info[SOC_MAX_NUM_DEVICES]; 59 60 /* HW Definitions */ 61 static bcmi_xgs5_port_drv_t bcmi_th3_port_drv; 62 63 static 64 int (*th3_port_attach_exec[PORT_ATTACH_EXEC__MAX])(int unit, bcm_port_t port) = { 65 /* MMU config init */ 66 &bcmi_th3_port_attach_mmu, 67 68 /* PORT module (bcm_esw_port_init) */ 69 &bcmi_xgs5_port_attach_dscp, 70 &bcmi_xgs5_port_attach_software, 71 &bcmi_xgs5_port_attach_egr_vlan_action, 72 &bcmi_xgs5_port_cfg_init, 73 &bcmi_xgs5_port_attach_port_probe, 74 &bcmi_xgs5_port_attach_frame_length_check, 75 &bcmi_xgs5_port_attach_rcpu_mtu, 76 &bcmi_xgs5_port_attach_outer_tpid, 77 &bcmi_xgs5_port_egr_block_profile_init, 78 &bcmi_xgs5_port_attach_vlan_protocol, 79 &bcmi_xgs5_port_attach_eee, 80 &bcmi_xgs5_port_attach_higig, 81 &bcmi_xgs5_port_attach_port_info_cfg, 82 &bcmi_xgs5_port_attach_egr_link_delay, 83 84 /* Other modules related to port */ 85 &bcmi_xgs5_port_attach_stg, 86 &bcmi_xgs5_port_attach_vlan, 87 &bcmi_xgs5_port_attach_trunk, 88 &bcm_th3_cosq_port_attach, 89 &bcmi_xgs5_port_attach_linkscan, 90 &bcmi_xgs5_port_attach_stat, 91 &bcmi_xgs5_port_attach_stack, 92 &bcmi_xgs5_port_attach_rate, 93 &bcmi_xgs5_port_attach_field, 94 &bcmi_xgs5_port_attach_mirror, 95 &bcmi_xgs5_port_attach_l3, 96 &bcmi_xgs5_port_attach_ipmc, 97 #if defined(INCLUDE_L3) 98 &bcm_th3_ipmc_repl_port_attach, 99 #else 100 NULL, 101 #endif 102 &bcmi_xgs5_port_attach_mpls, 103 &bcmi_xgs5_port_attach_mim, 104 }; 105 106 static 107 int (*th3_port_detach_exec[PORT_DETACH_EXEC__MAX])(int unit, bcm_port_t port) = { 108 /* Other modules related to port */ 109 #if defined(INCLUDE_L3) 110 &bcm_th3_ipmc_repl_port_detach, 111 #else 112 NULL, 113 #endif 114 &bcmi_xgs5_port_detach_ipmc, 115 &bcmi_xgs5_port_detach_mpls, 116 &bcmi_xgs5_port_detach_mim, 117 &bcmi_xgs5_port_detach_l3, 118 &bcmi_xgs5_port_detach_mirror, 119 &bcmi_xgs5_port_detach_field, 120 &bcmi_xgs5_port_detach_rate, 121 &bcmi_xgs5_port_detach_stack, 122 &bcm_th3_cosq_port_detach, 123 &bcmi_xgs5_port_detach_trunk, 124 &bcmi_xgs5_port_detach_vlan, 125 &bcmi_xgs5_port_detach_stg, 126 127 /* PORT module (_bcm_esw_port_deinit) */ 128 &bcmi_th3_port_detach_asf, 129 &bcmi_xgs5_port_detach_egr_link_delay, 130 &bcmi_xgs5_port_detach_higig, 131 &bcmi_xgs5_port_detach_eee, 132 &bcmi_xgs5_port_detach_vlan_protocol, 133 &bcmi_xgs5_port_egr_block_profile_init, 134 &bcmi_xgs5_port_detach_phy, 135 &bcmi_xgs5_port_detach_dscp, 136 &bcmi_xgs5_port_cfg_init, 137 &bcmi_xgs5_port_detach_egr_vlan_action, 138 &bcmi_xgs5_port_detach_software, 139 }; 140 141 /* 142 * Function: 143 * bcmi_th3_init_condition_set 144 * Purpose: 145 * Set the info of initialized modules in dev_info. 146 * Parameters: 147 * unit - (IN) Unit number. 148 * dev_info - (OUT) Device info used during flexport 149 * Returns: 150 * None 151 * Notes: 152 * Must follow the _bcm_modules_init() 153 */ 154 STATIC void 155 _bcmi_th3_init_condition_set(int unit, bcmi_xgs5_dev_info_t *dev_info) 156 { 157 int init_all; 158 159 init_all = soc_property_get(unit, "init_all_modules", 160 (SAL_BOOT_BCMSIM) || (!SAL_BOOT_SIMULATION)); 161 162 if (soc_feature(unit, soc_feature_virtual_switching) || 163 soc_feature(unit, soc_feature_gport_service_counters) || 164 soc_feature(unit, soc_feature_fast_init) || 165 soc_feature(unit, soc_feature_int_common_init)){ 166 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_COMMON); 167 } 168 169 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_PORT); 170 171 if (!(SAL_BOOT_SIMULATION && 172 soc_property_get(unit, spn_SKIP_L2_VLAN_INIT, 0))) { 173 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_L2); 174 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_VLAN); 175 } 176 177 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_STG); 178 179 if (init_all || 180 (soc_property_get(unit, "skip_cosq_init", 0) ? FALSE : TRUE)) { 181 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_COSQ); 182 } 183 if (init_all || 184 (soc_property_get(unit, "skip_mirror_init", 0) ? FALSE : TRUE)) { 185 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MIRROR); 186 } 187 if (init_all || 188 (soc_property_get(unit, "skip_ipmc_init", 0) ? FALSE : TRUE)) { 189 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_IPMC); 190 } 191 if (init_all) { 192 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_TRUNK); 193 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MCAST); 194 195 if (SOC_MEM_IS_VALID(unit, FP_UDF_TCAMm)) { 196 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_UDF); 197 } 198 199 #ifdef BCM_FIELD_SUPPORT 200 if (SOC_MEM_IS_VALID(unit, IFP_RANGE_CHECKm)) { 201 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_RANGE); 202 } 203 if (soc_feature(unit, soc_feature_field)) { 204 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_FIELD); 205 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_AUTH); 206 } 207 #endif 208 209 #ifdef INCLUDE_L3 210 if (soc_feature(unit, soc_feature_failover)) { 211 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_FAILOVER); 212 } 213 214 if (soc_feature(unit, soc_feature_l3) && 215 soc_property_get(unit, spn_L3_ENABLE, 1)) { 216 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_L3); 217 } 218 if (soc_feature(unit, soc_feature_ip_mcast)) { 219 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_IPMC); 220 } 221 222 #ifdef BCM_MPLS_SUPPORT 223 if (soc_feature(unit, soc_feature_mpls)) { 224 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MPLS); 225 } 226 #endif 227 if (soc_feature(unit, soc_feature_mim)) { 228 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MIM); 229 } 230 if (soc_feature(unit, soc_feature_wlan)) { 231 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_WLAN); 232 } 233 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_PROXY); 234 235 if (soc_feature(unit, soc_feature_subport) || 236 soc_feature(unit, soc_feature_linkphy_coe) || 237 soc_feature(unit, soc_feature_subtag_coe) || 238 soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 239 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_SUBPORT); 240 } 241 if (soc_feature(unit, soc_feature_trill)) { 242 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_TRILL); 243 } 244 if (soc_feature(unit, soc_feature_niv)) { 245 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_NIV); 246 } 247 if (soc_feature(unit, soc_feature_l2gre)) { 248 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_L2GRE); 249 } 250 if (soc_feature(unit, soc_feature_vxlan)) { 251 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_VXLAN); 252 } 253 if (soc_feature(unit, soc_feature_port_extension)) { 254 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_EXTENDER); 255 } 256 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MULTICAST); 257 #endif 258 if (soc_feature(unit, soc_feature_qos_profile)) { 259 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_QOS); 260 } 261 if (soc_feature(unit, soc_feature_oam) || 262 soc_feature(unit, soc_feature_fp_based_oam)) { 263 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_OAM); 264 } 265 #ifdef INCLUDE_PTP 266 if (soc_feature(unit, soc_feature_ptp)) { 267 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_PTP); 268 } 269 #endif 270 #ifdef INCLUDE_BFD 271 if (soc_feature(unit, soc_feature_bfd)) { 272 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_BFD); 273 } 274 #endif 275 if (soc_feature(unit, soc_feature_fcoe)) { 276 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_FCOE); 277 } 278 } 279 280 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_LINKSCAN); 281 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_STAT); 282 #ifdef INCLUDE_KNET 283 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_KNET); 284 #endif 285 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_TX); 286 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_RX); 287 #ifdef INCLUDE_REGEX 288 if (soc_feature(unit, soc_feature_regex)) { 289 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_REGEX); 290 } 291 #endif 292 if (soc_feature(unit, soc_feature_time_support)) { 293 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_TIME); 294 } 295 /* Service meter */ 296 if (soc_feature(unit, soc_feature_global_meter)) { 297 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_GLB_METER); 298 } 299 300 return; 301 } 302 #if 1 303 /* 304 * Function: 305 * bcmi_th3_port_dev_info_init 306 * Purpose: 307 * Initialize the device info. 308 * Parameters: 309 * unit - (IN) Unit number. 310 * Returns: 311 * BCM_E_xxx 312 * Notes: 313 */ 314 int 315 bcmi_th3_port_dev_info_init(int unit) 316 { 317 bcmi_xgs5_dev_info_t *dev_info; 318 soc_info_t *si = &SOC_INFO(unit); 319 int alloc_size; 320 int pipe, phy_port, blk, bindex, rsv_port; 321 int i, cntmaxsize; 322 323 /* Free bcmi_th3_dev_info[unit] if already allocated */ 324 if (bcmi_th3_dev_info[unit]) { 325 sal_free(bcmi_th3_dev_info[unit]); 326 bcmi_th3_dev_info[unit] = NULL; 327 } 328 329 /* Allocate memory for main SW data structure */ 330 alloc_size = sizeof(bcmi_xgs5_dev_info_t) + 331 (sizeof(bcmi_xgs5_phy_port_t) * _TH3_PHY_PORTS_PER_DEV); 332 dev_info = sal_alloc(alloc_size, "bcmi_th3_dev_info"); 333 if (dev_info == NULL) { 334 return BCM_E_MEMORY; 335 } 336 sal_memset(dev_info, 0, alloc_size); 337 dev_info->phy_port_info = (bcmi_xgs5_phy_port_t *)&dev_info[1]; 338 bcmi_th3_dev_info[unit] = dev_info; 339 340 /* Clear data structure */ 341 342 /* Device information init */ 343 dev_info = bcmi_th3_dev_info[unit]; 344 dev_info->phy_ports_max = _TH3_PHY_PORTS_PER_DEV; 345 dev_info->mmu_lossless = si->mmu_lossless; 346 dev_info->asf_prof_default = _SOC_ASF_MEM_PROFILE_SIMILAR; 347 dev_info->pipe_bound = 1; 348 for (pipe = 0; pipe < _TH3_PIPES_PER_DEV; pipe++) { 349 /* First logical port in pipe */ 350 dev_info->pipe_log_port_base[pipe] = _TH3_DEV_PORTS_PER_PIPE * pipe; 351 352 /* First physical port in pipe */ 353 dev_info->pipe_phy_port_base[pipe] = _TH3_GPHY_PORTS_PER_PIPE * pipe + 354 (pipe ? 1 : 0); 355 /* TH3 has no rserved ports*/ 356 rsv_port = 0; 357 dev_info->ports_pipe_max[pipe] = _TH3_DEV_PORTS_PER_PIPE - rsv_port; 358 } 359 /* 50G is the min speed in TDM calendar program. However, Tomahawk 3 360 * allows speeds 10G and 25G 361 */ 362 dev_info->tdm_speed_min = SPEED_10G; 363 364 /* 10G is the min speed in TDM calculations */ 365 dev_info->tdm_pipe_lr_bw_limit_checker_speed_min = SPEED_10G; 366 367 /* There is no CDPORT_CNTMAXSIZE, but maintain code consistency for these 368 * fields*/ 369 cntmaxsize = soc_property_get(unit, spn_BCM_STAT_JUMBO, 1518); 370 if (cntmaxsize > si->max_mtu) { 371 cntmaxsize = si->max_mtu; 372 } 373 dev_info->cntmaxsize_xl = cntmaxsize; 374 dev_info->cntmaxsize_cl = cntmaxsize; 375 376 dev_info->restriction_mask = /*BCMI_XGS5_FLEXPORT_RESTRICTION_PIPE_BANDWIDTH | 377 BCMI_XGS5_FLEXPORT_RESTRICTION_MIX_LR_OVS_DEV | */ 378 BCMI_XGS5_FLEXPORT_RESTRICTION_SPEED_CLASS | 379 BCMI_XGS5_FLEXPORT_RESTRICTION_PM_DOUBLE_PLL; 380 /*BCMI_XGS5_FLEXPORT_RESTRICTION_PM_MIX_ETH_HIGIG;*/ 381 382 dev_info->encap_mask = BCM_PA_ENCAP_IEEE; 383 384 /* 385 * Restriction 13:No port configurations with more than 4 port speed 386 * classes are supported. 387 * 388 * Restriction 15:All port configurations with 1-3 port speed classes are 389 * supported, except configurations that contain both 20G 390 * and 25G port speeds. 391 */ 392 dev_info->speed_class.speed_class_num = _TH3_TDM_SPEED_CLASS_MAX; 393 394 dev_info->port_ratio_mask = BCMI_XGS5_PORT_RATIO_SINGLE | 395 BCMI_XGS5_PORT_RATIO_DUAL_1_1 | 396 BCMI_XGS5_PORT_RATIO_DUAL_2_1 | 397 BCMI_XGS5_PORT_RATIO_DUAL_1_2 | 398 BCMI_XGS5_PORT_RATIO_TRI_023_2_1_1 | 399 BCMI_XGS5_PORT_RATIO_TRI_023_4_1_1 | 400 BCMI_XGS5_PORT_RATIO_TRI_012_1_1_2 | 401 BCMI_XGS5_PORT_RATIO_TRI_012_1_1_4 | 402 BCMI_XGS5_PORT_RATIO_QUAD; 403 404 /* 405 * Set physical port info: 406 * - Port lane capability 407 * - Port is enabled for flexport 408 * - pipe 409 */ 410 for (phy_port = 0; phy_port < _TH3_PHY_PORTS_PER_DEV; phy_port++) { 411 /* Set information to invalid */ 412 dev_info->phy_port_info[phy_port].pipe = -1; 413 } 414 415 /* Flexport is not supported for CPU/LB/MNG ports, so skip CPU/LB/MNG */ 416 for (phy_port = 1; phy_port <= _TH3_GPHY_PORTS_PER_DEV; phy_port++) { 417 /* Check for end of port list */ 418 if (SOC_PORT_BLOCK(unit, phy_port) < 0 && 419 SOC_PORT_BINDEX(unit, phy_port) < 0) { 420 break; 421 } 422 /* Set pipe information */ 423 dev_info->phy_port_info[phy_port].pipe = 424 (phy_port - 1) / _TH3_GPHY_PORTS_PER_PIPE; 425 426 427 /* Set TSC info */ 428 dev_info->phy_port_info[phy_port].force_lb = 0; 429 dev_info->phy_port_info[phy_port].max_lane_speed = 53000; 430 431 for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) { 432 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i); 433 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i); 434 435 if ((blk < 0) || (bindex < 0)) { 436 continue; 437 } 438 439 if (SOC_BLOCK_TYPE(unit, blk) == SOC_BLK_CDPORT) { 440 /* Set port lane capabilites */ 441 dev_info->phy_port_info[phy_port].lanes_valid = 442 BCMI_XGS5_PORT_LANES_1; 443 if (bindex == 0) { 444 dev_info->phy_port_info[phy_port].lanes_valid |= 445 BCMI_XGS5_PORT_LANES_2 | BCMI_XGS5_PORT_LANES_4 | 446 BCMI_XGS5_PORT_LANES_8; 447 } else if (bindex == 2 || bindex == 6) { 448 dev_info->phy_port_info[phy_port].lanes_valid |= 449 BCMI_XGS5_PORT_LANES_2; 450 } else if (bindex == 4) { 451 dev_info->phy_port_info[phy_port].lanes_valid |= 452 BCMI_XGS5_PORT_LANES_2 | BCMI_XGS5_PORT_LANES_4; 453 } 454 455 if (SHR_BITGET(si->flexible_pm_bitmap,blk)) { 456 dev_info->phy_port_info[phy_port].flex = 1; 457 } 458 } 459 } /* for port_num_blktype */ 460 } 461 462 /* Init condition */ 463 _bcmi_th3_init_condition_set(unit, dev_info); 464 465 return BCM_E_NONE; 466 } 467 #endif 468 /* 469 * Function: 470 * bcmi_td2p_port_fn_drv_init 471 * Purpose: 472 * Initialize the Port function driver. 473 * Parameters: 474 * unit - (IN) Unit number. 475 * Returns: 476 * BCM_E_xxx 477 * Notes: 478 */ 479 int 480 bcmi_th3_port_fn_drv_init(int unit) 481 { 482 int phase_pos, present; 483 484 BCM_IF_ERROR_RETURN 485 (bcmi_th3_port_dev_info_init(unit)); 486 487 /* BCMI Driver init */ 488 sal_memset(&bcmi_th3_port_drv, 0, sizeof(bcmi_th3_port_drv)); 489 bcmi_th3_port_drv.port_calls = &bcmi_th3_port_calls; 490 bcmi_th3_port_drv.dev_info[unit] = bcmi_th3_dev_info[unit]; 491 492 493 sal_memcpy(bcmi_th3_port_drv.port_calls->port_attach_exec, 494 th3_port_attach_exec, 495 sizeof(bcmi_th3_port_drv.port_calls->port_attach_exec)); 496 497 sal_memcpy(bcmi_th3_port_drv.port_calls->port_detach_exec, 498 th3_port_detach_exec, 499 sizeof(bcmi_th3_port_drv.port_calls->port_detach_exec)); 500 501 /* Initialize Common XGS5 Port module */ 502 BCM_IF_ERROR_RETURN 503 (bcmi_xgs5_port_fn_drv_init(unit, 504 &bcm_th3_port_drv, 505 &bcmi_th3_port_drv, 506 NULL)); 507 508 BCM_IF_ERROR_RETURN(soc_check_flex_phase(unit, th3_flexport_phases, 509 soc_tomahawk3_flex_top_port_down, 510 &present)); 511 /* Detach port enable/disable in DV Flexport */ 512 if (present) { 513 BCM_IF_ERROR_RETURN 514 (soc_detach_flex_phase(unit, th3_flexport_phases, 515 soc_tomahawk3_flex_top_port_down, 516 &phase_pos)); 517 } 518 BCM_IF_ERROR_RETURN(soc_check_flex_phase(unit, th3_flexport_phases, 519 soc_tomahawk3_flex_top_port_up, 520 &present)); 521 if (present) { 522 BCM_IF_ERROR_RETURN 523 (soc_detach_flex_phase(unit, th3_flexport_phases, 524 soc_tomahawk3_flex_top_port_up, 525 &phase_pos)); 526 } 527 528 return BCM_E_NONE; 529 } 530 /* 531 * Function: 532 * bcmi_th3_port_soc_resource_init 533 * Purpose: 534 * Initialize SOC Port Structure. 535 * This includes: 536 * Copy Port information from BCM port resource array. 537 * Set correct pipe, MMU port, IDB port for new logical port. 538 * Parameters: 539 * unit - (IN) Unit number. 540 * nport - (IN) Number of elements in array resource. 541 * resource - (IN) BCM Port resource configuration array. 542 * soc_resource - (OUT) SOC Port resource array. 543 * Returns: 544 * BCM_E_xxx 545 * Notes: 546 */ 547 int 548 bcmi_th3_port_soc_resource_init(int unit, int nport, 549 bcm_port_resource_t *resource, 550 soc_port_resource_t *soc_resource) 551 { 552 int i; 553 int logic_port, idb_port, mmu_port, pipe; 554 555 /* 556 * SOC Port Structure initialization 557 */ 558 559 /* Clear data structure */ 560 sal_memset(soc_resource, 0, sizeof(soc_port_resource_t) * nport); 561 562 /* Copy initial information */ 563 for (i = 0; i < nport; i++) { 564 logic_port = resource[i].port; 565 #if 0 566 567 if (logic_port == _TH3_DEV_RSV_PORT) { 568 return BCM_E_PORT; 569 } 570 #endif 571 pipe = logic_port/_TH3_DEV_PORTS_PER_PIPE; 572 idb_port = (logic_port % _TH3_DEV_PORTS_PER_PIPE) - (pipe == 0 ? 1 : 0); 573 mmu_port = pipe * _TH3_MMU_PORTS_OFFSET_PER_PIPE + idb_port; 574 575 soc_resource[i].flags = resource[i].flags; 576 soc_resource[i].logical_port = logic_port; 577 soc_resource[i].physical_port = resource[i].physical_port; 578 soc_resource[i].speed = resource[i].speed < SPEED_10G ? 579 SPEED_10G : resource[i].speed; 580 soc_resource[i].num_lanes = resource[i].lanes; 581 soc_resource[i].encap = resource[i].encap; 582 soc_resource[i].pipe = pipe; 583 soc_resource[i].idb_port = idb_port; 584 soc_resource[i].mmu_port = mmu_port; 585 /* TH3 does NOT support port configuration with a mix of line-rate ports 586 * and oversubscribed ports; all ports are oversub */ 587 soc_resource[i].oversub = 1; 588 589 /* New Speed Config parameters required for FlexPort */ 590 soc_resource[i].fec_type = resource[i].fec_type; 591 soc_resource[i].phy_lane_config = resource[i].phy_lane_config; 592 soc_resource[i].link_training = resource[i].link_training; 593 } 594 595 return BCM_E_NONE; 596 } 597 598 /* 599 * Function: 600 * bcmi_th3_port_resource_validate 601 * Purpose: 602 * Validate that the given FlexPort operations is valid. 603 * Parameters: 604 * unit - (IN) Unit number. 605 * port_schedule_state - (OUT) Port resource state. 606 * Returns: 607 * BCM_E_xxx 608 * Notes: 609 */ 610 int 611 bcmi_th3_port_resource_validate(int unit, 612 soc_port_schedule_state_t *port_schedule_state) 613 { 614 return BCM_E_NONE; 615 } 616 617 /* 618 * Function: 619 * bcmi_th3_pre_flexport_tdm 620 * Purpose: 621 * Pass TDM information pre FlexPort to DV FlexPort API 622 * Parameters: 623 * unit - (IN) Unit number. 624 * port_schedule_state - (OUT) Port resource state. 625 * Returns: 626 * BCM_E_xxx 627 * Notes: 628 */ 629 int 630 bcmi_th3_pre_flexport_tdm(int unit, 631 soc_port_schedule_state_t *port_schedule_state) 632 { 633 port_schedule_state->is_flexport = 1; 634 635 636 637 return BCM_E_NONE; 638 } 639 640 /* 641 * Function: 642 * bcmi_th3_post_flexport_tdm 643 * Purpose: 644 * Update TDM information in SOC with post FlexPort TDM state return from 645 * DV FlexPort API. 646 * Parameters: 647 * unit - (IN) Unit number. 648 * port_schedule_state - (IN) Port resource state. 649 * Returns: 650 * BCM_E_xxx 651 * Notes: 652 */ 653 int 654 bcmi_th3_post_flexport_tdm(int unit, 655 soc_port_schedule_state_t *port_schedule_state) 656 { 657 658 659 return BCM_E_NONE; 660 } 661 662 /* 663 * Function: 664 * bcmi_th3_cdport_update 665 * Purpose: 666 * Update CDPORT. 667 * Parameters: 668 * unit - (IN) Unit number. 669 * port_schedule_state - (IN) Port resource state. 670 * Returns: 671 * BCM_E_xxx 672 * Notes: 673 */ 674 int 675 bcmi_th3_cdport_update(int unit, 676 soc_port_schedule_state_t *port_schedule_state) 677 { 678 /* This function is intended to update port_mode in CDPORT_MODE_REG. 679 * On TH3, Portmod(PM8x50) will take care of port_mode update. 680 * So we just return E_NONE in this function. 681 */ 682 return BCM_E_NONE; 683 } 684 685 int 686 bcmi_th3_port_attach_mmu(int unit, int port) 687 { 688 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || 689 IS_MANAGEMENT_PORT(unit, port)) { 690 return BCM_E_PARAM; 691 } 692 # if 0 693 694 /* Assign the base queues and number of queues for the specified port. */ 695 BCM_IF_ERROR_RETURN 696 (soc_tomahawk3_num_cosq_init_port(unit, port)); 697 698 /* Reconfigure THDI, THDO settings */ 699 BCM_IF_ERROR_RETURN 700 (soc_th3_mmu_config_init_port(unit, port)); 701 #endif 702 return BCM_E_NONE; 703 } 704 705 /* 706 * Function: 707 * bcmi_th3_port_detach_asf 708 * Purpose: 709 * Update ASF when port deleted during Flexport operations. 710 * Parameters: 711 * unit - (IN) Unit number. 712 * port - (IN) Logical port number. 713 * Returns: 714 * BCM_E_xxx 715 * Notes: 716 */ 717 int 718 bcmi_th3_port_detach_asf(int unit, bcm_port_t port) 719 { 720 721 if (soc_feature(unit, soc_feature_asf_multimode)) { 722 BCM_IF_ERROR_RETURN 723 (soc_th3_port_asf_detach(unit, port)); 724 } 725 726 return BCM_E_NONE; 727 } 728 729 /* 730 * Function: 731 * bcmi_th3_port_enable 732 * Purpose: 733 * Enable port. 734 * Parameters: 735 * unit - (IN) Unit number. 736 * port_schedule_state - (IN) Port resource state. 737 * Returns: 738 * BCM_E_xxx 739 * Notes: 740 * This function should only be called with PORTMOD enabled 741 */ 742 int 743 bcmi_th3_port_enable(int unit, 744 soc_port_schedule_state_t *port_schedule_state) 745 { 746 int i, nport, rv = 0; 747 bcm_port_t *port; 748 749 nport = port_schedule_state->nport; 750 751 port = sal_alloc(nport * sizeof(bcm_port_t), "port array"); 752 if (port == NULL) { 753 return BCM_E_MEMORY; 754 } 755 for (i = 0; i < nport; i++) { 756 port[i] = port_schedule_state->resource[i].logical_port; 757 } 758 759 if (BCM_SUCCESS(rv)) { 760 rv = soc_tomahawk3_ep_port_up(unit, port_schedule_state); 761 } 762 763 if (!SAL_BOOT_BCMSIM) { 764 if (BCM_SUCCESS(rv)) { 765 rv = soc_tomahawk3_mmu_port_up(unit, port_schedule_state); 766 } 767 } 768 769 if (!SAL_BOOT_BCMSIM) { 770 if (BCM_SUCCESS(rv)) { 771 rv = soc_tomahawk3_idb_port_up(unit, port_schedule_state); 772 } 773 } 774 775 if (BCM_SUCCESS(rv)) 776 { 777 rv = bcmi_esw_portctrl_mac_up(unit, nport, port); 778 } 779 sal_free(port); 780 781 return rv; 782 } 783 784 /* 785 * Function: 786 * bcmi_th3_port_disable 787 * Purpose: 788 * Disable port. 789 * Parameters: 790 * unit - (IN) Unit number. 791 * port_schedule_state - (IN) Port resource state. 792 * Returns: 793 * BCM_E_xxx 794 * Notes: 795 * This function should only be called with PORTMOD enabled 796 */ 797 int 798 bcmi_th3_port_disable(int unit, 799 soc_port_schedule_state_t *port_schedule_state) 800 { 801 int i, nport, rv; 802 bcm_port_t *port; 803 804 nport = port_schedule_state->nport; 805 806 port = sal_alloc(nport * sizeof(bcm_port_t), "port array"); 807 if (port == NULL) { 808 return BCM_E_MEMORY; 809 } 810 for (i = 0; i < nport; i++) { 811 port[i] = port_schedule_state->resource[i].logical_port; 812 } 813 814 rv = bcmi_esw_portctrl_mac_rx_down(unit, nport, port); 815 816 if (!SAL_BOOT_BCMSIM) { 817 if (BCM_SUCCESS(rv)) { 818 rv = soc_tomahawk3_idb_port_down(unit, port_schedule_state); 819 } 820 } 821 822 if (!SAL_BOOT_BCMSIM) { 823 if (BCM_SUCCESS(rv)) { 824 rv = soc_tomahawk3_mmu_port_down(unit, port_schedule_state); 825 } 826 } 827 828 if (BCM_SUCCESS(rv)) { 829 rv = soc_tomahawk3_ep_port_down(unit, port_schedule_state); 830 } 831 /* Clear EDB_CREDIT_COUNTER */ 832 if (BCM_SUCCESS(rv)) { 833 rv = soc_tomahawk3_tdm_clear_edb_credit_counter(unit, 834 port_schedule_state); 835 } 836 if (BCM_SUCCESS(rv)) 837 { 838 rv = bcmi_esw_portctrl_mac_tx_down(unit, nport, port); 839 } 840 841 sal_free(port); 842 843 return rv; 844 } 845 846 /* 847 * Function: 848 * bcmi_th3_port_speed_1g_update 849 * Purpose: 850 * Special operations for 1G speed. 851 * Parameters: 852 * unit - (IN) Unit number. 853 * port - (IN) Logical port number. 854 * speed - (IN) port speed (Mbps). 855 * Returns: 856 * BCM_E_xxx 857 * Notes: 858 * In the PRD, nothing below 10G is officially supported. 859 * We enable customers with limited 1G support in Tomahawk3. 860 * 1G is not a support speed class in TDM calculation, thus treated same as 861 * 10G in TDM calculation. 1G port does NOT support cut through, flow 862 * control. 863 */ 864 int 865 bcmi_th3_port_speed_1g_update(int unit, bcm_port_t port, int speed) 866 { 867 if (speed != SPEED_1G) { 868 return BCM_E_NONE; 869 } 870 871 /* Update port speed info in soc_info */ 872 SOC_INFO(unit).port_init_speed[port] = speed; 873 874 /* Set asf mode to SAF */ 875 if (soc_feature(unit, soc_feature_asf_multimode)) { 876 BCM_IF_ERROR_RETURN 877 (soc_th_port_asf_mode_set(unit, port, speed, 878 _SOC_TH_ASF_MODE_SAF)); 879 } 880 881 /* Disable Pause */ 882 BCM_IF_ERROR_RETURN 883 (bcm_esw_port_pause_set(unit, port, 0, 0)); 884 885 /* Disable PFC */ 886 if (soc_feature(unit, soc_feature_priority_flow_control)) { 887 BCM_IF_ERROR_RETURN 888 (bcm_esw_port_control_set(unit, port, 889 bcmPortControlPFCReceive, 0)); 890 BCM_IF_ERROR_RETURN 891 (bcm_esw_port_control_set(unit, port, 892 bcmPortControlPFCTransmit, 0)); 893 } 894 895 return BCM_E_NONE; 896 } 897 898 /* 899 * Function: 900 * bcmi_th3_speed_ability_get 901 * Purpose: 902 * Retrieve the local port abilities. 903 * Parameters: 904 * unit - Unit. 905 * port - Logical port num. 906 * mask - (OUT) Mask of BCM_PORT_ABILITY_ values indicating the 907 * supported speeds of the port. 908 * Returns: 909 * BCM_E_NONE 910 * BCM_E_XXX 911 */ 912 int 913 bcmi_th3_speed_ability_get(int unit, bcm_port_t port, bcm_port_abil_t *mask) 914 { 915 if (IS_MANAGEMENT_PORT(unit, port)) { 916 /* TH3 Port Rates for Management ports: 917 * 100M, 1G, 2.5G, 10G, HG[11G] */ 918 *mask = BCM_PORT_ABILITY_10MB | BCM_PORT_ABILITY_100MB | 919 BCM_PORT_ABILITY_1000MB | BCM_PORT_ABILITY_2500MB | 920 BCM_PORT_ABILITY_10GB | BCM_PORT_ABILITY_11GB; 921 } else { 922 /* Not supported for PM8x50. */ 923 *mask = 0; 924 return BCM_E_UNAVAIL; 925 #if 0 926 BCM_IF_ERROR_RETURN 927 (soc_th3_support_speeds(unit, 928 SOC_INFO(unit).port_num_lanes[port], 929 mask)); 930 #endif 931 } 932 933 return BCM_E_NONE; 934 } 935 936 /* 937 * Function: 938 * bcmi_th3_tsc_xgxs_reset 939 * Purpose: 940 * Reset TSC. 941 * Parameters: 942 * unit - Unit. 943 * pbmp - Bitmap of ports to reset. 944 * Returns: 945 * BCM_E_NONE 946 * BCM_E_XXX 947 */ 948 int 949 bcmi_th3_tsc_xgxs_reset(int unit, pbmp_t pbmp) 950 { 951 int rv = BCM_E_NONE; 952 soc_info_t *si; 953 uint64 tsc_map, reset_tsc_map; 954 int tsc, ports[_TH3_PBLKS_PER_DEV]; 955 bcm_port_t port; 956 _bcm_port_info_t *port_info = NULL; 957 958 si = &SOC_INFO(unit); 959 960 /* Construct tsc_map covered by the specified pbmp */ 961 COMPILER_64_ZERO(tsc_map); 962 PBMP_ITER(pbmp, port) { 963 tsc = si->port_serdes[port]; 964 if (tsc != -1) { 965 COMPILER_64_BITSET(tsc_map, tsc); 966 } 967 } 968 969 COMPILER_64_ZERO(reset_tsc_map); 970 PBMP_PORT_ITER(unit, port) { 971 tsc = si->port_serdes[port]; 972 if (COMPILER_64_BITTEST(tsc_map, tsc)) { 973 _bcm_port_info_access(unit, port, &port_info); 974 if (port_info->flags & _PORT_INFO_PROBE_RESET_SERDES) { 975 port_info->flags &= ~_PORT_INFO_PROBE_RESET_SERDES; 976 COMPILER_64_BITSET(reset_tsc_map, tsc); 977 ports[tsc] = port; 978 } 979 } 980 } 981 982 for (tsc = 0; tsc < _TH3_PBLKS_PER_DEV; tsc++) { 983 if (COMPILER_64_BITTEST(reset_tsc_map, tsc)) { 984 rv = soc_tsc_xgxs_reset(unit, ports[tsc], 0); 985 } 986 } 987 988 return rv; 989 } 990 991 /* 992 * Function: 993 * bcm_th3_port_rate_egress_set 994 * Purpose: 995 * Set egress metering information 996 * Parameters: 997 * unit - (IN) Unit number 998 * port - (IN) Port number 999 * bandwidth - (IN) Kilobits per second or packets per second 1000 * zero if rate limiting is disabled 1001 * burst - (IN) Maximum burst size in kilobits or packets 1002 * mode - (IN) _BCM_PORT_RATE_BYTE_MODE or _BCM_PORT_RATE_PPS_MODE 1003 * Returns: 1004 * BCM_E_XXX 1005 */ 1006 int 1007 bcm_th3_port_rate_egress_set(int unit, bcm_port_t port, uint32 bandwidth, 1008 uint32 burst, uint32 mode) 1009 { 1010 soc_info_t *si; 1011 int index, pipe; 1012 soc_mem_t mem; 1013 uint32 rval, itu_mode_sel; 1014 mmu_mtro_egrmeteringconfig_entry_t entry; 1015 uint32 refresh_rate, bucketsize, granularity, flags; 1016 int refresh_bitsize, bucket_bitsize; 1017 1018 si = &SOC_INFO(unit); 1019 1020 sal_memset(&entry, 0, sizeof(entry)); 1021 1022 index = SOC_TH3_MMU_LOCAL_PORT(unit, port); 1023 pipe = si->port_pipe[port]; 1024 1025 mem = SOC_MEM_UNIQUE_ACC(unit, MMU_MTRO_EGRMETERINGCONFIGm)[pipe]; 1026 1027 /* If metering is disabled on this ingress port we are done. */ 1028 if (!bandwidth || !burst) { 1029 SOC_IF_ERROR_RETURN 1030 (soc_mem_write(unit, mem, MEM_BLOCK_ANY, index, &entry)); 1031 return BCM_E_NONE; 1032 } 1033 if((bandwidth < _BCM_TH3_PORT_RATE_MIN_KILOBITS || 1034 bandwidth > _BCM_TH3_PORT_RATE_MAX_KILOBITS) || 1035 (burst < _BCM_PORT_BURST_MIN_KILOBITS || 1036 burst > _BCM_PORT_BURST_MAX_KILOBITS)){ 1037 return BCM_E_PARAM; 1038 } 1039 flags = mode == _BCM_PORT_RATE_PPS_MODE ? 1040 _BCM_TD_METER_FLAG_PACKET_MODE : 0; 1041 1042 BCM_IF_ERROR_RETURN(READ_MMU_MTRO_CONFIGr(unit, &rval)); 1043 itu_mode_sel = soc_reg_field_get(unit, MMU_MTRO_CONFIGr, rval, ITU_MODE_SELf); 1044 1045 if (itu_mode_sel) { 1046 flags |= _BCM_TD_METER_FLAG_NON_LINEAR; 1047 } 1048 1049 refresh_bitsize = soc_mem_field_length(unit, mem, REFRESHf); 1050 bucket_bitsize = soc_mem_field_length(unit, mem, THD_SELf); 1051 BCM_IF_ERROR_RETURN 1052 (_bcm_th3_rate_to_bucket_encoding(unit, bandwidth, burst, flags, 1053 refresh_bitsize, bucket_bitsize, 1054 &refresh_rate, &bucketsize, 1055 &granularity)); 1056 soc_mem_field32_set(unit, mem, &entry, PACKET_SHAPINGf, 1057 mode == _BCM_PORT_RATE_PPS_MODE ? 1 : 0); 1058 1059 soc_mem_field32_set(unit, mem, &entry, METER_GRANf, granularity); 1060 soc_mem_field32_set(unit, mem, &entry, REFRESHf, refresh_rate); 1061 soc_mem_field32_set(unit, mem, &entry, THD_SELf, bucketsize); 1062 1063 SOC_IF_ERROR_RETURN 1064 (soc_mem_write(unit, mem, MEM_BLOCK_ANY, index, &entry)); 1065 1066 return BCM_E_NONE; 1067 } 1068 1069 /* 1070 * Function: 1071 * bcm_th3_port_rate_egress_get 1072 * Purpose: 1073 * Get egress metering information 1074 * Parameters: 1075 * unit - (IN) Unit number 1076 * port - (IN) Port number 1077 * bandwidth - (OUT) Kilobits per second or packets per second 1078 * zero if rate limiting is disabled 1079 * burst - (OUT) Maximum burst size in kilobits or packets 1080 * mode - (OUT) _BCM_PORT_RATE_BYTE_MODE or _BCM_PORT_RATE_PPS_MODE 1081 * Returns: 1082 * BCM_E_XXX 1083 */ 1084 int 1085 bcm_th3_port_rate_egress_get(int unit, bcm_port_t port, uint32 *bandwidth, 1086 uint32 *burst, uint32 *mode) 1087 { 1088 soc_info_t *si; 1089 int index, pipe; 1090 soc_mem_t mem; 1091 uint32 rval, itu_mode_sel; 1092 mmu_mtro_egrmeteringconfig_entry_t entry; 1093 uint32 refresh_rate, bucketsize, granularity, flags; 1094 1095 if (bandwidth == NULL || burst == NULL) { 1096 return BCM_E_PARAM; 1097 } 1098 1099 si = &SOC_INFO(unit); 1100 index = SOC_TH3_MMU_LOCAL_PORT(unit, port); 1101 pipe = si->port_pipe[port]; 1102 1103 mem = SOC_MEM_UNIQUE_ACC(unit, MMU_MTRO_EGRMETERINGCONFIGm)[pipe]; 1104 1105 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &entry)); 1106 1107 refresh_rate = soc_mem_field32_get(unit, mem, &entry, REFRESHf); 1108 bucketsize = soc_mem_field32_get(unit, mem, &entry, THD_SELf); 1109 granularity = soc_mem_field32_get(unit, mem, &entry, METER_GRANf); 1110 1111 flags = soc_mem_field32_get(unit, mem, &entry, PACKET_SHAPINGf) ? 1112 _BCM_TD_METER_FLAG_PACKET_MODE : 0; 1113 1114 BCM_IF_ERROR_RETURN(READ_MMU_MTRO_CONFIGr(unit, &rval)); 1115 itu_mode_sel = soc_reg_field_get(unit, MMU_MTRO_CONFIGr, rval, ITU_MODE_SELf); 1116 1117 if (itu_mode_sel) { 1118 flags |= _BCM_TD_METER_FLAG_NON_LINEAR; 1119 } 1120 1121 BCM_IF_ERROR_RETURN 1122 (_bcm_th3_bucket_encoding_to_rate(unit, refresh_rate, bucketsize, 1123 granularity, flags, bandwidth, 1124 burst)); 1125 *mode = flags & _BCM_TD_METER_FLAG_PACKET_MODE ? 1126 _BCM_PORT_RATE_PPS_MODE : _BCM_PORT_RATE_BYTE_MODE; 1127 1128 return BCM_E_NONE; 1129 } 1130 1131 /* 1132 * Function: 1133 * bcm_th3_device_speed_check 1134 * Purpose: 1135 * Restriction: Checks supported speeds for TH3 1136 * Parameters: 1137 * unit - (IN) Unit number 1138 * speed - (IN) speed 1139 * lanes - (IN) lanes (-1 if don't care about lanes) 1140 * Returns: 1141 * BCM_E_XXX 1142 */ 1143 int 1144 bcmi_th3_device_speed_check(int unit, int speed, int lanes) 1145 { 1146 switch(speed) { 1147 case 400000: 1148 if (SOC_INFO(unit).frequency < 1200) { 1149 break; 1150 } 1151 if (lanes > 0 && lanes != 8) { 1152 break; 1153 } 1154 return BCM_E_NONE; 1155 case 200000: 1156 if (lanes > 0 && lanes != 4) { 1157 break; 1158 } 1159 return BCM_E_NONE; 1160 case 100000: 1161 if (lanes > 0 && lanes != 4 && lanes != 2) { 1162 break; 1163 } 1164 if (SOC_INFO(unit).frequency < 600) { 1165 break; 1166 } 1167 return BCM_E_NONE; 1168 case 50000: 1169 if (lanes > 0 && lanes != 1 && lanes != 2) { 1170 break; 1171 } 1172 if (SOC_INFO(unit).frequency < 300) { 1173 break; 1174 } 1175 return BCM_E_NONE; 1176 case 40000: 1177 if (lanes > 0 && lanes != 4 && lanes != 2) { 1178 break; 1179 } 1180 return BCM_E_NONE; 1181 case 25000: 1182 if (lanes > 0 && lanes != 1) { 1183 break; 1184 } 1185 return BCM_E_NONE; 1186 case 10000: 1187 if (lanes > 0 && lanes != 1) { 1188 break; 1189 } 1190 return BCM_E_NONE; 1191 default: 1192 break; 1193 1194 } 1195 LOG_VERBOSE(BSL_LS_BCM_PORT, 1196 (BSL_META_U(unit, 1197 "Speed Unsupported " 1198 "speed=%d\n" 1199 "lanes=%d\n" 1200 "frequency=%d\n"), 1201 speed, lanes, SOC_INFO(unit).frequency)); 1202 1203 return BCM_E_PARAM; 1204 } 1205 1206 /* 1207 * Function: 1208 * bcmi_tomahawk3_reconfigure_ports 1209 * Purpose: 1210 * To bring the TSC clock for port macros being flexed up for 1211 * the flex operation, and back down if they were brought up 1212 * Parameters: 1213 * unit - (IN) Unit number 1214 * port_schedule_state - (IN) Flex info 1215 * Returns: 1216 * BCM_E_XXX 1217 */ 1218 int 1219 bcmi_tomahawk3_reconfigure_ports(int unit, 1220 soc_port_schedule_state_t *port_schedule_state) 1221 { 1222 int i; 1223 int nport; 1224 int phy_port; 1225 int pm_id; 1226 int portmod_pm_id; 1227 int is_init; 1228 int rv = BCM_E_NONE; 1229 char brought_up[SOC_TH3_PM8X50_COUNT]; 1230 soc_port_resource_t *resource; 1231 1232 resource = port_schedule_state->resource; 1233 nport = port_schedule_state->nport; 1234 1235 sal_memset(brought_up, 0, SOC_TH3_PM8X50_COUNT * sizeof(char)); 1236 1237 /* Find ports that are going to come up after flexing and enable 1238 * the TSC clock so that the DV Flexport code can access 1239 * the registers */ 1240 for (i = 0; i < nport; i++) { 1241 phy_port = resource[i].physical_port; 1242 1243 /* Skip Port deletes; we only care about ports coming up because 1244 * they'll require the port macro to be active */ 1245 if (phy_port == -1) { 1246 continue; 1247 } 1248 1249 /* Get the SDK port macro number */ 1250 pm_id = (phy_port - 1) / _TH3_PORTS_PER_PBLK; 1251 1252 /* Skip if we already brought it up */ 1253 if (brought_up[pm_id] == 1) { 1254 continue; 1255 } 1256 1257 /* Fetch the portmod pm id since indexing is different than sdk */ 1258 rv = portmod_phy_pm_id_get(unit, phy_port, 1259 &portmod_pm_id); 1260 if (BCM_FAILURE(rv)) { 1261 goto cleanup; 1262 } 1263 1264 /* Check if the core is initialized. If it's NOT initialized, 1265 * we will need to bring up the clocks so that DV Flexport code can 1266 * access registers 1267 */ 1268 rv = portmod_pm_is_initialized(unit, portmod_pm_id, &is_init); 1269 if (BCM_FAILURE(rv)) { 1270 goto cleanup; 1271 } 1272 1273 /* If the core is active, skip turning on the PM clocks; they're already on */ 1274 if (PORTMOD_CORE_INIT_FLAG_INITIALZIED_GET(is_init)) { 1275 continue; 1276 } 1277 1278 /* Enable the PM */ 1279 rv = portmod_pm_enable(unit, portmod_pm_id, 1); 1280 if (BCM_FAILURE(rv)) { 1281 goto cleanup; 1282 } 1283 1284 /* Mark that we brought up the clock on this PM so we can bring it 1285 * down after DV flexport 1286 */ 1287 brought_up[pm_id] = 1; 1288 } 1289 1290 1291 1292 /****************************** 1293 ** Perform DV Flexport Code ** 1294 */ 1295 rv = soc_tomahawk3_reconfigure_ports(unit, 1296 port_schedule_state); 1297 1298 1299 cleanup: 1300 /* Disable all of the port macros that we enabled now that DV flex 1301 * is done */ 1302 for (i = 0; i < SOC_TH3_PM8X50_COUNT; i++) { 1303 if (brought_up[i] == 1) { 1304 phy_port = (i * _TH3_PORTS_PER_PBLK) + 1; 1305 1306 /* These shouldn't return error since they passed in the above code 1307 * but catch the error anyway so it'll hopefully be easier to find 1308 * if there is a problem calling these functions */ 1309 BCM_IF_ERROR_RETURN(portmod_phy_pm_id_get(unit, phy_port, 1310 &portmod_pm_id)); 1311 /* Disable the PM */ 1312 BCM_IF_ERROR_RETURN(portmod_pm_enable(unit, portmod_pm_id, 0)); 1313 } 1314 } 1315 1316 return rv; 1317 } 1318 1319 #endif /* BCM_TOMAHAWK3_SUPPORT */