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

phy_unimac.c (26304B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  */
      7 int phy_unimac_not_empty;
      8 #if defined(INCLUDE_FCMAP) || defined(INCLUDE_MACSEC)  || defined(INCLUDE_PLP_IMACSEC)
      9 #include <sal/types.h>
     10 #include <sal/core/alloc.h>
     11 #include <sal/core/spl.h>
     12 #include <sal/core/libc.h>
     13 
     14 #include "phy_unimac.h"
     15 #include "phy_mac_ctrl.h"
     16 
     17 #if !defined(INCLUDE_FCMAP) && !defined(INCLUDE_MACSEC)
     18 extern void sal_usleep(uint32 usec);
     19 #define BMF_SAL_USLEEP sal_usleep
     20 #define BLMI_E_IF_ERROR_RETURN(op) \
     21         do { int __rv__; if ((__rv__ = (op)) < 0) return(__rv__); } while(0)
     22 #else
     23 #include <buser_sal.h>
     24 #include <blmi_err.h>
     25 #endif
     26 #define SPEED_MAPPING(_sp, _spr)    do { \
     27     switch ( _sp ) { \
     28     case 0:    return BLMI_E_NONE;  \
     29     case 10:   _spr = 0; break;     \
     30     case 100:  _spr = 1; break;     \
     31     case 1000: _spr = 2; break;     \
     32     default: return (BLMI_E_CONFIG); }  } while(0)
     33 
     34 /* JIRA BMACSEC-255 specific enhancement */
     35 #define UNIMAC_REG_BKP_IPG_CONFIG_RX_MASK    0x7c
     36 #define UNIMAC_REG_BKP_IPG_CONFIG_RX_SHIFT   2
     37 /***************************************************************
     38  * MACSEC driver functions.
     39  */
     40 /*
     41  * Function:
     42  *    phy_unimac_mac_init
     43  * Purpose:
     44  *    Initialize the MAC
     45  * Parameters:
     46  *    mmc - mac driver control
     47  *    dev_port - Port number
     48  * Notes:
     49  * The MAC will be put in Auto config mode at initilization
     50  * MAX Frame Size = 0x3fff
     51  * IPG = 12
     52  * TX and RX are enabled
     53  */
     54 int
     55 phy_unimac_mac_init(phy_mac_ctrl_t *mmc, int dev_port)
     56 {
     57 
     58     uint32 macsec_ctrl, cmd_cfg;
     59 
     60     /* Set MAC in Auto Config Mode */
     61     BLMI_E_IF_ERROR_RETURN(
     62         phy_unimac_mac_auto_cfg(mmc, dev_port, 1));
     63 
     64     /* Set MAX Frame length to 0x3fff */
     65     BLMI_E_IF_ERROR_RETURN(
     66         phy_unimac_mac_max_frame_set(mmc, dev_port,
     67                                UNIMAC_REG_DEFAULT_MAX_FRAME_SIZE));
     68 
     69     /* Set IPG to 12 */
     70     BLMI_E_IF_ERROR_RETURN(
     71         phy_unimac_mac_update_ipg(mmc, dev_port,
     72                             UNIMAC_REG_DEFAULT_IPG));
     73 
     74     /* Enable TX and RX */
     75     BLMI_E_IF_ERROR_RETURN(
     76         phy_unimac_mac_enable_set(mmc, dev_port, 1));
     77 
     78     /* Enable the TX CRC corrupt in MACSEC Control register */
     79     BLMI_E_IF_ERROR_RETURN(
     80         UNIMAC_READ_MACSEC_CNTL_REG(mmc, dev_port,
     81                                               &macsec_ctrl));
     82     macsec_ctrl &= ~(UNIMAC_REG_TX_CRC_ENABLE_MASK);
     83     macsec_ctrl |= (UNIMAC_REG_TX_CRC_ENABLE <<
     84                 UNIMAC_REG_TX_CRC_ENABLE_SHIFT);
     85     BLMI_E_IF_ERROR_RETURN(
     86         UNIMAC_WRITE_MACSEC_CNTL_REG(mmc, dev_port,macsec_ctrl));
     87 
     88     /* Set terminate CRC in the MAC and Pass MAC control Frames*/
     89     BLMI_E_IF_ERROR_RETURN(
     90         UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_cfg));
     91     cmd_cfg &= ~(UNIMAC_REG_CMD_CFG_CRC_FWD_MASK);
     92     cmd_cfg &= ~(UNIMAC_REG_CMD_CFG_CTL_FRM_ENA_MASK);
     93     cmd_cfg |= (UNIMAC_REG_CMD_CFG_CRC_FWD_DISABLE <<
     94                 UNIMAC_REG_CMD_CFG_CRC_FWD_SHIFT);
     95     cmd_cfg |= (1 << UNIMAC_REG_CMD_CTL_FRM_ENA_SHIFT);
     96     BLMI_E_IF_ERROR_RETURN(
     97         UNIMAC_WRITE_CMD_CFG_REG(mmc, dev_port, cmd_cfg));
     98     /* OVERFLOW check enable  */
     99 #ifdef INCLUDE_PLP_IMACSEC
    100     BLMI_E_IF_ERROR_RETURN(
    101         UNIMAC_READ_UMAC_EEE_CTRL_REG(mmc, dev_port, &cmd_cfg));
    102     cmd_cfg |= UNIMAC_REG_EEE_CTRL_RX_FIFO_CHECK;
    103     BLMI_E_IF_ERROR_RETURN(
    104         UNIMAC_WRITE_UMAC_EEE_CTRL_REG(mmc, dev_port, cmd_cfg));
    105     BLMI_E_IF_ERROR_RETURN(
    106         UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_cfg));
    107     cmd_cfg |= UNIMAC_REG_CMD_CFG_OVERFLOW_EN;
    108     BLMI_E_IF_ERROR_RETURN(
    109         UNIMAC_WRITE_CMD_CFG_REG(mmc, dev_port, cmd_cfg));
    110 #endif
    111 
    112     return BLMI_E_NONE;
    113 }
    114 
    115 /*
    116  * Function:
    117  *    phy_unimac_mac_auto_cfg
    118  * Purpose:
    119  *    This function puts the MAC in auto config if auto_cfg is 1.
    120  * Parameters:
    121  *    mmc - mac driver control
    122  *    dev_port - Port number
    123  *    auto_cfg - Auto configuration flag
    124  *               1 = Auto configuration
    125  *               0 = Forced mode
    126  * Notes:
    127  */
    128 int
    129 phy_unimac_mac_auto_cfg(phy_mac_ctrl_t *mmc, int dev_port, int auto_cfg)
    130 {
    131     uint32 cmd_reg, val;
    132 
    133     val = (auto_cfg) ? 1 : 0;
    134 
    135     BLMI_E_IF_ERROR_RETURN(
    136         UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_reg));
    137     cmd_reg &= ~(UNIMAC_REG_CMD_CFG_ENA_EXA_CONFIG_MASK);
    138     cmd_reg |= (val << UNIMAC_REG_CMD_CFG_ENA_EXA_CONFIG_SHIFT);
    139     BLMI_E_IF_ERROR_RETURN(
    140         UNIMAC_WRITE_CMD_CFG_REG(mmc, dev_port, cmd_reg));
    141 
    142     /* Need to sleep for 400ns (or 256 core clock cycles) */
    143     BMF_SAL_USLEEP(1);
    144 
    145     return BLMI_E_NONE;
    146 }
    147 
    148 /*
    149  */
    150 /*
    151  * Function:
    152  *    phy_unimac_mac_reset
    153  * Purpose:
    154  *    This function puts the MAC in reset if reset is 1 else takes mac
    155  *    out of reset
    156  * Parameters:
    157  *    mmc - mac driver control
    158  *    dev_port - Port number
    159  *    reset    - Reset MAC
    160  *               1 = Put in Reset
    161  *               0 = Take out of reset
    162  * Notes:
    163  */
    164 int
    165 phy_unimac_mac_reset(phy_mac_ctrl_t *mmc, int dev_port, int reset)
    166 {
    167     uint32 cmd_reg, val;
    168 
    169     val = (reset) ? 1 : 0;
    170 
    171     BLMI_E_IF_ERROR_RETURN(
    172         UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_reg));
    173     cmd_reg &= ~(UNIMAC_REG_CMD_CFG_SW_RESET_MASK);
    174     cmd_reg |= (val << UNIMAC_REG_CMD_CFG_SW_RESET_SHIFT);
    175     BLMI_E_IF_ERROR_RETURN(
    176         UNIMAC_WRITE_CMD_CFG_REG(mmc, dev_port, cmd_reg));
    177 
    178     return BLMI_E_NONE;
    179 }
    180 
    181 /*
    182  * Function:
    183  *    phy_unimac_mac_enable_set
    184  * Purpose:
    185  *    Enable/Disable MAC
    186  * Parameters:
    187  *    mmc - mac driver control
    188  *    dev_port - Port number
    189  *    enable   - Enable flag
    190  *               1 = Enable MAC
    191  *               0 = Disable MAC
    192  * Notes:
    193  */
    194 int
    195 phy_unimac_mac_enable_set(phy_mac_ctrl_t *mmc, int dev_port, int enable)
    196 {
    197     uint32 cmd_reg, val;
    198 
    199     val = (enable) ? 1 : 0;
    200     /* Put the mac in reset */
    201     BLMI_E_IF_ERROR_RETURN(
    202     phy_unimac_mac_reset(mmc, dev_port, 1));
    203 
    204     BLMI_E_IF_ERROR_RETURN(
    205         UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_reg));
    206     cmd_reg &= ~(UNIMAC_REG_CMD_CFG_TXEN_MASK);
    207     cmd_reg |= (val << UNIMAC_REG_CMD_CFG_TXEN_SHIFT);
    208     cmd_reg &= ~(UNIMAC_REG_CMD_CFG_RXEN_MASK);
    209     cmd_reg |= (val << UNIMAC_REG_CMD_CFG_RXEN_SHIFT);
    210     BLMI_E_IF_ERROR_RETURN(
    211         UNIMAC_WRITE_CMD_CFG_REG(mmc, dev_port, cmd_reg));
    212 
    213     /* Take mac out of reset */
    214     BLMI_E_IF_ERROR_RETURN(
    215         phy_unimac_mac_reset(mmc, dev_port, 0));
    216 
    217     return BLMI_E_NONE;
    218 }
    219 
    220 /*
    221  * Function:
    222  *    phy_unimac_mac_enable_get
    223  * Purpose:
    224  *    Get the enable status of MAC
    225  * Parameters:
    226  *    mmc - mac driver control
    227  *    dev_port - Port number
    228  *    enable   - (OUT)Enable flag
    229  *               1 = Enable MAC
    230  *               0 = Disable MAC
    231  * Notes:
    232  */
    233 int
    234 phy_unimac_mac_enable_get(phy_mac_ctrl_t *mmc, int dev_port, int *enable)
    235 {
    236     uint32   cmd_reg, val ;
    237 
    238     BLMI_E_IF_ERROR_RETURN(
    239         UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_reg));
    240     val = (cmd_reg & UNIMAC_REG_CMD_CFG_TXEN_MASK) >>
    241                      UNIMAC_REG_CMD_CFG_TXEN_SHIFT;
    242 
    243     *(enable) = (val) ? 1 : 0;
    244 
    245     return BLMI_E_NONE;
    246 }
    247 
    248 /*
    249  * Function:
    250  *    phy_unimac_mac_speed_set
    251  * Purpose:
    252  *    Set Speed of the MAC
    253  * Parameters:
    254  *    mmc - mac driver control
    255  *    dev_port - Port number
    256  *    speed    - 1000 - 1000Mbps
    257  *               100  - 100Mbps
    258  *               10   - 10Mbps
    259  * Notes:
    260  */
    261 int
    262 phy_unimac_mac_speed_set(phy_mac_ctrl_t *mmc, int dev_port, int speed)
    263 {
    264     uint32 cmd_reg;
    265     int      speed_select;
    266 
    267     switch (speed) {
    268     case 0:     /* No change */
    269         return BLMI_E_NONE;
    270     case 10:
    271         speed_select = 0;
    272     break;
    273     case 100:
    274         speed_select = 1;
    275     break;
    276     case 1000:
    277         speed_select = 2;
    278         break;
    279     default:
    280         return (BLMI_E_CONFIG);
    281     }
    282 
    283     BLMI_E_IF_ERROR_RETURN(
    284         phy_unimac_mac_reset(mmc, dev_port, 1));
    285 
    286     BLMI_E_IF_ERROR_RETURN(
    287         UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_reg));
    288 
    289     cmd_reg &= ~(UNIMAC_REG_CMD_CFG_SPEED_MASK);
    290     cmd_reg |= (speed_select << UNIMAC_REG_CMD_CFG_SPEED_SHIFT);
    291 
    292     BLMI_E_IF_ERROR_RETURN(
    293         UNIMAC_WRITE_CMD_CFG_REG(mmc, dev_port, cmd_reg));
    294 
    295     BLMI_E_IF_ERROR_RETURN(
    296         phy_unimac_mac_reset(mmc, dev_port, 0));
    297 
    298     return BLMI_E_NONE;
    299 }
    300 
    301 /*
    302  * Function:
    303  *    phy_unimac_mac_speed_get
    304  * Purpose:
    305  *    Get Speed of the MAC
    306  * Parameters:
    307  *    mmc - mac driver control
    308  *    dev_port - Port number
    309  *    speed    - (OUT) 1000 - 1000Mbps
    310  *                     100  - 100Mbps
    311  *                     10   - 10Mbps
    312  * Notes:
    313  */
    314 int
    315 phy_unimac_mac_speed_get(phy_mac_ctrl_t *mmc, int dev_port, int *speed)
    316 {
    317     int speed_select;
    318     uint32 cmd_reg;
    319 
    320     BLMI_E_IF_ERROR_RETURN(
    321         UNIMAC_READ_MAC_MODE_REG(mmc, dev_port, &cmd_reg));
    322     speed_select = (cmd_reg & UNIMAC_REG_MAC_MODE_SPEED_MASK) >>
    323                    UNIMAC_REG_MAC_MODE_SPEED_SHIFT;
    324 
    325     switch (speed_select) {
    326     case 0:
    327         *speed = 10;
    328     break;
    329     case 1:
    330         *speed = 100;
    331     break;
    332     case 2:
    333         *speed= 1000;
    334         break;
    335     default:
    336         return (BLMI_E_INTERNAL);
    337     }
    338     return BLMI_E_NONE;
    339 }
    340 
    341 
    342 /*
    343  * Function:
    344  *    phy_unimac_mac_duplex_set
    345  * Purpose:
    346  *    Set Duplex of the MAC
    347  * Parameters:
    348  *    mmc - mac driver control
    349  *    dev_port - Port number
    350  *    duplex   - 1 - Full Duplex
    351  *               0 - Half Duplex
    352  * Notes:
    353  */
    354 int
    355 phy_unimac_mac_duplex_set(phy_mac_ctrl_t *mmc, int dev_port, int duplex)
    356 {
    357 
    358     uint32 cmd_reg;
    359     int hd_enable, speed, rv = BLMI_E_NONE;
    360 
    361     hd_enable = (duplex) ? 0 : 1;
    362 
    363     BLMI_E_IF_ERROR_RETURN(
    364         phy_unimac_mac_reset(mmc, dev_port, 1));
    365 
    366     BLMI_E_IF_ERROR_RETURN(
    367         phy_unimac_mac_speed_get(mmc, dev_port, &speed));
    368     if ((speed >= 1000) && (hd_enable == 1)) {
    369         /* Half duplex with Gigabit speed not supported */
    370         rv = BLMI_E_PARAM;
    371         goto error;
    372     }
    373 
    374     BLMI_E_IF_ERROR_RETURN(
    375         UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_reg));
    376     cmd_reg &= ~(UNIMAC_REG_CMD_CFG_DUPLEX_MASK);
    377     cmd_reg |= (hd_enable << UNIMAC_REG_CMD_CFG_DUPLEX_SHIFT);
    378     BLMI_E_IF_ERROR_RETURN(
    379         UNIMAC_WRITE_CMD_CFG_REG(mmc, dev_port, cmd_reg));
    380 
    381 error:
    382     BLMI_E_IF_ERROR_RETURN(
    383         phy_unimac_mac_reset(mmc, dev_port, 0));
    384     return rv;
    385 }
    386 
    387 
    388 /*
    389  * Function:
    390  *    phy_unimac_mac_duplex_get
    391  * Purpose:
    392  *    Get Duplex of the MAC
    393  * Parameters:
    394  *    mmc - mac driver control
    395  *    dev_port - Port number
    396  *    duplex   - (OUT) 0 - Full Duplex
    397  *                     1 - Half Duplex
    398  * Notes:
    399  */
    400 int
    401 phy_unimac_mac_duplex_get(phy_mac_ctrl_t *mmc, int dev_port, int *fd)
    402 {
    403     uint32 cmd_reg;
    404     int      hd_enable;
    405 
    406     BLMI_E_IF_ERROR_RETURN(
    407         UNIMAC_READ_MAC_MODE_REG(mmc, dev_port, &cmd_reg));
    408     hd_enable = (cmd_reg & UNIMAC_REG_MAC_MODE_DUPLEX_MASK) >>
    409                                     UNIMAC_REG_MAC_MODE_DUPLEX_SHIFT;
    410 
    411     *fd = (hd_enable) ? 1 : 0;
    412     return BLMI_E_NONE;
    413 }
    414 
    415 
    416 
    417 /*
    418  * Function:
    419  *    phy_unimac_mac_pause_set
    420  * Purpose:
    421  *    Set pause of the MAC
    422  * Parameters:
    423  *    mmc - mac driver control
    424  *    dev_port - Port number
    425  *    pause    - 1 - Pause enable
    426  *               0 - Pause disable
    427  * Notes:
    428  */
    429 int
    430 phy_unimac_mac_pause_set(phy_mac_ctrl_t *mmc, int dev_port, int pause)
    431 {
    432     uint32 cmd_reg;
    433     int  tx_pause_ignore, rx_pause_ignore;
    434     int  duplex, rv = BLMI_E_NONE;
    435 
    436     if(pause == 1) {
    437         tx_pause_ignore = 0;
    438         rx_pause_ignore = 0;
    439     } else {
    440         tx_pause_ignore = 1;
    441         rx_pause_ignore = 1;
    442     }
    443 
    444     BLMI_E_IF_ERROR_RETURN(
    445         phy_unimac_mac_reset(mmc, dev_port, 1));
    446 
    447     BLMI_E_IF_ERROR_RETURN(
    448         phy_unimac_mac_duplex_get(mmc, dev_port, &duplex));
    449 
    450     /* handling of PAUSE is differnet in Half duplex more */
    451     if(duplex == 1) { /* Full Duplex */
    452         BLMI_E_IF_ERROR_RETURN(
    453             UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_reg));
    454         cmd_reg &= ~(UNIMAC_REG_CMD_CFG_TX_PAUSE_IGNORE_MASK);
    455         cmd_reg &= ~(UNIMAC_REG_CMD_CFG_RX_PAUSE_IGNORE_MASK);
    456         cmd_reg |= (tx_pause_ignore <<
    457                     UNIMAC_REG_CMD_CFG_TX_PAUSE_IGNORE_SHIFT);
    458         cmd_reg |= (rx_pause_ignore <<
    459                     UNIMAC_REG_CMD_CFG_RX_PAUSE_IGNORE_SHIFT);
    460         BLMI_E_IF_ERROR_RETURN(
    461             UNIMAC_WRITE_CMD_CFG_REG(mmc, dev_port, cmd_reg));
    462     } else {
    463         
    464     }
    465 
    466     BLMI_E_IF_ERROR_RETURN(
    467         phy_unimac_mac_reset(mmc, dev_port, 0));
    468     return rv;
    469 }
    470 
    471 
    472 /*
    473  * Function:
    474  *    phy_unimac_mac_update_ipg
    475  * Purpose:
    476  *    Set IPG of the MAC
    477  * Parameters:
    478  *    mmc - mac driver control
    479  *    dev_port - Port number
    480  *    ipg      - IPG value
    481  * Notes:
    482  */
    483 int
    484 phy_unimac_mac_update_ipg(phy_mac_ctrl_t *mmc, int dev_port, int ipg)
    485 {
    486     uint32 ipg_reg;
    487 
    488     if((ipg < 8) || (ipg > 64)) {
    489         return BLMI_E_PARAM;
    490     }
    491 
    492     ipg_reg = ipg;
    493     BLMI_E_IF_ERROR_RETURN(
    494         UNIMAC_WRITE_TX_IPG_REG(mmc, dev_port, ipg_reg));
    495 
    496     return BLMI_E_NONE;
    497 }
    498 
    499 
    500 /*
    501  * Function:
    502  *    phy_unimac_mac_max_frame_set
    503  * Purpose:
    504  *    Set Max frame of the MAC
    505  * Parameters:
    506  *    mmc  - MAC control structure pointer
    507  *    dev_port  - Port number
    508  *    max_frame - Max frame value
    509  * Notes:
    510  */
    511 int
    512 phy_unimac_mac_max_frame_set(phy_mac_ctrl_t *mmc, int dev_port,
    513                            uint32 max_frame)
    514 {
    515     /*
    516      * Maximum Frame size shouldn;t be less 48 and cannot be greater than
    517      * 0x3fff
    518      */
    519     if((max_frame < 48) || (max_frame > 0x3fff)) {
    520         return BLMI_E_PARAM;
    521     }
    522     BLMI_E_IF_ERROR_RETURN(
    523         UNIMAC_WRITE_FRM_LEN_REG(mmc, dev_port, max_frame));
    524 
    525     return BLMI_E_NONE;
    526 }
    527 
    528 /*
    529  * Function:
    530  *    phy_unimac_mac_frame_len_check_enable
    531  * Purpose:
    532  *    Enable the frame length check error mask in RSV vector
    533  *    to signal error to encryption block
    534  * Parameters:
    535  *    mmc  - MAC control structure pointer
    536  *    dev_port  - Port number
    537  *    enable - Enable the error mask
    538  *    1 -  enable
    539  *    0 -  disable
    540  * Notes:
    541  */
    542 int
    543 phy_unimac_mac_frame_len_check_enable(phy_mac_ctrl_t *mmc, int dev_port, int enable)
    544 {
    545     uint32 cmd_reg,rsv_mask;
    546     /*    */
    547     BLMI_E_IF_ERROR_RETURN(
    548         UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_reg));
    549     if(enable){
    550         cmd_reg &= ~UNIMAC_REG_CMD_CFG_CTL_FRM_NO_LGTH_CHECK_MASK;
    551     }else{
    552         cmd_reg |= UNIMAC_REG_CMD_CFG_CTL_FRM_NO_LGTH_CHECK_MASK;
    553     }
    554     BLMI_E_IF_ERROR_RETURN(
    555         UNIMAC_WRITE_CMD_CFG_REG(mmc, dev_port, cmd_reg));
    556     BLMI_E_IF_ERROR_RETURN(
    557         UNIMAC_READ_GPORT_RSV_MASK_REG(mmc, dev_port, &rsv_mask));
    558     if(enable){
    559         rsv_mask |= UNIMAC_REG_GPORT_RSV_FRM_LEN_CHK_MASK;
    560     }else{
    561         rsv_mask &= ~UNIMAC_REG_GPORT_RSV_FRM_LEN_CHK_MASK;
    562     }
    563     BLMI_E_IF_ERROR_RETURN(
    564         UNIMAC_WRITE_GPORT_RSV_MASK_REG(mmc, dev_port, rsv_mask));
    565 
    566     return BLMI_E_NONE;
    567 }
    568 
    569 /*
    570  * Function:
    571  *    phy_unimac_mac_rx_enable_set
    572  * Purpose:
    573  *    Enable/Disable MAC RX
    574  * Parameters:
    575  *    mmc  - MAC control structure pointer
    576  *    dev_port  - Port number
    577  *    enable - Enable the Rx
    578  *    1 -  enable
    579  *    0 -  disable
    580  * Notes:
    581  */
    582 int
    583 phy_unimac_mac_rx_enable_set(phy_mac_ctrl_t *mmc, int dev_port, int enable)
    584 {
    585     uint32 cmd_reg;
    586     BLMI_E_IF_ERROR_RETURN(
    587         UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_reg));
    588     if(enable){
    589         cmd_reg |= UNIMAC_REG_CMD_CFG_RXEN_MASK;
    590     }else{
    591         cmd_reg &= ~UNIMAC_REG_CMD_CFG_RXEN_MASK;
    592     }
    593     BLMI_E_IF_ERROR_RETURN(
    594         UNIMAC_WRITE_CMD_CFG_REG(mmc, dev_port, cmd_reg));
    595     return BLMI_E_NONE;
    596 }
    597 
    598 /*
    599  * Function:
    600  *    phy_unimac_mac_tx_enable_set
    601  * Purpose:
    602  *    Enable/Disable MAC TX
    603  * Parameters:
    604  *    mmc  - MAC control structure pointer
    605  *    dev_port  - Port number
    606  *    enable - Enable the Tx
    607  *    1 -  enable
    608  *    0 -  disable
    609  * Notes:
    610  */
    611 
    612 int
    613 phy_unimac_mac_tx_enable_set(phy_mac_ctrl_t *mmc, int dev_port, int enable)
    614 {
    615     uint32 cmd_reg;
    616     BLMI_E_IF_ERROR_RETURN(
    617         UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_reg));
    618     if(enable){ 
    619         cmd_reg |= UNIMAC_REG_CMD_CFG_TXEN_MASK;
    620     }else{
    621         cmd_reg &= ~UNIMAC_REG_CMD_CFG_TXEN_MASK;
    622     }
    623     BLMI_E_IF_ERROR_RETURN(
    624         UNIMAC_WRITE_CMD_CFG_REG(mmc, dev_port, cmd_reg));
    625     return BLMI_E_NONE;
    626 }
    627 
    628 /*
    629  * Function:
    630  *    phy_unimac_mac_tx_datapath_flush
    631  * Purpose:
    632  *    TX-FIFO flush control enable
    633  * Parameters:
    634  *    mmc  - MAC control structure pointer
    635  *    dev_port  - Port number
    636  *
    637  * Notes: Before calling TX datapath flush user has to disable pause function
    638  *  once TX_FIFO is empty reenable the pause function
    639  */
    640 int
    641 phy_unimac_mac_tx_datapath_flush(phy_mac_ctrl_t *mmc, int dev_port, int enable)
    642 {
    643    uint32 flush_ctrl;
    644    BLMI_E_IF_ERROR_RETURN(
    645       UNIMAC_READ_TX_FLUSH_CTRL_REG(mmc, dev_port, &flush_ctrl));
    646    if(enable){
    647        flush_ctrl |= UNIMAC_REG_TX_FLUSH_CTRL_MASK;
    648    }else{
    649        flush_ctrl &= ~UNIMAC_REG_TX_FLUSH_CTRL_MASK;
    650    }
    651 
    652    BLMI_E_IF_ERROR_RETURN(
    653          UNIMAC_WRITE_TX_FLUSH_CTRL_REG(mmc, dev_port, flush_ctrl));
    654 
    655 
    656     return BLMI_E_NONE;
    657 }
    658 /*
    659  * Function:
    660  *    phy_unimac_mac_max_frame_get
    661  * Purpose:
    662  *    Get Max frame of the MAC
    663  * Parameters:
    664  *    mmc  - MAC control structure pointer
    665  *    dev_port  - Port number
    666  *    max_frame - (OUT) Max frame
    667  * Notes:
    668  */
    669 int
    670 phy_unimac_mac_max_frame_get(phy_mac_ctrl_t *mmc, int dev_port,
    671                            uint32 *max_frame)
    672 {
    673     uint32 frame_len;
    674 
    675     BLMI_E_IF_ERROR_RETURN(
    676         UNIMAC_READ_FRM_LEN_REG(mmc, dev_port, &frame_len));
    677     *max_frame = frame_len & UNIMAC_REG_FRM_LENr_FMR_LEN_MASK;
    678 
    679     return BLMI_E_NONE;
    680 }
    681 
    682 /*
    683  * Function:
    684  *    phy_unimac_mac_pause_frame_fwd_set
    685  * Purpose:
    686  *    Enable/Disable Pause Frame Forward
    687  * Parameters:
    688  *    mmc  - MAC control structure pointer
    689  *    dev_port  - Port number
    690  *    pause_fwd - Pause forward
    691  *                1 - Forward pause
    692  *                0 - Consume PAUSE.
    693  * Notes:
    694  */
    695 int
    696 phy_unimac_mac_pause_frame_fwd_set(phy_mac_ctrl_t *mmc, int dev_port,
    697                              int pause_fwd)
    698 {
    699     int pause;
    700     uint32 cmd_reg;
    701 
    702     if (pause_fwd == 1) {
    703         pause = 1;
    704     } else {
    705         if (pause_fwd == 0) {
    706             pause = 0;
    707         } else {
    708             return BLMI_E_CONFIG;
    709         }
    710     }
    711     BLMI_E_IF_ERROR_RETURN(
    712         UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_reg));
    713     cmd_reg &= ~(UNIMAC_REG_CMD_CFG_PAUSE_FWD_MASK);
    714     cmd_reg |= (pause << UNIMAC_REG_CMD_CFG_PAUSE_FWD_SHIFT);
    715     BLMI_E_IF_ERROR_RETURN(
    716         UNIMAC_WRITE_CMD_CFG_REG(mmc, dev_port, cmd_reg));
    717 
    718     return BLMI_E_NONE;
    719 }
    720 
    721 /*
    722  * Function:
    723  *    phy_unimac_mac_pause_frame_fwd_get
    724  * Purpose:
    725  *    Get the status of Pause Frame Forward
    726  * Parameters:
    727  *    mmc  - MAC control structure pointer
    728  *    dev_port  - Port number
    729  *    pause_fwd - Pause forward
    730  *                1 - Forward pause
    731  *                0 - Consume PAUSE.
    732  * Notes:
    733  */
    734 int
    735 phy_unimac_mac_pause_frame_fwd_get(phy_mac_ctrl_t *mmc, int dev_port,
    736                                int *pause_fwd)
    737 {
    738     uint32 cmd_reg;
    739 
    740     BLMI_E_IF_ERROR_RETURN(
    741             UNIMAC_READ_CMD_CFG_REG(mmc, dev_port, &cmd_reg) );
    742     *pause_fwd = (cmd_reg & UNIMAC_REG_CMD_CFG_PAUSE_FWD_MASK)
    743                          >> UNIMAC_REG_CMD_CFG_PAUSE_FWD_SHIFT;
    744 
    745     return BLMI_E_NONE;
    746 }
    747 
    748 /*
    749  * Function:
    750  *    phy_unimac_mac_hd_flow_cntl_set
    751  * Purpose:
    752  *    Enable/Disable Half-Duplex Flow Control
    753  * Parameters:
    754  *    mmc - mac driver control
    755  *    dev_port - Port number
    756  *    enable   - Enable flag
    757  *               1 = Enable  Half-Duplex Flow Control
    758  *               0 = Disable Half-Duplex Flow Control
    759  * Notes:
    760  */
    761 int
    762 phy_unimac_mac_hd_flow_cntl_set(phy_mac_ctrl_t *mmc, int dev_port, int enable)
    763 {
    764     uint32  cmd_reg, val;
    765 
    766     val = (enable) ? 1 : 0;
    767 
    768     BLMI_E_IF_ERROR_RETURN(
    769             UNIMAC_READ_IPG_HD_BKP_CNTL_REG(mmc, dev_port, &cmd_reg));
    770     cmd_reg &= ~(UNIMAC_REG_BKP_HD_FC_ENA_MASK) |
    771                ~(UNIMAC_REG_BKP_HD_FC_BKOFF_MASK);
    772     cmd_reg |= (val << UNIMAC_REG_BKP_HD_FC_ENA_SHIFT) |
    773                (val << UNIMAC_REG_BKP_HD_FC_BKOFF_SHIFT);
    774     BLMI_E_IF_ERROR_RETURN(
    775             UNIMAC_WRITE_IPG_HD_BKP_CNTL_REG(mmc, dev_port, cmd_reg) );
    776 
    777     return BLMI_E_NONE;
    778 }
    779 
    780 /*
    781  * Function:
    782  *    phy_unimac_mac_hd_flow_cntl_get
    783  * Purpose:
    784  *    Get the enable status of Half-Duplex Flow Control
    785  * Parameters:
    786  *    mmc - mac driver control
    787  *    dev_port - Port number
    788  *    enable   - (OUT)Enable flag
    789  *               1 = Enable  Half-Duplex Flow Control
    790  *               0 = Disable Half-Duplex Flow Control
    791  * Notes:
    792  */
    793 int
    794 phy_unimac_mac_hd_flow_cntl_get(phy_mac_ctrl_t *mmc, int dev_port, int *enable)
    795 {
    796     uint32   cmd_reg;
    797 
    798     BLMI_E_IF_ERROR_RETURN(
    799             UNIMAC_READ_IPG_HD_BKP_CNTL_REG(mmc, dev_port, &cmd_reg) );
    800     *(enable) = (cmd_reg & UNIMAC_REG_BKP_HD_FC_ENA_MASK)
    801                         >> UNIMAC_REG_BKP_HD_FC_ENA_SHIFT;
    802     return BLMI_E_NONE;
    803 }
    804 
    805 
    806 /* Duplex Gateway support :   Line-side MAC = half-duplex  *\
    807 \*                          Switch-side MAC = full-duplex  */
    808 
    809 /*
    810  * Function:
    811  *    _mac_duplex_gateway_set
    812  * Purpose:
    813  *    Config line/switch-side MAC for Duplex Gateway mode
    814  * Notes:
    815  */
    816 static int
    817 _mac_duplex_gateway_set(phy_mac_ctrl_t *mmc, int port,
    818                         int speed, int fullduplex,
    819                         int ipg, int max_frame, int line_side)
    820 {
    821     uint32  cmd_reg;
    822 
    823     /* Put the MAC in reset */
    824     BLMI_E_IF_ERROR_RETURN(
    825         phy_unimac_mac_reset(mmc, port, 1) );
    826 
    827     /* set Max Frame Size and Interpacket Gap */
    828     BLMI_E_IF_ERROR_RETURN(
    829         phy_unimac_mac_max_frame_set(mmc, port, max_frame) );
    830     BLMI_E_IF_ERROR_RETURN(
    831         phy_unimac_mac_update_ipg(mmc, port, ipg) );
    832     /* enable back-pressure in half-duplex mode for the line-side MAC */
    833     BLMI_E_IF_ERROR_RETURN(
    834         phy_unimac_mac_hd_flow_cntl_set(mmc, port,
    835                                     (line_side && (!fullduplex)) ? 1 : 0) );
    836 
    837     /* read the COMMAND_CONFIG register */
    838     BLMI_E_IF_ERROR_RETURN(
    839         UNIMAC_READ_CMD_CFG_REG(mmc, port, &cmd_reg));
    840 
    841     BMACSEC_MAC_REG_FIELD_SET(cmd_reg, speed,
    842                                           UNIMAC_REG_CMD_CFG_SPEED_MASK,
    843                                           UNIMAC_REG_CMD_CFG_SPEED_SHIFT);
    844     BMACSEC_MAC_REG_FIELD_SET(cmd_reg, ((fullduplex) ? 0 : 1),
    845                                           UNIMAC_REG_CMD_CFG_DUPLEX_MASK,
    846                                           UNIMAC_REG_CMD_CFG_DUPLEX_SHIFT);
    847     BMACSEC_MAC_REG_FIELD_SET(cmd_reg, ((line_side) ? 1 : 0),
    848                                           UNIMAC_REG_CMD_CFG_ENA_EXA_CONFIG_MASK,
    849                                           UNIMAC_REG_CMD_CFG_ENA_EXA_CONFIG_SHIFT);
    850 
    851     BMACSEC_MAC_REG_FIELD_SET(cmd_reg, 1, UNIMAC_REG_CMD_CFG_TXEN_MASK,
    852                                           UNIMAC_REG_CMD_CFG_TXEN_SHIFT);
    853     BMACSEC_MAC_REG_FIELD_SET(cmd_reg, 1, UNIMAC_REG_CMD_CFG_RXEN_MASK,
    854                                           UNIMAC_REG_CMD_CFG_RXEN_SHIFT);
    855     BMACSEC_MAC_REG_FIELD_SET(cmd_reg, 1, UNIMAC_REG_CMD_CFG_PROMIS_EN_MASK,
    856                                           UNIMAC_REG_CMD_CFG_PROMIS_EN_SHIFT);
    857     BMACSEC_MAC_REG_FIELD_SET(cmd_reg, 0, UNIMAC_REG_CMD_CFG_CRC_FWD_MASK,
    858                                           UNIMAC_REG_CMD_CFG_CRC_FWD_SHIFT);
    859     BMACSEC_MAC_REG_FIELD_SET(cmd_reg, 0, UNIMAC_REG_CMD_CFG_PAUSE_FWD_MASK,
    860                                           UNIMAC_REG_CMD_CFG_PAUSE_FWD_SHIFT);
    861     BMACSEC_MAC_REG_FIELD_SET(cmd_reg, ((line_side) ? 0 : 1),
    862                                           UNIMAC_REG_CMD_CFG_SW_OVERRIDE_TX_MASK,
    863                                           UNIMAC_REG_CMD_CFG_SW_OVERRIDE_TX_SHIFT);
    864     BMACSEC_MAC_REG_FIELD_SET(cmd_reg, ((line_side) ? 0 : 1),
    865                                           UNIMAC_REG_CMD_CFG_SW_OVERRIDE_RX_MASK,
    866                                           UNIMAC_REG_CMD_CFG_SW_OVERRIDE_RX_SHIFT);
    867 
    868     /* write to COMMAND_CONFIG register */
    869     BLMI_E_IF_ERROR_RETURN(
    870         UNIMAC_WRITE_CMD_CFG_REG(mmc, port, cmd_reg));
    871 
    872     /* JIRA BMACSEC-255 specific enhancement  */
    873     if(!line_side) {
    874         uint32  data;
    875         BLMI_E_IF_ERROR_RETURN(UNIMAC_READ_IPG_HD_BKP_CNTL_REG(mmc, port, &data));
    876         if(speed == 0 || speed== 1) { /* 0 is 10M mode, 1 is 100M mode */
    877            data &= ~(UNIMAC_REG_BKP_IPG_CONFIG_RX_MASK);
    878            data |= 10 << UNIMAC_REG_BKP_IPG_CONFIG_RX_SHIFT;
    879         } else {  /* Otherwise, 1G or above mode */
    880            data &= ~(UNIMAC_REG_BKP_IPG_CONFIG_RX_MASK);
    881            data |= 5 << UNIMAC_REG_BKP_IPG_CONFIG_RX_SHIFT;
    882         }
    883         BLMI_E_IF_ERROR_RETURN(UNIMAC_WRITE_IPG_HD_BKP_CNTL_REG(mmc, port, data));
    884     }
    885 
    886     /* Take MAC out of reset */
    887     BLMI_E_IF_ERROR_RETURN(
    888         phy_unimac_mac_reset(mmc, port, 0));
    889 
    890     return BLMI_E_NONE;
    891 }
    892 
    893 /*
    894  * Function:
    895  *    unimac_mac_duplex_gateway_set
    896  * Purpose:
    897  *    Set Duplex Gateway mode
    898  * Parameters:
    899  *    mmc - mac driver control
    900  *    dgw - duplex gateway control structure
    901  * Notes:
    902  */
    903 int
    904 phy_unimac_mac_duplex_gateway_set(phy_mac_ctrl_t *mmc,
    905                               phy_mac_duplex_gateway_t *dgw)
    906 {
    907     int  speed;
    908     SPEED_MAPPING(dgw->speed, speed);
    909 
    910     /* config line-side MAC */
    911     BLMI_E_IF_ERROR_RETURN(
    912         _mac_duplex_gateway_set(mmc, dgw->lport,
    913                         speed, dgw->duplex, dgw->ipg, dgw->max_frame, 1) );
    914     /* config switch-side MAC, always full-duplex */
    915     BLMI_E_IF_ERROR_RETURN(
    916         _mac_duplex_gateway_set(mmc, dgw->sport,
    917                         speed, 1          , dgw->ipg, dgw->max_frame, 0) );
    918 
    919     return BLMI_E_NONE;
    920 }
    921 
    922 /***************************************************/
    923 /* MAC Driver Functions */
    924 phy_mac_drv_t phy_unimac_drv = {
    925     phy_unimac_mac_init,
    926     phy_unimac_mac_reset,
    927     phy_unimac_mac_auto_cfg,
    928     phy_unimac_mac_enable_set,
    929     phy_unimac_mac_enable_get,
    930     phy_unimac_mac_speed_set,
    931     phy_unimac_mac_speed_get,
    932     phy_unimac_mac_duplex_set,
    933     phy_unimac_mac_duplex_get,
    934     phy_unimac_mac_update_ipg,
    935     phy_unimac_mac_max_frame_set,
    936     phy_unimac_mac_max_frame_get,
    937     phy_unimac_mac_pause_set,
    938     NULL,
    939     phy_unimac_mac_pause_frame_fwd_set,
    940     phy_unimac_mac_pause_frame_fwd_get,
    941     phy_unimac_mac_duplex_gateway_set,
    942     phy_unimac_mac_frame_len_check_enable,
    943     phy_unimac_mac_rx_enable_set,
    944     phy_unimac_mac_tx_enable_set,
    945     phy_unimac_mac_tx_datapath_flush
    946 };
    947 
    948 #endif /* defined(INCLUDE_FCMAP) || defined (INCLUDE_MACSEC) */