[U-Boot-Users] 83xx, FSL_UEC reducing boot latency, printf causing crash

Russell McGuire rmcguire at videopresence.com
Wed Dec 19 04:58:40 CET 2007


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 at 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;
>  }
> --
> 1.5.2.2






More information about the U-Boot mailing list