port.c (86295B)
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 Management for Trident 3 9 * 10 * The purpose is to set port management implementation specified 11 * to Trident 3 in this file. 12 */ 13 14 #include <soc/defs.h> 15 16 #if defined(BCM_TRIDENT3_SUPPORT) 17 #include <sal/core/libc.h> 18 #include <soc/drv.h> 19 #include <soc/hash.h> 20 #include <soc/l2x.h> 21 #include <soc/trident3.h> 22 #include <soc/tomahawk.h> 23 #include <soc/esw/cancun.h> 24 #include <bcm/port.h> 25 #include <bcm/error.h> 26 27 #include <bcm_int/esw/port.h> 28 #include <bcm_int/esw/xgs3.h> 29 #include <bcm_int/esw/trx.h> 30 #include <bcm_int/esw/mirror.h> 31 #include <bcm_int/esw/firebolt.h> 32 #include <bcm_int/esw/trident3.h> 33 #if defined(BCM_HELIX5_SUPPORT) 34 #include <bcm_int/esw/helix5.h> 35 #endif 36 #include <bcm_int/esw/trident.h> 37 #include <bcm_int/esw/tomahawk.h> 38 39 #include <bcm_int/esw/xgs5.h> 40 #include <bcm_int/esw/portctrl.h> 41 #include <soc/flexport/trident3/trident3_flexport.h> 42 #include <soc/flexport/trident3/trident3_flexport_defines.h> 43 #include <include/bcm_int/esw/triumph3.h> 44 #include <bcm_int/esw/trident2plus.h> 45 /* 46 * Function Vector 47 */ 48 static bcm_esw_port_drv_t bcm_td3_port_drv = { 49 /* fn_drv_init */ bcmi_td3_port_fn_drv_init, 50 /* resource_set */ bcmi_xgs5_port_resource_set, 51 /* resource_get */ bcmi_xgs5_port_resource_get, 52 /* resource_multi_set */ bcmi_xgs5_port_resource_multi_set, 53 /* resource_speed_set */ bcmi_xgs5_port_speed_set, 54 /* resource_traverse */ bcmi_xgs5_port_resource_traverse, 55 /* port_redirect_set */ NULL, 56 /* port_redirect_get */ NULL, 57 /* port_enable_set */ bcmi_xgs5_port_enable_set, 58 /* encap_speed_check */ bcmi_xgs5_port_encap_speed_check, 59 /* force_lb_set */ NULL, 60 /* force_lb_check */ NULL, 61 /* resource_status_update */ bcmi_xgs5_port_resource_status_update, 62 /* port_resource_speed_multi_set */ bcmi_xgs5_port_resource_speed_multi_set, 63 /* device_speed_check */ NULL, 64 }; 65 66 /* Device programming routines */ 67 static bcmi_xgs5_port_func_t bcmi_td3_port_calls = { 68 /* reconfigure_ports */ soc_trident3_reconfigure_ports, 69 /* soc_resource_init */ bcmi_td3_port_soc_resource_init, 70 /* port_resource_validate */ bcmi_td3_port_resource_validate, 71 /* pre_flexport_tdm */ bcmi_td3_pre_flexport_tdm, 72 /* post_flexport_tdm */ bcmi_td3_post_flexport_tdm, 73 /* port_macro_update */ bcmi_td3_clport_update, 74 /* port_enable */ bcmi_td3_port_enable, 75 /* port_disable */ bcmi_td3_port_disable, 76 /* no_tdm_speed_update */ bcmi_td3_port_speed_1g_update, 77 /* speed_ability_get */ bcmi_td3_speed_ability_get, 78 /* speed_mix_validate */ bcmi_td3_speed_mix_validate, 79 /* cos_map_update */ bcmi_td3_port_cosmap_update, 80 }; 81 82 static bcmi_xgs5_dev_info_t *bcmi_td3_dev_info[SOC_MAX_NUM_DEVICES]; 83 84 /* HW Definitions */ 85 static bcmi_xgs5_port_drv_t bcmi_td3_port_drv; 86 87 static 88 int (*td3_port_attach_exec[PORT_ATTACH_EXEC__MAX])(int unit, bcm_port_t port) = { 89 /* MMU config init */ 90 &bcmi_td3_port_attach_mmu, 91 92 /* PORT module (bcm_esw_port_init) */ 93 &bcmi_xgs5_port_attach_dscp, 94 &bcmi_xgs5_port_attach_software, 95 &bcmi_xgs5_port_attach_egr_vlan_action, 96 &bcmi_xgs5_port_cfg_init, 97 &bcmi_xgs5_port_attach_port_probe, 98 &bcmi_xgs5_port_attach_frame_length_check, 99 &bcmi_xgs5_port_attach_rcpu_mtu, 100 &bcmi_xgs5_port_attach_outer_tpid, 101 &bcmi_xgs5_port_egr_block_profile_init, 102 &bcmi_xgs5_port_attach_vlan_protocol, 103 &bcmi_xgs5_port_attach_eee, 104 &bcmi_xgs5_port_attach_higig, 105 &bcmi_xgs5_port_attach_port_info_cfg, 106 &bcmi_xgs5_port_attach_egr_link_delay, 107 108 /* Other modules related to port */ 109 &bcmi_xgs5_port_attach_stg, 110 &bcmi_xgs5_port_attach_vlan, 111 &bcmi_xgs5_port_attach_trunk, 112 &bcm_td3_cosq_port_attach, 113 &bcmi_xgs5_port_attach_linkscan, 114 &bcmi_xgs5_port_attach_stat, 115 &bcmi_td3_port_attach_stack, 116 &bcmi_xgs5_port_attach_rate, 117 &bcmi_xgs5_port_attach_field, 118 &bcmi_xgs5_port_attach_mirror, 119 &bcmi_td3_port_attach_l3, 120 &bcmi_xgs5_port_attach_ipmc, 121 #if defined(INCLUDE_L3) 122 &bcm_th_ipmc_repl_port_attach, 123 #else 124 NULL, 125 #endif 126 &bcmi_xgs5_port_attach_mpls, 127 &bcmi_xgs5_port_attach_mim, 128 }; 129 130 static 131 int (*td3_port_detach_exec[PORT_DETACH_EXEC__MAX])(int unit, bcm_port_t port) = { 132 /* Other modules related to port */ 133 #if defined(INCLUDE_L3) 134 &bcm_th_ipmc_repl_port_detach, 135 #else 136 NULL, 137 #endif 138 &bcmi_xgs5_port_detach_ipmc, 139 &bcmi_xgs5_port_detach_mpls, 140 &bcmi_xgs5_port_detach_mim, 141 &bcmi_td3_port_detach_l3, 142 &bcmi_xgs5_port_detach_mirror, 143 &bcmi_xgs5_port_detach_field, 144 &bcmi_xgs5_port_detach_rate, 145 &bcmi_td3_port_detach_stack, 146 &bcm_td3_cosq_port_detach, 147 &bcmi_xgs5_port_detach_trunk, 148 &bcmi_xgs5_port_detach_vlan, 149 &bcmi_xgs5_port_detach_stg, 150 151 /* PORT module (_bcm_esw_port_deinit) */ 152 &bcmi_td3_port_detach_asf, 153 &bcmi_xgs5_port_detach_egr_link_delay, 154 &bcmi_xgs5_port_detach_higig, 155 &bcmi_xgs5_port_detach_eee, 156 &bcmi_xgs5_port_detach_vlan_protocol, 157 &bcmi_xgs5_port_egr_block_profile_init, 158 &bcmi_xgs5_port_detach_phy, 159 &bcmi_xgs5_port_detach_dscp, 160 &bcmi_xgs5_port_cfg_init, 161 &bcmi_xgs5_port_detach_egr_vlan_action, 162 &bcmi_xgs5_port_detach_software, 163 }; 164 165 /* 166 * Function: 167 * bcmi_td3_init_condition_set 168 * Purpose: 169 * Set the info of skiped modules during initialization in dev_info. 170 * Parameters: 171 * unit - (IN) Unit number. 172 * dev_info - (OUT) Device info used during flexport 173 * Returns: 174 * None 175 * Notes: 176 * Must follow the _bcm_modules_init() 177 */ 178 void 179 _bcmi_td3_init_condition_set(int unit, bcmi_xgs5_dev_info_t *dev_info) 180 { 181 int init_all; 182 183 init_all = soc_property_get(unit, "init_all_modules", 184 (SAL_BOOT_BCMSIM) || (!SAL_BOOT_SIMULATION)); 185 186 if (soc_feature(unit, soc_feature_virtual_switching) || 187 soc_feature(unit, soc_feature_gport_service_counters) || 188 soc_feature(unit, soc_feature_fast_init) || 189 soc_feature(unit, soc_feature_int_common_init)){ 190 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_COMMON); 191 } 192 193 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_PORT); 194 195 if (!(SAL_BOOT_SIMULATION && 196 soc_property_get(unit, spn_SKIP_L2_VLAN_INIT, 0))) { 197 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_L2); 198 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_VLAN); 199 } 200 201 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_STG); 202 203 if (init_all || 204 (soc_property_get(unit, "skip_cosq_init", 0) ? FALSE : TRUE)) { 205 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_COSQ); 206 } 207 if (init_all || 208 (soc_property_get(unit, "skip_stack_init", 0) ? FALSE : TRUE)) { 209 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_STK); 210 } 211 if (init_all || 212 (soc_property_get(unit, "skip_mirror_init", 0) ? FALSE : TRUE)) { 213 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MIRROR); 214 } 215 if (init_all) { 216 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_TRUNK); 217 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MCAST); 218 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_RATE); 219 220 if (SOC_MEM_IS_VALID(unit, FP_UDF_TCAMm)) { 221 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_UDF); 222 } 223 224 #ifdef BCM_FIELD_SUPPORT 225 if (SOC_MEM_IS_VALID(unit, IFP_RANGE_CHECKm)) { 226 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_RANGE); 227 } 228 if (soc_feature(unit, soc_feature_field)) { 229 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_FIELD); 230 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_AUTH); 231 } 232 #endif 233 234 #ifdef INCLUDE_L3 235 if (soc_feature(unit, soc_feature_failover)) { 236 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_FAILOVER); 237 } 238 239 if (soc_feature(unit, soc_feature_l3) && 240 soc_property_get(unit, spn_L3_ENABLE, 1)) { 241 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_L3); 242 } 243 if (soc_feature(unit, soc_feature_ip_mcast)) { 244 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_IPMC); 245 } 246 247 #ifdef BCM_MPLS_SUPPORT 248 if (soc_feature(unit, soc_feature_mpls)) { 249 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MPLS); 250 } 251 #endif 252 if (soc_feature(unit, soc_feature_mim)) { 253 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MIM); 254 } 255 if (soc_feature(unit, soc_feature_wlan)) { 256 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_WLAN); 257 } 258 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_PROXY); 259 260 if (soc_feature(unit, soc_feature_subport) || 261 soc_feature(unit, soc_feature_linkphy_coe) || 262 soc_feature(unit, soc_feature_subtag_coe) || 263 soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 264 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_SUBPORT); 265 } 266 if (soc_feature(unit, soc_feature_trill)) { 267 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_TRILL); 268 } 269 if (soc_feature(unit, soc_feature_niv)) { 270 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_NIV); 271 } 272 if (soc_feature(unit, soc_feature_l2gre)) { 273 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_L2GRE); 274 } 275 if (soc_feature(unit, soc_feature_vxlan)) { 276 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_VXLAN); 277 } 278 if (soc_feature(unit, soc_feature_port_extension)) { 279 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_EXTENDER); 280 } 281 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_MULTICAST); 282 #endif 283 if (soc_feature(unit, soc_feature_qos_profile)) { 284 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_QOS); 285 } 286 if (soc_feature(unit, soc_feature_oam) || 287 soc_feature(unit, soc_feature_fp_based_oam)) { 288 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_OAM); 289 } 290 #ifdef INCLUDE_PTP 291 if (soc_feature(unit, soc_feature_ptp)) { 292 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_PTP); 293 } 294 #endif 295 #ifdef INCLUDE_BFD 296 if (soc_feature(unit, soc_feature_bfd)) { 297 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_BFD); 298 } 299 #endif 300 if (soc_feature(unit, soc_feature_fcoe)) { 301 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_FCOE); 302 } 303 } 304 305 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_LINKSCAN); 306 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_STAT); 307 #ifdef INCLUDE_KNET 308 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_KNET); 309 #endif 310 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_TX); 311 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_RX); 312 #ifdef INCLUDE_REGEX 313 if (soc_feature(unit, soc_feature_regex)) { 314 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_REGEX); 315 } 316 #endif 317 if (soc_feature(unit, soc_feature_time_support)) { 318 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_TIME); 319 } 320 /* Service meter */ 321 if (soc_feature(unit, soc_feature_global_meter)) { 322 SHR_BITSET(dev_info->init_cond, SHR_BPROF_BCM_GLB_METER); 323 } 324 if (soc_property_get(unit, "skip_ipmc_init", 0)) { 325 SHR_BITCLR(dev_info->init_cond, SHR_BPROF_BCM_IPMC); 326 } 327 328 if (soc_property_get(unit, "skip_mpls_init", 0)) { 329 SHR_BITCLR(dev_info->init_cond, SHR_BPROF_BCM_MPLS); 330 } 331 332 if (soc_property_get(unit, "skip_mim_init", 0)) { 333 SHR_BITCLR(dev_info->init_cond, SHR_BPROF_BCM_MIM); 334 } 335 if (soc_property_get(unit, "skip_trunk_init", 0)) { 336 SHR_BITCLR(dev_info->init_cond, SHR_BPROF_BCM_TRUNK); 337 } 338 if (soc_property_get(unit, "skip_mirror_init", 0)) { 339 SHR_BITCLR(dev_info->init_cond, SHR_BPROF_BCM_MIRROR); 340 } 341 return; 342 343 } 344 345 346 /* 347 * Function: 348 * bcmi_td3_port_dev_info_init 349 * Purpose: 350 * Initialize the device info. 351 * Parameters: 352 * unit - (IN) Unit number. 353 * Returns: 354 * BCM_E_xxx 355 * Notes: 356 */ 357 int 358 bcmi_td3_port_dev_info_init(int unit) 359 { 360 bcmi_xgs5_dev_info_t *dev_info; 361 soc_info_t *si = &SOC_INFO(unit); 362 uint32 pipe_lr_bw; 363 int alloc_size; 364 int pipe, phy_port, blk, bindex; 365 int i, cntmaxsize; 366 367 /* Free bcmi_td3_dev_info[unit] if already allocated */ 368 if (bcmi_td3_dev_info[unit]) { 369 sal_free(bcmi_td3_dev_info[unit]); 370 bcmi_td3_dev_info[unit] = NULL; 371 } 372 373 /* Allocate memory for main SW data structure */ 374 alloc_size = sizeof(bcmi_xgs5_dev_info_t) + 375 (sizeof(bcmi_xgs5_phy_port_t) * TRIDENT3_PHY_PORTS_PER_DEV); 376 dev_info = sal_alloc(alloc_size, "bcmi_td3_dev_info"); 377 if (dev_info == NULL) { 378 return BCM_E_MEMORY; 379 } 380 sal_memset(dev_info, 0, alloc_size); 381 dev_info->phy_port_info = (bcmi_xgs5_phy_port_t *)&dev_info[1]; 382 bcmi_td3_dev_info[unit] = dev_info; 383 384 /* Clear data structure */ 385 386 /* Device information init */ 387 dev_info = bcmi_td3_dev_info[unit]; 388 dev_info->num_pipe = _TD3_PIPES_PER_DEV; 389 dev_info->num_tsc = _TD3_PBLKS_PER_DEV(unit); 390 dev_info->phy_ports_max = TRIDENT3_PHY_PORTS_PER_DEV; 391 dev_info->mmu_lossless = 0; 392 dev_info->asf_prof_default = _SOC_ASF_MEM_PROFILE_SIMILAR; 393 dev_info->pipe_bound = 1; 394 for (pipe = 0; pipe < _TD3_PIPES_PER_DEV; pipe++) { 395 /* First logical port in pipe */ 396 dev_info->pipe_log_port_base[pipe] = TRIDENT3_PHY_PORTS_PER_PIPE * pipe; 397 398 /* First physical port in pipe */ 399 dev_info->pipe_phy_port_base[pipe] = TRIDENT3_GPHY_PORTS_PER_PIPE * pipe + 400 (pipe ? 1 : 0); 401 402 dev_info->ports_pipe_max[pipe] = TRIDENT3_PHY_PORTS_PER_PIPE; 403 } 404 /* 10G is the min speed in TDM calendar program. 405 * TDM eventually sets minimum speed to 10G in TDM calendar. 406 */ 407 dev_info->tdm_speed_min = SPEED_1G; 408 409 /* 10G is the min speed in TDM calculations */ 410 dev_info->tdm_pipe_lr_bw_limit_checker_speed_min = SPEED_10G; 411 412 cntmaxsize = soc_property_get(unit, spn_BCM_STAT_JUMBO, 1518); 413 if (cntmaxsize > si->max_mtu) { 414 cntmaxsize = si->max_mtu; 415 } 416 dev_info->cntmaxsize_xl = cntmaxsize; 417 dev_info->cntmaxsize_cl = cntmaxsize; 418 419 dev_info->restriction_mask = BCMI_XGS5_FLEXPORT_RESTRICTION_PIPE_BANDWIDTH | 420 BCMI_XGS5_FLEXPORT_RESTRICTION_MIX_LR_OVS_DEV | 421 BCMI_XGS5_FLEXPORT_RESTRICTION_SPEED_CLASS | 422 BCMI_XGS5_FLEXPORT_RESTRICTION_PM_OVS_MIX_SISTER | 423 BCMI_XGS5_FLEXPORT_RESTRICTION_PM_MIX_ETH_HIGIG | 424 BCMI_XGS5_FLEXPORT_RESTRICTION_PM_LR_MIX_SISTER | 425 BCMI_XGS5_FLEXPORT_RESTRICTION_PM_HG_MIX_SPEED | 426 BCMI_XGS5_FLEXPORT_RESTRICTION_PM_SINGLE_PLL; 427 428 dev_info->encap_mask = BCM_PA_ENCAP_IEEE | BCM_PA_ENCAP_HIGIG2; 429 430 /* 431 * Restriction 13:No port configurations with more than 4 port speed 432 * classes are supported in LR. 433 * Restriction 15:All port configurations with 1-3 port speed classes are 434 * supported, except configurations that contain both 20G 435 * and 25G port speeds. 436 * OS speed class exception: 5 speed classes (10/25/40/50/100) are supported 437 * in oversub mode only. 438 */ 439 dev_info->speed_class.speed_class_num = si->oversub_mode ? 440 _TD3_TDM_OS_SPEED_CLASS_MAX : _TD3_TDM_LR_SPEED_CLASS_MAX; 441 442 dev_info->speed_class.no_mix_speed_mask = SOC_PA_SPEED_20GB 443 | SOC_PA_SPEED_25GB; 444 445 dev_info->port_ratio_mask = BCMI_XGS5_PORT_RATIO_SINGLE | 446 BCMI_XGS5_PORT_RATIO_DUAL_1_1 | 447 BCMI_XGS5_PORT_RATIO_DUAL_2_1 | 448 BCMI_XGS5_PORT_RATIO_DUAL_1_2 | 449 BCMI_XGS5_PORT_RATIO_TRI_023_2_1_1 | 450 BCMI_XGS5_PORT_RATIO_TRI_023_4_1_1 | 451 BCMI_XGS5_PORT_RATIO_TRI_012_1_1_2 | 452 BCMI_XGS5_PORT_RATIO_TRI_012_1_1_4 | 453 BCMI_XGS5_PORT_RATIO_QUAD; 454 455 /* Set max line rate bandwidth per pipeline */ 456 BCM_IF_ERROR_RETURN 457 (soc_td3_max_lr_bandwidth(unit, &pipe_lr_bw)); 458 dev_info->pipe_lr_bw = pipe_lr_bw * 1000; 459 460 /* Set valid speeds for 1/2/4 Lanes */ 461 BCM_IF_ERROR_RETURN 462 (soc_td3_support_speeds(unit, 1, &dev_info->speed_valid[1])); 463 BCM_IF_ERROR_RETURN 464 (soc_td3_support_speeds(unit, 2, &dev_info->speed_valid[2])); 465 BCM_IF_ERROR_RETURN 466 (soc_td3_support_speeds(unit, 4, &dev_info->speed_valid[4])); 467 468 /* 469 * Set physical port info: 470 * - Port lane capability 471 * - Port is enabled for flexport 472 * - pipe 473 */ 474 for (phy_port = 0; phy_port < TRIDENT3_PHY_PORTS_PER_DEV; phy_port++) { 475 /* Set information to invalid */ 476 dev_info->phy_port_info[phy_port].pipe = -1; 477 } 478 479 /* Flexport is not supported for CPU/LB/MNG ports, so skip CPU/LB/MNG */ 480 for (phy_port = 1; phy_port <= TRIDENT3_PHY_PORTS_PER_DEV; phy_port++) { 481 /* Check for end of port list */ 482 if (SOC_PORT_BLOCK(unit, phy_port) < 0 && 483 SOC_PORT_BINDEX(unit, phy_port) < 0) { 484 break; 485 } 486 /* Set pipe information */ 487 dev_info->phy_port_info[phy_port].pipe = 488 (phy_port - 1) / TRIDENT3_GPHY_PORTS_PER_PIPE; 489 490 for (i = 0; i < SOC_DRIVER(unit)->port_num_blktype; i++) { 491 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, i); 492 bindex = SOC_PORT_IDX_BINDEX(unit, phy_port, i); 493 494 if ((blk < 0) || (bindex < 0)) { 495 continue; 496 } 497 498 if (SOC_BLOCK_TYPE(unit, blk) == SOC_BLK_CLPORT) { 499 /* Set port lane capabilites */ 500 dev_info->phy_port_info[phy_port].lanes_valid = 501 BCMI_XGS5_PORT_LANES_1; 502 if (bindex == 0) { 503 dev_info->phy_port_info[phy_port].lanes_valid |= 504 BCMI_XGS5_PORT_LANES_2 | BCMI_XGS5_PORT_LANES_4; 505 } else if (bindex == 2) { 506 dev_info->phy_port_info[phy_port].lanes_valid |= 507 BCMI_XGS5_PORT_LANES_2; 508 } 509 510 if (SHR_BITGET(si->flexible_pm_bitmap,blk)) { 511 dev_info->phy_port_info[phy_port].flex = 1; 512 } 513 } 514 } /* for port_num_blktype */ 515 dev_info->phy_port_info[phy_port].max_lane_speed = 27000; 516 } 517 518 /* For TD3 encap type change (i.e calendar type from Ethernet type to 519 * HiGig type, or vice versa) should also be detected as a 520 * flexport trigger condition 521 */ 522 dev_info->encap_change_flex = 1; 523 524 /* Init condition */ 525 _bcmi_td3_init_condition_set(unit, dev_info); 526 527 return BCM_E_NONE; 528 } 529 530 531 532 /* 533 * Function: 534 * bcmi_td3_port_fn_drv_init 535 * Purpose: 536 * Initialize the Port function driver. 537 * Parameters: 538 * unit - (IN) Unit number. 539 * Returns: 540 * BCM_E_xxx 541 * Notes: 542 */ 543 int 544 bcmi_td3_port_fn_drv_init(int unit) 545 { 546 int phase_pos, present; 547 548 BCM_IF_ERROR_RETURN 549 (bcmi_td3_port_dev_info_init(unit)); 550 551 /* BCMI Driver init */ 552 bcmi_td3_port_drv.port_calls = &bcmi_td3_port_calls; 553 bcmi_td3_port_drv.dev_info[unit] = bcmi_td3_dev_info[unit]; 554 555 556 sal_memcpy(bcmi_td3_port_drv.port_calls->port_attach_exec, 557 td3_port_attach_exec, 558 sizeof(bcmi_td3_port_drv.port_calls->port_attach_exec)); 559 560 sal_memcpy(bcmi_td3_port_drv.port_calls->port_detach_exec, 561 td3_port_detach_exec, 562 sizeof(bcmi_td3_port_drv.port_calls->port_detach_exec)); 563 564 /* Initialize Common XGS5 Port module */ 565 BCM_IF_ERROR_RETURN 566 (bcmi_xgs5_port_fn_drv_init(unit, 567 &bcm_td3_port_drv, 568 &bcmi_td3_port_drv, 569 NULL)); 570 571 BCM_IF_ERROR_RETURN(soc_check_flex_phase(unit, td3_flexport_phases, 572 soc_trident3_flex_top_port_down, 573 &present)); 574 /* Detach port enable/disable in DV Flexport */ 575 if (present) { 576 BCM_IF_ERROR_RETURN 577 (soc_detach_flex_phase(unit, td3_flexport_phases, 578 soc_trident3_flex_top_port_down, 579 &phase_pos)); 580 } 581 BCM_IF_ERROR_RETURN(soc_check_flex_phase(unit, td3_flexport_phases, 582 soc_trident3_flex_top_port_up, 583 &present)); 584 if (present) { 585 BCM_IF_ERROR_RETURN 586 (soc_detach_flex_phase(unit, td3_flexport_phases, 587 soc_trident3_flex_top_port_up, 588 &phase_pos)); 589 } 590 return BCM_E_NONE; 591 } 592 593 /* 594 * Function: 595 * bcmi_td3_port_soc_resource_init 596 * Purpose: 597 * Initialize SOC Port Structure. 598 * This includes: 599 * Copy Port information from BCM port resource array. 600 * Set correct pipe, MMU port, IDB port for new logical port. 601 * Parameters: 602 * unit - (IN) Unit number. 603 * nport - (IN) Number of elements in array resource. 604 * resource - (IN) BCM Port resource configuration array. 605 * soc_resource - (OUT) SOC Port resource array. 606 * Returns: 607 * BCM_E_xxx 608 * Notes: 609 */ 610 int 611 bcmi_td3_port_soc_resource_init(int unit, int nport, 612 bcm_port_resource_t *resource, 613 soc_port_resource_t *soc_resource) 614 { 615 int i; 616 int logic_port, idb_port, mmu_port, pipe; 617 soc_info_t *si = &SOC_INFO(unit); 618 619 /* 620 * SOC Port Structure initialization 621 */ 622 623 /* Clear data structure */ 624 sal_memset(soc_resource, 0, sizeof(soc_port_resource_t) * nport); 625 626 /* Copy initial information */ 627 for (i = 0; i < nport; i++) { 628 logic_port = resource[i].port; 629 630 pipe = logic_port / TRIDENT3_PHY_PORTS_PER_PIPE; 631 idb_port = (logic_port % TRIDENT3_PHY_PORTS_PER_PIPE) - 1; 632 mmu_port = (pipe << 7) | idb_port; 633 634 soc_resource[i].flags = resource[i].flags; 635 soc_resource[i].logical_port = logic_port; 636 soc_resource[i].physical_port = resource[i].physical_port; 637 soc_resource[i].speed = resource[i].speed; 638 soc_resource[i].num_lanes = resource[i].lanes; 639 soc_resource[i].encap = resource[i].encap; 640 soc_resource[i].pipe = pipe; 641 soc_resource[i].idb_port = idb_port; 642 soc_resource[i].mmu_port = mmu_port; 643 /* TD3 does NOT support port configuration with a mix of line-rate ports 644 * and oversubscribed ports. */ 645 soc_resource[i].oversub = SOC_PBMP_IS_NULL(si->oversub_pbm) ? 0 : 1; 646 647 if (resource[i].speed >= 40000) { 648 soc_resource[i].hsp = 1; 649 } 650 } 651 652 return BCM_E_NONE; 653 } 654 655 /* Function: 656 * bcmi_td3_port_resource_validate 657 * Purpose: 658 * Validate that the given FlexPort operations is valid. 659 * Parameters: 660 * unit - (IN) Unit number. 661 * port_schedule_state - (OUT) Port resource state. 662 * Returns: 663 * BCM_E_xxx 664 * Notes: 665 */ 666 int 667 bcmi_td3_port_resource_validate(int unit, 668 soc_port_schedule_state_t *port_schedule_state) 669 { 670 soc_port_resource_t *pr; 671 int nport = port_schedule_state->nport; 672 int i, pmap_err = 0; 673 int port; /* Logical port associated to physical port */ 674 int phy_port; /* Physical port associated logical port */ 675 676 /* Allow only correct logical port to physical port association. */ 677 for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) { 678 if (pr->physical_port == -1) { 679 continue; 680 } 681 port = pr->logical_port; 682 phy_port = pr->physical_port; 683 if ((port >= 0) && (port <= 64)) { 684 if (port != phy_port) { 685 pmap_err = 1; 686 break; 687 } 688 } else if((port == 65) && (phy_port != 130)) { 689 pmap_err = 1; 690 break; 691 } else if ((port == 66) && (phy_port != 129)) { 692 pmap_err = 1; 693 break; 694 } else if((port >= 67) && (port <= 130)) { 695 if (port != phy_port + 2) { 696 pmap_err = 1; 697 break; 698 } 699 } else if((port == 131) && (phy_port != 131)) { 700 pmap_err = 1; 701 break; 702 } 703 } 704 if (pmap_err) { 705 LOG_CLI((BSL_META_U(unit, 706 "Port %d: Invalid logical port to physical port mapping.\n"), 707 port)); 708 return BCM_E_PORT; 709 } 710 return BCM_E_NONE; 711 } 712 713 /* 714 * Function: 715 * bcmi_td3_pre_flexport_tdm 716 * Purpose: 717 * Pass TDM information pre FlexPort to DV FlexPort API 718 * Parameters: 719 * unit - (IN) Unit number. 720 * port_schedule_state - (OUT) Port resource state. 721 * Returns: 722 * BCM_E_xxx 723 * Notes: 724 */ 725 int 726 bcmi_td3_pre_flexport_tdm(int unit, 727 soc_port_schedule_state_t *port_schedule_state) 728 { 729 port_schedule_state->is_flexport = 1; 730 731 BCM_IF_ERROR_RETURN 732 (soc_td3_port_schedule_tdm_init(unit, port_schedule_state)); 733 return BCM_E_NONE; 734 } 735 736 /* 737 * Function: 738 * bcmi_td3_post_flexport_tdm 739 * Purpose: 740 * Update TDM information in SOC with post FlexPort TDM state return from 741 * DV FlexPort API. 742 * Parameters: 743 * unit - (IN) Unit number. 744 * port_schedule_state - (IN) Port resource state. 745 * Returns: 746 * BCM_E_xxx 747 * Notes: 748 */ 749 int 750 bcmi_td3_post_flexport_tdm(int unit, 751 soc_port_schedule_state_t *port_schedule_state) 752 { 753 BCM_IF_ERROR_RETURN 754 (soc_td3_soc_tdm_update(unit, port_schedule_state)); 755 return BCM_E_NONE; 756 } 757 758 /* 759 * Function: 760 * bcmi_td3_clport_update 761 * Purpose: 762 * Update CLPORT. 763 * Parameters: 764 * unit - (IN) Unit number. 765 * port_schedule_state - (IN) Port resource state. 766 * Returns: 767 * BCM_E_xxx 768 * Notes: 769 */ 770 int 771 bcmi_td3_clport_update(int unit, 772 soc_port_schedule_state_t *port_schedule_state) 773 { 774 soc_info_t *si = &SOC_INFO(unit); 775 soc_port_resource_t *pr; 776 int i, nport; 777 int phy_port, logic_port, phy_port_base; 778 int blk; 779 int clport, lane, mode; 780 SHR_BITDCL pm_bmp[_SHR_BITDCLSIZE(SOC_MAX_NUM_BLKS)]; 781 soc_port_map_type_t *in_port_map; 782 uint32 rval; 783 static soc_field_t port_fields[TRIDENT3_PORTS_PER_PBLK] = { 784 PORT0f, PORT1f, PORT2f, PORT3f 785 }; 786 static const int mode_encodings[SOC_TD3_PORT_RATIO_COUNT] = { 787 4, 3, 3, 3, 2, 2, 1, 1, 0 788 }; 789 790 SHR_BITCLR_RANGE(pm_bmp, 0, SOC_MAX_NUM_BLKS); 791 792 nport = port_schedule_state->nport; 793 in_port_map = &port_schedule_state->in_port_map; 794 795 for (i = 0, pr = port_schedule_state->resource; i < nport; i++, pr++) { 796 if (!(pr->op & ~(BCMI_XGS5_PORT_RESOURCE_OP_SPEED| 797 BCMI_XGS5_PORT_RESOURCE_OP_ENCAP))) { 798 continue; 799 } 800 801 logic_port = pr->logical_port; 802 phy_port = pr->physical_port == -1 ? 803 in_port_map->port_l2p_mapping[logic_port] : 804 pr->physical_port; 805 blk = SOC_PORT_IDX_BLOCK(unit, phy_port, 0); 806 SHR_BITSET(pm_bmp, blk); 807 } 808 809 SHR_BIT_ITER(pm_bmp, SOC_MAX_NUM_BLKS, blk) { 810 if (!SOC_INFO(unit).block_valid[blk]) { 811 continue; 812 } 813 logic_port = SOC_BLOCK_PORT(unit, blk); 814 clport = SOC_BLOCK_NUMBER(unit, blk); 815 phy_port_base = PORT_BLOCK_BASE_PORT(logic_port); 816 817 /* Assert CLPORT soft reset */ 818 rval = 0; 819 for (lane = 0; lane < TRIDENT3_PORTS_PER_PBLK; lane++) { 820 if (si->port_p2l_mapping[phy_port_base + lane] != -1) { 821 soc_reg_field_set(unit, CLPORT_SOFT_RESETr, &rval, 822 port_fields[lane], 1); 823 } 824 } 825 SOC_IF_ERROR_RETURN(WRITE_CLPORT_SOFT_RESETr(unit, logic_port, rval)); 826 827 /* Set port mode */ 828 soc_td3_tdm_get_port_ratio(unit, port_schedule_state, clport, 829 &mode, 830 0); 831 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, CLPORT_MODE_REGr, 832 logic_port, 0, &rval)); 833 soc_reg_field_set(unit, CLPORT_MODE_REGr, &rval, XPORT0_CORE_PORT_MODEf, 834 mode_encodings[mode]); 835 soc_reg_field_set(unit, CLPORT_MODE_REGr, &rval, XPORT0_PHY_PORT_MODEf, 836 mode_encodings[mode]); 837 SOC_IF_ERROR_RETURN(WRITE_CLPORT_MODE_REGr(unit, logic_port, rval)); 838 839 /* De-assert XLPORT soft reset */ 840 SOC_IF_ERROR_RETURN(WRITE_CLPORT_SOFT_RESETr(unit, logic_port, 0)); 841 } 842 return BCM_E_NONE; 843 } 844 845 int 846 bcmi_td3_port_attach_mmu(int unit, int port) 847 { 848 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port) || 849 IS_MANAGEMENT_PORT(unit, port)) { 850 return BCM_E_PARAM; 851 } 852 853 /* Assign the base queues and number of queues for the specified port. */ 854 BCM_IF_ERROR_RETURN 855 (soc_trident3_num_cosq_init_port(unit, port)); 856 857 /* Enable enqueing packets to the port */ 858 SOC_IF_ERROR_RETURN( 859 soc_td3_port_mmu_tx_enable_set(unit, port, 1)); 860 SOC_IF_ERROR_RETURN( 861 soc_td3_port_mmu_rx_enable_set(unit, port, 1)); 862 863 /* Reconfigure THDI, THDO settings */ 864 BCM_IF_ERROR_RETURN 865 (soc_td3_mmu_config_init_port(unit, port)); 866 867 return BCM_E_NONE; 868 } 869 870 int 871 bcmi_td3_port_attach_stack(int unit, int port) 872 { 873 modport_map_subport_entry_t subport_entry; 874 modport_map_subport_mirror_entry_t subport_m_entry; 875 876 /* Configure logical subport numbers */ 877 sal_memset(&subport_entry, 0, sizeof(subport_entry)); 878 soc_MODPORT_MAP_SUBPORTm_field32_set(unit, &subport_entry, ENABLEf, 1); 879 soc_MODPORT_MAP_SUBPORTm_field32_set(unit, &subport_entry, DESTf, port); 880 SOC_IF_ERROR_RETURN 881 (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ALL, port, &subport_entry)); 882 883 /* Configure logical subport mirror numbers */ 884 sal_memset(&subport_m_entry, 0, sizeof(subport_m_entry)); 885 soc_MODPORT_MAP_SUBPORT_M0m_field32_set(unit, &subport_m_entry, ENABLEf, 1); 886 soc_MODPORT_MAP_SUBPORT_M0m_field32_set(unit, 887 &subport_m_entry, DESTf, port); 888 SOC_IF_ERROR_RETURN 889 (WRITE_MODPORT_MAP_SUBPORT_MIRRORm( 890 unit, MEM_BLOCK_ALL, port, &subport_m_entry)); 891 892 BCM_IF_ERROR_RETURN 893 (bcmi_xgs5_port_attach_stack(unit, port)); 894 895 return BCM_E_NONE; 896 } 897 898 int 899 bcmi_td3_port_detach_stack(int unit, int port) 900 { 901 modport_map_subport_entry_t subport_entry; 902 modport_map_subport_mirror_entry_t subport_m_entry; 903 904 /* Clear logical subport numbers */ 905 sal_memset(&subport_entry, 0, sizeof(subport_entry)); 906 SOC_IF_ERROR_RETURN 907 (WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ALL, port, &subport_entry)); 908 909 /* Clear logical subport mirror numbers */ 910 sal_memset(&subport_m_entry, 0, sizeof(subport_m_entry)); 911 SOC_IF_ERROR_RETURN 912 (WRITE_MODPORT_MAP_SUBPORT_MIRRORm( 913 unit, MEM_BLOCK_ALL, port, &subport_m_entry)); 914 915 BCM_IF_ERROR_RETURN 916 (bcmi_xgs5_port_detach_stack(unit, port)); 917 918 return BCM_E_NONE; 919 } 920 921 /* 922 * Function: 923 * bcmi_td3_port_attach_l3 924 * Purpose: 925 * Enable IPv4, IPv6 on port, add to default vfi membership profile 926 * Parameters: 927 * unit - (IN) Unit number. 928 * port - (IN) Logical port. 929 * Returns: 930 * SOC_E_XXX 931 */ 932 int 933 bcmi_td3_port_attach_l3(int unit, bcm_port_t port) 934 { 935 #ifdef INCLUDE_L3 936 int rv = BCM_E_NONE; 937 /* L3 */ 938 if (soc_feature(unit, soc_feature_l3) && 939 soc_property_get(unit, spn_L3_ENABLE, 1) && 940 !IS_ST_PORT(unit, port)) { 941 942 BCM_IF_ERROR_RETURN 943 (bcm_esw_port_control_set(unit, port, bcmPortControlIP4, 1)); 944 BCM_IF_ERROR_RETURN 945 (bcm_esw_port_control_set(unit, port, bcmPortControlIP6, 1)); 946 } 947 if (soc_feature(unit, soc_feature_l3) && 948 soc_property_get(unit, spn_L3_ENABLE, 1)) { 949 /* VFI */ 950 rv = _bcm_td2p_vfi_membership_port_attach(unit, port); 951 if (BCM_FAILURE(rv)) { 952 LOG_ERROR(BSL_LS_BCM_PORT, 953 (BSL_META_U(unit, 954 "Unable to add port to default VFI membership " 955 "unit=%d port=%d rv=%d\n"), 956 unit, port, rv)); 957 return rv; 958 } 959 } 960 #endif /* INCLUDE_L3 */ 961 return BCM_E_NONE; 962 } 963 964 /* 965 * Function: 966 * bcmi_td3_port_detach_l3 967 * Purpose: 968 * Disable IPv4, IPv6 on port, 969 * remove port from default vfi membership profile 970 * Parameters: 971 * unit - (IN) Unit number. 972 * port - (IN) Logical port. 973 * Returns: 974 * SOC_E_XXX 975 */ 976 int 977 bcmi_td3_port_detach_l3(int unit, bcm_port_t port) 978 { 979 #ifdef INCLUDE_L3 980 int rv = BCM_E_NONE; 981 /* L3 */ 982 if (soc_feature(unit, soc_feature_l3) && 983 soc_property_get(unit, spn_L3_ENABLE, 1) && 984 !IS_ST_PORT(unit, port)) { 985 986 BCM_IF_ERROR_RETURN 987 (bcm_esw_port_control_set(unit, port, bcmPortControlIP4, 0)); 988 BCM_IF_ERROR_RETURN 989 (bcm_esw_port_control_set(unit, port, bcmPortControlIP6, 0)); 990 } 991 if (soc_feature(unit, soc_feature_l3) && 992 soc_property_get(unit, spn_L3_ENABLE, 1)) { 993 /* VFI */ 994 rv = _bcm_td2p_vfi_membership_port_detach(unit, port); 995 if (BCM_FAILURE(rv)) { 996 LOG_ERROR(BSL_LS_BCM_PORT, 997 (BSL_META_U(unit, 998 "Unable to clear port in default VFI membership " 999 "unit=%d port=%d rv=%d\n"), 1000 unit, port, rv)); 1001 return rv; 1002 } 1003 } 1004 #endif /* INCLUDE_L3 */ 1005 return BCM_E_NONE; 1006 } 1007 1008 /* 1009 * Function: 1010 * bcmi_td3_port_detach_asf 1011 * Purpose: 1012 * Update ASF when port deleted during Flexport operations. 1013 * Parameters: 1014 * unit - (IN) Unit number. 1015 * port - (IN) Logical port number. 1016 * Returns: 1017 * BCM_E_xxx 1018 * Notes: 1019 */ 1020 int 1021 bcmi_td3_port_detach_asf(int unit, bcm_port_t port) 1022 { 1023 BCM_IF_ERROR_RETURN 1024 (soc_td3_port_asf_detach(unit, port)); 1025 1026 return BCM_E_NONE; 1027 } 1028 1029 /* 1030 * Function: 1031 * bcmi_td3_port_enable 1032 * Purpose: 1033 * Enable port. 1034 * Parameters: 1035 * unit - (IN) Unit number. 1036 * port_schedule_state - (IN) Port resource state. 1037 * Returns: 1038 * BCM_E_xxx 1039 * Notes: 1040 * This function should only be called with PORTMOD enabled 1041 */ 1042 int 1043 bcmi_td3_port_enable(int unit, 1044 soc_port_schedule_state_t *port_schedule_state) 1045 { 1046 int i, nport, rv = BCM_E_NONE; 1047 bcm_port_t *port; 1048 1049 nport = port_schedule_state->nport; 1050 1051 port = sal_alloc(nport * sizeof(bcm_port_t), "port array"); 1052 if (port == NULL) { 1053 return BCM_E_MEMORY; 1054 } 1055 for (i = 0; i < nport; i++) { 1056 port[i] = port_schedule_state->resource[i].logical_port; 1057 } 1058 1059 if (BCM_SUCCESS(rv) && (!(SAL_BOOT_XGSSIM || SAL_BOOT_BCMSIM))) { 1060 rv = soc_trident3_flex_mmu_port_up(unit, port_schedule_state); 1061 } 1062 if (BCM_SUCCESS(rv)) { 1063 rv = soc_trident3_flex_ep_port_up(unit, port_schedule_state); 1064 } 1065 if (BCM_SUCCESS(rv)) { 1066 rv = soc_trident3_flex_idb_port_up(unit, port_schedule_state); 1067 } 1068 if (BCM_SUCCESS(rv)) { 1069 rv = bcmi_esw_portctrl_mac_up(unit, nport, port); 1070 } 1071 sal_free(port); 1072 return rv; 1073 } 1074 1075 /* 1076 * Function: 1077 * bcmi_td3_port_disable 1078 * Purpose: 1079 * Disable port. 1080 * Parameters: 1081 * unit - (IN) Unit number. 1082 * port_schedule_state - (IN) Port resource state. 1083 * Returns: 1084 * BCM_E_xxx 1085 * Notes: 1086 * This function should only be called with PORTMOD enabled 1087 */ 1088 int 1089 bcmi_td3_port_disable(int unit, 1090 soc_port_schedule_state_t *port_schedule_state) 1091 { 1092 int i, nport, rv = BCM_E_NONE; 1093 bcm_port_t *port; 1094 1095 nport = port_schedule_state->nport; 1096 1097 port = sal_alloc(nport * sizeof(bcm_port_t), "port array"); 1098 if (port == NULL) { 1099 return BCM_E_MEMORY; 1100 } 1101 for (i = 0; i < nport; i++) { 1102 port[i] = port_schedule_state->resource[i].logical_port; 1103 } 1104 rv = bcmi_esw_portctrl_mac_rx_down(unit, nport, port); 1105 if (BCM_SUCCESS(rv)) { 1106 rv = soc_trident3_flex_idb_port_down(unit, port_schedule_state); 1107 } 1108 if (BCM_SUCCESS(rv) && (!(SAL_BOOT_XGSSIM || SAL_BOOT_BCMSIM))) { 1109 rv = soc_trident3_flex_mmu_port_down(unit, port_schedule_state); 1110 } 1111 if (BCM_SUCCESS(rv)) { 1112 rv = soc_trident3_flex_ep_port_down(unit, port_schedule_state); 1113 } 1114 if (BCM_SUCCESS(rv)) { 1115 rv = bcmi_esw_portctrl_mac_tx_down(unit, nport, port); 1116 } 1117 1118 sal_free(port); 1119 1120 return rv; 1121 } 1122 1123 /* 1124 * Function: 1125 * bcmi_td3_port_speed_1g_update 1126 * Purpose: 1127 * Special operations for 1G speed. 1128 * Parameters: 1129 * unit - (IN) Unit number. 1130 * port - (IN) Logical port number. 1131 * speed - (IN) port speed (Mbps). 1132 * Returns: 1133 * BCM_E_xxx 1134 * Notes: 1135 * In the PRD, nothing below 10G is officially supported. 1136 * We enable customers with limited 1G support in Trident 3. 1137 * 1G is not a support speed class in TDM calculation, thus treated same as 1138 * 10G in TDM calculation. 1G port does NOT support cut through, flow 1139 * control. 1140 */ 1141 int 1142 bcmi_td3_port_speed_1g_update(int unit, bcm_port_t port, int speed) 1143 { 1144 if (speed != SPEED_1G) { 1145 return BCM_E_NONE; 1146 } 1147 1148 /* Update port speed info in soc_info */ 1149 SOC_INFO(unit).port_init_speed[port] = speed; 1150 1151 /* Set asf mode to SAF */ 1152 if (soc_feature(unit, soc_feature_asf_multimode)) { 1153 BCM_IF_ERROR_RETURN 1154 (soc_td3_port_asf_mode_set(unit, port, speed, 1155 _SOC_TD3_ASF_MODE_SAF)); 1156 } 1157 1158 /* Disable Pause */ 1159 BCM_IF_ERROR_RETURN 1160 (bcm_esw_port_pause_set(unit, port, 0, 0)); 1161 1162 /* Disable PFC */ 1163 if (soc_feature(unit, soc_feature_priority_flow_control)) { 1164 BCM_IF_ERROR_RETURN 1165 (bcm_esw_port_control_set(unit, port, 1166 bcmPortControlPFCReceive, 0)); 1167 BCM_IF_ERROR_RETURN 1168 (bcm_esw_port_control_set(unit, port, 1169 bcmPortControlPFCTransmit, 0)); 1170 } 1171 1172 return BCM_E_NONE; 1173 } 1174 /* 1175 * Function: 1176 * bcmi_td3_speed_ability_get 1177 * Purpose: 1178 * Retrieve the local port abilities. 1179 * Parameters: 1180 * unit - Unit. 1181 * port - Logical port num. 1182 * mask - (OUT) Mask of BCM_PORT_ABILITY_ values indicating the 1183 * supported speeds of the port. 1184 * Returns: 1185 * BCM_E_NONE 1186 * BCM_E_XXX 1187 */ 1188 int 1189 bcmi_td3_speed_ability_get(int unit, bcm_port_t port, bcm_port_abil_t *mask) 1190 { 1191 if (IS_MANAGEMENT_PORT(unit, port)) { 1192 /* TD3 Port Rates for Management ports: 1193 * 10M 100M, 1G, 2.5G, 10G, HG[11G] */ 1194 *mask = BCM_PORT_ABILITY_10MB | BCM_PORT_ABILITY_100MB | 1195 BCM_PORT_ABILITY_1000MB | BCM_PORT_ABILITY_2500MB | 1196 BCM_PORT_ABILITY_10GB | BCM_PORT_ABILITY_11GB; 1197 } else { 1198 BCM_IF_ERROR_RETURN 1199 (soc_td3_support_speeds(unit, 1200 SOC_INFO(unit).port_num_lanes[port], 1201 mask)); 1202 } 1203 return BCM_E_NONE; 1204 } 1205 1206 int _bcm_td3_port_phb_map_tab1_default_entry_add(int unit, 1207 soc_profile_mem_t *prof) 1208 { 1209 phb_mapping_tbl_1_entry_t pri_map[_BCM_TD3_PHB_MAP_TAB1_ENTRIES_PER_PROFILE]; 1210 ing_untagged_phb_entry_t phb; 1211 int index, pkt_pri, cfi, base = 0; 1212 int phb_map_tab1_entry; 1213 void *entries[2]; 1214 1215 sal_memset(pri_map, 0, sizeof(phb_mapping_tbl_1_entry_t) * 1216 _BCM_TD3_PHB_MAP_TAB1_ENTRIES_PER_PROFILE); 1217 sal_memset(&phb, 0, sizeof(phb)); 1218 1219 for (cfi = 0; cfi <= 1; cfi++) { 1220 for (pkt_pri = 0; pkt_pri <= 7; pkt_pri++) { 1221 index = (pkt_pri << 1) | cfi; 1222 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map[index], 1223 INT_PRIf, pkt_pri); 1224 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &pri_map[index], 1225 CNGf, cfi); 1226 } 1227 } 1228 entries[0] = &pri_map; 1229 entries[1] = &phb; 1230 1231 #if defined(BCM_HELIX5_SUPPORT) 1232 if (SOC_IS_HELIX5(unit)) { 1233 phb_map_tab1_entry = _BCM_HX5_PHB_MAP_TAB1_ENTRIES_PER_PROFILE; 1234 } else 1235 #endif 1236 { 1237 phb_map_tab1_entry = _BCM_TD3_PHB_MAP_TAB1_ENTRIES_PER_PROFILE; 1238 } 1239 1240 BCM_IF_ERROR_RETURN 1241 (soc_profile_mem_add(unit, prof, entries, phb_map_tab1_entry, 1242 (uint32 *)&base)); 1243 if (base != soc_mem_index_min(unit, PHB_MAPPING_TBL_1m)) { 1244 return BCM_E_INTERNAL; 1245 } 1246 return BCM_E_NONE; 1247 } 1248 1249 /* 1250 * Function: 1251 * _bcm_td3_port_cfg_init 1252 * Purpose: 1253 * Initialize port configuration according to Initial System 1254 * Configuration (see init.c) 1255 * Parameters: 1256 * unit - (IN)StrataSwitch unit number. 1257 * port - (IN)Port number. 1258 * vlan_data - (IN)Initial VLAN data information 1259 * Returns: 1260 * BCM_E_XXX 1261 */ 1262 int 1263 _bcm_td3_port_cfg_init(int unit, bcm_port_t port, bcm_vlan_data_t *vlan_data) 1264 { 1265 soc_mem_t egr_port_mem = EGR_LPORT_PROFILEm; 1266 soc_field_t field; 1267 soc_field_t egr_port_field_ids[SOC_MAX_MEM_FIELD_WORDS]; 1268 uint32 egt_port_field_values[SOC_MAX_MEM_FIELD_WORDS]; 1269 int egr_port_field_count = 0; 1270 soc_field_t port_field_ids[SOC_MAX_MEM_FIELD_WORDS]; 1271 uint32 port_field_values[SOC_MAX_MEM_FIELD_WORDS]; 1272 int port_field_count = 0; 1273 1274 uint32 port_type; 1275 uint32 egr_port_type = 0; 1276 int dual_modid = 0; 1277 int key_type_value; 1278 int cpu_hg_index = -1; 1279 uint32 max_gid, gid; 1280 uint32 cancun_ver; 1281 1282 SOC_IF_ERROR_RETURN(soc_cancun_version_get(unit, &cancun_ver)); 1283 1284 if ((SOC_IS_TR_VL(unit)) && (NUM_MODID(unit) >= 2)) { 1285 dual_modid = 1; 1286 } 1287 1288 if (IS_CPU_PORT(unit,port)) { 1289 cpu_hg_index = SOC_INFO(unit).cpu_hg_index; 1290 port_type = 0; /* Same as Ethernet port */ 1291 egr_port_type = 1; /* CPU port needs to be HG port in EGR_PORT table */ 1292 } else if (IS_ST_PORT(unit, port)) { 1293 port_type = 1; 1294 egr_port_type = 1; 1295 } else if (IS_LB_PORT(unit, port)) { 1296 port_type = 2; 1297 egr_port_type = 2; 1298 } else { 1299 port_type = 0; 1300 } 1301 1302 /* EGR_LPORT_TABLE config init */ 1303 #ifdef BCM_SHADOW_SUPPORT 1304 /* EGR_PORT fields are Unsupported in shadow */ 1305 if (!SOC_IS_SHADOW(unit)) 1306 #endif 1307 { 1308 /* CPU port type is HG for CANCUN version >= B870.5.2.3 on TD3 */ 1309 if ((SOC_IS_TRIDENT3(unit)) && (cancun_ver <= SOC_CANCUN_VERSION_DEF_5_2_3)) { 1310 soc_mem_set_field_value_array(egr_port_field_ids, PORT_TYPEf, 1311 egt_port_field_values, port_type, 1312 egr_port_field_count); 1313 } else { 1314 soc_mem_set_field_value_array(egr_port_field_ids, PORT_TYPEf, 1315 egt_port_field_values, egr_port_type, 1316 egr_port_field_count); 1317 } 1318 soc_mem_set_field_value_array(egr_port_field_ids, EN_EFILTERf, 1319 egt_port_field_values, 1, 1320 egr_port_field_count); 1321 if (SOC_IS_TR_VL(unit)) { 1322 soc_mem_set_field_value_array(egr_port_field_ids, DUAL_MODID_ENABLEf, 1323 egt_port_field_values, dual_modid, 1324 egr_port_field_count); 1325 } 1326 1327 field = VT_PORT_GROUP_IDf; 1328 BCM_IF_ERROR_RETURN 1329 (_bcm_td3_egr_port_tab_conv(unit, &field, &egr_port_mem)); 1330 1331 max_gid = soc_mem_field_length(unit, egr_port_mem, field); 1332 if(max_gid > 31) { 1333 return BCM_E_INTERNAL; 1334 } 1335 max_gid = (1 << max_gid) - 1; 1336 gid = (port < max_gid) ? port : max_gid; 1337 soc_mem_set_field_value_array(egr_port_field_ids, field, 1338 egt_port_field_values, gid, 1339 egr_port_field_count); 1340 1341 if (soc_feature(unit, soc_feature_directed_mirror_only)) { 1342 soc_mem_set_field_value_array(egr_port_field_ids, EM_SRCMOD_CHANGEf, 1343 egt_port_field_values, 1, 1344 egr_port_field_count); 1345 } 1346 1347 _bcm_esw_egr_port_tab_multi_set(unit, port, egr_port_field_count, 1348 egr_port_field_ids, 1349 egt_port_field_values); 1350 1351 #if defined(CANCUN_SUPPORT) 1352 if (soc_feature(unit, soc_feature_cancun)) { 1353 /* initialize the Cancun tag profile entry setup 1354 * for VT_MISS_UNTAG action. Should be done in Cancun 1355 */ 1356 if (soc_cancun_cmh_check(unit, EGR_VLAN_CONTROL_1m, 1357 VT_MISS_UNTAGf) == SOC_E_NONE) { 1358 int rv = SOC_E_NONE; 1359 rv = soc_cancun_cmh_mem_set(unit, 1360 EGR_VLAN_CONTROL_1m, port, 1361 VT_MISS_UNTAGf, 1); 1362 if (BCM_FAILURE(rv) && rv != SOC_E_PARAM) { 1363 return rv; 1364 } 1365 } 1366 } 1367 #endif 1368 1369 /* Copy EGR port information to CPU Higig port if applied */ 1370 if (cpu_hg_index != -1 && 1371 soc_mem_index_max(unit, EGR_PORTm) == cpu_hg_index) { 1372 BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_multi_set(unit, cpu_hg_index, 1373 egr_port_field_count, egr_port_field_ids, 1374 egt_port_field_values)); 1375 } 1376 1377 } 1378 1379 /* PORT_TABLE config init */ 1380 soc_mem_set_field_value_array(port_field_ids, PORT_VIDf, 1381 port_field_values, vlan_data->vlan_tag, 1382 port_field_count); 1383 #if 0 1384 soc_mem_set_field_value_array(port_field_ids, OUTER_TPIDf, 1385 port_field_values, 0x8100, 1386 port_field_count); 1387 #endif 1388 soc_mem_set_field_value_array(port_field_ids, MAC_BASED_VID_ENABLEf, 1389 port_field_values, 1, 1390 port_field_count); 1391 soc_mem_set_field_value_array(port_field_ids, SUBNET_BASED_VID_ENABLEf, 1392 port_field_values, 1, 1393 port_field_count); 1394 #if 0 1395 soc_mem_set_field_value_array(port_field_ids, TRUST_INCOMING_VIDf, 1396 port_field_values, 1, 1397 port_field_count); 1398 #endif 1399 soc_mem_set_field_value_array(port_field_ids, PRI_MAPPINGf, 1400 port_field_values, 0xfac688, 1401 port_field_count); 1402 soc_mem_set_field_value_array(port_field_ids, CFI_0_MAPPINGf, 1403 port_field_values, 0, 1404 port_field_count); 1405 soc_mem_set_field_value_array(port_field_ids, CFI_1_MAPPINGf, 1406 port_field_values, 1, 1407 port_field_count); 1408 soc_mem_set_field_value_array(port_field_ids, IPRI_MAPPINGf, 1409 port_field_values, 0xfac688, 1410 port_field_count); 1411 soc_mem_set_field_value_array(port_field_ids, ICFI_0_MAPPINGf, 1412 port_field_values, 0, 1413 port_field_count); 1414 soc_mem_set_field_value_array(port_field_ids, ICFI_1_MAPPINGf, 1415 port_field_values, 1, 1416 port_field_count); 1417 soc_mem_set_field_value_array(port_field_ids, CML_FLAGS_NEWf, 1418 port_field_values, 0x8, 1419 port_field_count); 1420 soc_mem_set_field_value_array(port_field_ids, CML_FLAGS_MOVEf, 1421 port_field_values, 0x8, 1422 port_field_count); 1423 BCM_IF_ERROR_RETURN 1424 (_bcm_esw_pt_vtkey_type_value_get(unit, VLXLT_HASH_KEY_TYPE_OVID, 1425 &key_type_value)); 1426 soc_mem_set_field_value_array(port_field_ids, VT_KEY_TYPEf, 1427 port_field_values, key_type_value, 1428 port_field_count); 1429 soc_mem_set_field_value_array(port_field_ids, VT_PORT_TYPE_SELECT_1f, 1430 port_field_values, 1, 1431 port_field_count); 1432 BCM_IF_ERROR_RETURN 1433 (_bcm_esw_pt_vtkey_type_value_get(unit, VLXLT_HASH_KEY_TYPE_IVID, 1434 &key_type_value)); 1435 soc_mem_set_field_value_array(port_field_ids, VT_KEY_TYPE_2f, 1436 port_field_values, key_type_value, 1437 port_field_count); 1438 soc_mem_set_field_value_array(port_field_ids, VT_PORT_TYPE_SELECT_2f, 1439 port_field_values, 1, 1440 port_field_count); 1441 soc_mem_set_field_value_array(port_field_ids, PORT_TYPEf, 1442 port_field_values, port_type, 1443 port_field_count); 1444 soc_mem_set_field_value_array(port_field_ids, SRC_SYS_PORT_IDf, 1445 port_field_values, port, 1446 port_field_count); 1447 /* TD3TBD SYS_PORT_ID and PP_PORT_NUM should be covered by CIH, 1448 * will remove it after CIH is ready. */ 1449 soc_mem_set_field_value_array(port_field_ids, SYS_PORT_IDf, 1450 port_field_values, port, 1451 port_field_count); 1452 soc_mem_set_field_value_array(port_field_ids, PP_PORT_NUMf, 1453 port_field_values, port, 1454 port_field_count); 1455 soc_mem_set_field_value_array(port_field_ids, DUAL_MODID_ENABLEf, 1456 port_field_values, dual_modid, 1457 port_field_count); 1458 soc_mem_set_field_value_array(port_field_ids, TAG_ACTION_PROFILE_PTRf, 1459 port_field_values, 1, 1460 port_field_count); 1461 1462 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_multi_set(unit, port, _BCM_CPU_TABS_BOTH, 1463 port_field_count, port_field_ids, 1464 port_field_values)); 1465 1466 if (cpu_hg_index != -1) { 1467 soc_cancun_cmh_mem_set(unit, PORT_TABm, cpu_hg_index, PORT_TYPEf, 1); 1468 /* TD3TBD should be covered by CMH, will remove it after CMH 1469 * is ready. */ 1470 BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, ING_DEVICE_PORTm, 1471 cpu_hg_index, PORT_TYPEf, 1)); 1472 } 1473 #ifdef BCM_RCPU_SUPPORT 1474 if (SOC_IS_RCPU_ONLY(unit)) { 1475 soc_cancun_cmh_mem_set(unit, PORT_TABm, port, OUTER_TPID_ENABLEf, 0x1); 1476 } 1477 #endif /* BCM_RCPU_SUPPORT */ 1478 1479 return (BCM_E_NONE); 1480 } 1481 1482 /* 1483 * Function: 1484 * bcm_td3_port_cfg_init 1485 * Purpose: 1486 * Initialize the port configuration according to Initial System 1487 * Configuration (see init.c) 1488 * Parameters: 1489 * unit - (IN)StrataSwitch unit number. 1490 * port - (IN)Port number. 1491 * vlan_data - (IN)Initial VLAN data information 1492 * Returns: 1493 * BCM_E_XXX 1494 */ 1495 int 1496 bcm_td3_port_cfg_init(int unit, bcm_port_t port, bcm_vlan_data_t *vlan_data) 1497 { 1498 if (SOC_IS_TRIDENT3X(unit)) { 1499 return _bcm_td3_port_cfg_init(unit, port, vlan_data); 1500 } 1501 1502 return (BCM_E_NONE); 1503 } 1504 1505 /* 1506 * Function: 1507 * _bcm_td3_port_table_read 1508 * Purpose: 1509 * Read port table entry and parse it to a common 1510 * (bcm_port_cfg_t) structure. 1511 * Parameters: 1512 * unit - (IN)SOC unit number. 1513 * port - (IN)Port number. 1514 * port_cfg - (OUT)API port information structure. 1515 * Returns: 1516 * BCM_E_XXX 1517 * Notes: 1518 * The following port configuration settings 1519 * do not apply to FB/ER ports: 1520 * 1521 * port_cfg->pc_frame_type 1522 * port_cfg->pc_ether_type 1523 * port_cfg->pc_stp_state 1524 * port_cfg->pc_cpu 1525 * port_cfg->pc_ptype 1526 * port_cfg->pc_pbm 1527 * port_cfg->pc_ut_pbm 1528 * port_cfg->pc_trunk 1529 * port_cfg->pc_pfm 1530 * The following port configuration do not apply to ER 1531 * port_cfg->pc_nni_port 1532 */ 1533 STATIC int 1534 _bcm_td3_port_table_read(int unit, bcm_port_t port, 1535 bcm_port_cfg_t *port_cfg) 1536 { 1537 #define LPORT_FIELDS 22 1538 int discard_tag = 0; /* Discard tagged packets bit. */ 1539 int discard_untag = 0; /* Discard untagged packets bit. */ 1540 uint32 values[LPORT_FIELDS]; 1541 int i, value = 0; 1542 1543 soc_field_t fields[LPORT_FIELDS] = { 1544 PORT_DIS_TAGf, 1545 PORT_DIS_UNTAGf, 1546 DROP_BPDUf, 1547 MIRRORf, 1548 PORT_VIDf, 1549 IVIDf, 1550 TAG_ACTION_PROFILE_PTRf, 1551 V4L3_ENABLEf, 1552 V6L3_ENABLEf, 1553 OPRIf, 1554 OCFIf, 1555 IPRIf, 1556 ICFIf, 1557 TRUST_DSCP_V4f, 1558 TRUST_DSCP_V6f, 1559 EN_IFILTERf, 1560 PORT_BRIDGEf, 1561 URPF_MODEf, 1562 URPF_DEFAULTROUTECHECKf, 1563 PVLAN_ENABLEf, 1564 CML_FLAGS_NEWf, 1565 CML_FLAGS_MOVEf 1566 }; 1567 1568 #define _GET_FIELD_VALUE(_f, _v) \ 1569 do { \ 1570 for (i = 0; i < LPORT_FIELDS; i++) { \ 1571 if (fields[i] == (_f)) { \ 1572 (_v) = values[i]; \ 1573 break; \ 1574 } \ 1575 } \ 1576 } while (0) 1577 1578 BCM_IF_ERROR_RETURN( 1579 bcm_esw_port_lport_fields_get( 1580 unit, port, LPORT_PROFILE_LPORT_TAB, LPORT_FIELDS, 1581 fields, values)); 1582 1583 /* Get drop all tagged packets flag. */ 1584 _GET_FIELD_VALUE(PORT_DIS_TAGf, discard_tag); 1585 1586 /* Get drop all untagged packets flag. */ 1587 _GET_FIELD_VALUE(PORT_DIS_UNTAGf, discard_untag); 1588 1589 if (discard_tag && discard_untag) { 1590 port_cfg->pc_disc = BCM_PORT_DISCARD_ALL; 1591 } else if (discard_tag) { 1592 port_cfg->pc_disc = BCM_PORT_DISCARD_TAG; 1593 } else if (discard_untag) { 1594 port_cfg->pc_disc = BCM_PORT_DISCARD_UNTAG; 1595 } else { 1596 port_cfg->pc_disc = BCM_PORT_DISCARD_NONE; 1597 } 1598 1599 /* Get drop bpdu's on ingress flag. */ 1600 _GET_FIELD_VALUE(DROP_BPDUf, port_cfg->pc_bpdu_disable); 1601 1602 /* Get enable mirroring flag. */ 1603 _GET_FIELD_VALUE(MIRRORf, value); 1604 if (soc_feature(unit, soc_feature_mirror_flexible)) { 1605 /* Multi-bit field */ 1606 port_cfg->pc_mirror_ing = value; 1607 } else if (!soc_feature(unit, soc_feature_no_mirror) && value) { 1608 port_cfg->pc_mirror_ing |= BCM_MIRROR_MTP_ONE; 1609 } 1610 1611 /* Get port default vlan id (pvid). */ 1612 _GET_FIELD_VALUE(PORT_VIDf, port_cfg->pc_vlan); 1613 1614 _GET_FIELD_VALUE(IVIDf, port_cfg->pc_ivlan); 1615 _GET_FIELD_VALUE(TAG_ACTION_PROFILE_PTRf, port_cfg->pc_vlan_action); 1616 1617 /* Get L3 IPv4 forwarding enable bit. */ 1618 _GET_FIELD_VALUE(V4L3_ENABLEf, value); 1619 if (value) { 1620 port_cfg->pc_l3_flags |= BCM_PORT_L3_V4_ENABLE; 1621 } 1622 1623 /* Get L3 IPv6 forwarding enable bit. */ 1624 _GET_FIELD_VALUE(V6L3_ENABLEf, value); 1625 if (value) { 1626 port_cfg->pc_l3_flags |= BCM_PORT_L3_V6_ENABLE; 1627 } 1628 1629 /* Get port default priority.*/ 1630 _GET_FIELD_VALUE(OPRIf, port_cfg->pc_new_opri); 1631 _GET_FIELD_VALUE(OCFIf, port_cfg->pc_new_ocfi); 1632 _GET_FIELD_VALUE(IPRIf, port_cfg->pc_new_ipri); 1633 _GET_FIELD_VALUE(ICFIf, port_cfg->pc_new_icfi); 1634 1635 /* Get ingress port is trusted port, trust incoming IPv4 DSCP bit. */ 1636 _GET_FIELD_VALUE(TRUST_DSCP_V4f, port_cfg->pc_dse_mode); 1637 1638 /* Get ingress port is trusted port, trust incoming IPv6 DSCP bit. */ 1639 _GET_FIELD_VALUE(TRUST_DSCP_V6f, port_cfg->pc_dse_mode_ipv6); 1640 port_cfg->pc_dscp_prio = port_cfg->pc_dse_mode; 1641 port_cfg->pc_dscp = -1; 1642 1643 /* Get enable ingress filtering bit. */ 1644 _GET_FIELD_VALUE(EN_IFILTERf, port_cfg->pc_en_ifilter); 1645 1646 /* Get enable L2 bridging on the incoming port. */ 1647 _GET_FIELD_VALUE(PORT_BRIDGEf, port_cfg->pc_bridge_port); 1648 1649 /* Unicast rpf mode. */ 1650 _GET_FIELD_VALUE(URPF_MODEf, port_cfg->pc_urpf_mode); 1651 1652 /* Unicast rpf default gateway check. */ 1653 _GET_FIELD_VALUE(URPF_DEFAULTROUTECHECKf, port_cfg->pc_urpf_def_gw_check); 1654 1655 /* private VALN enable */ 1656 _GET_FIELD_VALUE(PVLAN_ENABLEf, port_cfg->pc_pvlan_enable); 1657 1658 /* If port cpu managed learning is not frozen read it from port. */ 1659 if (!soc_feature(unit, soc_feature_no_learning) && 1660 soc_l2x_frozen_cml_get(unit, port, &port_cfg->pc_cml, 1661 &port_cfg->pc_cml_move) < 0) { 1662 _GET_FIELD_VALUE(CML_FLAGS_NEWf, port_cfg->pc_cml); 1663 _GET_FIELD_VALUE(CML_FLAGS_MOVEf, port_cfg->pc_cml_move); 1664 } 1665 1666 return (BCM_E_NONE); 1667 } 1668 1669 /* 1670 * Function: 1671 * _bcm_td3_port_table_write 1672 * Purpose: 1673 * Prepare & write port table entry 1674 * Parameters: 1675 * unit - (IN)SOC unit number. 1676 * port - (IN)Port number. 1677 * port_cfg - (IN)API port information structure. 1678 * Returns: 1679 * BCM_E_XXX 1680 */ 1681 STATIC int 1682 _bcm_td3_port_table_write(int unit, bcm_port_t port, 1683 bcm_port_cfg_t *port_cfg) 1684 { 1685 soc_field_t port_field_ids[SOC_MAX_MEM_FIELD_WORDS]; 1686 uint32 port_field_values[SOC_MAX_MEM_FIELD_WORDS]; 1687 int port_field_count = 0; 1688 int repl_cml, repl_cml_move; 1689 int cml, cml_move; 1690 1691 /* Set drop all tagged/untagged packets flag. */ 1692 switch (port_cfg->pc_disc) { 1693 case BCM_PORT_DISCARD_NONE: 1694 soc_mem_set_field_value_array(port_field_ids, PORT_DIS_TAGf, 1695 port_field_values, 0, 1696 port_field_count); 1697 soc_mem_set_field_value_array(port_field_ids, PORT_DIS_UNTAGf, 1698 port_field_values, 0, 1699 port_field_count); 1700 break; 1701 case BCM_PORT_DISCARD_ALL: 1702 soc_mem_set_field_value_array(port_field_ids, PORT_DIS_TAGf, 1703 port_field_values, 1, 1704 port_field_count); 1705 soc_mem_set_field_value_array(port_field_ids, PORT_DIS_UNTAGf, 1706 port_field_values, 1, 1707 port_field_count); 1708 break; 1709 case BCM_PORT_DISCARD_UNTAG: 1710 soc_mem_set_field_value_array(port_field_ids, PORT_DIS_TAGf, 1711 port_field_values, 0, 1712 port_field_count); 1713 soc_mem_set_field_value_array(port_field_ids, PORT_DIS_UNTAGf, 1714 port_field_values, 1, 1715 port_field_count); 1716 break; 1717 case BCM_PORT_DISCARD_TAG: 1718 soc_mem_set_field_value_array(port_field_ids, PORT_DIS_TAGf, 1719 port_field_values, 1, 1720 port_field_count); 1721 soc_mem_set_field_value_array(port_field_ids, PORT_DIS_UNTAGf, 1722 port_field_values, 0, 1723 port_field_count); 1724 break; 1725 } 1726 1727 /* Set drop bpdu's on ingress flag. */ 1728 soc_mem_set_field_value_array(port_field_ids, DROP_BPDUf, 1729 port_field_values, port_cfg->pc_bpdu_disable, 1730 port_field_count); 1731 1732 /* Set ingress mirroring flag. */ 1733 if (soc_feature(unit, soc_feature_mirror_flexible)) { 1734 soc_mem_set_field_value_array(port_field_ids, MIRRORf, 1735 port_field_values, (port_cfg->pc_mirror_ing & BCM_TR2_MIRROR_MTP_MASK), 1736 port_field_count); 1737 } else if (!soc_feature(unit, soc_feature_no_mirror)) { 1738 soc_mem_set_field_value_array(port_field_ids, MIRRORf, 1739 port_field_values, (port_cfg->pc_mirror_ing & BCM_MIRROR_MTP_ONE), 1740 port_field_count); 1741 } 1742 1743 /* 1744 * Set cpu managed learning (cml). 1745 * if unit is not frozen set the same value to port table. 1746 * else set port table (cml) to PVP_CML_FORWARD. 1747 */ 1748 if (soc_l2x_frozen_cml_set(unit, port, port_cfg->pc_cml, 1749 port_cfg->pc_cml_move, &repl_cml, 1750 &repl_cml_move) < 0) { 1751 cml = port_cfg->pc_cml; 1752 cml_move = port_cfg->pc_cml_move; 1753 } else { 1754 cml = repl_cml; 1755 cml_move = repl_cml_move; 1756 } 1757 1758 if (SOC_IS_TRX(unit)) { 1759 soc_mem_set_field_value_array(port_field_ids, CML_FLAGS_MOVEf, 1760 port_field_values, cml_move, port_field_count); 1761 soc_mem_set_field_value_array(port_field_ids, CML_FLAGS_NEWf, 1762 port_field_values, cml, port_field_count); 1763 1764 soc_mem_set_field_value_array(port_field_ids, IVIDf, 1765 port_field_values, port_cfg->pc_ivlan, port_field_count); 1766 soc_mem_set_field_value_array(port_field_ids, TAG_ACTION_PROFILE_PTRf, 1767 port_field_values, port_cfg->pc_vlan_action, port_field_count); 1768 } 1769 1770 /* Set port default vlan id (pvid). */ 1771 soc_mem_set_field_value_array(port_field_ids, PORT_VIDf, 1772 port_field_values, port_cfg->pc_vlan, port_field_count); 1773 1774 /* Set L3 IPv4 forwarding enable bit. */ 1775 soc_mem_set_field_value_array(port_field_ids, V4L3_ENABLEf, 1776 port_field_values, 1777 (port_cfg->pc_l3_flags & BCM_PORT_L3_V4_ENABLE) ? 1 : 0, 1778 port_field_count); 1779 1780 /* Set L3 IPv6 forwarding enable bit. */ 1781 soc_mem_set_field_value_array(port_field_ids, V6L3_ENABLEf, 1782 port_field_values, 1783 (port_cfg->pc_l3_flags & BCM_PORT_L3_V6_ENABLE) ? 1 : 0, 1784 port_field_count); 1785 1786 /* Set new port default priority.*/ 1787 soc_mem_set_field_value_array(port_field_ids, PORT_PRIf, 1788 port_field_values, port_cfg->pc_new_opri, port_field_count); 1789 soc_mem_set_field_value_array(port_field_ids, OCFIf, 1790 port_field_values, port_cfg->pc_new_ocfi, port_field_count); 1791 soc_mem_set_field_value_array(port_field_ids, IPRIf, 1792 port_field_values, port_cfg->pc_new_ipri, port_field_count); 1793 soc_mem_set_field_value_array(port_field_ids, ICFIf, 1794 port_field_values, port_cfg->pc_new_icfi, port_field_count); 1795 1796 /* Set ingress port is trusted port, trust incoming IPv4 DSCP bit. */ 1797 soc_mem_set_field_value_array(port_field_ids, TRUST_DSCP_V4f, 1798 port_field_values, port_cfg->pc_dse_mode ? 1 : 0, port_field_count); 1799 1800 /* Set ingress port is trusted port, trust incoming IPv6 DSCP bit. */ 1801 soc_mem_set_field_value_array(port_field_ids, TRUST_DSCP_V6f, 1802 port_field_values, port_cfg->pc_dse_mode_ipv6 ? 1 : 0, port_field_count); 1803 1804 /* Set enable ingress filtering. */ 1805 soc_mem_set_field_value_array(port_field_ids, EN_IFILTERf, 1806 port_field_values, port_cfg->pc_en_ifilter, port_field_count); 1807 1808 /* Set enable ingress filtering. */ 1809 soc_mem_set_field_value_array(port_field_ids, PORT_BRIDGEf, 1810 port_field_values, port_cfg->pc_bridge_port, port_field_count); 1811 1812 /* Unicast rpf mode. */ 1813 soc_mem_set_field_value_array(port_field_ids, URPF_MODEf, 1814 port_field_values, port_cfg->pc_urpf_mode, port_field_count); 1815 1816 /* Unicast rpf default gateway check. */ 1817 soc_mem_set_field_value_array(port_field_ids, URPF_DEFAULTROUTECHECKf, 1818 port_field_values, port_cfg->pc_urpf_def_gw_check, port_field_count); 1819 1820 /* private VALN enable */ 1821 soc_mem_set_field_value_array(port_field_ids, PVLAN_ENABLEf, 1822 port_field_values, port_cfg->pc_pvlan_enable, port_field_count); 1823 1824 _bcm_esw_port_tab_multi_set(unit, port, _BCM_CPU_TABS_BOTH, 1825 port_field_count, port_field_ids, 1826 port_field_values); 1827 1828 return BCM_E_NONE; 1829 } 1830 1831 /* 1832 * Function: 1833 * bcm_td3_port_cfg_get 1834 * Purpose: 1835 * Get port configuration. 1836 * Parameters: 1837 * unit - (IN)SOC unit number. 1838 * port - (IN)Port number. 1839 * port_cfg - (OUT)API port information structure. 1840 * Returns: 1841 * BCM_E_XXX 1842 */ 1843 int 1844 bcm_td3_port_cfg_get(int unit, bcm_port_t port, bcm_port_cfg_t *port_cfg) 1845 { 1846 /* Input parameters check.*/ 1847 if (NULL == port_cfg) { 1848 return (BCM_E_PARAM); 1849 } 1850 1851 sal_memset(port_cfg, 0, sizeof(bcm_port_cfg_t)); 1852 1853 /* Read port table entry. */ 1854 BCM_IF_ERROR_RETURN(_bcm_td3_port_table_read(unit, port, port_cfg)); 1855 1856 return(BCM_E_NONE); 1857 } 1858 1859 /* 1860 * Function: 1861 * bcm_td3_port_cfg_set 1862 * Purpose: 1863 * Set port configuration. 1864 * Parameters: 1865 * unit - (IN)SOC unit number. 1866 * port - (IN)Port number. 1867 * port_cfg - (OUT)API port information structure. 1868 * Returns: 1869 * BCM_E_XXX 1870 */ 1871 int 1872 bcm_td3_port_cfg_set(int unit, bcm_port_t port, bcm_port_cfg_t *port_cfg) 1873 { 1874 /* Input parameters check.*/ 1875 if (NULL == port_cfg) { 1876 return (BCM_E_PARAM); 1877 } 1878 1879 /* Write port table entry. */ 1880 BCM_IF_ERROR_RETURN(_bcm_td3_port_table_write(unit, port, port_cfg)); 1881 1882 return (BCM_E_NONE); 1883 } 1884 1885 int 1886 _bcm_td3_egr_port_tab_conv(int unit, soc_field_t *field, soc_mem_t* mem) { 1887 1888 soc_mem_t m = EGR_LPORT_PROFILEm; 1889 soc_field_t f = *field; 1890 1891 switch(*field) { 1892 case QOS_CTRL_IDf: 1893 case PORT_TYPEf: 1894 case MY_MODIDf: 1895 case EGR_PORT_CTRL_IDf: 1896 case EGR_LPORT_PROFILE_IDXf: 1897 m = EGR_PORTm; 1898 break; 1899 case VT_PORT_GROUP_IDf: 1900 m = EGR_GPP_ATTRIBUTESm; 1901 break; 1902 default: 1903 break; 1904 } 1905 1906 if (SOC_MEM_FIELD_VALID(unit, m, f)) { 1907 *mem = m; 1908 *field = f; 1909 return BCM_E_NONE; 1910 } 1911 1912 return BCM_E_NOT_FOUND; 1913 } 1914 1915 int 1916 _bcm_td3_port_tab_conv(int unit, soc_field_t *field, soc_mem_t *mem) { 1917 1918 soc_mem_t m = LPORT_TABm; 1919 soc_field_t f = *field; 1920 1921 switch (*field) { 1922 case ECCPf: 1923 case PARITYf: 1924 case ECCf: 1925 case ECC_DATAf: 1926 case SRC_SYS_PORT_IDf: 1927 case FROM_REMOTE_CPU_ENf: 1928 case REMOTE_CPU_ENf: 1929 case DUAL_MODID_ENABLEf: 1930 case HIGIG_TRUNK_IDf: 1931 case HIGIG_TRUNKf: 1932 case MY_MODIDf: 1933 case POINTERf: 1934 case HG_TYPEf: 1935 case HDR_TYPE_0f: 1936 /*case HDR_TYPE_NAMESPACE_0f:*/ 1937 case INITIAL_SHIFT_AMOUNT_0f: 1938 case PARSE_CONTEXT_ID_0f: 1939 case PARSE_CTRL_ID_0f: 1940 case PKT_FLOW_SELECT_CTRL_ID_0f: 1941 case SUBPORT_ID_NAMESPACEf: 1942 case PP_PORT_NUMf: 1943 case SYS_PORT_IDf: 1944 case LPORT_PROFILE_IDXf: 1945 case PORT_TYPEf: 1946 case PORT_IPBM_INDEXf: 1947 case INSERT_RX_TIMESTAMPf: 1948 case DISABLE_TIMESTAMPINGf: 1949 m = ING_DEVICE_PORTm; 1950 break; 1951 case VT_PORT_TYPE_SELECTf: 1952 f = VT_PORT_TYPE_SELECT_1f; 1953 break; 1954 case SUBPORT_TAG_NAMESPACEf: 1955 m = ING_DEVICE_PORTm; 1956 f = SUBPORT_ID_NAMESPACEf; 1957 break; 1958 case OUTER_TPID_ENABLEf: 1959 m = SOURCE_TRUNK_MAP_TABLEm; 1960 break; 1961 default: 1962 break; 1963 } 1964 1965 if (SOC_MEM_FIELD_VALID(unit, m, f)) { 1966 *mem = m; 1967 *field = f; 1968 return BCM_E_NONE; 1969 } 1970 1971 return BCM_E_NOT_FOUND; 1972 } 1973 1974 /* 1975 * Function: 1976 * bcm_td3_port_ing_pri_cng_set 1977 * Description: 1978 * Set packet priority and cfi to internal priority and color mapping 1979 * Parameters: 1980 * unit - (IN) Device number 1981 * port - (IN) Port number 1982 * untagged - (IN) For untagged packet (ignore pkt_pri, cfi argumnet) 1983 * pkt_pri - (IN) Packet priority (802.1p cos) 1984 * cfi - (IN) Packet CFI 1985 * int_pri - (IN) Internal priority 1986 * color - (IN) Color 1987 * Return Value: 1988 * BCM_E_XXX 1989 * Note: 1990 * When both pkt_pri and cfi are -1, the setting is for untagged packet 1991 */ 1992 #define MAP_SIZE 64 1993 int 1994 bcm_td3_port_ing_pri_cng_set(int unit, bcm_port_t port, int untagged, 1995 int pkt_pri, int cfi, 1996 int int_pri, bcm_color_t color) 1997 { 1998 ing_pri_cng_map_entry_t map[MAP_SIZE]; 1999 void *entries[1]; 2000 uint32 prof_index, old_prof_index; 2001 int index; 2002 int pkt_pri_cur, pkt_pri_min, pkt_pri_max; 2003 int cfi_cur, cfi_min, cfi_max; 2004 int rv = BCM_E_NONE; 2005 soc_mem_t mem = ING_DEVICE_PORTm; 2006 2007 if (pkt_pri < 0) { 2008 pkt_pri_min = 0; 2009 pkt_pri_max = 7; 2010 } else { 2011 pkt_pri_min = pkt_pri; 2012 pkt_pri_max = pkt_pri; 2013 } 2014 2015 if (cfi < 0) { 2016 cfi_min = 0; 2017 cfi_max = 1; 2018 } else { 2019 cfi_min = cfi; 2020 cfi_max = cfi; 2021 } 2022 2023 /* Lock the port table */ 2024 soc_mem_lock(unit, mem); 2025 2026 rv = _bcm_esw_port_tab_get(unit, port, TRUST_DOT1P_PTRf, 2027 (void *)&old_prof_index); 2028 if (BCM_FAILURE(rv)) { 2029 goto __cleanup; 2030 } 2031 2032 old_prof_index = old_prof_index * MAP_SIZE; 2033 2034 entries[0] = map; 2035 2036 rv = _bcm_ing_pri_cng_map_entry_get(unit, old_prof_index, MAP_SIZE, entries); 2037 if (BCM_FAILURE(rv)) { 2038 goto __cleanup; 2039 } 2040 2041 for (pkt_pri_cur = pkt_pri_min; pkt_pri_cur <= pkt_pri_max; 2042 pkt_pri_cur++) { 2043 for (cfi_cur = cfi_min; cfi_cur <= cfi_max; cfi_cur++) { 2044 index = ((untagged != 0) << 4) | 2045 ((pkt_pri_cur << 1) & 0xe) | 2046 (cfi_cur & 0x1); 2047 if (int_pri >= 0) { 2048 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &map[index], 2049 INT_PRIf, int_pri); 2050 } 2051 if (color >= 0) { 2052 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &map[index], 2053 CNGf, 2054 _BCM_COLOR_ENCODING(unit, color)); 2055 } 2056 } 2057 } 2058 2059 rv = _bcm_ing_pri_cng_map_entry_add(unit, entries, MAP_SIZE, &prof_index); 2060 if (BCM_FAILURE(rv)) { 2061 goto __cleanup; 2062 } 2063 2064 if (prof_index != old_prof_index) { 2065 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 2066 TRUST_DOT1P_PTRf, prof_index / MAP_SIZE); 2067 if (BCM_FAILURE(rv)) { 2068 goto __cleanup; 2069 } 2070 } 2071 2072 if (old_prof_index != 0) { 2073 rv = _bcm_ing_pri_cng_map_entry_delete(unit, old_prof_index); 2074 if (BCM_FAILURE(rv)) { 2075 goto __cleanup; 2076 } 2077 } 2078 __cleanup: 2079 /* Release port table lock */ 2080 soc_mem_unlock(unit, mem); 2081 return rv; 2082 } 2083 2084 /* 2085 * Function: 2086 * bcm_td3_port_ing_pri_cng_get 2087 * Description: 2088 * Get packet priority and cfi to internal priority and color mapping 2089 * Parameters: 2090 * unit - (IN) Device number 2091 * port - (IN) Port number 2092 * untagged - (IN) For untagged packet (ignore pkt_pri, cfi argumnet) 2093 * pkt_pri - (IN) Packet priority (802.1p cos) 2094 * cfi - (IN) Packet CFI 2095 * int_pri - (OUT) Internal priority 2096 * color - (OUT) Color 2097 * Return Value: 2098 * BCM_E_XXX 2099 * Note: 2100 * When both pkt_pri and cfi are -1, the setting is for untagged packet 2101 */ 2102 int 2103 bcm_td3_port_ing_pri_cng_get(int unit, bcm_port_t port, int untagged, 2104 int pkt_pri, int cfi, 2105 int *int_pri, bcm_color_t *color) 2106 { 2107 ing_pri_cng_map_entry_t map[MAP_SIZE]; 2108 void *entries[1]; 2109 uint32 profile_index; 2110 int index; 2111 int hw_color; 2112 2113 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_get(unit, port, TRUST_DOT1P_PTRf, 2114 (void *)&profile_index)); 2115 profile_index = profile_index * MAP_SIZE; 2116 2117 entries[0] = map; 2118 2119 BCM_IF_ERROR_RETURN 2120 (_bcm_ing_pri_cng_map_entry_get(unit, profile_index, MAP_SIZE, entries)); 2121 2122 index = ((untagged != 0) << 4) | ((pkt_pri << 1) & 0xe) | (cfi & 0x1); 2123 2124 if (int_pri != NULL) { 2125 *int_pri = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &map[index], 2126 INT_PRIf); 2127 } 2128 if (color != NULL) { 2129 hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &map[index], 2130 CNGf); 2131 *color = _BCM_COLOR_DECODING(unit, hw_color); 2132 } 2133 2134 return BCM_E_NONE; 2135 } 2136 2137 /* 2138 * Function: 2139 * bcm_td3_port_rate_egress_set 2140 * Purpose: 2141 * Set egress metering information 2142 * Parameters: 2143 * unit - (IN) Unit number 2144 * port - (IN) Port number 2145 * bandwidth - (IN) Kilobits per second or packets per second 2146 * zero if rate limiting is disabled 2147 * burst - (IN) Maximum burst size in kilobits or packets 2148 * mode - (IN) _BCM_PORT_RATE_BYTE_MODE or _BCM_PORT_RATE_PPS_MODE 2149 * Returns: 2150 * BCM_E_XXX 2151 */ 2152 int 2153 bcm_td3_port_rate_egress_set(int unit, bcm_port_t port, uint32 bandwidth, 2154 uint32 burst, uint32 mode) 2155 { 2156 int phy_port, mmu_port, index; 2157 soc_mem_t mem = MMU_MTRO_EGRMETERINGCONFIG_MEMm; 2158 uint32 rval, itu_mode_sel; 2159 mmu_mtro_egrmeteringconfig_mem_0_entry_t entry; 2160 uint32 refresh_rate, bucketsize, granularity, flags; 2161 int refresh_bitsize, bucket_bitsize; 2162 2163 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 2164 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 2165 2166 sal_memset(&entry, 0, sizeof(entry)); 2167 2168 index = mmu_port % SOC_TD3_MMU_PORT_PER_PIPE; 2169 mem = SOC_TD3_PMEM(unit, port, MMU_MTRO_EGRMETERINGCONFIG_MEM_PIPE0m, 2170 MMU_MTRO_EGRMETERINGCONFIG_MEM_PIPE1m); 2171 2172 /* If metering is disabled on this ingress port we are done. */ 2173 if (!bandwidth || !burst) { 2174 SOC_IF_ERROR_RETURN 2175 (soc_mem_write(unit, mem, MEM_BLOCK_ANY, index, &entry)); 2176 return BCM_E_NONE; 2177 } 2178 2179 if((bandwidth < _BCM_PORT_RATE_MIN_KILOBITS || 2180 bandwidth > _BCM_PORT_RATE_MAX_KILOBITS) || 2181 (burst < _BCM_PORT_BURST_MIN_KILOBITS || 2182 burst > _BCM_PORT_BURST_MAX_KILOBITS)) { 2183 return BCM_E_PARAM; 2184 } 2185 2186 flags = mode == _BCM_PORT_RATE_PPS_MODE ? 2187 _BCM_TD_METER_FLAG_PACKET_MODE : 0; 2188 2189 BCM_IF_ERROR_RETURN(READ_MMU_SEDCFG_MISCCONFIGr(unit, &rval)); 2190 itu_mode_sel = soc_reg_field_get(unit, MMU_SEDCFG_MISCCONFIGr, rval, 2191 ITU_MODE_SELf); 2192 2193 if (itu_mode_sel) { 2194 flags |= _BCM_TD_METER_FLAG_NON_LINEAR; 2195 } 2196 2197 refresh_bitsize = soc_mem_field_length(unit, mem, REFRESHf); 2198 bucket_bitsize = soc_mem_field_length(unit, mem, THD_SELf); 2199 BCM_IF_ERROR_RETURN 2200 (_bcm_td_rate_to_bucket_encoding(unit, bandwidth, burst, flags, 2201 refresh_bitsize, bucket_bitsize, 2202 &refresh_rate, &bucketsize, 2203 &granularity)); 2204 soc_mem_field32_set(unit, mem, &entry, MODEf, 2205 mode == _BCM_PORT_RATE_PPS_MODE ? 1 : 0); 2206 soc_mem_field32_set(unit, mem, &entry, METER_GRANf, granularity); 2207 soc_mem_field32_set(unit, mem, &entry, REFRESHf, refresh_rate); 2208 soc_mem_field32_set(unit, mem, &entry, THD_SELf, bucketsize); 2209 2210 SOC_IF_ERROR_RETURN 2211 (soc_mem_write(unit, mem, MEM_BLOCK_ANY, index, &entry)); 2212 2213 return BCM_E_NONE; 2214 } 2215 2216 /* 2217 * Function: 2218 * bcm_td3_port_ipbm_opaque_set 2219 * Purpose: 2220 * Set egress metering information 2221 * Parameters: 2222 * unit - (IN) Unit number 2223 * stm_idx - (IN) SOURCE_TRUNK_MAP table index 2224 * class - (IN) port class value(range 0-131) 2225 * Returns: 2226 * BCM_E_XXX 2227 */ 2228 int 2229 bcm_td3_port_ipbm_opaque_set(int unit, int stm_idx, uint32 class) 2230 { 2231 int rv; 2232 int temp_p; 2233 uint32 pipe_port; 2234 int max_port = 0; 2235 uint32 ipbm_val = 0; 2236 uint32 opq_obj_val = 0; 2237 uint8 opaque_3 = _BCM_TD3_OPAQUE3_ID; 2238 uint8 opaque_4 = _BCM_TD3_OPAQUE4_ID; 2239 soc_mem_t mem = SOURCE_TRUNK_MAP_TABLEm; 2240 soc_field_t ipbm_fld = IPBM_INDEXf; 2241 soc_field_t opq_obj_fld = OPAQUE_OBJECTf; 2242 source_trunk_map_table_entry_t stm_entry; 2243 2244 if (!(SOC_MEM_FIELD_VALID(unit, mem, ipbm_fld) && 2245 SOC_MEM_FIELD_VALID(unit, mem, opq_obj_fld))) { 2246 return BCM_E_UNAVAIL; 2247 } 2248 2249 max_port = _BCM_TD3_NUM_PIPE_PORTS; 2250 2251 if(class >= max_port) { 2252 return BCM_E_PARAM; 2253 } 2254 2255 /* Read source trunk map table. */ 2256 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stm_idx, &stm_entry); 2257 BCM_IF_ERROR_RETURN(rv); 2258 2259 pipe_port = class; 2260 2261 /* Set IPBM_INDEX */ 2262 ipbm_val = (pipe_port < _FP_TD3_TCAM_IPBMP_SIZE) ? pipe_port : _FP_TD3_TCAM_IPBMP_SIZE+1; 2263 soc_mem_field32_set(unit, mem, &stm_entry, ipbm_fld, ipbm_val); 2264 2265 /* Set OPAQUE_OBJECT */ 2266 if (pipe_port >= _FP_TD3_TCAM_IPBMP_SIZE) { 2267 if (pipe_port >= (_FP_TD3_TCAM_IPBMP_SIZE + _FP_FLEX_PBMP_SIZE)) { 2268 opq_obj_val = opaque_4; 2269 temp_p = pipe_port - (_FP_TD3_TCAM_IPBMP_SIZE + _FP_FLEX_PBMP_SIZE); 2270 } else { 2271 opq_obj_val = opaque_3; 2272 temp_p = pipe_port - _FP_TD3_TCAM_IPBMP_SIZE; 2273 } 2274 opq_obj_val = ((1 << temp_p) << 3) | opq_obj_val; 2275 soc_mem_field32_set(unit, mem, &stm_entry, opq_obj_fld, opq_obj_val); 2276 } 2277 2278 /* Write source trunk map table */ 2279 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, stm_idx, &stm_entry); 2280 BCM_IF_ERROR_RETURN(rv); 2281 2282 return BCM_E_NONE; 2283 } 2284 2285 /* 2286 * Function: 2287 * bcm_td3_port_ipbm_opaque_get 2288 * Purpose: 2289 * Set egress metering information 2290 * Parameters: 2291 * unit - (IN) Unit number 2292 * stm_idx - (IN) SOURCE_TRUNK_MAP table index 2293 * class - (OUT) pointer of class 2294 * Returns: 2295 * BCM_E_XXX 2296 */ 2297 int 2298 bcm_td3_port_ipbm_opaque_get(int unit, int stm_idx, uint32* class) 2299 { 2300 int rv; 2301 uint32 temp_p; 2302 uint32 ipbm_val = 0; 2303 uint32 opq_obj_val = 0; 2304 uint8 opaque_3 = _BCM_TD3_OPAQUE3_ID; 2305 uint8 opaque_4 = _BCM_TD3_OPAQUE4_ID; 2306 soc_mem_t mem = SOURCE_TRUNK_MAP_TABLEm; 2307 soc_field_t ipbm_fld = IPBM_INDEXf; 2308 soc_field_t opq_obj_fld = OPAQUE_OBJECTf; 2309 source_trunk_map_table_entry_t stm_entry; 2310 uint32 temp_cnt = 0; 2311 2312 if (!(SOC_MEM_FIELD_VALID(unit, mem, ipbm_fld) && 2313 SOC_MEM_FIELD_VALID(unit, mem, opq_obj_fld))) { 2314 return BCM_E_UNAVAIL; 2315 } 2316 2317 /* Read source trunk map table. */ 2318 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, stm_idx, &stm_entry); 2319 BCM_IF_ERROR_RETURN(rv); 2320 2321 ipbm_val = soc_mem_field32_get(unit, mem, &stm_entry, ipbm_fld); 2322 2323 if (ipbm_val < _FP_TD3_TCAM_IPBMP_SIZE) { 2324 *class = ipbm_val; 2325 return BCM_E_NONE; 2326 } else { 2327 temp_p = soc_mem_field32_get(unit, mem, &stm_entry, opq_obj_fld); 2328 opq_obj_val = temp_p & _BCM_TD3_OPAQUE_ID_MASK; 2329 temp_p = temp_p >> 3; 2330 while ((temp_p = temp_p >> 1) > 0) { 2331 temp_cnt++; 2332 } 2333 if (opq_obj_val == opaque_3) { 2334 *class = temp_cnt + _FP_TD3_TCAM_IPBMP_SIZE; 2335 } else if (opq_obj_val == opaque_4) { 2336 *class = temp_cnt + _FP_TD3_TCAM_IPBMP_SIZE 2337 + _FP_FLEX_PBMP_SIZE; 2338 } else { 2339 return BCM_E_INTERNAL; 2340 } 2341 2342 return BCM_E_NONE; 2343 } 2344 } 2345 2346 /* 2347 * Function: 2348 * bcm_td3_port_rate_egress_get 2349 * Purpose: 2350 * Get egress metering information 2351 * Parameters: 2352 * unit - (IN) Unit number 2353 * port - (IN) Port number 2354 * bandwidth - (OUT) Kilobits per second or packets per second 2355 * zero if rate limiting is disabled 2356 * burst - (OUT) Maximum burst size in kilobits or packets 2357 * mode - (OUT) _BCM_PORT_RATE_BYTE_MODE or _BCM_PORT_RATE_PPS_MODE 2358 * Returns: 2359 * BCM_E_XXX 2360 */ 2361 int 2362 bcm_td3_port_rate_egress_get(int unit, bcm_port_t port, uint32 *bandwidth, 2363 uint32 *burst, uint32 *mode) 2364 { 2365 int phy_port, mmu_port, index; 2366 soc_mem_t mem = MMU_MTRO_EGRMETERINGCONFIG_MEMm; 2367 uint32 rval, itu_mode_sel; 2368 mmu_mtri_bkpmeteringconfig_mem_0_entry_t entry; 2369 uint32 refresh_rate, bucketsize, granularity, flags; 2370 2371 if (bandwidth == NULL || burst == NULL) { 2372 return BCM_E_PARAM; 2373 } 2374 2375 phy_port = SOC_INFO(unit).port_l2p_mapping[port]; 2376 mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port]; 2377 2378 index = mmu_port % SOC_TD3_MMU_PORT_PER_PIPE; 2379 mem = SOC_TD3_PMEM(unit, port, MMU_MTRO_EGRMETERINGCONFIG_MEM_PIPE0m, 2380 MMU_MTRO_EGRMETERINGCONFIG_MEM_PIPE1m); 2381 2382 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, &entry)); 2383 2384 refresh_rate = soc_mem_field32_get(unit, mem, &entry, REFRESHf); 2385 bucketsize = soc_mem_field32_get(unit, mem, &entry, THD_SELf); 2386 granularity = soc_mem_field32_get(unit, mem, &entry, METER_GRANf); 2387 2388 flags = soc_mem_field32_get(unit, mem, &entry, MODEf) ? 2389 _BCM_TD_METER_FLAG_PACKET_MODE : 0; 2390 2391 BCM_IF_ERROR_RETURN(READ_MMU_SEDCFG_MISCCONFIGr(unit, &rval)); 2392 itu_mode_sel = soc_reg_field_get(unit, MMU_SEDCFG_MISCCONFIGr, rval, 2393 ITU_MODE_SELf); 2394 2395 if (itu_mode_sel) { 2396 flags |= _BCM_TD_METER_FLAG_NON_LINEAR; 2397 } 2398 2399 BCM_IF_ERROR_RETURN 2400 (_bcm_td_bucket_encoding_to_rate(unit, refresh_rate, bucketsize, 2401 granularity, flags, bandwidth, burst)); 2402 2403 *mode = flags & _BCM_TD_METER_FLAG_PACKET_MODE ? 2404 _BCM_PORT_RATE_PPS_MODE : _BCM_PORT_RATE_BYTE_MODE; 2405 2406 return BCM_E_NONE; 2407 2408 } 2409 2410 int bcm_td3_port_drain_cells(int unit, int port) 2411 { 2412 mac_driver_t *macd; 2413 int rv = BCM_E_NONE; 2414 2415 if (IS_CPU_PORT(unit, port)) { 2416 return BCM_E_PORT; 2417 } 2418 2419 /* Call Port Control module */ 2420 if (SOC_USE_PORTCTRL(unit)) { 2421 return bcmi_esw_portctrl_egress_queue_drain(unit, port); 2422 } 2423 2424 PORT_LOCK(unit); 2425 rv = soc_mac_probe(unit, port, &macd); 2426 2427 if (BCM_SUCCESS(rv)) { 2428 rv = MAC_CONTROL_SET(macd, unit, port, SOC_MAC_CONTROL_EGRESS_DRAIN, 1); 2429 2430 } 2431 PORT_UNLOCK(unit); 2432 return rv; 2433 } 2434 2435 int 2436 bcm_td3_port_init(int unit) 2437 { 2438 int rv = BCM_E_NONE; 2439 int port; 2440 /* VLAN control TBA in FlexPP (SDK-66866) */ 2441 /* Add default entries for SYSTEM_CONFIG_TABLE profile */ 2442 #if 0 2443 /* TD3TBD */ 2444 int port, index; 2445 uint16 tpid; 2446 2447 tpid = _bcm_fb2_outer_tpid_default_get(unit); 2448 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_lkup(unit, tpid, &index)); 2449 2450 for (port = 0; port <= SOC_PORT_ADDR_MAX(unit); port++) { 2451 BCM_IF_ERROR_RETURN( 2452 _bcm_trx_source_trunk_map_set(unit, port, 2453 OUTER_TPID_ENABLEf, 1 << index)); 2454 } 2455 BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_tab_ref_count_add(unit, index, 1)); 2456 #endif 2457 2458 /* Move from _soc_trident3_misc_init */ 2459 if (soc_feature(unit, soc_feature_egr_all_profile)) { 2460 PBMP_ALL_ITER(unit, port) { 2461 soc_field_t flds[3] = { 2462 VT_MISS_UNTAGf, 2463 REMARK_OUTER_DOT1Pf, 2464 OUTER_TPID_VALIDf 2465 }; 2466 uint32 vals[3] = {0, 1, 1}; 2467 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_fields_set(unit, 2468 port, EGR_VLAN_CONTROL_1m, 3, flds, vals)); 2469 } 2470 } 2471 2472 return rv; 2473 } 2474 2475 int 2476 bcmi_td3_speed_mix_validate(int unit, uint32 speed_mask) 2477 { 2478 return soc_td3_speed_mix_validate(unit, speed_mask); 2479 } 2480 2481 #define FIELD_IDS_NUM 4 2482 /* 2483 * Function: 2484 * bcmi_td3_port_internal_loopback_set 2485 * Purpose: 2486 * Put the port in the internal loopback mode 2487 * 2488 * Parameters: 2489 * unit - (IN) Unit number 2490 * port - (IN) Port number 2491 * enable - (IN) TRUE or FALSE 2492 * Returns: 2493 * BCM_E_XXX 2494 */ 2495 int bcmi_td3_port_internal_loopback_set(int unit, bcm_port_t port, int enable) 2496 { 2497 soc_field_t fld_ids[FIELD_IDS_NUM]; 2498 uint32 fld_values[FIELD_IDS_NUM]; 2499 2500 fld_ids[0] = PORT_TYPEf; 2501 fld_ids[1] = PARSE_CONTEXT_ID_0f; 2502 if (enable) { /* enable */ 2503 fld_values[0] = 2; 2504 fld_values[1] = 4; 2505 } else { 2506 fld_values[0] = 0; 2507 fld_values[1] = 6; 2508 } 2509 2510 BCM_IF_ERROR_RETURN(_bcm_esw_port_tab_multi_set(unit, port, 2511 _BCM_CPU_TABS_BOTH, 2, fld_ids, fld_values)); 2512 fld_ids[0] = PORT_TYPEf; 2513 fld_ids[1] = EGR_PORT_CTRL_IDf; 2514 fld_ids[2] = EDIT_CTRL_IDf; 2515 fld_ids[3] = EM_SRCMOD_CHANGEf; 2516 if (enable) { /* enable */ 2517 fld_values[0] = 2; 2518 fld_values[1] = 2; 2519 fld_values[2] = 3; 2520 fld_values[3] = 0; 2521 } else { 2522 fld_values[0] = 0; 2523 fld_values[1] = 1; 2524 fld_values[2] = 0; 2525 fld_values[3] = 1; 2526 } 2527 BCM_IF_ERROR_RETURN(_bcm_esw_egr_port_tab_multi_set(unit, port, 2528 FIELD_IDS_NUM, fld_ids, fld_values)); 2529 if (enable) { 2530 /* enable IPv4 L3 on loopback port. The CPU masquerade packet 2531 * will reference the LPORT profile from source_trunk_map with 2532 * port number set in the loopback header. The default LPORT 2533 * profile index is 0 for all these masquerade ports. 2534 */ 2535 SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, LPORT_TABm, 0, 2536 V4L3_ENABLEf, 1)); 2537 2538 } 2539 PORT_LOCK(unit); 2540 if (enable) { 2541 SOC_PBMP_PORT_ADD(SOC_INFO(unit).lb_pbm, port); 2542 } else { 2543 SOC_PBMP_PORT_REMOVE(SOC_INFO(unit).lb_pbm, port); 2544 } 2545 PORT_UNLOCK(unit); 2546 2547 return BCM_E_NONE; 2548 } 2549 2550 #else /* BCM_TRIDENT3_SUPPORT */ 2551 int _td3_port_not_empty; 2552 2553 #endif /* BCM_TRIDENT3_SUPPORT */