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

tomahawk3_idb_init.c (151259B)


      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:        tomahawk3_idb_init.c
      8  * Purpose:
      9  * Requires:
     10  */
     11 
     12 #include <shared/bsl.h>
     13 #include <soc/tdm/core/tdm_top.h>
     14 
     15 #include <soc/defs.h>
     16 #include <soc/mem.h>
     17 
     18 #if defined(BCM_TOMAHAWK3_SUPPORT)
     19 
     20 #include <soc/init/tomahawk3_idb_init.h>
     21 #include <soc/flexport/flexport_common.h>
     22 
     23 /*** START SDK API COMMON CODE ***/
     24 
     25 
     26 /*! @file tomahawk3_idb_init.c
     27  *  @brief IDB init for Tomahawk3.
     28  *  Details are shown below.
     29  */
     30 
     31 static const struct soc_tomahawk3_obm_buffer_config_s {
     32     int buffer_start;
     33     int buffer_end;
     34 } soc_tomahawk3_obm_buffer_config_settings[9][8] = {
     35     /* indexed by number of lanes used in the port */
     36     { /* 0 lanes - invalid */ {0},{0},{0},{0},{0},{0},{0},{0}},
     37     { /* 1 lane */
     38         {0,459},         /* buffer_config port 0 */
     39         {460,919},       /* buffer_config port 1 */
     40         {920,1379},      /* buffer_config port 2 */
     41         {1380,1839},     /* buffer_config port 3 */
     42         {1840,2299},     /* buffer_config port 4 */
     43         {2300,2759},     /* buffer_config port 5 */
     44         {2760,3219},     /* buffer_config port 6 */
     45         {3220,3679}      /* buffer_config port 7 */
     46     },
     47     { /* 2 lanes */
     48         {0,919},         /* buffer_config port 0 */
     49         {0,919},         /* buffer_config port 1 */
     50         {920,1839},      /* buffer_config port 2 */
     51         {920,1839},      /* buffer_config port 3 */
     52         {1840,2759},     /* buffer_config port 4 */
     53         {1840,2759},     /* buffer_config port 5 */
     54         {2760,3679},     /* buffer_config port 6 */
     55         {2760,3679}      /* buffer_config port 7 */
     56     },
     57     { /* 3 lanes - invalid */ {0},{0},{0},{0},{0},{0},{0},{0}},
     58     { /* 4 lanes */
     59         {0,1839},        /* buffer_config port 0 */
     60         {0,1839},        /* buffer_config port 1 */
     61         {0,1839},        /* buffer_config port 2 */
     62         {0,1839},        /* buffer_config port 3 */
     63         {1840,3679},     /* buffer_config port 4 */
     64         {1840,3679},     /* buffer_config port 5 */
     65         {1840,3679},     /* buffer_config port 6 */
     66         {1840,3679}      /* buffer_config port 7 */
     67     },
     68     { /* 5 lanes - invalid */ {0},{0},{0},{0},{0},{0},{0},{0}},
     69     { /* 6 lanes - invalid */ {0},{0},{0},{0},{0},{0},{0},{0}},
     70     { /* 7 lanes - invalid */ {0},{0},{0},{0},{0},{0},{0},{0}},
     71     { /* 8 lanes */
     72         {0,3679},        /* buffer_config port 0 */
     73         {0,3679},        /* buffer_config port 1 */
     74         {0,3679},        /* buffer_config port 2 */
     75         {0,3679},        /* buffer_config port 3 */
     76         {0,3679},        /* buffer_config port 4 */
     77         {0,3679},        /* buffer_config port 5 */
     78         {0,3679},        /* buffer_config port 6 */
     79         {0,3679}         /* buffer_config port 7 */
     80     }
     81 };
     82 
     83 static const struct soc_tomahawk3_obm_setting_s {
     84     int discard_limit;
     85     int lossless_discard;
     86     int port_xoff;
     87     int port_xon;
     88     int lossless_xoff;
     89     int lossless_xon;
     90     int lossy_low_pri;
     91     int lossy_discard;
     92     int sop_discard_mode;
     93 } soc_tomahawk3_obm_settings[3][9] = {
     94     /* LOSSY Settings*/
     95     { /* indexed by number of lanes used in the port */
     96         { /* 0 lanes - invalid */ 0 },
     97         { /* 1 lane */
     98             457,             /* discard_limit */
     99             3677,            /* lossless_discard */
    100             3677,            /* port_xoff */
    101             3677,            /* port_xon */
    102             3677,            /* lossless_xoff */
    103             3677,            /* lossless_xon */
    104             370,             /* lossy_low_pri */
    105             455,             /* lossy_discard */
    106             1                /* sop_discard_mode */
    107         },
    108         { /* 2 lanes */
    109             917,             /* discard_limit */
    110             3677,            /* lossless_discard */
    111             3677,            /* port_xoff */
    112             3677,            /* port_xon */
    113             3677,            /* lossless_xoff */
    114             3677,            /* lossless_xon */
    115             830,             /* lossy_low_pri */
    116             915,             /* lossy_discard */
    117             1                /* sop_discard_mode */
    118         },
    119         { /* 3 - invalid  */ 0 },
    120         { /* 4 lanes */
    121             1837,            /* discard_limit */
    122             3677,            /* lossless_discard */
    123             3677,            /* port_xoff */
    124             3677,            /* port_xon */
    125             3677,            /* lossless_xoff */
    126             3677,            /* lossless_xon */
    127             1750,            /* lossy_low_pri */
    128             1835,            /* lossy_discard */
    129             1                /* sop_discard_mode */
    130         },
    131         { /* 5 lanes - Invalid*/ 0 },
    132         { /* 6 lanes - Invalid*/ 0 },
    133         { /* 7 lanes - Invalid*/ 0 },
    134         { /* 8 lanes */
    135             3677,            /* discard_limit */
    136             3677,            /* lossless_discard */
    137             3677,            /* port_xoff */
    138             3677,            /* port_xon */
    139             3677,            /* lossless_xoff */
    140             3677,            /* lossless_xon */
    141             3590,            /* lossy_low_pri */
    142             3675,            /* lossy_discard */
    143             1                /* sop_discard_mode */
    144         }
    145     },
    146     /* LOSSLESS Settings*/
    147     { /* indexed by number of lanes used in the port */
    148         { /* 0 lanes - invalid */ 0 },
    149         { /* 1 lane */
    150             457,             /* discard_limit */
    151             3677,            /* lossless_discard */
    152             209,             /* port_xoff */
    153             201,             /* port_xon */
    154             81,              /* lossless_xoff */
    155             73,              /* lossless_xon */
    156             60,              /* lossy_low_pri */
    157             145,             /* lossy_discard */
    158             1                /* sop_discard_mode */
    159         },
    160         { /* 2 lanes */
    161             917,             /* discard_limit */
    162             3677,            /* lossless_discard */
    163             524,             /* port_xoff */
    164             516,             /* port_xon */
    165             194,             /* lossless_xoff */
    166             186,             /* lossless_xon */
    167             60,              /* lossy_low_pri */
    168             145,             /* lossy_discard */
    169             1                /* sop_discard_mode */
    170         },
    171         { /* 3 lanes - invalid  */ 0 },
    172         { /* 4 lanes */
    173             1837,            /* discard_limit */
    174             3677,            /* lossless_discard */
    175             1129,            /* port_xoff */
    176             1121,            /* port_xon */
    177             384,             /* lossless_xoff */
    178             376,             /* lossless_xon */
    179             60,              /* lossy_low_pri */
    180             145,             /* lossy_discard */
    181             1                /* sop_discard_mode */
    182         },
    183         { /* 5 lanes - Invalid*/ 0 },
    184         { /* 6 lanes - Invalid*/ 0 },
    185         { /* 7 lanes - Invalid*/ 0 },
    186         { /* 8 lanes */
    187             3677,            /* discard_limit */
    188             3677,            /* lossless_discard */
    189             2372,            /* port_xoff */
    190             2364,            /* port_xon */
    191             768,             /* lossless_xoff */
    192             760,             /* lossless_xon */
    193             205,              /* lossy_low_pri */
    194             290,             /* lossy_discard */
    195             1                /* sop_discard_mode */
    196         }
    197     },
    198     /* LOSSY + LOSSLESS Settings*/
    199     { /* indexed by number of lanes used in the port */
    200         { /* 0 lanes - invalid */ 0 },
    201         { /* 1 lane */
    202             457,             /* discard_limit */
    203             3677,            /* lossless_discard */
    204             209,             /* port_xoff */
    205             201,             /* port_xon */
    206             81,              /* lossless_xoff */
    207             73,              /* lossless_xon */
    208             60,              /* lossy_low_pri */
    209             145,             /* lossy_discard */
    210             1                /* sop_discard_mode */
    211         },
    212         { /* 2 lanes */
    213             917,             /* discard_limit */
    214             3677,            /* lossless_discard */
    215             524,             /* port_xoff */
    216             516,             /* port_xon */
    217             194,             /* lossless_xoff */
    218             186,             /* lossless_xon */
    219             60,              /* lossy_low_pri */
    220             145,             /* lossy_discard */
    221             1                /* sop_discard_mode */
    222         },
    223         { /* 3 - invalid  */ 0 },
    224         { /* 4 lanes */
    225             1837,            /* discard_limit */
    226             3677,            /* lossless_discard */
    227             1129,            /* port_xoff */
    228             1121,            /* port_xon */
    229             384,             /* lossless_xoff */
    230             376,             /* lossless_xon */
    231             60,              /* lossy_low_pri */
    232             145,             /* lossy_discard */
    233             1                /* sop_discard_mode */
    234         },
    235         { /* 5 lanes - Invalid*/ 0 },
    236         { /* 6 lanes - Invalid*/ 0 },
    237         { /* 7 lanes - Invalid*/ 0 },
    238         { /* 8 lanes */
    239             3677,            /* discard_limit */
    240             3677,            /* lossless_discard */
    241             2372,            /* port_xoff */
    242             2364,            /* port_xon */
    243             768,             /* lossless_xoff */
    244             760,             /* lossless_xon */
    245             205,             /* lossy_low_pri */
    246             290,             /* lossy_discard */
    247             1                /* sop_discard_mode */
    248         }
    249     }
    250 };
    251 
    252 static const struct soc_tomahawk3_e2e_settings_s {
    253     int speed;
    254     /*Bubble MOP disable.*/
    255     uint8 bmop_disable[SOC_SWITCH_BYPASS_MODE_LOW + 1];
    256     int ca_ct_threshold;
    257     int obm_ct_threshold;
    258     int obm_unsatisfied_threshold;
    259     int ca_unsatisfied_threshold;
    260     int obm_enter_lagging_threshold;
    261     int obm_exit_lagging_threshold;
    262     int ca_enter_lagging_threshold;
    263     int ca_exit_lagging_threshold;
    264 } soc_tomahawk3_e2e_settings_tbl[] = {
    265     {    -1, {0, 0, 0}, 20, 8, 28, 30, 16, 0, 40, 20},       /* SAF     */
    266     { 10000, {1, 1, 1}, 20, 8, 28, 30, 48, 8, 40, 20},       /* 10GE    */
    267     { 25000, {0, 0, 0}, 20, 8, 28, 30, 48, 8, 40, 20},       /* 25GE    */
    268     { 40000, {0, 0, 0}, 20, 8, 28, 30, 48, 8, 40, 20},       /* 40GE    */
    269     { 50000, {0, 0, 0}, 20, 8, 28, 30, 48, 8, 40, 20},       /* 50GE    */
    270     {100000, {0, 0, 0}, 20, 8, 28, 30, 16, 0, 40, 20},       /* 100GE   */
    271     {200000, {0, 0, 0}, 20, 8, 28, 30, 16, 0, 40, 20},       /* 200GE   */
    272     {400000, {0, 0, 0}, 20, 8, 28, 30, 16, 0, 40, 20}        /* 400GE   */
    273 };
    274 
    275 static const struct soc_tomahawk3_peek_depth_settings_s {
    276     int speed;
    277     int peek_depth;
    278 } soc_tomahawk3_peek_depth_settings_tbl[] = {
    279     {    -1, 6},       /* Default */
    280     { 10000, 2},       /* 10GE    */
    281     { 25000, 2},       /* 25GE    */
    282     { 40000, 2},       /* 40GE    */
    283     { 50000, 2},       /* 50GE    */
    284     {100000, 2},       /* 100GE   */
    285     {200000, 4},       /* 200GE   */
    286     {400000, 6}        /* 400GE   */
    287 };
    288 
    289 static const soc_reg_t obm_ctrl_regs[_TH3_PIPES_PER_DEV][_TH3_PBLKS_PER_PIPE] =
    290 {
    291     {IDB_OBM0_CONTROL_PIPE0r, IDB_OBM1_CONTROL_PIPE0r,
    292      IDB_OBM2_CONTROL_PIPE0r, IDB_OBM3_CONTROL_PIPE0r},
    293     {IDB_OBM0_CONTROL_PIPE1r, IDB_OBM1_CONTROL_PIPE1r,
    294      IDB_OBM2_CONTROL_PIPE1r, IDB_OBM3_CONTROL_PIPE1r},
    295     {IDB_OBM0_CONTROL_PIPE2r, IDB_OBM1_CONTROL_PIPE2r,
    296      IDB_OBM2_CONTROL_PIPE2r, IDB_OBM3_CONTROL_PIPE2r},
    297     {IDB_OBM0_CONTROL_PIPE3r, IDB_OBM1_CONTROL_PIPE3r,
    298      IDB_OBM2_CONTROL_PIPE3r, IDB_OBM3_CONTROL_PIPE3r},
    299     {IDB_OBM0_CONTROL_PIPE4r, IDB_OBM1_CONTROL_PIPE4r,
    300      IDB_OBM2_CONTROL_PIPE4r, IDB_OBM3_CONTROL_PIPE4r},
    301     {IDB_OBM0_CONTROL_PIPE5r, IDB_OBM1_CONTROL_PIPE5r,
    302      IDB_OBM2_CONTROL_PIPE5r, IDB_OBM3_CONTROL_PIPE5r},
    303     {IDB_OBM0_CONTROL_PIPE6r, IDB_OBM1_CONTROL_PIPE6r,
    304      IDB_OBM2_CONTROL_PIPE6r, IDB_OBM3_CONTROL_PIPE6r},
    305     {IDB_OBM0_CONTROL_PIPE7r, IDB_OBM1_CONTROL_PIPE7r,
    306      IDB_OBM2_CONTROL_PIPE7r, IDB_OBM3_CONTROL_PIPE7r},
    307 };
    308 
    309 static const soc_reg_t obm_ram_ctrl_regs[_TH3_PIPES_PER_DEV][_TH3_PBLKS_PER_PIPE] =
    310 {
    311     {IDB_OBM0_RAM_CONTROL_PIPE0r, IDB_OBM1_RAM_CONTROL_PIPE0r,
    312      IDB_OBM2_RAM_CONTROL_PIPE0r, IDB_OBM3_RAM_CONTROL_PIPE0r},
    313     {IDB_OBM0_RAM_CONTROL_PIPE1r, IDB_OBM1_RAM_CONTROL_PIPE1r,
    314      IDB_OBM2_RAM_CONTROL_PIPE1r, IDB_OBM3_RAM_CONTROL_PIPE1r},
    315     {IDB_OBM0_RAM_CONTROL_PIPE2r, IDB_OBM1_RAM_CONTROL_PIPE2r,
    316      IDB_OBM2_RAM_CONTROL_PIPE2r, IDB_OBM3_RAM_CONTROL_PIPE2r},
    317     {IDB_OBM0_RAM_CONTROL_PIPE3r, IDB_OBM1_RAM_CONTROL_PIPE3r,
    318      IDB_OBM2_RAM_CONTROL_PIPE3r, IDB_OBM3_RAM_CONTROL_PIPE3r},
    319     {IDB_OBM0_RAM_CONTROL_PIPE4r, IDB_OBM1_RAM_CONTROL_PIPE4r,
    320      IDB_OBM2_RAM_CONTROL_PIPE4r, IDB_OBM3_RAM_CONTROL_PIPE4r},
    321     {IDB_OBM0_RAM_CONTROL_PIPE5r, IDB_OBM1_RAM_CONTROL_PIPE5r,
    322      IDB_OBM2_RAM_CONTROL_PIPE5r, IDB_OBM3_RAM_CONTROL_PIPE5r},
    323     {IDB_OBM0_RAM_CONTROL_PIPE6r, IDB_OBM1_RAM_CONTROL_PIPE6r,
    324      IDB_OBM2_RAM_CONTROL_PIPE6r, IDB_OBM3_RAM_CONTROL_PIPE6r},
    325     {IDB_OBM0_RAM_CONTROL_PIPE7r, IDB_OBM1_RAM_CONTROL_PIPE7r,
    326      IDB_OBM2_RAM_CONTROL_PIPE7r, IDB_OBM3_RAM_CONTROL_PIPE7r},
    327 };
    328 
    329 static const soc_reg_t ca_control_regs[_TH3_PIPES_PER_DEV][_TH3_PBLKS_PER_PIPE] =
    330    {{IDB_CA0_CONTROL_PIPE0r, IDB_CA1_CONTROL_PIPE0r,
    331      IDB_CA2_CONTROL_PIPE0r, IDB_CA3_CONTROL_PIPE0r},
    332     {IDB_CA0_CONTROL_PIPE1r, IDB_CA1_CONTROL_PIPE1r,
    333      IDB_CA2_CONTROL_PIPE1r, IDB_CA3_CONTROL_PIPE1r},
    334     {IDB_CA0_CONTROL_PIPE2r, IDB_CA1_CONTROL_PIPE2r,
    335      IDB_CA2_CONTROL_PIPE2r, IDB_CA3_CONTROL_PIPE2r},
    336     {IDB_CA0_CONTROL_PIPE3r, IDB_CA1_CONTROL_PIPE3r,
    337      IDB_CA2_CONTROL_PIPE3r, IDB_CA3_CONTROL_PIPE3r},
    338     {IDB_CA0_CONTROL_PIPE4r, IDB_CA1_CONTROL_PIPE4r,
    339      IDB_CA2_CONTROL_PIPE4r, IDB_CA3_CONTROL_PIPE4r},
    340     {IDB_CA0_CONTROL_PIPE5r, IDB_CA1_CONTROL_PIPE5r,
    341      IDB_CA2_CONTROL_PIPE5r, IDB_CA3_CONTROL_PIPE5r},
    342     {IDB_CA0_CONTROL_PIPE6r, IDB_CA1_CONTROL_PIPE6r,
    343      IDB_CA2_CONTROL_PIPE6r, IDB_CA3_CONTROL_PIPE6r},
    344     {IDB_CA0_CONTROL_PIPE7r, IDB_CA1_CONTROL_PIPE7r,
    345      IDB_CA2_CONTROL_PIPE7r, IDB_CA3_CONTROL_PIPE7r},
    346 };
    347 
    348 static const soc_reg_t ca_control_1_regs[_TH3_PIPES_PER_DEV] = {
    349     IDB_CA_CONTROL_1_PIPE0r,
    350     IDB_CA_CONTROL_1_PIPE1r,
    351     IDB_CA_CONTROL_1_PIPE2r,
    352     IDB_CA_CONTROL_1_PIPE3r,
    353     IDB_CA_CONTROL_1_PIPE4r,
    354     IDB_CA_CONTROL_1_PIPE5r,
    355     IDB_CA_CONTROL_1_PIPE6r,
    356     IDB_CA_CONTROL_1_PIPE7r
    357 };
    358 
    359 static const soc_mem_t pnum_map_tbl[_TH3_PIPES_PER_DEV] = {
    360     ING_PHY_TO_IDB_PORT_MAP_PIPE0m, ING_PHY_TO_IDB_PORT_MAP_PIPE1m,
    361     ING_PHY_TO_IDB_PORT_MAP_PIPE2m, ING_PHY_TO_IDB_PORT_MAP_PIPE3m,
    362     ING_PHY_TO_IDB_PORT_MAP_PIPE4m, ING_PHY_TO_IDB_PORT_MAP_PIPE5m,
    363     ING_PHY_TO_IDB_PORT_MAP_PIPE6m, ING_PHY_TO_IDB_PORT_MAP_PIPE7m
    364 };
    365 
    366 static const soc_mem_t idb_to_dev_pmap_tbl[_TH3_PIPES_PER_DEV] = {
    367     ING_IDB_TO_DEVICE_PORT_MAP_PIPE0m, ING_IDB_TO_DEVICE_PORT_MAP_PIPE1m,
    368     ING_IDB_TO_DEVICE_PORT_MAP_PIPE2m, ING_IDB_TO_DEVICE_PORT_MAP_PIPE3m,
    369     ING_IDB_TO_DEVICE_PORT_MAP_PIPE4m, ING_IDB_TO_DEVICE_PORT_MAP_PIPE5m,
    370     ING_IDB_TO_DEVICE_PORT_MAP_PIPE6m, ING_IDB_TO_DEVICE_PORT_MAP_PIPE7m
    371 };
    372 
    373 static const soc_reg_t th3_idb_ca_lpbk_ctrl[_TH3_PIPES_PER_DEV]= {
    374          IDB_CA_LPBK_CONTROL_PIPE0r,
    375          IDB_CA_LPBK_CONTROL_PIPE1r,
    376          IDB_CA_LPBK_CONTROL_PIPE2r,
    377          IDB_CA_LPBK_CONTROL_PIPE3r,
    378          IDB_CA_LPBK_CONTROL_PIPE4r,
    379          IDB_CA_LPBK_CONTROL_PIPE5r,
    380          IDB_CA_LPBK_CONTROL_PIPE6r,
    381          IDB_CA_LPBK_CONTROL_PIPE7r};
    382 
    383 static const soc_reg_t th3_idb_ca_cpu_ctrl[_TH3_PIPES_PER_DEV]= {
    384          IDB_CA_CPU_CONTROL_PIPE0r,
    385          IDB_CA_CPU_CONTROL_PIPE1r,
    386          IDB_CA_CPU_CONTROL_PIPE2r,
    387          IDB_CA_CPU_CONTROL_PIPE3r,
    388          IDB_CA_CPU_CONTROL_PIPE4r,
    389          IDB_CA_CPU_CONTROL_PIPE5r,
    390          IDB_CA_CPU_CONTROL_PIPE6r,
    391          IDB_CA_CPU_CONTROL_PIPE7r};
    392 
    393 static const soc_reg_t th3_idb_ca_control_2[_TH3_PIPES_PER_DEV] = {
    394         IDB_CA_CONTROL_2_PIPE0r, IDB_CA_CONTROL_2_PIPE1r,
    395         IDB_CA_CONTROL_2_PIPE2r, IDB_CA_CONTROL_2_PIPE3r,
    396         IDB_CA_CONTROL_2_PIPE4r, IDB_CA_CONTROL_2_PIPE5r,
    397         IDB_CA_CONTROL_2_PIPE6r, IDB_CA_CONTROL_2_PIPE7r
    398     };
    399 
    400 /*! @fn int soc_tomahawk3_get_pipe_from_phy_port(int pnum)
    401  *  @param pnum Physical por number.
    402  *  @brief Helper function to calculate pipe number from physical port number.
    403            This function works for both front panel ports &
    404            non-front panel ports.
    405  *  @returns pipe_number
    406  */
    407 int
    408 soc_tomahawk3_get_pipe_from_phy_port(int pnum)
    409 {
    410     return((pnum==_TH3_PHY_PORT_LPBK0)                        ? 0 :
    411            (pnum==_TH3_PHY_PORT_LPBK1)                        ? 1 :
    412            (pnum==_TH3_PHY_PORT_LPBK2)                        ? 2 :
    413            (pnum==_TH3_PHY_PORT_LPBK3)                        ? 3 :
    414            (pnum==_TH3_PHY_PORT_LPBK4)                        ? 4 :
    415            (pnum==_TH3_PHY_PORT_LPBK5)                        ? 5 :
    416            (pnum==_TH3_PHY_PORT_LPBK6)                        ? 6 :
    417            (pnum==_TH3_PHY_PORT_LPBK7)                        ? 7 :
    418            (pnum==_TH3_PHY_PORT_CPU)                          ? 0 :
    419            (pnum==_TH3_PHY_PORT_MNG0)                         ? 1 :
    420            (pnum==_TH3_PHY_PORT_MNG1)                         ? 5 :
    421            (((pnum - 1) >> 5) & 7));
    422 }
    423 
    424 /*! @fn int soc_tomahawk3_get_pipe_pm_from_phy_port(int pnum)
    425  *  @param pnum Physical por number.
    426  *  @brief Helper function to calculate PM number from physical port number.
    427            This function should be called only for front panel ports.
    428  *  @returns PM number
    429  */
    430 int
    431 soc_tomahawk3_get_pipe_pm_from_phy_port(int pnum)
    432 {
    433     return (((pnum - 1) & 0x1f) >> 3);
    434 }
    435 
    436 /*! @fn int soc_tomahawk3_get_subp_from_phy_port(int pnum)
    437  *  @param pnum Physical por number.
    438  *  @brief Helper function to calculate subport number from physical port number.
    439            This function should be called only for front panel ports.
    440  *  @returns subport number
    441  */
    442 int
    443 soc_tomahawk3_get_subp_from_phy_port(int pnum)
    444 {
    445     return ((pnum - 1) & 0x7);
    446 }
    447 
    448 /*! @fn int soc_tomahawk3_phy_is_lpbk_port(int pnum)
    449  *  @param pnum Physical por number.
    450  *  @brief Helper function to check if the physical port is loopback port.
    451  *  @returns 1 or 0
    452  */
    453 int
    454 soc_tomahawk3_phy_is_lpbk_port(int pnum)
    455 {
    456     return ((pnum==_TH3_PHY_PORT_LPBK0)||
    457             (pnum==_TH3_PHY_PORT_LPBK1)||
    458             (pnum==_TH3_PHY_PORT_LPBK2)||
    459             (pnum==_TH3_PHY_PORT_LPBK3)||
    460             (pnum==_TH3_PHY_PORT_LPBK4)||
    461             (pnum==_TH3_PHY_PORT_LPBK5)||
    462             (pnum==_TH3_PHY_PORT_LPBK6)||
    463             (pnum==_TH3_PHY_PORT_LPBK7));
    464 }
    465 
    466 /*! @fn int soc_tomahawk3_phy_is_cpu_mgmt_port(int pnum)
    467  *  @param pnum Physical por number.
    468  *  @brief Helper function to check if the physical port is either CPU or
    469  *         management port.
    470  *  @returns 1 or 0
    471  */
    472 int
    473 soc_tomahawk3_phy_is_cpu_mgmt_port(int pnum)
    474 {
    475     return ((pnum==_TH3_PHY_PORT_CPU)||
    476             (pnum==_TH3_PHY_PORT_MNG0)||
    477             (pnum==_TH3_PHY_PORT_MNG1));
    478 }
    479 
    480 /*! @fn int soc_tomahawk3_idb_pa_reset(int unit,
    481             soc_port_map_type_t *port_map, int lport, int reset)
    482  *  @param unit Chip unit number.
    483  *  @param port_map Pointer to a soc_port_map_type_t struct variable
    484  *  @param lport Logical port number for the port going up
    485  *  @param reset IDB CA write clock domain reset. 1 - Apply reset,
    486                                                   0 - Release reset.
    487  *  @brief Helper function to apply/ or release IDB OBM buffer reset.
    488  *  @returns SOC_E_NONE
    489  */
    490 int
    491 soc_tomahawk3_idb_pa_reset(int unit,
    492     soc_port_map_type_t *port_map, int lport, int reset)
    493 {
    494     soc_reg_t reg;
    495     uint32 rval32;
    496     int phy_port;
    497     int pipe_num;
    498     int pm_num;
    499     int rst_l;
    500     static const soc_reg_t idb_pa_reset_ctrl_regs[_TH3_PIPES_PER_DEV] = {
    501         IDB_PA_RESET_CONTROL_PIPE0r,
    502         IDB_PA_RESET_CONTROL_PIPE1r,
    503         IDB_PA_RESET_CONTROL_PIPE2r,
    504         IDB_PA_RESET_CONTROL_PIPE3r,
    505         IDB_PA_RESET_CONTROL_PIPE4r,
    506         IDB_PA_RESET_CONTROL_PIPE5r,
    507         IDB_PA_RESET_CONTROL_PIPE6r,
    508         IDB_PA_RESET_CONTROL_PIPE7r
    509     };
    510     static const soc_field_t idb_pa_reset_fields[] = {
    511         PM0_PA_RST_Lf, PM1_PA_RST_Lf, PM2_PA_RST_Lf, PM3_PA_RST_Lf
    512     };
    513 
    514     phy_port = port_map->port_l2p_mapping[lport];
    515     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
    516     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
    517     reg = idb_pa_reset_ctrl_regs[pipe_num];
    518     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit,
    519                            reg, REG_PORT_ANY, 0, &rval32));
    520     rst_l = reset ? 0 : 1;
    521     soc_reg_field_set(unit, reg, &rval32, idb_pa_reset_fields[pm_num], rst_l);
    522     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg,
    523                         REG_PORT_ANY, 0, rval32));
    524 
    525     return SOC_E_NONE;
    526 }
    527 
    528 /*! @fn int soc_tomahawk3_idb_obm_reset(int unit,
    529             soc_port_map_type_t *port_map, int lport, int reset)
    530  *  @param unit Chip unit number.
    531  *  @param port_map Pointer to a soc_port_map_type_t struct variable
    532  *  @param lport Logical port number for the port going up
    533  *  @param reset IDB CA write clock domain reset. 1 - Apply reset,
    534                                                   0 - Release reset.
    535  *  @brief Helper function to apply/ or release IDB OBM buffer reset.
    536  *  @returns SOC_E_NONE
    537  */
    538 int
    539 soc_tomahawk3_idb_obm_reset(int unit,
    540     soc_port_map_type_t *port_map, int lport, int reset)
    541 {
    542     soc_reg_t reg;
    543     uint64 rval64, fldval64;
    544     int phy_port;
    545     int pipe_num;
    546     int pm_num;
    547     int subp;
    548     static const soc_field_t obm_port_reset_fields[] = {
    549         PORT0_RESETf, PORT1_RESETf, PORT2_RESETf, PORT3_RESETf,
    550         PORT4_RESETf, PORT5_RESETf, PORT6_RESETf, PORT7_RESETf
    551     };
    552 
    553     phy_port = port_map->port_l2p_mapping[lport];
    554     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
    555     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
    556     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
    557     reg = obm_ctrl_regs[pipe_num][pm_num];
    558     SOC_IF_ERROR_RETURN(soc_reg_rawport_get(unit,
    559                            reg, REG_PORT_ANY, 0, &rval64));
    560     COMPILER_64_ZERO(fldval64);
    561     soc_reg64_field_set(unit, reg, &rval64, OBM_RESETf, fldval64);
    562     COMPILER_64_SET(fldval64,0, reset);
    563     soc_reg64_field_set(unit, reg, &rval64,
    564              obm_port_reset_fields[subp], fldval64);
    565     SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg,
    566                         REG_PORT_ANY, 0, rval64));
    567 
    568     return SOC_E_NONE;
    569 }
    570 
    571 /*! @fn int soc_tomahawk3_idb_obm_rst_rel_all(int unit)
    572  *  @param unit Chip unit number.
    573  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
    574                                struct variable
    575  *  @brief Helper function to release IDB OBM buffer reset
    576            for all the IDB front panel ports during init time bringup.
    577  *  @returns SOC_E_NONE
    578  */
    579 int
    580 soc_tomahawk3_idb_obm_rst_rel_all(int unit,
    581     soc_port_schedule_state_t *port_schedule_state)
    582 {
    583     soc_reg_t reg;
    584     uint64 rval64, fldval64;
    585     uint32 pipe_map;
    586     int pipe_num;
    587     int pm_num;
    588     int subp;
    589     int pnum;
    590     int lport;
    591     int tsc_enabled;
    592     uint16 dev_id;
    593     uint8 rev_id;
    594 
    595     static const soc_field_t obm_port_reset_fields[] = {
    596         PORT0_RESETf, PORT1_RESETf, PORT2_RESETf, PORT3_RESETf,
    597         PORT4_RESETf, PORT5_RESETf, PORT6_RESETf, PORT7_RESETf
    598     };
    599 
    600     soc_cm_get_id(unit, &dev_id, &rev_id);
    601   
    602     soc_tomahawk3_get_pipe_map(unit,port_schedule_state, &pipe_map);
    603     for (pipe_num = 0; pipe_num < _TH3_PIPES_PER_DEV; pipe_num++) {
    604         if ((pipe_map >> pipe_num) & 1){
    605             for (pm_num = 0; pm_num < _TH3_PBLKS_PER_PIPE; pm_num++) {
    606                 tsc_enabled=0;
    607                 for (subp = 0; subp < _TH3_PORTS_PER_PBLK; subp++) {
    608                    pnum = ((pipe_num<<5) | (pm_num<<3) | subp) +1;
    609                    lport = port_schedule_state->
    610                            out_port_map.port_p2l_mapping[pnum];
    611                    tsc_enabled |=
    612                        (port_schedule_state->
    613                        out_port_map.log_port_speed[lport] > 0 )?1:0;
    614                 }
    615                 if (tsc_enabled) {
    616                     reg = obm_ctrl_regs[pipe_num][pm_num];
    617                     SOC_IF_ERROR_RETURN(soc_reg_rawport_get(unit,
    618                         reg, REG_PORT_ANY, 0, &rval64));
    619                     COMPILER_64_ZERO(fldval64);
    620                     soc_reg64_field_set(unit, reg, &rval64,
    621                         OBM_RESETf, fldval64);
    622 
    623                     for (subp = 0; subp < _TH3_PORTS_PER_PBLK; subp++) {
    624                         COMPILER_64_ZERO(fldval64);
    625                         soc_reg64_field_set(unit, reg, &rval64,
    626                             obm_port_reset_fields[subp], fldval64);
    627                     }
    628                     SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg,
    629                                         REG_PORT_ANY, 0, rval64));
    630                   
    631                     if (rev_id == BCM56980_A0_REV_ID) {
    632                         reg = obm_ram_ctrl_regs[pipe_num][pm_num];
    633                         COMPILER_64_SET(rval64, 0, 0x180);
    634                         SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg,
    635                                         REG_PORT_ANY, 0, rval64));
    636                     }
    637 
    638                 }
    639             }
    640         }
    641     }
    642     return SOC_E_NONE;
    643 }
    644 
    645 /*! @fn int soc_tomahawk3_idb_ca_buffer_config(int unit,
    646  *          soc_port_map_type_t *port_map, int lport)
    647  *  @param unit Chip unit number.
    648  *  @param port_map Pointer to a soc_port_map_type_t struct variable
    649  *  @param lport Logical port number for the port going up
    650  *  @brief Helper function to Configure CA buffer start & buffer end address.
    651  *  @returns SOC_E_NONE
    652  */
    653 int
    654 soc_tomahawk3_idb_ca_buffer_config(
    655     int unit, soc_port_map_type_t *port_map, int lport)
    656 {
    657     soc_reg_t reg;
    658     uint32 rval32;
    659     uint32 buffer_start_addr;
    660     uint32 buffer_end_addr;
    661     int phy_port;
    662     int pm_num;
    663     int subp;
    664     int num_of_lanes;
    665     int pipe_num;
    666     static const soc_reg_t ca_buffer_config_regs[_TH3_PIPES_PER_DEV]
    667        [_TH3_PBLKS_PER_PIPE] =
    668        {{IDB_CA0_BUFFER_CONFIG_PIPE0r, IDB_CA1_BUFFER_CONFIG_PIPE0r,
    669          IDB_CA2_BUFFER_CONFIG_PIPE0r, IDB_CA3_BUFFER_CONFIG_PIPE0r},
    670         {IDB_CA0_BUFFER_CONFIG_PIPE1r, IDB_CA1_BUFFER_CONFIG_PIPE1r,
    671          IDB_CA2_BUFFER_CONFIG_PIPE1r, IDB_CA3_BUFFER_CONFIG_PIPE1r},
    672         {IDB_CA0_BUFFER_CONFIG_PIPE2r, IDB_CA1_BUFFER_CONFIG_PIPE2r,
    673          IDB_CA2_BUFFER_CONFIG_PIPE2r, IDB_CA3_BUFFER_CONFIG_PIPE2r},
    674         {IDB_CA0_BUFFER_CONFIG_PIPE3r, IDB_CA1_BUFFER_CONFIG_PIPE3r,
    675          IDB_CA2_BUFFER_CONFIG_PIPE3r, IDB_CA3_BUFFER_CONFIG_PIPE3r},
    676         {IDB_CA0_BUFFER_CONFIG_PIPE4r, IDB_CA1_BUFFER_CONFIG_PIPE4r,
    677          IDB_CA2_BUFFER_CONFIG_PIPE4r, IDB_CA3_BUFFER_CONFIG_PIPE4r},
    678         {IDB_CA0_BUFFER_CONFIG_PIPE5r, IDB_CA1_BUFFER_CONFIG_PIPE5r,
    679          IDB_CA2_BUFFER_CONFIG_PIPE5r, IDB_CA3_BUFFER_CONFIG_PIPE5r},
    680         {IDB_CA0_BUFFER_CONFIG_PIPE6r, IDB_CA1_BUFFER_CONFIG_PIPE6r,
    681          IDB_CA2_BUFFER_CONFIG_PIPE6r, IDB_CA3_BUFFER_CONFIG_PIPE6r},
    682         {IDB_CA0_BUFFER_CONFIG_PIPE7r, IDB_CA1_BUFFER_CONFIG_PIPE7r,
    683          IDB_CA2_BUFFER_CONFIG_PIPE7r, IDB_CA3_BUFFER_CONFIG_PIPE7r},
    684     };
    685 
    686     phy_port = port_map->port_l2p_mapping[lport];
    687     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
    688     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
    689     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
    690     num_of_lanes = port_map->port_num_lanes[lport];
    691     buffer_start_addr = subp * _TH3_CA_BUFFER_SIZE / _TH3_PORTS_PER_PBLK;
    692     buffer_end_addr = buffer_start_addr +
    693            num_of_lanes * _TH3_CA_BUFFER_SIZE/_TH3_PORTS_PER_PBLK -1;
    694     reg = ca_buffer_config_regs[pipe_num][pm_num];
    695     rval32 = 0;
    696     soc_reg_field_set(unit, reg, &rval32, BUFFER_STARTf,
    697                                            buffer_start_addr);
    698     soc_reg_field_set(unit, reg, &rval32, BUFFER_ENDf,
    699                                            buffer_end_addr);
    700     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit,
    701                                   reg, REG_PORT_ANY, subp, rval32));
    702     return SOC_E_NONE;
    703 }
    704 
    705 /*! @fn int soc_tomahawk3_idb_ca_wr_domain_reset(int unit,
    706             soc_port_map_type_t *port_map, int lport, int reset)
    707  *  @param unit Chip unit number.
    708  *  @param port_map Pointer to a soc_port_map_type_t struct variable
    709  *  @param lport Logical port number for the port going up
    710  *  @param reset IDB CA write clock domain reset. 1 - Apply reset,
    711                                                   0 - Release reset.
    712  *  @brief Helper function to apply/release IDB CA write clock domain reset.
    713  *  @returns SOC_E_NONE
    714  */
    715 int
    716 soc_tomahawk3_idb_ca_wr_domain_reset(
    717     int unit, soc_port_map_type_t *port_map, int lport, int reset)
    718 {
    719     soc_reg_t reg;
    720     uint32 rval32;
    721     uint32 fldval32;
    722     int phy_port;
    723     int pipe_num;
    724     int pm_num;
    725     int subp;
    726     static const soc_field_t ca_ctrl_reg_reset_fields[] = {
    727         PORT0_RESETf, PORT1_RESETf, PORT2_RESETf, PORT3_RESETf,
    728         PORT4_RESETf, PORT5_RESETf, PORT6_RESETf, PORT7_RESETf
    729     };
    730 
    731     phy_port = port_map->port_l2p_mapping[lport];
    732     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
    733     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
    734     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
    735     reg = ca_control_regs[pipe_num][pm_num];
    736     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit,
    737                            reg, REG_PORT_ANY, 0, &rval32));
    738     fldval32=reset;
    739     soc_reg_field_set(unit, reg, &rval32,
    740         ca_ctrl_reg_reset_fields[subp], fldval32);
    741     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg,
    742                         REG_PORT_ANY, 0, rval32));
    743     return SOC_E_NONE;
    744 }
    745 
    746 /*! @fn int soc_tomahawk3_idb_ca_wr_dom_rst_rel_all(int unit,
    747                 soc_port_schedule_state_t *port_schedule_state)
    748  *  @param unit Chip unit number.
    749  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
    750                                struct variable
    751  *  @brief Helper function to release IDB CA write clock domain reset
    752            for all the IDB front panel ports during init time bringup.
    753  *  @returns SOC_E_NONE
    754  */
    755 int
    756 soc_tomahawk3_idb_ca_wr_dom_rst_rel_all( int unit,
    757     soc_port_schedule_state_t *port_schedule_state)
    758 {
    759     soc_reg_t reg;
    760     uint32 rval32;
    761     uint32 fldval32;
    762     uint32 pipe_map;
    763     int pipe_num;
    764     int pm_num;
    765     int subp;
    766     int pnum;
    767     int lport;
    768     int tsc_enabled;
    769     static const soc_field_t ca_ctrl_reg_reset_fields[] = {
    770         PORT0_RESETf, PORT1_RESETf, PORT2_RESETf, PORT3_RESETf,
    771         PORT4_RESETf, PORT5_RESETf, PORT6_RESETf, PORT7_RESETf
    772     };
    773 
    774     soc_tomahawk3_get_pipe_map(unit,port_schedule_state, &pipe_map);
    775     for (pipe_num = 0; pipe_num < _TH3_PIPES_PER_DEV; pipe_num++) {
    776         if ((pipe_map >> pipe_num) & 1){
    777             for (pm_num = 0; pm_num < _TH3_PBLKS_PER_PIPE; pm_num++) {
    778                 tsc_enabled=0;
    779                 for (subp = 0; subp < _TH3_PORTS_PER_PBLK; subp++) {
    780                    pnum = ((pipe_num<<5) | (pm_num<<3) | subp) +1;
    781                    lport = port_schedule_state->
    782                            out_port_map.port_p2l_mapping[pnum];
    783                    tsc_enabled |=
    784                        (port_schedule_state->
    785                        out_port_map.log_port_speed[lport] > 0 )?1:0;
    786                 }
    787                 if (tsc_enabled) {
    788                     reg = ca_control_regs[pipe_num][pm_num];
    789                     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit,
    790                                            reg, REG_PORT_ANY, 0, &rval32));
    791                     for (subp = 0; subp < _TH3_PORTS_PER_PBLK; subp++) {
    792                         fldval32=0;
    793                         soc_reg_field_set(unit, reg, &rval32,
    794                             ca_ctrl_reg_reset_fields[subp], fldval32);
    795                     }
    796                     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg,
    797                                         REG_PORT_ANY, 0, rval32));
    798                 }
    799             }
    800         }
    801     }
    802     return SOC_E_NONE;
    803 }
    804 
    805 /*! @fn int soc_tomahawk3_idb_ca_rd_domain_reset(int unit,
    806             soc_port_map_type_t *port_map, int lport, int reset)
    807  *  @param unit Chip unit number.
    808  *  @param port_map Pointer to a soc_port_map_type_t struct variable
    809  *  @param lport Logical port number for the port going up
    810  *  @param reset IDB CA read clock domain reset. 1 - Apply reset,
    811                                                   0 - Release reset.
    812  *  @brief Helper function to release IDB CA read clock domain reset.
    813  *  @returns SOC_E_NONE
    814  */
    815 int
    816 soc_tomahawk3_idb_ca_rd_domain_reset(
    817     int unit, soc_port_map_type_t *port_map, int lport, int reset)
    818 {
    819     soc_reg_t reg;
    820     uint32 rval32;
    821     int phy_port;
    822     int pipe_num;
    823     int pm_num;
    824     int subp;
    825     static const soc_field_t ca_ctrl_1_reg_reset_fields[] = {
    826         PORT0_RESETf, PORT1_RESETf, PORT2_RESETf, PORT3_RESETf,
    827         PORT4_RESETf, PORT5_RESETf, PORT6_RESETf, PORT7_RESETf
    828     };
    829 
    830     phy_port = port_map->port_l2p_mapping[lport];
    831     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
    832     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
    833     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
    834     reg = ca_control_1_regs[pipe_num];
    835     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit,
    836                            reg, REG_PORT_ANY, pm_num, &rval32));
    837     soc_reg_field_set(unit, reg, &rval32,
    838         ca_ctrl_1_reg_reset_fields[subp], reset);
    839     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg,
    840                         REG_PORT_ANY, pm_num, rval32));
    841     return SOC_E_NONE;
    842 }
    843 
    844 /*! @fn int soc_tomahawk3_idb_ca_rd_dom_rst_rel_all(int unit,
    845                 soc_port_schedule_state_t *port_schedule_state)
    846  *  @param unit Chip unit number.
    847  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
    848                                struct variable
    849  *  @brief Helper function to release IDB CA read clock domain reset
    850            for all the IDB front panel ports during init time bringup.
    851  *  @returns SOC_E_NONE
    852  */
    853 int
    854 soc_tomahawk3_idb_ca_rd_dom_rst_rel_all(int unit,
    855     soc_port_schedule_state_t *port_schedule_state)
    856 {
    857     soc_reg_t reg;
    858     uint32 rval32;
    859     uint32 pipe_map;
    860     int pipe_num;
    861     int pm_num;
    862     int subp;
    863     int pnum;
    864     int lport;
    865     int tsc_enabled;
    866     static const soc_field_t ca_ctrl_1_reg_reset_fields[] = {
    867         PORT0_RESETf, PORT1_RESETf, PORT2_RESETf, PORT3_RESETf,
    868         PORT4_RESETf, PORT5_RESETf, PORT6_RESETf, PORT7_RESETf
    869     };
    870 
    871     soc_tomahawk3_get_pipe_map(unit,port_schedule_state, &pipe_map);
    872     for (pipe_num = 0; pipe_num < _TH3_PIPES_PER_DEV; pipe_num++) {
    873         if ((pipe_map >> pipe_num) & 1){
    874             for (pm_num = 0; pm_num < _TH3_PBLKS_PER_PIPE; pm_num++) {
    875                 tsc_enabled=0;
    876                 for (subp = 0; subp < _TH3_PORTS_PER_PBLK; subp++) {
    877                    pnum = ((pipe_num<<5) | (pm_num<<3) | subp) +1;
    878                    lport = port_schedule_state->
    879                            out_port_map.port_p2l_mapping[pnum];
    880                    tsc_enabled |=
    881                        (port_schedule_state->
    882                        out_port_map.log_port_speed[lport] > 0 )?1:0;
    883                 }
    884                 if (tsc_enabled) {
    885                     reg = ca_control_1_regs[pipe_num];
    886                     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit,
    887                                    reg, REG_PORT_ANY, pm_num, &rval32));
    888                     for (subp = 0; subp < _TH3_PORTS_PER_PBLK; subp++) {
    889                         soc_reg_field_set(unit, reg, &rval32,
    890                             ca_ctrl_1_reg_reset_fields[subp], 0);
    891                     }
    892                     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg,
    893                                         REG_PORT_ANY, pm_num, rval32));
    894                 }
    895             }
    896         }
    897     }
    898     return SOC_E_NONE;
    899 }
    900 
    901 /*! @fn int soc_tomahawk3_idb_init_pnum_mapping_tbl(int unit,
    902  *          soc_port_map_type_t *port_map, int lport)
    903  *  @param unit Chip unit number.
    904  *  @param port_map Pointer to a soc_port_map_type_t struct variable
    905  *  @param lport Logical port number for the port going up
    906  *  @brief Helper function to initialize phy to idb port mapping table for the
    907            front panel ports comming up. This function should be called
    908            only for front panel ports
    909  *  @returns SOC_E_NONE
    910  */
    911 int
    912 soc_tomahawk3_idb_init_pnum_mapping_tbl(
    913     int unit, soc_port_map_type_t *port_map, int lport)
    914 {
    915     soc_mem_t mem;
    916     uint32 entry[SOC_MAX_MEM_WORDS];
    917     uint32 memfld;
    918     int pipe, phy_port, idb_port;
    919 
    920     phy_port = port_map->port_l2p_mapping[lport];
    921     if (!_TH3_PHY_IS_FRONT_PANEL_PORT(phy_port)){
    922         LOG_ERROR(BSL_LS_SOC_PORT, (BSL_META_U(unit,
    923             "ERROR soc_tomahawk3_idb_init_pnum_mapping_tbl function"
    924             "should be called only for front panel ports.\n "
    925             "lport %0d phy_port %0d"),lport,phy_port));
    926         return SOC_E_PARAM;
    927     }
    928     sal_memset(entry, 0, sizeof(entry));
    929     idb_port = port_map->port_l2i_mapping[lport];
    930     pipe = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
    931     mem = pnum_map_tbl[pipe];
    932     memfld = idb_port;
    933     soc_mem_field_set(unit, mem, entry, IDB_PORTf, &memfld);
    934     memfld = 1;
    935     soc_mem_field_set(unit, mem, entry, VALIDf, &memfld);
    936     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
    937         (phy_port - 1 - (pipe * _TH3_GPHY_PORTS_PER_PIPE)), entry));
    938 
    939     return SOC_E_NONE;
    940 }
    941 
    942 /*! @fn int soc_tomahawk3_idb_init_idb_to_dev_pmap_tbl(int unit,
    943             soc_port_map_type_t *port_map, int lport)
    944  *  @param unit Chip unit number.
    945  *  @param port_map Pointer to a soc_port_map_type_t struct variable
    946  *  @param lport Logical port number for the port going up
    947  *  @brief Helper function to initialize idb to local device port number
    948            for the ports comming up. This function works for both
    949            front panel ports & non-front panel ports.
    950  *  @returns SOC_E_NONE
    951  */
    952 int
    953 soc_tomahawk3_idb_init_idb_to_dev_pmap_tbl(
    954     int unit, soc_port_map_type_t *port_map, int lport)
    955 {
    956     soc_mem_t mem;
    957     uint32 entry[SOC_MAX_MEM_WORDS];
    958     uint32 memfld;
    959     int pipe, phy_port, idb_port;
    960     int local_dev_port;
    961 
    962     sal_memset(entry, 0, sizeof(entry));
    963     phy_port = port_map->port_l2p_mapping[lport];
    964     idb_port = port_map->port_l2i_mapping[lport];
    965     pipe = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
    966     local_dev_port =
    967         port_map->port_p2l_mapping[phy_port] % _TH3_DEV_PORTS_PER_PIPE;
    968     mem = idb_to_dev_pmap_tbl[pipe];
    969     memfld = local_dev_port;
    970     soc_mem_field_set(unit, mem, entry, DEVICE_PORTf, &memfld);
    971     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
    972                                       idb_port, entry));
    973     return SOC_E_NONE;
    974 }
    975 
    976 
    977 /*! @fn int soc_tomahawk3_idb_init_idb_to_dev_all_pipe(int unit,
    978             int pipe)
    979  *  @param unit Chip unit number.
    980  *  @param pipe pipe num
    981  *  @brief Helper function to initialize idb to local device port number
    982            This function works for both
    983            front panel ports & non-front panel ports.
    984  *  @returns SOC_E_NONE
    985  */
    986 static int
    987 soc_tomahawk3_idb_init_idb_to_dev_all_pipe(
    988     int unit,
    989     int pipe)
    990 {
    991     soc_mem_t mem;
    992     uint32 entry[SOC_MAX_MEM_WORDS];
    993     uint32 memfld;
    994     int local_dev_port, idb_port;
    995 
    996    for (local_dev_port = 0; local_dev_port < _TH3_DEV_PORTS_PER_PIPE; local_dev_port++) {
    997         if (pipe == 0){
    998             idb_port = (local_dev_port == 0) ? 19 : (local_dev_port - 1);
    999         } else {
   1000             idb_port = (local_dev_port == 18) ? 19 :
   1001                        ((local_dev_port == 19) ? 18 : local_dev_port);
   1002         }
   1003 
   1004         sal_memset(entry, 0, sizeof(entry));
   1005         mem = idb_to_dev_pmap_tbl[pipe];
   1006         memfld = local_dev_port;
   1007         soc_mem_field_set(unit, mem, entry, DEVICE_PORTf, &memfld);
   1008         SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
   1009                                       idb_port, entry));
   1010     }
   1011     return SOC_E_NONE;
   1012 }
   1013 
   1014 
   1015 /*! @fn int soc_tomahawk3_idb_wr_obm_shared_config(int unit,
   1016             soc_port_schedule_state_t *port_schedule_state, int lport)
   1017  *  @param unit Chip unit number.
   1018  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   1019                                struct variable
   1020  *  @param lport Logical port number for the port going up.
   1021  *  @brief Helper function to config OBM shared config register.
   1022  *  @returns SOC_E_NONE
   1023  */
   1024 int
   1025 soc_tomahawk3_idb_wr_obm_shared_config(int unit,
   1026     soc_port_schedule_state_t *port_schedule_state, int lport)
   1027 {
   1028     soc_reg_t reg;
   1029     int sop_discard_mode;
   1030     uint32 rval;
   1031     int phy_port;
   1032     int pipe_num;
   1033     int pm_num;
   1034     int num_lanes;
   1035     int lossless;
   1036     const soc_reg_t obm_shared_cfg[_TH3_PIPES_PER_DEV][_TH3_PBLKS_PER_PIPE] = {
   1037         {IDB_OBM0_SHARED_CONFIG_PIPE0r, IDB_OBM1_SHARED_CONFIG_PIPE0r,
   1038          IDB_OBM2_SHARED_CONFIG_PIPE0r, IDB_OBM3_SHARED_CONFIG_PIPE0r},
   1039         {IDB_OBM0_SHARED_CONFIG_PIPE1r, IDB_OBM1_SHARED_CONFIG_PIPE1r,
   1040          IDB_OBM2_SHARED_CONFIG_PIPE1r, IDB_OBM3_SHARED_CONFIG_PIPE1r},
   1041         {IDB_OBM0_SHARED_CONFIG_PIPE2r, IDB_OBM1_SHARED_CONFIG_PIPE2r,
   1042          IDB_OBM2_SHARED_CONFIG_PIPE2r, IDB_OBM3_SHARED_CONFIG_PIPE2r},
   1043         {IDB_OBM0_SHARED_CONFIG_PIPE3r, IDB_OBM1_SHARED_CONFIG_PIPE3r,
   1044          IDB_OBM2_SHARED_CONFIG_PIPE3r, IDB_OBM3_SHARED_CONFIG_PIPE3r},
   1045         {IDB_OBM0_SHARED_CONFIG_PIPE4r, IDB_OBM1_SHARED_CONFIG_PIPE4r,
   1046          IDB_OBM2_SHARED_CONFIG_PIPE4r, IDB_OBM3_SHARED_CONFIG_PIPE4r},
   1047         {IDB_OBM0_SHARED_CONFIG_PIPE5r, IDB_OBM1_SHARED_CONFIG_PIPE5r,
   1048          IDB_OBM2_SHARED_CONFIG_PIPE5r, IDB_OBM3_SHARED_CONFIG_PIPE5r},
   1049         {IDB_OBM0_SHARED_CONFIG_PIPE6r, IDB_OBM1_SHARED_CONFIG_PIPE6r,
   1050          IDB_OBM2_SHARED_CONFIG_PIPE6r, IDB_OBM3_SHARED_CONFIG_PIPE6r},
   1051         {IDB_OBM0_SHARED_CONFIG_PIPE7r, IDB_OBM1_SHARED_CONFIG_PIPE7r,
   1052          IDB_OBM2_SHARED_CONFIG_PIPE7r, IDB_OBM3_SHARED_CONFIG_PIPE7r}
   1053     };
   1054 
   1055     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   1056     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1057     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1058     num_lanes = port_schedule_state->out_port_map.port_num_lanes[lport];
   1059     lossless = port_schedule_state->lossless;
   1060     reg = obm_shared_cfg[pipe_num][pm_num];
   1061     sop_discard_mode =
   1062         soc_tomahawk3_obm_settings[lossless][num_lanes].sop_discard_mode;
   1063     rval = 0;
   1064     soc_reg_field_set(unit, reg, &rval, SOP_DISCARD_MODEf, sop_discard_mode);
   1065     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY, 0, rval));
   1066     return SOC_E_NONE;
   1067 }
   1068 
   1069 /*! @fn int soc_tomahawk3_idb_obm_tdm(int unit,
   1070  *          soc_port_map_type_t *port_map, int lport)
   1071  *  @param unit Chip unit number.
   1072  *  @param port_map Pointer to a soc_port_map_type_t struct variable
   1073  *  @param lport Logical port number for the port going up
   1074  *  @brief Helper function to Configure OBM TDM slots for teh port going up.
   1075  *  @returns SOC_E_NONE
   1076  */
   1077 int
   1078 soc_tomahawk3_idb_obm_tdm_cfg(
   1079     int unit, soc_port_map_type_t *port_map, int lport)
   1080 {
   1081     soc_reg_t reg;
   1082     uint32 rval32;
   1083     int phy_port;
   1084     int phy_port_base;
   1085     int pm_num;
   1086     int num_lanes;
   1087     int pipe_num;
   1088     int curr_lport;
   1089     int lane;
   1090     int i;
   1091     static const soc_reg_t obm_tdm_regs[_TH3_PIPES_PER_DEV]
   1092        [_TH3_PBLKS_PER_PIPE] =
   1093        {{IDB_OBM0_TDM_PIPE0r, IDB_OBM1_TDM_PIPE0r,
   1094          IDB_OBM2_TDM_PIPE0r, IDB_OBM3_TDM_PIPE0r},
   1095         {IDB_OBM0_TDM_PIPE1r, IDB_OBM1_TDM_PIPE1r,
   1096          IDB_OBM2_TDM_PIPE1r, IDB_OBM3_TDM_PIPE1r},
   1097         {IDB_OBM0_TDM_PIPE2r, IDB_OBM1_TDM_PIPE2r,
   1098          IDB_OBM2_TDM_PIPE2r, IDB_OBM3_TDM_PIPE2r},
   1099         {IDB_OBM0_TDM_PIPE3r, IDB_OBM1_TDM_PIPE3r,
   1100          IDB_OBM2_TDM_PIPE3r, IDB_OBM3_TDM_PIPE3r},
   1101         {IDB_OBM0_TDM_PIPE4r, IDB_OBM1_TDM_PIPE4r,
   1102          IDB_OBM2_TDM_PIPE4r, IDB_OBM3_TDM_PIPE4r},
   1103         {IDB_OBM0_TDM_PIPE5r, IDB_OBM1_TDM_PIPE5r,
   1104          IDB_OBM2_TDM_PIPE5r, IDB_OBM3_TDM_PIPE5r},
   1105         {IDB_OBM0_TDM_PIPE6r, IDB_OBM1_TDM_PIPE6r,
   1106          IDB_OBM2_TDM_PIPE6r, IDB_OBM3_TDM_PIPE6r},
   1107         {IDB_OBM0_TDM_PIPE7r, IDB_OBM1_TDM_PIPE7r,
   1108          IDB_OBM2_TDM_PIPE7r, IDB_OBM3_TDM_PIPE7r},
   1109     };
   1110     static const int tdm_index[_TH3_PORTS_PER_PBLK] = {
   1111         0, 4, 2, 6, 1, 5, 3, 7
   1112     };
   1113     int lane_to_port_map[_TH3_PORTS_PER_PBLK];
   1114 
   1115     /* Set the lane_to_port_map based on num_lanes */
   1116     for (lane = 0; lane < _TH3_PORTS_PER_PBLK; lane++) {
   1117         lane_to_port_map[lane] = lane;
   1118     }
   1119     phy_port = port_map->port_l2p_mapping[lport];
   1120     phy_port_base = (((phy_port - 1) >> 3) << 3) + 1;
   1121     for (lane = 0; lane < _TH3_PORTS_PER_PBLK; lane++) {
   1122         curr_lport = port_map->port_p2l_mapping[phy_port_base + lane];
   1123         if (!((curr_lport == -1) || (port_map->log_port_speed[curr_lport] == 0))) {
   1124             num_lanes = port_map->port_num_lanes[curr_lport];
   1125             for (i = lane; i < (lane + num_lanes);i++){
   1126                 if (i >= _TH3_PORTS_PER_PBLK) {
   1127                     LOG_ERROR(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   1128                         "soc_tomahawk3_tdm_set_max_spacing()"
   1129                         "Unsupported sched_inst_name\n")));
   1130                     return SOC_E_PARAM;
   1131                 } else {
   1132                     lane_to_port_map[i] = lane;
   1133                 }
   1134             }
   1135         }
   1136     }
   1137     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1138     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1139     reg = obm_tdm_regs[pipe_num][pm_num];
   1140     rval32 = 0;
   1141     soc_reg_field_set(unit, reg, &rval32, SLOT0_PORT_NUMf,lane_to_port_map[tdm_index[0]]);
   1142     soc_reg_field_set(unit, reg, &rval32, SLOT1_PORT_NUMf,lane_to_port_map[tdm_index[1]]);
   1143     soc_reg_field_set(unit, reg, &rval32, SLOT2_PORT_NUMf,lane_to_port_map[tdm_index[2]]);
   1144     soc_reg_field_set(unit, reg, &rval32, SLOT3_PORT_NUMf,lane_to_port_map[tdm_index[3]]);
   1145     soc_reg_field_set(unit, reg, &rval32, SLOT4_PORT_NUMf,lane_to_port_map[tdm_index[4]]);
   1146     soc_reg_field_set(unit, reg, &rval32, SLOT5_PORT_NUMf,lane_to_port_map[tdm_index[5]]);
   1147     soc_reg_field_set(unit, reg, &rval32, SLOT6_PORT_NUMf,lane_to_port_map[tdm_index[6]]);
   1148     soc_reg_field_set(unit, reg, &rval32, SLOT7_PORT_NUMf,lane_to_port_map[tdm_index[7]]);
   1149     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit,
   1150                                   reg, REG_PORT_ANY, 0, rval32));
   1151     return SOC_E_NONE;
   1152 }
   1153 
   1154 /*! @fn int soc_tomahawk3_idb_obm_buffer_config(int unit,
   1155  *          soc_port_map_type_t *port_map, int lport)
   1156  *  @param unit Chip unit number.
   1157  *  @param port_map Pointer to a soc_port_map_type_t struct variable
   1158  *  @param lport Logical port number for the port going up
   1159  *  @brief Helper function to Configure CA buffer start & buffer end address.
   1160  *  @returns SOC_E_NONE
   1161  */
   1162 int
   1163 soc_tomahawk3_idb_obm_buffer_config(
   1164     int unit, soc_port_map_type_t *port_map, int lport)
   1165 {
   1166     soc_reg_t reg;
   1167     uint32 rval32;
   1168     uint32 buffer_start_addr;
   1169     uint32 buffer_end_addr;
   1170     int phy_port;
   1171     int pm_num;
   1172     int subp;
   1173     int num_lanes;
   1174     int pipe_num;
   1175     static const soc_reg_t obm_buffer_config_regs[_TH3_PIPES_PER_DEV]
   1176        [_TH3_PBLKS_PER_PIPE] =
   1177        {{IDB_OBM0_BUFFER_CONFIG_PIPE0r, IDB_OBM1_BUFFER_CONFIG_PIPE0r,
   1178          IDB_OBM2_BUFFER_CONFIG_PIPE0r, IDB_OBM3_BUFFER_CONFIG_PIPE0r},
   1179         {IDB_OBM0_BUFFER_CONFIG_PIPE1r, IDB_OBM1_BUFFER_CONFIG_PIPE1r,
   1180          IDB_OBM2_BUFFER_CONFIG_PIPE1r, IDB_OBM3_BUFFER_CONFIG_PIPE1r},
   1181         {IDB_OBM0_BUFFER_CONFIG_PIPE2r, IDB_OBM1_BUFFER_CONFIG_PIPE2r,
   1182          IDB_OBM2_BUFFER_CONFIG_PIPE2r, IDB_OBM3_BUFFER_CONFIG_PIPE2r},
   1183         {IDB_OBM0_BUFFER_CONFIG_PIPE3r, IDB_OBM1_BUFFER_CONFIG_PIPE3r,
   1184          IDB_OBM2_BUFFER_CONFIG_PIPE3r, IDB_OBM3_BUFFER_CONFIG_PIPE3r},
   1185         {IDB_OBM0_BUFFER_CONFIG_PIPE4r, IDB_OBM1_BUFFER_CONFIG_PIPE4r,
   1186          IDB_OBM2_BUFFER_CONFIG_PIPE4r, IDB_OBM3_BUFFER_CONFIG_PIPE4r},
   1187         {IDB_OBM0_BUFFER_CONFIG_PIPE5r, IDB_OBM1_BUFFER_CONFIG_PIPE5r,
   1188          IDB_OBM2_BUFFER_CONFIG_PIPE5r, IDB_OBM3_BUFFER_CONFIG_PIPE5r},
   1189         {IDB_OBM0_BUFFER_CONFIG_PIPE6r, IDB_OBM1_BUFFER_CONFIG_PIPE6r,
   1190          IDB_OBM2_BUFFER_CONFIG_PIPE6r, IDB_OBM3_BUFFER_CONFIG_PIPE6r},
   1191         {IDB_OBM0_BUFFER_CONFIG_PIPE7r, IDB_OBM1_BUFFER_CONFIG_PIPE7r,
   1192          IDB_OBM2_BUFFER_CONFIG_PIPE7r, IDB_OBM3_BUFFER_CONFIG_PIPE7r},
   1193     };
   1194 
   1195     phy_port = port_map->port_l2p_mapping[lport];
   1196     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1197     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1198     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   1199     num_lanes = port_map->port_num_lanes[lport];
   1200     buffer_start_addr =
   1201             soc_tomahawk3_obm_buffer_config_settings[num_lanes]
   1202             [subp].buffer_start;
   1203     buffer_end_addr =
   1204             soc_tomahawk3_obm_buffer_config_settings[num_lanes]
   1205             [subp].buffer_end;
   1206     reg = obm_buffer_config_regs[pipe_num][pm_num];
   1207     rval32 = 0;
   1208     soc_reg_field_set(unit, reg, &rval32, BUFFER_STARTf,
   1209                                            buffer_start_addr);
   1210     soc_reg_field_set(unit, reg, &rval32, BUFFER_ENDf,
   1211                                            buffer_end_addr);
   1212     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit,
   1213                                   reg, REG_PORT_ANY, subp, rval32));
   1214     return SOC_E_NONE;
   1215 }
   1216 
   1217 /*! @fn int soc_tomahawk3_idb_wr_obm_thresh(int unit,
   1218             soc_port_schedule_state_t *port_schedule_state, int lport)
   1219  *  @param unit Chip unit number.
   1220  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   1221                                struct variable
   1222  *  @param lport Logical port number for the port going up.
   1223  *  @brief Helper function to config OBM thresholds when port comming up.
   1224  *  @returns SOC_E_NONE
   1225  */
   1226 int
   1227 soc_tomahawk3_idb_wr_obm_thresh(int unit,
   1228     soc_port_schedule_state_t *port_schedule_state, int lport)
   1229 {
   1230     soc_reg_t reg;
   1231     int i;
   1232     uint32 lossless0_discard, lossy_discard, lossy_low_pri,
   1233            discard_limit, lossless1_discard;
   1234     uint64 rval64, fldval64;
   1235     int phy_port;
   1236     int pm_num;
   1237     int subp;
   1238     int num_lanes;
   1239     int pipe_num;
   1240     int lossless;
   1241     static const soc_reg_t obm_thresh_pp[_TH3_PIPES_PER_DEV][_TH3_PBLKS_PER_PIPE][2] =
   1242     {
   1243         {{IDB_OBM0_THRESHOLD_PIPE0r, IDB_OBM0_THRESHOLD_1_PIPE0r},
   1244          {IDB_OBM1_THRESHOLD_PIPE0r, IDB_OBM1_THRESHOLD_1_PIPE0r},
   1245          {IDB_OBM2_THRESHOLD_PIPE0r, IDB_OBM2_THRESHOLD_1_PIPE0r},
   1246          {IDB_OBM3_THRESHOLD_PIPE0r, IDB_OBM3_THRESHOLD_1_PIPE0r}},
   1247         {{IDB_OBM0_THRESHOLD_PIPE1r, IDB_OBM0_THRESHOLD_1_PIPE1r},
   1248          {IDB_OBM1_THRESHOLD_PIPE1r, IDB_OBM1_THRESHOLD_1_PIPE1r},
   1249          {IDB_OBM2_THRESHOLD_PIPE1r, IDB_OBM2_THRESHOLD_1_PIPE1r},
   1250          {IDB_OBM3_THRESHOLD_PIPE1r, IDB_OBM3_THRESHOLD_1_PIPE1r}},
   1251         {{IDB_OBM0_THRESHOLD_PIPE2r, IDB_OBM0_THRESHOLD_1_PIPE2r},
   1252          {IDB_OBM1_THRESHOLD_PIPE2r, IDB_OBM1_THRESHOLD_1_PIPE2r},
   1253          {IDB_OBM2_THRESHOLD_PIPE2r, IDB_OBM2_THRESHOLD_1_PIPE2r},
   1254          {IDB_OBM3_THRESHOLD_PIPE2r, IDB_OBM3_THRESHOLD_1_PIPE2r}},
   1255         {{IDB_OBM0_THRESHOLD_PIPE3r, IDB_OBM0_THRESHOLD_1_PIPE3r},
   1256          {IDB_OBM1_THRESHOLD_PIPE3r, IDB_OBM1_THRESHOLD_1_PIPE3r},
   1257          {IDB_OBM2_THRESHOLD_PIPE3r, IDB_OBM2_THRESHOLD_1_PIPE3r},
   1258          {IDB_OBM3_THRESHOLD_PIPE3r, IDB_OBM3_THRESHOLD_1_PIPE3r}},
   1259         {{IDB_OBM0_THRESHOLD_PIPE4r, IDB_OBM0_THRESHOLD_1_PIPE4r},
   1260          {IDB_OBM1_THRESHOLD_PIPE4r, IDB_OBM1_THRESHOLD_1_PIPE4r},
   1261          {IDB_OBM2_THRESHOLD_PIPE4r, IDB_OBM2_THRESHOLD_1_PIPE4r},
   1262          {IDB_OBM3_THRESHOLD_PIPE4r, IDB_OBM3_THRESHOLD_1_PIPE4r}},
   1263         {{IDB_OBM0_THRESHOLD_PIPE5r, IDB_OBM0_THRESHOLD_1_PIPE5r},
   1264          {IDB_OBM1_THRESHOLD_PIPE5r, IDB_OBM1_THRESHOLD_1_PIPE5r},
   1265          {IDB_OBM2_THRESHOLD_PIPE5r, IDB_OBM2_THRESHOLD_1_PIPE5r},
   1266          {IDB_OBM3_THRESHOLD_PIPE5r, IDB_OBM3_THRESHOLD_1_PIPE5r}},
   1267         {{IDB_OBM0_THRESHOLD_PIPE6r, IDB_OBM0_THRESHOLD_1_PIPE6r},
   1268          {IDB_OBM1_THRESHOLD_PIPE6r, IDB_OBM1_THRESHOLD_1_PIPE6r},
   1269          {IDB_OBM2_THRESHOLD_PIPE6r, IDB_OBM2_THRESHOLD_1_PIPE6r},
   1270          {IDB_OBM3_THRESHOLD_PIPE6r, IDB_OBM3_THRESHOLD_1_PIPE6r}},
   1271         {{IDB_OBM0_THRESHOLD_PIPE7r, IDB_OBM0_THRESHOLD_1_PIPE7r},
   1272          {IDB_OBM1_THRESHOLD_PIPE7r, IDB_OBM1_THRESHOLD_1_PIPE7r},
   1273          {IDB_OBM2_THRESHOLD_PIPE7r, IDB_OBM2_THRESHOLD_1_PIPE7r},
   1274          {IDB_OBM3_THRESHOLD_PIPE7r, IDB_OBM3_THRESHOLD_1_PIPE7r}}
   1275     };
   1276 
   1277     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   1278     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1279     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1280     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   1281     num_lanes = port_schedule_state->out_port_map.port_num_lanes[lport];
   1282     lossless = port_schedule_state->lossless;
   1283     discard_limit =
   1284         soc_tomahawk3_obm_settings[lossless][num_lanes].discard_limit;
   1285     lossless1_discard =
   1286         soc_tomahawk3_obm_settings[lossless][num_lanes].lossless_discard;
   1287     lossless0_discard =
   1288         soc_tomahawk3_obm_settings[lossless][num_lanes].lossless_discard;
   1289     lossy_discard =
   1290         soc_tomahawk3_obm_settings[lossless][num_lanes].lossy_discard;
   1291     lossy_low_pri =
   1292         soc_tomahawk3_obm_settings[lossless][num_lanes].lossy_low_pri;
   1293     for (i = 0; i < 2; i++) {
   1294         reg = obm_thresh_pp[pipe_num][pm_num][i];
   1295         if (i == 0) {
   1296             COMPILER_64_SET(rval64, 0, 0);
   1297             COMPILER_64_SET(fldval64, 0, lossless0_discard);
   1298             soc_reg64_field_set(unit, reg, &rval64, LOSSLESS0_DISCARDf,
   1299                                 fldval64);
   1300             COMPILER_64_SET(fldval64, 0, lossy_discard);
   1301             soc_reg64_field_set(unit, reg, &rval64, LOSSY_DISCARDf,
   1302                                 fldval64);
   1303             COMPILER_64_SET(fldval64, 0, lossy_low_pri);
   1304             soc_reg64_field_set(unit, reg, &rval64, LOSSY_LOW_PRIf,
   1305                                 fldval64);
   1306             SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, REG_PORT_ANY,
   1307                                                     subp, rval64));
   1308         }
   1309         else {
   1310             COMPILER_64_SET(rval64, 0, 0);
   1311             COMPILER_64_SET(fldval64, 0, discard_limit);
   1312             soc_reg64_field_set(unit, reg, &rval64, DISCARD_LIMITf,
   1313                                 fldval64);
   1314             COMPILER_64_SET(fldval64, 0, lossless1_discard);
   1315             soc_reg64_field_set(unit, reg, &rval64, LOSSLESS1_DISCARDf,
   1316                                 fldval64);
   1317             SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, REG_PORT_ANY,
   1318                                                     subp, rval64));
   1319         }
   1320     }
   1321 
   1322     return SOC_E_NONE;
   1323 }
   1324 
   1325 /*! @fn int soc_tomahawk3_idb_wr_obm_ct_thresh(int unit,
   1326             soc_port_schedule_state_t *port_schedule_state, int lport)
   1327  *  @param unit Chip unit number.
   1328  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   1329                                struct variable
   1330  *  @param lport Logical port number for the port going up.
   1331  *  @brief Helper function to config OBM CUT THRU thresholds
   1332            when port comming up.
   1333  *  @returns SOC_E_NONE
   1334  */
   1335 int
   1336 soc_tomahawk3_idb_wr_obm_ct_thresh(int unit,
   1337     soc_port_schedule_state_t *port_schedule_state, int lport)
   1338 {
   1339     soc_reg_t reg;
   1340     uint64 rval64, fldval64;
   1341     int phy_port;
   1342     int pm_num;
   1343     int subp;
   1344     int pipe_num;
   1345     int speed_encoding;
   1346     uint32 ct_threshold;
   1347     static const soc_reg_t obm_ct_thresh[_TH3_PIPES_PER_DEV]
   1348                                         [_TH3_PBLKS_PER_PIPE] =
   1349     {
   1350         {IDB_OBM0_CT_THRESHOLD_PIPE0r, IDB_OBM1_CT_THRESHOLD_PIPE0r,
   1351          IDB_OBM2_CT_THRESHOLD_PIPE0r, IDB_OBM3_CT_THRESHOLD_PIPE0r},
   1352         {IDB_OBM0_CT_THRESHOLD_PIPE1r, IDB_OBM1_CT_THRESHOLD_PIPE1r,
   1353          IDB_OBM2_CT_THRESHOLD_PIPE1r, IDB_OBM3_CT_THRESHOLD_PIPE1r},
   1354         {IDB_OBM0_CT_THRESHOLD_PIPE2r, IDB_OBM1_CT_THRESHOLD_PIPE2r,
   1355          IDB_OBM2_CT_THRESHOLD_PIPE2r, IDB_OBM3_CT_THRESHOLD_PIPE2r},
   1356         {IDB_OBM0_CT_THRESHOLD_PIPE3r, IDB_OBM1_CT_THRESHOLD_PIPE3r,
   1357          IDB_OBM2_CT_THRESHOLD_PIPE3r, IDB_OBM3_CT_THRESHOLD_PIPE3r},
   1358         {IDB_OBM0_CT_THRESHOLD_PIPE4r, IDB_OBM1_CT_THRESHOLD_PIPE4r,
   1359          IDB_OBM2_CT_THRESHOLD_PIPE4r, IDB_OBM3_CT_THRESHOLD_PIPE4r},
   1360         {IDB_OBM0_CT_THRESHOLD_PIPE5r, IDB_OBM1_CT_THRESHOLD_PIPE5r,
   1361          IDB_OBM2_CT_THRESHOLD_PIPE5r, IDB_OBM3_CT_THRESHOLD_PIPE5r},
   1362         {IDB_OBM0_CT_THRESHOLD_PIPE6r, IDB_OBM1_CT_THRESHOLD_PIPE6r,
   1363          IDB_OBM2_CT_THRESHOLD_PIPE6r, IDB_OBM3_CT_THRESHOLD_PIPE6r},
   1364         {IDB_OBM0_CT_THRESHOLD_PIPE7r, IDB_OBM1_CT_THRESHOLD_PIPE7r,
   1365          IDB_OBM2_CT_THRESHOLD_PIPE7r, IDB_OBM3_CT_THRESHOLD_PIPE7r}
   1366     };
   1367 
   1368     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   1369     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1370     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1371     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   1372     speed_encoding = soc_tomahawk3_speed_to_e2e_settings_class_map(
   1373         port_schedule_state->out_port_map.log_port_speed[lport]);
   1374     ct_threshold =
   1375         soc_tomahawk3_e2e_settings_tbl[speed_encoding].obm_ct_threshold;
   1376     reg = obm_ct_thresh[pipe_num][pm_num];
   1377     COMPILER_64_ZERO(rval64);
   1378     COMPILER_64_SET(fldval64, 0, ct_threshold);
   1379     soc_reg64_field_set(unit, reg, &rval64, CUT_THROUGH_OKf, fldval64);
   1380     SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, REG_PORT_ANY,
   1381                                                     subp, rval64));
   1382     return SOC_E_NONE;
   1383 }
   1384 
   1385 /*! @fn int soc_tomahawk3_idb_wr_obm_force_saf_config(int unit,
   1386             soc_port_schedule_state_t *port_schedule_state, int lport)
   1387  *  @param unit Chip unit number.
   1388  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   1389                                struct variable
   1390  *  @param lport Logical port number for the port going up.
   1391  *  @brief Helper function to config OBM force SAF unsatisfied threshold
   1392            when port comming up.
   1393  *  @returns SOC_E_NONE
   1394  */
   1395 int
   1396 soc_tomahawk3_idb_wr_obm_force_saf_config(int unit,
   1397     soc_port_schedule_state_t *port_schedule_state, int lport)
   1398 {
   1399     soc_reg_t reg;
   1400     uint32 rval32;
   1401     int phy_port;
   1402     int pm_num;
   1403     int subp;
   1404     int pipe_num;
   1405     int speed_encoding;
   1406     int unsatisfied_threshold;
   1407     static const soc_reg_t obm_force_saf_config_regs[_TH3_PIPES_PER_DEV]
   1408                                                     [_TH3_PBLKS_PER_PIPE] = {
   1409         {IDB_OBM0_DBG_A_PIPE0r, IDB_OBM1_DBG_A_PIPE0r,
   1410          IDB_OBM2_DBG_A_PIPE0r, IDB_OBM3_DBG_A_PIPE0r},
   1411         {IDB_OBM0_DBG_A_PIPE1r, IDB_OBM1_DBG_A_PIPE1r,
   1412          IDB_OBM2_DBG_A_PIPE1r, IDB_OBM3_DBG_A_PIPE1r},
   1413         {IDB_OBM0_DBG_A_PIPE2r, IDB_OBM1_DBG_A_PIPE2r,
   1414          IDB_OBM2_DBG_A_PIPE2r, IDB_OBM3_DBG_A_PIPE2r},
   1415         {IDB_OBM0_DBG_A_PIPE3r, IDB_OBM1_DBG_A_PIPE3r,
   1416          IDB_OBM2_DBG_A_PIPE3r, IDB_OBM3_DBG_A_PIPE3r},
   1417         {IDB_OBM0_DBG_A_PIPE4r, IDB_OBM1_DBG_A_PIPE4r,
   1418          IDB_OBM2_DBG_A_PIPE4r, IDB_OBM3_DBG_A_PIPE4r},
   1419         {IDB_OBM0_DBG_A_PIPE5r, IDB_OBM1_DBG_A_PIPE5r,
   1420          IDB_OBM2_DBG_A_PIPE5r, IDB_OBM3_DBG_A_PIPE5r},
   1421         {IDB_OBM0_DBG_A_PIPE6r, IDB_OBM1_DBG_A_PIPE6r,
   1422          IDB_OBM2_DBG_A_PIPE6r, IDB_OBM3_DBG_A_PIPE6r},
   1423         {IDB_OBM0_DBG_A_PIPE7r, IDB_OBM1_DBG_A_PIPE7r,
   1424          IDB_OBM2_DBG_A_PIPE7r, IDB_OBM3_DBG_A_PIPE7r}};
   1425 
   1426     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   1427     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1428     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1429     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   1430     speed_encoding = soc_tomahawk3_speed_to_e2e_settings_class_map(
   1431         port_schedule_state->out_port_map.log_port_speed[lport]);
   1432     unsatisfied_threshold =
   1433         soc_tomahawk3_e2e_settings_tbl[speed_encoding].
   1434         obm_unsatisfied_threshold;
   1435     reg = obm_force_saf_config_regs[pipe_num][pm_num];
   1436     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit, reg, REG_PORT_ANY,
   1437                                                       subp, &rval32));
   1438     soc_reg_field_set(unit, reg, &rval32, FIELD_Cf,
   1439                                            unsatisfied_threshold);
   1440     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY,
   1441                                                     subp, rval32));
   1442     return SOC_E_NONE;
   1443 }
   1444 
   1445 /*! @fn int soc_tomahawk3_idb_wr_obm_lag_detection_config(int unit,
   1446             soc_port_schedule_state_t *port_schedule_state, int lport)
   1447  *  @param unit Chip unit number.
   1448  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   1449                                struct variable
   1450  *  @param lport Logical port number for the port going up.
   1451  *  @brief Helper function to config OBM lag detection threshold
   1452            when port comming up.
   1453  *  @returns SOC_E_NONE
   1454  */
   1455 int
   1456 soc_tomahawk3_idb_wr_obm_lag_detection_config(int unit,
   1457     soc_port_schedule_state_t *port_schedule_state, int lport)
   1458 {
   1459     soc_reg_t reg;
   1460     uint32 rval32;
   1461     int phy_port;
   1462     int pm_num;
   1463     int subp;
   1464     int pipe_num;
   1465     int speed_encoding;
   1466     int enter_threshold;
   1467     int exit_threshold;
   1468     static const soc_reg_t obm_lag_detection_config_regs
   1469         [_TH3_PIPES_PER_DEV]
   1470         [_TH3_PBLKS_PER_PIPE] = {
   1471         {IDB_OBM0_DBG_B_PIPE0r, IDB_OBM1_DBG_B_PIPE0r,
   1472          IDB_OBM2_DBG_B_PIPE0r, IDB_OBM3_DBG_B_PIPE0r},
   1473         {IDB_OBM0_DBG_B_PIPE1r, IDB_OBM1_DBG_B_PIPE1r,
   1474          IDB_OBM2_DBG_B_PIPE1r, IDB_OBM3_DBG_B_PIPE1r},
   1475         {IDB_OBM0_DBG_B_PIPE2r, IDB_OBM1_DBG_B_PIPE2r,
   1476          IDB_OBM2_DBG_B_PIPE2r, IDB_OBM3_DBG_B_PIPE2r},
   1477         {IDB_OBM0_DBG_B_PIPE3r, IDB_OBM1_DBG_B_PIPE3r,
   1478          IDB_OBM2_DBG_B_PIPE3r, IDB_OBM3_DBG_B_PIPE3r},
   1479         {IDB_OBM0_DBG_B_PIPE4r, IDB_OBM1_DBG_B_PIPE4r,
   1480          IDB_OBM2_DBG_B_PIPE4r, IDB_OBM3_DBG_B_PIPE4r},
   1481         {IDB_OBM0_DBG_B_PIPE5r, IDB_OBM1_DBG_B_PIPE5r,
   1482          IDB_OBM2_DBG_B_PIPE5r, IDB_OBM3_DBG_B_PIPE5r},
   1483         {IDB_OBM0_DBG_B_PIPE6r, IDB_OBM1_DBG_B_PIPE6r,
   1484          IDB_OBM2_DBG_B_PIPE6r, IDB_OBM3_DBG_B_PIPE6r},
   1485         {IDB_OBM0_DBG_B_PIPE7r, IDB_OBM1_DBG_B_PIPE7r,
   1486          IDB_OBM2_DBG_B_PIPE7r, IDB_OBM3_DBG_B_PIPE7r}};
   1487 
   1488     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   1489     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1490     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1491     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   1492     speed_encoding = soc_tomahawk3_speed_to_e2e_settings_class_map(
   1493         port_schedule_state->out_port_map.log_port_speed[lport]);
   1494     enter_threshold =
   1495         soc_tomahawk3_e2e_settings_tbl[speed_encoding].
   1496         obm_enter_lagging_threshold;
   1497     exit_threshold =
   1498         soc_tomahawk3_e2e_settings_tbl[speed_encoding].
   1499         obm_exit_lagging_threshold;
   1500     reg = obm_lag_detection_config_regs[pipe_num][pm_num];
   1501     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit, reg, REG_PORT_ANY,
   1502                                                       subp, &rval32));
   1503     soc_reg_field_set(unit, reg, &rval32, FIELD_Af, enter_threshold);
   1504     soc_reg_field_set(unit, reg, &rval32, FIELD_Bf, exit_threshold);
   1505     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY,
   1506                                                     subp, rval32));
   1507     return SOC_E_NONE;
   1508 }
   1509 
   1510 /*! @fn int soc_tomahawk3_idb_wr_ca_force_saf_config(int unit,
   1511             soc_port_schedule_state_t *port_schedule_state, int lport)
   1512  *  @param unit Chip unit number.
   1513  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   1514                                struct variable
   1515  *  @param lport Logical port number for the port going up.
   1516  *  @brief Helper function to config CA force SAF unsatisfied threshold
   1517            when port comming up.
   1518  *  @returns SOC_E_NONE
   1519  */
   1520 int
   1521 soc_tomahawk3_idb_wr_ca_force_saf_config(int unit,
   1522     soc_port_schedule_state_t *port_schedule_state, int lport)
   1523 {
   1524     soc_reg_t reg;
   1525     uint32 rval32;
   1526     int phy_port;
   1527     int pm_num;
   1528     int subp;
   1529     int pipe_num;
   1530     int speed_encoding;
   1531     int unsatisfied_threshold;
   1532     static const soc_reg_t ca_force_saf_config_regs[_TH3_PIPES_PER_DEV]
   1533                                                     [_TH3_PBLKS_PER_PIPE] = {
   1534         {IDB_CA0_DBG_A_PIPE0r, IDB_CA1_DBG_A_PIPE0r,
   1535          IDB_CA2_DBG_A_PIPE0r, IDB_CA3_DBG_A_PIPE0r},
   1536         {IDB_CA0_DBG_A_PIPE1r, IDB_CA1_DBG_A_PIPE1r,
   1537          IDB_CA2_DBG_A_PIPE1r, IDB_CA3_DBG_A_PIPE1r},
   1538         {IDB_CA0_DBG_A_PIPE2r, IDB_CA1_DBG_A_PIPE2r,
   1539          IDB_CA2_DBG_A_PIPE2r, IDB_CA3_DBG_A_PIPE2r},
   1540         {IDB_CA0_DBG_A_PIPE3r, IDB_CA1_DBG_A_PIPE3r,
   1541          IDB_CA2_DBG_A_PIPE3r, IDB_CA3_DBG_A_PIPE3r},
   1542         {IDB_CA0_DBG_A_PIPE4r, IDB_CA1_DBG_A_PIPE4r,
   1543          IDB_CA2_DBG_A_PIPE4r, IDB_CA3_DBG_A_PIPE4r},
   1544         {IDB_CA0_DBG_A_PIPE5r, IDB_CA1_DBG_A_PIPE5r,
   1545          IDB_CA2_DBG_A_PIPE5r, IDB_CA3_DBG_A_PIPE5r},
   1546         {IDB_CA0_DBG_A_PIPE6r, IDB_CA1_DBG_A_PIPE6r,
   1547          IDB_CA2_DBG_A_PIPE6r, IDB_CA3_DBG_A_PIPE6r},
   1548         {IDB_CA0_DBG_A_PIPE7r, IDB_CA1_DBG_A_PIPE7r,
   1549          IDB_CA2_DBG_A_PIPE7r, IDB_CA3_DBG_A_PIPE7r}};
   1550 
   1551     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   1552     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1553     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1554     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   1555     speed_encoding = soc_tomahawk3_speed_to_e2e_settings_class_map(
   1556         port_schedule_state->out_port_map.log_port_speed[lport]);
   1557     unsatisfied_threshold =
   1558         soc_tomahawk3_e2e_settings_tbl[speed_encoding].
   1559         ca_unsatisfied_threshold;
   1560     reg = ca_force_saf_config_regs[pipe_num][pm_num];
   1561     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit, reg, REG_PORT_ANY,
   1562                                                       subp, &rval32));
   1563     soc_reg_field_set(unit, reg, &rval32, FIELD_Cf,
   1564                                            unsatisfied_threshold);
   1565     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY,
   1566                                                     subp, rval32));
   1567     return SOC_E_NONE;
   1568 }
   1569 
   1570 /*! @fn int soc_tomahawk3_idb_wr_ca_lag_detection_config(int unit,
   1571             soc_port_schedule_state_t *port_schedule_state, int lport)
   1572  *  @param unit Chip unit number.
   1573  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   1574                                struct variable
   1575  *  @param lport Logical port number for the port going up.
   1576  *  @brief Helper function to config CA lag detection threshold
   1577            when port comming up.
   1578  *  @returns SOC_E_NONE
   1579  */
   1580 int
   1581 soc_tomahawk3_idb_wr_ca_lag_detection_config(int unit,
   1582     soc_port_schedule_state_t *port_schedule_state, int lport)
   1583 {
   1584     soc_reg_t reg;
   1585     uint32 rval32;
   1586     int phy_port;
   1587     int pm_num;
   1588     int subp;
   1589     int pipe_num;
   1590     int speed_encoding;
   1591     int enter_threshold;
   1592     int exit_threshold;
   1593     static const soc_reg_t ca_lag_detection_config_regs
   1594         [_TH3_PIPES_PER_DEV]
   1595         [_TH3_PBLKS_PER_PIPE] = {
   1596         {IDB_CA0_DBG_B_PIPE0r, IDB_CA1_DBG_B_PIPE0r,
   1597          IDB_CA2_DBG_B_PIPE0r, IDB_CA3_DBG_B_PIPE0r},
   1598         {IDB_CA0_DBG_B_PIPE1r, IDB_CA1_DBG_B_PIPE1r,
   1599          IDB_CA2_DBG_B_PIPE1r, IDB_CA3_DBG_B_PIPE1r},
   1600         {IDB_CA0_DBG_B_PIPE2r, IDB_CA1_DBG_B_PIPE2r,
   1601          IDB_CA2_DBG_B_PIPE2r, IDB_CA3_DBG_B_PIPE2r},
   1602         {IDB_CA0_DBG_B_PIPE3r, IDB_CA1_DBG_B_PIPE3r,
   1603          IDB_CA2_DBG_B_PIPE3r, IDB_CA3_DBG_B_PIPE3r},
   1604         {IDB_CA0_DBG_B_PIPE4r, IDB_CA1_DBG_B_PIPE4r,
   1605          IDB_CA2_DBG_B_PIPE4r, IDB_CA3_DBG_B_PIPE4r},
   1606         {IDB_CA0_DBG_B_PIPE5r, IDB_CA1_DBG_B_PIPE5r,
   1607          IDB_CA2_DBG_B_PIPE5r, IDB_CA3_DBG_B_PIPE5r},
   1608         {IDB_CA0_DBG_B_PIPE6r, IDB_CA1_DBG_B_PIPE6r,
   1609          IDB_CA2_DBG_B_PIPE6r, IDB_CA3_DBG_B_PIPE6r},
   1610         {IDB_CA0_DBG_B_PIPE7r, IDB_CA1_DBG_B_PIPE7r,
   1611          IDB_CA2_DBG_B_PIPE7r, IDB_CA3_DBG_B_PIPE7r}};
   1612 
   1613     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   1614     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1615     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1616     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   1617     speed_encoding = soc_tomahawk3_speed_to_e2e_settings_class_map(
   1618         port_schedule_state->out_port_map.log_port_speed[lport]);
   1619     enter_threshold =
   1620         soc_tomahawk3_e2e_settings_tbl[speed_encoding].
   1621         ca_enter_lagging_threshold;
   1622     exit_threshold =
   1623         soc_tomahawk3_e2e_settings_tbl[speed_encoding].
   1624         ca_exit_lagging_threshold;
   1625     reg = ca_lag_detection_config_regs[pipe_num][pm_num];
   1626     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit, reg, REG_PORT_ANY,
   1627                                                       subp, &rval32));
   1628     soc_reg_field_set(unit, reg, &rval32, FIELD_Af, enter_threshold);
   1629     soc_reg_field_set(unit, reg, &rval32, FIELD_Bf, exit_threshold);
   1630     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY,
   1631                                                     subp, rval32));
   1632     return SOC_E_NONE;
   1633 }
   1634 
   1635 /*! @fn int soc_tomahawk3_idb_wr_ca_ct_thresh(int unit,
   1636             soc_port_schedule_state_t *port_schedule_state, int lport)
   1637  *  @param unit Chip unit number.
   1638  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   1639                                struct variable
   1640  *  @param lport Logical port number for the port going up.
   1641  *  @brief Helper function to config CA CUT THRU thresholds
   1642            when port comming up.
   1643  *  @returns SOC_E_NONE
   1644  */
   1645 int
   1646 soc_tomahawk3_idb_wr_ca_ct_thresh(int unit,
   1647     soc_port_schedule_state_t *port_schedule_state, int lport)
   1648 {
   1649     soc_reg_t reg;
   1650     uint64 rval64, fldval64;
   1651     int phy_port;
   1652     int pm_num;
   1653     int subp;
   1654     int pipe_num;
   1655     uint32 ct_threshold;
   1656     int speed_encoding;
   1657     static const soc_reg_t ca_ct_thresh[_TH3_PIPES_PER_DEV]
   1658                                        [_TH3_PBLKS_PER_PIPE] =
   1659     {
   1660        {IDB_CA0_CT_CONTROL_PIPE0r,IDB_CA1_CT_CONTROL_PIPE0r,
   1661         IDB_CA2_CT_CONTROL_PIPE0r,IDB_CA3_CT_CONTROL_PIPE0r},
   1662        {IDB_CA0_CT_CONTROL_PIPE1r,IDB_CA1_CT_CONTROL_PIPE1r,
   1663         IDB_CA2_CT_CONTROL_PIPE1r,IDB_CA3_CT_CONTROL_PIPE1r},
   1664        {IDB_CA0_CT_CONTROL_PIPE2r,IDB_CA1_CT_CONTROL_PIPE2r,
   1665         IDB_CA2_CT_CONTROL_PIPE2r,IDB_CA3_CT_CONTROL_PIPE2r},
   1666        {IDB_CA0_CT_CONTROL_PIPE3r,IDB_CA1_CT_CONTROL_PIPE3r,
   1667         IDB_CA2_CT_CONTROL_PIPE3r,IDB_CA3_CT_CONTROL_PIPE3r},
   1668        {IDB_CA0_CT_CONTROL_PIPE4r,IDB_CA1_CT_CONTROL_PIPE4r,
   1669         IDB_CA2_CT_CONTROL_PIPE4r,IDB_CA3_CT_CONTROL_PIPE4r},
   1670        {IDB_CA0_CT_CONTROL_PIPE5r,IDB_CA1_CT_CONTROL_PIPE5r,
   1671         IDB_CA2_CT_CONTROL_PIPE5r,IDB_CA3_CT_CONTROL_PIPE5r},
   1672        {IDB_CA0_CT_CONTROL_PIPE6r,IDB_CA1_CT_CONTROL_PIPE6r,
   1673         IDB_CA2_CT_CONTROL_PIPE6r,IDB_CA3_CT_CONTROL_PIPE6r},
   1674        {IDB_CA0_CT_CONTROL_PIPE7r,IDB_CA1_CT_CONTROL_PIPE7r,
   1675         IDB_CA2_CT_CONTROL_PIPE7r,IDB_CA3_CT_CONTROL_PIPE7r}
   1676     };
   1677     static const soc_field_t ca_ct_threshold_fields[] = {
   1678         PORT0_CT_THRESHOLDf, PORT1_CT_THRESHOLDf,
   1679         PORT2_CT_THRESHOLDf, PORT3_CT_THRESHOLDf,
   1680         PORT4_CT_THRESHOLDf, PORT5_CT_THRESHOLDf,
   1681         PORT6_CT_THRESHOLDf, PORT7_CT_THRESHOLDf
   1682     };
   1683 
   1684     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   1685     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1686     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1687     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   1688     speed_encoding = soc_tomahawk3_speed_to_e2e_settings_class_map(
   1689         port_schedule_state->out_port_map.log_port_speed[lport]);
   1690     ct_threshold =
   1691         soc_tomahawk3_e2e_settings_tbl[speed_encoding].ca_ct_threshold;
   1692     reg = ca_ct_thresh[pipe_num][pm_num];
   1693     SOC_IF_ERROR_RETURN(soc_reg_rawport_get(unit, reg, REG_PORT_ANY,
   1694                                             0, &rval64));
   1695     COMPILER_64_SET(fldval64, 0, ct_threshold);
   1696     soc_reg64_field_set(unit, reg, &rval64, ca_ct_threshold_fields[subp],
   1697                                                           fldval64);
   1698     SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, REG_PORT_ANY,
   1699                                                     0, rval64));
   1700 
   1701     return SOC_E_NONE;
   1702 }
   1703 
   1704 /*! @fn int soc_tomahawk3_idb_wr_obm_port_config(int unit,
   1705             soc_port_schedule_state_t *port_schedule_state, int lport)
   1706  *  @param unit Chip unit number.
   1707  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   1708                                struct variable
   1709  *  @param lport Logical port number for the port going up.
   1710  *  @brief Helper function to config OBM Per port config register
   1711            when port comming up.
   1712  *  @returns SOC_E_NONE
   1713  */
   1714 int
   1715 soc_tomahawk3_idb_wr_obm_port_config(int unit,
   1716     soc_port_schedule_state_t *port_schedule_state, int lport)
   1717 {
   1718     soc_reg_t reg;
   1719     uint32 rval32;
   1720     int phy_port;
   1721     int pm_num;
   1722     int subp;
   1723     int pipe_num;
   1724     static const soc_reg_t obm_port_config[_TH3_PIPES_PER_DEV]
   1725                                           [_TH3_PBLKS_PER_PIPE] = {
   1726         {IDB_OBM0_PORT_CONFIG_PIPE0r, IDB_OBM1_PORT_CONFIG_PIPE0r,
   1727          IDB_OBM2_PORT_CONFIG_PIPE0r, IDB_OBM3_PORT_CONFIG_PIPE0r},
   1728         {IDB_OBM0_PORT_CONFIG_PIPE1r, IDB_OBM1_PORT_CONFIG_PIPE1r,
   1729          IDB_OBM2_PORT_CONFIG_PIPE1r, IDB_OBM3_PORT_CONFIG_PIPE1r},
   1730         {IDB_OBM0_PORT_CONFIG_PIPE2r, IDB_OBM1_PORT_CONFIG_PIPE2r,
   1731          IDB_OBM2_PORT_CONFIG_PIPE2r, IDB_OBM3_PORT_CONFIG_PIPE2r},
   1732         {IDB_OBM0_PORT_CONFIG_PIPE3r, IDB_OBM1_PORT_CONFIG_PIPE3r,
   1733          IDB_OBM2_PORT_CONFIG_PIPE3r, IDB_OBM3_PORT_CONFIG_PIPE3r},
   1734         {IDB_OBM0_PORT_CONFIG_PIPE4r, IDB_OBM1_PORT_CONFIG_PIPE4r,
   1735          IDB_OBM2_PORT_CONFIG_PIPE4r, IDB_OBM3_PORT_CONFIG_PIPE4r},
   1736         {IDB_OBM0_PORT_CONFIG_PIPE5r, IDB_OBM1_PORT_CONFIG_PIPE5r,
   1737          IDB_OBM2_PORT_CONFIG_PIPE5r, IDB_OBM3_PORT_CONFIG_PIPE5r},
   1738         {IDB_OBM0_PORT_CONFIG_PIPE6r, IDB_OBM1_PORT_CONFIG_PIPE6r,
   1739          IDB_OBM2_PORT_CONFIG_PIPE6r, IDB_OBM3_PORT_CONFIG_PIPE6r},
   1740         {IDB_OBM0_PORT_CONFIG_PIPE7r, IDB_OBM1_PORT_CONFIG_PIPE7r,
   1741          IDB_OBM2_PORT_CONFIG_PIPE7r, IDB_OBM3_PORT_CONFIG_PIPE7r}};
   1742 
   1743     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   1744     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1745     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1746     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   1747     reg = obm_port_config[pipe_num][pm_num];
   1748     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit, reg, REG_PORT_ANY,
   1749                                                     subp, &rval32));
   1750     soc_reg_field_set(unit, reg, &rval32, OUTER_TPID_ENABLEf, 1);
   1751     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY,
   1752                                                     subp, rval32));
   1753     return SOC_E_NONE;
   1754 }
   1755 
   1756 
   1757 /*! @fn int soc_tomahawk3_idb_wr_obm_monitor_stats_config(int unit,
   1758             soc_port_schedule_state_t *port_schedule_state, int lport)
   1759  *  @param unit Chip unit number.
   1760  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   1761                                struct variable
   1762  *  @param lport Logical port number for the port going up.
   1763  *  @brief Helper function to config OBM Per port Instrumentation Monitor
   1764            when port comming up.
   1765  *  @returns SOC_E_NONE
   1766  */
   1767 int
   1768 soc_tomahawk3_idb_wr_obm_monitor_stats_config(int unit,
   1769     soc_port_schedule_state_t *port_schedule_state, int lport)
   1770 {
   1771     soc_reg_t reg;
   1772     uint32 rval32;
   1773     int phy_port;
   1774     int pm_num;
   1775     int subp;
   1776     int pipe_num;
   1777     int lossless;
   1778     int drop_count_select;
   1779     static const soc_reg_t obm_monitor_stats_config[_TH3_PIPES_PER_DEV]
   1780                                                    [_TH3_PBLKS_PER_PIPE] = {
   1781         {IDB_OBM0_MONITOR_STATS_CONFIG_PIPE0r,
   1782          IDB_OBM1_MONITOR_STATS_CONFIG_PIPE0r,
   1783          IDB_OBM2_MONITOR_STATS_CONFIG_PIPE0r,
   1784          IDB_OBM3_MONITOR_STATS_CONFIG_PIPE0r},
   1785         {IDB_OBM0_MONITOR_STATS_CONFIG_PIPE1r,
   1786          IDB_OBM1_MONITOR_STATS_CONFIG_PIPE1r,
   1787          IDB_OBM2_MONITOR_STATS_CONFIG_PIPE1r,
   1788          IDB_OBM3_MONITOR_STATS_CONFIG_PIPE1r},
   1789         {IDB_OBM0_MONITOR_STATS_CONFIG_PIPE2r,
   1790          IDB_OBM1_MONITOR_STATS_CONFIG_PIPE2r,
   1791          IDB_OBM2_MONITOR_STATS_CONFIG_PIPE2r,
   1792          IDB_OBM3_MONITOR_STATS_CONFIG_PIPE2r},
   1793         {IDB_OBM0_MONITOR_STATS_CONFIG_PIPE3r,
   1794          IDB_OBM1_MONITOR_STATS_CONFIG_PIPE3r,
   1795          IDB_OBM2_MONITOR_STATS_CONFIG_PIPE3r,
   1796          IDB_OBM3_MONITOR_STATS_CONFIG_PIPE3r},
   1797         {IDB_OBM0_MONITOR_STATS_CONFIG_PIPE4r,
   1798          IDB_OBM1_MONITOR_STATS_CONFIG_PIPE4r,
   1799          IDB_OBM2_MONITOR_STATS_CONFIG_PIPE4r,
   1800          IDB_OBM3_MONITOR_STATS_CONFIG_PIPE4r},
   1801         {IDB_OBM0_MONITOR_STATS_CONFIG_PIPE5r,
   1802          IDB_OBM1_MONITOR_STATS_CONFIG_PIPE5r,
   1803          IDB_OBM2_MONITOR_STATS_CONFIG_PIPE5r,
   1804          IDB_OBM3_MONITOR_STATS_CONFIG_PIPE5r},
   1805         {IDB_OBM0_MONITOR_STATS_CONFIG_PIPE6r,
   1806          IDB_OBM1_MONITOR_STATS_CONFIG_PIPE6r,
   1807          IDB_OBM2_MONITOR_STATS_CONFIG_PIPE6r,
   1808          IDB_OBM3_MONITOR_STATS_CONFIG_PIPE6r},
   1809         {IDB_OBM0_MONITOR_STATS_CONFIG_PIPE7r,
   1810          IDB_OBM1_MONITOR_STATS_CONFIG_PIPE7r,
   1811          IDB_OBM2_MONITOR_STATS_CONFIG_PIPE7r,
   1812          IDB_OBM3_MONITOR_STATS_CONFIG_PIPE7r}};
   1813 
   1814     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   1815     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1816     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1817     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   1818     lossless = port_schedule_state->lossless;
   1819     if (lossless == _TH3_OBM_PARAMS_LOSSLESS_INDEX){
   1820         drop_count_select = _TH3_OBM_PARAMS_DROP_COUNT_SELECT_LOSSLESS0;
   1821     } else {
   1822         drop_count_select = _TH3_OBM_PARAMS_DROP_COUNT_SELECT_LOSSY_LO;
   1823     }
   1824     reg = obm_monitor_stats_config[pipe_num][pm_num];
   1825     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit, reg, REG_PORT_ANY,
   1826                                                     subp, &rval32));
   1827     soc_reg_field_set(unit, reg, &rval32, DROP_COUNT_SELECTf, drop_count_select);
   1828     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY,
   1829                                                     subp, rval32));
   1830     return SOC_E_NONE;
   1831 }
   1832 
   1833 /*! @fn int soc_tomahawk3_idb_ca_ct_enable(int unit,
   1834             soc_port_schedule_state_t *port_schedule_state, int lport,
   1835             int ct_enable)
   1836  *  @param unit Chip unit number.
   1837  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   1838                                struct variable
   1839  *  @param lport Logical port number for the port going up.
   1840  *  @brief Helper function to config CA CUT THRU disable
   1841            when port comming up.
   1842  *  @returns SOC_E_NONE
   1843  */
   1844 int
   1845 soc_tomahawk3_idb_ca_ct_enable(int unit,
   1846     soc_port_schedule_state_t *port_schedule_state, int lport, int ct_enable)
   1847 {
   1848     soc_reg_t reg;
   1849     uint64 rval64, fldval64;
   1850     int phy_port;
   1851     int pm_num;
   1852     int subp;
   1853     int pipe_num;
   1854     int ct_disable;
   1855     static const soc_field_t ca_ct_disable_fields[] = {
   1856         PORT0_CT_DISABLEf, PORT1_CT_DISABLEf,
   1857         PORT2_CT_DISABLEf, PORT3_CT_DISABLEf,
   1858         PORT4_CT_DISABLEf, PORT5_CT_DISABLEf,
   1859         PORT6_CT_DISABLEf, PORT7_CT_DISABLEf
   1860     };
   1861 
   1862     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   1863     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1864     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1865     reg = th3_idb_ca_control_2[pipe_num];
   1866     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   1867     SOC_IF_ERROR_RETURN(soc_reg_rawport_get(unit, reg, REG_PORT_ANY,
   1868                                             pm_num, &rval64));
   1869     ct_disable = ct_enable ? 0: 1;
   1870     COMPILER_64_SET(fldval64, 0, ct_disable);
   1871     soc_reg64_field_set(unit, reg, &rval64, ca_ct_disable_fields[subp],
   1872                                                           fldval64);
   1873     SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, REG_PORT_ANY,
   1874                                                     pm_num, rval64));
   1875     return SOC_E_NONE;
   1876 }
   1877 
   1878 /*! @fn int soc_tomahawk3_idb_ca_peek_depth_cfg(int unit,
   1879             soc_port_map_type_t *port_map, int lport,
   1880             int ct_enable)
   1881  *  @param unit Chip unit number.
   1882  *  @param port_map Pointer to a soc_port_map_type_t
   1883                                struct variable
   1884  *  @param lport Logical port number for the port going up.
   1885  *  @brief Helper function to config CA peek_depth
   1886            when port comming up.
   1887  *  @returns SOC_E_NONE
   1888  */
   1889 int
   1890 soc_tomahawk3_idb_ca_peek_depth_cfg(int unit,
   1891     soc_port_map_type_t *port_map, int lport)
   1892 {
   1893     soc_reg_t reg;
   1894     uint64 rval64, fldval64;
   1895     int phy_port;
   1896     int pm_num;
   1897     int subp;
   1898     int pipe_num;
   1899     int peek_depth;
   1900     int speed_encoding;
   1901     static const soc_field_t ca_peek_depth_fields[] = {
   1902         PORT0_CA_PEEK_DEPTHf, PORT1_CA_PEEK_DEPTHf,
   1903         PORT2_CA_PEEK_DEPTHf, PORT3_CA_PEEK_DEPTHf,
   1904         PORT4_CA_PEEK_DEPTHf, PORT5_CA_PEEK_DEPTHf,
   1905         PORT6_CA_PEEK_DEPTHf, PORT7_CA_PEEK_DEPTHf
   1906     };
   1907 
   1908     phy_port = port_map->port_l2p_mapping[lport];
   1909     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1910     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   1911     reg = th3_idb_ca_control_2[pipe_num];
   1912     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   1913     SOC_IF_ERROR_RETURN(soc_reg_rawport_get(unit, reg, REG_PORT_ANY,
   1914                                             pm_num, &rval64));
   1915     speed_encoding = soc_tomahawk3_speed_to_e2e_settings_class_map(
   1916                      port_map->log_port_speed[lport]);
   1917     peek_depth = soc_tomahawk3_peek_depth_settings_tbl[speed_encoding].
   1918                      peek_depth;
   1919     COMPILER_64_SET(fldval64, 0, peek_depth);
   1920     soc_reg64_field_set(unit, reg, &rval64, ca_peek_depth_fields[subp],
   1921                                                           fldval64);
   1922     SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, REG_PORT_ANY,
   1923                                                     pm_num, rval64));
   1924     return SOC_E_NONE;
   1925 }
   1926 
   1927 /*! @fn int soc_tomahawk3_idb_lpbk_ca_peek_depth_cfg(int unit, int pipe_num)
   1928  *  @param unit Chip unit number.
   1929  *  @param pipe_num Tomahawk3 pipe number.
   1930  *  @brief Helper function to configure loopback port CA peek depth while 
   1931            the ports are comming up.
   1932  *  @returns SOC_E_NONE
   1933  */
   1934 int
   1935 soc_tomahawk3_idb_lpbk_ca_peek_depth_cfg(int unit, int pipe_num)
   1936 {
   1937     soc_reg_t reg;
   1938     uint32 rval;
   1939 
   1940     reg = th3_idb_ca_lpbk_ctrl[pipe_num];
   1941     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit, reg, REG_PORT_ANY, 0, &rval));
   1942     soc_reg_field_set(unit, reg, &rval, PEEK_DEPTHf, _TH3_IDB_CA_PEEK_DEPTH_CPU_LPBK_PORT);
   1943     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY, 0, rval));
   1944     return SOC_E_NONE;
   1945 }
   1946 
   1947 /*! @fn int soc_tomahawk3_idb_cpu_ca_peek_depth_cfg(int unit, int pipe_num)
   1948  *  @param unit Chip unit number.
   1949  *  @param pipe_num Tomahawk3 pipe number.
   1950  *  @brief Helper function to configure cpu port CA peek depth while 
   1951            the ports are comming up.
   1952  *  @returns SOC_E_NONE
   1953  */
   1954 int
   1955 soc_tomahawk3_idb_cpu_ca_peek_depth_cfg(int unit, int pipe_num)
   1956 {
   1957     soc_reg_t reg;
   1958     uint32 rval;
   1959 
   1960     reg = th3_idb_ca_cpu_ctrl[pipe_num];
   1961     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit, reg, REG_PORT_ANY, 0, &rval));
   1962     soc_reg_field_set(unit, reg, &rval, PEEK_DEPTHf, _TH3_IDB_CA_PEEK_DEPTH_CPU_LPBK_PORT);
   1963     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY, 0, rval));
   1964     return SOC_E_NONE;
   1965 }
   1966 
   1967 /*! @fn int soc_tomahawk3_idb_ca_bmop_set(int unit,
   1968             soc_port_schedule_state_t *port_schedule_state, int lport)
   1969  *  @param unit Chip unit number.
   1970  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   1971                                struct variable
   1972  *  @param lport Logical port number for the port going up.
   1973  *  @brief Helper function to config CA Bubble MOP settings
   1974            when port comming up.
   1975  *  @returns SOC_E_NONE
   1976  */
   1977 int
   1978 soc_tomahawk3_idb_ca_bmop_set(int unit,
   1979     soc_port_schedule_state_t *port_schedule_state, int lport)
   1980 {
   1981     soc_reg_t reg;
   1982     uint64 rval64, fldval64;
   1983     int phy_port;
   1984     int pm_num;
   1985     int subp;
   1986     int pipe_num;
   1987     uint32 bmop_disable;
   1988     int latency_mode;
   1989     int speed_encoding;
   1990     static const soc_field_t ca_bmop_disable_fields[] = {
   1991         PORT0_BUBBLE_MOP_DISABLEf, PORT1_BUBBLE_MOP_DISABLEf,
   1992         PORT2_BUBBLE_MOP_DISABLEf, PORT3_BUBBLE_MOP_DISABLEf,
   1993         PORT4_BUBBLE_MOP_DISABLEf, PORT5_BUBBLE_MOP_DISABLEf,
   1994         PORT6_BUBBLE_MOP_DISABLEf, PORT7_BUBBLE_MOP_DISABLEf
   1995     };
   1996 
   1997     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   1998     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   1999     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   2000     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   2001     latency_mode = port_schedule_state->cutthru_prop.switch_bypass_mode;
   2002     speed_encoding =
   2003         (port_schedule_state->cutthru_prop.asf_modes[lport]
   2004         == _SOC_ASF_MODE_SAF) ? 0 :
   2005         soc_tomahawk3_speed_to_e2e_settings_class_map(
   2006         port_schedule_state->out_port_map.log_port_speed[lport]);
   2007     bmop_disable = soc_tomahawk3_e2e_settings_tbl[speed_encoding].
   2008         bmop_disable[latency_mode];
   2009     reg = th3_idb_ca_control_2[pipe_num];
   2010     SOC_IF_ERROR_RETURN(soc_reg_rawport_get(unit, reg, REG_PORT_ANY,
   2011                                             pm_num, &rval64));
   2012     COMPILER_64_SET(fldval64, 0, bmop_disable);
   2013     soc_reg64_field_set(unit, reg, &rval64, ca_bmop_disable_fields[subp],
   2014                                                           fldval64);
   2015     SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, REG_PORT_ANY,
   2016                                                     pm_num, rval64));
   2017     return SOC_E_NONE;
   2018 }
   2019 
   2020 /*! @fn int soc_tomahawk3_idb_wr_obm_flow_ctrl_cfg(int unit,
   2021             soc_port_schedule_state_t *port_schedule_state, int lport)
   2022  *  @param unit Chip unit number.
   2023  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   2024                                struct variable
   2025  *  @param lport Logical port number for the port going up.
   2026  *  @brief Helper function to config OBM flow control config regsiter
   2027            during port going up.
   2028  *  @returns SOC_E_NONE
   2029  */
   2030 int
   2031 soc_tomahawk3_idb_wr_obm_flow_ctrl_cfg(int unit,
   2032     soc_port_schedule_state_t *port_schedule_state, int lport)
   2033 {
   2034     soc_reg_t reg;
   2035     uint64 rval64, fldval64;
   2036     int phy_port;
   2037     int pm_num;
   2038     int subp;
   2039     int pipe_num;
   2040     int lossless;
   2041     const soc_reg_t obm_flow_ctrl_cfg[_TH3_PIPES_PER_DEV][_TH3_PBLKS_PER_PIPE]
   2042         = {
   2043         {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE0r,
   2044          IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE0r,
   2045          IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE0r,
   2046          IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE0r},
   2047         {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE1r,
   2048          IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE1r,
   2049          IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE1r,
   2050          IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE1r},
   2051         {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE2r,
   2052          IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE2r,
   2053          IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE2r,
   2054          IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE2r},
   2055         {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE3r,
   2056          IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE3r,
   2057          IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE3r,
   2058          IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE3r},
   2059         {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE4r,
   2060          IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE4r,
   2061          IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE4r,
   2062          IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE4r},
   2063         {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE5r,
   2064          IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE5r,
   2065          IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE5r,
   2066          IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE5r},
   2067         {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE6r,
   2068          IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE6r,
   2069          IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE6r,
   2070          IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE6r},
   2071         {IDB_OBM0_FLOW_CONTROL_CONFIG_PIPE7r,
   2072          IDB_OBM1_FLOW_CONTROL_CONFIG_PIPE7r,
   2073          IDB_OBM2_FLOW_CONTROL_CONFIG_PIPE7r,
   2074          IDB_OBM3_FLOW_CONTROL_CONFIG_PIPE7r}
   2075         };
   2076 
   2077     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   2078     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   2079     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   2080     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   2081     lossless = port_schedule_state->lossless;
   2082     reg = obm_flow_ctrl_cfg[pipe_num][pm_num];
   2083     SOC_IF_ERROR_RETURN(soc_reg_rawport_get(unit, reg, REG_PORT_ANY, subp,
   2084                                             &rval64));
   2085     if (lossless == _TH3_OBM_PARAMS_LOSSLESS_INDEX) {
   2086         COMPILER_64_ZERO(fldval64);
   2087         soc_reg64_field_set(unit, reg, &rval64, FC_TYPEf, fldval64);
   2088         COMPILER_64_SET(fldval64, 0, 1);
   2089         soc_reg64_field_set(unit, reg, &rval64, PORT_FC_ENf, fldval64);
   2090         soc_reg64_field_set(unit, reg, &rval64, LOSSLESS0_FC_ENf, fldval64);
   2091         COMPILER_64_ZERO(fldval64);
   2092         soc_reg64_field_set(unit, reg, &rval64, LOSSLESS1_FC_ENf, fldval64);
   2093         COMPILER_64_SET(fldval64, 0, 0xffff);
   2094         soc_reg64_field_set(unit, reg, &rval64, LOSSLESS0_PRIORITY_PROFILEf, fldval64);
   2095         COMPILER_64_ZERO(fldval64);
   2096         soc_reg64_field_set(unit, reg, &rval64, LOSSLESS1_PRIORITY_PROFILEf, fldval64);
   2097     } else if (lossless == _TH3_OBM_PARAMS_LOSSY_INDEX) {
   2098         COMPILER_64_ZERO(fldval64);
   2099         soc_reg64_field_set(unit, reg, &rval64, FC_TYPEf, fldval64);
   2100         soc_reg64_field_set(unit, reg, &rval64, PORT_FC_ENf, fldval64);
   2101         soc_reg64_field_set(unit, reg, &rval64, LOSSLESS0_FC_ENf, fldval64);
   2102         soc_reg64_field_set(unit, reg, &rval64, LOSSLESS1_FC_ENf, fldval64);
   2103         soc_reg64_field_set(unit, reg, &rval64, LOSSLESS0_PRIORITY_PROFILEf, fldval64);
   2104         soc_reg64_field_set(unit, reg, &rval64, LOSSLESS1_PRIORITY_PROFILEf, fldval64);
   2105     } else { /* _TH3_OBM_PARAMS_LOSSY_PLUS_LOSSLESS_INDEX */
   2106         COMPILER_64_SET(fldval64, 0, 1);
   2107         soc_reg64_field_set(unit, reg, &rval64, FC_TYPEf, fldval64);
   2108         soc_reg64_field_set(unit, reg, &rval64, PORT_FC_ENf, fldval64);
   2109         soc_reg64_field_set(unit, reg, &rval64, LOSSLESS0_FC_ENf, fldval64);
   2110         COMPILER_64_ZERO(fldval64);
   2111         soc_reg64_field_set(unit, reg, &rval64, LOSSLESS1_FC_ENf, fldval64);
   2112         COMPILER_64_SET(fldval64, 0, 1);
   2113         soc_reg64_field_set(unit, reg, &rval64, LOSSLESS0_PRIORITY_PROFILEf, fldval64);
   2114         COMPILER_64_ZERO(fldval64);
   2115         soc_reg64_field_set(unit, reg, &rval64, LOSSLESS1_PRIORITY_PROFILEf, fldval64);
   2116     }
   2117     SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, REG_PORT_ANY, subp,
   2118                                             rval64));
   2119     return SOC_E_NONE;
   2120 }
   2121 
   2122 /*! @fn int soc_tomahawk3_idb_wr_obm_fc_threshold(int unit,
   2123             soc_port_schedule_state_t *port_schedule_state, int lport)
   2124  *  @param unit Chip unit number.
   2125  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   2126                                struct variable
   2127  *  @param lport Logical port number for the port going up.
   2128  *  @brief Helper function to config OBM flow-control thresholds.
   2129  *  @returns SOC_E_NONE
   2130  */
   2131 int
   2132 soc_tomahawk3_idb_wr_obm_fc_threshold(int unit,
   2133     soc_port_schedule_state_t *port_schedule_state, int lport)
   2134 {
   2135     soc_reg_t reg;
   2136     int i;
   2137     uint32 lossless0_xon, lossless0_xoff, lossless1_xon, lossless1_xoff,
   2138            port_xon, port_xoff;
   2139     uint64 rval64, fldval64;
   2140     int phy_port;
   2141     int pm_num;
   2142     int subp;
   2143     int num_lanes;
   2144     int lossless;
   2145     int pipe_num;
   2146     const soc_reg_t obm_fc_thresh_pp[_TH3_PIPES_PER_DEV]
   2147         [_TH3_PBLKS_PER_PIPE][2] = {
   2148         {{IDB_OBM0_FC_THRESHOLD_PIPE0r, IDB_OBM0_FC_THRESHOLD_1_PIPE0r},
   2149          {IDB_OBM1_FC_THRESHOLD_PIPE0r, IDB_OBM1_FC_THRESHOLD_1_PIPE0r},
   2150          {IDB_OBM2_FC_THRESHOLD_PIPE0r, IDB_OBM2_FC_THRESHOLD_1_PIPE0r},
   2151          {IDB_OBM3_FC_THRESHOLD_PIPE0r, IDB_OBM3_FC_THRESHOLD_1_PIPE0r}},
   2152         {{IDB_OBM0_FC_THRESHOLD_PIPE1r, IDB_OBM0_FC_THRESHOLD_1_PIPE1r},
   2153          {IDB_OBM1_FC_THRESHOLD_PIPE1r, IDB_OBM1_FC_THRESHOLD_1_PIPE1r},
   2154          {IDB_OBM2_FC_THRESHOLD_PIPE1r, IDB_OBM2_FC_THRESHOLD_1_PIPE1r},
   2155          {IDB_OBM3_FC_THRESHOLD_PIPE1r, IDB_OBM3_FC_THRESHOLD_1_PIPE1r}},
   2156         {{IDB_OBM0_FC_THRESHOLD_PIPE2r, IDB_OBM0_FC_THRESHOLD_1_PIPE2r},
   2157          {IDB_OBM1_FC_THRESHOLD_PIPE2r, IDB_OBM1_FC_THRESHOLD_1_PIPE2r},
   2158          {IDB_OBM2_FC_THRESHOLD_PIPE2r, IDB_OBM2_FC_THRESHOLD_1_PIPE2r},
   2159          {IDB_OBM3_FC_THRESHOLD_PIPE2r, IDB_OBM3_FC_THRESHOLD_1_PIPE2r}},
   2160         {{IDB_OBM0_FC_THRESHOLD_PIPE3r, IDB_OBM0_FC_THRESHOLD_1_PIPE3r},
   2161          {IDB_OBM1_FC_THRESHOLD_PIPE3r, IDB_OBM1_FC_THRESHOLD_1_PIPE3r},
   2162          {IDB_OBM2_FC_THRESHOLD_PIPE3r, IDB_OBM2_FC_THRESHOLD_1_PIPE3r},
   2163          {IDB_OBM3_FC_THRESHOLD_PIPE3r, IDB_OBM3_FC_THRESHOLD_1_PIPE3r}},
   2164         {{IDB_OBM0_FC_THRESHOLD_PIPE4r, IDB_OBM0_FC_THRESHOLD_1_PIPE4r},
   2165          {IDB_OBM1_FC_THRESHOLD_PIPE4r, IDB_OBM1_FC_THRESHOLD_1_PIPE4r},
   2166          {IDB_OBM2_FC_THRESHOLD_PIPE4r, IDB_OBM2_FC_THRESHOLD_1_PIPE4r},
   2167          {IDB_OBM3_FC_THRESHOLD_PIPE4r, IDB_OBM3_FC_THRESHOLD_1_PIPE4r}},
   2168         {{IDB_OBM0_FC_THRESHOLD_PIPE5r, IDB_OBM0_FC_THRESHOLD_1_PIPE5r},
   2169          {IDB_OBM1_FC_THRESHOLD_PIPE5r, IDB_OBM1_FC_THRESHOLD_1_PIPE5r},
   2170          {IDB_OBM2_FC_THRESHOLD_PIPE5r, IDB_OBM2_FC_THRESHOLD_1_PIPE5r},
   2171          {IDB_OBM3_FC_THRESHOLD_PIPE5r, IDB_OBM3_FC_THRESHOLD_1_PIPE5r}},
   2172         {{IDB_OBM0_FC_THRESHOLD_PIPE6r, IDB_OBM0_FC_THRESHOLD_1_PIPE6r},
   2173          {IDB_OBM1_FC_THRESHOLD_PIPE6r, IDB_OBM1_FC_THRESHOLD_1_PIPE6r},
   2174          {IDB_OBM2_FC_THRESHOLD_PIPE6r, IDB_OBM2_FC_THRESHOLD_1_PIPE6r},
   2175          {IDB_OBM3_FC_THRESHOLD_PIPE6r, IDB_OBM3_FC_THRESHOLD_1_PIPE6r}},
   2176         {{IDB_OBM0_FC_THRESHOLD_PIPE7r, IDB_OBM0_FC_THRESHOLD_1_PIPE7r},
   2177          {IDB_OBM1_FC_THRESHOLD_PIPE7r, IDB_OBM1_FC_THRESHOLD_1_PIPE7r},
   2178          {IDB_OBM2_FC_THRESHOLD_PIPE7r, IDB_OBM2_FC_THRESHOLD_1_PIPE7r},
   2179          {IDB_OBM3_FC_THRESHOLD_PIPE7r, IDB_OBM3_FC_THRESHOLD_1_PIPE7r}}
   2180     };
   2181 
   2182     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   2183     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   2184     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   2185     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   2186     num_lanes = port_schedule_state->out_port_map.port_num_lanes[lport];
   2187     lossless = port_schedule_state->lossless;
   2188     lossless0_xon =
   2189         soc_tomahawk3_obm_settings[lossless][num_lanes].lossless_xon;
   2190     lossless1_xon =
   2191         soc_tomahawk3_obm_settings[lossless][num_lanes].lossless_xon;
   2192     lossless0_xoff =
   2193         soc_tomahawk3_obm_settings[lossless][num_lanes].lossless_xoff;
   2194     lossless1_xoff =
   2195         soc_tomahawk3_obm_settings[lossless][num_lanes].lossless_xoff;
   2196     port_xon =
   2197         soc_tomahawk3_obm_settings[lossless][num_lanes].port_xon;
   2198     port_xoff =
   2199         soc_tomahawk3_obm_settings[lossless][num_lanes].port_xoff;
   2200     COMPILER_64_ZERO(rval64);
   2201     for (i = 0; i < 2; i++) {
   2202         reg = obm_fc_thresh_pp[pipe_num][pm_num][i];
   2203         if (i == 0) {
   2204             COMPILER_64_SET(fldval64, 0, lossless0_xon);
   2205             soc_reg64_field_set(unit, reg, &rval64, LOSSLESS0_XONf,
   2206                                 fldval64);
   2207             COMPILER_64_SET(fldval64, 0, lossless0_xoff);
   2208             soc_reg64_field_set(unit, reg, &rval64, LOSSLESS0_XOFFf,
   2209                                 fldval64);
   2210             COMPILER_64_SET(fldval64, 0, lossless1_xon);
   2211             soc_reg64_field_set(unit, reg, &rval64, LOSSLESS1_XONf,
   2212                                 fldval64);
   2213             COMPILER_64_SET(fldval64, 0, lossless1_xoff);
   2214             soc_reg64_field_set(unit, reg, &rval64, LOSSLESS1_XOFFf,
   2215                                 fldval64);
   2216             SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, REG_PORT_ANY,
   2217                                                     subp, rval64));
   2218         }
   2219         else {
   2220             COMPILER_64_SET(fldval64, 0, port_xon);
   2221             soc_reg64_field_set(unit, reg, &rval64, PORT_XONf, fldval64);
   2222             COMPILER_64_SET(fldval64, 0, port_xoff);
   2223             soc_reg64_field_set(unit, reg, &rval64, PORT_XOFFf, fldval64);
   2224             SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, REG_PORT_ANY,
   2225                                                     subp, rval64));
   2226         }
   2227     }
   2228     return SOC_E_NONE;
   2229 }
   2230 
   2231 /*! @fn int soc_tomahawk3_idb_obm_pri_map_set(int unit,
   2232  *              soc_port_schedule_state_t *port_schedule_state, int lport)
   2233  *  @param unit Chip unit number.
   2234  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   2235                                struct variable
   2236  *  @param lport Logical port number for the port going up.
   2237  *  @brief Helper function to configure IDB_OBM0_DSCP_MAP table as per the
   2238            lossy/lossless configuration.
   2239  *  @returns SOC_E_NONE
   2240  */
   2241 int
   2242 soc_tomahawk3_idb_obm_pri_map_set(
   2243     int unit, soc_port_schedule_state_t *port_schedule_state, int lport)
   2244 {
   2245     soc_mem_t mem;
   2246     uint32 entry[SOC_MAX_MEM_WORDS];
   2247     int pipe_num;
   2248     int pm_num;
   2249     int subp;
   2250     int phy_port;
   2251     int j;
   2252     int count;
   2253     int lossless;
   2254     uint32 priority;
   2255     static const soc_mem_t obm_pri_map_mem[_TH3_PBLKS_PER_PIPE]
   2256         [_TH3_PIPES_PER_DEV][_TH3_PORTS_PER_PBLK] = {
   2257         {{IDB_OBM0_PRI_MAP_PORT0_PIPE0m, IDB_OBM0_PRI_MAP_PORT1_PIPE0m,
   2258           IDB_OBM0_PRI_MAP_PORT2_PIPE0m, IDB_OBM0_PRI_MAP_PORT3_PIPE0m,
   2259           IDB_OBM0_PRI_MAP_PORT4_PIPE0m, IDB_OBM0_PRI_MAP_PORT5_PIPE0m,
   2260           IDB_OBM0_PRI_MAP_PORT6_PIPE0m, IDB_OBM0_PRI_MAP_PORT7_PIPE0m},
   2261          {IDB_OBM0_PRI_MAP_PORT0_PIPE1m, IDB_OBM0_PRI_MAP_PORT1_PIPE1m,
   2262           IDB_OBM0_PRI_MAP_PORT2_PIPE1m, IDB_OBM0_PRI_MAP_PORT3_PIPE1m,
   2263           IDB_OBM0_PRI_MAP_PORT4_PIPE1m, IDB_OBM0_PRI_MAP_PORT5_PIPE1m,
   2264           IDB_OBM0_PRI_MAP_PORT6_PIPE1m, IDB_OBM0_PRI_MAP_PORT7_PIPE1m},
   2265          {IDB_OBM0_PRI_MAP_PORT0_PIPE2m, IDB_OBM0_PRI_MAP_PORT1_PIPE2m,
   2266           IDB_OBM0_PRI_MAP_PORT2_PIPE2m, IDB_OBM0_PRI_MAP_PORT3_PIPE2m,
   2267           IDB_OBM0_PRI_MAP_PORT4_PIPE2m, IDB_OBM0_PRI_MAP_PORT5_PIPE2m,
   2268           IDB_OBM0_PRI_MAP_PORT6_PIPE2m, IDB_OBM0_PRI_MAP_PORT7_PIPE2m},
   2269          {IDB_OBM0_PRI_MAP_PORT0_PIPE3m, IDB_OBM0_PRI_MAP_PORT1_PIPE3m,
   2270           IDB_OBM0_PRI_MAP_PORT2_PIPE3m, IDB_OBM0_PRI_MAP_PORT3_PIPE3m,
   2271           IDB_OBM0_PRI_MAP_PORT4_PIPE3m, IDB_OBM0_PRI_MAP_PORT5_PIPE3m,
   2272           IDB_OBM0_PRI_MAP_PORT6_PIPE3m, IDB_OBM0_PRI_MAP_PORT7_PIPE3m},
   2273          {IDB_OBM0_PRI_MAP_PORT0_PIPE4m, IDB_OBM0_PRI_MAP_PORT1_PIPE4m,
   2274           IDB_OBM0_PRI_MAP_PORT2_PIPE4m, IDB_OBM0_PRI_MAP_PORT3_PIPE4m,
   2275           IDB_OBM0_PRI_MAP_PORT4_PIPE4m, IDB_OBM0_PRI_MAP_PORT5_PIPE4m,
   2276           IDB_OBM0_PRI_MAP_PORT6_PIPE4m, IDB_OBM0_PRI_MAP_PORT7_PIPE4m},
   2277          {IDB_OBM0_PRI_MAP_PORT0_PIPE5m, IDB_OBM0_PRI_MAP_PORT1_PIPE5m,
   2278           IDB_OBM0_PRI_MAP_PORT2_PIPE5m, IDB_OBM0_PRI_MAP_PORT3_PIPE5m,
   2279           IDB_OBM0_PRI_MAP_PORT4_PIPE5m, IDB_OBM0_PRI_MAP_PORT5_PIPE5m,
   2280           IDB_OBM0_PRI_MAP_PORT6_PIPE5m, IDB_OBM0_PRI_MAP_PORT7_PIPE5m},
   2281          {IDB_OBM0_PRI_MAP_PORT0_PIPE6m, IDB_OBM0_PRI_MAP_PORT1_PIPE6m,
   2282           IDB_OBM0_PRI_MAP_PORT2_PIPE6m, IDB_OBM0_PRI_MAP_PORT3_PIPE6m,
   2283           IDB_OBM0_PRI_MAP_PORT4_PIPE6m, IDB_OBM0_PRI_MAP_PORT5_PIPE6m,
   2284           IDB_OBM0_PRI_MAP_PORT6_PIPE6m, IDB_OBM0_PRI_MAP_PORT7_PIPE6m},
   2285          {IDB_OBM0_PRI_MAP_PORT0_PIPE7m, IDB_OBM0_PRI_MAP_PORT1_PIPE7m,
   2286           IDB_OBM0_PRI_MAP_PORT2_PIPE7m, IDB_OBM0_PRI_MAP_PORT3_PIPE7m,
   2287           IDB_OBM0_PRI_MAP_PORT4_PIPE7m, IDB_OBM0_PRI_MAP_PORT5_PIPE7m,
   2288           IDB_OBM0_PRI_MAP_PORT6_PIPE7m, IDB_OBM0_PRI_MAP_PORT7_PIPE7m}},
   2289         {{IDB_OBM1_PRI_MAP_PORT0_PIPE0m, IDB_OBM1_PRI_MAP_PORT1_PIPE0m,
   2290           IDB_OBM1_PRI_MAP_PORT2_PIPE0m, IDB_OBM1_PRI_MAP_PORT3_PIPE0m,
   2291           IDB_OBM1_PRI_MAP_PORT4_PIPE0m, IDB_OBM1_PRI_MAP_PORT5_PIPE0m,
   2292           IDB_OBM1_PRI_MAP_PORT6_PIPE0m, IDB_OBM1_PRI_MAP_PORT7_PIPE0m},
   2293          {IDB_OBM1_PRI_MAP_PORT0_PIPE1m, IDB_OBM1_PRI_MAP_PORT1_PIPE1m,
   2294           IDB_OBM1_PRI_MAP_PORT2_PIPE1m, IDB_OBM1_PRI_MAP_PORT3_PIPE1m,
   2295           IDB_OBM1_PRI_MAP_PORT4_PIPE1m, IDB_OBM1_PRI_MAP_PORT5_PIPE1m,
   2296           IDB_OBM1_PRI_MAP_PORT6_PIPE1m, IDB_OBM1_PRI_MAP_PORT7_PIPE1m},
   2297          {IDB_OBM1_PRI_MAP_PORT0_PIPE2m, IDB_OBM1_PRI_MAP_PORT1_PIPE2m,
   2298           IDB_OBM1_PRI_MAP_PORT2_PIPE2m, IDB_OBM1_PRI_MAP_PORT3_PIPE2m,
   2299           IDB_OBM1_PRI_MAP_PORT4_PIPE2m, IDB_OBM1_PRI_MAP_PORT5_PIPE2m,
   2300           IDB_OBM1_PRI_MAP_PORT6_PIPE2m, IDB_OBM1_PRI_MAP_PORT7_PIPE2m},
   2301          {IDB_OBM1_PRI_MAP_PORT0_PIPE3m, IDB_OBM1_PRI_MAP_PORT1_PIPE3m,
   2302           IDB_OBM1_PRI_MAP_PORT2_PIPE3m, IDB_OBM1_PRI_MAP_PORT3_PIPE3m,
   2303           IDB_OBM1_PRI_MAP_PORT4_PIPE3m, IDB_OBM1_PRI_MAP_PORT5_PIPE3m,
   2304           IDB_OBM1_PRI_MAP_PORT6_PIPE3m, IDB_OBM1_PRI_MAP_PORT7_PIPE3m},
   2305          {IDB_OBM1_PRI_MAP_PORT0_PIPE4m, IDB_OBM1_PRI_MAP_PORT1_PIPE4m,
   2306           IDB_OBM1_PRI_MAP_PORT2_PIPE4m, IDB_OBM1_PRI_MAP_PORT3_PIPE4m,
   2307           IDB_OBM1_PRI_MAP_PORT4_PIPE4m, IDB_OBM1_PRI_MAP_PORT5_PIPE4m,
   2308           IDB_OBM1_PRI_MAP_PORT6_PIPE4m, IDB_OBM1_PRI_MAP_PORT7_PIPE4m},
   2309          {IDB_OBM1_PRI_MAP_PORT0_PIPE5m, IDB_OBM1_PRI_MAP_PORT1_PIPE5m,
   2310           IDB_OBM1_PRI_MAP_PORT2_PIPE5m, IDB_OBM1_PRI_MAP_PORT3_PIPE5m,
   2311           IDB_OBM1_PRI_MAP_PORT4_PIPE5m, IDB_OBM1_PRI_MAP_PORT5_PIPE5m,
   2312           IDB_OBM1_PRI_MAP_PORT6_PIPE5m, IDB_OBM1_PRI_MAP_PORT7_PIPE5m},
   2313          {IDB_OBM1_PRI_MAP_PORT0_PIPE6m, IDB_OBM1_PRI_MAP_PORT1_PIPE6m,
   2314           IDB_OBM1_PRI_MAP_PORT2_PIPE6m, IDB_OBM1_PRI_MAP_PORT3_PIPE6m,
   2315           IDB_OBM1_PRI_MAP_PORT4_PIPE6m, IDB_OBM1_PRI_MAP_PORT5_PIPE6m,
   2316           IDB_OBM1_PRI_MAP_PORT6_PIPE6m, IDB_OBM1_PRI_MAP_PORT7_PIPE6m},
   2317          {IDB_OBM1_PRI_MAP_PORT0_PIPE7m, IDB_OBM1_PRI_MAP_PORT1_PIPE7m,
   2318           IDB_OBM1_PRI_MAP_PORT2_PIPE7m, IDB_OBM1_PRI_MAP_PORT3_PIPE7m,
   2319           IDB_OBM1_PRI_MAP_PORT4_PIPE7m, IDB_OBM1_PRI_MAP_PORT5_PIPE7m,
   2320           IDB_OBM1_PRI_MAP_PORT6_PIPE7m, IDB_OBM1_PRI_MAP_PORT7_PIPE7m}},
   2321         {{IDB_OBM2_PRI_MAP_PORT0_PIPE0m, IDB_OBM2_PRI_MAP_PORT1_PIPE0m,
   2322           IDB_OBM2_PRI_MAP_PORT2_PIPE0m, IDB_OBM2_PRI_MAP_PORT3_PIPE0m,
   2323           IDB_OBM2_PRI_MAP_PORT4_PIPE0m, IDB_OBM2_PRI_MAP_PORT5_PIPE0m,
   2324           IDB_OBM2_PRI_MAP_PORT6_PIPE0m, IDB_OBM2_PRI_MAP_PORT7_PIPE0m},
   2325          {IDB_OBM2_PRI_MAP_PORT0_PIPE1m, IDB_OBM2_PRI_MAP_PORT1_PIPE1m,
   2326           IDB_OBM2_PRI_MAP_PORT2_PIPE1m, IDB_OBM2_PRI_MAP_PORT3_PIPE1m,
   2327           IDB_OBM2_PRI_MAP_PORT4_PIPE1m, IDB_OBM2_PRI_MAP_PORT5_PIPE1m,
   2328           IDB_OBM2_PRI_MAP_PORT6_PIPE1m, IDB_OBM2_PRI_MAP_PORT7_PIPE1m},
   2329          {IDB_OBM2_PRI_MAP_PORT0_PIPE2m, IDB_OBM2_PRI_MAP_PORT1_PIPE2m,
   2330           IDB_OBM2_PRI_MAP_PORT2_PIPE2m, IDB_OBM2_PRI_MAP_PORT3_PIPE2m,
   2331           IDB_OBM2_PRI_MAP_PORT4_PIPE2m, IDB_OBM2_PRI_MAP_PORT5_PIPE2m,
   2332           IDB_OBM2_PRI_MAP_PORT6_PIPE2m, IDB_OBM2_PRI_MAP_PORT7_PIPE2m},
   2333          {IDB_OBM2_PRI_MAP_PORT0_PIPE3m, IDB_OBM2_PRI_MAP_PORT1_PIPE3m,
   2334           IDB_OBM2_PRI_MAP_PORT2_PIPE3m, IDB_OBM2_PRI_MAP_PORT3_PIPE3m,
   2335           IDB_OBM2_PRI_MAP_PORT4_PIPE3m, IDB_OBM2_PRI_MAP_PORT5_PIPE3m,
   2336           IDB_OBM2_PRI_MAP_PORT6_PIPE3m, IDB_OBM2_PRI_MAP_PORT7_PIPE3m},
   2337          {IDB_OBM2_PRI_MAP_PORT0_PIPE4m, IDB_OBM2_PRI_MAP_PORT1_PIPE4m,
   2338           IDB_OBM2_PRI_MAP_PORT2_PIPE4m, IDB_OBM2_PRI_MAP_PORT3_PIPE4m,
   2339           IDB_OBM2_PRI_MAP_PORT4_PIPE4m, IDB_OBM2_PRI_MAP_PORT5_PIPE4m,
   2340           IDB_OBM2_PRI_MAP_PORT6_PIPE4m, IDB_OBM2_PRI_MAP_PORT7_PIPE4m},
   2341          {IDB_OBM2_PRI_MAP_PORT0_PIPE5m, IDB_OBM2_PRI_MAP_PORT1_PIPE5m,
   2342           IDB_OBM2_PRI_MAP_PORT2_PIPE5m, IDB_OBM2_PRI_MAP_PORT3_PIPE5m,
   2343           IDB_OBM2_PRI_MAP_PORT4_PIPE5m, IDB_OBM2_PRI_MAP_PORT5_PIPE5m,
   2344           IDB_OBM2_PRI_MAP_PORT6_PIPE5m, IDB_OBM2_PRI_MAP_PORT7_PIPE5m},
   2345          {IDB_OBM2_PRI_MAP_PORT0_PIPE6m, IDB_OBM2_PRI_MAP_PORT1_PIPE6m,
   2346           IDB_OBM2_PRI_MAP_PORT2_PIPE6m, IDB_OBM2_PRI_MAP_PORT3_PIPE6m,
   2347           IDB_OBM2_PRI_MAP_PORT4_PIPE6m, IDB_OBM2_PRI_MAP_PORT5_PIPE6m,
   2348           IDB_OBM2_PRI_MAP_PORT6_PIPE6m, IDB_OBM2_PRI_MAP_PORT7_PIPE6m},
   2349          {IDB_OBM2_PRI_MAP_PORT0_PIPE7m, IDB_OBM2_PRI_MAP_PORT1_PIPE7m,
   2350           IDB_OBM2_PRI_MAP_PORT2_PIPE7m, IDB_OBM2_PRI_MAP_PORT3_PIPE7m,
   2351           IDB_OBM2_PRI_MAP_PORT4_PIPE7m, IDB_OBM2_PRI_MAP_PORT5_PIPE7m,
   2352           IDB_OBM2_PRI_MAP_PORT6_PIPE7m, IDB_OBM2_PRI_MAP_PORT7_PIPE7m}},
   2353         {{IDB_OBM3_PRI_MAP_PORT0_PIPE0m, IDB_OBM3_PRI_MAP_PORT1_PIPE0m,
   2354           IDB_OBM3_PRI_MAP_PORT2_PIPE0m, IDB_OBM3_PRI_MAP_PORT3_PIPE0m,
   2355           IDB_OBM3_PRI_MAP_PORT4_PIPE0m, IDB_OBM3_PRI_MAP_PORT5_PIPE0m,
   2356           IDB_OBM3_PRI_MAP_PORT6_PIPE0m, IDB_OBM3_PRI_MAP_PORT7_PIPE0m},
   2357          {IDB_OBM3_PRI_MAP_PORT0_PIPE1m, IDB_OBM3_PRI_MAP_PORT1_PIPE1m,
   2358           IDB_OBM3_PRI_MAP_PORT2_PIPE1m, IDB_OBM3_PRI_MAP_PORT3_PIPE1m,
   2359           IDB_OBM3_PRI_MAP_PORT4_PIPE1m, IDB_OBM3_PRI_MAP_PORT5_PIPE1m,
   2360           IDB_OBM3_PRI_MAP_PORT6_PIPE1m, IDB_OBM3_PRI_MAP_PORT7_PIPE1m},
   2361          {IDB_OBM3_PRI_MAP_PORT0_PIPE2m, IDB_OBM3_PRI_MAP_PORT1_PIPE2m,
   2362           IDB_OBM3_PRI_MAP_PORT2_PIPE2m, IDB_OBM3_PRI_MAP_PORT3_PIPE2m,
   2363           IDB_OBM3_PRI_MAP_PORT4_PIPE2m, IDB_OBM3_PRI_MAP_PORT5_PIPE2m,
   2364           IDB_OBM3_PRI_MAP_PORT6_PIPE2m, IDB_OBM3_PRI_MAP_PORT7_PIPE2m},
   2365          {IDB_OBM3_PRI_MAP_PORT0_PIPE3m, IDB_OBM3_PRI_MAP_PORT1_PIPE3m,
   2366           IDB_OBM3_PRI_MAP_PORT2_PIPE3m, IDB_OBM3_PRI_MAP_PORT3_PIPE3m,
   2367           IDB_OBM3_PRI_MAP_PORT4_PIPE3m, IDB_OBM3_PRI_MAP_PORT5_PIPE3m,
   2368           IDB_OBM3_PRI_MAP_PORT6_PIPE3m, IDB_OBM3_PRI_MAP_PORT7_PIPE3m},
   2369          {IDB_OBM3_PRI_MAP_PORT0_PIPE4m, IDB_OBM3_PRI_MAP_PORT1_PIPE4m,
   2370           IDB_OBM3_PRI_MAP_PORT2_PIPE4m, IDB_OBM3_PRI_MAP_PORT3_PIPE4m,
   2371           IDB_OBM3_PRI_MAP_PORT4_PIPE4m, IDB_OBM3_PRI_MAP_PORT5_PIPE4m,
   2372           IDB_OBM3_PRI_MAP_PORT6_PIPE4m, IDB_OBM3_PRI_MAP_PORT7_PIPE4m},
   2373          {IDB_OBM3_PRI_MAP_PORT0_PIPE5m, IDB_OBM3_PRI_MAP_PORT1_PIPE5m,
   2374           IDB_OBM3_PRI_MAP_PORT2_PIPE5m, IDB_OBM3_PRI_MAP_PORT3_PIPE5m,
   2375           IDB_OBM3_PRI_MAP_PORT4_PIPE5m, IDB_OBM3_PRI_MAP_PORT5_PIPE5m,
   2376           IDB_OBM3_PRI_MAP_PORT6_PIPE5m, IDB_OBM3_PRI_MAP_PORT7_PIPE5m},
   2377          {IDB_OBM3_PRI_MAP_PORT0_PIPE6m, IDB_OBM3_PRI_MAP_PORT1_PIPE6m,
   2378           IDB_OBM3_PRI_MAP_PORT2_PIPE6m, IDB_OBM3_PRI_MAP_PORT3_PIPE6m,
   2379           IDB_OBM3_PRI_MAP_PORT4_PIPE6m, IDB_OBM3_PRI_MAP_PORT5_PIPE6m,
   2380           IDB_OBM3_PRI_MAP_PORT6_PIPE6m, IDB_OBM3_PRI_MAP_PORT7_PIPE6m},
   2381          {IDB_OBM3_PRI_MAP_PORT0_PIPE7m, IDB_OBM3_PRI_MAP_PORT1_PIPE7m,
   2382           IDB_OBM3_PRI_MAP_PORT2_PIPE7m, IDB_OBM3_PRI_MAP_PORT3_PIPE7m,
   2383           IDB_OBM3_PRI_MAP_PORT4_PIPE7m, IDB_OBM3_PRI_MAP_PORT5_PIPE7m,
   2384           IDB_OBM3_PRI_MAP_PORT6_PIPE7m, IDB_OBM3_PRI_MAP_PORT7_PIPE7m}}
   2385     };
   2386     static const soc_field_t obm_ob_pri_fields[] = {
   2387         OFFSET0_OB_PRIORITYf, OFFSET1_OB_PRIORITYf, OFFSET2_OB_PRIORITYf,
   2388         OFFSET3_OB_PRIORITYf, OFFSET4_OB_PRIORITYf, OFFSET5_OB_PRIORITYf,
   2389         OFFSET6_OB_PRIORITYf, OFFSET7_OB_PRIORITYf
   2390     };
   2391 
   2392     sal_memset(entry, 0, sizeof(entry));
   2393     lossless = port_schedule_state->lossless;
   2394     count = COUNTOF(obm_ob_pri_fields);
   2395     phy_port = port_schedule_state->out_port_map.port_l2p_mapping[lport];
   2396     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   2397     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   2398     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   2399     mem = obm_pri_map_mem[pm_num][pipe_num][subp];
   2400     for (j = 0; j < count; j++) {
   2401        priority = (lossless == _TH3_OBM_PARAMS_LOSSY_INDEX) ?
   2402                                _TH3_OBM_PRIORITY_LOSSY_LO :
   2403                   (lossless == _TH3_OBM_PARAMS_LOSSLESS_INDEX) ?
   2404                                _TH3_OBM_PRIORITY_LOSSLESS0 :
   2405                   (j == 0) ?   _TH3_OBM_PRIORITY_LOSSLESS0 :
   2406                                _TH3_OBM_PRIORITY_LOSSY_LO;
   2407         soc_mem_field_set(unit, mem, entry, obm_ob_pri_fields[j], &priority);
   2408     }
   2409     SOC_IF_ERROR_RETURN
   2410         (soc_mem_write(unit, mem, MEM_BLOCK_ALL, 0, entry));
   2411     return SOC_E_NONE;
   2412 }
   2413 
   2414 /*! @fn int soc_tomahawk3_idb_outer_tpid_config(int unit,
   2415                 soc_port_map_type_t *port_map, int lport, int enable,
   2416                 int tag_num, int tag_value)
   2417  *  @param unit Chip unit number.
   2418  *  @param port_map Pointer to a soc_port_map_type_t struct variable
   2419  *  @param lport Logical port number for the port going up.
   2420  *  @param enable 1 - Enable match this outer TPID,
   2421                   0 - Disable match this outer TPID.
   2422  *  @param tag_num Tag number (Can be 0, 1, 2, 3).
   2423  *  @param tag_value TPID value to be programmed.
   2424  *  @brief Helper function to configure IDB OBM outer TPID.
   2425  *  @returns SOC_E_NONE
   2426  */
   2427 int
   2428 soc_tomahawk3_idb_outer_tpid_config(int unit,
   2429     soc_port_map_type_t *port_map, int lport, int enable,
   2430     int tag_num, int tag_value)
   2431 {
   2432     soc_reg_t reg;
   2433     uint32 rval32;
   2434     int phy_port;
   2435     int pm_num;
   2436     int pipe_num;
   2437     const soc_reg_t obm_fc_thresh_pp[_TH3_PIPES_PER_DEV]
   2438         [_TH3_PBLKS_PER_PIPE][4] = {
   2439         {{IDB_OBM0_OUTER_TPID_0_PIPE0r, IDB_OBM0_OUTER_TPID_1_PIPE0r,
   2440           IDB_OBM0_OUTER_TPID_2_PIPE0r, IDB_OBM0_OUTER_TPID_3_PIPE0r},
   2441          {IDB_OBM1_OUTER_TPID_0_PIPE0r, IDB_OBM1_OUTER_TPID_1_PIPE0r,
   2442           IDB_OBM1_OUTER_TPID_2_PIPE0r, IDB_OBM1_OUTER_TPID_3_PIPE0r},
   2443          {IDB_OBM2_OUTER_TPID_0_PIPE0r, IDB_OBM2_OUTER_TPID_1_PIPE0r,
   2444           IDB_OBM2_OUTER_TPID_2_PIPE0r, IDB_OBM2_OUTER_TPID_3_PIPE0r},
   2445          {IDB_OBM3_OUTER_TPID_0_PIPE0r, IDB_OBM3_OUTER_TPID_1_PIPE0r,
   2446           IDB_OBM3_OUTER_TPID_2_PIPE0r, IDB_OBM3_OUTER_TPID_3_PIPE0r}},
   2447         {{IDB_OBM0_OUTER_TPID_0_PIPE1r, IDB_OBM0_OUTER_TPID_1_PIPE1r,
   2448           IDB_OBM0_OUTER_TPID_2_PIPE1r, IDB_OBM0_OUTER_TPID_3_PIPE1r},
   2449          {IDB_OBM1_OUTER_TPID_0_PIPE1r, IDB_OBM1_OUTER_TPID_1_PIPE1r,
   2450           IDB_OBM1_OUTER_TPID_2_PIPE1r, IDB_OBM1_OUTER_TPID_3_PIPE1r},
   2451          {IDB_OBM2_OUTER_TPID_0_PIPE1r, IDB_OBM2_OUTER_TPID_1_PIPE1r,
   2452           IDB_OBM2_OUTER_TPID_2_PIPE1r, IDB_OBM2_OUTER_TPID_3_PIPE1r},
   2453          {IDB_OBM3_OUTER_TPID_0_PIPE1r, IDB_OBM3_OUTER_TPID_1_PIPE1r,
   2454           IDB_OBM3_OUTER_TPID_2_PIPE1r, IDB_OBM3_OUTER_TPID_3_PIPE1r}},
   2455         {{IDB_OBM0_OUTER_TPID_0_PIPE2r, IDB_OBM0_OUTER_TPID_1_PIPE2r,
   2456           IDB_OBM0_OUTER_TPID_2_PIPE2r, IDB_OBM0_OUTER_TPID_3_PIPE2r},
   2457          {IDB_OBM1_OUTER_TPID_0_PIPE2r, IDB_OBM1_OUTER_TPID_1_PIPE2r,
   2458           IDB_OBM1_OUTER_TPID_2_PIPE2r, IDB_OBM1_OUTER_TPID_3_PIPE2r},
   2459          {IDB_OBM2_OUTER_TPID_0_PIPE2r, IDB_OBM2_OUTER_TPID_1_PIPE2r,
   2460           IDB_OBM2_OUTER_TPID_2_PIPE2r, IDB_OBM2_OUTER_TPID_3_PIPE2r},
   2461          {IDB_OBM3_OUTER_TPID_0_PIPE2r, IDB_OBM3_OUTER_TPID_1_PIPE2r,
   2462           IDB_OBM3_OUTER_TPID_2_PIPE2r, IDB_OBM3_OUTER_TPID_3_PIPE2r}},
   2463         {{IDB_OBM0_OUTER_TPID_0_PIPE3r, IDB_OBM0_OUTER_TPID_1_PIPE3r,
   2464           IDB_OBM0_OUTER_TPID_2_PIPE3r, IDB_OBM0_OUTER_TPID_3_PIPE3r},
   2465          {IDB_OBM1_OUTER_TPID_0_PIPE3r, IDB_OBM1_OUTER_TPID_1_PIPE3r,
   2466           IDB_OBM1_OUTER_TPID_2_PIPE3r, IDB_OBM1_OUTER_TPID_3_PIPE3r},
   2467          {IDB_OBM2_OUTER_TPID_0_PIPE3r, IDB_OBM2_OUTER_TPID_1_PIPE3r,
   2468           IDB_OBM2_OUTER_TPID_2_PIPE3r, IDB_OBM2_OUTER_TPID_3_PIPE3r},
   2469          {IDB_OBM3_OUTER_TPID_0_PIPE3r, IDB_OBM3_OUTER_TPID_1_PIPE3r,
   2470           IDB_OBM3_OUTER_TPID_2_PIPE3r, IDB_OBM3_OUTER_TPID_3_PIPE3r}},
   2471         {{IDB_OBM0_OUTER_TPID_0_PIPE4r, IDB_OBM0_OUTER_TPID_1_PIPE4r,
   2472           IDB_OBM0_OUTER_TPID_2_PIPE4r, IDB_OBM0_OUTER_TPID_3_PIPE4r},
   2473          {IDB_OBM1_OUTER_TPID_0_PIPE4r, IDB_OBM1_OUTER_TPID_1_PIPE4r,
   2474           IDB_OBM1_OUTER_TPID_2_PIPE4r, IDB_OBM1_OUTER_TPID_3_PIPE4r},
   2475          {IDB_OBM2_OUTER_TPID_0_PIPE4r, IDB_OBM2_OUTER_TPID_1_PIPE4r,
   2476           IDB_OBM2_OUTER_TPID_2_PIPE4r, IDB_OBM2_OUTER_TPID_3_PIPE4r},
   2477          {IDB_OBM3_OUTER_TPID_0_PIPE4r, IDB_OBM3_OUTER_TPID_1_PIPE4r,
   2478           IDB_OBM3_OUTER_TPID_2_PIPE4r, IDB_OBM3_OUTER_TPID_3_PIPE4r}},
   2479         {{IDB_OBM0_OUTER_TPID_0_PIPE5r, IDB_OBM0_OUTER_TPID_1_PIPE5r,
   2480           IDB_OBM0_OUTER_TPID_2_PIPE5r, IDB_OBM0_OUTER_TPID_3_PIPE5r},
   2481          {IDB_OBM1_OUTER_TPID_0_PIPE5r, IDB_OBM1_OUTER_TPID_1_PIPE5r,
   2482           IDB_OBM1_OUTER_TPID_2_PIPE5r, IDB_OBM1_OUTER_TPID_3_PIPE5r},
   2483          {IDB_OBM2_OUTER_TPID_0_PIPE5r, IDB_OBM2_OUTER_TPID_1_PIPE5r,
   2484           IDB_OBM2_OUTER_TPID_2_PIPE5r, IDB_OBM2_OUTER_TPID_3_PIPE5r},
   2485          {IDB_OBM3_OUTER_TPID_0_PIPE5r, IDB_OBM3_OUTER_TPID_1_PIPE5r,
   2486           IDB_OBM3_OUTER_TPID_2_PIPE5r, IDB_OBM3_OUTER_TPID_3_PIPE5r}},
   2487         {{IDB_OBM0_OUTER_TPID_0_PIPE6r, IDB_OBM0_OUTER_TPID_1_PIPE6r,
   2488           IDB_OBM0_OUTER_TPID_2_PIPE6r, IDB_OBM0_OUTER_TPID_3_PIPE6r},
   2489          {IDB_OBM1_OUTER_TPID_0_PIPE6r, IDB_OBM1_OUTER_TPID_1_PIPE6r,
   2490           IDB_OBM1_OUTER_TPID_2_PIPE6r, IDB_OBM1_OUTER_TPID_3_PIPE6r},
   2491          {IDB_OBM2_OUTER_TPID_0_PIPE6r, IDB_OBM2_OUTER_TPID_1_PIPE6r,
   2492           IDB_OBM2_OUTER_TPID_2_PIPE6r, IDB_OBM2_OUTER_TPID_3_PIPE6r},
   2493          {IDB_OBM3_OUTER_TPID_0_PIPE6r, IDB_OBM3_OUTER_TPID_1_PIPE6r,
   2494           IDB_OBM3_OUTER_TPID_2_PIPE6r, IDB_OBM3_OUTER_TPID_3_PIPE6r}},
   2495         {{IDB_OBM0_OUTER_TPID_0_PIPE7r, IDB_OBM0_OUTER_TPID_1_PIPE7r,
   2496           IDB_OBM0_OUTER_TPID_2_PIPE7r, IDB_OBM0_OUTER_TPID_3_PIPE7r},
   2497          {IDB_OBM1_OUTER_TPID_0_PIPE7r, IDB_OBM1_OUTER_TPID_1_PIPE7r,
   2498           IDB_OBM1_OUTER_TPID_2_PIPE7r, IDB_OBM1_OUTER_TPID_3_PIPE7r},
   2499          {IDB_OBM2_OUTER_TPID_0_PIPE7r, IDB_OBM2_OUTER_TPID_1_PIPE7r,
   2500           IDB_OBM2_OUTER_TPID_2_PIPE7r, IDB_OBM2_OUTER_TPID_3_PIPE7r},
   2501          {IDB_OBM3_OUTER_TPID_0_PIPE7r, IDB_OBM3_OUTER_TPID_1_PIPE7r,
   2502           IDB_OBM3_OUTER_TPID_2_PIPE7r, IDB_OBM3_OUTER_TPID_3_PIPE7r}}
   2503     };
   2504 
   2505     if (tag_num>3) {
   2506         LOG_ERROR(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   2507           "Function soc_tomahawk3_idb_outer_tpid_config called with incorrect \
   2508            tag number %0d. Only 0 to 3 tag number are allowed.\n "),tag_num));
   2509     }
   2510     phy_port = port_map->port_l2p_mapping[lport];
   2511     pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   2512     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   2513     reg = obm_fc_thresh_pp[pipe_num][pm_num][tag_num];
   2514     rval32 = 0;
   2515     soc_reg_field_set(unit, reg, &rval32, ENABLEf, enable);
   2516     soc_reg_field_set(unit, reg, &rval32, TPIDf, tag_value);
   2517     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY,
   2518                                                     0, rval32));
   2519     return SOC_E_NONE;
   2520 }
   2521 
   2522 /*! @fn int soc_tomahawk3_enable_dpp_ctrl(int unit, int pipe)
   2523  *  @param unit Chip unit number.
   2524  *  @param pipe Pipe number going up.
   2525  *  @brief Helper function to enable DPP Control.
   2526  *  @returns SOC_E_NONE
   2527  */
   2528 int
   2529 soc_tomahawk3_enable_dpp_ctrl(int unit, int pipe)
   2530 {
   2531     soc_reg_t reg;
   2532     uint32 rval32;
   2533     static const soc_reg_t iarb_dpp_ctrl_regs[_TH3_PIPES_PER_DEV] = {
   2534         IARB_DPP_CTRL_PIPE0r,
   2535         IARB_DPP_CTRL_PIPE1r,
   2536         IARB_DPP_CTRL_PIPE2r,
   2537         IARB_DPP_CTRL_PIPE3r,
   2538         IARB_DPP_CTRL_PIPE4r,
   2539         IARB_DPP_CTRL_PIPE5r,
   2540         IARB_DPP_CTRL_PIPE6r,
   2541         IARB_DPP_CTRL_PIPE7r
   2542     };
   2543     reg = iarb_dpp_ctrl_regs[pipe];
   2544     rval32 = 0;
   2545     soc_reg_field_set(unit, reg, &rval32, RATE_ENf, 1);
   2546     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg,
   2547                         REG_PORT_ANY, 0, rval32));
   2548     return SOC_E_NONE;
   2549 }
   2550 
   2551 
   2552 /*! @fn int soc_tomahawk3_en_epc_link_bmap(int unit,
   2553  *              soc_port_schedule_state_t *port_schedule_state)
   2554  *  @param unit Chip unit number.
   2555  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t struct variable
   2556  *  @brief Helper function to Write EPC_LINK_BMAP table to enable forwarding traffic
   2557  *         to port.
   2558  *  @returns SOC_E_NONE
   2559  */
   2560 int
   2561 soc_tomahawk3_en_epc_link_bmap(
   2562     int unit, soc_port_schedule_state_t *port_schedule_state)
   2563 {
   2564     uint32 epc_link_bmap_tbl[SOC_MAX_MEM_WORDS];
   2565     uint32 memfld[5];
   2566     int lport;
   2567     sal_memset(epc_link_bmap_tbl, 0, sizeof(epc_link_bmap_tbl));
   2568     sal_memset(memfld, 0, sizeof(memfld));
   2569     /* Make EPC_LINK_BMAP=1 for all the ports going up */
   2570     for (lport = 0; lport < _TH3_DEV_PORTS_PER_DEV; lport++) {
   2571         if (port_schedule_state->out_port_map.log_port_speed[lport] > 0 ) {
   2572             memfld[(lport>>5)] |= (0x1<<(lport&0x1f));
   2573         }
   2574     }
   2575     LOG_DEBUG(BSL_LS_SOC_PORT,
   2576               (BSL_META_U(unit,
   2577                           "Enable EPC_LINK_BITMAP write:: %x %x %x %x %x \n"),
   2578                           memfld[0],memfld[1], memfld[2],memfld[3],memfld[4]));
   2579     soc_mem_field_set(unit, EPC_LINK_BMAPm, epc_link_bmap_tbl, PORT_BITMAPf,
   2580                       memfld);
   2581     SOC_IF_ERROR_RETURN(soc_mem_write(unit, EPC_LINK_BMAPm, MEM_BLOCK_ALL, 0,
   2582                                       epc_link_bmap_tbl));
   2583     return SOC_E_NONE;
   2584 }
   2585 
   2586 /*! @fn int soc_tomahawk3_en_dest_port_bmap(int unit,
   2587  *              soc_port_schedule_state_t *port_schedule_state)
   2588  *  @param unit Chip unit number.
   2589  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   2590                                struct variable
   2591  *  @brief Helper function to Write ING_DEST_PORT_ENABLE table to enable
   2592            forwarding traffic to port.
   2593  *  @returns SOC_E_NONE
   2594  */
   2595 int
   2596 soc_tomahawk3_en_dest_port_bmap(
   2597     int unit, soc_port_schedule_state_t *port_schedule_state)
   2598 {
   2599     uint32 ing_dst_p_en_tbl[SOC_MAX_MEM_WORDS];
   2600     uint32 memfld[5];
   2601     int lport;
   2602 
   2603     sal_memset(ing_dst_p_en_tbl, 0, sizeof(ing_dst_p_en_tbl));
   2604     sal_memset(memfld, 0, sizeof(memfld));
   2605     /* Make EPC_LINK_BMAP=1 for all the ports going up */
   2606     for (lport = 0; lport < _TH3_DEV_PORTS_PER_DEV; lport++) {
   2607         if (port_schedule_state->out_port_map.log_port_speed[lport] > 0 ) {
   2608             memfld[(lport>>5)] |= (0x1<<(lport&0x1f));
   2609         }
   2610     }
   2611     soc_mem_field_set(unit, ING_DEST_PORT_ENABLEm, ing_dst_p_en_tbl,
   2612                       PORT_BITMAPf,
   2613                       memfld);
   2614     SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_DEST_PORT_ENABLEm,
   2615                                       MEM_BLOCK_ALL, 0, ing_dst_p_en_tbl));
   2616 
   2617     return SOC_E_NONE;
   2618 }
   2619 
   2620 /*! @fn int soc_tomahawk3_ip_slot_pipeline_config(
   2621       int unit,
   2622       soc_port_schedule_state_t *port_schedule_state)
   2623  *  @param unit Chip unit number.
   2624  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   2625                struct variable.
   2626  *  @brief API to initialize SLOT_PIPELINE_CONFIG
   2627  *  @returns SOC_E_NONE
   2628  */
   2629 int soc_tomahawk3_ip_slot_pipeline_config(
   2630     int unit,
   2631     soc_port_schedule_state_t *port_schedule_state)
   2632 {
   2633     soc_reg_t reg;
   2634     uint32 rval;
   2635     int latency;
   2636 
   2637     /* Set the latency in Slot Pipeline config register */
   2638     reg = SLOT_PIPELINE_CONFIGr;
   2639     rval = 0;
   2640 
   2641     /*
   2642      * Recommended Latency  = (DPPL + A + B + C) * R + D + E + F
   2643      * DPP Latency (DPPL)                       : 134
   2644      * Extra latency in DPP clk (A)             : 6
   2645      * Domain crossing for output event fifo(B) : 3
   2646      * Outstanding Credit (C)                   : 20
   2647      * Early retrieval in core clk (E)          : -54
   2648      * Default margin (D)                       : 5
   2649      * Core clock to DPP clock ratio            : R
   2650      * Max Accumulation Latency                 : F
   2651      */
   2652 
   2653     soc_tomahawk3_get_set_slot_pipeline_latency(
   2654         port_schedule_state->frequency,
   2655         port_schedule_state->in_port_map.port_p2PBLK_inst_mapping[0],
   2656         134, /* DPP Latency (DPPL) */
   2657         6,   /* Extra latency in DPP clk (A) */
   2658         3,   /* Domain crossing for output event fifo(B) */
   2659         12,  /* N - Credit loop (12) */
   2660         20,  /* C - Outstanding Credit (20) */
   2661         5,   /*  Default margin (D) */
   2662         -54, /* Early retrieval in core clk (E) */
   2663         &latency);
   2664 
   2665     soc_reg_field_set(unit, reg, &rval, WR_ENf, 1);
   2666     soc_reg_field_set(unit, reg, &rval, LATENCYf, latency);
   2667     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
   2668     return SOC_E_NONE;
   2669 }
   2670 
   2671 /*! @fn int soc_tomahawk3_idb_obm_poll_buffer_empty(int unit, int pipe_num,
   2672  *              int pm_num, int subp)
   2673  *  @param unit Chip unit number.
   2674  *  @param pipe_num Tomahawk3 pipe number.
   2675  *  @param pm_num PM number within the pipe: Ranges from 0 to 3.
   2676  *  @param subp Subport number.
   2677  *  @brief Helper function to poll for IDB OBM buffer empty.
   2678  *  @returns SOC_E_NONE
   2679  */
   2680 int
   2681 soc_tomahawk3_idb_obm_poll_buffer_empty(int unit,
   2682                  int pipe_num, int pm_num, int subp)
   2683 {
   2684     soc_reg_t reg;
   2685     uint64 rval64, temp64;
   2686     uint64 total_count;
   2687     int timeout_in_usec;
   2688     int timeout_count;
   2689     int total_count_lo, total_count_hi;
   2690 
   2691     const soc_reg_t obm_usage_1_regs[_TH3_PIPES_PER_DEV][_TH3_PBLKS_PER_PIPE] = {
   2692         {IDB_OBM0_USAGE_1_PIPE0r, IDB_OBM1_USAGE_1_PIPE0r,
   2693          IDB_OBM2_USAGE_1_PIPE0r, IDB_OBM3_USAGE_1_PIPE0r},
   2694         {IDB_OBM0_USAGE_1_PIPE1r, IDB_OBM1_USAGE_1_PIPE1r,
   2695          IDB_OBM2_USAGE_1_PIPE1r, IDB_OBM3_USAGE_1_PIPE1r},
   2696         {IDB_OBM0_USAGE_1_PIPE2r, IDB_OBM1_USAGE_1_PIPE2r,
   2697          IDB_OBM2_USAGE_1_PIPE2r, IDB_OBM3_USAGE_1_PIPE2r},
   2698         {IDB_OBM0_USAGE_1_PIPE3r, IDB_OBM1_USAGE_1_PIPE3r,
   2699          IDB_OBM2_USAGE_1_PIPE3r, IDB_OBM3_USAGE_1_PIPE3r},
   2700         {IDB_OBM0_USAGE_1_PIPE4r, IDB_OBM1_USAGE_1_PIPE4r,
   2701          IDB_OBM2_USAGE_1_PIPE4r, IDB_OBM3_USAGE_1_PIPE4r},
   2702         {IDB_OBM0_USAGE_1_PIPE5r, IDB_OBM1_USAGE_1_PIPE5r,
   2703          IDB_OBM2_USAGE_1_PIPE5r, IDB_OBM3_USAGE_1_PIPE5r},
   2704         {IDB_OBM0_USAGE_1_PIPE6r, IDB_OBM1_USAGE_1_PIPE6r,
   2705          IDB_OBM2_USAGE_1_PIPE6r, IDB_OBM3_USAGE_1_PIPE6r},
   2706         {IDB_OBM0_USAGE_1_PIPE7r, IDB_OBM1_USAGE_1_PIPE7r,
   2707          IDB_OBM2_USAGE_1_PIPE7r, IDB_OBM3_USAGE_1_PIPE7r}
   2708     };
   2709 
   2710     if (SAL_BOOT_XGSSIM || SAL_BOOT_BCMSIM) {
   2711         return SOC_E_NONE;
   2712     }
   2713 
   2714     /* Timeout max 25 usec */
   2715     timeout_in_usec = 25;
   2716     timeout_count = 0;
   2717     COMPILER_64_ZERO(temp64);
   2718     reg = obm_usage_1_regs[pipe_num][pm_num];
   2719     do {
   2720         SOC_IF_ERROR_RETURN(soc_reg_rawport_get(unit, reg, REG_PORT_ANY, subp,
   2721                                                 &rval64));
   2722         total_count = soc_reg64_field_get(unit, reg, rval64, TOTAL_COUNTf);
   2723         if (!COMPILER_64_GT(total_count, temp64)) {
   2724             break;
   2725         }
   2726 
   2727         sal_usleep(1 + (SAL_BOOT_QUICKTURN ? 1 : 0) * EMULATION_FACTOR);
   2728         timeout_count++;
   2729         if (timeout_count > timeout_in_usec) {
   2730             total_count_lo = COMPILER_64_LO(total_count);
   2731             total_count_hi = COMPILER_64_HI(total_count);
   2732             LOG_ERROR(BSL_LS_SOC_COMMON,
   2733                (BSL_META_U(unit,
   2734                "Timeout:: soc_tomahawk3_idb_obm_poll_buffer_empty "
   2735                "%0d us timeout !! pipe %0d pm %0d total_count_lo %0d total_count_hi %0d subp %0d"),
   2736                timeout_in_usec,pipe_num,pm_num,total_count_lo,total_count_hi,subp));
   2737             return SOC_E_FAIL;
   2738         }
   2739     } while (COMPILER_64_GT(total_count, temp64));
   2740 
   2741     return SOC_E_NONE;
   2742 }
   2743 
   2744 /*! @fn int soc_tomahawk3_idb_ca_poll_buffer_empty(int unit,
   2745  *              int pipe_num, int pm_num, int subp)
   2746  *  @param unit Chip unit number.
   2747  *  @param pipe_num Tomahawk3 pipe number.
   2748  *  @param pm_num PM number within the pipe: Ranges from 0 to 3.
   2749  *  @param subp Subport number.
   2750  *  @brief Helper function to poll for IDB Cell Assembly buffer empty.
   2751  *  @returns SOC_E_NONE
   2752  */
   2753 int
   2754 soc_tomahawk3_idb_ca_poll_buffer_empty(int unit,
   2755                     int pipe_num, int pm_num, int subp)
   2756 {
   2757     soc_reg_t reg;
   2758     uint64 rval64;
   2759     uint64 ca_fifo_empty;
   2760     int timeout_in_usec;
   2761     int timeout_count;
   2762 
   2763     static const soc_reg_t ca_status_2_regs[_TH3_PIPES_PER_DEV]
   2764         [_TH3_PBLKS_PER_PIPE] = {
   2765         {IDB_CA0_HW_STATUS_2_PIPE0r, IDB_CA1_HW_STATUS_2_PIPE0r,
   2766          IDB_CA2_HW_STATUS_2_PIPE0r, IDB_CA3_HW_STATUS_2_PIPE0r},
   2767         {IDB_CA0_HW_STATUS_2_PIPE1r, IDB_CA1_HW_STATUS_2_PIPE1r,
   2768          IDB_CA2_HW_STATUS_2_PIPE1r, IDB_CA3_HW_STATUS_2_PIPE1r},
   2769         {IDB_CA0_HW_STATUS_2_PIPE2r, IDB_CA1_HW_STATUS_2_PIPE2r,
   2770          IDB_CA2_HW_STATUS_2_PIPE2r, IDB_CA3_HW_STATUS_2_PIPE2r},
   2771         {IDB_CA0_HW_STATUS_2_PIPE3r, IDB_CA1_HW_STATUS_2_PIPE3r,
   2772          IDB_CA2_HW_STATUS_2_PIPE3r, IDB_CA3_HW_STATUS_2_PIPE3r},
   2773         {IDB_CA0_HW_STATUS_2_PIPE4r, IDB_CA1_HW_STATUS_2_PIPE4r,
   2774          IDB_CA2_HW_STATUS_2_PIPE4r, IDB_CA3_HW_STATUS_2_PIPE4r},
   2775         {IDB_CA0_HW_STATUS_2_PIPE5r, IDB_CA1_HW_STATUS_2_PIPE5r,
   2776          IDB_CA2_HW_STATUS_2_PIPE5r, IDB_CA3_HW_STATUS_2_PIPE5r},
   2777         {IDB_CA0_HW_STATUS_2_PIPE6r, IDB_CA1_HW_STATUS_2_PIPE6r,
   2778          IDB_CA2_HW_STATUS_2_PIPE6r, IDB_CA3_HW_STATUS_2_PIPE6r},
   2779         {IDB_CA0_HW_STATUS_2_PIPE7r, IDB_CA1_HW_STATUS_2_PIPE7r,
   2780          IDB_CA2_HW_STATUS_2_PIPE7r, IDB_CA3_HW_STATUS_2_PIPE7r}
   2781     };
   2782     static const soc_field_t ca_status_2_regs_fifo_empty_fields[] = {
   2783         FIFO_EMPTY_PORT0f, FIFO_EMPTY_PORT1f,
   2784         FIFO_EMPTY_PORT2f, FIFO_EMPTY_PORT3f,
   2785         FIFO_EMPTY_PORT4f, FIFO_EMPTY_PORT5f,
   2786         FIFO_EMPTY_PORT6f, FIFO_EMPTY_PORT7f
   2787     };
   2788 
   2789     if (SAL_BOOT_XGSSIM || SAL_BOOT_BCMSIM) {
   2790         return SOC_E_NONE;
   2791     }
   2792 
   2793     /* Timeout max 25 usec */
   2794     timeout_in_usec = 25;
   2795     timeout_count = 0;
   2796     reg = ca_status_2_regs[pipe_num][pm_num];
   2797     do {
   2798         SOC_IF_ERROR_RETURN(soc_reg_rawport_get(unit,
   2799                                  reg, REG_PORT_ANY, 0, &rval64));
   2800         ca_fifo_empty = soc_reg64_field_get(unit, reg, rval64,
   2801                         ca_status_2_regs_fifo_empty_fields[subp]);
   2802         if (!COMPILER_64_IS_ZERO(ca_fifo_empty)) {
   2803             break;
   2804         }
   2805         sal_usleep(1 + (SAL_BOOT_QUICKTURN ? 1 : 0) * EMULATION_FACTOR);
   2806         timeout_count++;
   2807         if (timeout_count > timeout_in_usec) {
   2808             LOG_ERROR(BSL_LS_SOC_COMMON,
   2809                (BSL_META_U(unit,
   2810                "Timeout:: soc_tomahawk3_idb_ca_poll_buffer_empty "
   2811                            "%0d us timeout reached!!"),timeout_in_usec));
   2812             return SOC_E_FAIL;
   2813         }
   2814     } while (COMPILER_64_IS_ZERO(ca_fifo_empty));
   2815 
   2816     return SOC_E_NONE;
   2817 }
   2818 
   2819 /*! @fn int soc_tomahawk3_idb_lpbk_ca_in_reset(int unit, int pipe_num)
   2820  *  @param unit Chip unit number.
   2821  *  @param pipe_num Tomahawk3 pipe number.
   2822  *  @brief Helper function to check if the IDB loopback CA is in reset.
   2823  *  @returns Reset status.
   2824  */
   2825 int
   2826 soc_tomahawk3_idb_lpbk_ca_in_reset(int unit, int pipe_num)
   2827 {
   2828     soc_reg_t reg;
   2829     uint32 rval;
   2830     int buffer_in_reset;
   2831     reg = th3_idb_ca_lpbk_ctrl[pipe_num];
   2832     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit, reg, REG_PORT_ANY, 0, &rval));
   2833     buffer_in_reset = soc_reg_field_get(unit, reg, rval, PORT_RESETf);
   2834     return buffer_in_reset;
   2835 }
   2836 
   2837 /*! @fn int soc_tomahawk3_idb_ca_lpbk_poll_buffer_empty(int unit, int pipe_num)
   2838  *  @param unit Chip unit number.
   2839  *  @param pipe_num Tomahawk3 pipe number.
   2840  *  @brief Helper function to poll for IDB LOOPBACK port
   2841            Cell Assembly buffer empty.
   2842  *  @returns SOC_E_NONE
   2843  */
   2844 int
   2845 soc_tomahawk3_idb_ca_lpbk_poll_buffer_empty(int unit, int pipe_num)
   2846 {
   2847     soc_reg_t reg;
   2848     uint32 rval32;
   2849     uint32 ca_fifo_empty;
   2850     int timeout_in_usec;
   2851     int timeout_count;
   2852     const soc_reg_t th3_idb_ca_lpbk_hw_status[_TH3_PIPES_PER_DEV]= {
   2853         IDB_CA_LPBK_HW_STATUS_PIPE0r, IDB_CA_LPBK_HW_STATUS_PIPE1r,
   2854         IDB_CA_LPBK_HW_STATUS_PIPE2r, IDB_CA_LPBK_HW_STATUS_PIPE3r,
   2855         IDB_CA_LPBK_HW_STATUS_PIPE4r, IDB_CA_LPBK_HW_STATUS_PIPE5r,
   2856         IDB_CA_LPBK_HW_STATUS_PIPE6r, IDB_CA_LPBK_HW_STATUS_PIPE7r};
   2857     if (SAL_BOOT_XGSSIM || SAL_BOOT_BCMSIM) {
   2858         return SOC_E_NONE;
   2859     }
   2860     reg = th3_idb_ca_lpbk_hw_status[pipe_num];
   2861     /* Timeout max 25 usec */
   2862     timeout_in_usec = 25;
   2863     timeout_count = 0;
   2864     do {
   2865         SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit,
   2866                    reg, REG_PORT_ANY, 0, &rval32));
   2867         ca_fifo_empty = soc_reg_field_get(unit, reg, rval32,
   2868                                                 FIFO_EMPTYf);
   2869         if (ca_fifo_empty) {
   2870             break;
   2871         }
   2872         sal_usleep(1 + (SAL_BOOT_QUICKTURN ? 1 : 0) * EMULATION_FACTOR);
   2873         timeout_count++;
   2874         if (timeout_count > timeout_in_usec) {
   2875             LOG_ERROR(BSL_LS_SOC_COMMON,
   2876                (BSL_META_U(unit,
   2877                "Timeout:: soc_tomahawk3_idb_ca_lpbk_poll_buffer_empty "
   2878                            "%0d us timeout reached!!"),timeout_in_usec));
   2879             return SOC_E_FAIL;
   2880         }
   2881     } while (!ca_fifo_empty);
   2882     return SOC_E_NONE;
   2883 }
   2884 
   2885 /*! @fn int soc_tomahawk3_idb_cpu_ca_in_reset(int unit, int pipe_num)
   2886  *  @param unit Chip unit number.
   2887  *  @param pipe_num Tomahawk3 pipe number.
   2888  *  @brief Helper function to check if the IDB CPU CA is in reset.
   2889  *  @returns Reset status;
   2890  */
   2891 int
   2892 soc_tomahawk3_idb_cpu_ca_in_reset(int unit, int pipe_num)
   2893 {
   2894     soc_reg_t reg;
   2895     uint32 rval;
   2896     int buffer_in_reset;
   2897     reg = th3_idb_ca_cpu_ctrl[pipe_num];
   2898     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit, reg, REG_PORT_ANY, 0, &rval));
   2899     buffer_in_reset = soc_reg_field_get(unit, reg, rval, PORT_RESETf);
   2900     return buffer_in_reset;
   2901 }
   2902 
   2903 /*! @fn int soc_tomahawk3_idb_ca_cpu_poll_buffer_empty(int unit, int pipe_num)
   2904  *  @param unit Chip unit number.
   2905  *  @param pipe_num Tomahawk3 pipe number.
   2906  *  @brief Helper function to poll for IDB CPU Cell Assembly buffer empty.
   2907  *  @returns SOC_E_NONE
   2908  */
   2909 int
   2910 soc_tomahawk3_idb_ca_cpu_poll_buffer_empty(int unit, int pipe_num)
   2911 {
   2912     soc_reg_t reg;
   2913     uint32 rval32;
   2914     uint32 ca_fifo_empty;
   2915     int timeout_in_usec;
   2916     int timeout_count;
   2917     const soc_reg_t idb_ca_cpu_hw_status[_TH3_PIPES_PER_DEV]= {
   2918         IDB_CA_CPU_HW_STATUS_PIPE0r, IDB_CA_CPU_HW_STATUS_PIPE1r,
   2919         IDB_CA_CPU_HW_STATUS_PIPE2r, IDB_CA_CPU_HW_STATUS_PIPE3r,
   2920         IDB_CA_CPU_HW_STATUS_PIPE4r, IDB_CA_CPU_HW_STATUS_PIPE5r,
   2921         IDB_CA_CPU_HW_STATUS_PIPE6r, IDB_CA_CPU_HW_STATUS_PIPE7r};
   2922     if (SAL_BOOT_XGSSIM || SAL_BOOT_BCMSIM) {
   2923         return SOC_E_NONE;
   2924     }
   2925     reg = idb_ca_cpu_hw_status[pipe_num];
   2926     /* Timeout max 25 usec */
   2927     timeout_in_usec = 25;
   2928     timeout_count = 0;
   2929     do {
   2930         SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit,
   2931                    reg, REG_PORT_ANY, 0, &rval32));
   2932         ca_fifo_empty = soc_reg_field_get(unit, reg, rval32,
   2933                                                 FIFO_EMPTYf);
   2934         if (ca_fifo_empty) {
   2935             break;
   2936         }
   2937         sal_usleep(1 + (SAL_BOOT_QUICKTURN ? 1 : 0) * EMULATION_FACTOR);
   2938         timeout_count++;
   2939         if (timeout_count > timeout_in_usec) {
   2940             LOG_ERROR(BSL_LS_SOC_COMMON,
   2941                (BSL_META_U(unit,
   2942                "Timeout:: soc_tomahawk3_idb_obm_poll_buffer_empty "
   2943                            "%0d us timeout reached!!"),timeout_in_usec));
   2944             return SOC_E_FAIL;
   2945         }
   2946     } while (!ca_fifo_empty);
   2947     return SOC_E_NONE;
   2948 }
   2949 
   2950 /*! @fn int soc_tomahawk3_idb_lpbk_ca_reset_buffer(int unit, int pipe_num, 
   2951                       int reset_buffer)
   2952  *  @param unit Chip unit number.
   2953  *  @param pipe_num Tomahawk3 pipe number.
   2954  *  @param reset_buffer IDB Cell Assembly reset buffer: 1 - Apply reset.
   2955  *         0 - Release reset.
   2956  *  @brief Helper function to apply / or release IDB Cell Assembly buffer reset
   2957  *                  for loopback port.
   2958  *  @returns SOC_E_NONE
   2959  */
   2960 int
   2961 soc_tomahawk3_idb_lpbk_ca_reset_buffer(int unit, int pipe_num, int reset_buffer)
   2962 {
   2963     soc_reg_t reg;
   2964     uint32 rval;
   2965     reg = th3_idb_ca_lpbk_ctrl[pipe_num];
   2966     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit, reg, REG_PORT_ANY, 0, &rval));
   2967     soc_reg_field_set(unit, reg, &rval, PORT_RESETf, reset_buffer);
   2968     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY, 0, rval));
   2969     return SOC_E_NONE;
   2970 }
   2971 
   2972 /*! @fn int soc_tomahawk3_idb_cpu_ca_reset_buffer(int unit, int pipe_num, 
   2973                       int reset_buffer)
   2974  *  @param unit Chip unit number.
   2975  *  @param pipe_num Tomahawk3 pipe number.
   2976  *  @param reset_buffer IDB Cell Assembly reset buffer: 1 - Apply reset.
   2977  *         0 - Release reset.
   2978  *  @brief Helper function to apply / or release IDB Cell Assembly buffer reset
   2979  *                  for CPU port.
   2980  *  @returns SOC_E_NONE
   2981  */
   2982 int
   2983 soc_tomahawk3_idb_cpu_ca_reset_buffer(int unit, int pipe_num, int reset_buffer)
   2984 {
   2985     soc_reg_t reg;
   2986     uint32 rval;
   2987     reg = th3_idb_ca_cpu_ctrl[pipe_num];
   2988     SOC_IF_ERROR_RETURN(soc_reg32_rawport_get(unit, reg, REG_PORT_ANY, 0, &rval));
   2989     soc_reg_field_set(unit, reg, &rval, PORT_RESETf, reset_buffer);
   2990     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY, 0, rval));
   2991 
   2992     return SOC_E_NONE;
   2993 }
   2994 
   2995 /*! @fn int soc_tomahawk3_idb_force_saf_duration_timer_cfg(int unit,
   2996                 soc_port_schedule_state_t *port_schedule_state, int pipe_num)
   2997  *  @param unit Chip unit number.
   2998  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   2999                struct variable.
   3000  *  @param pipe_num Tomahawk3 pipe number.
   3001  *  @brief Helper function to configure 
   3002            IDB_FORCE_SAF_CONFIG.DURATION_TIMER register field.
   3003  *  @returns SOC_E_NONE
   3004  */
   3005 int
   3006 soc_tomahawk3_idb_force_saf_duration_timer_cfg(int unit, 
   3007     soc_port_schedule_state_t *port_schedule_state, int pipe_num)
   3008 {
   3009     soc_reg_t reg;
   3010     uint32 rval;
   3011     int core_clock_freq;
   3012     int duration_timer;
   3013     const soc_reg_t idb_force_saf_config_regs[_TH3_PIPES_PER_DEV] =
   3014     {IDB_DBG_B_PIPE0r, IDB_DBG_B_PIPE1r, IDB_DBG_B_PIPE2r, IDB_DBG_B_PIPE3r,
   3015      IDB_DBG_B_PIPE4r, IDB_DBG_B_PIPE5r, IDB_DBG_B_PIPE6r, IDB_DBG_B_PIPE7r};
   3016 
   3017     core_clock_freq = port_schedule_state->frequency;
   3018     duration_timer = 2*core_clock_freq;
   3019     reg = idb_force_saf_config_regs[pipe_num];
   3020     rval=0;
   3021     soc_reg_field_set(unit, reg, &rval, FIELD_Af, duration_timer);
   3022     SOC_IF_ERROR_RETURN(soc_reg32_rawport_set(unit, reg, REG_PORT_ANY, 0, rval));
   3023     return SOC_E_NONE;
   3024 }
   3025 
   3026 /*! @fn int soc_tomahawk3_speed_to_e2e_settings_class_map(int speed)
   3027  *  @param speed Port speed.
   3028  *  @brief Helper function to get e2e settings class as below::
   3029  *         The function look at the port speed & returns the encoding as below::
   3030  *          0 - SAF,
   3031  *          1 - 10GE,
   3032  *          2 - 25GE,
   3033  *          3 - 40GE,
   3034  *          4 - 50GE,
   3035  *          5 - 100GE,
   3036  *          6 - 200GE,
   3037  *          7 - 400GE,
   3038  *  @returns int
   3039  */
   3040 int
   3041 soc_tomahawk3_speed_to_e2e_settings_class_map(int speed)
   3042 {
   3043     int e2e_settings_class;
   3044     int i;
   3045 
   3046     e2e_settings_class=0;
   3047     for (i = 0; i < COUNTOF(soc_tomahawk3_e2e_settings_tbl); i++) {
   3048         if (soc_tomahawk3_e2e_settings_tbl[i].speed == speed) {
   3049             e2e_settings_class = i;
   3050             break;
   3051         }
   3052     }
   3053     return e2e_settings_class;
   3054 }
   3055 
   3056 
   3057 /*! @fn int soc_tomahawk3_idb_init(int unit,
   3058                soc_port_schedule_state_t *port_schedule_state)
   3059  *  @param unit Chip unit number.
   3060  *  @param port_schedule_state Pointer to soc_port_schedule_state_t variable.
   3061  *  @brief Helper function to initialize TH3 IDB.
   3062  *  @returns SOC_E_NONE
   3063  */
   3064 int
   3065 soc_tomahawk3_idb_init(int unit,
   3066                              soc_port_schedule_state_t *port_schedule_state)
   3067 {
   3068     int lport;
   3069     int phy_port;
   3070     int pmnum;
   3071     int pm_going_up;
   3072     int reset;
   3073     int lport_save = 0;
   3074     int pipe_num;
   3075     int pipe_going_up;
   3076     uint32 pipe_map;
   3077 
   3078     /* If multiple ports going up in same PM, write only once for the
   3079        general registers that are common to all sub-ports. */
   3080     for (pmnum = 0; pmnum < _TH3_NUM_OF_TSCBH ; pmnum++) {
   3081         pm_going_up=0;
   3082         lport_save=0;
   3083         for (lport = 0; lport < _TH3_DEV_PORTS_PER_DEV; lport++) {
   3084             if (port_schedule_state->out_port_map.log_port_speed[lport] > 0 ) {
   3085                 phy_port =
   3086                     port_schedule_state->out_port_map.port_l2p_mapping[lport];
   3087                 if (_TH3_PHY_IS_FRONT_PANEL_PORT(phy_port)&&
   3088                     (((phy_port - 1) >> 3) == pmnum)) {
   3089                     pm_going_up|= 1;
   3090                     lport_save = lport;
   3091                 }
   3092             }
   3093         }
   3094         LOG_DEBUG(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   3095                   "soc_tomahawk3_idb_port_init: pmnum %0d pm_going_up=%0d"),
   3096                   pmnum, pm_going_up));
   3097 
   3098         if (pm_going_up){
   3099             reset=0;
   3100             lport = lport_save;
   3101             SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_pa_reset(
   3102                 unit, &port_schedule_state->out_port_map,lport,reset));
   3103             SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_obm_tdm_cfg(
   3104                 unit, &port_schedule_state->out_port_map,lport));
   3105         }
   3106     }
   3107 
   3108     /*IDB to DEV mapping table configured for all entries */
   3109     soc_tomahawk3_get_pipe_map(unit, port_schedule_state, &pipe_map);
   3110     for (pipe_num = 0; pipe_num < _TH3_PIPES_PER_DEV; pipe_num++) {
   3111         if (!(pipe_map & (1 << pipe_num))) {
   3112             continue;
   3113         }
   3114         SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_init_idb_to_dev_all_pipe(
   3115             unit, pipe_num));
   3116     }
   3117 
   3118     /* Configure per port registers: Front Panel ports; */
   3119     for (lport = 0; lport < _TH3_DEV_PORTS_PER_DEV; lport++) {
   3120         if (port_schedule_state->out_port_map.log_port_speed[lport] > 0 ) {
   3121             phy_port =
   3122                     port_schedule_state->out_port_map.port_l2p_mapping[lport];
   3123             pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   3124             /*IDB mapping tables*/
   3125             /*SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_init_idb_to_dev_pmap_tbl(
   3126                 unit, &port_schedule_state->out_port_map,lport));*/
   3127 
   3128             if (_TH3_PHY_IS_FRONT_PANEL_PORT(phy_port)){
   3129                 LOG_DEBUG(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   3130                   "soc_tomahawk3_idb_init: Start obm init phy_port %0d"),
   3131                   phy_port));
   3132                 /*OBM init*/
   3133                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_wr_obm_shared_config(
   3134                     unit, port_schedule_state,lport));
   3135                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_wr_obm_thresh(
   3136                     unit, port_schedule_state,lport));
   3137                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_wr_obm_flow_ctrl_cfg(
   3138                     unit, port_schedule_state,lport));
   3139                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_wr_obm_fc_threshold(
   3140                     unit, port_schedule_state,lport));
   3141                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_wr_obm_ct_thresh(
   3142                     unit, port_schedule_state,lport));
   3143                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_wr_obm_port_config(
   3144                     unit, port_schedule_state,lport));
   3145                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_wr_obm_monitor_stats_config(
   3146                     unit, port_schedule_state,lport));
   3147                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_wr_obm_force_saf_config(
   3148                     unit, port_schedule_state,lport));
   3149                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_wr_obm_lag_detection_config(
   3150                     unit, port_schedule_state,lport));
   3151                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_obm_pri_map_set(
   3152                     unit, port_schedule_state,lport));
   3153                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_obm_buffer_config(
   3154                     unit, &port_schedule_state->out_port_map,lport));
   3155 
   3156                 /* Front panel Physical to IDB port mapping */
   3157                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_init_pnum_mapping_tbl(
   3158                     unit, &port_schedule_state->out_port_map,lport));
   3159 
   3160                 /*CA */
   3161                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_wr_ca_ct_thresh(
   3162                     unit, port_schedule_state,lport));
   3163                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_ca_bmop_set(
   3164                     unit, port_schedule_state,lport));
   3165                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_wr_ca_force_saf_config(
   3166                     unit, port_schedule_state,lport));
   3167                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_wr_ca_lag_detection_config(
   3168                     unit, port_schedule_state,lport));
   3169                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_ca_buffer_config(
   3170                     unit, &port_schedule_state->out_port_map,lport));
   3171                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_ca_peek_depth_cfg(
   3172                     unit, &port_schedule_state->out_port_map,lport));
   3173             }else if(soc_tomahawk3_phy_is_lpbk_port(phy_port)){
   3174                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_lpbk_ca_peek_depth_cfg(
   3175                     unit, pipe_num));
   3176             }else if(soc_tomahawk3_phy_is_cpu_mgmt_port(phy_port)){
   3177                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_cpu_ca_peek_depth_cfg(
   3178                     unit, pipe_num));
   3179             }
   3180         }
   3181     }
   3182     
   3183     /* Force SAF Duration timer configuration per pipe */
   3184     for (pipe_num = 0; pipe_num < _TH3_PIPES_PER_DEV ; pipe_num++) {
   3185         pipe_going_up=0;
   3186         for (lport = 0; lport < _TH3_DEV_PORTS_PER_DEV; lport++) {
   3187             if (port_schedule_state->out_port_map.log_port_speed[lport] > 0 ) {
   3188                 phy_port =
   3189                     port_schedule_state->out_port_map.port_l2p_mapping[lport];
   3190                 if (_TH3_PHY_IS_FRONT_PANEL_PORT(phy_port)&&
   3191                     (soc_tomahawk3_get_pipe_from_phy_port(phy_port) == pipe_num)) {
   3192                     pipe_going_up|= 1;
   3193                     break;
   3194                 }
   3195             }
   3196         }
   3197         if (pipe_going_up){
   3198             SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_force_saf_duration_timer_cfg(
   3199                 unit, port_schedule_state, pipe_num));
   3200         }
   3201     }
   3202 
   3203     /* Release reset for CPU & Loopback port CA */
   3204     reset = 0;
   3205     for (lport = 0; lport < _TH3_DEV_PORTS_PER_DEV; lport++) {
   3206         if (port_schedule_state->out_port_map.log_port_speed[lport] > 0 ) {
   3207             phy_port =
   3208                     port_schedule_state->out_port_map.port_l2p_mapping[lport];
   3209             pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   3210 
   3211             if(soc_tomahawk3_phy_is_lpbk_port(phy_port)){
   3212                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_lpbk_ca_reset_buffer(unit,
   3213                     pipe_num, reset));
   3214             }else if(soc_tomahawk3_phy_is_cpu_mgmt_port(phy_port)){
   3215                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_cpu_ca_reset_buffer(unit,
   3216                     pipe_num, reset));
   3217             }
   3218         }
   3219     }
   3220 
   3221     /* Release reset for All Front panel port CA */
   3222     SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_ca_wr_dom_rst_rel_all(
   3223         unit, port_schedule_state));
   3224     SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_ca_rd_dom_rst_rel_all(
   3225         unit, port_schedule_state));
   3226 
   3227     SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_obm_rst_rel_all(
   3228         unit, port_schedule_state));
   3229     return SOC_E_NONE;
   3230 }
   3231 
   3232 /*! @fn int soc_tomahawk3_ipipe_init(int unit,
   3233                soc_port_schedule_state_t *port_schedule_state)
   3234  *  @param unit Chip unit number.
   3235  *  @param port_schedule_state Pointer to soc_port_schedule_state_t variable.
   3236  *  @brief Helper function to initialize TH3 IPIPE.
   3237  *  @returns SOC_E_NONE
   3238  */
   3239 int
   3240 soc_tomahawk3_ipipe_init(int unit,
   3241                              soc_port_schedule_state_t *port_schedule_state)
   3242 {
   3243     SOC_IF_ERROR_RETURN(soc_tomahawk3_en_epc_link_bmap(
   3244         unit, port_schedule_state));
   3245     SOC_IF_ERROR_RETURN(soc_tomahawk3_en_dest_port_bmap(
   3246         unit, port_schedule_state));
   3247     SOC_IF_ERROR_RETURN(soc_tomahawk3_ip_slot_pipeline_config(
   3248         unit, port_schedule_state));
   3249     return SOC_E_NONE;
   3250 }
   3251 
   3252 /*! @fn int soc_tomahawk3_idb_port_down(int unit,
   3253                 soc_port_schedule_state_t *port_schedule_state)
   3254  *  @param unit Chip unit number.
   3255  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t struct
   3256            variable
   3257  *  @brief Helper function to follow IDB port down sequence based on
   3258            port_schedule_state->resource[i] array.
   3259            Follows the sequence specified in document 
   3260            "TH3 Flexport Specification.pdf", Revision 0.1, Section 5.1.
   3261            Two main parts:
   3262               (1) Poll untill IDB buffers are empty.
   3263               (2) Hold IDB buffers in reset state.
   3264  *  @returns SOC_E_NONE
   3265  */
   3266 int
   3267 soc_tomahawk3_idb_port_down(int unit,
   3268                             soc_port_schedule_state_t *port_schedule_state)
   3269 {
   3270     int i;
   3271     int pipe_num;
   3272     int pm_num;
   3273     int reset_buffer;
   3274     int phy_port;
   3275     int subp;
   3276     int lport;
   3277 
   3278     /* Poll until IDB buffers are empty for all the ports going down */
   3279     for (i = 0; i < port_schedule_state->nport; i++) {
   3280         if (port_schedule_state->resource[i].physical_port == -1) {
   3281             phy_port =
   3282                 port_schedule_state->in_port_map.port_l2p_mapping[
   3283                     port_schedule_state
   3284                     ->resource[i]
   3285                     .logical_port];
   3286             pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   3287             pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   3288             subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   3289             if (_TH3_PHY_IS_FRONT_PANEL_PORT(phy_port)) {
   3290                 LOG_DEBUG(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   3291                   "soc_tomahawk3_idb_port_down: call soc_tomahawk3_idb_obm_poll_buffer_empty %0d"),
   3292                   phy_port));
   3293                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_obm_poll_buffer_empty(
   3294                     unit, pipe_num, pm_num, subp));
   3295             }
   3296             if (_TH3_PHY_IS_FRONT_PANEL_PORT(phy_port)) {
   3297                 LOG_DEBUG(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   3298                   "soc_tomahawk3_idb_port_down: call soc_tomahawk3_idb_ca_poll_buffer_empty %0d"),
   3299                   phy_port));
   3300                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_ca_poll_buffer_empty(
   3301                     unit, pipe_num, pm_num, subp));
   3302             } else if(soc_tomahawk3_phy_is_lpbk_port(phy_port)){
   3303                 if (!soc_tomahawk3_idb_lpbk_ca_in_reset(unit,pipe_num)){
   3304                     SOC_IF_ERROR_RETURN(
   3305                         soc_tomahawk3_idb_ca_lpbk_poll_buffer_empty(
   3306                         unit, pipe_num));
   3307                 }
   3308             }else if(soc_tomahawk3_phy_is_cpu_mgmt_port(phy_port)){
   3309                 if (!soc_tomahawk3_idb_cpu_ca_in_reset(unit,pipe_num)){
   3310                     SOC_IF_ERROR_RETURN(
   3311                         soc_tomahawk3_idb_ca_cpu_poll_buffer_empty(
   3312                         unit, pipe_num));
   3313                 }
   3314             }
   3315         }
   3316     }
   3317 
   3318     /* Hold IDB buffers in reset state for all the ports going down */
   3319     for (i = 0; i < port_schedule_state->nport; i++) {
   3320         if (port_schedule_state->resource[i].physical_port == -1) {
   3321             lport = port_schedule_state->resource[i].logical_port;
   3322             phy_port = port_schedule_state->in_port_map.port_l2p_mapping[lport];
   3323             pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   3324             pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   3325             subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   3326             reset_buffer = 1;
   3327             if (_TH3_PHY_IS_FRONT_PANEL_PORT(phy_port)) {
   3328                 LOG_DEBUG(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   3329                   "port_down: call soc_tomahawk3_idb_obm_reset %0d"),
   3330                   phy_port));
   3331                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_obm_reset(
   3332                     unit, &port_schedule_state->in_port_map,
   3333                     lport, reset_buffer));
   3334             }
   3335             if (_TH3_PHY_IS_FRONT_PANEL_PORT(phy_port)) {
   3336                 LOG_DEBUG(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   3337                   "port_down: call soc_tomahawk3_idb_ca_rd_domain_reset %0d"),
   3338                   phy_port));
   3339                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_ca_rd_domain_reset(
   3340                     unit, &port_schedule_state->in_port_map,
   3341                     lport, reset_buffer));
   3342                 LOG_DEBUG(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   3343                   "port_down: call soc_tomahawk3_idb_ca_wr_domain_reset %0d"),
   3344                   phy_port));
   3345                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_ca_wr_domain_reset(
   3346                     unit, &port_schedule_state->in_port_map,
   3347                     lport, reset_buffer));
   3348             }else if(soc_tomahawk3_phy_is_lpbk_port(phy_port)){
   3349                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_lpbk_ca_reset_buffer(unit,
   3350                     pipe_num, reset_buffer));
   3351             }else if(soc_tomahawk3_phy_is_cpu_mgmt_port(phy_port)){
   3352                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_cpu_ca_reset_buffer(unit,
   3353                     pipe_num, reset_buffer));
   3354             }
   3355         }
   3356     }
   3357 
   3358     return SOC_E_NONE;
   3359 }
   3360 
   3361 /*! @fn int soc_tomahawk3_idb_port_up(int unit,
   3362  *              soc_port_schedule_state_t *port_schedule_state)
   3363  *  @param unit Chip unit number.
   3364  *  @param port_schedule_state Pointer to a soc_port_schedule_state_t
   3365                                struct variable
   3366  *  @brief Helper function to bringup IDB based on
   3367            port_schedule_state->resource[i] array.
   3368  *  @returns SOC_E_NONE
   3369  */
   3370 int
   3371 soc_tomahawk3_idb_port_up(int unit,
   3372                           soc_port_schedule_state_t *port_schedule_state)
   3373 {
   3374     int i;
   3375     int pipe_num;
   3376     int pm_num;
   3377     int reset_buffer;
   3378     int phy_port;
   3379     int lport;
   3380     int subp;
   3381 
   3382     LOG_DEBUG(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   3383                   "soc_tomahawk3_idb_port_up: start.")
   3384                   ));
   3385 
   3386     for (i = 0; i < port_schedule_state->nport; i++) {
   3387         if (port_schedule_state->resource[i].physical_port != -1) {
   3388             lport = port_schedule_state->resource[i].logical_port;
   3389             phy_port = 
   3390                 port_schedule_state->out_port_map.port_l2p_mapping[lport];
   3391             pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   3392             reset_buffer = 1;
   3393             if (_TH3_PHY_IS_FRONT_PANEL_PORT(phy_port)) {
   3394                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_obm_reset(
   3395                     unit, &port_schedule_state->out_port_map,
   3396                     lport, reset_buffer));
   3397             }
   3398             if (_TH3_PHY_IS_FRONT_PANEL_PORT(phy_port)) {
   3399                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_ca_rd_domain_reset(
   3400                     unit, &port_schedule_state->out_port_map,
   3401                     lport, reset_buffer));
   3402                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_ca_wr_domain_reset(
   3403                     unit, &port_schedule_state->out_port_map,
   3404                     lport, reset_buffer));
   3405             }else if(soc_tomahawk3_phy_is_lpbk_port(phy_port)){
   3406                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_lpbk_ca_reset_buffer(unit,
   3407                     pipe_num, reset_buffer));
   3408             }else if(soc_tomahawk3_phy_is_cpu_mgmt_port(phy_port)){
   3409                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_cpu_ca_reset_buffer(unit,
   3410                     pipe_num, reset_buffer));
   3411             }
   3412         }
   3413     }
   3414 
   3415     for (i = 0; i < port_schedule_state->nport; i++) {
   3416         if (port_schedule_state->resource[i].physical_port != -1) {
   3417             lport = port_schedule_state->resource[i].logical_port;
   3418             phy_port =
   3419                 port_schedule_state->out_port_map.port_l2p_mapping[lport];
   3420             pipe_num = soc_tomahawk3_get_pipe_from_phy_port(phy_port);
   3421             pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
   3422             subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
   3423             LOG_DEBUG(BSL_LS_SOC_PORT, (BSL_META_U(unit,
   3424                 "IDB port Up i %1d phy_port %1d pipe=%1d pm=%1d "
   3425                 "subp=%1d \n"),
   3426                 i, phy_port, pipe_num, pm_num, subp));
   3427             reset_buffer = 0;
   3428             if (_TH3_PHY_IS_FRONT_PANEL_PORT(phy_port)) {
   3429                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_ca_wr_domain_reset(
   3430                     unit, &port_schedule_state->out_port_map, lport, reset_buffer));
   3431                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_ca_rd_domain_reset(
   3432                     unit, &port_schedule_state->out_port_map, lport, reset_buffer));
   3433             }else if(soc_tomahawk3_phy_is_lpbk_port(phy_port)){
   3434                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_lpbk_ca_reset_buffer(unit,
   3435                     pipe_num, reset_buffer));
   3436             }else if(soc_tomahawk3_phy_is_cpu_mgmt_port(phy_port)){
   3437                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_cpu_ca_reset_buffer(unit,
   3438                     pipe_num, reset_buffer));
   3439             }
   3440             if (_TH3_PHY_IS_FRONT_PANEL_PORT(phy_port)) {
   3441                 SOC_IF_ERROR_RETURN(soc_tomahawk3_idb_obm_reset(
   3442                     unit, &port_schedule_state->out_port_map, lport, reset_buffer));
   3443             }
   3444         }
   3445     }
   3446     return SOC_E_NONE;
   3447 }
   3448 
   3449 
   3450 
   3451 /*** END SDK API COMMON CODE ***/
   3452 
   3453 #endif /* BCM_TOMAHAWK3_SUPPORT */