openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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 */