Subject: Help on PHY not supporting autoneg

From: Piergiorgio Beruto <[email-masked]>
Date: Wed, 30 Nov 2022 13:16:02 +0100

Hello netdev group,
I am looking for someone willing to help me on a problem I encountered
while trying to implement a driver for a PHY that does not support
autoneg. On my reference HW, the PHY is connected to a stmmac via MII.

This is what I did in the driver:
- implement get_features to report NO AN support, and the supported link
  modes.
- implement the IRQ handling (config_intr and handle_interrupt) to
  report the link status

The first problem I encountered is: how to start the PHY? The device
requires a bit (LINK_CONTROL) to be enabled before trying to bring up
the link. But I could not find any obvious callback from phylib to
actually do this. Eventually, I opted for implementing the
suspend/resume callbacks and set that bit in there. Is that right? Any
better option?

With that said, the thing still does not work as I would expect. When I
ifconfig up my device, here's what happens (the ncn_* prints are just
debug prinktks I've added to show the problem). See also my comments in
the log marked with //

/root # ifconfig eth0 up
[   26.950557] socfpga-dwmac ff700000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0
[   26.962673] ncn_soft_reset
[   26.966345] ncn_config_init
[   26.969168] ncn_config_intr
[   26.972211] disable IRQs   // OK, this is expected, phylib is resetting the device
[   26.975062] ncn_resume     // not sure I expected this to be here, but it does not harm
[   26.977746] socfpga-dwmac ff700000.ethernet eth0: PHY [stmmac-0:08] driver [NCN26000] (irq=49)
[   26.986861] ncn_config_intr
[   26.990045] ncn_config_intr ret = 8000, irqs = 0001
[   26.994958] ncn_handle_interrupt 8000
[   26.998941] ncn_handle_interrupt 8001
[   27.002752] link = 1, ret = 0829       // there I get a link UP!
[   27.016526] dwmac1000: Master AXI performs any burst length
[   27.022128] socfpga-dwmac ff700000.ethernet eth0: No Safety Features support found
[   27.029999] socfpga-dwmac ff700000.ethernet eth0: IEEE 1588-2008 Advanced Timestamp supported
[   27.039425] socfpga-dwmac ff700000.ethernet eth0: registered PTP clock
[   27.049388] socfpga-dwmac ff700000.ethernet eth0: configuring for phy/mii link mode
[   27.057155] ncn_resume  // I don't fully understand what happened since the link up, but it seems the MAC is doing more initialization
[   27.061251] ncn_handle_interrupt 8001
[   27.065100] link = 0, ret = 0809 // here I get a link down (???)

>From there on, if I read the LINK_CONTROL bit, someone set it to 0 (???)
This bit lies in the control register (Clause 22, address 0).

/root # mdio-tool -i eth0 -r -a 0
clause 22 register @eth0 0x0000 --> 0x0000   // ????? That explains the link down, though

If I manually set the LINK_CONTROL bit, then I magically get the link up

/root # mdio-tool -i eth0 -w -a 0 0x1000
[   81.276504] ncn_handle_interrupt 8001
[   81.280345] link = 1, ret = 0829
clause 22 register @eth0 0x0000 <-- 0x1000[   81.284442] socfpga-dwmac ff700000.ethernet eth0: No phy led trigger registered for speed(10)

/root # [   81.297690] socfpga-dwmac ff700000.ethernet eth0: Link is Up - 10Mbps/Half - flow control off

I've also tried a completely different approach, that is "emulating"
autoneg by implementing the config_aneg, aneg_done and read_status
callbacks. If I do this, then my driver works just fine and nobody seems
to be overwriting register 0.

Any clue on what I might be doing wrong here?

Thank you in advance for any help you might provide.
Regards,
Piergiorgio