|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH v4 1/8] plat/drivers: Introduce the virtio-net device
Hi Sharan and Simon,
I have a few questions and comments, please see inline.
On 10/25/18 12:49 PM, 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>
> 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)
> +
Shouldn't these VTNET_INTR_* definitions be in the netdev API?
Interrupts enabling is logic specific to all network device. Even more,
I would say we might even define those as specific to all devices.
> +/**
> + * 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];
> +};
> +
Is it expected for uk_netdev_tx_queue and uk_netdev_rx_queue structures
to be identical?
> +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;
> +};
Shouldn't queues, mtu, hw_addr, promisc be fields of the uk_netdev
structure?
> +
> +/**
> + * 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
>
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |