port.c (37726B)
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_TOMAHAWK2_SUPPORT) 14 #include <soc/tomahawk.h> 15 #include <soc/tomahawk2.h> 16 #include <soc/tomahawk2_tdm.h> 17 #include <bcm_int/esw/xgs5.h> 18 #include <bcm_int/esw/portctrl.h> 19 #include <bcm_int/esw/tomahawk.h> 20 #include <bcm_int/esw/tomahawk2.h> 21 #include <soc/flexport/tomahawk2_flexport.h> 22 23 /* 24 * Function Vector 25 */ 26 static bcm_esw_port_drv_t bcm_th2_port_drv = { 27 /* fn_drv_init */ bcmi_th2_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 */ bcmi_xgs5_port_force_lb_set, 38 /* force_lb_check */ bcmi_xgs5_port_force_lb_check, 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 */ NULL 42 }; 43 44 /* Device programming routines */ 45 static bcmi_xgs5_port_func_t bcmi_th2_port_calls = { 46 /* reconfigure_ports */ soc_tomahawk2_reconfigure_ports, 47 /* soc_resource_init */ bcmi_th2_port_soc_resource_init, 48 /* port_resource_validate */ bcmi_th2_port_resource_validate, 49 /* pre_flexport_tdm */ bcmi_th2_pre_flexport_tdm, 50 /* post_flexport_tdm */ bcmi_th2_post_flexport_tdm, 51 /* port_macro_update */ bcmi_th2_clport_update, 52 /* port_enable */ bcmi_th2_port_enable, 53 /* port_disable */ bcmi_th2_port_disable, 54 /* no_tdm_speed_update */ bcmi_th2_port_speed_1g_update, 55 /* speed_ability_get */ bcmi_th2_speed_ability_get, 56 /* speed_mix_validate */ bcmi_th2_speed_mix_validate, 57 }; 58 59 static int bcmi_th2_port_drv_internal_initialized = 0; 60 61 static bcmi_xgs5_dev_info_t *bcmi_th2_dev_info[SOC_MAX_NUM_DEVICES]; 62 63 /* HW Definitions */ 64 static bcmi_xgs5_port_drv_t bcmi_th2_port_drv; 65 66 static 67 int (*th2_port_attach_exec[PORT_ATTACH_EXEC__MAX])(int unit, bcm_port_t port) = { 68 /* MMU config init */ 69 &bcmi_th2_port_attach_mmu, 70 71 /* PORT module (bcm_esw_port_init) */ 72 &bcmi_xgs5_port_attach_dscp, 73 &bcmi_xgs5_port_attach_software, 74 &bcmi_xgs5_port_attach_egr_vlan_action, 75 &bcmi_xgs5_port_cfg_init, 76 &bcmi_xgs5_port_attach_port_probe, 77 &bcmi_xgs5_port_attach_frame_length_check, 78 &bcmi_xgs5_port_attach_rcpu_mtu, 79 &bcmi_xgs5_port_attach_outer_tpid, 80 &bcmi_xgs5_port_egr_block_profile_init, 81 &bcmi_xgs5_port_attach_vlan_protocol, 82 &bcmi_xgs5_port_attach_eee, 83 &bcmi_xgs5_port_attach_higig, 84 &bcmi_xgs5_port_attach_port_info_cfg, 85 &bcmi_xgs5_port_attach_egr_link_delay, 86 87 /* Other modules related to port */ 88 &bcmi_xgs5_port_attach_stg, 89 &bcmi_xgs5_port_attach_vlan, 90 &bcmi_xgs5_port_attach_trunk, 91 &bcm_th_cosq_port_attach, 92 &bcmi_xgs5_port_attach_linkscan, 93 &bcmi_xgs5_port_attach_stat, 94 &bcmi_xgs5_port_attach_stack, 95 &bcmi_xgs5_port_attach_rate, 96 &bcmi_xgs5_port_attach_field, 97 &bcmi_xgs5_port_attach_mirror, 98 &bcmi_xgs5_port_attach_l3, 99 &bcmi_xgs5_port_attach_ipmc, 100 &bcm_th2_ipmc_repl_port_attach, 101 &bcmi_xgs5_port_attach_mpls, 102 &bcmi_xgs5_port_attach_mim 103 }; 104 105 static 106 int (*th2_port_detach_exec[PORT_DETACH_EXEC__MAX])(int unit, bcm_port_t port) = { 107 /* Other modules related to port */ 108 &bcm_th2_ipmc_repl_port_detach, 109 &bcmi_xgs5_port_detach_ipmc, 110 &bcmi_xgs5_port_detach_mpls, 111 &bcmi_xgs5_port_detach_mim, 112 &bcmi_xgs5_port_detach_l3, 113 &bcmi_xgs5_port_detach_mirror, 114 &bcmi_xgs5_port_detach_field, 115 &bcmi_xgs5_port_detach_rate, 116 &bcmi_xgs5_port_detach_stack, 117 &bcm_th_cosq_port_detach, 118 &bcmi_xgs5_port_detach_trunk, 119 &bcmi_xgs5_port_detach_vlan, 120 &bcmi_xgs5_port_detach_stg, 121 122 /* PORT module (_bcm_esw_port_deinit) */ 123 &bcmi_th2_port_detach_asf, 124 &bcmi_xgs5_port_detach_egr_link_delay, 125 &bcmi_xgs5_port_detach_higig, 126 &bcmi_xgs5_port_detach_eee, 127 &bcmi_xgs5_port_detach_vlan_protocol, 128 &bcmi_xgs5_port_egr_block_profile_init, 129 &bcmi_xgs5_port_detach_phy, 130 &bcmi_xgs5_port_detach_dscp, 131 &bcmi_xgs5_port_cfg_init, 132 &bcmi_xgs5_port_detach_egr_vlan_action, 133 &bcmi_xgs5_port_detach_software, 134 }; 135 136 /* 137 * Function: 138 * bcmi_th2_init_condition_set 139 * Purpose: 140 * Set the info of initialized modules in dev_info. 141 * Parameters: 142 * unit - (IN) Unit number. 143 * dev_info - (OUT) Device info used during flexport 144 * Returns: 145 * None 146 * Notes: 147 * Must follow the _bcm_modules_init() 148 */ 149 STATIC void 150 _bcmi_th2_init_condition_set(int unit, bcmi_xgs5_dev_info_t *dev_info) 151 { 152 int init_all; 153 154 init_all = soc_property_get(unit, "init_all_modules", 155 (SAL_BOOT_BCMSIM) || (!SAL_BOOT_SIMULATION)); 156 157 if (soc_feature(unit, soc_feature_virtual_switching) || 158 soc_feature(unit, soc_feature_gport_service_counters) || 159 soc_feature(unit, soc_feature_fast_init) || 160 soc_feature(unit, soc_feature_int_common_init)){ 161 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_COMMON); 162 } 163 164 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_PORT); 165 166 if (!(SAL_BOOT_SIMULATION && 167 soc_property_get(unit, spn_SKIP_L2_VLAN_INIT, 0))) { 168 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_L2); 169 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_VLAN); 170 } 171 172 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_STG); 173 174 if (!(SAL_BOOT_SIMULATION && 175 soc_property_get(unit, "skip_trunk_init", 0))) { 176 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_TRUNK); 177 } 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_stack_init", 0) ? FALSE : TRUE)) { 185 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_STK); 186 } 187 if (init_all || 188 (soc_property_get(unit, "skip_mirror_init", 0) ? FALSE : TRUE)) { 189 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MIRROR); 190 } 191 if (init_all) { 192 if (!soc_property_get(unit, "skip_mcast_init", 0)) { 193 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MCAST); 194 } 195 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_RATE); 196 197 if (SOC_MEM_IS_VALID(unit, FP_UDF_TCAMm)) { 198 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_UDF); 199 } 200 201 #ifdef BCM_FIELD_SUPPORT 202 if (SOC_MEM_IS_VALID(unit, IFP_RANGE_CHECKm)) { 203 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_RANGE); 204 } 205 if (soc_feature(unit, soc_feature_field)) { 206 if (!soc_property_get(unit, "skip_field_init", 0)) { 207 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_FIELD); 208 } 209 if (!soc_property_get(unit, "skip_auth_init", 0)) { 210 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_AUTH); 211 } 212 } 213 #endif 214 215 #ifdef INCLUDE_L3 216 if (soc_feature(unit, soc_feature_failover)) { 217 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_FAILOVER); 218 } 219 220 if (soc_feature(unit, soc_feature_l3) && 221 soc_property_get(unit, spn_L3_ENABLE, 1) && 222 (!soc_property_get(unit, "skip_l3_init", 0))) { 223 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_L3); 224 } 225 if (soc_feature(unit, soc_feature_ip_mcast) && 226 (!soc_property_get(unit, "skip_ipmc_init", 0))) { 227 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_IPMC); 228 } 229 230 #ifdef BCM_MPLS_SUPPORT 231 if (soc_feature(unit, soc_feature_mpls) && 232 (!soc_property_get(unit, "skip_mpls_init", 0))) { 233 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MPLS); 234 } 235 #endif 236 if (soc_feature(unit, soc_feature_mim) && 237 (!soc_property_get(unit, "skip_mim_init", 0))) { 238 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MIM); 239 } 240 if (soc_feature(unit, soc_feature_wlan)) { 241 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_WLAN); 242 } 243 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_PROXY); 244 245 if (soc_feature(unit, soc_feature_subport) || 246 soc_feature(unit, soc_feature_linkphy_coe) || 247 soc_feature(unit, soc_feature_subtag_coe) || 248 soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 249 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_SUBPORT); 250 } 251 if (soc_feature(unit, soc_feature_trill)) { 252 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_TRILL); 253 } 254 if (soc_feature(unit, soc_feature_niv)) { 255 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_NIV); 256 } 257 if (soc_feature(unit, soc_feature_l2gre)) { 258 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_L2GRE); 259 } 260 if (soc_feature(unit, soc_feature_vxlan)) { 261 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_VXLAN); 262 } 263 if (soc_feature(unit, soc_feature_flex_flow)) { 264 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_FLOW); 265 } 266 if (soc_feature(unit, soc_feature_port_extension)) { 267 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_EXTENDER); 268 } 269 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MULTICAST); 270 #endif 271 if (soc_feature(unit, soc_feature_qos_profile) && 272 (!soc_property_get(unit, "skip_qos_init", 0))) { 273 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_QOS); 274 } 275 if (soc_feature(unit, soc_feature_time_support)) { 276 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_TIME); 277 } 278 #ifdef INCLUDE_PTP 279 if (soc_feature(unit, soc_feature_ptp)) { 280 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_PTP); 281 } 282 #endif 283 #ifdef INCLUDE_BFD 284 if (soc_feature(unit, soc_feature_bfd)) { 285 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_BFD); 286 } 287 #endif 288 if (soc_feature(unit, soc_feature_fcoe)) { 289 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_FCOE); 290 } 291 /* Service meter */ 292 if (soc_feature(unit, soc_feature_global_meter)) { 293 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_GLB_METER); 294 } 295 } 296 297 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_LINKSCAN); 298 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_STAT); 299 #ifdef INCLUDE_KNET 300 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_KNET); 301 #endif 302 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_TX); 303 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_RX); 304 #ifdef INCLUDE_REGEX 305 if (soc_feature(unit, soc_feature_regex)) { 306 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_REGEX); 307 } 308 #endif 309 if (soc_feature(unit, soc_feature_oam) || 310 soc_feature(unit, soc_feature_fp_based_oam)) { 311 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_OAM); 312 } 313 #ifdef SW_AUTONEG_SUPPORT 314 if (soc_feature(unit, soc_feature_sw_autoneg)) { 315 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_SW_AN); 316 } 317 #endif 318 319 return; 320 } 321 322 /* 323 * Function: 324 * bcmi_th2_port_dev_info_init 325 * Purpose: 326 * Initialize the device info. 327 * Parameters: 328 * unit - (IN) Unit number. 329 * Returns: 330 * BCM_E_xxx 331 * Notes: 332 */ 333 int 334 bcmi_th2_port_dev_info_init(int unit) 335 { 336 bcmi_xgs5_dev_info_t *dev_info; 337 soc_info_t *si = &SOC_INFO(unit); 338 uint32 pipe_lr_bw; 339 int alloc_size; 340 int pipe, phy_port, blk, bindex, rsv_port, tsc_id; 341 int i, cntmaxsize; 342 _soc_tomahawk2_tsc_otp_info_t tsc_info; 343 344 /* Free bcmi_th2_dev_info[unit] if already allocated */ 345 if (bcmi_th2_dev_info[unit]) { 346 sal_free(bcmi_th2_dev_info[unit]); 347 bcmi_th2_dev_info[unit] = NULL; 348 } 349 350 /* Allocate memory for main SW data structure */ 351 alloc_size = sizeof(bcmi_xgs5_dev_info_t) + 352 (sizeof(bcmi_xgs5_phy_port_t) * _TH2_PHY_PORTS_PER_DEV); 353 dev_info = sal_alloc(alloc_size, "bcmi_th2_dev_info"); 354 if (dev_info == NULL) { 355 return BCM_E_MEMORY; 356 } 357 sal_memset(dev_info, 0, alloc_size); 358 dev_info->phy_port_info = (bcmi_xgs5_phy_port_t *)&dev_info[1]; 359 bcmi_th2_dev_info[unit] = dev_info; 360 361 /* Device information init */ 362 dev_info = bcmi_th2_dev_info[unit]; 363 dev_info->num_pipe = _TH2_PIPES_PER_DEV; 364 dev_info->num_tsc = _TH2_PBLKS_PER_DEV; 365 dev_info->phy_ports_max = _TH2_PHY_PORTS_PER_DEV; 366 dev_info->mmu_lossless = si->mmu_lossless; 367 dev_info->asf_prof_default = _SOC_ASF_MEM_PROFILE_SIMILAR; 368 dev_info->pipe_bound = 1; 369 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV; pipe++) { 370 /* First logical port in pipe */ 371 dev_info->pipe_log_port_base[pipe] = _TH2_DEV_PORTS_PER_PIPE * pipe; 372 373 /* First physical port in pipe */ 374 dev_info->pipe_phy_port_base[pipe] = _TH2_GPHY_PORTS_PER_PIPE * pipe + 375 (pipe ? 1 : 0); 376 377 /* Pipe 3 has 1 reserved port (physical port 258) */ 378 rsv_port = pipe == 3 ? 1 : 0; 379 dev_info->ports_pipe_max[pipe] = _TH2_DEV_PORTS_PER_PIPE - rsv_port; 380 } 381 /* 10G is the min speed in TDM calendar program. */ 382 dev_info->tdm_speed_min = SPEED_10G; 383 384 cntmaxsize = soc_property_get(unit, spn_BCM_STAT_JUMBO, 1518); 385 if (cntmaxsize > si->max_mtu) { 386 cntmaxsize = si->max_mtu; 387 } 388 dev_info->cntmaxsize_xl = cntmaxsize; 389 dev_info->cntmaxsize_cl = cntmaxsize; 390 391 dev_info->restriction_mask = BCMI_XGS5_FLEXPORT_RESTRICTION_PIPE_BANDWIDTH | 392 BCMI_XGS5_FLEXPORT_RESTRICTION_MIX_LR_OVS_DEV | 393 BCMI_XGS5_FLEXPORT_RESTRICTION_SPEED_CLASS | 394 BCMI_XGS5_FLEXPORT_RESTRICTION_PM_OVS_MIX_SISTER | 395 BCMI_XGS5_FLEXPORT_RESTRICTION_PM_SINGLE_PLL; 396 397 dev_info->encap_mask = BCM_PA_ENCAP_IEEE; 398 if(soc_feature(unit, soc_feature_higig2)) { 399 dev_info->encap_mask |= BCM_PA_ENCAP_HIGIG2; 400 dev_info->hg_encap_mask |= BCM_PA_ENCAP_HIGIG2; 401 } 402 403 /* 404 * Restriction 13:No port configurations with more than 4 port speed 405 * classes are supported for LR, no port configurations with 406 * more than 5 port speed classes are supported for OS. 407 * Restriction 15:All port configurations with 1-3 port speed classes are 408 * supported, except configurations that contain both 20G 409 * and 25G port speeds. 410 */ 411 dev_info->speed_class.speed_class_num = si->oversub_mode ? 412 _TH2_TDM_OS_SPEED_CLASS_MAX : _TH2_TDM_LR_SPEED_CLASS_MAX; 413 dev_info->speed_class.no_mix_speed_mask = SOC_PA_SPEED_20GB 414 | SOC_PA_SPEED_25GB; 415 416 dev_info->port_ratio_mask = BCMI_XGS5_PORT_RATIO_SINGLE | 417 BCMI_XGS5_PORT_RATIO_DUAL_1_1 | 418 BCMI_XGS5_PORT_RATIO_DUAL_2_1 | 419 BCMI_XGS5_PORT_RATIO_DUAL_1_2 | 420 BCMI_XGS5_PORT_RATIO_TRI_023_2_1_1 | 421 BCMI_XGS5_PORT_RATIO_TRI_023_4_1_1 | 422 BCMI_XGS5_PORT_RATIO_TRI_012_1_1_2 | 423 BCMI_XGS5_PORT_RATIO_TRI_012_1_1_4 | 424 BCMI_XGS5_PORT_RATIO_QUAD; 425 426 /* Auxiliary ports */ 427 SOC_PBMP_PORT_ADD(dev_info->aux_pbm, 0); /* CPU port */ 428 SOC_PBMP_PORT_ADD(dev_info->aux_pbm, 33); /* Loopback port on pipe0 */ 429 SOC_PBMP_PORT_ADD(dev_info->aux_pbm, 66); /* Management0 on pipe1 */ 430 SOC_PBMP_PORT_ADD(dev_info->aux_pbm, 67); /* Loopback port on pipe1 */ 431 SOC_PBMP_PORT_ADD(dev_info->aux_pbm, 100); /* Management1 on pipe2 */ 432 SOC_PBMP_PORT_ADD(dev_info->aux_pbm, 101); /* Loopback port on pipe2 */ 433 SOC_PBMP_PORT_ADD(dev_info->aux_pbm, 134); /* Reserved port on pipe3 */ 434 SOC_PBMP_PORT_ADD(dev_info->aux_pbm, 135); /* Loopback port on pipe3 */ 435 436 /* Set max line rate bandwidth per pipeline */ 437 BCM_IF_ERROR_RETURN 438 (soc_th2_max_lr_bandwidth(unit, &pipe_lr_bw)); 439 dev_info->pipe_lr_bw = pipe_lr_bw * 1000; 440 441 /* 10G is the min speed in TDM calculations */ 442 dev_info->tdm_pipe_lr_bw_limit_checker_speed_min = SPEED_10G; 443 444 /* Set valid speeds for 1/2/4 Lanes */ 445 BCM_IF_ERROR_RETURN 446 (soc_th2_support_speeds(unit, 1, &dev_info->speed_valid[1])); 447 BCM_IF_ERROR_RETURN 448 (soc_th2_support_speeds(unit, 2, &dev_info->speed_valid[2])); 449 BCM_IF_ERROR_RETURN 450 (soc_th2_support_speeds(unit, 4, &dev_info->speed_valid[4])); 451 452 /* 453 * Set physical port info: 454 * - Port lane capability 455 * - Port is enabled for flexport 456 * - pipe 457 */ 458 for (phy_port = 0; phy_port < _TH2_PHY_PORTS_PER_DEV; phy_port++) { 459 /* Set information to invalid */ 460 dev_info->phy_port_info[phy_port].pipe = -1; 461 } 462 463 /* Flexport is not supported for CPU/LB/MNG ports, so skip CPU/LB/MNG */ 464 for (phy_port = 1; phy_port <= _TH2_GPHY_PORTS_PER_DEV; phy_port++) { 465 /* Check for end of port list */ 466 if (SOC_PORT_BLOCK(unit, phy_port) < 0 && 467 SOC_PORT_BINDEX(unit, phy_port) < 0) { 468 break; 469 } 470 471 /* Set pipe information */ 472 dev_info->phy_port_info[phy_port].pipe = 473 (phy_port - 1) / _TH2_GPHY_PORTS_PER_PIPE; 474 475 /* Set TSC info from OTP */ 476 memset(&tsc_info, 0, sizeof(tsc_info)); 477 tsc_id = (phy_port - 1) / _TH2_PORTS_PER_PBLK; 478 BCM_IF_ERROR_RETURN 479 (soc_tomahawk2_tsc_otp_info_get(unit, tsc_id, &tsc_info)); 480 dev_info->phy_port_info[phy_port].force_lb = tsc_info.force_loopback; 481 dev_info->phy_port_info[phy_port].force_hg = tsc_info.force_hg; 482 dev_info->phy_port_info[phy_port].max_lane_speed = 483 tsc_info.max_lane_speed; 484 if (tsc_info.disable) { 485 dev_info->phy_port_info[phy_port].flex = 0; 486 continue; 487 } 488 489 for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) { 490 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i); 491 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i); 492 493 if ((blk < 0) || (bindex < 0)) { 494 continue; 495 } 496 497 if (SOC_BLOCK_TYPE(unit, blk) == SOC_BLK_CLPORT) { 498 /* Set port lane capabilites */ 499 dev_info->phy_port_info[phy_port].lanes_valid = 500 BCMI_XGS5_PORT_LANES_1; 501 if (bindex == 0) { 502 dev_info->phy_port_info[phy_port].lanes_valid |= 503 BCMI_XGS5_PORT_LANES_2 | BCMI_XGS5_PORT_LANES_4; 504 } else if (bindex == 2) { 505 dev_info->phy_port_info[phy_port].lanes_valid |= 506 BCMI_XGS5_PORT_LANES_2; 507 } 508 509 if (SHR_BITGET(si->flexible_pm_bitmap,blk)) { 510 dev_info->phy_port_info[phy_port].flex = 1; 511 } 512 } 513 } /* for port_num_blktype */ 514 } 515 516 /* Init condition */ 517 _bcmi_th2_init_condition_set(unit, dev_info); 518 519 return BCM_E_NONE; 520 } 521 522 /* 523 * Function: 524 * bcmi_td2p_port_fn_drv_init 525 * Purpose: 526 * Initialize the Port function driver. 527 * Parameters: 528 * unit - (IN) Unit number. 529 * Returns: 530 * BCM_E_xxx 531 * Notes: 532 */ 533 int 534 bcmi_th2_port_fn_drv_init(int unit) 535 { 536 int phase_pos, present; 537 538 if (!bcmi_th2_port_drv_internal_initialized) { 539 /* BCMI Driver init */ 540 sal_memset(&bcmi_th2_port_drv, 0, sizeof(bcmi_th2_port_drv)); 541 bcmi_th2_port_drv.port_calls = &bcmi_th2_port_calls; 542 sal_memcpy(bcmi_th2_port_drv.port_calls->port_attach_exec, 543 th2_port_attach_exec, 544 sizeof(bcmi_th2_port_drv.port_calls->port_attach_exec)); 545 546 sal_memcpy(bcmi_th2_port_drv.port_calls->port_detach_exec, 547 th2_port_detach_exec, 548 sizeof(bcmi_th2_port_drv.port_calls->port_detach_exec)); 549 550 bcmi_th2_port_drv_internal_initialized = 1; 551 } 552 553 BCM_IF_ERROR_RETURN 554 (bcmi_th2_port_dev_info_init(unit)); 555 bcmi_th2_port_drv.dev_info[unit] = bcmi_th2_dev_info[unit]; 556 557 /* Initialize Common XGS5 Port module */ 558 BCM_IF_ERROR_RETURN 559 (bcmi_xgs5_port_fn_drv_init(unit, 560 &bcm_th2_port_drv, 561 &bcmi_th2_port_drv, 562 NULL)); 563 BCM_IF_ERROR_RETURN(soc_check_flex_phase(unit, flexport_phases, 564 soc_tomahawk2_flex_top_port_down, 565 &present)); 566 /* Detach port enable/disable in DV Flexport */ 567 if (present) { 568 BCM_IF_ERROR_RETURN 569 (soc_detach_flex_phase(unit, flexport_phases, 570 soc_tomahawk2_flex_top_port_down, 571 &phase_pos)); 572 } 573 BCM_IF_ERROR_RETURN(soc_check_flex_phase(unit, flexport_phases, 574 soc_tomahawk2_flex_top_port_up, 575 &present)); 576 if (present) { 577 BCM_IF_ERROR_RETURN 578 (soc_detach_flex_phase(unit, flexport_phases, 579 soc_tomahawk2_flex_top_port_up, 580 &phase_pos)); 581 } 582 583 return BCM_E_NONE; 584 } 585 586 /* 587 * Function: 588 * bcmi_th2_port_soc_resource_init 589 * Purpose: 590 * Initialize SOC Port Structure. 591 * This includes: 592 * Copy Port information from BCM port resource array. 593 * Set correct pipe, MMU port, IDB port for new logical port. 594 * Parameters: 595 * unit - (IN) Unit number. 596 * nport - (IN) Number of elements in array resource. 597 * resource - (IN) BCM Port resource configuration array. 598 * soc_resource - (OUT) SOC Port resource array. 599 * Returns: 600 * BCM_E_xxx 601 * Notes: 602 */ 603 int 604 bcmi_th2_port_soc_resource_init(int unit, int nport, 605 bcm_port_resource_t *resource, 606 soc_port_resource_t *soc_resource) 607 { 608 int i; 609 int logic_port, idb_port, mmu_port, pipe; 610 soc_info_t *si = &SOC_INFO(unit); 611 612 /* 613 * SOC Port Structure initialization 614 */ 615 616 /* Clear data structure */ 617 sal_memset(soc_resource, 0, sizeof(soc_port_resource_t) * nport); 618 619 /* Copy initial information */ 620 for (i = 0; i < nport; i++) { 621 logic_port = resource[i].port; 622 if (logic_port == _TH2_DEV_RSV_PORT) { 623 return BCM_E_PORT; 624 } 625 626 pipe = logic_port/_TH2_DEV_PORTS_PER_PIPE; 627 idb_port = (logic_port % _TH2_DEV_PORTS_PER_PIPE) - (pipe == 0 ? 1 : 0); 628 mmu_port = pipe * _TH2_MMU_PORTS_OFFSET_PER_PIPE + idb_port; 629 630 soc_resource[i].flags = resource[i].flags; 631 soc_resource[i].logical_port = logic_port; 632 soc_resource[i].physical_port = resource[i].physical_port; 633 soc_resource[i].speed = resource[i].speed < SPEED_10G ? 634 SPEED_10G : resource[i].speed; 635 soc_resource[i].num_lanes = resource[i].lanes; 636 soc_resource[i].encap = resource[i].encap; 637 soc_resource[i].pipe = pipe; 638 soc_resource[i].idb_port = idb_port; 639 soc_resource[i].mmu_port = mmu_port; 640 /* TH2 does NOT support port configuration with a mix of line-rate ports 641 * and oversubscribed ports. */ 642 soc_resource[i].oversub = si->oversub_mode; 643 644 if (resource[i].lanes > 1) { 645 soc_resource[i].hsp = 1; 646 } 647 } 648 649 return BCM_E_NONE; 650 } 651 652 /* 653 * Function: 654 * bcmi_th2_port_resource_validate 655 * Purpose: 656 * Validate that the given FlexPort operations is valid. 657 * Parameters: 658 * unit - (IN) Unit number. 659 * port_schedule_state - (OUT) Port resource state. 660 * Returns: 661 * BCM_E_xxx 662 * Notes: 663 */ 664 int 665 bcmi_th2_port_resource_validate(int unit, 666 soc_port_schedule_state_t *port_schedule_state) 667 { 668 return BCM_E_NONE; 669 } 670 671 /* 672 * Function: 673 * bcmi_th2_pre_flexport_tdm 674 * Purpose: 675 * Pass TDM information pre FlexPort to DV FlexPort API 676 * Parameters: 677 * unit - (IN) Unit number. 678 * port_schedule_state - (OUT) Port resource state. 679 * Returns: 680 * BCM_E_xxx 681 * Notes: 682 */ 683 int 684 bcmi_th2_pre_flexport_tdm(int unit, 685 soc_port_schedule_state_t *port_schedule_state) 686 { 687 port_schedule_state->is_flexport = 1; 688 689 BCM_IF_ERROR_RETURN 690 (soc_th2_port_schedule_tdm_init(unit, port_schedule_state)); 691 692 return BCM_E_NONE; 693 } 694 695 /* 696 * Function: 697 * bcmi_th2_post_flexport_tdm 698 * Purpose: 699 * Update TDM information in SOC with post FlexPort TDM state return from 700 * DV FlexPort API. 701 * Parameters: 702 * unit - (IN) Unit number. 703 * port_schedule_state - (IN) Port resource state. 704 * Returns: 705 * BCM_E_xxx 706 * Notes: 707 */ 708 int 709 bcmi_th2_post_flexport_tdm(int unit, 710 soc_port_schedule_state_t *port_schedule_state) 711 { 712 BCM_IF_ERROR_RETURN 713 (soc_th2_soc_tdm_update(unit, port_schedule_state)); 714 715 return BCM_E_NONE; 716 } 717 718 /* 719 * Function: 720 * bcmi_th2_clport_update 721 * Purpose: 722 * Update CLPORT. 723 * Parameters: 724 * unit - (IN) Unit number. 725 * port_schedule_state - (IN) Port resource state. 726 * Returns: 727 * BCM_E_xxx 728 * Notes: 729 */ 730 int 731 bcmi_th2_clport_update(int unit, 732 soc_port_schedule_state_t *port_schedule_state) 733 { 734 soc_info_t *si = &SOC_INFO(unit); 735 soc_port_resource_t *pr; 736 int i, nport; 737 int phy_port, logic_port, phy_port_base; 738 int blk; 739 int clport, lane, mode; 740 SHR_BITDCL pm_bmp[_SHR_BITDCLSIZE(SOC_MAX_NUM_BLKS)]; 741 soc_port_map_type_t *in_port_map; 742 uint32 rval; 743 static soc_field_t port_fields[_TH2_PORTS_PER_PBLK] = { 744 PORT0f, PORT1f, PORT2f, PORT3f 745 }; 746 static const int mode_encodings[SOC_TH_PORT_RATIO_COUNT] = { 747 4, 3, 3, 3, 2, 2, 1, 1, 0 748 }; 749 750 SHR_BITCLR_RANGE(pm_bmp, 0, SOC_MAX_NUM_BLKS); 751 752 nport = port_schedule_state->nport; 753 in_port_map = &port_schedule_state->in_port_map; 754 755 for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) { 756 if (!(pr->op & ~(BCMI_XGS5_PORT_RESOURCE_OP_SPEED| 757 BCMI_XGS5_PORT_RESOURCE_OP_ENCAP))) { 758 continue; 759 } 760 761 logic_port = pr->logical_port; 762 phy_port = pr->physical_port == -1 ? 763 in_port_map->port_l2p_mapping[logic_port] : 764 pr->physical_port; 765 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0); 766 SHR_BITSET(pm_bmp, blk); 767 } 768 769 SHR_BIT_ITER(pm_bmp, SOC_MAX_NUM_BLKS, blk) { 770 if (!SOC_INFO(unit).block_valid[blk]) { 771 continue; 772 } 773 logic_port = SOC_BLOCK_PORT(unit, blk); 774 clport = SOC_BLOCK_NUMBER(unit, blk); 775 phy_port_base = PORT_BLOCK_BASE_PORT(logic_port); 776 777 /* Assert CLPORT soft reset */ 778 rval = 0; 779 for (lane = 0; lane < _TH2_PORTS_PER_PBLK; lane++) { 780 if (si->port_p2l_mapping[phy_port_base + lane] != -1) { 781 soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &rval, 782 port_fields[lane], 1); 783 } 784 } 785 SOC_IF_ERROR_RETURN(WRITE_CLPORT_SOFT_RESETr(unit, logic_port, rval)); 786 787 /* Set port mode */ 788 soc_tomahawk2_port_ratio_get(unit, port_schedule_state, clport, 789 &mode, 790 0); 791 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, CLPORT_MODE_REGr, 792 logic_port, 0, &rval)); 793 soc_reg_field_set(unit, CLPORT_MODE_REGr, &rval, XPORT0_CORE_PORT_MODEf, 794 mode_encodings[mode]); 795 soc_reg_field_set(unit, CLPORT_MODE_REGr, &rval, XPORT0_PHY_PORT_MODEf, 796 mode_encodings[mode]); 797 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MODE_REGr(unit, logic_port, rval)); 798 799 /* De-assert XLPORT soft reset */ 800 SOC_IF_ERROR_RETURN(WRITE_CLPORT_SOFT_RESETr(unit, logic_port, 0)); 801 } 802 return BCM_E_NONE; 803 } 804 805 int 806 bcmi_th2_port_attach_mmu(int unit, int port) 807 { 808 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || 809 IS_MANAGEMENT_PORT(unit, port)) { 810 return BCM_E_PARAM; 811 } 812 813 /* Assign the base queues and number of queues for the specified port. */ 814 BCM_IF_ERROR_RETURN 815 (soc_tomahawk_num_cosq_init_port(unit, port)); 816 817 /* Reconfigure THDI, THDO settings */ 818 BCM_IF_ERROR_RETURN 819 (soc_th2_mmu_config_init_port(unit, port)); 820 821 return BCM_E_NONE; 822 } 823 824 /* 825 * Function: 826 * bcmi_th2_port_detach_asf 827 * Purpose: 828 * Update ASF when port deleted during Flexport operations. 829 * Parameters: 830 * unit - (IN) Unit number. 831 * port - (IN) Logical port number. 832 * Returns: 833 * BCM_E_xxx 834 * Notes: 835 */ 836 int 837 bcmi_th2_port_detach_asf(int unit, bcm_port_t port) 838 { 839 if (soc_feature(unit, soc_feature_asf_multimode)) { 840 BCM_IF_ERROR_RETURN 841 (soc_th_port_asf_detach(unit, port)); 842 } 843 844 return BCM_E_NONE; 845 } 846 847 /* 848 * Function: 849 * bcm_th2_ipmc_repl_port_attach 850 * Purpose: 851 * Initialize replication per-port configuration in the runtime. 852 * Parameters: 853 * unit - (IN) Unit number. 854 * port - (IN) Logical port number. 855 * Returns: 856 * BCM_E_xxx 857 * Notes: 858 */ 859 int 860 bcm_th2_ipmc_repl_port_attach(int unit, bcm_port_t port) 861 { 862 int rv = BCM_E_NONE; 863 864 #ifdef INCLUDE_L3 865 if (soc_feature(unit, soc_feature_ip_mcast) && 866 soc_feature(unit, soc_feature_ip_mcast_repl)) { 867 rv = bcm_th_ipmc_repl_port_attach(unit, port); 868 } 869 #endif 870 871 return rv; 872 } 873 874 /* 875 * Function: 876 * bcm_th2_ipmc_repl_port_detach 877 * Purpose: 878 * Clear replication per-port configuration in the runtime. 879 * Parameters: 880 * unit - (IN) Unit number. 881 * port - (IN) Logical port number. 882 * Returns: 883 * BCM_E_xxx 884 * Notes: 885 */ 886 int 887 bcm_th2_ipmc_repl_port_detach(int unit, bcm_port_t port) 888 { 889 int rv = BCM_E_NONE; 890 891 #ifdef INCLUDE_L3 892 if (soc_feature(unit, soc_feature_ip_mcast) && 893 soc_feature(unit, soc_feature_ip_mcast_repl)) { 894 rv = bcm_th_ipmc_repl_port_detach(unit, port); 895 } 896 #endif 897 898 return rv; 899 } 900 901 /* 902 * Function: 903 * bcmi_th2_port_enable 904 * Purpose: 905 * Enable port. 906 * Parameters: 907 * unit - (IN) Unit number. 908 * port_schedule_state - (IN) Port resource state. 909 * Returns: 910 * BCM_E_xxx 911 * Notes: 912 * This function should only be called with PORTMOD enabled 913 */ 914 int 915 bcmi_th2_port_enable(int unit, 916 soc_port_schedule_state_t *port_schedule_state) 917 { 918 int i, nport, rv; 919 bcm_port_t *port; 920 921 nport = port_schedule_state->nport; 922 923 port = sal_alloc(nport * sizeof(bcm_port_t), "port array"); 924 if (port == NULL) { 925 return BCM_E_MEMORY; 926 } 927 for (i = 0; i < nport; i++) { 928 port[i] = port_schedule_state->resource[i].logical_port; 929 } 930 931 rv = soc_tomahawk2_flex_mmu_port_up(unit, port_schedule_state); 932 if (BCM_SUCCESS(rv)) { 933 rv = soc_tomahawk2_flex_ep_port_up(unit, port_schedule_state); 934 } 935 if (BCM_SUCCESS(rv)) { 936 rv = soc_tomahawk2_flex_idb_port_up(unit, port_schedule_state); 937 } 938 if (BCM_SUCCESS(rv)) { 939 rv = bcmi_esw_portctrl_mac_up(unit, nport, port); 940 } 941 sal_free(port); 942 943 return rv; 944 } 945 946 /* 947 * Function: 948 * bcmi_th2_port_disable 949 * Purpose: 950 * Disable port. 951 * Parameters: 952 * unit - (IN) Unit number. 953 * port_schedule_state - (IN) Port resource state. 954 * Returns: 955 * BCM_E_xxx 956 * Notes: 957 * This function should only be called with PORTMOD enabled 958 */ 959 int 960 bcmi_th2_port_disable(int unit, 961 soc_port_schedule_state_t *port_schedule_state) 962 { 963 int i, nport, rv; 964 bcm_port_t *port; 965 966 nport = port_schedule_state->nport; 967 968 port = sal_alloc(nport * sizeof(bcm_port_t), "port array"); 969 if (port == NULL) { 970 return BCM_E_MEMORY; 971 } 972 for (i = 0; i < nport; i++) { 973 port[i] = port_schedule_state->resource[i].logical_port; 974 } 975 rv = bcmi_esw_portctrl_mac_rx_down(unit, nport, port); 976 if (BCM_SUCCESS(rv)) { 977 rv = soc_tomahawk2_flex_idb_port_down(unit, port_schedule_state); 978 } 979 if ((BCM_SUCCESS(rv)) && (!(SAL_BOOT_XGSSIM || SAL_BOOT_BCMSIM))) { 980 rv = soc_tomahawk2_flex_mmu_port_down(unit, port_schedule_state); 981 } 982 if (BCM_SUCCESS(rv)) { 983 rv = soc_tomahawk2_flex_ep_port_down(unit, port_schedule_state); 984 } 985 if (BCM_SUCCESS(rv)) { 986 rv = bcmi_esw_portctrl_mac_tx_down(unit, nport, port); 987 } 988 989 sal_free(port); 990 991 return rv; 992 } 993 994 /* 995 * Function: 996 * bcmi_th2_port_speed_1g_update 997 * Purpose: 998 * Special operations for 1G speed. 999 * Parameters: 1000 * unit - (IN) Unit number. 1001 * port - (IN) Logical port number. 1002 * speed - (IN) port speed (Mbps). 1003 * Returns: 1004 * BCM_E_xxx 1005 * Notes: 1006 * In the PRD, nothing below 10G is officially supported. 1007 * We enable customers with limited 1G support in Tomahawk2. 1008 * 1G is not a support speed class in TDM calculation, thus treated same as 1009 * 10G in TDM calculation. 1G port does NOT support cut through, flow 1010 * control. 1011 */ 1012 int 1013 bcmi_th2_port_speed_1g_update(int unit, bcm_port_t port, int speed) 1014 { 1015 if (speed != SPEED_1G) { 1016 return BCM_E_NONE; 1017 } 1018 1019 /* Update port speed info in soc_info */ 1020 SOC_INFO(unit).port_init_speed[port] = speed; 1021 1022 /* Set asf mode to SAF */ 1023 if (soc_feature(unit, soc_feature_asf_multimode)) { 1024 BCM_IF_ERROR_RETURN 1025 (soc_th_port_asf_mode_set(unit, port, speed, 1026 _SOC_TH_ASF_MODE_SAF)); 1027 } 1028 1029 /* Disable Pause */ 1030 BCM_IF_ERROR_RETURN 1031 (bcm_esw_port_pause_set(unit, port, 0, 0)); 1032 1033 /* Disable PFC */ 1034 if (soc_feature(unit, soc_feature_priority_flow_control)) { 1035 BCM_IF_ERROR_RETURN 1036 (bcm_esw_port_control_set(unit, port, 1037 bcmPortControlPFCReceive, 0)); 1038 BCM_IF_ERROR_RETURN 1039 (bcm_esw_port_control_set(unit, port, 1040 bcmPortControlPFCTransmit, 0)); 1041 } 1042 1043 return BCM_E_NONE; 1044 } 1045 1046 /* 1047 * Function: 1048 * bcmi_th2_speed_ability_get 1049 * Purpose: 1050 * Retrieve the local port abilities. 1051 * Parameters: 1052 * unit - Unit. 1053 * port - Logical port num. 1054 * mask - (OUT) Mask of BCM_PORT_ABILITY_ values indicating the 1055 * supported speeds of the port. 1056 * Returns: 1057 * BCM_E_NONE 1058 * BCM_E_XXX 1059 */ 1060 int 1061 bcmi_th2_speed_ability_get(int unit, bcm_port_t port, bcm_port_abil_t *mask) 1062 { 1063 if (IS_MANAGEMENT_PORT(unit, port)) { 1064 /* TH2 Port Rates for Management ports: 1065 * 10M, 100M, 1G, 2.5G, 10G, HG[11G] */ 1066 *mask = BCM_PORT_ABILITY_10MB | BCM_PORT_ABILITY_100MB | 1067 BCM_PORT_ABILITY_1000MB | BCM_PORT_ABILITY_2500MB | 1068 BCM_PORT_ABILITY_10GB | BCM_PORT_ABILITY_11GB; 1069 } else { 1070 BCM_IF_ERROR_RETURN 1071 (soc_th2_support_speeds(unit, 1072 SOC_INFO(unit).port_num_lanes[port], 1073 mask)); 1074 } 1075 1076 return BCM_E_NONE; 1077 } 1078 1079 /* 1080 * Function: 1081 * bcmi_th2_tsc_xgxs_reset 1082 * Purpose: 1083 * Reset TSC. 1084 * Parameters: 1085 * unit - Unit. 1086 * pbmp - Bitmap of ports to reset. 1087 * Returns: 1088 * BCM_E_NONE 1089 * BCM_E_XXX 1090 */ 1091 int 1092 bcmi_th2_tsc_xgxs_reset(int unit, pbmp_t pbmp) 1093 { 1094 int rv = BCM_E_NONE; 1095 soc_info_t *si; 1096 uint64 tsc_map, reset_tsc_map; 1097 int tsc, ports[_TH2_PBLKS_PER_DEV]; 1098 bcm_port_t port; 1099 _bcm_port_info_t *port_info = NULL; 1100 1101 si = &SOC_INFO(unit); 1102 1103 /* Construct tsc_map covered by the specified pbmp */ 1104 COMPILER_64_ZERO(tsc_map); 1105 PBMP_ITER(pbmp, port) { 1106 tsc = si->port_serdes[port]; 1107 if (tsc != -1) { 1108 COMPILER_64_BITSET(tsc_map, tsc); 1109 } 1110 } 1111 1112 COMPILER_64_ZERO(reset_tsc_map); 1113 PBMP_PORT_ITER(unit, port) { 1114 tsc = si->port_serdes[port]; 1115 if (COMPILER_64_BITTEST(tsc_map, tsc)) { 1116 _bcm_port_info_access(unit, port, &port_info); 1117 if (port_info->flags & _PORT_INFO_PROBE_RESET_SERDES) { 1118 port_info->flags &= ~_PORT_INFO_PROBE_RESET_SERDES; 1119 COMPILER_64_BITSET(reset_tsc_map, tsc); 1120 ports[tsc] = port; 1121 } 1122 } 1123 } 1124 1125 for (tsc = 0; tsc < _TH2_PBLKS_PER_DEV; tsc++) { 1126 if (COMPILER_64_BITTEST(reset_tsc_map, tsc)) { 1127 rv = soc_tsc_xgxs_reset(unit, ports[tsc], 0); 1128 } 1129 } 1130 1131 return rv; 1132 } 1133 1134 int 1135 bcmi_th2_speed_mix_validate(int unit, uint32 speed_mask) 1136 { 1137 return soc_th2_speed_mix_validate(unit, speed_mask); 1138 } 1139 1140 #endif /* BCM_TOMAHAWK2_SUPPORT */