Re: [PATCH] net: add virtio network driver

2021-10-02 Thread Sascha Hauer
On Mon, Sep 13, 2021 at 10:30:47AM +0200, Ahmad Fatoum wrote:
> This gives virtio-enabled boards an easy route to network connectivity:
> 
>   qemu-system-aarch64 -M virt  -serial mon:stdio -trace file=/dev/null \
>   -kernel images/barebox-dt-2nd.img -cpu cortex-a57 -nographic \
>   -device virtio-net-device,netdev=network0 -netdev 
> tap,id=network0,ifname=tap0
> 
> The tap0 interface created by QEMU can then be bridged/listened on.
> 
> Signed-off-by: Ahmad Fatoum 
> ---
>  Documentation/user/virtio.rst   |   2 +-
>  drivers/net/Kconfig |   7 +
>  drivers/net/Makefile|   1 +
>  drivers/net/virtio.c| 236 +
>  include/linux/virtio_config.h   |   7 +-
>  include/uapi/linux/virtio_net.h | 358 
>  6 files changed, 608 insertions(+), 3 deletions(-)
>  create mode 100644 drivers/net/virtio.c
>  create mode 100644 include/uapi/linux/virtio_net.h

Applied, thanks

Sascha

-- 
Pengutronix e.K.   | |
Steuerwalder Str. 21   | http://www.pengutronix.de/  |
31137 Hildesheim, Germany  | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |

___
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox


[PATCH] net: add virtio network driver

2021-09-13 Thread Ahmad Fatoum
This gives virtio-enabled boards an easy route to network connectivity:

qemu-system-aarch64 -M virt  -serial mon:stdio -trace file=/dev/null \
-kernel images/barebox-dt-2nd.img -cpu cortex-a57 -nographic \
-device virtio-net-device,netdev=network0 -netdev 
tap,id=network0,ifname=tap0

The tap0 interface created by QEMU can then be bridged/listened on.

Signed-off-by: Ahmad Fatoum 
---
 Documentation/user/virtio.rst   |   2 +-
 drivers/net/Kconfig |   7 +
 drivers/net/Makefile|   1 +
 drivers/net/virtio.c| 236 +
 include/linux/virtio_config.h   |   7 +-
 include/uapi/linux/virtio_net.h | 358 
 6 files changed, 608 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/virtio.c
 create mode 100644 include/uapi/linux/virtio_net.h

diff --git a/Documentation/user/virtio.rst b/Documentation/user/virtio.rst
index dde47d5f82b1..d944fa4821b1 100644
--- a/Documentation/user/virtio.rst
+++ b/Documentation/user/virtio.rst
@@ -35,7 +35,7 @@ queues configuration and buffer transfers are nearly 
identical. Both MMIO
 and non-legacy PCI are supported in barebox.
 
 The VirtIO spec defines a lots of VirtIO device types, however at present only
-block, console, input and RNG devices are supported.
+block, network, console, input and RNG devices are supported.
 
 Build Instructions
 --
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 397164f3f175..4947296f278a 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -258,6 +258,13 @@ config DRIVER_NET_EFI_SNP
bool "EFI SNP ethernet driver"
depends on EFI_BOOTUP
 
+config DRIVER_NET_VIRTIO
+   bool "virtio net driver"
+   depends on VIRTIO
+   help
+ This is the virtual net driver for virtio. It can be used with
+ QEMU based targets.
+
 config DRIVER_NET_AG71XX
bool "Atheros AG71xx ethernet driver"
depends on MACH_MIPS_ATH79
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index b1aa9571fc72..1921d0d9f91c 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -36,4 +36,5 @@ obj-$(CONFIG_DRIVER_NET_SMC9) += smc9.o
 obj-$(CONFIG_DRIVER_NET_TAP)   += tap.o
 obj-$(CONFIG_DRIVER_NET_TSE)   += altera_tse.o
 obj-$(CONFIG_DRIVER_NET_EFI_SNP)   += efi-snp.o
+obj-$(CONFIG_DRIVER_NET_VIRTIO)+= virtio.o
 obj-$(CONFIG_DRIVER_NET_AG71XX)+= ag71xx.o
diff --git a/drivers/net/virtio.c b/drivers/net/virtio.c
new file mode 100644
index ..275588e15c50
--- /dev/null
+++ b/drivers/net/virtio.c
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2018, Tuomas Tynkkynen 
+ * Copyright (C) 2018, Bin Meng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/* Amount of buffers to keep in the RX virtqueue */
+#define VIRTIO_NET_NUM_RX_BUFS 32
+
+/*
+ * This value comes from the VirtIO spec: 1500 for maximum packet size,
+ * 14 for the Ethernet header, 12 for virtio_net_hdr. In total 1526 bytes.
+ */
+#define VIRTIO_NET_RX_BUF_SIZE 1526
+
+struct virtio_net_priv {
+   union {
+   struct virtqueue *vqs[2];
+   struct {
+   struct virtqueue *rx_vq;
+   struct virtqueue *tx_vq;
+   };
+   };
+
+   char rx_buff[VIRTIO_NET_NUM_RX_BUFS][VIRTIO_NET_RX_BUF_SIZE];
+   bool rx_running;
+   int net_hdr_len;
+   struct eth_device edev;
+   struct virtio_device *vdev;
+};
+
+static inline struct virtio_net_priv *to_priv(struct eth_device *edev)
+{
+   return container_of(edev, struct virtio_net_priv, edev);
+}
+
+static int virtio_net_start(struct eth_device *edev)
+{
+   struct virtio_net_priv *priv = to_priv(edev);
+   struct virtio_sg sg;
+   struct virtio_sg *sgs[] = {  };
+   int i;
+
+   if (!priv->rx_running) {
+   /* receive buffer length is always 1526 */
+   sg.length = VIRTIO_NET_RX_BUF_SIZE;
+
+   /* setup the receive buffer address */
+   for (i = 0; i < VIRTIO_NET_NUM_RX_BUFS; i++) {
+   sg.addr = priv->rx_buff[i];
+   virtqueue_add(priv->rx_vq, sgs, 0, 1);
+   }
+
+   virtqueue_kick(priv->rx_vq);
+
+   /* setup the receive queue only once */
+   priv->rx_running = true;
+   }
+
+   return 0;
+}
+
+static int virtio_net_send(struct eth_device *edev, void *packet, int length)
+{
+   struct virtio_net_priv *priv = to_priv(edev);
+   struct virtio_net_hdr_v1 hdr_v1;
+   struct virtio_net_hdr hdr;
+   struct virtio_sg hdr_sg;
+   struct virtio_sg data_sg = { packet, length };
+   struct virtio_sg *sgs[] = { _sg, _sg };
+   int ret;
+
+   if (priv->net_hdr_len == sizeof(struct virtio_net_hdr))
+   hdr_sg.addr = 
+