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

helix5_tdm.c (93671B)


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