
Previously, waiting for auto-negotiation would only occur if a valid link had been detected. Problems arose when attempting to use a tsec immediately after bootup but before link was achieved, eg: => dhcp Auto-neg error, defaulting to 10BT/HD eTSEC1: No link. Auto-neg error, defaulting to 10BT/HD eTSEC2: No link. =>
With this patch applied the same operation as above resulted in: => dhcp Waiting for PHY auto negotiation to complete. done Enet starting in 1000BT/FD Speed: 1000, full duplex
Signed-off-by: Peter Tyser ptyser@xes-inc.com ---
drivers/net/tsec.c | 19 +++++++++---------- 1 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index dc90f23..2e30fe9 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -352,8 +352,8 @@ uint mii_cr_init(uint mii_reg, struct tsec_private * priv) return MIIM_CR_INIT; }
-/* Parse the status register for link, and then do - * auto-negotiation +/* + * Wait for auto-negotiation to complete, then determine link */ uint mii_parse_sr(uint mii_reg, struct tsec_private * priv) { @@ -362,8 +362,7 @@ uint mii_parse_sr(uint mii_reg, struct tsec_private * priv) * (ie - we're capable and it's not done) */ mii_reg = read_phy_reg(priv, MIIM_STATUS); - if ((mii_reg & MIIM_STATUS_LINK) && (mii_reg & PHY_BMSR_AUTN_ABLE) - && !(mii_reg & PHY_BMSR_AUTN_COMP)) { + if ((mii_reg & PHY_BMSR_AUTN_ABLE) && !(mii_reg & PHY_BMSR_AUTN_COMP)) { int i = 0;
puts("Waiting for PHY auto negotiation to complete"); @@ -384,15 +383,15 @@ uint mii_parse_sr(uint mii_reg, struct tsec_private * priv) mii_reg = read_phy_reg(priv, MIIM_STATUS); } puts(" done\n"); - priv->link = 1; + + /* Link status bit is latched low, read it again */ + mii_reg = read_phy_reg(priv, MIIM_STATUS); + udelay(500000); /* another 500 ms (results in faster booting) */ - } else { - if (mii_reg & MIIM_STATUS_LINK) - priv->link = 1; - else - priv->link = 0; }
+ priv->link = mii_reg & MIIM_STATUS_LINK ? 1 : 0; + return 0; }