From: Chih Kai Hsu <hsu.chih.kai@realtek.com>
To: "netdev-bot+sashiko@kernel.org" <netdev-bot+sashiko@kernel.org>
Cc: "davem@davemloft.net" <davem@davemloft.net>,
"kuba@kernel.org" <kuba@kernel.org>,
"netdev@vger.kernel.org" <netdev@vger.kernel.org>,
nic_swsd <nic_swsd@realtek.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-usb@vger.kernel.org" <linux-usb@vger.kernel.org>,
"edumazet@google.com" <edumazet@google.com>,
"bjorn@mork.no" <bjorn@mork.no>,
"pabeni@redhat.com" <pabeni@redhat.com>,
"andrew+netdev@lunn.ch" <andrew+netdev@lunn.ch>
Subject: RE: [PATCH net-next v5 7/9] r8152: add TGPHY register access for RTL8157 and RTL8159
Date: Tue, 6 Oct 2026 09:41:43 +0000 [thread overview]
Message-ID: <bb664c1a5277415a973812edabd448ef@realtek.com> (raw)
In-Reply-To: <179119424413.434549.4219292227441567313@kernel.org>
> 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?
Sure.
>
> > 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.
I think it should be solved by another series. The driver should introduce error handling
to solve the issue.
>
> [ ... ]
>
> > @@ -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?
Yes, it could reuse the handling.
>
> [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
Best Regards,
Chih-Kai
next prev parent reply other threads:[~2026-10-06 9:42 UTC|newest]
Thread overview: 23+ 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-06 9:18 ` Chih Kai Hsu
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-06 9:23 ` Chih Kai Hsu
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-06 9:24 ` Chih Kai Hsu
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
2026-10-06 9:41 ` Chih Kai Hsu [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-06 9:43 ` Chih Kai Hsu
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=bb664c1a5277415a973812edabd448ef@realtek.com \
--to=hsu.chih.kai@realtek.com \
--cc=andrew+netdev@lunn.ch \
--cc=bjorn@mork.no \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=netdev-bot+sashiko@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 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.