
Kim,
I am getting around to helping test out this reduced latency patch.
Interesting I have found the boot cycle times are MUCH faster, however, is it supposed to continuously restart the auto-negotiation each time a ethernet access is performed? i.e. a new ping, or tftp download? For example if I issue a tftp load three times in a row, the 2nd time it will tear down the link and restart it. The third time it will crash, though I believe this is to do with the below mentioned printf issue.
I am looking into ways to optimize this, are there any updates to the patch before I start modifying things?
Another bug?? Not sure this is Ethernet specific but perhaps U-boot generic. Is that if I add printf() statements throughout the uec code I get total crashes of u-boot, i.e. bad traps that result in a back trace and board resets.
-Russ ________________________________
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);
}
mii_info->link = 1;puts(" done\n");
- /* 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;
}
1.5.2.2