]> git.sur5r.net Git - u-boot/blobdiff - common/miiphyutil.c
Merge with /home/wd/git/u-boot/master
[u-boot] / common / miiphyutil.c
index b45ab06157e627ccdddd689a0f5c948afb0bc971..13b9c65dc8771668add77b8d88c7317ae4ad1443 100644 (file)
@@ -51,7 +51,7 @@ int miiphy_info (unsigned char addr,
 
        if (miiphy_read (addr, PHY_PHYIDR2, &tmp) != 0) {
 #ifdef DEBUG
-               printf ("PHY ID register 2 read failed\n");
+               puts ("PHY ID register 2 read failed\n");
 #endif
                return (-1);
        }
@@ -67,7 +67,7 @@ int miiphy_info (unsigned char addr,
 
        if (miiphy_read (addr, PHY_PHYIDR1, &tmp) != 0) {
 #ifdef DEBUG
-               printf ("PHY ID register 1 read failed\n");
+               puts ("PHY ID register 1 read failed\n");
 #endif
                return (-1);
        }
@@ -93,9 +93,15 @@ int miiphy_reset (unsigned char addr)
        unsigned short reg;
        int loop_cnt;
 
-       if (miiphy_write (addr, PHY_BMCR, 0x8000) != 0) {
+       if (miiphy_read (addr, PHY_BMCR, &reg) != 0) {
 #ifdef DEBUG
-               printf ("PHY reset failed\n");
+               printf ("PHY status read failed\n");
+#endif
+               return (-1);
+       }
+       if (miiphy_write (addr, PHY_BMCR, reg | 0x8000) != 0) {
+#ifdef DEBUG
+               puts ("PHY reset failed\n");
 #endif
                return (-1);
        }
@@ -112,7 +118,7 @@ int miiphy_reset (unsigned char addr)
        while (((reg & 0x8000) != 0) && (loop_cnt++ < 1000000)) {
                if (miiphy_read (addr, PHY_BMCR, &reg) != 0) {
 #     ifdef DEBUG
-                       printf ("PHY status read failed\n");
+                       puts ("PHY status read failed\n");
 #     endif
                        return (-1);
                }
@@ -120,7 +126,7 @@ int miiphy_reset (unsigned char addr)
        if ((reg & 0x8000) == 0) {
                return (0);
        } else {
-               printf ("PHY reset timed out\n");
+               puts ("PHY reset timed out\n");
                return (-1);
        }
        return (0);
@@ -135,6 +141,7 @@ int miiphy_speed (unsigned char addr)
 {
        unsigned short reg;
 
+#if defined(CONFIG_PHY_GIGE)
        if (miiphy_read (addr, PHY_1000BTSR, &reg)) {
                printf ("PHY 1000BT Status read failed\n");
        } else {
@@ -144,16 +151,33 @@ int miiphy_speed (unsigned char addr)
                        }
                }
        }
+#endif /* CONFIG_PHY_GIGE */
 
-       if (miiphy_read (addr, PHY_ANLPAR, &reg)) {
-               printf ("PHY speed1 read failed, assuming 10bT\n");
+       /* Check Basic Management Control Register first. */
+       if (miiphy_read (addr, PHY_BMCR, &reg)) {
+               puts ("PHY speed read failed, assuming 10bT\n");
                return (_10BASET);
        }
-       if ((reg & PHY_ANLPAR_100) != 0) {
+       /* Check if auto-negotiation is on. */
+       if ((reg & PHY_BMCR_AUTON) != 0) {
+               /* Get auto-negotiation results. */
+               if (miiphy_read (addr, PHY_ANLPAR, &reg)) {
+                       puts ("PHY AN speed read failed, assuming 10bT\n");
+                       return (_10BASET);
+               }
+               if ((reg & PHY_ANLPAR_100) != 0) {
+                       return (_100BASET);
+               } else {
+                       return (_10BASET);
+               }
+       }
+       /* Get speed from basic control settings. */
+       else if (reg & PHY_BMCR_100MB) {
                return (_100BASET);
        } else {
                return (_10BASET);
        }
+
 }
 
 
@@ -165,7 +189,7 @@ int miiphy_duplex (unsigned char addr)
 {
        unsigned short reg;
 
-
+#if defined(CONFIG_PHY_GIGE)
        if (miiphy_read (addr, PHY_1000BTSR, &reg)) {
                printf ("PHY 1000BT Status read failed\n");
        } else {
@@ -178,17 +202,34 @@ int miiphy_duplex (unsigned char addr)
                        }
                }
        }
+#endif /* CONFIG_PHY_GIGE */
 
-       if (miiphy_read (addr, PHY_ANLPAR, &reg)) {
-               printf ("PHY duplex read failed, assuming half duplex\n");
+       /* Check Basic Management Control Register first. */
+       if (miiphy_read (addr, PHY_BMCR, &reg)) {
+               puts ("PHY duplex read failed, assuming half duplex\n");
                return (HALF);
        }
+       /* Check if auto-negotiation is on. */
+       if ((reg & PHY_BMCR_AUTON) != 0) {
+               /* Get auto-negotiation results. */
+               if (miiphy_read (addr, PHY_ANLPAR, &reg)) {
+                       puts ("PHY AN duplex read failed, assuming half duplex\n");
+                       return (HALF);
+               }
 
-       if ((reg & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) != 0) {
+               if ((reg & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) != 0) {
+                       return (FULL);
+               } else {
+                       return (HALF);
+               }
+       }
+       /* Get speed from basic control settings. */
+       else if (reg & PHY_BMCR_DPLX) {
                return (FULL);
        } else {
                return (HALF);
        }
+
 }
 
 #ifdef CFG_FAULT_ECHO_LINK_DOWN
@@ -200,8 +241,10 @@ int miiphy_link (unsigned char addr)
 {
        unsigned short reg;
 
+       /* dummy read; needed to latch some phys */
+       (void)miiphy_read(addr, PHY_BMSR, &reg);
        if (miiphy_read (addr, PHY_BMSR, &reg)) {
-               printf ("PHY_BMSR read failed, assuming no link\n");
+               puts ("PHY_BMSR read failed, assuming no link\n");
                return (0);
        }