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

phy54xx.c (23605B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:        phy54xx.c
      8  *
      9  * The PHY drivers in this file mostly use the standard register set and
     10  * are implemented using the phy_fe/ge driver routines, with the
     11  * addition of a few chip-dependent register settings.
     12  *
     13  * If LDR is 1, then the PHY will be reset each time link down is
     14  * detected on copper.  BCM54xx has difficulty obtaining link with
     15  * certain other gigabit PHYs if not reset when link goes down.
     16  */
     17 
     18 #ifdef INCLUDE_PHY_54XX
     19 
     20 #include <sal/types.h>
     21 #include <sal/core/spl.h>
     22 
     23 #include <soc/drv.h>
     24 #include <soc/debug.h>
     25 #include <soc/error.h>
     26 #include <soc/phyreg.h>
     27 
     28 #include <soc/phy.h>
     29 #include <soc/phy/phyctrl.h>
     30 #include <soc/phy/drv.h>
     31 
     32 #include "phyident.h"
     33 #include "phyreg.h"
     34 #include "phynull.h"
     35 #include "phyfege.h"
     36 #include "phy54xx.h"
     37 
     38 #define LDR        1                /* Link Down Reset Workaround */
     39 
     40 #if LDR
     41 
     42 /*
     43  * Function:
     44  *        phy_54xx_reset_war
     45  * Purpose:
     46  *        Helper function for PHY reset workaround
     47  * Parameters:
     48  *        unit - StrataSwitch unit #.
     49  *        port - StrataSwitch port #.
     50  *        config_fn - PHY-specific post-reset initialization callback
     51  * Notes:
     52  *        PHYs in the 54xx family have an errata where after link goes
     53  *        down and then back up, autonegotiation may cycle forever and
     54  *        never finish.  The condition is infrequent but does happen.  The
     55  *        effective workaround is to reset the PHY any time the link goes
     56  *        down.  This routine performs a PHY reset while saving and
     57  *        restoring all the relevent register settings.
     58  * Returns:
     59  *        SOC_E_XXX
     60  */
     61 
     62 STATIC int
     63 phy_54xx_reset_war(int unit, soc_port_t port,
     64                    int (*config_fn)(int unit, soc_port_t port))
     65 {
     66     phy_ctrl_t   *pc;
     67     uint16        mii_ctrl, mii_ana, mii_gb_ctrl;
     68 
     69     pc = EXT_PHY_SW_STATE(unit, port);
     70     /* Save some of the registers */
     71 
     72     SOC_IF_ERROR_RETURN
     73         (READ_PHY54XX_MII_CTRLr(unit, pc, &mii_ctrl));
     74     SOC_IF_ERROR_RETURN
     75         (READ_PHY54XX_MII_ANAr(unit, pc, &mii_ana));
     76     SOC_IF_ERROR_RETURN
     77         (READ_PHY54XX_MII_GB_CTRLr(unit, pc, &mii_gb_ctrl));
     78 
     79     /* Reset PHY */
     80 
     81     SOC_IF_ERROR_RETURN(soc_phy_reset(unit, port));
     82 
     83     /* Perform PHY-specific initial configuration */
     84 
     85     if (config_fn != NULL) {
     86         SOC_IF_ERROR_RETURN(config_fn(unit, port));
     87     }
     88 
     89     /* Restore some of the registers */
     90     SOC_IF_ERROR_RETURN
     91         (WRITE_PHY54XX_MII_CTRLr(unit, pc, mii_ctrl));
     92     SOC_IF_ERROR_RETURN
     93         (WRITE_PHY54XX_MII_ANAr(unit, pc, mii_ana));
     94     SOC_IF_ERROR_RETURN
     95         (WRITE_PHY54XX_MII_GB_CTRLr(unit, pc, mii_gb_ctrl));
     96 
     97     return SOC_E_NONE;
     98 }
     99 
    100 #endif /* LDR */
    101 
    102 STATIC int
    103 _phy_54xx_init(int unit, soc_port_t port)
    104 {
    105     uint16             id0, id1;
    106     phy_ctrl_t       *pc;
    107 
    108     pc = EXT_PHY_SW_STATE(unit, port);
    109 
    110     PHY_FLAGS_SET(unit, port, PHY_FLAGS_COPPER);
    111     PHY_FLAGS_CLR(unit, port, PHY_FLAGS_FIBER);
    112 
    113     SOC_IF_ERROR_RETURN
    114         (READ_PHY54XX_MII_PHY_ID0r(unit, pc, &id0));
    115     SOC_IF_ERROR_RETURN
    116         (READ_PHY54XX_MII_PHY_ID1r(unit, pc, &id1));
    117 
    118     pc->phy_oui   = PHY_OUI(id0, id1);
    119     pc->phy_model = PHY_MODEL(id0, id1);
    120     pc->phy_rev   = PHY_REV(id0, id1);
    121 
    122     return SOC_E_NONE;
    123 }
    124 
    125 /*
    126  * Function:
    127  *        phy_5401_setup
    128  * Purpose:
    129  *        Initialize 5401 registers
    130  * Parameters:
    131  *        unit - StrataSwitch unit #.
    132  *        port - StrataSwitch port #.
    133  * Returns:
    134  *        SOC_E_XXX
    135  */
    136 
    137 STATIC int
    138 phy_5401_setup(int unit, soc_port_t port)
    139 {
    140     phy_ctrl_t *pc;
    141 
    142     pc = EXT_PHY_SW_STATE(unit, port);
    143 
    144     /*
    145      * Disable tap power-mgmt.
    146      * Will need to check revision number for later revisions.
    147      */
    148 
    149     SOC_IF_ERROR_RETURN(phy_reg_ge_write(unit, pc, 0x00, 0x0000, 0x18, 0x0c20));
    150     SOC_IF_ERROR_RETURN(phy_reg_ge_write(unit, pc, 0x00, 0x0012, 0x15, 0x1804));
    151     SOC_IF_ERROR_RETURN(phy_reg_ge_write(unit, pc, 0x00, 0x0013, 0x15, 0x1204));
    152     SOC_IF_ERROR_RETURN(phy_reg_ge_write(unit, pc, 0x00, 0x8006, 0x15, 0x0132));
    153     SOC_IF_ERROR_RETURN(phy_reg_ge_write(unit, pc, 0x00, 0x8006, 0x15, 0x0232));
    154     SOC_IF_ERROR_RETURN(phy_reg_ge_write(unit, pc, 0x00, 0x201f, 0x15, 0x0a20));
    155 
    156     return(SOC_E_NONE);
    157 }
    158 
    159 #if LDR
    160 
    161 /*
    162  * Function:
    163  *        phy_5401_linkdown
    164  * Purpose:
    165  *        Implement PHY reset workaround.
    166  * Parameters:
    167  *        unit - StrataSwitch unit #.
    168  *        port - StrataSwitch port #.
    169  * Returns:
    170  *        SOC_E_XXX
    171  */
    172 
    173 STATIC int
    174 phy_5401_linkdown(int unit, soc_port_t port)
    175 {
    176     return phy_54xx_reset_war(unit, port, phy_5401_setup);
    177 }
    178 
    179 #endif /* LDR */
    180 
    181 /*
    182  * Function:
    183  *        phy_bcm5401_init
    184  * Purpose:
    185  *        Init function for 5401 phy.  Write default registers.
    186  * Parameters:
    187  *        unit - StrataSwitch unit #.
    188  *        port - StrataSwitch port #.
    189  * Returns:
    190  *        SOC_E_XXX
    191  */
    192 
    193 STATIC int
    194 phy_bcm5401_init(int unit, soc_port_t port)
    195 {
    196     SOC_IF_ERROR_RETURN(_phy_54xx_init(unit, port));
    197     SOC_IF_ERROR_RETURN(phy_ge_init(unit, port));
    198     SOC_IF_ERROR_RETURN(phy_5401_setup(unit, port));
    199 
    200     return(SOC_E_NONE);
    201 }
    202 
    203 /*
    204  * Function:
    205  *        phy_5402_setup
    206  * Purpose:
    207  *        Initialize 5402 registers
    208  * Parameters:
    209  *        unit - StrataSwitch unit #.
    210  *        port - StrataSwitch port #.
    211  * Returns:
    212  *        SOC_E_XXX
    213  */
    214 
    215 STATIC int
    216 phy_5402_setup(int unit, soc_port_t port)
    217 {
    218     phy_ctrl_t    *pc;
    219 
    220     pc = EXT_PHY_SW_STATE(unit, port);
    221 
    222     if (port % 2) { /* set power for high port of pair. */
    223         SOC_IF_ERROR_RETURN
    224             (WRITE_PHY54XX_POWER_CTRLr(unit, pc, 0x0212));
    225     }
    226 
    227     /* Magic numbers for 100 speed initialization. */
    228     SOC_IF_ERROR_RETURN(phy_reg_ge_write(unit, pc, 0x00, 0x0000, 0x18, 0x0c20));
    229     SOC_IF_ERROR_RETURN(phy_reg_ge_write(unit, pc, 0x00, 0x0007, 0x15, 0x8107));
    230     SOC_IF_ERROR_RETURN(phy_reg_ge_write(unit, pc, 0x00, 0x0000, 0x18, 0x0420));
    231 
    232     return SOC_E_NONE;
    233 }
    234 
    235 #if LDR
    236 
    237 /*
    238  * Function:
    239  *        phy_5402_linkdown
    240  * Purpose:
    241  *        Implement PHY reset workaround.
    242  * Parameters:
    243  *        unit - StrataSwitch unit #.
    244  *        port - StrataSwitch port #.
    245  * Returns:
    246  *        SOC_E_XXX
    247  */
    248 
    249 STATIC int
    250 phy_5402_linkdown(int unit, soc_port_t port)
    251 {
    252     return phy_54xx_reset_war(unit, port, phy_5402_setup);
    253 }
    254 
    255 #endif /* LDR */
    256 
    257 /*
    258  * Function:
    259  *        phy_5402_init
    260  * Purpose:
    261  *        Init function for 5402 phy.  Write default registers.
    262  * Parameters:
    263  *        unit - StrataSwitch unit #.
    264  *        port - StrataSwitch port #.
    265  * Returns:
    266  *        SOC_E_XXX
    267  */
    268 
    269 STATIC int
    270 phy_5402_init(int unit, soc_port_t port)
    271 {
    272 
    273     SOC_IF_ERROR_RETURN(_phy_54xx_init(unit, port));
    274     SOC_IF_ERROR_RETURN(phy_ge_init(unit, port));
    275     SOC_IF_ERROR_RETURN(phy_5402_setup(unit, port));
    276 
    277     return(SOC_E_NONE);
    278 }
    279 
    280 /*
    281  * Function:
    282  *        phy_5404_setup
    283  * Purpose:
    284  *        Initialize 5404 registers
    285  * Parameters:
    286  *        unit - StrataSwitch unit #.
    287  *        port - StrataSwitch port #.
    288  * Returns:
    289  *        SOC_E_XXX
    290  */
    291 
    292 STATIC int
    293 phy_5404_setup(int unit, soc_port_t port)
    294 {
    295     phy_ctrl_t  *pc;
    296 
    297     pc = EXT_PHY_SW_STATE(unit, port);
    298 
    299     if (!((port + 2) % 4)) { /* set power for first port of quad. */
    300         SOC_IF_ERROR_RETURN
    301             (WRITE_PHY54XX_POWER_CTRLr(unit, pc, 0x0592));
    302     }
    303 
    304     /* led settings */
    305     SOC_IF_ERROR_RETURN
    306         (WRITE_PHY54XX_SPARE_CTRL1r(unit, pc, 0x8820));
    307 
    308     /* Bang autoneg register */
    309     SOC_IF_ERROR_RETURN
    310         (WRITE_PHY54XX_MII_ANAr(unit, pc, 0x05de));
    311 
    312     return SOC_E_NONE;
    313 }
    314 
    315 #if LDR
    316 
    317 /*
    318  * Function:
    319  *        phy_5404_linkdown
    320  * Purpose:
    321  *        Implement PHY reset workaround.
    322  * Parameters:
    323  *        unit - StrataSwitch unit #.
    324  *        port - StrataSwitch port #.
    325  * Returns:
    326  *        SOC_E_XXX
    327  */
    328 
    329 STATIC int
    330 phy_5404_linkdown(int unit, soc_port_t port)
    331 {
    332     return phy_54xx_reset_war(unit, port, phy_5404_setup);
    333 }
    334 
    335 #endif /* LDR */
    336 
    337 /*
    338  * Function:
    339  *        phy_5404_init
    340  * Purpose:
    341  *        Init function for 5404 phy.  Write default registers.
    342  * Parameters:
    343  *        unit - StrataSwitch unit #.
    344  *        port - StrataSwitch port #.
    345  * Returns:
    346  *        SOC_E_XXX
    347  */
    348 
    349 STATIC int
    350 phy_5404_init(int unit, soc_port_t port)
    351 {
    352 
    353     SOC_IF_ERROR_RETURN(_phy_54xx_init(unit, port));
    354     SOC_IF_ERROR_RETURN(phy_ge_init(unit, port));
    355     SOC_IF_ERROR_RETURN(phy_5404_setup(unit, port));
    356 
    357     return(SOC_E_NONE);
    358 }
    359 
    360 /*
    361  * Function:
    362  *        phy_5411_setup
    363  * Purpose:
    364  *        Initialize 5411 registers
    365  * Parameters:
    366  *        unit - StrataSwitch unit #.
    367  *        port - StrataSwitch port #.
    368  * Returns:
    369  *        SOC_E_XXX
    370  */
    371 
    372 STATIC int
    373 phy_5411_setup(int unit, soc_port_t port)
    374 {
    375     phy_ctrl_t *pc;
    376 
    377     pc = EXT_PHY_SW_STATE(unit, port);
    378     /*
    379      * NOTE: the following are provided only because earlier 48-port
    380      * boards left the external loopback input floating by accident.
    381      * Otherwise it is not required.
    382      */
    383 
    384     /* Clear ext loopback */
    385     SOC_IF_ERROR_RETURN
    386         (WRITE_PHY54XX_AUX_CTRLr(unit, pc, 0x0420));
    387 
    388     /* Clear Swap Rx MDIX and TXHalfout */
    389     SOC_IF_ERROR_RETURN
    390         (WRITE_PHY54XX_MISC_TESTr(unit, pc, 0x0004));
    391 
    392     return SOC_E_NONE;
    393 }
    394 
    395 #if LDR
    396 
    397 /*
    398  * Function:
    399  *        phy_5411_linkdown
    400  * Purpose:
    401  *        Implement PHY reset workaround.
    402  * Parameters:
    403  *        unit - StrataSwitch unit #.
    404  *        port - StrataSwitch port #.
    405  * Returns:
    406  *        SOC_E_XXX
    407  */
    408 
    409 STATIC int
    410 phy_5411_linkdown(int unit, soc_port_t port)
    411 {
    412     return phy_54xx_reset_war(unit, port, phy_5411_setup);
    413 }
    414 
    415 #endif /* LDR */
    416 
    417 /*
    418  * Function:
    419  *        phy_5411_init
    420  * Purpose:
    421  *        Init function for 5411 phy.  Write default registers.
    422  * Parameters:
    423  *        unit - StrataSwitch unit #.
    424  *        port - StrataSwitch port #.
    425  * Returns:
    426  *        SOC_E_XXX
    427  */
    428 
    429 STATIC int
    430 phy_5411_init(int unit, soc_port_t port)
    431 {
    432 
    433     SOC_IF_ERROR_RETURN(_phy_54xx_init(unit, port));
    434     SOC_IF_ERROR_RETURN(phy_ge_init(unit, port));
    435     SOC_IF_ERROR_RETURN(phy_5411_setup(unit, port));
    436 
    437     return(SOC_E_NONE);
    438 }
    439 
    440 /*
    441  * Function:
    442  *        phy_5424_setup
    443  * Purpose:
    444  *        Initialize 5424 registers
    445  * Parameters:
    446  *        unit - StrataSwitch unit #.
    447  *        port - StrataSwitch port #.
    448  * Returns:
    449  *        SOC_E_XXX
    450  */
    451 
    452 STATIC int
    453 phy_5424_setup(int unit, soc_port_t port)
    454 {
    455     uint16        tmp;
    456     phy_ctrl_t   *pc;
    457 
    458     pc = EXT_PHY_SW_STATE(unit, port);
    459 
    460     /* Configure Extended Control Register */
    461     SOC_IF_ERROR_RETURN
    462         (READ_PHY54XX_MII_ECRr(unit, pc, &tmp));
    463     tmp |= 0x0020;        /* Enable LEDs to indicate traffic status */
    464     tmp |= 0x0001;        /* Set high FIFO elasticity to support jumbo frames */
    465     SOC_IF_ERROR_RETURN
    466         (WRITE_PHY54XX_MII_ECRr(unit, pc, tmp));
    467 
    468     /* Enable extended packet length (4.5k through 25k) */
    469     SOC_IF_ERROR_RETURN
    470         (MODIFY_PHY54XX_AUX_CTRLr(unit, pc, 0x4000, 0x4000));
    471 
    472     return SOC_E_NONE;
    473 }
    474 
    475 #if LDR
    476 
    477 /*
    478  * Function:
    479  *        phy_5424_linkdown
    480  * Purpose:
    481  *        Implement PHY reset workaround.
    482  * Parameters:
    483  *        unit - StrataSwitch unit #.
    484  *        port - StrataSwitch port #.
    485  * Returns:
    486  *        SOC_E_XXX
    487  */
    488 
    489 STATIC int
    490 phy_5424_linkdown(int unit, soc_port_t port)
    491 {
    492     return phy_54xx_reset_war(unit, port, phy_5424_setup);
    493 }
    494 
    495 #endif /* LDR */
    496 
    497 /*
    498  * Function:
    499  *        phy_5424_init
    500  * Purpose:
    501  *        Init function for 5424/5434 phy.  Write default registers.
    502  * Parameters:
    503  *        unit - StrataSwitch unit #.
    504  *        port - StrataSwitch port #.
    505  * Returns:
    506  *        SOC_E_XXX
    507  */
    508 
    509 STATIC int
    510 phy_5424_init(int unit, soc_port_t port)
    511 {
    512 
    513     SOC_IF_ERROR_RETURN(_phy_54xx_init(unit, port));
    514     SOC_IF_ERROR_RETURN(phy_ge_init(unit, port));
    515     SOC_IF_ERROR_RETURN(phy_5424_setup(unit, port));
    516 
    517     return(SOC_E_NONE);
    518 }
    519 
    520 /*
    521  * Function:
    522  *     phy_54xx_enable_set
    523  * Description:
    524  *     Enable or disable the physical interface
    525  * Parameters:
    526  *     unit   - Device number
    527  *     port   - Port number
    528  *     enable - Boolean, true = enable, false = enable.
    529  * Returns:
    530  *     SOC_E_XXX
    531  */
    532 STATIC int
    533 phy_54xx_enable_set(int unit, soc_port_t port, int enable)
    534 {
    535     int          rv;         /* Return value */
    536     uint16       data;       /* New value to write to PHY register */
    537     phy_ctrl_t *pc;
    538 
    539     pc       = EXT_PHY_SW_STATE(unit, port);
    540     data     = enable ? 0 : MII_ECR_TD; /* Transmitt enable/disable */
    541 
    542     SOC_IF_ERROR_RETURN
    543         (MODIFY_PHY54XX_MII_ECRr(unit, pc, data, MII_ECR_TD));
    544 
    545     rv = phy_fe_ge_enable_set(unit, port, enable);
    546 
    547     return rv;
    548 }
    549 
    550 /*
    551  * Function:
    552  *      phy_54xx_reg_read
    553  * Purpose:
    554  *      Routine to read PHY register 
    555  * Parameters:
    556  *      uint         - BCM unit number
    557  *      pc           - PHY state
    558  *      flags        - Flags which specify the register type
    559  *      phy_reg_addr - Encoded register address
    560  *      phy_data     - (OUT) Value read from PHY register
    561  * Note:
    562  *      This register read function is not thread safe. Higher level
    563  * function that calls this function must obtain a per port lock
    564  * to avoid overriding register page mapping between threads. 
    565  */
    566 STATIC int
    567 phy_54xx_reg_read(int unit, soc_port_t port, uint32 flags,
    568                   uint32 phy_reg_addr, uint32 *phy_data)
    569 {
    570     uint32               reg_flags;
    571     uint16               reg_bank;
    572     uint8                reg_addr;
    573     uint16               data;     /* Temporary holder for phy_data */
    574     phy_ctrl_t           *pc;      /* PHY software state */
    575 
    576     COMPILER_REFERENCE(flags);
    577     EXT_PHY_INIT_CHECK(unit, port);
    578 
    579     pc   = EXT_PHY_SW_STATE(unit, port);
    580 
    581     reg_flags = SOC_PHY_REG_FLAGS(phy_reg_addr);
    582     reg_bank  = SOC_PHY_REG_BANK(phy_reg_addr);
    583     reg_addr  = SOC_PHY_REG_ADDR(phy_reg_addr);
    584 
    585     SOC_IF_ERROR_RETURN
    586         (phy_reg_ge_read(unit, pc, reg_flags, reg_bank, reg_addr, &data));
    587 
    588    *phy_data = data;
    589 
    590     return SOC_E_NONE;
    591 }
    592 
    593 /*
    594  * Function:
    595  *      phy_54xx_reg_write
    596  * Purpose:
    597  *      Routine to write PHY register 
    598  * Parameters:
    599  *      uint         - BCM unit number
    600  *      pc           - PHY state
    601  *      flags        - Flags which specify the register type
    602  *      phy_reg_addr - Encoded register address
    603  *      phy_data     - Value write to PHY register
    604  * Note:
    605  *      This register read function is not thread safe. Higher level
    606  * function that calls this function must obtain a per port lock
    607  * to avoid overriding register page mapping between threads. 
    608  */
    609 STATIC int
    610 phy_54xx_reg_write(int unit, soc_port_t port, uint32 flags,
    611                    uint32 phy_reg_addr, uint32 phy_data)
    612 {
    613     uint32               reg_flags;
    614     uint16               reg_bank;
    615     uint8                reg_addr;
    616     uint16               data;     /* Temporary holder for phy_data */
    617     phy_ctrl_t           *pc;      /* PHY software state */
    618 
    619     COMPILER_REFERENCE(flags);
    620 
    621     EXT_PHY_INIT_CHECK(unit, port);
    622 
    623     pc   = EXT_PHY_SW_STATE(unit, port);
    624     data = (uint16) (phy_data & 0x0000FFFF);
    625 
    626     reg_flags = SOC_PHY_REG_FLAGS(phy_reg_addr);
    627     reg_bank  = SOC_PHY_REG_BANK(phy_reg_addr);
    628     reg_addr  = SOC_PHY_REG_ADDR(phy_reg_addr);
    629 
    630     return phy_reg_ge_write(unit, pc, reg_flags, reg_bank, reg_addr, data);
    631 }   
    632 
    633 /*
    634  * Function:
    635  *      phy_54xx_reg_modify
    636  * Purpose:
    637  *      Routine to write PHY register 
    638  * Parameters:
    639  *      uint         - BCM unit number
    640  *      pc           - PHY state
    641  *      flags        - Flags which specify the register type
    642  *      phy_reg_addr - Encoded register address
    643  *      why_mo_data  - New value for the bits specified in phy_mo_mask 
    644  *      phy_mo_mask  - Bit mask to modify 
    645  * Note:
    646  *      This register read function is not thread safe. Higher level
    647  * function that calls this function must obtain a per port lock
    648  * to avoid overriding register page mapping between threads. 
    649  */
    650 STATIC int
    651 phy_54xx_reg_modify(int unit, soc_port_t port, uint32 flags,
    652                     uint32 phy_reg_addr, uint32 phy_data, uint32 phy_data_mask)
    653 {
    654     uint32               reg_flags;
    655     uint16               reg_bank;
    656     uint8                reg_addr;
    657     uint16               data;     /* Temporary holder for phy_data */
    658     uint16               mask;     /* Temporary holder for phy_data_mask */
    659     phy_ctrl_t           *pc;      /* PHY software state */
    660 
    661     COMPILER_REFERENCE(flags);
    662 
    663     EXT_PHY_INIT_CHECK(unit, port);
    664 
    665     pc   = EXT_PHY_SW_STATE(unit, port);
    666     data = (uint16) (phy_data & 0x0000FFFF);
    667     mask = (uint16) (phy_data_mask & 0x0000FFFF);
    668 
    669     reg_flags = SOC_PHY_REG_FLAGS(phy_reg_addr);
    670     reg_bank  = SOC_PHY_REG_BANK(phy_reg_addr);
    671     reg_addr  = SOC_PHY_REG_ADDR(phy_reg_addr);
    672 
    673     return phy_reg_ge_modify(unit, pc, reg_flags, reg_bank, reg_addr, data, mask);
    674 } 
    675 
    676 /*
    677  * Variable:        phy_5401drv_ge
    678  * Purpose:        Phy driver for 5401.
    679  */
    680 
    681 phy_driver_t phy_5401drv_ge = {
    682     "5401 Gigabit PHY Driver",
    683     phy_bcm5401_init,
    684     phy_fe_ge_reset,
    685     phy_fe_ge_link_get,
    686     phy_fe_ge_enable_set,
    687     phy_fe_ge_enable_get,
    688     phy_fe_ge_duplex_set,
    689     phy_fe_ge_duplex_get,
    690     phy_fe_ge_speed_set,
    691     phy_fe_ge_speed_get,
    692     phy_fe_ge_master_set,
    693     phy_fe_ge_master_get,
    694     phy_fe_ge_an_set,
    695     phy_fe_ge_an_get,
    696     phy_ge_adv_local_set,
    697     phy_ge_adv_local_get,
    698     phy_ge_adv_remote_get,
    699     phy_fe_ge_lb_set,
    700     phy_fe_ge_lb_get,
    701     phy_ge_interface_set,
    702     phy_ge_interface_get,
    703     phy_ge_ability_get,
    704     NULL,                       /* phy_linkup_evt */
    705 #if LDR
    706     phy_5401_linkdown,
    707 #else
    708     NULL,                       /* phy_linkdn_evt */
    709 #endif /* LDR */
    710     phy_null_mdix_set,
    711     phy_null_mdix_get,
    712     phy_null_mdix_status_get,
    713     NULL,                       /* phy_medium_config_set */
    714     NULL,                       /* phy_medium_config_get */ 
    715     phy_fe_ge_medium_get,
    716     NULL,                       /* phy_cable_diag */
    717     NULL,                       /* phy_link_change */
    718     NULL,                       /* phy_control_set */
    719     NULL,                       /* phy_control_get */
    720     phy_54xx_reg_read,
    721     phy_54xx_reg_write, 
    722     phy_54xx_reg_modify,
    723     NULL                        /* phy_notify */
    724 };
    725 
    726 
    727 /*
    728  * Variable:        phy_5402drv_ge
    729  * Purpose:        Phy driver for 5402.
    730  */
    731 
    732 phy_driver_t phy_5402drv_ge = {
    733     "5402 Gigabit PHY Driver",
    734     phy_5402_init,
    735     phy_fe_ge_reset,
    736     phy_fe_ge_link_get,
    737     phy_54xx_enable_set,
    738     phy_fe_ge_enable_get,
    739     phy_fe_ge_duplex_set,
    740     phy_fe_ge_duplex_get,
    741     phy_fe_ge_speed_set,
    742     phy_fe_ge_speed_get,
    743     phy_fe_ge_master_set,
    744     phy_fe_ge_master_get,
    745     phy_fe_ge_an_set,
    746     phy_fe_ge_an_get,
    747     phy_ge_adv_local_set,
    748     phy_ge_adv_local_get,
    749     phy_ge_adv_remote_get,
    750     phy_fe_ge_lb_set,
    751     phy_fe_ge_lb_get,
    752     phy_ge_interface_set,
    753     phy_ge_interface_get,
    754     phy_ge_ability_get,
    755     NULL,                       /* phy_linkup_evt */ 
    756 #if LDR
    757     phy_5402_linkdown,
    758 #else
    759     NULL,                       /* phy_linkdn_evt */
    760 #endif /* LDR */
    761     phy_null_mdix_set,
    762     phy_null_mdix_get,
    763     phy_null_mdix_status_get,
    764     NULL,                       /* phy_medium_config_set */
    765     NULL,                       /* phy_medium_config_get */
    766     phy_fe_ge_medium_get,
    767     NULL,
    768     NULL,                       /* phy_link_change */
    769     NULL,                       /* phy_control_set */
    770     NULL,                       /* phy_control_get */
    771     phy_54xx_reg_read,
    772     phy_54xx_reg_write, 
    773     phy_54xx_reg_modify,
    774     NULL                        /* phy_notify */
    775 };
    776 
    777 /*
    778  * Variable:        phy_5404drv_ge
    779  * Purpose:        Phy driver for 5404.
    780  */
    781 
    782 phy_driver_t phy_5404drv_ge = {
    783     "5404 Gigabit PHY Driver",
    784     phy_5404_init,
    785     phy_fe_ge_reset,
    786     phy_fe_ge_link_get,
    787     phy_54xx_enable_set,
    788     phy_fe_ge_enable_get,
    789     phy_fe_ge_duplex_set,
    790     phy_fe_ge_duplex_get,
    791     phy_fe_ge_speed_set,
    792     phy_fe_ge_speed_get,
    793     phy_fe_ge_master_set,
    794     phy_fe_ge_master_get,
    795     phy_fe_ge_an_set,
    796     phy_fe_ge_an_get,
    797     phy_ge_adv_local_set,
    798     phy_ge_adv_local_get,
    799     phy_ge_adv_remote_get,
    800     phy_fe_ge_lb_set,
    801     phy_fe_ge_lb_get,
    802     phy_ge_interface_set,
    803     phy_ge_interface_get,
    804     phy_ge_ability_get,
    805     NULL,                       /* phy_linkup_evt */
    806 #if LDR
    807     phy_5404_linkdown,
    808 #else
    809     NULL,                       /* phy_linkdn_evt */
    810 #endif /* LDR */
    811     phy_null_mdix_set,
    812     phy_null_mdix_get,
    813     phy_null_mdix_status_get,
    814     NULL,                       /* phy_medium_set */
    815     NULL,                       /* phy_medium_get */
    816     phy_fe_ge_medium_get,
    817     NULL,
    818     NULL,                       /* phy_link_change */
    819     NULL,                       /* phy_control_set */
    820     NULL,                       /* phy_control_get */
    821     phy_54xx_reg_read,
    822     phy_54xx_reg_write, 
    823     phy_54xx_reg_modify,
    824     NULL                        /* phy_notify */
    825 };
    826 
    827 /*
    828  * Variable:        phy_5411drv_ge
    829  * Purpose:        Phy driver for 5411.
    830  */
    831 
    832 phy_driver_t phy_5411drv_ge = {
    833     "5411 Gigabit PHY Driver",
    834     phy_5411_init,
    835     phy_fe_ge_reset,
    836     phy_fe_ge_link_get,
    837     phy_54xx_enable_set,
    838     phy_fe_ge_enable_get,
    839     phy_fe_ge_duplex_set,
    840     phy_fe_ge_duplex_get,
    841     phy_fe_ge_speed_set,
    842     phy_fe_ge_speed_get,
    843     phy_fe_ge_master_set,
    844     phy_fe_ge_master_get,
    845     phy_fe_ge_an_set,
    846     phy_fe_ge_an_get,
    847     phy_ge_adv_local_set,
    848     phy_ge_adv_local_get,
    849     phy_ge_adv_remote_get,
    850     phy_fe_ge_lb_set,
    851     phy_fe_ge_lb_get,
    852     phy_ge_interface_set,
    853     phy_ge_interface_get,
    854     phy_ge_ability_get,
    855     NULL,                        /* phy_linkup_event */
    856 #if LDR
    857     phy_5411_linkdown,
    858 #else
    859     NULL,                        /* phy_linkdn_event */
    860 #endif /* LDR */
    861     phy_null_mdix_set,
    862     phy_null_mdix_get,
    863     phy_null_mdix_status_get,
    864     NULL,                        /* phy_medium_config_set */
    865     NULL,                        /* phy_medium_config_get */
    866     phy_fe_ge_medium_get,
    867     NULL,
    868     NULL,                       /* phy_link_change */
    869     NULL,                       /* phy_control_set */
    870     NULL,                       /* phy_control_get */
    871     phy_54xx_reg_read,
    872     phy_54xx_reg_write, 
    873     phy_54xx_reg_modify,
    874     NULL                        /* phy_notify */
    875 };
    876 
    877 /*
    878  * Variable:        phy_5424drv_ge
    879  * Purpose:        Phy driver for 5424/5434.
    880  */
    881 phy_driver_t phy_5424drv_ge = {
    882     "5424/34 Gigabit PHY Driver",
    883     phy_5424_init,
    884     phy_fe_ge_reset,
    885     phy_fe_ge_link_get,
    886     phy_54xx_enable_set,
    887     phy_fe_ge_enable_get,
    888     phy_fe_ge_duplex_set,
    889     phy_fe_ge_duplex_get,
    890     phy_fe_ge_speed_set,
    891     phy_fe_ge_speed_get,
    892     phy_fe_ge_master_set,
    893     phy_fe_ge_master_get,
    894     phy_fe_ge_an_set,
    895     phy_fe_ge_an_get,
    896     phy_ge_adv_local_set,
    897     phy_ge_adv_local_get,
    898     phy_ge_adv_remote_get,
    899     phy_fe_ge_lb_set,
    900     phy_fe_ge_lb_get,
    901     phy_ge_interface_set,
    902     phy_ge_interface_get,
    903     phy_ge_ability_get,
    904     NULL,                       /* Phy link up event */
    905 #if LDR
    906     phy_5424_linkdown,
    907 #else
    908     NULL,                       /* Phy link down event */
    909 #endif /* LDR */
    910     phy_null_mdix_set,
    911     phy_null_mdix_get,
    912     phy_null_mdix_status_get,
    913     NULL,                       /* Phy config set */
    914     NULL,                       /* Phy config get */
    915     phy_fe_ge_medium_get,
    916     NULL,                       /* Phy medium set */
    917     NULL,                       /* phy_link_change */
    918     NULL,                       /* phy_control_set */
    919     NULL,                       /* phy_control_get */
    920     phy_54xx_reg_read,
    921     phy_54xx_reg_write, 
    922     phy_54xx_reg_modify,
    923     NULL                        /* Phy event notify */
    924 };
    925 
    926 #endif /* INCLUDE_PHY_54XX */
    927 
    928 int _soc_phy_54xx_not_empty;