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

clmac.c (101176B)


      1 /*
      2  *         
      3  * 
      4  * 
      5  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      6  * 
      7  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      8  */
      9 
     10 #include <soc/portmod/portmod.h>
     11 #include <soc/portmod/clmac.h>
     12 #include <soc/drv.h>
     13 
     14 #if defined(PORTMOD_PM4X25_SUPPORT)
     15 
     16 #ifdef _ERR_MSG_MODULE_NAME 
     17 #error "_ERR_MSG_MODULE_NAME redefined" 
     18 #endif
     19 #define _ERR_MSG_MODULE_NAME BSL_LS_SOC_PORT
     20 
     21 /*
     22  * version device
     23  * 0xA023  TD2P, Apache, Jericho, Jericho+, QAX, QMX
     24  * 0xA030  TH2
     25  */
     26 typedef enum {
     27     CLMAC_VERSION_A023 = 0xA023,
     28     CLMAC_VERSION_A030 = 0xA030
     29 }clmac_version_t;
     30 
     31 #define CLMAC_SPEED_100000 0x0
     32 #define CLMAC_CRC_MODE_APPEND   0
     33 #define CLMAC_CRC_MODE_REPLACE  2
     34 
     35 #define CLMAC_AVERAGE_IPG_DEFAULT         12
     36 #define CLMAC_AVERAGE_IPG_HIGIG           8
     37 
     38 #define CLMAC_TX_PREAMBLE_LENGTH  8
     39 
     40 #define CLMAC_JUMBO_MAXSZ 0x3fe8
     41 
     42 #define CLMAC_RUNT_THRESHOLD_ETH    64
     43 #define CLMAC_RUNT_THRESHOLD_HIGIG  72
     44 #define CLMAC_RUNT_THRESHOLD_HIGIG2 76
     45 
     46 /*
     47  *  WAN mode throttling
     48  *  THROT_10G_TO_5G: throt_num=21 throt_denom=21
     49  *  THROT_10G_TO_2P5G: throt_num=63 throt_denom=21
     50  */
     51 #define CLMAC_THROT_10G_TO_5G    256
     52 #define CLMAC_THROT_10G_TO_2P5G  257
     53 
     54 STATIC
     55 int _clmac_version_get(int unit, soc_port_t port, int32 *version)
     56 {
     57     uint64 reg_val;
     58     SOC_INIT_FUNC_DEFS;
     59 
     60     if (!SOC_REG_IS_VALID(unit, CLMAC_VERSION_IDr)) {
     61         *version = -1;
     62     }
     63     else {
     64         _SOC_IF_ERR_EXIT(READ_CLMAC_VERSION_IDr(unit, port, &reg_val));
     65         *version = soc_reg64_field32_get(unit, CLMAC_VERSION_IDr, reg_val, CLMAC_VERSIONf);
     66     }
     67 
     68 exit:
     69     SOC_FUNC_RETURN;
     70 }
     71 
     72 #ifdef BCM_APACHE_SUPPORT
     73 
     74 int soc_apache_clmac_gen2_ports[] = {
     75     0,                /* PHY port 0 is invalid              */
     76     0, 0, 0, 0,       /* PHY ports 1-4:   PM 4x10  inst 0   */
     77     0, 0, 0, 0,       /* PHY ports 5-8:   PM 4x10  inst 1   */
     78     0, 0, 0, 0,       /* PHY ports 9-12:  PM 4x10  inst 2   */
     79     0, 0, 0, 0,       /* PHY ports 13-16: PM 4x10  inst 3   */
     80     0, 0, 0, 0,       /* PHY ports 17-20: PM 12x10 inst 0.0 */
     81     0, 0, 0, 0,       /* PHY ports 21-24: PM 12x10 inst 0.1 */
     82     0, 0, 0, 0,       /* PHY ports 25-28: PM 12x10 inst 0.2 */
     83     1, 1, 1, 1,       /* PHY ports 29-32: PM 4x25  inst 0   */
     84     1, 1, 1, 1,       /* PHY ports 33-36: PM 4x25  inst 1   */
     85     0, 0, 0, 0,       /* PHY ports 37-40: PM 4x10  inst 4   */
     86     0, 0, 0, 0,       /* PHY ports 41-44: PM 4x10  inst 5   */
     87     0, 0, 0, 0,       /* PHY ports 45-48: PM 4x10  inst 6   */
     88     0, 0, 0, 0,       /* PHY ports 49-52: PM 4x10  inst 7   */
     89     0, 0, 0, 0,       /* PHY ports 53-56: PM 12x10 inst 1.0 */
     90     0, 0, 0, 0,       /* PHY ports 57-60: PM 12x10 inst 1.1 */
     91     0, 0, 0, 0,       /* PHY ports 61-64: PM 12x10 inst 1.2 */
     92     1, 1, 1, 1,       /* PHY ports 65-68: PM 4x25  inst 2   */
     93     1, 1, 1, 1,       /* PHY ports 69-72: PM 4x25  inst 3   */
     94 };
     95 
     96 
     97 int soc_apache_port_is_clg2_port(int unit, int port)
     98 {
     99     if (soc_feature(unit, soc_feature_clport_gen2)) {
    100         return (soc_apache_clmac_gen2_ports[SOC_INFO(unit).port_l2p_mapping[port]]);
    101     } else {
    102         return 0;
    103     }
    104 }
    105 
    106 
    107 #define RD_CLMAC(name, unit, port, val) do { \
    108         if (soc_apache_port_is_clg2_port(unit, port)) { \
    109             SOC_IF_ERROR_RETURN(READ_CLG2MAC_##name(unit, port, val)); \
    110         } else { \
    111             SOC_IF_ERROR_RETURN(READ_CLMAC_##name(unit, port, val)); \
    112         } \
    113     } while(0)
    114 
    115 #define WR_CLMAC(name, unit, port, val) do { \
    116         if (soc_apache_port_is_clg2_port(unit, port)) { \
    117             SOC_IF_ERROR_RETURN(WRITE_CLG2MAC_##name(unit, port, val)); \
    118         } else { \
    119             SOC_IF_ERROR_RETURN(WRITE_CLMAC_##name(unit, port, val)); \
    120         } \
    121     } while(0)
    122 
    123 
    124 #else
    125 
    126 #define RD_CLMAC(name, unit, port, val) SOC_IF_ERROR_RETURN(READ_CLMAC_##name(unit, port, val));
    127 #define WR_CLMAC(name, unit, port, val) SOC_IF_ERROR_RETURN(WRITE_CLMAC_##name(unit, port, val));
    128 
    129 #endif
    130 
    131 int clmac_init(int unit, soc_port_t port, uint32 init_flags)
    132 {
    133     portmod_pause_control_t pause_control;
    134     portmod_pfc_control_t pfc_control;
    135     portmod_llfc_control_t llfc_control;
    136     portmod_remote_fault_control_t remote_fault_control;
    137     portmod_local_fault_control_t local_fault_control;
    138     int crc_mode, is_ipg_check_disable;
    139     int is_strip_crc, is_append_crc, is_replace_crc, is_higig, is_pass_through_crc;
    140     uint64 reg_val;
    141     SOC_INIT_FUNC_DEFS;
    142 
    143     is_strip_crc =          (init_flags & CLMAC_INIT_F_RX_STRIP_CRC                 ? 1 : 0);
    144     is_append_crc =         (init_flags & CLMAC_INIT_F_TX_APPEND_CRC                ? 1 : 0);
    145     is_replace_crc =        (init_flags & CLMAC_INIT_F_TX_REPLACE_CRC               ? 1 : 0);
    146     is_pass_through_crc =   (init_flags & CLMAC_INIT_F_TX_PASS_THROUGH_CRC_MODE     ? 1 : 0);
    147     is_higig =              (init_flags & CLMAC_INIT_F_IS_HIGIG                     ? 1 : 0);
    148     is_ipg_check_disable =  (init_flags & CLMAC_INIT_F_IPG_CHECK_DISABLE            ? 1 : 0);
    149 
    150     if(is_append_crc + is_replace_crc + is_pass_through_crc > 1) {
    151         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("CLAMC_INIT_F_TX_APPEND_CRC, CLAMC_INIT_F_TX_REPLACE_CRC, and CLMAC_INIT_F_TX_PASS_THROUGH_CRC_MODE can't co-exist")));
    152     }
    153 
    154     /* RX Control */
    155     RD_CLMAC(RX_CTRLr, unit, port, &reg_val);
    156     soc_reg64_field32_set(unit, CLMAC_RX_CTRLr, &reg_val, STRIP_CRCf, is_strip_crc);
    157     soc_reg64_field32_set(unit, CLMAC_RX_CTRLr, &reg_val, STRICT_PREAMBLEf, is_higig ? 0 : 1);
    158     soc_reg64_field32_set(unit, CLMAC_RX_CTRLr, &reg_val, RUNT_THRESHOLDf, CLMAC_RUNT_THRESHOLD_ETH);
    159     WR_CLMAC(RX_CTRLr, unit, port, reg_val);
    160 
    161     /* TX Control */
    162     if(is_append_crc) {
    163         crc_mode = 0;
    164     } else if(is_replace_crc) {
    165         crc_mode = 2;
    166     } else if(is_pass_through_crc) {
    167         crc_mode = 1;
    168     } else { /* CRC AUTO Mode */
    169         crc_mode = 3;
    170     }
    171     RD_CLMAC(TX_CTRLr, unit, port, &reg_val);
    172     soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &reg_val, CRC_MODEf, crc_mode);
    173     soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &reg_val, AVERAGE_IPGf, is_higig ? CLMAC_AVERAGE_IPG_HIGIG : CLMAC_AVERAGE_IPG_DEFAULT);
    174     soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &reg_val, TX_PREAMBLE_LENGTHf, CLMAC_TX_PREAMBLE_LENGTH);
    175     WR_CLMAC(TX_CTRLr, unit, port, reg_val);
    176 
    177     /*Pause*/
    178     _SOC_IF_ERR_EXIT(portmod_pause_control_t_init(unit, &pause_control));
    179     /* PAUSE */
    180     pause_control.tx_enable = TRUE;
    181     pause_control.rx_enable = TRUE;
    182     _SOC_IF_ERR_EXIT(clmac_pause_control_set(unit, port, &pause_control));
    183     
    184     /*PFC*/
    185     _SOC_IF_ERR_EXIT(clmac_pfc_control_get(unit, port, &pfc_control));
    186     pfc_control.rx_enable = 0;
    187     pfc_control.tx_enable = 0;
    188     pfc_control.stats_en = 0;
    189     _SOC_IF_ERR_EXIT(clmac_pfc_control_set(unit, port, &pfc_control));
    190 
    191     /*LLFC*/
    192     _SOC_IF_ERR_EXIT(portmod_llfc_control_t_init(unit, &llfc_control));
    193     llfc_control.rx_enable = 0;
    194     llfc_control.tx_enable = 0;
    195     _SOC_IF_ERR_EXIT(clmac_llfc_control_set(unit, port, &llfc_control));
    196 
    197     /*LSS*/
    198     _SOC_IF_ERR_EXIT(portmod_remote_fault_control_t_init(unit, &remote_fault_control));
    199     remote_fault_control.enable = 1;
    200     remote_fault_control.drop_tx_on_fault = 1;
    201     _SOC_IF_ERR_EXIT(clmac_remote_fault_control_set(unit, port, &remote_fault_control));
    202 
    203     _SOC_IF_ERR_EXIT(portmod_local_fault_control_t_init(unit, &local_fault_control));
    204     local_fault_control.enable = 1;
    205     local_fault_control.drop_tx_on_fault = 1;
    206     _SOC_IF_ERR_EXIT(clmac_local_fault_control_set(unit, port, &local_fault_control));
    207 
    208     /*MAC control*/
    209     RD_CLMAC(CTRLr, unit, port, &reg_val);
    210     soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, LOCAL_LPBKf, 0);
    211     soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, TX_ENf, 1);
    212     soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, RX_ENf, 1);
    213     soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, SOFT_RESETf, 0); /*Deassert SOFT_RESET*/
    214     soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, XGMII_IPG_CHECK_DISABLEf, is_ipg_check_disable);
    215     soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, ALLOW_40B_AND_GREATER_PKTSf, 1);
    216     WR_CLMAC(CTRLr, unit, port, reg_val);
    217 
    218     RD_CLMAC(RX_MAX_SIZEr, unit, port, &reg_val);
    219     soc_reg64_field32_set(unit, CLMAC_RX_MAX_SIZEr, &reg_val, RX_MAX_SIZEf, CLMAC_JUMBO_MAXSZ);
    220     WR_CLMAC(RX_MAX_SIZEr, unit, port, reg_val);
    221 
    222 
    223 exit:
    224     SOC_FUNC_RETURN;
    225 }
    226 
    227 int clmac_enable_set(int unit, soc_port_t port, int flags, int enable)
    228 {
    229     uint64 reg_val, orig_reg_val;
    230     SOC_INIT_FUNC_DEFS;
    231 
    232 
    233     RD_CLMAC(CTRLr, unit, port, &reg_val);
    234     COMPILER_64_COPY(orig_reg_val, reg_val);
    235 
    236     if (flags & CLMAC_ENABLE_SET_FLAGS_TX_EN) {
    237         soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, TX_ENf, enable ? 1 : 0);
    238     } 
    239     if (flags & CLMAC_ENABLE_SET_FLAGS_RX_EN) {
    240         soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, RX_ENf, enable ? 1 : 0); 
    241     } 
    242     if (!(flags & CLMAC_ENABLE_SET_FLAGS_RX_EN) && !(flags & CLMAC_ENABLE_SET_FLAGS_TX_EN)) {
    243         soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, TX_ENf, enable ? 1 : 0);
    244         soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, RX_ENf, enable ? 1 : 0); 
    245     }
    246     if(COMPILER_64_NE(reg_val, orig_reg_val)) { /* write only if value changed */
    247         WR_CLMAC(CTRLr, unit, port, reg_val);
    248     }
    249 
    250     /*
    251      * check if mac soft reset operation is needed
    252      * if enable = 1, bring mac out of reset, else mac in reset.
    253      */
    254     if (!(flags & CLMAC_ENABLE_SET_FLAGS_SOFT_RESET_DIS)) {
    255         RD_CLMAC(CTRLr, unit, port, &reg_val);
    256         COMPILER_64_COPY(orig_reg_val, reg_val);
    257         soc_reg64_field32_set (unit, CLMAC_CTRLr, &reg_val, SOFT_RESETf,
    258                                enable ? 0 : 1);
    259     }    
    260 
    261     if(COMPILER_64_NE(reg_val, orig_reg_val)) {/* write only if value changed */
    262        SOC_IF_ERROR_RETURN(clmac_soft_reset_set(unit, port, !enable));
    263     }
    264 
    265     SOC_FUNC_RETURN;
    266 }
    267 
    268 int clmac_enable_get(int unit, soc_port_t port, int flags, int *enable)
    269 {
    270     uint64 reg_val;
    271     SOC_INIT_FUNC_DEFS;
    272 
    273     RD_CLMAC(CTRLr, unit, port, &reg_val);
    274     if (flags & CLMAC_ENABLE_SET_FLAGS_TX_EN) {
    275         *enable = soc_reg64_field32_get(unit, CLMAC_CTRLr, reg_val, TX_ENf); 
    276     } else {
    277         *enable = soc_reg64_field32_get(unit, CLMAC_CTRLr, reg_val, RX_ENf);
    278     }
    279     
    280 
    281     SOC_FUNC_RETURN;
    282 }
    283 
    284 int clmac_soft_reset_set(int unit, soc_port_t port, int enable)
    285 {
    286     uint64 reg_val;
    287 
    288     RD_CLMAC(CTRLr, unit, port, &reg_val);
    289 
    290     soc_reg64_field32_set (unit, CLMAC_CTRLr, &reg_val, 
    291                            SOFT_RESETf, enable? 1 : 0);
    292     WR_CLMAC(CTRLr, unit, port, reg_val);
    293     /*
    294      * Special handling for new mac version. Internally MAC loopback
    295      * looks for rising edge on MAC loopback configuration to enter
    296      * loopback state.
    297      * Do only if loopback is enabled on the port.
    298      */
    299     if (!enable &&
    300         soc_reg64_field32_get(unit, CLMAC_CTRLr, reg_val, LOCAL_LPBKf)) {
    301         soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, LOCAL_LPBKf, 0);
    302         WR_CLMAC(CTRLr, unit, port, reg_val);
    303         /* Wait 10usec as suggested by MAC designer */
    304         sal_udelay(10);
    305         soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, LOCAL_LPBKf, 1);
    306         WR_CLMAC(CTRLr, unit, port, reg_val);
    307     }
    308     return (SOC_E_NONE);
    309 }
    310 
    311 
    312 int clmac_soft_reset_get(int unit, soc_port_t port, int *enable)
    313 {
    314     uint64 reg_val;
    315 
    316     RD_CLMAC(CTRLr, unit, port, &reg_val);
    317 
    318     *enable = soc_reg64_field32_get(unit, CLMAC_CTRLr, reg_val, SOFT_RESETf)?1:0;
    319     return (SOC_E_NONE);
    320 }
    321 
    322 int clmac_timestamp_byte_adjust_set(int unit, soc_port_t port, int flags, int speed)
    323 {
    324     uint64 ctrl;
    325     uint32 byte_adjust = 0;
    326     SOC_INIT_FUNC_DEFS;
    327 
    328     if (100 == speed) {
    329         byte_adjust = 80;
    330     } else if (1000 == speed) {
    331         byte_adjust = 8;
    332     } else if (2500 == speed) {
    333         byte_adjust = 3;
    334     } else if (10000 == speed) {
    335         byte_adjust = 1;
    336     }
    337 
    338     if (SOC_REG_PORT_VALID(unit, CLMAC_TIMESTAMP_BYTE_ADJUSTr, port)) {
    339         if ((speed > 10000) || (flags == CLMAC_TIMESTAMP_BYTE_ADJUST_CLEAR)) {
    340             /* This shouldn't be enabled when speed is more than 10G */
    341             RD_CLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, &ctrl);
    342             soc_reg64_field32_set(unit, CLMAC_TIMESTAMP_BYTE_ADJUSTr, &ctrl,
    343                               TX_TIMER_BYTE_ADJUSTf, 0);
    344             soc_reg64_field32_set(unit, CLMAC_TIMESTAMP_BYTE_ADJUSTr, &ctrl,
    345                               TX_TIMER_BYTE_ADJUST_ENf, 0);
    346             soc_reg64_field32_set(unit, CLMAC_TIMESTAMP_BYTE_ADJUSTr, &ctrl,
    347                               RX_TIMER_BYTE_ADJUSTf, 0);
    348             soc_reg64_field32_set(unit, CLMAC_TIMESTAMP_BYTE_ADJUSTr, &ctrl,
    349                               RX_TIMER_BYTE_ADJUST_ENf, 0);
    350             WR_CLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, ctrl);
    351         } else {
    352             RD_CLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, &ctrl);
    353             soc_reg64_field32_set(unit, CLMAC_TIMESTAMP_BYTE_ADJUSTr, &ctrl,
    354                               TX_TIMER_BYTE_ADJUSTf, byte_adjust);
    355             WR_CLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, ctrl);
    356 
    357             RD_CLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, &ctrl);
    358             soc_reg64_field32_set(unit, CLMAC_TIMESTAMP_BYTE_ADJUSTr, &ctrl,
    359                               TX_TIMER_BYTE_ADJUST_ENf, 1);
    360             WR_CLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, ctrl);
    361 
    362             RD_CLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, &ctrl);
    363             soc_reg64_field32_set(unit, CLMAC_TIMESTAMP_BYTE_ADJUSTr, &ctrl,
    364                               RX_TIMER_BYTE_ADJUSTf, byte_adjust);
    365             WR_CLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, ctrl);
    366 
    367             RD_CLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, &ctrl);
    368             soc_reg64_field32_set(unit, CLMAC_TIMESTAMP_BYTE_ADJUSTr, &ctrl,
    369                               RX_TIMER_BYTE_ADJUST_ENf, 1);
    370             WR_CLMAC(TIMESTAMP_BYTE_ADJUSTr, unit, port, ctrl);
    371         }
    372     } else {
    373         return (SOC_E_UNAVAIL);
    374     }
    375 
    376     SOC_FUNC_RETURN;
    377 }
    378 
    379 int clmac_timestamp_delay_set(int unit, soc_port_t port,
    380                                           portmod_port_ts_adjust_t ts_adjust)
    381 {
    382     uint64 ctrl;
    383     int osts_delay = 0;
    384     int tsts_delay = 0;
    385 
    386     if (SOC_REG_IS_VALID(unit, CLMAC_TIMESTAMP_ADJUSTr)) {
    387 
    388 #ifdef BCM_TIMESYNC_SUPPORT
    389         uint32 clk_rate, tx_clk_ns;
    390         /* use VCO  25.78125 as default, CLMAC clock is VCO/40*/
    391         clk_rate =  644;
    392         tx_clk_ns = 1000 / clk_rate;
    393 #endif
    394 
    395         /* 6 TSC_CLK period + 1 TS_CLK period */
    396         if (ts_adjust.osts_adjust > 0) {
    397             osts_delay = ts_adjust.osts_adjust;
    398         }
    399 #ifdef BCM_TIMESYNC_SUPPORT
    400         else {
    401             osts_delay = SOC_TIMESYNC_PLL_CLOCK_NS(unit) + ((12 * tx_clk_ns ) / 2);
    402         }
    403 #endif
    404         RD_CLMAC(TIMESTAMP_ADJUSTr, unit, port, &ctrl);
    405         soc_reg64_field32_set(unit, CLMAC_TIMESTAMP_ADJUSTr, &ctrl,
    406                               TS_OSTS_ADJUSTf, osts_delay);
    407         WR_CLMAC(TIMESTAMP_ADJUSTr, unit, port, ctrl);
    408 
    409         /* (2.5 TSC_CLK period + 1 TS_CLK period */
    410         if (ts_adjust.tsts_adjust > 0) {
    411             tsts_delay = ts_adjust.tsts_adjust;
    412         }
    413 #ifdef BCM_TIMESYNC_SUPPORT
    414         else {
    415             tsts_delay = SOC_TIMESYNC_PLL_CLOCK_NS(unit) + ((5 * tx_clk_ns ) / 2);
    416         }
    417 #endif
    418         RD_CLMAC(TIMESTAMP_ADJUSTr, unit, port, &ctrl);
    419         soc_reg64_field32_set(unit, CLMAC_TIMESTAMP_ADJUSTr, &ctrl,
    420                               TS_TSTS_ADJUSTf, tsts_delay);
    421         WR_CLMAC(TIMESTAMP_ADJUSTr, unit, port, ctrl);
    422     }
    423 
    424 
    425     return SOC_E_NONE;
    426 }
    427 
    428 int clmac_timestamp_delay_get(int unit, soc_port_t port,
    429                               portmod_port_ts_adjust_t *ts_adjust)
    430 {
    431     uint64 reg_val;
    432 
    433     if (SOC_REG_IS_VALID(unit, CLMAC_TIMESTAMP_ADJUSTr)) {
    434         RD_CLMAC(TIMESTAMP_ADJUSTr, unit, port, &reg_val);
    435         ts_adjust->osts_adjust = soc_reg64_field32_get (unit, CLMAC_TIMESTAMP_ADJUSTr, reg_val,
    436                                      TS_OSTS_ADJUSTf);
    437         ts_adjust->tsts_adjust = soc_reg64_field32_get (unit, CLMAC_TIMESTAMP_ADJUSTr, reg_val,
    438                                      TS_TSTS_ADJUSTf);
    439     } else {
    440         return SOC_E_UNAVAIL;
    441     }
    442 
    443     return SOC_E_NONE;
    444 }
    445 
    446 int clmac_speed_set(int unit, soc_port_t port, int flags, int speed)
    447 {
    448     uint64 reg_val, orig_reg_val;
    449     int enable, enable_flags = 0;
    450     uint32 rval = 0, fault = 0;
    451     SOC_INIT_FUNC_DEFS;
    452 
    453     COMPILER_64_ZERO(orig_reg_val);
    454 
    455     SOC_IF_ERROR_RETURN(clmac_enable_get(unit, port, 0, &enable));
    456 
    457     /* disable before updating the speed */	
    458     if (enable) {
    459         if (flags & CLMAC_SPEED_SET_FLAGS_SOFT_RESET_DIS) {
    460             enable_flags |= CLMAC_ENABLE_SET_FLAGS_SOFT_RESET_DIS;
    461         }
    462         SOC_IF_ERROR_RETURN(clmac_enable_set(unit, port, enable_flags, 0));
    463     }
    464 
    465     RD_CLMAC(MODEr, unit, port, &reg_val);
    466     COMPILER_64_ADD_64(orig_reg_val, reg_val);
    467     soc_reg64_field32_set(unit, CLMAC_MODEr, &reg_val, SPEED_MODEf, ((speed>= 10000) || (speed==0)) ? 4 : 2); 
    468 
    469     if(COMPILER_64_NE(orig_reg_val, reg_val)) {
    470         WR_CLMAC(MODEr, unit, port, reg_val);
    471     }
    472 
    473     /*
    474      * Set REMOTE_FAULT/LOCAL_FAULT for CL ports,
    475      * else HW Linkscan interrupt would be suppressed.
    476      */
    477     if (SOC_REG_IS_VALID(unit, CLPORT_FAULT_LINK_STATUSr)) {
    478         fault = speed <= 1000 ? 0 : 1;
    479 
    480         SOC_IF_ERROR_RETURN(READ_CLPORT_FAULT_LINK_STATUSr(unit, port, &rval));
    481         soc_reg_field_set(unit, CLPORT_FAULT_LINK_STATUSr, &rval,
    482                           REMOTE_FAULTf, fault);
    483         soc_reg_field_set(unit, CLPORT_FAULT_LINK_STATUSr, &rval,
    484                           LOCAL_FAULTf, fault);
    485         SOC_IF_ERROR_RETURN(WRITE_CLPORT_FAULT_LINK_STATUSr(unit, port, rval));
    486     }
    487 
    488     if (enable) {
    489         if (flags & CLMAC_SPEED_SET_FLAGS_SOFT_RESET_DIS) {
    490             enable_flags |= CLMAC_ENABLE_SET_FLAGS_SOFT_RESET_DIS;
    491         }
    492         SOC_IF_ERROR_RETURN(clmac_enable_set(unit, port, enable_flags, 1));
    493     }
    494 
    495     SOC_FUNC_RETURN;
    496 }
    497 
    498 int clmac_loopback_set(int unit, soc_port_t port, portmod_loopback_mode_t lb, int enable)
    499 {
    500     uint64 reg_val;
    501     SOC_INIT_FUNC_DEFS;
    502 
    503     switch(lb){
    504         case portmodLoopbackMacOuter:
    505             RD_CLMAC(CTRLr, unit, port, &reg_val);
    506             soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, LOCAL_LPBKf, enable ? 1: 0);
    507             WR_CLMAC(CTRLr, unit, port, reg_val);
    508             break;
    509         default:
    510             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("unsupported loopback type %d"), lb));
    511     }
    512 
    513 exit:
    514     SOC_FUNC_RETURN;
    515 }
    516 
    517 int clmac_loopback_get(int unit, soc_port_t port, portmod_loopback_mode_t lb, int *enable)
    518 {
    519     uint64 reg_val;
    520     SOC_INIT_FUNC_DEFS;
    521 
    522     switch(lb){
    523         case portmodLoopbackMacOuter:
    524             RD_CLMAC(CTRLr, unit, port, &reg_val);
    525             *enable = soc_reg64_field32_get(unit, CLMAC_CTRLr, reg_val, LOCAL_LPBKf);
    526             break;
    527         default:
    528             /* set to 0 - this loopback is not in use for this MAC */
    529             *enable = 0;
    530             break;
    531     }
    532 
    533     SOC_FUNC_RETURN;
    534 }
    535 
    536 int clmac_tx_enable_set (int unit, soc_port_t port, int enable)
    537 {
    538     uint64 reg_val;
    539 
    540     RD_CLMAC(CTRLr , unit, port, &reg_val);
    541 
    542     soc_reg64_field32_set (unit, CLMAC_CTRLr, &reg_val,
    543                            TX_ENf, enable ? 1: 0);
    544     WR_CLMAC(CTRLr, unit, port, reg_val);
    545 
    546     return(SOC_E_NONE);
    547 }
    548 
    549 
    550 int clmac_tx_enable_get (int unit, soc_port_t port, int *enable)
    551 {
    552     uint64 reg_val;
    553 
    554     SOC_IF_ERROR_RETURN(READ_CLMAC_CTRLr(unit, port, &reg_val));
    555 
    556     *enable = soc_reg64_field32_get (unit, CLMAC_CTRLr, reg_val,
    557                                      TX_ENf);
    558 
    559     return(SOC_E_NONE);
    560 }
    561 
    562 int clmac_rx_enable_set (int unit, soc_port_t port, int enable)
    563 {
    564     uint64 reg_val;
    565 
    566     RD_CLMAC(CTRLr , unit, port, &reg_val);
    567 
    568     soc_reg64_field32_set (unit, CLMAC_CTRLr, &reg_val,
    569                            RX_ENf, enable ? 1: 0);
    570     WR_CLMAC(CTRLr, unit, port, reg_val);
    571 
    572     return(SOC_E_NONE);
    573 }
    574 
    575 int clmac_rx_enable_get (int unit, soc_port_t port, int *enable)
    576 {
    577     uint64 reg_val;
    578 
    579     RD_CLMAC(CTRLr, unit, port, &reg_val);
    580 
    581     *enable = soc_reg64_field32_get (unit, CLMAC_CTRLr, reg_val,
    582                                      RX_ENf);
    583 
    584     return(SOC_E_NONE);
    585 }
    586 
    587 /*
    588  * Function:
    589  *      _clmac_port_mode_update
    590  * Purpose:
    591  *      Set the CLMAC port encapsulation mode.
    592  * Parameters:
    593  *      unit - XGS unit #.
    594  *      port - XGS port # on unit.
    595  *      hg_mode - SOC HG encap modes. value={HG/HG2/HG2-LITE}
    596  * Returns:
    597  *      SOC_E_XXX
    598  */
    599 STATIC int
    600 _clmac_port_mode_update(int unit, soc_port_t port, int hg_mode)
    601 {
    602     uint64 tx_ctrl, rx_ctrl, mac_ctrl, mac_ctrl_orig;
    603 
    604     RD_CLMAC(CTRLr, unit, port, &mac_ctrl);
    605     RD_CLMAC(RX_CTRLr, unit, port, &rx_ctrl);
    606     RD_CLMAC(TX_CTRLr, unit, port, &tx_ctrl);
    607 
    608     mac_ctrl_orig = mac_ctrl;
    609 
    610     /* Disable Tx/Rx, assume that MAC is stable (or out of reset) */
    611     soc_reg64_field32_set(unit, CLMAC_CTRLr, &mac_ctrl, RX_ENf, 0);
    612     soc_reg64_field32_set(unit, CLMAC_CTRLr, &mac_ctrl, TX_ENf, 0);
    613 
    614     WR_CLMAC(CTRLr, unit, port, mac_ctrl);
    615 
    616     if (hg_mode != SOC_ENCAP_IEEE) { /* HiGig Mode */
    617         soc_reg64_field32_set(unit, CLMAC_CTRLr, &mac_ctrl_orig, XGMII_IPG_CHECK_DISABLEf, 1);
    618         soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &tx_ctrl, AVERAGE_IPGf, CLMAC_AVERAGE_IPG_HIGIG);
    619     } else {
    620         soc_reg64_field32_set(unit, CLMAC_CTRLr, &mac_ctrl_orig, XGMII_IPG_CHECK_DISABLEf, 0);
    621         soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &tx_ctrl, AVERAGE_IPGf, CLMAC_AVERAGE_IPG_DEFAULT);
    622     }
    623 
    624     WR_CLMAC(RX_CTRLr, unit, port, rx_ctrl);
    625     WR_CLMAC(TX_CTRLr, unit, port, tx_ctrl);
    626     WR_CLMAC(CTRLr, unit, port, mac_ctrl_orig); /* restore mac ctrl */
    627 
    628     return (SOC_E_NONE);
    629 }
    630 
    631 int clmac_encap_set(int unit, soc_port_t port, int flags, portmod_encap_t encap)
    632 {
    633     uint32 val = 0;
    634     uint64 reg_val;
    635     uint32 no_sop_for_crc_hg = 0;
    636     int enable, enable_flags = 0;
    637     SOC_INIT_FUNC_DEFS;
    638 
    639     switch(encap){
    640         case SOC_ENCAP_IEEE:
    641             val = 0;
    642             break;
    643         case SOC_ENCAP_HIGIG:
    644             val = 1;
    645             break;
    646         case SOC_ENCAP_HIGIG2:
    647             val = 2;
    648             break;
    649         case SOC_ENCAP_SOP_ONLY:
    650             val = 5;
    651             break;
    652         default:
    653             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("illegal encap mode %d"), encap));
    654     }
    655 
    656     SOC_IF_ERROR_RETURN(clmac_enable_get(unit, port, 0, &enable));
    657 
    658     if (enable) {
    659         if (flags & CLMAC_ENCAP_SET_FLAGS_SOFT_RESET_DIS) {
    660             enable_flags |= CLMAC_ENABLE_SET_FLAGS_SOFT_RESET_DIS;
    661         }
    662         /* Turn off TX/RX enable */
    663         SOC_IF_ERROR_RETURN(clmac_enable_set(unit, port, enable_flags, 0));
    664     }
    665 
    666     if ((IS_E_PORT(unit, port) && encap != SOC_ENCAP_IEEE) ||
    667             (IS_ST_PORT(unit, port) && encap == SOC_ENCAP_IEEE)) {
    668 
    669         SOC_IF_ERROR_RETURN(_clmac_port_mode_update(unit, port, encap));
    670     }
    671 
    672     if((encap == SOC_ENCAP_HIGIG) || (encap == SOC_ENCAP_HIGIG2)){
    673         if(flags & CLMAC_ENCAP_SET_FLAGS_NO_SOP_FOR_CRC_HG){
    674             no_sop_for_crc_hg = 1;
    675         }
    676     }
    677 
    678     RD_CLMAC(MODEr, unit, port, &reg_val);
    679     soc_reg64_field32_set(unit, CLMAC_MODEr, &reg_val, HDR_MODEf, val);
    680     soc_reg64_field32_set(unit, CLMAC_MODEr, &reg_val, NO_SOP_FOR_CRC_HGf, no_sop_for_crc_hg);
    681     WR_CLMAC(MODEr, unit, port, reg_val);
    682 
    683     if(encap == SOC_ENCAP_HIGIG2){
    684         RD_CLMAC(CTRLr, unit, port, &reg_val);
    685         soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, EXTENDED_HIG2_ENf, (flags & CLMAC_ENCAP_SET_FLAGS_EXTENDED_HIGIG2_EN) ? 1 : 0 );
    686         WR_CLMAC(CTRLr, unit, port, reg_val);
    687 
    688         RD_CLMAC(RX_CTRLr, unit, port, &reg_val);
    689         soc_reg64_field32_set(unit, CLMAC_RX_CTRLr, &reg_val, RUNT_THRESHOLDf, CLMAC_RUNT_THRESHOLD_HIGIG2);
    690         WR_CLMAC(RX_CTRLr, unit, port, reg_val);
    691     } else if (encap == SOC_ENCAP_HIGIG) {
    692         RD_CLMAC(RX_CTRLr, unit, port, &reg_val);
    693         soc_reg64_field32_set(unit, CLMAC_RX_CTRLr, &reg_val, RUNT_THRESHOLDf, CLMAC_RUNT_THRESHOLD_HIGIG);
    694         WR_CLMAC(RX_CTRLr, unit, port, reg_val);
    695     } else {
    696         RD_CLMAC(RX_CTRLr, unit, port, &reg_val);
    697         soc_reg64_field32_set(unit, CLMAC_RX_CTRLr, &reg_val, RUNT_THRESHOLDf, CLMAC_RUNT_THRESHOLD_ETH);
    698         WR_CLMAC(RX_CTRLr, unit, port, reg_val);
    699     }
    700 
    701     if (enable) {
    702         if (flags & CLMAC_ENCAP_SET_FLAGS_SOFT_RESET_DIS) {
    703             enable_flags |= CLMAC_ENABLE_SET_FLAGS_SOFT_RESET_DIS;
    704         }
    705         SOC_IF_ERROR_RETURN(clmac_enable_set(unit, port, enable_flags, 1));
    706     }
    707 
    708 exit:
    709     SOC_FUNC_RETURN;
    710 }
    711 
    712 int clmac_encap_get(int unit, soc_port_t port, int *flags, portmod_encap_t *encap){
    713     uint64 reg_val;
    714     uint32 fld_val;
    715     SOC_INIT_FUNC_DEFS;
    716 
    717     (*flags) = 0;
    718 
    719     RD_CLMAC(MODEr, unit, port, &reg_val);
    720     fld_val = soc_reg64_field32_get(unit, CLMAC_MODEr, reg_val, HDR_MODEf);
    721 
    722     switch(fld_val){
    723         case 0:
    724             *encap = SOC_ENCAP_IEEE;
    725             break;
    726         case 1:
    727             *encap = SOC_ENCAP_HIGIG;
    728             break;
    729         case 2:
    730             *encap = SOC_ENCAP_HIGIG2;
    731             break;
    732         case 5:
    733             *encap = SOC_ENCAP_SOP_ONLY;
    734             break;
    735         default:
    736             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("unknown encap mode %d"), fld_val));
    737             break;
    738     }
    739 
    740     if((*encap == SOC_ENCAP_HIGIG) || (*encap == SOC_ENCAP_HIGIG2)){
    741         fld_val = soc_reg64_field32_get(unit, CLMAC_MODEr, reg_val,
    742                                         NO_SOP_FOR_CRC_HGf);
    743         if(fld_val) {
    744             (*flags) |= CLMAC_ENCAP_SET_FLAGS_NO_SOP_FOR_CRC_HG;
    745         }
    746     }
    747 
    748     if(*encap == SOC_ENCAP_HIGIG2){
    749         RD_CLMAC(CTRLr, unit, port, &reg_val);
    750         fld_val = soc_reg64_field32_get(unit, CLMAC_CTRLr,
    751                                         reg_val, EXTENDED_HIG2_ENf);
    752         if(fld_val) {
    753             (*flags) |= CLMAC_ENCAP_SET_FLAGS_EXTENDED_HIGIG2_EN;
    754         }
    755     }
    756 
    757 exit:
    758     SOC_FUNC_RETURN;
    759 }
    760 
    761 int clmac_rx_max_size_set(int unit, soc_port_t port, int value)
    762 {
    763     uint64 reg_val;
    764     SOC_INIT_FUNC_DEFS;
    765 
    766     RD_CLMAC(RX_MAX_SIZEr, unit, port, &reg_val);
    767     soc_reg64_field32_set(unit, CLMAC_RX_MAX_SIZEr, &reg_val, RX_MAX_SIZEf, value);
    768     WR_CLMAC(RX_MAX_SIZEr, unit, port, reg_val);
    769 
    770     SOC_FUNC_RETURN;
    771 }
    772 
    773 int clmac_rx_max_size_get(int unit, soc_port_t port, int *value)
    774 {
    775     uint64 reg_val;
    776     SOC_INIT_FUNC_DEFS;
    777 
    778     RD_CLMAC(RX_MAX_SIZEr, unit, port, &reg_val);
    779     *value = soc_reg64_field32_get(unit, CLMAC_RX_MAX_SIZEr, reg_val, RX_MAX_SIZEf);
    780 
    781     SOC_FUNC_RETURN;
    782 }
    783 
    784 int clmac_pad_size_set(int unit, soc_port_t port, int value)
    785 {
    786     uint64 reg_val;
    787     SOC_INIT_FUNC_DEFS;
    788 
    789     RD_CLMAC(TX_CTRLr, unit, port, &reg_val);
    790     soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &reg_val, PAD_ENf, value ? 1 : 0);
    791     if(value){
    792         soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &reg_val, PAD_THRESHOLDf, value);
    793     }
    794     WR_CLMAC(TX_CTRLr, unit, port, reg_val);
    795 
    796     SOC_FUNC_RETURN;
    797 }
    798 
    799 int clmac_pad_size_get(int unit, soc_port_t port, int *value)
    800 {
    801     uint64 reg_val;
    802     int pad_en;
    803     SOC_INIT_FUNC_DEFS;
    804 
    805     RD_CLMAC(TX_CTRLr, unit, port, &reg_val);
    806     pad_en = soc_reg64_field32_get(unit, CLMAC_TX_CTRLr, reg_val, PAD_ENf);
    807     if(!pad_en){
    808         *value = 0;
    809     }
    810     else{
    811         *value = soc_reg64_field32_get(unit, CLMAC_TX_CTRLr, reg_val, PAD_THRESHOLDf);
    812     }
    813 
    814     SOC_FUNC_RETURN;
    815 }
    816 
    817 int clmac_runt_threshold_set(int unit, soc_port_t port, int value)
    818 {
    819     uint64 reg_val;
    820     SOC_INIT_FUNC_DEFS;
    821 
    822     if(value > 96){
    823         _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("runt size should be smaller than 96. got %d"), value));
    824     }
    825 
    826     RD_CLMAC(RX_CTRLr, unit, port, &reg_val);
    827     soc_reg64_field32_set(unit, CLMAC_RX_CTRLr, &reg_val, RUNT_THRESHOLDf, value);
    828     WR_CLMAC(RX_CTRLr, unit, port, reg_val);
    829 
    830 exit:
    831     SOC_FUNC_RETURN;
    832 }
    833 
    834 int clmac_runt_threshold_get(int unit, soc_port_t port, int *value)
    835 {
    836     uint64 reg_val;
    837     SOC_INIT_FUNC_DEFS;
    838 
    839     RD_CLMAC(RX_CTRLr, unit, port, &reg_val);
    840     *value = soc_reg64_field32_get(unit, CLMAC_RX_CTRLr, reg_val, RUNT_THRESHOLDf);
    841 
    842     SOC_FUNC_RETURN;
    843 }
    844 
    845 int clmac_strict_preamble_set(int unit, soc_port_t port, int value)
    846 {
    847     uint64 reg_val;
    848 
    849     RD_CLMAC(RX_CTRLr, unit, port, &reg_val);
    850     soc_reg64_field32_set(unit, CLMAC_RX_CTRLr, &reg_val, STRICT_PREAMBLEf, value);
    851     WR_CLMAC(RX_CTRLr, unit, port, reg_val);
    852 
    853     return (SOC_E_NONE);
    854 }
    855 
    856 int clmac_strict_preamble_get(int unit, soc_port_t port, int *value)
    857 {
    858     uint64 reg_val;
    859 
    860     SOC_IF_ERROR_RETURN(READ_CLMAC_RX_CTRLr(unit, port, &reg_val));
    861     *value = (int)soc_reg64_field32_get (unit, CLMAC_RX_CTRLr,
    862                                          reg_val, STRICT_PREAMBLEf);
    863     return (SOC_E_NONE);
    864 }
    865 
    866 int clmac_rx_vlan_tag_set(int unit, soc_port_t port, int outer_vlan_tag, int inner_vlan_tag)
    867 {
    868     uint64 reg_val;
    869     SOC_INIT_FUNC_DEFS;
    870 
    871     RD_CLMAC(RX_VLAN_TAGr, unit, port, &reg_val);
    872 
    873     if(inner_vlan_tag == -1){
    874         soc_reg64_field32_set(unit, CLMAC_RX_VLAN_TAGr, &reg_val, INNER_VLAN_TAG_ENABLEf, 0);
    875     } else{
    876         soc_reg64_field32_set(unit, CLMAC_RX_VLAN_TAGr, &reg_val, INNER_VLAN_TAGf, inner_vlan_tag);
    877         soc_reg64_field32_set(unit, CLMAC_RX_VLAN_TAGr, &reg_val, INNER_VLAN_TAG_ENABLEf, 1);
    878 
    879     }
    880 
    881     if(outer_vlan_tag == -1){
    882         soc_reg64_field32_set(unit, CLMAC_RX_VLAN_TAGr, &reg_val, OUTER_VLAN_TAG_ENABLEf, 0);
    883     } else {
    884         soc_reg64_field32_set(unit, CLMAC_RX_VLAN_TAGr, &reg_val, OUTER_VLAN_TAGf, outer_vlan_tag);
    885         soc_reg64_field32_set(unit, CLMAC_RX_VLAN_TAGr, &reg_val, OUTER_VLAN_TAG_ENABLEf, 1);
    886     }
    887 
    888     WR_CLMAC(RX_VLAN_TAGr, unit, port, reg_val);
    889 
    890     SOC_FUNC_RETURN;
    891 }
    892 
    893 
    894 int clmac_rx_vlan_tag_get(int unit, soc_port_t port, int *outer_vlan_tag, int *inner_vlan_tag)
    895 {
    896     uint64 reg_val;
    897     uint32 field_val = 0;
    898     SOC_INIT_FUNC_DEFS;
    899 
    900     RD_CLMAC(RX_VLAN_TAGr, unit, port, &reg_val);
    901     field_val = soc_reg64_field32_get(unit, CLMAC_RX_VLAN_TAGr, reg_val, INNER_VLAN_TAG_ENABLEf);
    902 
    903     if(field_val == 0){
    904         *inner_vlan_tag = -1;
    905     } else {
    906         *inner_vlan_tag = soc_reg64_field32_get(unit, CLMAC_RX_VLAN_TAGr, reg_val, INNER_VLAN_TAGf);
    907     }
    908 
    909     field_val = soc_reg64_field32_get(unit, CLMAC_RX_VLAN_TAGr, reg_val, OUTER_VLAN_TAG_ENABLEf);
    910     if(field_val == 0){
    911         *outer_vlan_tag = -1;
    912     } else {
    913         *outer_vlan_tag = soc_reg64_field32_get(unit, CLMAC_RX_VLAN_TAGr, reg_val, OUTER_VLAN_TAGf);
    914     }
    915 
    916     SOC_FUNC_RETURN;
    917 }
    918 
    919 int clmac_rx_mac_sa_set(int unit, soc_port_t port, sal_mac_addr_t mac)
    920 {
    921     uint64 mac_addr;
    922     SOC_INIT_FUNC_DEFS;
    923 
    924     /* high-order 8-bits of field value corresponds to mac[0],
    925        low-order 8-bits of field value corresponds to mac[5] */ 
    926     COMPILER_64_SET(mac_addr, _shr_uint16_read(&mac[0]), _shr_uint32_read(&mac[2]));
    927     
    928     WR_CLMAC(RX_MAC_SAr, unit, port, mac_addr);
    929 
    930     SOC_FUNC_RETURN;
    931 }
    932 
    933 
    934 int clmac_sw_link_status_select_set(int unit, soc_port_t port, int enable)
    935 {
    936     uint64 reg_val;
    937 
    938     RD_CLMAC(CTRLr, unit, port, &reg_val);
    939 
    940     soc_reg64_field32_set (unit, CLMAC_CTRLr, &reg_val, 
    941                            LINK_STATUS_SELECTf, enable);
    942 
    943     WR_CLMAC(CTRLr, unit, port, reg_val);
    944 
    945     return (SOC_E_NONE);
    946 }
    947 
    948 int clmac_sw_link_status_select_get(int unit, soc_port_t port, int *enable)
    949 {
    950     uint64 reg_val;
    951 
    952     RD_CLMAC(CTRLr, unit, port, &reg_val);
    953 
    954     *enable = (int)soc_reg64_field32_get (unit, CLMAC_CTRLr, reg_val, 
    955                                           LINK_STATUS_SELECTf);
    956     return (SOC_E_NONE);
    957 }
    958 
    959 int clmac_sw_link_status_set(int unit, soc_port_t port, int link)
    960 {
    961     uint64 reg_val;
    962 
    963     RD_CLMAC(CTRLr, unit, port, &reg_val);
    964 
    965     soc_reg64_field32_set(unit, CLMAC_CTRLr, &reg_val, SW_LINK_STATUSf, link);
    966     WR_CLMAC(CTRLr, unit, port, reg_val);
    967     return (SOC_E_NONE);
    968 }
    969 int clmac_rx_mac_sa_get(int unit, soc_port_t port, sal_mac_addr_t mac)
    970 {
    971     uint64 rval64, field64;
    972     uint32 values[2];
    973     SOC_INIT_FUNC_DEFS;
    974 
    975     RD_CLMAC(RX_MAC_SAr, unit, port, &rval64);
    976     field64 = soc_reg64_field_get(unit, CLMAC_RX_MAC_SAr, rval64, RX_SAf);
    977 
    978     values[0] = COMPILER_64_HI(field64);
    979     values[1] = COMPILER_64_LO(field64);
    980 
    981     mac[0] = (values[0] & 0x0000ff00) >> 8;
    982     mac[1] = values[0] & 0x000000ff;
    983     mac[2] = (values[1] & 0xff000000) >> 24;
    984     mac[3] = (values[1] & 0x00ff0000) >> 16;
    985     mac[4] = (values[1] & 0x0000ff00) >> 8;
    986     mac[5] = values[1] & 0x000000ff;
    987 
    988     SOC_FUNC_RETURN;
    989 }
    990 
    991 
    992 int clmac_tx_mac_sa_set(int unit, soc_port_t port, sal_mac_addr_t mac)
    993 {
    994     uint64 mac_addr;
    995     SOC_INIT_FUNC_DEFS;
    996 
    997     COMPILER_64_SET(mac_addr, _shr_uint16_read(&mac[0]), _shr_uint32_read(&mac[2]));
    998     
    999     WR_CLMAC(TX_MAC_SAr, unit, port, mac_addr);
   1000    
   1001     SOC_FUNC_RETURN;
   1002 }
   1003 
   1004 int clmac_tx_mac_sa_get(int unit, soc_port_t port, sal_mac_addr_t mac)
   1005 {
   1006     uint64 rval64;
   1007     uint32 values[2];
   1008     SOC_INIT_FUNC_DEFS;
   1009 
   1010     RD_CLMAC(TX_MAC_SAr, unit, port, &rval64);
   1011     values[0] = soc_reg64_field32_get(unit, CLMAC_TX_MAC_SAr, rval64, SA_HIf);
   1012     values[1] = soc_reg64_field32_get(unit, CLMAC_TX_MAC_SAr, rval64, SA_LOf);
   1013 
   1014     mac[0] = (values[0] & 0x0000ff00) >> 8;
   1015     mac[1] = values[0] & 0x000000ff;
   1016     mac[2] = (values[1] & 0xff000000) >> 24;
   1017     mac[3] = (values[1] & 0x00ff0000) >> 16;
   1018     mac[4] = (values[1] & 0x0000ff00) >> 8;
   1019     mac[5] = values[1] & 0x000000ff;
   1020 
   1021     SOC_FUNC_RETURN;
   1022 }
   1023 
   1024 int clmac_tx_average_ipg_set(int unit, soc_port_t port, int val)
   1025 {
   1026     uint64 reg_val;
   1027     SOC_INIT_FUNC_DEFS;
   1028 
   1029     COMPILER_64_ZERO(reg_val);
   1030 
   1031     RD_CLMAC(TX_CTRLr, unit, port, &reg_val);
   1032 
   1033     /* Silently adjust the specified ifp bits to valid value */
   1034     /* valid value: 8 to 64 bytes (i.e. multiple of 8 bits) */
   1035     val = val < 64 ? 64 : (val > 512 ? 512 : (val + 7) & (0x7f << 3));
   1036 
   1037     soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &reg_val, AVERAGE_IPGf, val/8);
   1038 
   1039     WR_CLMAC(TX_CTRLr, unit, port, reg_val);
   1040 
   1041     SOC_FUNC_RETURN
   1042 }
   1043 
   1044 int clmac_tx_average_ipg_get(int unit, soc_port_t port, int *val)
   1045 {
   1046     uint64 reg_val;
   1047     SOC_INIT_FUNC_DEFS;
   1048 
   1049     COMPILER_64_ZERO(reg_val);
   1050 
   1051     RD_CLMAC(TX_CTRLr, unit, port, &reg_val);
   1052 
   1053     *val = soc_reg64_field32_get(unit, CLMAC_TX_CTRLr, reg_val, AVERAGE_IPGf) * 8;
   1054 
   1055     SOC_FUNC_RETURN
   1056 }
   1057 
   1058 int clmac_tx_preamble_length_set(int unit, soc_port_t port, int length)
   1059 {
   1060     uint64 reg_val;
   1061 
   1062     if(length > 8){
   1063         LOG_VERBOSE(BSL_LS_SOC_COMMON,
   1064                     (BSL_META_U(unit, 
   1065                        "runt size should be small than 8. got %d"), length));
   1066         return (SOC_E_PARAM);
   1067     }
   1068 
   1069     COMPILER_64_ZERO(reg_val);
   1070 
   1071     RD_CLMAC(TX_CTRLr, unit, port, &reg_val);
   1072 
   1073     soc_reg64_field32_set (unit, CLMAC_TX_CTRLr, &reg_val, 
   1074                            TX_PREAMBLE_LENGTHf, length);
   1075     WR_CLMAC(TX_CTRLr, unit, port, reg_val);
   1076     return (SOC_E_NONE);
   1077 }
   1078 
   1079 /***************************************************************************** 
   1080  * Remote/local Fault                                                        *
   1081  */
   1082 
   1083 int clmac_remote_fault_control_set(int unit, soc_port_t port, const portmod_remote_fault_control_t *control)
   1084 {
   1085     uint64 reg_val;
   1086     SOC_INIT_FUNC_DEFS;
   1087 
   1088     RD_CLMAC(RX_LSS_CTRLr, unit, port, &reg_val);
   1089     soc_reg64_field32_set(unit, CLMAC_RX_LSS_CTRLr, &reg_val, REMOTE_FAULT_DISABLEf, control->enable ? 0 : 1 /*flip*/);
   1090     soc_reg64_field32_set(unit, CLMAC_RX_LSS_CTRLr, &reg_val, DROP_TX_DATA_ON_REMOTE_FAULTf, control->drop_tx_on_fault ? 1: 0);
   1091     WR_CLMAC(RX_LSS_CTRLr, unit, port, reg_val);
   1092 
   1093     SOC_FUNC_RETURN;
   1094 }
   1095 
   1096 int clmac_remote_fault_control_get(int unit, soc_port_t port, portmod_remote_fault_control_t *control)
   1097 {
   1098     uint64 reg_val;
   1099     uint32 field_val = 0;
   1100     SOC_INIT_FUNC_DEFS;
   1101 
   1102     RD_CLMAC(RX_LSS_CTRLr, unit, port, &reg_val);
   1103 
   1104     field_val = soc_reg64_field32_get(unit, CLMAC_RX_LSS_CTRLr, reg_val, REMOTE_FAULT_DISABLEf);
   1105     control->enable = (field_val ? 0 : 1);/*flip*/
   1106 
   1107     field_val = soc_reg64_field32_get(unit, CLMAC_RX_LSS_CTRLr, reg_val, DROP_TX_DATA_ON_REMOTE_FAULTf);
   1108     control->drop_tx_on_fault  = (field_val ? 1 : 0);
   1109 
   1110     SOC_FUNC_RETURN;
   1111 }
   1112 
   1113 int clmac_local_fault_control_set(int unit, soc_port_t port, const portmod_local_fault_control_t *control)
   1114 {
   1115     uint64 reg_val;
   1116     SOC_INIT_FUNC_DEFS;
   1117 
   1118     RD_CLMAC(RX_LSS_CTRLr, unit, port, &reg_val);
   1119     soc_reg64_field32_set(unit, CLMAC_RX_LSS_CTRLr, &reg_val, LOCAL_FAULT_DISABLEf, control->enable ? 0 : 1 /*flip*/);
   1120     soc_reg64_field32_set(unit, CLMAC_RX_LSS_CTRLr, &reg_val, DROP_TX_DATA_ON_LOCAL_FAULTf, control->drop_tx_on_fault ? 1: 0);
   1121     WR_CLMAC(RX_LSS_CTRLr, unit, port, reg_val);
   1122 
   1123     SOC_FUNC_RETURN;
   1124 }
   1125 
   1126 
   1127 int clmac_local_fault_control_get(int unit, soc_port_t port, portmod_local_fault_control_t *control)
   1128 {
   1129     uint64 reg_val;
   1130     uint32 field_val = 0;
   1131     SOC_INIT_FUNC_DEFS;
   1132 
   1133     RD_CLMAC(RX_LSS_CTRLr, unit, port, &reg_val);
   1134 
   1135     field_val = soc_reg64_field32_get(unit, CLMAC_RX_LSS_CTRLr, reg_val, LOCAL_FAULT_DISABLEf);
   1136     control->enable = (field_val ? 0 : 1);/*flip*/
   1137 
   1138     field_val = soc_reg64_field32_get(unit, CLMAC_RX_LSS_CTRLr, reg_val, DROP_TX_DATA_ON_LOCAL_FAULTf);
   1139     control->drop_tx_on_fault  = (field_val ? 1 : 0);
   1140 
   1141     SOC_FUNC_RETURN;
   1142 }
   1143 
   1144 int clmac_remote_fault_status_get(int unit, soc_port_t port, int clear_status, int *status)
   1145 {
   1146     uint64 reg_val, reg_val_clear;
   1147     uint32 field_val = 0;
   1148     SOC_INIT_FUNC_DEFS;
   1149 
   1150     COMPILER_64_ZERO(reg_val_clear);
   1151     if(clear_status) {
   1152         soc_reg64_field32_set(unit, CLMAC_CLEAR_RX_LSS_STATUSr, &reg_val_clear, CLEAR_REMOTE_FAULT_STATUSf, 1);
   1153     }
   1154 
   1155     RD_CLMAC(RX_LSS_STATUSr, unit, port, &reg_val);
   1156 
   1157     if(clear_status) {
   1158         WR_CLMAC(CLEAR_RX_LSS_STATUSr, unit, port, reg_val_clear);
   1159         COMPILER_64_ZERO(reg_val_clear);
   1160         WR_CLMAC(CLEAR_RX_LSS_STATUSr, unit, port, reg_val_clear);
   1161     }
   1162 
   1163     field_val = soc_reg64_field32_get(unit, CLMAC_RX_LSS_STATUSr, reg_val, REMOTE_FAULT_STATUSf);
   1164     *status = field_val ? 1: 0;
   1165 
   1166     SOC_FUNC_RETURN;
   1167 }
   1168 
   1169 int clmac_local_fault_status_get(int unit, soc_port_t port, int clear_status, int *status)
   1170 {
   1171     uint64 reg_val, reg_val_clear;
   1172     uint32 field_val = 0;
   1173     SOC_INIT_FUNC_DEFS;
   1174 
   1175     COMPILER_64_ZERO(reg_val_clear);
   1176     if(clear_status) {
   1177         soc_reg64_field32_set(unit, CLMAC_CLEAR_RX_LSS_STATUSr, &reg_val_clear, CLEAR_LOCAL_FAULT_STATUSf, 1);
   1178     }
   1179 
   1180     RD_CLMAC(RX_LSS_STATUSr, unit, port, &reg_val);
   1181 
   1182     if(clear_status) {
   1183         WR_CLMAC(CLEAR_RX_LSS_STATUSr, unit, port, reg_val_clear);
   1184         COMPILER_64_ZERO(reg_val_clear);
   1185         WR_CLMAC(CLEAR_RX_LSS_STATUSr, unit, port, reg_val_clear);
   1186     }
   1187 
   1188     field_val = soc_reg64_field32_get(unit, CLMAC_RX_LSS_STATUSr, reg_val, LOCAL_FAULT_STATUSf);
   1189     *status = field_val ? 1: 0;
   1190 
   1191     SOC_FUNC_RETURN;
   1192 }
   1193 
   1194 int clmac_clear_rx_lss_status_set(int unit, soc_port_t port, int lcl_fault, int rmt_fault)
   1195 {
   1196     uint64 reg_val;
   1197 
   1198     RD_CLMAC(CLEAR_RX_LSS_STATUSr, unit, port, &reg_val);
   1199     soc_reg64_field32_set(unit, CLMAC_CLEAR_RX_LSS_STATUSr, &reg_val, 
   1200                                      CLEAR_REMOTE_FAULT_STATUSf, rmt_fault);
   1201     soc_reg64_field32_set(unit, CLMAC_CLEAR_RX_LSS_STATUSr, &reg_val, 
   1202                                      CLEAR_LOCAL_FAULT_STATUSf, lcl_fault);
   1203     WR_CLMAC(CLEAR_RX_LSS_STATUSr, unit, port, reg_val);
   1204 
   1205     return (SOC_E_NONE);
   1206 }
   1207 
   1208 int clmac_clear_rx_lss_status_get(int unit, soc_port_t port, int *lcl_fault, int *rmt_fault)
   1209 {
   1210     uint64 reg_val;
   1211 
   1212     RD_CLMAC(CLEAR_RX_LSS_STATUSr, unit, port, &reg_val);
   1213     *rmt_fault = soc_reg64_field32_get(unit, CLMAC_CLEAR_RX_LSS_STATUSr, reg_val, 
   1214                                      CLEAR_REMOTE_FAULT_STATUSf);
   1215     *lcl_fault = soc_reg64_field32_get(unit, CLMAC_CLEAR_RX_LSS_STATUSr, reg_val, 
   1216                                      CLEAR_LOCAL_FAULT_STATUSf);
   1217 
   1218     return (SOC_E_NONE);
   1219 }
   1220 
   1221 /**************************************************************************** 
   1222  Flow Control
   1223  */
   1224 
   1225 int clmac_pause_control_set(int unit, soc_port_t port, const portmod_pause_control_t *control)
   1226 {
   1227     uint64 reg_val;
   1228     SOC_INIT_FUNC_DEFS;
   1229 
   1230     RD_CLMAC(PAUSE_CTRLr, unit, port , &reg_val);
   1231 
   1232     if(control->rx_enable || control->tx_enable){
   1233         if(control->refresh_timer > 0){
   1234             soc_reg64_field32_set(unit, CLMAC_PAUSE_CTRLr, &reg_val, PAUSE_REFRESH_TIMERf, control->refresh_timer);
   1235             soc_reg64_field32_set(unit, CLMAC_PAUSE_CTRLr, &reg_val, PAUSE_REFRESH_ENf, 1);
   1236         }else{
   1237             soc_reg64_field32_set(unit, CLMAC_PAUSE_CTRLr, &reg_val, PAUSE_REFRESH_ENf, 0);
   1238         }
   1239         soc_reg64_field32_set(unit, CLMAC_PAUSE_CTRLr, &reg_val, PAUSE_XOFF_TIMERf, control->xoff_timer);
   1240     }
   1241 
   1242     soc_reg64_field32_set(unit, CLMAC_PAUSE_CTRLr, &reg_val, TX_PAUSE_ENf, control->tx_enable);
   1243     soc_reg64_field32_set(unit, CLMAC_PAUSE_CTRLr, &reg_val, RX_PAUSE_ENf, control->rx_enable);
   1244 
   1245     WR_CLMAC(PAUSE_CTRLr, unit, port , reg_val);
   1246 
   1247     SOC_FUNC_RETURN;
   1248 }
   1249 
   1250 int clmac_pfc_control_set(int unit, soc_port_t port, const portmod_pfc_control_t *control)
   1251 {
   1252     uint64 reg_val;
   1253     SOC_INIT_FUNC_DEFS;
   1254 
   1255     RD_CLMAC(PFC_CTRLr, unit, port , &reg_val);
   1256 
   1257     if (control->refresh_timer) {
   1258         soc_reg64_field32_set(unit, CLMAC_PFC_CTRLr, &reg_val, PFC_REFRESH_TIMERf, control->refresh_timer);
   1259         soc_reg64_field32_set(unit, CLMAC_PFC_CTRLr, &reg_val, PFC_REFRESH_ENf, 1);
   1260     } else {
   1261         soc_reg64_field32_set(unit, CLMAC_PFC_CTRLr, &reg_val, PFC_REFRESH_ENf, 0);
   1262     }
   1263     soc_reg64_field32_set(unit, CLMAC_PFC_CTRLr, &reg_val, PFC_STATS_ENf, control->stats_en);
   1264     soc_reg64_field32_set(unit, CLMAC_PFC_CTRLr, &reg_val, PFC_XOFF_TIMERf, control->xoff_timer);
   1265     soc_reg64_field32_set(unit, CLMAC_PFC_CTRLr, &reg_val, FORCE_PFC_XONf, control->force_xon);
   1266 
   1267     soc_reg64_field32_set(unit, CLMAC_PFC_CTRLr, &reg_val, TX_PFC_ENf, control->tx_enable);
   1268     soc_reg64_field32_set(unit, CLMAC_PFC_CTRLr, &reg_val, RX_PFC_ENf, control->rx_enable);
   1269 
   1270     WR_CLMAC(PFC_CTRLr, unit, port , reg_val);
   1271 
   1272     SOC_FUNC_RETURN;
   1273 }
   1274 
   1275 int clmac_llfc_control_set(int unit, soc_port_t port, const portmod_llfc_control_t *control)
   1276 {
   1277     uint64 reg_val;
   1278     SOC_INIT_FUNC_DEFS;
   1279 
   1280     RD_CLMAC(LLFC_CTRLr, unit, port , &reg_val);
   1281 
   1282     if(control->rx_enable || control->tx_enable){
   1283         soc_reg64_field32_set(unit, CLMAC_LLFC_CTRLr, &reg_val, LLFC_IN_IPG_ONLYf, control->in_ipg_only);
   1284         soc_reg64_field32_set(unit, CLMAC_LLFC_CTRLr, &reg_val, LLFC_CRC_IGNOREf, control->crc_ignore);
   1285     }
   1286     soc_reg64_field32_set(unit, CLMAC_LLFC_CTRLr, &reg_val, TX_LLFC_ENf, control->tx_enable);
   1287     soc_reg64_field32_set(unit, CLMAC_LLFC_CTRLr, &reg_val, RX_LLFC_ENf, control->rx_enable);
   1288 
   1289     WR_CLMAC(LLFC_CTRLr, unit, port , reg_val);
   1290 
   1291     SOC_FUNC_RETURN;
   1292 }
   1293 
   1294 int clmac_pause_control_get(int unit, soc_port_t port, portmod_pause_control_t *control)
   1295 {
   1296     uint64 reg_val;
   1297     uint32 refresh_enable = 0;
   1298     uint32 refresh_timer = 0;
   1299     SOC_INIT_FUNC_DEFS;
   1300 
   1301     RD_CLMAC(PAUSE_CTRLr, unit, port , &reg_val);
   1302 
   1303     refresh_enable = soc_reg64_field32_get(unit, CLMAC_PAUSE_CTRLr, reg_val, PAUSE_REFRESH_ENf);
   1304     refresh_timer =  soc_reg64_field32_get(unit, CLMAC_PAUSE_CTRLr, reg_val, PAUSE_REFRESH_TIMERf);
   1305     control->refresh_timer = (refresh_enable ? refresh_timer : -1);
   1306     control->xoff_timer = soc_reg64_field32_get(unit, CLMAC_PAUSE_CTRLr, reg_val, PAUSE_XOFF_TIMERf);
   1307     control->rx_enable = soc_reg64_field32_get(unit, CLMAC_PAUSE_CTRLr, reg_val, RX_PAUSE_ENf);
   1308     control->tx_enable = soc_reg64_field32_get(unit, CLMAC_PAUSE_CTRLr, reg_val, TX_PAUSE_ENf);
   1309 
   1310     SOC_FUNC_RETURN;
   1311 }
   1312 
   1313 int clmac_pfc_control_get (int unit, soc_port_t port,
   1314                            portmod_pfc_control_t *control)
   1315 {
   1316     uint64 reg_val;
   1317     uint32 refresh_enable = 0;
   1318     uint32 refresh_timer = 0;
   1319     SOC_INIT_FUNC_DEFS;
   1320 
   1321     RD_CLMAC(PFC_CTRLr, unit, port , &reg_val);
   1322 
   1323     refresh_enable = soc_reg64_field32_get(unit, CLMAC_PFC_CTRLr, reg_val, PFC_REFRESH_ENf);
   1324     if (refresh_enable) {
   1325         refresh_timer = soc_reg64_field32_get(unit, CLMAC_PFC_CTRLr,
   1326                                               reg_val, PFC_REFRESH_TIMERf);
   1327     }
   1328     control->refresh_timer = refresh_timer;
   1329     control->stats_en = soc_reg64_field32_get(unit, CLMAC_PFC_CTRLr, reg_val, PFC_STATS_ENf);
   1330     control->xoff_timer = soc_reg64_field32_get(unit, CLMAC_PFC_CTRLr, reg_val, PFC_XOFF_TIMERf);
   1331     control->force_xon = soc_reg64_field32_get(unit, CLMAC_PFC_CTRLr, reg_val, FORCE_PFC_XONf);
   1332     control->rx_enable = soc_reg64_field32_get(unit, CLMAC_PFC_CTRLr, reg_val, RX_PFC_ENf);
   1333     control->tx_enable = soc_reg64_field32_get(unit, CLMAC_PFC_CTRLr, reg_val, TX_PFC_ENf);
   1334 
   1335     SOC_FUNC_RETURN;
   1336 }
   1337 
   1338 int clmac_llfc_control_get(int unit, soc_port_t port, portmod_llfc_control_t *control)
   1339 {
   1340     uint64 reg_val;
   1341     SOC_INIT_FUNC_DEFS;
   1342 
   1343     RD_CLMAC(LLFC_CTRLr, unit, port , &reg_val);
   1344 
   1345     control->in_ipg_only = soc_reg64_field32_get(unit, CLMAC_LLFC_CTRLr, reg_val, LLFC_IN_IPG_ONLYf);
   1346     control->crc_ignore = soc_reg64_field32_get(unit, CLMAC_LLFC_CTRLr, reg_val, LLFC_CRC_IGNOREf);
   1347     control->rx_enable = soc_reg64_field32_get(unit, CLMAC_LLFC_CTRLr, reg_val, RX_LLFC_ENf);
   1348     control->tx_enable = soc_reg64_field32_get(unit, CLMAC_LLFC_CTRLr, reg_val, TX_LLFC_ENf);
   1349 
   1350     SOC_FUNC_RETURN;
   1351 }
   1352 
   1353 /*
   1354  * Function:
   1355  *      clmac_duplex_set
   1356  * Purpose:
   1357  *      Set CLMAC in the specified duplex mode.
   1358  * Parameters:
   1359  *      unit - XGS unit #.
   1360  *      port - XGS port # on unit.
   1361  *      duplex - Boolean: true --> full duplex, false --> half duplex.
   1362  * Returns:
   1363  *      SOC_E_XXX
   1364  * Notes:
   1365  */
   1366 int
   1367 clmac_duplex_set(int unit, soc_port_t port, int duplex)
   1368 {
   1369     LOG_VERBOSE(BSL_LS_SOC_100G,
   1370                 (BSL_META_U(unit,
   1371                             "mac_cl_duplex_set: unit %d port %s duplex=%s\n"),
   1372                  unit, SOC_PORT_NAME(unit, port),
   1373                  duplex ? "Full" : "Half"));
   1374     return (duplex) ? (SOC_E_NONE) : (SOC_E_UNAVAIL) ;
   1375 }
   1376 
   1377 
   1378 /*
   1379  * Function:
   1380  *      clmac_duplex_get
   1381  * Purpose:
   1382  *      Get CLMAC duplex mode.
   1383  * Parameters:
   1384  *      unit - XGS unit #.
   1385  *      duplex - (OUT) Boolean: true --> full duplex, false --> half duplex.
   1386  * Returns:
   1387  *      SOC_E_XXX
   1388  */
   1389 int
   1390 clmac_duplex_get(int unit, soc_port_t port, int *duplex)
   1391 {
   1392     *duplex = TRUE; /* Always full duplex */
   1393 
   1394     LOG_VERBOSE(BSL_LS_SOC_100G,
   1395                 (BSL_META_U(unit,
   1396                             "mac_cl_duplex_get: unit %d port %s duplex=%s\n"),
   1397                  unit, SOC_PORT_NAME(unit, port),
   1398                  *duplex ? "Full" : "Half"));
   1399     return SOC_E_NONE;
   1400 }
   1401 
   1402 /*
   1403  * Function:
   1404  *      mac_cl_speed_get
   1405  * Purpose:
   1406  *      Get CLMAC speed
   1407  * Parameters:
   1408  *      unit - XGS unit #.
   1409  *      port - XGS port # on unit.
   1410  *      speed - (OUT) speed in Mb
   1411  * Returns:
   1412  *      SOC_E_XXX
   1413  */
   1414 
   1415 int
   1416 clmac_speed_get(int unit, soc_port_t port, int *speed)
   1417 {
   1418     uint64 rval;
   1419 
   1420     RD_CLMAC(MODEr, unit, port, &rval);
   1421     switch (soc_reg64_field32_get(unit, CLMAC_MODEr, rval, SPEED_MODEf)) {
   1422     case CLMAC_SPEED_100000:
   1423     default:
   1424         *speed = 100000;
   1425         break;
   1426     }
   1427 
   1428     LOG_VERBOSE(BSL_LS_SOC_100G,
   1429                 (BSL_META_U(unit,
   1430                             "mac_xl_speed_get: unit %d port %s speed=%dMb\n"),
   1431                  unit, SOC_PORT_NAME(unit, port),
   1432                  *speed));
   1433     return SOC_E_NONE;
   1434 }
   1435 
   1436 
   1437 /*! 
   1438  * clmac_eee_set
   1439  *
   1440  * @brief EEE Control and Timer set
   1441  *
   1442  * @param [in]  unit            - unit id
   1443  * @param [in]  port            - logical port
   1444  * @param [in]  eee             - 
   1445  */
   1446 int clmac_eee_set(int unit, int port, const portmod_eee_t* eee)
   1447 {
   1448     uint64 rval;
   1449 
   1450     RD_CLMAC(EEE_CTRLr, unit, port, &rval);
   1451     soc_reg64_field32_set(unit, CLMAC_EEE_CTRLr, &rval, EEE_ENf, eee->enable);
   1452     WR_CLMAC(EEE_CTRLr, unit, port, rval);
   1453 
   1454     RD_CLMAC(EEE_TIMERSr, unit, port, &rval);
   1455     soc_reg64_field32_set(unit, CLMAC_EEE_TIMERSr, &rval, EEE_DELAY_ENTRY_TIMERf, eee->tx_idle_time);
   1456     soc_reg64_field32_set(unit, CLMAC_EEE_TIMERSr, &rval, EEE_WAKE_TIMERf, eee->tx_wake_time);
   1457     WR_CLMAC(EEE_TIMERSr, unit, port, rval);
   1458 
   1459     return SOC_E_NONE;
   1460 }
   1461 
   1462 
   1463 /*! 
   1464  * clmac_eee_get
   1465  *
   1466  * @brief EEE Control and Timer get
   1467  *
   1468  * @param [in]  unit            - unit id
   1469  * @param [in]  port            - logical port
   1470  * @param [in]  eee             - 
   1471  */
   1472 int clmac_eee_get(int unit, int port, portmod_eee_t* eee)
   1473 {
   1474     uint64 rval;
   1475     portmod_eee_t* pEEE = (portmod_eee_t*)eee;
   1476 
   1477     RD_CLMAC(EEE_CTRLr, unit, port, &rval);
   1478     pEEE->enable = soc_reg64_field32_get(unit, CLMAC_EEE_CTRLr, rval, EEE_ENf);
   1479 
   1480     RD_CLMAC(EEE_TIMERSr, unit, port, &rval);
   1481 
   1482     pEEE->tx_idle_time = soc_reg64_field32_get (unit, CLMAC_EEE_TIMERSr, rval, 
   1483                                                EEE_DELAY_ENTRY_TIMERf);
   1484     pEEE->tx_wake_time = soc_reg64_field32_get (unit, CLMAC_EEE_TIMERSr, rval, 
   1485                                                EEE_WAKE_TIMERf);
   1486     return(SOC_E_NONE);
   1487 }
   1488 
   1489 int clmac_pass_control_frame_set(int unit, int port, int value)
   1490 {
   1491     int32 version;
   1492     uint64 rval;
   1493 
   1494     SOC_IF_ERROR_RETURN(_clmac_version_get(unit, port, &version));
   1495 
   1496     if (version < CLMAC_VERSION_A030) {
   1497         return SOC_E_UNAVAIL;
   1498     }
   1499 
   1500     SOC_IF_ERROR_RETURN(READ_CLMAC_RX_CTRLr(unit, port, &rval));
   1501     soc_reg64_field32_set(unit, CLMAC_RX_CTRLr, &rval,
   1502                                                     RX_PASS_CTRLf, (value? 1:0));
   1503     SOC_IF_ERROR_RETURN(WRITE_CLMAC_RX_CTRLr(unit, port, rval));
   1504 
   1505     return(SOC_E_NONE);
   1506 }
   1507 
   1508 int clmac_pass_control_frame_get(int unit, int port, int *value)
   1509 {
   1510     int32 version;
   1511     uint64 rval;
   1512 
   1513     SOC_IF_ERROR_RETURN(_clmac_version_get(unit, port, &version));
   1514 
   1515     if (version < CLMAC_VERSION_A030) {
   1516         return SOC_E_UNAVAIL;
   1517     }
   1518 
   1519     SOC_IF_ERROR_RETURN(READ_CLMAC_RX_CTRLr(unit, port, &rval));
   1520     *value = soc_reg64_field32_get(unit, CLMAC_RX_CTRLr, rval, RX_PASS_CTRLf);
   1521 
   1522     return(SOC_E_NONE);
   1523 }
   1524 
   1525 /*!
   1526  * clmac_pass_pfc_frame_set
   1527  *
   1528  * @brief send PFC frame to system side
   1529  *
   1530  * @param [in]  unit            - unit id
   1531  * @param [in]  port            - logical port
   1532  * @param [in]  value           - 1 or 0
   1533  */
   1534 int clmac_pass_pfc_frame_set(int unit, int port, int value)
   1535 {
   1536     int32 version;
   1537     uint64 rval;
   1538 
   1539     SOC_IF_ERROR_RETURN(_clmac_version_get(unit, port, &version));
   1540 
   1541     if (version < CLMAC_VERSION_A030) {
   1542         return SOC_E_UNAVAIL;
   1543     }
   1544 
   1545     SOC_IF_ERROR_RETURN(READ_CLMAC_RX_CTRLr(unit, port, &rval));
   1546     soc_reg64_field32_set(unit, CLMAC_RX_CTRLr, &rval,
   1547                                                     RX_PASS_PFCf, (value? 1:0));
   1548     SOC_IF_ERROR_RETURN(WRITE_CLMAC_RX_CTRLr(unit, port, rval));
   1549 
   1550     return(SOC_E_NONE);
   1551 }
   1552 
   1553 int clmac_pass_pfc_frame_get(int unit, int port, int *value)
   1554 {
   1555     int32 version;
   1556     uint64 rval;
   1557 
   1558     SOC_IF_ERROR_RETURN(_clmac_version_get(unit, port, &version));
   1559 
   1560     if (version < CLMAC_VERSION_A030) {
   1561         return SOC_E_UNAVAIL;
   1562     }
   1563 
   1564     SOC_IF_ERROR_RETURN(READ_CLMAC_RX_CTRLr(unit, port, &rval));
   1565     *value = soc_reg64_field32_get(unit, CLMAC_RX_CTRLr, rval, RX_PASS_PFCf);
   1566 
   1567     return(SOC_E_NONE);
   1568 }
   1569 
   1570 /*!
   1571  * clmac_pass_pause_frame_set
   1572  *
   1573  * @brief send pause frame to system side
   1574  *
   1575  * @param [in]  unit            - unit id
   1576  * @param [in]  port            - logical port
   1577  * @param [in]  value           - 1 or 0
   1578  */
   1579 int clmac_pass_pause_frame_set(int unit, int port, int value)
   1580 {
   1581     int32 version;
   1582     uint64 rval;
   1583 
   1584     SOC_IF_ERROR_RETURN(_clmac_version_get(unit, port, &version));
   1585 
   1586     if (version < CLMAC_VERSION_A030) {
   1587         return SOC_E_UNAVAIL;
   1588     }
   1589 
   1590     SOC_IF_ERROR_RETURN(READ_CLMAC_RX_CTRLr(unit, port, &rval));
   1591     soc_reg64_field32_set (unit, CLMAC_RX_CTRLr, &rval,
   1592                                                     RX_PASS_PAUSEf, (value? 1:0));
   1593     SOC_IF_ERROR_RETURN(WRITE_CLMAC_RX_CTRLr(unit, port, rval));
   1594 
   1595     return(SOC_E_NONE);
   1596 }
   1597 
   1598 int clmac_pass_pause_frame_get(int unit, int port, int *value)
   1599 {
   1600     int32 version;
   1601     uint64 rval;
   1602 
   1603     SOC_IF_ERROR_RETURN(_clmac_version_get(unit, port, &version));
   1604 
   1605     if (version < CLMAC_VERSION_A030) {
   1606         return SOC_E_UNAVAIL;
   1607     }
   1608 
   1609     SOC_IF_ERROR_RETURN(READ_CLMAC_RX_CTRLr(unit, port, &rval));
   1610     *value = soc_reg64_field32_get(unit, CLMAC_RX_CTRLr, rval, RX_PASS_PAUSEf);
   1611 
   1612     return(SOC_E_NONE);
   1613 }
   1614 
   1615 int clmac_lag_failover_loopback_set(int unit, int port, int val)
   1616 {
   1617     uint64 rval;
   1618 
   1619     SOC_INIT_FUNC_DEFS;
   1620 
   1621     /* Toggle link bit to notify IPIPE on link up */
   1622     RD_CLMAC(LAG_FAILOVER_STATUSr, unit, port, &rval);
   1623 
   1624     soc_reg64_field32_set (unit, CLMAC_LAG_FAILOVER_STATUSr, &rval, 
   1625                                             LAG_FAILOVER_LOOPBACKf, val);
   1626     WR_CLMAC(LAG_FAILOVER_STATUSr, unit, port, rval);
   1627 
   1628     SOC_FUNC_RETURN;
   1629 }
   1630 
   1631 int clmac_lag_failover_loopback_get(int unit, int port, int *val)
   1632 {
   1633     uint64 rval;
   1634 
   1635     SOC_INIT_FUNC_DEFS;
   1636 
   1637     /* Toggle link bit to notify IPIPE on link up */
   1638     RD_CLMAC(LAG_FAILOVER_STATUSr, unit, port, &rval);
   1639 
   1640     *val = soc_reg64_field32_get (unit, CLMAC_LAG_FAILOVER_STATUSr, rval, 
   1641                                                   LAG_FAILOVER_LOOPBACKf);
   1642 
   1643     SOC_FUNC_RETURN;
   1644 }
   1645 
   1646 /*!
   1647  * clmac_lag_failover_disable
   1648  *
   1649  * @brief Port Mac Control Lag Failover Disable. 
   1650  *
   1651  * @param [in]  unit            - unit id
   1652  * @param [in]  port            - logical port
   1653  */
   1654 int clmac_lag_failover_disable(int unit, int port)
   1655 {
   1656     uint64 mac_ctrl;
   1657 
   1658     RD_CLMAC(CTRLr, unit, port, &mac_ctrl);
   1659 
   1660     soc_reg64_field32_set(unit, CLMAC_CTRLr, &mac_ctrl, LAG_FAILOVER_ENf, 0);
   1661     soc_reg64_field32_set(unit, CLMAC_CTRLr, &mac_ctrl, LINK_STATUS_SELECTf, 0);
   1662     soc_reg64_field32_set(unit, CLMAC_CTRLr, &mac_ctrl, REMOVE_FAILOVER_LPBKf, 0);
   1663 
   1664     WR_CLMAC(CTRLr, unit, port, mac_ctrl);
   1665     return (SOC_E_NONE);
   1666 }   
   1667 
   1668         
   1669 /*!
   1670  * clmac_lag_failover_en_set
   1671  *
   1672  * @brief Port Mac Control Spacing Stretch
   1673  *
   1674  * @param [in]  unit            - unit id
   1675  * @param [in]  port            - logical port
   1676  * @param [in]  spacing         -
   1677  */
   1678 int clmac_lag_failover_en_set(int unit, int port, int val)
   1679 {
   1680     uint64 mac_ctrl;
   1681 
   1682     RD_CLMAC(CTRLr, unit, port, &mac_ctrl);
   1683 
   1684     soc_reg64_field32_set(unit, CLMAC_CTRLr, &mac_ctrl, LAG_FAILOVER_ENf, val);
   1685 
   1686     WR_CLMAC(CTRLr, unit, port, mac_ctrl);
   1687     return (SOC_E_NONE);
   1688 }   
   1689         
   1690 /*!     
   1691  * clmac_lag_failover_en_get
   1692  *      
   1693  * @brief Port Mac Control Spacing Stretch 
   1694  *  
   1695  * @param [in]  unit            - unit id
   1696  * @param [in]  port            - logical port
   1697  * @param [out]  val         -
   1698  */
   1699 int clmac_lag_failover_en_get(int unit, int port, int *val)
   1700 {                                 
   1701     uint64 mac_ctrl;
   1702  
   1703     RD_CLMAC(CTRLr, unit, port, &mac_ctrl);
   1704  
   1705     *val = soc_reg64_field32_get (unit, CLMAC_CTRLr,
   1706                                       mac_ctrl, LAG_FAILOVER_ENf);
   1707     return (SOC_E_NONE);
   1708 }
   1709 
   1710 
   1711 /*!
   1712  * clmac_lag_remove_failover_lpbk_set
   1713  *
   1714  * @brief Port Mac Control Spacing Stretch
   1715  *
   1716  * @param [in]  unit            - unit id
   1717  * @param [in]  port            - logical port
   1718  * @param [in]  spacing         -
   1719  */
   1720 int clmac_lag_remove_failover_lpbk_set(int unit, int port, int val)
   1721 {
   1722     uint64 mac_ctrl;
   1723 
   1724     RD_CLMAC(CTRLr, unit, port, &mac_ctrl);
   1725 
   1726     soc_reg64_field32_set(unit, CLMAC_CTRLr, &mac_ctrl, REMOVE_FAILOVER_LPBKf, val);
   1727 
   1728     WR_CLMAC(CTRLr, unit, port, mac_ctrl);
   1729     return (SOC_E_NONE);
   1730 }   
   1731         
   1732 /*!     
   1733  * clmac_lag_remove_failover_lpbk_get
   1734  *      
   1735  * @brief Port Mac Control Spacing Stretch 
   1736  *  
   1737  * @param [in]  unit            - unit id
   1738  * @param [in]  port            - logical port
   1739  * @param [out]  val         -
   1740  */
   1741 int clmac_lag_remove_failover_lpbk_get(int unit, int port, int *val)
   1742 {                                 
   1743     uint64 mac_ctrl;
   1744  
   1745     RD_CLMAC(CTRLr, unit, port, &mac_ctrl);
   1746  
   1747     *val = soc_reg64_field32_get (unit, CLMAC_CTRLr,
   1748                                       mac_ctrl, REMOVE_FAILOVER_LPBKf);
   1749     return (SOC_E_NONE);
   1750 }
   1751 
   1752 int clmac_reset_fc_timers_on_link_dn_set (int unit, soc_port_t port, int val)
   1753 {
   1754     uint64 reg_val;
   1755 
   1756     RD_CLMAC(RX_LSS_CTRLr, unit, port, &reg_val);
   1757 
   1758     soc_reg64_field32_set (unit, CLMAC_RX_LSS_CTRLr, &reg_val,
   1759                            RESET_FLOW_CONTROL_TIMERS_ON_LINK_DOWNf, val);
   1760 
   1761     WR_CLMAC(RX_LSS_CTRLr, unit, port, reg_val);
   1762     return (SOC_E_NONE);
   1763 }
   1764 
   1765 
   1766 int clmac_reset_fc_timers_on_link_dn_get(int unit, soc_port_t port, int *val)
   1767 {
   1768     uint64 reg_val;
   1769 
   1770     RD_CLMAC(RX_LSS_CTRLr, unit, port, &reg_val);
   1771 
   1772     *val = soc_reg64_field32_get (unit, CLMAC_RX_LSS_CTRLr, reg_val,
   1773                            RESET_FLOW_CONTROL_TIMERS_ON_LINK_DOWNf);
   1774     return (SOC_E_NONE);
   1775 }
   1776 
   1777 
   1778 int clmac_drain_cell_get (int unit, int port, portmod_drain_cells_t *drain_cells)
   1779 {   
   1780     uint64 rval;
   1781 
   1782     RD_CLMAC(PFC_CTRLr, unit, port, &rval);
   1783     drain_cells->rx_pfc_en = soc_reg64_field32_get(unit, CLMAC_PFC_CTRLr, 
   1784                                    rval, RX_PFC_ENf);
   1785 
   1786     RD_CLMAC(LLFC_CTRLr, unit, port, &rval);
   1787     drain_cells->llfc_en = soc_reg64_field32_get(unit, CLMAC_LLFC_CTRLr, 
   1788                                  rval, RX_LLFC_ENf);
   1789 
   1790     RD_CLMAC(PAUSE_CTRLr, unit, port , &rval);
   1791     drain_cells->rx_pause  = soc_reg64_field32_get (unit, CLMAC_PAUSE_CTRLr,
   1792                                                  rval, RX_PAUSE_ENf);
   1793     drain_cells->tx_pause  = soc_reg64_field32_get (unit, CLMAC_PAUSE_CTRLr,
   1794                                                  rval, TX_PAUSE_ENf);
   1795 
   1796     return (0);
   1797 }    
   1798 
   1799 int clmac_discard_set(int unit, soc_port_t port, int discard)
   1800 {
   1801     uint64 rval;
   1802 
   1803     /* Clear Discard fields */
   1804     RD_CLMAC(TX_CTRLr, unit, port, &rval);
   1805     soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &rval, DISCARDf, discard);
   1806     soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &rval, EP_DISCARDf, discard);
   1807     WR_CLMAC(TX_CTRLr, unit, port, rval);
   1808     return (SOC_E_NONE);
   1809 }
   1810 
   1811 int clmac_drain_cell_stop (int unit, int port, const portmod_drain_cells_t *drain_cells)
   1812 {   
   1813     uint64 rval;
   1814 
   1815     /* Clear Discard fields */
   1816     SOC_IF_ERROR_RETURN(clmac_discard_set(unit, port, 0));
   1817 
   1818     /* set pause fields */ 
   1819     RD_CLMAC(PAUSE_CTRLr, unit, port , &rval);
   1820     soc_reg64_field32_set (unit, CLMAC_PAUSE_CTRLr,
   1821                            &rval, RX_PAUSE_ENf, drain_cells->rx_pause);
   1822     soc_reg64_field32_set (unit, CLMAC_PAUSE_CTRLr,
   1823                            &rval, TX_PAUSE_ENf, drain_cells->tx_pause);
   1824     WR_CLMAC(PAUSE_CTRLr, unit, port , rval);
   1825 
   1826     /* set pfc rx_en fields */ 
   1827     RD_CLMAC(PFC_CTRLr, unit, port, &rval);
   1828     soc_reg64_field32_set(unit, CLMAC_PFC_CTRLr, 
   1829                           &rval, RX_PFC_ENf, drain_cells->rx_pfc_en);
   1830     WR_CLMAC(PFC_CTRLr, unit, port, rval);
   1831 
   1832     /* set llfc rx_en fields */ 
   1833     RD_CLMAC(LLFC_CTRLr, unit, port, &rval);
   1834     soc_reg64_field32_set(unit, CLMAC_LLFC_CTRLr, 
   1835                           &rval, RX_LLFC_ENf, drain_cells->llfc_en);
   1836     WR_CLMAC(LLFC_CTRLr, unit, port, rval);
   1837 
   1838     return (0);
   1839 }
   1840 
   1841 int clmac_drain_cell_start(int unit, int port)
   1842 {   
   1843     uint64 rval;
   1844 
   1845     RD_CLMAC(CTRLr, unit, port, &rval);
   1846 
   1847     /* Don't disable TX since it stops egress and hangs if CPU sends */
   1848     soc_reg64_field32_set(unit, CLMAC_CTRLr, &rval, TX_ENf, 1);
   1849     /* Disable RX */
   1850     soc_reg64_field32_set(unit, CLMAC_CTRLr, &rval, RX_ENf, 0);
   1851 
   1852     WR_CLMAC(CTRLr, unit, port, rval);
   1853 
   1854     RD_CLMAC(PAUSE_CTRLr, unit, port , &rval);
   1855     soc_reg64_field32_set (unit, CLMAC_PAUSE_CTRLr, &rval, RX_PAUSE_ENf, 0);
   1856     WR_CLMAC(PAUSE_CTRLr, unit, port, rval);
   1857 
   1858     RD_CLMAC(PFC_CTRLr, unit, port, &rval);
   1859     soc_reg64_field32_set(unit, CLMAC_PFC_CTRLr, &rval, RX_PFC_ENf, 0);
   1860     WR_CLMAC(PFC_CTRLr, unit, port, rval);
   1861 
   1862     RD_CLMAC(LLFC_CTRLr, unit, port, &rval);
   1863     soc_reg64_field32_set(unit, CLMAC_LLFC_CTRLr, &rval, RX_LLFC_ENf, 0);
   1864     WR_CLMAC(LLFC_CTRLr, unit, port, rval);
   1865 
   1866     RD_CLMAC(CTRLr, unit, port, &rval);
   1867     soc_reg64_field32_set(unit, CLMAC_CTRLr, &rval, SOFT_RESETf, 1);
   1868     WR_CLMAC(CTRLr, unit, port, rval);
   1869  
   1870     SOC_IF_ERROR_RETURN(clmac_discard_set(unit, port, 1));
   1871 
   1872     return (0);
   1873 }
   1874 
   1875 int
   1876 clmac_mac_ctrl_set(int unit, int port, uint64 mac_ctrl)
   1877 {
   1878     WR_CLMAC(CTRLr, unit, port, mac_ctrl);
   1879     return (0);
   1880 }
   1881 
   1882 
   1883 int clmac_txfifo_cell_cnt_get (int unit, int port, uint32* fval)
   1884 {
   1885     uint64 rval;
   1886 
   1887     RD_CLMAC(TXFIFO_CELL_CNTr, unit, port, &rval);
   1888     *fval = soc_reg64_field32_get(unit, CLMAC_TXFIFO_CELL_CNTr, rval,
   1889                                      CELL_CNTf);
   1890     return (0);
   1891 }
   1892 
   1893 int
   1894 clmac_egress_queue_drain_get(int unit, int port, uint64 *mac_ctrl, int *rx_en)
   1895 {
   1896     uint64 ctrl;
   1897 
   1898     RD_CLMAC(CTRLr, unit, port, &ctrl);
   1899     *mac_ctrl = ctrl;
   1900 
   1901     *rx_en = soc_reg64_field32_get(unit, CLMAC_CTRLr, ctrl, RX_ENf);
   1902 
   1903     return (0);
   1904 }
   1905 
   1906 int
   1907 clmac_egress_queue_drain_rx_en(int unit, int port, int rx_en)
   1908 {
   1909     uint64 ctrl;
   1910     /* Enable both TX and RX, de-assert SOFT_RESET */
   1911     RD_CLMAC(CTRLr, unit, port, &ctrl);
   1912     soc_reg64_field32_set(unit, CLMAC_CTRLr, &ctrl, RX_ENf, rx_en ? 1 : 0);
   1913     WR_CLMAC(CTRLr, unit, port, ctrl);
   1914     /*Bring mac out of reset */
   1915     SOC_IF_ERROR_RETURN(clmac_soft_reset_set(unit, port, 0));
   1916 
   1917     return (0);
   1918 }
   1919 
   1920 int
   1921 clmac_drain_cells_rx_enable(int unit, int port, int rx_en)
   1922 {
   1923     uint64 ctrl, octrl;
   1924     uint32 soft_reset = 0;
   1925 
   1926     /* Enable both TX and RX, de-assert SOFT_RESET */
   1927     RD_CLMAC(CTRLr, unit, port, &ctrl);
   1928     octrl = ctrl;
   1929 
   1930     /* Don't disable TX since it stops egress and hangs if CPU sends */
   1931     soc_reg64_field32_set(unit, CLMAC_CTRLr, &ctrl, TX_ENf, 1);
   1932     soc_reg64_field32_set(unit, CLMAC_CTRLr, &ctrl, RX_ENf, rx_en ? 1 : 0);
   1933 
   1934     if (COMPILER_64_EQ(ctrl, octrl)) {
   1935         /*
   1936          *  To avoid the unexpected early return to prevent this problem.
   1937          *  1. Problem occurred for disabling process only.
   1938          *  2. To comply original designing senario, CLMAC_CTRLr.SOFT_RESETf is 
   1939          *      used to early check to see if this port is at disabled state 
   1940          *      already.
   1941          */
   1942         soft_reset = soc_reg64_field32_get(unit, 
   1943                                            CLMAC_CTRLr, ctrl, SOFT_RESETf);
   1944         if ((rx_en) || (!rx_en && soft_reset)){
   1945             return SOC_E_NONE;
   1946         }
   1947     }
   1948 
   1949     WR_CLMAC(CTRLr, unit, port, ctrl);
   1950 
   1951     /*Bring mac out of reset */
   1952     if (rx_en) {
   1953         SOC_IF_ERROR_RETURN(clmac_soft_reset_set(unit, port, 0));
   1954     }
   1955 
   1956     return (0);
   1957 }
   1958 
   1959 /*
   1960  * Function:
   1961  *      
   1962  * Purpose:
   1963  *     This function checks if the MAC control values are already
   1964  *     set.
   1965  *
   1966  *     This function should be called before enabling/disabling the
   1967  *     MAC to prevent the following:
   1968  *     1. Problem occurred for disabling process only.
   1969  *     2. To comply original designing senario, CLMAC_CTRLr.SOFT_RESETf is 
   1970  *        used to early check to see if this port is at disabled state 
   1971  *        already.
   1972  * Parameters:
   1973  *      unit    - (IN) Unit number.
   1974  *      port    - (IN) Port number.
   1975  *      enable  - (IN) Indicates whether to check for enable or disable.
   1976  *      reset   - (OUT) Indicates MAC control needs to be reset or not.
   1977  * Returns:
   1978  *      SOC_E_XXX
   1979  */
   1980 int clmac_reset_check(int unit, int port, int enable, int *reset)
   1981 {
   1982     uint64 ctrl, octrl;
   1983 
   1984     *reset = 1;
   1985 
   1986     RD_CLMAC(CTRLr, unit, port, &ctrl);
   1987     octrl = ctrl;
   1988 
   1989     /* Don't disable TX since it stops egress and hangs if CPU sends */
   1990     soc_reg64_field32_set(unit, CLMAC_CTRLr, &ctrl, TX_ENf, enable ? 1 : 0);
   1991     soc_reg64_field32_set(unit, CLMAC_CTRLr, &ctrl, RX_ENf, enable ? 1 : 0);
   1992 
   1993     if (COMPILER_64_EQ(ctrl, octrl)) {
   1994         if (enable) {
   1995             *reset = 0;
   1996         } else {
   1997             if (soc_reg64_field32_get(unit, CLMAC_CTRLr, ctrl, SOFT_RESETf)) {
   1998                 *reset = 0;
   1999             }
   2000         }
   2001     }
   2002 
   2003     return SOC_E_NONE;
   2004 }
   2005 
   2006 
   2007 /*! 
   2008  * clmac_pfc_config_set
   2009  *
   2010  * @brief set pass control frames. 
   2011  *
   2012  * @param [in]  unit            - unit id
   2013  * @param [in]  port            - logical port
   2014  * @param [in]  pfc_cfg         - 
   2015  */
   2016 int clmac_pfc_config_set (int unit, int port, 
   2017                           const portmod_pfc_config_t* pfc_cfg)
   2018 {
   2019     uint32 fval; 
   2020     uint64 rval;
   2021 
   2022     RD_CLMAC(PFC_TYPEr, unit, port, &rval);
   2023     soc_reg64_field32_set(unit, CLMAC_PFC_TYPEr, &rval, PFC_ETH_TYPEf, pfc_cfg->type);
   2024     WR_CLMAC(PFC_TYPEr, unit, port, rval);
   2025 
   2026     RD_CLMAC(PFC_OPCODEr, unit, port, &rval);
   2027     soc_reg64_field32_set(unit, CLMAC_PFC_OPCODEr, &rval, PFC_OPCODEf, pfc_cfg->opcode);
   2028     WR_CLMAC(PFC_OPCODEr, unit, port, rval);
   2029 
   2030     RD_CLMAC(PFC_DAr, unit, port, &rval);
   2031     fval = soc_reg64_field32_get(unit, CLMAC_PFC_DAr, rval, PFC_MACDA_LOf);
   2032     fval &= 0x00ffffff;
   2033     fval |= (pfc_cfg->da_oui & 0xff) << 24;
   2034     soc_reg64_field32_set(unit, CLMAC_PFC_DAr, &rval, PFC_MACDA_LOf, fval);
   2035 
   2036     soc_reg64_field32_set(unit, CLMAC_PFC_DAr, &rval, PFC_MACDA_HIf,
   2037                           pfc_cfg->da_oui >> 8);
   2038     WR_CLMAC(PFC_DAr, unit, port, rval);
   2039 
   2040     RD_CLMAC(PFC_DAr, unit, port, &rval);
   2041     fval = soc_reg64_field32_get(unit, CLMAC_PFC_DAr, rval, PFC_MACDA_LOf);
   2042     fval &= 0xff000000;
   2043     fval |= pfc_cfg->da_nonoui;
   2044     soc_reg64_field32_set(unit, CLMAC_PFC_DAr, &rval, PFC_MACDA_LOf, fval);
   2045  
   2046     WR_CLMAC(PFC_DAr, unit, port, rval);
   2047     return (SOC_E_NONE);
   2048 }
   2049 
   2050 
   2051 
   2052 /*! 
   2053  * clmac_pfc_config_get
   2054  *
   2055  * @brief set pass control frames. 
   2056  *
   2057  * @param [in]  unit            - unit id
   2058  * @param [in]  port            - logical port
   2059  * @param [in]  pfc_cfg         - 
   2060  */
   2061 int clmac_pfc_config_get (int unit, int port, 
   2062                           const portmod_pfc_config_t* pfc_cfg)
   2063 {
   2064     uint64 rval;
   2065     uint32 fval;
   2066     uint32 fval0,fval1;
   2067     portmod_pfc_config_t* pcfg = (portmod_pfc_config_t*) pfc_cfg;
   2068 
   2069     RD_CLMAC(PFC_TYPEr, unit, port, &rval);
   2070 
   2071     pcfg->type = soc_reg64_field32_get (unit, CLMAC_PFC_TYPEr, 
   2072                                           rval, PFC_ETH_TYPEf);
   2073 
   2074     RD_CLMAC(PFC_OPCODEr, unit, port, &rval);
   2075     pcfg->opcode = soc_reg64_field32_get (unit, CLMAC_PFC_OPCODEr, 
   2076                                             rval, PFC_OPCODEf);
   2077 
   2078     RD_CLMAC(PFC_DAr, unit, port, &rval);
   2079     fval0 = soc_reg64_field32_get(unit, CLMAC_PFC_DAr, rval,
   2080                                   PFC_MACDA_LOf);
   2081     fval1 = soc_reg64_field32_get(unit, CLMAC_PFC_DAr, rval,
   2082                                   PFC_MACDA_HIf);
   2083     pcfg->da_oui = (fval0 >> 24) | (fval1 << 8);
   2084 
   2085     RD_CLMAC(PFC_DAr, unit, port, &rval);
   2086     fval = soc_reg64_field32_get(unit, CLMAC_PFC_DAr, rval,
   2087                                   PFC_MACDA_LOf);
   2088     pcfg->da_nonoui = fval & 0xFFFFFF;
   2089 
   2090     return (SOC_E_NONE);
   2091 }
   2092 
   2093 int clmac_e2ecc_hdr_get (int unit, int port, uint32_t *words)
   2094 {
   2095     uint64 rval64;
   2096 
   2097     RD_CLMAC(E2ECC_MODULE_HDR_0r, unit, port, &rval64);
   2098     words[0] = soc_reg64_field32_get (unit, CLMAC_E2ECC_MODULE_HDR_0r, rval64,
   2099                                       E2ECC_MODULE_HDR_0_HIf);
   2100     words[1] = soc_reg64_field32_get(unit, CLMAC_E2ECC_MODULE_HDR_0r, rval64,
   2101                                       E2ECC_MODULE_HDR_0_LOf);
   2102 
   2103     RD_CLMAC(E2ECC_MODULE_HDR_1r, unit, port, &rval64);
   2104     words[2] = soc_reg64_field32_get (unit, CLMAC_E2ECC_MODULE_HDR_1r, rval64,
   2105                                       E2ECC_MODULE_HDR_1_HIf);
   2106     words[3] = soc_reg64_field32_get(unit, CLMAC_E2ECC_MODULE_HDR_1r, rval64,
   2107                                       E2ECC_MODULE_HDR_1_LOf);
   2108 
   2109     RD_CLMAC(E2ECC_DATA_HDR_0r, unit, port, &rval64);
   2110     words[4] = soc_reg64_field32_get (unit, CLMAC_E2ECC_DATA_HDR_0r, rval64,
   2111                                       E2ECC_DATA_HDR_0_HIf);
   2112     words[5] = soc_reg64_field32_get(unit, CLMAC_E2ECC_DATA_HDR_0r, rval64,
   2113                                       E2ECC_DATA_HDR_0_LOf);
   2114 
   2115     RD_CLMAC(E2ECC_DATA_HDR_1r, unit, port, &rval64);
   2116     words[6] = soc_reg64_field32_get (unit, CLMAC_E2ECC_DATA_HDR_1r, rval64,
   2117                                       E2ECC_DATA_HDR_1_HIf);
   2118     words[7] = soc_reg64_field32_get(unit, CLMAC_E2ECC_DATA_HDR_1r, rval64,
   2119                                       E2ECC_DATA_HDR_1_LOf);
   2120 
   2121     return SOC_E_NONE;
   2122 }
   2123 
   2124 int clmac_e2ecc_hdr_set (int unit, int port, uint32_t *words)
   2125 {
   2126     uint64 rval64;
   2127     COMPILER_64_ZERO(rval64);
   2128 
   2129     soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_0r, &rval64,
   2130                                       E2ECC_MODULE_HDR_0_HIf, words[0]);
   2131     soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_0r, &rval64,
   2132                                       E2ECC_MODULE_HDR_0_LOf, words[1]);
   2133     WR_CLMAC(E2ECC_MODULE_HDR_0r, unit, port, rval64);
   2134 
   2135 
   2136     COMPILER_64_ZERO(rval64);
   2137     soc_reg64_field32_set (unit, CLMAC_E2ECC_MODULE_HDR_1r, &rval64,
   2138                                       E2ECC_MODULE_HDR_1_HIf, words[2]);
   2139     soc_reg64_field32_set(unit, CLMAC_E2ECC_MODULE_HDR_1r, &rval64,
   2140                                       E2ECC_MODULE_HDR_1_LOf, words[3]);
   2141     WR_CLMAC(E2ECC_MODULE_HDR_1r, unit, port, rval64);
   2142 
   2143 
   2144     COMPILER_64_ZERO(rval64);
   2145     soc_reg64_field32_set (unit, CLMAC_E2ECC_DATA_HDR_0r, &rval64,
   2146                                       E2ECC_DATA_HDR_0_HIf, words[4]);
   2147     soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_0r, &rval64,
   2148                                       E2ECC_DATA_HDR_0_LOf, words[5]);
   2149     WR_CLMAC(E2ECC_DATA_HDR_0r, unit, port, rval64);
   2150 
   2151 
   2152     COMPILER_64_ZERO(rval64);
   2153     soc_reg64_field32_set (unit, CLMAC_E2ECC_DATA_HDR_1r, &rval64,
   2154                                       E2ECC_DATA_HDR_1_HIf, words[6]);
   2155     soc_reg64_field32_set(unit, CLMAC_E2ECC_DATA_HDR_1r, &rval64,
   2156                                       E2ECC_DATA_HDR_1_LOf, words[7]);
   2157     WR_CLMAC(E2ECC_DATA_HDR_1r, unit, port, rval64);
   2158 
   2159     return SOC_E_NONE;
   2160 }
   2161 
   2162 int clmac_e2e_enable_set(int unit, int port, int enable)
   2163 {
   2164     uint64 rval64;
   2165 
   2166     RD_CLMAC(E2E_CTRLr, unit, port, &rval64);
   2167     soc_reg64_field32_set(unit, CLMAC_E2E_CTRLr, &rval64, E2E_ENABLEf, enable);
   2168     WR_CLMAC(E2E_CTRLr, unit, port, rval64);
   2169 
   2170     return (0);
   2171 }
   2172 
   2173 int clmac_e2e_enable_get(int unit, int port, int *enable)
   2174 {
   2175     uint64 rval64;
   2176 
   2177     RD_CLMAC(E2E_CTRLr, unit, port, &rval64);
   2178     *enable = soc_reg64_field32_get(unit, CLMAC_E2E_CTRLr, rval64, E2E_ENABLEf);
   2179 
   2180     return (0);
   2181 }
   2182 
   2183 /*!
   2184  * clmac_frame_spacing_stretch_set
   2185  *
   2186  * @brief Port Mac Control Spacing Stretch
   2187  *
   2188  * @param [in]  unit            - unit id
   2189  * @param [in]  port            - logical port
   2190  * @param [in]  spacing         -
   2191  */
   2192 int clmac_frame_spacing_stretch_set(int unit, int port, int spacing)
   2193 {
   2194     uint64 mac_ctrl;
   2195 
   2196     if (spacing < 0 || spacing > 257) {
   2197         return SOC_E_PARAM;
   2198     }
   2199 
   2200     RD_CLMAC(TX_CTRLr, unit, port, &mac_ctrl);
   2201 
   2202     if (spacing == CLMAC_THROT_10G_TO_5G) {
   2203         soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &mac_ctrl, THROT_DENOMf, 21);
   2204         soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &mac_ctrl, THROT_NUMf, 21);
   2205     } else if (spacing == CLMAC_THROT_10G_TO_2P5G) {
   2206         soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &mac_ctrl, THROT_DENOMf, 21);
   2207         soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &mac_ctrl, THROT_NUMf, 63);
   2208     } else if (spacing >= 8) {
   2209         soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &mac_ctrl, THROT_DENOMf, spacing);
   2210         soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &mac_ctrl, THROT_NUMf, 1);
   2211     } else {
   2212         soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &mac_ctrl, THROT_DENOMf, 0);
   2213         soc_reg64_field32_set(unit, CLMAC_TX_CTRLr, &mac_ctrl, THROT_NUMf, 0);
   2214     }
   2215 
   2216     WR_CLMAC(TX_CTRLr, unit, port, mac_ctrl);
   2217 
   2218     return (SOC_E_NONE);
   2219 }
   2220 
   2221 /*!
   2222  * clmac_frame_spacing_stretch_get
   2223  *
   2224  * @brief Port Mac Control Spacing Stretch
   2225  * 
   2226  * @param [in]  unit            - unit id
   2227  * @param [in]  port            - logical port
   2228  * @param [out]  spacing         -
   2229  */
   2230 int clmac_frame_spacing_stretch_get(int unit, int port, int *spacing)
   2231 {
   2232     uint64 mac_ctrl;
   2233 
   2234     RD_CLMAC(TX_CTRLr, unit, port, &mac_ctrl);
   2235 
   2236     *spacing = soc_reg64_field32_get (unit, CLMAC_TX_CTRLr,
   2237                                       mac_ctrl, THROT_DENOMf);
   2238     return (SOC_E_NONE);
   2239 }
   2240 
   2241 int clmac_interrupt_enable_get(int unit, int port, int intr_type, uint32 *value)
   2242 {
   2243     int32 version;
   2244     uint64 reg_val;
   2245     SOC_INIT_FUNC_DEFS;
   2246 
   2247     _SOC_IF_ERR_EXIT(_clmac_version_get(unit, port, &version));
   2248 
   2249     if (version < CLMAC_VERSION_A030) {
   2250         return SOC_E_UNAVAIL;
   2251     }
   2252 
   2253     _SOC_IF_ERR_EXIT(READ_CLMAC_INTR_ENABLEr(unit, port, &reg_val));
   2254 
   2255     switch(intr_type) {
   2256         case portmodIntrTypeTxPktUnderflow :
   2257                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_TX_PKT_UNDERFLOWf);
   2258                 break;
   2259         case portmodIntrTypeTxPktOverflow :
   2260                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_TX_PKT_OVERFLOWf);
   2261                 break;
   2262         case portmodIntrTypeTxLlfcMsgOverflow :
   2263                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_TX_LLFC_MSG_OVERFLOWf);
   2264                 break;
   2265         case portmodIntrTypeTxTSFifoOverflow :
   2266                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_TX_TS_FIFO_OVERFLOWf);
   2267                 break;
   2268         case portmodIntrTypeRxPktOverflow :
   2269                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_RX_PKT_OVERFLOWf);
   2270                 break;
   2271         case portmodIntrTypeRxMsgOverflow :
   2272                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_RX_MSG_OVERFLOWf);
   2273                 break;
   2274         case portmodIntrTypeTxCdcSingleBitErr :
   2275                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_TX_CDC_SINGLE_BIT_ERRf);
   2276                 break;
   2277         case portmodIntrTypeTxCdcDoubleBitErr :
   2278                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_TX_CDC_DOUBLE_BIT_ERRf);
   2279                 break;
   2280         case portmodIntrTypeRxCdcSingleBitErr :
   2281                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_RX_CDC_SINGLE_BIT_ERRf);
   2282                 break;
   2283         case portmodIntrTypeRxCdcDoubleBitErr :
   2284                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_RX_CDC_DOUBLE_BIT_ERRf);
   2285                 break;
   2286         case portmodIntrTypeRxTsMemSingleBitErr :
   2287                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_RX_TS_MEM_SINGLE_BIT_ERRf);
   2288                 break;
   2289         case portmodIntrTypeRxTsMemDoubleBitErr :
   2290                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_RX_TS_MEM_DOUBLE_BIT_ERRf);
   2291                 break;
   2292         case portmodIntrTypeLocalFaultStatus :
   2293                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_LOCAL_FAULT_STATUSf);
   2294                 break;
   2295         case portmodIntrTypeRemoteFaultStatus :
   2296                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_REMOTE_FAULT_STATUSf);
   2297                 break;
   2298         case portmodIntrTypeLinkInterruptionStatus :
   2299                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_LINK_INTERRUPTION_STATUSf);
   2300                 break;
   2301         case portmodIntrTypeTsEntryValid :
   2302                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_ENABLEr, reg_val, EN_TS_ENTRY_VALIDf);
   2303                 break;
   2304         default:
   2305                 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type")));
   2306                 break;
   2307      }
   2308 
   2309 exit:
   2310     SOC_FUNC_RETURN;
   2311 }
   2312 
   2313 int clmac_interrupt_enable_set(int unit, int port, int intr_type, uint32 value)
   2314 {
   2315     uint64 rval;
   2316     int32 version;
   2317     SOC_INIT_FUNC_DEFS;
   2318 
   2319     _SOC_IF_ERR_EXIT(_clmac_version_get(unit, port, &version));
   2320 
   2321     if (version < CLMAC_VERSION_A030) {
   2322         return SOC_E_UNAVAIL;
   2323     }
   2324 
   2325     _SOC_IF_ERR_EXIT(READ_CLMAC_INTR_ENABLEr(unit, port, &rval));
   2326 
   2327     switch(intr_type) {
   2328         case portmodIntrTypeTxPktUnderflow :
   2329                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_TX_PKT_UNDERFLOWf, value);
   2330                 break;
   2331         case portmodIntrTypeTxPktOverflow :
   2332                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_TX_PKT_OVERFLOWf, value);
   2333                 break;
   2334         case portmodIntrTypeTxLlfcMsgOverflow :
   2335                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_TX_LLFC_MSG_OVERFLOWf, value);
   2336                 break;
   2337         case portmodIntrTypeTxTSFifoOverflow :
   2338                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_TX_TS_FIFO_OVERFLOWf, value);
   2339                 break;
   2340         case portmodIntrTypeRxPktOverflow :
   2341                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_RX_PKT_OVERFLOWf, value);
   2342                 break;
   2343         case portmodIntrTypeRxMsgOverflow :
   2344                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_RX_MSG_OVERFLOWf, value);
   2345                 break;
   2346         case portmodIntrTypeTxCdcSingleBitErr :
   2347                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_TX_CDC_SINGLE_BIT_ERRf, value);
   2348                 break;
   2349         case portmodIntrTypeTxCdcDoubleBitErr :
   2350                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_TX_CDC_DOUBLE_BIT_ERRf, value);
   2351                 break;
   2352         case portmodIntrTypeRxCdcSingleBitErr :
   2353                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_RX_CDC_SINGLE_BIT_ERRf, value);
   2354                 break;
   2355         case portmodIntrTypeRxCdcDoubleBitErr :
   2356                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_RX_CDC_DOUBLE_BIT_ERRf, value);
   2357                 break;
   2358         case portmodIntrTypeRxTsMemSingleBitErr :
   2359                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_RX_TS_MEM_SINGLE_BIT_ERRf, value);
   2360                 break;
   2361         case portmodIntrTypeRxTsMemDoubleBitErr :
   2362                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_RX_TS_MEM_DOUBLE_BIT_ERRf, value);
   2363                 break;
   2364         case portmodIntrTypeLocalFaultStatus :
   2365                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_LOCAL_FAULT_STATUSf, value);
   2366                 break;
   2367         case portmodIntrTypeRemoteFaultStatus :
   2368                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_REMOTE_FAULT_STATUSf, value);
   2369                 break;
   2370         case portmodIntrTypeLinkInterruptionStatus :
   2371                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_LINK_INTERRUPTION_STATUSf, value);
   2372                 break;
   2373         case portmodIntrTypeTsEntryValid :
   2374                 soc_reg64_field32_set(unit, CLMAC_INTR_ENABLEr, &rval, EN_TS_ENTRY_VALIDf, value);
   2375                 break;
   2376         default:
   2377                 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type")));
   2378         break;
   2379     }
   2380 
   2381     _SOC_IF_ERR_EXIT(WRITE_CLMAC_INTR_ENABLEr(unit, port, rval));
   2382 
   2383 exit:
   2384     SOC_FUNC_RETURN;
   2385 }
   2386 
   2387 int clmac_interrupt_status_get(int unit, int port, int intr_type, uint32 *value)
   2388 {
   2389     int32 version;
   2390     uint64 reg_val;
   2391     SOC_INIT_FUNC_DEFS;
   2392 
   2393     _SOC_IF_ERR_EXIT(_clmac_version_get(unit, port, &version));
   2394 
   2395     if (version < CLMAC_VERSION_A030) {
   2396         return SOC_E_UNAVAIL;
   2397     }
   2398 
   2399     _SOC_IF_ERR_EXIT(READ_CLMAC_INTR_STATUSr(unit, port, &reg_val));
   2400 
   2401     switch(intr_type) {
   2402         case portmodIntrTypeTxPktUnderflow :
   2403                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TX_PKT_UNDERFLOWf);
   2404                 break;
   2405         case portmodIntrTypeTxPktOverflow :
   2406                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TX_PKT_OVERFLOWf);
   2407                 break;
   2408         case portmodIntrTypeTxLlfcMsgOverflow :
   2409                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TX_LLFC_MSG_OVERFLOWf);
   2410                 break;
   2411         case portmodIntrTypeTxTSFifoOverflow :
   2412                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TX_TS_FIFO_OVERFLOWf);
   2413                 break;
   2414         case portmodIntrTypeRxPktOverflow :
   2415                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_RX_PKT_OVERFLOWf);
   2416                 break;
   2417         case portmodIntrTypeRxMsgOverflow :
   2418                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_RX_MSG_OVERFLOWf);
   2419                 break;
   2420         case portmodIntrTypeTxCdcSingleBitErr :
   2421                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TX_CDC_SINGLE_BIT_ERRf);
   2422                 break;
   2423         case portmodIntrTypeTxCdcDoubleBitErr :
   2424                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TX_CDC_DOUBLE_BIT_ERRf);
   2425                 break;
   2426         case portmodIntrTypeRxCdcSingleBitErr :
   2427                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_RX_CDC_SINGLE_BIT_ERRf);
   2428                 break;
   2429         case portmodIntrTypeRxCdcDoubleBitErr :
   2430                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_RX_CDC_DOUBLE_BIT_ERRf);
   2431                 break;
   2432         case portmodIntrTypeRxTsMemSingleBitErr :
   2433                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_RX_TS_MEM_SINGLE_BIT_ERRf);
   2434                 break;
   2435         case portmodIntrTypeRxTsMemDoubleBitErr :
   2436                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_RX_TS_MEM_DOUBLE_BIT_ERRf);
   2437                 break;
   2438         case portmodIntrTypeLocalFaultStatus :
   2439                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_LOCAL_FAULT_STATUSf);
   2440                 break;
   2441         case portmodIntrTypeRemoteFaultStatus :
   2442                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_REMOTE_FAULT_STATUSf);
   2443                 break;
   2444         case portmodIntrTypeLinkInterruptionStatus :
   2445                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_LINK_INTERRUPTION_STATUSf);
   2446                 break;
   2447         case portmodIntrTypeTsEntryValid :
   2448                 *value = soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TS_ENTRY_VALIDf);
   2449                 break;
   2450         default:
   2451                 _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Invalid interrupt type")));
   2452                 break;
   2453     }
   2454 
   2455 exit:
   2456     SOC_FUNC_RETURN;
   2457 }
   2458 
   2459 int clmac_interrupts_status_get(int unit, int port, int arr_max_size, uint32* intr_arr, uint32* size)
   2460 {
   2461     uint32 cnt = 0;
   2462     int32 version;
   2463     uint64 reg_val;
   2464     SOC_INIT_FUNC_DEFS;
   2465 
   2466     _SOC_IF_ERR_EXIT(_clmac_version_get(unit, port, &version));
   2467 
   2468     if (version < CLMAC_VERSION_A030) {
   2469         return SOC_E_UNAVAIL;
   2470     }
   2471 
   2472     _SOC_IF_ERR_EXIT(READ_CLMAC_INTR_STATUSr(unit, port, &reg_val));
   2473 
   2474     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TX_PKT_UNDERFLOWf)) {
   2475         if (cnt >= arr_max_size) {
   2476             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2477         }
   2478         intr_arr[cnt++] = portmodIntrTypeTxPktUnderflow;
   2479     }
   2480 
   2481     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TX_PKT_OVERFLOWf)) {
   2482         if (cnt >= arr_max_size) {
   2483             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2484         }
   2485         intr_arr[cnt++] = portmodIntrTypeTxPktOverflow;
   2486     }
   2487 
   2488     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TX_LLFC_MSG_OVERFLOWf)) {
   2489         if (cnt >= arr_max_size) {
   2490             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2491         }
   2492         intr_arr[cnt++] = portmodIntrTypeTxLlfcMsgOverflow;
   2493     }
   2494 
   2495     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TX_TS_FIFO_OVERFLOWf)) {
   2496         if (cnt >= arr_max_size) {
   2497             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2498         }
   2499         intr_arr[cnt++] = portmodIntrTypeTxTSFifoOverflow;
   2500     }
   2501 
   2502     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_RX_PKT_OVERFLOWf)) {
   2503         if (cnt >= arr_max_size) {
   2504             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2505         }
   2506         intr_arr[cnt++] = portmodIntrTypeRxPktOverflow;
   2507     }
   2508 
   2509     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_RX_MSG_OVERFLOWf)) {
   2510         if (cnt >= arr_max_size) {
   2511             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2512         }
   2513         intr_arr[cnt++] = portmodIntrTypeRxMsgOverflow;
   2514     }
   2515 
   2516     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TX_CDC_SINGLE_BIT_ERRf)) {
   2517         if (cnt >= arr_max_size) {
   2518             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2519         }
   2520         intr_arr[cnt++] = portmodIntrTypeTxCdcSingleBitErr;
   2521     }
   2522 
   2523     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TX_CDC_DOUBLE_BIT_ERRf)) {
   2524         if (cnt >= arr_max_size) {
   2525             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2526         }
   2527         intr_arr[cnt++] = portmodIntrTypeTxCdcDoubleBitErr;
   2528     }
   2529 
   2530     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_RX_CDC_SINGLE_BIT_ERRf)) {
   2531         if (cnt >= arr_max_size) {
   2532             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2533         }
   2534         intr_arr[cnt++] = portmodIntrTypeRxCdcSingleBitErr;
   2535     }
   2536 
   2537     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_RX_CDC_DOUBLE_BIT_ERRf)) {
   2538         if (cnt >= arr_max_size) {
   2539             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2540         }
   2541         intr_arr[cnt++] = portmodIntrTypeRxCdcDoubleBitErr;
   2542     }
   2543 
   2544     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_RX_TS_MEM_SINGLE_BIT_ERRf)) {
   2545         if (cnt >= arr_max_size) {
   2546             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2547         }
   2548         intr_arr[cnt++] = portmodIntrTypeRxTsMemSingleBitErr;
   2549     }
   2550 
   2551     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_RX_TS_MEM_DOUBLE_BIT_ERRf)) {
   2552         if (cnt >= arr_max_size) {
   2553             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2554         }
   2555         intr_arr[cnt++] = portmodIntrTypeRxTsMemDoubleBitErr;
   2556     }
   2557 
   2558     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_LOCAL_FAULT_STATUSf)) {
   2559         if (cnt >= arr_max_size) {
   2560             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2561         }
   2562         intr_arr[cnt++] = portmodIntrTypeLocalFaultStatus;
   2563     }
   2564 
   2565     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_REMOTE_FAULT_STATUSf)) {
   2566         if (cnt >= arr_max_size) {
   2567             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2568         }
   2569         intr_arr[cnt++] = portmodIntrTypeRemoteFaultStatus;
   2570     }
   2571 
   2572     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_LINK_INTERRUPTION_STATUSf)) {
   2573         if (cnt >= arr_max_size) {
   2574             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2575         }
   2576         intr_arr[cnt++] = portmodIntrTypeLinkInterruptionStatus;
   2577     }
   2578 
   2579     if (soc_reg64_field32_get(unit, CLMAC_INTR_STATUSr, reg_val, SUM_TS_ENTRY_VALIDf)) {
   2580         if (cnt >= arr_max_size) {
   2581             _SOC_EXIT_WITH_ERR(SOC_E_PARAM, (_SOC_MSG("Insufficient Array size")));
   2582         }
   2583         intr_arr[cnt++] = portmodIntrTypeTsEntryValid;
   2584     }
   2585 
   2586     *size = cnt;
   2587 
   2588 exit:
   2589     SOC_FUNC_RETURN;
   2590 }
   2591 
   2592 int clmac_preemption_mode_set(int32 unit, soc_port_t port, uint32 enable)
   2593 {
   2594     uint64 reg_val;
   2595     int32 value = 0;
   2596 
   2597     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_CONFIGr(unit, port, &reg_val));
   2598     value = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2599                                   reg_val, PREEMPTION_MODEf);
   2600 
   2601     if (value != enable) {
   2602         soc_reg64_field32_set(unit, CLMAC_MERGE_CONFIGr,
   2603                               &reg_val, PREEMPTION_MODEf, enable? 1: 0);
   2604         SOC_IF_ERROR_RETURN(WRITE_CLMAC_MERGE_CONFIGr(unit, port, reg_val));
   2605     }
   2606 
   2607     return (SOC_E_NONE);
   2608 }
   2609 
   2610 int clmac_preemption_mode_get(int32 unit, soc_port_t port, uint32 *enable)
   2611 {
   2612     uint64 reg_val;
   2613 
   2614     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_CONFIGr(unit, port, &reg_val));
   2615     *enable = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2616                                     reg_val, PREEMPTION_MODEf);
   2617 
   2618     return (SOC_E_NONE);
   2619 }
   2620 
   2621 int clmac_preemption_tx_enable_set(int32 unit, soc_port_t port, uint32 enable)
   2622 {
   2623     uint64 reg_val, v_reg_val;
   2624     int32 value = 0, rc = SOC_E_NONE;
   2625     uint32 is_verify_set;
   2626     uint32 timeout = 0, num_attempts = 0;
   2627     uint32 verify_status = 0, verify_op_done = 0;
   2628     uint32 wait_time, iter = 0;
   2629 
   2630     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_CONFIGr(unit, port, &reg_val));
   2631     value = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2632                                   reg_val, PREEMPT_ENABLEf);
   2633 
   2634     is_verify_set = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2635                                           reg_val, VERIFY_ENABLEf);  
   2636 
   2637 
   2638     /* if preemption already enabled, return */
   2639     if (value == enable) {
   2640         return rc;
   2641     }
   2642 
   2643     /* Static configuration - no preemption negotaition with link partner*/
   2644     soc_reg64_field32_set(unit, CLMAC_MERGE_CONFIGr,
   2645                           &reg_val, PREEMPT_ENABLEf, enable? 1: 0);
   2646     SOC_IF_ERROR_RETURN(WRITE_CLMAC_MERGE_CONFIGr(unit, port, reg_val));
   2647 
   2648     if (is_verify_set) {
   2649         /*
   2650          * preemption negotiation enabled - wait for the negotiation
   2651          * to complete.
   2652          * Wait time >= (num verify attempts + 1) * (verify timeout + 1)
   2653          */
   2654         timeout = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2655                                         reg_val, VERIFY_TIMEf);  
   2656         num_attempts = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2657                                          reg_val, VERIFY_ATTEMPT_LIMITf);  
   2658         wait_time = (num_attempts + 1) * (timeout + 1);
   2659 
   2660         /* wait for (timeout + 1) millsecs, and check verify status */
   2661         sal_udelay((timeout + 1) * 1000);
   2662 
   2663         /* check verification status */
   2664         SOC_IF_ERROR_RETURN(
   2665                READ_CLMAC_MERGE_VERIFY_STATEr(unit, port, &v_reg_val));
   2666         verify_status = soc_reg64_field32_get(unit,
   2667                                               CLMAC_MERGE_VERIFY_STATEr,
   2668                                               v_reg_val,
   2669                                               PREEMPTION_VERIFY_STATUSf);
   2670         if ((verify_status == CLMAC_PREEMPT_VERIFY_SUCCEED) ||
   2671             (verify_status == CLMAC_PREEMPT_VERIFY_FAILED)) {
   2672             verify_op_done = 1;
   2673         }
   2674 
   2675         while (!verify_op_done) { 
   2676             sal_udelay((timeout + 1) * 1000);
   2677 
   2678             /* check verification status */
   2679             SOC_IF_ERROR_RETURN(
   2680                    READ_CLMAC_MERGE_VERIFY_STATEr(unit, port, &v_reg_val));
   2681             verify_status = soc_reg64_field32_get(unit,
   2682                                               CLMAC_MERGE_VERIFY_STATEr,
   2683                                               v_reg_val,
   2684                                               PREEMPTION_VERIFY_STATUSf);
   2685 
   2686             /* break if verify operation done or timeout */
   2687             if ((verify_status == CLMAC_PREEMPT_VERIFY_SUCCEED) ||
   2688                 (verify_status == CLMAC_PREEMPT_VERIFY_FAILED)  ||
   2689                 (((timeout + 1) * iter++) > wait_time)) {
   2690                 verify_op_done = 1;
   2691                 break;
   2692             }
   2693         }  
   2694     }
   2695 
   2696     if (verify_op_done) {
   2697         rc = (verify_status == CLMAC_PREEMPT_VERIFY_SUCCEED)? SOC_E_NONE:
   2698                                                              SOC_E_FAIL;
   2699     }
   2700     return (rc);
   2701 }
   2702 
   2703 int clmac_preemption_tx_enable_get(int32 unit, soc_port_t port, uint32 *enable)
   2704 {
   2705     uint64 reg_val;
   2706 
   2707     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_CONFIGr(unit, port, &reg_val));
   2708     *enable = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2709                                     reg_val, PREEMPT_ENABLEf);
   2710 
   2711     return (SOC_E_NONE);
   2712 }
   2713 
   2714 int clmac_preemption_verify_enable_set(int32 unit, soc_port_t port,
   2715                                        uint32 enable)
   2716 {
   2717     uint64 reg_val;
   2718     int32 value = 0;
   2719 
   2720     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_CONFIGr(unit, port, &reg_val));
   2721     value = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2722                                   reg_val, VERIFY_ENABLEf);
   2723 
   2724     if (value != enable) {
   2725         soc_reg64_field32_set(unit, CLMAC_MERGE_CONFIGr,
   2726                               &reg_val, VERIFY_ENABLEf, enable? 1: 0);
   2727         SOC_IF_ERROR_RETURN(WRITE_CLMAC_MERGE_CONFIGr(unit, port, reg_val));
   2728     }
   2729 
   2730     return (SOC_E_NONE);
   2731 }
   2732 
   2733 int clmac_preemption_verify_enable_get(int32 unit, soc_port_t port,
   2734                                        uint32 *enable)
   2735 {
   2736     uint64 reg_val;
   2737 
   2738     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_CONFIGr(unit, port, &reg_val));
   2739     *enable = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2740                                     reg_val, VERIFY_ENABLEf);
   2741 
   2742     return (SOC_E_NONE);
   2743 }
   2744 
   2745 int clmac_preemption_verify_time_set(int32 unit, soc_port_t port,
   2746                                      uint32 time_val)
   2747 {
   2748     uint64 reg_val;
   2749     int32 value = 0;
   2750 
   2751     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_CONFIGr(unit, port, &reg_val));
   2752     value = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2753                                   reg_val, VERIFY_TIMEf);
   2754 
   2755     if (value != time_val) {
   2756         soc_reg64_field32_set(unit, CLMAC_MERGE_CONFIGr,
   2757                               &reg_val, VERIFY_TIMEf, time_val);
   2758         SOC_IF_ERROR_RETURN(WRITE_CLMAC_MERGE_CONFIGr(unit, port, reg_val));
   2759     }
   2760 
   2761     return (SOC_E_NONE);
   2762 }
   2763 
   2764 int clmac_preemption_verify_time_get(int32 unit, soc_port_t port,
   2765                                      uint32 *time_val)
   2766 {
   2767     uint64 reg_val;
   2768 
   2769     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_CONFIGr(unit, port, &reg_val));
   2770     *time_val = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2771                                     reg_val, VERIFY_TIMEf);
   2772 
   2773     return (SOC_E_NONE);
   2774 }
   2775 
   2776 int clmac_preemption_verify_attempts_set(int32 unit, soc_port_t port,
   2777                                          uint32 num_attempts)
   2778 {
   2779     uint64 reg_val;
   2780     int32 value = 0;
   2781 
   2782     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_CONFIGr(unit, port, &reg_val));
   2783     value = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2784                                   reg_val, VERIFY_ATTEMPT_LIMITf);
   2785 
   2786     if (value != num_attempts) {
   2787         SOC_IF_ERROR_RETURN(soc_reg_field_validate(unit, CLMAC_MERGE_CONFIGr,
   2788                                                    VERIFY_ATTEMPT_LIMITf,
   2789                                                    num_attempts));
   2790         soc_reg64_field32_set(unit, CLMAC_MERGE_CONFIGr,
   2791                               &reg_val, VERIFY_ATTEMPT_LIMITf, num_attempts);
   2792         SOC_IF_ERROR_RETURN(WRITE_CLMAC_MERGE_CONFIGr(unit, port, reg_val));
   2793     }
   2794 
   2795     return (SOC_E_NONE);
   2796 }
   2797 
   2798 int clmac_preemption_verify_attempts_get(int32 unit, soc_port_t port,
   2799                                          uint32 *num_attempts)
   2800 {
   2801     uint64 reg_val;
   2802 
   2803     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_CONFIGr(unit, port, &reg_val));
   2804     *num_attempts = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2805                                     reg_val, VERIFY_ATTEMPT_LIMITf);
   2806 
   2807     return (SOC_E_NONE);
   2808 }
   2809 
   2810 int clmac_preemption_tx_status_get(int unit, soc_port_t port,
   2811                                    int flags, uint32 *value)
   2812 {
   2813     uint64 reg_val;
   2814     int rv = SOC_E_NONE;
   2815 
   2816     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_VERIFY_STATEr(unit, port, &reg_val));
   2817     
   2818     switch (flags) {
   2819         case CLMAC_PREEMPTION_TX_STATUS:
   2820             *value = soc_reg64_field32_get(unit, CLMAC_MERGE_VERIFY_STATEr,
   2821                                            reg_val, PREEMPTION_TX_STATUSf); 
   2822             break;
   2823         case CLMAC_PREEMPTION_VERIFY_STATUS:
   2824             *value = soc_reg64_field32_get(unit, CLMAC_MERGE_VERIFY_STATEr,
   2825                                            reg_val, PREEMPTION_VERIFY_STATUSf); 
   2826             break;
   2827         case CLMAC_PREEMPTION_VERIFY_CNT_STATUS:
   2828             *value = soc_reg64_field32_get(unit, CLMAC_MERGE_VERIFY_STATEr,
   2829                                            reg_val, TX_VERIFY_CNT_STATUSf); 
   2830             break;
   2831         default:
   2832             rv = SOC_E_PARAM;
   2833     }
   2834     return rv;
   2835 }
   2836                                     
   2837 int clmac_preemption_force_rx_lost_eop_set(int unit, soc_port_t port,
   2838                                            int flags, uint32 value)
   2839 {
   2840     uint64 reg_val;
   2841     int rv = SOC_E_NONE;
   2842 
   2843     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_CONFIGr(unit, port, &reg_val));
   2844     
   2845     switch (flags) {
   2846         case CLMAC_PREEMPTION_FORCE_SW_RX_EOP:
   2847             /*
   2848              * for forcing sw based rx lost eop, the sequence is to
   2849              * write a zero to the field SW_FORCE_RX_LOST_EOPf wait
   2850              * for a delay 10usecs, write a 1 to the field 
   2851              * SW_FORCE_RX_LOST_EOP
   2852              */
   2853             if (value) {
   2854                 soc_reg64_field32_set(unit, CLMAC_MERGE_CONFIGr,
   2855                                       &reg_val, SW_FORCE_RX_LOST_EOPf, 0);
   2856                 SOC_IF_ERROR_RETURN(
   2857                         WRITE_CLMAC_MERGE_CONFIGr(unit, port, reg_val));
   2858                 sal_udelay(10);
   2859             }
   2860             soc_reg64_field32_set(unit, CLMAC_MERGE_CONFIGr,
   2861                                   &reg_val, SW_FORCE_RX_LOST_EOPf, value);
   2862             SOC_IF_ERROR_RETURN(
   2863                     WRITE_CLMAC_MERGE_CONFIGr(unit, port, reg_val));
   2864             break;
   2865         case CLMAC_PREEMPTION_FORCE_AUTO_HW_RX_EOP:
   2866             soc_reg64_field32_set(unit, CLMAC_MERGE_CONFIGr,
   2867                               &reg_val, AUTO_HW_FORCE_RX_LOST_EOPf, value);
   2868             SOC_IF_ERROR_RETURN(
   2869                     WRITE_CLMAC_MERGE_CONFIGr(unit, port, reg_val));
   2870             break;
   2871         default:
   2872             rv = SOC_E_PARAM;
   2873     }
   2874     return rv;
   2875 }
   2876                                     
   2877 int clmac_preemption_force_rx_lost_eop_get(int unit, soc_port_t port,
   2878                                            int flags, uint32 *value)
   2879 {
   2880     uint64 reg_val;
   2881     int rv = SOC_E_NONE;
   2882 
   2883     SOC_IF_ERROR_RETURN(READ_CLMAC_MERGE_CONFIGr(unit, port, &reg_val));
   2884     
   2885     switch (flags) {
   2886         case CLMAC_PREEMPTION_FORCE_SW_RX_EOP:
   2887             /* get the sw rx lost eop setting */
   2888             *value = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2889                                            reg_val, SW_FORCE_RX_LOST_EOPf); 
   2890             break;
   2891         case CLMAC_PREEMPTION_FORCE_AUTO_HW_RX_EOP:
   2892             /* get the hw rx lost eop setting */
   2893             *value = soc_reg64_field32_get(unit, CLMAC_MERGE_CONFIGr,
   2894                                       reg_val, AUTO_HW_FORCE_RX_LOST_EOPf);
   2895             break;
   2896         default:
   2897             rv = SOC_E_PARAM;
   2898     }
   2899     return rv;
   2900 }
   2901 
   2902 int clmac_preemption_rx_timeout_info_set(int unit, soc_port_t port,
   2903                                          uint32 enable, uint32 timeout_val)
   2904 {
   2905     uint64 reg_val;
   2906 
   2907     SOC_IF_ERROR_RETURN(
   2908             READ_CLMAC_MERGE_RX_TIMEOUT_CONFIGr(unit, port, &reg_val));
   2909     
   2910     soc_reg64_field32_set(unit, CLMAC_MERGE_RX_TIMEOUT_CONFIGr,
   2911                           &reg_val, TIMEOUT_ENABLEf, enable? 1: 0);
   2912     
   2913     soc_reg64_field32_set(unit, CLMAC_MERGE_RX_TIMEOUT_CONFIGr,
   2914                           &reg_val, TIMEOUT_CNTf, timeout_val);
   2915 
   2916     SOC_IF_ERROR_RETURN(
   2917             WRITE_CLMAC_MERGE_RX_TIMEOUT_CONFIGr(unit, port, reg_val));
   2918     
   2919     return SOC_E_NONE;
   2920 }
   2921                                     
   2922 int clmac_preemption_rx_timeout_info_get(int unit, soc_port_t port,
   2923                                          uint32 *enable, uint32 *timeout_val)
   2924 {
   2925     uint64 reg_val;
   2926 
   2927     SOC_IF_ERROR_RETURN(
   2928             READ_CLMAC_MERGE_RX_TIMEOUT_CONFIGr(unit, port, &reg_val));
   2929     
   2930     *enable = soc_reg64_field32_get(unit, CLMAC_MERGE_RX_TIMEOUT_CONFIGr,
   2931                                     reg_val, TIMEOUT_ENABLEf);
   2932     
   2933     *timeout_val = soc_reg64_field32_get(unit, CLMAC_MERGE_RX_TIMEOUT_CONFIGr,
   2934                                          reg_val, TIMEOUT_CNTf);
   2935 
   2936     return SOC_E_NONE;
   2937 }
   2938 /*!
   2939  * clmac_timesync_tx_info_get
   2940  *
   2941  * @brief get port timestamps and sequence id form fifo
   2942  *
   2943  * @param [in]  unit            - unit id
   2944  * @param [in]  port            - logical port
   2945  * @param [in]  tx _info        - timestamp and seq id form fifo
   2946  */
   2947 int clmac_timesync_tx_info_get (int unit, int port,
   2948                                 portmod_fifo_status_t* tx_info)
   2949 {
   2950     uint64 rval;
   2951 
   2952     RD_CLMAC(TX_TIMESTAMP_FIFO_STATUSr, unit, port, &rval);
   2953 
   2954     if (soc_reg64_field32_get(unit, CLMAC_TX_TIMESTAMP_FIFO_STATUSr, rval,
   2955                                   ENTRY_COUNTf) == 0) {
   2956         return SOC_E_EMPTY;
   2957     }
   2958 
   2959     RD_CLMAC(TX_TIMESTAMP_FIFO_DATAr, unit, port, &rval);
   2960 
   2961     tx_info->timestamps_in_fifo = soc_reg64_field32_get(unit,
   2962                      CLMAC_TX_TIMESTAMP_FIFO_DATAr, rval, TIME_STAMPf);
   2963 
   2964     tx_info->timestamps_in_fifo_hi = 0;
   2965 
   2966     tx_info->sequence_id = soc_reg64_field32_get(unit,
   2967                      CLMAC_TX_TIMESTAMP_FIFO_DATAr, rval, SEQUENCE_IDf);
   2968 
   2969     return (SOC_E_NONE);
   2970 
   2971 }
   2972                                     
   2973 /*!
   2974  * clmac_diag_fifo_status_get
   2975  *
   2976  * @brief get port timestamps in fifo
   2977  *
   2978  * @param [in]  unit            - unit id
   2979  * @param [in]  port            - logical port
   2980  * @param [out]  ts_info        - timestamp from fifo
   2981  */
   2982 int clmac_diag_fifo_status_get (int unit, int port,
   2983                                 const portmod_fifo_status_t* ts_info)
   2984 {
   2985     uint64 rval;
   2986     portmod_fifo_status_t* pinfo =(portmod_fifo_status_t*)ts_info;
   2987 
   2988     RD_CLMAC(TX_TIMESTAMP_FIFO_STATUSr, unit, port, &rval);
   2989 
   2990     if (soc_reg64_field32_get(unit, CLMAC_TX_TIMESTAMP_FIFO_STATUSr, rval,
   2991                               ENTRY_COUNTf) == 0) {
   2992         return SOC_E_EMPTY;
   2993     }
   2994 
   2995     RD_CLMAC(TX_TIMESTAMP_FIFO_DATAr, unit, port, &rval);
   2996 
   2997     pinfo->timestamps_in_fifo = soc_reg64_field32_get(unit,
   2998                                                 CLMAC_TX_TIMESTAMP_FIFO_DATAr,
   2999                                                 rval, TIME_STAMPf);
   3000 
   3001     return (SOC_E_NONE);
   3002 }
   3003 
   3004 #undef _ERR_MSG_MODULE_NAME
   3005 
   3006 
   3007 #endif