* [PATCH net-next 0/3] r8169: handle firmware application errors
@ 2026-09-16 15:24 Matheus Alves de Almeida
2026-09-16 15:24 ` [PATCH net-next 1/3] r8169: propagate errors from PHY write operations Matheus Alves de Almeida
` (2 more replies)
0 siblings, 3 replies; 15+ messages in thread
From: Matheus Alves de Almeida @ 2026-09-16 15:24 UTC (permalink / raw)
To: Heiner Kallweit, nic_swsd
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, netdev, linux-kernel, Matheus Alves de Almeida
Propagate PHY read/write errors through the firmware interpreter and
release loaded firmware if application fails.
This resolves the existing TODO in r8169_apply_firmware().
Matheus Alves de Almeida (3):
r8169: propagate errors from PHY write operations
r8169: propagate firmware access errors
r8169: release firmware on application failure
drivers/net/ethernet/realtek/r8169_firmware.c | 15 ++++--
drivers/net/ethernet/realtek/r8169_firmware.h | 4 +-
drivers/net/ethernet/realtek/r8169_main.c | 50 +++++++++++--------
3 files changed, 43 insertions(+), 26 deletions(-)
base-commit: 87b80c2f6b05cad9f0ff9136709c62a0f59923e3
--
2.43.0
^ permalink raw reply [flat|nested] 15+ messages in thread* [PATCH net-next 1/3] r8169: propagate errors from PHY write operations 2026-09-16 15:24 [PATCH net-next 0/3] r8169: handle firmware application errors Matheus Alves de Almeida @ 2026-09-16 15:24 ` Matheus Alves de Almeida 2026-09-16 18:38 ` Andrew Lunn 2026-09-16 15:24 ` [PATCH net-next 2/3] r8169: propagate firmware access errors Matheus Alves de Almeida 2026-09-16 15:24 ` [PATCH net-next 3/3] r8169: release firmware on application failure Matheus Alves de Almeida 2 siblings, 1 reply; 15+ messages in thread From: Matheus Alves de Almeida @ 2026-09-16 15:24 UTC (permalink / raw) To: Heiner Kallweit, nic_swsd Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, Matheus Alves de Almeida Currently, hardware timeouts and other errors are ignored during PHY write operations. Return an error when these operations fail and propagate it through rtl_writephy(). Signed-off-by: Matheus Alves de Almeida <matheus.aalmeida@inf.ufrgs.br> --- drivers/net/ethernet/realtek/r8169_firmware.h | 2 +- drivers/net/ethernet/realtek/r8169_main.c | 44 +++++++++++-------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_firmware.h b/drivers/net/ethernet/realtek/r8169_firmware.h index 7dc348ed8..1285a1c28 100644 --- a/drivers/net/ethernet/realtek/r8169_firmware.h +++ b/drivers/net/ethernet/realtek/r8169_firmware.h @@ -12,7 +12,7 @@ #include <linux/firmware.h> struct rtl8169_private; -typedef void (*rtl_fw_write_t)(struct rtl8169_private *tp, int reg, int val); +typedef int (*rtl_fw_write_t)(struct rtl8169_private *tp, int reg, int val); typedef int (*rtl_fw_read_t)(struct rtl8169_private *tp, int reg); #define RTL_VER_SIZE 32 diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 5415ff62a..3c37c5a6c 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -1145,14 +1145,15 @@ DECLARE_RTL_COND(rtl_ocp_gphy_cond) return RTL_R32(tp, GPHY_OCP) & OCPAR_FLAG; } -static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) +static int r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) { if (rtl_ocp_reg_failure(reg)) - return; + return 0; RTL_W32(tp, GPHY_OCP, OCPAR_FLAG | (reg << 15) | data); - rtl_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10); + return rtl_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10) ? + 0 : -ETIMEDOUT; } static int r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg) @@ -1337,11 +1338,11 @@ static void rtl8168g_phy_suspend_quirk(struct rtl8169_private *tp, int value) } }; -static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value) +static int r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value) { if (reg == 0x1f) { tp->ocp_base = value ? value << 4 : OCP_STD_PHY_BASE; - return; + return 0; } if (tp->ocp_base != OCP_STD_PHY_BASE) @@ -1350,7 +1351,7 @@ static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value) if (tp->ocp_base == OCP_STD_PHY_BASE && reg == MII_BMCR) rtl8168g_phy_suspend_quirk(tp, value); - r8168_phy_ocp_write(tp, tp->ocp_base + reg * 2, value); + return r8168_phy_ocp_write(tp, tp->ocp_base + reg * 2, value); } static int r8168g_mdio_read(struct rtl8169_private *tp, int reg) @@ -1364,14 +1365,15 @@ static int r8168g_mdio_read(struct rtl8169_private *tp, int reg) return r8168_phy_ocp_read(tp, tp->ocp_base + reg * 2); } -static void mac_mcu_write(struct rtl8169_private *tp, int reg, int value) +static int mac_mcu_write(struct rtl8169_private *tp, int reg, int value) { if (reg == 0x1f) { tp->ocp_base = value << 4; - return; + return 0; } r8168_mac_ocp_write(tp, tp->ocp_base + reg, value); + return 0; } static bool rtl_is_8116af(struct rtl8169_private *tp) @@ -1393,16 +1395,19 @@ DECLARE_RTL_COND(rtl_phyar_cond) return RTL_R32(tp, PHYAR) & 0x80000000; } -static void r8169_mdio_write(struct rtl8169_private *tp, int reg, int value) +static int r8169_mdio_write(struct rtl8169_private *tp, int reg, int value) { RTL_W32(tp, PHYAR, 0x80000000 | (reg & 0x1f) << 16 | (value & 0xffff)); - rtl_loop_wait_low(tp, &rtl_phyar_cond, 25, 20); + if (!rtl_loop_wait_low(tp, &rtl_phyar_cond, 25, 20)) + return -ETIMEDOUT; /* * According to hardware specs a 20us delay is required after write * complete indication, but before sending next command. */ udelay(20); + + return 0; } static int r8169_mdio_read(struct rtl8169_private *tp, int reg) @@ -1440,13 +1445,17 @@ static void r8168dp_2_mdio_stop(struct rtl8169_private *tp) RTL_W32(tp, 0xd0, RTL_R32(tp, 0xd0) | R8168DP_1_MDIO_ACCESS_BIT); } -static void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg, int value) +static int r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg, int value) { + int rc; + r8168dp_2_mdio_start(tp); - r8169_mdio_write(tp, reg, value); + rc = r8169_mdio_write(tp, reg, value); r8168dp_2_mdio_stop(tp); + + return rc; } static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg) @@ -1466,19 +1475,16 @@ static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg) return value; } -static void rtl_writephy(struct rtl8169_private *tp, int location, int val) +static int rtl_writephy(struct rtl8169_private *tp, int location, int val) { switch (tp->mac_version) { case RTL_GIGA_MAC_VER_28: case RTL_GIGA_MAC_VER_31: - r8168dp_2_mdio_write(tp, location, val); - break; + return r8168dp_2_mdio_write(tp, location, val); case RTL_GIGA_MAC_VER_40 ... RTL_GIGA_MAC_VER_LAST: - r8168g_mdio_write(tp, location, val); - break; + return r8168g_mdio_write(tp, location, val); default: - r8169_mdio_write(tp, location, val); - break; + return r8169_mdio_write(tp, location, val); } } -- 2.43.0 ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 1/3] r8169: propagate errors from PHY write operations 2026-09-16 15:24 ` [PATCH net-next 1/3] r8169: propagate errors from PHY write operations Matheus Alves de Almeida @ 2026-09-16 18:38 ` Andrew Lunn 2026-09-16 21:10 ` Matheus Alves de Almeida 0 siblings, 1 reply; 15+ messages in thread From: Andrew Lunn @ 2026-09-16 18:38 UTC (permalink / raw) To: Matheus Alves de Almeida Cc: Heiner Kallweit, nic_swsd, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel > -static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) > +static int r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) > { > if (rtl_ocp_reg_failure(reg)) > - return; > + return 0; > > RTL_W32(tp, GPHY_OCP, OCPAR_FLAG | (reg << 15) | data); > > - rtl_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10); > + return rtl_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10) ? > + 0 : -ETIMEDOUT; Maybe rewrite rtl_loop_wait_low(), _high() and rtl_loop_wait() to use iopoll.h? Andrew ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 1/3] r8169: propagate errors from PHY write operations 2026-09-16 18:38 ` Andrew Lunn @ 2026-09-16 21:10 ` Matheus Alves de Almeida 2026-09-16 21:14 ` Andrew Lunn 0 siblings, 1 reply; 15+ messages in thread From: Matheus Alves de Almeida @ 2026-09-16 21:10 UTC (permalink / raw) To: Andrew Lunn Cc: Heiner Kallweit, nic_swsd, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel > Maybe rewrite rtl_loop_wait_low(), _high() and rtl_loop_wait() to use > iopoll.h? While I don’t think this fits the scope of this series, I’d be willing to look into it as a follow-up. Matheus Alves de Almeida ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 1/3] r8169: propagate errors from PHY write operations 2026-09-16 21:10 ` Matheus Alves de Almeida @ 2026-09-16 21:14 ` Andrew Lunn 2026-09-16 21:19 ` Matheus Alves de Almeida 0 siblings, 1 reply; 15+ messages in thread From: Andrew Lunn @ 2026-09-16 21:14 UTC (permalink / raw) To: Matheus Alves de Almeida Cc: Heiner Kallweit, nic_swsd, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel On Wed, Sep 16, 2026 at 06:10:00PM -0300, Matheus Alves de Almeida wrote: > > Maybe rewrite rtl_loop_wait_low(), _high() and rtl_loop_wait() to use > > iopoll.h? > > While I don’t think this fits the scope of this series, I’d be willing > to look into it as a follow-up. You trimmed too much context. The nice thing about iopoll.h is that they all return -ETIMEDOUT, or some other error code on error. So your current patch looking at the Boolean return value becomes redundant, you just follow the normal pattern: ret = rtl_loop_wait_low(); if (ret) return ret; So i think this is in scope, otherwise you are going to rewrite 90% of this patch when you do introduce it. Andrew ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 1/3] r8169: propagate errors from PHY write operations 2026-09-16 21:14 ` Andrew Lunn @ 2026-09-16 21:19 ` Matheus Alves de Almeida 0 siblings, 0 replies; 15+ messages in thread From: Matheus Alves de Almeida @ 2026-09-16 21:19 UTC (permalink / raw) To: Andrew Lunn Cc: Heiner Kallweit, nic_swsd, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel On 2026-09-16 18:14, Andrew Lunn Wrote: > On Wed, Sep 16, 2026 at 06:10:00PM -0300, Matheus Alves de Almeida wrote: >> > Maybe rewrite rtl_loop_wait_low(), _high() and rtl_loop_wait() to use >> > iopoll.h? >> >> While I don’t think this fits the scope of this series, I’d be willing >> to look into it as a follow-up. > > You trimmed too much context. > > The nice thing about iopoll.h is that they all return -ETIMEDOUT, or > some other error code on error. So your current patch looking at the > Boolean return value becomes redundant, you just follow the normal > pattern: > > ret = rtl_loop_wait_low(); > if (ret) > return ret; > > So i think this is in scope, otherwise you are going to rewrite 90% of > this patch when you do introduce it. > > Andrew Sorry about trimming too much context. That makes sense. I was thinking of the iopoll.h conversion primarily as cleanup. I’ll rework this for v2. ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH net-next 2/3] r8169: propagate firmware access errors 2026-09-16 15:24 [PATCH net-next 0/3] r8169: handle firmware application errors Matheus Alves de Almeida 2026-09-16 15:24 ` [PATCH net-next 1/3] r8169: propagate errors from PHY write operations Matheus Alves de Almeida @ 2026-09-16 15:24 ` Matheus Alves de Almeida 2026-09-16 15:24 ` [PATCH net-next 3/3] r8169: release firmware on application failure Matheus Alves de Almeida 2 siblings, 0 replies; 15+ messages in thread From: Matheus Alves de Almeida @ 2026-09-16 15:24 UTC (permalink / raw) To: Heiner Kallweit, nic_swsd Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, Matheus Alves de Almeida rtl_fw_write_firmware() does not check errors returned from fw_write() and fw_read(), nor does it report failures to its caller. Change rtl_fw_write_firmware() to return an int and propagate errors from fw_write() and fw_read(). Signed-off-by: Matheus Alves de Almeida <matheus.aalmeida@inf.ufrgs.br> --- drivers/net/ethernet/realtek/r8169_firmware.c | 15 ++++++++++++--- drivers/net/ethernet/realtek/r8169_firmware.h | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_firmware.c b/drivers/net/ethernet/realtek/r8169_firmware.c index 6dff3d947..645d510e6 100644 --- a/drivers/net/ethernet/realtek/r8169_firmware.c +++ b/drivers/net/ethernet/realtek/r8169_firmware.c @@ -137,7 +137,7 @@ static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw) return false; } -void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) +int rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) { struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; rtl_fw_write_t fw_write = rtl_fw->phy_write; @@ -150,10 +150,13 @@ void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) u32 data = action & 0x0000ffff; u32 regno = (action & 0x0fff0000) >> 16; enum rtl_fw_opcode opcode = action >> 28; + int rc; switch (opcode) { case PHY_READ: predata = fw_read(tp, regno); + if (predata < 0) + return predata; count++; break; case PHY_DATA_OR: @@ -179,7 +182,9 @@ void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) count = 0; break; case PHY_WRITE: - fw_write(tp, regno, data); + rc = fw_write(tp, regno, data); + if (rc < 0) + return rc; break; case PHY_READCOUNT_EQ_SKIP: if (count == data) @@ -194,7 +199,9 @@ void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) index += regno; break; case PHY_WRITE_PREVIOUS: - fw_write(tp, regno, predata); + rc = fw_write(tp, regno, predata); + if (rc < 0) + return rc; break; case PHY_SKIPN: index += regno; @@ -204,6 +211,8 @@ void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) break; } } + + return 0; } void rtl_fw_release_firmware(struct rtl_fw *rtl_fw) diff --git a/drivers/net/ethernet/realtek/r8169_firmware.h b/drivers/net/ethernet/realtek/r8169_firmware.h index 1285a1c28..36c89bfda 100644 --- a/drivers/net/ethernet/realtek/r8169_firmware.h +++ b/drivers/net/ethernet/realtek/r8169_firmware.h @@ -36,4 +36,4 @@ struct rtl_fw { int rtl_fw_request_firmware(struct rtl_fw *rtl_fw); void rtl_fw_release_firmware(struct rtl_fw *rtl_fw); -void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw); +int rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw); -- 2.43.0 ^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH net-next 3/3] r8169: release firmware on application failure 2026-09-16 15:24 [PATCH net-next 0/3] r8169: handle firmware application errors Matheus Alves de Almeida 2026-09-16 15:24 ` [PATCH net-next 1/3] r8169: propagate errors from PHY write operations Matheus Alves de Almeida 2026-09-16 15:24 ` [PATCH net-next 2/3] r8169: propagate firmware access errors Matheus Alves de Almeida @ 2026-09-16 15:24 ` Matheus Alves de Almeida 2026-09-16 18:42 ` Andrew Lunn 2 siblings, 1 reply; 15+ messages in thread From: Matheus Alves de Almeida @ 2026-09-16 15:24 UTC (permalink / raw) To: Heiner Kallweit, nic_swsd Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel, Matheus Alves de Almeida After an rtl_fw_write_firmware() failure, r8169_apply_firmware() does not release the firmware. A TODO notes that it should be released in this case. Release the firmware on failure and remove the TODO. Signed-off-by: Matheus Alves de Almeida <matheus.aalmeida@inf.ufrgs.br> --- drivers/net/ethernet/realtek/r8169_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 3c37c5a6c..c54423cd2 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -2596,12 +2596,14 @@ void r8169_apply_firmware(struct rtl8169_private *tp) { int val; - /* TODO: release firmware if rtl_fw_write_firmware signals failure. */ if (tp->rtl_fw) { - rtl_fw_write_firmware(tp, tp->rtl_fw); + int rc = rtl_fw_write_firmware(tp, tp->rtl_fw); /* At least one firmware doesn't reset tp->ocp_base. */ tp->ocp_base = OCP_STD_PHY_BASE; + if (rc < 0) + rtl_release_firmware(tp); + /* PHY soft reset may still be in progress */ if (tp->phydev) phy_read_poll_timeout(tp->phydev, MII_BMCR, val, -- 2.43.0 ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 3/3] r8169: release firmware on application failure 2026-09-16 15:24 ` [PATCH net-next 3/3] r8169: release firmware on application failure Matheus Alves de Almeida @ 2026-09-16 18:42 ` Andrew Lunn 2026-09-16 21:15 ` Matheus Alves de Almeida 0 siblings, 1 reply; 15+ messages in thread From: Andrew Lunn @ 2026-09-16 18:42 UTC (permalink / raw) To: Matheus Alves de Almeida Cc: Heiner Kallweit, nic_swsd, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel On Wed, Sep 16, 2026 at 12:24:44PM -0300, Matheus Alves de Almeida wrote: > After an rtl_fw_write_firmware() failure, r8169_apply_firmware() does > not release the firmware. A TODO notes that it should be released > in this case. > > Release the firmware on failure and remove the TODO. > > Signed-off-by: Matheus Alves de Almeida <matheus.aalmeida@inf.ufrgs.br> > --- > drivers/net/ethernet/realtek/r8169_main.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c > index 3c37c5a6c..c54423cd2 100644 > --- a/drivers/net/ethernet/realtek/r8169_main.c > +++ b/drivers/net/ethernet/realtek/r8169_main.c > @@ -2596,12 +2596,14 @@ void r8169_apply_firmware(struct rtl8169_private *tp) > { > int val; > > - /* TODO: release firmware if rtl_fw_write_firmware signals failure. */ > if (tp->rtl_fw) { > - rtl_fw_write_firmware(tp, tp->rtl_fw); > + int rc = rtl_fw_write_firmware(tp, tp->rtl_fw); > /* At least one firmware doesn't reset tp->ocp_base. */ > tp->ocp_base = OCP_STD_PHY_BASE; > > + if (rc < 0) > + rtl_release_firmware(tp); > + > /* PHY soft reset may still be in progress */ > if (tp->phydev) > phy_read_poll_timeout(tp->phydev, MII_BMCR, val, If the firmware cannot be written, is the device dead? Should this return an error, so the caller can abort the probe? Andrew ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 3/3] r8169: release firmware on application failure 2026-09-16 18:42 ` Andrew Lunn @ 2026-09-16 21:15 ` Matheus Alves de Almeida 2026-09-16 22:02 ` Andrew Lunn 0 siblings, 1 reply; 15+ messages in thread From: Matheus Alves de Almeida @ 2026-09-16 21:15 UTC (permalink / raw) To: Andrew Lunn Cc: Heiner Kallweit, nic_swsd, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel > If the firmware cannot be written, is the device dead? Should this > return an error, so the caller can abort the probe? A timeout while applying firmware could indeed indicate a PHY access problem. However, firmware loading failures are already non-fatal, and the callers of r8169_apply_firmware() do not propagate errors either. Making firmware application failures fatal would require broader changes to several r8169 PHY initialization paths. ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 3/3] r8169: release firmware on application failure 2026-09-16 21:15 ` Matheus Alves de Almeida @ 2026-09-16 22:02 ` Andrew Lunn 2026-09-16 22:21 ` Matheus Alves de Almeida 2026-09-17 2:19 ` Matheus Alves de Almeida 0 siblings, 2 replies; 15+ messages in thread From: Andrew Lunn @ 2026-09-16 22:02 UTC (permalink / raw) To: Matheus Alves de Almeida Cc: Heiner Kallweit, nic_swsd, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel On Wed, Sep 16, 2026 at 06:15:00PM -0300, Matheus Alves de Almeida wrote: > > If the firmware cannot be written, is the device dead? Should this > > return an error, so the caller can abort the probe? > > A timeout while applying firmware could indeed indicate a PHY access > problem. However, firmware loading failures are already non-fatal, > and the callers of r8169_apply_firmware() do not propagate errors > either. Making firmware application failures fatal would require > broader changes to several r8169 PHY initialization paths. But you are making such changes, returning errors up the call chain. Why are you making these changes? We either assume nothing can fail, so we throw away the return code, or we should assume everything can fail, and propagate the errors. If we assume error can happen, if there is an error in firmware download, isn't that fatal? Should we even care about care about PHY read/write errors if firmware download has failed? And since firmware download is probably the first thing to happen, if anything is likely to fair, i would expect firmware download is what is going to fail. Andrew ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 3/3] r8169: release firmware on application failure 2026-09-16 22:02 ` Andrew Lunn @ 2026-09-16 22:21 ` Matheus Alves de Almeida 2026-09-17 2:19 ` Matheus Alves de Almeida 1 sibling, 0 replies; 15+ messages in thread From: Matheus Alves de Almeida @ 2026-09-16 22:21 UTC (permalink / raw) To: Andrew Lunn Cc: Heiner Kallweit, nic_swsd, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel On 2026-09-16 19:02, Andrew Lunn wrote: > On Wed, Sep 16, 2026 at 06:15:00PM -0300, Matheus Alves de Almeida wrote: >> > If the firmware cannot be written, is the device dead? Should this >> > return an error, so the caller can abort the probe? >> >> A timeout while applying firmware could indeed indicate a PHY access >> problem. However, firmware loading failures are already non-fatal, >> and the callers of r8169_apply_firmware() do not propagate errors >> either. Making firmware application failures fatal would require >> broader changes to several r8169 PHY initialization paths. > > But you are making such changes, returning errors up the call chain. > Why are you making these changes? We either assume nothing can fail, > so we throw away the return code, or we should assume everything can > fail, and propagate the errors. > > If we assume error can happen, if there is an error in firmware > download, isn't that fatal? Should we even care about care about PHY > read/write errors if firmware download has failed? And since firmware > download is probably the first thing to happen, if anything is likely > to fair, i would expect firmware download is what is going to fail. > > Andrew You're right. It is one of the first things that happen, so checking it makes sense. I will make firmware application errors propagate up to rtl_open() in v2. Matheus ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 3/3] r8169: release firmware on application failure 2026-09-16 22:02 ` Andrew Lunn 2026-09-16 22:21 ` Matheus Alves de Almeida @ 2026-09-17 2:19 ` Matheus Alves de Almeida 2026-09-17 12:14 ` Andrew Lunn 1 sibling, 1 reply; 15+ messages in thread From: Matheus Alves de Almeida @ 2026-09-17 2:19 UTC (permalink / raw) To: Andrew Lunn Cc: Heiner Kallweit, nic_swsd, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel On 2026-09-16 19:02, Andrew Lunn wrote: > On Wed, Sep 16, 2026 at 06:15:00PM -0300, Matheus Alves de Almeida wrote: >> > If the firmware cannot be written, is the device dead? Should this >> > return an error, so the caller can abort the probe? >> >> A timeout while applying firmware could indeed indicate a PHY access >> problem. However, firmware loading failures are already non-fatal, >> and the callers of r8169_apply_firmware() do not propagate errors >> either. Making firmware application failures fatal would require >> broader changes to several r8169 PHY initialization paths. > > But you are making such changes, returning errors up the call chain. > Why are you making these changes? We either assume nothing can fail, > so we throw away the return code, or we should assume everything can > fail, and propagate the errors. > > If we assume error can happen, if there is an error in firmware > download, isn't that fatal? Should we even care about care about PHY > read/write errors if firmware download has failed? And since firmware > download is probably the first thing to happen, if anything is likely > to fair, i would expect firmware download is what is going to fail. > > Andrew Looking at this more in depth, I am leaning towards keeping the old non-fatal behavior. Right now, firmware application failures are ignored, so the device can keep going even if applying the firmware fails. The TODO also specifically says to release the firmware on failure, which seems to imply that continuing without it was the intended behavior, and that releasing it was mainly meant to prevent retrying the same failed firmware application later. Making firmware application failures fatal also creates a state problem. If we release tp->rtl_fw after a failure, later initialization attempts will see no firmware and continue without retrying it. Avoiding that would require tracking the failure separately or keeping the firmware loaded, which would no longer follow what the TODO suggests. At that point this becomes a larger behavior change and could possibly break hardware where firmware application failures are currently tolerated. Because of that, I am leaning towards keeping the existing behavior: detect the failure, release the firmware as the TODO says, and continue without it. What do you think? ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 3/3] r8169: release firmware on application failure 2026-09-17 2:19 ` Matheus Alves de Almeida @ 2026-09-17 12:14 ` Andrew Lunn 2026-09-18 0:45 ` Matheus Alves de Almeida 0 siblings, 1 reply; 15+ messages in thread From: Andrew Lunn @ 2026-09-17 12:14 UTC (permalink / raw) To: Matheus Alves de Almeida Cc: Heiner Kallweit, nic_swsd, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel > Right now, firmware application failures are ignored, so the device > can keep going even if applying the firmware fails. The TODO also > specifically says to release the firmware on failure, which seems to > imply that continuing without it was the intended behavior, and that > releasing it was mainly meant to prevent retrying the same failed > firmware application later. > > Making firmware application failures fatal also creates a state problem. I don't know this driver in detail, but fatal errors generally don't cause state problem. The probe method fails, so the device is destroyed. Is firmware download not performed in probe? This driver does support a number of different devices. How many do you have for testing? If you artificially cause firmware download to fail, is the device usable? Andrew ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 3/3] r8169: release firmware on application failure 2026-09-17 12:14 ` Andrew Lunn @ 2026-09-18 0:45 ` Matheus Alves de Almeida 0 siblings, 0 replies; 15+ messages in thread From: Matheus Alves de Almeida @ 2026-09-18 0:45 UTC (permalink / raw) To: Andrew Lunn Cc: Heiner Kallweit, nic_swsd, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, netdev, linux-kernel >> Right now, firmware application failures are ignored, so the device >> can keep going even if applying the firmware fails. The TODO also >> specifically says to release the firmware on failure, which seems to >> imply that continuing without it was the intended behavior, and that >> releasing it was mainly meant to prevent retrying the same failed >> firmware application later. >> >> Making firmware application failures fatal also creates a state problem. > > I don't know this driver in detail, but fatal errors generally don't > cause state problem. The probe method fails, so the device is > destroyed. Is firmware download not performed in probe? > > This driver does support a number of different devices. How many do > you have for testing? If you artificially cause firmware download to > fail, is the device usable? > > Andrew In the r8169 case, the firmware is not applied during probe, but rather during rtl_open(). I got my hands on a machine with an RTL8105E. While it runs without firmware, partial firmware application causes the NIC to stop working unless the failure happens near the beginning or end of the application. At this point I think the TODO I was trying to solve is stale. The proper handling here would be, as you suggested, to fail rtl_open() on a firmware application failure, which would release the firmware through the existing rtl_open() error cleanup. That would instead turn this into broader initialization error handling, which I am not knowledgeable enough about the netdev and r8169 code yet to do confidently. If desired, I could send the iopoll patch separately, but I do not think I am going to continue with this series. Thanks for your help and patience. I am still new to Linux kernel development and trying to get the hang of it. ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2026-09-18 0:46 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-09-16 15:24 [PATCH net-next 0/3] r8169: handle firmware application errors Matheus Alves de Almeida 2026-09-16 15:24 ` [PATCH net-next 1/3] r8169: propagate errors from PHY write operations Matheus Alves de Almeida 2026-09-16 18:38 ` Andrew Lunn 2026-09-16 21:10 ` Matheus Alves de Almeida 2026-09-16 21:14 ` Andrew Lunn 2026-09-16 21:19 ` Matheus Alves de Almeida 2026-09-16 15:24 ` [PATCH net-next 2/3] r8169: propagate firmware access errors Matheus Alves de Almeida 2026-09-16 15:24 ` [PATCH net-next 3/3] r8169: release firmware on application failure Matheus Alves de Almeida 2026-09-16 18:42 ` Andrew Lunn 2026-09-16 21:15 ` Matheus Alves de Almeida 2026-09-16 22:02 ` Andrew Lunn 2026-09-16 22:21 ` Matheus Alves de Almeida 2026-09-17 2:19 ` Matheus Alves de Almeida 2026-09-17 12:14 ` Andrew Lunn 2026-09-18 0:45 ` Matheus Alves de Almeida
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®