* [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support
@ 2025-08-13 10:04 Russell King (Oracle)
2025-08-13 10:10 ` Russell King (Oracle)
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Russell King (Oracle) @ 2025-08-13 10:04 UTC (permalink / raw)
To: Andrew Lunn, Heiner Kallweit
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Jon Hunter, netdev,
Paolo Abeni, Thierry Reding
Implement Wake-on-Lan for RTL8211F correctly. The existing
implementation has multiple issues:
1. It assumes that Wake-on-Lan can always be used, whether or not the
interrupt is wired, and whether or not the interrupt is capable of
waking the system. This breaks the ability for MAC drivers to detect
whether the PHY WoL is functional.
2. switching the interrupt pin in the .set_wol() method to PMEB mode
immediately silences link-state interrupts, which breaks phylib
when interrupts are being used rather than polling mode.
3. the code claiming to "reset WOL status" was doing nothing of the
sort. Bit 15 in page 0xd8a register 17 controls WoL reset, and
needs to be pulsed low to reset the WoL state. This bit was always
written as '1', resulting in no reset.
4. not resetting WoL state results in the PMEB pin remaining asserted,
which in turn leads to an interrupt storm. Only resetting the WoL
state in .set_wol() is not sufficient.
5. PMEB mode does not allow software detection of the wake-up event as
there is no status bit to indicate we received the WoL packet.
6. across reboots of at least the Jetson Xavier NX system, the WoL
configuration is preserved.
Fix all of these issues by essentially rewriting the support. We:
1. clear the WoL event enable register at probe time.
2. detect whether we can support wake-up by having a valid interrupt,
and the "wakeup-source" property in DT. If we can, then we mark
the MDIO device as wakeup capable, and associate the interrupt
with the wakeup source.
3. arrange for the get_wol() and set_wol() implementations to handle
the case where the MDIO device has not been marked as wakeup
capable (thereby returning no WoL support, and refusing to enable
WoL support.)
4. avoid switching to PMEB mode, instead using INTB mode with the
interrupt enable, reconfiguring the interrupt enables at suspend
time, and restoring their original state at resume time (we track
the state of the interrupt enable register in .config_intr()
register.)
5. move WoL reset from .set_wol() to the suspend function to ensure
that WoL state is cleared prior to suspend. This is necessary
after the PME interrupt has been enabled as a second WoL packet
will not re-raise a previously cleared PME interrupt.
6. when a PME interrupt (for wakeup) is asserted, pass this to the
PM wakeup so it knows which device woke the system.
This fixes WoL support in the Realtek RTL8211F driver when used on the
nVidia Jetson Xavier NX platform, and needs to be applied before stmmac
patches which allow these platforms to forward the ethtool WoL commands
to the Realtek PHY.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
drivers/net/phy/realtek/realtek_main.c | 172 ++++++++++++++++++++-----
1 file changed, 140 insertions(+), 32 deletions(-)
diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
index dd0d675149ad..4361529e68fb 100644
--- a/drivers/net/phy/realtek/realtek_main.c
+++ b/drivers/net/phy/realtek/realtek_main.c
@@ -10,6 +10,7 @@
#include <linux/bitops.h>
#include <linux/of.h>
#include <linux/phy.h>
+#include <linux/pm_wakeirq.h>
#include <linux/netdevice.h>
#include <linux/module.h>
#include <linux/delay.h>
@@ -31,6 +32,7 @@
#define RTL821x_INER 0x12
#define RTL8211B_INER_INIT 0x6400
#define RTL8211E_INER_LINK_STATUS BIT(10)
+#define RTL8211F_INER_PME BIT(7)
#define RTL8211F_INER_LINK_STATUS BIT(4)
#define RTL821x_INSR 0x13
@@ -96,17 +98,13 @@
#define RTL8211F_RXCR 0x15
#define RTL8211F_RX_DELAY BIT(3)
-/* RTL8211F WOL interrupt configuration */
-#define RTL8211F_INTBCR_PAGE 0xd40
-#define RTL8211F_INTBCR 0x16
-#define RTL8211F_INTBCR_INTB_PMEB BIT(5)
-
/* RTL8211F WOL settings */
-#define RTL8211F_WOL_SETTINGS_PAGE 0xd8a
+#define RTL8211F_WOL_PAGE 0xd8a
#define RTL8211F_WOL_SETTINGS_EVENTS 16
#define RTL8211F_WOL_EVENT_MAGIC BIT(12)
-#define RTL8211F_WOL_SETTINGS_STATUS 17
-#define RTL8211F_WOL_STATUS_RESET (BIT(15) | 0x1fff)
+#define RTL8211F_WOL_RST_RMSQ 17
+#define RTL8211F_WOL_RG_RSTB BIT(15)
+#define RTL8211F_WOL_RMSQ 0x1fff
/* RTL8211F Unique phyiscal and multicast address (WOL) */
#define RTL8211F_PHYSICAL_ADDR_PAGE 0xd8c
@@ -172,7 +170,8 @@ struct rtl821x_priv {
u16 phycr2;
bool has_phycr2;
struct clk *clk;
- u32 saved_wolopts;
+ /* rtl8211f */
+ u16 iner;
};
static int rtl821x_read_page(struct phy_device *phydev)
@@ -255,6 +254,34 @@ static int rtl821x_probe(struct phy_device *phydev)
return 0;
}
+static int rtl8211f_probe(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ int ret;
+
+ ret = rtl821x_probe(phydev);
+ if (ret < 0)
+ return ret;
+
+ /* Disable all PME events */
+ ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE,
+ RTL8211F_WOL_SETTINGS_EVENTS, 0);
+ if (ret < 0)
+ return ret;
+
+ /* Mark this PHY as wakeup capable and register the interrupt as a
+ * wakeup IRQ if the PHY is marked as a wakeup source in firmware,
+ * and the interrupt is valid.
+ */
+ if (device_property_read_bool(dev, "wakeup-source") &&
+ phy_interrupt_is_valid(phydev)) {
+ device_set_wakeup_capable(dev, true);
+ devm_pm_set_wake_irq(dev, phydev->irq);
+ }
+
+ return ret;
+}
+
static int rtl8201_ack_interrupt(struct phy_device *phydev)
{
int err;
@@ -352,6 +379,7 @@ static int rtl8211e_config_intr(struct phy_device *phydev)
static int rtl8211f_config_intr(struct phy_device *phydev)
{
+ struct rtl821x_priv *priv = phydev->priv;
u16 val;
int err;
@@ -362,8 +390,10 @@ static int rtl8211f_config_intr(struct phy_device *phydev)
val = RTL8211F_INER_LINK_STATUS;
err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
+ if (err == 0)
+ priv->iner = val;
} else {
- val = 0;
+ priv->iner = val = 0;
err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
if (err)
return err;
@@ -426,21 +456,34 @@ static irqreturn_t rtl8211f_handle_interrupt(struct phy_device *phydev)
return IRQ_NONE;
}
- if (!(irq_status & RTL8211F_INER_LINK_STATUS))
- return IRQ_NONE;
+ if (irq_status & RTL8211F_INER_LINK_STATUS) {
+ phy_trigger_machine(phydev);
+ return IRQ_HANDLED;
+ }
- phy_trigger_machine(phydev);
+ if (irq_status & RTL8211F_INER_PME) {
+ pm_wakeup_event(&phydev->mdio.dev, 0);
+ return IRQ_HANDLED;
+ }
- return IRQ_HANDLED;
+ return IRQ_NONE;
}
static void rtl8211f_get_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
{
int wol_events;
+ /* If the PHY is not capable of waking the system, then WoL can not
+ * be supported.
+ */
+ if (!device_can_wakeup(&dev->mdio.dev)) {
+ wol->supported = 0;
+ return;
+ }
+
wol->supported = WAKE_MAGIC;
- wol_events = phy_read_paged(dev, RTL8211F_WOL_SETTINGS_PAGE, RTL8211F_WOL_SETTINGS_EVENTS);
+ wol_events = phy_read_paged(dev, RTL8211F_WOL_PAGE, RTL8211F_WOL_SETTINGS_EVENTS);
if (wol_events < 0)
return;
@@ -453,6 +496,9 @@ static int rtl8211f_set_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
const u8 *mac_addr = dev->attached_dev->dev_addr;
int oldpage;
+ if (!device_can_wakeup(&dev->mdio.dev))
+ return -EOPNOTSUPP;
+
oldpage = phy_save_page(dev);
if (oldpage < 0)
goto err;
@@ -464,25 +510,23 @@ static int rtl8211f_set_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
__phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD1, mac_addr[3] << 8 | (mac_addr[2]));
__phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD2, mac_addr[5] << 8 | (mac_addr[4]));
- /* Enable magic packet matching and reset WOL status */
- rtl821x_write_page(dev, RTL8211F_WOL_SETTINGS_PAGE);
+ /* Enable magic packet matching */
+ rtl821x_write_page(dev, RTL8211F_WOL_PAGE);
__phy_write(dev, RTL8211F_WOL_SETTINGS_EVENTS, RTL8211F_WOL_EVENT_MAGIC);
- __phy_write(dev, RTL8211F_WOL_SETTINGS_STATUS, RTL8211F_WOL_STATUS_RESET);
-
- /* Enable the WOL interrupt */
- rtl821x_write_page(dev, RTL8211F_INTBCR_PAGE);
- __phy_set_bits(dev, RTL8211F_INTBCR, RTL8211F_INTBCR_INTB_PMEB);
+ /* Set the maximum packet size, and assert WoL reset */
+ __phy_write(dev, RTL8211F_WOL_RST_RMSQ, RTL8211F_WOL_RMSQ);
} else {
- /* Disable the WOL interrupt */
- rtl821x_write_page(dev, RTL8211F_INTBCR_PAGE);
- __phy_clear_bits(dev, RTL8211F_INTBCR, RTL8211F_INTBCR_INTB_PMEB);
-
- /* Disable magic packet matching and reset WOL status */
- rtl821x_write_page(dev, RTL8211F_WOL_SETTINGS_PAGE);
+ /* Disable magic packet matching */
+ rtl821x_write_page(dev, RTL8211F_WOL_PAGE);
__phy_write(dev, RTL8211F_WOL_SETTINGS_EVENTS, 0);
- __phy_write(dev, RTL8211F_WOL_SETTINGS_STATUS, RTL8211F_WOL_STATUS_RESET);
+
+ /* Place WoL in reset */
+ __phy_clear_bits(dev, RTL8211F_WOL_RST_RMSQ,
+ RTL8211F_WOL_RG_RSTB);
}
+ device_set_wakeup_enable(&dev->mdio.dev, !!(wol->wolopts & WAKE_MAGIC));
+
err:
return phy_restore_page(dev, oldpage, 0);
}
@@ -628,6 +672,52 @@ static int rtl821x_suspend(struct phy_device *phydev)
return ret;
}
+static int rtl8211f_suspend(struct phy_device *phydev)
+{
+ u16 wol_rst;
+ int ret;
+
+ ret = rtl821x_suspend(phydev);
+ if (ret < 0)
+ return ret;
+
+ /* If a PME event is enabled, then configure the interrupt for
+ * PME events only, disabling link interrupt. We avoid switching
+ * to PMEB mode as we don't have a status bit for that.
+ */
+ if (device_may_wakeup(&phydev->mdio.dev)) {
+ ret = phy_write_paged(phydev, 0xa42, RTL821x_INER,
+ RTL8211F_INER_PME);
+ if (ret < 0)
+ goto err;
+
+ /* Read the INSR to clear any pending interrupt */
+ phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR);
+
+ /* Reset the WoL to ensure that an event is picked up.
+ * Unless we do this, even if we receive another packet,
+ * we may not have a PME interrupt raised.
+ */
+ ret = phy_read_paged(phydev, RTL8211F_WOL_PAGE,
+ RTL8211F_WOL_RST_RMSQ);
+ if (ret < 0)
+ goto err;
+
+ wol_rst = ret & ~RTL8211F_WOL_RG_RSTB;
+ ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE,
+ RTL8211F_WOL_RST_RMSQ, wol_rst);
+ if (ret < 0)
+ goto err;
+
+ wol_rst |= RTL8211F_WOL_RG_RSTB;
+ ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE,
+ RTL8211F_WOL_RST_RMSQ, wol_rst);
+ }
+
+err:
+ return ret;
+}
+
static int rtl821x_resume(struct phy_device *phydev)
{
struct rtl821x_priv *priv = phydev->priv;
@@ -645,6 +735,24 @@ static int rtl821x_resume(struct phy_device *phydev)
return 0;
}
+static int rtl8211f_resume(struct phy_device *phydev)
+{
+ struct rtl821x_priv *priv = phydev->priv;
+ int ret;
+
+ ret = rtl821x_resume(phydev);
+ if (ret < 0)
+ return ret;
+
+ /* If the device was programmed for a PME event, restore the interrupt
+ * enable so phylib can receive link state interrupts.
+ */
+ if (device_may_wakeup(&phydev->mdio.dev))
+ ret = phy_write_paged(phydev, 0xa42, RTL821x_INER, priv->iner);
+
+ return ret;
+}
+
static int rtl8211x_led_hw_is_supported(struct phy_device *phydev, u8 index,
unsigned long rules)
{
@@ -1612,15 +1720,15 @@ static struct phy_driver realtek_drvs[] = {
}, {
PHY_ID_MATCH_EXACT(0x001cc916),
.name = "RTL8211F Gigabit Ethernet",
- .probe = rtl821x_probe,
+ .probe = rtl8211f_probe,
.config_init = &rtl8211f_config_init,
.read_status = rtlgen_read_status,
.config_intr = &rtl8211f_config_intr,
.handle_interrupt = rtl8211f_handle_interrupt,
.set_wol = rtl8211f_set_wol,
.get_wol = rtl8211f_get_wol,
- .suspend = rtl821x_suspend,
- .resume = rtl821x_resume,
+ .suspend = rtl8211f_suspend,
+ .resume = rtl8211f_resume,
.read_page = rtl821x_read_page,
.write_page = rtl821x_write_page,
.flags = PHY_ALWAYS_CALL_SUSPEND,
--
2.30.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support
2025-08-13 10:04 [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support Russell King (Oracle)
@ 2025-08-13 10:10 ` Russell King (Oracle)
2025-08-13 11:21 ` [PATCH net-next] dt-bindings: net: realtek,rtl82xx: document wakeup-source property Russell King (Oracle)
` (2 subsequent siblings)
3 siblings, 0 replies; 8+ messages in thread
From: Russell King (Oracle) @ 2025-08-13 10:10 UTC (permalink / raw)
To: Andrew Lunn, Heiner Kallweit, Daniel Braunwarth
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Jon Hunter, netdev,
Paolo Abeni, Thierry Reding
Sorry, I missed adding Daniel Braunwarth.
Please also note that this is essentially a rewrite of Daniels patch
merged during the previous merge window, thus I think it makes sense
for net-next rather than net. It may be appropriate to be backported
to stable at a later date.
On Wed, Aug 13, 2025 at 11:04:45AM +0100, Russell King (Oracle) wrote:
> Implement Wake-on-Lan for RTL8211F correctly. The existing
> implementation has multiple issues:
>
> 1. It assumes that Wake-on-Lan can always be used, whether or not the
> interrupt is wired, and whether or not the interrupt is capable of
> waking the system. This breaks the ability for MAC drivers to detect
> whether the PHY WoL is functional.
> 2. switching the interrupt pin in the .set_wol() method to PMEB mode
> immediately silences link-state interrupts, which breaks phylib
> when interrupts are being used rather than polling mode.
> 3. the code claiming to "reset WOL status" was doing nothing of the
> sort. Bit 15 in page 0xd8a register 17 controls WoL reset, and
> needs to be pulsed low to reset the WoL state. This bit was always
> written as '1', resulting in no reset.
> 4. not resetting WoL state results in the PMEB pin remaining asserted,
> which in turn leads to an interrupt storm. Only resetting the WoL
> state in .set_wol() is not sufficient.
> 5. PMEB mode does not allow software detection of the wake-up event as
> there is no status bit to indicate we received the WoL packet.
> 6. across reboots of at least the Jetson Xavier NX system, the WoL
> configuration is preserved.
>
> Fix all of these issues by essentially rewriting the support. We:
> 1. clear the WoL event enable register at probe time.
> 2. detect whether we can support wake-up by having a valid interrupt,
> and the "wakeup-source" property in DT. If we can, then we mark
> the MDIO device as wakeup capable, and associate the interrupt
> with the wakeup source.
> 3. arrange for the get_wol() and set_wol() implementations to handle
> the case where the MDIO device has not been marked as wakeup
> capable (thereby returning no WoL support, and refusing to enable
> WoL support.)
> 4. avoid switching to PMEB mode, instead using INTB mode with the
> interrupt enable, reconfiguring the interrupt enables at suspend
> time, and restoring their original state at resume time (we track
> the state of the interrupt enable register in .config_intr()
> register.)
> 5. move WoL reset from .set_wol() to the suspend function to ensure
> that WoL state is cleared prior to suspend. This is necessary
> after the PME interrupt has been enabled as a second WoL packet
> will not re-raise a previously cleared PME interrupt.
> 6. when a PME interrupt (for wakeup) is asserted, pass this to the
> PM wakeup so it knows which device woke the system.
>
> This fixes WoL support in the Realtek RTL8211F driver when used on the
> nVidia Jetson Xavier NX platform, and needs to be applied before stmmac
> patches which allow these platforms to forward the ethtool WoL commands
> to the Realtek PHY.
>
> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
> ---
> drivers/net/phy/realtek/realtek_main.c | 172 ++++++++++++++++++++-----
> 1 file changed, 140 insertions(+), 32 deletions(-)
>
> diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c
> index dd0d675149ad..4361529e68fb 100644
> --- a/drivers/net/phy/realtek/realtek_main.c
> +++ b/drivers/net/phy/realtek/realtek_main.c
> @@ -10,6 +10,7 @@
> #include <linux/bitops.h>
> #include <linux/of.h>
> #include <linux/phy.h>
> +#include <linux/pm_wakeirq.h>
> #include <linux/netdevice.h>
> #include <linux/module.h>
> #include <linux/delay.h>
> @@ -31,6 +32,7 @@
> #define RTL821x_INER 0x12
> #define RTL8211B_INER_INIT 0x6400
> #define RTL8211E_INER_LINK_STATUS BIT(10)
> +#define RTL8211F_INER_PME BIT(7)
> #define RTL8211F_INER_LINK_STATUS BIT(4)
>
> #define RTL821x_INSR 0x13
> @@ -96,17 +98,13 @@
> #define RTL8211F_RXCR 0x15
> #define RTL8211F_RX_DELAY BIT(3)
>
> -/* RTL8211F WOL interrupt configuration */
> -#define RTL8211F_INTBCR_PAGE 0xd40
> -#define RTL8211F_INTBCR 0x16
> -#define RTL8211F_INTBCR_INTB_PMEB BIT(5)
> -
> /* RTL8211F WOL settings */
> -#define RTL8211F_WOL_SETTINGS_PAGE 0xd8a
> +#define RTL8211F_WOL_PAGE 0xd8a
> #define RTL8211F_WOL_SETTINGS_EVENTS 16
> #define RTL8211F_WOL_EVENT_MAGIC BIT(12)
> -#define RTL8211F_WOL_SETTINGS_STATUS 17
> -#define RTL8211F_WOL_STATUS_RESET (BIT(15) | 0x1fff)
> +#define RTL8211F_WOL_RST_RMSQ 17
> +#define RTL8211F_WOL_RG_RSTB BIT(15)
> +#define RTL8211F_WOL_RMSQ 0x1fff
>
> /* RTL8211F Unique phyiscal and multicast address (WOL) */
> #define RTL8211F_PHYSICAL_ADDR_PAGE 0xd8c
> @@ -172,7 +170,8 @@ struct rtl821x_priv {
> u16 phycr2;
> bool has_phycr2;
> struct clk *clk;
> - u32 saved_wolopts;
> + /* rtl8211f */
> + u16 iner;
> };
>
> static int rtl821x_read_page(struct phy_device *phydev)
> @@ -255,6 +254,34 @@ static int rtl821x_probe(struct phy_device *phydev)
> return 0;
> }
>
> +static int rtl8211f_probe(struct phy_device *phydev)
> +{
> + struct device *dev = &phydev->mdio.dev;
> + int ret;
> +
> + ret = rtl821x_probe(phydev);
> + if (ret < 0)
> + return ret;
> +
> + /* Disable all PME events */
> + ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE,
> + RTL8211F_WOL_SETTINGS_EVENTS, 0);
> + if (ret < 0)
> + return ret;
> +
> + /* Mark this PHY as wakeup capable and register the interrupt as a
> + * wakeup IRQ if the PHY is marked as a wakeup source in firmware,
> + * and the interrupt is valid.
> + */
> + if (device_property_read_bool(dev, "wakeup-source") &&
> + phy_interrupt_is_valid(phydev)) {
> + device_set_wakeup_capable(dev, true);
> + devm_pm_set_wake_irq(dev, phydev->irq);
> + }
> +
> + return ret;
> +}
> +
> static int rtl8201_ack_interrupt(struct phy_device *phydev)
> {
> int err;
> @@ -352,6 +379,7 @@ static int rtl8211e_config_intr(struct phy_device *phydev)
>
> static int rtl8211f_config_intr(struct phy_device *phydev)
> {
> + struct rtl821x_priv *priv = phydev->priv;
> u16 val;
> int err;
>
> @@ -362,8 +390,10 @@ static int rtl8211f_config_intr(struct phy_device *phydev)
>
> val = RTL8211F_INER_LINK_STATUS;
> err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
> + if (err == 0)
> + priv->iner = val;
> } else {
> - val = 0;
> + priv->iner = val = 0;
> err = phy_write_paged(phydev, 0xa42, RTL821x_INER, val);
> if (err)
> return err;
> @@ -426,21 +456,34 @@ static irqreturn_t rtl8211f_handle_interrupt(struct phy_device *phydev)
> return IRQ_NONE;
> }
>
> - if (!(irq_status & RTL8211F_INER_LINK_STATUS))
> - return IRQ_NONE;
> + if (irq_status & RTL8211F_INER_LINK_STATUS) {
> + phy_trigger_machine(phydev);
> + return IRQ_HANDLED;
> + }
>
> - phy_trigger_machine(phydev);
> + if (irq_status & RTL8211F_INER_PME) {
> + pm_wakeup_event(&phydev->mdio.dev, 0);
> + return IRQ_HANDLED;
> + }
>
> - return IRQ_HANDLED;
> + return IRQ_NONE;
> }
>
> static void rtl8211f_get_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
> {
> int wol_events;
>
> + /* If the PHY is not capable of waking the system, then WoL can not
> + * be supported.
> + */
> + if (!device_can_wakeup(&dev->mdio.dev)) {
> + wol->supported = 0;
> + return;
> + }
> +
> wol->supported = WAKE_MAGIC;
>
> - wol_events = phy_read_paged(dev, RTL8211F_WOL_SETTINGS_PAGE, RTL8211F_WOL_SETTINGS_EVENTS);
> + wol_events = phy_read_paged(dev, RTL8211F_WOL_PAGE, RTL8211F_WOL_SETTINGS_EVENTS);
> if (wol_events < 0)
> return;
>
> @@ -453,6 +496,9 @@ static int rtl8211f_set_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
> const u8 *mac_addr = dev->attached_dev->dev_addr;
> int oldpage;
>
> + if (!device_can_wakeup(&dev->mdio.dev))
> + return -EOPNOTSUPP;
> +
> oldpage = phy_save_page(dev);
> if (oldpage < 0)
> goto err;
> @@ -464,25 +510,23 @@ static int rtl8211f_set_wol(struct phy_device *dev, struct ethtool_wolinfo *wol)
> __phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD1, mac_addr[3] << 8 | (mac_addr[2]));
> __phy_write(dev, RTL8211F_PHYSICAL_ADDR_WORD2, mac_addr[5] << 8 | (mac_addr[4]));
>
> - /* Enable magic packet matching and reset WOL status */
> - rtl821x_write_page(dev, RTL8211F_WOL_SETTINGS_PAGE);
> + /* Enable magic packet matching */
> + rtl821x_write_page(dev, RTL8211F_WOL_PAGE);
> __phy_write(dev, RTL8211F_WOL_SETTINGS_EVENTS, RTL8211F_WOL_EVENT_MAGIC);
> - __phy_write(dev, RTL8211F_WOL_SETTINGS_STATUS, RTL8211F_WOL_STATUS_RESET);
> -
> - /* Enable the WOL interrupt */
> - rtl821x_write_page(dev, RTL8211F_INTBCR_PAGE);
> - __phy_set_bits(dev, RTL8211F_INTBCR, RTL8211F_INTBCR_INTB_PMEB);
> + /* Set the maximum packet size, and assert WoL reset */
> + __phy_write(dev, RTL8211F_WOL_RST_RMSQ, RTL8211F_WOL_RMSQ);
> } else {
> - /* Disable the WOL interrupt */
> - rtl821x_write_page(dev, RTL8211F_INTBCR_PAGE);
> - __phy_clear_bits(dev, RTL8211F_INTBCR, RTL8211F_INTBCR_INTB_PMEB);
> -
> - /* Disable magic packet matching and reset WOL status */
> - rtl821x_write_page(dev, RTL8211F_WOL_SETTINGS_PAGE);
> + /* Disable magic packet matching */
> + rtl821x_write_page(dev, RTL8211F_WOL_PAGE);
> __phy_write(dev, RTL8211F_WOL_SETTINGS_EVENTS, 0);
> - __phy_write(dev, RTL8211F_WOL_SETTINGS_STATUS, RTL8211F_WOL_STATUS_RESET);
> +
> + /* Place WoL in reset */
> + __phy_clear_bits(dev, RTL8211F_WOL_RST_RMSQ,
> + RTL8211F_WOL_RG_RSTB);
> }
>
> + device_set_wakeup_enable(&dev->mdio.dev, !!(wol->wolopts & WAKE_MAGIC));
> +
> err:
> return phy_restore_page(dev, oldpage, 0);
> }
> @@ -628,6 +672,52 @@ static int rtl821x_suspend(struct phy_device *phydev)
> return ret;
> }
>
> +static int rtl8211f_suspend(struct phy_device *phydev)
> +{
> + u16 wol_rst;
> + int ret;
> +
> + ret = rtl821x_suspend(phydev);
> + if (ret < 0)
> + return ret;
> +
> + /* If a PME event is enabled, then configure the interrupt for
> + * PME events only, disabling link interrupt. We avoid switching
> + * to PMEB mode as we don't have a status bit for that.
> + */
> + if (device_may_wakeup(&phydev->mdio.dev)) {
> + ret = phy_write_paged(phydev, 0xa42, RTL821x_INER,
> + RTL8211F_INER_PME);
> + if (ret < 0)
> + goto err;
> +
> + /* Read the INSR to clear any pending interrupt */
> + phy_read_paged(phydev, RTL8211F_INSR_PAGE, RTL8211F_INSR);
> +
> + /* Reset the WoL to ensure that an event is picked up.
> + * Unless we do this, even if we receive another packet,
> + * we may not have a PME interrupt raised.
> + */
> + ret = phy_read_paged(phydev, RTL8211F_WOL_PAGE,
> + RTL8211F_WOL_RST_RMSQ);
> + if (ret < 0)
> + goto err;
> +
> + wol_rst = ret & ~RTL8211F_WOL_RG_RSTB;
> + ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE,
> + RTL8211F_WOL_RST_RMSQ, wol_rst);
> + if (ret < 0)
> + goto err;
> +
> + wol_rst |= RTL8211F_WOL_RG_RSTB;
> + ret = phy_write_paged(phydev, RTL8211F_WOL_PAGE,
> + RTL8211F_WOL_RST_RMSQ, wol_rst);
> + }
> +
> +err:
> + return ret;
> +}
> +
> static int rtl821x_resume(struct phy_device *phydev)
> {
> struct rtl821x_priv *priv = phydev->priv;
> @@ -645,6 +735,24 @@ static int rtl821x_resume(struct phy_device *phydev)
> return 0;
> }
>
> +static int rtl8211f_resume(struct phy_device *phydev)
> +{
> + struct rtl821x_priv *priv = phydev->priv;
> + int ret;
> +
> + ret = rtl821x_resume(phydev);
> + if (ret < 0)
> + return ret;
> +
> + /* If the device was programmed for a PME event, restore the interrupt
> + * enable so phylib can receive link state interrupts.
> + */
> + if (device_may_wakeup(&phydev->mdio.dev))
> + ret = phy_write_paged(phydev, 0xa42, RTL821x_INER, priv->iner);
> +
> + return ret;
> +}
> +
> static int rtl8211x_led_hw_is_supported(struct phy_device *phydev, u8 index,
> unsigned long rules)
> {
> @@ -1612,15 +1720,15 @@ static struct phy_driver realtek_drvs[] = {
> }, {
> PHY_ID_MATCH_EXACT(0x001cc916),
> .name = "RTL8211F Gigabit Ethernet",
> - .probe = rtl821x_probe,
> + .probe = rtl8211f_probe,
> .config_init = &rtl8211f_config_init,
> .read_status = rtlgen_read_status,
> .config_intr = &rtl8211f_config_intr,
> .handle_interrupt = rtl8211f_handle_interrupt,
> .set_wol = rtl8211f_set_wol,
> .get_wol = rtl8211f_get_wol,
> - .suspend = rtl821x_suspend,
> - .resume = rtl821x_resume,
> + .suspend = rtl8211f_suspend,
> + .resume = rtl8211f_resume,
> .read_page = rtl821x_read_page,
> .write_page = rtl821x_write_page,
> .flags = PHY_ALWAYS_CALL_SUSPEND,
> --
> 2.30.2
>
>
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net-next] dt-bindings: net: realtek,rtl82xx: document wakeup-source property
2025-08-13 10:04 [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support Russell King (Oracle)
2025-08-13 10:10 ` Russell King (Oracle)
@ 2025-08-13 11:21 ` Russell King (Oracle)
2025-08-13 16:59 ` Conor Dooley
2025-08-19 0:30 ` patchwork-bot+netdevbpf
2025-08-13 12:02 ` [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support Russell King (Oracle)
2025-08-19 0:30 ` patchwork-bot+netdevbpf
3 siblings, 2 replies; 8+ messages in thread
From: Russell King (Oracle) @ 2025-08-13 11:21 UTC (permalink / raw)
To: Andrew Lunn, Heiner Kallweit
Cc: Andrew Lunn, Conor Dooley, David S. Miller, devicetree,
Eric Dumazet, Florian Fainelli, Jakub Kicinski, Jon Hunter,
Krzysztof Kozlowski, netdev, Paolo Abeni, Rob Herring,
Thierry Reding
The RTL8211F PHY has two modes for a single INTB/PMEB pin:
1. INTB mode, where it signals interrupts to the CPU, which can
include wake-on-LAN events.
2. PMEB mode, where it only signals a wake-on-LAN event, which
may either be a latched logic low until software manually
clears the WoL state, or pulsed mode.
In the case of (1), there is no way to know whether the interrupt to
which the PHY is connected is capable of waking the system. In the
case of (2), there would be no interrupt property in the PHY's DT
description, and thus there is nothing to describe whether the pin is
even wired to anything such as a power management controller.
There is a "wakeup-source" property which can be applied to any device
- see Documentation/devicetree/bindings/power/wakeup-source.txt
Case 1 above matches example 2 in this document, and case 2 above
matches example 3. Therefore, it seems reasonable to make use of this
existing specification, albiet it hasn't been converted to YAML.
Document the wakeup-source property in the device description, which
will indicate that the PHY has been wired up in such a way that it
can wake the system from a low power state.
We will use this in a rewrite of the existing broken Wake-on-Lan code
that was merged during the 6.16 merge window to support case 1. Case 2
can be added to the driver later without needing to further alter the
DT description. To be clear, the existing Wake-on-Lan code that was
recently merged has multiple functional issues.
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
---
Apologies, this should've been sent with the patch to the driver which
can be found at:
https://lore.kernel.org/r/E1um8Ld-008jxD-Mc@rmk-PC.armlinux.org.uk
Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml b/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml
index d248a08a2136..2b5697bd7c5d 100644
--- a/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml
+++ b/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml
@@ -45,12 +45,16 @@ title: Realtek RTL82xx PHY
description:
Disable CLKOUT clock, CLKOUT clock default is enabled after hardware reset.
-
realtek,aldps-enable:
type: boolean
description:
Enable ALDPS mode, ALDPS mode default is disabled after hardware reset.
+ wakeup-source:
+ type: boolean
+ description:
+ Enable Wake-on-LAN support for the RTL8211F PHY.
+
unevaluatedProperties: false
allOf:
--
2.30.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support
2025-08-13 10:04 [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support Russell King (Oracle)
2025-08-13 10:10 ` Russell King (Oracle)
2025-08-13 11:21 ` [PATCH net-next] dt-bindings: net: realtek,rtl82xx: document wakeup-source property Russell King (Oracle)
@ 2025-08-13 12:02 ` Russell King (Oracle)
2025-08-15 22:59 ` Andrew Lunn
2025-08-19 0:30 ` patchwork-bot+netdevbpf
3 siblings, 1 reply; 8+ messages in thread
From: Russell King (Oracle) @ 2025-08-13 12:02 UTC (permalink / raw)
To: Andrew Lunn, Heiner Kallweit, Daniel Braunwarth
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Jon Hunter, netdev,
Paolo Abeni, Thierry Reding
On Wed, Aug 13, 2025 at 11:04:45AM +0100, Russell King (Oracle) wrote:
> + /* Mark this PHY as wakeup capable and register the interrupt as a
> + * wakeup IRQ if the PHY is marked as a wakeup source in firmware,
> + * and the interrupt is valid.
> + */
> + if (device_property_read_bool(dev, "wakeup-source") &&
> + phy_interrupt_is_valid(phydev)) {
> + device_set_wakeup_capable(dev, true);
> + devm_pm_set_wake_irq(dev, phydev->irq);
> + }
I'm wondering whether this should just check for the "wakeup-source"
property, which would allow for PMEB mode, and if we don't have a valid
interrupt, we set the INTB/PMEB pin to PMEB mode here. In other words:
if (device_property_read_bool(dev, "wakeup-source")) {
device_set_wakeup_capable(dev, true);
if (phy_interrupt_is_valid(phydev)) {
devm_pm_set_wake_irq(dev, phydev->irq);
} else {
ret = phy_modify_paged(phydev, RTL8211F_INTBCR_PAGE,
RTL8211F_INTBCR,
RTL8211F_INTBCR_INTB_PMEB,
RTL8211F_INTBCR_INTB_PMEB);
}
}
this would support example 3 in the wakeup-source document, where the
PHY is connected to an interrupt-less power management controller.
Any thoughts?
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] dt-bindings: net: realtek,rtl82xx: document wakeup-source property
2025-08-13 11:21 ` [PATCH net-next] dt-bindings: net: realtek,rtl82xx: document wakeup-source property Russell King (Oracle)
@ 2025-08-13 16:59 ` Conor Dooley
2025-08-19 0:30 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 8+ messages in thread
From: Conor Dooley @ 2025-08-13 16:59 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: Andrew Lunn, Heiner Kallweit, Andrew Lunn, Conor Dooley,
David S. Miller, devicetree, Eric Dumazet, Florian Fainelli,
Jakub Kicinski, Jon Hunter, Krzysztof Kozlowski, netdev,
Paolo Abeni, Rob Herring, Thierry Reding
[-- Attachment #1: Type: text/plain, Size: 2940 bytes --]
On Wed, Aug 13, 2025 at 12:21:19PM +0100, Russell King (Oracle) wrote:
> The RTL8211F PHY has two modes for a single INTB/PMEB pin:
>
> 1. INTB mode, where it signals interrupts to the CPU, which can
> include wake-on-LAN events.
> 2. PMEB mode, where it only signals a wake-on-LAN event, which
> may either be a latched logic low until software manually
> clears the WoL state, or pulsed mode.
>
> In the case of (1), there is no way to know whether the interrupt to
> which the PHY is connected is capable of waking the system. In the
> case of (2), there would be no interrupt property in the PHY's DT
> description, and thus there is nothing to describe whether the pin is
> even wired to anything such as a power management controller.
>
> There is a "wakeup-source" property which can be applied to any device
> - see Documentation/devicetree/bindings/power/wakeup-source.txt
>
> Case 1 above matches example 2 in this document, and case 2 above
> matches example 3. Therefore, it seems reasonable to make use of this
> existing specification, albiet it hasn't been converted to YAML.
>
> Document the wakeup-source property in the device description, which
> will indicate that the PHY has been wired up in such a way that it
> can wake the system from a low power state.
>
> We will use this in a rewrite of the existing broken Wake-on-Lan code
> that was merged during the 6.16 merge window to support case 1. Case 2
> can be added to the driver later without needing to further alter the
> DT description. To be clear, the existing Wake-on-Lan code that was
> recently merged has multiple functional issues.
>
> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
> ---
> Apologies, this should've been sent with the patch to the driver which
> can be found at:
>
> https://lore.kernel.org/r/E1um8Ld-008jxD-Mc@rmk-PC.armlinux.org.uk
Acked-by: Conor Dooley <conor.dooley@microchip.com>
>
> Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml b/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml
> index d248a08a2136..2b5697bd7c5d 100644
> --- a/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml
> +++ b/Documentation/devicetree/bindings/net/realtek,rtl82xx.yaml
> @@ -45,12 +45,16 @@ title: Realtek RTL82xx PHY
> description:
> Disable CLKOUT clock, CLKOUT clock default is enabled after hardware reset.
>
> -
> realtek,aldps-enable:
> type: boolean
> description:
> Enable ALDPS mode, ALDPS mode default is disabled after hardware reset.
>
> + wakeup-source:
> + type: boolean
> + description:
> + Enable Wake-on-LAN support for the RTL8211F PHY.
> +
> unevaluatedProperties: false
>
> allOf:
> --
> 2.30.2
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support
2025-08-13 12:02 ` [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support Russell King (Oracle)
@ 2025-08-15 22:59 ` Andrew Lunn
0 siblings, 0 replies; 8+ messages in thread
From: Andrew Lunn @ 2025-08-15 22:59 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: Heiner Kallweit, Daniel Braunwarth, David S. Miller, Eric Dumazet,
Jakub Kicinski, Jon Hunter, netdev, Paolo Abeni, Thierry Reding
On Wed, Aug 13, 2025 at 01:02:46PM +0100, Russell King (Oracle) wrote:
> On Wed, Aug 13, 2025 at 11:04:45AM +0100, Russell King (Oracle) wrote:
> > + /* Mark this PHY as wakeup capable and register the interrupt as a
> > + * wakeup IRQ if the PHY is marked as a wakeup source in firmware,
> > + * and the interrupt is valid.
> > + */
> > + if (device_property_read_bool(dev, "wakeup-source") &&
> > + phy_interrupt_is_valid(phydev)) {
> > + device_set_wakeup_capable(dev, true);
> > + devm_pm_set_wake_irq(dev, phydev->irq);
> > + }
>
> I'm wondering whether this should just check for the "wakeup-source"
> property, which would allow for PMEB mode, and if we don't have a valid
> interrupt, we set the INTB/PMEB pin to PMEB mode here. In other words:
>
> if (device_property_read_bool(dev, "wakeup-source")) {
> device_set_wakeup_capable(dev, true);
> if (phy_interrupt_is_valid(phydev)) {
> devm_pm_set_wake_irq(dev, phydev->irq);
> } else {
> ret = phy_modify_paged(phydev, RTL8211F_INTBCR_PAGE,
> RTL8211F_INTBCR,
> RTL8211F_INTBCR_INTB_PMEB,
> RTL8211F_INTBCR_INTB_PMEB);
> }
> }
>
> this would support example 3 in the wakeup-source document, where the
> PHY is connected to an interrupt-less power management controller.
>
> Any thoughts?
I guess you have no way to actually test it?
I would probably not support it now. When somebody actually needs it,
this email exists, it points out how to do it.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] dt-bindings: net: realtek,rtl82xx: document wakeup-source property
2025-08-13 11:21 ` [PATCH net-next] dt-bindings: net: realtek,rtl82xx: document wakeup-source property Russell King (Oracle)
2025-08-13 16:59 ` Conor Dooley
@ 2025-08-19 0:30 ` patchwork-bot+netdevbpf
1 sibling, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-08-19 0:30 UTC (permalink / raw)
To: Russell King
Cc: andrew, hkallweit1, andrew+netdev, conor+dt, davem, devicetree,
edumazet, f.fainelli, kuba, jonathanh, krzk+dt, netdev, pabeni,
robh, treding
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Wed, 13 Aug 2025 12:21:19 +0100 you wrote:
> The RTL8211F PHY has two modes for a single INTB/PMEB pin:
>
> 1. INTB mode, where it signals interrupts to the CPU, which can
> include wake-on-LAN events.
> 2. PMEB mode, where it only signals a wake-on-LAN event, which
> may either be a latched logic low until software manually
> clears the WoL state, or pulsed mode.
>
> [...]
Here is the summary with links:
- [net-next] dt-bindings: net: realtek,rtl82xx: document wakeup-source property
https://git.kernel.org/netdev/net-next/c/a510980e740c
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support
2025-08-13 10:04 [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support Russell King (Oracle)
` (2 preceding siblings ...)
2025-08-13 12:02 ` [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support Russell King (Oracle)
@ 2025-08-19 0:30 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-08-19 0:30 UTC (permalink / raw)
To: Russell King
Cc: andrew, hkallweit1, davem, edumazet, kuba, jonathanh, netdev,
pabeni, treding
Hello:
This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Wed, 13 Aug 2025 11:04:45 +0100 you wrote:
> Implement Wake-on-Lan for RTL8211F correctly. The existing
> implementation has multiple issues:
>
> 1. It assumes that Wake-on-Lan can always be used, whether or not the
> interrupt is wired, and whether or not the interrupt is capable of
> waking the system. This breaks the ability for MAC drivers to detect
> whether the PHY WoL is functional.
> 2. switching the interrupt pin in the .set_wol() method to PMEB mode
> immediately silences link-state interrupts, which breaks phylib
> when interrupts are being used rather than polling mode.
> 3. the code claiming to "reset WOL status" was doing nothing of the
> sort. Bit 15 in page 0xd8a register 17 controls WoL reset, and
> needs to be pulsed low to reset the WoL state. This bit was always
> written as '1', resulting in no reset.
> 4. not resetting WoL state results in the PMEB pin remaining asserted,
> which in turn leads to an interrupt storm. Only resetting the WoL
> state in .set_wol() is not sufficient.
> 5. PMEB mode does not allow software detection of the wake-up event as
> there is no status bit to indicate we received the WoL packet.
> 6. across reboots of at least the Jetson Xavier NX system, the WoL
> configuration is preserved.
>
> [...]
Here is the summary with links:
- [net-next] net: phy: realtek: fix RTL8211F wake-on-lan support
https://git.kernel.org/netdev/net-next/c/b826bf795564
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2025-08-19 0:30 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-13 10:04 [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support Russell King (Oracle)
2025-08-13 10:10 ` Russell King (Oracle)
2025-08-13 11:21 ` [PATCH net-next] dt-bindings: net: realtek,rtl82xx: document wakeup-source property Russell King (Oracle)
2025-08-13 16:59 ` Conor Dooley
2025-08-19 0:30 ` patchwork-bot+netdevbpf
2025-08-13 12:02 ` [PATCH net-next] net: phy: realtek: fix RTL8211F wake-on-lan support Russell King (Oracle)
2025-08-15 22:59 ` Andrew Lunn
2025-08-19 0:30 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).