[U-Boot-Users] [PATCH 2/2 (resubmit)] PPC4xx: Add Ethernet 1000BASE-X support for PPC4xx
Larry Johnson
lrj at arlinx.com
Wed Oct 31 17:22:33 CET 2007
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 at 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;
}
More information about the U-Boot
mailing list