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 (84555B)


      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 Trident3 SKUs
      9  * Requires:  soc/trident3.h
     10  */
     11 
     12 #include <soc/trident3.h>
     13 
     14 #if defined(BCM_TRIDENT3_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 
     25 
     26 #define _SOC_TD3_ASF_CLASS_CNT  13      /* 0 for SAF, 13-15 are reserved. */
     27 #define _SOC_TD3_ASF_QUERY      0xfe
     28 #define _SOC_TD3_ASF_RETRV      0xff
     29 
     30 #define _SOC_TD3_CT_CLASS_TO_SPEED_MAP(ct_class) \
     31         _soc_td3_asf_cfg_tbl[(ct_class)].speed
     32 
     33 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
     34 
     35 #define _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(ct_class, floor) \
     36         do {                                            \
     37             if (!(((ct_class) >= (floor)) &&                \
     38                   ((ct_class) < _SOC_TD3_ASF_CLASS_CNT))) \
     39                 return SOC_E_PARAM;                         \
     40         } while (0)
     41 
     42 #define _SOC_TD3_ASF_PORT_VALIDATE(unit, port)      \
     43         do {                                        \
     44             if (IS_CPU_PORT(((unit)), (port)) ||    \
     45                 IS_LB_PORT(((unit)), (port)) ||     \
     46                 SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), (port))) \
     47                 return SOC_E_UNAVAIL;               \
     48         } while (0)
     49 
     50 /* EP Credits Outstanding */
     51 typedef struct _soc_td3_ep_credit_s {
     52     uint8 base_cells;      /* Baseline cells */
     53     uint8 pfc_op_cells;    /* PFC Optimized cells */
     54 } _soc_td3_ep_credit_t;
     55 
     56 /* CT FIFO Threshold and Depth */
     57 typedef struct _soc_td3_ct_fifo_profile_s {
     58     uint8 line_rate;       /* Line-rate profile */
     59     uint8 oversub;         /* General profile */
     60 } _soc_td3_ct_fifo_profile_t;
     61 
     62 typedef struct _soc_td3_ct_fifo_s {
     63     _soc_td3_ct_fifo_profile_t ss;      /* Same-Speed */
     64     _soc_td3_ct_fifo_profile_t sf;      /* Slow-to-Fast */
     65     _soc_td3_ct_fifo_profile_t fs;      /* Fast-to-Slow */
     66 }_soc_td3_ct_fifo_t;
     67 
     68 /* Bubble MOP */
     69 typedef struct _soc_td3_mop_s {
     70     uint8 line_rate;           /* Line-rate profile */
     71     uint8 oversub;             /* Oversub profile */
     72 } _soc_td3_mop_t;
     73 
     74 /* EDB Prebuffer */
     75 typedef struct _soc_td3_edb_prebuf_profile_s {
     76     uint8 saf;  /* prebuffer for store-and-forward. 16B granularity. */
     77     uint8 ct;   /* prebuffer for cut-through. 16B granularity. */
     78 } _soc_td3_edb_prebuf_profile_t;
     79 typedef struct _soc_td3_edb_prebuf_s {
     80     _soc_td3_edb_prebuf_profile_t line_rate;
     81     _soc_td3_edb_prebuf_profile_t oversub_161;  /* 1.61 Oversub */
     82     _soc_td3_edb_prebuf_profile_t oversub_2_1;  /* 2:1 Oversub */
     83 } _soc_td3_edb_prebuf_t;
     84 
     85 /* MMU Credit Thresholds */
     86 typedef struct _soc_td3_mmu_credit_threshold_profile_s {
     87     uint8 lo;              /* MMU High Credit Threshold */
     88     uint8 hi;              /* MMU Low Credit Threshold */
     89 } _soc_td3_mmu_credit_threshold_profile_t;
     90 typedef struct _soc_td3_mmu_credit_threshold_s {
     91     _soc_td3_mmu_credit_threshold_profile_t lr_os_161;  /* line-rate and os ratio <= 1.61 */
     92     _soc_td3_mmu_credit_threshold_profile_t os_2_1;     /* os ratio > 1.61 */
     93 } _soc_td3_mmu_credit_threshold_t;
     94 
     95 /* IFSAF Threshold */
     96 typedef struct _soc_td3_ifsaf_threshold_s {
     97     uint8 saf;
     98     uint8 ct;
     99 }_soc_td3_ifsaf_threshold_t;
    100 
    101 /* ASF core config */
    102 typedef struct _soc_td3_asf_core_cfg_s {
    103     int                              speed;
    104     uint8                            min_sp;                   /* Min. Src. Port Speed */
    105     uint8                            max_sp;                   /* Max. Src. Port Speed */
    106     uint8                            mmu_prebuffer;            /* MMU prebuffer */
    107     _soc_td3_ct_fifo_t               ct_fifo_threshold;        /* Same-speed CT FIFO Threshold */
    108     _soc_td3_ct_fifo_t               ct_fifo_depth;            /* Same-speed CT FIFO Depth */
    109     uint8                            fast_to_slow_acc;         /* Fast to slow CT Accumulation */
    110     _soc_td3_mop_t                   mop_enable;               /* Bubble MOP enable */
    111     _soc_td3_edb_prebuf_t            edb_prebuffer;            /* EDB prebuffer. xmit start cnt */
    112     _soc_td3_mmu_credit_threshold_t  mmu_credit_threshold;     /* MMU Credit Threshold */
    113     _soc_td3_ep_credit_t             ep_credit;                /* EP Credit */
    114     _soc_td3_ifsaf_threshold_t       ca_thresh;                /* CA_CT_CONTROL threshold0 */
    115     _soc_td3_ifsaf_threshold_t       ct_ok_thresh;             /* CT_THRESHOLD cut_through_ok */
    116     _soc_td3_ifsaf_threshold_t       unsat_thresh;             /* FORCE_SAF_CONFIG unsatisfied_threshold */
    117     /* NOTE: DON'T ALTER FIELD ORDER */
    118 } _soc_td3_asf_core_cfg_t;
    119 
    120 /* ASF ctrl */
    121 typedef struct _soc_td3_asf_ctrl_s {
    122     uint8                     init;
    123     pbmp_t                    asf_ports;
    124     pbmp_t                    pause_restore;
    125     pbmp_t                    asf_ss;
    126     pbmp_t                    asf_sf;
    127     pbmp_t                    asf_fs;
    128     soc_td3_asf_mem_profile_e asf_mem_profile;
    129 } _soc_td3_asf_ctrl_t;
    130 
    131 #ifdef BCM_WARM_BOOT_SUPPORT
    132 /* ASF Warmboot */
    133 typedef struct _soc_td3_asf_wb_s {
    134     int unit;
    135     _soc_td3_asf_ctrl_t asf_ctrl;
    136 } _soc_td3_asf_wb_t;
    137 #endif
    138 
    139 /* ASF Core Config Table  */
    140 static const _soc_td3_asf_core_cfg_t
    141 _soc_td3_asf_cfg_tbl[_SOC_TD3_ASF_CLASS_CNT] = {
    142     {    -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}},   /* SAF     */
    143     { 10000,  1, 10,  6, {{3, 10}, { 9, 16}, {3, 10}}, {{8, 18}, {13, 24}, {38, 48}}, 31, {0, 0}, {{7, 32}, {15, 49}, {18,  56}}, {{2,  4}, {2,  6}}, {11, 11}, {4, 4}, { 0,  0}, {12, 12}},   /* 10GE    */
    144     { 11000,  1, 10,  6, {{3, 10}, { 9, 16}, {3, 10}}, {{8, 18}, {13, 24}, {38, 48}}, 31, {0, 0}, {{7, 32}, {15, 49}, {18,  56}}, {{2,  4}, {2,  6}}, {11, 11}, {4, 4}, { 0,  0}, {12, 12}},   /* HG[11]  */
    145     { 20000,  3, 10,  6, {{3, 10}, { 9, 16}, {3, 10}}, {{8, 25}, {14, 31}, {32, 48}}, 24, {1, 1}, {{7, 13}, {15, 58}, {18,  67}}, {{2,  7}, {2, 11}}, {16, 13}, {4, 4}, { 0,  0}, {12, 12}},   /* 20GE    */
    146     { 21000,  3, 10,  6, {{3, 10}, { 9, 16}, {3, 10}}, {{8, 25}, {14, 31}, {32, 48}}, 24, {1, 1}, {{7, 13}, {15, 58}, {18,  67}}, {{2,  7}, {2, 11}}, {16, 13}, {4, 4}, { 0,  0}, {12, 12}},   /* HG[21]  */
    147     { 25000,  5, 10,  7, {{3, 12}, {11, 20}, {3, 12}}, {{8, 32}, {16, 40}, {29, 50}}, 21, {1, 1}, {{7, 72}, {15, 91}, {18, 100}}, {{3,  7}, {3, 11}}, {20, 18}, {4, 4}, {22, 22}, {26, 26}},   /* 25GE    */
    148     { 27000,  5, 10,  7, {{3, 12}, {11, 20}, {3, 12}}, {{8, 32}, {16, 40}, {29, 50}}, 21, {1, 1}, {{7, 72}, {15, 91}, {18, 100}}, {{3,  7}, {3, 11}}, {20, 18}, {4, 4}, {22, 22}, {26, 26}},   /* HG[27]  */
    149     { 40000,  7, 12,  4, {{3, 10}, { 7, 14}, {3, 10}}, {{8, 30}, {12, 34}, {32, 48}}, 24, {1, 1}, {{7, 13}, {15, 29}, {18,  36}}, {{4, 13}, {4, 21}}, {25, 19}, {4, 4}, { 0,  0}, {12, 12}},   /* 40GE    */
    150     { 42000,  7, 12,  4, {{3, 10}, { 7, 14}, {3, 10}}, {{8, 30}, {12, 34}, {32, 48}}, 24, {1, 1}, {{7, 13}, {15, 29}, {18,  36}}, {{4, 13}, {4, 21}}, {25, 19}, {4, 4}, { 0,  0}, {12, 12}},   /* HG[42]  */
    151     { 50000,  9, 12,  4, {{3, 12}, { 7, 16}, {3, 12}}, {{8, 40}, {12, 44}, {29, 50}}, 21, {1, 1}, {{7, 13}, {15, 29}, {18,  36}}, {{4, 15}, {4, 21}}, {26, 22}, {6, 6}, { 0,  0}, {18, 18}},   /* 50GE    */
    152     { 53000,  9, 12,  4, {{3, 12}, { 7, 16}, {3, 12}}, {{8, 40}, {12, 44}, {29, 50}}, 21, {1, 1}, {{7, 13}, {15, 29}, {18,  36}}, {{4, 15}, {4, 21}}, {26, 22}, {6, 6}, { 0,  0}, {18, 18}},   /* HG[53]  */
    153     {100000, 11, 12,  4, {{3, 11}, { 7, 15}, {3, 11}}, {{8, 45}, {11, 49}, {10, 49}},  3, {1, 1}, {{7, 13}, {15, 29}, {18,  36}}, {{8, 27}, {8, 29}}, {41, 38}, {5, 5}, { 0,  0}, {18, 18}},   /* 100GE   */
    154     {106000, 11, 12,  4, {{3, 11}, { 7, 15}, {3, 11}}, {{8, 45}, {11, 49}, {10, 49}},  3, {1, 1}, {{7, 13}, {15, 29}, {18,  36}}, {{8, 27}, {8, 29}}, {41, 38}, {5, 5}, { 0,  0}, {18, 18}}    /* HG[106] */
    155 };
    156 
    157 /* ASF Control */
    158 static _soc_td3_asf_ctrl_t*
    159 _soc_td3_asf_ctrl[SOC_MAX_NUM_DEVICES] = {NULL};
    160 
    161 /* ASF profile billboard */
    162 static const char *asf_profile_str[3] =
    163     {"removed of cut-thru capability",
    164      "capable of limited speed range cut-thru",
    165      "capable of extended speed range cut-thru"};
    166 
    167 
    168 /*
    169  * Cut-through class encoding:
    170  *   0 - SAF
    171  *   1 - 10GE
    172  *   2 - HG[11]
    173  *   3 - 20GE
    174  *   4 - 21[HG}
    175  *   5 - 25GE
    176  *   6 - HG[27]
    177  *   7 - 40GE
    178  *   8 - HG[42]
    179  *   9 - 50GE
    180  *   10 - HG[53]
    181  *   11 - 100GE
    182  *   12 - HG[106]
    183  */
    184 STATIC int
    185 _soc_td3_speed_to_ct_class_map(int speed)
    186 {
    187     int ct_class;
    188 
    189     if (1000 == speed) { /* 1G ports use same setting as 10G ports */
    190         speed = 10000;
    191     }
    192 
    193     for (ct_class = 0; ct_class < _SOC_TD3_ASF_CLASS_CNT; ct_class++) {
    194         if (_soc_td3_asf_cfg_tbl[ct_class].speed == speed) {
    195             return ct_class;
    196         }
    197     }
    198 
    199     return SOC_E_PARAM;
    200 }
    201 
    202 /******************************************************************************
    203  * Name: _soc_td3_port_asf_class_get                                          *
    204  * Description:                                                               *
    205  *     Get Cut-through class configured for the specified port                *
    206  * IN params:                                                                 *
    207  *     - Unit                                                                 *
    208  *     - Logical Port                                                         *
    209  *     - Port Speed                                                           *
    210  * OUT params:                                                                *
    211  *     - CT class                                                             *
    212  * Returns:                                                                   *
    213  *     - SOC_E_NONE on success                                                *
    214  *     - SOC_E_PARAM on invalid parameter                                     *
    215  */
    216 STATIC int
    217 _soc_td3_port_asf_class_get(
    218     int             unit,
    219     soc_port_t      port,
    220     OUT int* const  ct_class)
    221 {
    222     egr_ip_cut_thru_class_entry_t entry;
    223 
    224     if (!ct_class) {
    225         return SOC_E_PARAM;
    226     }
    227 
    228     sal_memset(&entry, 0, sizeof(egr_ip_cut_thru_class_entry_t));
    229     SOC_IF_ERROR_RETURN
    230         (READ_EGR_IP_CUT_THRU_CLASSm(unit, MEM_BLOCK_ALL, port, &entry));
    231     *ct_class = soc_mem_field32_get(unit, EGR_IP_CUT_THRU_CLASSm, &entry,
    232                                     CUT_THRU_CLASSf);
    233 
    234     return SOC_E_NONE;
    235 }
    236 
    237 /******************************************************************************
    238  * Name: _soc_td3_port_asf_class_init                                         *
    239  * Description:                                                               *
    240  *     Initialize Cut-through class for the specified port                    *
    241  * IN params:                                                                 *
    242  *     - Unit                                                                 *
    243  *     - Logical Port                                                         *
    244  *     - CT class                                                             *
    245  * Returns:                                                                   *
    246  *     - SOC_E_NONE on success                                                *
    247  *     - SOC_E_PARAM on invalid parameter                                     *
    248  */
    249 STATIC int
    250 _soc_td3_port_asf_class_init(
    251     int          unit,
    252     soc_port_t   port,
    253     int          ct_class)
    254 {
    255     egr_ip_cut_thru_class_entry_t entry;
    256 
    257     sal_memset(&entry, 0, sizeof(egr_ip_cut_thru_class_entry_t));
    258     soc_mem_field32_set(unit, EGR_IP_CUT_THRU_CLASSm, &entry,
    259                         CUT_THRU_CLASSf, ct_class);
    260     SOC_IF_ERROR_RETURN
    261         (WRITE_EGR_IP_CUT_THRU_CLASSm(unit, MEM_BLOCK_ALL, port, &entry));
    262 
    263     return SOC_E_NONE;
    264 }
    265 
    266 /******************************************************************************
    267  * Name: _soc_td3_port_asf_xmit_start_count_get                               *
    268  * Description:                                                               *
    269  *     Query or retrieve the XMIT Start Count for the specified source class  *
    270  *     of the port depending on the magic number passed in xmit_cnt           *
    271  * IN params:                                                                 *
    272  *     - Unit                                                                 *
    273  *     - Logical Port                                                         *
    274  *     - Source Port's Class                                                  *
    275  *     - Destination Port's CT Class                                          *
    276  *     - ASF Mode                                                             *
    277  * IN/OUT params:                                                             *
    278  *     - xmit_cnt : IN:  carries magic number for query / retrieve            *
    279  *     - xmit_cnt : OUT: contains a valid XMIT START COUNT for the            *
    280  *       source port class, on success                                        *
    281  * Returns:                                                                   *
    282  *     - SOC_E_NONE on success                                                *
    283  *     - SOC_E_PARAM on invalid parameter                                     *
    284  *     - SOC_E_INTERNAL on init/soc errors                                    *
    285  */
    286 STATIC int
    287 _soc_td3_port_asf_xmit_start_count_get(
    288     int                      unit,
    289     soc_port_t               port,
    290     int                      sc,
    291     int                      dc,
    292     soc_td3_asf_mode_e       mode,
    293     IN_OUT uint8* const      xmit_cnt)
    294 {
    295     soc_info_t                  *si;
    296     egr_xmit_start_count_entry_t entry;
    297     int                          ovs_ratio, port_idx;
    298     soc_pbmp_t                   td3_ports, line_rate_ports, ovs_161_ports;
    299     soc_port_t                   td3_port;
    300     int                          speed;
    301     int                          ct_class;
    302     int                          pipe;
    303     soc_mem_t                    config_mem = INVALIDm;
    304 
    305     if (!(si = &SOC_INFO(unit))) {
    306         return SOC_E_INTERNAL;
    307     }
    308 
    309     pipe = si->port_pipe[port];
    310     config_mem = SOC_MEM_UNIQUE_ACC(unit, EGR_XMIT_START_COUNTm)[pipe];
    311 
    312     if (_SOC_TD3_ASF_MODE_CFG_UPDATE == mode) { /* translate to valid mode */
    313         /* reverse map speed class to speed, to surmount speed deficit */
    314         SOC_IF_ERROR_RETURN(_soc_td3_port_asf_class_get(unit, port, &ct_class));
    315         _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(ct_class, 0);
    316         speed = _SOC_TD3_CT_CLASS_TO_SPEED_MAP(ct_class);
    317         SOC_IF_ERROR_RETURN(soc_td3_port_asf_mode_get(unit, port, speed, &mode));
    318     }
    319     if (!xmit_cnt ||
    320         !((mode >= _SOC_TD3_ASF_MODE_SAF) &&
    321           (mode <= _SOC_TD3_ASF_MODE_FAST_TO_SLOW))) {
    322         return SOC_E_PARAM;
    323     }
    324     _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(sc, 0);
    325     _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(dc, 0);
    326 
    327     if (_SOC_TD3_ASF_RETRV == *xmit_cnt) {
    328         *xmit_cnt = 0;
    329         port_idx = ((port % _TD3_TDM_DEV_PORTS_PER_PIPE) * 16) + sc;
    330 
    331         sal_memset(&entry, 0, sizeof(egr_xmit_start_count_entry_t));
    332         SOC_IF_ERROR_RETURN(soc_mem_read(unit, config_mem, MEM_BLOCK_ALL,
    333                                          port_idx, &entry));
    334         *xmit_cnt = soc_mem_field32_get(unit, config_mem,
    335                                         &entry, THRESHOLDf);
    336     } else if (_SOC_TD3_ASF_QUERY == *xmit_cnt) {
    337         *xmit_cnt = 0;
    338         SOC_PBMP_CLEAR(td3_ports);
    339         SOC_PBMP_ASSIGN(td3_ports, PBMP_E_ALL(unit));
    340         SOC_PBMP_OR(td3_ports, PBMP_HG_ALL(unit));
    341         SOC_PBMP_REMOVE(td3_ports, PBMP_MANAGEMENT(unit));
    342         SOC_PBMP_CLEAR(line_rate_ports);
    343         SOC_PBMP_CLEAR(ovs_161_ports);
    344 
    345         PBMP_ITER(td3_ports, td3_port) {
    346             if (SOC_PBMP_MEMBER(si->oversub_pbm, td3_port)) {
    347                 SOC_IF_ERROR_RETURN(
    348                     soc_td3_port_oversub_ratio_get(unit, td3_port, &ovs_ratio));
    349                 if (ovs_ratio < 1620) { /* oversub ratio <= 1.61 */
    350                     SOC_PBMP_PORT_ADD(ovs_161_ports, td3_port);
    351                 }
    352             } else { /* Line-rate */
    353                 SOC_PBMP_PORT_ADD(line_rate_ports, td3_port);
    354             }
    355         }
    356 
    357         /* if sc < dc, use SAF setting; else, use CT setting */
    358         if (SOC_PBMP_EQ(td3_ports, line_rate_ports)) {
    359             *xmit_cnt = (sc < dc) ?
    360                 _soc_td3_asf_cfg_tbl[dc].edb_prebuffer.line_rate.saf :
    361                 _soc_td3_asf_cfg_tbl[dc].edb_prebuffer.line_rate.ct;
    362         } else if (SOC_PBMP_EQ(td3_ports, ovs_161_ports)) {
    363             *xmit_cnt = (sc < dc) ?
    364                 _soc_td3_asf_cfg_tbl[dc].edb_prebuffer.oversub_161.saf :
    365                 _soc_td3_asf_cfg_tbl[dc].edb_prebuffer.oversub_161.ct;
    366         } else {
    367             *xmit_cnt = (sc < dc) ?
    368                 _soc_td3_asf_cfg_tbl[dc].edb_prebuffer.oversub_2_1.saf :
    369                 _soc_td3_asf_cfg_tbl[dc].edb_prebuffer.oversub_2_1.ct;
    370         }
    371 
    372     }
    373 
    374     return SOC_E_NONE;
    375 }
    376 
    377 /******************************************************************************
    378  * Name: _soc_td3_port_asf_mmu_prebuf_get                                     *
    379  * Description:                                                               *
    380  *     Query or retrieve MMU Prebuffer (Min Source Port XMIT Count) for the   *
    381  *     specified port depending on the magic number passed in mmu_prebuf      *
    382  * IN params:                                                                 *
    383  *     - Unit                                                                 *
    384  *     - Logical Port                                                         *
    385  *     - Port Speed                                                           *
    386  * IN/OUT params:                                                             *
    387  *     - mmu_prebuf : IN:  carries magic number for query / retrieve          *
    388  *     - mmu_prebuf : OUT: contains a valid Min Source Port XMIT Count on     *
    389  *       success                                                              *
    390  * Returns:                                                                   *
    391  *     - SOC_E_NONE on success                                                *
    392  *     - SOC_E_PARAM on invalid parameter                                     *
    393  *     - SOC_E_INTERNAL on init/soc errors                                    *
    394  */
    395 STATIC int
    396 _soc_td3_port_asf_mmu_prebuf_get(
    397     int                   unit,
    398     soc_port_t            port,
    399     int                   port_speed,
    400     IN_OUT uint8* const   mmu_prebuf)
    401 {
    402     uint32 rval;
    403     int    speed_encoding;
    404 
    405     _SOC_TD3_ASF_PORT_VALIDATE(unit, port);
    406     if (!mmu_prebuf) {
    407         return SOC_E_PARAM;
    408     }
    409 
    410     if (_SOC_TD3_ASF_RETRV == *mmu_prebuf) {
    411         *mmu_prebuf = 0;
    412 
    413         if (!_soc_td3_asf_ctrl[unit]->init) {
    414             return SOC_E_INTERNAL;
    415         }
    416 
    417         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
    418         *mmu_prebuf = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
    419                                         MIN_SRC_PORT_XMIT_CNTf);
    420     } else if (_SOC_TD3_ASF_QUERY == *mmu_prebuf) {
    421         *mmu_prebuf = 0;
    422         speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed);
    423         _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1);
    424 
    425         *mmu_prebuf =
    426             _soc_td3_asf_cfg_tbl[speed_encoding].mmu_prebuffer;
    427     }
    428 
    429     return SOC_E_NONE;
    430 }
    431 
    432 /******************************************************************************
    433  * Name: _soc_td3_port_asf_fifo_threshold_get                                 *
    434  * Description:                                                               *
    435  *     Query or retrieve FIFO Threshold for the specified port depending on   *
    436  *     the magic number passed in fifo_threshold                              *
    437  * IN params:                                                                 *
    438  *     - Unit                                                                 *
    439  *     - Logical Port                                                         *
    440  *     - Port Speed                                                           *
    441  *     - ASF Mode                                                             *
    442  * IN/OUT params:                                                             *
    443  *     - fifo_threshold : IN:  carries magic number for query / retrieve      *
    444  *     - fifo_threshold : OUT: contains a valid FIFO Threshold on success     *
    445  * Returns:                                                                   *
    446  *     - SOC_E_NONE on success                                                *
    447  *     - SOC_E_PARAM on invalid parameter                                     *
    448  *     - SOC_E_INTERNAL on init/soc errors                                    *
    449  */
    450 STATIC int
    451 _soc_td3_port_asf_fifo_threshold_get(
    452     int                   unit,
    453     soc_port_t            port,
    454     int                   port_speed,
    455     soc_td3_asf_mode_e    mode,
    456     IN_OUT uint8* const   fifo_threshold)
    457 {
    458     uint32 rval;
    459     int    speed_encoding;
    460     uint8  oversub;
    461 
    462     _SOC_TD3_ASF_PORT_VALIDATE(unit, port);
    463     if (!fifo_threshold) {
    464         return SOC_E_PARAM;
    465     }
    466 
    467     if (_SOC_TD3_ASF_RETRV == *fifo_threshold) {
    468         *fifo_threshold = 0;
    469 
    470         if (!_soc_td3_asf_ctrl[unit]->init) {
    471             return SOC_E_INTERNAL;
    472         }
    473 
    474         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
    475         *fifo_threshold = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
    476                                             FIFO_THRESHOLDf);
    477     } else if (_SOC_TD3_ASF_QUERY == *fifo_threshold) {
    478         *fifo_threshold = 0;
    479         speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed);
    480         _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1);
    481         oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0);
    482 
    483         switch(mode) {
    484             case _SOC_TD3_ASF_MODE_SAME_SPEED:
    485                 *fifo_threshold = (oversub ?
    486                     _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_threshold.ss.oversub :
    487                     _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_threshold.ss.line_rate);
    488                 break;
    489 
    490             case _SOC_TD3_ASF_MODE_SLOW_TO_FAST:
    491                 *fifo_threshold = (oversub ?
    492                     _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_threshold.sf.oversub :
    493                     _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_threshold.sf.line_rate);
    494                 break;
    495 
    496             case _SOC_TD3_ASF_MODE_FAST_TO_SLOW:
    497                 *fifo_threshold = (oversub ?
    498                     _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_threshold.fs.oversub :
    499                     _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_threshold.fs.line_rate);
    500                 break;
    501 
    502             default:
    503                 return SOC_E_PARAM;
    504         }
    505     }
    506 
    507     return SOC_E_NONE;
    508 }
    509 
    510 /******************************************************************************
    511  * Name: _soc_td3_port_asf_fifo_depth_get                                     *
    512  * Description:                                                               *
    513  *     Query or retrieve FIFO Depth for the specified port depending on the   *
    514  *     magic number passed in buf_sz                                          *
    515  * IN params:                                                                 *
    516  *     - Unit                                                                 *
    517  *     - Logical Port                                                         *
    518  *     - Port Speed                                                           *
    519  *     - ASF Mode                                                             *
    520  * IN/OUT params:                                                             *
    521  *     - fifo_depth : IN:  carries magic number for query/retrieve            *
    522  *     - fifo_depth : OUT: contains a valid FIFO Depth on success             *
    523  * Returns:                                                                   *
    524  *     - SOC_E_NONE on success                                                *
    525  *     - SOC_E_PARAM on invalid parameter                                     *
    526  *     - SOC_E_INTERNAL on init/soc errors                                    *
    527  */
    528 STATIC int
    529 _soc_td3_port_asf_fifo_depth_get(
    530     int                   unit,
    531     soc_port_t            port,
    532     int                   port_speed,
    533     soc_td3_asf_mode_e    mode,
    534     IN_OUT uint8* const   fifo_depth)
    535 {
    536     uint32 rval;
    537     int    speed_encoding;
    538     uint8  oversub;
    539 
    540     _SOC_TD3_ASF_PORT_VALIDATE(unit, port);
    541     if (!fifo_depth) {
    542         return SOC_E_PARAM;
    543     }
    544 
    545     if (_SOC_TD3_ASF_RETRV == *fifo_depth) {
    546         if (!_soc_td3_asf_ctrl[unit]->init) {
    547             return SOC_E_INTERNAL;
    548         }
    549 
    550         *fifo_depth = 0;
    551         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
    552         *fifo_depth = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
    553                                         FIFO_DEPTHf);
    554     } else if (_SOC_TD3_ASF_QUERY == *fifo_depth) {
    555         *fifo_depth = 0;
    556         speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed);
    557         _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1);
    558         oversub = (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port) ? 1 : 0);
    559 
    560         switch(mode) {
    561             case _SOC_TD3_ASF_MODE_SAME_SPEED:
    562                 *fifo_depth = (oversub ?
    563                     _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_depth.ss.oversub :
    564                     _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_depth.ss.line_rate);
    565                 break;
    566 
    567             case _SOC_TD3_ASF_MODE_SLOW_TO_FAST:
    568                 *fifo_depth = (oversub ?
    569                     _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_depth.sf.oversub :
    570                     _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_depth.sf.line_rate);
    571                 break;
    572 
    573             case _SOC_TD3_ASF_MODE_FAST_TO_SLOW:
    574                 *fifo_depth = (oversub ?
    575                     _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_depth.fs.oversub :
    576                     _soc_td3_asf_cfg_tbl[speed_encoding].ct_fifo_depth.fs.line_rate);
    577                 break;
    578 
    579             default:
    580                 return SOC_E_PARAM;
    581         }
    582     }
    583 
    584     return SOC_E_NONE;
    585 }
    586 
    587 /******************************************************************************
    588  * Name: _soc_td3_port_asf_speed_limits_get                                   *
    589  * Description:                                                               *
    590  *     Query or retrieve min & max source port speeds for the specified port  *
    591  *     depending on the magic number passed in min_sp &                       *
    592  *     max_sp                                                                 *
    593  * IN params:                                                                 *
    594  *     - Unit                                                                 *
    595  *     - Logical Port                                                         *
    596  *     - Port Speed                                                           *
    597  *     - ASF Mode                                                             *
    598  * IN/OUT params:                                                             *
    599  *     - min_sp : IN:  carries magic number for query / retrieve              *
    600  *     - min_sp : OUT: contains a valid min source port speed                 *
    601  *       on success                                                           *
    602  *     - max_sp : IN:  carries magic number for query / retrieve              *
    603  *     - max_sp : OUT: contains a valid max source port speed                 *
    604  *       on success                                                           *
    605  * Returns:                                                                   *
    606  *     - SOC_E_NONE on success                                                *
    607  *     - SOC_E_PARAM on invalid parameter                                     *
    608  *     - SOC_E_INTERNAL on init/soc errors                                    *
    609  */
    610 STATIC int
    611 _soc_td3_port_asf_speed_limits_get(
    612     int                   unit,
    613     soc_port_t            port,
    614     int                   port_speed,
    615     soc_td3_asf_mode_e    mode,
    616     IN_OUT uint8* const   min_sp,
    617     IN_OUT uint8* const   max_sp)
    618 {
    619     uint32 rval;
    620     int    speed_encoding;
    621 
    622     _SOC_TD3_ASF_PORT_VALIDATE(unit, port);
    623     if (!min_sp || !max_sp) {
    624         return SOC_E_PARAM;
    625     }
    626 
    627     if ((_SOC_TD3_ASF_RETRV == *min_sp) &&
    628         (_SOC_TD3_ASF_RETRV == *max_sp)) {
    629         *min_sp = *max_sp = 0;
    630         if (!_soc_td3_asf_ctrl[unit]->init) {
    631             return SOC_E_INTERNAL;
    632         }
    633 
    634         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
    635 
    636         /* MIN_SRC_PORT_SPEED */
    637         *min_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
    638                                     MIN_SRC_PORT_SPEEDf);
    639         /* MAX_SRC_PORT_SPEED */
    640         *max_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval,
    641                                     MAX_SRC_PORT_SPEEDf);
    642     } else if ((_SOC_TD3_ASF_QUERY == *min_sp) &&
    643                (_SOC_TD3_ASF_QUERY == *max_sp)) {
    644         *min_sp = *max_sp = 0;
    645         speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed);
    646         _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0);
    647 
    648         switch(mode) {
    649             case _SOC_TD3_ASF_MODE_SAF:
    650                 return SOC_E_NONE;
    651 
    652             case _SOC_TD3_ASF_MODE_SAME_SPEED:
    653                 *min_sp = *max_sp = speed_encoding;
    654                 break;
    655 
    656             case _SOC_TD3_ASF_MODE_SLOW_TO_FAST:
    657                 *min_sp = _soc_td3_asf_cfg_tbl[speed_encoding].min_sp;
    658                 *max_sp = speed_encoding;
    659                 break;
    660 
    661             case _SOC_TD3_ASF_MODE_FAST_TO_SLOW:
    662                 if (_SOC_TD3_ASF_MEM_PROFILE_SIMILAR ==
    663                         _soc_td3_asf_ctrl[unit]->asf_mem_profile) {
    664                     if (speed_encoding % 2) { /* IEEE */
    665                         /* HG counterpart */
    666                         *max_sp = speed_encoding + 1;
    667                     } else { /* HG */
    668                         *max_sp = speed_encoding;
    669                     }
    670                 } else if (_SOC_TD3_ASF_MEM_PROFILE_EXTREME ==
    671                                _soc_td3_asf_ctrl[unit]->asf_mem_profile) {
    672                     *max_sp = _soc_td3_asf_cfg_tbl[speed_encoding].max_sp;
    673                 }
    674                 *min_sp = speed_encoding;
    675                 break;
    676 
    677             default:
    678                 return SOC_E_PARAM;
    679         }
    680     }
    681 
    682     return SOC_E_NONE;
    683 }
    684 
    685 /******************************************************************************
    686  * Name: _soc_td3_asf_obm_ca_fifo_thresh_set                                  *
    687  * Description:                                                               *
    688  *     Configure Cell Assembly CT FIFO threshold for all OBM and Pipe         *
    689  *     instances.                                                             *
    690  * IN params:                                                                 *
    691  *     - Unit                                                                 *
    692  *     - Logical Port                                                         *
    693  *     - Cell Assembly CT Threshold                                           *
    694  * Returns:                                                                   *
    695  *     - SOC_E_NONE on success                                                *
    696  *     - SOC_E_* on internal errors                                           *
    697  */
    698 STATIC int
    699 _soc_td3_asf_obm_ca_fifo_thresh_set(
    700     int     unit,
    701     soc_port_t    port,
    702     uint8   ca_thresh)
    703 {
    704     int  obm, pipe;
    705     int  lane;
    706     uint32 rval;
    707     soc_info_t *si = &SOC_INFO(unit);
    708     uint32 thresh_field[4] = { THRESHOLD0f, THRESHOLD1f,
    709            THRESHOLD2f, THRESHOLD3f };
    710     uint32 port_ct_sel_field[4] = { PORT0_CT_SELf, PORT1_CT_SELf,
    711            PORT2_CT_SELf, PORT3_CT_SELf };
    712     uint32 idb_obm_ca_ct_ctrl_reg[][2] = {
    713            {IDB_OBM0_CA_CT_CONTROL_PIPE0r, IDB_OBM0_CA_CT_CONTROL_PIPE1r},
    714            {IDB_OBM1_CA_CT_CONTROL_PIPE0r, IDB_OBM1_CA_CT_CONTROL_PIPE1r},
    715            {IDB_OBM2_CA_CT_CONTROL_PIPE0r, IDB_OBM2_CA_CT_CONTROL_PIPE1r},
    716            {IDB_OBM3_CA_CT_CONTROL_PIPE0r, IDB_OBM3_CA_CT_CONTROL_PIPE1r},
    717            {IDB_OBM4_CA_CT_CONTROL_PIPE0r, IDB_OBM4_CA_CT_CONTROL_PIPE1r},
    718            {IDB_OBM5_CA_CT_CONTROL_PIPE0r, IDB_OBM5_CA_CT_CONTROL_PIPE1r},
    719            {IDB_OBM6_CA_CT_CONTROL_PIPE0r, IDB_OBM6_CA_CT_CONTROL_PIPE1r},
    720            {IDB_OBM7_CA_CT_CONTROL_PIPE0r, IDB_OBM7_CA_CT_CONTROL_PIPE1r},
    721            {IDB_OBM8_CA_CT_CONTROL_PIPE0r, IDB_OBM8_CA_CT_CONTROL_PIPE1r},
    722            {IDB_OBM9_CA_CT_CONTROL_PIPE0r, IDB_OBM9_CA_CT_CONTROL_PIPE1r},
    723            {IDB_OBM10_CA_CT_CONTROL_PIPE0r, IDB_OBM10_CA_CT_CONTROL_PIPE1r},
    724            {IDB_OBM11_CA_CT_CONTROL_PIPE0r, IDB_OBM11_CA_CT_CONTROL_PIPE1r},
    725            {IDB_OBM12_CA_CT_CONTROL_PIPE0r, IDB_OBM12_CA_CT_CONTROL_PIPE1r},
    726            {IDB_OBM13_CA_CT_CONTROL_PIPE0r, IDB_OBM13_CA_CT_CONTROL_PIPE1r},
    727            {IDB_OBM14_CA_CT_CONTROL_PIPE0r, IDB_OBM14_CA_CT_CONTROL_PIPE1r},
    728            {IDB_OBM15_CA_CT_CONTROL_PIPE0r, IDB_OBM15_CA_CT_CONTROL_PIPE1r},
    729         };
    730 
    731     /* Get lane, pipe & obm */
    732     SOC_IF_ERROR_RETURN
    733         (soc_trident3_port_obm_info_get(unit, port, &obm, &lane));
    734     pipe = si->port_pipe[port];
    735 
    736     SOC_IF_ERROR_RETURN(
    737         soc_reg32_get(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe],
    738                       REG_PORT_ANY, 0, &rval));
    739 
    740     soc_reg_field_set(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe], &rval,
    741               port_ct_sel_field[lane], lane);
    742     soc_reg_field_set(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe], &rval,
    743               thresh_field[lane], ca_thresh);
    744 
    745     SOC_IF_ERROR_RETURN(
    746         soc_reg32_set(unit, idb_obm_ca_ct_ctrl_reg[obm][pipe],
    747                               REG_PORT_ANY, 0, rval));
    748 
    749     return SOC_E_NONE;
    750 }
    751 
    752 /******************************************************************************
    753  * Name: _soc_td3_asf_obm_bubble_mop_set                                      *
    754  * Description:                                                               *
    755  *     Configure Bubble MOP for all OBM and Pipe Instances                    *
    756  * IN params:                                                                 *
    757  *     - Unit                                                                 *
    758  *     - Logical Port                                                         *
    759  *     - Bubble MOP Flag                                                      *
    760  * Returns:                                                                   *
    761  *     - SOC_E_NONE on success                                                *
    762  *     - SOC_E_* on internal errors                                           *
    763  */
    764 STATIC int
    765 _soc_td3_asf_obm_bubble_mop_set(
    766     int     unit,
    767     soc_port_t    port,
    768     uint8   bubble_mop_disable)
    769 {
    770     int  obm, pipe;
    771     int  lane;
    772     uint32 rval;
    773     soc_info_t *si = &SOC_INFO(unit);
    774     uint32 port_field[4] = {
    775             PORT0_BUBBLE_MOP_DISABLEf, PORT1_BUBBLE_MOP_DISABLEf,
    776             PORT2_BUBBLE_MOP_DISABLEf, PORT3_BUBBLE_MOP_DISABLEf };
    777     uint32 idb_obm_ctrl_reg[][2] = {
    778            {IDB_OBM0_CONTROL_PIPE0r, IDB_OBM0_CONTROL_PIPE1r},
    779            {IDB_OBM1_CONTROL_PIPE0r, IDB_OBM1_CONTROL_PIPE1r},
    780            {IDB_OBM2_CONTROL_PIPE0r, IDB_OBM2_CONTROL_PIPE1r},
    781            {IDB_OBM3_CONTROL_PIPE0r, IDB_OBM3_CONTROL_PIPE1r},
    782            {IDB_OBM4_CONTROL_PIPE0r, IDB_OBM4_CONTROL_PIPE1r},
    783            {IDB_OBM5_CONTROL_PIPE0r, IDB_OBM5_CONTROL_PIPE1r},
    784            {IDB_OBM6_CONTROL_PIPE0r, IDB_OBM6_CONTROL_PIPE1r},
    785            {IDB_OBM7_CONTROL_PIPE0r, IDB_OBM7_CONTROL_PIPE1r},
    786            {IDB_OBM8_CONTROL_PIPE0r, IDB_OBM8_CONTROL_PIPE1r},
    787            {IDB_OBM9_CONTROL_PIPE0r, IDB_OBM9_CONTROL_PIPE1r},
    788            {IDB_OBM10_CONTROL_PIPE0r, IDB_OBM10_CONTROL_PIPE1r},
    789            {IDB_OBM11_CONTROL_PIPE0r, IDB_OBM11_CONTROL_PIPE1r},
    790            {IDB_OBM12_CONTROL_PIPE0r, IDB_OBM12_CONTROL_PIPE1r},
    791            {IDB_OBM13_CONTROL_PIPE0r, IDB_OBM13_CONTROL_PIPE1r},
    792            {IDB_OBM14_CONTROL_PIPE0r, IDB_OBM14_CONTROL_PIPE1r},
    793            {IDB_OBM15_CONTROL_PIPE0r, IDB_OBM15_CONTROL_PIPE1r},
    794         };
    795 
    796     /* Get lane, pipe & obm */
    797     SOC_IF_ERROR_RETURN
    798         (soc_trident3_port_obm_info_get(unit, port, &obm, &lane));
    799     pipe = si->port_pipe[port];
    800 
    801     /* BubbleMOP */
    802     SOC_IF_ERROR_RETURN(
    803         soc_reg32_get(unit, idb_obm_ctrl_reg[obm][pipe],
    804                       REG_PORT_ANY, 0, &rval));
    805 
    806     soc_reg_field_set(unit, idb_obm_ctrl_reg[obm][pipe], &rval,
    807                       port_field[lane], bubble_mop_disable);
    808 
    809     SOC_IF_ERROR_RETURN(
    810         soc_reg32_set(unit, idb_obm_ctrl_reg[obm][pipe], REG_PORT_ANY,
    811                       0, rval));
    812 
    813     return SOC_E_NONE;
    814 }
    815 
    816 /******************************************************************************
    817  * Name: _soc_td3_asf_obm_ct_thresh_ok_set                                    *
    818  * Description:                                                               *
    819  *     Configure IDB OBM CT FIFO threshold OK for all OBM and Pipe            *
    820  *     instances.                                                             *
    821  * IN params:                                                                 *
    822  *     - Unit                                                                 *
    823  *     - Logical Port                                                         *
    824  *     - CT allowed if usage is less than or eq threshold                     *
    825  * Returns:                                                                   *
    826  *     - SOC_E_NONE on success                                                *
    827  *     - SOC_E_* on internal errors                                           *
    828  */
    829 STATIC int
    830 _soc_td3_asf_obm_ct_thresh_ok_set(
    831     int     unit,
    832     soc_port_t    port,
    833     uint32   ct_ok_thresh)
    834 {
    835     int  obm, pipe;
    836     int  lane;
    837     uint64 rval64;
    838     soc_info_t *si = &SOC_INFO(unit);
    839     uint32 idb_obm_ct_thresh_reg[][2] = {
    840            {IDB_OBM0_CT_THRESHOLD_PIPE0r, IDB_OBM0_CT_THRESHOLD_PIPE1r},
    841            {IDB_OBM1_CT_THRESHOLD_PIPE0r, IDB_OBM1_CT_THRESHOLD_PIPE1r},
    842            {IDB_OBM2_CT_THRESHOLD_PIPE0r, IDB_OBM2_CT_THRESHOLD_PIPE1r},
    843            {IDB_OBM3_CT_THRESHOLD_PIPE0r, IDB_OBM3_CT_THRESHOLD_PIPE1r},
    844            {IDB_OBM4_CT_THRESHOLD_PIPE0r, IDB_OBM4_CT_THRESHOLD_PIPE1r},
    845            {IDB_OBM5_CT_THRESHOLD_PIPE0r, IDB_OBM5_CT_THRESHOLD_PIPE1r},
    846            {IDB_OBM6_CT_THRESHOLD_PIPE0r, IDB_OBM6_CT_THRESHOLD_PIPE1r},
    847            {IDB_OBM7_CT_THRESHOLD_PIPE0r, IDB_OBM7_CT_THRESHOLD_PIPE1r},
    848            {IDB_OBM8_CT_THRESHOLD_PIPE0r, IDB_OBM8_CT_THRESHOLD_PIPE1r},
    849            {IDB_OBM9_CT_THRESHOLD_PIPE0r, IDB_OBM9_CT_THRESHOLD_PIPE1r},
    850            {IDB_OBM10_CT_THRESHOLD_PIPE0r, IDB_OBM10_CT_THRESHOLD_PIPE1r},
    851            {IDB_OBM11_CT_THRESHOLD_PIPE0r, IDB_OBM11_CT_THRESHOLD_PIPE1r},
    852            {IDB_OBM12_CT_THRESHOLD_PIPE0r, IDB_OBM12_CT_THRESHOLD_PIPE1r},
    853            {IDB_OBM13_CT_THRESHOLD_PIPE0r, IDB_OBM13_CT_THRESHOLD_PIPE1r},
    854            {IDB_OBM14_CT_THRESHOLD_PIPE0r, IDB_OBM14_CT_THRESHOLD_PIPE1r},
    855            {IDB_OBM15_CT_THRESHOLD_PIPE0r, IDB_OBM15_CT_THRESHOLD_PIPE1r},
    856         };
    857 
    858     /* Get lane, pipe & obm */
    859     SOC_IF_ERROR_RETURN
    860         (soc_trident3_port_obm_info_get(unit, port, &obm, &lane));
    861     pipe = si->port_pipe[port];
    862 
    863     SOC_IF_ERROR_RETURN(
    864         soc_reg64_get(unit, idb_obm_ct_thresh_reg[obm][pipe],
    865                       REG_PORT_ANY, lane, &rval64));
    866 
    867     soc_reg64_field32_set(unit, idb_obm_ct_thresh_reg[obm][pipe], &rval64,
    868                           CUT_THROUGH_OKf, ct_ok_thresh);
    869 
    870     SOC_IF_ERROR_RETURN(
    871         soc_reg64_set(unit, idb_obm_ct_thresh_reg[obm][pipe],
    872                       REG_PORT_ANY, lane, rval64));
    873 
    874     return SOC_E_NONE;
    875 }
    876 
    877 /******************************************************************************
    878  * Name: _soc_td3_asf_force_saf_config_set                                    *
    879  * Description:                                                               *
    880  *     Configure IDB_OBMx_FORCE_SAF_CONFIG register for all OBM and Pipe      *
    881  *     instances.                                                             *
    882  * IN params:                                                                 *
    883  *     - Unit                                                                 *
    884  *     - Logical Port                                                         *
    885  *     - Port speed                                                           *
    886  *     - ASF mode                                                             *
    887  * Returns:                                                                   *
    888  *     - SOC_E_NONE on success                                                *
    889  *     - SOC_E_* on internal errors                                           *
    890  */
    891 STATIC int
    892 _soc_td3_asf_force_saf_config_set(
    893     int     unit,
    894     soc_port_t    port,
    895     int           port_speed,
    896     soc_td3_asf_mode_e   mode)
    897 {
    898     int obm, pipe;
    899     int lane;
    900     int ct_class;
    901     uint32 rval;
    902     uint32 field_a;
    903     uint32 field_b;
    904     uint32 field_c;
    905     soc_info_t *si = &SOC_INFO(unit);
    906     uint32 idb_obm_force_saf_config_reg[][2] = {
    907            {IDB_OBM0_DBG_A_PIPE0r, IDB_OBM0_DBG_A_PIPE1r},
    908            {IDB_OBM1_DBG_A_PIPE0r, IDB_OBM1_DBG_A_PIPE1r},
    909            {IDB_OBM2_DBG_A_PIPE0r, IDB_OBM2_DBG_A_PIPE1r},
    910            {IDB_OBM3_DBG_A_PIPE0r, IDB_OBM3_DBG_A_PIPE1r},
    911            {IDB_OBM4_DBG_A_PIPE0r, IDB_OBM4_DBG_A_PIPE1r},
    912            {IDB_OBM5_DBG_A_PIPE0r, IDB_OBM5_DBG_A_PIPE1r},
    913            {IDB_OBM6_DBG_A_PIPE0r, IDB_OBM6_DBG_A_PIPE1r},
    914            {IDB_OBM7_DBG_A_PIPE0r, IDB_OBM7_DBG_A_PIPE1r},
    915            {IDB_OBM8_DBG_A_PIPE0r, IDB_OBM8_DBG_A_PIPE1r},
    916            {IDB_OBM9_DBG_A_PIPE0r, IDB_OBM9_DBG_A_PIPE1r},
    917            {IDB_OBM10_DBG_A_PIPE0r, IDB_OBM10_DBG_A_PIPE1r},
    918            {IDB_OBM11_DBG_A_PIPE0r, IDB_OBM11_DBG_A_PIPE1r},
    919            {IDB_OBM12_DBG_A_PIPE0r, IDB_OBM12_DBG_A_PIPE1r},
    920            {IDB_OBM13_DBG_A_PIPE0r, IDB_OBM13_DBG_A_PIPE1r},
    921            {IDB_OBM14_DBG_A_PIPE0r, IDB_OBM14_DBG_A_PIPE1r},
    922            {IDB_OBM15_DBG_A_PIPE0r, IDB_OBM15_DBG_A_PIPE1r},
    923         };
    924 
    925     field_a = 1;
    926     field_b = 1;
    927 
    928     ct_class = _soc_td3_speed_to_ct_class_map(port_speed);
    929     _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(ct_class, 0);
    930     field_c = (mode == _SOC_TD3_ASF_MODE_SAF) ?
    931               _soc_td3_asf_cfg_tbl[ct_class].unsat_thresh.saf :
    932               _soc_td3_asf_cfg_tbl[ct_class].unsat_thresh.ct;
    933 
    934     /* Get lane, pipe & obm */
    935     SOC_IF_ERROR_RETURN
    936         (soc_trident3_port_obm_info_get(unit, port, &obm, &lane));
    937     pipe = si->port_pipe[port];
    938 
    939     SOC_IF_ERROR_RETURN(
    940         soc_reg32_get(unit, idb_obm_force_saf_config_reg[obm][pipe],
    941                       REG_PORT_ANY, lane, &rval));
    942 
    943     soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval,
    944               FIELD_Af, field_a);
    945     soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval,
    946               FIELD_Bf, field_b);
    947     soc_reg_field_set(unit, idb_obm_force_saf_config_reg[obm][pipe], &rval,
    948               FIELD_Cf, field_c);
    949 
    950     SOC_IF_ERROR_RETURN(
    951         soc_reg32_set(unit, idb_obm_force_saf_config_reg[obm][pipe],
    952                               REG_PORT_ANY, lane, rval));
    953 
    954     return SOC_E_NONE;
    955 }
    956 
    957 int
    958 soc_td3_port_asf_valid(
    959     int unit,
    960     soc_port_t port)
    961 {
    962     if (IS_CPU_PORT(((unit)), (port)) || IS_LB_PORT(((unit)), (port)) || \
    963         SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), (port))) {
    964         return FALSE;
    965     } else {
    966         return TRUE;
    967     }
    968 }
    969 
    970 /*************************************
    971  * Init Start Routine                *
    972  *    - Allocates ASF Ctrl structure *
    973  *      for the given unit           *
    974  */
    975 int
    976 soc_td3_asf_init_start(int unit)
    977 {
    978     if (!(_soc_td3_asf_ctrl[unit] =
    979               sal_alloc(sizeof(_soc_td3_asf_ctrl_t), "TD3 ASF Ctrl Area"))) {
    980         return SOC_E_MEMORY;
    981     }
    982     sal_memset(_soc_td3_asf_ctrl[unit], 0, sizeof(_soc_td3_asf_ctrl_t));
    983 
    984     /* ASF_MEM_PROFILE */
    985     _soc_td3_asf_ctrl[unit]->asf_mem_profile =
    986         soc_property_get(unit, spn_ASF_MEM_PROFILE,
    987                          _SOC_TD3_ASF_MEM_PROFILE_SIMILAR);
    988     if (!((_soc_td3_asf_ctrl[unit]->asf_mem_profile >= 0) &&
    989           (_soc_td3_asf_ctrl[unit]->asf_mem_profile < 3))) {
    990         _soc_td3_asf_ctrl[unit]->asf_mem_profile = 2;
    991     }
    992 
    993     return SOC_E_NONE;
    994 }
    995 
    996 /************************
    997  * Init Complete Marker *
    998  */
    999 int
   1000 soc_td3_asf_init_done(int unit)
   1001 {
   1002     if (_soc_td3_asf_ctrl[unit]) {
   1003         _soc_td3_asf_ctrl[unit]->init = 1;
   1004         LOG_CLI((BSL_META_U(unit, "*** unit %d: ports %s\n"), unit,
   1005                  asf_profile_str[_soc_td3_asf_ctrl[unit]->asf_mem_profile]));
   1006         return SOC_E_NONE;
   1007     } else {
   1008         return SOC_E_INTERNAL;
   1009     }
   1010 }
   1011 
   1012 /******************************************************************************
   1013  * Name: soc_td3_port_asf_init                                                *
   1014  * Description:                                                               *
   1015  *     Initialize ASF primitives for the specified port                       *
   1016  * IN params:                                                                 *
   1017  *     - Unit                                                                 *
   1018  *     - Logical Port                                                         *
   1019  *     - Port Speed                                                           *
   1020  *     - ASF Mode                                                             *
   1021  * Returns:                                                                   *
   1022  *     - SOC_E_NONE on success                                                *
   1023  *     - SOC_E_PARAM on invalid parameter                                     *
   1024  *     - SOC_E_INIT on init/soc errors                                        *
   1025  */
   1026 int
   1027 soc_td3_port_asf_init(
   1028     int                 unit,
   1029     soc_port_t          port,
   1030     int                 speed,
   1031     soc_td3_asf_mode_e  mode)
   1032 {
   1033     SOC_IF_ERROR_RETURN(soc_td3_port_asf_mode_set(unit, port, speed, mode));
   1034 
   1035     return SOC_E_NONE;
   1036 }
   1037 
   1038 /************************
   1039  * Init Start Routine   *
   1040  */
   1041 int
   1042 soc_td3_asf_deinit(int unit)
   1043 {
   1044     if (_soc_td3_asf_ctrl[unit]) {
   1045         sal_free(_soc_td3_asf_ctrl[unit]);
   1046         _soc_td3_asf_ctrl[unit] = NULL;
   1047     }
   1048 
   1049     return SOC_E_NONE;
   1050 }
   1051 
   1052 /******************************************************************************
   1053  * Name: _soc_td3_port_asf_xmit_start_count_set                               *
   1054  * Description:                                                               *
   1055  *     Initialize XMIT START COUNT memory for all the source class for the    *
   1056  *     specified port                                                         *
   1057  *     Support CPU and LB ports for init setting.                             *
   1058  * IN params:                                                                 *
   1059  *     - Unit                                                                 *
   1060  *     - Logical Port                                                         *
   1061  *     - Port Speed                                                           *
   1062  *     - ASF Mode                                                             *
   1063  *     - Extra cells (if any, to be added to xmit start count)                *
   1064  * Returns:                                                                   *
   1065  *     - SOC_E_NONE on success                                                *
   1066  *     - SOC_E_PARAM on invalid parameter                                     *
   1067  */
   1068 int
   1069 soc_td3_port_asf_xmit_start_count_set(
   1070     int                  unit,
   1071     soc_port_t           port,
   1072     int                  port_speed,
   1073     soc_td3_asf_mode_e   mode,
   1074     uint8                extra_cells)
   1075 {
   1076     egr_xmit_start_count_entry_t entry;
   1077     soc_info_t *si = &SOC_INFO(unit);
   1078     uint8      xmit_cnt = 0;
   1079     int        rv, src_class, dst_class = 0, port_idx;
   1080     int        pipe;
   1081     soc_mem_t  config_mem = INVALIDm;
   1082 
   1083     if (!((mode >= _SOC_TD3_ASF_MODE_SAF) &&
   1084           (mode <= _SOC_TD3_ASF_MODE_CFG_UPDATE))) {
   1085         return SOC_E_PARAM;
   1086     }
   1087 
   1088     if (IS_CPU_PORT(unit, port)) {
   1089         port_speed = 20000;
   1090     }
   1091     if (IS_LB_PORT(unit, port)) {
   1092         port_speed = 100000;
   1093     }
   1094 
   1095     if (_SOC_TD3_ASF_MODE_CFG_UPDATE != mode) {
   1096         if (SOC_E_PARAM == (dst_class = _soc_td3_speed_to_ct_class_map(port_speed))) {
   1097             /* port on a speed unsupported by CT - will resort to SAF */
   1098             dst_class = 0;
   1099         }
   1100     }
   1101 
   1102     sal_memset(&entry, 0, sizeof(egr_xmit_start_count_entry_t));
   1103 
   1104     pipe = si->port_pipe[port];
   1105     config_mem = SOC_MEM_UNIQUE_ACC(unit, EGR_XMIT_START_COUNTm)[pipe];
   1106 
   1107     for (src_class = 0; src_class < _SOC_TD3_ASF_CLASS_CNT; src_class++) {
   1108         if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
   1109             xmit_cnt = _soc_td3_asf_cfg_tbl[dst_class].edb_prebuffer.line_rate.saf;
   1110         } else {
   1111             if (_SOC_TD3_ASF_MODE_CFG_UPDATE == mode) {
   1112                 xmit_cnt = _SOC_TD3_ASF_RETRV;
   1113             } else {
   1114                 xmit_cnt = _SOC_TD3_ASF_QUERY;
   1115             }
   1116 
   1117             rv = _soc_td3_port_asf_xmit_start_count_get(unit, port, src_class,
   1118                                                         dst_class, mode, &xmit_cnt);
   1119 
   1120             if (SOC_FAILURE(rv)) {
   1121                 if (SOC_E_UNAVAIL == rv) {
   1122                     xmit_cnt = _soc_td3_asf_cfg_tbl[dst_class].edb_prebuffer.oversub_2_1.saf;
   1123                 } else {
   1124                     return rv;
   1125                 }
   1126             }
   1127 
   1128             xmit_cnt += extra_cells;
   1129         }
   1130 
   1131         port_idx = ((port % _TD3_TDM_DEV_PORTS_PER_PIPE) * 16) + src_class;
   1132 
   1133         soc_mem_field32_set(unit, config_mem, &entry,
   1134                             THRESHOLDf, xmit_cnt);
   1135         SOC_IF_ERROR_RETURN(soc_mem_write(unit, config_mem, MEM_BLOCK_ALL,
   1136                                           port_idx, &entry));
   1137     }
   1138 
   1139     return SOC_E_NONE;
   1140 }
   1141 
   1142 /******************************************************************************
   1143  * Name: soc_td3_port_asf_mode_get                                            *
   1144  * Description:                                                               *
   1145  *     Retrieve the ASF/SAF mode configured on the specified port             *
   1146  * IN params:                                                                 *
   1147  *     - Unit                                                                 *
   1148  *     - Logical Port                                                         *
   1149  *     - Port Speed                                                           *
   1150  * OUT params:                                                                *
   1151  *     - mode : OUT: contains the ASF/SAF mode confiugred on the specified    *
   1152  *       port on success                                                      *
   1153  * Returns:                                                                   *
   1154  *     - SOC_E_NONE on success                                                *
   1155  *     - SOC_E_PARAM on invalid parameter                                     *
   1156  *     - SOC_E_INTERNAL on init/soc errors                                    *
   1157  */
   1158 int
   1159 soc_td3_port_asf_mode_get(
   1160     int                            unit,
   1161     soc_port_t                     port,
   1162     int                            port_speed,
   1163     OUT soc_td3_asf_mode_e* const  mode)
   1164 {
   1165     uint32 rval;
   1166     int    speed_encoding;
   1167     uint8  max_sp, min_sp, enable;
   1168 
   1169     if (!mode) {
   1170         return SOC_E_INTERNAL;
   1171     }
   1172 
   1173     if (soc_td3_port_asf_valid(unit, port)) {
   1174         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   1175         enable = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, ENABLEf);
   1176         if (!enable) {
   1177             *mode = _SOC_TD3_ASF_MODE_SAF;
   1178             return SOC_E_NONE;
   1179         }
   1180     } else {
   1181         *mode = _SOC_TD3_ASF_MODE_SAF;
   1182         return SOC_E_NONE;
   1183     }
   1184 
   1185     if (!_soc_td3_asf_ctrl[unit] || !_soc_td3_asf_ctrl[unit]->init) {
   1186         return SOC_E_INTERNAL;
   1187     }
   1188 
   1189     max_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, MAX_SRC_PORT_SPEEDf);
   1190     min_sp = soc_reg_field_get(unit, ASF_EPORT_CFGr, rval, MIN_SRC_PORT_SPEEDf);
   1191 
   1192     speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed);
   1193     _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 1);
   1194 
   1195     if (max_sp && min_sp) {
   1196         if (max_sp == min_sp) {
   1197             if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_sf, port)) {
   1198                 *mode = _SOC_TD3_ASF_MODE_SLOW_TO_FAST;
   1199             } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_fs, port)) {
   1200                 *mode = _SOC_TD3_ASF_MODE_FAST_TO_SLOW;
   1201             } else {
   1202                 *mode = _SOC_TD3_ASF_MODE_SAME_SPEED;
   1203             }
   1204         } else if (max_sp == speed_encoding) {
   1205             *mode = _SOC_TD3_ASF_MODE_SLOW_TO_FAST;
   1206         } else if (min_sp == speed_encoding) {
   1207             *mode = _SOC_TD3_ASF_MODE_FAST_TO_SLOW;
   1208         } else {
   1209             *mode = _SOC_TD3_ASF_MODE_UNSUPPORTED;
   1210             return SOC_E_UNAVAIL;
   1211         }
   1212     } else {
   1213         *mode = _SOC_TD3_ASF_MODE_UNSUPPORTED;
   1214         return SOC_E_UNAVAIL;
   1215     }
   1216 
   1217     return SOC_E_NONE;
   1218 }
   1219 
   1220 /******************************************************************************
   1221  * Name: soc_td3_port_asf_mode_set                                            *
   1222  * Description:                                                               *
   1223  *     Configure specified ASF/SAF modes on the specified port                *
   1224  * IN params:                                                                 *
   1225  *     - Unit                                                                 *
   1226  *     - Logical Port                                                         *
   1227  *     - Port Speed                                                           *
   1228  *     - ASF Mode                                                             *
   1229  * OUT params:                                                                *
   1230  *     - None                                                                 *
   1231  * Returns:                                                                   *
   1232  *     - SOC_E_NONE on success                                                *
   1233  *     - SOC_E_PARAM on invalid parameter                                     *
   1234  *     - SOC_E_INTERNAL on init/soc errors                                    *
   1235  */
   1236 int
   1237 soc_td3_port_asf_mode_set(
   1238     int                 unit,
   1239     soc_port_t          port,
   1240     int                 port_speed,
   1241     soc_td3_asf_mode_e  mode)
   1242 {
   1243     int           ret, speed_encoding = 0;
   1244     uint8         min_sp = 0, max_sp = 0;
   1245     uint8         fifo_threshold = 0, fifo_depth = 0, mmu_prebuf = 0;
   1246     uint8         oversub = 0;
   1247     uint32        rval;
   1248     soc_info_t   *si = NULL;
   1249     int           init = 0;
   1250 
   1251     if (_SOC_TD3_ASF_MODE_INIT == mode) {
   1252         init = 1;
   1253         mode = _SOC_TD3_ASF_MODE_SAF;
   1254     }
   1255     if ((!init) && (!_soc_td3_asf_ctrl[unit] ||
   1256         !_soc_td3_asf_ctrl[unit]->init || !(si = &SOC_INFO(unit)))) {
   1257         return SOC_E_INTERNAL;
   1258     }
   1259     if (!_soc_td3_asf_ctrl[unit]->asf_mem_profile) { /* no cut-thru profile */
   1260         if ((_SOC_TD3_ASF_MODE_SAF != mode) &&
   1261             (_SOC_TD3_ASF_MODE_CFG_UPDATE != mode)) {
   1262             return SOC_E_UNAVAIL;
   1263         }
   1264     }
   1265     if (!soc_td3_port_asf_valid(unit, port)) {
   1266         if ((_SOC_TD3_ASF_MODE_SAF != mode) &&
   1267             (_SOC_TD3_ASF_MODE_CFG_UPDATE != mode)) {
   1268             return SOC_E_UNAVAIL;
   1269         }
   1270         SOC_IF_ERROR_RETURN(
   1271             soc_td3_port_asf_xmit_start_count_set(unit, port, port_speed,
   1272                                                   mode, 0));
   1273         return SOC_E_NONE;
   1274     }
   1275 
   1276     speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed);
   1277     _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0);
   1278 
   1279     /* min. and max. src port speeds */
   1280     if (_SOC_TD3_ASF_MODE_CFG_UPDATE != mode) {
   1281         min_sp = max_sp = _SOC_TD3_ASF_QUERY;
   1282         SOC_IF_ERROR_RETURN(
   1283             _soc_td3_port_asf_speed_limits_get(unit, port, port_speed, mode,
   1284                                               &min_sp, &max_sp));
   1285     }
   1286 
   1287     /* mode specific configurations */
   1288     switch(mode) {
   1289         case _SOC_TD3_ASF_MODE_SAF:
   1290             break;
   1291 
   1292         case _SOC_TD3_ASF_MODE_SAME_SPEED:
   1293             /* Cannot set cut-through mode for 1G ports */
   1294             if (1000 == port_speed) {
   1295                 return SOC_E_UNAVAIL;
   1296             }
   1297 
   1298             /* verify mode specific conformance */
   1299             if (min_sp != max_sp) {
   1300                 return SOC_E_PARAM;
   1301             }
   1302             break;
   1303 
   1304         case _SOC_TD3_ASF_MODE_SLOW_TO_FAST:
   1305             /* Cannot set cut-through mode for 1G ports */
   1306             if (1000 == port_speed) {
   1307                 return SOC_E_UNAVAIL;
   1308             }
   1309 
   1310             /* verify mode specific conformance */
   1311             if ( !((min_sp >=
   1312                     _soc_td3_asf_cfg_tbl[speed_encoding].min_sp) &&
   1313                    (max_sp == speed_encoding)) ) {
   1314                 return SOC_E_PARAM;
   1315             }
   1316             break;
   1317 
   1318         case _SOC_TD3_ASF_MODE_FAST_TO_SLOW:
   1319             /* Cannot set cut-through mode for 1G ports */
   1320             if (1000 == port_speed) {
   1321                 return SOC_E_UNAVAIL;
   1322             }
   1323 
   1324             /* verify mode specific conformance */
   1325             if ( !((max_sp <=
   1326                     _soc_td3_asf_cfg_tbl[speed_encoding].max_sp) &&
   1327                    (min_sp == speed_encoding)) ) {
   1328                 return SOC_E_PARAM;
   1329             }
   1330             break;
   1331 
   1332         case _SOC_TD3_ASF_MODE_CFG_UPDATE:
   1333             mode = _SOC_TD3_ASF_MODE_SAF;
   1334 
   1335             /* disable CT first */
   1336             SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   1337             soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   1338                               FIFO_THRESHOLDf, 0);
   1339             SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   1340             sal_usleep(1);
   1341             soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, ENABLEf, 0);
   1342             SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   1343 
   1344             /* update new settings & re-enable */
   1345             ret = soc_td3_port_asf_mode_set(unit, port, port_speed, mode);
   1346             return ret;
   1347 
   1348         default:
   1349             return SOC_E_PARAM;
   1350     }
   1351 
   1352     /* ASF_IPORT_CFG */
   1353     SOC_IF_ERROR_RETURN(READ_ASF_IPORT_CFGr(unit, port, &rval));
   1354     soc_reg_field_set(unit, ASF_IPORT_CFGr, &rval, ASF_PORT_SPEEDf,
   1355                       port_speed == 1000 ? 0: speed_encoding);
   1356     SOC_IF_ERROR_RETURN(WRITE_ASF_IPORT_CFGr(unit, port, rval));
   1357 
   1358     /* init CT class */
   1359     SOC_IF_ERROR_RETURN(_soc_td3_port_asf_class_init(unit, port, speed_encoding));
   1360 
   1361     if (_SOC_TD3_ASF_MODE_SAF != mode) {
   1362         /* Oversub */
   1363         oversub =  (SOC_PBMP_MEMBER(si->oversub_pbm, port) ? 1 : 0);
   1364 
   1365         /* FIFO threshold */
   1366         fifo_threshold = _SOC_TD3_ASF_QUERY;
   1367         SOC_IF_ERROR_RETURN(
   1368             _soc_td3_port_asf_fifo_threshold_get(unit, port, port_speed, mode,
   1369                                                  &fifo_threshold));
   1370 
   1371         /* FIFO depth */
   1372         fifo_depth = _SOC_TD3_ASF_QUERY;
   1373         SOC_IF_ERROR_RETURN(
   1374             _soc_td3_port_asf_fifo_depth_get(unit, port, port_speed, mode,
   1375                                              &fifo_depth));
   1376 
   1377         /* MMU Prebuffer */
   1378         mmu_prebuf = _SOC_TD3_ASF_QUERY;
   1379         SOC_IF_ERROR_RETURN(
   1380             _soc_td3_port_asf_mmu_prebuf_get(unit, port, port_speed,
   1381                                              &mmu_prebuf));
   1382 
   1383         SOC_IF_ERROR_RETURN(
   1384             soc_td3_port_asf_params_set(unit, port, port_speed, mode));
   1385 
   1386         /* drain the port CT FIFO */
   1387         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   1388         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, ENABLEf, 1);
   1389         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_THRESHOLDf, 0);
   1390         SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   1391 
   1392         sal_usleep(1);
   1393 
   1394         /* enable cut-through */
   1395         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, OVERSUBf, oversub);
   1396         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   1397                           MAX_SRC_PORT_SPEEDf, max_sp);
   1398         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   1399                           MIN_SRC_PORT_SPEEDf, min_sp);
   1400         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   1401                           MIN_SRC_PORT_XMIT_CNTf, mmu_prebuf);
   1402         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   1403                           FIFO_THRESHOLDf, fifo_threshold);
   1404         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_DEPTHf,
   1405                           fifo_depth);
   1406         SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   1407 
   1408         /* bookkeeping */
   1409         if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_ss, port)) {
   1410             SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_ss, port);
   1411         } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_sf, port)) {
   1412             SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_sf, port);
   1413         } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_fs, port)) {
   1414             SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_fs, port);
   1415         }
   1416         SOC_PBMP_PORT_ADD(_soc_td3_asf_ctrl[unit]->asf_ports, port);
   1417         if (_SOC_TD3_ASF_MODE_SAME_SPEED == mode) {
   1418             SOC_PBMP_PORT_ADD(_soc_td3_asf_ctrl[unit]->asf_ss, port);
   1419         } else if (_SOC_TD3_ASF_MODE_SLOW_TO_FAST== mode) {
   1420             SOC_PBMP_PORT_ADD(_soc_td3_asf_ctrl[unit]->asf_sf, port);
   1421         } else if (_SOC_TD3_ASF_MODE_FAST_TO_SLOW== mode) {
   1422             SOC_PBMP_PORT_ADD(_soc_td3_asf_ctrl[unit]->asf_fs, port);
   1423         }
   1424     } else {   /* Store and Forward */
   1425         fifo_depth = 0x40;
   1426         fifo_threshold = 0x20;
   1427         mmu_prebuf = 0;
   1428         min_sp = 0;
   1429         max_sp = 0;
   1430         oversub = 0;
   1431 
   1432         SOC_IF_ERROR_RETURN(
   1433             soc_td3_port_asf_params_set(unit, port, port_speed, mode));
   1434 
   1435         /* ASF_EPORT_CFG */
   1436         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   1437         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_THRESHOLDf, 0);
   1438         SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   1439 
   1440         sal_usleep(1);
   1441 
   1442         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, ENABLEf, 0);
   1443         SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   1444 
   1445         /* update SAF configs */
   1446         SOC_IF_ERROR_RETURN(READ_ASF_EPORT_CFGr(unit, port, &rval));
   1447         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, OVERSUBf, oversub);
   1448         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   1449                           MAX_SRC_PORT_SPEEDf, max_sp);
   1450         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   1451                           MIN_SRC_PORT_SPEEDf, min_sp);
   1452         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   1453                           MIN_SRC_PORT_XMIT_CNTf, mmu_prebuf);
   1454         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval,
   1455                           FIFO_THRESHOLDf, fifo_threshold);
   1456         soc_reg_field_set(unit, ASF_EPORT_CFGr, &rval, FIFO_DEPTHf,
   1457                           fifo_depth);
   1458         SOC_IF_ERROR_RETURN(WRITE_ASF_EPORT_CFGr(unit, port, rval));
   1459 
   1460         /* bookkeeping */
   1461         SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_ports, port);
   1462         if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_ss, port)) {
   1463             SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_ss, port);
   1464         } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_sf, port)) {
   1465             SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_sf, port);
   1466         } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_fs, port)) {
   1467             SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_fs, port);
   1468         }
   1469     }
   1470 
   1471     return SOC_E_NONE;
   1472 }
   1473 
   1474 /******************************************************************************
   1475  * Name: soc_td3_port_asf_params_set                                          *
   1476  * Description:                                                               *
   1477  *     Configure ASF/SAF mode params on the specified port                    *
   1478  * IN params:                                                                 *
   1479  *     - Unit                                                                 *
   1480  *     - Logical Port                                                         *
   1481  *     - Port Speed                                                           *
   1482  *     - ASF Mode                                                             *
   1483  * OUT params:                                                                *
   1484  *     - None                                                                 *
   1485  * Returns:                                                                   *
   1486  *     - SOC_E_NONE on success                                                *
   1487  *     - SOC_E_PARAM on invalid parameter                                     *
   1488  *     - SOC_E_INTERNAL on init/soc errors                                    *
   1489  */
   1490 int
   1491 soc_td3_port_asf_params_set(
   1492     int                 unit,
   1493     soc_port_t          port,
   1494     int                 port_speed,
   1495     soc_td3_asf_mode_e  mode)
   1496 {
   1497     uint32        mmu_ep_credits_hi = 0, mmu_ep_credits_lo = 0;
   1498     uint32        egr_mmu_cell_credits = 0;
   1499     uint32        rval;
   1500     uint32        ct_ok_thresh = 0;
   1501     uint8         ca_thresh = 0;
   1502     uint8         bubble_mop_disable = 0, oversub = 0;
   1503     int           ovs_ratio = 0;
   1504     int           speed_encoding = 0;
   1505     soc_info_t   *si = NULL;
   1506     egr_mmu_cell_credit_entry_t credit_entry;
   1507 
   1508     if (!(si = &SOC_INFO(unit))) {
   1509         return SOC_E_INTERNAL;
   1510     }
   1511 
   1512     speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed);
   1513     _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0);
   1514     /* EDB Prebuffer */
   1515     SOC_IF_ERROR_RETURN(
   1516         soc_td3_port_asf_xmit_start_count_set(unit, port, port_speed,
   1517                                               mode, 0));
   1518     /* OBM Cell Assembly FIFO threshold */
   1519     ca_thresh = (mode == _SOC_TD3_ASF_MODE_SAF) ?
   1520         _soc_td3_asf_cfg_tbl[speed_encoding].ca_thresh.saf :
   1521         _soc_td3_asf_cfg_tbl[speed_encoding].ca_thresh.ct;
   1522     SOC_IF_ERROR_RETURN(
   1523         _soc_td3_asf_obm_ca_fifo_thresh_set(unit, port, ca_thresh));
   1524     /* CT threshold */
   1525     ct_ok_thresh = (mode == _SOC_TD3_ASF_MODE_SAF) ?
   1526         _soc_td3_asf_cfg_tbl[speed_encoding].ct_ok_thresh.saf :
   1527         _soc_td3_asf_cfg_tbl[speed_encoding].ct_ok_thresh.ct;
   1528     SOC_IF_ERROR_RETURN(
   1529         _soc_td3_asf_obm_ct_thresh_ok_set(unit, port, ct_ok_thresh));
   1530     /* OBM ForceSAF config */
   1531     SOC_IF_ERROR_RETURN(
   1532         _soc_td3_asf_force_saf_config_set(unit, port, port_speed, mode));
   1533 
   1534     /* BubbleMOP */
   1535     if (_SOC_TD3_ASF_MODE_SAF != mode) {
   1536         oversub =  (SOC_PBMP_MEMBER(si->oversub_pbm, port) ? 1 : 0);
   1537         bubble_mop_disable = oversub ?
   1538             !(_soc_td3_asf_cfg_tbl[speed_encoding].mop_enable.oversub) :
   1539             !(_soc_td3_asf_cfg_tbl[speed_encoding].mop_enable.line_rate);
   1540     }
   1541     SOC_IF_ERROR_RETURN(
   1542         _soc_td3_asf_obm_bubble_mop_set(unit, port, bubble_mop_disable));
   1543 
   1544     /* MMU EP Credit Threshold */
   1545     SOC_IF_ERROR_RETURN(
   1546         soc_td3_port_oversub_ratio_get(unit, port, &ovs_ratio));
   1547     if ((CCLK_FREQ_1525MHZ == si->frequency) && (ovs_ratio < 1620)) {
   1548         mmu_ep_credits_lo =
   1549             _soc_td3_asf_cfg_tbl[speed_encoding].mmu_credit_threshold.lr_os_161.lo;
   1550         mmu_ep_credits_hi =
   1551             _soc_td3_asf_cfg_tbl[speed_encoding].mmu_credit_threshold.lr_os_161.hi;
   1552     } else {
   1553         mmu_ep_credits_lo =
   1554             _soc_td3_asf_cfg_tbl[speed_encoding].mmu_credit_threshold.os_2_1.lo;
   1555         mmu_ep_credits_hi =
   1556             _soc_td3_asf_cfg_tbl[speed_encoding].mmu_credit_threshold.os_2_1.hi;
   1557     }
   1558 
   1559     /* ASF_CREDIT_THRESH_LO */
   1560     SOC_IF_ERROR_RETURN(READ_ASF_CREDIT_THRESH_LOr(unit, port, &rval));
   1561     soc_reg_field_set(unit, ASF_CREDIT_THRESH_LOr, &rval, THRESHf,
   1562                       mmu_ep_credits_lo);
   1563     SOC_IF_ERROR_RETURN(WRITE_ASF_CREDIT_THRESH_LOr(unit, port, rval));
   1564 
   1565     /* ASF_CREDIT_THRESH_HI */
   1566     SOC_IF_ERROR_RETURN(READ_ASF_CREDIT_THRESH_HIr(unit, port, &rval));
   1567     soc_reg_field_set(unit, ASF_CREDIT_THRESH_HIr, &rval, THRESHf,
   1568                       mmu_ep_credits_hi);
   1569     SOC_IF_ERROR_RETURN(WRITE_ASF_CREDIT_THRESH_HIr(unit, port, rval));
   1570 
   1571     /* EP credits outstanding */
   1572     SOC_IF_ERROR_RETURN(
   1573         soc_td3_port_asf_speed_to_mmu_cell_credit(unit, port, port_speed,
   1574             &egr_mmu_cell_credits));
   1575 
   1576     /* EGR_MMU_CELL_CREDIT */
   1577     SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ANY,
   1578                         si->port_l2p_mapping[port], &credit_entry));
   1579     soc_EGR_MMU_CELL_CREDITm_field32_set(unit, &credit_entry, CREDITf,
   1580                                          egr_mmu_cell_credits);
   1581     SOC_IF_ERROR_RETURN(WRITE_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ALL,
   1582                         si->port_l2p_mapping[port], &credit_entry));
   1583 
   1584     return SOC_E_NONE;
   1585 }
   1586 
   1587 /******************************************************************************
   1588  * Name: soc_td3_port_asf_speed_to_mmu_cell_credit                            *
   1589  * Description:                                                               *
   1590  *     Retrieve mmu_cell_credit based on port speed configured.               *
   1591  *     Helper function for misc init.                                         *
   1592  *     Support CPU and LB ports.                                              *
   1593  * IN params:                                                                 *
   1594  *     - Unit                                                                 *
   1595  *     - Logical Port                                                         *
   1596  *     - Port Speed                                                           *
   1597  * OUT params:                                                                *
   1598  *     - MMU Cell credit                                                      *
   1599  * Returns:                                                                   *
   1600  *     - SOC_E_XXX on success                                                 *
   1601  */
   1602 int
   1603 soc_td3_port_asf_speed_to_mmu_cell_credit(
   1604     int        unit,
   1605     soc_port_t port,
   1606     int        port_speed,
   1607     OUT uint32 *mmu_cell_credit)
   1608 {
   1609     int          speed_encoding = 0, ovs_ratio = 0;
   1610     soc_info_t   *si = NULL;
   1611 
   1612     if (NULL == mmu_cell_credit) {
   1613         return SOC_E_PARAM;
   1614     }
   1615 
   1616     if (!(si = &SOC_INFO(unit))) {
   1617         return SOC_E_INTERNAL;
   1618     }
   1619 
   1620     if (IS_CPU_PORT(unit, port)) {
   1621         port_speed = 20000;
   1622     }
   1623     if (IS_LB_PORT(unit, port)) {
   1624         port_speed = 100000;
   1625     }
   1626 
   1627     speed_encoding = _soc_td3_speed_to_ct_class_map(port_speed);
   1628     _SOC_TD3_ASF_SPEED_CLASS_VALIDATE(speed_encoding, 0);
   1629 
   1630     SOC_IF_ERROR_RETURN(
   1631         soc_td3_port_oversub_ratio_get(unit, port, &ovs_ratio));
   1632 
   1633     if ((CCLK_FREQ_1525MHZ == si->frequency) && (ovs_ratio < 1620)) {
   1634         *mmu_cell_credit =
   1635             _soc_td3_asf_cfg_tbl[speed_encoding].ep_credit.pfc_op_cells;
   1636     } else {
   1637         *mmu_cell_credit =
   1638             _soc_td3_asf_cfg_tbl[speed_encoding].ep_credit.base_cells;
   1639     }
   1640 
   1641     return SOC_E_NONE;
   1642 }
   1643 
   1644 /******************************************************************************
   1645  * Name: soc_td3_port_asf_mmu_cell_credit_to_port_speed                       *
   1646  * Description:                                                               *
   1647  *     Retrieve port speed based on mmu_cell_credit configured.               *
   1648  *     Helper function for MAC driver speed get.                              *
   1649  * IN params:                                                                 *
   1650  *     - Unit                                                                 *
   1651  *     - Logical Port                                                         *
   1652  *     - MMU Cell credit                                                      *
   1653  * OUT params:                                                                *
   1654  *     - Port speed                                                           *
   1655  * Returns:                                                                   *
   1656  *     - SOC_E_XXX on success                                                 *
   1657  */
   1658 int
   1659 soc_td3_port_asf_mmu_cell_credit_to_speed(
   1660     int        unit,
   1661     soc_port_t port,
   1662     uint8      mmu_cell_credit,
   1663     OUT int    *port_speed)
   1664 {
   1665     int i, freq;
   1666     uint8 cell_credit;
   1667     int speed;
   1668     soc_info_t   *si = NULL;
   1669 
   1670     if (NULL == port_speed) {
   1671         return SOC_E_PARAM;
   1672     }
   1673 
   1674     if (!(si = &SOC_INFO(unit))) {
   1675         return SOC_E_INTERNAL;
   1676     }
   1677 
   1678     /* Special case for 1G ports since 1G ports use same setting as 10G port */
   1679     if (1000 == (speed = si->port_init_speed[port])) {  /* Use cached speed instead */
   1680         *port_speed = speed;
   1681         return SOC_E_NONE;
   1682     }
   1683 
   1684     freq = si->frequency;
   1685     for (i = 1; i < (COUNTOF(_soc_td3_asf_cfg_tbl) - 1); i++) {
   1686         int ovs_ratio = 0;
   1687         SOC_IF_ERROR_RETURN(
   1688             soc_td3_port_oversub_ratio_get(unit, port, &ovs_ratio));
   1689 
   1690         cell_credit = ((CCLK_FREQ_1525MHZ == freq) && (ovs_ratio < 1620))?
   1691             _soc_td3_asf_cfg_tbl[i].ep_credit.pfc_op_cells :
   1692             _soc_td3_asf_cfg_tbl[i].ep_credit.base_cells;
   1693 
   1694         if (mmu_cell_credit == cell_credit) {
   1695             if (IS_HG_PORT(unit, port)) {
   1696                 *port_speed = _soc_td3_asf_cfg_tbl[i + 1].speed;
   1697             } else {
   1698                 *port_speed = _soc_td3_asf_cfg_tbl[i].speed;
   1699             }
   1700 /* This func is not available right now. But we can skip the check since
   1701    credit data for each speed are all different. They can be distinguished. */
   1702 #if 0
   1703             if (SOC_E_NONE !=
   1704                 soc_td3_port_speed_supported(unit, port, *port_speed)) {
   1705                 continue;
   1706             }
   1707 #endif
   1708             return SOC_E_NONE;
   1709         }
   1710     }
   1711 
   1712     return SOC_E_NOT_FOUND;
   1713 }
   1714 
   1715 /******************************************************************************
   1716  * Name: soc_td3_port_asf_pause_bpmp_get                                      *
   1717  * Description:                                                               *
   1718  *     Get pointer of pause_restore bitmap for update                         *
   1719  * IN params:                                                                 *
   1720  *     - Unit                                                                 *
   1721  * OUT params:                                                                *
   1722  *                                                                            *
   1723  * Returns:                                                                   *
   1724  *     - Pointer of pause_restore bitmap                                      *
   1725  */
   1726 pbmp_t *
   1727 soc_td3_port_asf_pause_bpmp_get(int unit)
   1728 {
   1729     if (_soc_td3_asf_ctrl[unit] == NULL) {
   1730         return NULL;
   1731     }
   1732     return &_soc_td3_asf_ctrl[unit]->pause_restore;
   1733 }
   1734 
   1735 /************************
   1736  * ASF Warmboot Support *
   1737  */
   1738 #ifdef BCM_WARM_BOOT_SUPPORT
   1739 /*
   1740  * ASF Warmboot is a part of Port module Warmboot.
   1741  * Check Port module for scache_ver evolution.
   1742  */
   1743 /*
   1744 #define BCM_WB_VERSION_1_8                SOC_SCACHE_VERSION(1,8)
   1745 #define BCM_WB_DEFAULT_VERSION            BCM_WB_VERSION_1_8
   1746 */
   1747 int
   1748 soc_td3_asf_wb_memsz_get(
   1749     int               unit,
   1750     OUT uint32* const mem_sz,
   1751     uint16            scache_ver)
   1752 {
   1753     if (!mem_sz) {
   1754         return SOC_E_PARAM;
   1755     }
   1756     *mem_sz = 0;
   1757 
   1758     if (!SOC_WARM_BOOT(unit)) {
   1759         if (!_soc_td3_asf_ctrl[unit] || !_soc_td3_asf_ctrl[unit]->asf_mem_profile) {
   1760             return SOC_E_UNAVAIL;
   1761         }
   1762         if (!_soc_td3_asf_ctrl[unit]->init) {
   1763             return SOC_E_INTERNAL;
   1764         }
   1765     }
   1766 
   1767     *mem_sz = sizeof(_soc_td3_asf_wb_t);
   1768 
   1769     return SOC_E_NONE;
   1770 }
   1771 
   1772 int
   1773 soc_td3_asf_wb_sync(
   1774     int    unit,
   1775     IN_OUT uint8* const wb_data)
   1776 {
   1777     _soc_td3_asf_wb_t *wbd;
   1778 
   1779     if (!_soc_td3_asf_ctrl[unit] || !_soc_td3_asf_ctrl[unit]->asf_mem_profile) {
   1780         return SOC_E_UNAVAIL;
   1781     }
   1782     if (!_soc_td3_asf_ctrl[unit]->init) {
   1783         return SOC_E_INTERNAL;
   1784     }
   1785     if (!wb_data) {
   1786         return SOC_E_PARAM;
   1787     }
   1788 
   1789     wbd = (_soc_td3_asf_wb_t *) wb_data;
   1790     wbd->unit = unit;
   1791     sal_memcpy(&wbd->asf_ctrl, _soc_td3_asf_ctrl[unit],
   1792                sizeof(_soc_td3_asf_ctrl_t));
   1793 
   1794     return SOC_E_NONE;
   1795 }
   1796 
   1797 int
   1798 soc_td3_asf_wb_recover(
   1799     int          unit,
   1800     uint8* const wb_data,
   1801     uint16       scache_ver)
   1802 {
   1803     _soc_td3_asf_wb_t *wbd;
   1804 
   1805     if (!SOC_WARM_BOOT(unit)) {
   1806         return SOC_E_INTERNAL;
   1807     }
   1808     if (!wb_data) {
   1809         return SOC_E_PARAM;
   1810     }
   1811 
   1812     wbd = (_soc_td3_asf_wb_t *) wb_data;
   1813     if (wbd->unit == unit) {
   1814         if (!(_soc_td3_asf_ctrl[unit] =
   1815                    sal_alloc(sizeof(_soc_td3_asf_ctrl_t), "TD3 ASF Ctrl Area"))) {
   1816             return SOC_E_MEMORY;
   1817         }
   1818 
   1819         sal_memcpy(_soc_td3_asf_ctrl[unit], &wbd->asf_ctrl,
   1820                    sizeof(_soc_td3_asf_ctrl_t));
   1821     }
   1822 
   1823     LOG_CLI((BSL_META_U(unit, "*** unit %d: MMU-ASF subsystem warmbooted: "
   1824                         "ports %s\n"), unit,
   1825                         asf_profile_str[_soc_td3_asf_ctrl[unit]->asf_mem_profile]));
   1826 
   1827     return SOC_E_NONE;
   1828 }
   1829 #endif /* BCM_WARM_BOOT_SUPPORT */
   1830 
   1831 /**********************
   1832  * ASF Debug Support  *
   1833  */
   1834 int
   1835 soc_td3_asf_pbmp_get(int unit)
   1836 {
   1837     char pfmt[SOC_PBMP_FMT_LEN];
   1838 
   1839     if (!_soc_td3_asf_ctrl[unit]->init) {
   1840         return SOC_E_INTERNAL;
   1841     }
   1842 
   1843     LOG_CLI(("ASF PBMP: %s\n",
   1844              SOC_PBMP_FMT(_soc_td3_asf_ctrl[unit]->asf_ports, pfmt)));
   1845 
   1846     return SOC_E_NONE;
   1847 }
   1848 
   1849 int
   1850 soc_td3_port_asf_show(
   1851     int        unit,
   1852     soc_port_t port,
   1853     int        port_speed)
   1854 {
   1855     int ret;
   1856     char mode_str[4][15] = {"SAF", "Same speed  ", "Slow to Fast",
   1857                              "Fast to Slow"};
   1858     char speed_str[_SOC_TD3_ASF_CLASS_CNT][10] = {"SAF", "10G", "HG[11]", "20G",
   1859                                 "HG[21]", "25G", "HG[27]", "40G", "HG[42]",
   1860                                 "50G", "HG[53]", "100G", "HG[106]"};
   1861     soc_td3_asf_mode_e mode = _SOC_TD3_ASF_RETRV;
   1862     uint8 min_speed, max_speed;
   1863 
   1864     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
   1865         return BCM_E_NONE;
   1866     }
   1867 
   1868     min_speed = max_speed = _SOC_TD3_ASF_RETRV;
   1869     ret = soc_td3_port_asf_mode_get(unit, port, port_speed, &mode);
   1870     if (SOC_E_UNAVAIL == ret) {
   1871         mode = _SOC_TD3_ASF_MODE_SAF;
   1872     } else if (SOC_E_NONE != ret) {
   1873         return ret;
   1874     }
   1875 
   1876     LOG_CLI(("%-5s     %-11s      ", SOC_PORT_NAME(unit, port), mode_str[mode]));
   1877 
   1878     if (_SOC_TD3_ASF_MODE_SAF == mode) {
   1879         LOG_CLI(("    .. NA ..\n"));
   1880     } else if (_SOC_TD3_ASF_MODE_FAST_TO_SLOW == mode) {
   1881         ret = _soc_td3_port_asf_speed_limits_get(unit, port, port_speed, mode,
   1882                                                  &min_speed, &max_speed);
   1883         LOG_CLI(("%s / %s\n", speed_str[max_speed], speed_str[min_speed]));
   1884     } else {
   1885         ret = _soc_td3_port_asf_speed_limits_get(unit, port, port_speed, mode,
   1886                                                  &min_speed, &max_speed);
   1887         LOG_CLI(("%s / %s\n", speed_str[min_speed], speed_str[max_speed]));
   1888     }
   1889 
   1890     return SOC_E_NONE;
   1891 }
   1892 
   1893 int soc_td3_asf_config_dump(int unit)
   1894 {
   1895     char asf_profile_str[3][25] = {"No cut-thru support",
   1896                                    "Similar speed cut-thru",
   1897                                    "Extreme speed cut-thru"};
   1898 
   1899     if (!_soc_td3_asf_ctrl[unit] || !_soc_td3_asf_ctrl[unit]->init) {
   1900         return SOC_E_INTERNAL;
   1901     }
   1902 
   1903     LOG_CLI(("ASF Profile: %s\n\n",
   1904              asf_profile_str[_soc_td3_asf_ctrl[unit]->asf_mem_profile]));
   1905 
   1906     return SOC_E_NONE;
   1907 }
   1908 
   1909 int
   1910 soc_td3_port_asf_config_dump(
   1911     int        unit,
   1912     soc_port_t port,
   1913     int        port_speed)
   1914 {
   1915     int    txp = 0, rxp = 0, ct_class = 0;
   1916     uint8  src_class = 0, dst_class = 0;
   1917     uint8  min_sp = 0, max_sp = 0;
   1918     uint8  fifo_threshold = 0, fifo_depth = 0, mmu_prebuf = 0;
   1919     uint8  xmit_start_cnt[13] = {0};
   1920     uint32 rval, mmu_ep_credits = 0, egr_mmu_cell_credits = 0;
   1921     mac_driver_t *macd;
   1922     soc_td3_asf_mode_e mode = _SOC_TD3_ASF_RETRV;
   1923     egr_mmu_cell_credit_entry_t credit_entry;
   1924 
   1925     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
   1926         return BCM_E_NONE;
   1927     }
   1928 
   1929     if (!_soc_td3_asf_ctrl[unit] || !_soc_td3_asf_ctrl[unit]->init) {
   1930         return SOC_E_INTERNAL;
   1931     }
   1932 
   1933     SOC_IF_ERROR_RETURN(
   1934         soc_td3_port_asf_mode_get(unit, port, port_speed, &mode));
   1935 
   1936     if (soc_td3_port_asf_valid(unit, port)) {
   1937         min_sp = max_sp = fifo_threshold = _SOC_TD3_ASF_RETRV;
   1938         fifo_depth = mmu_prebuf = _SOC_TD3_ASF_RETRV;
   1939 
   1940         SOC_IF_ERROR_RETURN(
   1941             _soc_td3_port_asf_class_get(unit, port, &ct_class));
   1942         SOC_IF_ERROR_RETURN(
   1943             _soc_td3_port_asf_speed_limits_get(unit, port, port_speed, mode,
   1944                                                &min_sp, &max_sp));
   1945         SOC_IF_ERROR_RETURN(
   1946             _soc_td3_port_asf_fifo_threshold_get(unit, port, port_speed, mode,
   1947                                                  &fifo_threshold));
   1948 
   1949         SOC_IF_ERROR_RETURN(
   1950             _soc_td3_port_asf_fifo_depth_get(unit, port, port_speed, mode,
   1951                                              &fifo_depth));
   1952 
   1953         SOC_IF_ERROR_RETURN(
   1954             _soc_td3_port_asf_mmu_prebuf_get(unit, port, port_speed,
   1955                                              &mmu_prebuf));
   1956 
   1957         SOC_IF_ERROR_RETURN(READ_ASF_CREDIT_THRESH_HIr(unit, port, &rval));
   1958         mmu_ep_credits = soc_reg_field_get(unit, ASF_CREDIT_THRESH_HIr,
   1959                                            rval, THRESHf);
   1960     }
   1961 
   1962     dst_class = _soc_td3_speed_to_ct_class_map(port_speed);
   1963     for (src_class = 0; src_class < _SOC_TD3_ASF_CLASS_CNT; src_class++) {
   1964         xmit_start_cnt[src_class] = _SOC_TD3_ASF_RETRV;
   1965         SOC_IF_ERROR_RETURN(
   1966             _soc_td3_port_asf_xmit_start_count_get(unit, port, src_class,
   1967                                                    dst_class, mode,
   1968                                                    &xmit_start_cnt[src_class]));
   1969     }
   1970 
   1971     /*
   1972      * COVERITY
   1973      *
   1974      * min_sp and max_sp will be updated in _soc_td3_port_asf_speed_limits_get.
   1975      * So they won't overrun _soc_td3_asf_cfg_tbl.
   1976      */
   1977     /* coverity[overrun-local : FALSE] */
   1978     LOG_CLI(("%-5s %-3d %-3d %-6d %-6d %-3d %-3d   ", SOC_PORT_NAME(unit, port),
   1979              mode, ct_class, _SOC_TD3_CT_CLASS_TO_SPEED_MAP(min_sp),
   1980             _SOC_TD3_CT_CLASS_TO_SPEED_MAP(max_sp), fifo_threshold,
   1981             fifo_depth));
   1982     for (src_class = 0; src_class < _SOC_TD3_ASF_CLASS_CNT; src_class++) {
   1983         LOG_CLI(("%-3d ", xmit_start_cnt[src_class]));
   1984     }
   1985 
   1986     SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ANY,
   1987                         SOC_INFO(unit).port_l2p_mapping[port], &credit_entry));
   1988     egr_mmu_cell_credits = soc_EGR_MMU_CELL_CREDITm_field32_get(unit,
   1989                            &credit_entry, CREDITf);
   1990 
   1991     SOC_IF_ERROR_RETURN(soc_mac_probe(unit, port, &macd));
   1992     SOC_IF_ERROR_RETURN(MAC_PAUSE_GET(macd, unit, port, &txp, &rxp));
   1993 
   1994     LOG_CLI((" %-3d %-3d %-3d %-3d\n", mmu_prebuf, mmu_ep_credits,
   1995              egr_mmu_cell_credits, rxp));
   1996 
   1997     return SOC_E_NONE;
   1998 }
   1999 
   2000 /******************************************************************************
   2001  * Name: soc_td3_port_asf_detach                                              *
   2002  * Description:                                                               *
   2003  *     Update ASF when port deleted during Flexport operation                 *
   2004  * IN params:                                                                 *
   2005  *     - Unit                                                                 *
   2006  *     - Logical Port                                                         *
   2007  * Returns:                                                                   *
   2008  *     - SOC_E_NONE on success                                                *
   2009  *     - SOC_E_PARAM on invalid parameter                                     *
   2010  */
   2011 int
   2012 soc_td3_port_asf_detach(int unit, soc_port_t port)
   2013 {
   2014     if (_soc_td3_asf_ctrl[unit] == NULL) {
   2015         return SOC_E_INIT;
   2016     }
   2017 
   2018     if (soc_td3_port_asf_valid(unit, port)) {
   2019         SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_ports, port);
   2020         SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->pause_restore, port);
   2021         if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_ss, port)) {
   2022             SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_ss, port);
   2023         } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_sf, port)) {
   2024             SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_sf, port);
   2025         } else if (SOC_PBMP_MEMBER(_soc_td3_asf_ctrl[unit]->asf_fs, port)) {
   2026             SOC_PBMP_PORT_REMOVE(_soc_td3_asf_ctrl[unit]->asf_fs, port);
   2027         }
   2028     }
   2029     return SOC_E_NONE;
   2030 }
   2031 
   2032 #endif /* BCM_TRIDENT3_SUPPORT */
   2033