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

asf.c (139339B)


      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:      asf.c
      8  * Purpose:   ASF feature support for Tomahawk SKUs
      9  * Requires:  soc/tomahawk.h
     10  */
     11 
     12 #include <soc/tomahawk.h>
     13 
     14 #if defined(BCM_TOMAHAWK_SUPPORT)
     15 
     16 #include <appl/diag/system.h>
     17 #include <soc/drv.h>
     18 #include <soc/ll.h>
     19 #include <soc/property.h>
     20 #include <shared/bsl.h>
     21 #ifdef BCM_WARM_BOOT_SUPPORT
     22 #include <soc/scache.h>
     23 #endif
     24 #include <bcm/link.h>
     25 #include <soc/esw/portctrl.h>
     26 
     27 /* Linkscan/PHY control Declarations */
     28 extern int bcm_esw_linkscan_register(int, bcm_linkscan_handler_t);
     29 extern int bcm_esw_linkscan_unregister(int, bcm_linkscan_handler_t);
     30 extern int bcm_esw_port_phy_control_get(int,bcm_port_t,bcm_port_phy_control_t,uint32 *);
     31 
     32 #define _SOC_TH_ASF_QUERY   0xfe
     33 #define _SOC_TH_ASF_RETRV   0xff
     34 
     35 #define _SOC_TH_CT_CLASS_TO_SPEED_MAP(ct_class) \
     36         _soc_th_asf_cfg_tbl[(ct_class)].speed
     37 
     38 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
     39 
     40 #define _SOC_TH_PORT_ASF_XMIT_START_COUNT_INIT \
     41         soc_th_port_asf_xmit_start_count_set
     42 
     43 #define _SOC_TH_PORT_ASF_REINIT \
     44         soc_th_port_asf_init
     45 
     46 #define _SOC_TH_ASF_SPEED_CLASS_VALIDATE(class, floor) \
     47         if (!(((class) >= (floor)) && ((class) <= 12)))   \
     48             return SOC_E_PARAM;
     49 
     50 #define _SOC_TH_ASF_PORT_VALIDATE(unit, port) \
     51         if (IS_CPU_PORT(((unit)), (port)) || IS_LB_PORT(((unit)), (port)) || \
     52             SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), (port))) \
     53             return SOC_E_UNAVAIL;
     54 
     55 
     56 /* EP credit accumulation */
     57 typedef struct _soc_th_ep_credit_acc_s {
     58     uint8 line_rate;       /* Line-rate profile */
     59     uint8 oversub;         /* General profile */
     60 } _soc_th_ep_credit_acc_t;
     61 
     62 /* MMU EP Credit Thresholds */
     63 typedef struct _soc_th_mmu_ep_credit_s {
     64     uint8 base_cells;      /* Baseline cells */
     65     uint8 pfc_op_cells;    /* PFC Optimized cells */
     66 } _soc_th_mmu_ep_credit_t;
     67 
     68 /* EP Credits Outstanding */
     69 typedef struct _soc_th_egr_mmu_cell_credit_s {
     70     uint8 base_cells;      /* Baseline cells */
     71     uint8 pfc_op_cells;    /* PFC Optimized cells */
     72 } _soc_th_egr_mmu_cell_credit_t;
     73 
     74 /* Transmit Start Count */
     75 typedef struct _soc_th_egr_xmit_start_count_s {
     76     uint8 saf;             /* Store-And-Forward */
     77     uint8 oversub_2_1;     /* 2:1 Oversub */
     78     uint8 oversub_3_2;     /* 3:2 Oversub */
     79     uint8 line_rate;       /* Line-rate */
     80 } _soc_th_egr_xmit_start_count_t;
     81 
     82 /* ASF core config */
     83 typedef struct _soc_th_asf_core_cfg_s {
     84     int                              speed;
     85     uint8                            min_sp;                   /* Min. Src. Port Speed */
     86     uint8                            max_sp;                   /* Max. Src. Port Speed */
     87     uint8                            min_src_port_xmit_cnt;    /* MMU prebuffer */
     88     _soc_th_ep_credit_acc_t          ep_credit_acc;            /* EP Credit Accumulation */
     89     uint8                            encap_acc;                /* Encap Accumulation */
     90     uint8                            mmu_prebuf_depth;         /* Extra MMU Prebuffer depth */
     91     uint8                            fast_to_slow_acc;         /* Fast to slow CT Accumulation */
     92     _soc_th_mmu_ep_credit_t          mmu_ep_credit;            /* MMU EP credit thresholds */
     93     _soc_th_egr_mmu_cell_credit_t    egr_mmu_credit;           /* EGR MMU cell credits */
     94     _soc_th_egr_xmit_start_count_t   xmit_cnt_l2_latency;      /* L2 Latency Mode */
     95     _soc_th_egr_xmit_start_count_t   xmit_cnt_l3_full_latency; /* L3 & Full Latency Modes */
     96     /* NOTE: DON'T ALTER FIELD ORDER */
     97 } _soc_th_asf_core_cfg_t;
     98 #ifdef BCM_TOMAHAWK2_SUPPORT
     99 /* CT FIFO Threshold and Depth */
    100 typedef struct _soc_th2_ct_fifo_profile_s {
    101     uint8 line_rate;       /* Line-rate profile */
    102     uint8 oversub;         /* General profile */
    103 } _soc_th2_ct_fifo_profile_t;
    104 typedef struct _soc_th2_ct_fifo_s {
    105     _soc_th2_ct_fifo_profile_t ss;      /* Same-Speed */
    106     _soc_th2_ct_fifo_profile_t sf;      /* Slow-to-Fast */
    107     _soc_th2_ct_fifo_profile_t fs;      /* Fast-to-Slow */
    108 }_soc_th2_ct_fifo_t;
    109 
    110 /* Bubble MOP */
    111 typedef struct _soc_th2_mop_s {
    112     uint8 line_rate[SOC_SWITCH_BYPASS_MODE_LOW + 1];           /* Line-rate profile */
    113     uint8 oversub[SOC_SWITCH_BYPASS_MODE_LOW + 1];             /* Oversub profile */
    114 } _soc_th2_mop_t;
    115 
    116 /* EDB Prebuffer */
    117 typedef struct _soc_th2_edb_prebuf_profile_s {
    118     uint8 saf;                                  /* prebuffer for store-and-forward */
    119     uint8 ct[SOC_SWITCH_BYPASS_MODE_LOW + 1];   /* prebuffer for cut-through, latency none/L3/L2 */
    120 } _soc_th2_edb_prebuf_profile_t;
    121 typedef struct _soc_th2_edb_prebuf_s {
    122     _soc_th2_edb_prebuf_profile_t line_rate;
    123     _soc_th2_edb_prebuf_profile_t oversub_3_2;                 /* 3:2 Oversub */
    124     _soc_th2_edb_prebuf_profile_t oversub_2_1;                 /* 2:1 Oversub */
    125 } _soc_th2_edb_prebuf_t;
    126 
    127 /* MMU Credit Thresholds */
    128 typedef struct _soc_th2_mmu_credit_threshold_profile_s {
    129     uint8 lo;              /* MMU High Credit Threshold */
    130     uint8 hi;              /* MMU Low Credit Threshold */
    131 } _soc_th2_mmu_credit_threshold_profile_t;
    132 typedef struct _soc_th2_mmu_credit_threshold_s {
    133     _soc_th2_mmu_credit_threshold_profile_t lr_os_1_5;         /* line-rate and os ratio <= 3:2 */
    134     _soc_th2_mmu_credit_threshold_profile_t os_2_1;            /* os ratio > 3:2 */
    135 } _soc_th2_mmu_credit_threshold_t;
    136 
    137 /* IFSAF Threshold */
    138 typedef struct _soc_th2_ifsaf_threshold_s {
    139     uint8 ct;
    140     uint8 saf;
    141 }_soc_th2_ifsaf_threshold_t;
    142 
    143 /* ASF core config */
    144 typedef struct _soc_th2_asf_core_cfg_s {
    145     int                              speed;
    146     uint8                            min_sp;                   /* Min. Src. Port Speed */
    147     uint8                            max_sp;                   /* Max. Src. Port Speed */
    148     uint8                            mmu_prebuffer;            /* MMU prebuffer */
    149     _soc_th2_ct_fifo_t               ct_fifo_threshold;        /* Same-speed CT FIFO Threshold */
    150     _soc_th2_ct_fifo_t               ct_fifo_depth;            /* Same-speed CT FIFO Depth */
    151     uint8                            fast_to_slow_acc;         /* Fast to slow CT Accumulation */
    152     _soc_th2_mop_t                   mop_enable;               /* Bubble MOP enable */
    153     _soc_th2_edb_prebuf_t            edb_prebuffer;            /* EDB prebuffer */
    154     _soc_th2_mmu_credit_threshold_t  mmu_credit_threshold;     /* MMU Credit Threshold */
    155     _soc_th_egr_mmu_cell_credit_t    ep_credit;                /* EP Credit */
    156     _soc_th2_ifsaf_threshold_t       ifsaf_threshold;          /* IFSAF Threshold */
    157     /* NOTE: DON'T ALTER FIELD ORDER */
    158 } _soc_th2_asf_core_cfg_t;
    159 #endif
    160 
    161 /* ASF ctrl */
    162 typedef struct _soc_th_asf_ctrl_s {
    163     uint8                     init;
    164     pbmp_t                    asf_ports;
    165     pbmp_t                    pause_restore;
    166     pbmp_t                    asf_ss;
    167     pbmp_t                    asf_sf;
    168     pbmp_t                    asf_fs;
    169     soc_th_asf_mem_profile_e  asf_mem_profile;
    170     int                       latency;
    171 } _soc_th_asf_ctrl_t;
    172 
    173 #ifdef BCM_WARM_BOOT_SUPPORT
    174 /* ASF Warmboot */
    175 typedef struct _soc_th_asf_wb_s {
    176     int unit;
    177     _soc_th_asf_ctrl_t asf_ctrl;
    178 } _soc_th_asf_wb_t;
    179 #endif
    180 
    181 /* ASF Core Config Table  */
    182 static const _soc_th_asf_core_cfg_t
    183 _soc_th_asf_cfg_tbl[] = {
    184     {    -1,  1,  1,  0, {0,  0}, 0,  0, 0,  { 0,  0}, { 0,   0}, {18,  0,  0,  0}, {18,  0,  0,  0}},   /* SAF     */
    185     { 10000,  1, 10,  6, {2,  8}, 6, 10, 38, { 9,  8}, {13,  11}, {18, 51, 42, 30}, {18, 60, 48, 27}},   /* 10GE    */
    186     { 11000,  1, 10,  6, {2,  8}, 6, 10, 38, { 9,  8}, {13,  11}, {18, 51, 42, 30}, {18, 60, 48, 27}},   /* HG[11]  */
    187     { 20000,  3, 10,  7, {2,  8}, 7, 11, 29, {13, 12}, {18,  16}, {18, 63, 48, 30}, {18, 54, 42, 21}},   /* 20GE    */
    188     { 21000,  3, 10,  7, {2,  8}, 7, 11, 29, {13, 12}, {18,  16}, {18, 63, 48, 30}, {18, 54, 42, 21}},   /* HG[21]  */
    189     { 25000,  5, 10,  7, {3,  8}, 6, 11, 25, {12, 11}, {16,  15}, {18, 60, 48, 27}, {18, 51, 36, 18}},   /* 25GE    */
    190     { 27000,  5, 10,  7, {3,  8}, 6, 11, 25, {12, 11}, {16,  15}, {18, 60, 48, 27}, {18, 51, 36, 18}},   /* HG[27]  */
    191     { 40000,  7, 12,  7, {3, 12}, 8, 11, 29, {18, 14}, {25,  19}, {18, 57, 45, 24}, {18, 42, 30, 12}},   /* 40GE    */
    192     { 42000,  7, 12,  7, {3, 12}, 8, 11, 29, {18, 14}, {25,  19}, {18, 57, 45, 24}, {18, 42, 30, 12}},   /* HG[42]  */
    193     { 50000,  7, 12, 20, {1, 12}, 8, 31, 25, {20, 17}, {27,  23}, {18, 54, 42, 21}, {18, 33, 27, 12}},   /* 50GE    */
    194     { 53000,  7, 12,  7, {1, 12}, 8, 11, 25, {20, 17}, {27,  23}, {18, 54, 42, 21}, {18, 33, 27, 12}},   /* HG[53]  */
    195     {100000, 11, 12,  6, {3,  3}, 8, 10,  3, {33, 27}, {44,  36}, {18, 48, 36, 18}, {18, 33, 27, 15}},   /* 100GE   */
    196     {106000, 11, 12,  6, {3,  3}, 8, 10,  3, {33, 27}, {44,  36}, {18, 48, 36, 18}, {18, 33, 27, 15}}    /* HG[106] */
    197 };
    198 #ifdef BCM_TOMAHAWK2_SUPPORT
    199 static const _soc_th2_asf_core_cfg_t
    200 _soc_th2_asf_cfg_tbl[] = {
    201     {    -1,  0,  0,  0, {{0,  0}, { 0,  0}, {0,  0}}, {{0,  0}, { 0,  0}, { 0,  0}},  0, {{0, 0, 0}, {0, 0, 0}}, {{0, { 0,  0,  0}}, { 0, { 0,  0,  0}}, { 0, { 0,  0,  0}}}, {{0,  0}, { 0,  0}}, {10,  8}, {12, 12}},   /* SAF     */
    202     { 10000,  1, 10,  0, {{3, 10}, { 9, 16}, {3, 10}}, {{8, 19}, {14, 25}, {46, 57}}, 38, {{0, 0, 0}, {0, 0, 0}}, {{7, {29, 29, 29}}, {12, {40, 40, 40}}, {16, {48, 48, 48}}}, {{1,  5}, { 1,  7}}, {10,  9}, {12, 12}},   /* 10GE    */
    203     { 11000,  1, 10,  6, {{3, 10}, { 9, 16}, {3, 10}}, {{8, 19}, {14, 25}, {46, 57}}, 38, {{0, 0, 0}, {0, 0, 0}}, {{7, {29, 29, 29}}, {12, {40, 40, 40}}, {16, {48, 48, 48}}}, {{1,  5}, { 1,  7}}, {10,  9}, {12, 12}},   /* HG[11]  */
    204     { 20000,  3, 10,  0, {{3, 10}, {10, 17}, {3, 10}}, {{8, 22}, {15, 26}, {37, 51}}, 29, {{1, 1, 0}, {0, 0, 0}}, {{7, {28, 35, 30}}, {12, {41, 41, 41}}, {16, {49, 49, 49}}}, {{1,  7}, { 3, 12}}, {17, 11}, {12, 12}},   /* 20GE    */
    205     { 21000,  3, 10,  7, {{3, 10}, {10, 17}, {3, 10}}, {{8, 22}, {15, 26}, {37, 51}}, 29, {{1, 1, 0}, {0, 0, 0}}, {{7, {28, 35, 30}}, {12, {41, 41, 41}}, {16, {49, 49, 49}}}, {{1,  7}, { 3, 12}}, {17, 11}, {12, 12}},   /* HG[21]  */
    206     { 25000,  5, 10,  0, {{3, 10}, {10, 17}, {3, 10}}, {{8, 23}, {15, 26}, {33, 48}}, 25, {{1, 1, 0}, {1, 0, 0}}, {{7, {25, 35, 30}}, {12, {47, 41, 41}}, {16, {56, 49, 49}}}, {{2,  8}, { 3, 12}}, {17, 13}, {18, 18}},   /* 25GE    */
    207     { 27000,  5, 10,  7, {{3, 10}, {10, 17}, {3, 10}}, {{8, 23}, {15, 26}, {33, 48}}, 25, {{1, 1, 0}, {1, 0, 0}}, {{7, {25, 35, 30}}, {12, {47, 41, 41}}, {16, {56, 49, 49}}}, {{2,  8}, { 3, 12}}, {17, 13}, {18, 18}},   /* HG[27]  */
    208     { 40000,  7, 12,  0, {{3, 10}, {10, 17}, {3, 10}}, {{8, 25}, {15, 26}, {37, 54}}, 29, {{1, 1, 1}, {1, 1, 0}}, {{7, {13, 18, 38}}, {12, {52, 52, 44}}, {16, {44, 62, 52}}}, {{3, 12}, { 5, 21}}, {26, 17}, {12, 12}},   /* 40GE    */
    209     { 42000,  7, 12,  7, {{3, 10}, {10, 17}, {3, 10}}, {{8, 25}, {15, 26}, {37, 54}}, 29, {{1, 1, 1}, {1, 1, 0}}, {{7, {13, 18, 38}}, {12, {52, 52, 44}}, {16, {44, 62, 52}}}, {{3, 12}, { 5, 21}}, {26, 17}, {12, 12}},   /* HG[42]  */
    210     { 50000,  9, 12,  0, {{3, 10}, {10, 17}, {3, 10}}, {{8, 27}, {15, 26}, {33, 52}}, 25, {{1, 1, 1}, {1, 1, 1}}, {{7, {13, 14, 38}}, {12, {24, 52, 50}}, {16, {39, 62, 59}}}, {{3, 14}, { 6, 22}}, {28, 19}, {18, 18}},   /* 50GE    */
    211     { 53000,  9, 12,  7, {{3, 10}, {10, 17}, {3, 10}}, {{8, 27}, {15, 26}, {33, 52}}, 25, {{1, 1, 1}, {1, 1, 1}}, {{7, {13, 14, 38}}, {12, {24, 52, 50}}, {16, {39, 62, 59}}}, {{3, 14}, { 6, 22}}, {28, 19}, {18, 18}},   /* HG[53]  */
    212     {100000, 11, 12,  0, {{3, 10}, {11, 18}, {3, 10}}, {{8, 34}, {16, 27}, {11, 37}},  3, {{1, 1, 1}, {1, 1, 1}}, {{7, {13, 13, 28}}, {12, {24, 34, 64}}, {16, {31, 34, 74}}}, {{7, 25}, {11, 32}}, {48, 31}, {18, 18}},   /* 100GE   */
    213     {106000, 11, 12,  8, {{3, 10}, {11, 18}, {3, 10}}, {{8, 34}, {16, 27}, {11, 37}},  0, {{1, 1, 1}, {1, 1, 1}}, {{7, {13, 13, 28}}, {12, {24, 34, 64}}, {16, {31, 34, 74}}}, {{7, 25}, {11, 32}}, {48, 31}, {18, 18}}    /* HG[106] */
    214 };
    215 #endif
    216 
    217 /* ASF Core Config Table with FEC/CL91 enabled */
    218 static const _soc_th_asf_core_cfg_t
    219 _soc_th_asf_cfg_tbl_fec[] = {
    220     {    -1,  1,  1,  0, {0,  0}, 0,  0, 0,  { 0,  0}, { 0,   0}, {18,  0,  0,  0}, {18,  0,  0,  0}},   /* SAF     */
    221     { 10000,  1, 10,  6, {2,  8}, 6, 10, 38, { 9,  8}, {13,  11}, {18, 51, 42, 30}, {18, 60, 48, 27}},   /* 10GE    */
    222     { 11000,  1, 10,  6, {2,  8}, 6, 10, 38, { 9,  8}, {13,  11}, {18, 51, 42, 30}, {18, 60, 48, 27}},   /* HG[11]  */
    223     { 20000,  3, 10,  7, {2,  8}, 7, 11, 29, {13, 12}, {18,  16}, {18, 63, 48, 30}, {18, 54, 42, 21}},   /* 20GE    */
    224     { 21000,  3, 10,  7, {2,  8}, 7, 11, 29, {13, 12}, {18,  16}, {18, 63, 48, 30}, {18, 54, 42, 21}},   /* HG[21]  */
    225     { 25000,  5, 10,  7, {3,  8}, 6, 11, 25, {12, 12}, {16,  16}, {18, 95, 83, 62}, {18, 86, 71, 53}},   /* 25GE    */
    226     { 27000,  5, 10,  7, {3,  8}, 6, 11, 25, {12, 12}, {16,  16}, {18, 95, 83, 62}, {18, 86, 71, 53}},   /* HG[27]  */
    227     { 40000,  7, 12,  7, {3, 12}, 8, 11, 29, {18, 14}, {25,  19}, {18, 57, 45, 24}, {18, 42, 30, 12}},   /* 40GE    */
    228     { 42000,  7, 12,  7, {3, 12}, 8, 11, 29, {18, 14}, {25,  19}, {18, 57, 45, 24}, {18, 42, 30, 12}},   /* HG[42]  */
    229     { 50000,  7, 12, 20, {1, 12}, 8, 31, 25, {20, 17}, {30,  24}, {18, 94, 82, 61}, {18, 73, 67, 52}},   /* 50GE    */
    230     { 53000,  7, 12,  7, {1, 12}, 8, 11, 25, {20, 17}, {30,  24}, {18, 94, 82, 61}, {18, 73, 67, 52}},   /* HG[53]  */
    231     {100000, 11, 12,  6, {3,  3}, 8, 10,  3, {33, 27}, {44,  36}, {18, 48, 36, 18}, {18, 33, 27, 15}},   /* 100GE   */
    232     {106000, 11, 12,  6, {3,  3}, 8, 10,  3, {33, 27}, {44,  36}, {18, 48, 36, 18}, {18, 33, 27, 15}}    /* HG[106] */
    233 };
    234 #ifdef BCM_TOMAHAWK2_SUPPORT
    235 static const _soc_th2_asf_core_cfg_t
    236 _soc_th2_asf_cfg_tbl_fec[] = {
    237     {    -1,  0,  0,  0, {{0,  0}, { 0,  0}, {0,  0}}, {{ 0,  0}, { 0,  0}, { 0,  0}},  0, {{0, 0, 0}, {0, 0, 0}}, {{0, { 0,  0,  0}}, { 0, { 0,  0,  0}}, { 0, { 0,  0,  0}}}, {{0,  0}, { 0,  0}}, {10,  8}, {12, 12}},   /* SAF     */
    238     { 10000,  1, 10,  0, {{3, 10}, { 9, 16}, {3, 10}}, {{ 8, 19}, {14, 25}, {46, 57}}, 38, {{0, 0, 0}, {0, 0, 0}}, {{7, {29, 29, 29}}, {12, {40, 40, 40}}, {16, {48, 48, 48}}}, {{1,  5}, { 1,  7}}, {10,  9}, {12, 12}},   /* 10GE    */
    239     { 11000,  1, 10,  6, {{3, 10}, { 9, 16}, {3, 10}}, {{ 8, 19}, {14, 25}, {46, 57}}, 38, {{0, 0, 0}, {0, 0, 0}}, {{7, {29, 29, 29}}, {12, {40, 40, 40}}, {16, {48, 48, 48}}}, {{1,  5}, { 1,  7}}, {10,  9}, {12, 12}},   /* HG[11]  */
    240     { 20000,  3, 10,  0, {{3, 10}, {10, 17}, {3, 10}}, {{ 8, 22}, {15, 26}, {37, 51}}, 29, {{1, 1, 0}, {0, 0, 0}}, {{7, {28, 35, 30}}, {12, {41, 41, 41}}, {16, {49, 49, 49}}}, {{1,  7}, { 3, 12}}, {17, 11}, {12, 12}},   /* 20GE    */
    241     { 21000,  3, 10,  7, {{3, 10}, {10, 17}, {3, 10}}, {{ 8, 22}, {15, 26}, {37, 51}}, 29, {{1, 1, 0}, {0, 0, 0}}, {{7, {28, 35, 30}}, {12, {41, 41, 41}}, {16, {49, 49, 49}}}, {{1,  7}, { 3, 12}}, {17, 11}, {12, 12}},   /* HG[21]  */
    242     { 25000,  5, 10,  0, {{3, 12}, {13, 20}, {3, 12}}, {{10, 27}, {20, 31}, {35, 50}}, 25, {{0, 0, 0}, {0, 0, 0}}, {{7, {64, 64, 64}}, {12, {75, 75, 75}}, {16, {83, 83, 83}}}, {{3, 10}, { 2, 12}}, {18, 16}, {10, 18}},   /* 25GE    */
    243     { 27000,  5, 10,  7, {{3, 12}, {13, 20}, {3, 12}}, {{10, 27}, {20, 31}, {35, 50}}, 25, {{0, 0, 0}, {0, 0, 0}}, {{7, {64, 64, 64}}, {12, {75, 75, 75}}, {16, {83, 83, 83}}}, {{3, 10}, { 2, 12}}, {18, 16}, {10, 18}},   /* HG[27]  */
    244     { 40000,  7, 12,  0, {{3, 10}, {10, 17}, {3, 10}}, {{ 8, 25}, {15, 26}, {37, 54}}, 29, {{1, 1, 1}, {1, 1, 0}}, {{7, {13, 18, 38}}, {12, {52, 52, 44}}, {16, {44, 62, 52}}}, {{3, 12}, { 5, 21}}, {26, 17}, {12, 12}},   /* 40GE    */
    245     { 42000,  7, 12,  7, {{3, 10}, {10, 17}, {3, 10}}, {{ 8, 25}, {15, 26}, {37, 54}}, 29, {{1, 1, 1}, {1, 1, 0}}, {{7, {13, 18, 38}}, {12, {52, 52, 44}}, {16, {44, 62, 52}}}, {{3, 12}, { 5, 21}}, {26, 17}, {12, 12}},   /* HG[42]  */
    246     { 50000,  9, 12,  0, {{3, 12}, {13, 20}, {3, 12}}, {{ 8, 29}, {20, 31}, {35, 54}}, 25, {{1, 0, 0}, {0, 0, 0}}, {{7, {78, 72, 72}}, {12, {83, 83, 83}}, {16, {91, 91, 91}}}, {{4, 14}, { 7, 24}}, {32, 22}, { 6, 18}},   /* 50GE    */
    247     { 53000,  9, 12,  7, {{3, 12}, {13, 20}, {3, 12}}, {{ 8, 29}, {20, 31}, {35, 54}}, 25, {{1, 0, 0}, {0, 0, 0}}, {{7, {78, 72, 72}}, {12, {83, 83, 83}}, {16, {91, 91, 91}}}, {{4, 14}, { 7, 24}}, {32, 22}, { 6, 18}},   /* HG[53]  */
    248     {100000, 11, 12,  0, {{3, 12}, {11, 20}, {3, 12}}, {{ 8, 36}, {18, 29}, {11, 39}},  3, {{1, 1, 1}, {1, 1, 1}}, {{7, {13, 13, 28}}, {12, {24, 34, 64}}, {16, {31, 34, 74}}}, {{7, 25}, {11, 32}}, {48, 31}, { 6, 18}},   /* 100GE   */
    249     {106000, 11, 12,  8, {{3, 12}, {11, 20}, {3, 12}}, {{ 8, 36}, {18, 29}, {11, 39}},  0, {{1, 1, 1}, {1, 1, 1}}, {{7, {13, 13, 28}}, {12, {24, 34, 64}}, {16, {31, 34, 74}}}, {{7, 25}, {11, 32}}, {48, 31}, { 6, 18}}    /* HG[106] */
    250 };
    251 
    252 /* Use FEC cfg only */
    253 #define _SOC_TH2_ASF_CFG_TBL(unit, cl91)    (_soc_th2_asf_cfg_tbl_fec)
    254 #endif
    255 
    256 /* ASF Control */
    257 static _soc_th_asf_ctrl_t*
    258 _soc_th_asf_ctrl[SOC_MAX_NUM_DEVICES] = {NULL};
    259 
    260 /* ASF profile billboard */
    261 static const char *asf_profile_str[3] =
    262     {"removed of cut-thru capability",
    263      "capable of limited speed range cut-thru",
    264      "capable of extended speed range cut-thru"};
    265 
    266 /*  Linkscan callback routine                                               */
    267 /*  Reconfigures ASF settings on 25G/50G ports when FEC91/FEC108 is enabled */
    268 STATIC void
    269 soc_th_asf_linkscan_callback(int unit, soc_port_t port, bcm_port_info_t *info)
    270 {
    271     soc_th_asf_mode_e mode;
    272     int port_speed;
    273 
    274     if (info->linkstatus != BCM_PORT_LINK_STATUS_UP) {
    275         return;
    276     }
    277     port_speed = info->speed;
    278 
    279     if (_soc_th_asf_ctrl[unit] == NULL) {
    280         LOG_CLI((BSL_META_U(unit,
    281                             "!!! error: _soc_th_asf_ctrl[%d] is NULL pointer !!!\n"),
    282                  unit));
    283         return;
    284     }
    285 
    286     /* Reconfigure ASF settings for 25G/50G ports if CL91/CL108 is enabled on the ports */
    287     if (_soc_th_asf_ctrl[unit]->init) {
    288         if ((port_speed == 25000) || (port_speed == 27000) ||
    289             (port_speed == 50000) || (port_speed == 53000) ||
    290             (port_speed == 100000) || (port_speed == 106000)) {
    291                     if (SOC_E_NONE == soc_th_port_asf_mode_get(unit, port, port_speed, &mode)) {
    292                         soc_th_port_asf_mode_set(unit, port, port_speed, mode);
    293                     }
    294         }
    295     }
    296     return;
    297 }
    298 
    299 /*
    300  * Cut-through class encoding:
    301  *   0 - SAF
    302  *   1 - 10GE
    303  *   2 - HG[11]
    304  *   3 - 20GE
    305  *   4 - 21[HG}
    306  *   5 - 25GE
    307  *   6 - HG[27]
    308  *   7 - 40GE
    309  *   8 - HG[42]
    310  *   9 - 50GE
    311  *   10 - HG[53]
    312  *   11 - 100GE
    313  *   12 - HG[106]
    314  */
    315 STATIC int
    316 _soc_th_speed_to_ct_class_map(int speed)
    317 {
    318     int ct_class;
    319 
    320     if (1000 == speed) { /* 1G ports always in SAF, use same setting as 10G ports */
    321         speed = 10000;
    322     }
    323 
    324     for (ct_class = 0; ct_class <= 12; ct_class++) {
    325         if (_soc_th_asf_cfg_tbl[ct_class].speed == speed) {
    326             return ct_class;
    327         }
    328     }
    329 
    330     return SOC_E_PARAM;
    331 }
    332 
    333 /******************************************************************************
    334  * Name: _soc_th_port_asf_class_get                                           *
    335  * Description:                                                               *
    336  *     Get Cut-through class configured for the specified port                *
    337  * IN params:                                                                 *
    338  *     - Unit                                                                 *
    339  *     - Logical Port                                                         *
    340  *     - Port Speed                                                           *
    341  * OUT params:                                                                *
    342  *     - CT class                                                             *
    343  * Returns:                                                                   *
    344  *     - SOC_E_NONE on success                                                *
    345  *     - SOC_E_PARAM on invalid parameter                                     *
    346  */
    347 STATIC int
    348 _soc_th_port_asf_class_get(
    349     int             unit,
    350     soc_port_t      port,
    351     OUT int* const  class)
    352 {
    353     egr_ip_cut_thru_class_entry_t entry;
    354 
    355     if (!class) {
    356         return SOC_E_PARAM;
    357     }
    358 
    359     sal_memset(&entry, 0, sizeof(egr_ip_cut_thru_class_entry_t));
    360     SOC_IF_ERROR_RETURN
    361         (READ_EGR_IP_CUT_THRU_CLASSm(unit, MEM_BLOCK_ALL, port, &entry));
    362     *class = soc_mem_field32_get(unit, EGR_IP_CUT_THRU_CLASSm, &entry,
    363                                  CUT_THRU_CLASSf);
    364 
    365     return SOC_E_NONE;
    366 }
    367 
    368 /******************************************************************************
    369  * Name: _soc_th_port_asf_class_init                                          *
    370  * Description:                                                               *
    371  *     Initialize Cut-through class for the specified port                    *
    372  * IN params:                                                                 *
    373  *     - Unit                                                                 *
    374  *     - Logical Port                                                         *
    375  *     - CT class                                                             *
    376  * Returns:                                                                   *
    377  *     - SOC_E_NONE on success                                                *
    378  *     - SOC_E_PARAM on invalid parameter                                     *
    379  */
    380 STATIC int
    381 _soc_th_port_asf_class_init(
    382     int          unit,
    383     soc_port_t   port,
    384     int          ct_class)
    385 {
    386     egr_ip_cut_thru_class_entry_t entry;
    387 
    388     sal_memset(&entry, 0, sizeof(egr_ip_cut_thru_class_entry_t));
    389     soc_mem_field32_set(unit, EGR_IP_CUT_THRU_CLASSm, &entry,
    390                         CUT_THRU_CLASSf, ct_class);
    391     SOC_IF_ERROR_RETURN
    392         (WRITE_EGR_IP_CUT_THRU_CLASSm(unit, MEM_BLOCK_ALL, port, &entry));
    393 
    394     return SOC_E_NONE;
    395 }
    396 
    397 /******************************************************************************
    398  * Name: _soc_th_port_asf_port_cl91_get                                       *
    399  * Description:                                                               *
    400  *     Retreives the cl91 fec state for given port                            *
    401  * IN params:                                                                 *
    402  *     - Unit                                                                 *
    403  *     - Logical Port                                                         *
    404  * OUT params:                                                                *
    405  *     - port_cl91_state : 1 if FEC CL91 is enabled on the port               *
    406  * Returns:                                                                   *
    407  *     - SOC_E_NONE on success                                                *
    408  *     - SOC_E_PARAM on invalid parameter                                     *
    409  *     - SOC_E_INTERNAL on init/soc errors                                    *
    410  */
    411 STATIC int
    412 _soc_th_port_asf_port_cl91_get(
    413     int           unit,
    414     soc_port_t    port,
    415     uint32        *port_cl91_state)
    416 {
    417     int retVal;
    418 
    419     *port_cl91_state = 0;
    420 
    421     if ((!_soc_th_asf_ctrl[unit]) || 
    422         (IS_CPU_PORT(unit, port)) || (IS_LB_PORT(unit, port))) {
    423         return SOC_E_NONE;
    424     }
    425 
    426     retVal = bcm_esw_port_phy_control_get(unit, port, BCM_PORT_PHY_CONTROL_FORWARD_ERROR_CORRECTION_CL91,
    427         port_cl91_state);
    428 
    429     if ((retVal != SOC_E_NONE) && (retVal != SOC_E_INIT) && (retVal != SOC_E_UNAVAIL)) {
    430         return retVal;
    431     }
    432 
    433     return SOC_E_NONE;
    434 }
    435 
    436 
    437 #ifdef BCM_TOMAHAWK2_SUPPORT
    438 /******************************************************************************
    439  * Name: _soc_th2_port_asf_xmit_start_count_get                                *
    440  * Description:                                                               *
    441  *     Query or retrieve the XMIT Start Count for the specified source class  *
    442  *     of the port depending on the magic number passed in xmit_cnt           *
    443  * IN params:                                                                 *
    444  *     - Unit                                                                 *
    445  *     - Logical Port                                                         *
    446  *     - Source Port's Class                                                  *
    447  *     - Destination Port's CT Class                                          *
    448  *     - ASF Mode                                                             *
    449  * IN/OUT params:                                                             *
    450  *     - xmit_cnt : IN:  carries magic number for query / retrieve            *
    451  *     - xmit_cnt : OUT: contains a valid XMIT START COUNT for the            *
    452  *       source port class, on success                                        *
    453  * Returns:                                                                   *
    454  *     - SOC_E_NONE on success                                                *
    455  *     - SOC_E_PARAM on invalid parameter                                     *
    456  *     - SOC_E_INTERNAL on init/soc errors                                    *
    457  */
    458 STATIC int
    459 _soc_th2_port_asf_xmit_start_count_get(
    460     int                      unit,
    461     soc_port_t               port,
    462     int                      sc,
    463     int                      dc,
    464     soc_th_asf_mode_e        mode,
    465     IN_OUT uint8* const      xmit_cnt)
    466 {
    467     soc_info_t                  *si;
    468     egr_xmit_start_count_entry_t entry;
    469     int                          ovs_ratio, port_idx;
    470     soc_pbmp_t                   th_ports, line_rate_ports, ovs_3_2_ports;
    471     soc_port_t                   th_port;
    472     int                          latency = SOC_SWITCH_BYPASS_MODE_NONE;
    473     int                          speed;
    474     int                          class;
    475     int                          pipe;
    476     soc_mem_t                    config_mem = INVALIDm;
    477     uint32                       port_cl91_state;
    478     const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table;
    479 
    480     _SOC_TH_UNIT_VALIDATE(unit);
    481 
    482     if (!(si = &SOC_INFO(unit))) {
    483         return SOC_E_INTERNAL;
    484     }
    485 
    486     pipe = si->port_pipe[port];
    487     config_mem = SOC_MEM_UNIQUE_ACC(unit, EGR_XMIT_START_COUNTm)[pipe];
    488 
    489     if (_SOC_TH_ASF_MODE_CFG_UPDATE == mode) { /* translate to valid mode */
    490         /* reverse map speed class to speed, to surmount speed deficit */
    491         SOC_IF_ERROR_RETURN(_soc_th_port_asf_class_get(unit, port, &class));
    492         _SOC_TH_ASF_SPEED_CLASS_VALIDATE(class, 0);
    493         speed = _SOC_TH_CT_CLASS_TO_SPEED_MAP(class);
    494         SOC_IF_ERROR_RETURN(soc_th_port_asf_mode_get(unit, port, speed, &mode));
    495     }
    496     if (!xmit_cnt ||
    497         !((mode >= _SOC_TH_ASF_MODE_SAF) &&
    498           (mode <= _SOC_TH_ASF_MODE_FAST_TO_SLOW))) {
    499         return SOC_E_PARAM;
    500     }
    501     _SOC_TH_ASF_SPEED_CLASS_VALIDATE(sc, 0);
    502     _SOC_TH_ASF_SPEED_CLASS_VALIDATE(dc, 0);
    503 
    504     if (_SOC_TH_ASF_RETRV == *xmit_cnt) {
    505         *xmit_cnt = 0;
    506         port_idx = ((port % 34) * 16) + sc;
    507 
    508         sal_memset(&entry, 0, sizeof(egr_xmit_start_count_entry_t));
    509         SOC_IF_ERROR_RETURN(soc_mem_read(unit, config_mem, MEM_BLOCK_ALL,
    510                                                      port_idx, &entry));
    511         *xmit_cnt = soc_mem_field32_get(unit, config_mem,
    512                                         &entry, THRESHOLDf);
    513     } else if (_SOC_TH_ASF_QUERY == *xmit_cnt) {
    514         *xmit_cnt = 0;
    515         SOC_PBMP_CLEAR(th_ports);
    516         SOC_PBMP_ASSIGN(th_ports, PBMP_E_ALL(unit));
    517         SOC_PBMP_OR(th_ports, PBMP_HG_ALL(unit));
    518         SOC_PBMP_REMOVE(th_ports, PBMP_MANAGEMENT(unit));
    519         SOC_PBMP_CLEAR(line_rate_ports);
    520         SOC_PBMP_CLEAR(ovs_3_2_ports);
    521 
    522         PBMP_ITER(th_ports, th_port) {
    523             if (SOC_PBMP_MEMBER(si->oversub_pbm, th_port)) {
    524                 SOC_IF_ERROR_RETURN(
    525                     soc_th_port_oversub_ratio_get(unit, th_port, &ovs_ratio));
    526                 if (ovs_ratio <= 1500) { /* oversub ratio <= 3:2 */
    527                     SOC_PBMP_PORT_ADD(ovs_3_2_ports, th_port);
    528                 }
    529             }
    530             else { /* Line-rate */
    531                 SOC_PBMP_PORT_ADD(line_rate_ports, th_port);
    532             }
    533         }
    534 
    535         SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
    536         _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state);
    537 
    538         /* Get current switch latency mode & set xmit_cnt accordingly */
    539         SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency));
    540 
    541         /* if sc < dc, use SAF setting; else, use CT setting */
    542         if (SOC_PBMP_EQ(th_ports, line_rate_ports)) {
    543             *xmit_cnt = (sc < dc) ? 
    544                 _soc_th2_asf_cfg_table[dc].edb_prebuffer.line_rate.saf :
    545                 _soc_th2_asf_cfg_table[dc].edb_prebuffer.line_rate.ct[latency];
    546         } else if (SOC_PBMP_EQ(th_ports, ovs_3_2_ports)) {
    547             *xmit_cnt = (sc < dc) ? 
    548                 _soc_th2_asf_cfg_table[dc].edb_prebuffer.oversub_3_2.saf :
    549                 _soc_th2_asf_cfg_table[dc].edb_prebuffer.oversub_3_2.ct[latency];
    550         } else {
    551             *xmit_cnt = (sc < dc) ? 
    552                 _soc_th2_asf_cfg_table[dc].edb_prebuffer.oversub_2_1.saf :
    553                 _soc_th2_asf_cfg_table[dc].edb_prebuffer.oversub_2_1.ct[latency];
    554         }
    555 
    556     }
    557 
    558     return SOC_E_NONE;
    559 }
    560 
    561 /******************************************************************************
    562  * Name: _soc_th2_port_asf_mmu_prebuf_get                                      *
    563  * Description:                                                               *
    564  *     Query or retrieve MMU Prebuffer (Min Source Port XMIT Count) for the   *
    565  *     specified port depending on the magic number passed in mmu_prebuf      *
    566  * IN params:                                                                 *
    567  *     - Unit                                                                 *
    568  *     - Logical Port                                                         *
    569  *     - Port Speed                                                           *
    570  *     - ASF Mode                                                             *
    571  * IN/OUT params:                                                             *
    572  *     - mmu_prebuf : IN:  carries magic number for query / retrieve          *
    573  *     - mmu_prebuf : OUT: contains a valid Min Source Port XMIT Count on     *
    574  *       success                                                              *
    575  * Returns:                                                                   *
    576  *     - SOC_E_NONE on success                                                *
    577  *     - SOC_E_PARAM on invalid parameter                                     *
    578  *     - SOC_E_INTERNAL on init/soc errors                                    *
    579  */
    580 STATIC int
    581 _soc_th2_port_asf_mmu_prebuf_get(
    582     int                   unit,
    583     soc_port_t            port,
    584     int                   port_speed,
    585     int                   min_sp,
    586     IN_OUT uint8* const   mmu_prebuf)
    587 {
    588     uint32 rval;
    589     int    speed_encoding;
    590     uint32 port_cl91_state;
    591     const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table;
    592 
    593     _SOC_TH_UNIT_VALIDATE(unit);
    594     _SOC_TH_ASF_PORT_VALIDATE(unit, port);
    595     if (!mmu_prebuf) {
    596         return SOC_E_PARAM;
    597     }
    598 
    599     if (_SOC_TH_ASF_RETRV == *mmu_prebuf) {
    600         *mmu_prebuf = 0;
    601 
    602         if (!_soc_th_asf_ctrl[unit]->init) {
    603             return SOC_E_INTERNAL;
    604         }
    605 
    606         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
    607         *mmu_prebuf = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
    608                                         MIN_SRC_PORT_XMIT_CNTf);
    609     } else if (_SOC_TH_ASF_QUERY == *mmu_prebuf) {
    610         *mmu_prebuf = 0;
    611         speed_encoding = _soc_th_speed_to_ct_class_map(port_speed);
    612         _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1);
    613 
    614         SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
    615         _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state);
    616 
    617         *mmu_prebuf = 
    618             _soc_th2_asf_cfg_table[speed_encoding].mmu_prebuffer;
    619     }
    620 
    621     return SOC_E_NONE;
    622 }
    623 
    624 /******************************************************************************
    625  * Name: _soc_th2_port_asf_fifo_threshold_get                                  *
    626  * Description:                                                               *
    627  *     Query or retrieve FIFO Threshold for the specified port depending on   *
    628  *     the magic number passed in fifo_threshold                              *
    629  * IN params:                                                                 *
    630  *     - Unit                                                                 *
    631  *     - Logical Port                                                         *
    632  *     - Port Speed                                                           *
    633  *     - ASF Mode                                                             *
    634  *     - Min Source Port Speed                                                *
    635  * IN/OUT params:                                                             *
    636  *     - fifo_threshold : IN:  carries magic number for query / retrieve      *
    637  *     - fifo_threshold : OUT: contains a valid FIFO Threshold on success     *
    638  * Returns:                                                                   *
    639  *     - SOC_E_NONE on success                                                *
    640  *     - SOC_E_PARAM on invalid parameter                                     *
    641  *     - SOC_E_INTERNAL on init/soc errors                                    *
    642  */
    643 STATIC int
    644 _soc_th2_port_asf_fifo_threshold_get(
    645     int                   unit,
    646     soc_port_t            port,
    647     int                   port_speed,
    648     soc_th_asf_mode_e     mode,
    649     int                   min_sp,
    650     IN_OUT uint8* const   fifo_threshold)
    651 {
    652     uint32 rval;
    653     int    speed_encoding;
    654     uint32 oversub, port_cl91_state;
    655     const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table;
    656 
    657     _SOC_TH_UNIT_VALIDATE(unit);
    658     _SOC_TH_ASF_PORT_VALIDATE(unit, port);
    659     if (!fifo_threshold) {
    660         return SOC_E_PARAM;
    661     }
    662 
    663     if (_SOC_TH_ASF_RETRV == *fifo_threshold) {
    664         *fifo_threshold = 0;
    665 
    666         if (!_soc_th_asf_ctrl[unit]->init) {
    667             return SOC_E_INTERNAL;
    668         }
    669 
    670         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
    671         *fifo_threshold = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
    672                                             FIFO_THRESHOLDf);
    673     } else if (_SOC_TH_ASF_QUERY == *fifo_threshold) {
    674         speed_encoding = _soc_th_speed_to_ct_class_map(port_speed);
    675         _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1);
    676         oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0);
    677 
    678         SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
    679         _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state);
    680 
    681         switch(mode) {
    682             case _SOC_TH_ASF_MODE_SAME_SPEED:
    683                 *fifo_threshold = (oversub ?
    684                     _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_threshold.ss.oversub :
    685                     _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_threshold.ss.line_rate);
    686                 break;
    687 
    688             case _SOC_TH_ASF_MODE_SLOW_TO_FAST:
    689                 *fifo_threshold = (oversub ?
    690                     _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_threshold.sf.oversub :
    691                     _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_threshold.sf.line_rate);
    692                 break;
    693 
    694             case _SOC_TH_ASF_MODE_FAST_TO_SLOW:
    695                 *fifo_threshold = (oversub ?
    696                     _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_threshold.fs.oversub :
    697                     _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_threshold.fs.line_rate);
    698                 break;
    699 
    700             default:
    701                 *fifo_threshold = 0;
    702                 return SOC_E_PARAM;
    703         }
    704     }
    705 
    706     return SOC_E_NONE;
    707 }
    708 
    709 /******************************************************************************
    710  * Name: _soc_th2_port_asf_fifo_depth_get                                      *
    711  * Description:                                                               *
    712  *     Query or retrieve FIFO Depth for the specified port depending on the   *
    713  *     magic number passed in buf_sz                                          *
    714  * IN params:                                                                 *
    715  *     - Unit                                                                 *
    716  *     - Logical Port                                                         *
    717  *     - Port Speed                                                           *
    718  *     - ASF Mode                                                             *
    719  *     - Min Src Port Speed                                                   *
    720  * IN/OUT params:                                                             *
    721  *     - fifo_depth : IN:  carries magic number for query/retrieve            *
    722  *     - fifo_depth : OUT: contains a valid FIFO Depth on success             *
    723  * Returns:                                                                   *
    724  *     - SOC_E_NONE on success                                                *
    725  *     - SOC_E_PARAM on invalid parameter                                     *
    726  *     - SOC_E_INTERNAL on init/soc errors                                    *
    727  */
    728 STATIC int
    729 _soc_th2_port_asf_fifo_depth_get(
    730     int                   unit,
    731     soc_port_t            port,
    732     int                   port_speed,
    733     soc_th_asf_mode_e     mode,
    734     int                   min_sp,
    735     IN_OUT uint8* const   fifo_depth)
    736 {
    737     uint32 rval;
    738     int    speed_encoding;
    739     uint32 oversub, port_cl91_state;
    740     const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table;
    741 
    742     _SOC_TH_UNIT_VALIDATE(unit);
    743     _SOC_TH_ASF_PORT_VALIDATE(unit, port);
    744     if (!fifo_depth) {
    745         return SOC_E_PARAM;
    746     }
    747 
    748     if (_SOC_TH_ASF_RETRV == *fifo_depth) {
    749         if (!_soc_th_asf_ctrl[unit]->init) {
    750             return SOC_E_INTERNAL;
    751         }
    752 
    753         *fifo_depth = 0;
    754         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
    755         *fifo_depth = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
    756                                         FIFO_DEPTHf);
    757     } else if (_SOC_TH_ASF_QUERY == *fifo_depth) {
    758         speed_encoding = _soc_th_speed_to_ct_class_map(port_speed);
    759         _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1);
    760         oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0);
    761 
    762         SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
    763         _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state);
    764 
    765         switch(mode) {
    766             case _SOC_TH_ASF_MODE_SAME_SPEED:
    767                 *fifo_depth = (oversub ?
    768                     _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_depth.ss.oversub :
    769                     _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_depth.ss.line_rate);
    770                 break;
    771 
    772             case _SOC_TH_ASF_MODE_SLOW_TO_FAST:
    773                 *fifo_depth = (oversub ?
    774                     _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_depth.sf.oversub :
    775                     _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_depth.sf.line_rate);
    776                 break;
    777 
    778             case _SOC_TH_ASF_MODE_FAST_TO_SLOW:
    779                 *fifo_depth = (oversub ?
    780                     _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_depth.fs.oversub :
    781                     _soc_th2_asf_cfg_table[speed_encoding].ct_fifo_depth.fs.line_rate);
    782                 break;
    783 
    784             default:
    785                 *fifo_depth = 0;
    786                 return SOC_E_PARAM;
    787         }
    788     }
    789 
    790     return SOC_E_NONE;
    791 }
    792 
    793 #endif
    794 
    795 
    796 /******************************************************************************
    797  * Name: _soc_th_port_asf_xmit_start_count_get                                *
    798  * Description:                                                               *
    799  *     Query or retrieve the XMIT Start Count for the specified source class  *
    800  *     of the port depending on the magic number passed in xmit_cnt           *
    801  * IN params:                                                                 *
    802  *     - Unit                                                                 *
    803  *     - Logical Port                                                         *
    804  *     - Source Port's Class                                                  *
    805  *     - Destination Port's CT Class                                          *
    806  *     - ASF Mode                                                             *
    807  * IN/OUT params:                                                             *
    808  *     - xmit_cnt : IN:  carries magic number for query / retrieve            *
    809  *     - xmit_cnt : OUT: contains a valid XMIT START COUNT for the            *
    810  *       source port class, on success                                        *
    811  * Returns:                                                                   *
    812  *     - SOC_E_NONE on success                                                *
    813  *     - SOC_E_PARAM on invalid parameter                                     *
    814  *     - SOC_E_INTERNAL on init/soc errors                                    *
    815  */
    816 STATIC int
    817 _soc_th_port_asf_xmit_start_count_get(
    818     int                      unit,
    819     soc_port_t               port,
    820     int                      sc,
    821     int                      dc,
    822     soc_th_asf_mode_e        mode,
    823     IN_OUT uint8* const      xmit_cnt)
    824 {
    825     soc_info_t                  *si;
    826     egr_xmit_start_count_entry_t entry;
    827     int                          ovs_ratio, port_idx;
    828     int                          speed;
    829     int                          class;
    830     int                          pipe;
    831     soc_mem_t                    config_mem = INVALIDm;
    832     const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table;
    833     uint32 port_cl91_state;
    834 
    835     _SOC_TH_UNIT_VALIDATE(unit);
    836 
    837     if (!(si = &SOC_INFO(unit))) {
    838         return SOC_E_INTERNAL;
    839     }
    840 
    841     _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl;
    842 
    843     /* Get the FEC/CL91 state of the port to choose correct CT parameters */
    844     SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
    845 
    846     if (port_cl91_state) {
    847         _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec;
    848     }
    849 
    850     pipe = si->port_pipe[port];
    851     config_mem = SOC_MEM_UNIQUE_ACC(unit, EGR_XMIT_START_COUNTm)[pipe];
    852 
    853     if (_SOC_TH_ASF_MODE_CFG_UPDATE == mode) { /* translate to valid mode */
    854         /* reverse map speed class to speed, to surmount speed deficit */
    855         SOC_IF_ERROR_RETURN(_soc_th_port_asf_class_get(unit, port, &class));
    856         _SOC_TH_ASF_SPEED_CLASS_VALIDATE(class, 0);
    857         speed = _SOC_TH_CT_CLASS_TO_SPEED_MAP(class);
    858         SOC_IF_ERROR_RETURN(soc_th_port_asf_mode_get(unit, port, speed, &mode));
    859     }
    860     if (!xmit_cnt ||
    861         !((mode >= _SOC_TH_ASF_MODE_SAF) &&
    862           (mode <= _SOC_TH_ASF_MODE_FAST_TO_SLOW))) {
    863         return SOC_E_PARAM;
    864     }
    865     _SOC_TH_ASF_SPEED_CLASS_VALIDATE(sc, 0);
    866     _SOC_TH_ASF_SPEED_CLASS_VALIDATE(dc, 0);
    867 
    868     if (_SOC_TH_ASF_RETRV == *xmit_cnt) {
    869         *xmit_cnt = 0;
    870         port_idx = ((port % 34) * 16) + sc;
    871 
    872         sal_memset(&entry, 0, sizeof(egr_xmit_start_count_entry_t));
    873         SOC_IF_ERROR_RETURN(soc_mem_read(unit, config_mem, MEM_BLOCK_ALL,
    874                                                      port_idx, &entry));
    875         *xmit_cnt = soc_mem_field32_get(unit, config_mem,
    876                                         &entry, THRESHOLDf);
    877     } else if (_SOC_TH_ASF_QUERY == *xmit_cnt) {
    878         *xmit_cnt = 0;
    879 
    880         if ((_SOC_TH_ASF_MODE_SAF == mode) || (sc < dc)) {
    881             *xmit_cnt =  _soc_th_asf_cfg_table[dc].xmit_cnt_l2_latency.saf;
    882         } else if (SOC_PBMP_IS_NULL(si->oversub_pbm)) { /* ports are line-rate */
    883             if (_SOC_TH_ASF_MODE_FAST_TO_SLOW == mode) {  /* special case */
    884                 *xmit_cnt =
    885                     (SOC_SWITCH_BYPASS_MODE_LOW == _soc_th_asf_ctrl[unit]->latency) ?
    886                         _soc_th_asf_cfg_table[dc].xmit_cnt_l2_latency.oversub_2_1 :
    887                         _soc_th_asf_cfg_table[dc].xmit_cnt_l3_full_latency.oversub_2_1;
    888 
    889             } else {
    890                 *xmit_cnt =
    891                     (SOC_SWITCH_BYPASS_MODE_LOW == _soc_th_asf_ctrl[unit]->latency) ?
    892                         _soc_th_asf_cfg_table[dc].xmit_cnt_l2_latency.line_rate :
    893                         _soc_th_asf_cfg_table[dc].xmit_cnt_l3_full_latency.line_rate;
    894             }
    895          } else { /* oversub */
    896             SOC_IF_ERROR_RETURN(
    897                 soc_th_port_oversub_ratio_get(unit, port, &ovs_ratio));
    898             if (ovs_ratio <= 1560) { /* oversub ratio <= 3:2 */
    899                 *xmit_cnt =
    900                     (SOC_SWITCH_BYPASS_MODE_LOW == _soc_th_asf_ctrl[unit]->latency) ?
    901                         _soc_th_asf_cfg_table[dc].xmit_cnt_l2_latency.oversub_3_2 :
    902                         _soc_th_asf_cfg_table[dc].xmit_cnt_l3_full_latency.oversub_3_2;
    903             } else {
    904                 *xmit_cnt =
    905                     (SOC_SWITCH_BYPASS_MODE_LOW == _soc_th_asf_ctrl[unit]->latency) ?
    906                         _soc_th_asf_cfg_table[dc].xmit_cnt_l2_latency.oversub_2_1 :
    907                         _soc_th_asf_cfg_table[dc].xmit_cnt_l3_full_latency.oversub_2_1;
    908             }
    909         }
    910     }
    911 
    912     return SOC_E_NONE;
    913 }
    914 
    915 /******************************************************************************
    916  * Name: _soc_th_port_asf_speed_limits_get                                    *
    917  * Description:                                                               *
    918  *     Query or retrieve min & max source port speeds for the specified port  *
    919  *     depending on the magic number passed in min_sp &                       *
    920  *     max_sp                                                                 *
    921  * IN params:                                                                 *
    922  *     - Unit                                                                 *
    923  *     - Logical Port                                                         *
    924  *     - Port Speed                                                           *
    925  *     - ASF Mode                                                             *
    926  * IN/OUT params:                                                             *
    927  *     - min_sp : IN:  carries magic number for query / retrieve              *
    928  *     - min_sp : OUT: contains a valid min source port speed                 *
    929  *       on success                                                           *
    930  *     - max_sp : IN:  carries magic number for query / retrieve              *
    931  *     - max_sp : OUT: contains a valid max source port speed                 *
    932  *       on success                                                           *
    933  * Returns:                                                                   *
    934  *     - SOC_E_NONE on success                                                *
    935  *     - SOC_E_PARAM on invalid parameter                                     *
    936  *     - SOC_E_INTERNAL on init/soc errors                                    *
    937  */
    938 STATIC int
    939 _soc_th_port_asf_speed_limits_get(
    940     int                   unit,
    941     soc_port_t            port,
    942     int                   port_speed,
    943     soc_th_asf_mode_e     mode,
    944     IN_OUT uint8* const   min_sp,
    945     IN_OUT uint8* const   max_sp)
    946 {
    947     uint32 rval;
    948     int    speed_encoding;
    949     const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table;
    950     uint32 port_cl91_state;
    951 
    952     _SOC_TH_UNIT_VALIDATE(unit);
    953     _SOC_TH_ASF_PORT_VALIDATE(unit, port);
    954     if (!min_sp || !max_sp) {
    955         return SOC_E_PARAM;
    956     }
    957 
    958     _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl;
    959 
    960     /* Get the FEC/CL91 state of the port to choose correct CT parameters */
    961     SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
    962 
    963     if (port_cl91_state) {
    964         _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec;
    965     }
    966 
    967     if ((_SOC_TH_ASF_RETRV == *min_sp) &&
    968         (_SOC_TH_ASF_RETRV == *max_sp)) {
    969         *min_sp = *max_sp = 0;
    970         if (!_soc_th_asf_ctrl[unit]->init) {
    971             return SOC_E_INTERNAL;
    972         }
    973 
    974         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
    975 
    976         /* MIN_SRC_PORT_SPEED */
    977         *min_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
    978                                     MIN_SRC_PORT_SPEEDf);
    979         /* MAX_SRC_PORT_SPEED */
    980         *max_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
    981                                     MAX_SRC_PORT_SPEEDf);
    982     } else if ((_SOC_TH_ASF_QUERY == *min_sp) &&
    983                (_SOC_TH_ASF_QUERY == *max_sp)) {
    984         *min_sp = *max_sp = 0;
    985         speed_encoding = _soc_th_speed_to_ct_class_map(port_speed);
    986         _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0);
    987 
    988         switch(mode) {
    989             case _SOC_TH_ASF_MODE_SAF:
    990                 return SOC_E_NONE;
    991 
    992             case _SOC_TH_ASF_MODE_SAME_SPEED:
    993                 *min_sp = *max_sp = speed_encoding;
    994                 break;
    995 
    996             case _SOC_TH_ASF_MODE_SLOW_TO_FAST:
    997                 *min_sp = _soc_th_asf_cfg_table[speed_encoding].min_sp;
    998 #ifdef BCM_TOMAHAWK2_SUPPORT
    999                 /* 40G->50G will be removed from TH support as well,
   1000                    so this workaround will be deleted after TH ASF changes. */
   1001                 if (SOC_IS_TOMAHAWK2(unit)) {
   1002                     *min_sp = _soc_th2_asf_cfg_tbl[speed_encoding].min_sp;
   1003                 }
   1004 #endif
   1005                 *max_sp = speed_encoding;
   1006                 break;
   1007 
   1008             case _SOC_TH_ASF_MODE_FAST_TO_SLOW:
   1009                 if (_SOC_TH_ASF_MEM_PROFILE_SIMILAR ==
   1010                         _soc_th_asf_ctrl[unit]->asf_mem_profile) {
   1011                     if (speed_encoding % 2) { /* IEEE */
   1012                         /* HG counterpart */
   1013                         *max_sp = speed_encoding + 1;
   1014                     } else { /* HG */
   1015                         *max_sp = speed_encoding;
   1016                     }
   1017                 } else if (_SOC_TH_ASF_MEM_PROFILE_EXTREME ==
   1018                                _soc_th_asf_ctrl[unit]->asf_mem_profile) {
   1019                     *max_sp = _soc_th_asf_cfg_table[speed_encoding].max_sp;
   1020                 }
   1021                 *min_sp = speed_encoding;
   1022                 break;
   1023 
   1024             default:
   1025                 return SOC_E_PARAM;
   1026         }
   1027     }
   1028 
   1029     return SOC_E_NONE;
   1030 }
   1031 
   1032 /******************************************************************************
   1033  * Name: _soc_th_port_asf_mmu_prebuf_get                                      *
   1034  * Description:                                                               *
   1035  *     Query or retrieve MMU Prebuffer (Min Source Port XMIT Count) for the   *
   1036  *     specified port depending on the magic number passed in mmu_prebuf      *
   1037  * IN params:                                                                 *
   1038  *     - Unit                                                                 *
   1039  *     - Logical Port                                                         *
   1040  *     - Port Speed                                                           *
   1041  *     - ASF Mode                                                             *
   1042  * IN/OUT params:                                                             *
   1043  *     - mmu_prebuf : IN:  carries magic number for query / retrieve          *
   1044  *     - mmu_prebuf : OUT: contains a valid Min Source Port XMIT Count on     *
   1045  *       success                                                              *
   1046  * Returns:                                                                   *
   1047  *     - SOC_E_NONE on success                                                *
   1048  *     - SOC_E_PARAM on invalid parameter                                     *
   1049  *     - SOC_E_INTERNAL on init/soc errors                                    *
   1050  */
   1051 STATIC int
   1052 _soc_th_port_asf_mmu_prebuf_get(
   1053     int                   unit,
   1054     soc_port_t            port,
   1055     int                   port_speed,
   1056     int                   min_sp,
   1057     IN_OUT uint8* const   mmu_prebuf)
   1058 {
   1059     uint32 rval;
   1060     int    speed_encoding;
   1061     const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table;
   1062     uint32 port_cl91_state;
   1063 
   1064     _SOC_TH_UNIT_VALIDATE(unit);
   1065     _SOC_TH_ASF_PORT_VALIDATE(unit, port);
   1066     if (!mmu_prebuf) {
   1067         return SOC_E_PARAM;
   1068     }
   1069 
   1070     _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl;
   1071 
   1072     /* Get the FEC/CL91 state of the port to choose correct CT parameters */
   1073     SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
   1074 
   1075     if (port_cl91_state) {
   1076         _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec;
   1077     }
   1078 
   1079     if (_SOC_TH_ASF_RETRV == *mmu_prebuf) {
   1080         *mmu_prebuf = 0;
   1081 
   1082         if (!_soc_th_asf_ctrl[unit]->init) {
   1083             return SOC_E_INTERNAL;
   1084         }
   1085 
   1086         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   1087         *mmu_prebuf = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
   1088                                         MIN_SRC_PORT_XMIT_CNTf);
   1089     } else if (_SOC_TH_ASF_QUERY == *mmu_prebuf) {
   1090         *mmu_prebuf = 0;
   1091         speed_encoding = _soc_th_speed_to_ct_class_map(port_speed);
   1092         _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1);
   1093 
   1094         /* special cases : 50GE & HG[53] */
   1095         if ((9 == speed_encoding) || (10 == speed_encoding)) {
   1096             if ((7 == min_sp) || (8 == min_sp)) {  /* 40GE or HG[42] */
   1097                 *mmu_prebuf = 20;
   1098             } else if (9 == min_sp) {   /* HG[50] */
   1099                 *mmu_prebuf = 7;
   1100             }
   1101         } else {
   1102             *mmu_prebuf =
   1103                 _soc_th_asf_cfg_table[speed_encoding].min_src_port_xmit_cnt;
   1104         }
   1105     }
   1106 
   1107     return SOC_E_NONE;
   1108 }
   1109 
   1110 /******************************************************************************
   1111  * Name: _soc_th_port_asf_fifo_threshold_get                                  *
   1112  * Description:                                                               *
   1113  *     Query or retrieve FIFO Threshold for the specified port depending on   *
   1114  *     the magic number passed in fifo_threshold                              *
   1115  * IN params:                                                                 *
   1116  *     - Unit                                                                 *
   1117  *     - Logical Port                                                         *
   1118  *     - Port Speed                                                           *
   1119  *     - ASF Mode                                                             *
   1120  *     - Min Source Port Speed                                                *
   1121  * IN/OUT params:                                                             *
   1122  *     - fifo_threshold : IN:  carries magic number for query / retrieve      *
   1123  *     - fifo_threshold : OUT: contains a valid FIFO Threshold on success     *
   1124  * Returns:                                                                   *
   1125  *     - SOC_E_NONE on success                                                *
   1126  *     - SOC_E_PARAM on invalid parameter                                     *
   1127  *     - SOC_E_INTERNAL on init/soc errors                                    *
   1128  */
   1129 STATIC int
   1130 _soc_th_port_asf_fifo_threshold_get(
   1131     int                   unit,
   1132     soc_port_t            port,
   1133     int                   port_speed,
   1134     soc_th_asf_mode_e     mode,
   1135     int                   min_sp,
   1136     IN_OUT uint8* const   fifo_threshold)
   1137 {
   1138     uint32 rval;
   1139     int    ret, speed_encoding;
   1140     uint8  mmu_prebuf = 0, oversub;
   1141     uint32 port_cl91_state;
   1142 
   1143     _SOC_TH_UNIT_VALIDATE(unit);
   1144     _SOC_TH_ASF_PORT_VALIDATE(unit, port);
   1145     if (!fifo_threshold) {
   1146         return SOC_E_PARAM;
   1147     }
   1148 
   1149     if (_SOC_TH_ASF_RETRV == *fifo_threshold) {
   1150         *fifo_threshold = 0;
   1151 
   1152         if (!_soc_th_asf_ctrl[unit]->init) {
   1153             return SOC_E_INTERNAL;
   1154         }
   1155 
   1156         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   1157         *fifo_threshold = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
   1158                                             FIFO_THRESHOLDf);
   1159     } else if (_SOC_TH_ASF_QUERY == *fifo_threshold) {
   1160         *fifo_threshold = 0;
   1161         speed_encoding = _soc_th_speed_to_ct_class_map(port_speed);
   1162         _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1);
   1163 
   1164         oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0);
   1165 
   1166         /* Get port CL91 state */
   1167         SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
   1168 
   1169         switch(mode) {
   1170             case _SOC_TH_ASF_MODE_SAME_SPEED:
   1171                 if (oversub) {
   1172                     *fifo_threshold = 10;
   1173                 } else {
   1174                     *fifo_threshold = 3;
   1175                 }
   1176 /* Based on SV testing and feedback from arch, if CL91/CL108 is enabled    */
   1177 /* for same speed CT on 25G ports, fifo_threshold should be increased by 1 */
   1178 /* for 50G and 100G ports, fifo_threshold should be increased by 2         */
   1179                 if (port_cl91_state) {
   1180                     int speed;
   1181                     int class;
   1182 
   1183                     SOC_IF_ERROR_RETURN(_soc_th_port_asf_class_get(unit, port, &class));
   1184                     _SOC_TH_ASF_SPEED_CLASS_VALIDATE(class, 0);
   1185                     speed = _SOC_TH_CT_CLASS_TO_SPEED_MAP(class);
   1186 
   1187                     if ((speed == 25000) || (speed == 27000)) {
   1188                         *fifo_threshold = *fifo_threshold + 1;
   1189                     }
   1190                     else if ((speed == 50000) || (speed == 53000) ||
   1191                         (speed == 100000) || (speed == 106000)) {
   1192                         *fifo_threshold = *fifo_threshold + 2;
   1193                     }
   1194                 }
   1195                 break;
   1196             case _SOC_TH_ASF_MODE_FAST_TO_SLOW:
   1197                 if (oversub) {
   1198                     *fifo_threshold = 10;
   1199                 } else {
   1200                     *fifo_threshold = 3;
   1201                 }
   1202                 break;
   1203 
   1204             case _SOC_TH_ASF_MODE_SLOW_TO_FAST:
   1205                 if (oversub) {
   1206                     *fifo_threshold = 10;
   1207                 } else {
   1208                     *fifo_threshold = 3;
   1209                 }
   1210 
   1211                 mmu_prebuf = _SOC_TH_ASF_QUERY;
   1212                 ret = _soc_th_port_asf_mmu_prebuf_get(unit, port, port_speed,
   1213                                                       min_sp, &mmu_prebuf);
   1214                 if (SOC_E_NONE != ret) {
   1215                     return ret;
   1216                 }
   1217 
   1218                 *fifo_threshold += mmu_prebuf;
   1219                 break;
   1220 
   1221             default:
   1222                 return SOC_E_PARAM;
   1223         }
   1224     }
   1225 
   1226     return SOC_E_NONE;
   1227 }
   1228 
   1229 /******************************************************************************
   1230  * Name: _soc_th_port_asf_fifo_depth_get                                      *
   1231  * Description:                                                               *
   1232  *     Query or retrieve FIFO Depth for the specified port depending on the   *
   1233  *     magic number passed in buf_sz                                          *
   1234  * IN params:                                                                 *
   1235  *     - Unit                                                                 *
   1236  *     - Logical Port                                                         *
   1237  *     - Port Speed                                                           *
   1238  *     - ASF Mode                                                             *
   1239  *     - Min Src Port Speed                                                   *
   1240  * IN/OUT params:                                                             *
   1241  *     - fifo_depth : IN:  carries magic number for query/retrieve            *
   1242  *     - fifo_depth : OUT: contains a valid FIFO Depth on success             *
   1243  * Returns:                                                                   *
   1244  *     - SOC_E_NONE on success                                                *
   1245  *     - SOC_E_PARAM on invalid parameter                                     *
   1246  *     - SOC_E_INTERNAL on init/soc errors                                    *
   1247  */
   1248 STATIC int
   1249 _soc_th_port_asf_fifo_depth_get(
   1250     int                   unit,
   1251     soc_port_t            port,
   1252     int                   port_speed,
   1253     soc_th_asf_mode_e     mode,
   1254     int                   min_sp,
   1255     IN_OUT uint8* const   fifo_depth)
   1256 {
   1257     uint32 rval;
   1258     int    speed_encoding;
   1259     uint8  oversub, mmu_prebuf_depth = 0;
   1260     uint8  same_speed_ct_depth = 0, same_speed_ct_threshold = 0;
   1261     const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table;
   1262     uint32 port_cl91_state;
   1263 
   1264     _SOC_TH_UNIT_VALIDATE(unit);
   1265     _SOC_TH_ASF_PORT_VALIDATE(unit, port);
   1266     if (!fifo_depth) {
   1267         return SOC_E_PARAM;
   1268     }
   1269 
   1270     _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl;
   1271 
   1272     /* Get the FEC/CL91 state of the port to choose correct CT parameters */
   1273     SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
   1274 
   1275     if (port_cl91_state) {
   1276         _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec;
   1277     }
   1278 
   1279     if (_SOC_TH_ASF_RETRV == *fifo_depth) {
   1280         if (!_soc_th_asf_ctrl[unit]->init) {
   1281             return SOC_E_INTERNAL;
   1282         }
   1283 
   1284         *fifo_depth = 0;
   1285         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   1286         *fifo_depth = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
   1287                                         FIFO_DEPTHf);
   1288     } else if (_SOC_TH_ASF_QUERY == *fifo_depth) {
   1289         *fifo_depth = 0;
   1290         speed_encoding = _soc_th_speed_to_ct_class_map(port_speed);
   1291         _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1);
   1292 
   1293         oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0);
   1294 
   1295         switch(mode) {
   1296             case _SOC_TH_ASF_MODE_SAME_SPEED:
   1297                 if (oversub) {
   1298                     *fifo_depth =
   1299                     (_soc_th_asf_cfg_table[speed_encoding].ep_credit_acc.oversub +
   1300                      _soc_th_asf_cfg_table[speed_encoding].encap_acc + 17);
   1301                 } else {
   1302                     *fifo_depth =
   1303                     (_soc_th_asf_cfg_table[speed_encoding].ep_credit_acc.line_rate + 6);
   1304                 }
   1305 /* Based on SV testing and feedback from arch, if CL91/CL108 is enabled */
   1306 /* for same speed CT on 25G ports, fifo_depth should be increased by 2  */
   1307 /* for 50G/100G, fifo_depth should be increased by 4.                   */
   1308                 if (port_cl91_state) {
   1309                    int speed;
   1310                    int class;
   1311 
   1312                    SOC_IF_ERROR_RETURN(_soc_th_port_asf_class_get(unit, port, &class));
   1313                    _SOC_TH_ASF_SPEED_CLASS_VALIDATE(class, 0);
   1314                    speed = _SOC_TH_CT_CLASS_TO_SPEED_MAP(class);
   1315 
   1316                     if ((speed == 25000) || (speed == 27000)) {
   1317                         *fifo_depth = *fifo_depth + 2;
   1318                     } else if ((speed == 50000) || (speed == 53000) ||
   1319                         (speed == 100000) || (speed == 106000)) {
   1320                         *fifo_depth = *fifo_depth + 4;
   1321                     }
   1322                 }
   1323                 break;
   1324 
   1325             case _SOC_TH_ASF_MODE_SLOW_TO_FAST:
   1326                 if (oversub) {
   1327                     *fifo_depth =
   1328                     (_soc_th_asf_cfg_table[speed_encoding].ep_credit_acc.oversub +
   1329                      _soc_th_asf_cfg_table[speed_encoding].encap_acc + 17);
   1330                 } else {
   1331                     *fifo_depth =
   1332                     (_soc_th_asf_cfg_table[speed_encoding].ep_credit_acc.line_rate + 6);
   1333                 }
   1334 
   1335                 /* Extra MMU prebuffer depth */
   1336                 if ((9 == speed_encoding) || (10 == speed_encoding)) { /* special cases : 50GE & HG[53] */
   1337                     if ((7 == min_sp) || (8 == min_sp)) {  /* 40GE or HG[42] */
   1338                         mmu_prebuf_depth = 31;
   1339                     } else if (9 == min_sp) {   /* HG[50] */
   1340                         mmu_prebuf_depth = 11;
   1341                     }
   1342                 } else {
   1343                     mmu_prebuf_depth = _soc_th_asf_cfg_table[speed_encoding].mmu_prebuf_depth;
   1344                 }
   1345 
   1346                 *fifo_depth += mmu_prebuf_depth;
   1347                 break;
   1348 
   1349             case _SOC_TH_ASF_MODE_FAST_TO_SLOW:
   1350                 if (oversub) {
   1351                     same_speed_ct_depth =
   1352                     (_soc_th_asf_cfg_table[speed_encoding].ep_credit_acc.oversub +
   1353                      _soc_th_asf_cfg_table[speed_encoding].encap_acc + 17);
   1354 
   1355                     same_speed_ct_threshold = 10;
   1356                 } else {
   1357                     same_speed_ct_depth =
   1358                     (_soc_th_asf_cfg_table[speed_encoding].ep_credit_acc.line_rate + 6);
   1359 
   1360                     same_speed_ct_threshold = 3;
   1361                 }
   1362 
   1363                 *fifo_depth =
   1364                  MIN((same_speed_ct_depth + _soc_th_asf_cfg_table[speed_encoding].fast_to_slow_acc),
   1365                      (same_speed_ct_threshold + 46) );
   1366                 break;
   1367 
   1368             default:
   1369                 return SOC_E_PARAM;
   1370         }
   1371     }
   1372 
   1373     return SOC_E_NONE;
   1374 }
   1375 
   1376 /******************************************************************************
   1377  * Name: _soc_th_asf_obm_ca_fifo_thresh_set                                   *
   1378  * Description:                                                               *
   1379  *     Configure Cell Assembly CT FIFO threshold for all OBM and Pipe         *
   1380  *     instances.                                                             *
   1381  * IN params:                                                                 *
   1382  *     - Unit                                                                 *
   1383  *     - Logical Port                                                         *
   1384  *     - Cell Assembly CT Threshold                                           *
   1385  * Returns:                                                                   *
   1386  *     - SOC_E_NONE on success                                                *
   1387  *     - SOC_E_* on internal errors                                           *
   1388  */
   1389 STATIC int
   1390 _soc_th_asf_obm_ca_fifo_thresh_set(
   1391     int     unit,
   1392     soc_port_t    port,
   1393     uint8   ca_thresh)
   1394 {
   1395     int  obm, pipe, clport;
   1396     int port_block_base, phy_port, lane;
   1397     uint32 rval;
   1398     soc_info_t *si = &SOC_INFO(unit);
   1399     uint32 thresh_field[4] = { THRESHOLD0f, THRESHOLD1f,
   1400            THRESHOLD2f, THRESHOLD3f };
   1401     uint32 port_ct_sel_field[4] = { PORT0_CT_SELf, PORT1_CT_SELf,
   1402            PORT2_CT_SELf, PORT3_CT_SELf };
   1403     uint32 idb_obm_ca_ct_ctrl_reg[][4] = {
   1404            {IDB_OBM0_CA_CT_CONTROL_PIPE0r, IDB_OBM0_CA_CT_CONTROL_PIPE1r,
   1405             IDB_OBM0_CA_CT_CONTROL_PIPE2r, IDB_OBM0_CA_CT_CONTROL_PIPE3r},
   1406            {IDB_OBM1_CA_CT_CONTROL_PIPE0r, IDB_OBM1_CA_CT_CONTROL_PIPE1r,
   1407             IDB_OBM1_CA_CT_CONTROL_PIPE2r, IDB_OBM1_CA_CT_CONTROL_PIPE3r},
   1408            {IDB_OBM2_CA_CT_CONTROL_PIPE0r, IDB_OBM2_CA_CT_CONTROL_PIPE1r,
   1409             IDB_OBM2_CA_CT_CONTROL_PIPE2r, IDB_OBM2_CA_CT_CONTROL_PIPE3r},
   1410            {IDB_OBM3_CA_CT_CONTROL_PIPE0r, IDB_OBM3_CA_CT_CONTROL_PIPE1r,
   1411             IDB_OBM3_CA_CT_CONTROL_PIPE2r, IDB_OBM3_CA_CT_CONTROL_PIPE3r},
   1412            {IDB_OBM4_CA_CT_CONTROL_PIPE0r, IDB_OBM4_CA_CT_CONTROL_PIPE1r,
   1413             IDB_OBM4_CA_CT_CONTROL_PIPE2r, IDB_OBM4_CA_CT_CONTROL_PIPE3r},
   1414            {IDB_OBM5_CA_CT_CONTROL_PIPE0r, IDB_OBM5_CA_CT_CONTROL_PIPE1r,
   1415             IDB_OBM5_CA_CT_CONTROL_PIPE2r, IDB_OBM5_CA_CT_CONTROL_PIPE3r},
   1416            {IDB_OBM6_CA_CT_CONTROL_PIPE0r, IDB_OBM6_CA_CT_CONTROL_PIPE1r,
   1417             IDB_OBM6_CA_CT_CONTROL_PIPE2r, IDB_OBM6_CA_CT_CONTROL_PIPE3r},
   1418            {IDB_OBM7_CA_CT_CONTROL_PIPE0r, IDB_OBM7_CA_CT_CONTROL_PIPE1r,
   1419             IDB_OBM7_CA_CT_CONTROL_PIPE2r, IDB_OBM7_CA_CT_CONTROL_PIPE3r},
   1420 #ifdef BCM_TOMAHAWK2_SUPPORT
   1421            {IDB_OBM8_CA_CT_CONTROL_PIPE0r, IDB_OBM8_CA_CT_CONTROL_PIPE1r,
   1422             IDB_OBM8_CA_CT_CONTROL_PIPE2r, IDB_OBM8_CA_CT_CONTROL_PIPE3r},
   1423            {IDB_OBM9_CA_CT_CONTROL_PIPE0r, IDB_OBM9_CA_CT_CONTROL_PIPE1r,
   1424             IDB_OBM9_CA_CT_CONTROL_PIPE2r, IDB_OBM9_CA_CT_CONTROL_PIPE3r},
   1425            {IDB_OBM10_CA_CT_CONTROL_PIPE0r, IDB_OBM10_CA_CT_CONTROL_PIPE1r,
   1426             IDB_OBM10_CA_CT_CONTROL_PIPE2r, IDB_OBM10_CA_CT_CONTROL_PIPE3r},
   1427            {IDB_OBM11_CA_CT_CONTROL_PIPE0r, IDB_OBM11_CA_CT_CONTROL_PIPE1r,
   1428             IDB_OBM11_CA_CT_CONTROL_PIPE2r, IDB_OBM11_CA_CT_CONTROL_PIPE3r},
   1429            {IDB_OBM12_CA_CT_CONTROL_PIPE0r, IDB_OBM12_CA_CT_CONTROL_PIPE1r,
   1430             IDB_OBM12_CA_CT_CONTROL_PIPE2r, IDB_OBM12_CA_CT_CONTROL_PIPE3r},
   1431            {IDB_OBM13_CA_CT_CONTROL_PIPE0r, IDB_OBM13_CA_CT_CONTROL_PIPE1r,
   1432             IDB_OBM13_CA_CT_CONTROL_PIPE2r, IDB_OBM13_CA_CT_CONTROL_PIPE3r},
   1433            {IDB_OBM14_CA_CT_CONTROL_PIPE0r, IDB_OBM14_CA_CT_CONTROL_PIPE1r,
   1434             IDB_OBM14_CA_CT_CONTROL_PIPE2r, IDB_OBM14_CA_CT_CONTROL_PIPE3r},
   1435            {IDB_OBM15_CA_CT_CONTROL_PIPE0r, IDB_OBM15_CA_CT_CONTROL_PIPE1r,
   1436             IDB_OBM15_CA_CT_CONTROL_PIPE2r, IDB_OBM15_CA_CT_CONTROL_PIPE3r},
   1437 #endif
   1438         };
   1439 
   1440     _SOC_TH_UNIT_VALIDATE(unit);
   1441 
   1442     /* Get lane, pipe & obm */
   1443     phy_port = si->port_l2p_mapping[port];
   1444     port_block_base = PORT_BLOCK_BASE_PORT(port);
   1445     lane = phy_port - port_block_base;
   1446     pipe = si->port_pipe[port];
   1447     clport = si->port_serdes[port];
   1448     if (SOC_IS_TOMAHAWK(unit)) {
   1449         /* obm number is reversed (mirrored) in odd pipe */
   1450         obm = pipe & 1 ? 7 - (clport & 7) : clport & 7;
   1451     } else {
   1452         obm = clport & 15;
   1453     }
   1454 
   1455     SOC_IF_ERROR_RETURN(
   1456         soc_reg32_get(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe],
   1457                       REG_PORT_ANY, 0, &rval));
   1458 
   1459     soc_reg_field_set(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe], &rval,
   1460               port_ct_sel_field[lane], lane);
   1461     soc_reg_field_set(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe], &rval,
   1462               thresh_field[lane], ca_thresh);
   1463 
   1464     SOC_IF_ERROR_RETURN(
   1465         soc_reg32_set(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe],
   1466                               REG_PORT_ANY, 0, rval));
   1467 
   1468     return SOC_E_NONE;
   1469 }
   1470 
   1471 /******************************************************************************
   1472  * Name: _soc_th_asf_obm_bubble_mop_set                                       *
   1473  * Description:                                                               *
   1474  *     Configure Bubble MOP for all OBM and Pipe Instances                    *
   1475  * IN params:                                                                 *
   1476  *     - Unit                                                                 *
   1477  *     - Logical Port                                                         *
   1478  *     - Bubble MOP Flag                                                      *
   1479  * Returns:                                                                   *
   1480  *     - SOC_E_NONE on success                                                *
   1481  *     - SOC_E_* on internal errors                                           *
   1482  */
   1483 STATIC int
   1484 _soc_th_asf_obm_bubble_mop_set(
   1485     int     unit,
   1486     soc_port_t    port,
   1487     uint8   bubble_mop_disable)
   1488 {
   1489     int  obm, pipe, clport;
   1490     int port_block_base, phy_port, lane;
   1491     uint32 rval;
   1492     soc_info_t *si = &SOC_INFO(unit);
   1493     uint32 port_field[4] = {
   1494             PORT0_BUBBLE_MOP_DISABLEf, PORT1_BUBBLE_MOP_DISABLEf,
   1495             PORT2_BUBBLE_MOP_DISABLEf, PORT3_BUBBLE_MOP_DISABLEf };
   1496     uint32 idb_obm_ctrl_reg[][4] = {
   1497            {IDB_OBM0_CONTROL_PIPE0r, IDB_OBM0_CONTROL_PIPE1r,
   1498             IDB_OBM0_CONTROL_PIPE2r, IDB_OBM0_CONTROL_PIPE3r},
   1499            {IDB_OBM1_CONTROL_PIPE0r, IDB_OBM1_CONTROL_PIPE1r,
   1500             IDB_OBM1_CONTROL_PIPE2r, IDB_OBM1_CONTROL_PIPE3r},
   1501            {IDB_OBM2_CONTROL_PIPE0r, IDB_OBM2_CONTROL_PIPE1r,
   1502             IDB_OBM2_CONTROL_PIPE2r, IDB_OBM2_CONTROL_PIPE3r},
   1503            {IDB_OBM3_CONTROL_PIPE0r, IDB_OBM3_CONTROL_PIPE1r,
   1504             IDB_OBM3_CONTROL_PIPE2r, IDB_OBM3_CONTROL_PIPE3r},
   1505            {IDB_OBM4_CONTROL_PIPE0r, IDB_OBM4_CONTROL_PIPE1r,
   1506             IDB_OBM4_CONTROL_PIPE2r, IDB_OBM4_CONTROL_PIPE3r},
   1507            {IDB_OBM5_CONTROL_PIPE0r, IDB_OBM5_CONTROL_PIPE1r,
   1508             IDB_OBM5_CONTROL_PIPE2r, IDB_OBM5_CONTROL_PIPE3r},
   1509            {IDB_OBM6_CONTROL_PIPE0r, IDB_OBM6_CONTROL_PIPE1r,
   1510             IDB_OBM6_CONTROL_PIPE2r, IDB_OBM6_CONTROL_PIPE3r},
   1511            {IDB_OBM7_CONTROL_PIPE0r, IDB_OBM7_CONTROL_PIPE1r,
   1512             IDB_OBM7_CONTROL_PIPE2r, IDB_OBM7_CONTROL_PIPE3r},
   1513 #ifdef BCM_TOMAHAWK2_SUPPORT
   1514            {IDB_OBM8_CONTROL_PIPE0r, IDB_OBM8_CONTROL_PIPE1r,
   1515             IDB_OBM8_CONTROL_PIPE2r, IDB_OBM8_CONTROL_PIPE3r},
   1516            {IDB_OBM9_CONTROL_PIPE0r, IDB_OBM9_CONTROL_PIPE1r,
   1517             IDB_OBM9_CONTROL_PIPE2r, IDB_OBM9_CONTROL_PIPE3r},
   1518            {IDB_OBM10_CONTROL_PIPE0r, IDB_OBM10_CONTROL_PIPE1r,
   1519             IDB_OBM10_CONTROL_PIPE2r, IDB_OBM10_CONTROL_PIPE3r},
   1520            {IDB_OBM11_CONTROL_PIPE0r, IDB_OBM11_CONTROL_PIPE1r,
   1521             IDB_OBM11_CONTROL_PIPE2r, IDB_OBM11_CONTROL_PIPE3r},
   1522            {IDB_OBM12_CONTROL_PIPE0r, IDB_OBM12_CONTROL_PIPE1r,
   1523             IDB_OBM12_CONTROL_PIPE2r, IDB_OBM12_CONTROL_PIPE3r},
   1524            {IDB_OBM13_CONTROL_PIPE0r, IDB_OBM13_CONTROL_PIPE1r,
   1525             IDB_OBM13_CONTROL_PIPE2r, IDB_OBM13_CONTROL_PIPE3r},
   1526            {IDB_OBM14_CONTROL_PIPE0r, IDB_OBM14_CONTROL_PIPE1r,
   1527             IDB_OBM14_CONTROL_PIPE2r, IDB_OBM14_CONTROL_PIPE3r},
   1528            {IDB_OBM15_CONTROL_PIPE0r, IDB_OBM15_CONTROL_PIPE1r,
   1529             IDB_OBM15_CONTROL_PIPE2r, IDB_OBM15_CONTROL_PIPE3r},
   1530 #endif
   1531         };
   1532 
   1533     _SOC_TH_UNIT_VALIDATE(unit);
   1534 
   1535     /* Get lane, pipe & obm */
   1536     phy_port = si->port_l2p_mapping[port];
   1537     port_block_base = PORT_BLOCK_BASE_PORT(port);
   1538     lane = phy_port - port_block_base;
   1539     pipe = si->port_pipe[port];
   1540     clport = si->port_serdes[port];
   1541     if (SOC_IS_TOMAHAWK(unit)) {
   1542         /* obm number is reversed (mirrored) in odd pipe */
   1543         obm = pipe & 1 ? 7 - (clport & 7) : clport & 7;
   1544     } else {
   1545         obm = clport & 15;
   1546     }
   1547 
   1548     /* BubbleMOP - At present only L3 & Full Latency Mode supported */
   1549     SOC_IF_ERROR_RETURN(
   1550         soc_reg32_get(unit, idb_obm_ctrl_reg[obm][pipe],
   1551                       REG_PORT_ANY, 0, &rval));
   1552 
   1553     soc_reg_field_set(unit, idb_obm_ctrl_reg[obm][pipe], &rval,
   1554                       port_field[lane], bubble_mop_disable);
   1555 
   1556     SOC_IF_ERROR_RETURN(
   1557         soc_reg32_set(unit, idb_obm_ctrl_reg[obm][pipe], REG_PORT_ANY,
   1558                       0, rval));
   1559 
   1560     return SOC_E_NONE;
   1561 }
   1562 
   1563 /******************************************************************************
   1564  * Name: _soc_th_asf_obm_ct_thresh_ok_set                                     *
   1565  * Description:                                                               *
   1566  *     Configure IDB OBM CT FIFO threshold OK for all OBM and Pipe            *
   1567  *     instances.                                                             *
   1568  * IN params:                                                                 *
   1569  *     - Unit                                                                 *
   1570  *     - Logical Port                                                         *
   1571  *     - CT allowed if usage is less than or eq threshold                     *
   1572  * Returns:                                                                   *
   1573  *     - SOC_E_NONE on success                                                *
   1574  *     - SOC_E_* on internal errors                                           *
   1575  */
   1576 STATIC int
   1577 _soc_th_asf_obm_ct_thresh_ok_set(
   1578     int     unit,
   1579     soc_port_t    port,
   1580     uint32   ct_ok_thresh)
   1581 {
   1582     int  obm, pipe, clport;
   1583     int port_block_base, phy_port, lane;
   1584     uint64 rval64;
   1585     soc_info_t *si = &SOC_INFO(unit);
   1586     uint32 idb_obm_ct_thresh_reg[][4] = {
   1587            {IDB_OBM0_CT_THRESHOLD_PIPE0r, IDB_OBM0_CT_THRESHOLD_PIPE1r,
   1588             IDB_OBM0_CT_THRESHOLD_PIPE2r, IDB_OBM0_CT_THRESHOLD_PIPE3r},
   1589            {IDB_OBM1_CT_THRESHOLD_PIPE0r, IDB_OBM1_CT_THRESHOLD_PIPE1r,
   1590             IDB_OBM1_CT_THRESHOLD_PIPE2r, IDB_OBM1_CT_THRESHOLD_PIPE3r},
   1591            {IDB_OBM2_CT_THRESHOLD_PIPE0r, IDB_OBM2_CT_THRESHOLD_PIPE1r,
   1592             IDB_OBM2_CT_THRESHOLD_PIPE2r, IDB_OBM2_CT_THRESHOLD_PIPE3r},
   1593            {IDB_OBM3_CT_THRESHOLD_PIPE0r, IDB_OBM3_CT_THRESHOLD_PIPE1r,
   1594             IDB_OBM3_CT_THRESHOLD_PIPE2r, IDB_OBM3_CT_THRESHOLD_PIPE3r},
   1595            {IDB_OBM4_CT_THRESHOLD_PIPE0r, IDB_OBM4_CT_THRESHOLD_PIPE1r,
   1596             IDB_OBM4_CT_THRESHOLD_PIPE2r, IDB_OBM4_CT_THRESHOLD_PIPE3r},
   1597            {IDB_OBM5_CT_THRESHOLD_PIPE0r, IDB_OBM5_CT_THRESHOLD_PIPE1r,
   1598             IDB_OBM5_CT_THRESHOLD_PIPE2r, IDB_OBM5_CT_THRESHOLD_PIPE3r},
   1599            {IDB_OBM6_CT_THRESHOLD_PIPE0r, IDB_OBM6_CT_THRESHOLD_PIPE1r,
   1600             IDB_OBM6_CT_THRESHOLD_PIPE2r, IDB_OBM6_CT_THRESHOLD_PIPE3r},
   1601            {IDB_OBM7_CT_THRESHOLD_PIPE0r, IDB_OBM7_CT_THRESHOLD_PIPE1r,
   1602             IDB_OBM7_CT_THRESHOLD_PIPE2r, IDB_OBM7_CT_THRESHOLD_PIPE3r},
   1603 #ifdef BCM_TOMAHAWK2_SUPPORT
   1604            {IDB_OBM8_CT_THRESHOLD_PIPE0r, IDB_OBM8_CT_THRESHOLD_PIPE1r,
   1605             IDB_OBM8_CT_THRESHOLD_PIPE2r, IDB_OBM8_CT_THRESHOLD_PIPE3r},
   1606            {IDB_OBM9_CT_THRESHOLD_PIPE0r, IDB_OBM9_CT_THRESHOLD_PIPE1r,
   1607             IDB_OBM9_CT_THRESHOLD_PIPE2r, IDB_OBM9_CT_THRESHOLD_PIPE3r},
   1608            {IDB_OBM10_CT_THRESHOLD_PIPE0r, IDB_OBM10_CT_THRESHOLD_PIPE1r,
   1609             IDB_OBM10_CT_THRESHOLD_PIPE2r, IDB_OBM10_CT_THRESHOLD_PIPE3r},
   1610            {IDB_OBM11_CT_THRESHOLD_PIPE0r, IDB_OBM11_CT_THRESHOLD_PIPE1r,
   1611             IDB_OBM11_CT_THRESHOLD_PIPE2r, IDB_OBM11_CT_THRESHOLD_PIPE3r},
   1612            {IDB_OBM12_CT_THRESHOLD_PIPE0r, IDB_OBM12_CT_THRESHOLD_PIPE1r,
   1613             IDB_OBM12_CT_THRESHOLD_PIPE2r, IDB_OBM12_CT_THRESHOLD_PIPE3r},
   1614            {IDB_OBM13_CT_THRESHOLD_PIPE0r, IDB_OBM13_CT_THRESHOLD_PIPE1r,
   1615             IDB_OBM13_CT_THRESHOLD_PIPE2r, IDB_OBM13_CT_THRESHOLD_PIPE3r},
   1616            {IDB_OBM14_CT_THRESHOLD_PIPE0r, IDB_OBM14_CT_THRESHOLD_PIPE1r,
   1617             IDB_OBM14_CT_THRESHOLD_PIPE2r, IDB_OBM14_CT_THRESHOLD_PIPE3r},
   1618            {IDB_OBM15_CT_THRESHOLD_PIPE0r, IDB_OBM15_CT_THRESHOLD_PIPE1r,
   1619             IDB_OBM15_CT_THRESHOLD_PIPE2r, IDB_OBM15_CT_THRESHOLD_PIPE3r},
   1620 #endif
   1621         };
   1622 
   1623     _SOC_TH_UNIT_VALIDATE(unit);
   1624 
   1625     /* Get lane, pipe & obm */
   1626     phy_port = si->port_l2p_mapping[port];
   1627     port_block_base = PORT_BLOCK_BASE_PORT(port);
   1628     lane = phy_port - port_block_base;
   1629     pipe = si->port_pipe[port];
   1630     clport = si->port_serdes[port];
   1631     if (SOC_IS_TOMAHAWK(unit)) {
   1632         /* obm number is reversed (mirrored) in odd pipe */
   1633         obm = pipe & 1 ? 7 - (clport & 7) : clport & 7;
   1634     } else {
   1635         obm = clport & 15;
   1636     }
   1637 
   1638     SOC_IF_ERROR_RETURN(
   1639         soc_reg64_get(unit, idb_obm_ct_thresh_reg[obm][pipe],
   1640                       REG_PORT_ANY, lane, &rval64));
   1641 
   1642     soc_reg64_field32_set(unit, idb_obm_ct_thresh_reg[obm][pipe], &rval64,
   1643               CUT_THROUGH_OKf, ct_ok_thresh);
   1644 
   1645     SOC_IF_ERROR_RETURN(
   1646         soc_reg64_set(unit, idb_obm_ct_thresh_reg[obm][pipe],
   1647                               REG_PORT_ANY, lane, rval64));
   1648 
   1649     return SOC_E_NONE;
   1650 }
   1651 
   1652 /******************************************************************************
   1653  * Name: _soc_th_asf_force_saf_config_set                                     *
   1654  * Description:                                                               *
   1655  *     Configure IDB_OBM_FORCE_SAF_CONFIG register for all OBM and Pipe       *
   1656  *     instances. Also configure IDB_FORCE_SAF_CONFIG register.               *
   1657  * IN params:                                                                 *
   1658  *     - Unit                                                                 *
   1659  *     - Logical Port                                                         *
   1660  * Returns:                                                                   *
   1661  *     - SOC_E_NONE on success                                                *
   1662  *     - SOC_E_* on internal errors                                           *
   1663  */
   1664 STATIC int
   1665 _soc_th_asf_force_saf_config_set(
   1666     int     unit,
   1667     soc_port_t    port,
   1668     soc_th_asf_mode_e   mode)
   1669 {
   1670     int  obm, pipe, clport;
   1671     int port_block_base, phy_port, lane;
   1672     uint32 port_cl91_state;
   1673     int speed;
   1674     int class;
   1675     uint32 rval;
   1676     uint32 field_a;
   1677     uint32 field_b;
   1678     uint32 field_c;
   1679     soc_info_t *si = &SOC_INFO(unit);
   1680     uint32 idb_obm_force_saf_config_reg[][4] = {
   1681            {IDB_OBM0_DBG_A_PIPE0r, IDB_OBM0_DBG_A_PIPE1r,
   1682             IDB_OBM0_DBG_A_PIPE2r, IDB_OBM0_DBG_A_PIPE3r},
   1683            {IDB_OBM1_DBG_A_PIPE0r, IDB_OBM1_DBG_A_PIPE1r,
   1684             IDB_OBM1_DBG_A_PIPE2r, IDB_OBM1_DBG_A_PIPE3r},
   1685            {IDB_OBM2_DBG_A_PIPE0r, IDB_OBM2_DBG_A_PIPE1r,
   1686             IDB_OBM2_DBG_A_PIPE2r, IDB_OBM2_DBG_A_PIPE3r},
   1687            {IDB_OBM3_DBG_A_PIPE0r, IDB_OBM3_DBG_A_PIPE1r,
   1688             IDB_OBM3_DBG_A_PIPE2r, IDB_OBM3_DBG_A_PIPE3r},
   1689            {IDB_OBM4_DBG_A_PIPE0r, IDB_OBM4_DBG_A_PIPE1r,
   1690             IDB_OBM4_DBG_A_PIPE2r, IDB_OBM4_DBG_A_PIPE3r},
   1691            {IDB_OBM5_DBG_A_PIPE0r, IDB_OBM5_DBG_A_PIPE1r,
   1692             IDB_OBM5_DBG_A_PIPE2r, IDB_OBM5_DBG_A_PIPE3r},
   1693            {IDB_OBM6_DBG_A_PIPE0r, IDB_OBM6_DBG_A_PIPE1r,
   1694             IDB_OBM6_DBG_A_PIPE2r, IDB_OBM6_DBG_A_PIPE3r},
   1695            {IDB_OBM7_DBG_A_PIPE0r, IDB_OBM7_DBG_A_PIPE1r,
   1696             IDB_OBM7_DBG_A_PIPE2r, IDB_OBM7_DBG_A_PIPE3r},
   1697 #ifdef BCM_TOMAHAWK2_SUPPORT
   1698            {IDB_OBM8_DBG_A_PIPE0r, IDB_OBM8_DBG_A_PIPE1r,
   1699             IDB_OBM8_DBG_A_PIPE2r, IDB_OBM8_DBG_A_PIPE3r},
   1700            {IDB_OBM9_DBG_A_PIPE0r, IDB_OBM9_DBG_A_PIPE1r,
   1701             IDB_OBM9_DBG_A_PIPE2r, IDB_OBM9_DBG_A_PIPE3r},
   1702            {IDB_OBM10_DBG_A_PIPE0r, IDB_OBM10_DBG_A_PIPE1r,
   1703             IDB_OBM10_DBG_A_PIPE2r, IDB_OBM10_DBG_A_PIPE3r},
   1704            {IDB_OBM11_DBG_A_PIPE0r, IDB_OBM11_DBG_A_PIPE1r,
   1705             IDB_OBM11_DBG_A_PIPE2r, IDB_OBM11_DBG_A_PIPE3r},
   1706            {IDB_OBM12_DBG_A_PIPE0r, IDB_OBM12_DBG_A_PIPE1r,
   1707             IDB_OBM12_DBG_A_PIPE2r, IDB_OBM12_DBG_A_PIPE3r},
   1708            {IDB_OBM13_DBG_A_PIPE0r, IDB_OBM13_DBG_A_PIPE1r,
   1709             IDB_OBM13_DBG_A_PIPE2r, IDB_OBM13_DBG_A_PIPE3r},
   1710            {IDB_OBM14_DBG_A_PIPE0r, IDB_OBM14_DBG_A_PIPE1r,
   1711             IDB_OBM14_DBG_A_PIPE2r, IDB_OBM14_DBG_A_PIPE3r},
   1712            {IDB_OBM15_DBG_A_PIPE0r, IDB_OBM15_DBG_A_PIPE1r,
   1713             IDB_OBM15_DBG_A_PIPE2r, IDB_OBM15_DBG_A_PIPE3r},
   1714 #endif
   1715         };
   1716 
   1717     uint32 idb_force_saf_config_reg[4] = {
   1718            IDB_DBG_B_PIPE0r, IDB_DBG_B_PIPE1r,
   1719            IDB_DBG_B_PIPE2r, IDB_DBG_B_PIPE3r};
   1720 
   1721     _SOC_TH_UNIT_VALIDATE(unit);
   1722 
   1723     /* Get the FEC/CL91 state of the port to choose correct CT parameters */
   1724     SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
   1725 
   1726     SOC_IF_ERROR_RETURN(_soc_th_port_asf_class_get(unit, port, &class));
   1727     _SOC_TH_ASF_SPEED_CLASS_VALIDATE(class, 0);
   1728     speed = _SOC_TH_CT_CLASS_TO_SPEED_MAP(class);
   1729 
   1730     field_a = 1;
   1731     field_b = 1;
   1732     field_c = 4;    /* Default value for speeds other than 25G/50G/100G */
   1733 
   1734     if ((speed == 25000) || (speed == 27000)) {
   1735         if (port_cl91_state) {
   1736             field_c = 10;
   1737         }
   1738         else {
   1739             field_c = 6;
   1740         }
   1741     }
   1742     else if ((speed == 50000) || (speed == 53000) ||
   1743             (speed == 100000) || (speed == 106000)) {
   1744             field_c= 6;
   1745     }
   1746 
   1747     /* Get lane, pipe & obm */
   1748     phy_port = si->port_l2p_mapping[port];
   1749     port_block_base = PORT_BLOCK_BASE_PORT(port);
   1750     lane = phy_port - port_block_base;
   1751     pipe = si->port_pipe[port];
   1752     clport = si->port_serdes[port];
   1753     if (SOC_IS_TOMAHAWK(unit)) {
   1754         /* obm number is reversed (mirrored) in odd pipe */
   1755         obm = pipe & 1 ? 7 - (clport & 7) : clport & 7;
   1756     } else {
   1757         obm = clport & 15;
   1758     }
   1759 
   1760 #ifdef BCM_TOMAHAWK2_SUPPORT
   1761     if (SOC_IS_TOMAHAWK2(unit)) {
   1762         const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table;
   1763         _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state);
   1764         field_c = (mode == _SOC_TH_ASF_MODE_SAF) ?
   1765             _soc_th2_asf_cfg_table[class].ifsaf_threshold.saf :
   1766             _soc_th2_asf_cfg_table[class].ifsaf_threshold.ct;
   1767 
   1768         /* TH2 only need adjust FIELD_C, others are set in _soc_tomahawk2_ing_fsaf_init */
   1769         SOC_IF_ERROR_RETURN(
   1770             soc_reg32_get(unit, idb_obm_force_saf_config_reg[obm][pipe],
   1771                           REG_PORT_ANY, lane, &rval));
   1772         soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval,
   1773                   FIELD_Cf, field_c);
   1774         SOC_IF_ERROR_RETURN(
   1775             soc_reg32_set(unit, idb_obm_force_saf_config_reg[obm][pipe],
   1776                                   REG_PORT_ANY, lane, rval));
   1777 
   1778         return SOC_E_NONE;
   1779     }
   1780 #endif
   1781 
   1782     SOC_IF_ERROR_RETURN(
   1783         soc_reg32_get(unit, idb_obm_force_saf_config_reg[obm][pipe],
   1784                       REG_PORT_ANY, lane, &rval));
   1785 
   1786     soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval,
   1787               FIELD_Af, field_a);
   1788     soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval,
   1789               FIELD_Bf, field_b);
   1790     soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval,
   1791               FIELD_Cf, field_c);
   1792 
   1793     SOC_IF_ERROR_RETURN(
   1794         soc_reg32_set(unit, idb_obm_force_saf_config_reg[obm][pipe],
   1795                               REG_PORT_ANY, lane, rval));
   1796 
   1797     /* Now setup the IDB_FORCE_SAF_CONFIG register */
   1798     switch (si->frequency) {
   1799     case 850: field_a = 1700;
   1800         break;
   1801     case 765: field_a = 1532;
   1802         break;
   1803     case 672: field_a = 1344;
   1804         break;
   1805     case 645: field_a = 1290;
   1806         break;
   1807     case 545: field_a = 1090;
   1808         break;
   1809     default:
   1810         break;
   1811     }
   1812 
   1813     SOC_IF_ERROR_RETURN(
   1814         soc_reg32_get(unit, idb_force_saf_config_reg[pipe],
   1815                       REG_PORT_ANY, 0, &rval));
   1816     soc_reg_field_set(unit, idb_force_saf_config_reg[pipe], &rval,
   1817               FIELD_Af, field_a);
   1818     SOC_IF_ERROR_RETURN(
   1819         soc_reg32_set(unit, idb_force_saf_config_reg[pipe],
   1820                               REG_PORT_ANY, 0, rval));
   1821 
   1822     return SOC_E_NONE;
   1823 }
   1824 
   1825 int
   1826 soc_th_port_asf_valid(
   1827     int unit,
   1828     soc_port_t port)
   1829 {
   1830     if (IS_CPU_PORT(((unit)), (port)) || IS_LB_PORT(((unit)), (port)) || \
   1831         SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), (port))) {
   1832         return FALSE;
   1833     } else {
   1834         return TRUE;
   1835     }
   1836 }
   1837 
   1838 /*************************************
   1839  * Init Start Routine                *
   1840  *    - Allocates ASF Ctrl structure *
   1841  *      for the given unit           *
   1842  */
   1843 int
   1844 soc_th_asf_init_start(int unit)
   1845 {
   1846     _SOC_TH_UNIT_VALIDATE(unit);
   1847 
   1848     if (!(_soc_th_asf_ctrl[unit] =
   1849               sal_alloc(sizeof(_soc_th_asf_ctrl_t), "TH ASF Ctrl Area"))) {
   1850         return SOC_E_MEMORY;
   1851     }
   1852 
   1853     sal_memset(_soc_th_asf_ctrl[unit], 0, sizeof(_soc_th_asf_ctrl_t));
   1854 
   1855     /* Get current switch latency mode */
   1856     SOC_IF_ERROR_RETURN(
   1857         soc_th_latency_get(unit, &_soc_th_asf_ctrl[unit]->latency));
   1858 
   1859     /* ASF_MEM_PROFILE */
   1860     _soc_th_asf_ctrl[unit]->asf_mem_profile =
   1861         soc_property_get(unit, spn_ASF_MEM_PROFILE,
   1862                          _SOC_TH_ASF_MEM_PROFILE_SIMILAR);
   1863     if (!((_soc_th_asf_ctrl[unit]->asf_mem_profile >= 0) &&
   1864           (_soc_th_asf_ctrl[unit]->asf_mem_profile < 3))) {
   1865         _soc_th_asf_ctrl[unit]->asf_mem_profile = 2;
   1866     }
   1867 
   1868     return SOC_E_NONE;
   1869 }
   1870 
   1871 int
   1872 soc_asf_register_linkscan_cb(int unit)
   1873 {
   1874     int retVal;
   1875 
   1876     /* Register linkscan callback routine */
   1877     retVal = bcm_esw_linkscan_register(unit, soc_th_asf_linkscan_callback);
   1878     return retVal;
   1879 }
   1880 
   1881 /************************
   1882  * Init Complete Marker *
   1883  */
   1884 int
   1885 soc_th_asf_init_done(int unit)
   1886 {
   1887     _SOC_TH_UNIT_VALIDATE(unit);
   1888 
   1889     if (_soc_th_asf_ctrl[unit]) {
   1890         _soc_th_asf_ctrl[unit]->init = 1;
   1891         LOG_DEBUG(BSL_LS_SOC_INIT,
   1892                     (BSL_META_U(unit, "*** unit %d: ports %s\n"), unit,
   1893                      asf_profile_str[_soc_th_asf_ctrl[unit]->asf_mem_profile]));
   1894         return SOC_E_NONE;
   1895     } else {
   1896         return SOC_E_INTERNAL;
   1897     }
   1898 }
   1899 
   1900 /******************************************************************************
   1901  * Name: soc_th_port_asf_init                                                 *
   1902  * Description:                                                               *
   1903  *     Initialize ASF primitives for the specified port                       *
   1904  * IN params:                                                                 *
   1905  *     - Unit                                                                 *
   1906  *     - Logical Port                                                         *
   1907  *     - Port Speed                                                           *
   1908  *     - ASF Mode                                                             *
   1909  * Returns:                                                                   *
   1910  *     - SOC_E_NONE on success                                                *
   1911  *     - SOC_E_PARAM on invalid parameter                                     *
   1912  *     - SOC_E_INIT on init/soc errors                                        *
   1913  */
   1914 int
   1915 soc_th_port_asf_init(
   1916     int                 unit,
   1917     soc_port_t          port,
   1918     int                 speed,
   1919     soc_th_asf_mode_e   mode)
   1920 {
   1921     int speed_encoding;
   1922 
   1923     _SOC_TH_UNIT_VALIDATE(unit);
   1924     if (SOC_E_PARAM == (speed_encoding = _soc_th_speed_to_ct_class_map(speed))) {
   1925         /* port on a speed unsupported by CT - will resort to SAF */
   1926         speed_encoding = 0;
   1927     }
   1928 
   1929     SOC_IF_ERROR_RETURN(soc_th_port_asf_mode_set(unit, port, speed, mode));
   1930 
   1931     return SOC_E_NONE;
   1932 }
   1933 
   1934 /************************
   1935  * Init Start Routine   *
   1936  */
   1937 int
   1938 soc_th_asf_deinit(int unit)
   1939 {
   1940     _SOC_TH_UNIT_VALIDATE(unit);
   1941     /* Unregister linkscan callback routine */
   1942     bcm_esw_linkscan_unregister(unit, soc_th_asf_linkscan_callback);
   1943 
   1944     if (_soc_th_asf_ctrl[unit]) {
   1945         sal_free(_soc_th_asf_ctrl[unit]);
   1946         _soc_th_asf_ctrl[unit] = NULL;
   1947     }
   1948 
   1949     return SOC_E_NONE;
   1950 }
   1951 
   1952 /******************************************************************************
   1953  * Name: _soc_th_port_asf_xmit_start_count_set                                *
   1954  * Description:                                                               *
   1955  *     Initialize XMIT START COUNT memory for all the source class for the    *
   1956  *     specified port                                                         *
   1957  * IN params:                                                                 *
   1958  *     - Unit                                                                 *
   1959  *     - Logical Port                                                         *
   1960  *     - Port Speed                                                           *
   1961  *     - ASF Mode                                                             *
   1962  *     - Extra cells (if any, to be added to xmit start count)                *
   1963  * Returns:                                                                   *
   1964  *     - SOC_E_NONE on success                                                *
   1965  *     - SOC_E_PARAM on invalid parameter                                     *
   1966  */
   1967 int
   1968 soc_th_port_asf_xmit_start_count_set(
   1969     int                  unit,
   1970     soc_port_t           port,
   1971     int                  port_speed,
   1972     soc_th_asf_mode_e    mode,
   1973     uint8                extra_cells)
   1974 {
   1975     egr_xmit_start_count_entry_t entry;
   1976     soc_info_t *si = &SOC_INFO(unit);
   1977     uint8                        xmit_cnt = 0;
   1978     int                          rv, src_class, dst_class = 0, port_idx;
   1979     int                          pipe;
   1980     soc_mem_t                    config_mem = INVALIDm;
   1981 
   1982     if (!((mode >= _SOC_TH_ASF_MODE_SAF) &&
   1983           (mode <= _SOC_TH_ASF_MODE_CFG_UPDATE))) {
   1984         return SOC_E_PARAM;
   1985     }
   1986 
   1987     if (_SOC_TH_ASF_MODE_CFG_UPDATE != mode) {
   1988         if (SOC_E_PARAM == (dst_class = _soc_th_speed_to_ct_class_map(port_speed))) {
   1989             /* port on a speed unsupported by CT - will resort to SAF */
   1990             dst_class = 0;
   1991         }
   1992     }
   1993 
   1994     sal_memset(&entry, 0, sizeof(egr_xmit_start_count_entry_t));
   1995 
   1996     pipe = si->port_pipe[port];
   1997     config_mem = SOC_MEM_UNIQUE_ACC(unit, EGR_XMIT_START_COUNTm)[pipe];
   1998 
   1999     for (src_class = 0; src_class < 13; src_class++) {
   2000         if (_SOC_TH_ASF_MODE_CFG_UPDATE == mode) {
   2001             xmit_cnt = _SOC_TH_ASF_RETRV;
   2002         } else {
   2003             xmit_cnt = _SOC_TH_ASF_QUERY;
   2004         }
   2005 
   2006 #ifdef BCM_TOMAHAWK2_SUPPORT
   2007         if (SOC_IS_TOMAHAWK2(unit)) {
   2008             rv = _soc_th2_port_asf_xmit_start_count_get(unit, port, src_class,
   2009                                                    dst_class, mode, &xmit_cnt);
   2010         } else
   2011 #endif
   2012         {
   2013             rv = _soc_th_port_asf_xmit_start_count_get(unit, port, src_class,
   2014                                                    dst_class, mode, &xmit_cnt);
   2015         }
   2016         if (SOC_FAILURE(rv)) {
   2017             if (SOC_E_UNAVAIL == rv) {
   2018                 xmit_cnt = 18;
   2019             } else {
   2020                 return rv;
   2021             }
   2022         }
   2023 
   2024         xmit_cnt += extra_cells;
   2025 
   2026         port_idx = ((port % 34) * 16) + src_class;
   2027 
   2028         soc_mem_field32_set(unit, config_mem, &entry,
   2029                             THRESHOLDf, xmit_cnt);
   2030         SOC_IF_ERROR_RETURN(soc_mem_write(unit, config_mem, MEM_BLOCK_ALL,
   2031                                           port_idx, &entry));
   2032     }
   2033 
   2034     return SOC_E_NONE;
   2035 }
   2036 
   2037 /******************************************************************************
   2038  * Name: soc_th_port_asf_mode_get                                             *
   2039  * Description:                                                               *
   2040  *     Retrieve the ASF/SAF mode configured on the specified port             *
   2041  * IN params:                                                                 *
   2042  *     - Unit                                                                 *
   2043  *     - Logical Port                                                         *
   2044  *     - Port Speed                                                           *
   2045  * OUT params:                                                                *
   2046  *     - mode : OUT: contains the ASF/SAF mode confiugred on the specified    *
   2047  *       port on success                                                      *
   2048  * Returns:                                                                   *
   2049  *     - SOC_E_NONE on success                                                *
   2050  *     - SOC_E_PARAM on invalid parameter                                     *
   2051  *     - SOC_E_INTERNAL on init/soc errors                                    *
   2052  */
   2053 int
   2054 soc_th_port_asf_mode_get(
   2055     int                            unit,
   2056     soc_port_t                     port,
   2057     int                            port_speed,
   2058     OUT soc_th_asf_mode_e* const   mode)
   2059 {
   2060     uint32 rval;
   2061     int    speed_encoding;
   2062     uint8  max_sp, min_sp, enable;
   2063 
   2064     _SOC_TH_UNIT_VALIDATE(unit);
   2065     if (!mode) {
   2066         return SOC_E_INTERNAL;
   2067     }
   2068 
   2069     if (soc_th_port_asf_valid(unit, port)) {
   2070         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   2071         enable = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, ENABLEf);
   2072         if (!enable) {
   2073             *mode = _SOC_TH_ASF_MODE_SAF;
   2074             return SOC_E_NONE;
   2075         }
   2076     } else {
   2077         *mode = _SOC_TH_ASF_MODE_SAF;
   2078         return SOC_E_NONE;
   2079     }
   2080 
   2081     if (!_soc_th_asf_ctrl[unit] || !_soc_th_asf_ctrl[unit]->init) {
   2082         return SOC_E_INTERNAL;
   2083     }
   2084 
   2085     max_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, MAX_SRC_PORT_SPEEDf);
   2086     min_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, MIN_SRC_PORT_SPEEDf);
   2087 
   2088     speed_encoding = _soc_th_speed_to_ct_class_map(port_speed);
   2089     _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1);
   2090 
   2091     if (max_sp && min_sp) {
   2092         if (max_sp == min_sp) {
   2093             if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_sf, port)) {
   2094                 *mode = _SOC_TH_ASF_MODE_SLOW_TO_FAST;
   2095             } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_fs, port)) {
   2096                 *mode = _SOC_TH_ASF_MODE_FAST_TO_SLOW;
   2097             } else {
   2098                 *mode = _SOC_TH_ASF_MODE_SAME_SPEED;
   2099             }
   2100         } else if (max_sp == speed_encoding) {
   2101             *mode = _SOC_TH_ASF_MODE_SLOW_TO_FAST;
   2102         }
   2103         else if (min_sp == speed_encoding) {
   2104             *mode = _SOC_TH_ASF_MODE_FAST_TO_SLOW;
   2105         } else {
   2106             *mode = _SOC_TH_ASF_MODE_UNSUPPORTED;
   2107             return SOC_E_UNAVAIL;
   2108         }
   2109     } else {
   2110         *mode = _SOC_TH_ASF_MODE_UNSUPPORTED;
   2111         return SOC_E_UNAVAIL;
   2112     }
   2113 
   2114     return SOC_E_NONE;
   2115 }
   2116 
   2117 /******************************************************************************
   2118  * Name: soc_th_port_asf_mode_set                                             *
   2119  * Description:                                                               *
   2120  *     Configure specified ASF/SAF modes on the specified port                *
   2121  * IN params:                                                                 *
   2122  *     - Unit                                                                 *
   2123  *     - Logical Port                                                         *
   2124  *     - Port Speed                                                           *
   2125  *     - ASF Mode                                                             *
   2126  * OUT params:                                                                *
   2127  *     - None                                                                 *
   2128  * Returns:                                                                   *
   2129  *     - SOC_E_NONE on success                                                *
   2130  *     - SOC_E_PARAM on invalid parameter                                     *
   2131  *     - SOC_E_INTERNAL on init/soc errors                                    *
   2132  */
   2133 int
   2134 soc_th_port_asf_mode_set(
   2135     int                 unit,
   2136     soc_port_t          port,
   2137     int                 port_speed,
   2138     soc_th_asf_mode_e   mode)
   2139 {
   2140     int           ret, speed_encoding = 0, pause_enable = 0, txp = 0, rxp = 0;
   2141     uint8         min_sp = 0, max_sp = 0;
   2142     uint8         fifo_threshold = 0, fifo_depth = 0, mmu_prebuf = 0;
   2143     uint8         oversub = 0, ca_thresh = 0;
   2144     uint8         bubble_mop_disable = 0;
   2145     uint32        rval;
   2146     soc_info_t   *si = NULL;
   2147     mac_driver_t *macd;
   2148     int           latency = SOC_SWITCH_BYPASS_MODE_NONE;
   2149     int           init = 0;
   2150     int           ct_class = 0, original_speed = 0;
   2151     const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table;
   2152     uint32 port_cl91_state;
   2153     uint32 ct_ok_thresh;
   2154 
   2155     _SOC_TH_UNIT_VALIDATE(unit);
   2156 
   2157     _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl;
   2158 
   2159     /* Get the FEC/CL91 state of the port to choose correct CT parameters */
   2160     SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
   2161 
   2162     if (port_cl91_state) {
   2163         _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec;
   2164     }
   2165 
   2166     if (_SOC_TH_ASF_MODE_INIT == mode) {
   2167         init = 1;
   2168         mode = _SOC_TH_ASF_MODE_SAF;
   2169     }
   2170     if ((!init) && (!_soc_th_asf_ctrl[unit] ||
   2171         !_soc_th_asf_ctrl[unit]->init || !(si = &SOC_INFO(unit)))) {
   2172         return SOC_E_INTERNAL;
   2173     }
   2174     if (!_soc_th_asf_ctrl[unit]->asf_mem_profile) { /* no cut-thru profile */
   2175         if ((_SOC_TH_ASF_MODE_SAF != mode) &&
   2176             (_SOC_TH_ASF_MODE_CFG_UPDATE != mode)) {
   2177             return SOC_E_UNAVAIL;
   2178         }
   2179     }
   2180     if (!soc_th_port_asf_valid(unit, port)) {
   2181         if ((_SOC_TH_ASF_MODE_SAF != mode) &&
   2182             (_SOC_TH_ASF_MODE_CFG_UPDATE != mode)) {
   2183             return SOC_E_UNAVAIL;
   2184         }
   2185         SOC_IF_ERROR_RETURN(
   2186             soc_th_port_asf_xmit_start_count_set(unit, port, port_speed,
   2187                                                  mode, 0));
   2188         return SOC_E_NONE;
   2189     }
   2190 
   2191     speed_encoding = _soc_th_speed_to_ct_class_map(port_speed);
   2192     _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0);
   2193 
   2194     /* min. and max. src port speeds */
   2195     if (_SOC_TH_ASF_MODE_CFG_UPDATE != mode) {
   2196         min_sp = max_sp = _SOC_TH_ASF_QUERY;
   2197         SOC_IF_ERROR_RETURN(
   2198             _soc_th_port_asf_speed_limits_get(unit, port, port_speed, mode,
   2199                                               &min_sp, &max_sp));
   2200     }
   2201 
   2202     /* mode specific configurations */
   2203     switch(mode) {
   2204         case _SOC_TH_ASF_MODE_SAF:
   2205             break;
   2206 
   2207         case _SOC_TH_ASF_MODE_SAME_SPEED:
   2208             /* Cannot set cut-through mode for 1G ports */
   2209             if (1000 == port_speed) {
   2210                 return SOC_E_UNAVAIL;
   2211             }
   2212             /* verify mode specific conformance */
   2213             if (min_sp != max_sp) {
   2214                 return SOC_E_PARAM;
   2215             }
   2216             break;
   2217 
   2218         case _SOC_TH_ASF_MODE_SLOW_TO_FAST:
   2219             /* Cannot set cut-through mode for 1G ports */
   2220             if (1000 == port_speed) {
   2221                 return SOC_E_UNAVAIL;
   2222             }
   2223             /* verify mode specific conformance */
   2224             if ( !((min_sp >=
   2225                     _soc_th_asf_cfg_table[speed_encoding].min_sp) &&
   2226                    (max_sp == speed_encoding)) ) {
   2227                 return SOC_E_PARAM;
   2228             }
   2229             break;
   2230 
   2231         case _SOC_TH_ASF_MODE_FAST_TO_SLOW:
   2232             /* Cannot set cut-through mode for 1G ports */
   2233             if (1000 == port_speed) {
   2234                 return SOC_E_UNAVAIL;
   2235             }
   2236             /* verify mode specific conformance */
   2237             if ( !((max_sp <=
   2238                     _soc_th_asf_cfg_table[speed_encoding].max_sp) &&
   2239                    (min_sp == speed_encoding)) ) {
   2240                 return SOC_E_PARAM;
   2241             }
   2242             break;
   2243 
   2244         case _SOC_TH_ASF_MODE_CFG_UPDATE:
   2245             SOC_IF_ERROR_RETURN(
   2246                 _soc_th_port_asf_class_get(unit, port, &ct_class));
   2247             original_speed = _soc_th_asf_cfg_table[ct_class].speed;
   2248             ret = soc_th_port_asf_mode_get(unit, port, original_speed, &mode);
   2249             if (SOC_E_NONE != ret) {
   2250                 mode = _SOC_TH_ASF_MODE_SAF;
   2251             }
   2252 
   2253             /* disable CT first */
   2254             SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   2255             soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   2256                               FIFO_THRESHOLDf, 0);
   2257             SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   2258             sal_usleep(1);
   2259             soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, ENABLEf, 0);
   2260             SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   2261 
   2262             /* update new settings & re-enable */
   2263             ret = soc_th_port_asf_mode_set(unit, port, port_speed, mode);
   2264             return ret;
   2265 
   2266         default:
   2267             return SOC_E_PARAM;
   2268     }
   2269 
   2270     if (SOC_IS_TOMAHAWK(unit)) {
   2271         SOC_IF_ERROR_RETURN(soc_mac_probe(unit, port, &macd));
   2272     }
   2273 
   2274     /* ASF_IPORT_CFG */
   2275     SOC_IF_ERROR_RETURN(READ_ASF_IPORT_CFGr(unit, port, &rval));
   2276     soc_reg_field_set(unit, ASF_IPORT_CFGr, &rval, ASF_PORT_SPEEDf,
   2277                       port_speed == 1000 ? 0: speed_encoding);
   2278     SOC_IF_ERROR_RETURN(WRITE_ASF_IPORT_CFGr(unit, port, rval));
   2279 
   2280     /* init CT class */
   2281     SOC_IF_ERROR_RETURN(_soc_th_port_asf_class_init(unit, port, speed_encoding));
   2282 
   2283     if (_SOC_TH_ASF_MODE_SAF != mode) {
   2284         /* Oversub */
   2285         oversub =  (SOC_PBMP_MEMBER(si->oversub_pbm, port) ? 1 : 0);
   2286 
   2287 #ifdef BCM_TOMAHAWK2_SUPPORT
   2288         if (SOC_IS_TOMAHAWK2(unit)) {
   2289             /* FIFO threshold */
   2290             fifo_threshold = _SOC_TH_ASF_QUERY;
   2291             SOC_IF_ERROR_RETURN(
   2292                 _soc_th2_port_asf_fifo_threshold_get(unit, port, port_speed, mode,
   2293                                                     min_sp, &fifo_threshold));
   2294             
   2295             /* FIFO depth */
   2296             fifo_depth = _SOC_TH_ASF_QUERY;
   2297             SOC_IF_ERROR_RETURN(
   2298                 _soc_th2_port_asf_fifo_depth_get(unit, port, port_speed, mode,
   2299                                                 min_sp, &fifo_depth));
   2300             
   2301             /* MMU Prebuffer */
   2302             mmu_prebuf = _SOC_TH_ASF_QUERY;
   2303             SOC_IF_ERROR_RETURN(
   2304                 _soc_th2_port_asf_mmu_prebuf_get(unit, port, port_speed,
   2305                                                 min_sp, &mmu_prebuf));
   2306         } else
   2307 #endif
   2308         {
   2309             /* FIFO threshold */
   2310             fifo_threshold = _SOC_TH_ASF_QUERY;
   2311             SOC_IF_ERROR_RETURN(
   2312                 _soc_th_port_asf_fifo_threshold_get(unit, port, port_speed, mode,
   2313                                                     min_sp, &fifo_threshold));
   2314     
   2315             /* FIFO depth */
   2316             fifo_depth = _SOC_TH_ASF_QUERY;
   2317             SOC_IF_ERROR_RETURN(
   2318                 _soc_th_port_asf_fifo_depth_get(unit, port, port_speed, mode,
   2319                                                 min_sp, &fifo_depth));
   2320     
   2321             /* MMU Prebuffer */
   2322             mmu_prebuf = _SOC_TH_ASF_QUERY;
   2323             SOC_IF_ERROR_RETURN(
   2324                 _soc_th_port_asf_mmu_prebuf_get(unit, port, port_speed,
   2325                                                 min_sp, &mmu_prebuf));
   2326         }
   2327 
   2328         /* Disable BubbleMOP for low latency mode */
   2329         SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency));
   2330 #ifdef BCM_TOMAHAWK2_SUPPORT
   2331         if (SOC_IS_TOMAHAWK2(unit)) {
   2332             const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table;
   2333             _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state);
   2334             bubble_mop_disable = oversub ? 
   2335                 !(_soc_th2_asf_cfg_table[speed_encoding].mop_enable.oversub[latency]) :
   2336                 !(_soc_th2_asf_cfg_table[speed_encoding].mop_enable.line_rate[latency]);
   2337         } else
   2338 #endif
   2339         {
   2340             /* special cases: 10G & HG[11] */
   2341             if ((SOC_SWITCH_BYPASS_MODE_LOW == latency) &&
   2342                 ((1 == speed_encoding) || (2 == speed_encoding))) {
   2343                 bubble_mop_disable = 1;
   2344             } else {
   2345                 bubble_mop_disable = 0;
   2346             }
   2347         }
   2348 
   2349         pause_enable = 0;
   2350         ca_thresh = 4;
   2351         ct_ok_thresh = 0;
   2352 
   2353         if (port_cl91_state) {
   2354             if ((port_speed == 50000) || (port_speed == 53000) ||
   2355                 (port_speed == 100000) || (port_speed == 106000)) {
   2356                 ca_thresh = 6;
   2357             }
   2358             if ((port_speed == 25000) || (port_speed == 27000)) {
   2359                 ct_ok_thresh = (SOC_IS_TOMAHAWK2(unit) ? 15 : 5);
   2360             }
   2361         }
   2362 
   2363         SOC_IF_ERROR_RETURN(
   2364             _soc_th_asf_obm_ct_thresh_ok_set(unit, port, ct_ok_thresh));
   2365 
   2366         SOC_IF_ERROR_RETURN(
   2367             soc_th_port_asf_params_set(unit, port, port_speed, mode,
   2368                                        bubble_mop_disable, ca_thresh,
   2369                                        speed_encoding));
   2370 
   2371         if (SOC_IS_TOMAHAWK(unit)) {
   2372             /* PAUSE */
   2373             SOC_IF_ERROR_RETURN(MAC_PAUSE_GET(macd, unit, port, &txp, &rxp));
   2374             if (rxp) {
   2375                 SOC_PBMP_PORT_ADD(_soc_th_asf_ctrl[unit]->pause_restore, port);
   2376             }
   2377             rxp = pause_enable;
   2378             SOC_IF_ERROR_RETURN(MAC_PAUSE_SET(macd, unit, port, txp, rxp));
   2379         }
   2380 
   2381         /* drain the port CT FIFO */
   2382         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   2383         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, ENABLEf, 1);
   2384         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_THRESHOLDf, 0);
   2385         SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   2386 
   2387         sal_usleep(1);
   2388 
   2389         /* enable cut-through */
   2390         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, OVERSUBf, oversub);
   2391         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   2392                           MAX_SRC_PORT_SPEEDf, max_sp);
   2393         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   2394                           MIN_SRC_PORT_SPEEDf, min_sp);
   2395         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   2396                           MIN_SRC_PORT_XMIT_CNTf, mmu_prebuf);
   2397         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   2398                           FIFO_THRESHOLDf, fifo_threshold);
   2399         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_DEPTHf,
   2400                           fifo_depth);
   2401         SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   2402 
   2403         /* bookkeeping */
   2404         if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_ss, port)) {
   2405             SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_ss, port);
   2406         } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_sf, port)) {
   2407             SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_sf, port);
   2408         } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_fs, port)) {
   2409             SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_fs, port);
   2410         }
   2411         SOC_PBMP_PORT_ADD(_soc_th_asf_ctrl[unit]->asf_ports, port);
   2412         if (_SOC_TH_ASF_MODE_SAME_SPEED == mode) {
   2413             SOC_PBMP_PORT_ADD(_soc_th_asf_ctrl[unit]->asf_ss, port);
   2414         } else if (_SOC_TH_ASF_MODE_SLOW_TO_FAST== mode) {
   2415             SOC_PBMP_PORT_ADD(_soc_th_asf_ctrl[unit]->asf_sf, port);
   2416         } else if (_SOC_TH_ASF_MODE_FAST_TO_SLOW== mode) {
   2417             SOC_PBMP_PORT_ADD(_soc_th_asf_ctrl[unit]->asf_fs, port);
   2418         }
   2419     } else {   /* Store and Forward */
   2420         fifo_depth = 0x40;
   2421         fifo_threshold = 0x20;
   2422         mmu_prebuf = 0;
   2423         min_sp = 0;
   2424         max_sp = 0;
   2425         oversub = 0;
   2426         pause_enable = 1;
   2427         ca_thresh = 4;
   2428         bubble_mop_disable = 0;
   2429 
   2430         if (1000 == port_speed) {
   2431             pause_enable = 0;
   2432         }
   2433 
   2434         if (SOC_IS_TOMAHAWK(unit)) {
   2435             SOC_IF_ERROR_RETURN(
   2436                 _soc_th_asf_obm_ct_thresh_ok_set(unit, port, 0));
   2437         }
   2438 
   2439         SOC_IF_ERROR_RETURN(
   2440             soc_th_port_asf_params_set(unit, port, port_speed, mode,
   2441                                        bubble_mop_disable, ca_thresh,
   2442                                        speed_encoding));
   2443 
   2444         /* ASF_EPORT_CFG */
   2445         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   2446         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_THRESHOLDf, 0);
   2447         SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   2448 
   2449         sal_usleep(1);
   2450 
   2451         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, ENABLEf, 0);
   2452         SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   2453 
   2454         /* update SAF configs */
   2455         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   2456         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, OVERSUBf, oversub);
   2457         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   2458                           MAX_SRC_PORT_SPEEDf, max_sp);
   2459         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   2460                           MIN_SRC_PORT_SPEEDf, min_sp);
   2461         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   2462                           MIN_SRC_PORT_XMIT_CNTf, mmu_prebuf);
   2463         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   2464                           FIFO_THRESHOLDf, fifo_threshold);
   2465         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_DEPTHf,
   2466                           fifo_depth);
   2467         SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   2468 
   2469         if (SOC_IS_TOMAHAWK(unit)) {
   2470             /* restore pause */
   2471             if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->pause_restore, port)) {
   2472                 SOC_IF_ERROR_RETURN(MAC_PAUSE_GET(macd, unit, port, &txp, &rxp));
   2473                 rxp = 1;
   2474                 SOC_IF_ERROR_RETURN(MAC_PAUSE_SET(macd, unit, port, txp, rxp));
   2475                 SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->pause_restore, port);
   2476             }
   2477         }
   2478 
   2479         /* bookkeeping */
   2480         SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_ports, port);
   2481         if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_ss, port)) {
   2482             SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_ss, port);
   2483         } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_sf, port)) {
   2484             SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_sf, port);
   2485         } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_fs, port)) {
   2486             SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_fs, port);
   2487         }
   2488     }
   2489 
   2490     return SOC_E_NONE;
   2491 }
   2492 
   2493 /******************************************************************************
   2494  * Name: soc_th_port_asf_params_set                                           *
   2495  * Description:                                                               *
   2496  *     Configure ASF/SAF mode params on the specified port                    *
   2497  * IN params:                                                                 *
   2498  *     - Unit                                                                 *
   2499  *     - Logical Port                                                         *
   2500  *     - Port Speed                                                           *
   2501  *     - ASF Mode                                                             *
   2502  *     - Bubble MOP disable flag                                              *
   2503  *     - CA Threshold                                                         *
   2504  *     - Speed Encoding                                                       *
   2505  * OUT params:                                                                *
   2506  *     - None                                                                 *
   2507  * Returns:                                                                   *
   2508  *     - SOC_E_NONE on success                                                *
   2509  *     - SOC_E_PARAM on invalid parameter                                     *
   2510  *     - SOC_E_INTERNAL on init/soc errors                                    *
   2511  */
   2512 int
   2513 soc_th_port_asf_params_set(
   2514     int                 unit,
   2515     soc_port_t          port,
   2516     int                 port_speed,
   2517     soc_th_asf_mode_e   mode,
   2518     uint8               bubble_mop_disable,
   2519     uint8               ca_thresh,
   2520     int                 speed_encoding)
   2521 {
   2522     uint32        mmu_ep_credits = 0, egr_mmu_cell_credits = 0;
   2523     uint32        rval;
   2524     soc_info_t   *si = NULL;
   2525     uint8  oversub;
   2526 #if defined(BCM_TOMAHAWK2_SUPPORT)
   2527     egr_mmu_cell_credit_entry_t credit_entry;
   2528 #endif
   2529     const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table;
   2530     uint32 port_cl91_state;
   2531 
   2532     if (!(si = &SOC_INFO(unit))) {
   2533         return SOC_E_INTERNAL;
   2534     }
   2535 
   2536     /* If oversub mode, setup Ingress Force SAF registers */
   2537     oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0);
   2538     if (oversub) {
   2539         _soc_th_asf_force_saf_config_set(unit, port, mode);
   2540     }
   2541 
   2542     _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl;
   2543 
   2544     /* Get the FEC/CL91 state of the port to choose correct CT parameters */
   2545     SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
   2546 
   2547     if (port_cl91_state) {
   2548         _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec;
   2549     }
   2550 
   2551     /* EDB Prebuffer */
   2552     SOC_IF_ERROR_RETURN(
   2553         soc_th_port_asf_xmit_start_count_set(unit, port, port_speed,
   2554                                              mode, 0));
   2555     /* OBM Cell Assembly FIFO threshold */
   2556     SOC_IF_ERROR_RETURN(
   2557         _soc_th_asf_obm_ca_fifo_thresh_set(unit, port, ca_thresh));
   2558 
   2559     /* BubbleMOP - At present only L3 & Full Latency Mode supported */
   2560     SOC_IF_ERROR_RETURN(
   2561         _soc_th_asf_obm_bubble_mop_set(unit, port, bubble_mop_disable));
   2562 
   2563     /* MMU EP Credit Threshold */
   2564 #if defined(BCM_TOMAHAWK2_SUPPORT)
   2565     if (SOC_IS_TOMAHAWK2(unit)) {
   2566         int ovs_ratio = 0;
   2567         uint8 mmu_ep_credits_lo = 0;
   2568         const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table;
   2569 
   2570         _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state);
   2571 
   2572         SOC_IF_ERROR_RETURN(
   2573             soc_th_port_oversub_ratio_get(unit, port, &ovs_ratio));
   2574         if ((1700 == si->frequency) && (ovs_ratio <= 1500)) {
   2575             mmu_ep_credits_lo = 
   2576                 _soc_th2_asf_cfg_table[speed_encoding].mmu_credit_threshold.lr_os_1_5.lo;
   2577             mmu_ep_credits = 
   2578                 _soc_th2_asf_cfg_table[speed_encoding].mmu_credit_threshold.lr_os_1_5.hi;
   2579         } else {
   2580             mmu_ep_credits_lo = 
   2581                 _soc_th2_asf_cfg_table[speed_encoding].mmu_credit_threshold.os_2_1.lo;
   2582             mmu_ep_credits = 
   2583                 _soc_th2_asf_cfg_table[speed_encoding].mmu_credit_threshold.os_2_1.hi;
   2584         }
   2585         
   2586         /* ASF_CREDIT_THRESH_LO */
   2587         SOC_IF_ERROR_RETURN(READ_ASF_CREDIT_THRESH_LOr(unit, port, &rval));
   2588         soc_reg_field_set(unit, ASF_CREDIT_THRESH_LOr, &rval, THRESHf,
   2589                           mmu_ep_credits_lo);
   2590         SOC_IF_ERROR_RETURN(WRITE_ASF_CREDIT_THRESH_LOr(unit, port, rval));
   2591     } else
   2592 #endif
   2593     {
   2594         if (CCLK_FREQ_850MHZ <= si->frequency) {
   2595             mmu_ep_credits =
   2596             _soc_th_asf_cfg_table[speed_encoding].mmu_ep_credit.pfc_op_cells;
   2597         } else {
   2598             mmu_ep_credits =
   2599             _soc_th_asf_cfg_table[speed_encoding].mmu_ep_credit.base_cells;
   2600         }
   2601     }
   2602     /* ASF_CREDIT_THRESH_HI */
   2603     SOC_IF_ERROR_RETURN(READ_ASF_CREDIT_THRESH_HIr(unit, port, &rval));
   2604     soc_reg_field_set(unit, ASF_CREDIT_THRESH_HIr, &rval, THRESHf,
   2605                       mmu_ep_credits);
   2606     SOC_IF_ERROR_RETURN(WRITE_ASF_CREDIT_THRESH_HIr(unit, port, rval));
   2607 
   2608     /* EP credits outstanding */
   2609     SOC_IF_ERROR_RETURN(
   2610         soc_th_port_asf_speed_to_mmu_cell_credit(unit, port, port_speed, 
   2611             &egr_mmu_cell_credits));
   2612 
   2613     /* EGR_MMU_CELL_CREDIT */
   2614 #if defined(BCM_TOMAHAWK2_SUPPORT)
   2615     if (soc_feature(unit, soc_feature_egr_mmu_cell_credit_is_memory)) {
   2616         SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ANY,
   2617                             si->port_l2p_mapping[port], &credit_entry));
   2618         soc_EGR_MMU_CELL_CREDITm_field32_set(unit, &credit_entry, CREDITf,
   2619                                              egr_mmu_cell_credits);
   2620         SOC_IF_ERROR_RETURN(WRITE_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ALL,
   2621                             si->port_l2p_mapping[port], &credit_entry));
   2622     } else
   2623 #endif
   2624     {
   2625         if (SOC_MEM_IS_VALID(unit, EGR_MMU_CELL_CREDITm)) {
   2626             SOC_IF_ERROR_RETURN(soc_mem_field32_modify(unit, EGR_MMU_CELL_CREDITm,
   2627                                     port, CREDITf, egr_mmu_cell_credits));
   2628         } else {
   2629             /* EGR_MMU_CELL_CREDIT */
   2630             SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITr(unit, port, &rval));
   2631             soc_reg_field_set(unit, EGR_MMU_CELL_CREDITr, &rval, CREDITf,
   2632                               egr_mmu_cell_credits);
   2633             SOC_IF_ERROR_RETURN(WRITE_EGR_MMU_CELL_CREDITr(unit, port, rval));
   2634         }
   2635     }
   2636 
   2637     return SOC_E_NONE;
   2638 }
   2639 
   2640 /******************************************************************************
   2641  * Name: soc_th_port_asf_speed_to_mmu_cell_credit                             *
   2642  * Description:                                                               *
   2643  *     Retrieve mmu_cell_credit based on port speed configured.               *
   2644  *     Helper function for misc init.                                         *
   2645  * IN params:                                                                 *
   2646  *     - Unit                                                                 *
   2647  *     - Logical Port                                                         *
   2648  *     - Port Speed                                                           *
   2649  * OUT params:                                                                *
   2650  *     - MMU Cell credit                                                      *
   2651  * Returns:                                                                   *
   2652  *     - SOC_E_XXX on success                                                 *
   2653  */
   2654 int
   2655 soc_th_port_asf_speed_to_mmu_cell_credit(
   2656     int        unit,
   2657     soc_port_t port,
   2658     int        port_speed,
   2659     OUT uint32 *mmu_cell_credit)
   2660 {
   2661     int          speed_encoding = 0;
   2662     soc_info_t   *si = NULL;
   2663     const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table;
   2664     uint32 port_cl91_state;
   2665 
   2666     _SOC_TH_UNIT_VALIDATE(unit);
   2667 
   2668     if (NULL == mmu_cell_credit) {
   2669         return SOC_E_PARAM;
   2670     }
   2671 
   2672     if (!(si = &SOC_INFO(unit))) {
   2673         return SOC_E_INTERNAL;
   2674     }
   2675 
   2676     _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl;
   2677 
   2678     /* Get the FEC/CL91 state of the port to choose correct CT parameters */
   2679     SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
   2680 
   2681     if (port_cl91_state) {
   2682         _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec;
   2683     }
   2684 
   2685     speed_encoding = _soc_th_speed_to_ct_class_map(port_speed);
   2686     _SOC_TH_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0);
   2687     
   2688 #if defined(BCM_TOMAHAWK2_SUPPORT)
   2689     if (SOC_IS_TOMAHAWK2(unit)) {
   2690         int ovs_ratio = 0;
   2691         const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table;
   2692 
   2693         _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state);
   2694         SOC_IF_ERROR_RETURN(
   2695             soc_th_port_oversub_ratio_get(unit, port, &ovs_ratio));
   2696         if (IS_CPU_PORT(unit, port)) {
   2697             speed_encoding = 3;     /* 20G for CPU */
   2698         } else if (IS_LB_PORT(unit, port)) {
   2699             speed_encoding = 11;    /* 100G for LB */
   2700         }
   2701         /* At MAX FREQ, the ovs_ratio will always be less than 3:2;
   2702          * Still add that check
   2703          */
   2704         if ((1700 == si->frequency) && (ovs_ratio <= 1500)) {
   2705             *mmu_cell_credit = 
   2706                 _soc_th2_asf_cfg_table[speed_encoding].ep_credit.pfc_op_cells;
   2707         } else {
   2708             *mmu_cell_credit = 
   2709                 _soc_th2_asf_cfg_table[speed_encoding].ep_credit.base_cells;
   2710         }
   2711     } else
   2712 #endif
   2713     {
   2714         if (CCLK_FREQ_850MHZ == si->frequency) {
   2715             *mmu_cell_credit = (speed_encoding ?
   2716                 _soc_th_asf_cfg_table[speed_encoding].egr_mmu_credit.pfc_op_cells : 
   2717                 11);
   2718         } else {
   2719             *mmu_cell_credit = (speed_encoding ?
   2720                 _soc_th_asf_cfg_table[speed_encoding].egr_mmu_credit.base_cells :
   2721                 13);
   2722         }
   2723     }
   2724 
   2725     return SOC_E_NONE;
   2726 }
   2727 
   2728 /******************************************************************************
   2729  * Name: soc_th_port_asf_mmu_cell_credit_to_port_speed                        *
   2730  * Description:                                                               *
   2731  *     Retrieve port speed based on mmu_cell_credit configured.               *
   2732  *     Helper function for MAC driver speed get.                              *
   2733  * IN params:                                                                 *
   2734  *     - Unit                                                                 *
   2735  *     - Logical Port                                                         *
   2736  *     - MMU Cell credit                                                      *
   2737  * OUT params:                                                                *
   2738  *     - Port speed                                                           *
   2739  * Returns:                                                                   *
   2740  *     - SOC_E_XXX on success                                                 *
   2741  */
   2742 int
   2743 soc_th_port_asf_mmu_cell_credit_to_speed(
   2744     int        unit,
   2745     soc_port_t port,
   2746     uint8      mmu_cell_credit,
   2747     OUT int    *port_speed)
   2748 {
   2749     int i, freq;
   2750     uint8 cell_credit;
   2751     int speed;
   2752     soc_info_t   *si = NULL;
   2753     const _soc_th_asf_core_cfg_t *_soc_th_asf_cfg_table;
   2754     uint32 port_cl91_state;
   2755 #if defined (BCM_TOMAHAWK_SUPPORT)
   2756     uint8  oversub;
   2757     int port_mode;
   2758     uint32 rval;
   2759 #endif
   2760 
   2761     _SOC_TH_UNIT_VALIDATE(unit);
   2762 
   2763     if (NULL == port_speed) {
   2764         return SOC_E_PARAM;
   2765     }
   2766 
   2767     if (!(si = &SOC_INFO(unit))) {
   2768         return SOC_E_INTERNAL;
   2769     }
   2770 
   2771 #if defined (BCM_TOMAHAWK_SUPPORT)
   2772     oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0);
   2773 #endif
   2774 
   2775     /* Special case for 1G ports since 1G ports use same setting as 10G port */
   2776     if (1000 == (speed = si->port_init_speed[port])) {  /* Use cached speed instead */
   2777         *port_speed = speed;
   2778         return SOC_E_NONE;
   2779     }
   2780 
   2781     _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl;
   2782 
   2783     /* Get the FEC/CL91 state of the port to choose correct CT parameters */
   2784     SOC_IF_ERROR_RETURN(_soc_th_port_asf_port_cl91_get(unit, port, &port_cl91_state));
   2785 
   2786     if (port_cl91_state) {
   2787         _soc_th_asf_cfg_table = _soc_th_asf_cfg_tbl_fec;
   2788     }
   2789 
   2790     freq = si->frequency;
   2791     for (i = 1; i < (COUNTOF(_soc_th_asf_cfg_tbl) - 1); i++) {
   2792 #if defined(BCM_TOMAHAWK2_SUPPORT)
   2793         if (SOC_IS_TOMAHAWK2(unit)) {
   2794             int ovs_ratio = 0;
   2795             const _soc_th2_asf_core_cfg_t *_soc_th2_asf_cfg_table;
   2796 
   2797             _soc_th2_asf_cfg_table = _SOC_TH2_ASF_CFG_TBL(unit, port_cl91_state);
   2798             SOC_IF_ERROR_RETURN(
   2799                 soc_th_port_oversub_ratio_get(unit, port, &ovs_ratio));
   2800             /* At max frequency, use the 1.5 ratio settings.
   2801              * For all other cases, use the 1.5 ratio as the threshold to
   2802              * determine which settings to use.
   2803              */
   2804             cell_credit = ((1700 == freq) && (ovs_ratio <= 1500)) ?
   2805                 _soc_th2_asf_cfg_table[i].ep_credit.pfc_op_cells :
   2806                 _soc_th2_asf_cfg_table[i].ep_credit.base_cells;
   2807         } else
   2808 #endif
   2809         {
   2810             cell_credit = (CCLK_FREQ_850MHZ == freq) ?
   2811                 _soc_th_asf_cfg_table[i].egr_mmu_credit.pfc_op_cells :
   2812                 _soc_th_asf_cfg_table[i].egr_mmu_credit.base_cells;
   2813         }
   2814         if (mmu_cell_credit == cell_credit) {
   2815 #if defined (BCM_TOMAHAWK_SUPPORT)
   2816             if (oversub &&
   2817                 mmu_cell_credit == 16) { /* 16 is EDB credit value for 25G/20G */
   2818                 SOC_IF_ERROR_RETURN(READ_CLPORT_MODE_REGr(unit, port, &rval));
   2819                 port_mode = soc_reg_field_get(unit, CLPORT_MODE_REGr, rval,
   2820                                               XPORT0_CORE_PORT_MODEf);
   2821                 if (!port_mode) {
   2822                     *port_speed = IS_HG_PORT(unit, port) ? 27000 : 25000;
   2823                     return SOC_E_NONE;
   2824                 }
   2825             }
   2826 #endif
   2827             if (IS_HG_PORT(unit, port)) {
   2828                 *port_speed = _soc_th_asf_cfg_table[i + 1].speed;
   2829             } else {
   2830                 *port_speed = _soc_th_asf_cfg_table[i].speed;
   2831             }
   2832 #if defined(BCM_TOMAHAWK2_SUPPORT)
   2833         if (SOC_IS_TOMAHAWK2(unit)) {
   2834             if (SOC_E_NONE !=
   2835                 soc_th_port_speed_supported(unit, port, *port_speed)) {
   2836                 continue;
   2837             }
   2838         }
   2839 #endif
   2840             return SOC_E_NONE;
   2841         }
   2842     }
   2843 
   2844     return SOC_E_NOT_FOUND;
   2845 }
   2846 
   2847 /******************************************************************************
   2848  * Name: soc_th_port_asf_pause_bpmp_get                                       *
   2849  * Description:                                                               *
   2850  *     Get pointer of pause_restore bitmap for update                         *
   2851  * IN params:                                                                 *
   2852  *     - Unit                                                                 *
   2853  * OUT params:                                                                *
   2854  *                                                                            *
   2855  * Returns:                                                                   *
   2856  *     - Pointer of pause_restore bitmap                                      *
   2857  */
   2858 pbmp_t *
   2859 soc_th_port_asf_pause_bpmp_get(int unit)
   2860 {
   2861     if (_soc_th_asf_ctrl[unit] == NULL) {
   2862         return NULL;
   2863     }
   2864     return &_soc_th_asf_ctrl[unit]->pause_restore;
   2865 }
   2866 
   2867 /************************
   2868  * ASF Warmboot Support *
   2869  */
   2870 #ifdef BCM_WARM_BOOT_SUPPORT
   2871 
   2872 #define BCM_WB_VERSION_1_0                SOC_SCACHE_VERSION(1,0)
   2873 #define BCM_WB_VERSION_1_1                SOC_SCACHE_VERSION(1,1)
   2874 #define BCM_WB_VERSION_1_2                SOC_SCACHE_VERSION(1,2)
   2875 #define BCM_WB_VERSION_1_3                SOC_SCACHE_VERSION(1,3)
   2876 #define BCM_WB_VERSION_1_4                SOC_SCACHE_VERSION(1,4)
   2877 #define BCM_WB_VERSION_1_5                SOC_SCACHE_VERSION(1,5)
   2878 #define BCM_WB_VERSION_1_6                SOC_SCACHE_VERSION(1,6)
   2879 #define BCM_WB_VERSION_1_7                SOC_SCACHE_VERSION(1,7)
   2880 #define BCM_WB_VERSION_1_8                SOC_SCACHE_VERSION(1,8)
   2881 #define BCM_WB_DEFAULT_VERSION            BCM_WB_VERSION_1_8
   2882 
   2883 int
   2884 soc_th_asf_wb_memsz_get(
   2885     int               unit,
   2886     OUT uint32* const mem_sz,
   2887     uint16            scache_ver)
   2888 {
   2889     _SOC_TH_UNIT_VALIDATE(unit);
   2890     if (!mem_sz) {
   2891         return SOC_E_PARAM;
   2892     }
   2893     *mem_sz = 0;
   2894 
   2895     if (!SOC_WARM_BOOT(unit)) {
   2896         if (!_soc_th_asf_ctrl[unit] || !_soc_th_asf_ctrl[unit]->asf_mem_profile) {
   2897             return SOC_E_UNAVAIL;
   2898         }
   2899         if (!_soc_th_asf_ctrl[unit]->init) {
   2900             return SOC_E_INTERNAL;
   2901         }
   2902     }
   2903 
   2904     *mem_sz = sizeof(_soc_th_asf_wb_t);
   2905 
   2906     if (scache_ver < BCM_WB_VERSION_1_8) {
   2907         /* adjust wb area sz for lower versions */
   2908         *mem_sz -= sizeof(int);
   2909     }
   2910 
   2911     return SOC_E_NONE;
   2912 }
   2913 
   2914 int
   2915 soc_th_asf_wb_sync(
   2916     int    unit,
   2917     IN_OUT uint8* const wb_data)
   2918 {
   2919     _soc_th_asf_wb_t *wbd;
   2920 
   2921     _SOC_TH_UNIT_VALIDATE(unit);
   2922     if (!_soc_th_asf_ctrl[unit] || !_soc_th_asf_ctrl[unit]->asf_mem_profile) {
   2923         return SOC_E_UNAVAIL;
   2924     }
   2925     if (!_soc_th_asf_ctrl[unit]->init) {
   2926         return SOC_E_INTERNAL;
   2927     }
   2928     if (!wb_data) {
   2929         return SOC_E_PARAM;
   2930     }
   2931 
   2932     wbd = (_soc_th_asf_wb_t *) wb_data;
   2933     wbd->unit = unit;
   2934     sal_memcpy(&wbd->asf_ctrl, _soc_th_asf_ctrl[unit],
   2935                sizeof(_soc_th_asf_ctrl_t));
   2936 
   2937     return SOC_E_NONE;
   2938 }
   2939 
   2940 int
   2941 soc_th_asf_wb_recover(
   2942     int          unit,
   2943     uint8* const wb_data,
   2944     uint16       scache_ver)
   2945 {
   2946     _soc_th_asf_wb_t *wbd;
   2947     int adj = 0; /*scache ver adjustment */
   2948 
   2949     _SOC_TH_UNIT_VALIDATE(unit);
   2950     if (!SOC_WARM_BOOT(unit)) {
   2951         return SOC_E_INTERNAL;
   2952     }
   2953     if (!wb_data) {
   2954         return SOC_E_PARAM;
   2955     }
   2956 
   2957     wbd = (_soc_th_asf_wb_t *) wb_data;
   2958     if (wbd->unit == unit) {
   2959         if (!(_soc_th_asf_ctrl[unit] =
   2960                    sal_alloc(sizeof(_soc_th_asf_ctrl_t), "TH ASF Ctrl Area"))) {
   2961             return SOC_E_MEMORY;
   2962         }
   2963 
   2964         if (scache_ver < BCM_WB_VERSION_1_8) {
   2965             /* adjust for lower versions */
   2966             adj = sizeof(int);
   2967             /* backfill latency querying latency subsystem */
   2968             SOC_IF_ERROR_RETURN(
   2969                 soc_th_latency_get(unit, &_soc_th_asf_ctrl[unit]->latency));
   2970         }
   2971 
   2972         sal_memcpy(_soc_th_asf_ctrl[unit], &wbd->asf_ctrl,
   2973                    (sizeof(_soc_th_asf_ctrl_t) - adj));
   2974     }
   2975 
   2976     LOG_CLI((BSL_META_U(unit, "*** unit %d: MMU-ASF subsystem warmbooted: "
   2977                         "ports %s\n"), unit,
   2978                         asf_profile_str[_soc_th_asf_ctrl[unit]->asf_mem_profile]));
   2979 
   2980     return SOC_E_NONE;
   2981 }
   2982 #endif /* BCM_WARM_BOOT_SUPPORT */
   2983 
   2984 /**********************
   2985  * ASF Debug Support  *
   2986  */
   2987 int
   2988 soc_th_asf_pbmp_get(int unit)
   2989 {
   2990     char pfmt[SOC_PBMP_FMT_LEN];
   2991 
   2992     _SOC_TH_UNIT_VALIDATE(unit);
   2993     if (!_soc_th_asf_ctrl[unit]->init) {
   2994         return SOC_E_INTERNAL;
   2995     }
   2996 
   2997     LOG_CLI(("ASF PBMP: %s\n",
   2998              SOC_PBMP_FMT(_soc_th_asf_ctrl[unit]->asf_ports, pfmt)));
   2999 
   3000     return SOC_E_NONE;
   3001 }
   3002 
   3003 int
   3004 soc_th_port_asf_show(
   3005     int        unit,
   3006     soc_port_t port,
   3007     int        port_speed)
   3008 {
   3009     int ret;
   3010     char mode_str[4][15] = {"SAF", "Same speed  ", "Slow to Fast",
   3011                              "Fast to Slow"};
   3012     char speed_str[13][10] = {"SAF", "10G", "HG[11]", "20G", "HG[21]", "25G",
   3013                                "HG[27]", "40G", "HG[42]", "50G", "HG[53]",
   3014                                "100G", "HG[106]"};
   3015     soc_th_asf_mode_e mode = _SOC_TH_ASF_RETRV;
   3016     uint8 min_speed, max_speed;
   3017 
   3018     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
   3019         return BCM_E_NONE;
   3020     }
   3021 
   3022     min_speed = max_speed = _SOC_TH_ASF_RETRV;
   3023     ret = soc_th_port_asf_mode_get(unit, port, port_speed, &mode);
   3024     if (SOC_E_UNAVAIL == ret) {
   3025         mode = _SOC_TH_ASF_MODE_SAF;
   3026     } else if (SOC_E_NONE != ret) {
   3027         return ret;
   3028     }
   3029 
   3030     LOG_CLI(("%-5s     %-11s      ", SOC_PORT_NAME(unit, port), mode_str[mode]));
   3031 
   3032     if (_SOC_TH_ASF_MODE_SAF == mode) {
   3033         LOG_CLI(("    .. NA ..\n"));
   3034     } else if (_SOC_TH_ASF_MODE_FAST_TO_SLOW == mode) {
   3035         ret = _soc_th_port_asf_speed_limits_get(unit, port, port_speed, mode,
   3036                                                 &min_speed, &max_speed);
   3037         LOG_CLI(("%s / %s\n", speed_str[max_speed], speed_str[min_speed]));
   3038     } else {
   3039         ret = _soc_th_port_asf_speed_limits_get(unit, port, port_speed, mode,
   3040                                                 &min_speed, &max_speed);
   3041         LOG_CLI(("%s / %s\n", speed_str[min_speed], speed_str[max_speed]));
   3042     }
   3043 
   3044     return SOC_E_NONE;
   3045 }
   3046 
   3047 int soc_th_asf_config_dump(int unit)
   3048 {
   3049     char asf_profile_str[3][25] = {"No cut-thru support",
   3050                                    "Similar speed cut-thru",
   3051                                    "Extreme speed cut-thru"};
   3052 
   3053     _SOC_TH_UNIT_VALIDATE(unit);
   3054     if (!_soc_th_asf_ctrl[unit] || !_soc_th_asf_ctrl[unit]->init) {
   3055         return SOC_E_INTERNAL;
   3056     }
   3057 
   3058     LOG_CLI(("ASF Profile: %s\n\n",
   3059              asf_profile_str[_soc_th_asf_ctrl[unit]->asf_mem_profile]));
   3060 
   3061     return SOC_E_NONE;
   3062 }
   3063 
   3064 int
   3065 soc_th_port_asf_config_dump(
   3066     int        unit,
   3067     soc_port_t port,
   3068     int        port_speed)
   3069 {
   3070     int    txp = 0, rxp = 0, ct_class = 0;
   3071     uint8  src_class = 0, dst_class = 0;
   3072     uint8  min_sp = 0, max_sp = 0;
   3073     uint8  fifo_threshold = 0, fifo_depth = 0, mmu_prebuf = 0;
   3074     uint8  xmit_start_cnt[13] = {0};
   3075     uint32 rval, mmu_ep_credits = 0, egr_mmu_cell_credits = 0;
   3076     mac_driver_t *macd;
   3077     soc_th_asf_mode_e mode = _SOC_TH_ASF_RETRV;
   3078 #if defined(BCM_TOMAHAWK2_SUPPORT)
   3079     egr_mmu_cell_credit_entry_t credit_entry;
   3080 #endif
   3081 
   3082     _SOC_TH_UNIT_VALIDATE(unit);
   3083 
   3084     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
   3085         return BCM_E_NONE;
   3086     }
   3087 
   3088     if (!_soc_th_asf_ctrl[unit] || !_soc_th_asf_ctrl[unit]->init) {
   3089         return SOC_E_INTERNAL;
   3090     }
   3091 
   3092     SOC_IF_ERROR_RETURN(
   3093         soc_th_port_asf_mode_get(unit, port, port_speed, &mode));
   3094 
   3095     if (soc_th_port_asf_valid(unit, port)) {
   3096         min_sp = max_sp = fifo_threshold = _SOC_TH_ASF_RETRV;
   3097         fifo_depth = mmu_prebuf = _SOC_TH_ASF_RETRV;
   3098 
   3099         SOC_IF_ERROR_RETURN(
   3100             _soc_th_port_asf_class_get(unit, port, &ct_class));
   3101         SOC_IF_ERROR_RETURN(
   3102             _soc_th_port_asf_speed_limits_get(unit, port, port_speed, mode,
   3103                                               &min_sp, &max_sp));
   3104 #ifdef BCM_TOMAHAWK2_SUPPORT
   3105     if (SOC_IS_TOMAHAWK2(unit)) {
   3106         SOC_IF_ERROR_RETURN(
   3107             _soc_th2_port_asf_fifo_threshold_get(unit, port, port_speed, mode,
   3108                                                 min_sp, &fifo_threshold));
   3109         
   3110         SOC_IF_ERROR_RETURN(
   3111             _soc_th2_port_asf_fifo_depth_get(unit, port, port_speed, mode,
   3112                                             min_sp, &fifo_depth));
   3113         
   3114         SOC_IF_ERROR_RETURN(
   3115             _soc_th2_port_asf_mmu_prebuf_get(unit, port, port_speed,
   3116                                             min_sp, &mmu_prebuf));
   3117         } else
   3118 #endif
   3119         {
   3120             SOC_IF_ERROR_RETURN(
   3121                 _soc_th_port_asf_fifo_threshold_get(unit, port, port_speed, mode,
   3122                                                     min_sp, &fifo_threshold));
   3123             SOC_IF_ERROR_RETURN(
   3124                 _soc_th_port_asf_fifo_depth_get(unit, port, port_speed, mode,
   3125                                                 min_sp, &fifo_depth));
   3126             SOC_IF_ERROR_RETURN(
   3127                 _soc_th_port_asf_mmu_prebuf_get(unit, port, port_speed,
   3128                                                 min_sp, &mmu_prebuf));
   3129         }
   3130         SOC_IF_ERROR_RETURN(READ_ASF_CREDIT_THRESH_HIr(unit, port, &rval));
   3131         mmu_ep_credits = soc_reg_field_get(unit, ASF_CREDIT_THRESH_HIr,
   3132                                            rval, THRESHf);
   3133     }
   3134         
   3135 #ifdef BCM_TOMAHAWK2_SUPPORT
   3136     if (SOC_IS_TOMAHAWK2(unit)) {
   3137         dst_class = _soc_th_speed_to_ct_class_map(port_speed);
   3138         for (src_class = 0; src_class <= 12; src_class++) {
   3139             xmit_start_cnt[src_class] = _SOC_TH_ASF_RETRV;
   3140             SOC_IF_ERROR_RETURN(
   3141                 _soc_th2_port_asf_xmit_start_count_get(unit, port, src_class,
   3142                                                       dst_class, mode,
   3143                                                       &xmit_start_cnt[src_class]));
   3144         }
   3145     } else
   3146 #endif
   3147     {
   3148         dst_class = _soc_th_speed_to_ct_class_map(port_speed);
   3149         for (src_class = 0; src_class <= 12; src_class++) {
   3150             xmit_start_cnt[src_class] = _SOC_TH_ASF_RETRV;
   3151             SOC_IF_ERROR_RETURN(
   3152                 _soc_th_port_asf_xmit_start_count_get(unit, port, src_class,
   3153                                                       dst_class, mode,
   3154                                                       &xmit_start_cnt[src_class]));
   3155         }
   3156     }
   3157 
   3158     /*
   3159      * COVERITY
   3160      *
   3161      * This fault is false detected. As min_sp and max_sp will be initialized to 0 inside
   3162      * _soc_th_port_asf_speed_limits_get and will not be 255(_SOC_TH_ASF_RETRV) when code
   3163      * runs to code paragraph.
   3164      */
   3165     /* coverity[overrun-local] */
   3166     LOG_CLI(("%-5s %-3d %-3d %-6d %-6d %-3d %-3d   ", SOC_PORT_NAME(unit, port),
   3167              mode, ct_class, _SOC_TH_CT_CLASS_TO_SPEED_MAP(min_sp),
   3168             _SOC_TH_CT_CLASS_TO_SPEED_MAP(max_sp), fifo_threshold,
   3169             fifo_depth));
   3170     for (src_class = 0; src_class <= 12; src_class++) {
   3171         LOG_CLI(("%-3d ", xmit_start_cnt[src_class]));
   3172     }
   3173 
   3174 
   3175 #if defined(BCM_TOMAHAWK2_SUPPORT)
   3176     if (soc_feature(unit, soc_feature_egr_mmu_cell_credit_is_memory)) {
   3177         SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ANY,
   3178                             SOC_INFO(unit).port_l2p_mapping[port], &credit_entry));
   3179         egr_mmu_cell_credits = soc_EGR_MMU_CELL_CREDITm_field32_get(unit,
   3180                                &credit_entry, CREDITf);
   3181     } else
   3182 #endif
   3183     {
   3184         SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITr(unit, port, &rval));
   3185         egr_mmu_cell_credits = soc_reg_field_get(unit, EGR_MMU_CELL_CREDITr,
   3186                                                  rval, CREDITf);
   3187     }
   3188 
   3189     SOC_IF_ERROR_RETURN(soc_mac_probe(unit, port, &macd));
   3190     SOC_IF_ERROR_RETURN(MAC_PAUSE_GET(macd, unit, port, &txp, &rxp));
   3191 
   3192     LOG_CLI((" %-3d %-3d %-3d %-3d\n", mmu_prebuf, mmu_ep_credits,
   3193              egr_mmu_cell_credits, rxp));
   3194 
   3195     return SOC_E_NONE;
   3196 }
   3197 
   3198 /******************************************************************************
   3199  * Name: soc_th_port_asf_detach                                              *
   3200  * Description:                                                               *
   3201  *     Update ASF when port deleted during Flexport operation                 *
   3202  * IN params:                                                                 *
   3203  *     - Unit                                                                 *
   3204  *     - Logical Port                                                         *
   3205  * Returns:                                                                   *
   3206  *     - SOC_E_NONE on success                                                *
   3207  *     - SOC_E_PARAM on invalid parameter                                     *
   3208  */
   3209 int
   3210 soc_th_port_asf_detach(int unit, soc_port_t port)
   3211 {
   3212     _SOC_TH_UNIT_VALIDATE(unit);
   3213 
   3214     if (_soc_th_asf_ctrl[unit] == NULL) {
   3215         return SOC_E_INIT;
   3216     }
   3217 
   3218     SOC_IF_ERROR_RETURN
   3219         (soc_th_port_asf_mode_set(unit, port,
   3220                                   SOC_INFO(unit).port_init_speed[port],
   3221                                   _SOC_TH_ASF_MODE_SAF));
   3222 
   3223     if (soc_th_port_asf_valid(unit, port)) {
   3224         SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_ports, port);
   3225         SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->pause_restore, port);
   3226         if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_ss, port)) {
   3227             SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_ss, port);
   3228         } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_sf, port)) {
   3229             SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_sf, port);
   3230         } else if (SOC_PBMP_MEMBER(_soc_th_asf_ctrl[unit]->asf_fs, port)) {
   3231             SOC_PBMP_PORT_REMOVE(_soc_th_asf_ctrl[unit]->asf_fs, port);
   3232         }
   3233     }
   3234     return SOC_E_NONE;
   3235 }
   3236 
   3237 #endif /* BCM_TOMAHAWK_SUPPORT */
   3238