]> git.sur5r.net Git - u-boot/blobdiff - common/miiphyutil.c
esd WUH405 and DU405 board updated
[u-boot] / common / miiphyutil.c
index 6b2425f660fef240472d50e456e56f7a3869332d..2b0dcf4f2ce1af67d7f02f7100757dad921c85d4 100644 (file)
@@ -47,19 +47,15 @@ int miiphy_info (unsigned char addr,
                 unsigned char *model, unsigned char *rev)
 {
        unsigned int reg = 0;
+       unsigned short tmp;
 
-       /*
-        * Trick: we are reading two 16 registers into a 32 bit variable
-        * so we do a 16 read into the high order bits of the variable (big
-        * endian, you know), shift it down 16 bits, and the read the rest.
-        */
-       if (miiphy_read (addr, PHY_PHYIDR2, (unsigned short *) &reg) != 0) {
+       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);
        }
-       reg >>= 16;
+       reg = tmp;
 
 #ifdef DEBUG
        printf ("PHY_PHYIDR2 @ 0x%x = 0x%04x\n", addr, reg);
@@ -69,12 +65,13 @@ int miiphy_info (unsigned char addr,
                return (-1);
        }
 
-       if (miiphy_read (addr, PHY_PHYIDR1, (unsigned short *) &reg) != 0) {
+       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);
        }
+       reg |= tmp << 16;
 #ifdef DEBUG
        printf ("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
 #endif
@@ -98,11 +95,13 @@ int miiphy_reset (unsigned char addr)
 
        if (miiphy_write (addr, PHY_BMCR, 0x8000) != 0) {
 #ifdef DEBUG
-               printf ("PHY reset failed\n");
+               puts ("PHY reset failed\n");
 #endif
                return (-1);
        }
-
+#ifdef CONFIG_PHY_RESET_DELAY
+       udelay (CONFIG_PHY_RESET_DELAY);        /* Intel LXT971A needs this */
+#endif
        /*
         * Poll the control register for the reset bit to go to 0 (it is
         * auto-clearing).  This should happen within 0.5 seconds per the
@@ -113,7 +112,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);
                }
@@ -121,7 +120,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);
@@ -136,16 +135,43 @@ int miiphy_speed (unsigned char addr)
 {
        unsigned short reg;
 
-       if (miiphy_read (addr, PHY_ANLPAR, &reg)) {
-               printf ("PHY speed1 read failed, assuming 10bT\n");
-               return (_10BASET);
+#if defined(CONFIG_PHY_GIGE)
+       if (miiphy_read (addr, PHY_1000BTSR, &reg)) {
+               printf ("PHY 1000BT Status read failed\n");
+       } else {
+               if (reg != 0xFFFF) {
+                       if ((reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) !=0) {
+                               return (_1000BASET);
+                       }
+               }
        }
+#endif /* CONFIG_PHY_GIGE */
 
-       if ((reg & PHY_ANLPAR_100) != 0) {
+       /* Check Basic Management Control Register first. */
+       if (miiphy_read (addr, PHY_BMCR, &reg)) {
+               puts ("PHY speed read failed, assuming 10bT\n");
+               return (_10BASET);
+       }
+       /* 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);
        }
+
 }
 
 
@@ -157,16 +183,72 @@ int miiphy_duplex (unsigned char addr)
 {
        unsigned short reg;
 
-       if (miiphy_read (addr, PHY_ANLPAR, &reg)) {
-               printf ("PHY duplex read failed, assuming half duplex\n");
+#if defined(CONFIG_PHY_GIGE)
+       if (miiphy_read (addr, PHY_1000BTSR, &reg)) {
+               printf ("PHY 1000BT Status read failed\n");
+       } else {
+               if ( (reg != 0xFFFF) &&
+                    (reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) ) {
+                       if ((reg & PHY_1000BTSR_1000FD) !=0) {
+                               return (FULL);
+                       } else {
+                               return (HALF);
+                       }
+               }
+       }
+#endif /* CONFIG_PHY_GIGE */
+
+       /* 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
+/*****************************************************************************
+ *
+ * Determine link status
+ */
+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)) {
+               puts ("PHY_BMSR read failed, assuming no link\n");
+               return (0);
+       }
+
+       /* Determine if a link is active */
+       if ((reg & PHY_BMSR_LS) != 0) {
+               return (1);
+       } else {
+               return (0);
+       }
 }
+#endif
 
 #endif /* CONFIG_MII || (CONFIG_COMMANDS & CFG_CMD_MII) */