public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* How to approach slow firmware loading process?
@ 2026-03-20 16:48 Patryk
  2026-03-20 21:44 ` Andrew Lunn
  0 siblings, 1 reply; 2+ messages in thread
From: Patryk @ 2026-03-20 16:48 UTC (permalink / raw)
  To: netdev

Hello
I've been working on a 10G QXGMII Ethernet PHY bring-up and stumbled
upon a problem.
One of the first steps in the bring-up sequence is to load the PHY's firmware.
So the sequence is as follows:
1) For each port (phy_device) the PHY layer calls the driver's probe
function. In this function I check the port index number and calculate
phy base addr. Then I connect this phydev into the phy package using
devm_phy_package_join.
2) Then the PHY layer calls the config_init. In the config_init I use
phy_package_init_once to check whether the common init function has
already been called. If not then I call the common init function that
is responsible for broadcasting firmware to all ports of the PHY.
And this is the place where things get problematic. The thing is that
loading firmware takes ages... namely around 30 seconds, which results
in the boot process waiting for config_init to complete its execution.
The firmware size is around 300 kB. I've also done some tests using a
vendor userspace tool that also has fw loading capability and in
general it takes the same time.

I'm wondering how I should approach this? I obviously don't want to
block the boot process until the PHY's firmware is loaded. The one
thing that comes to my mind is to submit firmware loading to workqueue
and just return success from config_init. The problem is that in every
other function like read_status, config_aneg and so on I will have to
check whether or not the firmware has already been loaded and it's up
and running. Technically that is feasible however it sounds to me like
kind of a workaround, especially given the fact that if I decide to
submit firmware loading to workqueue I will have to return success
from config_init so I guess that phy layer in the kernel will assume
that everything works fine which in fact may not be true if e.g. fw
loading procedure fail or the phy will not bring up after the reset.

How would you approach this? I will be grateful  for some suggestions.

Best regards
Patryk

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

* Re: How to approach slow firmware loading process?
  2026-03-20 16:48 How to approach slow firmware loading process? Patryk
@ 2026-03-20 21:44 ` Andrew Lunn
  0 siblings, 0 replies; 2+ messages in thread
From: Andrew Lunn @ 2026-03-20 21:44 UTC (permalink / raw)
  To: Patryk; +Cc: netdev

On Fri, Mar 20, 2026 at 05:48:05PM +0100, Patryk wrote:
> Hello
> I've been working on a 10G QXGMII Ethernet PHY bring-up and stumbled
> upon a problem.

It is a good idea to Cc: the PHY Maintainers when you have a PHY
problem.

Also, you were lucky that i even read this, because the subject has
nothing in it to suggest it is PHY problem...

> 2) Then the PHY layer calls the config_init. In the config_init I use
> phy_package_init_once to check whether the common init function has
> already been called. If not then I call the common init function that
> is responsible for broadcasting firmware to all ports of the PHY.
> And this is the place where things get problematic. The thing is that
> loading firmware takes ages... namely around 30 seconds, which results
> in the boot process waiting for config_init to complete its execution.

This is not a simple problem to solve, apart from buying some FLASH
for your PHY chip :-)

Historically, PHY devices have not needed firmware downloaded. This
lead to assumptions being made about when a PHY is assumed to be
usable.

MAC drivers typically connect to the PHY in open(), not probe(). In
probe(), if the PHY has not registered itself yet, because it is still
probing, i.e. downloading firmware, you could return -EPROBE_DEFER and
get the core to try again later. In open() it is too late, you cannot
return -EPROBE_DEFER you have to fail the open() which is not supposed
to happen.

And as you pointed out, phylib assumes that as soon as
probe()/config_init() returns, the PHY is good to go. So if you did
return from config_init(), with the PHY still downloading firmware,
you are going to get into a bad situation later on.

There are a few things you can try to speed it up.

Check if the MDIO bus supports running at a faster speed. A few
drivers support the "clock-frequency" property. It should default to
2.5Mhz. But many PHYs will works at higher speeds. Check the
datasheet. It might be the MDIO driver you are using does not
implement this property, and you will need to see if it can be added.

I've achieved 3x speed up playing around with this.

Another thing you can sometimes do is disable the preamble. An MDIO
bus transaction starts with 32 bits of preamble. But some PHYs are
happy without it. If you can turn it off, you send 50% less.

Combine these two, and you can get a 6x speed up.

Another thing to do is check the maths. One C22 MDIO transaction is 64
bits. Assuming a 2.5Mhz clock, you can work out how long that
takes. Look at the download protocol, is it efficient, 1 transaction
for very 2 bytes? You can work out the theoretical time it takes.
Then compare to what it actually takes. Because normally very few MDIO
bus transactions are performed, the implementation is not always
tuned. Sometimes the polling for the transaction to complete is too
large, for example. So you might be able to make the basic write
operation faster.

       Andrew

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

end of thread, other threads:[~2026-03-20 21:44 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-20 16:48 How to approach slow firmware loading process? Patryk
2026-03-20 21:44 ` Andrew Lunn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox