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

cdmac.c (75396B)


      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  * File:    cdmac.c
     10  * Purpose: 
     11  */
     12 
     13 #include <soc/portmod/portmod.h>
     14 #include <soc/portmod/cdmac.h>
     15 #include <soc/drv.h>
     16 
     17 #if defined(PORTMOD_PM8X50_SUPPORT)
     18 
     19 #ifdef _ERR_MSG_MODULE_NAME 
     20 #error "_ERR_MSG_MODULE_NAME redefined" 
     21 #endif
     22 #define _ERR_MSG_MODULE_NAME BSL_LS_SOC_PORT
     23 
     24 /* Minimun and maximum average IPG value in bits */
     25 #define CDMAC_AVE_IPG_MIN 64
     26 #define CDMAC_AVE_IPG_MAX 480
     27 
     28 int cdmac_init(int unit, soc_port_t port, uint32 init_flags)
     29 {
     30     uint32 rval;
     31     portmod_pause_control_t pause_control;
     32     portmod_pfc_control_t pfc_control;
     33     portmod_remote_fault_control_t remote_fault_control;
     34     portmod_local_fault_control_t local_fault_control;
     35     int crc_mode;
     36     int is_strip_crc, is_append_crc, is_replace_crc, is_pass_through_crc;
     37     int ctr_enable = 0, ctr_clear = 0;
     38     SOC_INIT_FUNC_DEFS;
     39 
     40     is_strip_crc = (init_flags & CDMAC_INIT_F_RX_STRIP_CRC ? 1 : 0);
     41     is_append_crc = (init_flags & CDMAC_INIT_F_TX_APPEND_CRC ? 1 : 0);
     42     is_replace_crc = (init_flags & CDMAC_INIT_F_TX_REPLACE_CRC ? 1 : 0);
     43     is_pass_through_crc = (init_flags & CDMAC_INIT_F_TX_PASS_THROUGH_CRC_MODE?
     44                            1: 0);
     45 
     46     if(is_append_crc + is_replace_crc + is_pass_through_crc > 1) {
     47         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
     48                           (_SOC_MSG("CDMAC_INIT_F_TX_APPEND_CRC, "
     49                                     "CDMAC_INIT_F_TX_REPLACE_CRC, and "
     50                                     "CDMAC_INIT_F_TX_PASS_THROUGH_CRC_MODE "
     51                                     "can't co-exist")));
     52     }
     53 
     54     /* RX Max size */
     55     _SOC_IF_ERR_EXIT(cdmac_rx_max_size_set(unit, port, CDMAC_JUMBO_MAXSZ));
     56 
     57     /*
     58      * Enable and Clear the CDMAC MIB counters
     59      * No need to explicitly set the clear flag to 0 since the
     60      * function internally unsets the clear flag
     61      */
     62     ctr_enable = TRUE;
     63     ctr_clear = TRUE;
     64     _SOC_IF_ERR_EXIT(cdmac_mib_counter_control_set(unit, port, ctr_enable,
     65                                                    ctr_clear));
     66 
     67     /* RX Control */
     68     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_CTRLr(unit, port, &rval));
     69     soc_reg_field_set(unit, CDMAC_RX_CTRLr, &rval, STRIP_CRCf, is_strip_crc);
     70     soc_reg_field_set(unit, CDMAC_RX_CTRLr, &rval, RX_PASS_PAUSEf, 0);
     71     soc_reg_field_set(unit, CDMAC_RX_CTRLr, &rval, RX_PASS_PFCf, 0);
     72     soc_reg_field_set(unit, CDMAC_RX_CTRLr, &rval, RUNT_THRESHOLDf,
     73                       CDMAC_RUNT_THRESHOLD_DEFAULT);
     74     _SOC_IF_ERR_EXIT(WRITE_CDMAC_RX_CTRLr(unit, port, rval));
     75 
     76     /* TX Control */
     77     if(is_append_crc) {
     78         /* CRC is computed on incoming packet data and appended. */
     79         crc_mode = 0;
     80     } else if(is_replace_crc) {
     81         /* Incoming pkt CRC is replaced with CRC value computed by the MAC */
     82         crc_mode = 2;
     83     } else if(is_pass_through_crc) {
     84         /* Incoming pkt CRC is passed through without modifications */
     85         crc_mode = 1;
     86     } else {
     87         /* The CRC mode is determined by the HW */
     88         crc_mode = 3;
     89     }
     90 
     91     _SOC_IF_ERR_EXIT(READ_CDMAC_TX_CTRLr(unit, port, &rval));
     92     soc_reg_field_set(unit, CDMAC_TX_CTRLr, &rval, CRC_MODEf, crc_mode);
     93     soc_reg_field_set(unit, CDMAC_TX_CTRLr, &rval, DISCARDf, FALSE);
     94     soc_reg_field_set(unit, CDMAC_TX_CTRLr, &rval, PAD_ENf, FALSE);
     95     soc_reg_field_set(unit, CDMAC_TX_CTRLr, &rval, PAD_THRESHOLDf,
     96                       CDMAC_PAD_THRESHOLD_SIZE_DEFAULT);
     97     soc_reg_field_set(unit, CDMAC_TX_CTRLr, &rval, AVERAGE_IPGf,
     98                       CDMAC_AVERAGE_IPG_DEFAULT);
     99     soc_reg_field_set(unit, CDMAC_TX_CTRLr, &rval, TX_THRESHOLDf, 1);
    100     _SOC_IF_ERR_EXIT(WRITE_CDMAC_TX_CTRLr(unit, port, rval));
    101 
    102     /* ECC control */
    103     /* TX CDC ecc control */
    104     _SOC_IF_ERR_EXIT(READ_CDMAC_ECC_CTRLr(unit, port, &rval));
    105 
    106     soc_reg_field_set(unit, CDMAC_ECC_CTRLr, &rval,
    107                       TX_CDC_ECC_CTRL_ENf, 1);
    108     soc_reg_field_set(unit, CDMAC_ECC_CTRLr, &rval, TX_CDC_ECC_CTRL_ENf, TRUE);
    109     soc_reg_field_set(unit, CDMAC_ECC_CTRLr, &rval, MIB_COUNTER_ECC_CTRL_ENf,
    110                       TRUE);
    111     _SOC_IF_ERR_EXIT(WRITE_CDMAC_ECC_CTRLr(unit, port, rval));
    112 
    113     /* LSS */
    114     _SOC_IF_ERR_EXIT(
    115             portmod_remote_fault_control_t_init(unit,&remote_fault_control));
    116     remote_fault_control.enable = TRUE;
    117     remote_fault_control.drop_tx_on_fault = TRUE;
    118     _SOC_IF_ERR_EXIT(cdmac_remote_fault_control_set(unit, port,
    119                                                     &remote_fault_control));
    120 
    121     _SOC_IF_ERR_EXIT(
    122             portmod_local_fault_control_t_init(unit, &local_fault_control));
    123     local_fault_control.enable = TRUE;
    124     local_fault_control.drop_tx_on_fault = TRUE;
    125     _SOC_IF_ERR_EXIT(cdmac_local_fault_control_set(unit, port,
    126                                                    &local_fault_control));
    127 
    128     /* Pause */
    129     _SOC_IF_ERR_EXIT(portmod_pause_control_t_init(unit, &pause_control));
    130     pause_control.tx_enable = TRUE;
    131     pause_control.rx_enable = TRUE;
    132     _SOC_IF_ERR_EXIT(cdmac_pause_control_set(unit, port, &pause_control));
    133 
    134     /* PFC */
    135     _SOC_IF_ERR_EXIT(cdmac_pfc_control_get(unit, port, &pfc_control));
    136     pfc_control.rx_enable = FALSE;
    137     pfc_control.tx_enable = FALSE;
    138     pfc_control.stats_en = TRUE;
    139     _SOC_IF_ERR_EXIT(cdmac_pfc_control_set(unit, port, &pfc_control));
    140 
    141     /* MAC control */
    142     _SOC_IF_ERR_EXIT(READ_CDMAC_CTRLr(unit, port, &rval));
    143     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, LOCAL_LPBKf, FALSE);
    144     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, TX_ENf, TRUE);
    145     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, RX_ENf, TRUE);
    146     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, MAC_LINK_DOWN_SEQ_ENf, TRUE);
    147     /* de-assert SOFT RESET */
    148     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, SOFT_RESETf, FALSE);
    149     _SOC_IF_ERR_EXIT(WRITE_CDMAC_CTRLr(unit, port, rval));
    150 
    151 exit:
    152     SOC_FUNC_RETURN;
    153 }
    154 
    155 int cdmac_speed_set(int unit, soc_port_t port, int flags, int speed)
    156 {
    157     /*
    158      * There is nothing to be programmed in CDMAC for Speed.
    159      * Speed setting is handled in the serdes.
    160      */
    161     return (SOC_E_NONE);
    162 }
    163 
    164 int cdmac_speed_get(int unit, soc_port_t port, int *speed)
    165 {
    166     /*
    167      * There is nothing to be programmed in CDMAC for Speed.
    168      * Speed setting is handled in the serdes.
    169      */
    170     return (SOC_E_NONE);
    171 }
    172 
    173 int cdmac_encap_set(int unit, soc_port_t port, int flags,
    174                     portmod_encap_t encap)
    175 {
    176 
    177     uint32 val = 0;
    178     uint32 rval;
    179     SOC_INIT_FUNC_DEFS;
    180 
    181     /*
    182      * Only IEEE encap support, HIGIG not supported.
    183      */
    184     switch(encap){
    185         case SOC_ENCAP_IEEE:
    186             val = 0;
    187             break;
    188         case SOC_ENCAP_SOP_ONLY:
    189         /* no preamble or sfd, 0xFB is followed by mac da */
    190             val = 5;
    191             break;
    192         default:
    193             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
    194                                (_SOC_MSG("illegal encap mode %d"), encap));
    195             break;
    196     }
    197 
    198     _SOC_IF_ERR_EXIT(READ_CDMAC_MODEr(unit, port, &rval));
    199     soc_reg_field_set(unit, CDMAC_MODEr, &rval, HDR_MODEf, val);
    200     _SOC_IF_ERR_EXIT(WRITE_CDMAC_MODEr(unit, port, rval));
    201 
    202 exit:
    203     SOC_FUNC_RETURN;
    204 }
    205 
    206 int cdmac_encap_get(int unit, soc_port_t port, int *flags,
    207                     portmod_encap_t *encap)
    208 {
    209     uint32 rval;
    210     uint32 fld_val;
    211     SOC_INIT_FUNC_DEFS;
    212 
    213     (*flags) = 0;
    214 
    215     _SOC_IF_ERR_EXIT(READ_CDMAC_MODEr(unit, port, &rval));
    216     fld_val = soc_reg_field_get(unit, CDMAC_MODEr, rval, HDR_MODEf);
    217 
    218     switch(fld_val){
    219         case 0:
    220             *encap = SOC_ENCAP_IEEE;
    221             break;
    222         case 5:
    223             *encap = SOC_ENCAP_SOP_ONLY;
    224             break;
    225         default:
    226             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
    227                               (_SOC_MSG("unknown encap mode %d"), fld_val));
    228             break;
    229     }
    230 
    231 exit:
    232     SOC_FUNC_RETURN;
    233 }
    234 
    235 int cdmac_enable_set(int unit, soc_port_t port, int flags, int enable)
    236 {
    237     uint32 rval;
    238 
    239     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
    240 
    241     /* Don't disable TX since it stops egress and hangs if CPU sends */
    242     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, TX_ENf, 1);
    243     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, RX_ENf, enable? 1: 0);
    244     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, SOFT_RESETf, enable? 0: 1);
    245 
    246     SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
    247 
    248     return (SOC_E_NONE);
    249 }
    250 
    251 int cdmac_enable_get(int unit, soc_port_t port, int flags, int *enable)
    252 {
    253     uint32 rval;
    254 
    255     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
    256 
    257     if (flags & CDMAC_ENABLE_SET_FLAGS_TX_EN) {
    258         *enable = soc_reg_field_get(unit, CDMAC_CTRLr, rval, TX_ENf);
    259     } else {
    260         *enable = soc_reg_field_get(unit, CDMAC_CTRLr, rval, RX_ENf);
    261     }
    262 
    263     return (SOC_E_NONE);
    264 }
    265 
    266 /*
    267  * This function can be called to either set/reset
    268  * the TX/RX or put the MAC in reset/bring the MAC
    269  * out of reset.
    270  * Only one operation allowed in a single call.
    271  */
    272 int cdmac_enable_selective_set(int unit, soc_port_t port,
    273                                int flags, int enable)
    274 {
    275     uint32 rval, orig_rval;
    276     SOC_INIT_FUNC_DEFS;
    277 
    278 
    279     if (!(flags == CDMAC_ENABLE_SET_FLAGS_TX_EN) &&
    280         !(flags == CDMAC_ENABLE_SET_FLAGS_RX_EN) &&
    281         !(flags == CDMAC_ENABLE_SET_FLAGS_SOFT_RESET)) {
    282         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
    283                           (_SOC_MSG("unknown control flag - %x"), flags));
    284     }
    285 
    286     /*
    287      * based on the flags passed the required fields are set/reset
    288      */
    289 
    290     _SOC_IF_ERR_EXIT(READ_CDMAC_CTRLr(unit, port, &rval));
    291      orig_rval = rval;
    292 
    293     if (flags == CDMAC_ENABLE_SET_FLAGS_TX_EN) {
    294         soc_reg_field_set(unit, CDMAC_CTRLr, &rval, TX_ENf, enable? 1: 0);
    295     }
    296 
    297     if (flags == CDMAC_ENABLE_SET_FLAGS_RX_EN) {
    298         if (enable) {
    299             uint32 cdmac_tx_ctrl_rval;
    300 
    301             SOC_IF_ERROR_RETURN(READ_CDMAC_TX_CTRLr(unit, port, &cdmac_tx_ctrl_rval));
    302 
    303             soc_reg_field_set(unit, CDMAC_CTRLr, &rval, RX_ENf, 0);
    304             SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
    305 
    306             soc_reg_field_set(unit, CDMAC_TX_CTRLr, &cdmac_tx_ctrl_rval, DISCARDf, 1);
    307             SOC_IF_ERROR_RETURN(WRITE_CDMAC_TX_CTRLr(unit, port, cdmac_tx_ctrl_rval));
    308             sal_usleep(10000);
    309 
    310             soc_reg_field_set(unit, CDMAC_CTRLr, &rval, RX_ENf, 1);
    311             SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
    312 
    313             soc_reg_field_set(unit, CDMAC_TX_CTRLr, &cdmac_tx_ctrl_rval, DISCARDf, 0);
    314             SOC_IF_ERROR_RETURN(WRITE_CDMAC_TX_CTRLr(unit, port, cdmac_tx_ctrl_rval));
    315             sal_usleep(10000);
    316         } else {
    317             soc_reg_field_set(unit, CDMAC_CTRLr, &rval, RX_ENf, 0);
    318             SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
    319         }
    320     }
    321 
    322     /*
    323      * if enable = 0, bring mac out of reset, else mac in reset.
    324      */
    325     if (flags == CDMAC_ENABLE_SET_FLAGS_SOFT_RESET) {
    326         soc_reg_field_set(unit, CDMAC_CTRLr, &rval, SOFT_RESETf, enable? 1: 0);
    327     }
    328 
    329     /* write only if value changed */
    330     if(rval != orig_rval) { /* write only if value changed */
    331        _SOC_IF_ERR_EXIT(WRITE_CDMAC_CTRLr(unit, port, rval));
    332     }
    333 
    334 exit:
    335     SOC_FUNC_RETURN;
    336 }
    337 
    338 int cdmac_duplex_set(int unit, soc_port_t port, int duplex)
    339 {
    340     SOC_INIT_FUNC_DEFS;
    341     if (!duplex) {
    342         _SOC_EXIT_WITH_ERR(SOC_E_UNAVAIL,
    343                           (_SOC_MSG("half-duplex unsupported")));
    344     }
    345 
    346     /* Only duplex support, nothing to be done here */
    347 exit:
    348     SOC_FUNC_RETURN;
    349 }
    350 
    351 int cdmac_duplex_get(int unit, soc_port_t port, int *duplex)
    352 {
    353     SOC_INIT_FUNC_DEFS;
    354 
    355     /* Only duplex support */
    356     *duplex = TRUE;
    357 
    358     SOC_FUNC_RETURN;
    359 }
    360 
    361 
    362 int cdmac_loopback_set(int unit, soc_port_t port, portmod_loopback_mode_t lb,
    363                        int enable)
    364 {
    365     uint32 rval;
    366     SOC_INIT_FUNC_DEFS;
    367 
    368     /* only line side loopback supported */
    369     if (lb == portmodLoopbackMacOuter) {
    370         _SOC_IF_ERR_EXIT(READ_CDMAC_CTRLr(unit, port, &rval));
    371         soc_reg_field_set(unit, CDMAC_CTRLr, &rval, LOCAL_LPBKf,
    372                           enable? 1: 0);
    373         _SOC_IF_ERR_EXIT(WRITE_CDMAC_CTRLr(unit, port, rval));
    374     } else {
    375         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
    376                           (_SOC_MSG("unsupported loopback type %d"), lb));
    377     }
    378 
    379 exit:
    380     SOC_FUNC_RETURN;
    381 }
    382 
    383 int cdmac_loopback_get(int unit, soc_port_t port, portmod_loopback_mode_t lb,
    384                        int *enable)
    385 {
    386     uint32 rval;
    387     SOC_INIT_FUNC_DEFS;
    388 
    389     if (lb == portmodLoopbackMacOuter) {
    390         _SOC_IF_ERR_EXIT(READ_CDMAC_CTRLr(unit, port, &rval));
    391         *enable = soc_reg_field_get(unit, CDMAC_CTRLr, rval, LOCAL_LPBKf);
    392     } else {
    393         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
    394                           (_SOC_MSG("unsupported loopback type %d"), lb));
    395     }
    396 
    397 exit:
    398     SOC_FUNC_RETURN;
    399 }
    400 
    401 /*
    402  * portmod_port_tx_mac_enable_set is the caller function
    403  */
    404 int cdmac_tx_enable_set (int unit, soc_port_t port, int enable)
    405 {
    406     return(cdmac_enable_selective_set(unit, port,
    407                         CDMAC_ENABLE_SET_FLAGS_TX_EN, enable));
    408 }
    409 
    410 /*
    411  * portmod_port_tx_mac_enable_get is the caller function
    412  */
    413 int cdmac_tx_enable_get (int unit, soc_port_t port, int *enable)
    414 {
    415     uint32 rval;
    416 
    417     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
    418     *enable = soc_reg_field_get(unit, CDMAC_CTRLr, rval, TX_ENf);
    419 
    420     return (SOC_E_NONE);
    421 }
    422 
    423 /*
    424  * portmod_port_rx_mac_enable_set is the caller function
    425  */
    426 int cdmac_rx_enable_set (int unit, soc_port_t port, int enable)
    427 {
    428 
    429     return(cdmac_enable_selective_set(unit, port,
    430                         CDMAC_ENABLE_SET_FLAGS_RX_EN, enable));
    431 }
    432 
    433 /*
    434  * portmod_port_rx_mac_enable_get is the caller function
    435  */
    436 int cdmac_rx_enable_get (int unit, soc_port_t port, int *enable)
    437 {
    438     uint32 rval;
    439 
    440     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
    441     *enable = soc_reg_field_get(unit, CDMAC_CTRLr, rval, RX_ENf);
    442 
    443     return (SOC_E_NONE);
    444 }
    445 
    446 /*
    447  * portmod_port_mac_reset_set is the caller function
    448  */
    449 int cdmac_soft_reset_set(int unit, soc_port_t port, int enable)
    450 {
    451     return(cdmac_enable_selective_set(unit, port,
    452                         CDMAC_ENABLE_SET_FLAGS_SOFT_RESET, enable));
    453 }
    454 
    455 /*
    456  * portmod_port_mac_reset_set is the caller function
    457  */
    458 int cdmac_soft_reset_get(int unit, soc_port_t port, int *enable)
    459 {
    460     uint32 rval;
    461 
    462     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
    463     *enable = soc_reg_field_get(unit, CDMAC_CTRLr, rval, SOFT_RESETf);
    464 
    465     return (SOC_E_NONE);
    466 }
    467 
    468 int cdmac_tx_mac_sa_set(int unit, soc_port_t port, sal_mac_addr_t mac)
    469 {
    470     uint64 rval64;
    471     SOC_INIT_FUNC_DEFS;
    472 
    473     /*
    474      * Write bytes in the following order.
    475      * mac[0] -> BYTE 5(MSB) of the MAC address in HW
    476      * mac[1] -> BYTE 4
    477      * mac[2] -> BYTE 3
    478      * mac[3] -> BYTE 2
    479      * mac[4] -> BYTE 1
    480      * mac[5] -> BYTE 0(LSB)
    481      */
    482     COMPILER_64_ZERO(rval64);
    483     COMPILER_64_SET(rval64, _shr_uint16_read(&mac[0]),
    484                     _shr_uint32_read(&mac[2]));
    485 
    486     _SOC_IF_ERR_EXIT(WRITE_CDMAC_TX_MAC_SAr(unit, port, rval64));
    487 
    488 exit:
    489     SOC_FUNC_RETURN;
    490 }
    491 
    492 int cdmac_tx_mac_sa_get(int unit, soc_port_t port, sal_mac_addr_t mac)
    493 {
    494     uint64 rval64, field64;
    495     uint32 mac_addr[2];
    496     SOC_INIT_FUNC_DEFS;
    497 
    498     _SOC_IF_ERR_EXIT(READ_CDMAC_TX_MAC_SAr(unit, port, &rval64));
    499     field64 = soc_reg64_field_get(unit, CDMAC_TX_MAC_SAr, rval64, CTRL_SAf);
    500 
    501     mac_addr[0] = COMPILER_64_HI(field64);
    502     mac_addr[1] = COMPILER_64_LO(field64);
    503 
    504     /*
    505      * Extract bytes in the following order
    506      * BYTE 5(MSB) -> mac[0]
    507      * BYTE 4 -> mac[1]
    508      * BYTE 3 -> mac[2]
    509      * BYTE 2 -> mac[3]
    510      * BYTE 1 -> mac[4]
    511      * BYTE 0(LSB) -> mac[5]
    512      */
    513     mac[0] = (mac_addr[0] & 0x0000ff00) >> 8;
    514     mac[1] = (mac_addr[0] & 0x000000ff);
    515     mac[2] = (mac_addr[1] & 0xff000000) >> 24;
    516     mac[3] = (mac_addr[1] & 0x00ff0000) >> 16;
    517     mac[4] = (mac_addr[1] & 0x0000ff00) >> 8;
    518     mac[5] = (mac_addr[1] & 0x000000ff);
    519 
    520 exit:
    521     SOC_FUNC_RETURN;
    522 }
    523 
    524 int cdmac_rx_mac_sa_set(int unit, soc_port_t port, sal_mac_addr_t mac)
    525 {
    526     uint64 rval64;
    527     SOC_INIT_FUNC_DEFS;
    528 
    529     COMPILER_64_ZERO(rval64);
    530     COMPILER_64_SET(rval64, _shr_uint16_read(&mac[0]),
    531                     _shr_uint32_read(&mac[2]));
    532 
    533     /*
    534      * Write bytes in the following order.
    535      * mac[0] -> BYTE 5(MSB) of the MAC address in HW
    536      * mac[1] -> BYTE 4
    537      * mac[2] -> BYTE 3
    538      * mac[3] -> BYTE 2
    539      * mac[4] -> BYTE 1
    540      * mac[5] -> BYTE 0(LSB)
    541      */
    542     _SOC_IF_ERR_EXIT(WRITE_CDMAC_RX_MAC_SAr(unit, port, rval64));
    543 
    544 exit:
    545     SOC_FUNC_RETURN;
    546 }
    547 
    548 int cdmac_rx_mac_sa_get(int unit, soc_port_t port, sal_mac_addr_t mac)
    549 {
    550     uint64 rval64, field64;
    551     uint32 mac_addr[2];
    552     SOC_INIT_FUNC_DEFS;
    553 
    554     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_MAC_SAr(unit, port, &rval64));
    555     field64 = soc_reg64_field_get(unit, CDMAC_RX_MAC_SAr, rval64, RX_SAf);
    556 
    557     mac_addr[0] = COMPILER_64_HI(field64);
    558     mac_addr[1] = COMPILER_64_LO(field64);
    559 
    560     /*
    561      * Extract bytes in the following order
    562      * BYTE 5(MSB) -> mac[0]
    563      * BYTE 4 -> mac[1]
    564      * BYTE 3 -> mac[2]
    565      * BYTE 2 -> mac[3]
    566      * BYTE 1 -> mac[4]
    567      * BYTE 0(LSB) -> mac[5]
    568      */
    569     mac[0] = (mac_addr[0] & 0x0000ff00) >> 8;
    570     mac[1] = (mac_addr[0] & 0x000000ff);
    571     mac[2] = (mac_addr[1] & 0xff000000) >> 24;
    572     mac[3] = (mac_addr[1] & 0x00ff0000) >> 16;
    573     mac[4] = (mac_addr[1] & 0x0000ff00) >> 8;
    574     mac[5] = (mac_addr[1] & 0x000000ff);
    575 
    576 exit:
    577     SOC_FUNC_RETURN;
    578 }
    579 
    580 int cdmac_rx_vlan_tag_set(int unit, soc_port_t port, int outer_vlan_tag,
    581                           int inner_vlan_tag)
    582 {
    583     uint64 rval64;
    584     SOC_INIT_FUNC_DEFS;
    585 
    586     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_VLAN_TAGr(unit, port, &rval64));
    587 
    588     if(inner_vlan_tag == -1) {
    589        soc_reg64_field32_set(unit, CDMAC_RX_VLAN_TAGr, &rval64,
    590                              INNER_VLAN_TAG_ENABLEf, 0);
    591     } else {
    592        soc_reg64_field32_set(unit, CDMAC_RX_VLAN_TAGr, &rval64,
    593                              INNER_VLAN_TAGf, inner_vlan_tag);
    594        soc_reg64_field32_set(unit, CDMAC_RX_VLAN_TAGr, &rval64,
    595                              INNER_VLAN_TAG_ENABLEf, 1);
    596     }
    597 
    598     if(outer_vlan_tag == -1) {
    599        soc_reg64_field32_set(unit, CDMAC_RX_VLAN_TAGr, &rval64,
    600                              OUTER_VLAN_TAG_ENABLEf, 0);
    601     } else {
    602        soc_reg64_field32_set(unit, CDMAC_RX_VLAN_TAGr, &rval64,
    603                              OUTER_VLAN_TAGf, outer_vlan_tag);
    604        soc_reg64_field32_set(unit, CDMAC_RX_VLAN_TAGr, &rval64,
    605                              OUTER_VLAN_TAG_ENABLEf, 1);
    606     }
    607 
    608 exit:
    609     SOC_FUNC_RETURN;
    610 }
    611 
    612 int cdmac_rx_vlan_tag_get(int unit, soc_port_t port, int *outer_vlan_tag,
    613                           int *inner_vlan_tag)
    614 {
    615     uint64 rval64;
    616     uint32 is_enabled = 0;
    617     SOC_INIT_FUNC_DEFS;
    618 
    619     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_VLAN_TAGr(unit, port, &rval64));
    620 
    621     is_enabled = soc_reg64_field32_get(unit, CDMAC_RX_VLAN_TAGr, rval64,
    622                                        INNER_VLAN_TAG_ENABLEf);
    623     if(is_enabled == 0) {
    624        *inner_vlan_tag = -1;
    625     } else {
    626        *inner_vlan_tag = soc_reg64_field32_get(unit, CDMAC_RX_VLAN_TAGr,
    627                                                rval64, INNER_VLAN_TAGf);
    628     }
    629 
    630     is_enabled = soc_reg64_field32_get(unit, CDMAC_RX_VLAN_TAGr, rval64,
    631                                        OUTER_VLAN_TAG_ENABLEf);
    632     if(is_enabled == 0) {
    633        *outer_vlan_tag = -1;
    634     } else {
    635        *outer_vlan_tag = soc_reg64_field32_get(unit, CDMAC_RX_VLAN_TAGr,
    636                                                rval64, OUTER_VLAN_TAGf);
    637     }
    638 
    639 exit:
    640     SOC_FUNC_RETURN;
    641 }
    642 
    643 int cdmac_rx_max_size_set(int unit, soc_port_t port, int value)
    644 {
    645     uint32 rval;
    646     SOC_INIT_FUNC_DEFS;
    647 
    648     /*
    649      * Maximum packet size in receive direction, exclusive of preamble
    650      * and  CRC in strip mode. Packets greater than this size are
    651      * truncated to this value.
    652      */
    653     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_MAX_SIZEr(unit, port, &rval));
    654     soc_reg_field_set(unit, CDMAC_RX_MAX_SIZEr, &rval, RX_MAX_SIZEf, value);
    655     _SOC_IF_ERR_EXIT(WRITE_CDMAC_RX_MAX_SIZEr(unit, port, rval));
    656 
    657 exit:
    658     SOC_FUNC_RETURN;
    659 }
    660 
    661 int cdmac_rx_max_size_get(int unit, soc_port_t port, int *value)
    662 {
    663     uint32 rval;
    664     SOC_INIT_FUNC_DEFS;
    665 
    666     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_MAX_SIZEr(unit, port, &rval));
    667      *value = soc_reg_field_get(unit, CDMAC_RX_MAX_SIZEr, rval, RX_MAX_SIZEf);
    668 
    669 exit:
    670     SOC_FUNC_RETURN;
    671 }
    672 
    673 int cdmac_pad_size_set(int unit, soc_port_t port, int value)
    674 {
    675     uint32 rval;
    676     SOC_INIT_FUNC_DEFS;
    677 
    678     if (((value < CDMAC_PAD_THRESHOLD_SIZE_MIN) ||
    679         (value > CDMAC_PAD_THRESHOLD_SIZE_MAX)) &&
    680         (value != 0)) {
    681         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
    682                    (_SOC_MSG("unsupported pad threshold size %d"), value));
    683     }
    684 
    685     /*
    686      * If PAD_EN is set, packets smaller than PAD_THRESHOLD are padded
    687      * to this size. PAD_THRESHOLD must be >=64 and <= 96.
    688      */
    689     _SOC_IF_ERR_EXIT(READ_CDMAC_TX_CTRLr(unit, port, &rval));
    690     soc_reg_field_set(unit, CDMAC_TX_CTRLr, &rval, PAD_ENf, value? 1: 0);
    691     if (value) {
    692         soc_reg_field_set(unit, CDMAC_TX_CTRLr, &rval, PAD_THRESHOLDf, value);
    693     }
    694     _SOC_IF_ERR_EXIT(WRITE_CDMAC_TX_CTRLr(unit, port, rval));
    695 
    696 exit:
    697     SOC_FUNC_RETURN;
    698 }
    699 
    700 int cdmac_pad_size_get(int unit, soc_port_t port, int *value)
    701 {
    702     uint32 rval;
    703     uint32 pad_en;
    704     SOC_INIT_FUNC_DEFS;
    705 
    706     _SOC_IF_ERR_EXIT(READ_CDMAC_TX_CTRLr(unit, port, &rval));
    707     pad_en = soc_reg_field_get(unit, CDMAC_TX_CTRLr, rval, PAD_ENf);
    708     if(!pad_en) {
    709         *value = 0;
    710     } else {
    711         *value = soc_reg_field_get(unit, CDMAC_TX_CTRLr, rval, PAD_THRESHOLDf);
    712     }
    713 
    714 exit:
    715     SOC_FUNC_RETURN;
    716 }
    717 
    718 int cdmac_tx_average_ipg_set(int unit, soc_port_t port, int val)
    719 {
    720     uint32 rval;
    721     SOC_INIT_FUNC_DEFS;
    722 
    723     /*
    724      * Average inter packet gap can be in the range 8 to 56 or 60.
    725      * should be 56 for XLGMII, 60 for XGMII,
    726      * default is 12.
    727      * Granularity is in bytes.
    728      * Input 'val' is in bits.
    729      */
    730     if ((val < CDMAC_AVE_IPG_MIN) || (val > CDMAC_AVE_IPG_MAX)) {
    731        _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
    732                           (_SOC_MSG("Average IPG is out of range.")));
    733     }
    734 
    735     _SOC_IF_ERR_EXIT(READ_CDMAC_TX_CTRLr(unit, port, &rval));
    736     soc_reg_field_set(unit, CDMAC_TX_CTRLr, &rval, AVERAGE_IPGf, val/8);
    737     _SOC_IF_ERR_EXIT(WRITE_CDMAC_TX_CTRLr(unit, port, rval));
    738 
    739 exit:
    740     SOC_FUNC_RETURN;
    741 }
    742 
    743 int cdmac_tx_average_ipg_get(int unit, soc_port_t port, int *val)
    744 {
    745     uint32 rval;
    746     SOC_INIT_FUNC_DEFS;
    747 
    748     /*
    749      * Register value is in bytes.
    750      * Output 'val' is in bits.
    751      */
    752 
    753     _SOC_IF_ERR_EXIT(READ_CDMAC_TX_CTRLr(unit, port, &rval));
    754 
    755     *val = soc_reg_field_get(unit, CDMAC_TX_CTRLr, rval, AVERAGE_IPGf) * 8;
    756 
    757 exit:
    758     SOC_FUNC_RETURN;
    759 }
    760 
    761 int cdmac_runt_threshold_set(int unit, soc_port_t port, int value)
    762 {
    763     uint32 rval;
    764     SOC_INIT_FUNC_DEFS;
    765 
    766     /*
    767      * The threshold, below which the packets are dropped or
    768      * marked as runt. Should be programmed >=64 and <= 96 bytes.
    769      */
    770     if ((value < CDMAC_RUNT_THRESHOLD_MIN) ||
    771         (value > CDMAC_RUNT_THRESHOLD_MAX)) {
    772         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
    773             (_SOC_MSG("runt size should be greater than %d and "
    774             "smaller than %d. got %d"), CDMAC_RUNT_THRESHOLD_MIN,
    775             CDMAC_RUNT_THRESHOLD_MAX,  value));
    776     }
    777 
    778     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_CTRLr(unit, port, &rval));
    779     soc_reg_field_set(unit, CDMAC_RX_CTRLr, &rval, RUNT_THRESHOLDf, value);
    780     _SOC_IF_ERR_EXIT(WRITE_CDMAC_RX_CTRLr(unit, port, rval));
    781 
    782 exit:
    783     SOC_FUNC_RETURN;
    784 }
    785 
    786 int cdmac_runt_threshold_get(int unit, soc_port_t port, int *value)
    787 {
    788     uint32 rval;
    789     SOC_INIT_FUNC_DEFS;
    790 
    791     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_CTRLr(unit, port, &rval));
    792     *value = soc_reg_field_get(unit, CDMAC_RX_CTRLr, rval, RUNT_THRESHOLDf);
    793 
    794 exit:
    795     SOC_FUNC_RETURN;
    796 }
    797 
    798 /*
    799  * portmod_port_remote_fault_control_set is the caller of this function.
    800  */
    801 int cdmac_remote_fault_control_set(int unit, soc_port_t port,
    802                           const portmod_remote_fault_control_t *control)
    803 {
    804     uint32 rval;
    805     SOC_INIT_FUNC_DEFS;
    806 
    807     /*
    808      * REMOTE_FAULT_DISABLE determines the transmit response during remote
    809      * fault state. The REMOTE_FAULT_STATUS bit is always updated irrespective
    810      * of this configuration.
    811      * If set, MAC will continue to transmit data irrespective of
    812      *  REMOTE_FAULT_STATUS.
    813      * If reset, MAC transmit behavior is governed by
    814      * DROP_TX_DATA_ON_REMOTE_FAULT configuration.
    815      */
    816     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_CTRLr(unit, port, &rval));
    817 
    818     soc_reg_field_set(unit, CDMAC_RX_LSS_CTRLr, &rval, REMOTE_FAULT_DISABLEf,
    819                       control->enable? 0: 1); /* flip */
    820     soc_reg_field_set(unit, CDMAC_RX_LSS_CTRLr, &rval,
    821                       DROP_TX_DATA_ON_REMOTE_FAULTf,
    822                       control->drop_tx_on_fault? 1: 0);
    823     _SOC_IF_ERR_EXIT(WRITE_CDMAC_RX_LSS_CTRLr(unit, port, rval));
    824 
    825 exit:
    826     SOC_FUNC_RETURN;
    827 }
    828 
    829 /*
    830  * portmod_port_remote_fault_control_get is the caller of this function.
    831  */
    832 int cdmac_remote_fault_control_get(int unit, soc_port_t port,
    833                                    portmod_remote_fault_control_t *control)
    834 {
    835     uint32 rval;
    836     uint32 fval;
    837     SOC_INIT_FUNC_DEFS;
    838 
    839     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_CTRLr(unit, port, &rval));
    840 
    841     fval = soc_reg_field_get(unit, CDMAC_RX_LSS_CTRLr, rval,
    842                              REMOTE_FAULT_DISABLEf);
    843     /* if fval is reset, indicates enable */
    844     control->enable = (fval? 0: 1); 
    845 
    846     fval = soc_reg_field_get(unit, CDMAC_RX_LSS_CTRLr, rval,
    847                              DROP_TX_DATA_ON_REMOTE_FAULTf);
    848     control->drop_tx_on_fault = (fval? 1: 0);
    849 
    850 exit:
    851     SOC_FUNC_RETURN;
    852 }
    853 
    854 /*
    855  * portmod_port_remote_fault_status_get is the caller of this function.
    856  * The status bit is clear on read, no seperate api for status_clear  
    857  * required.
    858  */
    859 int cdmac_remote_fault_status_get(int unit, soc_port_t port, int *status)
    860 {
    861     uint32 rval;
    862     uint32 fval;
    863     SOC_INIT_FUNC_DEFS;
    864 
    865     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_STATUSr(unit, port, &rval));
    866     /* fault status bits clear on read */
    867     fval = soc_reg_field_get(unit, CDMAC_RX_LSS_STATUSr, rval,
    868                              REMOTE_FAULT_STATUSf);
    869     *status = (fval? 1: 0);
    870 
    871 exit:
    872     SOC_FUNC_RETURN;
    873 }
    874 
    875 /*
    876  * portmod_port_local_fault_control_set is the caller of this function.
    877  */
    878 int cdmac_local_fault_control_set(int unit, soc_port_t port,
    879                                   const portmod_local_fault_control_t *control)
    880 {
    881     uint32 rval;
    882     SOC_INIT_FUNC_DEFS;
    883 
    884     /*
    885      * LOCALFAULT_DISABLE determines the transmit response during remote
    886      * fault state. The LOCAL_FAULT_STATUS bit is always updated irrespective
    887      * of this configuration.
    888      * If set, MAC will continue to transmit data irrespective of
    889      *  REMOTE_FAULT_STATUS.
    890      * If reset, MAC transmit behavior is governed by 
    891      * DROP_TX_DATA_ON_LOCAL_FAULT configuration.
    892      */
    893     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_CTRLr(unit, port, &rval));
    894 
    895     soc_reg_field_set(unit, CDMAC_RX_LSS_CTRLr, &rval, LOCAL_FAULT_DISABLEf,
    896                       control->enable? 0: 1); /* flip */
    897     soc_reg_field_set(unit, CDMAC_RX_LSS_CTRLr, &rval,
    898                       DROP_TX_DATA_ON_LOCAL_FAULTf,
    899                       control->drop_tx_on_fault? 1: 0);
    900     _SOC_IF_ERR_EXIT(WRITE_CDMAC_RX_LSS_CTRLr(unit, port, rval));
    901 
    902 exit:
    903     SOC_FUNC_RETURN;
    904 }
    905 
    906 /*
    907  * portmod_port_local_fault_control_get is the caller of this function.
    908  */
    909 int cdmac_local_fault_control_get(int unit, soc_port_t port,
    910                                   portmod_local_fault_control_t *control)
    911 {
    912     uint32 rval;
    913     uint32 fval;
    914     SOC_INIT_FUNC_DEFS;
    915 
    916     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_CTRLr(unit, port, &rval));
    917 
    918     fval = soc_reg_field_get(unit, CDMAC_RX_LSS_CTRLr, rval,
    919                              LOCAL_FAULT_DISABLEf);
    920     control->enable = (fval? 0: 1);
    921 
    922     fval = soc_reg_field_get(unit, CDMAC_RX_LSS_CTRLr, rval,
    923                              DROP_TX_DATA_ON_LOCAL_FAULTf);
    924     control->drop_tx_on_fault = (fval? 1: 0);
    925 
    926 exit:
    927     SOC_FUNC_RETURN;
    928 }
    929 
    930 /*
    931  * portmod_port_local_fault_status_get is the caller of this function.
    932  * The status bit is clear on read, no seperate api for status_clear  
    933  * required.
    934  */
    935 int cdmac_local_fault_status_get(int unit, soc_port_t port, int *status)
    936 {
    937     uint32 rval;
    938     uint32 fval;
    939     SOC_INIT_FUNC_DEFS;
    940 
    941     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_STATUSr(unit, port, &rval));
    942     /* fault status bits clear on read */
    943     fval = soc_reg_field_get(unit, CDMAC_RX_LSS_STATUSr, rval,
    944                              LOCAL_FAULT_STATUSf);
    945     *status = (fval? 1: 0);
    946 
    947 exit:
    948     SOC_FUNC_RETURN;
    949 }
    950 
    951 /*
    952  * portmod_port_pfc_control_set is the caller of this function.
    953  */
    954 int cdmac_pfc_control_set(int unit, soc_port_t port,
    955                          const portmod_pfc_control_t *control)
    956 {
    957     uint64 rval64;
    958     uint32 rval;
    959     SOC_INIT_FUNC_DEFS;
    960 
    961     _SOC_IF_ERR_EXIT(READ_CDMAC_PAUSE_CTRLr(unit, port, &rval64));
    962 
    963     /** When control->refresh_timer=-1 PFC_REFRESH_TIMER must be set to 
    964       * 0xFFFF and the PFC_REFRESH_EN must be 1, to be consistent with clmac/xlmac */
    965     if(control->refresh_timer) {
    966         soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64,
    967                 PFC_REFRESH_TIMERf, control->refresh_timer);
    968 
    969         soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64,
    970                 PFC_REFRESH_ENf, 1);
    971     } else {
    972         soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64,
    973                 PFC_REFRESH_ENf, 0);
    974     }
    975 
    976     soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64,
    977             PFC_XOFF_TIMERf, control->xoff_timer);
    978 
    979     _SOC_IF_ERR_EXIT(WRITE_CDMAC_PAUSE_CTRLr(unit, port, rval64));
    980 
    981 
    982     _SOC_IF_ERR_EXIT(READ_CDMAC_PFC_CTRLr(unit, port, &rval));
    983 
    984     soc_reg_field_set(unit, CDMAC_PFC_CTRLr, &rval, PFC_STATS_ENf,
    985                       control->stats_en);
    986     soc_reg_field_set(unit, CDMAC_PFC_CTRLr, &rval, FORCE_PFC_XONf,
    987                       control->force_xon);
    988     soc_reg_field_set(unit, CDMAC_PFC_CTRLr, &rval, TX_PFC_ENf,
    989                       control->tx_enable);
    990     soc_reg_field_set(unit, CDMAC_PFC_CTRLr, &rval, RX_PFC_ENf,
    991                       control->rx_enable);
    992 
    993     _SOC_IF_ERR_EXIT(WRITE_CDMAC_PFC_CTRLr(unit, port, rval));
    994 
    995 exit:
    996     SOC_FUNC_RETURN;
    997 }
    998 
    999 int cdmac_pfc_control_get(int unit, soc_port_t port,
   1000                           portmod_pfc_control_t *control)
   1001 {
   1002     uint64 rval64;
   1003     uint32 rval;
   1004     uint32 refresh_enable = 0;
   1005     uint32 refresh_timer = 0;
   1006     SOC_INIT_FUNC_DEFS;
   1007 
   1008     _SOC_IF_ERR_EXIT(READ_CDMAC_PAUSE_CTRLr(unit, port, &rval64));
   1009 
   1010     refresh_enable = soc_reg64_field32_get(unit, CDMAC_PAUSE_CTRLr, rval64,
   1011                                        PFC_REFRESH_ENf);
   1012 
   1013     refresh_timer = soc_reg64_field32_get(unit, CDMAC_PAUSE_CTRLr, rval64,
   1014             PFC_REFRESH_TIMERf);
   1015 
   1016     control->refresh_timer = (refresh_enable? refresh_timer: 0);
   1017 
   1018     control->xoff_timer = soc_reg64_field32_get(unit, CDMAC_PAUSE_CTRLr,
   1019             rval64, PFC_XOFF_TIMERf);
   1020 
   1021     _SOC_IF_ERR_EXIT(READ_CDMAC_PFC_CTRLr(unit, port, &rval));
   1022 
   1023     control->stats_en = soc_reg_field_get(unit, CDMAC_PFC_CTRLr, rval,
   1024                                            PFC_STATS_ENf);
   1025     control->force_xon = soc_reg_field_get(unit, CDMAC_PFC_CTRLr, rval,
   1026                                            FORCE_PFC_XONf);
   1027     control->tx_enable = soc_reg_field_get(unit, CDMAC_PFC_CTRLr, rval,
   1028                                            TX_PFC_ENf);
   1029     control->rx_enable = soc_reg_field_get(unit, CDMAC_PFC_CTRLr, rval,
   1030                                            RX_PFC_ENf);
   1031 
   1032 exit:
   1033     SOC_FUNC_RETURN;
   1034 }
   1035 
   1036 int cdmac_pause_control_set(int unit, soc_port_t port,
   1037                             const portmod_pause_control_t *control)
   1038 {
   1039     uint64 rval64;
   1040     SOC_INIT_FUNC_DEFS;
   1041 
   1042     _SOC_IF_ERR_EXIT(READ_CDMAC_PAUSE_CTRLr(unit, port, &rval64));
   1043 
   1044     if(control->rx_enable || control->tx_enable) {
   1045        if(control->refresh_timer > 0 ) {
   1046           soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64,
   1047                             PAUSE_REFRESH_TIMERf, control->refresh_timer);
   1048           soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64,
   1049                             PAUSE_REFRESH_ENf, 1);
   1050        } else {
   1051           soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64,
   1052                             PAUSE_REFRESH_ENf, 0);
   1053        }
   1054        soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64,
   1055                          PAUSE_XOFF_TIMERf, control->xoff_timer);
   1056     }
   1057 
   1058     soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64, TX_PAUSE_ENf,
   1059                       control->tx_enable);
   1060     soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf,
   1061                       control->rx_enable);
   1062 
   1063     _SOC_IF_ERR_EXIT(WRITE_CDMAC_PAUSE_CTRLr(unit, port, rval64));
   1064 
   1065 exit:
   1066     SOC_FUNC_RETURN;
   1067 }
   1068 
   1069 int cdmac_pause_control_get(int unit, soc_port_t port,
   1070                             portmod_pause_control_t *control)
   1071 {
   1072     uint64 rval64;
   1073     uint32 refresh_enable;
   1074     uint32 refresh_timer;
   1075     SOC_INIT_FUNC_DEFS;
   1076 
   1077     _SOC_IF_ERR_EXIT(READ_CDMAC_PAUSE_CTRLr(unit, port, &rval64));
   1078 
   1079     refresh_enable = soc_reg64_field32_get(unit, CDMAC_PAUSE_CTRLr, rval64,
   1080                                        PAUSE_REFRESH_ENf);
   1081     refresh_timer = soc_reg64_field32_get(unit, CDMAC_PAUSE_CTRLr, rval64,
   1082                                       PAUSE_REFRESH_TIMERf);
   1083 
   1084     control->refresh_timer = (refresh_enable? refresh_timer: -1);
   1085     control->xoff_timer = soc_reg64_field32_get(unit, CDMAC_PAUSE_CTRLr,
   1086                                                 rval64, PAUSE_XOFF_TIMERf);
   1087 
   1088     control->tx_enable = soc_reg64_field32_get(unit, CDMAC_PAUSE_CTRLr, rval64,
   1089                                            TX_PAUSE_ENf);
   1090     control->rx_enable = soc_reg64_field32_get(unit, CDMAC_PAUSE_CTRLr, rval64,
   1091                                            RX_PAUSE_ENf);
   1092 
   1093 exit:
   1094     SOC_FUNC_RETURN;
   1095 }
   1096 
   1097 int cdmac_pfc_config_set (int unit, int port,
   1098                           const portmod_pfc_config_t* pfc_cfg)
   1099 {
   1100     uint32 rval;
   1101     uint32 fval[2] = {0};
   1102     uint64 rval64;
   1103     uint64 fval64;
   1104 
   1105     SOC_IF_ERROR_RETURN(READ_CDMAC_PFC_TYPEr(unit, port, &rval));
   1106     soc_reg_field_set(unit, CDMAC_PFC_TYPEr, &rval, PFC_ETH_TYPEf,
   1107                       pfc_cfg->type);
   1108     SOC_IF_ERROR_RETURN(WRITE_CDMAC_PFC_TYPEr(unit, port, rval));
   1109 
   1110     SOC_IF_ERROR_RETURN(READ_CDMAC_PFC_OPCODEr(unit, port, &rval));
   1111     soc_reg_field_set(unit, CDMAC_PFC_OPCODEr, &rval, PFC_OPCODEf,
   1112                       pfc_cfg->opcode);
   1113     SOC_IF_ERROR_RETURN(WRITE_CDMAC_PFC_OPCODEr(unit, port, rval));
   1114 
   1115     SOC_IF_ERROR_RETURN(READ_CDMAC_PFC_DAr(unit, port, &rval64));
   1116     fval[0] |= pfc_cfg->da_nonoui;
   1117     fval[0] |= (pfc_cfg->da_oui & 0xff) << 24;
   1118     fval[1] |= (pfc_cfg->da_oui & 0xffff00) >> 8;
   1119 
   1120     COMPILER_64_SET(fval64, fval[1], fval[0]);
   1121     soc_reg64_field_set(unit, CDMAC_PFC_DAr, &rval64, PFC_MACDAf, fval64);
   1122     SOC_IF_ERROR_RETURN(WRITE_CDMAC_PFC_DAr(unit, port, rval64));
   1123 
   1124     return (SOC_E_NONE);
   1125 }
   1126 
   1127 int cdmac_pfc_config_get (int unit, int port, portmod_pfc_config_t* pfc_cfg)
   1128 {
   1129     uint32 rval;
   1130     uint32 fval[2] = {0};
   1131     uint64 rval64;
   1132     uint64 fval64;
   1133 
   1134     SOC_IF_ERROR_RETURN(READ_CDMAC_PFC_TYPEr(unit, port, &rval));
   1135     pfc_cfg->type = soc_reg_field_get(unit, CDMAC_PFC_TYPEr, rval,
   1136                                       PFC_ETH_TYPEf);
   1137 
   1138     SOC_IF_ERROR_RETURN(READ_CDMAC_PFC_OPCODEr(unit, port, &rval));
   1139     pfc_cfg->opcode = soc_reg_field_get(unit, CDMAC_PFC_OPCODEr, rval,
   1140                                         PFC_OPCODEf);
   1141 
   1142     SOC_IF_ERROR_RETURN(READ_CDMAC_PFC_DAr(unit, port, &rval64));
   1143     fval64 = soc_reg64_field_get(unit, CDMAC_PFC_DAr, rval64, PFC_MACDAf);
   1144     fval[0] = COMPILER_64_LO(fval64);
   1145     fval[1] = COMPILER_64_HI(fval64);
   1146 
   1147     pfc_cfg->da_nonoui = fval[0] & 0xffffff;
   1148     pfc_cfg->da_oui = (fval[1] << 8) | (fval[0] >> 24);
   1149 
   1150     return (SOC_E_NONE);
   1151 }
   1152 
   1153 
   1154 int cdmac_pass_control_frame_set(int unit, int port, int value)
   1155 {
   1156     uint32 rval;
   1157 
   1158     /* 
   1159      * This configuration is used to drop or pass all control frames
   1160      * (with ether type 0x8808) except pause packets.
   1161      * If set, all control frames are passed to system side.
   1162      * if reset, control frames (including pfc frames wih ether type 0x8808)i
   1163      * are dropped in CDMAC.
   1164      */
   1165     SOC_IF_ERROR_RETURN(READ_CDMAC_RX_CTRLr(unit, port, &rval));
   1166     soc_reg_field_set(unit, CDMAC_RX_CTRLr, &rval,
   1167                       RX_PASS_CTRLf, (value? 1: 0));
   1168     SOC_IF_ERROR_RETURN(WRITE_CDMAC_RX_CTRLr(unit, port, rval));
   1169 
   1170     return (SOC_E_NONE);
   1171 }
   1172 
   1173 
   1174 int cdmac_pass_control_frame_get(int unit, int port, int *value)
   1175 {
   1176     uint32 rval;
   1177 
   1178     SOC_IF_ERROR_RETURN(READ_CDMAC_RX_CTRLr(unit, port, &rval));
   1179     *value = soc_reg_field_get(unit, CDMAC_RX_CTRLr, rval, RX_PASS_CTRLf);
   1180 
   1181     return (SOC_E_NONE);
   1182 }
   1183 
   1184 
   1185 int cdmac_pass_pfc_frame_set(int unit, int port, int value)
   1186 {
   1187     uint32 rval;
   1188 
   1189     /*
   1190      * This configuration is used to pass or drop PFC packets when 
   1191      * PFC_ETH_TYPE is not equal to 0x8808.
   1192      * If set, PFC frames are passed to system side.
   1193      * If reset, PFC frames are dropped in CDMAC.
   1194      */
   1195     SOC_IF_ERROR_RETURN(READ_CDMAC_RX_CTRLr(unit, port, &rval));
   1196     soc_reg_field_set(unit, CDMAC_RX_CTRLr, &rval,
   1197                       RX_PASS_PFCf, (value? 1: 0));
   1198     SOC_IF_ERROR_RETURN(WRITE_CDMAC_RX_CTRLr(unit, port, rval));
   1199 
   1200     return (SOC_E_NONE);
   1201 }
   1202 
   1203 
   1204 int cdmac_pass_pfc_frame_get(int unit, int port, int *value)
   1205 {
   1206     uint32 rval;
   1207 
   1208     SOC_IF_ERROR_RETURN(READ_CDMAC_RX_CTRLr(unit, port, &rval));
   1209     *value = soc_reg_field_get(unit, CDMAC_RX_CTRLr, rval, RX_PASS_PFCf);
   1210 
   1211     return (SOC_E_NONE);
   1212 }
   1213 
   1214 
   1215 int cdmac_pass_pause_frame_set(int unit, int port, int value)
   1216 {
   1217     uint32 rval;
   1218 
   1219     /*
   1220      * If set, PAUSE frames are passed to sytem side.
   1221      * If reset, PAUSE frames are dropped in CDMAC
   1222      */
   1223     SOC_IF_ERROR_RETURN(READ_CDMAC_RX_CTRLr(unit, port, &rval));
   1224     soc_reg_field_set(unit, CDMAC_RX_CTRLr, &rval,
   1225                       RX_PASS_PAUSEf, (value? 1: 0));
   1226     SOC_IF_ERROR_RETURN(WRITE_CDMAC_RX_CTRLr(unit, port, rval));
   1227 
   1228     return (SOC_E_NONE);
   1229 }
   1230 
   1231 
   1232 int cdmac_pass_pause_frame_get(int unit, int port, int *value)
   1233 {
   1234     uint32 rval;
   1235 
   1236     SOC_IF_ERROR_RETURN(READ_CDMAC_RX_CTRLr(unit, port, &rval));
   1237     *value = soc_reg_field_get(unit, CDMAC_RX_CTRLr, rval, RX_PASS_PAUSEf);
   1238 
   1239     return (SOC_E_NONE);
   1240 }
   1241 
   1242 /*
   1243  * LAG FAILOVER
   1244  * Following routines are used and invoked for the LAG
   1245  * failover feature.
   1246  * When a LAG(Trunk) member port goes down, if LAG failover
   1247  * is enabled all the tx packets are loopback to RX path.
   1248  * This is done by enabling loopback on the port which went
   1249  * down, when the port comes back up, the software detects
   1250  * the LINK UP event and removes the loopback.
   1251  * Programming Sequence:
   1252  * CDMAC_CTRL.LAG_FAILOVER_ENf 1/0, enable/disable feature.
   1253  *                             If set, enable LAG Failover.
   1254  * This bit has priority over LOCAL_LPBK. The lag failover
   1255  * kicks in when the link status selected by LINK_STATUS_SELECT
   1256  * transitions from 1 to 0. TSC clock and TSC credits must
   1257  * be active for lag failover.
   1258  *
   1259  * portmod_port_trunk_hwfailover_config_set is the caller
   1260  * of this function, which in turn is called by the bcm
   1261  * application layer function calls handling the lag  hardware
   1262  * failover feature.
   1263  */
   1264 int cdmac_lag_failover_en_set(int unit, int port, int val)
   1265 {
   1266     uint32 rval;
   1267 
   1268     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1269 
   1270     /* need to disable MAC_LINK_DOWN_SEQ_ENf when faliover is enabled */
   1271     if (val) {
   1272         uint32  cdmac_tx_ctrl_rval;
   1273         SOC_IF_ERROR_RETURN(READ_CDMAC_TX_CTRLr(unit, port, &cdmac_tx_ctrl_rval));
   1274         soc_reg_field_set(unit, CDMAC_CTRLr, &rval, MAC_LINK_DOWN_SEQ_ENf, FALSE);
   1275         /* need to reable rx and disable tx discard */
   1276         soc_reg_field_set(unit, CDMAC_CTRLr, &rval, RX_ENf, 1);
   1277         SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
   1278         soc_reg_field_set(unit, CDMAC_TX_CTRLr, &cdmac_tx_ctrl_rval, DISCARDf, 0);
   1279         SOC_IF_ERROR_RETURN(WRITE_CDMAC_TX_CTRLr(unit, port, cdmac_tx_ctrl_rval));
   1280     } else {
   1281         /*once lag failover is disable, need to restore the MAC_LINK_DOWN_SEQ_EN bit */
   1282         soc_reg_field_set(unit, CDMAC_CTRLr, &rval, MAC_LINK_DOWN_SEQ_ENf, TRUE);
   1283     }
   1284 
   1285     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, LAG_FAILOVER_ENf, val);
   1286     SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
   1287 
   1288     return (SOC_E_NONE);
   1289 }
   1290 
   1291 /*
   1292  * portmod_port_trunk_hwfailover_config_get is the caller
   1293  * of this function, returns if the hw lag failover feature
   1294  * is enabled on a port.
   1295  */
   1296 int cdmac_lag_failover_en_get(int unit, int port, int *val)
   1297 {
   1298     uint32 rval;
   1299 
   1300     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1301     *val = soc_reg_field_get(unit, CDMAC_CTRLr, rval, LAG_FAILOVER_ENf);
   1302 
   1303     return (SOC_E_NONE);
   1304 }
   1305 
   1306 /*
   1307  * This function is used to disable the LAG failover feature
   1308  * on a port.
   1309  * portmod_port_lag_failover_disable is the caller
   1310  * of this function, which in turn is called by the bcm
   1311  * application layer function calls handling the lag hardware
   1312  * failover feature.
   1313  */
   1314 int cdmac_lag_failover_disable(int unit, int port)
   1315 {
   1316     uint32 rval;
   1317 
   1318     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1319 
   1320     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, LAG_FAILOVER_ENf, 0);
   1321     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, LINK_STATUS_SELECTf, 0);
   1322     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, REMOVE_FAILOVER_LPBKf, 0);
   1323 
   1324     SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
   1325 
   1326     return (SOC_E_NONE);
   1327 }
   1328 
   1329 /*
   1330  * portmod_port_lag_failover_loopback_set is the caller
   1331  * of this function.
   1332  */
   1333 int cdmac_lag_failover_loopback_set(int unit, int port, int val)
   1334 {
   1335     uint32 rval;
   1336 
   1337     SOC_IF_ERROR_RETURN(READ_CDMAC_LAG_FAILOVER_STATUSr(unit, port, &rval));
   1338     /* If set, indicates that the port is in lag failover state */
   1339     soc_reg_field_set(unit, CDMAC_LAG_FAILOVER_STATUSr, &rval,
   1340                       LAG_FAILOVER_LOOPBACKf, val);
   1341     SOC_IF_ERROR_RETURN(WRITE_CDMAC_LAG_FAILOVER_STATUSr(unit, port, rval));
   1342 
   1343     return (SOC_E_NONE);
   1344 }
   1345 
   1346 /*
   1347  * portmod_port_lag_failover_loopback_get is the caller
   1348  * of this function. This function is invoked as part of
   1349  * LINK events from LINKSCAN thread
   1350  */
   1351 int cdmac_lag_failover_loopback_get(int unit, int port, int *val)
   1352 {
   1353     uint32 rval;
   1354 
   1355     SOC_IF_ERROR_RETURN(READ_CDMAC_LAG_FAILOVER_STATUSr(unit, port, &rval));
   1356     /*
   1357      * The LAG_FAILOVER_LOOPBACK is SET by the hardware if
   1358      * the LINK goes down and LAG_FAILOVER_ENf is set on the port.
   1359      */
   1360     *val = soc_reg_field_get(unit, CDMAC_LAG_FAILOVER_STATUSr, rval,
   1361                              LAG_FAILOVER_LOOPBACKf);
   1362 
   1363     return (SOC_E_NONE);
   1364 }
   1365 
   1366 /*
   1367  * portmod_port_lag_remove_failover_lpbk_set is the caller
   1368  * of this function. This function is invoked as part of
   1369  * LINK events from LINKSCAN thread
   1370  */
   1371 int cdmac_lag_remove_failover_lpbk_set(int unit, int port, int val)
   1372 {
   1373     uint32 rval;
   1374 
   1375     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1376     /*
   1377      * If set, CDMAC port will move from lag failover state to
   1378      * normal operation. This bit should be set after link is up.
   1379      * A transition from 0 to 1 is required, so first a write with
   1380      * 0 should be followed by a write with 1.
   1381      * The BCM layer should take care of the calling sequnce as
   1382      * part of LINK events.
   1383      */
   1384     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, REMOVE_FAILOVER_LPBKf, val);
   1385     SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
   1386 
   1387     return (SOC_E_NONE);
   1388 }
   1389 
   1390 /*
   1391  * portmod_port_lag_remove_failover_lpbk_get is the caller
   1392  * of this function.
   1393  */
   1394 int cdmac_lag_remove_failover_lpbk_get(int unit, int port, int *val)
   1395 {
   1396     uint32 rval;
   1397 
   1398     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1399     *val = soc_reg_field_get(unit, CDMAC_CTRLr, rval, REMOVE_FAILOVER_LPBKf);
   1400 
   1401     return (SOC_E_NONE);
   1402 }
   1403 
   1404 int cdmac_reset_fc_timers_on_link_dn_get(int unit, soc_port_t port, int *val)
   1405 {
   1406     uint32 rval;
   1407 
   1408     SOC_IF_ERROR_RETURN(READ_CDMAC_RX_LSS_CTRLr(unit, port, &rval));
   1409     *val = soc_reg_field_get(unit, CDMAC_RX_LSS_CTRLr, rval,
   1410                              RESET_FLOW_CONTROL_TIMERS_ON_LINK_DOWNf);
   1411 
   1412     return (SOC_E_NONE);
   1413 }
   1414 
   1415 /*
   1416  * portmod_port_trunk_hwfailover_config_set is the caller of this
   1417  * function. This function is invoked during lag failover config
   1418  * on a port.
   1419  */
   1420 int cdmac_reset_fc_timers_on_link_dn_set(int unit, soc_port_t port, int val)
   1421 {
   1422     uint32 rval;
   1423 
   1424     /*
   1425      * If set, the receive pause and PFC timers are reset whenever the link
   1426      * status is down, or local or remote faults are received.
   1427      */
   1428     SOC_IF_ERROR_RETURN(READ_CDMAC_RX_LSS_CTRLr(unit, port, &rval));
   1429     soc_reg_field_set(unit, CDMAC_RX_LSS_CTRLr, &rval,
   1430                       RESET_FLOW_CONTROL_TIMERS_ON_LINK_DOWNf, val);
   1431     SOC_IF_ERROR_RETURN(WRITE_CDMAC_RX_LSS_CTRLr(unit, port, rval));
   1432 
   1433     return (SOC_E_NONE);
   1434 }
   1435 
   1436 
   1437 int cdmac_mac_ctrl_set(int unit, int port, uint64 ctrl)
   1438 {
   1439     uint32 rval;
   1440 
   1441     COMPILER_64_TO_32_LO(rval, ctrl);
   1442     SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
   1443     return (SOC_E_NONE);
   1444 }
   1445 
   1446 int cdmac_drain_cell_get(int unit, int port,
   1447                          portmod_drain_cells_t *drain_cells)
   1448 {
   1449     uint32 rval;
   1450     uint64 rval64;
   1451 
   1452     SOC_IF_ERROR_RETURN(READ_CDMAC_PFC_CTRLr(unit, port, &rval));
   1453     drain_cells->rx_pfc_en = soc_reg_field_get(unit, CDMAC_PFC_CTRLr, rval,
   1454                                                RX_PFC_ENf);
   1455 
   1456     SOC_IF_ERROR_RETURN(READ_CDMAC_PAUSE_CTRLr(unit, port, &rval64));
   1457     drain_cells->rx_pause = soc_reg64_field32_get(unit, CDMAC_PAUSE_CTRLr,
   1458                                                   rval64, RX_PAUSE_ENf);
   1459     drain_cells->tx_pause = soc_reg64_field32_get(unit, CDMAC_PAUSE_CTRLr,
   1460                                                   rval64, TX_PAUSE_ENf);
   1461 
   1462     return (SOC_E_NONE);
   1463 }
   1464 
   1465 
   1466 int cdmac_discard_set(int unit, soc_port_t port, int discard)
   1467 {
   1468     uint32 rval;
   1469 
   1470     /* Clear Discard fields */
   1471     SOC_IF_ERROR_RETURN(READ_CDMAC_TX_CTRLr(unit, port, &rval));
   1472     soc_reg_field_set(unit, CDMAC_TX_CTRLr, &rval, DISCARDf, discard);
   1473     SOC_IF_ERROR_RETURN(WRITE_CDMAC_TX_CTRLr(unit, port, rval));
   1474 
   1475     return (SOC_E_NONE);
   1476 }
   1477 
   1478 
   1479 int cdmac_drain_cell_stop(int unit, int port,
   1480                            const portmod_drain_cells_t *drain_cells)
   1481 {
   1482     uint32 rval;
   1483     uint64 rval64;
   1484 
   1485     /* Clear Discard fields */
   1486     SOC_IF_ERROR_RETURN(cdmac_discard_set(unit, port, 0));
   1487 
   1488     /* set pause fields */
   1489     SOC_IF_ERROR_RETURN(READ_CDMAC_PAUSE_CTRLr(unit, port, &rval64));
   1490     soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf,
   1491                       drain_cells->rx_pause);
   1492     soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64, TX_PAUSE_ENf,
   1493                       drain_cells->tx_pause);
   1494     SOC_IF_ERROR_RETURN(WRITE_CDMAC_PAUSE_CTRLr(unit, port, rval64));
   1495 
   1496     /* set pfc rx_en fields */
   1497     SOC_IF_ERROR_RETURN(READ_CDMAC_PFC_CTRLr(unit, port, &rval));
   1498     soc_reg_field_set(unit, CDMAC_PFC_CTRLr, &rval, RX_PFC_ENf,
   1499                       drain_cells->rx_pfc_en);
   1500     SOC_IF_ERROR_RETURN(WRITE_CDMAC_PFC_CTRLr(unit, port, rval));
   1501 
   1502     return (SOC_E_NONE);
   1503 }
   1504 
   1505 int cdmac_drain_cell_start(int unit, int port)
   1506 {
   1507     uint32 rval;
   1508     uint64 rval64;
   1509 
   1510     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1511 
   1512     /* Don't disable TX since it stops egress and hangs if CPU sends */
   1513     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, TX_ENf, 1);
   1514     /* Disable RX */
   1515     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, RX_ENf, 0);
   1516 
   1517     SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
   1518 
   1519     SOC_IF_ERROR_RETURN(READ_CDMAC_PAUSE_CTRLr(unit, port, &rval64));
   1520     soc_reg64_field32_set(unit, CDMAC_PAUSE_CTRLr, &rval64, RX_PAUSE_ENf,0);
   1521     SOC_IF_ERROR_RETURN(WRITE_CDMAC_PAUSE_CTRLr(unit, port, rval64));
   1522 
   1523     SOC_IF_ERROR_RETURN(READ_CDMAC_PFC_CTRLr(unit, port, &rval));
   1524     soc_reg_field_set(unit, CDMAC_PFC_CTRLr, &rval, RX_PFC_ENf, 0);
   1525     SOC_IF_ERROR_RETURN(WRITE_CDMAC_PFC_CTRLr(unit, port, rval));
   1526 
   1527     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1528     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, SOFT_RESETf, 1);
   1529     SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
   1530 
   1531     SOC_IF_ERROR_RETURN(cdmac_discard_set(unit, port, 1));
   1532 
   1533     return (SOC_E_NONE);
   1534 }
   1535 
   1536 
   1537 int cdmac_txfifo_cell_cnt_get(int unit, int port, uint32* val)
   1538 {
   1539     uint32 rval;
   1540 
   1541     SOC_IF_ERROR_RETURN(READ_CDMAC_TXFIFO_CELL_CNTr(unit, port, &rval));
   1542     *val = soc_reg_field_get(unit, CDMAC_TXFIFO_CELL_CNTr, rval, CELL_CNTf);
   1543 
   1544     return (SOC_E_NONE);
   1545 }
   1546 
   1547 int cdmac_egress_queue_drain_get(int unit, int port, uint64 *mac_ctrl,
   1548                                  int *rx_en)
   1549 {
   1550     uint32 rval;
   1551 
   1552     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1553     COMPILER_64_SET(*mac_ctrl, 0, rval);
   1554 
   1555     *rx_en = soc_reg_field_get(unit, CDMAC_CTRLr, rval, RX_ENf);
   1556 
   1557     return (SOC_E_NONE);
   1558 }
   1559 
   1560 
   1561 int cdmac_drain_cells_rx_enable(int unit, int port, int rx_en)
   1562 {
   1563     uint32 rval, orig_rval;
   1564     uint32 soft_reset = 0;
   1565 
   1566     /* Enable both TX and RX, de-assert SOFT_RESET */
   1567     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1568     orig_rval = rval;
   1569 
   1570     /* Don't disable TX since it stops egress and hangs if CPU sends */
   1571     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, TX_ENf, 1);
   1572     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, RX_ENf, rx_en ? 1: 0);
   1573 
   1574     if (rval == orig_rval) {
   1575         /*
   1576          *  To avoid the unexpected early return to prevent this problem.
   1577          *  1. Problem occurred for disabling process only.
   1578          *  2. To comply original designing scenario, CDMAC_CTRLr.SOFT_RESETf
   1579          *     is used to early check to see if this port is at disabled state
   1580          *     already.
   1581          */
   1582         soft_reset = soc_reg_field_get(unit, CDMAC_CTRLr, rval, SOFT_RESETf);
   1583         if ((rx_en) || (!rx_en && soft_reset)){
   1584             return SOC_E_NONE;
   1585         }
   1586     }
   1587 
   1588     if (rx_en) {
   1589         soc_reg_field_set(unit, CDMAC_CTRLr, &rval, SOFT_RESETf, 0);
   1590     }
   1591 
   1592     SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
   1593 
   1594     return (SOC_E_NONE);
   1595 }
   1596 
   1597 int cdmac_egress_queue_drain_rx_en(int unit, int port, int rx_en)
   1598 {
   1599     uint32 rval;
   1600 
   1601     /* Enable RX, de-assert SOFT_RESET */
   1602     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1603     if (rx_en) {
   1604         uint32 cdmac_tx_ctrl_rval;
   1605 
   1606         SOC_IF_ERROR_RETURN(READ_CDMAC_TX_CTRLr(unit, port, &cdmac_tx_ctrl_rval));
   1607 
   1608         soc_reg_field_set(unit, CDMAC_CTRLr, &rval, RX_ENf, 0);
   1609         SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
   1610 
   1611         soc_reg_field_set(unit, CDMAC_TX_CTRLr, &cdmac_tx_ctrl_rval, DISCARDf, 1);
   1612         SOC_IF_ERROR_RETURN(WRITE_CDMAC_TX_CTRLr(unit, port, cdmac_tx_ctrl_rval));
   1613         sal_usleep(10000);
   1614 
   1615         soc_reg_field_set(unit, CDMAC_CTRLr, &rval, RX_ENf, 1);
   1616         SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
   1617 
   1618         soc_reg_field_set(unit, CDMAC_TX_CTRLr, &cdmac_tx_ctrl_rval, DISCARDf, 0);
   1619         SOC_IF_ERROR_RETURN(WRITE_CDMAC_TX_CTRLr(unit, port, cdmac_tx_ctrl_rval));
   1620         sal_usleep(10000);
   1621     } else {
   1622         soc_reg_field_set(unit, CDMAC_CTRLr, &rval, RX_ENf, 0);
   1623         SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
   1624     }
   1625 
   1626     /*Bring mac out of reset */
   1627     SOC_IF_ERROR_RETURN(cdmac_soft_reset_set(unit, port, 0));
   1628 
   1629     return (SOC_E_NONE);
   1630 }
   1631 
   1632 int cdmac_reset_check(int unit, int port, int enable, int *reset)
   1633 {
   1634     uint32 rval, orig_rval;
   1635 
   1636     *reset = 1;
   1637 
   1638     /* Enable both TX and RX, de-assert SOFT_RESET */
   1639     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1640     orig_rval = rval;
   1641 
   1642     /* In cdmac_enable_set, we never disable TX since it stops egress
   1643      * and hangs if CPU sends.
   1644      * However, TX_EN will be disabled in bcmi_th3_port_disable
   1645      * as part of port disable sequence within SDK.
   1646      * As a result, in this functoin, if enable==0, the expected
   1647      * register value will be TX_EN==0 && RX_EN==0.
   1648      */
   1649     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, TX_ENf, enable? 1: 0);
   1650     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, RX_ENf, enable? 1: 0);
   1651 
   1652     if (rval == orig_rval) {
   1653         if (enable) {
   1654             *reset = 0;
   1655         } else {
   1656             if (soc_reg_field_get(unit, CDMAC_CTRLr, rval, SOFT_RESETf)) {
   1657                 *reset = 0;
   1658             }
   1659         }
   1660     }
   1661 
   1662     return (SOC_E_NONE);
   1663 }
   1664 
   1665 /*
   1666  * portmod_port_trunk_hwfailover_config_set is the caller of this
   1667  * function. This function is invoked during lag failover config
   1668  * on a port.
   1669  */
   1670 int cdmac_sw_link_status_select_set(int unit, soc_port_t port, int enable)
   1671 {
   1672     uint32 rval;
   1673 
   1674     /*
   1675      * This configuration chooses between link status indication from software
   1676      * (SW_LINK_STATUSf) or the hardware link status indication from the PCS i
   1677      * to MAC. If set, hardware link status is used.
   1678      */
   1679     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1680     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, LINK_STATUS_SELECTf, enable);
   1681     SOC_IF_ERROR_RETURN(WRITE_CDMAC_CTRLr(unit, port, rval));
   1682 
   1683     return (SOC_E_NONE);
   1684 }
   1685 
   1686 int cdmac_sw_link_status_select_get(int unit, soc_port_t port, int *enable)
   1687 {
   1688     uint32 rval;
   1689 
   1690     SOC_IF_ERROR_RETURN(READ_CDMAC_CTRLr(unit, port, &rval));
   1691     *enable = soc_reg_field_get(unit, CDMAC_CTRLr, rval, LINK_STATUS_SELECTf);
   1692 
   1693     return (SOC_E_NONE);
   1694 }
   1695 
   1696 int cdmac_sw_link_status_set (int unit, soc_port_t port, int link)
   1697 {
   1698     uint32 rval;
   1699     SOC_INIT_FUNC_DEFS;
   1700 
   1701     /*
   1702      * This is valid only if LINK_STATUS_SELECT is 0, which means the 
   1703      * software drives the link status. If SW_LINK_STATUS is set,
   1704      * it indicates that the link is active. The use case is if there is  
   1705      * some other mechanism used for the link status determination other
   1706      * than hardware.
   1707      */
   1708     _SOC_IF_ERR_EXIT(READ_CDMAC_CTRLr(unit, port, &rval));
   1709     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, SW_LINK_STATUSf, link);
   1710     _SOC_IF_ERR_EXIT(WRITE_CDMAC_CTRLr(unit, port, rval));
   1711 
   1712 exit:
   1713     SOC_FUNC_RETURN;
   1714 }
   1715 
   1716 int cdmac_sw_link_status_get (int unit, soc_port_t port, int *link)
   1717 {
   1718     uint32 rval;
   1719     int link_status_sel = 0;
   1720     SOC_INIT_FUNC_DEFS;
   1721 
   1722     /*
   1723      * check if link status selection is software based, if yes return 
   1724      * sw_link_status.
   1725      */
   1726     _SOC_IF_ERR_EXIT(
   1727         cdmac_sw_link_status_select_get(unit, port, &link_status_sel));
   1728 
   1729     /* link status selection is software based */
   1730     if (!link_status_sel) {
   1731         _SOC_IF_ERR_EXIT(READ_CDMAC_CTRLr(unit, port, &rval));
   1732         *link = soc_reg_field_get(unit, CDMAC_CTRLr, rval, SW_LINK_STATUSf);
   1733     }
   1734 
   1735 exit:
   1736     SOC_FUNC_RETURN;
   1737 }
   1738 
   1739 int cdmac_mib_counter_control_set(int unit, soc_port_t port,
   1740                                   int enable, int clear)
   1741 {
   1742     uint32 rval;
   1743 
   1744     /* 
   1745      * For enabling the MIB statistics counters for a port, the ENABLE field 
   1746      * must be set.
   1747      * To reset/clear MIB statistics counters, CLEAR field should be set 1.
   1748      * A low-to-high(0->1) transition on this bit(CLEAR field) will trigger
   1749      * the counter-clear operation.
   1750      * Please Note:
   1751      * If a subsequent counter-clear operation is required, this bit has to 
   1752      * be first written to 0 and then written to 1. Instead of doing this
   1753      * setting CLEAR field to 0 after setting to 1.
   1754      * SW name for CLEAR field is CNT_CLEARf.
   1755      */
   1756     SOC_IF_ERROR_RETURN(READ_CDMAC_MIB_COUNTER_CTRLr(unit, port, &rval));
   1757     soc_reg_field_set(unit, CDMAC_MIB_COUNTER_CTRLr, &rval,
   1758                       ENABLEf, enable);
   1759     soc_reg_field_set(unit, CDMAC_MIB_COUNTER_CTRLr, &rval, CNT_CLEARf, clear);
   1760 
   1761     SOC_IF_ERROR_RETURN(WRITE_CDMAC_MIB_COUNTER_CTRLr(unit, port, rval));
   1762 
   1763     /*
   1764      * set CLEARf to 0, this operation is not mandatory, adding to 
   1765      * remove ambiguity in interpretation if a read on this register
   1766      */
   1767     if (clear) {
   1768         SOC_IF_ERROR_RETURN(READ_CDMAC_MIB_COUNTER_CTRLr(unit, port, &rval));
   1769         soc_reg_field_set(unit, CDMAC_MIB_COUNTER_CTRLr, &rval, CNT_CLEARf, 0);
   1770         SOC_IF_ERROR_RETURN(WRITE_CDMAC_MIB_COUNTER_CTRLr(unit, port, rval));
   1771     }
   1772 
   1773     return (SOC_E_NONE);
   1774 }
   1775 
   1776 /*
   1777  * portmod_port_cntmaxsize_set is caller of this function
   1778  */
   1779 int cdmac_cntmaxsize_set(int unit, int port, int val)
   1780 {
   1781     uint32 rval;
   1782     int field_len = 0;
   1783     SOC_INIT_FUNC_DEFS;
   1784 
   1785     field_len = soc_reg_field_length(unit, CDMAC_MIB_COUNTER_CTRLr,
   1786                                      CNTMAXSIZEf);
   1787 
   1788     if ((!field_len) || (val > ((1 << field_len) - 1))) {
   1789         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   1790                           (_SOC_MSG("invalid field length(%d) or value(%d)"),
   1791                           field_len, val));
   1792     }
   1793     /*
   1794      * The maximum packet size that is used in statistics counter updates.
   1795      * default size is 1518. Note if RX_MAX_SIZE(max frame size received)
   1796      * is greater than CNTMAXSIZEf, a good packet that is valid CRC and
   1797      * contains no other errors, will increment the OVR(oversize) counters
   1798      * if the length of the packet > CNTMAXSIZE < RX_MAX_SIZE values.
   1799      * Having CNTMAXSIZE > RX_MAX_SIZE is not recommended.
   1800      * This is generally taken care in the statistics module while
   1801      * accumulating the counts.
   1802      */
   1803     _SOC_IF_ERR_EXIT(READ_CDMAC_MIB_COUNTER_CTRLr(unit, port, &rval));
   1804     soc_reg_field_set(unit, CDMAC_MIB_COUNTER_CTRLr, &rval, CNTMAXSIZEf, val);
   1805     _SOC_IF_ERR_EXIT(WRITE_CDMAC_MIB_COUNTER_CTRLr(unit, port, rval));
   1806 
   1807 exit:
   1808     SOC_FUNC_RETURN;
   1809 }
   1810 
   1811 /*
   1812  * portmod_port_cntmaxsize_get is caller of this function
   1813  */
   1814 int cdmac_cntmaxsize_get(int unit, int port, int *val)
   1815 {
   1816     uint32 rval;
   1817     SOC_INIT_FUNC_DEFS;
   1818 
   1819     _SOC_IF_ERR_EXIT(READ_CDMAC_MIB_COUNTER_CTRLr(unit, port, &rval));
   1820     *val = soc_reg_field_get(unit, CDMAC_MIB_COUNTER_CTRLr, rval, CNTMAXSIZEf);
   1821 
   1822 exit:
   1823     SOC_FUNC_RETURN;
   1824 }
   1825 
   1826 /*
   1827  * This function controls which RSV(Receive statistics vector) event
   1828  * causes a purge event that triggers RXERR to be set for the packet
   1829  * sent by the MAC to the IP. These bits are used to mask RSV[34:16]
   1830  * for CDMAC; bit[18] of MASK maps to bit[34] of RSV, bit[0] of MASK
   1831  * maps to bit[16] of RSV.
   1832  * Enable : Set 0. Go through
   1833  * Disable: Set 1. Purged.
   1834  * bit[18] --> PFC frame detected
   1835  * bit[17] --> Reserved
   1836  * bit[16] --> Reserved
   1837  * bit[15] --> Unicast detected
   1838  * bit[14] --> VLAN tag detected
   1839  * bit[13] --> Unsupported opcode detected
   1840  * bit[12] --> Pause frame received
   1841  * bit[11] --> Control frame received
   1842  * bit[10] --> Promiscuous packet detected
   1843  * bit[ 9] --> Broadcast detected
   1844  * bit[ 8] --> Multicast detected
   1845  * bit[ 7] --> Receive OK
   1846  * bit[ 6] --> Truncated/Frame out of Range
   1847  * bit[ 5] --> Frame length not out of range, but incorrect -
   1848  *             IEEE length check failed
   1849  * bit[ 4] --> CRC error
   1850  * bit[ 3] --> Receive terminate/code error
   1851  * bit[ 2] --> Unsupported DA for pause/PFC packets detected
   1852  * bit[ 1] --> Stack VLAN detected
   1853  * bit[ 0] --> Wrong SA
   1854  */
   1855 int cdmac_rsv_mask_control_set(int unit, int port, uint32 flags, uint32 value)
   1856 {
   1857 
   1858     int i = 0;
   1859     uint32 tmp_mask = CDMAC_RSV_MASK_MIN;
   1860     uint32 rsv_mask = 0;
   1861     SOC_INIT_FUNC_DEFS;
   1862 
   1863     if (flags > CDMAC_RSV_MASK_ALL) {
   1864         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   1865                            (_SOC_MSG("invalid mask %x"), flags));
   1866     }
   1867 
   1868     _SOC_IF_ERR_EXIT(cdmac_rsv_mask_get(unit, port, &rsv_mask));
   1869 
   1870     while(tmp_mask <= CDMAC_RSV_MASK_MAX) {
   1871         if (flags & tmp_mask) {
   1872             /*
   1873              * if value = 1 means Enable, set the mask to 0.
   1874              * if value = 0 means Purge, set the mask to 1.
   1875              */
   1876             if (value) {
   1877                 SHR_BITCLR(&rsv_mask, i);
   1878             } else {
   1879                 SHR_BITSET(&rsv_mask, i);
   1880             }
   1881         }
   1882         tmp_mask = (1 << ++i);
   1883     }
   1884 
   1885     _SOC_IF_ERR_EXIT(cdmac_rsv_mask_set(unit, port, rsv_mask));
   1886 
   1887 exit:
   1888    SOC_FUNC_RETURN;
   1889 }
   1890 
   1891 int cdmac_rsv_mask_control_get(int unit, int port, uint32 flags, uint32 *value)
   1892 {
   1893 
   1894     uint32 rsv_mask;
   1895     SOC_INIT_FUNC_DEFS;
   1896 
   1897     /* Check if only 1 bit is set in flags */
   1898     if ((flags > CDMAC_RSV_MASK_MAX) || ((flags) & (flags - 1))) {
   1899         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   1900                            (_SOC_MSG("invalid mask %x"), flags));
   1901     }
   1902 
   1903     _SOC_IF_ERR_EXIT(cdmac_rsv_mask_get(unit, port, &rsv_mask));
   1904 
   1905     /*
   1906      * if bit in rsv_mask = 0 means Enable, return 1.
   1907      * if bit in rsv_mask = 1 means Purge, return 0.
   1908      */
   1909     *value = (rsv_mask & flags)? 0: 1;
   1910 
   1911 exit:
   1912    SOC_FUNC_RETURN;
   1913 }
   1914 
   1915 int cdmac_rsv_mask_set(int unit, int port, uint32 rsv_mask)
   1916 {
   1917     uint32 rval;
   1918     SOC_INIT_FUNC_DEFS;
   1919 
   1920     if (rsv_mask > CDMAC_RSV_MASK_ALL) {
   1921         _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   1922                            (_SOC_MSG("invalid mask %x"), rsv_mask));
   1923     }
   1924 
   1925     _SOC_IF_ERR_EXIT(READ_CDMAC_RSV_MASKr(unit, port, &rval));
   1926     soc_reg_field_set(unit, CDMAC_RSV_MASKr, &rval, MASKf, rsv_mask);
   1927     _SOC_IF_ERR_EXIT(WRITE_CDMAC_RSV_MASKr(unit, port, rsv_mask));
   1928 
   1929 exit:
   1930    SOC_FUNC_RETURN;
   1931 }
   1932 
   1933 int cdmac_rsv_mask_get(int unit, int port, uint32 *rsv_mask)
   1934 {
   1935     uint32 rval;
   1936     SOC_INIT_FUNC_DEFS;
   1937 
   1938     _SOC_IF_ERR_EXIT(READ_CDMAC_RSV_MASKr(unit, port, &rval));
   1939     *rsv_mask = soc_reg_field_get(unit, CDMAC_RSV_MASKr, rval, MASKf);
   1940 
   1941 exit:
   1942    SOC_FUNC_RETURN;
   1943 }
   1944 
   1945 int cdmac_link_down_sequence_enable_set(int unit, int port, uint32 value)
   1946 {
   1947     uint32 rval;
   1948     SOC_INIT_FUNC_DEFS;
   1949 
   1950     _SOC_IF_ERR_EXIT(READ_CDMAC_CTRLr(unit, port, &rval));
   1951     soc_reg_field_set(unit, CDMAC_CTRLr, &rval, MAC_LINK_DOWN_SEQ_ENf,
   1952                       (value)? 1: 0);
   1953     _SOC_IF_ERR_EXIT(WRITE_CDMAC_CTRLr(unit, port, rval));
   1954 
   1955 exit:
   1956     SOC_FUNC_RETURN;
   1957 }
   1958 
   1959 int cdmac_link_down_sequence_enable_get(int unit, int port, uint32 *value)
   1960 {
   1961     uint32 rval;
   1962     SOC_INIT_FUNC_DEFS;
   1963 
   1964     _SOC_IF_ERR_EXIT(READ_CDMAC_CTRLr(unit, port, &rval));
   1965     *value = soc_reg_field_get(unit, CDMAC_CTRLr, rval,
   1966                                MAC_LINK_DOWN_SEQ_ENf);
   1967 
   1968 exit:
   1969     SOC_FUNC_RETURN;
   1970 }
   1971 
   1972 int cdmac_interrupt_enable_get(int unit, int port, int intr_type, uint32 *value)
   1973 {
   1974     uint32 rval;
   1975     SOC_INIT_FUNC_DEFS;
   1976 
   1977     _SOC_IF_ERR_EXIT(READ_CDMAC_INTR_ENABLEr(unit, port, &rval));
   1978 
   1979     switch(intr_type) {
   1980         case portmodIntrTypeTxPktUnderflow :
   1981             *value = soc_reg_field_get(unit, CDMAC_INTR_ENABLEr, rval, 
   1982                                        TX_PKT_UNDERFLOWf);
   1983             break;
   1984         case portmodIntrTypeTxPktOverflow :
   1985             *value = soc_reg_field_get(unit, CDMAC_INTR_ENABLEr, rval, 
   1986                                        TX_PKT_OVERFLOWf);
   1987             break;
   1988         case portmodIntrTypeTxCdcSingleBitErr :
   1989             *value = soc_reg_field_get(unit, CDMAC_INTR_ENABLEr, rval,
   1990                                        TX_CDC_SINGLE_BIT_ERRf);
   1991             break;
   1992         case portmodIntrTypeTxCdcDoubleBitErr :
   1993             *value = soc_reg_field_get(unit, CDMAC_INTR_ENABLEr, rval,
   1994                                        TX_CDC_DOUBLE_BIT_ERRf);
   1995             break;
   1996         case portmodIntrTypeLocalFaultStatus :
   1997             *value = soc_reg_field_get(unit, CDMAC_INTR_ENABLEr, rval,
   1998                                        LOCAL_FAULT_STATUSf);
   1999             break;
   2000         case portmodIntrTypeRemoteFaultStatus :
   2001             *value = soc_reg_field_get(unit, CDMAC_INTR_ENABLEr, rval,
   2002                                        REMOTE_FAULT_STATUSf);
   2003             break;
   2004         case portmodIntrTypeLinkInterruptionStatus :
   2005             *value = soc_reg_field_get(unit, CDMAC_INTR_ENABLEr, rval,
   2006                                        LINK_INTERRUPTION_STATUSf);
   2007             break;
   2008         case portmodIntrTypeMibMemSingleBitErr :
   2009             *value = soc_reg_field_get(unit, CDMAC_INTR_ENABLEr, rval,
   2010                                        MIB_COUNTER_SINGLE_BIT_ERRf);
   2011             break;
   2012         case portmodIntrTypeMibMemDoubleBitErr :
   2013             *value = soc_reg_field_get(unit, CDMAC_INTR_ENABLEr, rval,
   2014                                        MIB_COUNTER_DOUBLE_BIT_ERRf);
   2015             break;
   2016         case portmodIntrTypeMibMemMultipleBitErr :
   2017             *value = soc_reg_field_get(unit, CDMAC_INTR_ENABLEr, rval,
   2018                                        MIB_COUNTER_MULTIPLE_ERRf);
   2019             break;
   2020         default:
   2021                 _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2022                                   (_SOC_MSG("Invalid interrupt type")));
   2023                 break;
   2024      }
   2025 
   2026 exit:
   2027     SOC_FUNC_RETURN;
   2028 }
   2029 
   2030 int cdmac_interrupt_enable_set(int unit, int port, int intr_type, uint32 value)
   2031 {
   2032     uint32 rval;
   2033     SOC_INIT_FUNC_DEFS;
   2034 
   2035     _SOC_IF_ERR_EXIT(READ_CDMAC_INTR_ENABLEr(unit, port, &rval));
   2036 
   2037     switch(intr_type) {
   2038         case portmodIntrTypeTxPktUnderflow :
   2039             soc_reg_field_set(unit, CDMAC_INTR_ENABLEr, &rval, 
   2040                               TX_PKT_UNDERFLOWf, value);
   2041             break;
   2042         case portmodIntrTypeTxPktOverflow :
   2043             soc_reg_field_set(unit, CDMAC_INTR_ENABLEr, &rval, 
   2044                               TX_PKT_OVERFLOWf, value);
   2045             break;
   2046         case portmodIntrTypeTxCdcSingleBitErr :
   2047             soc_reg_field_set(unit, CDMAC_INTR_ENABLEr, &rval,
   2048                               TX_CDC_SINGLE_BIT_ERRf, value);
   2049             break;
   2050         case portmodIntrTypeTxCdcDoubleBitErr :
   2051             soc_reg_field_set(unit, CDMAC_INTR_ENABLEr, &rval,
   2052                               TX_CDC_DOUBLE_BIT_ERRf, value);
   2053             break;
   2054         case portmodIntrTypeLocalFaultStatus :
   2055             soc_reg_field_set(unit, CDMAC_INTR_ENABLEr, &rval,
   2056                               LOCAL_FAULT_STATUSf, value);
   2057             break;
   2058         case portmodIntrTypeRemoteFaultStatus :
   2059             soc_reg_field_set(unit, CDMAC_INTR_ENABLEr, &rval,
   2060                               REMOTE_FAULT_STATUSf, value);
   2061             break;
   2062         case portmodIntrTypeLinkInterruptionStatus :
   2063             soc_reg_field_set(unit, CDMAC_INTR_ENABLEr, &rval,
   2064                               LINK_INTERRUPTION_STATUSf, value);
   2065             break;
   2066         case portmodIntrTypeMibMemSingleBitErr :
   2067             soc_reg_field_set(unit, CDMAC_INTR_ENABLEr, &rval,
   2068                               MIB_COUNTER_SINGLE_BIT_ERRf, value);
   2069             break;
   2070         case portmodIntrTypeMibMemDoubleBitErr :
   2071             soc_reg_field_set(unit, CDMAC_INTR_ENABLEr, &rval,
   2072                               MIB_COUNTER_DOUBLE_BIT_ERRf, value);
   2073             break;
   2074         case portmodIntrTypeMibMemMultipleBitErr :
   2075             soc_reg_field_set(unit, CDMAC_INTR_ENABLEr, &rval,
   2076                               MIB_COUNTER_MULTIPLE_ERRf, value);
   2077             break;
   2078         default:
   2079                 _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2080                                   (_SOC_MSG("Invalid interrupt type")));
   2081                 break;
   2082      }
   2083 
   2084     _SOC_IF_ERR_EXIT(WRITE_CDMAC_INTR_ENABLEr(unit, port, rval));
   2085 
   2086 exit:
   2087     SOC_FUNC_RETURN;
   2088 }
   2089 
   2090 int cdmac_interrupt_status_get(int unit, int port, int intr_type, uint32 *value)
   2091 {
   2092     uint32 rval;
   2093     uint32 read_ecc_status = FALSE;
   2094     soc_field_t field = INVALIDf;
   2095     SOC_INIT_FUNC_DEFS;
   2096 
   2097     switch(intr_type) {
   2098         case portmodIntrTypeTxPktUnderflow :
   2099             /* Clear on Read Operation */
   2100             _SOC_IF_ERR_EXIT(READ_CDMAC_FIFO_STATUSr(unit, port, &rval));
   2101             *value = soc_reg_field_get(unit, CDMAC_FIFO_STATUSr, rval,
   2102                                        TX_PKT_UNDERFLOWf);
   2103             break;
   2104         case portmodIntrTypeTxPktOverflow :
   2105             /* Clear on Read Operation */
   2106             _SOC_IF_ERR_EXIT(READ_CDMAC_FIFO_STATUSr(unit, port, &rval));
   2107             *value = soc_reg_field_get(unit, CDMAC_FIFO_STATUSr, rval,
   2108                                        TX_PKT_OVERFLOWf);
   2109             break;
   2110         case portmodIntrTypeLocalFaultStatus :
   2111             /* Clear on Read Operation */
   2112             _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_STATUSr(unit, port, &rval));
   2113             *value = soc_reg_field_get(unit, CDMAC_RX_LSS_STATUSr, rval,
   2114                                        LOCAL_FAULT_STATUSf);
   2115             break;
   2116         case portmodIntrTypeRemoteFaultStatus :
   2117             /* Clear on Read Operation */
   2118             _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_STATUSr(unit, port, &rval));
   2119             *value = soc_reg_field_get(unit, CDMAC_RX_LSS_STATUSr, rval,
   2120                                        REMOTE_FAULT_STATUSf);
   2121             break;
   2122         case portmodIntrTypeLinkInterruptionStatus :
   2123             /* Clear on Read Operation */
   2124             _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_STATUSr(unit, port, &rval));
   2125             *value = soc_reg_field_get(unit, CDMAC_RX_LSS_STATUSr, rval,
   2126                                        LINK_INTERRUPTION_STATUSf);
   2127             break;
   2128         case portmodIntrTypeTxCdcSingleBitErr :
   2129             read_ecc_status = TRUE;
   2130             field = TX_CDC_SINGLE_BIT_ERRf;
   2131             break;
   2132         case portmodIntrTypeTxCdcDoubleBitErr :
   2133             read_ecc_status = TRUE;
   2134             field = TX_CDC_DOUBLE_BIT_ERRf;
   2135             break;
   2136         case portmodIntrTypeMibMemSingleBitErr :
   2137             read_ecc_status = TRUE;
   2138             field = MIB_COUNTER_SINGLE_BIT_ERRf;
   2139             break;
   2140         case portmodIntrTypeMibMemDoubleBitErr :
   2141             read_ecc_status = TRUE;
   2142             field = MIB_COUNTER_DOUBLE_BIT_ERRf;
   2143             break;
   2144         case portmodIntrTypeMibMemMultipleBitErr :
   2145             read_ecc_status = TRUE;
   2146             field = MIB_COUNTER_MULTIPLE_ERRf;
   2147             break;
   2148         default:
   2149             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2150                               (_SOC_MSG("Invalid interrupt type")));
   2151             break;
   2152     }
   2153 
   2154     /* Read ECC status register */
   2155     if (read_ecc_status) {
   2156         /* Clear on Read Operation */
   2157         _SOC_IF_ERR_EXIT(READ_CDMAC_ECC_STATUSr(unit, port, &rval));
   2158 
   2159         *value = soc_reg_field_get(unit, CDMAC_ECC_STATUSr, rval, field);
   2160     }
   2161 
   2162 exit:
   2163     SOC_FUNC_RETURN;
   2164 }
   2165 
   2166 int cdmac_interrupts_status_get(int unit, int port, int arr_max_size,
   2167                                 uint32* intr_arr, uint32* size)
   2168 {
   2169     uint32 cnt = 0;
   2170     uint32 rval;
   2171     SOC_INIT_FUNC_DEFS;
   2172 
   2173     /* Clear on Read */
   2174     _SOC_IF_ERR_EXIT(READ_CDMAC_INTR_STATUSr(unit, port, &rval));
   2175 
   2176     /* Read FIFO STATUS - Clear on Read Operation */
   2177     _SOC_IF_ERR_EXIT(READ_CDMAC_FIFO_STATUSr(unit, port, &rval));
   2178 
   2179     if (soc_reg_field_get(unit, CDMAC_FIFO_STATUSr, rval, TX_PKT_UNDERFLOWf)) {
   2180         if (cnt >= arr_max_size) {
   2181             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2182                               (_SOC_MSG("Insufficient Array size")));
   2183         }
   2184         intr_arr[cnt++] = portmodIntrTypeTxPktUnderflow;
   2185     }
   2186 
   2187     if (soc_reg_field_get(unit, CDMAC_FIFO_STATUSr, rval, TX_PKT_OVERFLOWf)) {
   2188         if (cnt >= arr_max_size) {
   2189             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2190                               (_SOC_MSG("Insufficient Array size")));
   2191         }
   2192         intr_arr[cnt++] = portmodIntrTypeTxPktOverflow;
   2193     }
   2194 
   2195     /* Read RX LSS STATUS register - Clear on Read Operation */
   2196     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_STATUSr(unit, port, &rval));
   2197 
   2198     if (soc_reg_field_get(unit, CDMAC_RX_LSS_STATUSr, rval,
   2199                           LOCAL_FAULT_STATUSf)) {
   2200         if (cnt >= arr_max_size) {
   2201             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2202                               (_SOC_MSG("Insufficient Array size")));
   2203         }
   2204         intr_arr[cnt++] = portmodIntrTypeLocalFaultStatus;
   2205     }
   2206 
   2207     if (soc_reg_field_get(unit, CDMAC_RX_LSS_STATUSr, rval,
   2208                           REMOTE_FAULT_STATUSf)) {
   2209         if (cnt >= arr_max_size) {
   2210             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2211                               (_SOC_MSG("Insufficient Array size")));
   2212         }
   2213         intr_arr[cnt++] = portmodIntrTypeRemoteFaultStatus;
   2214     }
   2215 
   2216     if (soc_reg_field_get(unit, CDMAC_RX_LSS_STATUSr, rval,
   2217                           LINK_INTERRUPTION_STATUSf)) {
   2218         if (cnt >= arr_max_size) {
   2219             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2220                               (_SOC_MSG("Insufficient Array size")));
   2221         }
   2222         intr_arr[cnt++] = portmodIntrTypeLinkInterruptionStatus;
   2223     }
   2224 
   2225     /* Read ECC STATUS register - Clear on Read Operation */
   2226     _SOC_IF_ERR_EXIT(READ_CDMAC_ECC_STATUSr(unit, port, &rval));
   2227 
   2228     if (soc_reg_field_get(unit, CDMAC_ECC_STATUSr, rval,
   2229                           TX_CDC_SINGLE_BIT_ERRf)) {
   2230         if (cnt >= arr_max_size) {
   2231             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2232                               (_SOC_MSG("Insufficient Array size")));
   2233         }
   2234         intr_arr[cnt++] = portmodIntrTypeTxCdcSingleBitErr;
   2235     }
   2236 
   2237     if (soc_reg_field_get(unit, CDMAC_ECC_STATUSr, rval,
   2238                           TX_CDC_DOUBLE_BIT_ERRf)) {
   2239         if (cnt >= arr_max_size) {
   2240             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2241                               (_SOC_MSG("Insufficient Array size")));
   2242         }
   2243         intr_arr[cnt++] = portmodIntrTypeTxCdcDoubleBitErr;
   2244     }
   2245 
   2246     if (soc_reg_field_get(unit, CDMAC_ECC_STATUSr, rval,
   2247                           MIB_COUNTER_SINGLE_BIT_ERRf)) {
   2248         if (cnt >= arr_max_size) {
   2249             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2250                               (_SOC_MSG("Insufficient Array size")));
   2251         }
   2252         intr_arr[cnt++] = portmodIntrTypeMibMemSingleBitErr;
   2253     }
   2254 
   2255     if (soc_reg_field_get(unit, CDMAC_ECC_STATUSr, rval,
   2256                           MIB_COUNTER_DOUBLE_BIT_ERRf)) {
   2257         if (cnt >= arr_max_size) {
   2258             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2259                               (_SOC_MSG("Insufficient Array size")));
   2260         }
   2261         intr_arr[cnt++] = portmodIntrTypeMibMemDoubleBitErr;
   2262     }
   2263 
   2264     if (soc_reg_field_get(unit, CDMAC_ECC_STATUSr, rval,
   2265                           MIB_COUNTER_MULTIPLE_ERRf)) {
   2266         if (cnt >= arr_max_size) {
   2267             _SOC_EXIT_WITH_ERR(SOC_E_PARAM,
   2268                               (_SOC_MSG("Insufficient Array size")));
   2269         }
   2270         intr_arr[cnt++] = portmodIntrTypeMibMemMultipleBitErr;
   2271     }
   2272 
   2273     *size = cnt;
   2274 
   2275 exit:
   2276     SOC_FUNC_RETURN;
   2277 }
   2278 
   2279 int cdmac_link_interrupt_ordered_set_enable(int unit, int port, uint32 enable)
   2280 {
   2281     uint32 rval;
   2282     SOC_INIT_FUNC_DEFS;
   2283 
   2284     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_CTRLr(unit, port, &rval));
   2285     if (enable) {
   2286         soc_reg_field_set(unit, CDMAC_RX_LSS_CTRLr, &rval, FORCE_LINK_INTERRUPT_OSf, 1);
   2287         soc_reg_field_set(unit, CDMAC_RX_LSS_CTRLr, &rval, FAULT_SOURCE_FOR_TXf, 2);
   2288     } else {
   2289         soc_reg_field_set(unit, CDMAC_RX_LSS_CTRLr, &rval, FORCE_LINK_INTERRUPT_OSf, 0);
   2290         soc_reg_field_set(unit, CDMAC_RX_LSS_CTRLr, &rval, FAULT_SOURCE_FOR_TXf, 0);
   2291     }
   2292     _SOC_IF_ERR_EXIT(WRITE_CDMAC_RX_LSS_CTRLr(unit, port, rval));
   2293 
   2294 exit:
   2295     SOC_FUNC_RETURN;
   2296 }
   2297 
   2298 int cdmac_link_interrupt_ordered_set_enable_get(int unit, int port, uint32* enable)
   2299 {
   2300     uint32 rval;
   2301     SOC_INIT_FUNC_DEFS;
   2302 
   2303     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_CTRLr(unit, port, &rval));
   2304     *enable = soc_reg_field_get(unit, CDMAC_RX_LSS_CTRLr, rval,  FORCE_LINK_INTERRUPT_OSf);
   2305 
   2306 exit:
   2307     SOC_FUNC_RETURN;
   2308 }
   2309 
   2310 
   2311 int cdmac_link_interruption_live_status_get(int unit, int port, uint32* status)
   2312 {
   2313     uint32 rval;
   2314     SOC_INIT_FUNC_DEFS;
   2315 
   2316     _SOC_IF_ERR_EXIT(READ_CDMAC_RX_LSS_STATUSr(unit, port, &rval));
   2317     /* fault status bits clear on read */
   2318     *status = soc_reg_field_get(unit, CDMAC_RX_LSS_STATUSr, rval,
   2319               LINK_INTERRUPTION_LIVE_STATUSf);
   2320 exit:
   2321     SOC_FUNC_RETURN;
   2322 }
   2323 
   2324 int cdmac_tx_stall_enable_set(int unit, int port, uint32 enable)
   2325 {
   2326     uint32 rval;
   2327     SOC_INIT_FUNC_DEFS;
   2328 
   2329     _SOC_IF_ERR_EXIT(READ_CDMAC_TX_CTRLr(unit, port, &rval));
   2330 
   2331     soc_reg_field_set(unit, CDMAC_TX_CTRLr, &rval, STALL_TXf, enable);
   2332 
   2333     _SOC_IF_ERR_EXIT(WRITE_CDMAC_TX_CTRLr(unit, port, rval));
   2334 
   2335 exit:
   2336     SOC_FUNC_RETURN;
   2337 }
   2338 #undef _ERR_MSG_MODULE_NAME
   2339 
   2340 #endif