Skip to contentSkip to conversation

can: virtio: Add virtio CAN driver

PATCH Superseded Matias Ezequiel Vara Larsen 2 participants 3 messages Jan 20 – Jan 26

Subsystems (3)

v8 of 15 Superseded Latest is v15 →

lore
Share & tools
lore

Matias Ezequiel Vara Larsen

author maintainer
#0 lore raw

PATCH v8 1/1 can: virtio: Add virtio CAN driver

Add virtio CAN driver based on Virtio 1.4 specification (see
https://github.com/oasis-tcs/virtio-spec/tree/virtio-1.4). The driver implements a complete CAN bus interface over Virtio transport, supporting both CAN Classic and CAN-FD Ids. In term of frames, it supports classic and CAN FD. RTR frames are only supported with classic CAN.

Usage:
- "ip link set up can0" - start controller
- "ip link set down can0" - stop controller
- "candump can0" - receive frames
- "cansend can0 123#DEADBEEF" - send frames

---
V8:
* Address nits

V7:
* Address nits
* Remove unnecessary comments
* Remove io_callbacks[]
* Use guard() syntax
* Remove kicking for each inbuf
* replace sdu_len with rpkt_len
* Use devm_kzalloc()
* Use scoped_guard() to protect virtqueue_add_sgs() and virtqueue_kicks() for tx queue
* Tested with vhost-device-can
(see https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-can) and Qemu (942b0d3) with [1]. A reviewer observed that the device stops to work after flooding from host. This issue is still present.

[1]
https://lore.kernel.org/qemu-devel/[email protected]/

V6:
* Address nits
* Check for error during register_virtio_can()
* Remove virtio_device_ready()
* Allocate virtio_can_rx rpkt[] at probe
* Define virtio_can_control struct
* Return VIRTIO_CAN_RESULT_NOT_OK after unlocking
* Define sdu[] as a flex array for both tx and rx. For rx, use VIRTIO_CAN_F_CAN_FD to figure out the max len for sdu
* Fix statistics in virtio_can_read_tx_queue() and
how we indicate error to the user when getting VIRTIO_CAN_RESULT_NOT_OK
* Fix syntax of virtio_find_vqs()
* Drop tx_list
* Fix values of VIRTIO_CAN_F_LATE_TX_ACK and VIRTIO_CAN_F_RTR_FRAMES
* Tested with vhost-device-can
(see
https://github.com/rust-vmm/vhost-device/tree/main/vhost-device-can)
and qemu (see
https://github.com/virtualopensystems/qemu/tree/vhu-can-rfc)

V5:
* Re-base on top of linux-next (next-20240103)
* Tested with https://github.com/OpenSynergy/qemu/tree/virtio-can-spec-rfc-v3

RFC V4:
* Apply reverse Christmas tree style
* Add member *classic_dlc to RX and TX CAN frames
* Fix race causing a NETDEV_TX_BUSY return
* Fix TX queue going stuck on -ENOMEM
* Update stats.tx_dropped on kzalloc() failure
* Replace "(err != 0)" with "(unlikely(err))"
* Use "ARRAY_SIZE(sgs)"
* Refactor SGs in virtio_can_send_ctrl_msg()
* Tested with https://github.com/OpenSynergy/qemu/tree/virtio-can-spec-rfc-v3

RFC V3:
* Incorporate patch "[PATCH] can: virtio-can: cleanups" from
https://lore.kernel.org/all/[email protected]/
* Add missing can_free_echo_skb()
* Replace home-brewed ID allocator with the standard one from kernel
* Simplify flow control
* Tested with https://github.com/OpenSynergy/qemu/tree/virtio-can-spec-rfc-v3

RFC V2:
* Remove the event indication queue and use the config space instead, to indicate a bus off condition
* Rework RX and TX messages having a length field and some more fields for CAN EXT

---
 MAINTAINERS                     |   8 +
 drivers/net/can/Kconfig         |  12 +
 drivers/net/can/Makefile        |   1 +
 drivers/net/can/virtio_can.c    | 951 ++++++++++++++++++++++++++++++++
 include/uapi/linux/virtio_can.h |  78 +++
 5 files changed, 1050 insertions(+)
 create mode 100644 drivers/net/can/virtio_can.c
 create mode 100644 include/uapi/linux/virtio_can.h
MAINTAINERS +8 -0
index 80cd3498c293..2f71bc4a4b1a 100644
@@ -27068,6 +27068,14 @@ F:	drivers/scsi/virtio_scsi.c
 F:	include/uapi/linux/virtio_blk.h
 F:	include/uapi/linux/virtio_scsi.h
 
+VIRTIO CAN DRIVER
+M:	"Harald Mommer" <[email protected]>
+L:	[email protected]
+L:	[email protected]
+S:	Maintained
+F:	drivers/net/can/virtio_can.c
+F:	include/uapi/linux/virtio_can.h
+
 VIRTIO CONSOLE DRIVER
 M:	Amit Shah <[email protected]>
 L:	[email protected]
drivers/net/can/Kconfig +12 -0
index d43d56694667..7b5806f11853 100644
@@ -217,6 +217,18 @@ config CAN_XILINXCAN
 	  Xilinx CAN driver. This driver supports both soft AXI CAN IP and
 	  Zynq CANPS IP.
 
+config CAN_VIRTIO_CAN
+	depends on VIRTIO
+	tristate "Virtio CAN device support"
+	default n
+	help
+	  Say Y here if you want to support for Virtio CAN.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called virtio-can.
+
+	  If unsure, say N.
+
 source "drivers/net/can/c_can/Kconfig"
 source "drivers/net/can/cc770/Kconfig"
 source "drivers/net/can/ctucanfd/Kconfig"
drivers/net/can/Makefile +1 -0
index 56138d8ddfd2..2ddea733ed5d 100644
@@ -32,6 +32,7 @@ obj-$(CONFIG_CAN_PEAK_PCIEFD)	+= peak_canfd/
 obj-$(CONFIG_CAN_SJA1000)	+= sja1000/
 obj-$(CONFIG_CAN_SUN4I)		+= sun4i_can.o
 obj-$(CONFIG_CAN_TI_HECC)	+= ti_hecc.o
+obj-$(CONFIG_CAN_VIRTIO_CAN)	+= virtio_can.o
 obj-$(CONFIG_CAN_XILINXCAN)	+= xilinx_can.o
 
 subdir-ccflags-$(CONFIG_CAN_DEBUG_DEVICES) += -DDEBUG
drivers/net/can/virtio_can.c new file +951 -0

951 lines not on this page · raw message

include/uapi/linux/virtio_can.h new file +78 -0

78 lines not on this page · raw message

base-commit: 0d97f2067c166eb495771fede9f7b73999c67f66

Signature · 1 line
2.42.0
Reviewed-by Tested-by on v8 1/1
#1 lore raw

Hi Matias,

If an additional version is foreseen, consider dropping some more note-like comments, as in future they might become dangling.

E.g.:

On Tue, Jan 20, 2026 at 07:05:38PM +0100, Matias Ezequiel Vara Larsen wrote:

[...]

Quoted 7 lines
drivers/net/can/virtio_can.c new file +7 -0
+
+/* Poll TX used queue for sent CAN messages
+ * See https://wiki.linuxfoundation.org/networking/napi function
+ * int (*poll)(struct napi_struct *napi, int budget);
+ */
+static int virtio_can_tx_poll(struct napi_struct *napi, int quota)
+{

[...]

Quoted 3 lines
drivers/net/can/virtio_can.c new file +3 -0
+/* See m_can_poll() / m_can_handle_state_errors() m_can_handle_state_change() */
+static int virtio_can_handle_busoff(struct net_device *dev)
+{

[...]

Quoted 9 lines
drivers/net/can/virtio_can.c new file +9 -0
+/* Poll RX used queue for received CAN messages
+ * See https://wiki.linuxfoundation.org/networking/napi function
+ * int (*poll)(struct napi_struct *napi, int budget);
+ * Important: "The networking subsystem promises that poll() will not be
+ * invoked simultaneously (for the same napi_struct) on multiple processors"
+ */
+static int virtio_can_rx_poll(struct napi_struct *napi, int quota)
+{
+

[...]

Quoted 5 lines
drivers/net/can/virtio_can.c new file +5 -0
+/* Compare with m_can.c/m_can_suspend(), virtio_net.c/virtnet_freeze() and
+ * virtio_card.c/virtsnd_freeze()
+ */
+static int __maybe_unused virtio_can_freeze(struct virtio_device *vdev)
+{

[...]

drivers/net/can/virtio_can.c line 894

Quoted 6 lines
drivers/net/can/virtio_can.c new file +6 -0
+
+/* Compare with m_can.c/m_can_resume(), virtio_net.c/virtnet_restore() and
+ * virtio_card.c/virtsnd_restore()
+ */
+static int __maybe_unused virtio_can_restore(struct virtio_device *vdev)
+{

With this (maybe negligible) note considered:

Thank you!

Regards,
Francesco

author maintainer
#2 lore raw
Quoted 5 lines · Francesco Valla

Hi Matias,

If an additional version is foreseen, consider dropping some more note-like comments, as in future they might become dangling.

Yes! I am planing to remove some comments and send v9. I was not completely sure which ones. Also, I was thinking to set myself as a maintainer in case Harald is busy.

Quoted 51 lines

E.g.:

On Tue, Jan 20, 2026 at 07:05:38PM +0100, Matias Ezequiel Vara Larsen wrote:

[...]

Quoted 7 lines
drivers/net/can/virtio_can.c new file +7 -0
+
+/* Poll TX used queue for sent CAN messages
+ * See https://wiki.linuxfoundation.org/networking/napi function
+ * int (*poll)(struct napi_struct *napi, int budget);
+ */
+static int virtio_can_tx_poll(struct napi_struct *napi, int quota)
+{

[...]

Quoted 3 lines
drivers/net/can/virtio_can.c new file +3 -0
+/* See m_can_poll() / m_can_handle_state_errors() m_can_handle_state_change() */
+static int virtio_can_handle_busoff(struct net_device *dev)
+{

[...]

Quoted 9 lines
drivers/net/can/virtio_can.c new file +9 -0
+/* Poll RX used queue for received CAN messages
+ * See https://wiki.linuxfoundation.org/networking/napi function
+ * int (*poll)(struct napi_struct *napi, int budget);
+ * Important: "The networking subsystem promises that poll() will not be
+ * invoked simultaneously (for the same napi_struct) on multiple processors"
+ */
+static int virtio_can_rx_poll(struct napi_struct *napi, int quota)
+{
+

[...]

Quoted 5 lines
drivers/net/can/virtio_can.c new file +5 -0
+/* Compare with m_can.c/m_can_suspend(), virtio_net.c/virtnet_freeze() and
+ * virtio_card.c/virtsnd_freeze()
+ */
+static int __maybe_unused virtio_can_freeze(struct virtio_device *vdev)
+{

[...]

drivers/net/can/virtio_can.c line 894

Quoted 6 lines
drivers/net/can/virtio_can.c new file +6 -0
+
+/* Compare with m_can.c/m_can_resume(), virtio_net.c/virtnet_restore() and
+ * virtio_card.c/virtsnd_restore()
+ */
+static int __maybe_unused virtio_can_restore(struct virtio_device *vdev)
+{

With this (maybe negligible) note considered:

Quoted 3 lines

Thanks Francesco!

Matias