[PATCH 3/4] can: dev: set IFF_ECHO when allocating echo skbs
From: Vincent Mailhol
Date: Tue Aug 04 2026 - 15:56:28 EST
Drivers which request echo skb slots from alloc_candev() are expected to
use the generic CAN echo skb helpers and handle local echo themselves.
Such drivers also need to set IFF_ECHO to prevent PF_CAN from performing
fallback echo.
Set IFF_ECHO from alloc_candev_mqs() whenever echo_skb_max is non-zero.
This ties the flag to the generic echo skb allocation and avoids
requiring every driver to set it manually.
This also covers ucan as a side effect. That driver already requests
echo skb slots and uses can_put_echo_skb(), can_get_echo_skb(), and
can_free_echo_skb(), but forgot to set IFF_ECHO.
After this change, drivers which use the generic echo skb helpers have
one less thing to remember during netdevice setup. Update the CAN
documentation accordingly.
Signed-off-by: Vincent Mailhol <mailhol@xxxxxxxxxx>
---
Documentation/networking/can.rst | 5 ++++-
drivers/net/can/dev/dev.c | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/Documentation/networking/can.rst b/Documentation/networking/can.rst
index fbd0d501ea4e..bf3d8dc193a7 100644
--- a/Documentation/networking/can.rst
+++ b/Documentation/networking/can.rst
@@ -1124,7 +1124,10 @@ As described in :ref:`socketcan-local-loopback1` the CAN network device driver s
support a local loopback functionality similar to the local echo
e.g. of tty devices. In this case the driver flag IFF_ECHO has to be
set to prevent the PF_CAN core from locally echoing sent frames
-(aka loopback) as fallback solution::
+(aka loopback) as fallback solution. For CAN drivers which request
+echo skb slots through ``alloc_candev()`` or ``alloc_candev_mqs()``,
+the framework sets ``IFF_ECHO`` automatically. The other drivers need
+to set it manually::
dev->flags |= IFF_ECHO;
diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 769745e22a3c..7089ce871b24 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -338,6 +338,7 @@ struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,
priv->echo_skb_max = echo_skb_max;
priv->echo_skb = (void *)priv +
(size - echo_skb_max * sizeof(struct sk_buff *));
+ dev->flags |= IFF_ECHO;
}
priv->state = CAN_STATE_STOPPED;
--
2.54.0