
On Wed, 5 Dec 2007 00:50:48 +0100 "Joakim Tjernlund" joakim.tjernlund@transmode.se wrote:
-----Original Message----- From: u-boot-users-bounces@lists.sourceforge.net [mailto:u-boot-users-bounces@lists.sourceforge.net] On Behalf Of Kim Phillips Sent: den 4 december 2007 23:04 To: rmcguire@videopresence.com Cc: u-boot-users@lists.sourceforge.net Subject: Re: [U-Boot-Users] CONFIG_MII, 83xx, no MII device?
On Fri, 30 Nov 2007 03:22:37 -0800 "Russell McGuire" rmcguire@videopresence.com wrote:
How can I enable full MII commands? Currently it just says
there are NO MII
devices available, i.e. a blank list will appear.
Hi Kim
Perhaps you can have a look at "MPC83xx Ethernet bug" while you are at it?
<sigh>
Hi Jocke,
not completely tested yet; perhaps you can help? :
Subject: [PATCH] net: reduce boot latency on QE UEC based boards
actually polling for PHY autonegotiation to finish enables us to remove the paranoid (and horrid) 5 second boot prompt latency present on QE based boards.
autonegotiation wait code shamelessly stolen from tsec driver.
Signed-off-by: Kim Phillips kim.phillips@freescale.com --- drivers/qe/uec.c | 17 ++++------------- drivers/qe/uec_phy.c | 49 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 28 deletions(-)
diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c index dc2765b..9bd80e7 100644 --- a/drivers/qe/uec.c +++ b/drivers/qe/uec.c @@ -562,21 +562,12 @@ static void adjust_link(struct eth_device *dev) static void phy_change(struct eth_device *dev) { uec_private_t *uec = (uec_private_t *)dev->priv; - uec_t *uec_regs; - int result = 0; - - uec_regs = uec->uec_regs; - - /* Delay 5s to give the PHY a chance to change the register state */ - udelay(5000000);
/* Update the link, speed, duplex */ - result = uec->mii_info->phyinfo->read_status(uec->mii_info); + uec->mii_info->phyinfo->read_status(uec->mii_info);
/* Adjust the interface according to speed */ - if ((0 == result) || (uec->mii_info->link == 0)) { - adjust_link(dev); - } + adjust_link(dev); }
static int uec_set_mac_address(uec_private_t *uec, u8 *mac_addr) @@ -1103,6 +1094,8 @@ static int uec_init(struct eth_device* dev, bd_t *bd) uec_private_t *uec; int err;
+ phy_change(dev); + uec = (uec_private_t *)dev->priv;
if (uec->the_first_run == 0) { @@ -1271,8 +1264,6 @@ int uec_initialize(int index) return err; }
- phy_change(dev); - return 1; } #endif /* CONFIG_QE */ diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c index ca6faa6..f3382f2 100644 --- a/drivers/qe/uec_phy.c +++ b/drivers/qe/uec_phy.c @@ -270,20 +270,41 @@ static int genmii_update_link (struct uec_mii_info *mii_info) { u16 status;
- /* Do a fake read */ - phy_read (mii_info, PHY_BMSR); - - /* Read link and autonegotiation status */ - status = phy_read (mii_info, PHY_BMSR); - if ((status & PHY_BMSR_LS) == 0) - mii_info->link = 0; - else + /* + * Wait if the link is up, and autonegotiation is in progress + * (ie - we're capable and it's not done) + */ + status = phy_read(mii_info, PHY_BMSR); + if ((status & PHY_BMSR_LS) && (status & PHY_BMSR_AUTN_ABLE) + && !(status & PHY_BMSR_AUTN_COMP)) { + int i = 0; + + puts("Waiting for PHY auto negotiation to complete"); + while (!(status & PHY_BMSR_AUTN_COMP)) { + /* + * Timeout reached ? + */ + if (i > UGETH_AN_TIMEOUT) { + puts(" TIMEOUT !\n"); + mii_info->link = 0; + return 0; + } + + if ((i++ % 1000) == 0) { + putc('.'); + } + udelay(1000); /* 1 ms */ + status = phy_read(mii_info, PHY_BMSR); + } + puts(" done\n"); mii_info->link = 1; - - /* If we are autonegotiating, and not done, - * return an error */ - if (mii_info->autoneg && !(status & PHY_BMSR_AUTN_COMP)) - return -EAGAIN; + udelay(500000); /* another 500 ms (results in faster booting) */ + } else { + if (status & PHY_BMSR_LS) + mii_info->link = 1; + else + mii_info->link = 0; + }
return 0; } @@ -397,8 +418,6 @@ static int dm9161_init (struct uec_mii_info *mii_info) config_genmii_advert (mii_info); /* Start/restart aneg */ genmii_config_aneg (mii_info); - /* Delay to wait the aneg compeleted */ - udelay (3000000);
return 0; }