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

maverick2_tdm.c (92696B)


      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:        maverick2_tdm.c
      8  * Purpose:
      9  * Requires:
     10  */
     11 
     12 
     13 #include <shared/bsl.h>
     14 #include <soc/tdm/core/tdm_top.h>
     15 
     16 #include <soc/defs.h>
     17 #include <soc/mem.h>
     18 
     19 #if defined(BCM_MAVERICK2_SUPPORT)
     20 #include <soc/maverick2.h>
     21 #include <soc/maverick2_tdm.h>
     22 #include <soc/tdm/maverick2/tdm_mv2_defines.h>
     23 
     24 
     25 /*** START SDK API COMMON CODE ***/
     26 
     27 /*! @fn void _soc_mv2_tdm_print_port_map(
     28         int unit,
     29         soc_port_map_type_t *port_map)
     30     @param unit Chip unit number.
     31     @param port_map Pointer to a soc_port_map_type_t struct variable.
     32     @brief Debug API to print soc_port_map_type_t
     33  */
     34 void
     35 _soc_mv2_tdm_print_port_map(int unit, soc_port_map_type_t *port_map)
     36 {
     37     int port;
     38     int is_hg2, is_ovs, is_mgm;
     39     int speed, phy_port, idb_port, mmu_port, num_lanes, pblk;
     40     int phy_bmap, p2l_map, m2p_map;
     41 
     42     for (port = 0; port < MV2_NUM_EXT_PORTS; port++) {
     43         is_mgm = SOC_PBMP_MEMBER(port_map->management_pbm, port) ? 1 : 0;
     44         if ((is_mgm == 1) || (port_map->log_port_speed[port] > 0)) {
     45             speed     = is_mgm ? 10 : port_map->log_port_speed[port]/1000;
     46             phy_port  = port_map->port_l2p_mapping[port];
     47             idb_port  = port_map->port_l2i_mapping[port];
     48             mmu_port  = port_map->port_p2m_mapping[phy_port];
     49             num_lanes = port_map->port_num_lanes[port];
     50             pblk      = port_map->port_p2PBLK_inst_mapping[phy_port];
     51             phy_bmap  = SOC_PBMP_MEMBER(port_map->physical_pbm,
     52                                         phy_port) ? 1 : 0;
     53             is_hg2    = SOC_PBMP_MEMBER(port_map->hg2_pbm,
     54                                         port) ? 1 : 0;
     55             is_ovs    = SOC_PBMP_MEMBER(port_map->oversub_pbm, port) ? 1 : 0;
     56             p2l_map   = port_map->port_p2l_mapping[phy_port];
     57             m2p_map   = port_map->port_m2p_mapping[mmu_port];
     58             LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
     59                                 "log_port=%3d phy_port=%3d speed=%3dG "
     60                                 "%s %s idb_port=%3d mmu_port=%3d "
     61                                 "num_lanes=%1d pblk=%3d phy_bmap=%1d "
     62                                 "p2l_map=%3d "),
     63                                 port, phy_port, speed,
     64                                 (is_hg2==1) ? "HG2" : "ETH",
     65                                 (is_ovs==1) ? "OVS" : " LR",
     66                                 idb_port, mmu_port, num_lanes, pblk,
     67                                 phy_bmap, p2l_map));
     68             LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "m2p_map=%3d %s\n"),
     69                                 m2p_map, (is_mgm==1) ? "MGM" : "" ));
     70         }
     71     }
     72 
     73 }
     74 
     75 
     76 /*! @fn void _soc_mv2_tdm_print_tdm_info(
     77         int unit,
     78         soc_tdm_schedule_t *tdm_info,
     79         int hpipe,
     80         int is_ing)
     81     @param unit Chip unit number.
     82     @param tdm_info Pointer to a soc_tdm_schedule_t struct variable.
     83     @param hpipe Half Pipe.
     84     @param is_ing distinguishes between IP and EP schedulers
     85     @brief Debug API to print soc_tdm_schedule_t
     86  */
     87 void
     88 _soc_mv2_tdm_print_tdm_info(int unit, soc_tdm_schedule_t *tdm_info,
     89                             int hpipe, int is_ing)
     90 {
     91     int cal_len, j, m;
     92 
     93     if (hpipe == 0) {
     94         for (cal_len = tdm_info->cal_len; cal_len > 0; cal_len--) {
     95             if (tdm_info->linerate_schedule[cal_len - 1] != MV2_NUM_EXT_PORTS) {
     96                 break;
     97             }
     98         }
     99 
    100         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    101                     "\tMAIN CALENDAR: cal_len=%3d \n"),
    102                     cal_len ));
    103         for (j=0; j < cal_len; j++) {
    104             if (j%16==0) {
    105                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    106                             "\n %3d : %3d\t"),
    107                             j, j+15));
    108             }
    109             LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "%5d"),
    110                         tdm_info->linerate_schedule[j]));
    111         }
    112     }
    113 
    114     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    115                 "\n\n\tOVS TABLES: HPIPE= %3d \n"),
    116                 hpipe ));
    117     for (j=0; j< tdm_info->num_ovs_groups; j++) {
    118         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\nOVS_CAL[%d]:\t"),
    119                     j ));
    120         for (m=0; m< tdm_info->ovs_group_len; m++) {
    121             if (tdm_info->oversub_schedule[j][m] != MV2_NUM_EXT_PORTS) {
    122                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "%d\t"),
    123                             tdm_info->oversub_schedule[j][m] ));
    124             } else {
    125                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "---\t")));
    126             }
    127         }
    128     }
    129 
    130     if (is_ing == 1) {
    131         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    132                     "\n\n\tPKT_SCHEDULER: HPIPE= %3d \n"),
    133                     hpipe ));
    134         for (j=0; j<tdm_info->pkt_sch_or_ovs_space_len; j++) {
    135             if (j%16==0) {
    136                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    137                             "\n %3d : %3d\t"),
    138                             j, j+15 ));
    139             }
    140             if (tdm_info->pkt_sch_or_ovs_space[0][j] != MV2_NUM_EXT_PORTS) {
    141                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\t%d"),
    142                             tdm_info->pkt_sch_or_ovs_space[0][j] ));
    143             } else {
    144                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\t---")));
    145             }
    146         }
    147     }
    148     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,"\n")));
    149 }
    150 
    151 
    152 /*! @fn void _soc_mv2_tdm_print_port_resource(
    153         int unit,
    154         soc_port_resource_t *port_info,
    155         int entry_num)
    156     @param unit Chip unit number.
    157     @param port_info Pointer to a soc_port_resource_t struct variable.
    158     @param entry_num entry number.
    159     @brief Debug API to print soc_port_resource_t
    160  */
    161 void
    162 _soc_mv2_tdm_print_port_resource(int unit,
    163                                  soc_port_resource_t *port_info,
    164                                  int entry_num)
    165 {
    166     int is_hg2, lane;
    167 
    168     is_hg2 = 0;
    169     if (port_info->encap == _SHR_PORT_ENCAP_HIGIG2) {
    170         is_hg2=1;
    171     }
    172 
    173     if (port_info->physical_port == -1) {
    174         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    175                             "nport=%3d DOWN: "
    176                             "logical_port=%3d physical_port=%3d\n"),
    177                             entry_num, port_info->logical_port,
    178                             port_info->physical_port));
    179     } else {
    180         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    181                             "nport=%3d  UP : "
    182                             "logical_port=%3d physical_port=%3d mmu_port=%3d "),
    183                             entry_num, port_info->logical_port,
    184                             port_info->physical_port,
    185                             port_info->mmu_port ));
    186         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    187                             "idb_port=%3d pipe=%3d speed=%3d num_lanes=%1d "
    188                             "%s  %s\n"),
    189                             port_info->idb_port,
    190                             port_info->pipe, port_info->speed/1000,
    191                             port_info->num_lanes,
    192                             (is_hg2==1) ? "HG2": "ETH",
    193                             (port_info->oversub==1) ? "OVS": " LR" ));
    194         for (lane = 0; lane < SOC_PORT_RESOURCE_LANES_MAX; lane++) {
    195             if (port_info->lane_info[lane] != NULL) {
    196                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    197                                     "nport=%3d lane_info[%d]: pgw=%3d"
    198                                     "xlp=%3d port_index=%3d\n"),
    199                                     entry_num, lane,
    200                                     port_info->lane_info[lane]->pgw,
    201                                     port_info->lane_info[lane]->xlp,
    202                                     port_info->lane_info[lane]->port_index));
    203             }
    204         }
    205     }
    206 }
    207 
    208 
    209 /*! @fn void _soc_mv2_tdm_print_schedule_state(
    210         int unit,
    211         soc_port_schedule_state_t *sch_info)
    212     @param unit Chip unit number.
    213     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
    214     @brief Debug API to print sch_info
    215  */
    216 void
    217 _soc_mv2_tdm_print_schedule_state(int unit,
    218                                   soc_port_schedule_state_t *sch_info)
    219 {
    220     int i, pipe, hpipe, print_tdm;
    221     soc_tdm_schedule_t *tdm_schedule;
    222 
    223     print_tdm = 1;
    224 
    225     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    226                         "\n\nPRINTING soc_port_schedule_state_t \n")));
    227     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    228                         "nport= %3d\n"),
    229                         sch_info->nport));
    230     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    231                         "frequency= %4dMHz\n"),
    232                         sch_info->frequency));
    233     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    234                         "bandwidth= %4d\n"),
    235                         sch_info->bandwidth));
    236     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    237                         "io_bandwidth= %4d\n"),
    238                         sch_info->io_bandwidth));
    239     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    240                         "lossless= %1d\n"),
    241                         sch_info->lossless));
    242     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    243                         "is_flexport= %1d\n"),
    244                         sch_info->is_flexport));
    245 
    246     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    247                         "\nPRINTING soc_port_schedule_state_t"
    248                         "::[in_port_map]\n")));
    249     _soc_mv2_tdm_print_port_map(unit, &sch_info->in_port_map);
    250 
    251     if (sch_info->is_flexport == 1) {
    252         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    253                             "\nPRINTING soc_port_schedule_state_t"
    254                             "::[out_port_map]\n")));
    255         _soc_mv2_tdm_print_port_map(unit, &sch_info->out_port_map);
    256     }
    257 
    258     if (print_tdm == 1) {
    259         for (pipe = 0; pipe< NUM_PIPE(unit); pipe++) {
    260              LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    261                                  "\n====== TDM Tables PIPE=%1d INGRESS\n"),
    262                                  pipe));
    263             for (hpipe = 0; hpipe< MAX_SCH_SLICES; hpipe++) {
    264                 tdm_schedule = &(sch_info->tdm_ingress_schedule_pipe[
    265                                  pipe].tdm_schedule_slice[hpipe]);
    266                 _soc_mv2_tdm_print_tdm_info(unit, tdm_schedule, hpipe, 1);
    267             }
    268             LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    269                         "\n====== TDM Tables PIPE=%1d  EGRESS\n"),
    270                         pipe));
    271             for (hpipe = 0; hpipe< MAX_SCH_SLICES; hpipe++) {
    272                 tdm_schedule = &(sch_info->tdm_egress_schedule_pipe[
    273                                  pipe].tdm_schedule_slice[hpipe]);
    274                 _soc_mv2_tdm_print_tdm_info(unit, tdm_schedule, hpipe, 0);
    275             }
    276         }
    277     }
    278 
    279     if ((sch_info->is_flexport == 1) && (sch_info->nport > 0)) {
    280         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    281                             "\n====== FLEXPORT RESOURCES ===== "
    282                             "num entries= %d = \n"),
    283                             sch_info->nport));
    284         for (i = 0; i < sch_info->nport; i++) {
    285             _soc_mv2_tdm_print_port_resource(unit, &sch_info->resource[i], i);
    286         }
    287     }
    288 }
    289 
    290 
    291 /*! @fn void soc_mv2_tdm_get_port_ratio(
    292         int unit,
    293         soc_port_schedule_state_t *sch_info,
    294         int pm_num,
    295         int *pm_mode,
    296         int prev_or_new)
    297     @param unit   Chip unit number.
    298     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
    299     @param pm_num PM block_id (0 to 31)
    300     @param *pm_mode mode to be returned.
    301     @param prev_or_new function looks in in_port_map or out_port_map.
    302     @brief Help function to get port ratio.
    303  */
    304 
    305 /*
    306  * #1   single: 100  -   x  -   x  -   x  SOC_MV2_PORT_RATIO_SINGLE
    307  * #2   single:  40  -   x  -   x  -   x  SOC_MV2_PORT_RATIO_TRI_023_2_1_1
    308  * #3   dual:    50  -   x  -  50  -   x  SOC_MV2_PORT_RATIO_DUAL_1_1
    309  * #4   dual:    40  -   x  -  40  -   x  SOC_MV2_PORT_RATIO_DUAL_1_1
    310  * #5   dual:    20  -   x  -  20  -   x  SOC_MV2_PORT_RATIO_DUAL_1_1
    311  * #6   dual:    40  -   x  -  20  -   x  SOC_MV2_PORT_RATIO_DUAL_2_1
    312  * #7   dual:    20  -   x  -  40  -   x  SOC_MV2_PORT_RATIO_DUAL_1_2
    313  * #8   tri:     50  -   x  - 25/x - 25/x SOC_MV2_PORT_RATIO_TRI_023_2_1_1
    314  * #9   tri:     20  -   x  - 10/x - 10/x SOC_MV2_PORT_RATIO_TRI_023_2_1_1
    315  * #10  tri:     40  -   x  - 10/x - 10/x SOC_MV2_PORT_RATIO_TRI_023_4_1_1
    316  * #11  tri:    25/x - 25/x -  50  -   x  SOC_MV2_PORT_RATIO_TRI_012_1_1_2
    317  * #12  tri:    10/x - 10/x -  20  -   x  SOC_MV2_PORT_RATIO_TRI_012_1_1_2
    318  * #13  tri:    10/x - 10/x -  40  -   x  SOC_MV2_PORT_RATIO_TRI_012_1_1_4
    319  * #14  quad:   25/x - 25/x - 25/x - 25/x SOC_MV2_PORT_RATIO_QUAD
    320  * #15  quad:   10/x - 10/x - 10/x - 10/x SOC_MV2_PORT_RATIO_QUAD
    321  */
    322 void
    323 soc_mv2_tdm_get_port_ratio(int unit,
    324                             soc_port_schedule_state_t *sch_info,
    325                             int pm_num, int *pm_mode, int prev_or_new)
    326 {
    327     int port, phy_port_base, lane, mode = 0;
    328     int num_lanes[MAVERICK2_TDM_PORTS_PER_PBLK];
    329     int speed_max[MAVERICK2_TDM_PORTS_PER_PBLK];
    330     soc_port_map_type_t *port_map;
    331     int l_speed = 0, l_num_lanes = 0;
    332 
    333     sal_memset(num_lanes, 0, MAVERICK2_TDM_PORTS_PER_PBLK*sizeof(int));
    334     sal_memset(speed_max, 0, MAVERICK2_TDM_PORTS_PER_PBLK*sizeof(int));
    335 
    336     if (prev_or_new == 1) {
    337         port_map = &(sch_info->in_port_map);
    338     } else {
    339         port_map = &(sch_info->out_port_map);
    340     }
    341 
    342     phy_port_base = 1 + (pm_num * MAVERICK2_TDM_PORTS_PER_PBLK);
    343     for (lane = 0; lane < MAVERICK2_TDM_PORTS_PER_PBLK; lane += 2) {
    344         port = port_map->port_p2l_mapping[phy_port_base + lane];
    345         if ( (port == -1) || (port_map->log_port_speed[port]==0) ) {
    346             num_lanes[lane] = -1;
    347             speed_max[lane] = -1;
    348         } else {
    349             soc_mv2_tdm_get_log_port_speed(unit, sch_info, port,
    350                 prev_or_new, &l_speed, &l_num_lanes);
    351             num_lanes[lane] = l_num_lanes;
    352             speed_max[lane] = l_speed;
    353         }
    354     }
    355 
    356     if (num_lanes[0] == 4) {
    357         mode = SOC_MV2_PORT_RATIO_SINGLE;
    358     } else if (num_lanes[0] == 2 && num_lanes[2] == 2) {
    359         if (speed_max[0] == speed_max[2]) {
    360             mode = SOC_MV2_PORT_RATIO_DUAL_1_1;
    361         } else if (speed_max[0] > speed_max[2]) {
    362             mode = SOC_MV2_PORT_RATIO_DUAL_2_1;
    363         } else {
    364             mode = SOC_MV2_PORT_RATIO_DUAL_1_2;
    365         }
    366     } else if (num_lanes[0] == 2) {
    367         if (num_lanes[2] == -1) {
    368             mode = SOC_MV2_PORT_RATIO_DUAL_1_1;
    369         } else {
    370             mode = (speed_max[0] == 20000 || speed_max[0] == 21000 ||
    371                     speed_max[0] == 50000 || speed_max[0] == 53000) ?
    372                    SOC_MV2_PORT_RATIO_TRI_023_2_1_1 :
    373                    SOC_MV2_PORT_RATIO_TRI_023_4_1_1;
    374         }
    375     } else if (num_lanes[2] == 2) {
    376         if (num_lanes[0] == -1) {
    377             mode = SOC_MV2_PORT_RATIO_DUAL_1_1;
    378         } else {
    379             mode = (speed_max[2] == 20000 || speed_max[2] == 21000 ||
    380                     speed_max[2] == 50000 || speed_max[2] == 53000) ?
    381                    SOC_MV2_PORT_RATIO_TRI_012_1_1_2 :
    382                    SOC_MV2_PORT_RATIO_TRI_012_1_1_4;
    383         }
    384     } else {
    385         mode = SOC_MV2_PORT_RATIO_QUAD;
    386     }
    387 
    388     *pm_mode = mode;
    389 }
    390 
    391 
    392 /*! @fn void _soc_mv2_tdm_get_pipe_map(
    393         int unit,
    394         soc_port_schedule_state_t *sch_info,
    395         uint32 *pipe_map)
    396     @param unit Chip unit number.
    397     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
    398     @param pipe_map Returned pipe map.
    399     @brief Returns pipe bitmap.
    400  * Description:
    401         For init, a pipe gets 1 if exists active port within that pipe.
    402         For flexport, a pipe gets 1 if exists flexed port within that pipe.
    403  */
    404 void
    405 _soc_mv2_tdm_get_pipe_map(int unit,
    406                           soc_port_schedule_state_t *sch_info,
    407                           uint32 *pipe_map)
    408 {
    409     uint32 port, pipe, i, pipe_bmap = 0;
    410 
    411     if (sch_info->is_flexport == 0) { /* Init */
    412         for (port = 0; port < MAVERICK2_TDM_PHY_PORTS_PER_DEV; port++) {
    413             if (sch_info->out_port_map.log_port_speed[port] > 0 ) {
    414                 pipe = port / MAVERICK2_TDM_PHY_PORTS_PER_PIPE;
    415                 pipe_bmap |= 1 << pipe;
    416             }
    417         }
    418     } else { /* FlexPort */
    419         for (i = 0; i < sch_info->nport; i++) {
    420             port = sch_info->resource[i].logical_port;
    421             pipe = port / MAVERICK2_TDM_PHY_PORTS_PER_PIPE;
    422             pipe_bmap |= 1 << pipe;
    423         }
    424     }
    425     *pipe_map = pipe_bmap;
    426 }
    427 
    428 
    429 /*! @fn void _soc_mv2_tdm_get_ovs_pipe_map(
    430         int unit,
    431         soc_port_schedule_state_t *sch_info,
    432         uint32 *ovs_pipe_map)
    433     @param unit Chip unit number.
    434     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
    435     @param ovs_pipe_map Returned pipe map.
    436     @brief Returns OVS pipe bitmap.
    437  * Description:
    438         For init, a pipe gets 1 if exists oversub port within that pipe.
    439  */
    440 void
    441 _soc_mv2_tdm_get_ovs_pipe_map(int unit,
    442                               soc_port_schedule_state_t *sch_info,
    443                               uint32 *ovs_pipe_map)
    444 {
    445     uint32 port, pipe, pipe_bmap = 0;
    446     int is_ovs_map;
    447 
    448     if (sch_info->is_flexport == 0) { /* Init */
    449         for (port = 0; port < MAVERICK2_TDM_PHY_PORTS_PER_DEV; port++) {
    450             is_ovs_map = SOC_PBMP_MEMBER(sch_info->out_port_map.oversub_pbm,
    451                                          port) ? 1 : 0;
    452             if ((sch_info->out_port_map.log_port_speed[port] > 0) &&
    453                 (1 == is_ovs_map) ) {
    454                 pipe = port / MAVERICK2_TDM_PHY_PORTS_PER_PIPE;
    455                 pipe_bmap |= 1 << pipe;
    456             }
    457         }
    458     }
    459     *ovs_pipe_map = pipe_bmap;
    460 }
    461 
    462 
    463 /*! @fn int _soc_mv2_tdm_get_speed_ovs_class(
    464         int unit,
    465         int speed)
    466     @param unit   Chip unit number.
    467     @param speed Speed
    468     @return port_speed_class to be returned
    469     @brief Help function to determine ovs class
    470  * Description:
    471     Oversubscription speed group class encoding
    472         0 - 0
    473         1 - 2 (10G)
    474         2 - 4 (20G)
    475         3 - 5 (25G)
    476         4 - 8 (40G)
    477         5 - 10 (50G)
    478         6 - 20 (100G)
    479  */
    480 int
    481 _soc_mv2_tdm_get_speed_ovs_class(int unit, int speed)
    482 {
    483     int speed_class = 0;
    484     uint16 dev_id = 0;
    485     uint8  rev_id = 0;
    486 
    487     if (speed >= 40000) {
    488         if (speed >= 100000) {
    489             speed_class = 6;
    490         } else if (speed >= 50000) {
    491             speed_class = 5;
    492         } else {
    493             speed_class = 4;
    494         }
    495     } else {
    496         if (speed >= 25000) {
    497             speed_class = 3;
    498         } else if (speed >= 20000) {
    499             speed_class = 2;
    500         } else if (speed >= 10000) {
    501             speed_class = 1;
    502         } else if (speed >= 1000) {
    503             /* take 1G speed as 10G in MV2 for ovsb port */
    504             speed_class = 1;
    505         }
    506     }
    507 
    508     soc_cm_get_id(unit, &dev_id, &rev_id);
    509     if (((dev_id & TDM_MV2_DEV_ID_MASK) ==
    510         (TDM_MV2_DEV_ID_BCM56770 & TDM_MV2_DEV_ID_MASK)) &&
    511         (speed_class == 1)) {
    512         speed_class = 3;
    513     }
    514 
    515     return (speed_class);
    516 }
    517 
    518 
    519 /*! @fn int _soc_mv2_tdm_check_is_hsp_port_e(
    520         int unit,
    521         int speed)
    522     @param unit   Chip unit number.
    523     @param speed Speed
    524     @return 1->high speed port; 0->not high speed port;
    525     @brief To determine the same port spacing for egress pipe
    526  * Description:
    527     Oversubscription speed group class encoding
    528         0 - 0
    529         1 - 2 (10G)
    530         2 - 4 (20G)
    531         3 - 5 (25G)
    532         4 - 8 (40G)
    533         5 - 10 (50G)
    534         6 - 20 (100G)
    535  */
    536 STATIC int
    537 _soc_mv2_tdm_check_is_hsp_port_e(int unit, int speed)
    538 {
    539     int speed_class, port_is_hsp = 0;
    540 
    541     speed_class = _soc_mv2_tdm_get_speed_ovs_class(unit, speed);
    542     switch (speed_class) {
    543         case 2: /* 20G */
    544         case 4: /* 40G */
    545         case 5: /* 50G */
    546         case 6: /* 100G */
    547             port_is_hsp = 1;
    548             break;
    549         default:
    550             port_is_hsp = 0;
    551             break;
    552     }
    553 
    554     return (port_is_hsp);
    555 }
    556 
    557 /*! @fn int _soc_mv2_tdm_check_mgmt_enable(
    558         int unit,
    559         soc_port_schedule_state_t *sch_info)
    560     @param unit   Chip unit number.
    561     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
    562     @return 1-> management port enabled; 0 -> otherwise
    563     @brief Help function to determine if management port is enabled.
    564  */
    565 STATIC int
    566 _soc_mv2_tdm_check_mgmt_enable(int unit,
    567                                soc_port_schedule_state_t *sch_info)
    568 {
    569     int port;
    570     int mgmt_port_cnt = 0;
    571     int mgmt_port_en = 0;
    572 
    573     SOC_PBMP_ITER(sch_info->in_port_map.management_pbm, port) {
    574         mgmt_port_cnt++;
    575     }
    576     if (mgmt_port_cnt>0) {
    577         mgmt_port_en = 1;
    578     }
    579 
    580     return (mgmt_port_en);
    581 }
    582 
    583 /*! @fn int _soc_mv2_tdm_check_2nd_mgmt_enable(
    584         int unit,
    585         soc_port_schedule_state_t *sch_info)
    586     @param unit   Chip unit number.
    587     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
    588     @return 1-> 2nd management port enabled; 0 -> otherwise
    589     @brief Help function to determine if 2nd management port is enabled.
    590  */
    591 STATIC int
    592 _soc_mv2_tdm_check_2nd_mgmt_enable(int unit,
    593                                    soc_port_schedule_state_t *sch_info)
    594 {
    595     int port;
    596     int mgmt_port_cnt = 0;
    597     int mgmt_2nd_port_en = 0;
    598 
    599     SOC_PBMP_ITER(sch_info->in_port_map.management_pbm, port) {
    600         mgmt_port_cnt++;
    601     }
    602     if (mgmt_port_cnt>1) {
    603         mgmt_2nd_port_en = 1;
    604     }
    605 
    606     return (mgmt_2nd_port_en);
    607 }
    608 
    609 
    610 /*! @fn int _soc_mv2_tdm_get_same_port_spacing_e(
    611         int unit,
    612         int speed)
    613     @param unit   Chip unit number.
    614     @param speed Speed
    615     @return same port spacing of the given speed port
    616     @brief To determine the same port spacing for egress pipe
    617            - 8 for high speed port
    618            - 14 for not high speed port
    619  */
    620 int
    621 _soc_mv2_tdm_get_same_port_spacing_e(int unit, int speed)
    622 {
    623     int port_same_spacing = 0;
    624 
    625     if (_soc_mv2_tdm_check_is_hsp_port_e(unit, speed) == 1) {
    626         port_same_spacing = 8;
    627     } else {
    628         port_same_spacing = 14;
    629     }
    630 
    631     return (port_same_spacing);
    632 }
    633 
    634 
    635 /*! @fn int _soc_mv2_tdm_calculation(
    636         int unit,
    637         soc_port_schedule_state_t *sch_info)
    638     @param unit Chip unit number.
    639     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
    640     @brief API to calculate TDM tables.
    641  */
    642 int
    643 _soc_mv2_tdm_calculation(int unit, soc_port_schedule_state_t *sch_info)
    644 {
    645     int i, j, pm_num, phy_port, lgc_port, phy_port_tmp;
    646     int pipe, hpipe;
    647     int lane, group, index;
    648     int mgmt_pm_hg = 0, mgmt_mode = 0;
    649     int tdm_idb_cal_len, tdm_mmu_cal_len, tdm_pipe_grp_num, tdm_pipe_grp_len;
    650     int *tdm_idb_pipe_main, *tdm_mmu_pipe_main;
    651     int **tdm_pipe_ovs_group;
    652     tdm_soc_t _chip_pkg;
    653     tdm_mod_t *_tdm_pkg;
    654     uint32 port_speeds[MAVERICK2_TDM_PHY_PORTS_PER_DEV];
    655     uint32 port_states[MAVERICK2_TDM_PHY_PORTS_PER_DEV];
    656     int l_speed = 0, l_num_lanes = 0, prev_or_new = 1;
    657 
    658     uint16 dev_id = 0;
    659     uint8  rev_id = 0;
    660 
    661     soc_cm_get_id(unit, &dev_id, &rev_id);
    662     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    663                                     "mv2_tdm_dev_id 0x%0x\n"),
    664                                     dev_id));
    665 
    666     sal_memset(port_speeds, 0, MAVERICK2_TDM_PHY_PORTS_PER_DEV*sizeof(uint32));
    667     sal_memset(port_states, 0, MAVERICK2_TDM_PHY_PORTS_PER_DEV*sizeof(uint32));
    668 
    669     /* Remap input speeds to ETH bitrates */
    670     soc_maverick2_port_schedule_speed_remap(unit, sch_info);
    671 
    672     /* Set port states and speeds */
    673     for (lgc_port = 0; lgc_port < MAVERICK2_TDM_PHY_PORTS_PER_DEV; lgc_port++) {
    674         phy_port = sch_info->in_port_map.port_l2p_mapping[lgc_port];
    675         if (phy_port < MAVERICK2_TDM_PHY_PORTS_PER_DEV) {
    676             if (sch_info->in_port_map.log_port_speed[lgc_port] > 0 ) {
    677                 if (SOC_PBMP_MEMBER(sch_info->in_port_map.hg2_pbm,lgc_port)) {
    678                     port_states[phy_port] =
    679                         SOC_PBMP_MEMBER(sch_info->in_port_map.oversub_pbm,
    680                                         lgc_port) ? PORT_STATE__OVERSUB_HG :
    681                                                     PORT_STATE__LINERATE_HG;
    682                 } else {
    683                     port_states[phy_port] =
    684                         SOC_PBMP_MEMBER(sch_info->in_port_map.oversub_pbm,
    685                                         lgc_port) ? PORT_STATE__OVERSUB :
    686                                                     PORT_STATE__LINERATE;
    687                 }
    688 
    689                 soc_mv2_tdm_get_log_port_speed(unit, sch_info, lgc_port,
    690                     prev_or_new, &l_speed, &l_num_lanes);
    691                 for (lane = 1; lane < l_num_lanes; lane++) {
    692                     phy_port_tmp = phy_port + lane;
    693                     if (phy_port_tmp < MAVERICK2_TDM_PHY_PORTS_PER_DEV) {
    694                         port_states[phy_port_tmp] = PORT_STATE__COMBINE;
    695                     }
    696                 }
    697                 port_speeds[phy_port] = l_speed;
    698             }
    699             if (SOC_PBMP_MEMBER(sch_info->in_port_map.management_pbm, lgc_port)) {
    700                     if (SOC_PBMP_MEMBER(sch_info->in_port_map.hg2_pbm,
    701                                         lgc_port)) {
    702                         mgmt_pm_hg = 1; /* HIGIG2 : ETHERNET */
    703                     }
    704                     port_speeds[phy_port] = 0;
    705                     port_states[phy_port] = 0;
    706             }
    707         }
    708     }
    709     if (_soc_mv2_tdm_check_mgmt_enable(unit, sch_info) == 1) {
    710         mgmt_mode = (mgmt_pm_hg == 1) ? 2 : 0;
    711     } else {
    712         mgmt_mode = 1;
    713     }
    714     /* Print input config */
    715     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
    716         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    717                             "frequency: %dMHz\n"),
    718                             sch_info->frequency));
    719         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    720                             "%8s%8s%8s\n"),
    721                             "port", "speed", "state"));
    722         for (phy_port = 0; phy_port < MAVERICK2_TDM_PHY_PORTS_PER_DEV;
    723              phy_port++) {
    724             LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    725                                 "%8d%8d%8d\n"),
    726                                 phy_port, port_speeds[phy_port]/1000,
    727                                 port_states[phy_port]));
    728         }
    729         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\n")));
    730     }
    731     /* Initialize input variables for SW TDM Generation:
    732        -- unit
    733        -- dev_id
    734        -- num_ext_ports
    735        -- state
    736        -- speed
    737        -- clk_freq
    738        -- flex_port_en: 0->init, 1->flex
    739        -- mgmt_pm_hg: 0->Ethernet mgmt, 1->HiGig2 mgmt
    740        -- mgmt_mode:
    741                        0 -> Enable Etherner management port (default)
    742                        1 -> Disable management port
    743                        2 -> Enable HiGig management port
    744     */
    745     sal_memset(&_chip_pkg, 0, sizeof(tdm_soc_t));
    746     _chip_pkg.unit          = unit;
    747     _chip_pkg.dev_id        = dev_id;
    748     _chip_pkg.num_ext_ports = MV2_NUM_EXT_PORTS;
    749     _chip_pkg.state = sal_alloc((_chip_pkg.num_ext_ports)*sizeof(int),
    750                                 "port state list");
    751     if (_chip_pkg.state == NULL) {
    752         return SOC_E_MEMORY;
    753     }
    754     _chip_pkg.speed = sal_alloc((_chip_pkg.num_ext_ports)*sizeof(int),
    755                                 "port speed list");
    756     if (_chip_pkg.speed == NULL) {
    757         sal_free(_chip_pkg.state);
    758         return SOC_E_MEMORY;
    759     }
    760     for (index = 0; index < _chip_pkg.num_ext_ports; index++) {
    761         _chip_pkg.state[index] = 0;
    762         _chip_pkg.speed[index] = 0;
    763     }
    764     for (index = 0; index < _chip_pkg.num_ext_ports &&
    765                     index < MAVERICK2_TDM_PHY_PORTS_PER_DEV; index++) {
    766         _chip_pkg.state[index] = port_states[index];
    767         _chip_pkg.speed[index] = port_speeds[index];
    768     }
    769     /* Shift port state to left one position; required by C_TDM */
    770     for (index = 1; index < _chip_pkg.num_ext_ports; index++) {
    771         _chip_pkg.state[index - 1] = _chip_pkg.state[index];
    772     }
    773     _chip_pkg.clk_freq               = sch_info->frequency;
    774     _chip_pkg.flex_port_en           = sch_info->is_flexport;
    775     _chip_pkg.pmap                   = 0;
    776     _chip_pkg.pmap_num_modules       = 0;
    777     _chip_pkg.pmap_num_lanes         = 0;
    778     _chip_pkg.pm_num_phy_modules     = 0;
    779     _chip_pkg.lr_idx_limit           = 0;
    780     _chip_pkg.tvec_size              = 0;
    781     _chip_pkg.soc_vars.mv2.mgmt_pm_hg= mgmt_pm_hg;
    782     _chip_pkg.soc_vars.mv2.mgmt_mode = mgmt_mode;
    783 
    784     /* Populate TDM tables by invoking SW TDM API */
    785     /* coverity[dont_call : FALSE] */
    786     _tdm_pkg = _soc_set_tdm_tbl(SOC_SEL_TDM(&_chip_pkg));
    787 
    788     /* Free the memory allocated to port states and speeds */
    789     sal_free(_chip_pkg.state);
    790     sal_free(_chip_pkg.speed);
    791 
    792     /* Copy TDM result into output structure */
    793     if (_tdm_pkg == NULL) {
    794         LOG_CLI((BSL_META_U(unit,
    795                 "Unsupported config for TDM calendar generation\n")));
    796         return SOC_E_FAIL;
    797     } else {
    798         /* IDB calendar (0-3), MMU calendar (4-7) */
    799         for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
    800             switch (pipe) {
    801                 /* IDB_PIPE_0, MMU_PIPE_0 */
    802                 /*
    803                 case 0:
    804                     tdm_pipe_ovs_group = _tdm_pkg->_chip_data.cal_0.cal_grp;
    805                     tdm_pipe_grp_num   = _tdm_pkg->_chip_data.cal_0.grp_num;
    806                     tdm_pipe_grp_len   = _tdm_pkg->_chip_data.cal_0.grp_len;
    807                     tdm_idb_pipe_main  = _tdm_pkg->_chip_data.cal_0.cal_main;
    808                     tdm_idb_cal_len    = _tdm_pkg->_chip_data.cal_0.cal_len;
    809                     tdm_mmu_pipe_main  = _tdm_pkg->_chip_data.cal_4.cal_main;
    810                     tdm_mmu_cal_len    = _tdm_pkg->_chip_data.cal_4.cal_len;
    811                     break; */
    812                 /* IDB_PIPE_1, MMU_PIPE_1 */
    813                 default:
    814                     tdm_pipe_ovs_group = _tdm_pkg->_chip_data.cal_0.cal_grp;
    815                     tdm_pipe_grp_num   = _tdm_pkg->_chip_data.cal_0.grp_num;
    816                     tdm_pipe_grp_len   = _tdm_pkg->_chip_data.cal_0.grp_len;
    817                     tdm_idb_pipe_main  = _tdm_pkg->_chip_data.cal_0.cal_main;
    818                     tdm_idb_cal_len    = _tdm_pkg->_chip_data.cal_0.cal_len;
    819                     tdm_mmu_pipe_main  = _tdm_pkg->_chip_data.cal_4.cal_main;
    820                     tdm_mmu_cal_len    = _tdm_pkg->_chip_data.cal_4.cal_len;
    821                     break;
    822             }
    823             if (tdm_pipe_ovs_group == NULL ||
    824                 tdm_idb_pipe_main == NULL ||
    825                 tdm_mmu_pipe_main == NULL) {
    826                 LOG_CLI((BSL_META_U(unit,
    827                         "Unsupported config for TDM calendar generation\n")));
    828                 tdm_mv2_main_free(_tdm_pkg);
    829                 sal_free(_tdm_pkg);
    830                 return SOC_E_FAIL;
    831             } else {
    832                 /* IDB TDM main calendar */
    833                 for (index = 0; index < tdm_idb_cal_len; index++) {
    834                     sch_info->tdm_ingress_schedule_pipe[pipe].
    835                     tdm_schedule_slice[0].linerate_schedule[index] =
    836                     tdm_idb_pipe_main[index];
    837                 }
    838                 /* MMU TDM main calendar */
    839                 for (index = 0; index < tdm_mmu_cal_len; index++) {
    840                     sch_info->tdm_egress_schedule_pipe[pipe].
    841                     tdm_schedule_slice[0].linerate_schedule[index] =
    842                     tdm_mmu_pipe_main[index];
    843                 }
    844 
    845                 /* IDB and MMU OverSub Groups */
    846                 for (i = 0; i < tdm_pipe_grp_num; i++) {
    847                     /* Group 0:5 -> hpipe 0, Group 6:11 -> hpipe1 */
    848                     hpipe = i / MAVERICK2_TDM_OVS_GROUPS_PER_HPIPE;
    849                     group = i % MAVERICK2_TDM_OVS_GROUPS_PER_HPIPE;
    850                     for (j = 0; j < tdm_pipe_grp_len; j++) {
    851                         sch_info->tdm_ingress_schedule_pipe[pipe].
    852                         tdm_schedule_slice[hpipe].oversub_schedule[group][j] =
    853                         tdm_pipe_ovs_group[i][j];
    854                         sch_info->tdm_egress_schedule_pipe[pipe].
    855                         tdm_schedule_slice[hpipe].oversub_schedule[group][j] =
    856                         tdm_pipe_ovs_group[i][j];
    857                     }
    858                 }
    859 
    860                 /* Packet shaper */
    861                 for (hpipe = 0; hpipe < 2; hpipe++) {
    862                     for (j = 0; j < MV2_SHAPING_GRP_LEN; j++) {
    863                         sch_info->tdm_ingress_schedule_pipe[pipe].
    864                         tdm_schedule_slice[hpipe].pkt_sch_or_ovs_space[0][j] =
    865                         tdm_pipe_ovs_group[hpipe+MV2_SHAPING_GRP_IDX_0][j];
    866                     }
    867                 }
    868             }
    869         }
    870         /* Re-evaluate this at FlexPort;
    871          * Before calling FlexPort sch_info->in_port_map.port_p2PBLK_inst_mapping should be copied in pm_num_to_pblk
    872          * After FlexPort pm_num_to_pblk should be copied back to sch_info->out_port_map.port_p2PBLK_inst_mapping
    873          */
    874         sal_memset(sch_info->out_port_map.port_p2PBLK_inst_mapping,
    875                    0, sizeof(int) * SOC_MAX_NUM_PORTS);
    876         for (pm_num = 0; pm_num < MV2_NUM_PHY_PM; pm_num++) {
    877             for (lane = 0; lane < MAVERICK2_TDM_PORTS_PER_PBLK; lane++) {
    878                 sch_info->out_port_map.port_p2PBLK_inst_mapping[
    879                 (pm_num * MAVERICK2_TDM_PORTS_PER_PBLK) + 1 + lane] =
    880                 _tdm_pkg->_chip_data.soc_pkg.soc_vars.mv2.pm_num_to_pblk[pm_num];
    881             }
    882         }
    883         /* Free the memory allocated in TDM algorithm code */
    884         tdm_mv2_main_free(_tdm_pkg); /* This function frees all pointers allocated during _soc_set_tdm_tbl call */
    885         sal_free(_tdm_pkg);
    886     }
    887 
    888     /* Print TDM result */
    889     if (LOG_CHECK(BSL_LS_SOC_TDM | BSL_INFO)) {
    890         for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
    891             /* IDB TDM main calendar */
    892             LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    893                         "Pipe %d [IDB TDM main calendar]\n"),
    894                         pipe));
    895             for (index = 0; index < MAX_CAL_LEN; index++) {
    896                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, " %3d"),
    897                             sch_info->tdm_ingress_schedule_pipe[pipe].
    898                             tdm_schedule_slice[0].linerate_schedule[index]));
    899                 if (index % 16 == 0 && index > 0) {
    900                     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\n")));
    901                 }
    902             }
    903             LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\n")));
    904             /* Oversub groups */
    905             for (hpipe = 0; hpipe < MAVERICK2_TDM_HPIPES_PER_PIPE; hpipe++) {
    906                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    907                             "Pipe %d Half-Pipe %d [IDB TDM Oversub Groups]\n"),
    908                             pipe, hpipe));
    909                 for (group = 0; group < MAVERICK2_TDM_OVS_GROUPS_PER_HPIPE;
    910                      group++) {
    911                     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    912                                 "oversub group %d: "), group));
    913                     for (index = 0; index < MAVERICK2_TDM_OVS_GROUP_LENGTH;
    914                          index++) {
    915                         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, " %3d"),
    916                                     sch_info->tdm_ingress_schedule_pipe[pipe].
    917                                     tdm_schedule_slice[hpipe].oversub_schedule[
    918                                     group][index]));
    919                     }
    920                     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\n")));
    921                 }
    922                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\n")));
    923             }
    924             /* Packet scheduler */
    925             for (hpipe = 0; hpipe < MAVERICK2_TDM_HPIPES_PER_PIPE; hpipe++) {
    926                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    927                             "Pipe %d Half-Pipe %d [IDB TDM PKT SCHEDULER]\n"),
    928                             pipe, hpipe));
    929                 for (index = 0; index < MV2_SHAPING_GRP_LEN; index++) {
    930                     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, " %3d"),
    931                     sch_info->tdm_ingress_schedule_pipe[pipe].
    932                     tdm_schedule_slice[hpipe].pkt_sch_or_ovs_space[0][index]));
    933                     if (index % 16 == 0 && index > 0) {
    934                         LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\n")));
    935                     }
    936                 }
    937                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\n")));
    938             }
    939             /* MMU TDM main calendar */
    940             LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit,
    941                         "Pipe %d [MMU TDM main calendar]:\n"), pipe));
    942             for (index = 0; index < MAX_CAL_LEN; index++) {
    943                 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, " %3d"),
    944                             sch_info->tdm_egress_schedule_pipe[pipe].
    945                             tdm_schedule_slice[0].linerate_schedule[index]));
    946                 if (index % 16 == 0 && index > 0) {
    947                     LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\n")));
    948                 }
    949             }
    950             LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "\n")));
    951         }
    952     }
    953 
    954     /* If init then just copy in_port_map to out_port_map*/
    955     if (sch_info->is_flexport == 0) {
    956         for (i= 0; i< SOC_MAX_NUM_PORTS;i++) {
    957             sch_info->out_port_map.log_port_speed[i]   =
    958                 sch_info->in_port_map.log_port_speed[i];
    959             sch_info->out_port_map.port_p2l_mapping[i] =
    960                 sch_info->in_port_map.port_p2l_mapping[i];
    961             sch_info->out_port_map.port_l2p_mapping[i] =
    962                 sch_info->in_port_map.port_l2p_mapping[i];
    963             sch_info->out_port_map.port_p2m_mapping[i] =
    964                 sch_info->in_port_map.port_p2m_mapping[i];
    965             sch_info->out_port_map.port_num_lanes[i]   =
    966                 sch_info->in_port_map.port_num_lanes[i];
    967             sch_info->out_port_map.port_l2i_mapping[i] =
    968                 sch_info->in_port_map.port_l2i_mapping[i];
    969         }
    970         for (i = 0; i < SOC_MAX_NUM_MMU_PORTS; i++) {
    971             sch_info->out_port_map.port_m2p_mapping[i] =
    972                 sch_info->in_port_map.port_m2p_mapping[i];
    973         }
    974         for (i = 0; i < _SHR_PBMP_WORD_MAX; i++) {
    975             sch_info->out_port_map.physical_pbm.pbits[i]   =
    976                 sch_info->in_port_map.physical_pbm.pbits[i];
    977             sch_info->out_port_map.hg2_pbm.pbits[i]        =
    978                 sch_info->in_port_map.hg2_pbm.pbits[i];
    979             sch_info->out_port_map.management_pbm.pbits[i] =
    980                 sch_info->in_port_map.management_pbm.pbits[i];
    981             sch_info->out_port_map.oversub_pbm.pbits[i]    =
    982                 sch_info->in_port_map.oversub_pbm.pbits[i];
    983         }
    984     }
    985     /*
    986      * else {
    987      *    HERE future handling of FlexPort between in_port_map to out_port_map
    988      * }
    989     */
    990 
    991     _soc_mv2_tdm_print_schedule_state(unit, sch_info);
    992     return SOC_E_NONE;
    993 }
    994 
    995 
    996 /*! @fn int _soc_mv2_tdm_set_idb_calendar(
    997         int unit,
    998         soc_port_schedule_state_t *sch_info)
    999     @param unit Chip unit number.
   1000     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
   1001     @brief API to initialize the MV2 IDB main calendar.
   1002  */
   1003 int
   1004 _soc_mv2_tdm_set_idb_calendar(int unit, soc_port_schedule_state_t *sch_info)
   1005 {
   1006     uint32 pipe_map;
   1007     uint32 cal_len;
   1008     soc_mem_t mem;
   1009     soc_reg_t reg;
   1010     soc_field_t cal_end_field;
   1011     int pipe, slot, id, length, calendar_id;
   1012     int phy_port, idb_port;
   1013     int port;
   1014     uint32 rval = 0;
   1015     uint32 memfld;
   1016     uint32 entry[SOC_MAX_MEM_WORDS];
   1017     uint32 mem_indx;
   1018     static const soc_mem_t idb_tdm_cal_mem[MAVERICK2_TDM_PIPES_PER_DEV][2] = {
   1019         {IS_TDM_CALENDAR0_PIPE0m, IS_TDM_CALENDAR1_PIPE0m}/* ,
   1020         {IS_TDM_CALENDAR0_PIPE1m, IS_TDM_CALENDAR1_PIPE1m} */
   1021     };
   1022     static const soc_reg_t idb_tdm_cfg_reg[MAVERICK2_TDM_PIPES_PER_DEV] = {
   1023         IS_TDM_CONFIG_PIPE0r/* , IS_TDM_CONFIG_PIPE1r */
   1024     };
   1025     static const soc_field_t calendar_end_fields[] = {
   1026         CAL0_ENDf, CAL1_ENDf
   1027     };
   1028 
   1029     _soc_mv2_tdm_get_pipe_map(unit, sch_info, &pipe_map);
   1030     sal_memset(entry, 0, sizeof(uint32) * soc_mem_entry_words(unit,
   1031                IS_TDM_CALENDAR0_PIPE0m));
   1032     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   1033         /* coverity[overrun-local : FALSE] */
   1034         reg = idb_tdm_cfg_reg[pipe];
   1035         /* Pipe is empty */
   1036         if ((pipe_map & (1 << pipe)) == 0) {
   1037             /* At init, even if the pipe doesn't have active ports,
   1038              * enable scheduler for sbus accesses to PP IPIPE
   1039              */
   1040             if (sch_info->is_flexport == 0) {
   1041                 rval = 0;
   1042                 soc_reg_field_set(unit, reg, &rval, ENABLEf, 1);
   1043                 SOC_IF_ERROR_RETURN(
   1044                     soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1045             }
   1046             continue;
   1047         }
   1048         /* Determine calendar_id : 0 or 1 */
   1049         if (sch_info->is_flexport == 1) { /* choose "the other calendar" */
   1050             SOC_IF_ERROR_RETURN(
   1051                 soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   1052             calendar_id = soc_reg_field_get(unit, reg, rval, CURR_CALf) ^ 1;
   1053         } else {
   1054             /* At init use calendar_id=0 */
   1055             calendar_id = 0;
   1056             /* Also, before writing the TDM calendar entries, make sure
   1057              * calendar is disabled again;
   1058              * IDB scheduler may be already enabled at this point to allow
   1059              * sbus access to IPIPE for reset purpose (Sec. 3.1.2 SW_init doc)
   1060              */
   1061             rval = 0;
   1062             soc_reg_field_set(unit, reg, &rval, ENABLEf, 0);
   1063             SOC_IF_ERROR_RETURN(
   1064                 soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1065         }
   1066         /* coverity[overrun-local : FALSE] */
   1067         mem = idb_tdm_cal_mem[pipe][calendar_id];
   1068         cal_end_field = calendar_end_fields[calendar_id];
   1069 
   1070         /* TDM Calendar is always taken from slice 0 */
   1071         cal_len = sch_info->tdm_ingress_schedule_pipe[pipe].
   1072                             tdm_schedule_slice[0].cal_len;
   1073         for (length = cal_len; length > 0; length--) {
   1074             if (sch_info->tdm_ingress_schedule_pipe[pipe].
   1075                           tdm_schedule_slice[0].linerate_schedule[length - 1]
   1076                           != MV2_NUM_EXT_PORTS) {
   1077                 break;
   1078             }
   1079         }
   1080         for (slot = 0; slot < length; slot += 2) {
   1081             /* EVEN */
   1082             phy_port = sch_info->tdm_ingress_schedule_pipe[pipe].
   1083                        tdm_schedule_slice[0].linerate_schedule[slot];
   1084             if (phy_port == MV2_OVSB_TOKEN) {
   1085                 idb_port = MAVERICK2_TDM_IDB_OVSB_TOKEN;
   1086             } else if (phy_port == MV2_IDL1_TOKEN) {
   1087                 idb_port = MAVERICK2_TDM_IDB_SBUS_TOKEN;
   1088             } else if (phy_port == MV2_IDL2_TOKEN) {
   1089                 idb_port = MAVERICK2_TDM_IDB_UNUSED_TOKEN;
   1090             } else if (phy_port == MV2_NULL_TOKEN) {
   1091                 idb_port = MAVERICK2_TDM_IDB_NULL_TOKEN;
   1092             } else if (phy_port >= MV2_NUM_EXT_PORTS) {
   1093                 idb_port = MAVERICK2_TDM_IDB_UNUSED_TOKEN;
   1094             } else if (phy_port == MV2_MGM1_TOKEN) {
   1095                 /* TDM code always allocates slots for management port.
   1096                  * If mgmt ports are omitted from config, this mapping
   1097                  * is not set up.
   1098                  */
   1099                 idb_port = MAVERICK2_TDM_IDB_MGMT1_TOKEN;
   1100             } else {
   1101                 port = sch_info->out_port_map.port_p2l_mapping[phy_port];
   1102                 idb_port = sch_info->out_port_map.port_l2i_mapping[port] & 0x7f;
   1103             }
   1104             if (idb_port > 63) { /* Not a general front panel port */
   1105                 id = 0xf;
   1106             } else {
   1107                 id = (phy_port - 1) / MAVERICK2_TDM_PORTS_PER_PBLK;
   1108             }
   1109             memfld = idb_port & 0x7f; /* [0,69] && 127 */
   1110             soc_mem_field_set(unit, mem, entry, PORT_NUM_EVENf, &memfld);
   1111             memfld = id & 0xf;
   1112             soc_mem_field_set(unit, mem, entry, PHY_PORT_ID_EVENf, &memfld);
   1113             /* ODD */
   1114             phy_port = sch_info->tdm_ingress_schedule_pipe[pipe].tdm_schedule_slice[0].linerate_schedule[slot + 1];
   1115             if (phy_port == MV2_OVSB_TOKEN) {
   1116                 idb_port = MAVERICK2_TDM_IDB_OVSB_TOKEN;
   1117             } else if (phy_port == MV2_IDL1_TOKEN) {
   1118                 idb_port = MAVERICK2_TDM_IDB_SBUS_TOKEN;
   1119             } else if (phy_port == MV2_IDL2_TOKEN) {
   1120                 idb_port = MAVERICK2_TDM_IDB_UNUSED_TOKEN;
   1121             } else if (phy_port == MV2_NULL_TOKEN) {
   1122                 idb_port = MAVERICK2_TDM_IDB_NULL_TOKEN;
   1123             } else if (phy_port >= MV2_NUM_EXT_PORTS) {
   1124                 idb_port = MAVERICK2_TDM_IDB_UNUSED_TOKEN;
   1125             } else if (phy_port == MV2_MGM1_TOKEN) {
   1126                 /* TDM code always allocates slots for management port.
   1127                  * If mgmt ports are omitted from config, this mapping
   1128                  * is not set up.
   1129                  */
   1130                 idb_port = MAVERICK2_TDM_IDB_MGMT1_TOKEN;
   1131             } else {
   1132                 port = sch_info->out_port_map.port_p2l_mapping[phy_port];
   1133                 idb_port = sch_info->out_port_map.port_l2i_mapping[port] & 0x7f;
   1134             }
   1135             if (idb_port > 63) { /* Not a general front panel port */
   1136                 id = 0xf;
   1137             } else {
   1138                 id = (phy_port - 1) / MAVERICK2_TDM_PORTS_PER_PBLK;
   1139             }
   1140             memfld = idb_port & 0x7f; /* [0,69] && 127 */
   1141             soc_mem_field_set(unit, mem, entry, PORT_NUM_ODDf, &memfld);
   1142             memfld = id & 0xf;
   1143             soc_mem_field_set(unit, mem, entry, PHY_PORT_ID_ODDf, &memfld);
   1144             /* Memory entry */
   1145             mem_indx = slot / 2;
   1146             SOC_IF_ERROR_RETURN
   1147                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, mem_indx, entry));
   1148         }
   1149 
   1150         /* set for 2nd management port */
   1151         if (_soc_mv2_tdm_check_2nd_mgmt_enable(unit, sch_info) == 1 &&
   1152             pipe == (MAVERICK2_TDM_PIPES_PER_DEV - 1)) {
   1153             /* reg: IS_TDM_CONFIG_PIPExr */
   1154             soc_reg_field_set(unit, reg, &rval, MGMT_2ND_PORT_ENABLEf, 1);
   1155         }
   1156 
   1157         soc_reg_field_set(unit, reg, &rval, cal_end_field, length-1);
   1158         soc_reg_field_set(unit, reg, &rval, CURR_CALf, calendar_id);
   1159         soc_reg_field_set(unit, reg, &rval, ENABLEf, 1);
   1160         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1161     }
   1162 
   1163     return SOC_E_NONE;
   1164 }
   1165 
   1166 
   1167 /*! @fn int _soc_mv2_tdm_set_idb_hsp(
   1168         int unit,
   1169         soc_port_schedule_state_t *sch_info)
   1170     @param unit Chip unit number.
   1171     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
   1172     @brief API to initialize the MV2 IDB HSP.
   1173  */
   1174 int
   1175 _soc_mv2_tdm_set_idb_hsp(int unit, soc_port_schedule_state_t *sch_info)
   1176 {
   1177     soc_reg_t reg;
   1178     uint32 pipe_map;
   1179     int pipe;
   1180     uint32 pmap;
   1181     uint32 rval = 0;
   1182 
   1183     static const soc_reg_t idb_tdm_hsp[MAVERICK2_TDM_PIPES_PER_DEV][2] = {
   1184         {IS_TDM_HSP_0_PIPE0r, IS_TDM_HSP_1_PIPE0r}/* ,
   1185         {IS_TDM_HSP_0_PIPE1r, IS_TDM_HSP_1_PIPE1r} */
   1186     };
   1187 
   1188     /* IDB always configures PORT_BMPf field for idb_tdm_hsp regs
   1189      * to 0xFFFF_FFFF_FFFF_FFFF, independent of the port's speed.
   1190      */
   1191     pmap = 0xffffffff; /* up to 32 ports */
   1192 
   1193     _soc_mv2_tdm_get_pipe_map(unit, sch_info, &pipe_map);
   1194     for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
   1195         if (!(pipe_map & (1 << pipe))) {
   1196             continue;
   1197         }
   1198         reg = idb_tdm_hsp[pipe][0];
   1199         soc_reg_field_set(unit, reg, &rval, PORT_BMPf, pmap);
   1200         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1201 
   1202         reg = idb_tdm_hsp[pipe][1];
   1203         soc_reg_field_set(unit, reg, &rval, PORT_BMPf, pmap);
   1204         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1205     }
   1206 
   1207     return SOC_E_NONE;
   1208 }
   1209 
   1210 
   1211 /*! @fn int _soc_mv2_tdm_set_idb_ppe_credit(
   1212         int unit,
   1213         soc_port_schedule_state_t
   1214         *sch_info,
   1215         int full_credit_threshold_0,
   1216         int opp_credit_threshold_0,
   1217         int full_credit_threshold_1,
   1218         int opp_credit_threshold_1 )
   1219     @param unit Chip unit number.
   1220     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
   1221     @param full_credit_threshold_0
   1222     @param opp_credit_threshold_0
   1223     @param full_credit_threshold_1
   1224     @param opp_credit_threshold_1
   1225     @brief API to initialize the MV2 IDB PPE Credit Config register.
   1226            Regs/Mems configured:PPE_CREDIT_CONFIG_PIPE<pipe>
   1227  */
   1228 int
   1229 _soc_mv2_tdm_set_idb_ppe_credit(int unit,
   1230                                 soc_port_schedule_state_t *sch_info,
   1231                                 int full_credit_threshold_0,
   1232                                 int opp_credit_threshold_0,
   1233                                 int full_credit_threshold_1,
   1234                                 int opp_credit_threshold_1 )
   1235 {
   1236     soc_reg_t reg;
   1237     uint32 pipe_map;
   1238     int pipe;
   1239     uint32 rval = 0;
   1240     static const soc_reg_t idb_ppe_credit[MAVERICK2_TDM_PIPES_PER_DEV] = {
   1241         PPE_CREDIT_CONFIG_PIPE0r/* , PPE_CREDIT_CONFIG_PIPE1r */
   1242     };
   1243 
   1244     _soc_mv2_tdm_get_pipe_map(unit, sch_info, &pipe_map);
   1245 
   1246     for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
   1247         if (!(pipe_map & (1 << pipe))) {
   1248             continue;
   1249         }
   1250         reg = idb_ppe_credit[pipe];
   1251         rval = 0;
   1252         /*SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));*/
   1253         soc_reg_field_set(unit, reg, &rval, FULL_CREDIT_THRESHOLD_0f,
   1254                                             full_credit_threshold_0);
   1255         soc_reg_field_set(unit, reg, &rval, OPP_CREDIT_THRESHOLD_0f,
   1256                                             opp_credit_threshold_0);
   1257         soc_reg_field_set(unit, reg, &rval, FULL_CREDIT_THRESHOLD_1f,
   1258                                             full_credit_threshold_1);
   1259         soc_reg_field_set(unit, reg, &rval, OPP_CREDIT_THRESHOLD_1f,
   1260                                             opp_credit_threshold_1);
   1261         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1262     }
   1263 
   1264     return SOC_E_NONE;
   1265 }
   1266 
   1267 
   1268 /*! @fn int _soc_mv2_tdm_set_idb_opportunistic(
   1269         int unit,
   1270         soc_port_schedule_state_t *sch_info,
   1271         int cpu_op_en,
   1272         int lb_opp_en,
   1273         int opp1_port_en,
   1274         int opp2_port_en,
   1275         int opp_ovr_sub_en)
   1276     @param unit Chip unit number.
   1277     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
   1278     @param cpu_op_en
   1279     @param lb_opp_en
   1280     @param opp1_port_en
   1281     @param opp2_port_en
   1282     @param opp_ovr_sub_en
   1283     @brief API to initialize the MV2 IDB Opportunistic related registers
   1284            Regs/Mems configured: IS_CPU_LB_OPP_CFG_PIPE<pipe>
   1285                                  IS_OPP_SCHED_CFG_PIPE<pipe>
   1286  */
   1287 int
   1288 _soc_mv2_tdm_set_idb_opportunistic(int unit,
   1289                                    soc_port_schedule_state_t *sch_info,
   1290                                    int cpu_op_en,
   1291                                    int lb_opp_en,
   1292                                    int opp1_port_en,
   1293                                    int opp2_port_en,
   1294                                    int opp_ovr_sub_en)
   1295 {
   1296     soc_reg_t reg;
   1297     uint32 pipe_map;
   1298     int pipe;
   1299     uint32 rval = 0;
   1300     static const soc_reg_t idb_cpu_lb_opp_cfg[MAVERICK2_TDM_PIPES_PER_DEV] = {
   1301         IS_CPU_LB_OPP_CFG_PIPE0r/* , IS_CPU_LB_OPP_CFG_PIPE1r */
   1302     };
   1303     static const soc_reg_t idb_opp_sched_cfg[MAVERICK2_TDM_PIPES_PER_DEV] = {
   1304         IS_OPP_SCHED_CFG_PIPE0r/* , IS_OPP_SCHED_CFG_PIPE1r */
   1305     };
   1306 
   1307     _soc_mv2_tdm_get_pipe_map(unit, sch_info, &pipe_map);
   1308 
   1309     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
   1310         if ((pipe_map & (1 << pipe)) == 0) {
   1311             /* Enable OPP1 to enable sbus access to the rest of IPIPE*/
   1312             reg = idb_opp_sched_cfg[pipe];
   1313             SOC_IF_ERROR_RETURN(
   1314                 soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   1315             soc_reg_field_set(unit, reg, &rval, OPP1_PORT_ENf,
   1316                               (opp1_port_en == 1) ? 1 : 0);
   1317             soc_reg_field_set(unit, reg, &rval, OPP1_SPACINGf, 8);
   1318             SOC_IF_ERROR_RETURN(
   1319                 soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1320             continue;
   1321         }
   1322 
   1323         reg = idb_cpu_lb_opp_cfg[pipe];
   1324         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   1325         soc_reg_field_set(unit, reg, &rval, CPU_OPP_ENf,
   1326                           (cpu_op_en == 1) ? 1 : 0);
   1327         soc_reg_field_set(unit, reg, &rval, LB_OPP_ENf,
   1328                           (lb_opp_en == 1) ? 1 : 0);
   1329         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1330 
   1331         reg = idb_opp_sched_cfg[pipe];
   1332         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   1333         soc_reg_field_set(unit, reg, &rval, OPP1_PORT_ENf,
   1334                           (opp1_port_en == 1) ? 1 : 0);
   1335         soc_reg_field_set(unit, reg, &rval, OPP1_SPACINGf, 8);
   1336         soc_reg_field_set(unit, reg, &rval, OPP2_PORT_ENf,
   1337                           (opp2_port_en == 1) ? 1 : 0);
   1338         soc_reg_field_set(unit, reg, &rval, OPP2_SPACINGf, 0);
   1339         soc_reg_field_set(unit, reg, &rval, OPP_OVR_SUB_ENf,
   1340                           (opp_ovr_sub_en == 1) ? 1 : 0);
   1341         soc_reg_field_set(unit, reg, &rval, OPP_STRICT_PRIf, 1);
   1342         soc_reg_field_set(unit, reg, &rval, DISABLE_PORT_NUMf, 67); /* NULL port */
   1343         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1344     }
   1345 
   1346     return SOC_E_NONE;
   1347 }
   1348 
   1349 
   1350 /*! @fn int soc_mv2_tdm_set_idb_dpp_ctrl(
   1351         int unit,
   1352         soc_port_schedule_state_t *sch_info,
   1353         int credits)
   1354     @param unit Chip unit number.
   1355     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
   1356     @param credits
   1357     @brief API to initialize the MV2 IDB_DPP_CTRL register.
   1358  */
   1359 int
   1360 soc_mv2_tdm_set_idb_dpp_ctrl(int unit,
   1361                              soc_port_schedule_state_t *sch_info,
   1362                              int credits)
   1363 {
   1364     soc_reg_t reg;
   1365     uint32 pipe_map;
   1366     int pipe;
   1367     uint32 rval = 0;
   1368     static const soc_reg_t idb_dpp_ctrl[MAVERICK2_TDM_PIPES_PER_DEV] = {
   1369         IDB_DPP_CTRL_PIPE0r/* , IDB_DPP_CTRL_PIPE1r */
   1370     };
   1371 
   1372     _soc_mv2_tdm_get_pipe_map(unit, sch_info, &pipe_map);
   1373 
   1374     for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
   1375         if (!(pipe_map & (1 << pipe))) {
   1376             continue;
   1377         }
   1378         reg = idb_dpp_ctrl[pipe];
   1379         rval = 0;
   1380         /*SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));*/
   1381         soc_reg_field_set(unit, reg, &rval, MAX_REF_CNTf, 4);
   1382         soc_reg_field_set(unit, reg, &rval, MAX_SBUS_CNTf, 4);
   1383         soc_reg_field_set(unit, reg, &rval, CREDITSf, credits);
   1384         soc_reg_field_set(unit, reg, &rval, DONEf, 0);
   1385         soc_reg_field_set(unit, reg, &rval, STARTf, 1);
   1386         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   1387     }
   1388 
   1389     return SOC_E_NONE;
   1390 }
   1391 
   1392 
   1393 /*! @fn int _soc_mv2_tdm_set_idb_pkt_calendar(
   1394         int unit,
   1395         soc_port_schedule_state_t *sch_info)
   1396     @param unit Chip unit number.
   1397     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
   1398     @brief API to initialize the MV2 IDB Packet Shaper calendar.
   1399            Regs/Mems configured: IDB PKT_SCH_CALENDAR
   1400  */
   1401 int
   1402 _soc_mv2_tdm_set_idb_pkt_calendar(int unit,
   1403                                   soc_port_schedule_state_t *sch_info)
   1404 {
   1405     uint32 pipe_map;
   1406     soc_mem_t mem;
   1407     int pipe, slot, hpipe;
   1408     int port, phy_port, idb_port;
   1409     uint32 memfld;
   1410     uint32 entry[SOC_MAX_MEM_WORDS];
   1411     static const soc_mem_t idb_pkt_shaper_mems[MAVERICK2_TDM_PIPES_PER_DEV][2] = {
   1412         {PKT_SCH_CALENDAR0_PIPE0m, PKT_SCH_CALENDAR1_PIPE0m}/* ,
   1413         {PKT_SCH_CALENDAR0_PIPE1m, PKT_SCH_CALENDAR1_PIPE1m} */
   1414     };
   1415 
   1416     _soc_mv2_tdm_get_pipe_map(unit, sch_info, &pipe_map);
   1417 
   1418     for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
   1419         if (!(pipe_map & (1 << pipe))) {
   1420             continue;
   1421         }
   1422         /* Configure packet shaper calendar */
   1423         for (hpipe = 0; hpipe < MAVERICK2_TDM_HPIPES_PER_PIPE; hpipe++) {
   1424             mem = idb_pkt_shaper_mems[pipe][hpipe];
   1425             for (slot = 0; slot < MV2_SHAPING_GRP_LEN; slot ++) {
   1426                 phy_port = sch_info->tdm_ingress_schedule_pipe[pipe].
   1427                 tdm_schedule_slice[hpipe].pkt_sch_or_ovs_space[0][slot];
   1428                 if ((phy_port >= MV2_NUM_EXT_PORTS) || (phy_port <= 0)) {
   1429                     idb_port = MAVERICK2_TDM_IDB_UNUSED_TOKEN;
   1430                 } else {
   1431                     port = sch_info->in_port_map.port_p2l_mapping[phy_port];
   1432                     idb_port = sch_info->in_port_map.port_l2i_mapping[port] &
   1433                                0x1f;
   1434                 }
   1435                 sal_memset(entry, 0, sizeof(uint32) * soc_mem_entry_words(unit,
   1436                                      PKT_SCH_CALENDAR0_PIPE0m));
   1437                 memfld = idb_port & 0x3f;
   1438                 soc_mem_field_set(unit, mem, entry, PORT_NUMf, &memfld);
   1439                 SOC_IF_ERROR_RETURN(
   1440                     soc_mem_write(unit, mem, MEM_BLOCK_ALL, slot, entry));
   1441             }
   1442         }
   1443     }
   1444 
   1445     return SOC_E_NONE;
   1446 }
   1447 
   1448 /*! @fn int _soc_mv2_tdm_set_ovs_group_sel(
   1449         int unit,
   1450         soc_port_schedule_state_t *sch_info,
   1451         int set_idb,
   1452         int set_mmu)
   1453     @param unit Chip unit number.
   1454     @param sch_info : Pointer to a soc_port_schedule_state_t struct variable.
   1455     @param set_idb if 1 then IDB OVS tables are configured
   1456     @param set_mmu if 1 then MMU OVS tables are configured
   1457     @brief API to initialize the MV2 MMU &/or IDB OVS tables.
   1458             Regs/Mems configured: IDB HPIPE0/1_OVR_SUB_GRP_CFG,
   1459                                   HPIPE0/1_OVR_SUB_GRP_CFG
   1460                                   PBLK<n>_CALENDAR
   1461  */
   1462 int
   1463 _soc_mv2_tdm_set_ovs_group_sel(int unit,
   1464                                soc_port_schedule_state_t *sch_info,
   1465                                int set_idb, int set_mmu)
   1466 {
   1467     uint32 pipe_map, ovs_pipe_map;
   1468     soc_reg_t reg, reg1;
   1469     int pipe, hpipe, group, lane, slot, id = 0, mode;
   1470     int port, phy_port, phy_port_base, idb_port, mmu_port, inst;
   1471     int speed_max;
   1472     uint32 rval = 0, rval1 = 0;
   1473     int pblks[MAVERICK2_TDM_PIPES_PER_DEV][2][MAVERICK2_TDM_PBLKS_PER_HPIPE];
   1474     int pm_num, pblk_cal_idx;
   1475     int pblk_valid, pblk_spacing;
   1476     int port_speed_class, port_same_spacing, port_sister_spacing;
   1477     int l_speed = 0, l_num_lanes = 0, prev_or_new = 0;
   1478 
   1479     static const soc_reg_t idb_grp_cfg_regs[MAVERICK2_TDM_PIPES_PER_DEV][2] = {
   1480         {IS_HPIPE0_OVR_SUB_GRP_CFG_PIPE0r, IS_HPIPE1_OVR_SUB_GRP_CFG_PIPE0r}/* ,
   1481         {IS_HPIPE0_OVR_SUB_GRP_CFG_PIPE1r, IS_HPIPE1_OVR_SUB_GRP_CFG_PIPE1r} */
   1482     };
   1483 
   1484     static const soc_reg_t mmu_grp_cfg_regs[2] = {
   1485         HPIPE0_OVR_SUB_GRP_CFGr, HPIPE1_OVR_SUB_GRP_CFGr
   1486     };
   1487 
   1488     static const soc_reg_t idb_grp_ovs_regs[MAVERICK2_TDM_PIPES_PER_DEV][2][6] = {
   1489         {
   1490             {IS_HPIPE0_OVR_SUB_GRP0_TBL_PIPE0r, IS_HPIPE0_OVR_SUB_GRP1_TBL_PIPE0r,
   1491              IS_HPIPE0_OVR_SUB_GRP2_TBL_PIPE0r, IS_HPIPE0_OVR_SUB_GRP3_TBL_PIPE0r,
   1492              IS_HPIPE0_OVR_SUB_GRP4_TBL_PIPE0r, IS_HPIPE0_OVR_SUB_GRP5_TBL_PIPE0r },
   1493             {IS_HPIPE1_OVR_SUB_GRP0_TBL_PIPE0r, IS_HPIPE1_OVR_SUB_GRP1_TBL_PIPE0r,
   1494              IS_HPIPE1_OVR_SUB_GRP2_TBL_PIPE0r, IS_HPIPE1_OVR_SUB_GRP3_TBL_PIPE0r,
   1495              IS_HPIPE1_OVR_SUB_GRP4_TBL_PIPE0r, IS_HPIPE1_OVR_SUB_GRP5_TBL_PIPE0r }
   1496         }/* ,
   1497         {
   1498             {IS_HPIPE0_OVR_SUB_GRP0_TBL_PIPE1r, IS_HPIPE0_OVR_SUB_GRP1_TBL_PIPE1r,
   1499              IS_HPIPE0_OVR_SUB_GRP2_TBL_PIPE1r, IS_HPIPE0_OVR_SUB_GRP3_TBL_PIPE1r,
   1500              IS_HPIPE0_OVR_SUB_GRP4_TBL_PIPE1r, IS_HPIPE0_OVR_SUB_GRP5_TBL_PIPE1r },
   1501             {IS_HPIPE1_OVR_SUB_GRP0_TBL_PIPE1r, IS_HPIPE1_OVR_SUB_GRP1_TBL_PIPE1r,
   1502              IS_HPIPE1_OVR_SUB_GRP2_TBL_PIPE1r, IS_HPIPE1_OVR_SUB_GRP3_TBL_PIPE1r,
   1503              IS_HPIPE1_OVR_SUB_GRP4_TBL_PIPE1r, IS_HPIPE1_OVR_SUB_GRP5_TBL_PIPE1r }
   1504         } */
   1505     };
   1506 
   1507     static const soc_reg_t mmu_grp_ovs_regs[2][6] = {
   1508         {HPIPE0_OVR_SUB_GRP0_TBLr, HPIPE0_OVR_SUB_GRP1_TBLr,
   1509          HPIPE0_OVR_SUB_GRP2_TBLr, HPIPE0_OVR_SUB_GRP3_TBLr,
   1510          HPIPE0_OVR_SUB_GRP4_TBLr, HPIPE0_OVR_SUB_GRP5_TBLr },
   1511         {HPIPE1_OVR_SUB_GRP0_TBLr, HPIPE1_OVR_SUB_GRP1_TBLr,
   1512          HPIPE1_OVR_SUB_GRP2_TBLr, HPIPE1_OVR_SUB_GRP3_TBLr,
   1513          HPIPE1_OVR_SUB_GRP4_TBLr, HPIPE1_OVR_SUB_GRP5_TBLr }
   1514     };
   1515 
   1516     static const soc_reg_t idb_pblk_cal_regs[MAVERICK2_TDM_PIPES_PER_DEV][2][10] = {
   1517         {
   1518             {IS_HPIPE0_PBLK0_CALENDAR_PIPE0r, IS_HPIPE0_PBLK1_CALENDAR_PIPE0r,
   1519              IS_HPIPE0_PBLK2_CALENDAR_PIPE0r, IS_HPIPE0_PBLK3_CALENDAR_PIPE0r,
   1520              IS_HPIPE0_PBLK4_CALENDAR_PIPE0r, IS_HPIPE0_PBLK5_CALENDAR_PIPE0r,
   1521              IS_HPIPE0_PBLK6_CALENDAR_PIPE0r, IS_HPIPE0_PBLK7_CALENDAR_PIPE0r,
   1522              IS_HPIPE0_PBLK8_CALENDAR_PIPE0r, IS_HPIPE0_PBLK9_CALENDAR_PIPE0r },
   1523             {IS_HPIPE1_PBLK0_CALENDAR_PIPE0r, IS_HPIPE1_PBLK1_CALENDAR_PIPE0r,
   1524              IS_HPIPE1_PBLK2_CALENDAR_PIPE0r, IS_HPIPE1_PBLK3_CALENDAR_PIPE0r,
   1525              IS_HPIPE1_PBLK4_CALENDAR_PIPE0r, IS_HPIPE1_PBLK5_CALENDAR_PIPE0r,
   1526              IS_HPIPE1_PBLK6_CALENDAR_PIPE0r, IS_HPIPE1_PBLK7_CALENDAR_PIPE0r,
   1527              IS_HPIPE1_PBLK8_CALENDAR_PIPE0r, IS_HPIPE1_PBLK9_CALENDAR_PIPE0r }
   1528         }/* ,
   1529         {
   1530             {IS_HPIPE0_PBLK0_CALENDAR_PIPE1r, IS_HPIPE0_PBLK1_CALENDAR_PIPE1r,
   1531              IS_HPIPE0_PBLK2_CALENDAR_PIPE1r, IS_HPIPE0_PBLK3_CALENDAR_PIPE1r,
   1532              IS_HPIPE0_PBLK4_CALENDAR_PIPE1r, IS_HPIPE0_PBLK5_CALENDAR_PIPE1r,
   1533              IS_HPIPE0_PBLK6_CALENDAR_PIPE1r, IS_HPIPE0_PBLK7_CALENDAR_PIPE1r },
   1534             {IS_HPIPE1_PBLK0_CALENDAR_PIPE1r, IS_HPIPE1_PBLK1_CALENDAR_PIPE1r,
   1535              IS_HPIPE1_PBLK2_CALENDAR_PIPE1r, IS_HPIPE1_PBLK3_CALENDAR_PIPE1r,
   1536              IS_HPIPE1_PBLK4_CALENDAR_PIPE1r, IS_HPIPE1_PBLK5_CALENDAR_PIPE1r,
   1537              IS_HPIPE1_PBLK6_CALENDAR_PIPE1r, IS_HPIPE1_PBLK7_CALENDAR_PIPE1r }
   1538         } */
   1539     };
   1540 
   1541     static const soc_reg_t mmu_pblk_cal_regs[2][10] = {
   1542         {HPIPE0_PBLK0_CALENDARr, HPIPE0_PBLK1_CALENDARr,
   1543          HPIPE0_PBLK2_CALENDARr, HPIPE0_PBLK3_CALENDARr,
   1544          HPIPE0_PBLK4_CALENDARr, HPIPE0_PBLK5_CALENDARr,
   1545          HPIPE0_PBLK6_CALENDARr, HPIPE0_PBLK7_CALENDARr,
   1546          HPIPE0_PBLK8_CALENDARr, HPIPE0_PBLK9_CALENDARr},
   1547         {HPIPE1_PBLK0_CALENDARr, HPIPE1_PBLK1_CALENDARr,
   1548          HPIPE1_PBLK2_CALENDARr, HPIPE1_PBLK3_CALENDARr,
   1549          HPIPE1_PBLK4_CALENDARr, HPIPE1_PBLK5_CALENDARr,
   1550          HPIPE1_PBLK6_CALENDARr, HPIPE1_PBLK7_CALENDARr,
   1551          HPIPE1_PBLK8_CALENDARr, HPIPE1_PBLK9_CALENDARr}
   1552     };
   1553 
   1554     static int pblk_slots[SOC_MV2_PORT_RATIO_COUNT][7] = {
   1555         { 0, -1,  0,  0, -1,  0, -1 }, /* SOC_MV2_PORT_RATIO_SINGLE */
   1556         { 0, -1,  2,  0, -1,  2, -1 }, /* SOC_MV2_PORT_RATIO_DUAL_1_1 */
   1557         { 0,  0,  2,  0,  0,  2, -1 }, /* SOC_MV2_PORT_RATIO_DUAL_2_1 */
   1558         { 0,  2,  2,  0,  2,  2, -1 }, /* SOC_MV2_PORT_RATIO_DUAL_1_2 */
   1559         { 0, -1,  2,  0, -1,  3, -1 }, /* SOC_MV2_PORT_RATIO_TRI_023_2_1_1 */
   1560         { 0,  0,  2,  0,  0,  3, -1 }, /* SOC_MV2_PORT_RATIO_TRI_023_4_1_1 */
   1561         { 0, -1,  2,  1, -1,  2, -1 }, /* SOC_MV2_PORT_RATIO_TRI_012_1_1_2 */
   1562         { 0,  2,  2,  1,  2,  2, -1 }, /* SOC_MV2_PORT_RATIO_TRI_012_1_1_4 */
   1563         { 0, -1,  2,  1, -1,  3, -1 }  /* SOC_MV2_PORT_RATIO_QUAD */
   1564     };
   1565 
   1566     _soc_mv2_tdm_get_pipe_map(unit, sch_info, &pipe_map);
   1567     _soc_mv2_tdm_get_ovs_pipe_map(unit, sch_info, &ovs_pipe_map);
   1568 
   1569     /* OVS tables  */
   1570     for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
   1571         if (!(ovs_pipe_map & (1 << pipe))) {
   1572             continue;
   1573         }
   1574         inst = pipe | SOC_REG_ADDR_INSTANCE_MASK;
   1575         for (hpipe = 0; hpipe < MAVERICK2_TDM_HPIPES_PER_PIPE; hpipe++) {
   1576             for (group = 0; group < MAVERICK2_TDM_OVS_GROUPS_PER_HPIPE; group++) {
   1577                 for (slot = 0; slot < MAVERICK2_TDM_OVS_GROUP_LENGTH; slot++) {
   1578                     phy_port = sch_info->tdm_ingress_schedule_pipe[pipe].
   1579                                          tdm_schedule_slice[hpipe].
   1580                                          oversub_schedule[group][slot];
   1581                     /* PORT_NUMf restricts port numbering within [0-31] & 0x3f
   1582                      *      HPIPE0 port 0-31 maps to mmu/idb port 0-31
   1583                      *      HPIPE1 port 0-31 maps to mmu/idb port 32-63
   1584                      * PHY_PORT_IDf restricts port block id within [0-9]
   1585                      */
   1586                     if (phy_port > MV2_NUM_PHY_PORTS) {
   1587                         idb_port = 0x3f;
   1588                         mmu_port = 0x3f;
   1589                         id = 0xf; /* 0x7 */
   1590                     } else {
   1591                         port = sch_info->in_port_map.port_p2l_mapping[phy_port];
   1592                         idb_port = sch_info->in_port_map.port_l2i_mapping[
   1593                                    port] & 0x1f;
   1594                         mmu_port = sch_info->in_port_map.port_p2m_mapping[
   1595                                    phy_port] & 0x1f;
   1596                         id = sch_info->out_port_map.port_p2PBLK_inst_mapping[
   1597                              phy_port] & 0xf; /* 0x7 */
   1598                     }
   1599                     /* IDB OverSub Groups */
   1600                     if (set_idb == 1) {
   1601                         rval = 0;
   1602                         reg = idb_grp_ovs_regs[pipe][hpipe][group];
   1603                         soc_reg_field_set(unit, reg, &rval, PHY_PORT_IDf, id);
   1604                         soc_reg_field_set(unit, reg, &rval, PORT_NUMf, idb_port);
   1605                         SOC_IF_ERROR_RETURN(
   1606                             soc_reg32_set(unit, reg, REG_PORT_ANY, slot, rval));
   1607                     }
   1608                     /* MMU OverSub Groups */
   1609                     if (set_mmu == 1) {
   1610                         rval = 0;
   1611                         reg = mmu_grp_ovs_regs[hpipe][group];
   1612                         soc_reg_field_set(unit, reg, &rval, PHY_PORT_IDf, id);
   1613                         soc_reg_field_set(unit, reg, &rval, PORT_NUMf, mmu_port);
   1614                         SOC_IF_ERROR_RETURN(
   1615                             soc_reg32_set(unit, reg, inst, slot, rval));
   1616                     }
   1617                 }
   1618 
   1619                 /* Handle the case where the first element in the group
   1620                  * is invalid but other valid ports exist in the group.
   1621                  */
   1622                 for (slot = 0; slot < MAVERICK2_TDM_OVS_GROUP_LENGTH; slot++) {
   1623                     phy_port = sch_info->tdm_ingress_schedule_pipe[pipe].
   1624                                          tdm_schedule_slice[hpipe].
   1625                                          oversub_schedule[group][slot];
   1626                     if (phy_port < MV2_NUM_EXT_PORTS) {
   1627                         break;
   1628                     }
   1629                 }
   1630 
   1631                 /* No valid ports found, skip group */
   1632                 if (MAVERICK2_TDM_OVS_GROUP_LENGTH == slot) {
   1633                     port_speed_class = 0;
   1634                     port_same_spacing = 0;
   1635                     port_sister_spacing = 0;
   1636                 } else {
   1637                     port = sch_info->in_port_map.port_p2l_mapping[phy_port];
   1638                     prev_or_new = 1;
   1639                     soc_mv2_tdm_get_log_port_speed(unit, sch_info, port,
   1640                         prev_or_new, &l_speed, &l_num_lanes);
   1641                     speed_max = 25000 * l_num_lanes;
   1642                     if (speed_max > l_speed) speed_max = l_speed;
   1643 
   1644                     port_speed_class =
   1645                         _soc_mv2_tdm_get_speed_ovs_class(unit, speed_max);
   1646                     port_same_spacing =
   1647                         _soc_mv2_tdm_get_same_port_spacing_e(unit, speed_max);
   1648                     port_sister_spacing = 4;
   1649                 }
   1650                 if (set_idb == 1) {
   1651                     rval = 0;
   1652                     reg = idb_grp_cfg_regs[pipe][hpipe];
   1653                     soc_reg_field_set(unit, reg, &rval, SAME_SPACINGf, 8); /* on ingress, all ports have same spacing */
   1654                     soc_reg_field_set(unit, reg, &rval, SISTER_SPACINGf,
   1655                                                         port_sister_spacing);
   1656                     soc_reg_field_set(unit, reg, &rval, SPEEDf,
   1657                                                         port_speed_class);
   1658                     SOC_IF_ERROR_RETURN(
   1659                         soc_reg32_set(unit, reg, REG_PORT_ANY, group, rval));
   1660                 }
   1661                 if (set_mmu == 1) {
   1662                     rval = 0;
   1663                     reg = mmu_grp_cfg_regs[hpipe];
   1664                     soc_reg_field_set(unit, reg, &rval, SAME_SPACINGf,
   1665                                                         port_same_spacing);
   1666                     soc_reg_field_set(unit, reg, &rval, SISTER_SPACINGf,
   1667                                                         port_sister_spacing);
   1668                     soc_reg_field_set(unit, reg, &rval, SPEEDf,
   1669                                                         port_speed_class);
   1670                     SOC_IF_ERROR_RETURN(
   1671                         soc_reg32_set(unit, reg, inst, group, rval));
   1672                 }
   1673             }
   1674         }
   1675     }
   1676 
   1677     /* 16 Port-blocks are supported, with each instance of Oversubscription
   1678      * Cell Scheduler supports up to 8 Portblocks. */
   1679 
   1680     /* First get pblk_cal_idx to pm_num mapping from
   1681      * pm_num to pblk_cal_idx
   1682      * and **oversub_schedule
   1683      */
   1684     /* sal_memset(pblks, -1, sizeof(pblks)); */
   1685     sal_memset(pblks, -1, sizeof(int) * MAVERICK2_TDM_PIPES_PER_DEV * 2 *
   1686                MAVERICK2_TDM_PBLKS_PER_HPIPE);
   1687     for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
   1688         if (!(ovs_pipe_map & (1 << pipe))) {
   1689             continue;
   1690         }
   1691         for (hpipe = 0; hpipe < MAVERICK2_TDM_HPIPES_PER_PIPE; hpipe++) {
   1692             for (group = 0; group < MAVERICK2_TDM_OVS_GROUPS_PER_HPIPE; group++) {
   1693                 for (slot = 0; slot < MAVERICK2_TDM_OVS_GROUP_LENGTH; slot++) {
   1694                     phy_port = sch_info->tdm_ingress_schedule_pipe[pipe].
   1695                                          tdm_schedule_slice[hpipe].
   1696                                          oversub_schedule[group][slot];
   1697                     if (phy_port < MV2_NUM_EXT_PORTS) {
   1698                         pm_num = (phy_port - 1) / MAVERICK2_TDM_PORTS_PER_PBLK;
   1699                         pblk_cal_idx = sch_info->out_port_map.
   1700                                        port_p2PBLK_inst_mapping[phy_port];
   1701                         if (pblk_cal_idx >= 0 &&
   1702                             pblk_cal_idx < MAVERICK2_TDM_PBLKS_PER_HPIPE) {
   1703                             pblks[pipe][hpipe][pblk_cal_idx] = pm_num;
   1704                         } else {
   1705                             return SOC_E_FAIL; /* invalid mapping */
   1706                         }
   1707                     }
   1708                 }
   1709             }
   1710         }
   1711     }
   1712 
   1713     /* Configure PBLKs */
   1714     for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
   1715         if (!(ovs_pipe_map & (1 << pipe))) {
   1716             continue;
   1717         }
   1718 
   1719         inst = pipe | SOC_REG_ADDR_INSTANCE_MASK;
   1720         for (hpipe = 0; hpipe < MAVERICK2_TDM_HPIPES_PER_PIPE; hpipe++) {
   1721             for (pblk_cal_idx = 0; pblk_cal_idx < MAVERICK2_TDM_PBLKS_PER_HPIPE;
   1722                     pblk_cal_idx++) {
   1723                 pm_num = pblks[pipe][hpipe][pblk_cal_idx];
   1724                 phy_port_base = 1 + (pm_num * MAVERICK2_TDM_PORTS_PER_PBLK);
   1725                 /* Get port ratio for this Port Macro */
   1726                 soc_mv2_tdm_get_port_ratio(unit, sch_info, pm_num, &mode, 1);
   1727                 reg  = idb_pblk_cal_regs[pipe][hpipe][pblk_cal_idx];
   1728                 reg1 = mmu_pblk_cal_regs[hpipe][pblk_cal_idx];
   1729                 /* Write PBLK regs
   1730                  *      Only first 6 out of 7 slots could be valid
   1731                  */
   1732                 if ((pm_num < 0) || (pm_num > MAVERICK2_TDM_PBLKS_PER_DEV)) {
   1733                     /* To speed-up init this branch could be skipped */
   1734                     for (slot = 0; slot < 6; slot++) {
   1735                         rval = 0;
   1736                         rval1 = 0;
   1737                         if (set_idb == 1) {
   1738                             soc_reg_field_set(unit, reg, &rval, PORT_NUMf,
   1739                                                                 0x3f);
   1740                             SOC_IF_ERROR_RETURN(
   1741                                 soc_reg32_set(unit, reg, REG_PORT_ANY, slot,
   1742                                               rval));
   1743                         }
   1744                         if (set_mmu == 1) {
   1745                             soc_reg_field_set(unit, reg1, &rval1, PORT_NUMf,
   1746                                                                   0x3f);
   1747                             SOC_IF_ERROR_RETURN(
   1748                                 soc_reg32_set(unit, reg1, inst, slot, rval1));
   1749                         }
   1750                     }
   1751                 } else {
   1752                     for (slot = 0; slot < 6; slot++) {
   1753                         rval = 0;
   1754                         rval1 = 0;
   1755                         lane = pblk_slots[mode][slot];
   1756                         if (lane == -1) {
   1757                             pblk_valid = 0;
   1758                             idb_port = 0x3f;
   1759                             mmu_port = 0x3f;
   1760                             pblk_spacing = 0; /* same spacing */
   1761                         } else {
   1762                             pblk_valid = 1;
   1763                             port = sch_info->in_port_map.port_p2l_mapping[
   1764 												phy_port_base + lane];
   1765                             idb_port = sch_info->in_port_map.port_l2i_mapping[
   1766 												port] & 0x1f;
   1767                             mmu_port = sch_info->in_port_map.port_p2m_mapping[
   1768 												phy_port_base + lane] & 0x1f;
   1769 
   1770                             prev_or_new = 1;
   1771                             soc_mv2_tdm_get_log_port_speed(unit, sch_info,
   1772                                 port, prev_or_new, &l_speed, &l_num_lanes);
   1773                             speed_max = 25000 * l_num_lanes;
   1774                             if (speed_max > l_speed) speed_max = l_speed;
   1775 
   1776                             port_speed_class =
   1777                                 _soc_mv2_tdm_get_speed_ovs_class(unit,
   1778                                                                  speed_max);
   1779                             pblk_spacing =
   1780                                 _soc_mv2_tdm_get_same_port_spacing_e(unit,
   1781                                                                      speed_max);
   1782                         }
   1783 
   1784                         soc_reg_field_set(unit, reg, &rval, VALIDf, pblk_valid);
   1785                         soc_reg_field_set(unit, reg, &rval, SPACINGf, 8);
   1786                         soc_reg_field_set(unit, reg, &rval, PORT_NUMf,
   1787                                                             idb_port);
   1788                         soc_reg_field_set(unit, reg1, &rval1, VALIDf,
   1789                                                               pblk_valid);
   1790                         soc_reg_field_set(unit, reg1, &rval1, SPACINGf,
   1791                                                               pblk_spacing);
   1792                         soc_reg_field_set(unit, reg1, &rval1, PORT_NUMf,
   1793                                                               mmu_port);
   1794                         if (set_idb == 1) {
   1795                             SOC_IF_ERROR_RETURN(
   1796                                 soc_reg32_set(unit, reg, REG_PORT_ANY, slot,
   1797                                               rval));
   1798                         }
   1799                         if (set_mmu == 1) {
   1800                             SOC_IF_ERROR_RETURN(
   1801                                 soc_reg32_set(unit, reg1, inst, slot, rval1));
   1802                         }
   1803                     }
   1804                 }
   1805             }
   1806         }
   1807     }
   1808 
   1809     return SOC_E_NONE;
   1810 }
   1811 
   1812 
   1813 /*! @fn int _soc_mv2_tdm_set_ovs_group(
   1814         int unit,
   1815         soc_port_schedule_state_t *sch_info)
   1816     @param unit Chip unit number.
   1817     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
   1818     @brief API to initialize the MV2 MMU & IDB OVS tables.
   1819             Regs/Mems configured: IDB HPIPE0/1_OVR_SUB_GRP_CFG
   1820                                   HPIPE0/1_OVR_SUB_GRP_CFG
   1821                                   PBLK<n>_CALENDAR
   1822  */
   1823 int
   1824 _soc_mv2_tdm_set_ovs_group(int unit, soc_port_schedule_state_t *sch_info)
   1825 {
   1826     return (_soc_mv2_tdm_set_ovs_group_sel(unit, sch_info, 1, 1));
   1827 }
   1828 
   1829 
   1830 /*! @fn int _soc_mv2_tdm_set_mmu_calendar(
   1831         int unit,
   1832         soc_port_schedule_state_t *sch_info)
   1833     @param unit Chip unit number.
   1834     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
   1835     @brief API to initialize the MV2 MMU main calendar.
   1836             Regs/Mems configured: MMU TDM_CALENDAR
   1837                                   TDM_CONFIG
   1838  */
   1839 int
   1840 _soc_mv2_tdm_set_mmu_calendar(int unit, soc_port_schedule_state_t *sch_info)
   1841 {
   1842     uint32 pipe_map;
   1843     uint32 cal_len;
   1844     soc_mem_t mem;
   1845     soc_reg_t reg;
   1846     soc_field_t cal_end_field;
   1847     int pipe, slot, id, length, calendar_id;
   1848     int phy_port, mmu_port, inst;
   1849     uint32 rval = 0;
   1850     uint32 memfld;
   1851     uint32 entry[SOC_MAX_MEM_WORDS];
   1852     uint32 mem_indx;
   1853     static const soc_mem_t calendar_mems[] = {
   1854         TDM_CALENDAR0_PIPE0m,
   1855         /* TDM_CALENDAR0_PIPE1m, */
   1856         TDM_CALENDAR1_PIPE0m/* ,
   1857         TDM_CALENDAR1_PIPE1m */
   1858     };
   1859     static const soc_field_t calendar_end_fields[] = {
   1860         CAL0_ENDf, CAL1_ENDf
   1861     };
   1862 
   1863     _soc_mv2_tdm_get_pipe_map(unit, sch_info, &pipe_map);
   1864     sal_memset(entry, 0, sizeof(uint32) * soc_mem_entry_words(unit,
   1865 								TDM_CALENDAR0_PIPE0m));
   1866     for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
   1867         if (!(pipe_map & (1 << pipe))) {
   1868             continue;
   1869         }
   1870 
   1871         /* Determine calendar_id: 0 or 1 */
   1872         reg = TDM_CONFIGr;
   1873         inst = pipe | SOC_REG_ADDR_INSTANCE_MASK;
   1874         if (sch_info->is_flexport == 1) { /* choose "the other one" */
   1875             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, inst, 0, &rval));
   1876             calendar_id = soc_reg_field_get(unit, reg, rval, CURR_CALf) ^ 1;
   1877         } else {
   1878             calendar_id = 0; /* At init use calendar_id=0 */
   1879             rval = 0;
   1880         }
   1881         mem = calendar_mems[(calendar_id * MAVERICK2_TDM_PIPES_PER_DEV) + pipe];
   1882         cal_end_field = calendar_end_fields[calendar_id];
   1883 
   1884         /* TDM Calendar is always taken from slice 0 */
   1885         cal_len = sch_info->tdm_egress_schedule_pipe[pipe].
   1886                             tdm_schedule_slice[0].cal_len;
   1887         for (length = cal_len; length > 0; length--) {
   1888             if (sch_info->tdm_egress_schedule_pipe[pipe].
   1889                           tdm_schedule_slice[0].
   1890                           linerate_schedule[length - 1] != MV2_NUM_EXT_PORTS) {
   1891                 break;
   1892             }
   1893         }
   1894         for (slot = 0; slot < length; slot += 2) {
   1895             /* EVEN */
   1896             phy_port = sch_info->tdm_egress_schedule_pipe[
   1897 				pipe].tdm_schedule_slice[0].linerate_schedule[slot];
   1898             if (phy_port == MV2_OVSB_TOKEN) {
   1899                 mmu_port = MAVERICK2_TDM_MMU_OVSB_TOKEN;
   1900             } else if (phy_port == MV2_IDL1_TOKEN) {
   1901                 mmu_port = MAVERICK2_TDM_MMU_PURG_TOKEN;
   1902             } else if (phy_port == MV2_IDL2_TOKEN) {
   1903                 mmu_port = MAVERICK2_TDM_MMU_UNUSED_TOKEN;
   1904             } else if (phy_port == MV2_NULL_TOKEN) {
   1905                 mmu_port = MAVERICK2_TDM_MMU_NULL_TOKEN;
   1906             } else if (phy_port >= MV2_NUM_EXT_PORTS) {
   1907                 mmu_port = MAVERICK2_TDM_MMU_UNUSED_TOKEN;
   1908             } else if (phy_port == MV2_MGM1_TOKEN) {
   1909                 /* TDM code always allocates slots for management port.
   1910                  * If mgmt ports are omitted from config, this mapping
   1911                  * is not set up.
   1912                  */
   1913                 mmu_port = MAVERICK2_TDM_MMU_MGMT1_TOKEN;
   1914             } else {
   1915                 /* [0,69] && 127 */
   1916                 mmu_port = sch_info->out_port_map.port_p2m_mapping[phy_port] &
   1917                            0x7f;
   1918             }
   1919             if (mmu_port > 63) {
   1920                 id = 0xf;
   1921             } else {
   1922                 id = (phy_port - 1) / MAVERICK2_TDM_PORTS_PER_PBLK;
   1923             }
   1924             memfld = mmu_port & 0x7f;
   1925             soc_mem_field_set(unit, mem, entry, PORT_NUM_EVENf, &memfld);
   1926             memfld = id & 0xf;
   1927             soc_mem_field_set(unit, mem, entry, PHY_PORT_ID_EVENf, &memfld);
   1928             /* ODD */
   1929             phy_port = sch_info->tdm_egress_schedule_pipe[
   1930 					pipe].tdm_schedule_slice[0].linerate_schedule[slot + 1];
   1931             if (phy_port == MV2_OVSB_TOKEN) {
   1932                 mmu_port = MAVERICK2_TDM_MMU_OVSB_TOKEN;
   1933             } else if (phy_port == MV2_IDL1_TOKEN) {
   1934                 mmu_port = MAVERICK2_TDM_MMU_PURG_TOKEN;
   1935             } else if (phy_port == MV2_IDL2_TOKEN) {
   1936                 mmu_port = MAVERICK2_TDM_MMU_UNUSED_TOKEN;
   1937             } else if (phy_port == MV2_NULL_TOKEN) {
   1938                 mmu_port = MAVERICK2_TDM_MMU_NULL_TOKEN;
   1939             } else if (phy_port >= MV2_NUM_EXT_PORTS) {
   1940                 mmu_port = MAVERICK2_TDM_MMU_UNUSED_TOKEN;
   1941             } else if (phy_port == MV2_MGM1_TOKEN) {
   1942                 /* TDM code always allocates slots for management port.
   1943                  * If mgmt ports are omitted from config, this mapping
   1944                  * is not set up.
   1945                  */
   1946                 mmu_port = MAVERICK2_TDM_MMU_MGMT1_TOKEN;
   1947             } else {
   1948                 /* [0,69] && 127 */
   1949                 mmu_port = sch_info->out_port_map.port_p2m_mapping[
   1950 								phy_port] & 0x7f;
   1951             }
   1952             if (mmu_port > 63) {
   1953                 id = 0xf;
   1954             } else {
   1955                 id = (phy_port - 1) / MAVERICK2_TDM_PORTS_PER_PBLK;
   1956             }
   1957             memfld = mmu_port & 0x7f;
   1958             soc_mem_field_set(unit, mem, entry, PORT_NUM_ODDf, &memfld);
   1959             memfld = id & 0xf;
   1960             soc_mem_field_set(unit, mem, entry, PHY_PORT_ID_ODDf, &memfld);
   1961             /* Memory entry */
   1962             mem_indx = slot / 2;
   1963             SOC_IF_ERROR_RETURN
   1964                 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, mem_indx, entry));
   1965         }
   1966 
   1967         /* set for 2nd management port */
   1968         if (_soc_mv2_tdm_check_2nd_mgmt_enable(unit, sch_info) == 1 &&
   1969             pipe == (MAVERICK2_TDM_PIPES_PER_DEV - 1)) {
   1970             soc_reg_field_set(unit, reg, &rval, MGMT_2ND_PORT_ENABLEf, 1);
   1971         }
   1972 
   1973         soc_reg_field_set(unit, reg, &rval, cal_end_field, length-1);
   1974         soc_reg_field_set(unit, reg, &rval, CURR_CALf, calendar_id);
   1975         soc_reg_field_set(unit, reg, &rval, ENABLEf, 1);
   1976         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, 0, rval));
   1977     }
   1978 
   1979     return SOC_E_NONE;
   1980 }
   1981 
   1982 
   1983 /*! @fn int _soc_mv2_tdm_set_mmu_hsp(
   1984         int unit,
   1985         soc_port_schedule_state_t *sch_info)
   1986     @param unit Chip unit number.
   1987     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
   1988     @brief API to initialize the MV2 MMU HSP.
   1989             Regs/Mems configured: TDM_HSP_PIPE
   1990  */
   1991 int
   1992 _soc_mv2_tdm_set_mmu_hsp(int unit,
   1993                          soc_port_schedule_state_t *sch_info)
   1994 {
   1995     soc_reg_t reg;
   1996     uint32 pipe_map;
   1997     int pipe, hpipe, inst;
   1998     int port, mmu_port, phy_port;
   1999     uint32 port_map[MAVERICK2_TDM_PIPES_PER_DEV][2];
   2000     uint32 rval = 0;
   2001     int l_speed = 0, l_num_lanes = 0, prev_or_new = 0;
   2002 
   2003     _soc_mv2_tdm_get_pipe_map(unit, sch_info, &pipe_map);
   2004 
   2005     for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
   2006         port_map[pipe][0] = 0;
   2007         port_map[pipe][1] = 0;
   2008     }
   2009 
   2010     for (port = 0; port < MAVERICK2_TDM_PHY_PORTS_PER_DEV; port++) {
   2011         if (sch_info->out_port_map.log_port_speed[port] > 0) {
   2012             soc_mv2_tdm_get_log_port_speed(unit, sch_info, port,
   2013                 prev_or_new, &l_speed, &l_num_lanes);
   2014             if (_soc_mv2_tdm_check_is_hsp_port_e(unit, l_speed) == 1) {
   2015                 phy_port = sch_info->out_port_map.port_l2p_mapping[port];
   2016                 if ((phy_port >= 1) &&
   2017                     (phy_port <= MAVERICK2_TDM_GPORTS_PER_DEV)) {
   2018                     pipe = (phy_port - 1) / MAVERICK2_TDM_GPORTS_PER_PIPE;
   2019                     hpipe = ((phy_port - 1) & 0x3f) /
   2020                             MAVERICK2_TDM_GPORTS_PER_HPIPE;
   2021                     mmu_port =
   2022                         sch_info->out_port_map.port_p2m_mapping[phy_port] &
   2023                         0x1f;
   2024                     if (pipe < MAVERICK2_TDM_PIPES_PER_DEV && hpipe < 2) {
   2025                         port_map[pipe][hpipe] |= 1 << mmu_port;
   2026                     }
   2027                 }
   2028             }
   2029         }
   2030     }
   2031 
   2032     for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
   2033         if (!(pipe_map & (1 << pipe))) {
   2034             continue;
   2035         }
   2036         inst = pipe | SOC_REG_ADDR_INSTANCE_MASK;
   2037 
   2038         reg = TDM_HSP_0r;
   2039         soc_reg_field_set(unit, reg, &rval, PORT_BMPf, port_map[pipe][0]);
   2040         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, 0, rval));
   2041 
   2042         reg = TDM_HSP_1r;
   2043         soc_reg_field_set(unit, reg, &rval, PORT_BMPf, port_map[pipe][1]);
   2044         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, 0, rval));
   2045     }
   2046 
   2047     return SOC_E_NONE;
   2048 }
   2049 
   2050 
   2051 /*! @fn int _soc_mv2_tdm_set_mmu_opportunistic(
   2052         int unit,
   2053         soc_port_schedule_state_t *sch_info,
   2054         int cpu_op_en,
   2055         int lb_opp_en,
   2056         int opp1_port_en,
   2057         int opp2_port_en,
   2058         int opp_ovr_sub_en)
   2059     @param unit Chip unit number.
   2060     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
   2061     @param cpu_op_en
   2062     @param lb_opp_en
   2063     @param opp1_port_en
   2064     @param opp2_port_en
   2065     @param opp_ovr_sub_en
   2066     @brief API to initialize the MV2 MMU Opportunistic related registers
   2067             Regs/Mems configured: CPU_LB_OPP_CFG
   2068                                   OPP_SCHED_CFG
   2069  */
   2070 int
   2071 _soc_mv2_tdm_set_mmu_opportunistic(int unit,
   2072                                    soc_port_schedule_state_t *sch_info,
   2073                                    int cpu_op_en,
   2074                                    int lb_opp_en,
   2075                                    int opp1_port_en,
   2076                                    int opp2_port_en,
   2077                                    int opp_ovr_sub_en)
   2078 {
   2079     uint32 pipe_map;
   2080     soc_reg_t reg;
   2081     int pipe;
   2082     int inst;
   2083     uint32 rval = 0;
   2084 
   2085     _soc_mv2_tdm_get_pipe_map(unit, sch_info, &pipe_map);
   2086 
   2087     for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) {
   2088         if (!(pipe_map & (1 << pipe))) {
   2089             continue;
   2090         }
   2091 
   2092         inst = pipe | SOC_REG_ADDR_INSTANCE_MASK;
   2093 
   2094         reg = CPU_LB_OPP_CFGr;
   2095         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, inst, 0, &rval));
   2096         soc_reg_field_set(unit, reg, &rval, CPU_OPP_ENf,
   2097                                             (cpu_op_en == 1) ? 1 : 0);
   2098         soc_reg_field_set(unit, reg, &rval, LB_OPP_ENf,
   2099                                             (lb_opp_en == 1) ? 1 : 0);
   2100         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, 0, rval));
   2101 
   2102         reg = OPP_SCHED_CFGr;
   2103         SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, inst, 0, &rval));
   2104         soc_reg_field_set(unit, reg, &rval, OPP1_PORT_ENf,
   2105                                             (opp1_port_en == 1) ? 1 : 0);
   2106         soc_reg_field_set(unit, reg, &rval, OPP1_SPACINGf, 6);
   2107         soc_reg_field_set(unit, reg, &rval, OPP2_PORT_ENf,
   2108                                             (opp2_port_en == 1) ? 1 : 0);
   2109         soc_reg_field_set(unit, reg, &rval, OPP2_SPACINGf, 0);
   2110         soc_reg_field_set(unit, reg, &rval, OPP_OVR_SUB_ENf,
   2111                                             (opp_ovr_sub_en == 1) ? 1 : 0);
   2112         soc_reg_field_set(unit, reg, &rval, OPP_STRICT_PRIf, 0);
   2113         soc_reg_field_set(unit, reg, &rval, DISABLE_PORT_NUMf, 67);
   2114         SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, inst, 0, rval));
   2115     }
   2116 
   2117     return SOC_E_NONE;
   2118 }
   2119 
   2120 
   2121 /*! @fn int soc_mv2_tdm_init(
   2122         int unit,
   2123         soc_port_schedule_state_t *sch_info)
   2124     @param unit Chip unit number.
   2125     @param sch_info Pointer to a soc_port_schedule_state_t struct variable.
   2126     @brief Main API for TDM init
   2127  */
   2128 int soc_mv2_tdm_init(int unit, soc_port_schedule_state_t *sch_info)
   2129 {
   2130     SOC_IF_ERROR_RETURN(_soc_mv2_tdm_calculation(unit, sch_info));
   2131 
   2132     SOC_IF_ERROR_RETURN(_soc_mv2_tdm_set_idb_calendar(unit, sch_info));
   2133     SOC_IF_ERROR_RETURN(_soc_mv2_tdm_set_idb_hsp(unit, sch_info));
   2134     SOC_IF_ERROR_RETURN(_soc_mv2_tdm_set_idb_pkt_calendar(unit, sch_info));
   2135     SOC_IF_ERROR_RETURN(_soc_mv2_tdm_set_idb_ppe_credit(unit, sch_info,
   2136                                                         20, 9, 20, 9));
   2137     /* SOC_IF_ERROR_RETURN(soc_mv2_tdm_set_idb_dpp_ctrl(unit, sch_info, 32)); */
   2138     /* IDB opp1_port_en should always be 1 to enable sbus access to the rest of IPIPE*/
   2139     SOC_IF_ERROR_RETURN(_soc_mv2_tdm_set_idb_opportunistic(unit, sch_info,
   2140                                                            1, 1, 1, 1, 1));
   2141 
   2142     SOC_IF_ERROR_RETURN(_soc_mv2_tdm_set_ovs_group(unit, sch_info));
   2143 
   2144     SOC_IF_ERROR_RETURN(_soc_mv2_tdm_set_mmu_calendar(unit, sch_info));
   2145     SOC_IF_ERROR_RETURN(_soc_mv2_tdm_set_mmu_hsp(unit, sch_info));
   2146     SOC_IF_ERROR_RETURN(_soc_mv2_tdm_set_mmu_opportunistic(unit, sch_info,
   2147                                                            1, 1, 1, 1, 1));
   2148 
   2149     return SOC_E_NONE;
   2150 }
   2151 
   2152 /*! @fn int soc_maverick2_port_speed_higig2eth(int speed)
   2153  *  @param int speed
   2154  *  @brief Map port speed to ETH bitrates
   2155  */
   2156 static int
   2157 soc_maverick2_port_speed_higig2eth(int speed)
   2158 {
   2159     switch (speed) {
   2160     case 11000:
   2161         /* 10G */
   2162         return 10000;
   2163     case 21000:
   2164         /* 20G */
   2165         return 20000;
   2166     case 27000:
   2167         /* 25G */
   2168         return 25000;
   2169     case 42000:
   2170         /* 40G */
   2171         return 40000;
   2172     case 53000:
   2173         /* 50G */
   2174         return 50000;
   2175     case 106000:
   2176         /* 100G */
   2177         return 100000;
   2178     default:
   2179         return speed;
   2180     }
   2181 }
   2182 
   2183 /*! @fn void soc_maverick2_port_schedule_speed_remap(int unit,
   2184  *               soc_port_schedule_state_t *port_schedule_state)
   2185  *  @param unit Chip unit number.
   2186  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t struct
   2187  *         variable.
   2188  *  @brief API to remap speeds to ETH bitrates
   2189  */
   2190 void
   2191 soc_maverick2_port_schedule_speed_remap(
   2192     int  unit,
   2193     soc_port_schedule_state_t *port_schedule_state)
   2194 {
   2195     int i, port;
   2196 
   2197     /* Speed remap for in_port_map*/
   2198     for (port=0; port < SOC_MAX_NUM_PORTS; port++) {
   2199         port_schedule_state->in_port_map.log_port_speed[port] =
   2200             soc_maverick2_port_speed_higig2eth(
   2201                 port_schedule_state->in_port_map.log_port_speed[port]);
   2202     }
   2203 
   2204     if (port_schedule_state->is_flexport == 1) {
   2205         /* Speed remap for out_port_map*/
   2206         for (port=0; port < SOC_MAX_NUM_PORTS; port++) {
   2207             port_schedule_state->out_port_map.log_port_speed[port] =
   2208                 soc_maverick2_port_speed_higig2eth(
   2209                     port_schedule_state->out_port_map.log_port_speed[port]);
   2210         }
   2211         /* Speed remap for resource */
   2212         for (i = 0; i < port_schedule_state->nport; i++) {
   2213             if (-1 != port_schedule_state->resource[i].physical_port) { /* that is, port up */
   2214                 port_schedule_state->resource[i].speed =
   2215                     soc_maverick2_port_speed_higig2eth(
   2216                         port_schedule_state->resource[i].speed);
   2217             }
   2218         }
   2219     }
   2220 }
   2221 
   2222 /*! @fn int soc_mv2_tdm_get_log_port_speed(int unit,
   2223  *   soc_port_schedule_state_t *port_schedule_state,
   2224  *  int log_port,
   2225  *  int prev_or_new,
   2226  *  int *speed,
   2227  *  int *num_lanes)
   2228  *  @param unit Chip unit number.
   2229  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t struct
   2230  *         variable.
   2231  *  @param log_port: logical port
   2232  *  @param prev_or_new: if = 1 use in_port_map, otherwise use out_port_map.
   2233  *  int *speed: port speed returned
   2234  *  int *num_lanes: num lanes returned
   2235  *  @brief helper func to get the scheduler speed and num lanes
   2236  */
   2237 int
   2238 soc_mv2_tdm_get_log_port_speed(
   2239     int unit,
   2240     soc_port_schedule_state_t *port_schedule_state,
   2241     int log_port,
   2242     int prev_or_new,
   2243     int *speed,
   2244     int *num_lanes)
   2245 {
   2246     soc_port_map_type_t *port_map;
   2247 
   2248     if (prev_or_new == 1) {
   2249         port_map = &port_schedule_state->in_port_map;
   2250     } else {
   2251         port_map = &port_schedule_state->out_port_map;
   2252     }
   2253 
   2254     *speed = port_map->log_port_speed[log_port];
   2255     *num_lanes = port_map->port_num_lanes[log_port];
   2256 
   2257     /* If 25G should act as 50G in the scheduler, change speed and num_lanes */
   2258     if (SOC_PBMP_MEMBER(port_map->physical_pbm, log_port) &&
   2259         (*speed == 25000) ) {
   2260         *speed = 50000;
   2261         *num_lanes = 2;
   2262     }
   2263 
   2264     return SOC_E_NONE;
   2265 }
   2266 
   2267 /*** END SDK API COMMON CODE ***/
   2268 
   2269 #endif /* BCM_MAVERICK2_SUPPORT */