|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH v3 1/7] plat/drivers: Introduce the virtio-net device
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>
Reviewed-by: Simon Kuenzer <simon.kuenzer@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..41ba860
--- /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_bus.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_BUS_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
--
2.7.4
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |