public inbox for linux-can@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/3] can: propagate CAN device capabilities via ml_priv
  2026-01-01 19:13 [PATCH 1/3] " Oliver Hartkopp
@ 2026-01-01 19:13 ` Oliver Hartkopp
  2026-01-06 15:40   ` Oliver Hartkopp
  2026-01-09 10:37   ` Marc Kleine-Budde
  0 siblings, 2 replies; 15+ messages in thread
From: Oliver Hartkopp @ 2026-01-01 19:13 UTC (permalink / raw)
  To: linux-can
  Cc: Oliver Hartkopp, Marc Kleine-Budde, Arnd Bergmann,
	Vincent Mailhol

Commit 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
caused a sequence of dependency and linker fixes.

The entire problem was caused by the requirement that a new network layer
feature needed to know about the protocol capabilities of the CAN devices.
Instead of accessing CAN device internal data structures which caused the
dependency problems this patch introduces capability information into the
CAN specific ml_priv data which is accessible from both sides.

With this change the CAN network layer can check the required features and
the decoupling of the driver layer and network layer is restored.

Fixes: 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
 drivers/net/can/dev/dev.c     | 24 ++++++++++++++++++++++++
 drivers/net/can/dev/netlink.c |  1 +
 drivers/net/can/vcan.c        | 15 +++++++++++++++
 drivers/net/can/vxcan.c       | 15 +++++++++++++++
 include/linux/can/can-ml.h    | 25 +++++++++++++++++++++++++
 include/linux/can/dev.h       |  1 +
 6 files changed, 81 insertions(+)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 091f30e94c61..aaa669fc0d2b 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -373,10 +373,33 @@ void can_set_default_mtu(struct net_device *dev)
 		dev->min_mtu = CAN_MTU;
 		dev->max_mtu = CAN_MTU;
 	}
 }
 
+void can_set_cap_info(struct net_device *dev)
+{
+	struct can_priv *priv = netdev_priv(dev);
+	u32 can_cap = CAN_CAP_CC;
+
+	if (can_dev_in_xl_only_mode(priv)) {
+		/* XL only mode => no CC/FD capability */
+		can_cap = CAN_CAP_XL;
+	} else {
+		if (priv->ctrlmode & CAN_CTRLMODE_FD)
+			can_cap |= CAN_CAP_FD;
+
+		if (priv->ctrlmode & CAN_CTRLMODE_XL)
+			can_cap |= CAN_CAP_XL;
+	}
+
+	if (priv->ctrlmode & (CAN_CTRLMODE_LISTENONLY |
+			      CAN_CTRLMODE_RESTRICTED))
+		can_cap |= CAN_CAP_RO;
+
+	can_set_cap(dev, can_cap);
+}
+
 /* helper to define static CAN controller features at device creation time */
 int can_set_static_ctrlmode(struct net_device *dev, u32 static_mode)
 {
 	struct can_priv *priv = netdev_priv(dev);
 
@@ -388,10 +411,11 @@ int can_set_static_ctrlmode(struct net_device *dev, u32 static_mode)
 	}
 	priv->ctrlmode = static_mode;
 
 	/* override MTU which was set by default in can_setup()? */
 	can_set_default_mtu(dev);
+	can_set_cap_info(dev);
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(can_set_static_ctrlmode);
 
diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
index d6b0e686fb11..0498198a4696 100644
--- a/drivers/net/can/dev/netlink.c
+++ b/drivers/net/can/dev/netlink.c
@@ -375,10 +375,11 @@ static int can_ctrlmode_changelink(struct net_device *dev,
 		memset(&priv->xl.tdc, 0, sizeof(priv->xl.tdc));
 		memset(&priv->xl.pwm, 0, sizeof(priv->xl.pwm));
 	}
 
 	can_set_default_mtu(dev);
+	can_set_cap_info(dev);
 
 	return 0;
 }
 
 static int can_tdc_changelink(struct data_bittiming_params *dbt_params,
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index fdc662aea279..76e6b7b5c6a1 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -128,10 +128,23 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
 		consume_skb(skb);
 	}
 	return NETDEV_TX_OK;
 }
 
+static void vcan_set_cap_info(struct net_device *dev)
+{
+	u32 can_cap = CAN_CAP_CC;
+
+	if (dev->mtu > CAN_MTU)
+		can_cap |= CAN_CAP_FD;
+
+	if (dev->mtu >= CANXL_MIN_MTU)
+		can_cap |= CAN_CAP_XL;
+
+	can_set_cap(dev, can_cap);
+}
+
 static int vcan_change_mtu(struct net_device *dev, int new_mtu)
 {
 	/* Do not allow changing the MTU while running */
 	if (dev->flags & IFF_UP)
 		return -EBUSY;
@@ -139,10 +152,11 @@ static int vcan_change_mtu(struct net_device *dev, int new_mtu)
 	if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU &&
 	    !can_is_canxl_dev_mtu(new_mtu))
 		return -EINVAL;
 
 	WRITE_ONCE(dev->mtu, new_mtu);
+	vcan_set_cap_info(dev);
 	return 0;
 }
 
 static const struct net_device_ops vcan_netdev_ops = {
 	.ndo_start_xmit = vcan_tx,
@@ -160,10 +174,11 @@ static void vcan_setup(struct net_device *dev)
 	dev->hard_header_len	= 0;
 	dev->addr_len		= 0;
 	dev->tx_queue_len	= 0;
 	dev->flags		= IFF_NOARP;
 	can_set_ml_priv(dev, netdev_priv(dev));
+	vcan_set_cap_info(dev);
 
 	/* set flags according to driver capabilities */
 	if (echo)
 		dev->flags |= IFF_ECHO;
 
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index b2c19f8c5f8e..f14c6f02b662 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -123,10 +123,23 @@ static int vxcan_get_iflink(const struct net_device *dev)
 	rcu_read_unlock();
 
 	return iflink;
 }
 
+static void vxcan_set_cap_info(struct net_device *dev)
+{
+	u32 can_cap = CAN_CAP_CC;
+
+	if (dev->mtu > CAN_MTU)
+		can_cap |= CAN_CAP_FD;
+
+	if (dev->mtu >= CANXL_MIN_MTU)
+		can_cap |= CAN_CAP_XL;
+
+	can_set_cap(dev, can_cap);
+}
+
 static int vxcan_change_mtu(struct net_device *dev, int new_mtu)
 {
 	/* Do not allow changing the MTU while running */
 	if (dev->flags & IFF_UP)
 		return -EBUSY;
@@ -134,10 +147,11 @@ static int vxcan_change_mtu(struct net_device *dev, int new_mtu)
 	if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU &&
 	    !can_is_canxl_dev_mtu(new_mtu))
 		return -EINVAL;
 
 	WRITE_ONCE(dev->mtu, new_mtu);
+	vxcan_set_cap_info(dev);
 	return 0;
 }
 
 static const struct net_device_ops vxcan_netdev_ops = {
 	.ndo_open	= vxcan_open,
@@ -165,10 +179,11 @@ static void vxcan_setup(struct net_device *dev)
 	dev->ethtool_ops	= &vxcan_ethtool_ops;
 	dev->needs_free_netdev	= true;
 
 	can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN);
 	can_set_ml_priv(dev, can_ml);
+	vxcan_set_cap_info(dev);
 }
 
 /* forward declaration for rtnl_create_link() */
 static struct rtnl_link_ops vxcan_link_ops;
 
diff --git a/include/linux/can/can-ml.h b/include/linux/can/can-ml.h
index 8afa92d15a66..ff77097ae79f 100644
--- a/include/linux/can/can-ml.h
+++ b/include/linux/can/can-ml.h
@@ -44,10 +44,16 @@
 
 #include <linux/can.h>
 #include <linux/list.h>
 #include <linux/netdevice.h>
 
+/* exposed CAN device capabilities for network layer */
+#define CAN_CAP_CC 0x1U /* CAN CC aka Classical CAN */
+#define CAN_CAP_FD 0x2U /* CAN FD */
+#define CAN_CAP_XL 0x4U /* CAN XL */
+#define CAN_CAP_RO 0x8U /* read-only mode (LISTEN/RESTRICTED) */
+
 #define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS)
 #define CAN_EFF_RCV_HASH_BITS 10
 #define CAN_EFF_RCV_ARRAY_SZ (1 << CAN_EFF_RCV_HASH_BITS)
 
 enum { RX_ERR, RX_ALL, RX_FIL, RX_INV, RX_MAX };
@@ -62,10 +68,11 @@ struct can_dev_rcv_lists {
 struct can_ml_priv {
 	struct can_dev_rcv_lists dev_rcv_lists;
 #ifdef CAN_J1939
 	struct j1939_priv *j1939_priv;
 #endif
+	u32 can_cap;
 };
 
 static inline struct can_ml_priv *can_get_ml_priv(struct net_device *dev)
 {
 	return netdev_get_ml_priv(dev, ML_PRIV_CAN);
@@ -75,6 +82,24 @@ static inline void can_set_ml_priv(struct net_device *dev,
 				   struct can_ml_priv *ml_priv)
 {
 	netdev_set_ml_priv(dev, ml_priv, ML_PRIV_CAN);
 }
 
+static inline bool can_cap_enabled(struct net_device *dev, u32 cap)
+{
+	struct can_ml_priv *can_ml = can_get_ml_priv(dev);
+
+	if (!can_ml)
+		return true;
+
+	return (can_ml->can_cap & cap);
+}
+
+static inline void can_set_cap(struct net_device *dev, u32 cap)
+{
+	struct can_ml_priv *can_ml = can_get_ml_priv(dev);
+
+	if (can_ml)
+		can_ml->can_cap = cap;
+}
+
 #endif /* CAN_ML_H */
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 52c8be5c160e..6d0710d6f571 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -114,10 +114,11 @@ void free_candev(struct net_device *dev);
 struct can_priv *safe_candev_priv(struct net_device *dev);
 
 int open_candev(struct net_device *dev);
 void close_candev(struct net_device *dev);
 void can_set_default_mtu(struct net_device *dev);
+void can_set_cap_info(struct net_device *dev);
 int __must_check can_set_static_ctrlmode(struct net_device *dev,
 					 u32 static_mode);
 int can_hwtstamp_get(struct net_device *netdev,
 		     struct kernel_hwtstamp_config *cfg);
 int can_hwtstamp_set(struct net_device *netdev,
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/3] can: propagate CAN device capabilities via ml_priv
  2026-01-01 19:13 ` [PATCH 2/3] can: propagate CAN device capabilities via ml_priv Oliver Hartkopp
@ 2026-01-06 15:40   ` Oliver Hartkopp
  2026-01-09  9:23     ` Marc Kleine-Budde
  2026-01-09 10:37   ` Marc Kleine-Budde
  1 sibling, 1 reply; 15+ messages in thread
From: Oliver Hartkopp @ 2026-01-06 15:40 UTC (permalink / raw)
  To: Marc Kleine-Budde, Vincent Mailhol; +Cc: linux-can, Arnd Bergmann

Hi Marc/Vincent,

On 01.01.26 20:13, Oliver Hartkopp wrote:
> Commit 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
> caused a sequence of dependency and linker fixes.
> 
> The entire problem was caused by the requirement that a new network layer
> feature needed to know about the protocol capabilities of the CAN devices.
> Instead of accessing CAN device internal data structures which caused the
> dependency problems this patch introduces capability information into the
> CAN specific ml_priv data which is accessible from both sides.
> 
> With this change the CAN network layer can check the required features and
> the decoupling of the driver layer and network layer is restored.
> 
> Fixes: 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")

Are you fine with this patch set?
I've tested it and it works as expected.

IMO the two patches after the revert should have no problems to be 
accepted as they restore the functionality we already had in 6.19-rc1.

Best regards,
Oliver

> Cc: Marc Kleine-Budde <mkl@pengutronix.de>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Vincent Mailhol <mailhol@kernel.org>
> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
> ---
>   drivers/net/can/dev/dev.c     | 24 ++++++++++++++++++++++++
>   drivers/net/can/dev/netlink.c |  1 +
>   drivers/net/can/vcan.c        | 15 +++++++++++++++
>   drivers/net/can/vxcan.c       | 15 +++++++++++++++
>   include/linux/can/can-ml.h    | 25 +++++++++++++++++++++++++
>   include/linux/can/dev.h       |  1 +
>   6 files changed, 81 insertions(+)
> 
> diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
> index 091f30e94c61..aaa669fc0d2b 100644
> --- a/drivers/net/can/dev/dev.c
> +++ b/drivers/net/can/dev/dev.c
> @@ -373,10 +373,33 @@ void can_set_default_mtu(struct net_device *dev)
>   		dev->min_mtu = CAN_MTU;
>   		dev->max_mtu = CAN_MTU;
>   	}
>   }
>   
> +void can_set_cap_info(struct net_device *dev)
> +{
> +	struct can_priv *priv = netdev_priv(dev);
> +	u32 can_cap = CAN_CAP_CC;
> +
> +	if (can_dev_in_xl_only_mode(priv)) {
> +		/* XL only mode => no CC/FD capability */
> +		can_cap = CAN_CAP_XL;
> +	} else {
> +		if (priv->ctrlmode & CAN_CTRLMODE_FD)
> +			can_cap |= CAN_CAP_FD;
> +
> +		if (priv->ctrlmode & CAN_CTRLMODE_XL)
> +			can_cap |= CAN_CAP_XL;
> +	}
> +
> +	if (priv->ctrlmode & (CAN_CTRLMODE_LISTENONLY |
> +			      CAN_CTRLMODE_RESTRICTED))
> +		can_cap |= CAN_CAP_RO;
> +
> +	can_set_cap(dev, can_cap);
> +}
> +
>   /* helper to define static CAN controller features at device creation time */
>   int can_set_static_ctrlmode(struct net_device *dev, u32 static_mode)
>   {
>   	struct can_priv *priv = netdev_priv(dev);
>   
> @@ -388,10 +411,11 @@ int can_set_static_ctrlmode(struct net_device *dev, u32 static_mode)
>   	}
>   	priv->ctrlmode = static_mode;
>   
>   	/* override MTU which was set by default in can_setup()? */
>   	can_set_default_mtu(dev);
> +	can_set_cap_info(dev);
>   
>   	return 0;
>   }
>   EXPORT_SYMBOL_GPL(can_set_static_ctrlmode);
>   
> diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
> index d6b0e686fb11..0498198a4696 100644
> --- a/drivers/net/can/dev/netlink.c
> +++ b/drivers/net/can/dev/netlink.c
> @@ -375,10 +375,11 @@ static int can_ctrlmode_changelink(struct net_device *dev,
>   		memset(&priv->xl.tdc, 0, sizeof(priv->xl.tdc));
>   		memset(&priv->xl.pwm, 0, sizeof(priv->xl.pwm));
>   	}
>   
>   	can_set_default_mtu(dev);
> +	can_set_cap_info(dev);
>   
>   	return 0;
>   }
>   
>   static int can_tdc_changelink(struct data_bittiming_params *dbt_params,
> diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
> index fdc662aea279..76e6b7b5c6a1 100644
> --- a/drivers/net/can/vcan.c
> +++ b/drivers/net/can/vcan.c
> @@ -128,10 +128,23 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
>   		consume_skb(skb);
>   	}
>   	return NETDEV_TX_OK;
>   }
>   
> +static void vcan_set_cap_info(struct net_device *dev)
> +{
> +	u32 can_cap = CAN_CAP_CC;
> +
> +	if (dev->mtu > CAN_MTU)
> +		can_cap |= CAN_CAP_FD;
> +
> +	if (dev->mtu >= CANXL_MIN_MTU)
> +		can_cap |= CAN_CAP_XL;
> +
> +	can_set_cap(dev, can_cap);
> +}
> +
>   static int vcan_change_mtu(struct net_device *dev, int new_mtu)
>   {
>   	/* Do not allow changing the MTU while running */
>   	if (dev->flags & IFF_UP)
>   		return -EBUSY;
> @@ -139,10 +152,11 @@ static int vcan_change_mtu(struct net_device *dev, int new_mtu)
>   	if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU &&
>   	    !can_is_canxl_dev_mtu(new_mtu))
>   		return -EINVAL;
>   
>   	WRITE_ONCE(dev->mtu, new_mtu);
> +	vcan_set_cap_info(dev);
>   	return 0;
>   }
>   
>   static const struct net_device_ops vcan_netdev_ops = {
>   	.ndo_start_xmit = vcan_tx,
> @@ -160,10 +174,11 @@ static void vcan_setup(struct net_device *dev)
>   	dev->hard_header_len	= 0;
>   	dev->addr_len		= 0;
>   	dev->tx_queue_len	= 0;
>   	dev->flags		= IFF_NOARP;
>   	can_set_ml_priv(dev, netdev_priv(dev));
> +	vcan_set_cap_info(dev);
>   
>   	/* set flags according to driver capabilities */
>   	if (echo)
>   		dev->flags |= IFF_ECHO;
>   
> diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
> index b2c19f8c5f8e..f14c6f02b662 100644
> --- a/drivers/net/can/vxcan.c
> +++ b/drivers/net/can/vxcan.c
> @@ -123,10 +123,23 @@ static int vxcan_get_iflink(const struct net_device *dev)
>   	rcu_read_unlock();
>   
>   	return iflink;
>   }
>   
> +static void vxcan_set_cap_info(struct net_device *dev)
> +{
> +	u32 can_cap = CAN_CAP_CC;
> +
> +	if (dev->mtu > CAN_MTU)
> +		can_cap |= CAN_CAP_FD;
> +
> +	if (dev->mtu >= CANXL_MIN_MTU)
> +		can_cap |= CAN_CAP_XL;
> +
> +	can_set_cap(dev, can_cap);
> +}
> +
>   static int vxcan_change_mtu(struct net_device *dev, int new_mtu)
>   {
>   	/* Do not allow changing the MTU while running */
>   	if (dev->flags & IFF_UP)
>   		return -EBUSY;
> @@ -134,10 +147,11 @@ static int vxcan_change_mtu(struct net_device *dev, int new_mtu)
>   	if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU &&
>   	    !can_is_canxl_dev_mtu(new_mtu))
>   		return -EINVAL;
>   
>   	WRITE_ONCE(dev->mtu, new_mtu);
> +	vxcan_set_cap_info(dev);
>   	return 0;
>   }
>   
>   static const struct net_device_ops vxcan_netdev_ops = {
>   	.ndo_open	= vxcan_open,
> @@ -165,10 +179,11 @@ static void vxcan_setup(struct net_device *dev)
>   	dev->ethtool_ops	= &vxcan_ethtool_ops;
>   	dev->needs_free_netdev	= true;
>   
>   	can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN);
>   	can_set_ml_priv(dev, can_ml);
> +	vxcan_set_cap_info(dev);
>   }
>   
>   /* forward declaration for rtnl_create_link() */
>   static struct rtnl_link_ops vxcan_link_ops;
>   
> diff --git a/include/linux/can/can-ml.h b/include/linux/can/can-ml.h
> index 8afa92d15a66..ff77097ae79f 100644
> --- a/include/linux/can/can-ml.h
> +++ b/include/linux/can/can-ml.h
> @@ -44,10 +44,16 @@
>   
>   #include <linux/can.h>
>   #include <linux/list.h>
>   #include <linux/netdevice.h>
>   
> +/* exposed CAN device capabilities for network layer */
> +#define CAN_CAP_CC 0x1U /* CAN CC aka Classical CAN */
> +#define CAN_CAP_FD 0x2U /* CAN FD */
> +#define CAN_CAP_XL 0x4U /* CAN XL */
> +#define CAN_CAP_RO 0x8U /* read-only mode (LISTEN/RESTRICTED) */
> +
>   #define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS)
>   #define CAN_EFF_RCV_HASH_BITS 10
>   #define CAN_EFF_RCV_ARRAY_SZ (1 << CAN_EFF_RCV_HASH_BITS)
>   
>   enum { RX_ERR, RX_ALL, RX_FIL, RX_INV, RX_MAX };
> @@ -62,10 +68,11 @@ struct can_dev_rcv_lists {
>   struct can_ml_priv {
>   	struct can_dev_rcv_lists dev_rcv_lists;
>   #ifdef CAN_J1939
>   	struct j1939_priv *j1939_priv;
>   #endif
> +	u32 can_cap;
>   };
>   
>   static inline struct can_ml_priv *can_get_ml_priv(struct net_device *dev)
>   {
>   	return netdev_get_ml_priv(dev, ML_PRIV_CAN);
> @@ -75,6 +82,24 @@ static inline void can_set_ml_priv(struct net_device *dev,
>   				   struct can_ml_priv *ml_priv)
>   {
>   	netdev_set_ml_priv(dev, ml_priv, ML_PRIV_CAN);
>   }
>   
> +static inline bool can_cap_enabled(struct net_device *dev, u32 cap)
> +{
> +	struct can_ml_priv *can_ml = can_get_ml_priv(dev);
> +
> +	if (!can_ml)
> +		return true;
> +
> +	return (can_ml->can_cap & cap);
> +}
> +
> +static inline void can_set_cap(struct net_device *dev, u32 cap)
> +{
> +	struct can_ml_priv *can_ml = can_get_ml_priv(dev);
> +
> +	if (can_ml)
> +		can_ml->can_cap = cap;
> +}
> +
>   #endif /* CAN_ML_H */
> diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
> index 52c8be5c160e..6d0710d6f571 100644
> --- a/include/linux/can/dev.h
> +++ b/include/linux/can/dev.h
> @@ -114,10 +114,11 @@ void free_candev(struct net_device *dev);
>   struct can_priv *safe_candev_priv(struct net_device *dev);
>   
>   int open_candev(struct net_device *dev);
>   void close_candev(struct net_device *dev);
>   void can_set_default_mtu(struct net_device *dev);
> +void can_set_cap_info(struct net_device *dev);
>   int __must_check can_set_static_ctrlmode(struct net_device *dev,
>   					 u32 static_mode);
>   int can_hwtstamp_get(struct net_device *netdev,
>   		     struct kernel_hwtstamp_config *cfg);
>   int can_hwtstamp_set(struct net_device *netdev,


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/3] can: propagate CAN device capabilities via ml_priv
  2026-01-06 15:40   ` Oliver Hartkopp
@ 2026-01-09  9:23     ` Marc Kleine-Budde
  2026-01-09  9:43       ` Oliver Hartkopp
  0 siblings, 1 reply; 15+ messages in thread
From: Marc Kleine-Budde @ 2026-01-09  9:23 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: Vincent Mailhol, linux-can, Arnd Bergmann

[-- Attachment #1: Type: text/plain, Size: 1615 bytes --]

On 06.01.2026 16:40:07, Oliver Hartkopp wrote:
> On 01.01.26 20:13, Oliver Hartkopp wrote:
> > Commit 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
> > caused a sequence of dependency and linker fixes.
> >
> > The entire problem was caused by the requirement that a new network layer
> > feature needed to know about the protocol capabilities of the CAN devices.
> > Instead of accessing CAN device internal data structures which caused the
> > dependency problems this patch introduces capability information into the
> > CAN specific ml_priv data which is accessible from both sides.
> >
> > With this change the CAN network layer can check the required features and
> > the decoupling of the driver layer and network layer is restored.
> >
> > Fixes: 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
>
> Are you fine with this patch set?
> I've tested it and it works as expected.

It seems to be OK as an interim solution, that fixes current mess.

But the main problem is, that we don't have the "struct can_priv can" in
the netdev_priv of virtual devices. That should be fixed sooner or
later.

> IMO the two patches after the revert should have no problems to be accepted
> as they restore the functionality we already had in 6.19-rc1.

Yes, I think so.

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/3] can: propagate CAN device capabilities via ml_priv
  2026-01-09  9:23     ` Marc Kleine-Budde
@ 2026-01-09  9:43       ` Oliver Hartkopp
  0 siblings, 0 replies; 15+ messages in thread
From: Oliver Hartkopp @ 2026-01-09  9:43 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: Vincent Mailhol, linux-can, Arnd Bergmann



On 09.01.26 10:23, Marc Kleine-Budde wrote:
> On 06.01.2026 16:40:07, Oliver Hartkopp wrote:
>> On 01.01.26 20:13, Oliver Hartkopp wrote:
>>> Commit 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
>>> caused a sequence of dependency and linker fixes.
>>>
>>> The entire problem was caused by the requirement that a new network layer
>>> feature needed to know about the protocol capabilities of the CAN devices.
>>> Instead of accessing CAN device internal data structures which caused the
>>> dependency problems this patch introduces capability information into the
>>> CAN specific ml_priv data which is accessible from both sides.
>>>
>>> With this change the CAN network layer can check the required features and
>>> the decoupling of the driver layer and network layer is restored.
>>>
>>> Fixes: 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
>>
>> Are you fine with this patch set?
>> I've tested it and it works as expected.
> 
> It seems to be OK as an interim solution, that fixes current mess.
> 
> But the main problem is, that we don't have the "struct can_priv can" in
> the netdev_priv of virtual devices. That should be fixed sooner or
> later.

I don't think so. In fact the virtual CAN interfaces vcan/vxcan don't 
need any CAN driver infrastructure to do their work. So why require to 
add lots of code for hardware-less setups?

When you really want to play with a virtual CAN driver that supports the 
entire struct can_priv mechanic and netlink configuration, Vincents new 
dummy_can driver does an excellent work.

Maybe we should improve the v[x]can drivers to reduce code duplications 
in the future.

>> IMO the two patches after the revert should have no problems to be accepted
>> as they restore the functionality we already had in 6.19-rc1.
> 
> Yes, I think so.

Thanks. The three patches are candidates for Jakubs "Current release - 
fix to a fix:" section in his PR description ;-)

Best regards,
Oliver


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/3] can: propagate CAN device capabilities via ml_priv
  2026-01-01 19:13 ` [PATCH 2/3] can: propagate CAN device capabilities via ml_priv Oliver Hartkopp
  2026-01-06 15:40   ` Oliver Hartkopp
@ 2026-01-09 10:37   ` Marc Kleine-Budde
  2026-01-09 11:31     ` Oliver Hartkopp
  1 sibling, 1 reply; 15+ messages in thread
From: Marc Kleine-Budde @ 2026-01-09 10:37 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: linux-can, Arnd Bergmann, Vincent Mailhol

[-- Attachment #1: Type: text/plain, Size: 4722 bytes --]

Can you please add a cover letter to this series.

more comments inline...

On 01.01.2026 20:13:29, Oliver Hartkopp wrote:
> Commit 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
> caused a sequence of dependency and linker fixes.
>
> The entire problem was caused by the requirement that a new network layer
> feature needed to know about the protocol capabilities of the CAN devices.
> Instead of accessing CAN device internal data structures which caused the
> dependency problems this patch introduces capability information into the
> CAN specific ml_priv data which is accessible from both sides.
>
> With this change the CAN network layer can check the required features and
> the decoupling of the driver layer and network layer is restored.
>
> Fixes: 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
> Cc: Marc Kleine-Budde <mkl@pengutronix.de>
> Cc: Arnd Bergmann <arnd@arndb.de>
> Cc: Vincent Mailhol <mailhol@kernel.org>
> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
> ---
>  drivers/net/can/dev/dev.c     | 24 ++++++++++++++++++++++++
>  drivers/net/can/dev/netlink.c |  1 +
>  drivers/net/can/vcan.c        | 15 +++++++++++++++
>  drivers/net/can/vxcan.c       | 15 +++++++++++++++
>  include/linux/can/can-ml.h    | 25 +++++++++++++++++++++++++
>  include/linux/can/dev.h       |  1 +
>  6 files changed, 81 insertions(+)
>
> diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
> index 091f30e94c61..aaa669fc0d2b 100644
> --- a/drivers/net/can/dev/dev.c
> +++ b/drivers/net/can/dev/dev.c
> @@ -373,10 +373,33 @@ void can_set_default_mtu(struct net_device *dev)
>  		dev->min_mtu = CAN_MTU;
>  		dev->max_mtu = CAN_MTU;
>  	}
>  }
>
> +void can_set_cap_info(struct net_device *dev)
> +{
> +	struct can_priv *priv = netdev_priv(dev);
> +	u32 can_cap = CAN_CAP_CC;

I personally I would move the CAN_CAP_CC into the else branch. YMMV.

> +
> +	if (can_dev_in_xl_only_mode(priv)) {
> +		/* XL only mode => no CC/FD capability */
> +		can_cap = CAN_CAP_XL;
> +	} else {
> +		if (priv->ctrlmode & CAN_CTRLMODE_FD)
> +			can_cap |= CAN_CAP_FD;
> +
> +		if (priv->ctrlmode & CAN_CTRLMODE_XL)
> +			can_cap |= CAN_CAP_XL;
> +	}
> +
> +	if (priv->ctrlmode & (CAN_CTRLMODE_LISTENONLY |
> +			      CAN_CTRLMODE_RESTRICTED))
> +		can_cap |= CAN_CAP_RO;
> +
> +	can_set_cap(dev, can_cap);
> +}
> +

[...]

> diff --git a/include/linux/can/can-ml.h b/include/linux/can/can-ml.h
> index 8afa92d15a66..ff77097ae79f 100644
> --- a/include/linux/can/can-ml.h
> +++ b/include/linux/can/can-ml.h
> @@ -44,10 +44,16 @@
>
>  #include <linux/can.h>
>  #include <linux/list.h>
>  #include <linux/netdevice.h>
>
> +/* exposed CAN device capabilities for network layer */
> +#define CAN_CAP_CC 0x1U /* CAN CC aka Classical CAN */
> +#define CAN_CAP_FD 0x2U /* CAN FD */
> +#define CAN_CAP_XL 0x4U /* CAN XL */
> +#define CAN_CAP_RO 0x8U /* read-only mode (LISTEN/RESTRICTED) */

Can we use BIT() here?

> +
>  #define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS)
>  #define CAN_EFF_RCV_HASH_BITS 10
>  #define CAN_EFF_RCV_ARRAY_SZ (1 << CAN_EFF_RCV_HASH_BITS)
>
>  enum { RX_ERR, RX_ALL, RX_FIL, RX_INV, RX_MAX };
> @@ -62,10 +68,11 @@ struct can_dev_rcv_lists {
>  struct can_ml_priv {
>  	struct can_dev_rcv_lists dev_rcv_lists;
>  #ifdef CAN_J1939
>  	struct j1939_priv *j1939_priv;
>  #endif
> +	u32 can_cap;
>  };
>
>  static inline struct can_ml_priv *can_get_ml_priv(struct net_device *dev)
>  {
>  	return netdev_get_ml_priv(dev, ML_PRIV_CAN);
> @@ -75,6 +82,24 @@ static inline void can_set_ml_priv(struct net_device *dev,
>  				   struct can_ml_priv *ml_priv)
>  {
>  	netdev_set_ml_priv(dev, ml_priv, ML_PRIV_CAN);
>  }
>
> +static inline bool can_cap_enabled(struct net_device *dev, u32 cap)
> +{
> +	struct can_ml_priv *can_ml = can_get_ml_priv(dev);
> +
> +	if (!can_ml)
> +		return true;

Why is the capability enabled, if the device doesn't have a CAN ml_priv?

> +
> +	return (can_ml->can_cap & cap);
> +}
> +
> +static inline void can_set_cap(struct net_device *dev, u32 cap)
> +{
> +	struct can_ml_priv *can_ml = can_get_ml_priv(dev);
> +
> +	if (can_ml)

IMHO it's a bug if can_ml is NULL, it should not be ignored silently.
Maybe just de-ref the NULL pointer?

> +		can_ml->can_cap = cap;
> +}
> +
>  #endif /* CAN_ML_H */

Thanks,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/3] can: propagate CAN device capabilities via ml_priv
  2026-01-09 10:37   ` Marc Kleine-Budde
@ 2026-01-09 11:31     ` Oliver Hartkopp
  2026-01-09 11:53       ` Marc Kleine-Budde
  0 siblings, 1 reply; 15+ messages in thread
From: Oliver Hartkopp @ 2026-01-09 11:31 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: linux-can, Arnd Bergmann, Vincent Mailhol



On 09.01.26 11:37, Marc Kleine-Budde wrote:
> Can you please add a cover letter to this series.

Ok.
> 
> more comments inline...
> 
> On 01.01.2026 20:13:29, Oliver Hartkopp wrote:
>> Commit 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
>> caused a sequence of dependency and linker fixes.
>>
>> The entire problem was caused by the requirement that a new network layer
>> feature needed to know about the protocol capabilities of the CAN devices.
>> Instead of accessing CAN device internal data structures which caused the
>> dependency problems this patch introduces capability information into the
>> CAN specific ml_priv data which is accessible from both sides.
>>
>> With this change the CAN network layer can check the required features and
>> the decoupling of the driver layer and network layer is restored.
>>
>> Fixes: 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
>> Cc: Marc Kleine-Budde <mkl@pengutronix.de>
>> Cc: Arnd Bergmann <arnd@arndb.de>
>> Cc: Vincent Mailhol <mailhol@kernel.org>
>> Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
>> ---
>>   drivers/net/can/dev/dev.c     | 24 ++++++++++++++++++++++++
>>   drivers/net/can/dev/netlink.c |  1 +
>>   drivers/net/can/vcan.c        | 15 +++++++++++++++
>>   drivers/net/can/vxcan.c       | 15 +++++++++++++++
>>   include/linux/can/can-ml.h    | 25 +++++++++++++++++++++++++
>>   include/linux/can/dev.h       |  1 +
>>   6 files changed, 81 insertions(+)
>>
>> diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
>> index 091f30e94c61..aaa669fc0d2b 100644
>> --- a/drivers/net/can/dev/dev.c
>> +++ b/drivers/net/can/dev/dev.c
>> @@ -373,10 +373,33 @@ void can_set_default_mtu(struct net_device *dev)
>>   		dev->min_mtu = CAN_MTU;
>>   		dev->max_mtu = CAN_MTU;
>>   	}
>>   }
>>
>> +void can_set_cap_info(struct net_device *dev)
>> +{
>> +	struct can_priv *priv = netdev_priv(dev);
>> +	u32 can_cap = CAN_CAP_CC;
> 
> I personally I would move the CAN_CAP_CC into the else branch. YMMV.
> 

Ok.

>> +
>> +	if (can_dev_in_xl_only_mode(priv)) {
>> +		/* XL only mode => no CC/FD capability */
>> +		can_cap = CAN_CAP_XL;
>> +	} else {
>> +		if (priv->ctrlmode & CAN_CTRLMODE_FD)
>> +			can_cap |= CAN_CAP_FD;
>> +
>> +		if (priv->ctrlmode & CAN_CTRLMODE_XL)
>> +			can_cap |= CAN_CAP_XL;
>> +	}
>> +
>> +	if (priv->ctrlmode & (CAN_CTRLMODE_LISTENONLY |
>> +			      CAN_CTRLMODE_RESTRICTED))
>> +		can_cap |= CAN_CAP_RO;
>> +
>> +	can_set_cap(dev, can_cap);
>> +}
>> +
> 
> [...]
> 
>> diff --git a/include/linux/can/can-ml.h b/include/linux/can/can-ml.h
>> index 8afa92d15a66..ff77097ae79f 100644
>> --- a/include/linux/can/can-ml.h
>> +++ b/include/linux/can/can-ml.h
>> @@ -44,10 +44,16 @@
>>
>>   #include <linux/can.h>
>>   #include <linux/list.h>
>>   #include <linux/netdevice.h>
>>
>> +/* exposed CAN device capabilities for network layer */
>> +#define CAN_CAP_CC 0x1U /* CAN CC aka Classical CAN */
>> +#define CAN_CAP_FD 0x2U /* CAN FD */
>> +#define CAN_CAP_XL 0x4U /* CAN XL */
>> +#define CAN_CAP_RO 0x8U /* read-only mode (LISTEN/RESTRICTED) */
> 
> Can we use BIT() here?
> 

Yes. Good idea.

>> +
>>   #define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS)
>>   #define CAN_EFF_RCV_HASH_BITS 10
>>   #define CAN_EFF_RCV_ARRAY_SZ (1 << CAN_EFF_RCV_HASH_BITS)
>>
>>   enum { RX_ERR, RX_ALL, RX_FIL, RX_INV, RX_MAX };
>> @@ -62,10 +68,11 @@ struct can_dev_rcv_lists {
>>   struct can_ml_priv {
>>   	struct can_dev_rcv_lists dev_rcv_lists;
>>   #ifdef CAN_J1939
>>   	struct j1939_priv *j1939_priv;
>>   #endif
>> +	u32 can_cap;
>>   };
>>
>>   static inline struct can_ml_priv *can_get_ml_priv(struct net_device *dev)
>>   {
>>   	return netdev_get_ml_priv(dev, ML_PRIV_CAN);
>> @@ -75,6 +82,24 @@ static inline void can_set_ml_priv(struct net_device *dev,
>>   				   struct can_ml_priv *ml_priv)
>>   {
>>   	netdev_set_ml_priv(dev, ml_priv, ML_PRIV_CAN);
>>   }
>>
>> +static inline bool can_cap_enabled(struct net_device *dev, u32 cap)
>> +{
>> +	struct can_ml_priv *can_ml = can_get_ml_priv(dev);
>> +
>> +	if (!can_ml)
>> +		return true;
> 
> Why is the capability enabled, if the device doesn't have a CAN ml_priv?

I have been thought about virtual CAN interfaces first but they also 
have a can_ml.

It's just a double-check if we really have a CAN interface here.
But returning false would make more sense then. Will change.

>> +
>> +	return (can_ml->can_cap & cap);
>> +}
>> +
>> +static inline void can_set_cap(struct net_device *dev, u32 cap)
>> +{
>> +	struct can_ml_priv *can_ml = can_get_ml_priv(dev);
>> +
>> +	if (can_ml)
> 
> IMHO it's a bug if can_ml is NULL, it should not be ignored silently.
> Maybe just de-ref the NULL pointer?

Right the callers have a valid can_ml before calling can_set_cap().
Will remove this check.

Best regards,
Oliver

> 
>> +		can_ml->can_cap = cap;
>> +}
>> +
>>   #endif /* CAN_ML_H */
> 
> Thanks,
> Marc
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 2/3] can: propagate CAN device capabilities via ml_priv
  2026-01-09 11:31     ` Oliver Hartkopp
@ 2026-01-09 11:53       ` Marc Kleine-Budde
  0 siblings, 0 replies; 15+ messages in thread
From: Marc Kleine-Budde @ 2026-01-09 11:53 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: linux-can, Arnd Bergmann, Vincent Mailhol

[-- Attachment #1: Type: text/plain, Size: 881 bytes --]

On 09.01.2026 12:31:08, Oliver Hartkopp wrote:
> > > +static inline bool can_cap_enabled(struct net_device *dev, u32 cap)
> > > +{
> > > +	struct can_ml_priv *can_ml = can_get_ml_priv(dev);
> > > +
> > > +	if (!can_ml)
> > > +		return true;
> >
> > Why is the capability enabled, if the device doesn't have a CAN ml_priv?
>
> I have been thought about virtual CAN interfaces first but they also have a
> can_ml.
>
> It's just a double-check if we really have a CAN interface here.
> But returning false would make more sense then. Will change.

...or do we want to just de-ref here, too?

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames"
@ 2026-01-09 14:41 Oliver Hartkopp
  2026-01-09 14:41 ` [PATCH 1/3] " Oliver Hartkopp
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Oliver Hartkopp @ 2026-01-09 14:41 UTC (permalink / raw)
  To: linux-can; +Cc: Oliver Hartkopp

This reverts commit 1a620a723853a0f49703c317d52dc6b9602cbaa8

and its follow-up fixes for the introduced dependency issues.

commit 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
commit cb2dc6d2869a ("can: Kconfig: select CAN driver infrastructure by default")
commit 6abd4577bccc ("can: fix build dependency")
commit 5a5aff6338c0 ("can: fix build dependency")

The reverted patch was accessing CAN device internal data structures
from the network layer because it needs to know about the CAN protocol
capabilities of the CAN devices.

This data access caused build problems between the CAN network and the
CAN driver layer which introduced unwanted Kconfig dependencies and fixes.

The patches 2 & 3 implement a better approach which makes use of the
CAN specific ml_priv data which is accessible from both sides.

With this change the CAN network layer can check the required features
and the decoupling of the driver layer and network layer is restored.

Oliver Hartkopp (3):
  Revert "can: raw: instantly reject unsupported CAN frames"
  can: propagate CAN device capabilities via ml_priv
  can: raw: instantly reject disabled CAN frames

 drivers/net/can/Kconfig       |  7 +++--
 drivers/net/can/Makefile      |  2 +-
 drivers/net/can/dev/Makefile  |  5 ++--
 drivers/net/can/dev/dev.c     | 27 +++++++++++++++++++
 drivers/net/can/dev/netlink.c |  1 +
 drivers/net/can/vcan.c        | 15 +++++++++++
 drivers/net/can/vxcan.c       | 15 +++++++++++
 include/linux/can/can-ml.h    | 24 +++++++++++++++++
 include/linux/can/dev.h       |  8 +-----
 net/can/raw.c                 | 49 ++++++-----------------------------
 10 files changed, 100 insertions(+), 53 deletions(-)

-- 
2.47.3


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 1/3] Revert "can: raw: instantly reject unsupported CAN frames"
  2026-01-09 14:41 [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames" Oliver Hartkopp
@ 2026-01-09 14:41 ` Oliver Hartkopp
  2026-01-09 14:41 ` [PATCH 2/3] can: propagate CAN device capabilities via ml_priv Oliver Hartkopp
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 15+ messages in thread
From: Oliver Hartkopp @ 2026-01-09 14:41 UTC (permalink / raw)
  To: linux-can
  Cc: Oliver Hartkopp, Marc Kleine-Budde, Arnd Bergmann,
	Vincent Mailhol

This reverts commit 1a620a723853a0f49703c317d52dc6b9602cbaa8

and its follow-up fixes for the introduced dependency issues.

commit 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
commit cb2dc6d2869a ("can: Kconfig: select CAN driver infrastructure by default")
commit 6abd4577bccc ("can: fix build dependency")
commit 5a5aff6338c0 ("can: fix build dependency")

The entire problem was caused by the requirement that a new network layer
feature needed to know about the protocol capabilities of the CAN devices.
Instead of accessing CAN device internal data structures which caused the
dependency problems a better approach has been developed which makes use of
CAN specific ml_priv data which is accessible from both sides.

Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
 drivers/net/can/Kconfig      |  7 +++--
 drivers/net/can/Makefile     |  2 +-
 drivers/net/can/dev/Makefile |  5 ++--
 include/linux/can/dev.h      |  7 -----
 net/can/raw.c                | 54 ++++++------------------------------
 5 files changed, 17 insertions(+), 58 deletions(-)

diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index cfaea6178a71..e15e320db476 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -1,9 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
 menuconfig CAN_DEV
-	bool "CAN Device Drivers"
+	tristate "CAN Device Drivers"
 	default y
 	depends on CAN
 	help
 	  Controller Area Network (CAN) is serial communications protocol up to
 	  1Mbit/s for its original release (now known as Classical CAN) and up
@@ -15,11 +15,14 @@ menuconfig CAN_DEV
 
 	  This section contains all the CAN(-FD) device drivers including the
 	  virtual ones. If you own such devices or plan to use the virtual CAN
 	  interfaces to develop applications, say Y here.
 
-if CAN_DEV && CAN
+	  To compile as a module, choose M here: the module will be called
+	  can-dev.
+
+if CAN_DEV
 
 config CAN_VCAN
 	tristate "Virtual Local CAN Interface (vcan)"
 	help
 	  Similar to the network loopback devices, vcan offers a
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 37e2f1a2faec..d7bc10a6b8ea 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -5,11 +5,11 @@
 
 obj-$(CONFIG_CAN_VCAN)		+= vcan.o
 obj-$(CONFIG_CAN_VXCAN)		+= vxcan.o
 obj-$(CONFIG_CAN_SLCAN)		+= slcan/
 
-obj-$(CONFIG_CAN_DEV)		+= dev/
+obj-y				+= dev/
 obj-y				+= esd/
 obj-y				+= rcar/
 obj-y				+= rockchip/
 obj-y				+= spi/
 obj-y				+= usb/
diff --git a/drivers/net/can/dev/Makefile b/drivers/net/can/dev/Makefile
index 64226acf0f3d..633687d6b6c0 100644
--- a/drivers/net/can/dev/Makefile
+++ b/drivers/net/can/dev/Makefile
@@ -1,10 +1,11 @@
 # SPDX-License-Identifier: GPL-2.0
 
-obj-$(CONFIG_CAN) += can-dev.o
+obj-$(CONFIG_CAN_DEV) += can-dev.o
+
+can-dev-y += skb.o
 
-can-dev-$(CONFIG_CAN_DEV) += skb.o
 can-dev-$(CONFIG_CAN_CALC_BITTIMING) += calc_bittiming.o
 can-dev-$(CONFIG_CAN_NETLINK) += bittiming.o
 can-dev-$(CONFIG_CAN_NETLINK) += dev.o
 can-dev-$(CONFIG_CAN_NETLINK) += length.o
 can-dev-$(CONFIG_CAN_NETLINK) += netlink.o
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index f6416a56e95d..52c8be5c160e 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -109,18 +109,11 @@ struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,
 #define alloc_candev_mq(sizeof_priv, echo_skb_max, count) \
 	alloc_candev_mqs(sizeof_priv, echo_skb_max, count, count)
 void free_candev(struct net_device *dev);
 
 /* a candev safe wrapper around netdev_priv */
-#if IS_ENABLED(CONFIG_CAN_NETLINK)
 struct can_priv *safe_candev_priv(struct net_device *dev);
-#else
-static inline struct can_priv *safe_candev_priv(struct net_device *dev)
-{
-	return NULL;
-}
-#endif
 
 int open_candev(struct net_device *dev);
 void close_candev(struct net_device *dev);
 void can_set_default_mtu(struct net_device *dev);
 int __must_check can_set_static_ctrlmode(struct net_device *dev,
diff --git a/net/can/raw.c b/net/can/raw.c
index be1ef7cf4204..f36a83d3447c 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -890,62 +890,24 @@ static void raw_put_canxl_vcid(struct raw_sock *ro, struct sk_buff *skb)
 		cxl->prio &= CANXL_PRIO_MASK;
 		cxl->prio |= ro->tx_vcid_shifted;
 	}
 }
 
-static inline bool raw_dev_cc_enabled(struct net_device *dev,
-				      struct can_priv *priv)
+static unsigned int raw_check_txframe(struct raw_sock *ro, struct sk_buff *skb, int mtu)
 {
-	/* The CANXL-only mode disables error-signalling on the CAN bus
-	 * which is needed to send CAN CC/FD frames
-	 */
-	if (priv)
-		return !can_dev_in_xl_only_mode(priv);
-
-	/* virtual CAN interfaces always support CAN CC */
-	return true;
-}
-
-static inline bool raw_dev_fd_enabled(struct net_device *dev,
-				      struct can_priv *priv)
-{
-	/* check FD ctrlmode on real CAN interfaces */
-	if (priv)
-		return (priv->ctrlmode & CAN_CTRLMODE_FD);
-
-	/* check MTU for virtual CAN FD interfaces */
-	return (READ_ONCE(dev->mtu) >= CANFD_MTU);
-}
-
-static inline bool raw_dev_xl_enabled(struct net_device *dev,
-				      struct can_priv *priv)
-{
-	/* check XL ctrlmode on real CAN interfaces */
-	if (priv)
-		return (priv->ctrlmode & CAN_CTRLMODE_XL);
-
-	/* check MTU for virtual CAN XL interfaces */
-	return can_is_canxl_dev_mtu(READ_ONCE(dev->mtu));
-}
-
-static unsigned int raw_check_txframe(struct raw_sock *ro, struct sk_buff *skb,
-				      struct net_device *dev)
-{
-	struct can_priv *priv = safe_candev_priv(dev);
-
-	/* Classical CAN */
-	if (can_is_can_skb(skb) && raw_dev_cc_enabled(dev, priv))
+	/* Classical CAN -> no checks for flags and device capabilities */
+	if (can_is_can_skb(skb))
 		return CAN_MTU;
 
-	/* CAN FD */
+	/* CAN FD -> needs to be enabled and a CAN FD or CAN XL device */
 	if (ro->fd_frames && can_is_canfd_skb(skb) &&
-	    raw_dev_fd_enabled(dev, priv))
+	    (mtu == CANFD_MTU || can_is_canxl_dev_mtu(mtu)))
 		return CANFD_MTU;
 
-	/* CAN XL */
+	/* CAN XL -> needs to be enabled and a CAN XL device */
 	if (ro->xl_frames && can_is_canxl_skb(skb) &&
-	    raw_dev_xl_enabled(dev, priv))
+	    can_is_canxl_dev_mtu(mtu))
 		return CANXL_MTU;
 
 	return 0;
 }
 
@@ -997,11 +959,11 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 		goto free_skb;
 
 	err = -EINVAL;
 
 	/* check for valid CAN (CC/FD/XL) frame content */
-	txmtu = raw_check_txframe(ro, skb, dev);
+	txmtu = raw_check_txframe(ro, skb, READ_ONCE(dev->mtu));
 	if (!txmtu)
 		goto free_skb;
 
 	/* only CANXL: clear/forward/set VCID value */
 	if (txmtu == CANXL_MTU)
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 2/3] can: propagate CAN device capabilities via ml_priv
  2026-01-09 14:41 [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames" Oliver Hartkopp
  2026-01-09 14:41 ` [PATCH 1/3] " Oliver Hartkopp
@ 2026-01-09 14:41 ` Oliver Hartkopp
  2026-01-09 14:41 ` [PATCH 3/3] can: raw: instantly reject disabled CAN frames Oliver Hartkopp
  2026-01-09 15:19 ` [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames" Marc Kleine-Budde
  3 siblings, 0 replies; 15+ messages in thread
From: Oliver Hartkopp @ 2026-01-09 14:41 UTC (permalink / raw)
  To: linux-can
  Cc: Oliver Hartkopp, Marc Kleine-Budde, Arnd Bergmann,
	Vincent Mailhol

Commit 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
caused a sequence of dependency and linker fixes.

Instead of accessing CAN device internal data structures which caused the
dependency problems this patch introduces capability information into the
CAN specific ml_priv data which is accessible from both sides.

With this change the CAN network layer can check the required features and
the decoupling of the driver layer and network layer is restored.

Fixes: 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
 drivers/net/can/dev/dev.c     | 27 +++++++++++++++++++++++++++
 drivers/net/can/dev/netlink.c |  1 +
 drivers/net/can/vcan.c        | 15 +++++++++++++++
 drivers/net/can/vxcan.c       | 15 +++++++++++++++
 include/linux/can/can-ml.h    | 24 ++++++++++++++++++++++++
 include/linux/can/dev.h       |  1 +
 6 files changed, 83 insertions(+)

diff --git a/drivers/net/can/dev/dev.c b/drivers/net/can/dev/dev.c
index 091f30e94c61..7ab9578f5b89 100644
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -373,10 +373,36 @@ void can_set_default_mtu(struct net_device *dev)
 		dev->min_mtu = CAN_MTU;
 		dev->max_mtu = CAN_MTU;
 	}
 }
 
+void can_set_cap_info(struct net_device *dev)
+{
+	struct can_priv *priv = netdev_priv(dev);
+	u32 can_cap;
+
+	if (can_dev_in_xl_only_mode(priv)) {
+		/* XL only mode => no CC/FD capability */
+		can_cap = CAN_CAP_XL;
+	} else {
+		/* mixed mode => CC + FD/XL capability */
+		can_cap = CAN_CAP_CC;
+
+		if (priv->ctrlmode & CAN_CTRLMODE_FD)
+			can_cap |= CAN_CAP_FD;
+
+		if (priv->ctrlmode & CAN_CTRLMODE_XL)
+			can_cap |= CAN_CAP_XL;
+	}
+
+	if (priv->ctrlmode & (CAN_CTRLMODE_LISTENONLY |
+			      CAN_CTRLMODE_RESTRICTED))
+		can_cap |= CAN_CAP_RO;
+
+	can_set_cap(dev, can_cap);
+}
+
 /* helper to define static CAN controller features at device creation time */
 int can_set_static_ctrlmode(struct net_device *dev, u32 static_mode)
 {
 	struct can_priv *priv = netdev_priv(dev);
 
@@ -388,10 +414,11 @@ int can_set_static_ctrlmode(struct net_device *dev, u32 static_mode)
 	}
 	priv->ctrlmode = static_mode;
 
 	/* override MTU which was set by default in can_setup()? */
 	can_set_default_mtu(dev);
+	can_set_cap_info(dev);
 
 	return 0;
 }
 EXPORT_SYMBOL_GPL(can_set_static_ctrlmode);
 
diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c
index d6b0e686fb11..0498198a4696 100644
--- a/drivers/net/can/dev/netlink.c
+++ b/drivers/net/can/dev/netlink.c
@@ -375,10 +375,11 @@ static int can_ctrlmode_changelink(struct net_device *dev,
 		memset(&priv->xl.tdc, 0, sizeof(priv->xl.tdc));
 		memset(&priv->xl.pwm, 0, sizeof(priv->xl.pwm));
 	}
 
 	can_set_default_mtu(dev);
+	can_set_cap_info(dev);
 
 	return 0;
 }
 
 static int can_tdc_changelink(struct data_bittiming_params *dbt_params,
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index fdc662aea279..76e6b7b5c6a1 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -128,10 +128,23 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
 		consume_skb(skb);
 	}
 	return NETDEV_TX_OK;
 }
 
+static void vcan_set_cap_info(struct net_device *dev)
+{
+	u32 can_cap = CAN_CAP_CC;
+
+	if (dev->mtu > CAN_MTU)
+		can_cap |= CAN_CAP_FD;
+
+	if (dev->mtu >= CANXL_MIN_MTU)
+		can_cap |= CAN_CAP_XL;
+
+	can_set_cap(dev, can_cap);
+}
+
 static int vcan_change_mtu(struct net_device *dev, int new_mtu)
 {
 	/* Do not allow changing the MTU while running */
 	if (dev->flags & IFF_UP)
 		return -EBUSY;
@@ -139,10 +152,11 @@ static int vcan_change_mtu(struct net_device *dev, int new_mtu)
 	if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU &&
 	    !can_is_canxl_dev_mtu(new_mtu))
 		return -EINVAL;
 
 	WRITE_ONCE(dev->mtu, new_mtu);
+	vcan_set_cap_info(dev);
 	return 0;
 }
 
 static const struct net_device_ops vcan_netdev_ops = {
 	.ndo_start_xmit = vcan_tx,
@@ -160,10 +174,11 @@ static void vcan_setup(struct net_device *dev)
 	dev->hard_header_len	= 0;
 	dev->addr_len		= 0;
 	dev->tx_queue_len	= 0;
 	dev->flags		= IFF_NOARP;
 	can_set_ml_priv(dev, netdev_priv(dev));
+	vcan_set_cap_info(dev);
 
 	/* set flags according to driver capabilities */
 	if (echo)
 		dev->flags |= IFF_ECHO;
 
diff --git a/drivers/net/can/vxcan.c b/drivers/net/can/vxcan.c
index b2c19f8c5f8e..f14c6f02b662 100644
--- a/drivers/net/can/vxcan.c
+++ b/drivers/net/can/vxcan.c
@@ -123,10 +123,23 @@ static int vxcan_get_iflink(const struct net_device *dev)
 	rcu_read_unlock();
 
 	return iflink;
 }
 
+static void vxcan_set_cap_info(struct net_device *dev)
+{
+	u32 can_cap = CAN_CAP_CC;
+
+	if (dev->mtu > CAN_MTU)
+		can_cap |= CAN_CAP_FD;
+
+	if (dev->mtu >= CANXL_MIN_MTU)
+		can_cap |= CAN_CAP_XL;
+
+	can_set_cap(dev, can_cap);
+}
+
 static int vxcan_change_mtu(struct net_device *dev, int new_mtu)
 {
 	/* Do not allow changing the MTU while running */
 	if (dev->flags & IFF_UP)
 		return -EBUSY;
@@ -134,10 +147,11 @@ static int vxcan_change_mtu(struct net_device *dev, int new_mtu)
 	if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU &&
 	    !can_is_canxl_dev_mtu(new_mtu))
 		return -EINVAL;
 
 	WRITE_ONCE(dev->mtu, new_mtu);
+	vxcan_set_cap_info(dev);
 	return 0;
 }
 
 static const struct net_device_ops vxcan_netdev_ops = {
 	.ndo_open	= vxcan_open,
@@ -165,10 +179,11 @@ static void vxcan_setup(struct net_device *dev)
 	dev->ethtool_ops	= &vxcan_ethtool_ops;
 	dev->needs_free_netdev	= true;
 
 	can_ml = netdev_priv(dev) + ALIGN(sizeof(struct vxcan_priv), NETDEV_ALIGN);
 	can_set_ml_priv(dev, can_ml);
+	vxcan_set_cap_info(dev);
 }
 
 /* forward declaration for rtnl_create_link() */
 static struct rtnl_link_ops vxcan_link_ops;
 
diff --git a/include/linux/can/can-ml.h b/include/linux/can/can-ml.h
index 8afa92d15a66..1e99fda2b380 100644
--- a/include/linux/can/can-ml.h
+++ b/include/linux/can/can-ml.h
@@ -44,10 +44,16 @@
 
 #include <linux/can.h>
 #include <linux/list.h>
 #include <linux/netdevice.h>
 
+/* exposed CAN device capabilities for network layer */
+#define CAN_CAP_CC BIT(0) /* CAN CC aka Classical CAN */
+#define CAN_CAP_FD BIT(1) /* CAN FD */
+#define CAN_CAP_XL BIT(2) /* CAN XL */
+#define CAN_CAP_RO BIT(3) /* read-only mode (LISTEN/RESTRICTED) */
+
 #define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS)
 #define CAN_EFF_RCV_HASH_BITS 10
 #define CAN_EFF_RCV_ARRAY_SZ (1 << CAN_EFF_RCV_HASH_BITS)
 
 enum { RX_ERR, RX_ALL, RX_FIL, RX_INV, RX_MAX };
@@ -62,10 +68,11 @@ struct can_dev_rcv_lists {
 struct can_ml_priv {
 	struct can_dev_rcv_lists dev_rcv_lists;
 #ifdef CAN_J1939
 	struct j1939_priv *j1939_priv;
 #endif
+	u32 can_cap;
 };
 
 static inline struct can_ml_priv *can_get_ml_priv(struct net_device *dev)
 {
 	return netdev_get_ml_priv(dev, ML_PRIV_CAN);
@@ -75,6 +82,23 @@ static inline void can_set_ml_priv(struct net_device *dev,
 				   struct can_ml_priv *ml_priv)
 {
 	netdev_set_ml_priv(dev, ml_priv, ML_PRIV_CAN);
 }
 
+static inline bool can_cap_enabled(struct net_device *dev, u32 cap)
+{
+	struct can_ml_priv *can_ml = can_get_ml_priv(dev);
+
+	if (!can_ml)
+		return false;
+
+	return (can_ml->can_cap & cap);
+}
+
+static inline void can_set_cap(struct net_device *dev, u32 cap)
+{
+	struct can_ml_priv *can_ml = can_get_ml_priv(dev);
+
+	can_ml->can_cap = cap;
+}
+
 #endif /* CAN_ML_H */
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index 52c8be5c160e..6d0710d6f571 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -114,10 +114,11 @@ void free_candev(struct net_device *dev);
 struct can_priv *safe_candev_priv(struct net_device *dev);
 
 int open_candev(struct net_device *dev);
 void close_candev(struct net_device *dev);
 void can_set_default_mtu(struct net_device *dev);
+void can_set_cap_info(struct net_device *dev);
 int __must_check can_set_static_ctrlmode(struct net_device *dev,
 					 u32 static_mode);
 int can_hwtstamp_get(struct net_device *netdev,
 		     struct kernel_hwtstamp_config *cfg);
 int can_hwtstamp_set(struct net_device *netdev,
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 3/3] can: raw: instantly reject disabled CAN frames
  2026-01-09 14:41 [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames" Oliver Hartkopp
  2026-01-09 14:41 ` [PATCH 1/3] " Oliver Hartkopp
  2026-01-09 14:41 ` [PATCH 2/3] can: propagate CAN device capabilities via ml_priv Oliver Hartkopp
@ 2026-01-09 14:41 ` Oliver Hartkopp
  2026-01-09 15:19 ` [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames" Marc Kleine-Budde
  3 siblings, 0 replies; 15+ messages in thread
From: Oliver Hartkopp @ 2026-01-09 14:41 UTC (permalink / raw)
  To: linux-can
  Cc: Oliver Hartkopp, Marc Kleine-Budde, Arnd Bergmann,
	Vincent Mailhol

For real CAN interfaces the CAN_CTRLMODE_FD and CAN_CTRLMODE_XL control
modes indicate whether an interface can handle those CAN FD/XL frames.

In the case a CAN XL interface is configured in CANXL-only mode with
disabled error-signalling neither CAN CC nor CAN FD frames can be sent.

The checks are now performed on CAN_RAW sockets to give an instant feedback
to the user when writing unsupported CAN frames to the interface or when
the CAN interface is in read-only mode.

Fixes: 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Vincent Mailhol <mailhol@kernel.org>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
---
 net/can/raw.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/net/can/raw.c b/net/can/raw.c
index f36a83d3447c..d66036da6753 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -47,12 +47,12 @@
 #include <linux/netdevice.h>
 #include <linux/socket.h>
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
 #include <linux/can.h>
+#include <linux/can/can-ml.h>
 #include <linux/can/core.h>
-#include <linux/can/dev.h> /* for can_is_canxl_dev_mtu() */
 #include <linux/can/skb.h>
 #include <linux/can/raw.h>
 #include <net/sock.h>
 #include <net/net_namespace.h>
 
@@ -890,24 +890,25 @@ static void raw_put_canxl_vcid(struct raw_sock *ro, struct sk_buff *skb)
 		cxl->prio &= CANXL_PRIO_MASK;
 		cxl->prio |= ro->tx_vcid_shifted;
 	}
 }
 
-static unsigned int raw_check_txframe(struct raw_sock *ro, struct sk_buff *skb, int mtu)
+static unsigned int raw_check_txframe(struct raw_sock *ro, struct sk_buff *skb,
+				      struct net_device *dev)
 {
-	/* Classical CAN -> no checks for flags and device capabilities */
-	if (can_is_can_skb(skb))
+	/* Classical CAN */
+	if (can_is_can_skb(skb) && can_cap_enabled(dev, CAN_CAP_CC))
 		return CAN_MTU;
 
-	/* CAN FD -> needs to be enabled and a CAN FD or CAN XL device */
+	/* CAN FD */
 	if (ro->fd_frames && can_is_canfd_skb(skb) &&
-	    (mtu == CANFD_MTU || can_is_canxl_dev_mtu(mtu)))
+	    can_cap_enabled(dev, CAN_CAP_FD))
 		return CANFD_MTU;
 
-	/* CAN XL -> needs to be enabled and a CAN XL device */
+	/* CAN XL */
 	if (ro->xl_frames && can_is_canxl_skb(skb) &&
-	    can_is_canxl_dev_mtu(mtu))
+	    can_cap_enabled(dev, CAN_CAP_XL))
 		return CANXL_MTU;
 
 	return 0;
 }
 
@@ -942,10 +943,14 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 
 	dev = dev_get_by_index(sock_net(sk), ifindex);
 	if (!dev)
 		return -ENXIO;
 
+	/* no sending on a CAN device in read-only mode */
+	if (can_cap_enabled(dev, CAN_CAP_RO))
+		return -EACCES;
+
 	skb = sock_alloc_send_skb(sk, size + sizeof(struct can_skb_priv),
 				  msg->msg_flags & MSG_DONTWAIT, &err);
 	if (!skb)
 		goto put_dev;
 
@@ -959,11 +964,11 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 		goto free_skb;
 
 	err = -EINVAL;
 
 	/* check for valid CAN (CC/FD/XL) frame content */
-	txmtu = raw_check_txframe(ro, skb, READ_ONCE(dev->mtu));
+	txmtu = raw_check_txframe(ro, skb, dev);
 	if (!txmtu)
 		goto free_skb;
 
 	/* only CANXL: clear/forward/set VCID value */
 	if (txmtu == CANXL_MTU)
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames"
  2026-01-09 14:41 [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames" Oliver Hartkopp
                   ` (2 preceding siblings ...)
  2026-01-09 14:41 ` [PATCH 3/3] can: raw: instantly reject disabled CAN frames Oliver Hartkopp
@ 2026-01-09 15:19 ` Marc Kleine-Budde
  2026-01-09 15:25   ` Marc Kleine-Budde
  2026-01-09 15:42   ` Oliver Hartkopp
  3 siblings, 2 replies; 15+ messages in thread
From: Marc Kleine-Budde @ 2026-01-09 15:19 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: linux-can

[-- Attachment #1: Type: text/plain, Size: 1392 bytes --]

On 09.01.2026 15:41:32, Oliver Hartkopp wrote:
> This reverts commit 1a620a723853a0f49703c317d52dc6b9602cbaa8
>
> and its follow-up fixes for the introduced dependency issues.
>
> commit 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
> commit cb2dc6d2869a ("can: Kconfig: select CAN driver infrastructure by default")
> commit 6abd4577bccc ("can: fix build dependency")
> commit 5a5aff6338c0 ("can: fix build dependency")
>
> The reverted patch was accessing CAN device internal data structures
> from the network layer because it needs to know about the CAN protocol
> capabilities of the CAN devices.
>
> This data access caused build problems between the CAN network and the
> CAN driver layer which introduced unwanted Kconfig dependencies and fixes.
>
> The patches 2 & 3 implement a better approach which makes use of the
> CAN specific ml_priv data which is accessible from both sides.
>
> With this change the CAN network layer can check the required features
> and the decoupling of the driver layer and network layer is restored.

Applied to linux-can.

Thanks,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames"
  2026-01-09 15:19 ` [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames" Marc Kleine-Budde
@ 2026-01-09 15:25   ` Marc Kleine-Budde
  2026-01-09 15:42   ` Oliver Hartkopp
  1 sibling, 0 replies; 15+ messages in thread
From: Marc Kleine-Budde @ 2026-01-09 15:25 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: linux-can

[-- Attachment #1: Type: text/plain, Size: 676 bytes --]

I've given the series a more descriptive name: "can: raw: better
approach to instantly reject unsupported CAN frames"...

On 09.01.2026 16:19:48, Marc Kleine-Budde wrote:
> On 09.01.2026 15:41:32, Oliver Hartkopp wrote:
> > This reverts commit 1a620a723853a0f49703c317d52dc6b9602cbaa8

... and replaced this by: "1a620a723853 ("can: raw: instantly reject
unsupported CAN frames")"

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames"
  2026-01-09 15:19 ` [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames" Marc Kleine-Budde
  2026-01-09 15:25   ` Marc Kleine-Budde
@ 2026-01-09 15:42   ` Oliver Hartkopp
  2026-01-09 15:48     ` Marc Kleine-Budde
  1 sibling, 1 reply; 15+ messages in thread
From: Oliver Hartkopp @ 2026-01-09 15:42 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: linux-can



On 09.01.26 16:19, Marc Kleine-Budde wrote:
> On 09.01.2026 15:41:32, Oliver Hartkopp wrote:
>> This reverts commit 1a620a723853a0f49703c317d52dc6b9602cbaa8
>>
>> and its follow-up fixes for the introduced dependency issues.
>>
>> commit 1a620a723853 ("can: raw: instantly reject unsupported CAN frames")
>> commit cb2dc6d2869a ("can: Kconfig: select CAN driver infrastructure by default")
>> commit 6abd4577bccc ("can: fix build dependency")
>> commit 5a5aff6338c0 ("can: fix build dependency")
>>
>> The reverted patch was accessing CAN device internal data structures
>> from the network layer because it needs to know about the CAN protocol
>> capabilities of the CAN devices.
>>
>> This data access caused build problems between the CAN network and the
>> CAN driver layer which introduced unwanted Kconfig dependencies and fixes.
>>
>> The patches 2 & 3 implement a better approach which makes use of the
>> CAN specific ml_priv data which is accessible from both sides.
>>
>> With this change the CAN network layer can check the required features
>> and the decoupling of the driver layer and network layer is restored.
> 
> Applied to linux-can.

Thanks!

Unfortunately we had some snow problems here so I missed your PR.
¯\_(ツ)_/¯

Have a nice weekend!
Oliver


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames"
  2026-01-09 15:42   ` Oliver Hartkopp
@ 2026-01-09 15:48     ` Marc Kleine-Budde
  0 siblings, 0 replies; 15+ messages in thread
From: Marc Kleine-Budde @ 2026-01-09 15:48 UTC (permalink / raw)
  To: Oliver Hartkopp; +Cc: linux-can

[-- Attachment #1: Type: text/plain, Size: 520 bytes --]

On 09.01.2026 16:42:57, Oliver Hartkopp wrote:
> > Applied to linux-can.
>
> Thanks!
>
> Unfortunately we had some snow problems here so I missed your PR.
> ¯\_(ツ)_/¯

I've some patches to write, so there will be another one soon.

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde          |
Embedded Linux                   | https://www.pengutronix.de |
Vertretung Nürnberg              | Phone: +49-5121-206917-129 |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-9   |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-01-09 15:48 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-09 14:41 [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames" Oliver Hartkopp
2026-01-09 14:41 ` [PATCH 1/3] " Oliver Hartkopp
2026-01-09 14:41 ` [PATCH 2/3] can: propagate CAN device capabilities via ml_priv Oliver Hartkopp
2026-01-09 14:41 ` [PATCH 3/3] can: raw: instantly reject disabled CAN frames Oliver Hartkopp
2026-01-09 15:19 ` [PATCH 0/3] Revert "can: raw: instantly reject unsupported CAN frames" Marc Kleine-Budde
2026-01-09 15:25   ` Marc Kleine-Budde
2026-01-09 15:42   ` Oliver Hartkopp
2026-01-09 15:48     ` Marc Kleine-Budde
  -- strict thread matches above, loose matches on Subject: below --
2026-01-01 19:13 [PATCH 1/3] " Oliver Hartkopp
2026-01-01 19:13 ` [PATCH 2/3] can: propagate CAN device capabilities via ml_priv Oliver Hartkopp
2026-01-06 15:40   ` Oliver Hartkopp
2026-01-09  9:23     ` Marc Kleine-Budde
2026-01-09  9:43       ` Oliver Hartkopp
2026-01-09 10:37   ` Marc Kleine-Budde
2026-01-09 11:31     ` Oliver Hartkopp
2026-01-09 11:53       ` Marc Kleine-Budde

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox