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 (28385B)


      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:     TH3 SOC Port driver.
      9  */
     10 #include <shared/bsl.h>
     11 #include <soc/error.h>
     12 #include <soc/defs.h>
     13 #include <soc/tdm/core/tdm_top.h>
     14 
     15 #if defined(BCM_TOMAHAWK3_SUPPORT)
     16 #include <soc/init/tomahawk3_tdm.h>
     17 #include <soc/tomahawk3.h>
     18 #include <soc/scache.h>
     19 
     20 #ifdef BCM_WARM_BOOT_SUPPORT
     21 
     22 #define SOC_FLEXPORT_WB_VERSION_1_0                SOC_SCACHE_VERSION(1,0)
     23 #define SOC_FLEXPORT_WB_DEFAULT_VERSION            SOC_FLEXPORT_WB_VERSION_1_0
     24 
     25 extern int
     26 _soc_th3_port_speed_cap[SOC_MAX_NUM_DEVICES][_TH3_DEV_PORTS_PER_DEV];
     27 #endif
     28 
     29 /*
     30  * Function:
     31  *      soc_th3_port_schedule_tdm_init
     32  * Purpose:
     33  *      Initialize TDM information in port_schedule_state that will be passed
     34  *      to DV FlexPort API
     35  * Parameters:
     36  *      unit                 - (IN)  Unit number.
     37  *      port_schedule_state  - (OUT) Port resource state.
     38  * Returns:
     39  *      BCM_E_xxx
     40  * Notes:
     41  *      If called during Scheduler Initialization, only below values need to be
     42  *      properly set:
     43  *        soc_tdm_schedule_pipe_t::num_slices
     44  *        soc_tdm_schedule_t:: cal_len
     45  *        soc_tdm_schedule_t:: num_ovs_groups
     46  *        soc_tdm_schedule_t:: ovs_group_len
     47  *        soc_tdm_schedule_t:: num_pkt_sch_or_ovs_space
     48  *        soc_tdm_schedule_t:: pkt_sch_or_ovs_space_len 
     49  */
     50 int
     51 soc_th3_port_schedule_tdm_init(int unit,
     52                             soc_port_schedule_state_t *port_schedule_state)
     53 {
     54 #if 1
     55     
     56     soc_control_t *soc = SOC_CONTROL(unit);
     57     _soc_tomahawk3_tdm_t *tdm = soc->tdm_info;
     58     soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd;
     59     soc_tdm_schedule_t *sched;
     60     int pipe, hpipe, is_flexport;
     61 
     62     if (tdm == NULL) {
     63         /*XGSSIM will skip tdm configuration on TH3*/
     64         if (SAL_BOOT_SIMULATION) {
     65             return SOC_E_NONE;
     66         }
     67         return SOC_E_INIT;
     68     }
     69 
     70     is_flexport = port_schedule_state->is_flexport;
     71 
     72     /* Construct tdm_ingress_schedule_pipe and tdm_egress_schedule_pipe */
     73     for (pipe = 0; pipe <  _TH3_PIPES_PER_DEV; pipe++) {
     74         tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe];
     75         tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe];
     76 
     77         tdm_ischd->num_slices = _TH3_OVS_HPIPE_COUNT_PER_PIPE;
     78         tdm_eschd->num_slices = _TH3_OVS_HPIPE_COUNT_PER_PIPE;
     79 
     80         if (is_flexport) {
     81             /* TDM Calendar is always in slice 0 */
     82             sal_memcpy(tdm_ischd->tdm_schedule_slice[0].linerate_schedule,
     83                         tdm->tdm_pipe[pipe].idb_tdm,
     84                         sizeof(int)*_TH3_TDM_LENGTH);
     85             sal_memcpy(tdm_eschd->tdm_schedule_slice[0].linerate_schedule,
     86                         tdm->tdm_pipe[pipe].mmu_tdm,
     87                         sizeof(int)*_TH3_TDM_LENGTH);
     88         }
     89 
     90         /* OVS */
     91         for (hpipe = 0; hpipe < _TH3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) {
     92             /* IDB OVERSUB*/
     93             sched = &tdm_ischd->tdm_schedule_slice[hpipe];
     94             sched->cal_len = _TH3_TDM_LENGTH;
     95 
     96 /* TDM says everything related to hpipe and pblk can be removed except
     97  * sched->cal_len = _TH3_TDM_LENGTH; */
     98 #if 0
     99             sched->num_ovs_groups = _TH3_OVS_GROUP_COUNT_PER_HPIPE;
    100             sched->ovs_group_len = _TH3_OVS_GROUP_TDM_LENGTH;
    101             sched->num_pkt_sch_or_ovs_space = 1;
    102             sched->pkt_sch_or_ovs_space_len = _TH3_PKT_SCH_LENGTH;
    103 
    104             if (is_flexport) {
    105                 for (group = 0; group < _TH3_OVS_GROUP_COUNT_PER_HPIPE; group++) {
    106                     for (slot = 0; slot < _TH3_OVS_GROUP_TDM_LENGTH; slot++) {
    107                         sched->oversub_schedule[group][slot] =
    108                             tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot];
    109                     }
    110                 }
    111                 for (slot = 0; slot < _TH3_PKT_SCH_LENGTH; slot++) {
    112                     sched->pkt_sch_or_ovs_space[0][slot] = 
    113                         tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot];
    114                 }
    115             }
    116 
    117             /* MMU OVERSUB */
    118             sched = &tdm_eschd->tdm_schedule_slice[hpipe];
    119             sched->cal_len = _TH3_TDM_LENGTH;
    120             sched->num_ovs_groups = _TH3_OVS_GROUP_COUNT_PER_HPIPE;
    121             sched->ovs_group_len = _TH3_OVS_GROUP_TDM_LENGTH;
    122             sched->num_pkt_sch_or_ovs_space = 1;
    123             sched->pkt_sch_or_ovs_space_len = _TH3_PKT_SCH_LENGTH;
    124 
    125             if (is_flexport) {
    126                 for (group = 0; group < _TH3_OVS_GROUP_COUNT_PER_HPIPE; group++) {
    127                     for (slot = 0; slot < _TH3_OVS_GROUP_TDM_LENGTH; slot++) {
    128                         sched->oversub_schedule[group][slot] =
    129                             tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot];
    130                         }
    131                     }
    132                 for (slot = 0; slot < _TH3_PKT_SCH_LENGTH; slot++) {
    133                     sched->pkt_sch_or_ovs_space[0][slot] = 
    134                         tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot];
    135                 }
    136             }
    137 #endif
    138         }
    139     }
    140 
    141 /* TDM says everything related to hpipe and pblk can be removed except
    142  * sched->cal_len = _TH3_TDM_LENGTH; */
    143 #if 0
    144     if (is_flexport) {
    145         port_p2PBLK_inst_mapping =
    146             port_schedule_state->in_port_map.port_p2PBLK_inst_mapping;
    147         /* pblk info for phy_port */
    148         for (phy_port = 1; phy_port < TH3_NUM_EXT_PORTS; phy_port++) {
    149             if (tdm->pblk_info[phy_port].pblk_cal_idx == -1) {
    150                 continue;
    151             }
    152             port_p2PBLK_inst_mapping[phy_port] =
    153                                         tdm->pblk_info[phy_port].pblk_cal_idx;
    154         }
    155     }
    156 #endif
    157 #endif
    158     return SOC_E_NONE;
    159 }
    160 
    161 /*
    162  * Function:
    163  *      soc_th3_soc_tdm_update
    164  * Purpose:
    165  *      Update TDM information in SOC with TDM state return from DV FlexPort API
    166  * Parameters:
    167  *      unit                 - (IN)  Unit number.
    168  *      port_schedule_state  - (OUT) Port resource state.
    169  * Returns:
    170  *      BCM_E_xxx
    171  * Notes:
    172  */
    173 int
    174 soc_th3_soc_tdm_update(int unit,
    175                             soc_port_schedule_state_t *port_schedule_state)
    176 {
    177 #if 1
    178     
    179     soc_control_t *soc = SOC_CONTROL(unit);
    180     _soc_tomahawk3_tdm_t *tdm = soc->tdm_info;
    181     soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd;
    182     int pipe, cdport;
    183 
    184     if (tdm == NULL) {
    185         /*XGSSIM will skip tdm configuration on TH3*/
    186         if (SAL_BOOT_XGSSIM) {
    187             return SOC_E_NONE;
    188         }
    189         return SOC_E_INIT;
    190     }
    191 
    192     /* Copy info from soc_port_schedule_state_t to _soc_tomahawk3_tdm_t */
    193     for (pipe = 0; pipe <  _TH3_PIPES_PER_DEV; pipe++) {
    194         tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe];
    195         tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe];
    196 
    197         /* TDM Calendar is always in slice 0 */
    198         sal_memcpy(tdm->tdm_pipe[pipe].idb_tdm,
    199                     tdm_ischd->tdm_schedule_slice[0].linerate_schedule,
    200                     sizeof(int)*_TH3_TDM_LENGTH);
    201         sal_memcpy(tdm->tdm_pipe[pipe].mmu_tdm,
    202                     tdm_eschd->tdm_schedule_slice[0].linerate_schedule,
    203                     sizeof(int)*_TH3_TDM_LENGTH);
    204 /* TDM says can be removed */
    205 #if 0
    206         for (hpipe = 0; hpipe < _TH3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) {
    207             sched = &tdm_ischd->tdm_schedule_slice[hpipe];
    208             for (group = 0; group < _TH3_OVS_GROUP_COUNT_PER_HPIPE; group++) {
    209                 for (slot = 0; slot < _TH3_OVS_GROUP_TDM_LENGTH; slot++) {
    210                     tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot] =
    211                         sched->oversub_schedule[group][slot];
    212                 }
    213             }
    214             for (slot = 0; slot < _TH3_PKT_SCH_LENGTH; slot++) {
    215                 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot] =
    216                     sched->pkt_sch_or_ovs_space[0][slot];
    217 
    218             }
    219         }
    220 #endif
    221     }
    222 /* TDM says pblk stuff can be removed */
    223 #if 0
    224     /* pblk info init  */
    225     for (phy_port = 1; phy_port < TH3_NUM_EXT_PORTS; phy_port++) {
    226         tdm->pblk_info[phy_port].pblk_cal_idx = -1;
    227         tdm->pblk_info[phy_port].pblk_hpipe_num = -1;
    228     }
    229 
    230     /* pblk info for phy_port */
    231     for (pipe = 0; pipe < _TH3_PIPES_PER_DEV; pipe++) {
    232         tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe];
    233         for (hpipe = 0; hpipe < _TH3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) {
    234             for (group = 0; group < _TH3_OVS_GROUP_COUNT_PER_HPIPE; group++) {
    235                 for (index = 0; index < _TH3_OVS_GROUP_TDM_LENGTH; index++) {
    236                     phy_port =
    237                         tdm_ischd->tdm_schedule_slice[hpipe].oversub_schedule[group][index];
    238                     if (phy_port < TH3_NUM_EXT_PORTS) {
    239                         tdm->pblk_info[phy_port].pblk_hpipe_num = hpipe;
    240                         tdm->pblk_info[phy_port].pblk_cal_idx =
    241                             port_schedule_state->out_port_map.port_p2PBLK_inst_mapping[phy_port];
    242                     }
    243                 }
    244             }
    245         }
    246     }
    247 #endif
    248 
    249     /* Port Macros in TH3 have 2 MACs.  Mac 0 is in bits 0-3, Mac 1 is in bits 4-7 */
    250     /* CDPORT port ratio */
    251     for (cdport = 0; cdport < _TH3_PBLKS_PER_DEV; cdport++) {
    252         soc_tomahawk3_port_ratio_get_schedule_state(unit, port_schedule_state, cdport,
    253             &tdm->port_ratio[cdport], 1);
    254     }
    255 /* TDM says should be removed or completely redefined for TH3 */
    256 #if 0
    257     /* Calculate the oversub ratio */
    258     for (pipe = 0; pipe < _TH3_PIPES_PER_DEV; pipe++) {
    259         /* At MAX Frequency OVS is always 3:2 */
    260         if (si->frequency == 1700) {
    261             for (hpipe = 0; hpipe < _TH3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) {
    262                 tdm->ovs_ratio_x1000[pipe][hpipe] = 1500;
    263             }
    264             continue;
    265         }
    266 
    267         tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe];
    268         /* Count number of OVSB_TOKEN assigned by the TDM code */
    269         for (length = _TH3_TDM_LENGTH; length > 0; length--) {
    270             if (tdm_ischd->tdm_schedule_slice[0].linerate_schedule[length - 1]
    271                     != TH3_NUM_EXT_PORTS) {
    272                 break;
    273             }
    274         }
    275         ovs_core_slot_count = 0;
    276         for (index = 0; index < length; index++) {
    277             if (tdm_ischd->tdm_schedule_slice[0].linerate_schedule[index]
    278                     == TH3_OVSB_TOKEN) {
    279                 ovs_core_slot_count++;
    280             }
    281         }
    282 
    283         /* At line-rate with less than max frequency, OVS picks the 2:1 */
    284         if (ovs_core_slot_count == 0) {
    285             for (hpipe = 0; hpipe < _TH3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) {
    286                 tdm->ovs_ratio_x1000[pipe][hpipe] = 2000;
    287             }
    288         }
    289 
    290         /* Count number of slot needed for half-pipe's oversub I/O bandwidth */
    291         for (hpipe = 0; hpipe < _TH3_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) {
    292             ovs_io_slot_count = 0;
    293             for (group = 0; group < _TH3_OVS_GROUP_COUNT_PER_HPIPE; group++) {
    294                 for (index = 0; index < _TH3_OVS_GROUP_TDM_LENGTH; index++) {
    295                     phy_port = tdm_ischd->tdm_schedule_slice[hpipe].oversub_schedule[group][index];
    296                     if (phy_port == TH3_NUM_EXT_PORTS) {
    297                         continue;
    298                     }
    299                     port = si->port_p2l_mapping[phy_port];
    300                     if ((port == -1) || IS_CPU_PORT(unit, port) ||
    301                         IS_LB_PORT(unit, port) ||
    302                         IS_MANAGEMENT_PORT(unit, port)) {
    303                         LOG_ERROR(BSL_LS_SOC_PORT,
    304                                   (BSL_META_U(unit,
    305                                               "Flexport: Invalid physical "
    306                                               "port %d in OverSub table.\n"),
    307                                    phy_port));
    308                         continue;
    309                     }
    310                     port_slot_count = si->port_init_speed[port] / 2500;
    311                     ovs_io_slot_count += port_slot_count;
    312                 }
    313             }
    314             if (ovs_core_slot_count != 0) {
    315                 tdm->ovs_ratio_x1000[pipe][hpipe] =
    316                     ovs_io_slot_count * 1000 / (ovs_core_slot_count / 2);
    317             }
    318         }
    319     }
    320 #endif
    321 #endif
    322     return SOC_E_NONE;
    323 }
    324 
    325 /*
    326  * Function:
    327  *      soc_th3_support_speeds
    328  * Purpose:
    329  *      Get the supported speed of port for specified lanes
    330  * Parameters:
    331  *      unit                 - (IN)  Unit number.
    332  *      lanes                - (IN)  Number of Lanes for the port.
    333  *      speed_mask           - (IN)  Bitmap for supported speed.
    334  * Returns:
    335  *      BCM_E_xxx
    336  * Notes: This is NOT supported because PM8x50 is not supported in
    337  *        bcm_port_ability_t
    338  */
    339 int
    340 soc_th3_support_speeds(int unit, int lanes, uint32 *speed_mask)
    341 {
    342     *speed_mask = 0;
    343 
    344     return SOC_E_NONE;
    345 }
    346 
    347 #ifdef BCM_WARM_BOOT_SUPPORT
    348 int soc_th3_flexport_scache_allocate(int unit)
    349 {
    350     int rv = SOC_E_NONE;
    351     uint8 *flexport_scache_ptr;
    352     soc_scache_handle_t scache_handle;
    353     uint32 alloc_get = 0;
    354     uint32 alloc_size = 0;
    355     int stable_size;
    356     int default_ver = SOC_FLEXPORT_WB_DEFAULT_VERSION;
    357 
    358     alloc_size =  (sizeof(int) * _TH3_PHY_PORTS_PER_DEV)  + /* phy to logical*/
    359                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* logical to phy */
    360                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* max port speed */
    361                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* init port speed */
    362                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* num of lanes */
    363                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port fec*/
    364                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port phy lane config */
    365                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port link training */
    366                    (sizeof(pbmp_t));                        /* Disabled bitmap */
    367     alloc_get = alloc_size;
    368 
    369     SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0);
    370     /* check to see if an scache table has been configured */
    371     rv = soc_stable_size_get(unit, &stable_size);
    372     if (SOC_FAILURE(rv) || stable_size <= 0) {
    373         return rv;
    374     }
    375 
    376     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
    377                                           TRUE, &alloc_get,
    378                                           &flexport_scache_ptr,
    379                                           default_ver,
    380                                           NULL);
    381 
    382     if (rv  == SOC_E_CONFIG) {
    383         /* Probably Level1 */
    384         return SOC_E_NONE;
    385     }
    386     /* NotRequired but just to confirm Get the pointer for the Level 2 cache */
    387     if (alloc_get != alloc_size) {
    388         /* Expected size doesn't match retrieved size */
    389         LOG_ERROR(BSL_LS_SOC_COMMON,
    390                 (BSL_META_U(unit,
    391                  "ERROR: scache memory for flexport size mismatch"
    392                  "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
    393         return SOC_E_INTERNAL;
    394     }
    395 
    396     if (NULL == flexport_scache_ptr) {
    397         LOG_ERROR(BSL_LS_SOC_COMMON,
    398                 (BSL_META_U(unit,
    399                  "ERROR: scache memory not allocated for flexport"
    400                  "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
    401         return SOC_E_MEMORY;
    402     }
    403     LOG_VERBOSE(BSL_LS_SOC_COMMON,
    404                 (BSL_META_U(unit,
    405                 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
    406     return SOC_E_NONE;
    407 
    408 }
    409 
    410 /*
    411  * Function:
    412  *      soc_th3_flexport_scache_sync
    413  * Purpose:
    414  *      Record Port info that maybe changed during flexport for Level 2 WB
    415  *
    416  * Warm Boot Version Map:
    417  *
    418  *  BCM_WB_VERSION_1_0
    419  *    port_p2l_mapping
    420  *    port_l2p_mapping
    421  *    port_speed_max
    422  *    port_init_speed
    423  *    port_num_lanes
    424  *    disabled_bitmap
    425  *
    426  * Parameters:
    427  *      unit - StrataSwitch unit number.
    428  * Returns:
    429  *      SOC_E_XXX
    430  */
    431 int soc_th3_flexport_scache_sync(int unit)
    432 {
    433     uint8 *flexport_scache_ptr;
    434     soc_scache_handle_t scache_handle;
    435     uint32 alloc_get = 0;
    436     uint32 alloc_size = 0;
    437     uint32 var_size = 0;
    438     soc_info_t *si = &SOC_INFO(unit);
    439     uint32 scache_offset=0;
    440     int rv = 0;
    441 
    442     alloc_size =  (sizeof(int) * _TH3_PHY_PORTS_PER_DEV)  + /* phy to logical*/
    443                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* logical to phy */
    444                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* max port speed */
    445                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* init port speed */
    446                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* num of lanes */
    447                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port fec*/
    448                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port phy lane config */
    449                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port link training */
    450                    (sizeof(pbmp_t));                        /* Disabled bitmap */
    451 
    452     alloc_get = alloc_size;
    453 
    454     SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0);
    455     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
    456                         FALSE, &alloc_get,
    457                         &flexport_scache_ptr,
    458                         SOC_FLEXPORT_WB_DEFAULT_VERSION,
    459                         NULL);
    460     if (rv == SOC_E_NOT_FOUND) {
    461         /* Probably Level1 */
    462         return SOC_E_NONE;
    463     }
    464     if (alloc_get != alloc_size) {
    465         /* Expected size doesn't match retrieved size */
    466         LOG_ERROR(BSL_LS_SOC_COMMON,
    467                 (BSL_META_U(unit,
    468                  "ERROR: scache memory for flexport size mismatch"
    469                  "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
    470         return SOC_E_INTERNAL;
    471     }
    472     if (NULL == flexport_scache_ptr) {
    473         LOG_ERROR(BSL_LS_SOC_COMMON,
    474                 (BSL_META_U(unit,
    475                  "ERROR: scache memory not allocated for flexport"
    476                  "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(),  __LINE__));
    477         return SOC_E_MEMORY;
    478     }
    479 
    480     /* Physical to logical port mapping */
    481     var_size = sizeof(int) * _TH3_PHY_PORTS_PER_DEV;
    482     sal_memcpy(&flexport_scache_ptr[scache_offset],
    483                si->port_p2l_mapping, var_size);
    484     scache_offset += var_size;
    485 
    486     var_size = sizeof(int) * _TH3_DEV_PORTS_PER_DEV;
    487 
    488     /* Logical to Physical port mapping */
    489     sal_memcpy(&flexport_scache_ptr[scache_offset],
    490                si->port_l2p_mapping, var_size);
    491     scache_offset += var_size;
    492 
    493     /* Max port speed */
    494     sal_memcpy(&flexport_scache_ptr[scache_offset],
    495                si->port_speed_max, var_size);
    496     scache_offset += var_size;
    497 
    498     /* Init port speed */
    499     sal_memcpy(&flexport_scache_ptr[scache_offset],
    500                si->port_init_speed, var_size);
    501     scache_offset += var_size;
    502 
    503     /* Num of lanes */
    504     sal_memcpy(&flexport_scache_ptr[scache_offset],
    505                si->port_num_lanes, var_size);
    506     scache_offset += var_size;
    507 
    508     /* Fec */
    509     sal_memcpy(&flexport_scache_ptr[scache_offset],
    510                si->port_fec_type, var_size);
    511     scache_offset += var_size;
    512 
    513     /* Phy Lane Config */
    514     sal_memcpy(&flexport_scache_ptr[scache_offset],
    515                si->port_phy_lane_config, var_size);
    516     scache_offset += var_size;
    517 
    518     /* Link Training */
    519     sal_memcpy(&flexport_scache_ptr[scache_offset],
    520                si->port_link_training, var_size);
    521     scache_offset += var_size;
    522 
    523     /* Disabled Port Bitmap */
    524     sal_memcpy(&flexport_scache_ptr[scache_offset],
    525                &si->all.disabled_bitmap,
    526                sizeof(pbmp_t));
    527     scache_offset += sizeof(pbmp_t);
    528 
    529     LOG_VERBOSE(BSL_LS_SOC_COMMON,
    530                 (BSL_META_U(unit,
    531                  "%s()[LINE:%d] \n"),FUNCTION_NAME(),  __LINE__));
    532 
    533     return SOC_E_NONE;
    534 }
    535 
    536 /*
    537  * Function:
    538  *      soc_th3_flexport_scache_recovery
    539  * Purpose:
    540  *      Recover Port info that maybe changed during flexport for Level 2 WB
    541  *
    542  * Warm Boot Version Map:
    543  *
    544  *  BCM_WB_VERSION_1_0
    545  *    port_p2l_mapping
    546  *    port_l2p_mapping
    547  *    port_speed_max
    548  *    port_init_speed
    549  *    port_num_lanes
    550  *    disabled_bitmap
    551  *
    552  * Parameters:
    553  *      unit - StrataSwitch unit number.
    554  * Returns:
    555  *      SOC_E_XXX
    556  */
    557 int soc_th3_flexport_scache_recovery(int unit)
    558 {
    559     uint32 alloc_get = 0;
    560     uint32 alloc_size = 0;
    561     int rv = SOC_E_NONE;
    562     uint8 *flexport_scache_ptr = NULL;
    563     soc_scache_handle_t scache_handle;
    564     uint32 scache_offset=0;
    565     uint32 var_size = 0;
    566     uint16 recovered_ver = 0;
    567     soc_info_t *si = &SOC_INFO(unit);
    568 
    569     alloc_size =  (sizeof(int) * _TH3_PHY_PORTS_PER_DEV)  + /* phy to logical*/
    570                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* logical to phy */
    571                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* max port speed */
    572                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* init port speed */
    573                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* num of lanes */
    574                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port fec*/
    575                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port phy lane config */
    576                    (sizeof(int) * _TH3_DEV_PORTS_PER_DEV) + /* port link training */
    577                    (sizeof(pbmp_t));                        /* Disabled bitmap */
    578 
    579     alloc_get = alloc_size;
    580 
    581     SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0);
    582     rv = soc_versioned_scache_ptr_get(unit, scache_handle,
    583                         FALSE, &alloc_get,
    584                         &flexport_scache_ptr,
    585                         SOC_FLEXPORT_WB_DEFAULT_VERSION,
    586                         &recovered_ver);
    587     if (SOC_FAILURE(rv)) {
    588         if ((rv == SOC_E_CONFIG) ||
    589             (rv == SOC_E_NOT_FOUND)) {
    590             /* warmboot file does not contain this
    591             * module, or the warmboot state does not exist.
    592             * in this case return SOC_E_NOT_FOUND
    593             */
    594             return SOC_E_NOT_FOUND;
    595         } else {
    596             /* Only Level2 - flexport treat this as a error */
    597             LOG_ERROR(BSL_LS_SOC_COMMON,
    598                      (BSL_META_U(unit,
    599                      "Failed to recover scache data - %s\n"),soc_errmsg(rv)));
    600             return rv;
    601         }
    602     }
    603     if (alloc_get != alloc_size) {
    604         /* Expected size doesn't match retrieved size */
    605         LOG_ERROR(BSL_LS_SOC_COMMON,
    606                 (BSL_META_U(unit,
    607                  "ERROR: scache recovery for flexport"
    608                  "%s()[LINE:%d] DONE \n"),
    609                   FUNCTION_NAME(),  __LINE__));
    610         return SOC_E_INTERNAL;
    611     }
    612 
    613     if (NULL == flexport_scache_ptr) {
    614         LOG_ERROR(BSL_LS_SOC_COMMON,
    615                 (BSL_META_U(unit,
    616                  "ERROR: scache recovery for flexport"
    617                  "%s()[LINE:%d] DONE \n"),
    618                   FUNCTION_NAME(),  __LINE__));
    619         return SOC_E_MEMORY;
    620     }
    621 
    622     /*Physical to logical port mapping */
    623     var_size = (sizeof(int) * _TH3_PHY_PORTS_PER_DEV);
    624     sal_memcpy(si->port_p2l_mapping,
    625                &flexport_scache_ptr[scache_offset],
    626                var_size);
    627     scache_offset += var_size;
    628 
    629     var_size = (sizeof(int) * _TH3_DEV_PORTS_PER_DEV);
    630 
    631     /*Logical to Physical port mapping*/
    632     sal_memcpy(si->port_l2p_mapping,
    633                &flexport_scache_ptr[scache_offset],
    634                var_size);
    635     scache_offset += var_size;
    636 
    637     /* Max port speed */
    638     sal_memcpy(_soc_th3_port_speed_cap[unit],
    639                &flexport_scache_ptr[scache_offset],
    640                var_size);
    641     scache_offset += var_size;
    642 
    643     /* Init port speed */
    644     sal_memcpy(si->port_speed_max,
    645                &flexport_scache_ptr[scache_offset],
    646                var_size);
    647     scache_offset += var_size;
    648 
    649     /* Num of lanes */
    650     sal_memcpy(si->port_num_lanes,
    651                &flexport_scache_ptr[scache_offset],
    652                var_size);
    653     scache_offset += var_size;
    654 
    655     /* Fec */
    656     sal_memcpy(si->port_fec_type,
    657                &flexport_scache_ptr[scache_offset],
    658                var_size);
    659     scache_offset += var_size;
    660 
    661     /* Phy Lane Config */
    662     sal_memcpy(si->port_phy_lane_config,
    663                &flexport_scache_ptr[scache_offset],
    664                var_size);
    665     scache_offset += var_size;
    666 
    667     /* Link Training */
    668     sal_memcpy(si->port_link_training,
    669                &flexport_scache_ptr[scache_offset],
    670                var_size);
    671     scache_offset += var_size;
    672 
    673     /* Disabled Port Bitmap */
    674     sal_memcpy(&si->all.disabled_bitmap,
    675            &flexport_scache_ptr[scache_offset],
    676            sizeof(pbmp_t));
    677     scache_offset += sizeof(pbmp_t);
    678 
    679     LOG_VERBOSE(BSL_LS_SOC_COMMON,
    680                 (BSL_META_U(unit,
    681                  "%s()[LINE:%d] \n"),FUNCTION_NAME(),  __LINE__));
    682 
    683     return SOC_E_NONE;
    684 }
    685 #endif /* BCM_WARM_BOOT_SUPPORT */
    686 
    687 void
    688 soc_th3_flexport_sw_dump(int unit)
    689 {
    690     int port, phy_port, mmu_port, pipe, pm, cosq, numq, uc_cosq, uc_numq;
    691     int max_speed, init_speed, num_lanes, fec, link_training, phy_lane_config;
    692     char  pfmt[SOC_PBMP_FMT_LEN];
    693 
    694     LOG_CLI((BSL_META_U(unit,
    695                             "  port(log/phy/mmu)  pipe  pm  lanes    "
    696                             "speed(Max)    fec  link train  lane config  "
    697                             "uc_Qbase/Numq mc_Qbase/Numq\n")));
    698     PBMP_ALL_ITER(unit, port) {
    699         pipe = SOC_INFO(unit).port_pipe[port];
    700         phy_port = SOC_INFO(unit).port_l2p_mapping[port];
    701         mmu_port = SOC_INFO(unit).port_p2m_mapping[phy_port];
    702         num_lanes = SOC_INFO(unit).port_num_lanes[port];
    703         pm = SOC_INFO(unit).port_serdes[port];
    704         max_speed = SOC_INFO(unit).port_speed_max[port];
    705         init_speed = SOC_INFO(unit).port_init_speed[port];
    706         cosq = SOC_INFO(unit).port_cosq_base[port];
    707         numq = SOC_INFO(unit).port_num_cosq[port];
    708         uc_cosq = SOC_INFO(unit).port_uc_cosq_base[port];
    709         uc_numq = SOC_INFO(unit).port_num_uc_cosq[port];
    710         fec = SOC_INFO(unit).port_fec_type[port];
    711         link_training = SOC_INFO(unit).port_link_training[port];
    712         phy_lane_config = SOC_INFO(unit).port_phy_lane_config[port];
    713 
    714         LOG_CLI((BSL_META_U(unit,
    715                             "  %4s(%3d/%3d/%3d)  %4d  %2d  %5d %7d(%7d) %3d"
    716                             "%10d %11d %6d/%-6d  %6d/%-6d\n"),
    717                 SOC_INFO(unit).port_name[port], port, phy_port, mmu_port,
    718                 pipe, pm, num_lanes, init_speed, max_speed, fec, link_training,
    719                 phy_lane_config, uc_cosq, uc_numq, cosq, numq));
    720     }
    721 
    722     LOG_CLI((BSL_META_U(unit,
    723                         "\n    Oversub Bitmap: %s"),
    724        SOC_PBMP_FMT(SOC_INFO(unit).oversub_pbm, pfmt)));
    725     LOG_CLI((BSL_META_U(unit,
    726                         "\n    Disabled Bitmap: %s \n"),
    727        SOC_PBMP_FMT(SOC_INFO(unit).all.disabled_bitmap, pfmt)));
    728 }
    729 
    730 /*
    731  * Function:
    732  *      soc_th3_port_mode_get
    733  * Description:
    734  *      Get port mode by giving first logical port of TSC4
    735  * Parameters:
    736  *      unit          - Device number
    737  *      port          - Logical port
    738  *      int*          - Port Mode
    739  *
    740  * Each TSC4 can be configured into following 5 mode:
    741  *   Lane number    0    1    2    3
    742  *   ------------  ---  ---  ---  ---
    743  *      quad port  25G  25G  25G  25G
    744  *   tri_012 port  25G  25G  50G   x
    745  *   tri_023 port  50G   x   25G  25G
    746  *      dual port  50G   x   50G   x
    747  *    single port  100G  x    x    x
    748  */
    749 int
    750 soc_th3_port_mode_get(int unit, int logical_port, int *mode)
    751 {
    752 #if 0
    753     
    754     soc_info_t *si;
    755     int lane;
    756     int port, first_phyport, phy_port;
    757     int num_lanes[_TH2_PORTS_PER_PBLK];
    758 
    759     si = &SOC_INFO(unit);
    760     first_phyport = si->port_l2p_mapping[logical_port];
    761 
    762     for (lane = 0; lane < _TH2_PORTS_PER_PBLK; lane++) {
    763         phy_port = first_phyport + lane;
    764         port = si->port_p2l_mapping[phy_port];
    765         if (port == -1 || SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) {
    766             num_lanes[lane] = -1;
    767         } else {
    768             num_lanes[lane] = si->port_num_lanes[port];
    769         }
    770     }
    771 
    772     if (num_lanes[0] == 4) {
    773         *mode = SOC_TH2_PORT_MODE_QUAD;
    774     } else if (num_lanes[0] == 2 && num_lanes[2] == 2) {
    775         *mode = SOC_TH2_PORT_MODE_DUAL;
    776     } else if (num_lanes[0] == 2 && num_lanes[2] == 1 && num_lanes[3] == 1) {
    777         *mode = SOC_TH2_PORT_MODE_TRI_023;
    778     } else if (num_lanes[0] == 1 && num_lanes[1] == 1 && num_lanes[2] == 2) {
    779         *mode = SOC_TH2_PORT_MODE_TRI_012;
    780     } else {
    781         *mode = SOC_TH2_PORT_MODE_SINGLE;
    782     }
    783 #endif
    784     return SOC_E_NONE;
    785 }
    786 
    787 #endif /* BCM_TOMAHAWK3_SUPPORT */