From: netdev-bot+sashiko@kernel.org
To: hsu.chih.kai@realtek.com
Cc: davem@davemloft.net, kuba@kernel.org, netdev@vger.kernel.org,
nic_swsd@realtek.com, linux-kernel@vger.kernel.org,
linux-usb@vger.kernel.org, edumazet@google.com, bjorn@mork.no,
pabeni@redhat.com, andrew+netdev@lunn.ch
Subject: Re: [PATCH net-next v5 7/9] r8152: add TGPHY register access for RTL8157 and RTL8159
Date: Mon, 05 Oct 2026 09:57:24 +0000 [thread overview]
Message-ID: <179119424413.434549.4219292227441567313@kernel.org> (raw)
In-Reply-To: <20261001091144.28191-8-nic_swsd@realtek.com>
Thank you for your contribution! Sashiko AI review found 3 potential
issue(s) to consider.
Critical: 0 · High: 0 (1) · Medium: 1 (1) · Low: 2
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [Medium] On RTL8157/RTL8159, a TGPHY busy timeout leaves the device
dead with no recovery.
- [Low] The commit message does not match the error-handling changes in
the diff.
- [Low] In rtl_tgphy_access(), a write sets TGPHY_CMD_BUSY|TGPHY_CMD_WR
in USB_TGPHY_CMD and returns without waiting for BUSY to clear.
Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but the TGPHY
timeout adds another way to reach it.
- [Medium] read_mii_word(), the driver's mii_if_info.mdio_read callback,
returns -ENODEV when RTL8152_INACCESSIBLE is set.
--
r8152: add TGPHY register access for RTL8157 and RTL8159
This commit adds rtl_ops.phy_read/phy_write hooks. RTL8157 and RTL8159
now use the USB_TGPHY_ADDR/DATA/CMD command channel for PHY access, and
older chips keep the OCP base switching path. The PHY accessors and the
helpers built on them now return int. A TGPHY busy timeout latches
RTL8152_INACCESSIBLE.
> The status is checked only where an errno would otherwise be taken for
> register content or reported as success: the pause parameters,
> rtl8152_set_speed(), SIOCGMIIREG/SIOCSMIIREG, the PHY patch handshake
> and the PHY firmware version checks.
>
> The remaining callers, notably the hw_phy_cfg and init sequences,
> r8153_phy_status(), r8152_mmd_read(), EEE handling and the MII library
> callbacks, still ignore the status and rely on the latch to stop
> further access.
[Severity: Low]
Does this description match the diff?
r8153_phy_status() now breaks out of its loop when ocp_reg_read() fails.
r8153_get_eee() now returns the errno to ethtool. r8156_eee_en() returns
early when its read fails.
rtl8152_get_link_ksettings() now returns an errno to userspace.
rtl8153_in_nway(), r8156_mdio_force_mode() and rtl8152_fw_phy_fixup()
also return early on failure.
So ETHTOOL_GLINKSETTINGS and ETHTOOL_GEEE can now fail with -ENODEV, and
the message does not mention either. Could the message be updated to list
these paths?
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index f805ef0763d70..be8b0db15033b 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
[ ... ]
> @@ -1664,16 +1675,33 @@ static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data)
[ ... ]
> +static int r8152_mdio_read(struct r8152 *tp, u32 reg_addr)
> +{
> + u16 data;
> + int ret;
> +
> + ret = ocp_reg_read(tp, OCP_BASE_MII + reg_addr * 2, &data);
> +
> + return ret < 0 ? ret : data;
> }
[Severity: Medium]
This is a pre-existing issue, but r8152_mdio_read() can now return a
negative errno. read_mii_word(), the mii_if_info.mdio_read callback,
passes that value straight to drivers/net/mii.c, which treats it as
register bits:
read_mii_word() {
if (test_bit(RTL8152_INACCESSIBLE, &tp->flags))
return -ENODEV;
...
ret = r8152_mdio_read(tp, reg);
return ret;
}
read_mii_word() already returned -ENODEV for a latched device before this
patch. The TGPHY timeout adds another way to reach that state.
In mii_nway_restart():
bmcr = mii->mdio_read(mii->dev, mii->phy_id, MII_BMCR);
if (bmcr & BMCR_ANENABLE) {
-ENODEV is 0xffffffed as a bit pattern, so BMCR_ANENABLE tests as set.
The function then calls write_mii_word() and returns 0.
Would rtl8152_nway_reset() and rtl_ethtool_set_eee() then report success
on a latched device? mii_ethtool_get_link_ksettings() would also build
link modes from the errno bit pattern.
[ ... ]
> @@ -1906,100 +1950,219 @@ static void ocp_byte_set_bits(struct r8152 *tp, u16 type, u16 index, u8 set)
[ ... ]
> +static int wait_tgphy_cmd_ready(struct r8152 *tp)
> +{
> + u16 ocp_data;
> + int ret;
> +
> + ret = read_poll_timeout(ocp_read_word, ocp_data,
> + test_bit(RTL8152_INACCESSIBLE, &tp->flags) ||
> + !(ocp_data & TGPHY_CMD_BUSY),
> + 2000, 20000, false, tp,
> + MCU_TYPE_USB, USB_TGPHY_CMD);
> +
> + if (ret) {
> + rtl_set_inaccessible(tp);
> + dev_err(&tp->intf->dev, "TGPHY cmd busy timeout\n");
> + }
[Severity: Medium]
Should this latch go through the same recovery as r8152_control_msg()?
That path sets PROBE_SHOULD_RETRY while probe is still running, and
otherwise queues a limited number of resets:
r8152_control_msg() {
...
rtl_set_inaccessible(tp);
if (!test_bit(PROBED_WITH_NO_ERRORS, &tp->flags)) {
set_bit(PROBE_SHOULD_RETRY, &tp->flags);
return ret;
}
...
if (tp->reg_access_reset_count < REGISTER_ACCESS_MAX_RESETS) {
usb_queue_reset_device(tp->intf);
tp->reg_access_reset_count++;
...
}
Here only rtl_set_inaccessible() is called. On RTL8157/RTL8159 this seems
to have a few effects.
A timeout during rtl_ops.init(), or in the hw_phy_work queued from
rtl8152_probe_once(), is not caught by the PROBE_SHOULD_RETRY check in
rtl8152_probe_once(). Probe then succeeds and registers a netdev that
cannot reach the hardware.
A timeout in r8157_hw_phy_cfg()/r8159_hw_phy_cfg() after
rtl_phy_patch_request(tp, true, true) makes the matching
rtl_phy_patch_request(tp, false, true) return -ENODEV immediately.
PATCH_REQUEST stays set, ALDPS and EEE stay disabled, and no reset follows
to undo it.
If the link is up when the latch is set, rtl_work_func_t() and
rtl_hw_phy_work_func_t() return early, so the carrier is never cleared.
bottom_half() also returns early, so TX packets are silently dropped.
rtl8152_start_xmit() only stops the queue when tp->tx_free is empty, and
tx_free is not empty here. So the watchdog never calls
rtl8152_tx_timeout(), and skbs keep building up on tp->tx_queue.
Only system resume (rtl8152_resume()->usb_reset_device()) or a replug
seems to bring the device back.
The commit message says recovery is a separate problem. Before this
patch, PHY access on these chips went through r8152_phy_read() and
r8152_phy_write(), where a failure came from r8152_control_msg() and
queued a reset. Could the TGPHY timeout reuse that handling instead of
going around it?
[Severity: High]
This isn't a bug introduced by this patch, but this timeout is another
way to latch the device without queuing a reset. That makes an existing
problem in the close path easier to reach.
When RTL8152_INACCESSIBLE is set, rtl8152_close() does:
if (res < 0 || test_bit(RTL8152_INACCESSIBLE, &tp->flags)) {
rtl_drop_queued_tx(tp);
rtl_stop_rx(tp);
} else {
...
free_all_mem(tp);
rtl_disable() also returns early on INACCESSIBLE and skips the
usb_kill_urb() loop over tp->tx_info[i].urb. Are TX bulk-OUT URBs that are
still in flight ever cancelled on this path?
free_all_mem() then calls usb_free_urb(), which only drops a reference
while the HCD still holds its own. It also kfree()s
tp->tx_info[i].buffer. Can the host controller then DMA from the freed
buffer and send its contents to the device?
When such a URB later completes, write_bulk_callback() adds agg->list
back onto tp->tx_free. If the interface was reopened in between,
alloc_all_mem() has already reinitialised tx_free and added the same agg.
Could that double list_add corrupt tx_free?
Disconnect looks safe, because usb_unbind_interface() calls
usb_disable_interface() before ->disconnect. A plain ifdown does not have
that protection.
> +
> + return test_bit(RTL8152_INACCESSIBLE, &tp->flags) ? -ENODEV : ret;
> +}
> +
> +static int rtl_tgphy_access(struct r8152 *tp, u16 addr, u16 *data, bool write)
> +{
> + u16 cmd = 0;
> + int ret;
> +
> + ret = wait_tgphy_cmd_ready(tp);
> + if (ret < 0)
> + goto out;
> +
> + if (write) {
> + cmd |= TGPHY_CMD_WR;
> + ocp_write_word(tp, MCU_TYPE_USB, USB_TGPHY_DATA, *data);
> + }
> +
> + ocp_write_word(tp, MCU_TYPE_USB, USB_TGPHY_ADDR, addr);
> +
> + cmd |= TGPHY_CMD_BUSY;
> + ocp_write_word(tp, MCU_TYPE_USB, USB_TGPHY_CMD, cmd);
> +
> + if (!write) {
> + ret = wait_tgphy_cmd_ready(tp);
> + if (ret < 0)
> + goto out;
> +
> + *data = ocp_read_word(tp, MCU_TYPE_USB, USB_TGPHY_DATA);
> + }
[Severity: Low]
For a write, the command is posted with TGPHY_CMD_BUSY | TGPHY_CMD_WR and
the function returns without waiting for BUSY to clear. The second
wait_tgphy_cmd_ready() only runs under if (!write).
If the PHY never finishes that write, the call still returns 0. The
failure only shows up as a timeout on the next PHY access.
The commit message says the status is now checked where a failure would
otherwise be "reported as success". These callers would still report
success for such a write:
SIOCSMIIREG in rtl8152_ioctl():
res = r8152_mdio_write(tp, data->reg_num, data->val_in);
the final MII_ADVERTISE write in rtl8152_set_pauseparam()
the final MII_BMCR write in rtl8152_set_speed() when BMCR_RESET is not
set
In the last case, rtl8152_set_link_ksettings() then stores tp->autoneg,
tp->speed, tp->duplex and tp->advertising.
ocp_adv_write() posts writes the same way, so this matches existing driver
practice. Should TGPHY writes also wait for completion, so the reported
status covers the write itself?
> +
> +out:
> + return test_bit(RTL8152_INACCESSIBLE, &tp->flags) ? -ENODEV : ret;
> +}
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261001091144.28191-1-nic_swsd%40realtek.com
next prev parent reply other threads:[~2026-10-05 9:57 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-01 9:11 [PATCH net-next v5 0/9] r8152: refactor and extend RTL8157/8159 support Chih Kai Hsu
2026-10-01 9:11 ` [PATCH net-next v5 1/9] r8152: split r8156_init per chip and add missing init writes Chih Kai Hsu
2026-10-05 9:57 ` netdev-bot+sashiko
2026-10-01 9:11 ` [PATCH net-next v5 2/9] r8152: split RTL_VER_17 into QFN68 and QFN100 package variants Chih Kai Hsu
2026-10-05 9:57 ` netdev-bot+sashiko
2026-10-01 9:11 ` [PATCH net-next v5 3/9] r8152: split rtl8156_enable/up/down into per-chip-family functions Chih Kai Hsu
2026-10-01 9:11 ` [PATCH net-next v5 4/9] r8152: fix up and down register settings for RTL8156/8156B/8157/8159 Chih Kai Hsu
2026-10-01 9:11 ` [PATCH net-next v5 5/9] r8152: split r8157_hw_phy_cfg into RTL8157 and RTL8159 variants Chih Kai Hsu
2026-10-05 9:57 ` netdev-bot+sashiko
2026-10-01 9:11 ` [PATCH net-next v5 6/9] r8152: add rtl8157_unload and rtl8157_change_mtu Chih Kai Hsu
2026-10-05 9:57 ` netdev-bot+sashiko
2026-10-01 9:11 ` [PATCH net-next v5 7/9] r8152: add TGPHY register access for RTL8157 and RTL8159 Chih Kai Hsu
2026-10-05 9:57 ` netdev-bot+sashiko [this message]
2026-10-01 9:11 ` [PATCH net-next v5 8/9] r8152: extract rtl_fc_pause_pkt_en() and apply it to RTL8156/8157/8159 Chih Kai Hsu
2026-10-05 9:57 ` netdev-bot+sashiko
2026-10-01 9:11 ` [PATCH net-next v5 9/9] r8152: enable UPS for RTL8157 and RTL8159 QFN68 Chih Kai Hsu
2026-10-05 9:57 ` netdev-bot+sashiko
2026-10-01 9:13 ` [PATCH net-next v5 0/9] r8152: refactor and extend RTL8157/8159 support netdev-bot+sinfo
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=179119424413.434549.4219292227441567313@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=bjorn@mork.no \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hsu.chih.kai@realtek.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=nic_swsd@realtek.com \
--cc=pabeni@redhat.com \
/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 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®