[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Minios-devel] [UNIKRAFT PATCH v2 1/7] plat/drivers: Introduce the virtio-net device



Reviewed-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>

On 19.10.18 15:39, Sharan Santhanam wrote:
This patch introduces the virtio net driver initialization, the API
functions callback to interact with the libuknet.

Signed-off-by: Sharan Santhanam <sharan.santhanam@xxxxxxxxx>
Signed-off-by: Razvan Cojocaru <razvan.cojocaru93@xxxxxxxxx>
---
  plat/drivers/include/virtio/virtio_net.h | 258 +++++++++++++++++++
  plat/drivers/virtio/virtio_net.c         | 417 +++++++++++++++++++++++++++++++
  plat/kvm/Config.uk                       |   8 +
  plat/kvm/Makefile.uk                     |   2 +
  4 files changed, 685 insertions(+)
  create mode 100644 plat/drivers/include/virtio/virtio_net.h
  create mode 100644 plat/drivers/virtio/virtio_net.c

diff --git a/plat/drivers/include/virtio/virtio_net.h 
b/plat/drivers/include/virtio/virtio_net.h
new file mode 100644
index 0000000..f33fce4
--- /dev/null
+++ b/plat/drivers/include/virtio/virtio_net.h
@@ -0,0 +1,258 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/* This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS 
IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
+/**
+ * Taken and modified from Linux kernel
+ * include/uapi/linux/virtio_net.h
+ *
+ * commit-id: faa9b39f0e9d
+ */
+#ifndef __PLAT_DRV_VIRTIO_NET_H
+#define __PLAT_DRV_VIRTIO_NET_H
+#include <uk/config.h>
+#include <uk/arch/types.h>
+
+#ifdef CONFIG_LIBUKNETDEV
+#include <uk/netdev_core.h>
+#endif /* CONFIG_LIBUKNETDEV */
+
+#include <virtio/virtio_ids.h>
+#include <virtio/virtio_config.h>
+#include <virtio/virtio_types.h>
+
+/* The feature bitmap for virtio net */
+#define VIRTIO_NET_F_CSUM      0       /* Host handles pkts w/ partial csum */
+#define VIRTIO_NET_F_GUEST_CSUM        1       /* Guest handles pkts w/ 
partial csum */
+#define VIRTIO_NET_F_CTRL_GUEST_OFFLOADS 2 /* Dynamic offload configuration. */
+#define VIRTIO_NET_F_MTU       3       /* Initial MTU advice */
+#define VIRTIO_NET_F_MAC       5       /* Host has given MAC address. */
+#define VIRTIO_NET_F_GUEST_TSO4        7       /* Guest can handle TSOv4 in. */
+#define VIRTIO_NET_F_GUEST_TSO6        8       /* Guest can handle TSOv6 in. */
+#define VIRTIO_NET_F_GUEST_ECN 9       /* Guest can handle TSO[6] w/ ECN in. */
+#define VIRTIO_NET_F_GUEST_UFO 10      /* Guest can handle UFO in. */
+#define VIRTIO_NET_F_HOST_TSO4 11      /* Host can handle TSOv4 in. */
+#define VIRTIO_NET_F_HOST_TSO6 12      /* Host can handle TSOv6 in. */
+#define VIRTIO_NET_F_HOST_ECN  13      /* Host can handle TSO[6] w/ ECN in. */
+#define VIRTIO_NET_F_HOST_UFO  14      /* Host can handle UFO in. */
+#define VIRTIO_NET_F_MRG_RXBUF 15      /* Host can merge receive buffers. */
+#define VIRTIO_NET_F_STATUS    16      /* virtio_net_config.status available */
+#define VIRTIO_NET_F_CTRL_VQ   17      /* Control channel available */
+#define VIRTIO_NET_F_CTRL_RX   18      /* Control channel RX mode support */
+#define VIRTIO_NET_F_CTRL_VLAN 19      /* Control channel VLAN filtering */
+#define VIRTIO_NET_F_CTRL_RX_EXTRA 20  /* Extra RX mode control support */
+#define VIRTIO_NET_F_GUEST_ANNOUNCE 21 /* Guest can announce device on the
+                                        * network
+                                        */
+#define VIRTIO_NET_F_MQ        22              /* Device supports Receive Flow
+                                        * Steering
+                                        */
+#define VIRTIO_NET_F_CTRL_MAC_ADDR 23  /* Set MAC address */
+
+#define VIRTIO_NET_F_SPEED_DUPLEX 63   /* Device set linkspeed and duplex */
+
+#ifndef VIRTIO_NET_NO_LEGACY
+#define VIRTIO_NET_F_GSO       6       /* Host handles pkts w/ any GSO type */
+#endif /* VIRTIO_NET_NO_LEGACY */
+
+#define VIRTIO_NET_S_LINK_UP   1       /* Link is up */
+#define VIRTIO_NET_S_ANNOUNCE  2       /* Announcement is needed */
+
+struct virtio_net_config {
+       /* The config defining mac address (if VIRTIO_NET_F_MAC) */
+       __u8 mac[UK_NETDEV_HWADDR_LEN];
+       /* See VIRTIO_NET_F_STATUS and VIRTIO_NET_S_* above */
+       __u16 status;
+       /* Maximum number of each of transmit and receive queues;
+        * see VIRTIO_NET_F_MQ and VIRTIO_NET_CTRL_MQ.
+        * Legal values are between 1 and 0x8000
+        */
+       __u16 max_virtqueue_pairs;
+       /* Default maximum transmit unit advice */
+       __u16 mtu;
+       /*
+        * speed, in units of 1Mb. All values 0 to INT_MAX are legal.
+        * Any other value stands for unknown.
+        */
+       __u32 speed;
+       /*
+        * 0x00 - half duplex
+        * 0x01 - full duplex
+        * Any other value stands for unknown.
+        */
+       __u8 duplex;
+} __packed;
+
+/* This header comes first in the scatter-gather list.
+ * For legacy virtio, if VIRTIO_F_ANY_LAYOUT is not negotiated, it must
+ * be the first element of the scatter-gather list.  If you don't
+ * specify GSO or CSUM features, you can simply ignore the header.
+ */
+struct virtio_net_hdr {
+#define VIRTIO_NET_HDR_F_NEEDS_CSUM 1   /* Use csum_start, csum_offset */
+#define VIRTIO_NET_HDR_F_DATA_VALID 2   /* Csum is valid */
+       /* See VIRTIO_NET_HDR_F_* */
+       __u8 flags;
+#define VIRTIO_NET_HDR_GSO_NONE     0   /* Not a GSO frame */
+#define VIRTIO_NET_HDR_GSO_TCPV4    1   /* GSO frame, IPv4 TCP (TSO) */
+#define VIRTIO_NET_HDR_GSO_UDP      3   /* GSO frame, IPv4 UDP (UFO) */
+#define VIRTIO_NET_HDR_GSO_TCPV6    4   /* GSO frame, IPv6 TCP */
+#define VIRTIO_NET_HDR_GSO_ECN      0x80    /* TCP has ECN set */
+       /* See VIRTIO_NET_HDR_GSO_* */
+       __u8 gso_type;
+       __virtio_le16 hdr_len;  /* Ethernet + IP + tcp/udp hdrs */
+       __virtio_le16 gso_size; /* Bytes to append to hdr_len per frame */
+       __virtio_le16 csum_start; /* Position to start checksumming from */
+       __virtio_le16 csum_offset; /* Offset after that to place checksum */
+};
+
+/* This is the version of the header to use when the MRG_RXBUF
+ * feature has been negotiated.
+ */
+struct virtio_net_hdr_mrg_rxbuf {
+       struct virtio_net_hdr hdr;
+       __virtio_le16 num_buffers;      /* Number of merged rx buffers */
+};
+
+/*
+ * Control virtqueue data structures
+ *
+ * The control virtqueue expects a header in the first sg entry
+ * and an ack/status response in the last entry.  Data for the
+ * command goes in between.
+ */
+struct virtio_net_ctrl_hdr {
+       __u8 class;
+       __u8 cmd;
+} __packed;
+
+typedef __u8 virtio_net_ctrl_ack;
+
+#define VIRTIO_NET_OK     0
+#define VIRTIO_NET_ERR    1
+
+/*
+ * Control the RX mode, ie. promisucous, allmulti, etc...
+ * All commands require an "out" sg entry containing a 1 byte
+ * state value, zero = disable, non-zero = enable.  Commands
+ * 0 and 1 are supported with the VIRTIO_NET_F_CTRL_RX feature.
+ * Commands 2-5 are added with VIRTIO_NET_F_CTRL_RX_EXTRA.
+ */
+#define VIRTIO_NET_CTRL_RX    0
+ #define VIRTIO_NET_CTRL_RX_PROMISC      0
+ #define VIRTIO_NET_CTRL_RX_ALLMULTI     1
+ #define VIRTIO_NET_CTRL_RX_ALLUNI       2
+ #define VIRTIO_NET_CTRL_RX_NOMULTI      3
+ #define VIRTIO_NET_CTRL_RX_NOUNI        4
+ #define VIRTIO_NET_CTRL_RX_NOBCAST      5
+
+/*
+ * Control the MAC
+ *
+ * The MAC filter table is managed by the hypervisor, the guest should
+ * assume the size is infinite.  Filtering should be considered
+ * non-perfect, ie. based on hypervisor resources, the guest may
+ * received packets from sources not specified in the filter list.
+ *
+ * In addition to the class/cmd header, the TABLE_SET command requires
+ * two out scatterlists.  Each contains a 4 byte count of entries followed
+ * by a concatenated byte stream of the ETH_ALEN MAC addresses.  The
+ * first sg list contains unicast addresses, the second is for multicast.
+ * This functionality is present if the VIRTIO_NET_F_CTRL_RX feature
+ * is available.
+ *
+ * The ADDR_SET command requests one out scatterlist, it contains a
+ * 6 bytes MAC address. This functionality is present if the
+ * VIRTIO_NET_F_CTRL_MAC_ADDR feature is available.
+ */
+struct virtio_net_ctrl_mac {
+       __virtio_le32 entries;
+       __u8 macs[][UK_NETDEV_HWADDR_LEN];
+} __packed;
+
+#define VIRTIO_NET_CTRL_MAC    1
+ #define VIRTIO_NET_CTRL_MAC_TABLE_SET        0
+ #define VIRTIO_NET_CTRL_MAC_ADDR_SET         1
+
+/*
+ * Control VLAN filtering
+ *
+ * The VLAN filter table is controlled via a simple ADD/DEL interface.
+ * VLAN IDs not added may be filterd by the hypervisor.  Del is the
+ * opposite of add.  Both commands expect an out entry containing a 2
+ * byte VLAN ID.  VLAN filterting is available with the
+ * VIRTIO_NET_F_CTRL_VLAN feature bit.
+ */
+#define VIRTIO_NET_CTRL_VLAN       2
+ #define VIRTIO_NET_CTRL_VLAN_ADD             0
+ #define VIRTIO_NET_CTRL_VLAN_DEL             1
+
+/*
+ * Control link announce acknowledgment
+ *
+ * The command VIRTIO_NET_CTRL_ANNOUNCE_ACK is used to indicate that
+ * driver has recevied the notification; device would clear the
+ * VIRTIO_NET_S_ANNOUNCE bit in the status field after it receives
+ * this command.
+ */
+#define VIRTIO_NET_CTRL_ANNOUNCE       3
+ #define VIRTIO_NET_CTRL_ANNOUNCE_ACK         0
+
+/*
+ * Control Receive Flow Steering
+ *
+ * The command VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET
+ * enables Receive Flow Steering, specifying the number of the transmit and
+ * receive queues that will be used. After the command is consumed and acked by
+ * the device, the device will not steer new packets on receive virtqueues
+ * other than specified nor read from transmit virtqueues other than specified.
+ * Accordingly, driver should not transmit new packets  on virtqueues other 
than
+ * specified.
+ */
+struct virtio_net_ctrl_mq {
+       __virtio_le16 virtqueue_pairs;
+};
+
+#define VIRTIO_NET_CTRL_MQ   4
+ #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET        0
+ #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN        1
+ #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX        0x8000
+
+/*
+ * Control network offloads
+ *
+ * Reconfigures the network offloads that Guest can handle.
+ *
+ * Available with the VIRTIO_NET_F_CTRL_GUEST_OFFLOADS feature bit.
+ *
+ * Command data format matches the feature bit mask exactly.
+ *
+ * See VIRTIO_NET_F_GUEST_* for the list of offloads
+ * that can be enabled/disabled.
+ */
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS   5
+#define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET        0
+
+#endif /* __PLAT_CMN_VIRTIO_NET_H */
diff --git a/plat/drivers/virtio/virtio_net.c b/plat/drivers/virtio/virtio_net.c
new file mode 100644
index 0000000..5617039
--- /dev/null
+++ b/plat/drivers/virtio/virtio_net.c
@@ -0,0 +1,417 @@
+/*
+ * Authors: Dan Williams
+ *          Martin Lucina
+ *          Ricardo Koller
+ *          Razvan Cojocaru <razvan.cojocaru93@xxxxxxxxx>
+ *          Sharan Santhanam
+ *
+ * Copyright (c) 2015-2017 IBM
+ * Copyright (c) 2016-2017 Docker, Inc.
+ * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software
+ * for any purpose with or without fee is hereby granted, provided
+ * that the above copyright notice and this permission notice appear
+ * in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <uk/print.h>
+#include <uk/assert.h>
+#include <uk/essentials.h>
+#include <uk/sglist.h>
+#include <uk/arch/types.h>
+#include <uk/arch/limits.h>
+#include <uk/netbuf.h>
+#include <uk/netdev.h>
+#include <uk/netdev_core.h>
+#include <uk/netdev_driver.h>
+#include <virtio/virtio.h>
+#include <virtio/virtqueue.h>
+#include <virtio/virtio_net.h>
+
+/**
+ * VIRTIO_PKT_BUFFER_LEN = VIRTIO_NET_HDR + ETH_HDR + ETH_PKT_PAYLOAD_LEN
+ * VIRTIO_NET_HDR: 10 bytes in length in legacy mode + 2 byte of padded data.
+ *                12 bytes in length in modern mode.
+ */
+#define VIRTIO_HDR_LEN          12
+#define ETH_HDR_LEN             14
+#define ETH_PKT_PAYLOAD_LEN   1500
+#define VIRTIO_PKT_BUFFER_LEN ((ETH_PKT_PAYLOAD_LEN)   \
+                              + (ETH_HDR_LEN)          \
+                              + (VIRTIO_HDR_LEN))
+
+#define DRIVER_NAME           "virtio-net"
+
+
+#define  VTNET_RX_HEADER_PAD (4)
+#define  VTNET_INTR_EN   (1 << 0)
+#define  VTNET_INTR_EN_MASK   (1)
+#define  VTNET_INTR_USR_EN   (1 << 1)
+#define  VTNET_INTR_USR_EN_MASK   (2)
+
+/**
+ * Define max possible fragments for the network packets.
+ */
+#define NET_MAX_FRAGMENTS    ((__U16_MAX >> __PAGE_SHIFT) + 2)
+
+#define to_virtionetdev(ndev) \
+       __containerof(ndev, struct virtio_net_device, netdev)
+
+#define VIRTIO_NET_DRV_FEATURES(features)           \
+       (VIRTIO_FEATURES_UPDATE(features, VIRTIO_NET_F_MAC))
+
+typedef enum {
+       VNET_RX,
+       VNET_TX,
+} virtq_type_t;
+
+/**
+ * @internal structure to represent the transmit queue.
+ */
+struct uk_netdev_tx_queue {
+       /* The virtqueue reference */
+       struct virtqueue *vq;
+       /* The hw queue identifier */
+       uint16_t hwvq_id;
+       /* The user queue identifier */
+       uint16_t lqueue_id;
+       /* The nr. of descriptor limit */
+       uint16_t max_nb_desc;
+       /* The nr. of descriptor user configured */
+       uint16_t nb_desc;
+       /* The flag to interrupt on the transmit queue */
+       uint8_t intr_enabled;
+       /* Reference to the uk_netdev */
+       struct uk_netdev *ndev;
+       /* The scatter list and its associated fragements */
+       struct uk_sglist sg;
+       struct uk_sglist_seg sgsegs[NET_MAX_FRAGMENTS];
+};
+
+/**
+ * @internal structure to represent the receive queue.
+ */
+struct uk_netdev_rx_queue {
+       /* The virtqueue reference */
+       struct virtqueue *vq;
+       /* The virtqueue hw identifier */
+       uint16_t hwvq_id;
+       /* The libuknet queue identifier */
+       uint16_t lqueue_id;
+       /* The nr. of descriptor limit */
+       uint16_t max_nb_desc;
+       /* The nr. of descriptor user configured */
+       uint16_t nb_desc;
+       /* The flag to interrupt on the transmit queue */
+       uint8_t intr_enabled;
+       /* Reference to the uk_netdev */
+       struct uk_netdev *ndev;
+       /* The scatter list and its associated fragements */
+       struct uk_sglist sg;
+       struct uk_sglist_seg sgsegs[NET_MAX_FRAGMENTS];
+};
+
+struct virtio_net_device {
+       /* Virtio Device */
+       struct virtio_dev *vdev;
+       /* List of all the virtqueue in the pci device */
+       struct virtqueue *vq;
+       struct uk_netdev netdev;
+       /* Count of the number of the virtqueues */
+       __u16 max_vqueue_pairs;
+       /* List of the Rx/Tx queue */
+       __u16    rx_vqueue_cnt;
+       struct   uk_netdev_rx_queue *rxqs;
+       __u16    tx_vqueue_cnt;
+       struct   uk_netdev_tx_queue *txqs;
+       /* The netdevice identifier */
+       __u16 uid;
+       /* The max mtu */
+       __u16 max_mtu;
+       /* The mtu */
+       __u16 mtu;
+       /* The hw address of the netdevice */
+       struct uk_hwaddr hw_addr;
+       /*  Netdev state */
+       __u8 state;
+       /* RX promiscuous mode. */
+       __u8 promisc : 1;
+};
+
+/**
+ * Static function declarations.
+ */
+static int virtio_net_drv_init(struct uk_alloc *drv_allocator);
+static int virtio_net_add_dev(struct virtio_dev *vdev);
+static void virtio_net_info_get(struct uk_netdev *dev,
+                               struct uk_netdev_info *dev_info);
+static inline void virtio_netdev_feature_set(struct virtio_net_device *vndev);
+static int virtio_netdev_configure(struct uk_netdev *n,
+                                  const struct uk_netdev_conf *conf);
+static struct uk_netdev_tx_queue *virtio_netdev_tx_queue_setup(
+                                       struct uk_netdev *n, uint16_t queue_id,
+                                       uint16_t nb_desc,
+                                       struct uk_netdev_txqueue_conf *conf);
+static struct uk_netdev_rx_queue *virtio_netdev_rx_queue_setup(
+                                       struct uk_netdev *n,
+                                       uint16_t queue_id, uint16_t nb_desc,
+                                       struct uk_netdev_rxqueue_conf *conf);
+static int virtio_net_rx_intr_disable(struct uk_netdev *n,
+                                     struct uk_netdev_rx_queue *queue);
+static int virtio_net_rx_intr_enable(struct uk_netdev *n,
+                                    struct uk_netdev_rx_queue *queue);
+static int virtio_netdev_xmit(struct uk_netdev *dev,
+                             struct uk_netdev_tx_queue *queue,
+                             struct uk_netbuf *pkt);
+static int virtio_netdev_recv(struct uk_netdev *dev,
+                             struct uk_netdev_rx_queue *queue,
+                             struct uk_netbuf **pkt,
+                             struct uk_netbuf *fillup[],
+                             uint16_t *fillup_count);
+static const struct uk_hwaddr *virtio_net_mac_get(struct uk_netdev *n);
+static __u16 virtio_net_mtu_get(struct uk_netdev *n);
+static unsigned virtio_net_promisc_get(struct uk_netdev *n);
+static int virtio_netdev_rxq_info_get(struct uk_netdev *dev, __u16 queue_id,
+                                     struct uk_netdev_queue_info *qinfo);
+static int virtio_netdev_txq_info_get(struct uk_netdev *dev, __u16 queue_id,
+                                     struct uk_netdev_queue_info *qinfo);
+
+/**
+ * Static global constants
+ */
+static const char *drv_name = DRIVER_NAME;
+static struct uk_alloc *a;
+
+/**
+ * The Driver method implementation.
+ */
+static int virtio_netdev_xmit(struct uk_netdev *dev,
+                             struct uk_netdev_tx_queue *queue,
+                             struct uk_netbuf *pkt)
+{
+       int rc = 0;
+
+       UK_ASSERT(dev);
+       UK_ASSERT(pkt && queue);
+
+       return rc;
+}
+
+static int virtio_netdev_recv(struct uk_netdev *dev __unused,
+                             struct uk_netdev_rx_queue *queue,
+                             struct uk_netbuf **pkt __unused,
+                             struct uk_netbuf *fillup[],
+                             uint16_t *fillup_count)
+{
+       int rc = 0;
+
+       UK_ASSERT(dev && queue);
+       UK_ASSERT(!fillup || (fillup && *fillup_count > 0));
+
+       return rc;
+}
+
+static struct uk_netdev_rx_queue *virtio_netdev_rx_queue_setup(
+                               struct uk_netdev *n, uint16_t queue_id __unused,
+                               uint16_t nb_desc __unused,
+                               struct uk_netdev_rxqueue_conf *conf __unused)
+{
+       struct uk_netdev_rx_queue *rxq = NULL;
+
+       UK_ASSERT(n);
+
+       return rxq;
+}
+
+static struct uk_netdev_tx_queue *virtio_netdev_tx_queue_setup(
+                               struct uk_netdev *n, uint16_t queue_id __unused,
+                               uint16_t nb_desc __unused,
+                               struct uk_netdev_txqueue_conf *conf __unused)
+{
+       struct uk_netdev_tx_queue *txq = NULL;
+
+       UK_ASSERT(n);
+       return txq;
+}
+
+static int virtio_netdev_rxq_info_get(struct uk_netdev *dev,
+                                     __u16 queue_id __unused,
+                                     struct uk_netdev_queue_info *qinfo)
+{
+       UK_ASSERT(dev);
+       UK_ASSERT(qinfo);
+       return 0;
+}
+
+static int virtio_netdev_txq_info_get(struct uk_netdev *dev,
+                                     __u16 queue_id __unused,
+                                     struct uk_netdev_queue_info *qinfo)
+{
+       UK_ASSERT(dev);
+       UK_ASSERT(qinfo);
+       return 0;
+}
+
+static unsigned virtio_net_promisc_get(struct uk_netdev *n)
+{
+       UK_ASSERT(n);
+       return 0;
+}
+
+static const struct uk_hwaddr *virtio_net_mac_get(struct uk_netdev *n)
+{
+       UK_ASSERT(n);
+       return NULL;
+}
+
+static __u16 virtio_net_mtu_get(struct uk_netdev *n)
+{
+       UK_ASSERT(n);
+       return 0;
+}
+
+static int virtio_netdev_configure(struct uk_netdev *n,
+                                  const struct uk_netdev_conf *conf __unused)
+{
+       int rc = 0;
+
+       UK_ASSERT(n);
+
+       return rc;
+}
+
+static int virtio_net_rx_intr_enable(struct uk_netdev *n,
+                                    struct uk_netdev_rx_queue *queue __unused)
+{
+       int rc = 0;
+
+       UK_ASSERT(n);
+
+       return rc;
+}
+
+static int virtio_net_rx_intr_disable(struct uk_netdev *n,
+                                     struct uk_netdev_rx_queue *queue __unused)
+{
+       UK_ASSERT(n);
+       return 0;
+}
+
+static void virtio_net_info_get(struct uk_netdev *dev,
+                               struct uk_netdev_info *dev_info)
+{
+       struct virtio_net_device *vndev;
+
+       UK_ASSERT(dev && dev_info);
+       vndev = to_virtionetdev(dev);
+
+       dev_info->max_rx_queues = vndev->max_vqueue_pairs;
+       dev_info->max_tx_queues = vndev->max_vqueue_pairs;
+}
+
+static int virtio_net_start(struct uk_netdev *n)
+{
+       UK_ASSERT(n != NULL);
+       return 0;
+}
+
+static inline void virtio_netdev_feature_set(struct virtio_net_device *vndev)
+{
+       vndev->vdev->features = 0;
+       /* Setting the feature the driver support */
+       VIRTIO_NET_DRV_FEATURES(vndev->vdev->features);
+       /**
+        * TODO:
+        * Adding multiqueue support for the virtio net driver.
+        */
+       vndev->max_vqueue_pairs = 1;
+}
+
+static const struct uk_netdev_ops virtio_netdev_ops = {
+       .configure = virtio_netdev_configure,
+       .rxq_configure = virtio_netdev_rx_queue_setup,
+       .txq_configure = virtio_netdev_tx_queue_setup,
+       .start = virtio_net_start,
+       .rxq_intr_enable = virtio_net_rx_intr_enable,
+       .rxq_intr_disable = virtio_net_rx_intr_disable,
+       .info_get = virtio_net_info_get,
+       .promiscuous_get = virtio_net_promisc_get,
+       .hwaddr_get = virtio_net_mac_get,
+       .mtu_get = virtio_net_mtu_get,
+       .txq_info_get = virtio_netdev_txq_info_get,
+       .rxq_info_get = virtio_netdev_rxq_info_get,
+};
+
+static int virtio_net_add_dev(struct virtio_dev *vdev)
+{
+       struct virtio_net_device *vndev;
+       int rc = 0;
+
+       UK_ASSERT(vdev != NULL);
+
+       vndev = uk_malloc(a, sizeof(*vndev));
+       if (!vndev) {
+               rc = -ENOMEM;
+               goto err_out;
+       }
+       vndev->vdev = vdev;
+       /* register netdev */
+       vndev->netdev.rx_one = virtio_netdev_recv;
+       vndev->netdev.tx_one = virtio_netdev_xmit;
+       vndev->netdev.ops = &virtio_netdev_ops;
+
+       rc = uk_netdev_drv_register(&vndev->netdev, a, drv_name);
+       if (rc < 0) {
+               uk_pr_err("Failed to register virtio-net device with 
libuknet\n");
+               goto err_netdev_data;
+       }
+       vndev->uid = rc;
+       rc = 0;
+       vndev->max_mtu = ETH_PKT_PAYLOAD_LEN;
+       vndev->mtu = vndev->max_mtu;
+       vndev->promisc = 0;
+       virtio_netdev_feature_set(vndev);
+       uk_pr_info("virtio-net device registered with libuknet\n");
+
+exit:
+       return rc;
+err_netdev_data:
+       uk_free(a, vndev);
+err_out:
+       goto exit;
+}
+
+static int virtio_net_drv_init(struct uk_alloc *drv_allocator)
+{
+       /* driver initialization */
+       if (!drv_allocator)
+               return -EINVAL;
+
+       a = drv_allocator;
+       return 0;
+}
+
+static const struct virtio_dev_id vnet_dev_id[] = {
+       {VIRTIO_ID_NET},
+       {VIRTIO_ID_INVALID} /* List Terminator */
+};
+
+static struct virtio_driver vnet_drv = {
+       .dev_ids = vnet_dev_id,
+       .init    = virtio_net_drv_init,
+       .add_dev = virtio_net_add_dev
+};
+VIRTIO_REGISTER_DRIVER(&vnet_drv);
diff --git a/plat/kvm/Config.uk b/plat/kvm/Config.uk
index 13e5575..fb3677a 100644
--- a/plat/kvm/Config.uk
+++ b/plat/kvm/Config.uk
@@ -71,5 +71,13 @@ config VIRTIO_PCI
         help
                 Support virtio devices on PCI bus
+config VIRTIO_NET
+       bool "Virtio Net device"
+       default n
+       depends on LIBUKNETDEV
+       select VIRTIO
+       select LIBUKSGLIST
+       help
+              Virtual network driver.
  endmenu
  endif
diff --git a/plat/kvm/Makefile.uk b/plat/kvm/Makefile.uk
index ccc8319..1f9c5dc 100644
--- a/plat/kvm/Makefile.uk
+++ b/plat/kvm/Makefile.uk
@@ -96,3 +96,5 @@ LIBKVMVIRTIO_SRCS-$(CONFIG_VIRTIO_BUS) +=\
                                                        
$(UK_PLAT_DRIVERS_BASE)/virtio/virtio_ring.c
  LIBKVMVIRTIO_SRCS-$(CONFIG_VIRTIO_PCI) +=\
                                                        
$(UK_PLAT_DRIVERS_BASE)/virtio/virtio_pci.c
+LIBKVMVIRTIO_SRCS-$(CONFIG_VIRTIO_NET) +=\
+                                                       
$(UK_PLAT_DRIVERS_BASE)/virtio/virtio_net.c


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.