X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Fmiiphyutil.c;h=2b0dcf4f2ce1af67d7f02f7100757dad921c85d4;hb=82f4c6ac84b3fe81359f863a476196def9fb35ab;hp=6b2425f660fef240472d50e456e56f7a3869332d;hpb=c609719b8d1b2dca590e0ed499016d041203e403;p=u-boot diff --git a/common/miiphyutil.c b/common/miiphyutil.c index 6b2425f660..2b0dcf4f2c 100644 --- a/common/miiphyutil.c +++ b/common/miiphyutil.c @@ -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 *) ®) != 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 *) ®) != 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, ®) != 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, ®)) { - printf ("PHY speed1 read failed, assuming 10bT\n"); - return (_10BASET); +#if defined(CONFIG_PHY_GIGE) + if (miiphy_read (addr, PHY_1000BTSR, ®)) { + 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, ®)) { + 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, ®)) { + 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, ®)) { - printf ("PHY duplex read failed, assuming half duplex\n"); +#if defined(CONFIG_PHY_GIGE) + if (miiphy_read (addr, PHY_1000BTSR, ®)) { + 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, ®)) { + 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, ®)) { + 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, ®); + if (miiphy_read (addr, PHY_BMSR, ®)) { + 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) */