All of lore.kernel.org
 help / color / mirror / Atom feed
* Atheros 8035 PHY only works when at803x_config_init() is commented out
@ 2015-04-08 16:28 Mason
  2015-04-08 17:29 ` Florian Fainelli
  0 siblings, 1 reply; 24+ messages in thread
From: Mason @ 2015-04-08 16:28 UTC (permalink / raw)
  To: netdev; +Cc: Florian Fainelli, Mugunthan, David S. Miller

Hello everyone,

I have a weird problem, that I've only started investigating, and I'd be
grateful if anyone can help me along.

I have an ARM-based SoC that provides (AFAIU) an Atheros 8035 PHY.

If I enable the driver in my kernel (CONFIG_AT803X_PHY) then something
goes wrong, and the system cannot load the nfsroot. Bizarrely, DHCP
seems to work (so there is limited connectivity) but then the NFS
server just times out.

However, if I just comment this line:
	//.config_init = at803x_config_init,
in at803x_driver[0]
then everything seems to work. (At least, the system sets the PHY
to Gbit, and manages to download the nfsroot.)

If I'm reading the code right (big "if"), when config_init is NULL,
then phy_init_hw() turns into a NOP?

So either at803x_config_init() or something called from phy_init_hw()
seems to be hosing this system's networking?

Sprinkling printk over phy_init_hw shows no errors (no premature exit)
and phydev->drv->config_init(phydev) returns 0.

Maybe I didn't set something up correctly, and phy_write() is scribbling
over the wrong register?

Does anyone see something I missed?

Regards.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-08 16:28 Atheros 8035 PHY only works when at803x_config_init() is commented out Mason
@ 2015-04-08 17:29 ` Florian Fainelli
  2015-04-08 21:37   ` Mason
  2015-04-09 11:44   ` Mason
  0 siblings, 2 replies; 24+ messages in thread
From: Florian Fainelli @ 2015-04-08 17:29 UTC (permalink / raw)
  To: Mason, netdev; +Cc: Mugunthan, David S. Miller

On 08/04/15 09:28, Mason wrote:
> Hello everyone,
> 
> I have a weird problem, that I've only started investigating, and I'd be
> grateful if anyone can help me along.
> 
> I have an ARM-based SoC that provides (AFAIU) an Atheros 8035 PHY.
> 
> If I enable the driver in my kernel (CONFIG_AT803X_PHY) then something
> goes wrong, and the system cannot load the nfsroot. Bizarrely, DHCP
> seems to work (so there is limited connectivity) but then the NFS
> server just times out.
> 
> However, if I just comment this line:
>     //.config_init = at803x_config_init,
> in at803x_driver[0]
> then everything seems to work. (At least, the system sets the PHY
> to Gbit, and manages to download the nfsroot.)
> 
> If I'm reading the code right (big "if"), when config_init is NULL,
> then phy_init_hw() turns into a NOP?
> 
> So either at803x_config_init() or something called from phy_init_hw()
> seems to be hosing this system's networking?
> 
> Sprinkling printk over phy_init_hw shows no errors (no premature exit)
> and phydev->drv->config_init(phydev) returns 0.
> 
> Maybe I didn't set something up correctly, and phy_write() is scribbling
> over the wrong register?
> 
> Does anyone see something I missed?

So one possibility could be that the bootloader initializes the PHY in a
certain way, typically by applying workarounds, and your config_init()
callback is not restoring any of theses, which is why, after
phy_init_hw(), which does a software reset of the PHY, all of these
workarounds are wiped out, and your PHY behaves funky.

The reason why config_init() needs to put the PHY back into a fully
functional state is because the PHY library should be able to software
reset the PHY when it needs to, but also be able to deal with deep sleep
modes etc.. where the PHY could loose its settings, yet the kernel
should be able to bring you back in a good state.

An easy way to bypass that is to provide a soft_reset calback which does
nothing, and see if calling either at803x_config_init(), or
genphy_config_init() is sufficient to preserve the PHY settings.
Although the real solution is to look at what the bootloader does on
that front and replicate it in the config_init() callback.

Hope this helps.
-- 
Florian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-08 17:29 ` Florian Fainelli
@ 2015-04-08 21:37   ` Mason
  2015-04-09 11:44   ` Mason
  1 sibling, 0 replies; 24+ messages in thread
From: Mason @ 2015-04-08 21:37 UTC (permalink / raw)
  To: Florian Fainelli, netdev; +Cc: Mugunthan, David S. Miller

On 08/04/2015 19:29, Florian Fainelli wrote:
> On 08/04/15 09:28, Mason wrote:
>> Hello everyone,
>>
>> I have a weird problem, that I've only started investigating, and I'd be
>> grateful if anyone can help me along.
>>
>> I have an ARM-based SoC that provides (AFAIU) an Atheros 8035 PHY.
>>
>> If I enable the driver in my kernel (CONFIG_AT803X_PHY) then something
>> goes wrong, and the system cannot load the nfsroot. Bizarrely, DHCP
>> seems to work (so there is limited connectivity) but then the NFS
>> server just times out.
>>
>> However, if I just comment this line:
>>     //.config_init = at803x_config_init,
>> in at803x_driver[0]
>> then everything seems to work. (At least, the system sets the PHY
>> to Gbit, and manages to download the nfsroot.)
>>
>> If I'm reading the code right (big "if"), when config_init is NULL,
>> then phy_init_hw() turns into a NOP?
>>
>> So either at803x_config_init() or something called from phy_init_hw()
>> seems to be hosing this system's networking?
>>
>> Sprinkling printk over phy_init_hw shows no errors (no premature exit)
>> and phydev->drv->config_init(phydev) returns 0.
>>
>> Maybe I didn't set something up correctly, and phy_write() is scribbling
>> over the wrong register?
>>
>> Does anyone see something I missed?
> 
> So one possibility could be that the bootloader initializes the PHY in a
> certain way, typically by applying workarounds, and your config_init()
> callback is not restoring any of theses, which is why, after
> phy_init_hw(), which does a software reset of the PHY, all of these
> workarounds are wiped out, and your PHY behaves funky.
> 
> The reason why config_init() needs to put the PHY back into a fully
> functional state is because the PHY library should be able to software
> reset the PHY when it needs to, but also be able to deal with deep sleep
> modes etc.. where the PHY could loose its settings, yet the kernel
> should be able to bring you back in a good state.
> 
> An easy way to bypass that is to provide a soft_reset calback which does
> nothing, and see if calling either at803x_config_init(), or
> genphy_config_init() is sufficient to preserve the PHY settings.
> Although the real solution is to look at what the bootloader does on
> that front and replicate it in the config_init() callback.
> 
> Hope this helps.

Thanks for the insight. I hadn't considered the bootloader's role.

One thing I forgot to mention is that I'm using an old kernel 3.14
and it doesn't seem to have the soft_reset function pointer.

http://lxr.free-electrons.com/source/drivers/net/phy/phy_device.c?v=3.14#L535

phy_init_hw() just calls phy_write(phydev, MII_BMCR, BMCR_RESET)
and then phy_poll_reset(phydev) -- the equivalent of today's
genphy_soft_reset().

Anyway, I will look more closely at the points you mentioned.

Thanks again.

Regards.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-08 17:29 ` Florian Fainelli
  2015-04-08 21:37   ` Mason
@ 2015-04-09 11:44   ` Mason
  2015-04-09 13:15     ` Mason
  2015-04-09 13:36     ` Daniel Mack
  1 sibling, 2 replies; 24+ messages in thread
From: Mason @ 2015-04-09 11:44 UTC (permalink / raw)
  To: Florian Fainelli, netdev
  Cc: Mugunthan, David S. Miller, Matus Ujhelyi, Daniel Mack

[ Problem with Atheros AR8035 PHY reset ]

Florian Fainelli wrote:

> Mason wrote:
>
>> I have a weird problem, that I've only started investigating, and I'd be
>> grateful if anyone can help me along.
>>
>> I have an ARM-based SoC that provides (AFAIU) an Atheros 8035 PHY.
>>
>> If I enable the driver in my kernel (CONFIG_AT803X_PHY) then something
>> goes wrong, and the system cannot load the nfsroot. Bizarrely, DHCP
>> seems to work (so there is limited connectivity) but then the NFS
>> server just times out.
>>
>> However, if I just comment this line:
>>      //.config_init = at803x_config_init,
>> in at803x_driver[0]
>> then everything seems to work. (At least, the system sets the PHY
>> to Gbit, and manages to download the nfsroot.)
>>
>> If I'm reading the code right (big "if"), when config_init is NULL,
>> then phy_init_hw() turns into a NOP?
>>
>> So either at803x_config_init() or something called from phy_init_hw()
>> seems to be hosing this system's networking?
>>
>> Sprinkling printk over phy_init_hw shows no errors (no premature exit)
>> and phydev->drv->config_init(phydev) returns 0.
>>
>> Maybe I didn't set something up correctly, and phy_write() is scribbling
>> over the wrong register?
>>
>> Does anyone see something I missed?
>
> So one possibility could be that the bootloader initializes the PHY in a
> certain way, typically by applying workarounds, and your config_init()
> callback is not restoring any of theses, which is why, after
> phy_init_hw(), which does a software reset of the PHY, all of these
> workarounds are wiped out, and your PHY behaves funky.
>
> The reason why config_init() needs to put the PHY back into a fully
> functional state is because the PHY library should be able to software
> reset the PHY when it needs to, but also be able to deal with deep sleep
> modes etc.. where the PHY could loose its settings, yet the kernel
> should be able to bring you back in a good state.
>
> An easy way to bypass that is to provide a soft_reset callback which does
> nothing, and see if calling either at803x_config_init(), or
> genphy_config_init() is sufficient to preserve the PHY settings.
> Although the real solution is to look at what the bootloader does on
> that front and replicate it in the config_init() callback.

Here is the data sheet for the AR8035:
http://www.redeszone.net/app/uploads/2014/04/AR8035.pdf

It seems the problem comes from the fact that the PHY treats
HW reset and SW reset differently:

     HW reset: registers are set to specific values
     SW reset: some bits are retained across reset

Case in point: the control register (BMCR)
HW reset: BMCR = 0x3100
SW reset: retain bits[6,8,12,13] / other bits = 0

(0x3100 means bit_6=0, bit_8=bit_12=bit_13=1)

When we execute this line from genphy_soft_reset()

     phy_write(phydev, MII_BMCR, BMCR_RESET);

we reset the bits in BMCR, and SW reset does not restore them.

It seems to me (please tell me if I am wrong) that it should
be safe for all PHYs to write old_val | BMCR_RESET, instead of
just BMCR_RESET. Thus...

On chips that REALLY reset, the old_val bits will be discarded;
while on chips that retain some bits, we do want to keep them.

So the patch would go something like below. What do you think?

Regards


diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index bdfe51f..4bcbde3 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1087,9 +1087,10 @@ static int gen10g_read_status(struct phy_device *phydev)
   */
  int genphy_soft_reset(struct phy_device *phydev)
  {
-       int ret;
+       int ret, val;
  
-       ret = phy_write(phydev, MII_BMCR, BMCR_RESET);
+       val = phy_read (phydev, MII_BMCR);
+       ret = phy_write(phydev, MII_BMCR, val | BMCR_RESET);
         if (ret < 0)
                 return ret;
  

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 11:44   ` Mason
@ 2015-04-09 13:15     ` Mason
  2015-04-09 13:36     ` Daniel Mack
  1 sibling, 0 replies; 24+ messages in thread
From: Mason @ 2015-04-09 13:15 UTC (permalink / raw)
  To: Florian Fainelli, netdev
  Cc: Mugunthan, David S. Miller, Matus Ujhelyi, Daniel Mack

Mason wrote:

> [ Problem with Atheros AR8035 PHY reset ]
>
> Florian Fainelli wrote:
>
>> Mason wrote:
>>
>>> I have a weird problem, that I've only started investigating, and I'd be
>>> grateful if anyone can help me along.
>>>
>>> I have an ARM-based SoC that provides (AFAIU) an Atheros 8035 PHY.
>>>
>>> If I enable the driver in my kernel (CONFIG_AT803X_PHY) then something
>>> goes wrong, and the system cannot load the nfsroot. Bizarrely, DHCP
>>> seems to work (so there is limited connectivity) but then the NFS
>>> server just times out.
>>>
>>> However, if I just comment this line:
>>>      //.config_init = at803x_config_init,
>>> in at803x_driver[0]
>>> then everything seems to work. (At least, the system sets the PHY
>>> to Gbit, and manages to download the nfsroot.)
>>>
>>> If I'm reading the code right (big "if"), when config_init is NULL,
>>> then phy_init_hw() turns into a NOP?
>>>
>>> So either at803x_config_init() or something called from phy_init_hw()
>>> seems to be hosing this system's networking?
>>>
>>> Sprinkling printk over phy_init_hw shows no errors (no premature exit)
>>> and phydev->drv->config_init(phydev) returns 0.
>>>
>>> Maybe I didn't set something up correctly, and phy_write() is scribbling
>>> over the wrong register?
>>>
>>> Does anyone see something I missed?
>>
>> So one possibility could be that the bootloader initializes the PHY in a
>> certain way, typically by applying workarounds, and your config_init()
>> callback is not restoring any of theses, which is why, after
>> phy_init_hw(), which does a software reset of the PHY, all of these
>> workarounds are wiped out, and your PHY behaves funky.
>>
>> The reason why config_init() needs to put the PHY back into a fully
>> functional state is because the PHY library should be able to software
>> reset the PHY when it needs to, but also be able to deal with deep sleep
>> modes etc.. where the PHY could loose its settings, yet the kernel
>> should be able to bring you back in a good state.
>>
>> An easy way to bypass that is to provide a soft_reset callback which does
>> nothing, and see if calling either at803x_config_init(), or
>> genphy_config_init() is sufficient to preserve the PHY settings.
>> Although the real solution is to look at what the bootloader does on
>> that front and replicate it in the config_init() callback.
>
> Here is the data sheet for the AR8035:
> http://www.redeszone.net/app/uploads/2014/04/AR8035.pdf
>
> It seems the problem comes from the fact that the PHY treats
> HW reset and SW reset differently:
>
>      HW reset: registers are set to specific values
>      SW reset: some bits are retained across reset
>
> Case in point: the control register (BMCR)
> HW reset: BMCR = 0x3100
> SW reset: retain bits[6,8,12,13] / other bits = 0
>
> (0x3100 means bit_6=0, bit_8=bit_12=bit_13=1)
>
> When we execute this line from genphy_soft_reset()
>
>      phy_write(phydev, MII_BMCR, BMCR_RESET);
>
> we reset the bits in BMCR, and SW reset does not restore them.
>
> It seems to me (please tell me if I am wrong) that it should
> be safe for all PHYs to write old_val | BMCR_RESET, instead of
> just BMCR_RESET. Thus...
>
> On chips that REALLY reset, the old_val bits will be discarded;
> while on chips that retain some bits, we do want to keep them.

I should add that all is not well, however.

If I set .config_init to NULL, it takes the system 4.5 seconds
to boot. But if I leave .config_init set to at803x_config_init,
then it takes 8.2 seconds to boot :-(

In 1) the link comes up at 1.66, we get an IP address at 4.2
In 2) the link comes up at 4.72, we get an IP address at 7.9

Looks like there are still mysteries to solve...

Regards.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 11:44   ` Mason
  2015-04-09 13:15     ` Mason
@ 2015-04-09 13:36     ` Daniel Mack
  2015-04-09 14:38       ` Mason
  2015-04-09 19:05       ` Mason
  1 sibling, 2 replies; 24+ messages in thread
From: Daniel Mack @ 2015-04-09 13:36 UTC (permalink / raw)
  To: Mason, Florian Fainelli, netdev; +Cc: Mugunthan, David S. Miller, Matus Ujhelyi

Hi,

On 04/09/2015 01:44 PM, Mason wrote:
> Florian Fainelli wrote:
>> So one possibility could be that the bootloader initializes the PHY in a
>> certain way, typically by applying workarounds, and your config_init()
>> callback is not restoring any of theses, which is why, after
>> phy_init_hw(), which does a software reset of the PHY, all of these
>> workarounds are wiped out, and your PHY behaves funky.
>>
>> The reason why config_init() needs to put the PHY back into a fully
>> functional state is because the PHY library should be able to software
>> reset the PHY when it needs to, but also be able to deal with deep sleep
>> modes etc.. where the PHY could loose its settings, yet the kernel
>> should be able to bring you back in a good state.
>>
>> An easy way to bypass that is to provide a soft_reset callback which does
>> nothing, and see if calling either at803x_config_init(), or
>> genphy_config_init() is sufficient to preserve the PHY settings.
>> Although the real solution is to look at what the bootloader does on
>> that front and replicate it in the config_init() callback.
> 
> Here is the data sheet for the AR8035:
> http://www.redeszone.net/app/uploads/2014/04/AR8035.pdf
> 
> It seems the problem comes from the fact that the PHY treats
> HW reset and SW reset differently:
> 
>      HW reset: registers are set to specific values
>      SW reset: some bits are retained across reset
> 
> Case in point: the control register (BMCR)
> HW reset: BMCR = 0x3100
> SW reset: retain bits[6,8,12,13] / other bits = 0
> 
> (0x3100 means bit_6=0, bit_8=bit_12=bit_13=1)
> 
> When we execute this line from genphy_soft_reset()
> 
>      phy_write(phydev, MII_BMCR, BMCR_RESET);
> 
> we reset the bits in BMCR, and SW reset does not restore them.
> 
> It seems to me (please tell me if I am wrong) that it should
> be safe for all PHYs to write old_val | BMCR_RESET, instead of
> just BMCR_RESET. Thus...
> 
> On chips that REALLY reset, the old_val bits will be discarded;
> while on chips that retain some bits, we do want to keep them.
> 
> So the patch would go something like below. What do you think?

I don't think that'll work, because writing a 1 into the RESET bit of
the register causes the PHY to enter its software reset routine
immediately. The other bits should hence be reset to their defaults,
regardless of what you set them to at the same time.

My suggestion is to dump the entire register set when
at803x_config_init() is entered and again when it's left. Then try to
find the differences and see if you can bring the PHY into the needed
mode through the exisiting configuration hooks in the kernel.

Note that it really should be possible for the kernel to bring the PHY
into the mode needed for your board. Relying on the bootloader to do the
magic is fragile, and as Florian said, this will break once a suspend
mode switches off the power domain that feeds the PHY.


Thanks,
Daniel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 13:36     ` Daniel Mack
@ 2015-04-09 14:38       ` Mason
  2015-04-09 15:22         ` Mason
  2015-04-09 19:05       ` Mason
  1 sibling, 1 reply; 24+ messages in thread
From: Mason @ 2015-04-09 14:38 UTC (permalink / raw)
  To: Daniel Mack, netdev
  Cc: Florian Fainelli, Mugunthan, David S. Miller, Matus Ujhelyi

Hello,

On 09/04/2015 15:36, Daniel Mack wrote:
> On 04/09/2015 01:44 PM, Mason wrote:
>> Florian Fainelli wrote:
>>> So one possibility could be that the bootloader initializes the PHY in a
>>> certain way, typically by applying workarounds, and your config_init()
>>> callback is not restoring any of theses, which is why, after
>>> phy_init_hw(), which does a software reset of the PHY, all of these
>>> workarounds are wiped out, and your PHY behaves funky.
>>>
>>> The reason why config_init() needs to put the PHY back into a fully
>>> functional state is because the PHY library should be able to software
>>> reset the PHY when it needs to, but also be able to deal with deep sleep
>>> modes etc.. where the PHY could loose its settings, yet the kernel
>>> should be able to bring you back in a good state.
>>>
>>> An easy way to bypass that is to provide a soft_reset callback which does
>>> nothing, and see if calling either at803x_config_init(), or
>>> genphy_config_init() is sufficient to preserve the PHY settings.
>>> Although the real solution is to look at what the bootloader does on
>>> that front and replicate it in the config_init() callback.
>>
>> Here is the data sheet for the AR8035:
>> http://www.redeszone.net/app/uploads/2014/04/AR8035.pdf
>>
>> It seems the problem comes from the fact that the PHY treats
>> HW reset and SW reset differently:
>>
>>       HW reset: registers are set to specific values
>>       SW reset: some bits are retained across reset
>>
>> Case in point: the control register (BMCR)
>> HW reset: BMCR = 0x3100
>> SW reset: retain bits[6,8,12,13] / other bits = 0
>>
>> (0x3100 means bit_6=0, bit_8=bit_12=bit_13=1)
>>
>> When we execute this line from genphy_soft_reset()
>>
>>       phy_write(phydev, MII_BMCR, BMCR_RESET);
>>
>> we reset the bits in BMCR, and SW reset does not restore them.
>>
>> It seems to me (please tell me if I am wrong) that it should
>> be safe for all PHYs to write old_val | BMCR_RESET, instead of
>> just BMCR_RESET. Thus...
>>
>> On chips that REALLY reset, the old_val bits will be discarded;
>> while on chips that retain some bits, we do want to keep them.
>>
>> So the patch would go something like below. What do you think?
>
> I don't think that'll work, because writing a 1 into the RESET bit of
> the register causes the PHY to enter its software reset routine
> immediately. The other bits should hence be reset to their defaults,
> regardless of what you set them to at the same time.

I'm confused by your answer, because it seems to be ignoring the
whole "some bits retain their value across SW reset" issue?

This can be settled quickly by an execution trace.
(Note, I'm using kernel 3.14)

I have instrumented phy_init_hw thus:
(I've also added a printk after phy_poll_reset)

	printk("BMCR = 0x%x\n", (unsigned)phy_read (phydev, MII_BMCR));
#if 0
	val = phy_read (phydev, MII_BMCR);
	ret = phy_write(phydev, MII_BMCR, val | BMCR_RESET);
#else
	ret = phy_write(phydev, MII_BMCR, BMCR_RESET);
#endif
	printk("BMCR = 0x%x\n", (unsigned)phy_read (phydev, MII_BMCR));


Running the #else branch outputs:
[    0.623188] BMCR = 0x3100
[    0.625957] BMCR = 0x0
[    0.686817] BMCR = 0x0

Running the #if branch outputs:
[    0.623151] BMCR = 0x3100
[    0.625979] BMCR = 0x3100
[    0.686817] BMCR = 0x3100

As you can see, writing val | BMCR_RESET is required on this PHY.

> My suggestion is to dump the entire register set when
> at803x_config_init() is entered and again when it's left. Then try to
> find the differences and see if you can bring the PHY into the needed
> mode through the existing configuration hooks in the kernel.

Good idea.

[    0.685330] IDX= 1 796d != 7949
[    0.688490] IDX= 5 c1e1 != 0000
[    0.691647] IDX= 6 000f != 0004
[    0.694803] IDX=10 3800 != 0000
[    0.697960] IDX=17 bc10 != 0012
[    0.701115] IDX=19 7400 != 0000
[    0.704271] IDX=27 060e != 0600

Hmmm, didn't expect so many differences. I'll have to take a closer look.

> Note that it really should be possible for the kernel to bring the PHY
> into the mode needed for your board. Relying on the bootloader to do the
> magic is fragile, and as Florian said, this will break once a suspend
> mode switches off the power domain that feeds the PHY.

Uboot dev boards, uboot runs (and uboot speaks Ethernet). I don't know if
uboot tweaks the PHY. But on production boards, there is no uboot, and the
early bootloaders don't touch the PHY.

Regards.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 14:38       ` Mason
@ 2015-04-09 15:22         ` Mason
  2015-04-09 15:32           ` Daniel Mack
  2015-04-09 17:25           ` Florian Fainelli
  0 siblings, 2 replies; 24+ messages in thread
From: Mason @ 2015-04-09 15:22 UTC (permalink / raw)
  To: Daniel Mack, netdev
  Cc: Florian Fainelli, Mugunthan, David S. Miller, Matus Ujhelyi

Mason wrote:

> Daniel Mack wrote:
>
>> My suggestion is to dump the entire register set when
>> at803x_config_init() is entered and again when it's left. Then try to
>> find the differences and see if you can bring the PHY into the needed
>> mode through the existing configuration hooks in the kernel.
>
> [    0.685330] IDX= 1 796d != 7949
> [    0.688490] IDX= 5 c1e1 != 0000
> [    0.691647] IDX= 6 000f != 0004
> [    0.694803] IDX=10 3800 != 0000
> [    0.697960] IDX=17 bc10 != 0012
> [    0.701115] IDX=19 7400 != 0000
> [    0.704271] IDX=27 060e != 0600
>
> Hmmm, didn't expect so many differences. I'll have to take a closer look.

For the record, I dumped the PHY registers
A) upon entering phy_init_hw
B) before leaving phy_init_hw (thus right after at803x_config_init)

IDX 1: b2 LINK STATUS, b5 AUTO-NEGOTIATION COMPLETE
=> Difference in status bits, seems reasonable

IDX 5: Link partner ability (base page)
=> seems reasonable (no partner yet?)

IDX 6: Auto-Negotiation Expansion
=> seems reasonable (no partner yet?)

IDX 10: 1000 BASE-T Status (HW reset = SW reset = 0)
(ALSO: Contents of this register clear after a read operation has occurred.)
=> Looks like my own read cleared it

IDX 17: PHY-Specific Status
b1 = "POLARITY (real time)"?
=> Difference in status bits, seems reasonable? (

IDX 19: Interrupt Status
=> Looks like some interrupt requests might have been discarded?

IDX 27: This register is undocumented

Nothing looks suspicious, except maybe the Interrupt Status?

Is speed auto-negotiation supposed to be complete when phy_init_hw exits?

Regards.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 15:22         ` Mason
@ 2015-04-09 15:32           ` Daniel Mack
  2015-04-09 15:58             ` Mason
  2015-04-09 17:25           ` Florian Fainelli
  1 sibling, 1 reply; 24+ messages in thread
From: Daniel Mack @ 2015-04-09 15:32 UTC (permalink / raw)
  To: Mason, netdev; +Cc: Florian Fainelli, Mugunthan, David S. Miller, Matus Ujhelyi

On 04/09/2015 05:22 PM, Mason wrote:
> For the record, I dumped the PHY registers
> A) upon entering phy_init_hw
> B) before leaving phy_init_hw (thus right after at803x_config_init)
> 
> IDX 1: b2 LINK STATUS, b5 AUTO-NEGOTIATION COMPLETE
> => Difference in status bits, seems reasonable
> 
> IDX 5: Link partner ability (base page)
> => seems reasonable (no partner yet?)
> 
> IDX 6: Auto-Negotiation Expansion
> => seems reasonable (no partner yet?)
> 
> IDX 10: 1000 BASE-T Status (HW reset = SW reset = 0)
> (ALSO: Contents of this register clear after a read operation has occurred.)
> => Looks like my own read cleared it
> 
> IDX 17: PHY-Specific Status
> b1 = "POLARITY (real time)"?
> => Difference in status bits, seems reasonable? (
> 
> IDX 19: Interrupt Status
> => Looks like some interrupt requests might have been discarded?
> 
> IDX 27: This register is undocumented
> 
> Nothing looks suspicious, except maybe the Interrupt Status?

What about the debug registers, such as the one that configures the
RGMII TX/RX clock delay (4.2.25, 4.2.26). These are indirectly
addressed, see at803x_config_init().


Daniel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 15:32           ` Daniel Mack
@ 2015-04-09 15:58             ` Mason
  0 siblings, 0 replies; 24+ messages in thread
From: Mason @ 2015-04-09 15:58 UTC (permalink / raw)
  To: Daniel Mack, netdev
  Cc: Florian Fainelli, Mugunthan, David S. Miller, Matus Ujhelyi

On 09/04/2015 17:32, Daniel Mack wrote:

> What about the debug registers, such as the one that configures the
> RGMII TX/RX clock delay (4.2.25, 4.2.26). These are indirectly
> addressed, see at803x_config_init().

My dump code:

void mydump(struct phy_device *phydev, int *foo, int *bar)
{
	int i;
	for (i = 0; i < 32; ++i) foo[i] = phy_read(phydev, i);
	for (i = 0; i < 20; ++i) {
		phy_write(phydev, 0x1d, i);
		mdelay(1);
		bar[i] = phy_read(phydev, 0x1e);
	}
}

[    0.738528] IDX=0x01 796d != 7949
[    0.741860] IDX=0x05 c1e1 != 0000
[    0.745191] IDX=0x06 000f != 0004
[    0.748521] IDX=0x0a 3800 != 0000
[    0.751851] IDX=0x11 bc10 != 0012
[    0.755182] IDX=0x13 7400 != 0000
[    0.758513] IDX=0x1b 060e != 0600
[    0.761842] DEBUG REGS
[    0.764211] IDX=0x01 ffd0 != 0032
[    0.767542] IDX=0x02 3f0f != 3110
[    0.770872] IDX=0x03 3fff != 3f00
[    0.774203] IDX=0x0c 0800 != 1801
[    0.777533] IDX=0x0d 0100 != 0000
[    0.780863] IDX=0x0e 0023 != 0040

Differences in debug registers only occur in undocumented registers.
(Only 0x00, 0x05, 0x10, 0x11, 0x12 are documented.)

Regards.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 15:22         ` Mason
  2015-04-09 15:32           ` Daniel Mack
@ 2015-04-09 17:25           ` Florian Fainelli
  2015-04-09 18:52             ` Mason
  1 sibling, 1 reply; 24+ messages in thread
From: Florian Fainelli @ 2015-04-09 17:25 UTC (permalink / raw)
  To: Mason, Daniel Mack, netdev; +Cc: Mugunthan, David S. Miller, Matus Ujhelyi

On 09/04/15 08:22, Mason wrote:
> Mason wrote:
> 
>> Daniel Mack wrote:
>>
>>> My suggestion is to dump the entire register set when
>>> at803x_config_init() is entered and again when it's left. Then try to
>>> find the differences and see if you can bring the PHY into the needed
>>> mode through the existing configuration hooks in the kernel.
>>
>> [    0.685330] IDX= 1 796d != 7949
>> [    0.688490] IDX= 5 c1e1 != 0000
>> [    0.691647] IDX= 6 000f != 0004
>> [    0.694803] IDX=10 3800 != 0000
>> [    0.697960] IDX=17 bc10 != 0012
>> [    0.701115] IDX=19 7400 != 0000
>> [    0.704271] IDX=27 060e != 0600
>>
>> Hmmm, didn't expect so many differences. I'll have to take a closer look.
> 
> For the record, I dumped the PHY registers
> A) upon entering phy_init_hw
> B) before leaving phy_init_hw (thus right after at803x_config_init)
> 
> IDX 1: b2 LINK STATUS, b5 AUTO-NEGOTIATION COMPLETE
> => Difference in status bits, seems reasonable
> 
> IDX 5: Link partner ability (base page)
> => seems reasonable (no partner yet?)
> 
> IDX 6: Auto-Negotiation Expansion
> => seems reasonable (no partner yet?)
> 
> IDX 10: 1000 BASE-T Status (HW reset = SW reset = 0)
> (ALSO: Contents of this register clear after a read operation has
> occurred.)
> => Looks like my own read cleared it
> 
> IDX 17: PHY-Specific Status
> b1 = "POLARITY (real time)"?
> => Difference in status bits, seems reasonable? (
> 
> IDX 19: Interrupt Status
> => Looks like some interrupt requests might have been discarded?
> 
> IDX 27: This register is undocumented
> 
> Nothing looks suspicious, except maybe the Interrupt Status?
> 
> Is speed auto-negotiation supposed to be complete when phy_init_hw exits?

There is no such guarantee, and the PHY state machine is started later,
which will take care of auto-neg and other things.
-- 
Florian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 17:25           ` Florian Fainelli
@ 2015-04-09 18:52             ` Mason
  2015-04-09 19:00               ` Florian Fainelli
  0 siblings, 1 reply; 24+ messages in thread
From: Mason @ 2015-04-09 18:52 UTC (permalink / raw)
  To: Florian Fainelli, netdev
  Cc: Daniel Mack, Mugunthan, David S. Miller, Matus Ujhelyi

Florian Fainelli wrote:

> Mason wrote:
>
>> Is speed auto-negotiation supposed to be complete when phy_init_hw exits?
> 
> There is no such guarantee, and the PHY state machine is started later,
> which will take care of auto-neg and other things.

That's what I thought.

So it's expected that many status bits will only change later.

You didn't comment on my patch. What's your take on it?

Regards.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 18:52             ` Mason
@ 2015-04-09 19:00               ` Florian Fainelli
  2015-04-09 19:30                 ` Mason
  0 siblings, 1 reply; 24+ messages in thread
From: Florian Fainelli @ 2015-04-09 19:00 UTC (permalink / raw)
  To: Mason, netdev; +Cc: Daniel Mack, Mugunthan, David S. Miller, Matus Ujhelyi

On 09/04/15 11:52, Mason wrote:
> Florian Fainelli wrote:
> 
>> Mason wrote:
>>
>>> Is speed auto-negotiation supposed to be complete when phy_init_hw exits?
>>
>> There is no such guarantee, and the PHY state machine is started later,
>> which will take care of auto-neg and other things.
> 
> That's what I thought.
> 
> So it's expected that many status bits will only change later.
> 
> You didn't comment on my patch. What's your take on it?

Quoting IEEE 802.3 section 2, paragprah 22.2.4.1:

"Resetting a PHY is accomplished by setting bit 0.15 to a logic one.
This action shall set the status and con-trol registers to their default
states. As a consequence this action may change the internal state of
the PHY
and the state of the physical link associated with the PHY. This bit is
self-clearing, and a PHY shall return a
value of one in bit 0.15 until the reset process is completed. A PHY is
not required to accept a write transac-
tion to the control register until the reset process is completed, and
writes to bits of the control register other
than 0.15 may have no effect until the reset process is completed. The
reset process shall be completed
within 0.5 s from the setting of bit 0.15.
"

So even though this is not extremely specific about whether or not doing
a RMW instead of W is accepted, considering that this resets the PHY
internal state, and the fact that there is a lack of clarify on whether
setting any bits other than 15 is going to fall under the "A PHY is not
required to accept a write transaction to the control register until the
reset process is completed" statement, setting only this bit at least
guarantees that you are back into your reset defaults.

As Daniel suggested, I would be looking for undocumented/proprietary
registers for reasons as to why your PHY is not working, in particular
(RG)MII tuning.
-- 
Florian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 13:36     ` Daniel Mack
  2015-04-09 14:38       ` Mason
@ 2015-04-09 19:05       ` Mason
  1 sibling, 0 replies; 24+ messages in thread
From: Mason @ 2015-04-09 19:05 UTC (permalink / raw)
  To: Daniel Mack, netdev
  Cc: Florian Fainelli, Mugunthan, David S. Miller, Matus Ujhelyi

Daniel Mack wrote:

> Mason wrote:
> 
>> Here is the data sheet for the AR8035:
>> http://www.redeszone.net/app/uploads/2014/04/AR8035.pdf
>>
>> It seems the problem comes from the fact that the PHY treats
>> HW reset and SW reset differently:
>>
>>      HW reset: registers are set to specific values
>>      SW reset: some bits are retained across reset
>>
>> Case in point: the control register (BMCR)
>> HW reset: BMCR = 0x3100
>> SW reset: retain bits[6,8,12,13] / other bits = 0
>>
>> (0x3100 means bit_6=0, bit_8=bit_12=bit_13=1)
>>
>> When we execute this line from genphy_soft_reset()
>>
>>      phy_write(phydev, MII_BMCR, BMCR_RESET);
>>
>> we reset the bits in BMCR, and SW reset does not restore them.
>>
>> It seems to me (please tell me if I am wrong) that it should
>> be safe for all PHYs to write old_val | BMCR_RESET, instead of
>> just BMCR_RESET. Thus...
>>
>> On chips that REALLY reset, the old_val bits will be discarded;
>> while on chips that retain some bits, we do want to keep them.
>>
>> So the patch would go something like below. What do you think?
> 
> I don't think that'll work, because writing a 1 into the RESET bit of
> the register causes the PHY to enter its software reset routine
> immediately. The other bits should hence be reset to their defaults,
> regardless of what you set them to at the same time.

I forgot to ask:

(I presume you have a system with an AR8035.)

When the PHY is reset, you don't see the odd behavior I get?

Can you print the value of BMCR, before and after

    phy_write(phydev, MII_BMCR, BMCR_RESET);

Regards.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 19:00               ` Florian Fainelli
@ 2015-04-09 19:30                 ` Mason
  2015-04-09 20:26                   ` Florian Fainelli
                                     ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Mason @ 2015-04-09 19:30 UTC (permalink / raw)
  To: Florian Fainelli, netdev
  Cc: Daniel Mack, Mugunthan, David S. Miller, Matus Ujhelyi

Florian Fainelli wrote:
> Mason wrote:
>> Florian Fainelli wrote:
>>
>>> Mason wrote:
>>>
>>>> Is speed auto-negotiation supposed to be complete when phy_init_hw exits?
>>>
>>> There is no such guarantee, and the PHY state machine is started later,
>>> which will take care of auto-neg and other things.
>>
>> That's what I thought.
>>
>> So it's expected that many status bits will only change later.
>>
>> You didn't comment on my patch. What's your take on it?
> 
> Quoting IEEE 802.3 section 2, paragraph 22.2.4.1:
> 
> "Resetting a PHY is accomplished by setting bit 0.15 to a logic one.
> This action shall set the status and control registers to their 
> default states. As a consequence this action may change the internal 
> state of the PHY and the state of the physical link associated with 
> the PHY. This bit is self-clearing, and a PHY shall return a value
> of one in bit 0.15 until the reset process is completed. A PHY is
> not required to accept a write transaction to the control register 
> until the reset process is completed, and writes to bits of the 
> control register other than 0.15 may have no effect until the reset 
> process is completed. The reset process shall be completed within
> 0.5 s from the setting of bit 0.15"
> 
> So even though this is not extremely specific about whether or not doing
> a RMW instead of W is accepted, considering that this resets the PHY
> internal state, and the fact that there is a lack of clarify on whether
> setting any bits other than 15 is going to fall under the "A PHY is not
> required to accept a write transaction to the control register until the
> reset process is completed" statement, setting only this bit at least
> guarantees that you are back into your reset defaults.
> 
> As Daniel suggested, I would be looking for undocumented/proprietary
> registers for reasons as to why your PHY is not working, in particular
> (RG)MII tuning.

Am I the only having problems with the AR8035? :-(

The standard driver works for everyone but me? 

Did you take a look at the data sheet? Do you understand the
difference between "Hardware Reset" and "Software Reset"?

Maybe on my PHY, writing BMCR_RESET to BMCR triggers a SW reset,
while it triggers a HW reset on other boards?

Would that be possible?

Also, why do you say the PHY is not working? When I apply the
patch I proposed, it doesn't malfunction.

Regards.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 19:30                 ` Mason
@ 2015-04-09 20:26                   ` Florian Fainelli
  2015-04-09 22:10                     ` Mason
  2015-04-09 22:31                   ` Fabio Estevam
  2015-04-10  9:33                   ` Daniel Mack
  2 siblings, 1 reply; 24+ messages in thread
From: Florian Fainelli @ 2015-04-09 20:26 UTC (permalink / raw)
  To: Mason, netdev; +Cc: Daniel Mack, Mugunthan, David S. Miller, Matus Ujhelyi

On 09/04/15 12:30, Mason wrote:
> Florian Fainelli wrote:
>> Mason wrote:
>>> Florian Fainelli wrote:
>>>
>>>> Mason wrote:
>>>>
>>>>> Is speed auto-negotiation supposed to be complete when phy_init_hw exits?
>>>>
>>>> There is no such guarantee, and the PHY state machine is started later,
>>>> which will take care of auto-neg and other things.
>>>
>>> That's what I thought.
>>>
>>> So it's expected that many status bits will only change later.
>>>
>>> You didn't comment on my patch. What's your take on it?
>>
>> Quoting IEEE 802.3 section 2, paragraph 22.2.4.1:
>>
>> "Resetting a PHY is accomplished by setting bit 0.15 to a logic one.
>> This action shall set the status and control registers to their 
>> default states. As a consequence this action may change the internal 
>> state of the PHY and the state of the physical link associated with 
>> the PHY. This bit is self-clearing, and a PHY shall return a value
>> of one in bit 0.15 until the reset process is completed. A PHY is
>> not required to accept a write transaction to the control register 
>> until the reset process is completed, and writes to bits of the 
>> control register other than 0.15 may have no effect until the reset 
>> process is completed. The reset process shall be completed within
>> 0.5 s from the setting of bit 0.15"
>>
>> So even though this is not extremely specific about whether or not doing
>> a RMW instead of W is accepted, considering that this resets the PHY
>> internal state, and the fact that there is a lack of clarify on whether
>> setting any bits other than 15 is going to fall under the "A PHY is not
>> required to accept a write transaction to the control register until the
>> reset process is completed" statement, setting only this bit at least
>> guarantees that you are back into your reset defaults.
>>
>> As Daniel suggested, I would be looking for undocumented/proprietary
>> registers for reasons as to why your PHY is not working, in particular
>> (RG)MII tuning.
> 
> Am I the only having problems with the AR8035? :-(
> 
> The standard driver works for everyone but me? 
> 
> Did you take a look at the data sheet? Do you understand the
> difference between "Hardware Reset" and "Software Reset"?

I did not.

> 
> Maybe on my PHY, writing BMCR_RESET to BMCR triggers a SW reset,
> while it triggers a HW reset on other boards?
> 
> Would that be possible?

Possible, but certainly non-compliant behavior, in which case you would
want to override the soft_reset() callback.

> 
> Also, why do you say the PHY is not working? When I apply the
> patch I proposed, it doesn't malfunction.

There are no BMCR registers that would affect directly the passing of
unicast or broadcast traffic with distinction, which is how you
originally reported the problem, or maybe that was a bad description of
the issue?

Have you checked the Ethernet MAC MIB counters to see if there are any
errors reported differently from the working case to the non-working
case? What about your link partner, what does it looks like on its end
when it does not work?
-- 
Florian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 20:26                   ` Florian Fainelli
@ 2015-04-09 22:10                     ` Mason
  2015-04-09 22:30                       ` Florian Fainelli
  0 siblings, 1 reply; 24+ messages in thread
From: Mason @ 2015-04-09 22:10 UTC (permalink / raw)
  To: Florian Fainelli, netdev
  Cc: Daniel Mack, Mugunthan, David S. Miller, Matus Ujhelyi

Florian Fainelli wrote:
> Mason wrote:
>> Florian Fainelli wrote:
>>> Quoting IEEE 802.3 section 2, paragraph 22.2.4.1:
>>>
>>> "Resetting a PHY is accomplished by setting bit 0.15 to a logic one.
>>> This action shall set the status and control registers to their 
>>> default states. As a consequence this action may change the internal 
>>> state of the PHY and the state of the physical link associated with 
>>> the PHY. This bit is self-clearing, and a PHY shall return a value
>>> of one in bit 0.15 until the reset process is completed. A PHY is
>>> not required to accept a write transaction to the control register 
>>> until the reset process is completed, and writes to bits of the 
>>> control register other than 0.15 may have no effect until the reset 
>>> process is completed. The reset process shall be completed within
>>> 0.5 s from the setting of bit 0.15"
>>>
>>> So even though this is not extremely specific about whether or not doing
>>> a RMW instead of W is accepted, considering that this resets the PHY
>>> internal state, and the fact that there is a lack of clarify on whether
>>> setting any bits other than 15 is going to fall under the "A PHY is not
>>> required to accept a write transaction to the control register until the
>>> reset process is completed" statement, setting only this bit at least
>>> guarantees that you are back into your reset defaults.
>>>
>>> As Daniel suggested, I would be looking for undocumented/proprietary
>>> registers for reasons as to why your PHY is not working, in particular
>>> (RG)MII tuning.
>>
>> Am I the only having problems with the AR8035? :-(
>>
>> The standard driver works for everyone but me? 
>>
>> Did you take a look at the data sheet? Do you understand the
>> difference between "Hardware Reset" and "Software Reset"?
> 
> I did not.

If I understand your quote from the standard correctly,
then the behavior documented in the data sheet looks
very non-compliant to my untrained eye.

>> Also, why do you say the PHY is not working? When I apply the
>> patch I proposed, it doesn't malfunction.
> 
> There are no BMCR registers that would affect directly the passing of
> unicast or broadcast traffic with distinction, which is how you
> originally reported the problem, or maybe that was a bad description of
> the issue?

I didn't say anything about unicast vs broadcast.

When I run the unpatched code, it looks like the PHY negotiates
only 10 Mbps Half-duplex, then DHCP appears to succeed (IIUC
only the very first packets are broadcast), and then the system
hangs trying to mount the root filesystem over NFS.

I actually left it running over lunch break, and according
to the kernel's time stamps, the system seems to have managed
to mount the root file system after 2000+ seconds.

> Have you checked the Ethernet MAC MIB counters to see if there are any
> errors reported differently from the working case to the non-working
> case? What about your link partner, what does it looks like on its end
> when it does not work?

Should I use ethtool for this?

Or do it directly with kernel code? (If so which API?)

The catch is that I need the network to get a running system.
No network, no root file system.

Maybe I need to write the kernel to non-volatile storage.


Going on a wild goose hunt...

Somewhat related discussion
https://community.freescale.com/thread/289362

Let me check how u-boot handles the AR8035.
http://git.denx.de/?p=u-boot.git;a=blob;f=drivers/net/phy/atheros.c

static int ar8035_config(struct phy_device *phydev)
{
	int regval;

	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x0007);
	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
	regval = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, (regval|0x0018));

	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
	regval = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, (regval|0x0100));

	phydev->supported = phydev->drv->features;

	return 0;
}

Data sheet states:
Register 0xd = "MMD Access Control". 
Register 0xe = "MMD Access Control Data".

MMD register access:
See detail in register description
example: Write 0x8000 to Register 0 of MMD3
1. Write 0x3 to register 0xD: 
0xD=0x0003;(function= address; set the device address)
2. Write 0x0 to register 0xE: 0xE=0x0; (set the register offset address)
3. Write 0x4003 to register 
0xD:0xD=0x4003;(function=data; keep the device address)
4. Read register 0xE:0xE==(data from register 0x0 of MMD3)
5. Write 0x8000 to register 0xE 
:0xE=0x8000(write 0x8000 to register 0x0 of MMD3)
Please Note:Read operation please refers to process 1 ~ 4

Important note:
CLK_25M default outputs 25MHz, can be configured to
50MHz, 62.5MHz, or 125MHz by register MMD7 8016[4:3].

Ah yes, there it is on page 58:
Device address = 7, address offset = 0x8016 (Hex)
4:3 Select_clk125m
CLK_25M output clock select
00=25M
01=50M
10=62.5M
11=125M


So...

	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x0007);
	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
	regval = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, (regval|0x0018));

R[0xd] = 0x0007  ; select MMD7
R[0xe] = 0x8016  ; offset 0x8016, so 
R[0xd] = 0x4007  ; select "data, no post increment" for MMD7
then we read the current value of MMD7/offset=0x8016
and set bits 3 and 4 on top of that => 125 MHz clock

HW reset val = 0
SW reset val = retain previous value
so the reset in Linux shouldn't affect this...


	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
	regval = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, (regval|0x0100));

set debug port offset to 5 (DR5)
read current value
set bit 8 (rgmii_tx_clk_dly)

Rgmii tx clock delay control bit:
1 = rgmii tx clock delay enable
0 = rgmii tx clock delay disable.

AFAICT, the Linux code doesn't RMW, it just blindly writes
AT803X_DEBUG_RGMII_TX_CLK_DLY. Dunno if it makes any difference...

Meh, I'm still grasping at straws...

Regards.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 22:10                     ` Mason
@ 2015-04-09 22:30                       ` Florian Fainelli
  0 siblings, 0 replies; 24+ messages in thread
From: Florian Fainelli @ 2015-04-09 22:30 UTC (permalink / raw)
  To: Mason, netdev; +Cc: Daniel Mack, Mugunthan, David S. Miller, Matus Ujhelyi

On 09/04/15 15:10, Mason wrote:
> Florian Fainelli wrote:
>> Mason wrote:
>>> Florian Fainelli wrote:
>>>> Quoting IEEE 802.3 section 2, paragraph 22.2.4.1:
>>>>
>>>> "Resetting a PHY is accomplished by setting bit 0.15 to a logic one.
>>>> This action shall set the status and control registers to their 
>>>> default states. As a consequence this action may change the internal 
>>>> state of the PHY and the state of the physical link associated with 
>>>> the PHY. This bit is self-clearing, and a PHY shall return a value
>>>> of one in bit 0.15 until the reset process is completed. A PHY is
>>>> not required to accept a write transaction to the control register 
>>>> until the reset process is completed, and writes to bits of the 
>>>> control register other than 0.15 may have no effect until the reset 
>>>> process is completed. The reset process shall be completed within
>>>> 0.5 s from the setting of bit 0.15"
>>>>
>>>> So even though this is not extremely specific about whether or not doing
>>>> a RMW instead of W is accepted, considering that this resets the PHY
>>>> internal state, and the fact that there is a lack of clarify on whether
>>>> setting any bits other than 15 is going to fall under the "A PHY is not
>>>> required to accept a write transaction to the control register until the
>>>> reset process is completed" statement, setting only this bit at least
>>>> guarantees that you are back into your reset defaults.
>>>>
>>>> As Daniel suggested, I would be looking for undocumented/proprietary
>>>> registers for reasons as to why your PHY is not working, in particular
>>>> (RG)MII tuning.
>>>
>>> Am I the only having problems with the AR8035? :-(
>>>
>>> The standard driver works for everyone but me? 
>>>
>>> Did you take a look at the data sheet? Do you understand the
>>> difference between "Hardware Reset" and "Software Reset"?
>>
>> I did not.
> 
> If I understand your quote from the standard correctly,
> then the behavior documented in the data sheet looks
> very non-compliant to my untrained eye.
> 
>>> Also, why do you say the PHY is not working? When I apply the
>>> patch I proposed, it doesn't malfunction.
>>
>> There are no BMCR registers that would affect directly the passing of
>> unicast or broadcast traffic with distinction, which is how you
>> originally reported the problem, or maybe that was a bad description of
>> the issue?
> 
> I didn't say anything about unicast vs broadcast.
> 
> When I run the unpatched code, it looks like the PHY negotiates
> only 10 Mbps Half-duplex, then DHCP appears to succeed (IIUC
> only the very first packets are broadcast), and then the system
> hangs trying to mount the root filesystem over NFS.

So maybe you can make sure that your driver properly advertises all the
supported modes by your PHY, for instance, drivers/net/phy/bcm7xxx.c
calls genphy_config_aneg() to make sure that all modes are advertised
(the PHY does not advertise half-duplex modes by default).

> 
> I actually left it running over lunch break, and according
> to the kernel's time stamps, the system seems to have managed
> to mount the root file system after 2000+ seconds.

Ah, so it's doing something after all.

> 
>> Have you checked the Ethernet MAC MIB counters to see if there are any
>> errors reported differently from the working case to the non-working
>> case? What about your link partner, what does it looks like on its end
>> when it does not work?
> 
> Should I use ethtool for this?

Yes. Which might be difficult since you depend on networking to mount
your rootfs, you should probably use an initramfs so you need NFS root
to work.

> 
> Or do it directly with kernel code? (If so which API?)
> 
> The catch is that I need the network to get a running system.
> No network, no root file system.
> 
> Maybe I need to write the kernel to non-volatile storage.
> 
> 
> Going on a wild goose hunt...
> 
> Somewhat related discussion
> https://community.freescale.com/thread/289362
> 
> Let me check how u-boot handles the AR8035.
> http://git.denx.de/?p=u-boot.git;a=blob;f=drivers/net/phy/atheros.c
> 
> static int ar8035_config(struct phy_device *phydev)
> {
> 	int regval;
> 
> 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x0007);
> 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
> 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
> 	regval = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
> 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, (regval|0x0018));
> 
> 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
> 	regval = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
> 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, (regval|0x0100));
> 
> 	phydev->supported = phydev->drv->features;
> 
> 	return 0;
> }
> 
> Data sheet states:
> Register 0xd = "MMD Access Control". 
> Register 0xe = "MMD Access Control Data".
> 
> MMD register access:
> See detail in register description
> example: Write 0x8000 to Register 0 of MMD3
> 1. Write 0x3 to register 0xD: 
> 0xD=0x0003;(function= address; set the device address)
> 2. Write 0x0 to register 0xE: 0xE=0x0; (set the register offset address)
> 3. Write 0x4003 to register 
> 0xD:0xD=0x4003;(function=data; keep the device address)
> 4. Read register 0xE:0xE==(data from register 0x0 of MMD3)
> 5. Write 0x8000 to register 0xE 
> :0xE=0x8000(write 0x8000 to register 0x0 of MMD3)
> Please Note:Read operation please refers to process 1 ~ 4
> 
> Important note:
> CLK_25M default outputs 25MHz, can be configured to
> 50MHz, 62.5MHz, or 125MHz by register MMD7 8016[4:3].
> 
> Ah yes, there it is on page 58:
> Device address = 7, address offset = 0x8016 (Hex)
> 4:3 Select_clk125m
> CLK_25M output clock select
> 00=25M
> 01=50M
> 10=62.5M
> 11=125M
> 
> 
> So...
> 
> 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x0007);
> 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
> 	phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
> 	regval = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
> 	phy_write(phydev, MDIO_DEVAD_NONE, 0xe, (regval|0x0018));
> 
> R[0xd] = 0x0007  ; select MMD7
> R[0xe] = 0x8016  ; offset 0x8016, so 
> R[0xd] = 0x4007  ; select "data, no post increment" for MMD7
> then we read the current value of MMD7/offset=0x8016
> and set bits 3 and 4 on top of that => 125 MHz clock
> 
> HW reset val = 0
> SW reset val = retain previous value
> so the reset in Linux shouldn't affect this...
> 
> 
> 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
> 	regval = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
> 	phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, (regval|0x0100));
> 
> set debug port offset to 5 (DR5)
> read current value
> set bit 8 (rgmii_tx_clk_dly)
> 
> Rgmii tx clock delay control bit:
> 1 = rgmii tx clock delay enable
> 0 = rgmii tx clock delay disable.
> 
> AFAICT, the Linux code doesn't RMW, it just blindly writes
> AT803X_DEBUG_RGMII_TX_CLK_DLY. Dunno if it makes any difference...
> 
> Meh, I'm still grasping at straws...
> 
> Regards.
> 


-- 
Florian

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 19:30                 ` Mason
  2015-04-09 20:26                   ` Florian Fainelli
@ 2015-04-09 22:31                   ` Fabio Estevam
  2015-04-10 10:27                     ` Fabio Estevam
  2015-04-10  9:33                   ` Daniel Mack
  2 siblings, 1 reply; 24+ messages in thread
From: Fabio Estevam @ 2015-04-09 22:31 UTC (permalink / raw)
  To: Mason
  Cc: Florian Fainelli, netdev, Daniel Mack, Mugunthan,
	David S. Miller, Matus Ujhelyi

On Thu, Apr 9, 2015 at 4:30 PM, Mason <slash.tmp@free.fr> wrote:

> Am I the only having problems with the AR8035? :-(
>
> The standard driver works for everyone but me?

Works well on a imx6q-hummingboard:

fec 2188000.ethernet eth0: Freescale FEC PHY driver [Atheros 8035
ethernet] (mii_bus:phy_addr=2188000.ethernet:00, irq=-1)

Regards,

Fabio Estevam

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 19:30                 ` Mason
  2015-04-09 20:26                   ` Florian Fainelli
  2015-04-09 22:31                   ` Fabio Estevam
@ 2015-04-10  9:33                   ` Daniel Mack
  2015-04-10 10:01                     ` Mason
  2 siblings, 1 reply; 24+ messages in thread
From: Daniel Mack @ 2015-04-10  9:33 UTC (permalink / raw)
  To: Mason, Florian Fainelli, netdev; +Cc: Mugunthan, David S. Miller, Matus Ujhelyi

On 04/09/2015 09:30 PM, Mason wrote:> Am I the only having problems with
the AR8035? :-(
>
> The standard driver works for everyone but me?

A company I used to work with ships various hardware models in
quantities which features this chip, and they're using the unpatched
mainline kernel version of the driver.

> Did you take a look at the data sheet? Do you understand the
> difference between "Hardware Reset" and "Software Reset"?

I did, most notably because I was desperately trying to find a sane way
to conduct a full reset of the PHY to work around a confirmed bug in the
DIE of the chip which causes the internal state machine to lock up on
link loss under certain conditions.

Unfortunately, I failed to find a way to really put the chip into
complete reset state through the registers. Instead, I added a
possibility to let the driver pull the hardware reset (see 13a56b4493).

Other than that, however, I didn't encounter any problems.

> Maybe on my PHY, writing BMCR_RESET to BMCR triggers a SW reset,
> while it triggers a HW reset on other boards?

AFAIK, the chip does not do this, no. But even if it did,

> Also, why do you say the PHY is not working? When I apply the
> patch I proposed, it doesn't malfunction.

You're referring to the one that removes the phy init routine?

I'd still go and check if there's anything in one of the chained
bootloaders that does some magic. One other thing that might give you a
hint is to manually pull the RESET line low for a short time right when
the kernel decompressor is started. That way, the kernel has to deal
with a device that has just seen a hardware reset. Just see if that
makes any difference.

Also, some delays in between the register writes during initialization
might also be worth a try. But that's all just random guessing right
now, sorry.


Daniel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-10  9:33                   ` Daniel Mack
@ 2015-04-10 10:01                     ` Mason
  2015-04-10 10:21                       ` Daniel Mack
  0 siblings, 1 reply; 24+ messages in thread
From: Mason @ 2015-04-10 10:01 UTC (permalink / raw)
  To: Daniel Mack, netdev
  Cc: Florian Fainelli, Mugunthan, David S. Miller, Matus Ujhelyi

Daniel Mack wrote:

> Mason wrote:
>
>> Am I the only having problems with the AR8035? :-(
>> The standard driver works for everyone but me?
>
> A company I used to work with ships various hardware models in
> quantities which features this chip, and they're using the unpatched
> mainline kernel version of the driver.

It seems something was done differently on my SoC.
I'll keep looking.

>> Did you take a look at the data sheet? Do you understand the
>> difference between "Hardware Reset" and "Software Reset"?
>
> I did, most notably because I was desperately trying to find a sane way
> to conduct a full reset of the PHY to work around a confirmed bug in the
> DIE of the chip which causes the internal state machine to lock up on
> link loss under certain conditions.
>
> Unfortunately, I failed to find a way to really put the chip into
> complete reset state through the registers. Instead, I added a
> possibility to let the driver pull the hardware reset (see 13a56b4493).
>
> Other than that, however, I didn't encounter any problems.

I wonder what value the CONTROL register was set to on your SoC
after a SW reset. Maybe the "retain value" jiggery-pokery is just
a red herring.

>> Maybe on my PHY, writing BMCR_RESET to BMCR triggers a SW reset,
>> while it triggers a HW reset on other boards?
>
> AFAIK, the chip does not do this, no. But even if it did,

Did you forget to finish that sentence? :-)


>> Also, why do you say the PHY is not working? When I apply the
>> patch I proposed, it doesn't malfunction.
>
> You're referring to the one that removes the phy init routine?

No, the RMW of the CONTROL register for when triggering reset.

> I'd still go and check if there's anything in one of the chained
> bootloaders that does some magic. One other thing that might give you a
> hint is to manually pull the RESET line low for a short time right when
> the kernel decompressor is started. That way, the kernel has to deal
> with a device that has just seen a hardware reset. Just see if that
> makes any difference.

I'd force a HW reset by jiggling the appropriate GPIO pin?
Like you did in the at803x.c driver?

> Also, some delays in between the register writes during initialization
> might also be worth a try. But that's all just random guessing right
> now, sorry.

Thanks for your help, by the way (and Fabio too).

Regards.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-10 10:01                     ` Mason
@ 2015-04-10 10:21                       ` Daniel Mack
  0 siblings, 0 replies; 24+ messages in thread
From: Daniel Mack @ 2015-04-10 10:21 UTC (permalink / raw)
  To: Mason, netdev; +Cc: Florian Fainelli, Mugunthan, David S. Miller, Matus Ujhelyi

On 04/10/2015 12:01 PM, Mason wrote:
> Daniel Mack wrote:

>> A company I used to work with ships various hardware models in
>> quantities which features this chip, and they're using the unpatched
>> mainline kernel version of the driver.

Meh. I just double-checked the references again and figured the final
verions of the hardware design featured a 8030 model, not 8035. Sorry
for that.

So there might be a difference, and maybe the 8035 needs special
treatment. Then again, Fabio said he has a 8035 working.

>>> Maybe on my PHY, writing BMCR_RESET to BMCR triggers a SW reset,
>>> while it triggers a HW reset on other boards?
>>
>> AFAIK, the chip does not do this, no. But even if it did,
> 
> Did you forget to finish that sentence? :-)

Even if it did, the kernel driver should still be able to set up the
device just fine.

>> I'd still go and check if there's anything in one of the chained
>> bootloaders that does some magic. One other thing that might give you a
>> hint is to manually pull the RESET line low for a short time right when
>> the kernel decompressor is started. That way, the kernel has to deal
>> with a device that has just seen a hardware reset. Just see if that
>> makes any difference.
> 
> I'd force a HW reset by jiggling the appropriate GPIO pin?
> Like you did in the at803x.c driver?

Yes. But that's just to gain more ideas where to look for, and possibly
find a pattern.



Daniel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-09 22:31                   ` Fabio Estevam
@ 2015-04-10 10:27                     ` Fabio Estevam
  2015-04-10 15:04                       ` Mason
  0 siblings, 1 reply; 24+ messages in thread
From: Fabio Estevam @ 2015-04-10 10:27 UTC (permalink / raw)
  To: Mason
  Cc: Florian Fainelli, netdev, Daniel Mack, Mugunthan,
	David S. Miller, Matus Ujhelyi

On Thu, Apr 9, 2015 at 7:31 PM, Fabio Estevam <festevam@gmail.com> wrote:
> On Thu, Apr 9, 2015 at 4:30 PM, Mason <slash.tmp@free.fr> wrote:
>
>> Am I the only having problems with the AR8035? :-(
>>
>> The standard driver works for everyone but me?
>
> Works well on a imx6q-hummingboard:
>
> fec 2188000.ethernet eth0: Freescale FEC PHY driver [Atheros 8035
> ethernet] (mii_bus:phy_addr=2188000.ethernet:00, irq=-1)

Forgot to point out that we also have a 8035 fixup in
arch/arm/mach-imx/mach-imx6q.c. Search for ar8035_phy_fixup().

Regards,

Fabio Estevam

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Atheros 8035 PHY only works when at803x_config_init() is commented out
  2015-04-10 10:27                     ` Fabio Estevam
@ 2015-04-10 15:04                       ` Mason
  0 siblings, 0 replies; 24+ messages in thread
From: Mason @ 2015-04-10 15:04 UTC (permalink / raw)
  To: Fabio Estevam
  Cc: Florian Fainelli, netdev, Daniel Mack, Mugunthan,
	David S. Miller, Matus Ujhelyi

Fabio Estevam wrote:
> Fabio Estevam wrote:
>> Mason wrote:
>>
>>> Am I the only having problems with the AR8035? :-(
>>>
>>> The standard driver works for everyone but me?
>>
>> Works well on a imx6q-hummingboard:
>>
>> fec 2188000.ethernet eth0: Freescale FEC PHY driver [Atheros 8035
>> ethernet] (mii_bus:phy_addr=2188000.ethernet:00, irq=-1)

Could you tell me the value of BMCR on entry and exit of phy_init_hw?

> Forgot to point out that we also have a 8035 fixup in
> arch/arm/mach-imx/mach-imx6q.c. Search for ar8035_phy_fixup().

Thanks for the pointer.

Freescale's ar8031_phy_fixup() is almost the same as U-boot's ar8035_config()
The only difference is one extra sanitizing instruction: val &= 0xffe3;

What's the point of masking bits 3 and 4, when they are set by the
next instruction:

   val &= 0xffe3;
   val |= 0x18;

The result of these two operations is
bit2=0 bit3=1 bit4=1 other=unchanged

Bit 2 is undocumented, why does Freescale set it to 0?

The tx clock delay is already done in the generic driver.
Do you know why it is necessary? Why not rx clock delay also?

I'll give the "disable SmartEEE" fixup a try.

Not sure why they reset the POWER_DOWN bit? It's cleared by both
HW and SW resets.

Regards.

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2015-04-10 15:04 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-08 16:28 Atheros 8035 PHY only works when at803x_config_init() is commented out Mason
2015-04-08 17:29 ` Florian Fainelli
2015-04-08 21:37   ` Mason
2015-04-09 11:44   ` Mason
2015-04-09 13:15     ` Mason
2015-04-09 13:36     ` Daniel Mack
2015-04-09 14:38       ` Mason
2015-04-09 15:22         ` Mason
2015-04-09 15:32           ` Daniel Mack
2015-04-09 15:58             ` Mason
2015-04-09 17:25           ` Florian Fainelli
2015-04-09 18:52             ` Mason
2015-04-09 19:00               ` Florian Fainelli
2015-04-09 19:30                 ` Mason
2015-04-09 20:26                   ` Florian Fainelli
2015-04-09 22:10                     ` Mason
2015-04-09 22:30                       ` Florian Fainelli
2015-04-09 22:31                   ` Fabio Estevam
2015-04-10 10:27                     ` Fabio Estevam
2015-04-10 15:04                       ` Mason
2015-04-10  9:33                   ` Daniel Mack
2015-04-10 10:01                     ` Mason
2015-04-10 10:21                       ` Daniel Mack
2015-04-09 19:05       ` Mason

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.