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


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