* [PATCH net-next v4 01/10] net: ethernet: ravb: Remove gPTP control from WoL setup and restore
2026-09-09 17:30 [PATCH net-next v4 00/10] ravb: Add gPTP support for Gen4 Niklas Söderlund
@ 2026-09-09 17:30 ` Niklas Söderlund
2026-09-10 17:31 ` sashiko-bot
2026-09-09 17:30 ` [PATCH net-next v4 02/10] net: ethernet: ravb: Move programming of gPTP timer interval Niklas Söderlund
` (8 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Niklas Söderlund @ 2026-09-09 17:30 UTC (permalink / raw)
To: paul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Richard Cochran, Andrew Lunn,
DavidS. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Vadim Fedorenko, Sergey Shtylyov, linux-renesas-soc, devicetree,
linux-kernel, netdev
Cc: Niklas Söderlund
Since commit a6a85ba36fd0 ("net: ravb: Move PTP initialization in the
driver's ndo_open API for ccc_gac platorms") the gPTP clock (if
supported) is stopped and started by opening and closing the ndev.
This makes the special case to stop and start it when resuming from WoL
redundant. As the ndev will always be closed and re-opened when
suspending and resuming the system.
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Sergey Shtylyov <sergei.shtylyov@gmail.com>
---
drivers/net/ethernet/renesas/ravb_main.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index ea1c7e536791..36173a09e2fd 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -3182,9 +3182,6 @@ static int ravb_wol_setup(struct net_device *ndev)
/* Enable MagicPacket */
ravb_modify(ndev, ECMR, ECMR_MPDE, ECMR_MPDE);
- if (priv->info->ccc_gac)
- ravb_ptp_stop(ndev);
-
return enable_irq_wake(priv->emac_irq);
}
@@ -3204,9 +3201,6 @@ static int ravb_wol_restore(struct net_device *ndev)
if (error)
return error;
- if (priv->info->ccc_gac)
- ravb_ptp_init(ndev, priv->pdev);
-
if (info->nc_queues)
napi_enable(&priv->napi[RAVB_NC]);
napi_enable(&priv->napi[RAVB_BE]);
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v4 01/10] net: ethernet: ravb: Remove gPTP control from WoL setup and restore
2026-09-09 17:30 ` [PATCH net-next v4 01/10] net: ethernet: ravb: Remove gPTP control from WoL setup and restore Niklas Söderlund
@ 2026-09-10 17:31 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-09-10 17:31 UTC (permalink / raw)
To: Niklas Söderlund; +Cc: robh, conor+dt, wsa+renesas, devicetree
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Meaningful code and commit message mismatch leading to unintended PTP clock lifecycle.
--
commit d9a97079fb4ac0a52b7c3683f3c046c7743362d3
Author: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
net: ethernet: ravb: Remove gPTP control from WoL setup and restore
This commit removes the explicit gPTP stop/start calls from the Wake-on-LAN
(WoL) suspend and resume paths. It asserts that opening and closing the
netdev already handles this clock control.
> As the ndev will always be closed and re-opened when
> suspending and resuming the system.
[Severity: Medium]
Is this assumption in the commit message accurate? Looking at ravb_suspend()
in drivers/net/ethernet/renesas/ravb_main.c, it appears to bypass
ravb_close() entirely when WoL is enabled:
if (priv->wol_enabled) {
ret = ravb_wol_setup(ndev);
rtnl_unlock();
return ret;
}
ret = ravb_close(ndev);
> diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
> --- a/drivers/net/ethernet/renesas/ravb_main.c
> +++ b/drivers/net/ethernet/renesas/ravb_main.c
> @@ -3182,9 +3182,6 @@ static int ravb_wol_setup(struct net_device *ndev)
> /* Enable MagicPacket */
> ravb_modify(ndev, ECMR, ECMR_MPDE, ECMR_MPDE);
>
> - if (priv->info->ccc_gac)
> - ravb_ptp_stop(ndev);
> -
[Severity: Medium]
Since ravb_close() is skipped for WoL suspend, does removing the explicit
ravb_ptp_stop() leave the gPTP clock running?
It looks like this might introduce an unintended asymmetric lifecycle on
ccc_gac platforms, where the clock stays running during WoL suspend but is
then unregistered during resume when ravb_wol_restore() invokes ravb_close().
> return enable_irq_wake(priv->emac_irq);
> }
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260909173027.2201560-1-niklas.soderlund+renesas@ragnatech.se?part=1
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next v4 02/10] net: ethernet: ravb: Move programming of gPTP timer interval
2026-09-09 17:30 [PATCH net-next v4 00/10] ravb: Add gPTP support for Gen4 Niklas Söderlund
2026-09-09 17:30 ` [PATCH net-next v4 01/10] net: ethernet: ravb: Remove gPTP control from WoL setup and restore Niklas Söderlund
@ 2026-09-09 17:30 ` Niklas Söderlund
2026-09-10 17:31 ` sashiko-bot
2026-09-09 17:30 ` [PATCH net-next v4 03/10] net: ethernet: ravb: Simplify gPTP start and stop Niklas Söderlund
` (7 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Niklas Söderlund @ 2026-09-09 17:30 UTC (permalink / raw)
To: paul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Richard Cochran, Andrew Lunn,
DavidS. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Vadim Fedorenko, Sergey Shtylyov, linux-renesas-soc, devicetree,
linux-kernel, netdev
Cc: Niklas Söderlund
Commit f384ab481cab ("net: ravb: Split GTI computation and set
operations") broke apart the operations of computing the timer interval
and programming of it. However it kept the programming of the interval
in the RAVB main logic.
Having split the two apart this can be improved further by moving the
programming to the gPTP initialization function, as the first action of
the gPTP init function is to wait for the timer interval programming to
be acknowledge by the hardware.
As an added bonus the interaction with the gPTP registers for the
programming can then also be done while holding the gPTP registers lock.
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Sergey Shtylyov <sergei.shtylyov@gmail.com>
---
drivers/net/ethernet/renesas/ravb_main.c | 16 ----------------
drivers/net/ethernet/renesas/ravb_ptp.c | 11 ++++++++++-
2 files changed, 10 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 36173a09e2fd..a89f6fe7866f 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -1846,20 +1846,6 @@ static int ravb_set_config_mode(struct net_device *ndev)
return error;
}
-static void ravb_set_gti(struct net_device *ndev)
-{
- struct ravb_private *priv = netdev_priv(ndev);
- const struct ravb_hw_info *info = priv->info;
-
- if (!(info->gptp || info->ccc_gac))
- return;
-
- ravb_write(ndev, priv->gti_tiv, GTI);
-
- /* Request GTI loading */
- ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
-}
-
static int ravb_compute_gti(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
@@ -1974,8 +1960,6 @@ static int ravb_open(struct net_device *ndev)
ravb_emac_init(ndev);
- ravb_set_gti(ndev);
-
/* Initialise PTP Clock driver */
if (info->gptp || info->ccc_gac)
ravb_ptp_init(ndev, priv->pdev);
diff --git a/drivers/net/ethernet/renesas/ravb_ptp.c b/drivers/net/ethernet/renesas/ravb_ptp.c
index 43218bc15b15..157fb78209c7 100644
--- a/drivers/net/ethernet/renesas/ravb_ptp.c
+++ b/drivers/net/ethernet/renesas/ravb_ptp.c
@@ -321,11 +321,20 @@ void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev)
priv->ptp.info = ravb_ptp_info;
- priv->ptp.default_addend = ravb_read(ndev, GTI);
+ priv->ptp.default_addend = priv->gti_tiv;
priv->ptp.current_addend = priv->ptp.default_addend;
spin_lock_irqsave(&priv->lock, flags);
+
+ /* Set gPTP Timer Increment Value. */
+ ravb_write(ndev, priv->ptp.default_addend, GTI);
+
+ /* Request GTI loading. */
+ ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
+
+ /* Wait for GIT loading to complete. */
ravb_wait(ndev, GCCR, GCCR_TCR, GCCR_TCR_NOREQ);
+
ravb_modify(ndev, GCCR, GCCR_TCSS, GCCR_TCSS_ADJGPTP);
spin_unlock_irqrestore(&priv->lock, flags);
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v4 02/10] net: ethernet: ravb: Move programming of gPTP timer interval
2026-09-09 17:30 ` [PATCH net-next v4 02/10] net: ethernet: ravb: Move programming of gPTP timer interval Niklas Söderlund
@ 2026-09-10 17:31 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-09-10 17:31 UTC (permalink / raw)
To: Niklas Söderlund; +Cc: robh, conor+dt, devicetree, wsa+renesas
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Incorrect wait condition for GTI loading completion causes a read-modify-write race on GCCR.
--
commit f10e77bf451957f130f23e3dcc282e0d86b9d848
Author: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
net: ethernet: ravb: Move programming of gPTP timer interval
This commit moves the programming of the gPTP timer interval from the
main RAVB logic into the gPTP initialization function. It also executes
this operation while holding the gPTP registers lock and attempts to
wait for the hardware to acknowledge the programming.
> diff --git a/drivers/net/ethernet/renesas/ravb_ptp.c b/drivers/net/ethernet/renesas/ravb_ptp.c
> index 43218bc15b151..157fb78209c78 100644
> --- a/drivers/net/ethernet/renesas/ravb_ptp.c
> +++ b/drivers/net/ethernet/renesas/ravb_ptp.c
[ ... ]
> @@ -321,11 +321,20 @@ void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev)
>
> priv->ptp.info = ravb_ptp_info;
>
> - priv->ptp.default_addend = ravb_read(ndev, GTI);
> + priv->ptp.default_addend = priv->gti_tiv;
> priv->ptp.current_addend = priv->ptp.default_addend;
>
> spin_lock_irqsave(&priv->lock, flags);
> +
> + /* Set gPTP Timer Increment Value. */
> + ravb_write(ndev, priv->ptp.default_addend, GTI);
> +
> + /* Request GTI loading. */
> + ravb_modify(ndev, GCCR, GCCR_LTI, GCCR_LTI);
> +
> + /* Wait for GIT loading to complete. */
> ravb_wait(ndev, GCCR, GCCR_TCR, GCCR_TCR_NOREQ);
[Severity: High]
Does this wait on the correct bits for GTI loading? The comment mentions
waiting for the load to complete, which is triggered by GCCR_LTI, but the
code polls GCCR_TCR instead.
Since the wait condition on GCCR_TCR is likely already met (no TCR request
active), this wait will return immediately.
> +
> ravb_modify(ndev, GCCR, GCCR_TCSS, GCCR_TCSS_ADJGPTP);
If the hardware is still processing the LTI request, could this read-modify-write
operation cause a race condition?
It might read the still-active GCCR_LTI bit and write it back to 1,
erroneously re-triggering the loading and potentially corrupting the gPTP
hardware state machine during normal interface configuration.
> spin_unlock_irqrestore(&priv->lock, flags);
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260909173027.2201560-1-niklas.soderlund+renesas@ragnatech.se?part=2
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next v4 03/10] net: ethernet: ravb: Simplify gPTP start and stop
2026-09-09 17:30 [PATCH net-next v4 00/10] ravb: Add gPTP support for Gen4 Niklas Söderlund
2026-09-09 17:30 ` [PATCH net-next v4 01/10] net: ethernet: ravb: Remove gPTP control from WoL setup and restore Niklas Söderlund
2026-09-09 17:30 ` [PATCH net-next v4 02/10] net: ethernet: ravb: Move programming of gPTP timer interval Niklas Söderlund
@ 2026-09-09 17:30 ` Niklas Söderlund
2026-09-10 17:31 ` sashiko-bot
2026-09-09 17:30 ` [PATCH net-next v4 04/10] net: ethernet: ravb: Remove redundant argument to ravb_ptp_init() Niklas Söderlund
` (6 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Niklas Söderlund @ 2026-09-09 17:30 UTC (permalink / raw)
To: paul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Richard Cochran, Andrew Lunn,
DavidS. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Vadim Fedorenko, Sergey Shtylyov, linux-renesas-soc, devicetree,
linux-kernel, netdev
Cc: Niklas Söderlund
For devices that do not support the gPTP clock in config mode the
somewhat oddly named flag gptp is set, compared to devices that do
support the gPTP clock in config and operation mode where the flag
ccc_gac is set instead. The two flags are mutually exclusive.
For the gptp-flag devices (Gen2) the clock is tied to the AVB-DMAC, when
it is stopped so is the gPTP clock. For ccc_gac-flag devices (Gen3) the
gPTP clock is available whenever the ndev is open.
Prepare to add Gen4 support which will add a third way by cleaning the
Gen2 and Gen3 cases up a bit.
Fold the gptp-flag start and stop calls into ravb_dmac_init() and
ravb_stop_dma(), which start and stop the AVB-DMAC. There are no
functional change as all call sites to the construct:
if (info->gptp)
ravb_ptp_init(ndev, priv->pdev);
are always just after a call to into ravb_dmac_init() and all call sites
to the construct:
if (info->gptp)
ravb_ptp_stop(ndev);
are always directly followed by a call to ravb_stop_dma().
There are two special cases where the calling construct covers both the
gptp-flag and info->ccc_gac devices, one for start and one for stop. The
condition that it is preceded by a call to ravb_dmac_init(), or followed
by a call to ravb_stop_dma() are however true for them too. Reworked the
two special cases to drop the check of info->gptp.
The end result is that the gPTP clock will be started or stopped for the
gptp-flag devices in tandem with the AVB-DMAC, while the info->ccc_gac
devices will be controlled, as before, when the ndev is opened or
closed.
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Sergey Shtylyov <sergei.shtylyov@gmail.com>
---
* Changes since v1
- Improve spelling in commit message.
---
drivers/net/ethernet/renesas/ravb_main.c | 37 ++++++++++--------------
1 file changed, 16 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index a89f6fe7866f..2d0022a4f85c 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -707,7 +707,15 @@ static int ravb_dmac_init(struct net_device *ndev)
return error;
/* Setting the control will start the AVB-DMAC process. */
- return ravb_set_opmode(ndev, CCC_OPC_OPERATION);
+ error = ravb_set_opmode(ndev, CCC_OPC_OPERATION);
+ if (error)
+ return error;
+
+ /* Initialise PTP Clock driver */
+ if (info->gptp)
+ ravb_ptp_init(ndev, priv->pdev);
+
+ return 0;
}
static void ravb_get_tx_tstamp(struct net_device *ndev)
@@ -1115,6 +1123,10 @@ static int ravb_stop_dma(struct net_device *ndev)
netdev_err(ndev, "failed to stop AXI BUS\n");
}
+ /* Stop PTP Clock driver */
+ if (info->gptp)
+ ravb_ptp_stop(ndev);
+
/* Stop AVB-DMAC process */
return ravb_set_opmode(ndev, CCC_OPC_CONFIG);
}
@@ -1719,9 +1731,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
if (netif_running(ndev)) {
netif_device_detach(ndev);
- /* Stop PTP Clock driver */
- if (info->gptp)
- ravb_ptp_stop(ndev);
+
/* Wait for DMA stopping */
error = ravb_stop_dma(ndev);
if (error) {
@@ -1752,10 +1762,6 @@ static int ravb_set_ringparam(struct net_device *ndev,
ravb_emac_init(ndev);
- /* Initialise PTP Clock driver */
- if (info->gptp)
- ravb_ptp_init(ndev, priv->pdev);
-
netif_device_attach(ndev);
}
@@ -1961,7 +1967,7 @@ static int ravb_open(struct net_device *ndev)
ravb_emac_init(ndev);
/* Initialise PTP Clock driver */
- if (info->gptp || info->ccc_gac)
+ if (info->ccc_gac)
ravb_ptp_init(ndev, priv->pdev);
/* PHY control start */
@@ -1974,9 +1980,6 @@ static int ravb_open(struct net_device *ndev)
return 0;
out_ptp_stop:
- /* Stop PTP Clock driver */
- if (info->gptp || info->ccc_gac)
- ravb_ptp_stop(ndev);
ravb_stop_dma(ndev);
out_set_reset:
ravb_set_opmode(ndev, CCC_OPC_RESET);
@@ -2020,10 +2023,6 @@ static void ravb_tx_timeout_work(struct work_struct *work)
netif_tx_stop_all_queues(ndev);
- /* Stop PTP Clock driver */
- if (info->gptp)
- ravb_ptp_stop(ndev);
-
/* Wait for DMA stopping */
if (ravb_stop_dma(ndev)) {
/* If ravb_stop_dma() fails, the hardware is still operating
@@ -2056,10 +2055,6 @@ static void ravb_tx_timeout_work(struct work_struct *work)
ravb_emac_init(ndev);
out:
- /* Initialise PTP Clock driver */
- if (info->gptp)
- ravb_ptp_init(ndev, priv->pdev);
-
netif_tx_start_all_queues(ndev);
out_unlock:
@@ -2374,7 +2369,7 @@ static int ravb_close(struct net_device *ndev)
}
/* Stop PTP Clock driver */
- if (info->gptp || info->ccc_gac)
+ if (info->ccc_gac)
ravb_ptp_stop(ndev);
/* Set the config mode to stop the AVB-DMAC's processes */
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v4 03/10] net: ethernet: ravb: Simplify gPTP start and stop
2026-09-09 17:30 ` [PATCH net-next v4 03/10] net: ethernet: ravb: Simplify gPTP start and stop Niklas Söderlund
@ 2026-09-10 17:31 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-09-10 17:31 UTC (permalink / raw)
To: Niklas Söderlund; +Cc: devicetree, robh, wsa+renesas, conor+dt
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [Critical] For gptp devices, early returns in ravb_stop_dma() skip stopping the PTP clock, leading to Use-After-Free in ravb_close().
- [High] Missing PTP clock cleanup on ravb_open() error path for ccc_gac devices.
- [Medium] PTP clock remains permanently stopped if ravb_stop_dma() fails late during TX timeout recovery.
Pre-existing issues:
- [High] Missing NAPI synchronization before freeing DMA rings can lead to concurrent access.
--
commit cfbb6c5f1a7c830cb10526b29bb3646d146532ea
Author: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Subject: net: ethernet: ravb: Simplify gPTP start and stop
The patch simplifies the start and stop of gPTP clocks for Gen2 (gptp-flag)
and Gen3 (ccc_gac) devices. It ties Gen2's PTP clock to the AVB-DMAC start
and stop, while Gen3's PTP clock remains controlled on interface open/close.
> diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
> index a89f6fe7866fe..2d0022a4f85c3 100644
> --- a/drivers/net/ethernet/renesas/ravb_main.c
> +++ b/drivers/net/ethernet/renesas/ravb_main.c
[ ... ]
> @@ -1115,6 +1123,10 @@ static int ravb_stop_dma(struct net_device *ndev)
> netdev_err(ndev, "failed to stop AXI BUS\n");
> }
>
> + /* Stop PTP Clock driver */
> + if (info->gptp)
> + ravb_ptp_stop(ndev);
> +
[Severity: Critical]
Could moving the PTP clock stop to the end of ravb_stop_dma() introduce a use-after-free
if there is a hardware timeout?
ravb_stop_dma() contains multiple early returns if ravb_wait() times out:
static int ravb_stop_dma(struct net_device *ndev)
{
...
/* Wait for stopping the hardware TX process */
error = ravb_wait(ndev, TCCR, info->tccr_mask, 0);
if (error)
return error;
...
If one of these early returns is taken, the new ravb_ptp_stop() call is bypassed.
Later, during device teardown, ravb_close() ignores errors from ravb_stop_dma():
/* Set the config mode to stop the AVB-DMAC's processes */
if (ravb_stop_dma(ndev) < 0)
netdev_err(ndev,
"device will be stopped after h/w processes are done.\n");
/* Clear the timestamp list */
Since ravb_close() continues and frees the device structures, what happens if the PTP clock
was bypassed and remains registered? It appears subsequent ioctls to /dev/ptpX
could dereference the freed pointer.
> /* Stop AVB-DMAC process */
> return ravb_set_opmode(ndev, CCC_OPC_CONFIG);
> }
[ ... ]
> @@ -1719,9 +1731,7 @@ static int ravb_set_ringparam(struct net_device *ndev,
>
> if (netif_running(ndev)) {
> netif_device_detach(ndev);
> - /* Stop PTP Clock driver */
> - if (info->gptp)
> - ravb_ptp_stop(ndev);
> +
> /* Wait for DMA stopping */
> error = ravb_stop_dma(ndev);
[Severity: High]
This isn't a bug introduced by this patch, but does freeing the rings here race
with NAPI polling?
Just after this block in ravb_set_ringparam(), the code frees the DMA buffers
without disabling NAPI:
synchronize_irq(ndev->irq);
/* Free all the skb's in the RX queue and the DMA buffers. */
ravb_ring_free(ndev, RAVB_BE);
Since synchronize_irq() only waits for hard IRQ handlers to finish, a NAPI poll
could execute concurrently on another CPU while the rings are being freed.
Would it be better to call napi_disable() before freeing the resources?
[ ... ]
> @@ -1974,9 +1980,6 @@ static int ravb_open(struct net_device *ndev)
> return 0;
>
> out_ptp_stop:
> - /* Stop PTP Clock driver */
> - if (info->gptp || info->ccc_gac)
> - ravb_ptp_stop(ndev);
> ravb_stop_dma(ndev);
> out_set_reset:
[Severity: High]
Is there a resource leak of the PTP clock for ccc_gac devices when removing this
explicit cleanup?
If ravb_open() fails during ravb_phy_start() on a device with the ccc_gac flag,
it jumps to the out_ptp_stop label. With this patch, the cleanup relies entirely
on ravb_stop_dma().
However, ravb_stop_dma() only stops the PTP clock if info->gptp is true. Since
info->gptp and info->ccc_gac are mutually exclusive, it seems the PTP clock will
remain registered when initialization fails for ccc_gac devices.
[ ... ]
> @@ -2056,10 +2055,6 @@ static void ravb_tx_timeout_work(struct work_struct *work)
> ravb_emac_init(ndev);
>
> out:
> - /* Initialise PTP Clock driver */
> - if (info->gptp)
> - ravb_ptp_init(ndev, priv->pdev);
> -
[Severity: Medium]
Will the PTP clock become permanently disabled here if ravb_stop_dma() fails
late during timeout recovery?
If ravb_stop_dma() fails during its final ravb_set_opmode() call, it returns
an error after it has already stopped the PTP clock.
In ravb_tx_timeout_work(), this failure causes a jump directly to the out label:
if (ravb_stop_dma(ndev)) {
ravb_rcv_snd_enable(ndev);
goto out;
}
Because ravb_ptp_init() has been removed from the out label, the PTP clock
will remain stopped even though the device resumes passing traffic.
> netif_tx_start_all_queues(ndev);
>
> out_unlock:
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260909173027.2201560-1-niklas.soderlund+renesas@ragnatech.se?part=3
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next v4 04/10] net: ethernet: ravb: Remove redundant argument to ravb_ptp_init()
2026-09-09 17:30 [PATCH net-next v4 00/10] ravb: Add gPTP support for Gen4 Niklas Söderlund
` (2 preceding siblings ...)
2026-09-09 17:30 ` [PATCH net-next v4 03/10] net: ethernet: ravb: Simplify gPTP start and stop Niklas Söderlund
@ 2026-09-09 17:30 ` Niklas Söderlund
2026-09-09 17:30 ` [PATCH net-next v4 05/10] net: ethernet: ravb: Propagate error from ptp_clock_register() Niklas Söderlund
` (5 subsequent siblings)
9 siblings, 0 replies; 19+ messages in thread
From: Niklas Söderlund @ 2026-09-09 17:30 UTC (permalink / raw)
To: paul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Richard Cochran, Andrew Lunn,
DavidS. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Vadim Fedorenko, Sergey Shtylyov, linux-renesas-soc, devicetree,
linux-kernel, netdev
Cc: Niklas Söderlund
There is no need to explicitly pass the struct platform_device pointer
to ravb_ptp_init(), it can retrieve it directly from the private data
structure.
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Sergey Shtylyov <sergei.shtylyov@gmail.com>
---
drivers/net/ethernet/renesas/ravb.h | 2 +-
drivers/net/ethernet/renesas/ravb_main.c | 4 ++--
drivers/net/ethernet/renesas/ravb_ptp.c | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index 3ee4c6108189..aa45f5466001 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -1163,7 +1163,7 @@ void ravb_modify(struct net_device *ndev, enum ravb_reg reg, u32 clear,
int ravb_wait(struct net_device *ndev, enum ravb_reg reg, u32 mask, u32 value);
void ravb_ptp_interrupt(struct net_device *ndev);
-void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev);
+void ravb_ptp_init(struct net_device *ndev);
void ravb_ptp_stop(struct net_device *ndev);
#endif /* #ifndef __RAVB_H__ */
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 2d0022a4f85c..e44d065f77cc 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -713,7 +713,7 @@ static int ravb_dmac_init(struct net_device *ndev)
/* Initialise PTP Clock driver */
if (info->gptp)
- ravb_ptp_init(ndev, priv->pdev);
+ ravb_ptp_init(ndev);
return 0;
}
@@ -1968,7 +1968,7 @@ static int ravb_open(struct net_device *ndev)
/* Initialise PTP Clock driver */
if (info->ccc_gac)
- ravb_ptp_init(ndev, priv->pdev);
+ ravb_ptp_init(ndev);
/* PHY control start */
error = ravb_phy_start(ndev);
diff --git a/drivers/net/ethernet/renesas/ravb_ptp.c b/drivers/net/ethernet/renesas/ravb_ptp.c
index 157fb78209c7..f70b616ac847 100644
--- a/drivers/net/ethernet/renesas/ravb_ptp.c
+++ b/drivers/net/ethernet/renesas/ravb_ptp.c
@@ -313,7 +313,7 @@ void ravb_ptp_interrupt(struct net_device *ndev)
ravb_write(ndev, ~(gis | GIS_RESERVED), GIS);
}
-void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev)
+void ravb_ptp_init(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
struct ptp_clock *clock;
@@ -338,7 +338,7 @@ void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev)
ravb_modify(ndev, GCCR, GCCR_TCSS, GCCR_TCSS_ADJGPTP);
spin_unlock_irqrestore(&priv->lock, flags);
- clock = ptp_clock_register(&priv->ptp.info, &pdev->dev);
+ clock = ptp_clock_register(&priv->ptp.info, &priv->pdev->dev);
if (IS_ERR(clock)) {
netdev_err(ndev, "failed to register PTP clock: %pe\n", clock);
clock = NULL;
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH net-next v4 05/10] net: ethernet: ravb: Propagate error from ptp_clock_register()
2026-09-09 17:30 [PATCH net-next v4 00/10] ravb: Add gPTP support for Gen4 Niklas Söderlund
` (3 preceding siblings ...)
2026-09-09 17:30 ` [PATCH net-next v4 04/10] net: ethernet: ravb: Remove redundant argument to ravb_ptp_init() Niklas Söderlund
@ 2026-09-09 17:30 ` Niklas Söderlund
2026-09-10 17:31 ` sashiko-bot
2026-09-09 17:30 ` [PATCH net-next v4 06/10] net: ethernet: ravb: Replace gPTP flags with callbacks Niklas Söderlund
` (4 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Niklas Söderlund @ 2026-09-09 17:30 UTC (permalink / raw)
To: paul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Richard Cochran, Andrew Lunn,
DavidS. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Vadim Fedorenko, Sergey Shtylyov, linux-renesas-soc, devicetree,
linux-kernel, netdev
Cc: Niklas Söderlund
If the PTP clock registration failed the error is silently ignored.
Before reworking all callers of ravb_ptp_init() handle and propagate the
error so it can be used.
Link: https://sashiko.dev/#/patchset/20260610102432.3538432-2-niklas.soderlund+renesas@ragnatech.se?part=1
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Sergey Shtylyov <sergei.shtylyov@gmail.com>
---
* Changes since v3
- Add check to keep sashiko happy, the remark is fixed already later in
the series but to keep the bot happy.
* Changes since v2
- Rework to remove the caching of phc_index added by LLM without access
to hardware.
* Changes since v1
- New in v2.
---
drivers/net/ethernet/renesas/ravb.h | 3 +--
drivers/net/ethernet/renesas/ravb_main.c | 5 ++---
drivers/net/ethernet/renesas/ravb_ptp.c | 27 +++++++++++-------------
3 files changed, 15 insertions(+), 20 deletions(-)
diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index aa45f5466001..0c122a815840 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -1028,7 +1028,6 @@ struct ravb_ptp_perout {
struct ravb_ptp {
struct ptp_clock *clock;
struct ptp_clock_info info;
- int phc_index;
u32 default_addend;
u32 current_addend;
int extts[N_EXT_TS];
@@ -1163,7 +1162,7 @@ void ravb_modify(struct net_device *ndev, enum ravb_reg reg, u32 clear,
int ravb_wait(struct net_device *ndev, enum ravb_reg reg, u32 mask, u32 value);
void ravb_ptp_interrupt(struct net_device *ndev);
-void ravb_ptp_init(struct net_device *ndev);
+int ravb_ptp_init(struct net_device *ndev);
void ravb_ptp_stop(struct net_device *ndev);
#endif /* #ifndef __RAVB_H__ */
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index e44d065f77cc..5ba322593a01 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -1774,7 +1774,7 @@ static int ravb_get_ts_info(struct net_device *ndev,
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *hw_info = priv->info;
- if (hw_info->gptp || hw_info->ccc_gac) {
+ if (priv->ptp.clock && (hw_info->gptp || hw_info->ccc_gac)) {
info->so_timestamping =
SOF_TIMESTAMPING_TX_SOFTWARE |
SOF_TIMESTAMPING_TX_HARDWARE |
@@ -1785,7 +1785,7 @@ static int ravb_get_ts_info(struct net_device *ndev,
(1 << HWTSTAMP_FILTER_NONE) |
(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
(1 << HWTSTAMP_FILTER_ALL);
- info->phc_index = READ_ONCE(priv->ptp.phc_index);
+ info->phc_index = ptp_clock_index(priv->ptp.clock);
}
return 0;
@@ -2934,7 +2934,6 @@ static int ravb_probe(struct platform_device *pdev)
priv->rstc = rstc;
priv->ndev = ndev;
priv->pdev = pdev;
- priv->ptp.phc_index = -1;
priv->num_tx_ring[RAVB_BE] = BE_TX_RING_SIZE;
priv->num_rx_ring[RAVB_BE] = BE_RX_RING_SIZE;
if (info->nc_queues) {
diff --git a/drivers/net/ethernet/renesas/ravb_ptp.c b/drivers/net/ethernet/renesas/ravb_ptp.c
index f70b616ac847..37161c0579ce 100644
--- a/drivers/net/ethernet/renesas/ravb_ptp.c
+++ b/drivers/net/ethernet/renesas/ravb_ptp.c
@@ -313,11 +313,11 @@ void ravb_ptp_interrupt(struct net_device *ndev)
ravb_write(ndev, ~(gis | GIS_RESERVED), GIS);
}
-void ravb_ptp_init(struct net_device *ndev)
+int ravb_ptp_init(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
- struct ptp_clock *clock;
unsigned long flags;
+ int ret = 0;
priv->ptp.info = ravb_ptp_info;
@@ -338,15 +338,14 @@ void ravb_ptp_init(struct net_device *ndev)
ravb_modify(ndev, GCCR, GCCR_TCSS, GCCR_TCSS_ADJGPTP);
spin_unlock_irqrestore(&priv->lock, flags);
- clock = ptp_clock_register(&priv->ptp.info, &priv->pdev->dev);
- if (IS_ERR(clock)) {
- netdev_err(ndev, "failed to register PTP clock: %pe\n", clock);
- clock = NULL;
+ priv->ptp.clock = ptp_clock_register(&priv->ptp.info, &priv->pdev->dev);
+ if (IS_ERR(priv->ptp.clock)) {
+ ret = PTR_ERR(priv->ptp.clock);
+ priv->ptp.clock = NULL;
+ ravb_ptp_stop(ndev);
}
- WRITE_ONCE(priv->ptp.clock, clock);
- if (clock)
- WRITE_ONCE(priv->ptp.phc_index, ptp_clock_index(clock));
+ return ret;
}
static void ravb_ptp_disable(struct net_device *ndev)
@@ -369,14 +368,12 @@ static void ravb_ptp_sync_irqs(struct net_device *ndev)
void ravb_ptp_stop(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
- struct ptp_clock *clock;
-
- WRITE_ONCE(priv->ptp.phc_index, -1);
- clock = xchg(&priv->ptp.clock, NULL);
ravb_ptp_disable(ndev);
ravb_ptp_sync_irqs(ndev);
- if (clock)
- ptp_clock_unregister(clock);
+ if (priv->ptp.clock) {
+ ptp_clock_unregister(priv->ptp.clock);
+ priv->ptp.clock = NULL;
+ }
}
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v4 05/10] net: ethernet: ravb: Propagate error from ptp_clock_register()
2026-09-09 17:30 ` [PATCH net-next v4 05/10] net: ethernet: ravb: Propagate error from ptp_clock_register() Niklas Söderlund
@ 2026-09-10 17:31 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-09-10 17:31 UTC (permalink / raw)
To: Niklas Söderlund; +Cc: wsa+renesas, conor+dt, devicetree, robh
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Missing WRITE_ONCE and temporary exposure of ERR_PTR in a locklessly accessed variable.
--
commit b7840c35cf3291bc3d465af40f2ae38cc9f5f972
Author: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
net: ethernet: ravb: Propagate error from ptp_clock_register()
This commit reworks ravb_ptp_init() to check the return value of
ptp_clock_register() and propagate any errors back to the caller. It also
refactors the clock assignment by removing the intermediate local variable.
Link: https://sashiko.dev/#/patchset/20260610102432.3538432-2-niklas.soderlund+renesas@ragnatech.se?part=1
> diff --git a/drivers/net/ethernet/renesas/ravb_ptp.c b/drivers/net/ethernet/renesas/ravb_ptp.c
> index f70b616ac847c..37161c0579ce7 100644
> --- a/drivers/net/ethernet/renesas/ravb_ptp.c
> +++ b/drivers/net/ethernet/renesas/ravb_ptp.c
[ ... ]
> -void ravb_ptp_init(struct net_device *ndev)
> +int ravb_ptp_init(struct net_device *ndev)
> {
> struct ravb_private *priv = netdev_priv(ndev);
> - struct ptp_clock *clock;
> unsigned long flags;
> + int ret = 0;
>
> priv->ptp.info = ravb_ptp_info;
>
[ ... ]
> - clock = ptp_clock_register(&priv->ptp.info, &priv->pdev->dev);
> - if (IS_ERR(clock)) {
> - netdev_err(ndev, "failed to register PTP clock: %pe\n", clock);
> - clock = NULL;
> + priv->ptp.clock = ptp_clock_register(&priv->ptp.info, &priv->pdev->dev);
> + if (IS_ERR(priv->ptp.clock)) {
> + ret = PTR_ERR(priv->ptp.clock);
> + priv->ptp.clock = NULL;
> + ravb_ptp_stop(ndev);
> }
>
> - WRITE_ONCE(priv->ptp.clock, clock);
> - if (clock)
> - WRITE_ONCE(priv->ptp.phc_index, ptp_clock_index(clock));
> + return ret;
> }
[Severity: Medium]
Does this introduce a data race by directly publishing an invalid pointer?
The ravb_ptp_interrupt() handler accesses priv->ptp.clock locklessly via
READ_ONCE(). Because the interrupt handler is registered and enabled via
ravb_setup_irq() before ravb_ptp_init() runs, the hardware interrupt might
already be firing when we reach this point.
If ptp_clock_register() fails, it returns an ERR_PTR. By assigning it
directly to priv->ptp.clock without WRITE_ONCE(), we could have a scenario
where an interrupt fires immediately after the assignment, but before the
error check clears priv->ptp.clock to NULL.
The interrupt handler in ravb_ptp_interrupt() would then read the ERR_PTR:
struct ptp_clock *clock = READ_ONCE(priv->ptp.clock);
...
if ((gis & GIS_PTCF) && clock) {
...
ptp_clock_event(clock, &event);
Could this crash by dereferencing the ERR_PTR? Would it be safer to
restore the original local variable pattern and retain the WRITE_ONCE()
so that priv->ptp.clock only ever sees a valid pointer or NULL?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260909173027.2201560-1-niklas.soderlund+renesas@ragnatech.se?part=5
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next v4 06/10] net: ethernet: ravb: Replace gPTP flags with callbacks
2026-09-09 17:30 [PATCH net-next v4 00/10] ravb: Add gPTP support for Gen4 Niklas Söderlund
` (4 preceding siblings ...)
2026-09-09 17:30 ` [PATCH net-next v4 05/10] net: ethernet: ravb: Propagate error from ptp_clock_register() Niklas Söderlund
@ 2026-09-09 17:30 ` Niklas Söderlund
2026-09-10 17:31 ` sashiko-bot
2026-09-09 17:30 ` [PATCH net-next v4 07/10] net: ethernet: ravb: Add callback for gPTP probe Niklas Söderlund
` (3 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Niklas Söderlund @ 2026-09-09 17:30 UTC (permalink / raw)
To: paul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Richard Cochran, Andrew Lunn,
DavidS. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Vadim Fedorenko, Sergey Shtylyov, linux-renesas-soc, devicetree,
linux-kernel, netdev
Cc: Niklas Söderlund
Prepare for adding Gen4 support which will add a third and new way to
interact with the gPTP clock by replacing the flags for Gen2 behavior
(info->gptp) and Gen3 behavior (info->ccc_gac) with callbacks.
This will make adding Gen4 support cleaner as the code will not have "if
else if else" sprinkled all over to handle each generations special
cases.
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Sergey Shtylyov <sergei.shtylyov@gmail.com>
---
* Changes since v1
- Handle error from starting the PTP clock.
---
drivers/net/ethernet/renesas/ravb.h | 24 ++++++-
drivers/net/ethernet/renesas/ravb_main.c | 83 +++++++++++++++---------
2 files changed, 76 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index 0c122a815840..6603f90b19e1 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -1034,6 +1034,27 @@ struct ravb_ptp {
struct ravb_ptp_perout perout[N_PER_OUT];
};
+/**
+ * struct ravb_gptp_info - Platform specific gPTP behavior
+ *
+ * Each generation of RAVB have slightly different behaviors when interacting
+ * with the gPTP clock. This struct provides the callbacks to be called at
+ * critical points in the RAVB driver.
+ *
+ * @set_config_mode: Enter config mode
+ * @dmac_start: Called when the DMAC starts
+ * @dmac_stop: Called when the DMAC stops
+ * @ndev_open: Called when the ndev is opened
+ * @ndev_close: Called when the ndev is closed
+ */
+struct ravb_gptp_info {
+ int (*set_config_mode)(struct net_device *ndev);
+ int (*dmac_start)(struct net_device *ndev);
+ void (*dmac_stop)(struct net_device *ndev);
+ int (*ndev_open)(struct net_device *ndev);
+ void (*ndev_close)(struct net_device *ndev);
+};
+
struct ravb_hw_info {
int (*receive)(struct net_device *ndev, int budget, int q);
void (*set_rate)(struct net_device *ndev);
@@ -1052,6 +1073,7 @@ struct ravb_hw_info {
u32 rx_buffer_size;
u32 rx_desc_size;
u32 dbat_entry_num;
+ const struct ravb_gptp_info *ptp; /* Callbacks to handle gPTP interactions. */
unsigned aligned_tx: 1;
unsigned coalesce_irqs:1; /* Needs software IRQ coalescing */
@@ -1062,8 +1084,6 @@ struct ravb_hw_info {
unsigned multi_irqs:1; /* AVB-DMAC and E-MAC has multiple irqs */
unsigned irq_en_dis:1; /* Has separate irq enable and disable regs */
unsigned err_mgmt_irqs:1; /* Line1 (Err) and Line2 (Mgmt) irqs are separate */
- unsigned gptp:1; /* AVB-DMAC has gPTP support */
- unsigned ccc_gac:1; /* AVB-DMAC has gPTP support active in config mode */
unsigned gptp_ref_clk:1; /* gPTP has separate reference clock */
unsigned nc_queues:1; /* AVB-DMAC has RX and TX NC queues */
unsigned magic_pkt:1; /* E-MAC supports magic packet detection */
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 5ba322593a01..9e9b1c4fbe95 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -712,8 +712,8 @@ static int ravb_dmac_init(struct net_device *ndev)
return error;
/* Initialise PTP Clock driver */
- if (info->gptp)
- ravb_ptp_init(ndev);
+ if (info->ptp && info->ptp->dmac_start)
+ return info->ptp->dmac_start(ndev);
return 0;
}
@@ -1124,8 +1124,8 @@ static int ravb_stop_dma(struct net_device *ndev)
}
/* Stop PTP Clock driver */
- if (info->gptp)
- ravb_ptp_stop(ndev);
+ if (info->ptp && info->ptp->dmac_stop)
+ info->ptp->dmac_stop(ndev);
/* Stop AVB-DMAC process */
return ravb_set_opmode(ndev, CCC_OPC_CONFIG);
@@ -1774,7 +1774,7 @@ static int ravb_get_ts_info(struct net_device *ndev,
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *hw_info = priv->info;
- if (priv->ptp.clock && (hw_info->gptp || hw_info->ccc_gac)) {
+ if (priv->ptp.clock && hw_info->ptp) {
info->so_timestamping =
SOF_TIMESTAMPING_TX_SOFTWARE |
SOF_TIMESTAMPING_TX_HARDWARE |
@@ -1835,21 +1835,11 @@ static int ravb_set_config_mode(struct net_device *ndev)
{
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *info = priv->info;
- int error;
- if (info->gptp) {
- error = ravb_set_opmode(ndev, CCC_OPC_CONFIG);
- if (error)
- return error;
- /* Set CSEL value */
- ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB);
- } else if (info->ccc_gac) {
- error = ravb_set_opmode(ndev, CCC_OPC_CONFIG | CCC_GAC | CCC_CSEL_HPB);
- } else {
- error = ravb_set_opmode(ndev, CCC_OPC_CONFIG);
- }
+ if (info->ptp && info->ptp->set_config_mode)
+ return info->ptp->set_config_mode(ndev);
- return error;
+ return ravb_set_opmode(ndev, CCC_OPC_CONFIG);
}
static int ravb_compute_gti(struct net_device *ndev)
@@ -1860,7 +1850,7 @@ static int ravb_compute_gti(struct net_device *ndev)
unsigned long rate;
u64 inc;
- if (!(info->gptp || info->ccc_gac))
+ if (!info->ptp)
return 0;
if (info->gptp_ref_clk)
@@ -1967,8 +1957,11 @@ static int ravb_open(struct net_device *ndev)
ravb_emac_init(ndev);
/* Initialise PTP Clock driver */
- if (info->ccc_gac)
- ravb_ptp_init(ndev);
+ if (info->ptp && info->ptp->ndev_open) {
+ error = info->ptp->ndev_open(ndev);
+ if (error)
+ goto out_ptp_stop;
+ }
/* PHY control start */
error = ravb_phy_start(ndev);
@@ -2187,7 +2180,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev)
desc->dptr = cpu_to_le32(dma_addr);
/* TX timestamp required */
- if (info->gptp || info->ccc_gac) {
+ if (info->ptp) {
if (q == RAVB_NC) {
ts_skb = kmalloc_obj(*ts_skb, GFP_ATOMIC);
if (!ts_skb) {
@@ -2369,8 +2362,8 @@ static int ravb_close(struct net_device *ndev)
}
/* Stop PTP Clock driver */
- if (info->ccc_gac)
- ravb_ptp_stop(ndev);
+ if (info->ptp && info->ptp->ndev_close)
+ info->ptp->ndev_close(ndev);
/* Set the config mode to stop the AVB-DMAC's processes */
if (ravb_stop_dma(ndev) < 0)
@@ -2378,7 +2371,7 @@ static int ravb_close(struct net_device *ndev)
"device will be stopped after h/w processes are done.\n");
/* Clear the timestamp list */
- if (info->gptp || info->ccc_gac) {
+ if (info->ptp) {
list_for_each_entry_safe(ts_skb, ts_skb2, &priv->ts_skb_list, list) {
list_del(&ts_skb->list);
kfree_skb(ts_skb->skb);
@@ -2660,6 +2653,26 @@ static int ravb_mdio_release(struct ravb_private *priv)
return 0;
}
+static int ravb_gen2_ptp_set_config_mode(struct net_device *ndev)
+{
+ int ret;
+
+ ret = ravb_set_opmode(ndev, CCC_OPC_CONFIG);
+ if (ret)
+ return ret;
+
+ /* gPTP Clock Select High-speed peripheral bus clock. */
+ ravb_modify(ndev, CCC, CCC_CSEL, CCC_CSEL_HPB);
+
+ return 0;
+}
+
+static const struct ravb_gptp_info ravb_gen2_ptp_info = {
+ .set_config_mode = ravb_gen2_ptp_set_config_mode,
+ .dmac_start = ravb_ptp_init,
+ .dmac_stop = ravb_ptp_stop,
+};
+
static const struct ravb_hw_info ravb_gen2_hw_info = {
.receive = ravb_rx_rcar,
.set_rate = ravb_set_rate_rcar,
@@ -2678,12 +2691,24 @@ static const struct ravb_hw_info ravb_gen2_hw_info = {
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)),
.rx_desc_size = sizeof(struct ravb_ex_rx_desc),
.dbat_entry_num = 22,
+ .ptp = &ravb_gen2_ptp_info,
.aligned_tx = 1,
- .gptp = 1,
.nc_queues = 1,
.magic_pkt = 1,
};
+static int ravb_gen3_ptp_set_config_mode(struct net_device *ndev)
+{
+ /* Enable gPTP Clock and Select High-speed peripheral bus clock. */
+ return ravb_set_opmode(ndev, CCC_OPC_CONFIG | CCC_GAC | CCC_CSEL_HPB);
+}
+
+static const struct ravb_gptp_info ravb_gen3_ptp_info = {
+ .set_config_mode = ravb_gen3_ptp_set_config_mode,
+ .ndev_open = ravb_ptp_init,
+ .ndev_close = ravb_ptp_stop,
+};
+
static const struct ravb_hw_info ravb_gen3_hw_info = {
.receive = ravb_rx_rcar,
.set_rate = ravb_set_rate_rcar,
@@ -2702,11 +2727,11 @@ static const struct ravb_hw_info ravb_gen3_hw_info = {
SKB_DATA_ALIGN(sizeof(struct skb_shared_info)),
.rx_desc_size = sizeof(struct ravb_ex_rx_desc),
.dbat_entry_num = 22,
+ .ptp = &ravb_gen3_ptp_info,
.internal_delay = 1,
.tx_counters = 1,
.multi_irqs = 1,
.irq_en_dis = 1,
- .ccc_gac = 1,
.nc_queues = 1,
.magic_pkt = 1,
};
@@ -2733,7 +2758,7 @@ static const struct ravb_hw_info ravb_gen4_hw_info = {
.tx_counters = 1,
.multi_irqs = 1,
.irq_en_dis = 1,
- .ccc_gac = 1,
+ .ptp = &ravb_gen3_ptp_info,
.nc_queues = 1,
.magic_pkt = 1,
};
@@ -2758,7 +2783,7 @@ static const struct ravb_hw_info ravb_rzv2m_hw_info = {
.dbat_entry_num = 22,
.multi_irqs = 1,
.err_mgmt_irqs = 1,
- .gptp = 1,
+ .ptp = &ravb_gen2_ptp_info,
.gptp_ref_clk = 1,
.nc_queues = 1,
.magic_pkt = 1,
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v4 06/10] net: ethernet: ravb: Replace gPTP flags with callbacks
2026-09-09 17:30 ` [PATCH net-next v4 06/10] net: ethernet: ravb: Replace gPTP flags with callbacks Niklas Söderlund
@ 2026-09-10 17:31 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-09-10 17:31 UTC (permalink / raw)
To: Niklas Söderlund; +Cc: robh, devicetree, conor+dt, wsa+renesas
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Critical] The PTP clock driver is leaked on the ravb_open() error path for Gen3 hardware, leading to a resource leak and Use-After-Free on unbind.
Pre-existing issues:
- [High] DMA descriptor rings and RX buffers are leaked if ravb_dmac_init() or ravb_open() fails.
--
commit e94a5eaa93f99ec3240945371b306afb7c9c715b
Author: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
net: ethernet: ravb: Replace gPTP flags with callbacks
This commit prepares for Gen4 support by replacing the Gen2 (info->gptp)
and Gen3 (info->ccc_gac) flags with callbacks in a new ravb_gptp_info
struct, simplifying hardware-specific checks.
> diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
> --- a/drivers/net/ethernet/renesas/ravb_main.c
> +++ b/drivers/net/ethernet/renesas/ravb_main.c
> @@ -712,8 +712,8 @@ static int ravb_dmac_init(struct net_device *ndev)
> return error;
>
> /* Initialise PTP Clock driver */
> - if (info->gptp)
> - ravb_ptp_init(ndev);
> + if (info->ptp && info->ptp->dmac_start)
> + return info->ptp->dmac_start(ndev);
[Severity: High]
This is a pre-existing issue, but does this error return leak the previously
allocated DMA descriptor rings and RX buffers?
If ravb_dmac_init() fails here (or at ravb_set_opmode earlier), the caller
ravb_open() branches to out_set_reset, which skips calling ravb_ring_free().
Because ravb_open() is reachable via a userspace command like ip link set up,
could this be triggered repeatedly to exhaust DMA coherent memory?
[ ... ]
> @@ -1124,8 +1124,8 @@ static int ravb_stop_dma(struct net_device *ndev)
> }
>
> /* Stop PTP Clock driver */
> - if (info->gptp)
> - ravb_ptp_stop(ndev);
> + if (info->ptp && info->ptp->dmac_stop)
> + info->ptp->dmac_stop(ndev);
[Severity: Critical]
For Gen3 devices, dmac_stop is NULL since they use ndev_close. If ravb_open()
fails during PHY initialization after the PTP clock has been started,
ravb_open() jumps to out_ptp_stop and calls ravb_stop_dma().
Since dmac_stop is NULL, does the PTP clock remain fully registered?
If the interface is left down and the module is subsequently removed,
unregister_netdev() will skip ravb_close(), leaving the PTP clock device
active. Could userspace then access the leaked /dev/ptpX device and trigger a
use-after-free on the freed priv pointer?
[ ... ]
> @@ -1967,8 +1957,11 @@ static int ravb_open(struct net_device *ndev)
> ravb_emac_init(ndev);
>
> /* Initialise PTP Clock driver */
> - if (info->ccc_gac)
> - ravb_ptp_init(ndev);
> + if (info->ptp && info->ptp->ndev_open) {
> + error = info->ptp->ndev_open(ndev);
> + if (error)
> + goto out_ptp_stop;
> + }
>
> /* PHY control start */
> error = ravb_phy_start(ndev);
[Severity: Critical]
If ravb_phy_start() fails, the code branches to out_ptp_stop, which calls
ravb_stop_dma(ndev). As noted above, ravb_stop_dma() will not clean up the
Gen3 PTP clock because dmac_stop is NULL.
Should the out_ptp_stop block in ravb_open() explicitly call
info->ptp->ndev_close(ndev) to ensure the clock is properly unregistered on
this error path?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260909173027.2201560-1-niklas.soderlund+renesas@ragnatech.se?part=6
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next v4 07/10] net: ethernet: ravb: Add callback for gPTP probe
2026-09-09 17:30 [PATCH net-next v4 00/10] ravb: Add gPTP support for Gen4 Niklas Söderlund
` (5 preceding siblings ...)
2026-09-09 17:30 ` [PATCH net-next v4 06/10] net: ethernet: ravb: Replace gPTP flags with callbacks Niklas Söderlund
@ 2026-09-09 17:30 ` Niklas Söderlund
2026-09-10 17:31 ` sashiko-bot
2026-09-09 17:30 ` [PATCH net-next v4 08/10] net: ethernet: ravb: Add callback for gPTP clock index Niklas Söderlund
` (2 subsequent siblings)
9 siblings, 1 reply; 19+ messages in thread
From: Niklas Söderlund @ 2026-09-09 17:30 UTC (permalink / raw)
To: paul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Richard Cochran, Andrew Lunn,
DavidS. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Vadim Fedorenko, Sergey Shtylyov, linux-renesas-soc, devicetree,
linux-kernel, netdev
Cc: Niklas Söderlund
Different generations of the RAVB IP have different needs when it probes
the gPTP timer clock. Add a callback in the PTP information to allow
each generation to probe its own way.
With this the last gPTP specific flag (gptp_ref_clk) can be removed.
However the primary motivation for the change is to prepare for Gen4
support, which compared to other generations with gPTP support does not
have the clock as part of the IP itself.
Gen4 will not need to compute GTI value as it have nowhere to write it,
as the gPTP clock is external. For this reason move the computation of
it into the newly gPTP probe specific callbacks for the RAVB IP's that
support it.
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Sergey Shtylyov <sergei.shtylyov@gmail.com>
---
* Changes since v1
- Improve spelling in commit message.
---
drivers/net/ethernet/renesas/ravb.h | 3 +-
drivers/net/ethernet/renesas/ravb_main.c | 53 +++++++++++++++---------
2 files changed, 35 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index 6603f90b19e1..b788e8f5260d 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -1041,6 +1041,7 @@ struct ravb_ptp {
* with the gPTP clock. This struct provides the callbacks to be called at
* critical points in the RAVB driver.
*
+ * @probe: Probe the gPTP clock
* @set_config_mode: Enter config mode
* @dmac_start: Called when the DMAC starts
* @dmac_stop: Called when the DMAC stops
@@ -1048,6 +1049,7 @@ struct ravb_ptp {
* @ndev_close: Called when the ndev is closed
*/
struct ravb_gptp_info {
+ int (*probe)(struct net_device *ndev);
int (*set_config_mode)(struct net_device *ndev);
int (*dmac_start)(struct net_device *ndev);
void (*dmac_stop)(struct net_device *ndev);
@@ -1084,7 +1086,6 @@ struct ravb_hw_info {
unsigned multi_irqs:1; /* AVB-DMAC and E-MAC has multiple irqs */
unsigned irq_en_dis:1; /* Has separate irq enable and disable regs */
unsigned err_mgmt_irqs:1; /* Line1 (Err) and Line2 (Mgmt) irqs are separate */
- unsigned gptp_ref_clk:1; /* gPTP has separate reference clock */
unsigned nc_queues:1; /* AVB-DMAC has RX and TX NC queues */
unsigned magic_pkt:1; /* E-MAC supports magic packet detection */
unsigned half_duplex:1; /* E-MAC supports half duplex mode */
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 9e9b1c4fbe95..1092e8ada188 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -1842,21 +1842,14 @@ static int ravb_set_config_mode(struct net_device *ndev)
return ravb_set_opmode(ndev, CCC_OPC_CONFIG);
}
-static int ravb_compute_gti(struct net_device *ndev)
+static int ravb_compute_gti(struct net_device *ndev, struct clk *clk)
{
struct ravb_private *priv = netdev_priv(ndev);
- const struct ravb_hw_info *info = priv->info;
struct device *dev = ndev->dev.parent;
unsigned long rate;
u64 inc;
- if (!info->ptp)
- return 0;
-
- if (info->gptp_ref_clk)
- rate = clk_get_rate(priv->gptp_clk);
- else
- rate = clk_get_rate(priv->clk);
+ rate = clk_get_rate(clk);
if (!rate)
return -EINVAL;
@@ -2653,6 +2646,13 @@ static int ravb_mdio_release(struct ravb_private *priv)
return 0;
}
+static int ravb_gen2_ptp_probe(struct net_device *ndev)
+{
+ struct ravb_private *priv = netdev_priv(ndev);
+
+ return ravb_compute_gti(ndev, priv->clk);
+}
+
static int ravb_gen2_ptp_set_config_mode(struct net_device *ndev)
{
int ret;
@@ -2668,6 +2668,7 @@ static int ravb_gen2_ptp_set_config_mode(struct net_device *ndev)
}
static const struct ravb_gptp_info ravb_gen2_ptp_info = {
+ .probe = ravb_gen2_ptp_probe,
.set_config_mode = ravb_gen2_ptp_set_config_mode,
.dmac_start = ravb_ptp_init,
.dmac_stop = ravb_ptp_stop,
@@ -2704,6 +2705,7 @@ static int ravb_gen3_ptp_set_config_mode(struct net_device *ndev)
}
static const struct ravb_gptp_info ravb_gen3_ptp_info = {
+ .probe = ravb_gen2_ptp_probe,
.set_config_mode = ravb_gen3_ptp_set_config_mode,
.ndev_open = ravb_ptp_init,
.ndev_close = ravb_ptp_stop,
@@ -2763,6 +2765,24 @@ static const struct ravb_hw_info ravb_gen4_hw_info = {
.magic_pkt = 1,
};
+static int ravb_rzv2m_ptp_probe(struct net_device *ndev)
+{
+ struct ravb_private *priv = netdev_priv(ndev);
+
+ priv->gptp_clk = devm_clk_get(&priv->pdev->dev, "gptp");
+ if (IS_ERR(priv->gptp_clk))
+ return PTR_ERR(priv->gptp_clk);
+
+ return ravb_compute_gti(ndev, priv->gptp_clk);
+}
+
+static const struct ravb_gptp_info ravb_rzv2m_ptp_info = {
+ .probe = ravb_rzv2m_ptp_probe,
+ .set_config_mode = ravb_gen2_ptp_set_config_mode,
+ .dmac_start = ravb_ptp_init,
+ .dmac_stop = ravb_ptp_stop,
+};
+
static const struct ravb_hw_info ravb_rzv2m_hw_info = {
.receive = ravb_rx_rcar,
.set_rate = ravb_set_rate_rcar,
@@ -2783,8 +2803,7 @@ static const struct ravb_hw_info ravb_rzv2m_hw_info = {
.dbat_entry_num = 22,
.multi_irqs = 1,
.err_mgmt_irqs = 1,
- .ptp = &ravb_gen2_ptp_info,
- .gptp_ref_clk = 1,
+ .ptp = &ravb_rzv2m_ptp_info,
.nc_queues = 1,
.magic_pkt = 1,
};
@@ -2976,12 +2995,10 @@ static int ravb_probe(struct platform_device *pdev)
goto out_reset_assert;
}
- if (info->gptp_ref_clk) {
- priv->gptp_clk = devm_clk_get(&pdev->dev, "gptp");
- if (IS_ERR(priv->gptp_clk)) {
- error = PTR_ERR(priv->gptp_clk);
+ if (info->ptp && info->ptp->probe) {
+ error = info->ptp->probe(ndev);
+ if (error)
goto out_reset_assert;
- }
}
priv->refclk = devm_clk_get_optional(&pdev->dev, "refclk");
@@ -3034,10 +3051,6 @@ static int ravb_probe(struct platform_device *pdev)
ndev->netdev_ops = &ravb_netdev_ops;
ndev->ethtool_ops = &ravb_ethtool_ops;
- error = ravb_compute_gti(ndev);
- if (error)
- goto out_rpm_put;
-
ravb_parse_delay_mode(np, ndev);
/* Allocate descriptor base address table */
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v4 07/10] net: ethernet: ravb: Add callback for gPTP probe
2026-09-09 17:30 ` [PATCH net-next v4 07/10] net: ethernet: ravb: Add callback for gPTP probe Niklas Söderlund
@ 2026-09-10 17:31 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-09-10 17:31 UTC (permalink / raw)
To: Niklas Söderlund; +Cc: wsa+renesas, conor+dt, devicetree, robh
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] PTP clock leak on ravb_open error path for Gen3/Gen4 hardware.
--
commit 934b0b048427cb972701430838997a53612ec30f
Author: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
net: ethernet: ravb: Add callback for gPTP probe
This commit introduces a new probe callback for gPTP to handle differing
hardware generation requirements. It migrates the GTI computation into these
callbacks and prepares the driver for Gen4 support.
> diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
> index 9e9b1c4fbe956..1092e8ada188b 100644
> --- a/drivers/net/ethernet/renesas/ravb_main.c
> +++ b/drivers/net/ethernet/renesas/ravb_main.c
[ ... ]
> @@ -2704,6 +2705,7 @@ static int ravb_gen3_ptp_set_config_mode(struct net_device *ndev)
> }
>
> static const struct ravb_gptp_info ravb_gen3_ptp_info = {
> + .probe = ravb_gen2_ptp_probe,
> .set_config_mode = ravb_gen3_ptp_set_config_mode,
> .ndev_open = ravb_ptp_init,
> .ndev_close = ravb_ptp_stop,
[Severity: Medium]
Does this setup leak the PTP clock struct on the ravb_open() error path for
Gen3/Gen4 hardware?
If a failure occurs during ravb_open() (for example, if ravb_phy_start()
fails), the error path calls ravb_stop_dma(ndev):
drivers/net/ethernet/renesas/ravb_main.c:ravb_open() {
...
out_ptp_stop:
ravb_stop_dma(ndev);
out_free_irq:
...
}
Since ravb_stop_dma() relies on info->ptp->dmac_stop being set to stop the
PTP clock, it skips the teardown for Gen3 because ravb_gen3_ptp_info uses
.ndev_close instead of .dmac_stop.
Because .ndev_close is never invoked on this error path, is the ptp_clock
registered via ravb_ptp_init() left dangling when the interface fails to
open?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260909173027.2201560-1-niklas.soderlund+renesas@ragnatech.se?part=7
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next v4 08/10] net: ethernet: ravb: Add callback for gPTP clock index
2026-09-09 17:30 [PATCH net-next v4 00/10] ravb: Add gPTP support for Gen4 Niklas Söderlund
` (6 preceding siblings ...)
2026-09-09 17:30 ` [PATCH net-next v4 07/10] net: ethernet: ravb: Add callback for gPTP probe Niklas Söderlund
@ 2026-09-09 17:30 ` Niklas Söderlund
2026-09-09 17:30 ` [PATCH net-next v4 09/10] dt-bindings: net: renesas,etheravb: Add optional gPTP phandle for Gen4 Niklas Söderlund
2026-09-09 17:30 ` [PATCH net-next v4 10/10] net: ethernet: ravb: Add gPTP support " Niklas Söderlund
9 siblings, 0 replies; 19+ messages in thread
From: Niklas Söderlund @ 2026-09-09 17:30 UTC (permalink / raw)
To: paul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Richard Cochran, Andrew Lunn,
DavidS. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Vadim Fedorenko, Sergey Shtylyov, linux-renesas-soc, devicetree,
linux-kernel, netdev
Cc: Niklas Söderlund
Prepare for adding Gen4 support which have an optional external gPTP
clock. Add a callback to get the clock index and use it to determine if
the device shall report gPTP support.
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Sergey Shtylyov <sergei.shtylyov@gmail.com>
---
* Changes since v3
- Add check to feed sashiko.
---
drivers/net/ethernet/renesas/ravb.h | 2 ++
drivers/net/ethernet/renesas/ravb_main.c | 22 ++++++++++++++++++++--
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index b788e8f5260d..27e2b31955ba 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -1042,6 +1042,7 @@ struct ravb_ptp {
* critical points in the RAVB driver.
*
* @probe: Probe the gPTP clock
+ * @clock_index: Get the PTP clock index, if any
* @set_config_mode: Enter config mode
* @dmac_start: Called when the DMAC starts
* @dmac_stop: Called when the DMAC stops
@@ -1050,6 +1051,7 @@ struct ravb_ptp {
*/
struct ravb_gptp_info {
int (*probe)(struct net_device *ndev);
+ int (*clock_index)(struct net_device *ndev);
int (*set_config_mode)(struct net_device *ndev);
int (*dmac_start)(struct net_device *ndev);
void (*dmac_stop)(struct net_device *ndev);
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 1092e8ada188..8617c30dbb14 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -1773,8 +1773,13 @@ static int ravb_get_ts_info(struct net_device *ndev,
{
struct ravb_private *priv = netdev_priv(ndev);
const struct ravb_hw_info *hw_info = priv->info;
+ int index = -1;
- if (priv->ptp.clock && hw_info->ptp) {
+ if (hw_info->ptp && hw_info->ptp->clock_index)
+ index = hw_info->ptp->clock_index(ndev);
+
+ /* Only advertise ptp clock if present. */
+ if (index >= 0) {
info->so_timestamping =
SOF_TIMESTAMPING_TX_SOFTWARE |
SOF_TIMESTAMPING_TX_HARDWARE |
@@ -1785,7 +1790,7 @@ static int ravb_get_ts_info(struct net_device *ndev,
(1 << HWTSTAMP_FILTER_NONE) |
(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
(1 << HWTSTAMP_FILTER_ALL);
- info->phc_index = ptp_clock_index(priv->ptp.clock);
+ info->phc_index = index;
}
return 0;
@@ -2653,6 +2658,16 @@ static int ravb_gen2_ptp_probe(struct net_device *ndev)
return ravb_compute_gti(ndev, priv->clk);
}
+static int ravb_gen2_ptp_clock_index(struct net_device *ndev)
+{
+ struct ravb_private *priv = netdev_priv(ndev);
+
+ if (!priv->ptp.clock)
+ return -ENODEV;
+
+ return ptp_clock_index(priv->ptp.clock);
+}
+
static int ravb_gen2_ptp_set_config_mode(struct net_device *ndev)
{
int ret;
@@ -2669,6 +2684,7 @@ static int ravb_gen2_ptp_set_config_mode(struct net_device *ndev)
static const struct ravb_gptp_info ravb_gen2_ptp_info = {
.probe = ravb_gen2_ptp_probe,
+ .clock_index = ravb_gen2_ptp_clock_index,
.set_config_mode = ravb_gen2_ptp_set_config_mode,
.dmac_start = ravb_ptp_init,
.dmac_stop = ravb_ptp_stop,
@@ -2706,6 +2722,7 @@ static int ravb_gen3_ptp_set_config_mode(struct net_device *ndev)
static const struct ravb_gptp_info ravb_gen3_ptp_info = {
.probe = ravb_gen2_ptp_probe,
+ .clock_index = ravb_gen2_ptp_clock_index,
.set_config_mode = ravb_gen3_ptp_set_config_mode,
.ndev_open = ravb_ptp_init,
.ndev_close = ravb_ptp_stop,
@@ -2778,6 +2795,7 @@ static int ravb_rzv2m_ptp_probe(struct net_device *ndev)
static const struct ravb_gptp_info ravb_rzv2m_ptp_info = {
.probe = ravb_rzv2m_ptp_probe,
+ .clock_index = ravb_gen2_ptp_clock_index,
.set_config_mode = ravb_gen2_ptp_set_config_mode,
.dmac_start = ravb_ptp_init,
.dmac_stop = ravb_ptp_stop,
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* [PATCH net-next v4 09/10] dt-bindings: net: renesas,etheravb: Add optional gPTP phandle for Gen4
2026-09-09 17:30 [PATCH net-next v4 00/10] ravb: Add gPTP support for Gen4 Niklas Söderlund
` (7 preceding siblings ...)
2026-09-09 17:30 ` [PATCH net-next v4 08/10] net: ethernet: ravb: Add callback for gPTP clock index Niklas Söderlund
@ 2026-09-09 17:30 ` Niklas Söderlund
2026-09-10 17:31 ` sashiko-bot
2026-09-09 17:30 ` [PATCH net-next v4 10/10] net: ethernet: ravb: Add gPTP support " Niklas Söderlund
9 siblings, 1 reply; 19+ messages in thread
From: Niklas Söderlund @ 2026-09-09 17:30 UTC (permalink / raw)
To: paul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Richard Cochran, Andrew Lunn,
DavidS. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Vadim Fedorenko, Sergey Shtylyov, linux-renesas-soc, devicetree,
linux-kernel, netdev
Cc: Niklas Söderlund, Krzysztof Kozlowski
The RAVB module on Gen4 have no gPTP clock as part of the RAVB module
itself, instead it relies on an external system wide gPTP clock. The
gPTP clock is shared with RTSN on V4H and RSWITCH on S4.
Add an optional phandle so that the RAVB driver can find and use the
gPTP clock. Ideally this should have been a mandatory property but for
backward compatible it is optional. The RAVB module is capable of
functioning without it, but can in such cases not provided PTP
functionality.
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Sergey Shtylyov <sergei.shtylyov@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
* Changes since v1
- Use generic ptp-timer property instead of vendor specific one.
- Improve spelling in commit message.
---
.../devicetree/bindings/net/renesas,etheravb.yaml | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/renesas,etheravb.yaml b/Documentation/devicetree/bindings/net/renesas,etheravb.yaml
index 1e00ef5b3acd..fad002492421 100644
--- a/Documentation/devicetree/bindings/net/renesas,etheravb.yaml
+++ b/Documentation/devicetree/bindings/net/renesas,etheravb.yaml
@@ -97,6 +97,8 @@ properties:
phy-handle: true
+ ptp-timer: true
+
'#address-cells':
description: Number of address cells for the MDIO bus.
const: 1
@@ -305,6 +307,15 @@ allOf:
items:
- const: fck
- const: refclk
+ - if:
+ not:
+ properties:
+ compatible:
+ contains:
+ const: renesas,etheravb-rcar-gen4
+ then:
+ properties:
+ ptp-timer: false
additionalProperties: false
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v4 09/10] dt-bindings: net: renesas,etheravb: Add optional gPTP phandle for Gen4
2026-09-09 17:30 ` [PATCH net-next v4 09/10] dt-bindings: net: renesas,etheravb: Add optional gPTP phandle for Gen4 Niklas Söderlund
@ 2026-09-10 17:31 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-09-10 17:31 UTC (permalink / raw)
To: Niklas Söderlund; +Cc: robh, wsa+renesas, devicetree, conor+dt
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Fatal error propagation from ptp_clock_register() breaks Ethernet TX timeout recovery and ring parameter updates.
--
commit c3fb74adfa830cee3ff5a146680ac62339b2b230
Author: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
dt-bindings: net: renesas,etheravb: Add optional gPTP phandle for Gen4
This commit adds an optional ptp-timer property for the RAVB module on Gen4,
allowing the driver to find and use an external system-wide gPTP clock.
The clock is shared with RTSN on V4H and RSWITCH on S4. The module can
function without it, but will not provide PTP functionality in such cases.
> diff --git a/Documentation/devicetree/bindings/net/renesas,etheravb.yaml b/Documentation/devicetree/bindings/net/renesas,etheravb.yaml
> index 1e00ef5b3acda..fad002492421a 100644
> --- a/Documentation/devicetree/bindings/net/renesas,etheravb.yaml
> +++ b/Documentation/devicetree/bindings/net/renesas,etheravb.yaml
> @@ -97,6 +97,8 @@ properties:
>
> phy-handle: true
>
> + ptp-timer: true
> +
[Severity: High]
If this PTP timer is optional, could this introduce a regression where its
absence causes the driver to fail during initialization or timeout recovery?
Looking at ravb_ptp_init() in drivers/net/ethernet/renesas/ravb_ptp.c,
it propagates a fatal error if PTP registration fails:
drivers/net/ethernet/renesas/ravb_ptp.c:ravb_ptp_init() {
priv->ptp.clock = ptp_clock_register(&priv->ptp.info, &priv->pdev->dev);
if (IS_ERR(priv->ptp.clock)) {
ret = PTR_ERR(priv->ptp.clock);
priv->ptp.clock = NULL;
ravb_ptp_stop(ndev);
}
return ret;
}
This error returns up the call chain through ravb_dmac_init() to
ravb_tx_timeout_work() in drivers/net/ethernet/renesas/ravb_main.c:
drivers/net/ethernet/renesas/ravb_main.c:ravb_tx_timeout_work() {
error = ravb_dmac_init(ndev);
if (error) {
netdev_err(ndev, "%s: ravb_dmac_init() failed, error %d\n",
__func__, error);
goto out_unlock;
}
}
Could this cause the main Ethernet interface to become permanently disabled
on a TX timeout if the optional PTP clock fails to register?
Similarly, in ravb_set_ringparam(), an error from ravb_dmac_init() interrupts
the ring parameter update:
drivers/net/ethernet/renesas/ravb_main.c:ravb_set_ringparam() {
error = ravb_dmac_init(ndev);
if (error) {
netdev_err(ndev,
"%s: ravb_dmac_init() failed, error %d\n",
__func__, error);
return error;
}
}
Would this leave the network device detached when applying ring parameters
if the PTP clock is absent?
> '#address-cells':
> description: Number of address cells for the MDIO bus.
> const: 1
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260909173027.2201560-1-niklas.soderlund+renesas@ragnatech.se?part=9
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH net-next v4 10/10] net: ethernet: ravb: Add gPTP support for Gen4
2026-09-09 17:30 [PATCH net-next v4 00/10] ravb: Add gPTP support for Gen4 Niklas Söderlund
` (8 preceding siblings ...)
2026-09-09 17:30 ` [PATCH net-next v4 09/10] dt-bindings: net: renesas,etheravb: Add optional gPTP phandle for Gen4 Niklas Söderlund
@ 2026-09-09 17:30 ` Niklas Söderlund
2026-09-10 17:31 ` sashiko-bot
9 siblings, 1 reply; 19+ messages in thread
From: Niklas Söderlund @ 2026-09-09 17:30 UTC (permalink / raw)
To: paul, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Geert Uytterhoeven, Magnus Damm, Richard Cochran, Andrew Lunn,
DavidS. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Vadim Fedorenko, Sergey Shtylyov, linux-renesas-soc, devicetree,
linux-kernel, netdev
Cc: Niklas Söderlund
While driver advertises gPTP support on Gen4 platforms it is in fact
completely broken. On R-Car Gen4 devices the RAVB module have no
internal gPTP clock as generations before it. Instead it utilizes a
system-wide gPTP clock.
This change utilizes the refactoring of the RAVB gPTP code to add
support for a system-wide clock and stops the Gen4 devices trying to use
the non-existing internal gPTP clock.
To remain backward compatible the ptp-timer property is optional.If not
present, or not enabled, the RAVB driver will no longer advertise gPTP
support to user-space.
Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Sergey Shtylyov <sergei.shtylyov@gmail.com>
---
* Changes since v2
- Use full 100 character width instead of breaking at 80.
- Remove superfluous return statement.
* Changes since v1
- Use the standard generic ptp-timer property from
ethernet-controller.yaml instead of a vendor specific one.
- Improve spelling in commit message.
---
drivers/net/ethernet/renesas/ravb.h | 3 ++
drivers/net/ethernet/renesas/ravb_main.c | 54 +++++++++++++++++++++++-
2 files changed, 56 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/renesas/ravb.h b/drivers/net/ethernet/renesas/ravb.h
index 27e2b31955ba..5d35b40d7c58 100644
--- a/drivers/net/ethernet/renesas/ravb.h
+++ b/drivers/net/ethernet/renesas/ravb.h
@@ -249,6 +249,8 @@ enum APSR_BIT {
APSR_RDM = 0x00002000,
APSR_TDM = 0x00004000,
APSR_MIISELECT = 0x01000000, /* R-Car V4M only */
+ APSR_GPTPTIMER_SOURCE = BIT(25), /* Gen4 */
+ APSR_GPTPCLOCK = BIT(29), /* Gen4 */
};
/* RCR */
@@ -1132,6 +1134,7 @@ struct ravb_private {
struct list_head ts_skb_list;
u32 ts_skb_tag;
struct ravb_ptp ptp;
+ struct device_node *of_gptp; /* Reference to external gPTP clock, if any. */
spinlock_t lock; /* Register access lock */
u32 cur_rx[NUM_RX_QUEUE]; /* Consumer ring indices */
u32 dirty_rx[NUM_RX_QUEUE]; /* Producer ring indices */
diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
index 8617c30dbb14..c8aa40136c3d 100644
--- a/drivers/net/ethernet/renesas/ravb_main.c
+++ b/drivers/net/ethernet/renesas/ravb_main.c
@@ -2755,6 +2755,57 @@ static const struct ravb_hw_info ravb_gen3_hw_info = {
.magic_pkt = 1,
};
+static int ravb_gen4_ptp_probe(struct net_device *ndev)
+{
+ struct ravb_private *priv = netdev_priv(ndev);
+
+ priv->of_gptp = of_parse_phandle(priv->pdev->dev.of_node, "ptp-timer", 0);
+ if (!priv->of_gptp)
+ return 0;
+
+ if (!of_device_is_available(priv->of_gptp)) {
+ of_node_put(priv->of_gptp);
+ priv->of_gptp = NULL;
+ }
+
+ return 0;
+}
+
+static int ravb_gen4_ptp_clock_index(struct net_device *ndev)
+{
+ struct ravb_private *priv = netdev_priv(ndev);
+
+ /* If no clock, mimic ptp_clock_index_by_of_node() fail and return -1 */
+ if (!priv->of_gptp)
+ return -1;
+
+ return ptp_clock_index_by_of_node(priv->of_gptp);
+}
+
+static int ravb_gen4_ptp_set_config_mode(struct net_device *ndev)
+{
+ struct ravb_private *priv = netdev_priv(ndev);
+ int ret;
+
+ /* Enable gPTP Clock and Select High-speed peripheral bus clock. */
+ ret = ravb_set_opmode(ndev, CCC_OPC_CONFIG | CCC_GAC | CCC_CSEL_HPB);
+ if (ret)
+ return ret;
+
+ /* Set PTP source to GPTP module, only option on Gen4. */
+ if (priv->of_gptp)
+ ravb_modify(ndev, APSR, APSR_GPTPTIMER_SOURCE | APSR_GPTPCLOCK,
+ APSR_GPTPTIMER_SOURCE | APSR_GPTPCLOCK);
+
+ return 0;
+}
+
+static const struct ravb_gptp_info ravb_gen4_ptp_info = {
+ .probe = ravb_gen4_ptp_probe,
+ .clock_index = ravb_gen4_ptp_clock_index,
+ .set_config_mode = ravb_gen4_ptp_set_config_mode,
+};
+
static const struct ravb_hw_info ravb_gen4_hw_info = {
.receive = ravb_rx_rcar,
.set_rate = ravb_set_rate_rcar,
@@ -2777,7 +2828,7 @@ static const struct ravb_hw_info ravb_gen4_hw_info = {
.tx_counters = 1,
.multi_irqs = 1,
.irq_en_dis = 1,
- .ptp = &ravb_gen3_ptp_info,
+ .ptp = &ravb_gen4_ptp_info,
.nc_queues = 1,
.magic_pkt = 1,
};
@@ -3191,6 +3242,7 @@ static void ravb_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
pm_runtime_dont_use_autosuspend(dev);
clk_unprepare(priv->refclk);
+ of_node_put(priv->of_gptp);
reset_control_assert(priv->rstc);
free_netdev(ndev);
platform_set_drvdata(pdev, NULL);
--
2.55.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH net-next v4 10/10] net: ethernet: ravb: Add gPTP support for Gen4
2026-09-09 17:30 ` [PATCH net-next v4 10/10] net: ethernet: ravb: Add gPTP support " Niklas Söderlund
@ 2026-09-10 17:31 ` sashiko-bot
0 siblings, 0 replies; 19+ messages in thread
From: sashiko-bot @ 2026-09-10 17:31 UTC (permalink / raw)
To: Niklas Söderlund; +Cc: devicetree, robh, conor+dt, wsa+renesas
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [Medium] Memory leak of the OF node reference `priv->of_gptp` on `ravb_probe()` error paths.
Pre-existing issues:
- [High] Early return on `pm_runtime_resume_and_get()` failure in `ravb_remove()` bypasses all device unregistration and cleanup, causing Use-After-Free (UAF) and memory leaks.
--
commit 48076f5d1eda0f850642f3a64b86b20eefb56947
Author: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
net: ethernet: ravb: Add gPTP support for Gen4
This commit adds gPTP support for R-Car Gen4 devices by utilizing a
system-wide gPTP clock. It adds the ptp-timer property parsing and modifies
device initialization and teardown to manage the external clock reference.
> diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c
> index 8617c30dbb14e..c8aa40136c3da 100644
> --- a/drivers/net/ethernet/renesas/ravb_main.c
> +++ b/drivers/net/ethernet/renesas/ravb_main.c
> @@ -2755,6 +2755,57 @@ static const struct ravb_hw_info ravb_gen3_hw_info = {
> .magic_pkt = 1,
> };
>
> +static int ravb_gen4_ptp_probe(struct net_device *ndev)
> +{
> + struct ravb_private *priv = netdev_priv(ndev);
> +
> + priv->of_gptp = of_parse_phandle(priv->pdev->dev.of_node, "ptp-timer", 0);
[Severity: Medium]
Does this code leak the device node reference on error paths?
In ravb_probe(), this new ravb_gen4_ptp_probe() is called via
info->ptp->probe(ndev) and acquires the reference.
If a subsequent step in ravb_probe() fails (for example,
devm_clk_get_optional() or register_netdev()), the function jumps to shared
error labels like out_reset_assert or out_rpm_disable.
None of these error paths call of_node_put(priv->of_gptp), which leaves the
node reference permanently leaked.
> + if (!priv->of_gptp)
> + return 0;
> +
> + if (!of_device_is_available(priv->of_gptp)) {
> + of_node_put(priv->of_gptp);
> + priv->of_gptp = NULL;
> + }
> +
> + return 0;
> +}
[ ... ]
> @@ -3191,6 +3242,7 @@ static void ravb_remove(struct platform_device *pdev)
> pm_runtime_disable(&pdev->dev);
> pm_runtime_dont_use_autosuspend(dev);
> clk_unprepare(priv->refclk);
> + of_node_put(priv->of_gptp);
[Severity: High]
This is a pre-existing issue, but does the early return in ravb_remove()
cause a use-after-free and memory leaks?
Earlier in ravb_remove(), there is an early return if
pm_runtime_resume_and_get() fails:
error = pm_runtime_resume_and_get(dev);
if (error < 0)
return;
When this fails, ravb_remove() abruptly returns without calling
unregister_netdev() or any teardown logic.
Since the driver unbinds anyway, devres will automatically unmap the device
memory (e.g., priv->addr).
However, because unregister_netdev() was skipped, the network device remains
active and will attempt to access the unmapped memory during network operations
or interrupts, leading to a kernel crash.
Additionally, this early return will also skip the newly added
of_node_put(priv->of_gptp) call, leaking the OF node reference.
> reset_control_assert(priv->rstc);
> free_netdev(ndev);
> platform_set_drvdata(pdev, NULL);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260909173027.2201560-1-niklas.soderlund+renesas@ragnatech.se?part=10
^ permalink raw reply [flat|nested] 19+ messages in thread