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

tomahawk2_tdm.c (95633B)


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