[U-Boot-Users] CONFIG_MII, 83xx, no MII device?

All,
Trying to figure out how to enable the MII debugging, query commands in u-boot so I can debug a Gigabit national DP83865 PHY chip on a MPC8360E board.
I have enabled the CONFIG_MII and CONFIG_CMD_II, along with PHY address and CONFIG_PHY_GIGE.
I have 'added' the DP83865 to the list of detected PHY's inside the uec_phy.c file, <copied from the standard MII stuff>.
I am able to boot U-boot and see the device is detected. As well it works up to 100BaseTX. However, I cannot get it to work in 1000BaseT mode. So I KNOW the MII bus is operational and working correctly.
How can I enable full MII commands? Currently it just says there are NO MII devices available, i.e. a blank list will appear.
Is there a registration command that needs to be added to our custom board files? More or less I have cloned the MPC8360E-MDS board files.
-Russ

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.
try this:
diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c index 9bd80e7..7fa4246 100644 --- a/drivers/qe/uec.c +++ b/drivers/qe/uec.c @@ -21,6 +21,7 @@
#include "common.h" #include "net.h" +#include "miiphy.h" #include "malloc.h" #include "asm/errno.h" #include "asm/io.h" @@ -69,6 +70,9 @@ static uec_info_t eth2_uec_info = { }; #endif
+/* needed for the u-boot mii command interface */ +static struct eth_device *eth_devs[2]; + static int uec_mac_enable(uec_private_t *uec, comm_dir_e mode) { uec_t *uec_regs; @@ -1202,6 +1206,50 @@ static int uec_recv(struct eth_device* dev) return 1; }
+/* + * Read a MII PHY register. + * + * Returns: + * 0 on success + */ +static int uec_miiphy_read(char *devname, unsigned char addr, + unsigned char reg, unsigned short *value) +{ + unsigned short ret; + int index; + struct eth_device *dev; + + /* devname is 'FSL UECn', so generate an index from that */ + index = devname[7] - '0'; + dev = eth_devs[index]; + + ret = (unsigned short)uec_read_phy_reg(dev, addr, reg); + *value = ret; + + return 0; +} + +/* + * Write a MII PHY register. + * + * Returns: + * 0 on success + */ +static int uec_miiphy_write(char *devname, unsigned char addr, + unsigned char reg, unsigned short value) +{ + int index; + struct eth_device *dev; + + /* devname is 'FSL UECn', so generate an index from that */ + index = devname[7] - '0'; + dev = eth_devs[index]; + + uec_write_phy_reg(dev, addr, reg, value); + + return 0; +} + int uec_initialize(int index) { struct eth_device *dev; @@ -1252,12 +1300,17 @@ int uec_initialize(int index)
eth_register(dev);
+ eth_devs[index] = dev; + err = uec_startup(uec); if (err) { printf("%s: Cannot configure net device, aborting.",dev->name); return err; }
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) && !defined(BITBANGMII) + miiphy_register(dev->name, uec_miiphy_read, uec_miiphy_write); +#endif err = init_phy(dev); if (err) { printf("%s: Cannot initialize PHY, aborting.\n", dev->name); ---
you might have to
mii device 'FSL UEC1'
first.
I'll submit a proper patch if it works for you.
Kim

-----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?
Jocke

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

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

On Tue, 2007-12-18 at 19:58 -0800, Russell McGuire wrote:
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.
Kim sent me an updated patch after some feedback from me. I did two more updates, one of them removes the AN for each transfer. The printf() crash sounds familiar, perhaps it is gone now?
Patches attached.
The last 2 patches are on top of Kims.
Jocke

On Tue, 2007-12-18 at 19:58 -0800, Russell McGuire wrote:
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 ________________________________
[SNIP]
- 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");
This printout never happens for me, even though AN is restarted.
I am not really sure that AN needs to be restarted on the first access either. An AN restart adds a 2 seconds delay for me that I didn't have before. Maybe it would be enough to check if AN needs to be restarted and only perform an restart if needed?
Jocke

So I have patched up all the files and running with it.
The system boots up great, but any attempt to access the Ethernet after boot causes U-boot to reset. I did some debugging and have found that it is hosing itself over in the drivers/qe/uec.c: phy_change() function.
Calling: uec->mii_info->phyinfo->read_status(uec->mii_info); causes the crash.
I added some debug output to the pointers being used here, are we sure the structures are being initialized prior to usage?
Example Code with output:
static void phy_change(struct eth_device *dev) { uec_private_t *uec = (uec_private_t *)dev->priv;
printf("%s:%d\n", __FUNCTION__, __LINE__); //RWM DEBUG printf("uec = %x08\n", uec); //RWM DEBUG printf("uec->mii_info = %x08\n", uec->mii_info); //RWM DEBUG printf("uec->mii_info->phyinfo = %x08\n", uec->mii_info->phyinfo); //All works up to this point.
/* Update the link, speed, duplex */ uec->mii_info->phyinfo->read_status(uec->mii_info); //This line causes the crash
printf("%s:%d\n", __FUNCTION__, __LINE__); //RWM DEBUG, never gets to here /* Adjust the interface according to speed */ adjust_link(dev); }
Output form this looks like the following:
UBOOT> ping 192.168.1.1 phy_change:586 uec = 1ffa320008 //seems ok, as I am running with 512MB RAM uec->mii_info = 008 //Seems odd uec->mii_info->phyinfo = feffffdf08 //really seems odd Machine check in kernel mode. Caused by (from msr): regs 1ffa0b10 Unknown values in msr NIP: 0000111C XER: 00000000 LR: 1FFD2484 REGS: 1ffa0b10 TRAP: 0200 DAR: 00000000 MSR: 00001000 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 00
GPR00: 1FFD2484 1FFA0C00 00000080 00000000 00000001 00000010 00000001 00000008 GPR08: 00000000 FEFFFFDF 00000000 1FFA09B6 1FFA09B8 8AA7F71E 1FFFC000 3FFC3000 GPR16: 92A3B06C 00000000 00000000 00000000 00000000 00000000 00000000 00000000 GPR24: 1FFA95F0 1FFA31C0 1FFF57B0 1FFED660 1FFA3200 1FFA0F54 1FFFC630 1FFA31C0 Call backtrace: 1FFD2484 1FFD2664 1FFCADBC 1FFC9484 1FFDB7A4 1FFE2B70 1FFE2268 1FFE2478 1FFD5504 1FFE2B70 1FFE2268 1FFE23C4 1FFD47BC 1FFC7CFC 1FFC673C 00086002 machine check Resetting the board.
Any ideas?
-Russ
-----Original Message----- From: Joakim Tjernlund [mailto:joakim.tjernlund@transmode.se] Sent: Wednesday, December 19, 2007 12:07 AM To: rmcguire@videopresence.com Cc: 'Kim Phillips'; u-boot-users@lists.sourceforge.net Subject: Re: 83xx, FSL_UEC reducing boot latency, printf causing crash
On Tue, 2007-12-18 at 19:58 -0800, Russell McGuire wrote:
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 ________________________________
[SNIP]
- 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");
This printout never happens for me, even though AN is restarted.
I am not really sure that AN needs to be restarted on the first access either. An AN restart adds a 2 seconds delay for me that I didn't have before. Maybe it would be enough to check if AN needs to be restarted and only perform an restart if needed?
Jocke

On Wed, 19 Dec 2007 15:36:42 -0800 "Russell McGuire" rmcguire@videopresence.com wrote:
Any ideas?
depends on your toolchain, but try reverting commit 928fe33b24cdf382a8dc8687fed24b1961cdb5d6.
Kim
participants (3)
-
Joakim Tjernlund
-
Kim Phillips
-
Russell McGuire