From: Aleksei Sviridkin <f@lex.la>
To: netdev@vger.kernel.org
Cc: andrew@lunn.ch, hkallweit1@gmail.com, linux@armlinux.org.uk,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, Aleksei Sviridkin <f@lex.la>
Subject: [RFC PATCH net-next 5/9] net: phy: air: skip the download when the MD32 is already running
Date: Sat, 29 Aug 2026 05:25:42 +0000 [thread overview]
Message-ID: <20260829052546.1152446-6-f@lex.la> (raw)
In-Reply-To: <20260829052546.1152446-1-f@lex.la>
The download is unconditional, so a chip whose firmware was loaded by
something else - a bootloader, an earlier bind of the PHY driver, or
an MDIO device serving the chip - is reprogrammed with what it is
already running, at 144KB per probe.
Read the status register the loader already polls for readiness and
skip the download when it reports ready, only picking up the running
firmware's version. The wait that follows is what makes this safe: a
chip that was not in fact running fails there instead of coming up
misprogrammed.
Living in the shared helper, the check covers every caller, and it is
what lets the PHY driver and the coming MDIO device driver coexist:
whichever runs second finds the firmware already up and leaves it
alone.
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
---
drivers/net/phy/air_en8811h.c | 5 ++++-
drivers/net/phy/air_phy_lib.c | 28 ++++++++++++++++++++++++++++
drivers/net/phy/air_phy_lib.h | 1 +
3 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/air_en8811h.c b/drivers/net/phy/air_en8811h.c
index fdc64362a565..fcc6e373edd6 100644
--- a/drivers/net/phy/air_en8811h.c
+++ b/drivers/net/phy/air_en8811h.c
@@ -1030,7 +1030,10 @@ static int en8811h_probe(struct phy_device *phydev)
if (ret < 0)
return ret;
- /* mcu has just restarted after firmware load */
+ /* Freshly downloaded firmware has just started; firmware adopted
+ * from the bootloader is already past its own start. Neither needs
+ * the restart a later resume would.
+ */
priv->mcu_needs_restart = false;
/* MDIO_DEVS1/2 empty, so set mmds_present bits here */
diff --git a/drivers/net/phy/air_phy_lib.c b/drivers/net/phy/air_phy_lib.c
index 1ed5c69d7073..c1187f357f4c 100644
--- a/drivers/net/phy/air_phy_lib.c
+++ b/drivers/net/phy/air_phy_lib.c
@@ -374,6 +374,12 @@ static int air_mmd_status_read(struct mii_bus *bus, int addr, bool is_c45)
return ret;
}
+bool air_en8811h_mcu_running(struct mii_bus *bus, int addr, bool is_c45)
+{
+ return air_mmd_status_read(bus, addr, is_c45) == EN8811H_PHY_READY;
+}
+EXPORT_SYMBOL_GPL(air_en8811h_mcu_running);
+
int air_en8811h_wait_mcu_ready(struct mii_bus *bus, int addr, bool is_c45,
struct device *dev)
{
@@ -409,6 +415,28 @@ int air_en8811h_fw_download(struct mii_bus *bus, int addr, bool is_c45,
const struct firmware *fw1, *fw2;
int ret;
+ if (air_en8811h_mcu_running(bus, addr, is_c45)) {
+ /* Loaded by a bootloader, an earlier bind, or another
+ * device serving the chip. The wait below is what makes
+ * trusting the status register safe: a chip that was not
+ * in fact running fails there instead of coming up
+ * misprogrammed.
+ */
+ ret = air_en8811h_wait_mcu_ready(bus, addr, is_c45, dev);
+ if (ret < 0)
+ return ret;
+
+ ret = air_mdio_buckpbus_reg_read(bus, addr,
+ EN8811H_FW_VERSION,
+ fw_version);
+ if (ret < 0)
+ return ret;
+
+ dev_info(dev, "MD32 already running, firmware %08x\n",
+ *fw_version);
+ return 0;
+ }
+
ret = request_firmware_direct(&fw1, EN8811H_MD32_DM, dev);
if (ret < 0)
return ret;
diff --git a/drivers/net/phy/air_phy_lib.h b/drivers/net/phy/air_phy_lib.h
index 6b11dbeaea9b..8d9f24da1271 100644
--- a/drivers/net/phy/air_phy_lib.h
+++ b/drivers/net/phy/air_phy_lib.h
@@ -59,6 +59,7 @@ struct firmware;
int air_fw_write_buf(struct mii_bus *bus, int addr, u32 address,
const struct firmware *fw);
+bool air_en8811h_mcu_running(struct mii_bus *bus, int addr, bool is_c45);
int air_en8811h_wait_mcu_ready(struct mii_bus *bus, int addr, bool is_c45,
struct device *dev);
int air_en8811h_fw_download(struct mii_bus *bus, int addr, bool is_c45,
--
2.53.0
next prev parent reply other threads:[~2026-08-29 5:26 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-29 5:25 [RFC PATCH net-next 0/9] net: survive a PHY whose firmware arrives after the MAC probes Aleksei Sviridkin
2026-08-29 5:25 ` [RFC PATCH net-next 1/9] dt-bindings: net: add Airoha EN8811H PHY MCU Aleksei Sviridkin
2026-08-29 5:25 ` [RFC PATCH net-next 2/9] dt-bindings: net: ethernet-controller: add slow-to-probe Aleksei Sviridkin
2026-08-30 5:26 ` sashiko-bot
2026-09-04 0:29 ` Andrew Lunn
2026-08-29 5:25 ` [RFC PATCH net-next 3/9] net: phy: air: type the buckpbus core on the bus and address Aleksei Sviridkin
2026-09-04 0:48 ` Andrew Lunn
2026-08-29 5:25 ` [RFC PATCH net-next 4/9] net: phy: air: move the EN8811H firmware download into the library Aleksei Sviridkin
2026-09-04 1:16 ` Andrew Lunn
2026-08-29 5:25 ` Aleksei Sviridkin [this message]
2026-08-29 5:25 ` [RFC PATCH net-next 6/9] net: mdio: add Airoha EN8811H MDIO device driver Aleksei Sviridkin
2026-08-30 5:26 ` sashiko-bot
2026-09-04 1:36 ` Andrew Lunn
2026-08-29 5:25 ` [RFC PATCH net-next 7/9] net: mdio: en8811h: add the nested pass-through bus Aleksei Sviridkin
2026-09-04 1:43 ` Andrew Lunn
2026-08-29 5:25 ` [RFC PATCH net-next 8/9] net: phylink: wait for PHYs that are known to probe late Aleksei Sviridkin
2026-08-30 5:26 ` sashiko-bot
2026-08-29 5:25 ` [RFC PATCH net-next 9/9] net: phylink: report no link modes while a late PHY is missing Aleksei Sviridkin
2026-08-30 5:26 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260829052546.1152446-6-f@lex.la \
--to=f@lex.la \
--cc=andrew@lunn.ch \
--cc=conor+dt@kernel.org \
--cc=davem@davemloft.net \
--cc=devicetree@vger.kernel.org \
--cc=edumazet@google.com \
--cc=hkallweit1@gmail.com \
--cc=krzk+dt@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.