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


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:      asf.c
      8  * Purpose:   ASF feature support for Tomahawk3 SKUs
      9  * Requires:
     10  */
     11 
     12 
     13 #if defined(BCM_TOMAHAWK3_SUPPORT)
     14 #include <soc/tomahawk3.h>
     15 #include <soc/init/tomahawk3_idb_init.h>
     16 #include <soc/init/tomahawk3_ep_init.h>
     17 #include <appl/diag/system.h>
     18 #include <soc/drv.h>
     19 #include <soc/ll.h>
     20 #include <soc/property.h>
     21 #include <shared/bsl.h>
     22 #ifdef PORTMOD_SUPPORT
     23 #include <soc/portmod/portmod.h>
     24 #include <soc/esw/portctrl.h>
     25 #endif
     26 
     27 
     28 #ifdef BCM_WARM_BOOT_SUPPORT
     29 #include <soc/scache.h>
     30 #endif /* BCM_WARM_BOOT_SUPPORT */
     31 
     32 #define _SOC_TH3_ASF_QUERY   0xfe
     33 #define _SOC_TH3_ASF_RETRV   0xff
     34 
     35 #define _SOC_TH3_ASF_MAX_FACTOR 4
     36 #define _SOC_TH3_ASF_MAX_SPEED 400000
     37 
     38 #define _SOC_TH3_SAF_COMMIT_ID_NUM 16
     39 
     40 #define _SOC_TH3_CT_CLASS_VALID_NUM 8
     41 #define _SOC_TH3_CT_CLASS_TOTAL_NUM 16
     42 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
     43 #define _TH3_PORT_SPEED(si, port) (si)->port_init_speed[(port)]
     44 
     45 #define _SOC_ASF_TH3_UNIT_VALIDATE(unit)   \
     46         if ( !(((unit) >= 0) && ((unit) <= SOC_MAX_NUM_DEVICES)) ) \
     47             return SOC_E_UNIT;
     48 
     49 #define _SOC_TH3_ASF_SPEED_CLASS_VALIDATE(class) \
     50         if(!(((class) >= 0 && (class) < _SOC_TH3_CT_CLASS_VALID_NUM))) \
     51             return SOC_E_PARAM;
     52 
     53 #define _SOC_TH3_CT_CLASS_TO_SPEED_MAP(ct_class) \
     54             soc_th3_asf_config_tbl[ct_class].speed
     55 
     56 typedef enum _soc_th3_pipe_bandwidth_config_e {
     57 
     58     _SOC_PIPE_BANDWIDTH_CONFIG_400G = 0,
     59     _SOC_PIPE_BANDWIDTH_CONFIG_50G_400G = 1,
     60     _SOC_PIPE_BADWIDTH_CONFIG_16x100G = 2,
     61     _SOC_PIPE_BANDWIDTH_CONFIG_OTHER = 3,
     62     _SOC_PIPE_BANDWIDTH_CONFIG_MAX = 4
     63 
     64 } _soc_th3_pipe_bandwidth_config_t;
     65 
     66 typedef struct _soc_th3_saf_commit_config_s {
     67 
     68     uint16 saf_commit_id[_SOC_TH3_SAF_COMMIT_ID_NUM];
     69 
     70 } _soc_th3_saf_commit_config_t;
     71 
     72 typedef enum _soc_th3_asf_speed_encoding_e {
     73     _SOC_TH3_SPEED_ID_RESERVED = 0,
     74     _SOC_TH3_SPEED_ID_10G,
     75     _SOC_TH3_SPEED_ID_25G,
     76     _SOC_TH3_SPEED_ID_40G,
     77     _SOC_TH3_SPEED_ID_50G,
     78     _SOC_TH3_SPEED_ID_100G,
     79     _SOC_TH3_SPEED_ID_200G,
     80     _SOC_TH3_SPEED_ID_400G,
     81     _SOC_TH3_SPEED_ID_ERROR
     82 } _soc_th3_asf_speed_encoding_t;
     83 
     84 
     85 
     86 static const
     87 _soc_th3_saf_commit_config_t
     88   _soc_th3_saf_commit_tbl[_SOC_PIPE_BANDWIDTH_CONFIG_MAX] = {
     89     {{0, 0, 0, 4, 4, 4, 4, 8, 8, 8, 8, 12, 12, 12, 12, 16}},  /* 4X400GE */
     90     {{1, 2, 3, 3, 4, 5, 6, 6, 7, 9, 11, 13, 15, 17, 19, 21}}, /* Mixed 50GE, 400GE */
     91     {{4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20}}, /* 16x100GE */
     92     /*{{1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 8, 9, 10, 11, 12, 13}}    others */
     93     {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}   /* others */
     94 };
     95 static const struct _soc_th3_bmop_settings_s {
     96     int speed;
     97     /*Bubble MOP disable.*/
     98     uint8 bmop_disable[3];
     99 } _soc_th3_bmop_settings_tbl[] = {
    100     {    -1, {0, 0, 0} },       /* SAF     */
    101     { 10000, {1, 1, 1} },       /* 10GE    */
    102     { 25000, {0, 0, 0} },       /* 25GE    */
    103     { 40000, {0, 0, 0} },       /* 40GE    */
    104     { 50000, {0, 0, 0} },       /* 50GE    */
    105     {100000, {0, 0, 0} },       /* 100GE   */
    106     {200000, {0, 0, 0} },       /* 200GE   */
    107     {400000, {0, 0, 0} }        /* 400GE   */
    108 };
    109 
    110 /* ASF ctrl */
    111 typedef struct _soc_th3_asf_ctrl_s {
    112     uint8                     init;
    113     pbmp_t                    asf_ports;
    114     pbmp_t                    pause_restore;
    115 } _soc_th3_asf_ctrl_t;
    116 
    117 /* ASF Control */
    118 static _soc_th3_asf_ctrl_t*
    119 _soc_th3_asf_ctrl[SOC_MAX_NUM_DEVICES] = {NULL};
    120 
    121 #ifdef BCM_WARM_BOOT_SUPPORT
    122 /* ASF Warmboot */
    123 typedef struct _soc_th3_asf_wb_s {
    124     int unit;
    125     _soc_th3_asf_ctrl_t asf_ctrl;
    126 } _soc_th3_asf_wb_t;
    127 #endif  /* BCM_WARM_BOOT_SUPPORT */
    128 
    129 /*
    130  * Function:
    131  *    _soc_th3_asf_speed_encoding_get
    132  * Purpose:
    133  *   Return speed encoding given a speed in MB/S
    134  * Parameters:
    135  *     speed - (IN) speed in MB/s
    136  * Returns:
    137  *     SOC_E_XXX
    138  */
    139 
    140 STATIC int
    141 _soc_th3_asf_speed_encoding_get(int speed) {
    142     switch(speed) {
    143         case 10000:
    144             return _SOC_TH3_SPEED_ID_10G;
    145         case 25000:
    146             return _SOC_TH3_SPEED_ID_25G;
    147         case 40000:
    148             return _SOC_TH3_SPEED_ID_40G;
    149         case 50000:
    150             return _SOC_TH3_SPEED_ID_50G;
    151         case 100000:
    152         case 160000:
    153             return _SOC_TH3_SPEED_ID_100G;
    154         case 200000:
    155             return _SOC_TH3_SPEED_ID_200G;
    156         case 400000:
    157             return _SOC_TH3_SPEED_ID_400G;
    158         default:
    159             return _SOC_TH3_SPEED_ID_ERROR;
    160     }
    161 }
    162 
    163 STATIC int
    164 _soc_th3_asf_speed_get (int speed_encode) {
    165     switch(speed_encode) {
    166         case _SOC_TH3_SPEED_ID_10G:
    167             return 10000;
    168         case _SOC_TH3_SPEED_ID_25G:
    169             return 25000;
    170         case _SOC_TH3_SPEED_ID_40G:
    171             return 40000;
    172         case _SOC_TH3_SPEED_ID_50G:
    173             return 50000;
    174         case _SOC_TH3_SPEED_ID_100G:
    175             return 100000;
    176         case _SOC_TH3_SPEED_ID_200G:
    177             return 200000;
    178         case _SOC_TH3_SPEED_ID_400G:
    179             return 400000;
    180         default:
    181             return -1;
    182     }
    183 }
    184 
    185 /*
    186  * Function:
    187  *    _soc_th3_port_asf_speed_limits_get
    188  * Purpose:
    189  *   Get the max and min src speed (encoding)
    190  *   given a dst port speed.
    191  * Parameters:
    192  *     unit       - (IN) unit number
    193  *     port_speed  - (IN)  dst port speed
    194  *     mode - (IN) forwarding mode
    195  *     min_sp (OUT) min src speed encoding
    196  *     max_sp (OUT) max src speed encoding
    197  * Returns:
    198  *     SOC_E_XXX
    199  */
    200 
    201 STATIC int
    202 _soc_th3_port_asf_speed_limits_get(
    203     int unit,
    204     int port_speed,
    205     int mode,
    206     int *min_sp,
    207     int *max_sp)
    208 {
    209     if(SOC_TH3_ASF_MODE_SAF != mode) {
    210         *min_sp = _soc_th3_asf_speed_encoding_get(port_speed);
    211         *max_sp = MIN(port_speed*_SOC_TH3_ASF_MAX_FACTOR, _SOC_TH3_ASF_MAX_SPEED);
    212         *max_sp = _soc_th3_asf_speed_encoding_get(*max_sp);
    213         _SOC_TH3_ASF_SPEED_CLASS_VALIDATE(*min_sp);
    214         _SOC_TH3_ASF_SPEED_CLASS_VALIDATE(*max_sp);
    215     } else {
    216         *min_sp = -1;
    217         *max_sp = -1;
    218     }
    219 
    220     return SOC_E_NONE;
    221 
    222 }
    223 
    224 /*
    225  * Function:
    226  *    _soc_th3_port_asf_speed_limits_read
    227  * Purpose:
    228  *   Get the max and min src speed (encoding)
    229  *   given a dst port speed.
    230  * Parameters:
    231  *     unit       - (IN) unit number
    232  *     port  - (IN)  dst port
    233  *     min_sp (OUT) min src speed encoding
    234  *     max_sp (OUT) max src speed encoding
    235  * Returns:
    236  *     SOC_E_XXX
    237  */
    238 
    239 STATIC int
    240 _soc_th3_port_asf_speed_limits_read(
    241     int unit,
    242     soc_port_t port,
    243     int *min_sp,
    244     int *max_sp)
    245 {
    246     soc_reg_t asf_config_reg = MMU_EBCTM_EPORT_CT_CFGr;
    247     uint32 rval = 0;
    248     soc_field_t min_sp_fld = DST_PORT_SPEEDf;
    249     soc_field_t max_sp_fld = MAX_SRC_PORT_SPEEDf;
    250 
    251     SOC_IF_ERROR_RETURN
    252         (soc_reg32_get(unit, asf_config_reg, port, 0, &rval));
    253     *min_sp = soc_reg_field_get(unit, asf_config_reg, rval, min_sp_fld);
    254     *max_sp = soc_reg_field_get(unit, asf_config_reg, rval, max_sp_fld);
    255     return SOC_E_NONE;
    256 
    257 }
    258 
    259 /*
    260  * Function:
    261  *    _soc_th3_idb_ca_bmop_set
    262  * Purpose:
    263  *   Config bubble MOP settings given a logic port.
    264  * Parameters:
    265  *     unit       - (IN) unit number
    266  *     port  - (IN) logic port
    267  *     port_speed - (IN) port_speed.
    268  *     mode  - (IN) ASF mode
    269  * Returns:
    270  *     SOC_E_XXX
    271  */
    272 
    273 STATIC int
    274 _soc_th3_idb_ca_bmop_set(int unit, soc_port_t port, int port_speed, int mode)
    275 {
    276     soc_reg_t reg;
    277     uint64 rval64, fldval64;
    278     int phy_port;
    279     int pm_num;
    280     int subp;
    281     int pipe_num;
    282     uint32 bmop_disable;
    283     int latency_mode;
    284     int speed_encoding;
    285     soc_info_t *si;
    286 
    287     static const soc_reg_t th3_idb_ca_control_2[_TH3_PIPES_PER_DEV] = {
    288         IDB_CA_CONTROL_2_PIPE0r, IDB_CA_CONTROL_2_PIPE1r,
    289         IDB_CA_CONTROL_2_PIPE2r, IDB_CA_CONTROL_2_PIPE3r,
    290         IDB_CA_CONTROL_2_PIPE4r, IDB_CA_CONTROL_2_PIPE5r,
    291         IDB_CA_CONTROL_2_PIPE6r, IDB_CA_CONTROL_2_PIPE7r
    292     };
    293     static const soc_field_t ca_bmop_disable_fields[] = {
    294         PORT0_BUBBLE_MOP_DISABLEf, PORT1_BUBBLE_MOP_DISABLEf,
    295         PORT2_BUBBLE_MOP_DISABLEf, PORT3_BUBBLE_MOP_DISABLEf,
    296         PORT4_BUBBLE_MOP_DISABLEf, PORT5_BUBBLE_MOP_DISABLEf,
    297         PORT6_BUBBLE_MOP_DISABLEf, PORT7_BUBBLE_MOP_DISABLEf
    298     };
    299     si = &(SOC_INFO(unit));
    300     if(si == NULL) {
    301         return SOC_E_INTERNAL;
    302     }
    303     phy_port = si->port_l2p_mapping[port];
    304     pipe_num = si->port_pipe[port];
    305     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
    306     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
    307 
    308     SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency_mode));
    309 
    310     speed_encoding =
    311         (mode == SOC_TH3_ASF_MODE_SAF) ? 0 :
    312             soc_tomahawk3_speed_to_e2e_settings_class_map(port_speed);
    313     bmop_disable = _soc_th3_bmop_settings_tbl[speed_encoding].
    314         bmop_disable[latency_mode];
    315     reg = th3_idb_ca_control_2[pipe_num];
    316     SOC_IF_ERROR_RETURN(soc_reg_rawport_get(unit, reg, REG_PORT_ANY,
    317                                             pm_num, &rval64));
    318     COMPILER_64_SET(fldval64, 0, bmop_disable);
    319     soc_reg64_field_set(unit, reg, &rval64, ca_bmop_disable_fields[subp],
    320                                                           fldval64);
    321     SOC_IF_ERROR_RETURN(soc_reg_rawport_set(unit, reg, REG_PORT_ANY,
    322                                                     pm_num, rval64));
    323     return SOC_E_NONE;
    324 }
    325 
    326 
    327 /*
    328  * Function:
    329  *    _soc_th3_asf_pause_update
    330  * Purpose:
    331  *   Update PAUSE settings for a port
    332  * Parameters:
    333  *     unit   - (IN) unit number
    334  *     port  - (IN)  logical port number
    335  *     mode - (IN) forwarding mode
    336  * Returns:
    337  *     SOC_E_XXX
    338  */
    339 
    340 STATIC int
    341 _soc_th3_asf_pause_update(
    342     int unit,
    343     soc_port_t port,
    344     soc_th3_asf_mode_t mode)
    345 {
    346 
    347 #ifdef PORTMOD_SUPPORT
    348     int rv = SOC_E_NONE;
    349     portmod_pause_control_t pause_control;
    350 
    351     SOC_IF_ERROR_RETURN(soc_esw_portctrl_init_check(unit));
    352 
    353     rv = portmod_port_pause_control_get(unit, port, &pause_control);
    354     if (!rv) {
    355         /* Retrieve current rx/tx pause enable for port */
    356         SOC_IF_ERROR_RETURN(
    357                 portmod_port_pause_control_get(unit, port, &pause_control));
    358         if(mode != SOC_TH3_ASF_MODE_SAF) {
    359             if (pause_control.rx_enable == 1) {
    360                 SOC_PBMP_PORT_ADD((_soc_th3_asf_ctrl[unit])->pause_restore, port);
    361                 pause_control.rx_enable = 0;
    362                 SOC_IF_ERROR_RETURN(
    363                         portmod_port_pause_control_set(unit, port,
    364                             &pause_control));
    365             }
    366         } else {
    367             if (SOC_PBMP_MEMBER((_soc_th3_asf_ctrl[unit])->pause_restore, port)) {
    368                 pause_control.rx_enable = 1;
    369                 SOC_IF_ERROR_RETURN(
    370                         portmod_port_pause_control_set(unit, port, &pause_control));
    371                 SOC_PBMP_PORT_REMOVE(_soc_th3_asf_ctrl[unit]->pause_restore, port);
    372             }
    373         }
    374 
    375         SOC_IF_ERROR_RETURN(
    376                 portmod_port_pause_control_set(unit, port, &pause_control));
    377     }
    378 
    379 
    380     return rv;
    381 
    382 #else  /* PORTMOD_SUPPORT */
    383     return SOC_E_UNAVAIL;
    384 #endif /* PORTMOD_SUPPORT */
    385 }
    386 
    387 /**
    388  * Function:
    389  *     _soc_th3_asf_tct_config_set
    390  * Purpose:
    391  *      Configure Transitional CT.
    392  * Parameters:
    393  *      unit - (IN) Unit number.
    394  * Returns:
    395  *      SOC_E_xxx
    396  */
    397 STATIC int
    398 _soc_th3_asf_tct_config_set(int unit)
    399 {
    400 #define _SOC_TH3_ASF_VALID_SPEED_NUM 7
    401     int i;
    402     soc_reg_t reg = INVALIDr;
    403     uint64 rval;
    404     static const struct _soc_th3_tct_config_s {
    405         uint8 itm_pkt_th;
    406         uint8 mmu_pkt_th;
    407         uint8 itm_cell_th;
    408         uint8 mmu_cell_th;
    409         uint32 cell_reduction_cycle;
    410         uint32 cell_reduction_num;
    411         uint32 exit_tct_timer;
    412         uint32 exit_cell_threshold;
    413     } config_t[_SOC_TH3_ASF_VALID_SPEED_NUM] = {
    414         {16, 16, 38, 38, 4096, 8, 32000, 76},
    415         {16, 16, 38, 38, 4096, 8, 32000, 76},
    416         {16, 16, 38, 38, 4096, 8, 32000, 76},
    417         {16, 16, 38, 38, 4096, 8, 32000, 76},
    418         {31, 31, 38, 38, 4096, 8, 32000, 76},
    419         {62, 62, 62, 62, 4096, 8, 16000, 100},
    420         {124, 124, 124, 124, 4096, 8, 8000, 162},
    421     };
    422 
    423     for(i = 0; i < _SOC_TH3_ASF_VALID_SPEED_NUM; i++){
    424         reg = MMU_EBCTM_TCT_ENTER_SPEED_CFGr;
    425         SOC_IF_ERROR_RETURN
    426             (soc_reg64_get(unit, reg, REG_PORT_ANY, i, &rval));
    427 
    428         soc_reg64_field32_set(unit, reg, &rval, ENTER_TCT_ITM_PKT_THRESHOLDf,
    429             config_t[i].itm_pkt_th);
    430         soc_reg64_field32_set(unit, reg, &rval, ENTER_TCT_MMU_PKT_THRESHOLDf,
    431             config_t[i].mmu_pkt_th);
    432         soc_reg64_field32_set(unit, reg, &rval, ENTER_TCT_ITM_CELL_THRESHOLDf,
    433             config_t[i].itm_cell_th);
    434         soc_reg64_field32_set(unit, reg, &rval, ENTER_TCT_MMU_CELL_THRESHOLDf,
    435             config_t[i].mmu_cell_th);
    436 
    437         SOC_IF_ERROR_RETURN
    438             (soc_reg64_set(unit, reg, REG_PORT_ANY, i, rval));
    439 
    440         reg = MMU_EBCTM_TCT_EXIT_SPEED_CFGr;
    441         SOC_IF_ERROR_RETURN
    442             (soc_reg64_get(unit, reg, REG_PORT_ANY, i, &rval));
    443 
    444         soc_reg64_field32_set(unit, reg, &rval, TCT_BUFFER_CELL_REDUCTION_CYCLESf,
    445             config_t[i].cell_reduction_cycle);
    446         soc_reg64_field32_set(unit, reg, &rval, TCT_BUFFER_CELL_REDUCTION_NUMBERf,
    447             config_t[i].cell_reduction_num);
    448         soc_reg64_field32_set(unit, reg, &rval, EXIT_TCT_TIMERf,
    449             config_t[i].exit_tct_timer);
    450         soc_reg64_field32_set(unit, reg, &rval, EXIT_TCT_MMU_CELL_THRESHOLDf,
    451             config_t[i].exit_cell_threshold);
    452 
    453         SOC_IF_ERROR_RETURN
    454             (soc_reg64_set(unit, reg, REG_PORT_ANY, i, rval));
    455     }
    456 
    457 #undef _SOC_TH3_ASF_VALID_SPEED_NUM
    458 
    459     return SOC_E_NONE;
    460 }
    461 
    462 #if 0
    463 /**
    464  * Function:
    465  *     _soc_th3_asf_port_enable
    466  * Purpose:
    467  *      Enable/Disable a given port for CT in IDB.
    468  * Parameters:
    469  *      unit - (IN) Unit number.
    470  *      port - (IN) Logical port number.
    471  *      enable - (IN) 0: disable, 1: enable.
    472  * Returns:
    473  *      SOC_E_xxx
    474  */
    475 STATIC int
    476 _soc_th3_idb_ca_asf_enable(int unit, soc_port_t port, uint8 ct_enable)
    477 {
    478     soc_reg_t reg;
    479     uint64 rval64;
    480     uint32 fval;
    481     int phy_port;
    482     int pm_num;
    483     int subp;
    484     int pipe_num;
    485     soc_info_t *si = &SOC_INFO(unit);
    486     static const soc_reg_t ca_control_2[_TH3_PIPES_PER_DEV] =
    487     {
    488         IDB_CA_CONTROL_2_PIPE0r, IDB_CA_CONTROL_2_PIPE1r,
    489         IDB_CA_CONTROL_2_PIPE2r, IDB_CA_CONTROL_2_PIPE3r,
    490         IDB_CA_CONTROL_2_PIPE4r, IDB_CA_CONTROL_2_PIPE5r,
    491         IDB_CA_CONTROL_2_PIPE6r, IDB_CA_CONTROL_2_PIPE7r
    492     };
    493     static const soc_field_t ca_ct_disable_fields[] = {
    494         PORT0_CT_DISABLEf, PORT1_CT_DISABLEf,
    495         PORT2_CT_DISABLEf, PORT3_CT_DISABLEf,
    496         PORT4_CT_DISABLEf, PORT5_CT_DISABLEf,
    497         PORT6_CT_DISABLEf, PORT7_CT_DISABLEf
    498     };
    499 
    500     if(si == NULL) {
    501         return SOC_E_INTERNAL;
    502     }
    503     phy_port = si->port_l2p_mapping[port];
    504     pipe_num = si->port_pipe[port];
    505     pm_num = soc_tomahawk3_get_pipe_pm_from_phy_port(phy_port);
    506     reg = ca_control_2[pipe_num];
    507     subp = soc_tomahawk3_get_subp_from_phy_port(phy_port);
    508     SOC_IF_ERROR_RETURN(soc_reg64_get(unit, reg, REG_PORT_ANY,
    509                                             pm_num, &rval64));
    510     fval = ct_enable ? 0: 1;
    511     soc_reg64_field32_set(unit, reg, &rval64, ca_ct_disable_fields[subp],
    512                                                           fval);
    513     SOC_IF_ERROR_RETURN(soc_reg64_set(unit, reg, REG_PORT_ANY,
    514                                                     pm_num, rval64));
    515     return SOC_E_NONE;
    516 }
    517 #endif
    518 
    519 /**
    520  * Function:
    521  *     _soc_th3_asf_port_enable
    522  * Purpose:
    523  *      Enable/Disable a given port for CT.
    524  * Parameters:
    525  *      unit - (IN) Unit number.
    526  *      port - (IN) Logical port number.
    527  *      port_speed (IN) port speed in MB/s.
    528  *      enable - (IN) 0: disable, 1: enable.
    529  * Returns:
    530  *      SOC_E_xxx
    531  */
    532 STATIC int
    533 _soc_th3_asf_port_enable(
    534     int unit,
    535     soc_port_t port,
    536     int port_speed,
    537     uint8 enable)
    538 {
    539     
    540     int dst_speed_id, max_src_speed_id;
    541     uint32 rval;
    542     soc_reg_t reg = MMU_EBCTM_EPORT_CT_CFGr;
    543     dst_speed_id = _soc_th3_asf_speed_encoding_get(port_speed);
    544     max_src_speed_id = _soc_th3_asf_speed_encoding_get
    545             (MIN((port_speed*_SOC_TH3_ASF_MAX_FACTOR), _SOC_TH3_ASF_MAX_SPEED));
    546 
    547     _SOC_TH3_ASF_SPEED_CLASS_VALIDATE(dst_speed_id);
    548     _SOC_TH3_ASF_SPEED_CLASS_VALIDATE(max_src_speed_id);
    549 
    550     SOC_IF_ERROR_RETURN
    551             (soc_reg32_get(unit, reg, port, 0, &rval));
    552     if(enable) {
    553 
    554         soc_reg_field_set(unit, reg, &rval, DST_PORT_SPEEDf, dst_speed_id);
    555         soc_reg_field_set(unit, reg, &rval, MAX_SRC_PORT_SPEEDf,
    556             max_src_speed_id);
    557 
    558     }
    559 
    560     soc_reg_field_set(unit, reg, &rval, CT_ENABLEf, enable);
    561     SOC_IF_ERROR_RETURN
    562             (soc_reg32_set(unit, reg, port, 0, rval));
    563 
    564     /* disable/enable per port TCT */
    565     reg = MMU_EBCTM_EPORT_TCT_CFGr;
    566     SOC_IF_ERROR_RETURN
    567            (soc_reg32_get(unit, reg, port, 0, &rval));
    568     soc_reg_field_set(unit, reg, &rval, TCT_ENABLEf, enable);
    569     SOC_IF_ERROR_RETURN
    570             (soc_reg32_set(unit, reg, port, 0, rval));
    571 
    572 #if 0
    573     /*enable/diable CT in IDB */
    574     SOC_IF_ERROR_RETURN
    575         (_soc_th3_idb_ca_asf_enable(unit, port, enable));
    576 #endif
    577     return SOC_E_NONE;
    578 }
    579 
    580 /**
    581  * Function:
    582  *     _soc_th3_mmu_rl_tile_config_set
    583  * Purpose:
    584  *      Configure Read launcher.
    585  * Parameters:
    586  *      unit - (IN) Unit number.
    587  * Returns:
    588  *      SOC_E_xxx
    589  */
    590 STATIC int
    591 _soc_th3_mmu_rl_tile_config_set(int unit)
    592 {
    593     soc_reg_t reg = INVALIDr;
    594     uint64 rval;
    595 
    596     static const struct _soc_th3_mmu_rl_tile_config_s {
    597 
    598         uint32 buffer_activity;
    599         uint32 high_th;
    600         uint16 ebq_backup_th;
    601         uint32 ebq_backup;
    602         uint32 stop_cooloff;
    603 
    604     } rl_config = {
    605         1024, 5120, 64, 512, 512
    606     };
    607 
    608 
    609     reg = MMU_RL_CT_TILE_ACTIVITYr;
    610     SOC_IF_ERROR_RETURN
    611             (soc_reg64_get(unit, reg, REG_PORT_ANY, 0, &rval));
    612 
    613     soc_reg64_field32_set(unit, reg, &rval,
    614                             STOP_DUE_TO_EBQ_BACKUPf, rl_config.ebq_backup);
    615     soc_reg64_field32_set(unit, reg, &rval,
    616                     STOP_DUE_TO_BUFFER_ACTIVITYf, rl_config.buffer_activity);
    617     soc_reg64_field32_set(unit, reg, &rval,
    618                             EBQ_BACKUP_THRESHOLDf, rl_config.ebq_backup_th);
    619 
    620     SOC_IF_ERROR_RETURN
    621             (soc_reg64_set(unit, reg, REG_PORT_ANY, 0, rval));
    622 
    623     reg = MMU_RL_CT_TILE_ACTIVITY2r;
    624     COMPILER_64_ZERO(rval);
    625 
    626     SOC_IF_ERROR_RETURN
    627             (soc_reg64_get(unit, reg, REG_PORT_ANY, 0, &rval));
    628 
    629     soc_reg64_field32_set(unit, reg, &rval,
    630                                 STOP_COOLOFFf, rl_config.stop_cooloff);
    631     soc_reg64_field32_set(unit, reg, &rval,
    632                                 HIGH_ACTIVITY_THf, rl_config.high_th);
    633 
    634     SOC_IF_ERROR_RETURN
    635             (soc_reg64_set(unit, reg, REG_PORT_ANY, 0, rval));
    636 
    637     return SOC_E_NONE;
    638 }
    639 
    640 /**
    641  * Function:
    642  *     _soc_th3_port_asf_fifo_threshold_set
    643  * Purpose:
    644  *     Set CT FIFO threshold.
    645  * Parameters:
    646  *      unit - (IN) Unit number.
    647  * Returns:
    648  *      SOC_E_xxx
    649  */
    650 STATIC int
    651 _soc_th3_port_asf_fifo_threshold_set(int unit)
    652 {
    653     int i;
    654     soc_reg_t reg;
    655     soc_reg_t ct_cfg_regs[] = {
    656         MMU_EBCTM_CT_SPEED_6_CFGr, MMU_EBCTM_CT_SPEED_5_CFGr,
    657         MMU_EBCTM_CT_SPEED_4_CFGr, MMU_EBCTM_CT_SPEED_3_CFGr,
    658         MMU_EBCTM_CT_SPEED_2_CFGr, MMU_EBCTM_CT_SPEED_1_CFGr,
    659         MMU_EBCTM_CT_SPEED_0_CFGr};
    660     uint32 rval;
    661     uint32 fval[] = {66, 38, 24, 16, 16, 16, 16};
    662     soc_field_t field = CT_FIFO_THRESHOLDf;
    663 
    664     for(i = 0; i < sizeof(fval)/sizeof(uint32); i++){
    665         reg = ct_cfg_regs[i];
    666         SOC_IF_ERROR_RETURN
    667             (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
    668         soc_reg_field_set(unit, reg, &rval, field, fval[i]);
    669         SOC_IF_ERROR_RETURN
    670             (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
    671     }
    672 
    673     return SOC_E_NONE;
    674 }
    675 
    676 /**
    677  * Function:
    678  *     _soc_th3_mmu_saf_commitment_config_set
    679  * Purpose:
    680  *     Set SAF commitment register based on pipe configuration.
    681  * Parameters:
    682  *      unit - (IN) Unit number.
    683  *      pipe - (IN) Pipe number.
    684  * Returns:
    685  *      SOC_E_xxx
    686  */
    687 STATIC int
    688 _soc_th3_mmu_saf_commitment_config_set(int unit, int pipe) {
    689 
    690     int i, pipe_cfg;
    691     uint32 rval;
    692     const _soc_th3_saf_commit_config_t *saf_commit_p;
    693     soc_reg_t reg = MMU_EBCTM_CT_BUDGET_SAF_COMMITMENT_CFGr;
    694     soc_field_t field = CTBUDGET_SAFCOMMITMENTf;
    695 
    696     if (pipe < 0 || pipe >= SOC_MAX_NUM_PIPES) {
    697         return SOC_E_PARAM;
    698     }
    699 
    700     pipe_cfg = _SOC_PIPE_BANDWIDTH_CONFIG_OTHER;
    701 
    702     saf_commit_p = &(_soc_th3_saf_commit_tbl[pipe_cfg]);
    703 
    704     for(i = 0; i < _SOC_TH3_SAF_COMMIT_ID_NUM; i++) {
    705         rval = 0;
    706         SOC_IF_ERROR_RETURN(
    707             soc_tomahawk3_eb_reg32_get(unit, reg, pipe, pipe, i, &rval));
    708         soc_reg_field_set(unit, reg, &rval, field, saf_commit_p->saf_commit_id[i]);
    709         SOC_IF_ERROR_RETURN
    710             (soc_tomahawk3_eb_reg32_set(unit, reg, pipe, pipe, i, rval));
    711     }
    712     return SOC_E_NONE;
    713 }
    714 
    715 STATIC int
    716 _soc_th3_mmu_saf_speed_bucket_config_set(int unit) {
    717 #define MOP_SPACE_200G_LOW_FREQ 4
    718     soc_reg_t speed_cfg_reg = MMU_EBCTM_MIN_MOP_SPACING_SPEED_BUCKET_1_CFGr;
    719     uint32 rval = 0;
    720     SOC_IF_ERROR_RETURN(
    721         soc_tomahawk3_eb_reg32_get(unit, speed_cfg_reg, REG_PORT_ANY, 0, 0,
    722             &rval));
    723     soc_reg_field_set(unit, speed_cfg_reg, &rval, NUM_CLK_PER_MOP_CELLf,
    724             MOP_SPACE_200G_LOW_FREQ);
    725     SOC_IF_ERROR_RETURN
    726         (soc_tomahawk3_eb_reg32_set(unit, speed_cfg_reg, REG_PORT_ANY, 0, 0,
    727                                     rval));
    728 #undef MOP_SPACE_200G_LOW_FREQ
    729     return SOC_E_NONE;
    730 }
    731 
    732 STATIC int
    733 _soc_th3_ct_override_settings (int unit) {
    734     uint32 rval = 0;
    735     soc_reg_t reg;
    736     soc_field_t field;
    737     int fld_val, pipe;
    738     soc_info_t *si = &SOC_INFO(unit);
    739     static const soc_reg_t idb_min_port_pick_regs[] = {
    740         IS_MIN_PORT_PICK_SPACING_WITHIN_PKT_PIPE0r, IS_MIN_PORT_PICK_SPACING_WITHIN_PKT_PIPE1r,
    741         IS_MIN_PORT_PICK_SPACING_WITHIN_PKT_PIPE2r, IS_MIN_PORT_PICK_SPACING_WITHIN_PKT_PIPE3r,
    742         IS_MIN_PORT_PICK_SPACING_WITHIN_PKT_PIPE4r, IS_MIN_PORT_PICK_SPACING_WITHIN_PKT_PIPE5r,
    743         IS_MIN_PORT_PICK_SPACING_WITHIN_PKT_PIPE6r, IS_MIN_PORT_PICK_SPACING_WITHIN_PKT_PIPE7r
    744     };
    745 
    746     static const soc_reg_t idb_min_cell_spacing_regs[] = {
    747         IS_MIN_CELL_SPACING_EOP_TO_SOP_PIPE0r, IS_MIN_CELL_SPACING_EOP_TO_SOP_PIPE1r,
    748         IS_MIN_CELL_SPACING_EOP_TO_SOP_PIPE2r, IS_MIN_CELL_SPACING_EOP_TO_SOP_PIPE3r,
    749         IS_MIN_CELL_SPACING_EOP_TO_SOP_PIPE4r, IS_MIN_CELL_SPACING_EOP_TO_SOP_PIPE5r,
    750         IS_MIN_CELL_SPACING_EOP_TO_SOP_PIPE6r, IS_MIN_CELL_SPACING_EOP_TO_SOP_PIPE7r
    751     };
    752 
    753 
    754     /* MMU_EBCTM_CT_BUDGET_CFG.CT_BUDGET = 'd16 */
    755     reg = MMU_EBCTM_CT_BUDGET_CFGr;
    756     field = CT_BUDGETf;
    757     fld_val = 16;
    758     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
    759     soc_reg_field_set(unit, reg, &rval, field, fld_val);
    760     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
    761 
    762     /* MMU_RL_EBP_OVRD.CT_BURST_TH = 'd12 */
    763     reg = MMU_RL_EBP_OVRDr;
    764     field = CT_BURST_THf;
    765     fld_val = 12;
    766     rval = 0x0;
    767     SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
    768     soc_reg_field_set(unit, reg, &rval, field, fld_val);
    769     SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval));
    770 
    771     for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    772         if (!SOC_PBMP_IS_NULL(si->pipe_pbm[pipe])) {
    773 
    774             /* MIN_PORT_PICK_SPACING_WITHIN_PKT.MID_PKT_400G_MIN_SPACING = 6 */
    775             reg = idb_min_port_pick_regs[pipe];
    776             field = MID_PKT_400G_MIN_SPACINGf;
    777             fld_val = 6;
    778             rval = 0x0;
    779             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pipe, 0, &rval));
    780             soc_reg_field_set(unit, reg, &rval, field, fld_val);
    781             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pipe, 0, rval));
    782 
    783             /* IS_MIN_CELL_SPACING_EOP_TO_SOP.INTER_PKT_400G_MIN_SPACING = 2 */
    784             reg = idb_min_cell_spacing_regs[pipe];
    785             field = INTER_PKT_400G_MIN_SPACINGf;
    786             fld_val = 2;
    787             rval = 0x0;
    788             SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pipe, 0, &rval));
    789             soc_reg_field_set(unit, reg, &rval, field, fld_val);
    790             SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pipe, 0, rval));
    791         }
    792     }
    793 
    794     /* For lower frequencies,
    795        MIN_PORT_PICK_SPACING_WITHIN_PKT.MID_PKT_200G_MIN_SPACING = 6 */
    796     if (si->frequency < 1325) {
    797         for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) {
    798             if (!SOC_PBMP_IS_NULL(si->pipe_pbm[pipe])) {
    799                 reg = idb_min_port_pick_regs[pipe];
    800                 field = MID_PKT_200G_MIN_SPACINGf;
    801                 fld_val = 6;
    802                 rval = 0x0;
    803                 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, pipe, 0, &rval));
    804                 soc_reg_field_set(unit, reg, &rval, field, fld_val);
    805                 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, pipe, 0, rval));
    806             }
    807         }
    808     }
    809 
    810 
    811 
    812     return SOC_E_NONE;
    813 }
    814 
    815 /*************************************
    816  * Init Start Routine                *
    817  *    - Allocates ASF Ctrl structure *
    818  *      for the given unit           *
    819  */
    820 STATIC int
    821 _soc_th3_asf_init_start(int unit)
    822 {
    823     _SOC_ASF_TH3_UNIT_VALIDATE(unit);
    824 
    825     if (!(_soc_th3_asf_ctrl[unit] =
    826               sal_alloc(sizeof(_soc_th3_asf_ctrl_t), "TH3 ASF Ctrl Area"))) {
    827         return SOC_E_MEMORY;
    828     }
    829     sal_memset(_soc_th3_asf_ctrl[unit], 0, sizeof(_soc_th3_asf_ctrl_t));
    830 
    831     return SOC_E_NONE;
    832 }
    833 
    834 /**
    835  * Function:
    836  *     soc_th3_port_asf_valid
    837  * Purpose:
    838  *      Check if a port is eligible for CT.
    839  * Parameters:
    840  *      unit - (IN) Unit number.
    841  *      port - (IN) Logical port number.
    842  * Returns:
    843  *      SOC_E_xxx
    844  */
    845 int
    846 soc_th3_port_asf_valid(
    847     int unit,
    848     soc_port_t port)
    849 {
    850     if(IS_CPU_PORT(unit, port) || IS_MANAGEMENT_PORT(unit, port)
    851             || IS_LB_PORT(unit, port)) {
    852         return FALSE;
    853     }
    854 
    855     return TRUE;
    856 }
    857 
    858 /**
    859  * Function:
    860  *     soc_th3_port_asf_mode_get
    861  * Purpose:
    862  *      Get traffic forwarding mode for a specific port.
    863  * Parameters:
    864  *      unit - (IN) Unit number.
    865  *      port - (IN) Logical port number.
    866  *      port_speed - (IN) Port speed in MB/s.
    867  *      mode - (OUT) ASF mode
    868  * Returns:
    869  *      SOC_E_xxx
    870  */
    871 int
    872 soc_th3_port_asf_mode_get(
    873     int unit,
    874     soc_port_t port,
    875     int port_speed,
    876     soc_th3_asf_mode_t *mode)
    877 {
    878     uint32 rval, enable;
    879     _SOC_ASF_TH3_UNIT_VALIDATE(unit);
    880 
    881     if(NULL == mode) {
    882         return SOC_E_INTERNAL;
    883     }
    884     if(soc_th3_port_asf_valid(unit, port)) {
    885         soc_reg_t reg = MMU_EBCTM_EPORT_CT_CFGr;
    886         SOC_IF_ERROR_RETURN
    887             (soc_reg32_get(unit, reg, port, 0, &rval));
    888         enable = soc_reg_field_get(unit, reg, rval, CT_ENABLEf);
    889         if(enable) {
    890             *mode = SOC_TH3_ASF_MODE_CT;
    891         }
    892         else {
    893             *mode = SOC_TH3_ASF_MODE_SAF;
    894         }
    895     } else {
    896         *mode = SOC_TH3_ASF_MODE_SAF;
    897     }
    898 
    899     return SOC_E_NONE;
    900 }
    901 /**
    902  * Function:
    903  *     soc_th3_port_asf_mode_set
    904  * Purpose:
    905  *      Set traffic forwarding mode for a specific port.
    906  * Parameters:
    907  *      unit - (IN) Unit number.
    908  *      port - (IN) Logical port number.
    909  *      port_speed - (IN) Port speed in MB/s.
    910  *      mode - (IN) ASF mode
    911  * Returns:
    912  *      SOC_E_xxx
    913  */
    914 int
    915 soc_th3_port_asf_mode_set(
    916     int                 unit,
    917     soc_port_t          port,
    918     int                 port_speed,
    919     soc_th3_asf_mode_t  mode)
    920 {
    921     int init = 0;
    922     soc_info_t *si = &SOC_INFO(unit);
    923     _SOC_ASF_TH3_UNIT_VALIDATE(unit);
    924 
    925     if(SOC_TH3_ASF_MODE_INIT == mode) {
    926         init = 1;
    927         mode = SOC_TH3_ASF_MODE_SAF;
    928     }
    929     if ((!init) && (!_soc_th3_asf_ctrl[unit] ||
    930         !_soc_th3_asf_ctrl[unit]->init || !si)) {
    931         return SOC_E_INTERNAL;
    932     }
    933     if(!soc_th3_port_asf_valid(unit, port)) {
    934         if(SOC_TH3_ASF_MODE_SAF != mode) {
    935             return SOC_E_UNAVAIL;
    936         }
    937         return SOC_E_NONE;
    938     }
    939 
    940     if(SOC_TH3_ASF_MODE_SAF != mode) {
    941         /* CT settings */
    942         /* Bubble Mop setting */
    943         SOC_IF_ERROR_RETURN
    944             (_soc_th3_idb_ca_bmop_set(unit, port, port_speed, mode));
    945 
    946 
    947         /* Disable pause */
    948         SOC_IF_ERROR_RETURN
    949             (_soc_th3_asf_pause_update(unit, port, mode));
    950 
    951         /*Enable CT */
    952         SOC_IF_ERROR_RETURN
    953             (_soc_th3_asf_port_enable(unit, port, port_speed, 1));
    954 
    955         /*bookkeeping */
    956         SOC_PBMP_PORT_ADD(_soc_th3_asf_ctrl[unit]->asf_ports, port);
    957 
    958     } else {
    959         /* Bubble Mop setting */
    960         SOC_IF_ERROR_RETURN
    961             (_soc_th3_idb_ca_bmop_set(unit, port, port_speed, mode));
    962         /* Disable CT */
    963         SOC_IF_ERROR_RETURN
    964             (_soc_th3_asf_port_enable(unit, port, port_speed, 0));
    965         /* Restore Pause */
    966         SOC_IF_ERROR_RETURN
    967             (_soc_th3_asf_pause_update(unit, port, mode));
    968 
    969         /*bookkeeping */
    970         SOC_PBMP_PORT_REMOVE(_soc_th3_asf_ctrl[unit]->asf_ports, port);
    971     }
    972 
    973     return SOC_E_NONE;
    974 }
    975 
    976 /************************
    977  * Init Complete Marker *
    978  */
    979 STATIC int
    980 _soc_th3_asf_init_done(int unit)
    981 {
    982     _SOC_ASF_TH3_UNIT_VALIDATE(unit);
    983 
    984 
    985     if (_soc_th3_asf_ctrl[unit]) {
    986         _soc_th3_asf_ctrl[unit]->init = 1;
    987 
    988         return SOC_E_NONE;
    989     } else {
    990         return SOC_E_INTERNAL;
    991     }
    992 }
    993 
    994 /**
    995  * Function:
    996  *      soc_th3_asf_init
    997  * Purpose:
    998  *      Initialize ASF subsystem and configure all the applicable ports
    999  *      to the specified forwarding mode
   1000  * Parameters:
   1001  *      unit - (IN) Unit number.
   1002  * Returns:
   1003  *      SOC_E_xxx
   1004  */
   1005 
   1006 int
   1007 soc_th3_asf_init(int unit)
   1008 {
   1009     soc_port_t port;
   1010     int speed, pipe;
   1011     uint32 pipe_map;
   1012     soc_info_t *si;
   1013     int core_clock;
   1014     if (!(si = &SOC_INFO(unit))) {
   1015         return SOC_E_INTERNAL;
   1016     }
   1017     SOC_IF_ERROR_RETURN(_soc_th3_asf_init_start(unit));
   1018     /* 1. chip/pipe-level init */
   1019 
   1020     /* 1.1 RL config */
   1021     SOC_IF_ERROR_RETURN(_soc_th3_mmu_rl_tile_config_set(unit));
   1022     /* 1.2 CT FIFO threshold config */
   1023     SOC_IF_ERROR_RETURN(_soc_th3_port_asf_fifo_threshold_set(unit));
   1024     /* 1.3 TCT config */
   1025     SOC_IF_ERROR_RETURN
   1026         (_soc_th3_asf_tct_config_set(unit));
   1027     /* 1.4 SAF commitment config */
   1028     soc_tomahawk3_pipe_map_get(unit, &pipe_map);
   1029     for(pipe = 0; pipe < _TH3_PIPES_PER_DEV; pipe++) {
   1030         if(pipe_map & (1 << pipe)) {
   1031             SOC_IF_ERROR_RETURN(
   1032                 _soc_th3_mmu_saf_commitment_config_set(unit, pipe));
   1033         }
   1034     }
   1035 
   1036     /* 1.5 MOP min spacing config for lower frequencies */
   1037     core_clock = si->frequency;
   1038     if (core_clock <= 1000) {
   1039         _soc_th3_mmu_saf_speed_bucket_config_set(unit);
   1040     }
   1041 
   1042     /* Additional settings for SDK-166459 */
   1043     SOC_IF_ERROR_RETURN(_soc_th3_ct_override_settings(unit));
   1044 
   1045     /* Per-port config */
   1046     PBMP_PORT_ITER(unit, port) {
   1047         if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)
   1048                 || IS_MANAGEMENT_PORT(unit, port)) {
   1049             continue;
   1050         }
   1051         speed = _TH3_PORT_SPEED(si, port);
   1052         SOC_IF_ERROR_RETURN
   1053             (soc_th3_port_asf_mode_set(unit, port, speed, SOC_TH3_ASF_MODE_INIT));
   1054 
   1055     }
   1056 
   1057     SOC_IF_ERROR_RETURN(_soc_th3_asf_init_done(unit));
   1058     return SOC_E_NONE;
   1059 }
   1060 
   1061 /************************
   1062  * Deinit Routine   *
   1063  */
   1064 int
   1065 soc_th3_asf_deinit(int unit)
   1066 {
   1067 #if 0
   1068     /* Unregister linkscan callback routine */
   1069     bcm_esw_linkscan_unregister(unit, soc_th_asf_linkscan_callback);
   1070 #endif
   1071 
   1072     if (_soc_th3_asf_ctrl[unit]) {
   1073         sal_free(_soc_th3_asf_ctrl[unit]);
   1074         _soc_th3_asf_ctrl[unit] = NULL;
   1075     }
   1076 
   1077     return SOC_E_NONE;
   1078 }
   1079 
   1080 /******************************************************************************
   1081  * Name: soc_th3_port_asf_detach                                              *
   1082  * Description:                                                               *
   1083  *     Update ASF when port deleted during Flexport operation                 *
   1084  * IN params:                                                                 *
   1085  *     - Unit                                                                 *
   1086  *     - Logical Port                                                         *
   1087  * Returns:                                                                   *
   1088  *     - SOC_E_NONE on success                                                *
   1089  *     - SOC_E_PARAM on invalid parameter                                     *
   1090  */
   1091 int
   1092 soc_th3_port_asf_detach(int unit, soc_port_t port)
   1093 {
   1094     _SOC_ASF_TH3_UNIT_VALIDATE(unit);
   1095 
   1096     if (_soc_th3_asf_ctrl[unit] == NULL) {
   1097         return SOC_E_INIT;
   1098     }
   1099 
   1100     SOC_IF_ERROR_RETURN
   1101         (soc_th3_port_asf_mode_set(unit, port,
   1102                                   SOC_INFO(unit).port_init_speed[port],
   1103                                   SOC_TH3_ASF_MODE_SAF));
   1104 
   1105     if (soc_th3_port_asf_valid(unit, port)) {
   1106         SOC_PBMP_PORT_REMOVE(_soc_th3_asf_ctrl[unit]->asf_ports, port);
   1107         SOC_PBMP_PORT_REMOVE(_soc_th3_asf_ctrl[unit]->pause_restore, port);
   1108     }
   1109     return SOC_E_NONE;
   1110 }
   1111 
   1112 int
   1113 soc_th3_asf_config_dump(int unit)
   1114 {
   1115     _SOC_ASF_TH3_UNIT_VALIDATE(unit);
   1116     if (!_soc_th3_asf_ctrl[unit] || !_soc_th3_asf_ctrl[unit]->init) {
   1117         return SOC_E_INTERNAL;
   1118     }
   1119     return SOC_E_NONE;
   1120 }
   1121 
   1122 /**
   1123  * Function:
   1124  *     _soc_th3_port_asf_class_get
   1125  * Purpose:
   1126  *      Return CT class of a given port.
   1127  * Parameters:
   1128  *      unit - (IN) Unit number.
   1129  *      port - (IN) logical port number.
   1130  *      class - (OUT) CT class
   1131  * Returns:
   1132  *      SOC_E_xxx
   1133  */
   1134 
   1135 STATIC int
   1136 _soc_th3_port_asf_class_get(
   1137     int unit,
   1138     soc_port_t port,
   1139     int  *class)
   1140 {
   1141     edb_ip_cut_thru_class_entry_t entry;
   1142 
   1143     if (NULL == class) {
   1144         return SOC_E_PARAM;
   1145     }
   1146 
   1147     sal_memset(&entry, 0, sizeof(edb_ip_cut_thru_class_entry_t));
   1148     SOC_IF_ERROR_RETURN
   1149         (READ_EDB_IP_CUT_THRU_CLASSm(unit, MEM_BLOCK_ALL, port, &entry));
   1150     *class = soc_mem_field32_get(unit, EDB_IP_CUT_THRU_CLASSm, &entry,
   1151                                  CUT_THRU_CLASSf);
   1152 
   1153     return SOC_E_NONE;
   1154 }
   1155 
   1156 /**
   1157  * Function:
   1158  *     _soc_th3_port_asf_fifo_threshold_get
   1159  * Purpose:
   1160  *      Get MMU CT FIFO Threshold based on port speed.
   1161  * Parameters:
   1162  *      unit - (IN) Unit number.
   1163  *      port_speed - (IN) Port speed in MB/s.
   1164  *      ct_thresh - (OUT) CT FIFO Threshold.
   1165  * Returns:
   1166  *      SOC_E_xxx
   1167  */
   1168 STATIC int
   1169 _soc_th3_port_asf_fifo_threshold_get(
   1170     int unit,
   1171     int port_speed,
   1172     int* ct_thresh)
   1173 
   1174 {
   1175     int speed_id;
   1176     uint32 rval;
   1177     soc_reg_t reg = INVALIDr;
   1178     soc_reg_t ct_cfg_regs[] = {
   1179         INVALIDr,                  MMU_EBCTM_CT_SPEED_6_CFGr,
   1180         MMU_EBCTM_CT_SPEED_5_CFGr, MMU_EBCTM_CT_SPEED_4_CFGr,
   1181         MMU_EBCTM_CT_SPEED_3_CFGr, MMU_EBCTM_CT_SPEED_2_CFGr,
   1182         MMU_EBCTM_CT_SPEED_1_CFGr, MMU_EBCTM_CT_SPEED_0_CFGr};
   1183 
   1184     speed_id = _soc_th3_asf_speed_encoding_get(port_speed);
   1185     reg = ct_cfg_regs[speed_id];
   1186     _SOC_TH3_ASF_SPEED_CLASS_VALIDATE(speed_id);
   1187     if(SOC_REG_IS_VALID(unit, reg)) {
   1188         SOC_IF_ERROR_RETURN
   1189             (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval));
   1190         *ct_thresh = soc_reg_field_get(unit, reg, rval, CT_FIFO_THRESHOLDf);
   1191     }
   1192     return SOC_E_NONE;
   1193 }
   1194 
   1195 /**
   1196  * Function:
   1197  *     soc_th3_port_asf_config_dump
   1198  * Purpose:
   1199  *      Dump per-port asf configurations to diag Shell.
   1200  * Parameters:
   1201  *      unit - (IN) Unit number.
   1202  *      port - (IN) Logical port number.
   1203  *      port_speed - (IN) Port speed in MB/s.
   1204  * Returns:
   1205  *      SOC_E_xxx
   1206  */
   1207 int
   1208 soc_th3_port_asf_config_dump(int unit, soc_port_t port, int port_speed)
   1209 {
   1210     int    ct_class = 0;
   1211     uint8  src_class = 0, dst_class = 0;
   1212     int  min_sp = 0, max_sp = 0, fifo_threshold = 0;
   1213     uint8  xmit_start_cnt[_SOC_TH3_CT_CLASS_VALID_NUM] = {0};
   1214     uint32 egr_mmu_cell_credits = 0;
   1215     portmod_pause_control_t pause_control;
   1216     int rxp;
   1217     soc_th3_asf_mode_t mode = SOC_TH3_ASF_MODE_SAF;
   1218     egr_mmu_cell_credit_entry_t credit_entry;
   1219     int phy_port;
   1220     int min_speed, max_speed, dst_port_speed;
   1221     soc_info_t *si = &SOC_INFO(unit);
   1222 
   1223     if(si == NULL) {
   1224         return SOC_E_INTERNAL;
   1225     }
   1226     phy_port = si->port_l2p_mapping[port];
   1227 
   1228     _SOC_ASF_TH3_UNIT_VALIDATE(unit);
   1229     SOC_IF_ERROR_RETURN(soc_esw_portctrl_init_check(unit));
   1230 
   1231     if (!soc_th3_port_asf_valid(unit, port)) {
   1232         return BCM_E_NONE;
   1233     }
   1234 
   1235     if (!_soc_th3_asf_ctrl[unit] || !_soc_th3_asf_ctrl[unit]->init) {
   1236         return SOC_E_INTERNAL;
   1237     }
   1238 
   1239     SOC_IF_ERROR_RETURN(
   1240         soc_th3_port_asf_mode_get(unit, port, port_speed, &mode));
   1241 
   1242     SOC_IF_ERROR_RETURN(
   1243         _soc_th3_port_asf_speed_limits_read(unit, port, &min_sp, &max_sp));
   1244 
   1245     min_speed = _soc_th3_asf_speed_get(min_sp);
   1246     max_speed = _soc_th3_asf_speed_get(max_sp);
   1247 
   1248     if (mode != SOC_TH3_ASF_MODE_SAF) {
   1249         dst_port_speed = min_speed;
   1250     } else {
   1251         dst_port_speed = port_speed;
   1252     }
   1253 
   1254     SOC_IF_ERROR_RETURN(
   1255         _soc_th3_port_asf_class_get(unit, port, &ct_class));
   1256 
   1257     SOC_IF_ERROR_RETURN(
   1258         _soc_th3_port_asf_fifo_threshold_get(unit, dst_port_speed,
   1259             &fifo_threshold));
   1260 
   1261     dst_class = soc_tomahawk3_get_ct_class(dst_port_speed);
   1262     for (src_class = 0; src_class < _SOC_TH3_CT_CLASS_VALID_NUM; src_class++) {
   1263         xmit_start_cnt[src_class] = _SOC_TH3_ASF_RETRV;
   1264         SOC_IF_ERROR_RETURN(
   1265             soc_th3_port_asf_xmit_start_count_get(unit, port, src_class,
   1266                                                   dst_class, mode,
   1267                                                   &xmit_start_cnt[src_class]));
   1268     }
   1269 
   1270     LOG_CLI(("%-5s %-3d %-3d %-6d %-6d %-3d   ", SOC_PORT_NAME(unit, port),
   1271              mode, ct_class, min_speed, max_speed, fifo_threshold));
   1272     for (src_class = 0; src_class < _SOC_TH3_CT_CLASS_VALID_NUM; src_class++) {
   1273         LOG_CLI(("%-3d ", xmit_start_cnt[src_class]));
   1274     }
   1275 
   1276 
   1277     SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ANY,
   1278                         phy_port, &credit_entry));
   1279     egr_mmu_cell_credits = soc_EGR_MMU_CELL_CREDITm_field32_get(unit,
   1280                            &credit_entry, CREDITf);
   1281 
   1282     SOC_IF_ERROR_RETURN(
   1283             portmod_port_pause_control_get(unit, port, &pause_control));
   1284     rxp = pause_control.rx_enable;
   1285     LOG_CLI((" %-3d %-3d \n", egr_mmu_cell_credits, rxp));
   1286 
   1287     return SOC_E_NONE;
   1288 }
   1289 
   1290 /**
   1291  * Function:
   1292  * soc_th3_port_asf_show
   1293  * Purpose:
   1294  *      Print per-port traffic forwarding mode in diag Shell.
   1295  * Parameters:
   1296  *      unit - (IN) Unit number.
   1297  *      port - (IN) Logical port number.
   1298  *      port_speed - (IN) Port speed in MB/s.
   1299  * Returns:
   1300  *      SOC_E_xxx
   1301  */
   1302 int
   1303 soc_th3_port_asf_show(
   1304     int        unit,
   1305     soc_port_t port,
   1306     int        port_speed)
   1307 {
   1308 #define _STRING_LEN 5
   1309 #define _ASF_MODE_NUM 2
   1310 
   1311     char mode_str[_ASF_MODE_NUM][_STRING_LEN] = {"SAF", "CT"};
   1312     char speed_str[_SOC_TH3_CT_CLASS_VALID_NUM][_STRING_LEN] = {
   1313                               "SAF", "10G", "25G", "40G",
   1314                               "50G", "100G", "200G", "400G"};
   1315     soc_th3_asf_mode_t mode = SOC_TH3_ASF_MODE_SAF;
   1316     int min_speed, max_speed;
   1317 
   1318     if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) {
   1319         return BCM_E_NONE;
   1320     }
   1321 
   1322     SOC_IF_ERROR_RETURN(
   1323         soc_th3_port_asf_mode_get(unit, port, port_speed, &mode));
   1324 
   1325 
   1326     LOG_CLI(("%-5s     %-11s      ", SOC_PORT_NAME(unit, port), mode_str[mode]));
   1327 
   1328     if (SOC_TH3_ASF_MODE_SAF == mode) {
   1329         LOG_CLI(("    .. NA ..\n"));
   1330     } else if (SOC_TH3_ASF_MODE_CT == mode) {
   1331         SOC_IF_ERROR_RETURN(
   1332             _soc_th3_port_asf_speed_limits_get(unit, port_speed, mode,
   1333                                                 &min_speed, &max_speed));
   1334         LOG_CLI(("%s / %s\n", speed_str[max_speed], speed_str[min_speed]));
   1335     }
   1336 #undef _STRING_LEN
   1337 #undef _ASF_MODE_NUM
   1338     return SOC_E_NONE;
   1339 }
   1340 
   1341 /**
   1342  * Function:
   1343  * soc_th3_asf_class_init
   1344  * Purpose:
   1345  *      Initialize CT class memory.
   1346  * Parameters:
   1347  *      unit - (IN) Unit number.
   1348  *      port - (IN) Logical port number.
   1349  *      class_id (IN) CT class ID.
   1350  * Returns:
   1351  *      SOC_E_xxx
   1352  */
   1353 
   1354 int
   1355 soc_th3_asf_class_init(
   1356     int unit,
   1357     soc_port_t port,
   1358     uint32 class_id)
   1359 {
   1360     edb_ip_cut_thru_class_entry_t entry;
   1361     sal_memset(&entry, 0, sizeof(edb_ip_cut_thru_class_entry_t));
   1362     soc_mem_field32_set(unit, EDB_IP_CUT_THRU_CLASSm, &entry,
   1363                         CUT_THRU_CLASSf, class_id);
   1364     SOC_IF_ERROR_RETURN
   1365         (WRITE_EDB_IP_CUT_THRU_CLASSm(unit, MEM_BLOCK_ALL, port, &entry));
   1366 
   1367     return SOC_E_NONE;
   1368 }
   1369 
   1370 
   1371 /******************************************************************************
   1372  * Name: soc_th3_port_asf_xmit_start_count_get                                *
   1373  * Description:                                                               *
   1374  *     Query or retrieve the XMIT Start Count for the specified source class  *
   1375  *     of the port depending on the magic number passed in xmit_cnt           *
   1376  * IN params:                                                                 *
   1377  *     - Unit                                                                 *
   1378  *     - Logical Port                                                         *
   1379  *     - Source Port's Class                                                  *
   1380  *     - Destination Port's CT Class                                          *
   1381  *     - ASF Mode                                                             *
   1382  * IN/OUT params:                                                             *
   1383  *     - xmit_cnt : IN:  carries magic number for query / retrieve            *
   1384  *     - xmit_cnt : OUT: contains a valid XMIT START COUNT for the            *
   1385  *       source port class, on success                                        *
   1386  * Returns:                                                                   *
   1387  *     - SOC_E_NONE on success                                                *
   1388  *     - SOC_E_PARAM on invalid parameter                                     *
   1389  *     - SOC_E_INTERNAL on init/soc errors                                    *
   1390  */
   1391 int
   1392 soc_th3_port_asf_xmit_start_count_get(
   1393     int                      unit,
   1394     soc_port_t               port,
   1395     int                      sc,
   1396     int                      dc,
   1397     soc_th3_asf_mode_t        mode,
   1398     uint8                    *xmit_cnt)
   1399 {
   1400     soc_info_t *si;
   1401     edb_xmit_start_count_entry_t entry;
   1402     int port_idx;
   1403     int pipe;
   1404     soc_mem_t config_mem = INVALIDm;
   1405 
   1406     _SOC_ASF_TH3_UNIT_VALIDATE(unit);
   1407 
   1408     if (!(si = &SOC_INFO(unit))) {
   1409         return SOC_E_INTERNAL;
   1410     }
   1411 
   1412     pipe = si->port_pipe[port];
   1413     config_mem = SOC_MEM_UNIQUE_ACC(unit, EDB_XMIT_START_COUNTm)[pipe];
   1414 
   1415     if (!xmit_cnt ||
   1416         !((mode >= SOC_TH3_ASF_MODE_SAF) &&
   1417           (mode <= SOC_TH3_ASF_MODE_CT))) {
   1418         return SOC_E_PARAM;
   1419     }
   1420     _SOC_TH3_ASF_SPEED_CLASS_VALIDATE(sc);
   1421     _SOC_TH3_ASF_SPEED_CLASS_VALIDATE(dc);
   1422 
   1423 
   1424     if (_SOC_TH3_ASF_RETRV == *xmit_cnt) {
   1425         *xmit_cnt = 0;
   1426         port_idx = ((port % SOC_TH3_MAX_DEV_PORTS_PER_PIPE)
   1427                     * _SOC_TH3_CT_CLASS_TOTAL_NUM) + sc;
   1428 
   1429         sal_memset(&entry, 0, sizeof(edb_xmit_start_count_entry_t));
   1430         SOC_IF_ERROR_RETURN(soc_mem_read(unit, config_mem, MEM_BLOCK_ALL,
   1431                                                      port_idx, &entry));
   1432         *xmit_cnt = soc_mem_field32_get(unit, config_mem,
   1433                                         &entry, THRESHOLDf);
   1434     } else if (_SOC_TH3_ASF_QUERY == *xmit_cnt) {
   1435         /* TH3: EDB_XMIT_START_COUNT is programmed by
   1436          * soc_tomahawk3_ep_set_xmit_start_cnt. This function should not be used
   1437          * to query and program the memory*/
   1438         return SOC_E_INTERNAL;
   1439 
   1440     }
   1441 
   1442     return SOC_E_NONE;
   1443 }
   1444 /******************************************************************************
   1445  * Name: soc_th3_port_asf_xmit_start_count_set                                *
   1446  * Description:                                                               *
   1447  *     Initialize XMIT START COUNT memory for all the source class for the    *
   1448  *     specified port                                                         *
   1449  * IN params:                                                                 *
   1450  *     - Unit                                                                 *
   1451  *     - Logical Port                                                         *
   1452  *     - Port Speed                                                           *
   1453  *     - ASF Mode                                                             *
   1454  *     - Extra cells (if any, to be added to xmit start count)                *
   1455  * Returns:                                                                   *
   1456  *     - SOC_E_NONE on success                                                *
   1457  *     - SOC_E_PARAM on invalid parameter                                     *
   1458  */
   1459 int
   1460 soc_th3_port_asf_xmit_start_count_set(
   1461     int                  unit,
   1462     soc_port_t           port,
   1463     int                  port_speed,
   1464     soc_th3_asf_mode_t    mode,
   1465     uint8                extra_cells)
   1466 {
   1467     edb_xmit_start_count_entry_t entry;
   1468     soc_info_t *si = &SOC_INFO(unit);
   1469     uint8                        xmit_cnt = 0;
   1470     int                          src_class, dst_class = 0, port_idx;
   1471     int                          pipe;
   1472     soc_mem_t                    config_mem = INVALIDm;
   1473 
   1474     if (!((mode >= SOC_TH3_ASF_MODE_SAF) &&
   1475           (mode <= SOC_TH3_ASF_MODE_CFG_UPDATE))) {
   1476         return SOC_E_PARAM;
   1477     }
   1478 
   1479     if (SOC_TH3_ASF_MODE_CFG_UPDATE != mode) {
   1480         if (SOC_E_PARAM == (dst_class = soc_tomahawk3_get_ct_class(port_speed))) {
   1481             /* port on a speed unsupported by CT - will resort to SAF */
   1482             dst_class = 0;
   1483         }
   1484     }
   1485 
   1486     sal_memset(&entry, 0, sizeof(edb_xmit_start_count_entry_t));
   1487 
   1488     pipe = si->port_pipe[port];
   1489     config_mem = SOC_MEM_UNIQUE_ACC(unit, EDB_XMIT_START_COUNTm)[pipe];
   1490 
   1491     for (src_class = 0; src_class < _SOC_TH3_CT_CLASS_VALID_NUM; src_class++) {
   1492         if (SOC_TH3_ASF_MODE_CFG_UPDATE == mode) {
   1493             xmit_cnt = _SOC_TH3_ASF_RETRV;
   1494         } else {
   1495             xmit_cnt = _SOC_TH3_ASF_QUERY;
   1496         }
   1497         SOC_IF_ERROR_RETURN(
   1498             soc_th3_port_asf_xmit_start_count_get(unit, port, src_class,
   1499                                                    dst_class, mode, &xmit_cnt));
   1500         xmit_cnt += extra_cells;
   1501 
   1502         port_idx = ((port % SOC_TH3_MAX_DEV_PORTS_PER_PIPE)
   1503                         * _SOC_TH3_CT_CLASS_TOTAL_NUM) + src_class;
   1504 
   1505         soc_mem_field32_set(unit, config_mem, &entry,
   1506                             THRESHOLDf, xmit_cnt);
   1507         SOC_IF_ERROR_RETURN(soc_mem_write(unit, config_mem, MEM_BLOCK_ALL,
   1508                                           port_idx, &entry));
   1509     }
   1510 
   1511     return SOC_E_NONE;
   1512 }
   1513 
   1514 /************************
   1515  * ASF Warmboot Support *
   1516  */
   1517 #ifdef BCM_WARM_BOOT_SUPPORT
   1518 
   1519 #define BCM_WB_VERSION_1_0                SOC_SCACHE_VERSION(1,0)
   1520 #define BCM_WB_VERSION_1_1                SOC_SCACHE_VERSION(1,1)
   1521 #define BCM_WB_VERSION_1_2                SOC_SCACHE_VERSION(1,2)
   1522 #define BCM_WB_VERSION_1_3                SOC_SCACHE_VERSION(1,3)
   1523 #define BCM_WB_VERSION_1_4                SOC_SCACHE_VERSION(1,4)
   1524 #define BCM_WB_VERSION_1_5                SOC_SCACHE_VERSION(1,5)
   1525 #define BCM_WB_VERSION_1_6                SOC_SCACHE_VERSION(1,6)
   1526 #define BCM_WB_VERSION_1_7                SOC_SCACHE_VERSION(1,7)
   1527 #define BCM_WB_VERSION_1_8                SOC_SCACHE_VERSION(1,8)
   1528 #define BCM_WB_DEFAULT_VERSION            BCM_WB_VERSION_1_8
   1529 
   1530 int
   1531 soc_th3_asf_wb_memsz_get(
   1532     int               unit,
   1533     OUT uint32* const mem_sz,
   1534     uint16            scache_ver)
   1535 {
   1536     if (!mem_sz) {
   1537         return SOC_E_PARAM;
   1538     }
   1539     *mem_sz = 0;
   1540 
   1541     if (!SOC_WARM_BOOT(unit)) {
   1542         if (!_soc_th3_asf_ctrl[unit] ) {
   1543             return SOC_E_UNAVAIL;
   1544         }
   1545         if (!_soc_th3_asf_ctrl[unit]->init) {
   1546             return SOC_E_INTERNAL;
   1547         }
   1548     }
   1549 
   1550     *mem_sz = sizeof(_soc_th3_asf_wb_t);
   1551 
   1552     if (scache_ver < BCM_WB_VERSION_1_8) {
   1553         /* adjust wb area sz for lower versions */
   1554         *mem_sz -= sizeof(int);
   1555     }
   1556 
   1557     return SOC_E_NONE;
   1558 }
   1559 
   1560 int
   1561 soc_th3_asf_wb_sync(
   1562     int    unit,
   1563     IN_OUT uint8* const wb_data)
   1564 {
   1565     _soc_th3_asf_wb_t *wbd;
   1566 
   1567     if (!_soc_th3_asf_ctrl[unit]) {
   1568         return SOC_E_UNAVAIL;
   1569     }
   1570     if (!_soc_th3_asf_ctrl[unit]->init) {
   1571         return SOC_E_INTERNAL;
   1572     }
   1573     if (!wb_data) {
   1574         return SOC_E_PARAM;
   1575     }
   1576 
   1577     wbd = (_soc_th3_asf_wb_t *) wb_data;
   1578     wbd->unit = unit;
   1579     sal_memcpy(&wbd->asf_ctrl, _soc_th3_asf_ctrl[unit],
   1580                sizeof(_soc_th3_asf_ctrl_t));
   1581 
   1582     return SOC_E_NONE;
   1583 }
   1584 
   1585 int
   1586 soc_th3_asf_wb_recover(
   1587     int          unit,
   1588     uint8* const wb_data,
   1589     uint16       scache_ver)
   1590 {
   1591     _soc_th3_asf_wb_t *wbd;
   1592     int adj = 0; /*scache ver adjustment */
   1593 
   1594     if (!SOC_WARM_BOOT(unit)) {
   1595         return SOC_E_INTERNAL;
   1596     }
   1597     if (!wb_data) {
   1598         return SOC_E_PARAM;
   1599     }
   1600 
   1601     wbd = (_soc_th3_asf_wb_t *) wb_data;
   1602     if (wbd->unit == unit) {
   1603         if (!(_soc_th3_asf_ctrl[unit] =
   1604                    sal_alloc(sizeof(_soc_th3_asf_ctrl_t), "TH ASF Ctrl Area"))) {
   1605             return SOC_E_MEMORY;
   1606         }
   1607 
   1608         sal_memcpy(_soc_th3_asf_ctrl[unit], &wbd->asf_ctrl,
   1609                    (sizeof(_soc_th3_asf_ctrl_t) - adj));
   1610     }
   1611 
   1612     LOG_CLI((BSL_META_U(unit, "*** unit %d: MMU-ASF subsystem warmbooted: \n"),
   1613                      unit));
   1614 
   1615     return SOC_E_NONE;
   1616 }
   1617 #endif /* BCM_WARM_BOOT_SUPPORT */
   1618 
   1619 #endif