* [PATCH] 44x ethernet MDIO access @ 2004-08-05 19:01 Ralph Siemsen 2004-08-05 20:05 ` Ralph Siemsen 2004-08-05 21:23 ` Matt Porter 0 siblings, 2 replies; 6+ messages in thread From: Ralph Siemsen @ 2004-08-05 19:01 UTC (permalink / raw) To: Linux PPC Dev, Matt Porter [-- Attachment #1: Type: text/plain, Size: 713 bytes --] There is a small bug in the emac_phy_write() routine defined in drivers/net/ibm_emac/ibm_emac_core.c (present in latest 2.6.8-rc3). At the end of the function, check is done for phy error; however as written this will always be false, because "stacr" contains the value _written_ to the hardware, rather than the value read back from hardware. Simple on-line fix attached. In a related issue, both the PHY read and write functions use a fixed time delay (MDIO_DELAY = 50) presently... it seems I need a longer value on my hardware, and having such hardcoded values is trouble anyways... I suggest we change the code to poll for completion, with a short delay and an upper limit on the number of loops. =Ralph [-- Attachment #2: mdio_write.patch --] [-- Type: text/plain, Size: 500 bytes --] Allow proper detection of phy write error. --- linux-2.6.8-rc3/drivers/net/ibm_emac/ibm_emac_core.c.orig 2004-08-05 14:54:22.000000000 -0400 +++ linux-2.6.8-rc3/drivers/net/ibm_emac/ibm_emac_core.c 2004-08-05 14:54:56.000000000 -0400 @@ -453,7 +453,7 @@ udelay(MDIO_DELAY); - if ((in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) + if (((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name); /* Check for a write error */ ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] 44x ethernet MDIO access 2004-08-05 19:01 [PATCH] 44x ethernet MDIO access Ralph Siemsen @ 2004-08-05 20:05 ` Ralph Siemsen 2004-08-05 21:34 ` Matt Porter 2004-08-06 12:12 ` Geert Uytterhoeven 2004-08-05 21:23 ` Matt Porter 1 sibling, 2 replies; 6+ messages in thread From: Ralph Siemsen @ 2004-08-05 20:05 UTC (permalink / raw) To: Linux PPC Dev; +Cc: Matt Porter [-- Attachment #1: Type: text/plain, Size: 1236 bytes --] Ralph Siemsen wrote: > In a related issue, both the PHY read and write functions use a fixed > time delay (MDIO_DELAY = 50) presently... it seems I need a longer value > on my hardware, and having such hardcoded values is trouble anyways... I > suggest we change the code to poll for completion, with a short delay > and an upper limit on the number of loops. I've just checked the hardware, it seems that the MDIO clock is driven at EPB clock divided by 10. So on the IBM eval board its 7.6MHz. Each MDIO transfer involves moving 64 bits of data. So that means just the data transfer (never mind any processing in the PHY) takes 8.4us. The important part to note is that EPB could vary over a considerable range, so the time needed for MDIO is potentially longer than the 50us currently used in the code. Attached is a patch that "works for me" - turns the long udelay() into a polling loop with short little delays instead. This allows MDIO_DELAY to be increased to a larger value (say 150) without slowing down most systems. Also I can be used to measure just how long the transfers actually take. If MDIO_DEBUG is enabled then you'll see how many "loops" were needed... on the Ocotea board i get values around 25. -Ralph [-- Attachment #2: mdio_loop.patch --] [-- Type: text/plain, Size: 1667 bytes --] Change MDIO read/write to poll for completion rather than waiting an arbitrary length of time. Note this changes the semantics of the MDIO_DELAY definition - it is now a maximal loop count, rather than a time delay in microseconds. --- linux-2.6.8-rc3/drivers/net/ibm_emac/ibm_emac_core.c 2004-08-05 14:54:56.000000000 -0400 +++ linux-2.6-devel/drivers/net/ibm_emac/ibm_emac_core.c 2004-08-05 15:08:50.000000000 -0400 @@ -367,6 +371,7 @@ int emac_phy_read(struct net_device *dev, int mii_id, int reg) { + int count; uint32_t stacr; struct ocp_enet_private *fep = dev->priv; emac_t *emacp = fep->emacp; @@ -398,8 +403,11 @@ out_be32(&emacp->em0stacr, stacr); - udelay(MDIO_DELAY); - stacr = in_be32(&emacp->em0stacr); + count = 0; + while ((((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) + && (count++ < MDIO_DELAY)) + udelay(1); + MDIO_DEBUG((" (count was %d)\n", count)); if ((stacr & EMAC_STACR_OC) == 0) { printk(KERN_WARNING "%s: PHY read timeout #2!\n", dev->name); @@ -419,6 +427,7 @@ void emac_phy_write(struct net_device *dev, int mii_id, int reg, int data) { + int count; uint32_t stacr; struct ocp_enet_private *fep = dev->priv; emac_t *emacp = fep->emacp; @@ -451,9 +460,13 @@ out_be32(&emacp->em0stacr, stacr); - udelay(MDIO_DELAY); + count = 0; + while (((stacr = in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) + && (count++ < 5000)) + udelay(1); + MDIO_DEBUG((" (count was %d)\n", count)); - if (((stacr = in_be32(&emacp->em0stacr)) & EMAC_STACR_OC) == 0) + if ((stacr & EMAC_STACR_OC) == 0) printk(KERN_WARNING "%s: PHY write timeout #2!\n", dev->name); /* Check for a write error */ ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] 44x ethernet MDIO access 2004-08-05 20:05 ` Ralph Siemsen @ 2004-08-05 21:34 ` Matt Porter 2004-08-06 12:12 ` Geert Uytterhoeven 1 sibling, 0 replies; 6+ messages in thread From: Matt Porter @ 2004-08-05 21:34 UTC (permalink / raw) To: Ralph Siemsen; +Cc: Linux PPC Dev, Matt Porter On Thu, Aug 05, 2004 at 04:05:41PM -0400, Ralph Siemsen wrote: > Ralph Siemsen wrote: > > In a related issue, both the PHY read and write functions use a fixed > > time delay (MDIO_DELAY = 50) presently... it seems I need a longer value > > on my hardware, and having such hardcoded values is trouble anyways... I > > suggest we change the code to poll for completion, with a short delay > > and an upper limit on the number of loops. > > I've just checked the hardware, it seems that the MDIO clock is driven > at EPB clock divided by 10. So on the IBM eval board its 7.6MHz. Each > MDIO transfer involves moving 64 bits of data. So that means just the > data transfer (never mind any processing in the PHY) takes 8.4us. > > The important part to note is that EPB could vary over a considerable > range, so the time needed for MDIO is potentially longer than the 50us > currently used in the code. > > Attached is a patch that "works for me" - turns the long udelay() into a > polling loop with short little delays instead. This allows MDIO_DELAY > to be increased to a larger value (say 150) without slowing down most > systems. > > Also I can be used to measure just how long the transfers actually take. > If MDIO_DEBUG is enabled then you'll see how many "loops" were > needed... on the Ocotea board i get values around 25. > > -Ralph Applied (with minor mods). Ralph, can you take a look at http://kerneltrap.org/node/view/3180 and sign off your future patches accordingly? Thanks, Matt ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] 44x ethernet MDIO access 2004-08-05 20:05 ` Ralph Siemsen 2004-08-05 21:34 ` Matt Porter @ 2004-08-06 12:12 ` Geert Uytterhoeven 2004-08-06 13:04 ` Ralph Siemsen 1 sibling, 1 reply; 6+ messages in thread From: Geert Uytterhoeven @ 2004-08-06 12:12 UTC (permalink / raw) To: Ralph Siemsen; +Cc: Linux PPC Dev, Matt Porter On Thu, 5 Aug 2004, Ralph Siemsen wrote: > Attached is a patch that "works for me" - turns the long udelay() into a > polling loop with short little delays instead. This allows MDIO_DELAY > to be increased to a larger value (say 150) without slowing down most > systems. > @@ -451,9 +460,13 @@ > > out_be32(&emacp->em0stacr, stacr); > > - udelay(MDIO_DELAY); > + count = 0; > + while (((stacr = in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) > + && (count++ < 5000)) ^^^^ MDIO_DELAY? And perhaps you want to create a (possibly inlined) function just for this loop? Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] 44x ethernet MDIO access 2004-08-06 12:12 ` Geert Uytterhoeven @ 2004-08-06 13:04 ` Ralph Siemsen 0 siblings, 0 replies; 6+ messages in thread From: Ralph Siemsen @ 2004-08-06 13:04 UTC (permalink / raw) To: Geert Uytterhoeven; +Cc: Linux PPC Dev, Matt Porter Geert Uytterhoeven wrote: >>- udelay(MDIO_DELAY); >>+ count = 0; >>+ while (((stacr = in_be32(&emacp->em0stacr) & EMAC_STACR_OC) == 0) >>+ && (count++ < 5000)) > > ^^^^ > MDIO_DELAY? > > And perhaps you want to create a (possibly inlined) function just for this > loop? Good catch - yes, should be MDIO_DELAY not 5000. I had found that 50 was not enough so I had upped it in my testing - forgot to change it back :( I'd also suggest the default MDIO_DELAY be increased from its present value of 50 to perhaps 100 or 150... Does anyone know what the slowest possible EPB clock speed is? -R ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] 44x ethernet MDIO access 2004-08-05 19:01 [PATCH] 44x ethernet MDIO access Ralph Siemsen 2004-08-05 20:05 ` Ralph Siemsen @ 2004-08-05 21:23 ` Matt Porter 1 sibling, 0 replies; 6+ messages in thread From: Matt Porter @ 2004-08-05 21:23 UTC (permalink / raw) To: Ralph Siemsen; +Cc: Linux PPC Dev, Matt Porter On Thu, Aug 05, 2004 at 03:01:39PM -0400, Ralph Siemsen wrote: > There is a small bug in the emac_phy_write() routine defined in > drivers/net/ibm_emac/ibm_emac_core.c (present in latest 2.6.8-rc3). At > the end of the function, check is done for phy error; however as written > this will always be false, because "stacr" contains the value _written_ > to the hardware, rather than the value read back from hardware. > > Simple on-line fix attached. > > In a related issue, both the PHY read and write functions use a fixed > time delay (MDIO_DELAY = 50) presently... it seems I need a longer value > on my hardware, and having such hardcoded values is trouble anyways... I > suggest we change the code to poll for completion, with a short delay > and an upper limit on the number of loops. > > =Ralph Applied, thanks. -Matt ** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/ ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2004-08-06 13:04 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-08-05 19:01 [PATCH] 44x ethernet MDIO access Ralph Siemsen 2004-08-05 20:05 ` Ralph Siemsen 2004-08-05 21:34 ` Matt Porter 2004-08-06 12:12 ` Geert Uytterhoeven 2004-08-06 13:04 ` Ralph Siemsen 2004-08-05 21:23 ` Matt Porter
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).