[U-Boot-Users] [PATCH 2/2 (resubmit)] PPC4xx: Add Ethernet 1000BASE-X support for PPC4xx

This patch adds a new switch: "CONFIG_PHY_DYNAMIC_ANEG". When this symbol is defined, the PHY will advertise it's capabilities for autonegotiation based on the capabilities shown in the PHY's status registers, including 1000BASE-X. When "CONFIG_PHY_DYNAMIC_ANEG" is not defined, the PHY will advertise hard-coded capabilities, as before.
Signed-off-by: Larry Johnson lrj@acm.org ---
cpu/ppc4xx/miiphy.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 80 insertions(+), 5 deletions(-)
diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c index 2fa1b57..4056ca8 100644 --- a/cpu/ppc4xx/miiphy.c +++ b/cpu/ppc4xx/miiphy.c @@ -66,9 +66,82 @@ void miiphy_dump (char *devname, unsigned char addr) /***********************************************************/ int phy_setup_aneg (char *devname, unsigned char addr) { - unsigned short ctl, adv; + u16 bmcr; + +#if defined(CONFIG_PHY_DYNAMIC_ANEG) + /* + * Set up advertisement based on capablilities reported by the PHY. + * This should work for both copper and fiber. + */ + u16 bmsr; +#if defined(CONFIG_PHY_GIGE) + u16 exsr = 0x0000; +#endif + + miiphy_read (devname, addr, PHY_BMSR, &bmsr); + +#if defined(CONFIG_PHY_GIGE) + if (bmsr & PHY_BMSR_EXT_STAT) { + miiphy_read (devname, addr, PHY_EXSR, &exsr); + } + + if (exsr & (PHY_EXSR_1000XF | PHY_EXSR_1000XH)) { + /* 1000BASE-X */ + u16 anar = 0x0000; + + if (exsr & PHY_EXSR_1000XF) { + anar |= PHY_X_ANLPAR_FD; + } + if (exsr & PHY_EXSR_1000XH) { + anar |= PHY_X_ANLPAR_HD; + } + miiphy_write (devname, addr, PHY_ANAR, anar); + } else +#endif + { + u16 anar, btcr; + + miiphy_read (devname, addr, PHY_ANAR, &anar); + anar &= ~(0x5000 | PHY_ANLPAR_T4 | PHY_ANLPAR_TXFD | + PHY_ANLPAR_TX | PHY_ANLPAR_10FD | PHY_ANLPAR_10); + + miiphy_read (devname, addr, PHY_1000BTCR, &btcr); + btcr &= ~(0x00FF | PHY_1000BTCR_1000FD | PHY_1000BTCR_1000HD); + + if (bmsr & PHY_BMSR_100T4) { + anar |= PHY_ANLPAR_T4; + } + if (bmsr & PHY_BMSR_100TXF) { + anar |= PHY_ANLPAR_TXFD; + } + if (bmsr & PHY_BMSR_100TXH) { + anar |= PHY_ANLPAR_TX; + } + if (bmsr & PHY_BMSR_10TF) { + anar |= PHY_ANLPAR_10FD; + } + if (bmsr & PHY_BMSR_10TH) { + anar |= PHY_ANLPAR_10; + } + miiphy_write (devname, addr, PHY_ANAR, anar); + +#if defined(CONFIG_PHY_GIGE) + if (exsr & PHY_EXSR_1000TF) { + btcr |= PHY_1000BTCR_1000FD; + } + if (exsr & PHY_EXSR_1000TH) { + btcr |= PHY_1000BTCR_1000HD; + } + miiphy_write (devname, addr, PHY_1000BTCR, btcr); +#endif + } + +#else /* defined(CONFIG_PHY_DYNAMIC_ANEG) */ + /* + * Set up standard advertisement + */ + u16 adv;
- /* Setup standard advertise */ miiphy_read (devname, addr, PHY_ANAR, &adv); adv |= (PHY_ANLPAR_ACK | PHY_ANLPAR_RF | PHY_ANLPAR_T4 | PHY_ANLPAR_TXFD | PHY_ANLPAR_TX | PHY_ANLPAR_10FD | @@ -79,10 +152,12 @@ int phy_setup_aneg (char *devname, unsigned char addr) adv |= (0x0300); miiphy_write (devname, addr, PHY_1000BTCR, adv);
+#endif /* defined(CONFIG_PHY_DYNAMIC_ANEG) */ + /* Start/Restart aneg */ - miiphy_read (devname, addr, PHY_BMCR, &ctl); - ctl |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); - miiphy_write (devname, addr, PHY_BMCR, ctl); + miiphy_read (devname, addr, PHY_BMCR, &bmcr); + bmcr |= (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); + miiphy_write (devname, addr, PHY_BMCR, bmcr);
return 0; }
participants (1)
-
Larry Johnson