]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/miiphyutil.c
Preserve PHY_BMCR during a soft reset.
[karo-tx-uboot.git] / common / miiphyutil.c
index 721d109a132177eebe9481e0df63bd0f13dc19ee..13b9c65dc8771668add77b8d88c7317ae4ad1443 100644 (file)
@@ -93,7 +93,13 @@ 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 status read failed\n");
+#endif
+               return (-1);
+       }
+       if (miiphy_write (addr, PHY_BMCR, reg | 0x8000) != 0) {
 #ifdef DEBUG
                puts ("PHY reset failed\n");
 #endif
@@ -147,15 +153,31 @@ int miiphy_speed (unsigned char addr)
        }
 #endif /* CONFIG_PHY_GIGE */
 
-       if (miiphy_read (addr, PHY_ANLPAR, &reg)) {
-               puts ("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);
        }
+
 }
 
 
@@ -182,16 +204,32 @@ int miiphy_duplex (unsigned char addr)
        }
 #endif /* CONFIG_PHY_GIGE */
 
-       if (miiphy_read (addr, PHY_ANLPAR, &reg)) {
+       /* 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