// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2017 - 2019 Cambridge Greys Limited
 * Copyright (C) 2011 - 2014 Cisco Systems Inc
 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
 * James Leu (jleu@mindspring.net).
 * Copyright (C) 2001 by various other people who didn't put their name here.
 */

#include <linux/version.h>
#include <linux/memblock.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/inetdevice.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <linux/rtnetlink.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
#include <linux/fs.h>
#include <uapi/linux/filter.h>
#include <init.h>
#include <irq_kern.h>
#include <irq_user.h>
#include <net_kern.h>
#include <os.h>
#include "mconsole_kern.h"
#include "vector_user.h"
#include "vector_kern.h"

/*
 * Adapted from network devices with the following major changes:
 * All transports are static - simplifies the code significantly
 * Multiple FDs/IRQs per device
 * Vector IO optionally used for read/write, falling back to legacy
 * based on configuration and/or availability
 * Configuration is no longer positional - L2TPv3 and GRE require up to
 * 10 parameters, passing this as positional is not fit for purpose.
 * Only socket transports are supported
 */


#define DRIVER_NAME "uml-vector"
struct vector_cmd_line_arg {
	struct list_head list;
	int unit;
	char *arguments;
};

struct vector_device {
	struct list_head list;
	struct net_device *dev;
	struct platform_device pdev;
	int unit;
	int opened;
};

static LIST_HEAD(vec_cmd_line);

static DEFINE_SPINLOCK(vector_devices_lock);
static LIST_HEAD(vector_devices);

static int driver_registered;

static void vector_eth_configure(int n, struct arglist *def);

/* Argument accessors to set variables (and/or set default values)
 * mtu, buffer sizing, default headroom, etc
 */

#define DEFAULT_HEADROOM 2
#define SAFETY_MARGIN 32
#define DEFAULT_VECTOR_SIZE 64
#define TX_SMALL_PACKET 128
#define MAX_IOV_SIZE (MAX_SKB_FRAGS + 1)
#define MAX_ITERATIONS 64

static const struct {
	const char string[ETH_GSTRING_LEN];
} ethtool_stats_keys[] = {
	{ "rx_queue_max" },
	{ "rx_queue_running_average" },
	{ "tx_queue_max" },
	{ "tx_queue_running_average" },
	{ "rx_encaps_errors" },
	{ "tx_timeout_count" },
	{ "tx_restart_queue" },
	{ "tx_kicks" },
	{ "tx_flow_control_xon" },
	{ "tx_flow_control_xoff" },
	{ "rx_csum_offload_good" },
	{ "rx_csum_offload_errors"},
	{ "sg_ok"},
	{ "sg_linearized"},
};

#define VECTOR_NUM_STATS	ARRAY_SIZE(ethtool_stats_keys)

static void vector_reset_stats(struct vector_private *vp)
{
	vp->estats.rx_queue_max = 0;
	vp->estats.rx_queue_running_average = 0;
	vp->estats.tx_queue_max = 0;
	vp->estats.tx_queue_running_average = 0;
	vp->estats.rx_encaps_errors = 0;
	vp->estats.tx_timeout_count = 0;
	vp->estats.tx_restart_queue = 0;
	vp->estats.tx_kicks = 0;
	vp->estats.tx_flow_control_xon = 0;
	vp->estats.tx_flow_control_xoff = 0;
	vp->estats.sg_ok = 0;
	vp->estats.sg_linearized = 0;
}

static int get_mtu(struct arglist *def)
{
	char *mtu = uml_vector_fetch_arg(def, "mtu");
	long result;

	if (mtu != NULL) {
		if (kstrtoul(mtu, 10, &result) == 0)
			if ((result < (1 << 16) - 1) && (result >= 576))
				return result;
	}
	return ETH_MAX_PACKET;
}

static char *get_bpf_file(struct arglist *def)
{
	return uml_vector_fetch_arg(def, "bpffile");
}

static bool get_bpf_flash(struct arglist *def)
{
	char *allow = uml_vector_fetch_arg(def, "bpfflash");
	long result;

	if (allow != NULL) {
		if (kstrtoul(allow, 10, &result) == 0)
			return (allow > 0);
	}
	return false;
}

static int get_depth(struct arglist *def)
{
	char *mtu = uml_vector_fetch_arg(def, "depth");
	long result;

	if (mtu != NULL) {
		if (kstrtoul(mtu, 10, &result) == 0)
			return result;
	}
	return DEFAULT_VECTOR_SIZE;
}

static int get_headroom(struct arglist *def)
{
	char *mtu = uml_vector_fetch_arg(def, "headroom");
	long result;

	if (mtu != NULL) {
		if (kstrtoul(mtu, 10, &result) == 0)
			return result;
	}
	return DEFAULT_HEADROOM;
}

static int get_req_size(struct arglist *def)
{
	char *gro = uml_vector_fetch_arg(def, "gro");
	long result;

	if (gro != NULL) {
		if (kstrtoul(gro, 10, &result) == 0) {
			if (result > 0)
				return 65536;
		}
	}
	return get_mtu(def) + ETH_HEADER_OTHER +
		get_headroom(def) + SAFETY_MARGIN;
}


static int get_transport_options(struct arglist *def)
{
	char *transport = uml_vector_fetch_arg(def, "transport");
	char *vector = uml_vector_fetch_arg(def, "vec");

	int vec_rx = VECTOR_RX;
	int vec_tx = VECTOR_TX;
	long parsed;
	int result = 0;

	if (transport == NULL)
		return -EINVAL;

	if (vector != NULL) {
		if (kstrtoul(vector, 10, &parsed) == 0) {
			if (parsed == 0) {
				vec_rx = 0;
				vec_tx = 0;
			}
		}
	}

	if (get_bpf_flash(def))
		result = VECTOR_BPF_FLASH;

	if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0)
		return result;
	if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0)
		return (result | vec_rx | VECTOR_BPF);
	if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0)
		return (result | vec_rx | vec_tx | VECTOR_QDISC_BYPASS);
	return (result | vec_rx | vec_tx);
}


/* A mini-buffer for packet drop read
 * All of our supported transports are datagram oriented and we always
 * read using recvmsg or recvmmsg. If we pass a buffer which is smaller
 * than the packet size it still counts as full packet read and will
 * clean the incoming stream to keep sigio/epoll happy
 */

#define DROP_BUFFER_SIZE 32

static char *drop_buffer;

/* Array backed queues optimized for bulk enqueue/dequeue and
 * 1:N (small values of N) or 1:1 enqueuer/dequeuer ratios.
 * For more details and full design rationale see
 * http://foswiki.cambridgegreys.com/Main/EatYourTailAndEnjoyIt
 */


/*
 * Advance the mmsg queue head by n = advance. Resets the queue to
 * maximum enqueue/dequeue-at-once capacity if possible. Called by
 * dequeuers. Caller must hold the head_lock!
 */

static int vector_advancehead(struct vector_queue *qi, int advance)
{
	int queue_depth;

	qi->head =
		(qi->head + advance)
			% qi->max_depth;


	spin_lock(&qi->tail_lock);
	qi->queue_depth -= advance;

	/* we are at 0, use this to
	 * reset head and tail so we can use max size vectors
	 */

	if (qi->queue_depth == 0) {
		qi->head = 0;
		qi->tail = 0;
	}
	queue_depth = qi->queue_depth;
	spin_unlock(&qi->tail_lock);
	return queue_depth;
}

/*	Advance the queue tail by n = advance.
 *	This is called by enqueuers which should hold the
 *	head lock already
 */

static int vector_advancetail(struct vector_queue *qi, int advance)
{
	int queue_depth;

	qi->tail =
		(qi->tail + advance)
			% qi->max_depth;
	spin_lock(&qi->head_lock);
	qi->queue_depth += advance;
	queue_depth = qi->queue_depth;
	spin_unlock(&qi->head_lock);
	return queue_depth;
}

static int prep_msg(struct vector_private *vp,
	struct sk_buff *skb,
	struct iovec *iov)
{
	int iov_index = 0;
	int nr_frags, frag;
	skb_frag_t *skb_frag;

	nr_frags = skb_shinfo(skb)->nr_frags;
	if (nr_frags > MAX_IOV_SIZE) {
		if (skb_linearize(skb) != 0)
			goto drop;
	}
	if (vp->header_size > 0) {
		iov[iov_index].iov_len = vp->header_size;
		vp->form_header(iov[iov_index].iov_base, skb, vp);
		iov_index++;
	}
	iov[iov_index].iov_base = skb->data;
	if (nr_frags > 0) {
		iov[iov_index].iov_len = skb->len - skb->data_len;
		vp->estats.sg_ok++;
	} else
		iov[iov_index].iov_len = skb->len;
	iov_index++;
	for (frag = 0; frag < nr_frags; frag++) {
		skb_frag = &skb_shinfo(skb)->frags[frag];
		iov[iov_index].iov_base = skb_frag_address_safe(skb_frag);
		iov[iov_index].iov_len = skb_frag_size(skb_frag);
		iov_index++;
	}
	return iov_index;
drop:
	return -1;
}
/*
 * Generic vector enqueue with support for forming headers using transport
 * specific callback. Allows GRE, L2TPv3, RAW and other transports
 * to use a common enqueue procedure in vector mode
 */

static int vector_enqueue(struct vector_queue *qi, struct sk_buff *skb)
{
	struct vector_private *vp = netdev_priv(qi->dev);
	int queue_depth;
	int packet_len;
	struct mmsghdr *mmsg_vector = qi->mmsg_vector;
	int iov_count;

	spin_lock(&qi->tail_lock);
	spin_lock(&qi->head_lock);
	queue_depth = qi->queue_depth;
	spin_unlock(&qi->head_lock);

	if (skb)
		packet_len = skb->len;

	if (queue_depth < qi->max_depth) {

		*(qi->skbuff_vector + qi->tail) = skb;
		mmsg_vector += qi->tail;
		iov_count = prep_msg(
			vp,
			skb,
			mmsg_vector->msg_hdr.msg_iov
		);
		if (iov_count < 1)
			goto drop;
		mmsg_vector->msg_hdr.msg_iovlen = iov_count;
		mmsg_vector->msg_hdr.msg_name = vp->fds->remote_addr;
		mmsg_vector->msg_hdr.msg_namelen = vp->fds->remote_addr_size;
		queue_depth = vector_advancetail(qi, 1);
	} else
		goto drop;
	spin_unlock(&qi->tail_lock);
	return queue_depth;
drop:
	qi->dev->stats.tx_dropped++;
	if (skb != NULL) {
		packet_len = skb->len;
		dev_consume_skb_any(skb);
		netdev_completed_queue(qi->dev, 1, packet_len);
	}
	spin_unlock(&qi->tail_lock);
	return queue_depth;
}

static int consume_vector_skbs(struct vector_queue *qi, int count)
{
	struct sk_buff *skb;
	int skb_index;
	int bytes_compl = 0;

	for (skb_index = qi->head; skb_index < qi->head + count; skb_index++) {
		skb = *(qi->skbuff_vector + skb_index);
		/* mark as empty to ensure correct destruction if
		 * needed
		 */
		bytes_compl += skb->len;
		*(qi->skbuff_vector + skb_index) = NULL;
		dev_consume_skb_any(skb);
	}
	qi->dev->stats.tx_bytes += bytes_compl;
	qi->dev->stats.tx_packets += count;
	netdev_completed_queue(qi->dev, count, bytes_compl);
	return vector_advancehead(qi, count);
}

/*
 * Generic vector deque via sendmmsg with support for forming headers
 * using transport specific callback. Allows GRE, L2TPv3, RAW and
 * other transports to use a common dequeue procedure in vector mode
 */


static int vector_send(struct vector_queue *qi)
{
	struct vector_private *vp = netdev_priv(qi->dev);
	struct mmsghdr *send_from;
	int result = 0, send_len, queue_depth = qi->max_depth;

	if (spin_trylock(&qi->head_lock)) {
		if (spin_trylock(&qi->tail_lock)) {
			/* update queue_depth to current value */
			queue_depth = qi->queue_depth;
			spin_unlock(&qi->tail_lock);
			while (queue_depth > 0) {
				/* Calculate the start of the vector */
				send_len = queue_depth;
				send_from = qi->mmsg_vector;
				send_from += qi->head;
				/* Adjust vector size if wraparound */
				if (send_len + qi->head > qi->max_depth)
					send_len = qi->max_depth - qi->head;
				/* Try to TX as many packets as possible */
				if (send_len > 0) {
					result = uml_vector_sendmmsg(
						 vp->fds->tx_fd,
						 send_from,
						 send_len,
						 0
					);
					vp->in_write_poll =
						(result != send_len);
				}
				/* For some of the sendmmsg error scenarios
				 * we may end being unsure in the TX success
				 * for all packets. It is safer to declare
				 * them all TX-ed and blame the network.
				 */
				if (result < 0) {
					if (net_ratelimit())
						netdev_err(vp->dev, "sendmmsg err=%i\n",
							result);
					vp->in_error = true;
					result = send_len;
				}
				if (result > 0) {
					queue_depth =
						consume_vector_skbs(qi, result);
					/* This is equivalent to an TX IRQ.
					 * Restart the upper layers to feed us
					 * more packets.
					 */
					if (result > vp->estats.tx_queue_max)
						vp->estats.tx_queue_max = result;
					vp->estats.tx_queue_running_average =
						(vp->estats.tx_queue_running_average + result) >> 1;
				}
				netif_trans_update(qi->dev);
				netif_wake_queue(qi->dev);
				/* if TX is busy, break out of the send loop,
				 *  poll write IRQ will reschedule xmit for us
				 */
				if (result != send_len) {
					vp->estats.tx_restart_queue++;
					break;
				}
			}
		}
		spin_unlock(&qi->head_lock);
	} else {
		tasklet_schedule(&vp->tx_poll);
	}
	return queue_depth;
}

/* Queue destructor. Deliberately stateless so we can use
 * it in queue cleanup if initialization fails.
 */

static void destroy_queue(struct vector_queue *qi)
{
	int i;
	struct iovec *iov;
	struct vector_private *vp = netdev_priv(qi->dev);
	struct mmsghdr *mmsg_vector;

	if (qi == NULL)
		return;
	/* deallocate any skbuffs - we rely on any unused to be
	 * set to NULL.
	 */
	if (qi->skbuff_vector != NULL) {
		for (i = 0; i < qi->max_depth; i++) {
			if (*(qi->skbuff_vector + i) != NULL)
				dev_kfree_skb_any(*(qi->skbuff_vector + i));
		}
		kfree(qi->skbuff_vector);
	}
	/* deallocate matching IOV structures including header buffs */
	if (qi->mmsg_vector != NULL) {
		mmsg_vector = qi->mmsg_vector;
		for (i = 0; i < qi->max_depth; i++) {
			iov = mmsg_vector->msg_hdr.msg_iov;
			if (iov != NULL) {
				if ((vp->header_size > 0) &&
					(iov->iov_base != NULL))
					kfree(iov->iov_base);
				kfree(iov);
			}
			mmsg_vector++;
		}
		kfree(qi->mmsg_vector);
	}
	kfree(qi);
}

/*
 * Queue constructor. Create a queue with a given side.
 */
static struct vector_queue *create_queue(
	struct vector_private *vp,
	int max_size,
	int header_size,
	int num_extra_frags)
{
	struct vector_queue *result;
	int i;
	struct iovec *iov;
	struct mmsghdr *mmsg_vector;

	result = kmalloc(sizeof(struct vector_queue), GFP_KERNEL);
	if (result == NULL)
		return NULL;
	result->max_depth = max_size;
	result->dev = vp->dev;
	result->mmsg_vector = kmalloc(
		(sizeof(struct mmsghdr) * max_size), GFP_KERNEL);
	if (result->mmsg_vector == NULL)
		goto out_mmsg_fail;
	result->skbuff_vector = kmalloc(
		(sizeof(void *) * max_size), GFP_KERNEL);
	if (result->skbuff_vector == NULL)
		goto out_skb_fail;

	/* further failures can be handled safely by destroy_queue*/

	mmsg_vector = result->mmsg_vector;
	for (i = 0; i < max_size; i++) {
		/* Clear all pointers - we use non-NULL as marking on
		 * what to free on destruction
		 */
		*(result->skbuff_vector + i) = NULL;
		mmsg_vector->msg_hdr.msg_iov = NULL;
		mmsg_vector++;
	}
	mmsg_vector = result->mmsg_vector;
	result->max_iov_frags = num_extra_frags;
	for (i = 0; i < max_size; i++) {
		if (vp->header_size > 0)
			iov = kmalloc_array(3 + num_extra_frags,
					    sizeof(struct iovec),
					    GFP_KERNEL
			);
		else
			iov = kmalloc_array(2 + num_extra_frags,
					    sizeof(struct iovec),
					    GFP_KERNEL
			);
		if (iov == NULL)
			goto out_fail;
		mmsg_vector->msg_hdr.msg_iov = iov;
		mmsg_vector->msg_hdr.msg_iovlen = 1;
		mmsg_vector->msg_hdr.msg_control = NULL;
		mmsg_vector->msg_hdr.msg_controllen = 0;
		mmsg_vector->msg_hdr.msg_flags = MSG_DONTWAIT;
		mmsg_vector->msg_hdr.msg_name = NULL;
		mmsg_vector->msg_hdr.msg_namelen = 0;
		if (vp->header_size > 0) {
			iov->iov_base = kmalloc(header_size, GFP_KERNEL);
			if (iov->iov_base == NULL)
				goto out_fail;
			iov->iov_len = header_size;
			mmsg_vector->msg_hdr.msg_iovlen = 2;
			iov++;
		}
		iov->iov_base = NULL;
		iov->iov_len = 0;
		mmsg_vector++;
	}
	spin_lock_init(&result->head_lock);
	spin_lock_init(&result->tail_lock);
	result->queue_depth = 0;
	result->head = 0;
	result->tail = 0;
	return result;
out_skb_fail:
	kfree(result->mmsg_vector);
out_mmsg_fail:
	kfree(result);
	return NULL;
out_fail:
	destroy_queue(result);
	return NULL;
}

/*
 * We do not use the RX queue as a proper wraparound queue for now
 * This is not necessary because the consumption via netif_rx()
 * happens in-line. While we can try using the return code of
 * netif_rx() for flow control there are no drivers doing this today.
 * For this RX specific use we ignore the tail/head locks and
 * just read into a prepared queue filled with skbuffs.
 */

static struct sk_buff *prep_skb(
	struct vector_private *vp,
	struct user_msghdr *msg)
{
	int linear = vp->max_packet + vp->headroom + SAFETY_MARGIN;
	struct sk_buff *result;
	int iov_index = 0, len;
	struct iovec *iov = msg->msg_iov;
	int err, nr_frags, frag;
	skb_frag_t *skb_frag;

	if (vp->req_size <= linear)
		len = linear;
	else
		len = vp->req_size;
	result = alloc_skb_with_frags(
		linear,
		len - vp->max_packet,
		3,
		&err,
		GFP_ATOMIC
	);
	if (vp->header_size > 0)
		iov_index++;
	if (result == NULL) {
		iov[iov_index].iov_base = NULL;
		iov[iov_index].iov_len = 0;
		goto done;
	}
	skb_reserve(result, vp->headroom);
	result->dev = vp->dev;
	skb_put(result, vp->max_packet);
	result->data_len = len - vp->max_packet;
	result->len += len - vp->max_packet;
	skb_reset_mac_header(result);
	result->ip_summed = CHECKSUM_NONE;
	iov[iov_index].iov_base = result->data;
	iov[iov_index].iov_len = vp->max_packet;
	iov_index++;

	nr_frags = skb_shinfo(result)->nr_frags;
	for (frag = 0; frag < nr_frags; frag++) {
		skb_frag = &skb_shinfo(result)->frags[frag];
		iov[iov_index].iov_base = skb_frag_address_safe(skb_frag);
		if (iov[iov_index].iov_base != NULL)
			iov[iov_index].iov_len = skb_frag_size(skb_frag);
		else
			iov[iov_index].iov_len = 0;
		iov_index++;
	}
done:
	msg->msg_iovlen = iov_index;
	return result;
}


/* Prepare queue for recvmmsg one-shot rx - fill with fresh sk_buffs*/

static void prep_queue_for_rx(struct vector_queue *qi)
{
	struct vector_private *vp = netdev_priv(qi->dev);
	struct mmsghdr *mmsg_vector = qi->mmsg_vector;
	void **skbuff_vector = qi->skbuff_vector;
	int i;

	if (qi->queue_depth == 0)
		return;
	for (i = 0; i < qi->queue_depth; i++) {
		/* it is OK if allocation fails - recvmmsg with NULL data in
		 * iov argument still performs an RX, just drops the packet
		 * This allows us stop faffing around with a "drop buffer"
		 */

		*skbuff_vector = prep_skb(vp, &mmsg_vector->msg_hdr);
		skbuff_vector++;
		mmsg_vector++;
	}
	qi->queue_depth = 0;
}

static struct vector_device *find_device(int n)
{
	struct vector_device *device;
	struct list_head *ele;

	spin_lock(&vector_devices_lock);
	list_for_each(ele, &vector_devices) {
		device = list_entry(ele, struct vector_device, list);
		if (device->unit == n)
			goto out;
	}
	device = NULL;
 out:
	spin_unlock(&vector_devices_lock);
	return device;
}

static int vector_parse(char *str, int *index_out, char **str_out,
			char **error_out)
{
	int n, len, err;
	char *start = str;

	len = strlen(str);

	while ((*str != ':') && (strlen(str) > 1))
		str++;
	if (*str != ':') {
		*error_out = "Expected ':' after device number";
		return -EINVAL;
	}
	*str = '\0';

	err = kstrtouint(start, 0, &n);
	if (err < 0) {
		*error_out = "Bad device number";
		return err;
	}

	str++;
	if (find_device(n)) {
		*error_out = "Device already configured";
		return -EINVAL;
	}

	*index_out = n;
	*str_out = str;
	return 0;
}

static int vector_config(char *str, char **error_out)
{
	int err, n;
	char *params;
	struct arglist *parsed;

	err = vector_parse(str, &n, &params, error_out);
	if (err != 0)
		return err;

	/* This string is broken up and the pieces used by the underlying
	 * driver. We should copy it to make sure things do not go wrong
	 * later.
	 */

	params = kstrdup(params, GFP_KERNEL);
	if (params == NULL) {
		*error_out = "vector_config failed to strdup string";
		return -ENOMEM;
	}

	parsed = uml_parse_vector_ifspec(params);

	if (parsed == NULL) {
		*error_out = "vector_config failed to parse parameters";
		kfree(params);
		return -EINVAL;
	}

	vector_eth_configure(n, parsed);
	return 0;
}

static int vector_id(char **str, int *start_out, int *end_out)
{
	char *end;
	int n;

	n = simple_strtoul(*str, &end, 0);
	if ((*end != '\0') || (end == *str))
		return -1;

	*start_out = n;
	*end_out = n;
	*str = end;
	return n;
}

static int vector_remove(int n, char **error_out)
{
	struct vector_device *vec_d;
	struct net_device *dev;
	struct vector_private *vp;

	vec_d = find_device(n);
	if (vec_d == NULL)
		return -ENODEV;
	dev = vec_d->dev;
	vp = netdev_priv(dev);
	if (vp->fds != NULL)
		return -EBUSY;
	unregister_netdev(dev);
	platform_device_unregister(&vec_d->pdev);
	return 0;
}

/*
 * There is no shared per-transport initialization code, so
 * we will just initialize each interface one by one and
 * add them to a list
 */

static struct platform_driver uml_net_driver = {
	.driver = {
		.name = DRIVER_NAME,
	},
};


static void vector_device_release(struct device *dev)
{
	struct vector_device *device = dev_get_drvdata(dev);
	struct net_device *netdev = device->dev;

	list_del(&device->list);
	kfree(device);
	free_netdev(netdev);
}

/* Bog standard recv using recvmsg - not used normally unless the user
 * explicitly specifies not to use recvmmsg vector RX.
 */

static int vector_legacy_rx(struct vector_private *vp)
{
	int pkt_len;
	struct user_msghdr hdr;
	struct iovec iov[2 + MAX_IOV_SIZE]; /* header + data use case only */
	int iovpos = 0;
	struct sk_buff *skb;
	int header_check;

	hdr.msg_name = NULL;
	hdr.msg_namelen = 0;
	hdr.msg_iov = (struct iovec *) &iov;
	hdr.msg_control = NULL;
	hdr.msg_controllen = 0;
	hdr.msg_flags = 0;

	if (vp->header_size > 0) {
		iov[0].iov_base = vp->header_rxbuffer;
		iov[0].iov_len = vp->header_size;
	}

	skb = prep_skb(vp, &hdr);

	if (skb == NULL) {
		/* Read a packet into drop_buffer and don't do
		 * anything with it.
		 */
		iov[iovpos].iov_base = drop_buffer;
		iov[iovpos].iov_len = DROP_BUFFER_SIZE;
		hdr.msg_iovlen = 1;
		vp->dev->stats.rx_dropped++;
	}

	pkt_len = uml_vector_recvmsg(vp->fds->rx_fd, &hdr, 0);
	if (pkt_len < 0) {
		vp->in_error = true;
		return pkt_len;
	}

	if (skb != NULL) {
		if (pkt_len > vp->header_size) {
			if (vp->header_size > 0) {
				header_check = vp->verify_header(
					vp->header_rxbuffer, skb, vp);
				if (header_check < 0) {
					dev_kfree_skb_irq(skb);
					vp->dev->stats.rx_dropped++;
					vp->estats.rx_encaps_errors++;
					return 0;
				}
				if (header_check > 0) {
					vp->estats.rx_csum_offload_good++;
					skb->ip_summed = CHECKSUM_UNNECESSARY;
				}
			}
			pskb_trim(skb, pkt_len - vp->rx_header_size);
			skb->protocol = eth_type_trans(skb, skb->dev);
			vp->dev->stats.rx_bytes += skb->len;
			vp->dev->stats.rx_packets++;
			netif_rx(skb);
		} else {
			dev_kfree_skb_irq(skb);
		}
	}
	return pkt_len;
}

/*
 * Packet at a time TX which falls back to vector TX if the
 * underlying transport is busy.
 */



static int writev_tx(struct vector_private *vp, struct sk_buff *skb)
{
	struct iovec iov[3 + MAX_IOV_SIZE];
	int iov_count, pkt_len = 0;

	iov[0].iov_base = vp->header_txbuffer;
	iov_count = prep_msg(vp, skb, (struct iovec *) &iov);

	if (iov_count < 1)
		goto drop;

	pkt_len = uml_vector_writev(
		vp->fds->tx_fd,
		(struct iovec *) &iov,
		iov_count
	);

	if (pkt_len < 0)
		goto drop;

	netif_trans_update(vp->dev);
	netif_wake_queue(vp->dev);

	if (pkt_len > 0) {
		vp->dev->stats.tx_bytes += skb->len;
		vp->dev->stats.tx_packets++;
	} else {
		vp->dev->stats.tx_dropped++;
	}
	consume_skb(skb);
	return pkt_len;
drop:
	vp->dev->stats.tx_dropped++;
	consume_skb(skb);
	if (pkt_len < 0)
		vp->in_error = true;
	return pkt_len;
}

/*
 * Receive as many messages as we can in one call using the special
 * mmsg vector matched to an skb vector which we prepared earlier.
 */

static int vector_mmsg_rx(struct vector_private *vp)
{
	int packet_count, i;
	struct vector_queue *qi = vp->rx_queue;
	struct sk_buff *skb;
	struct mmsghdr *mmsg_vector = qi->mmsg_vector;
	void **skbuff_vector = qi->skbuff_vector;
	int header_check;

	/* Refresh the vector and make sure it is with new skbs and the
	 * iovs are updated to point to them.
	 */

	prep_queue_for_rx(qi);

	/* Fire the Lazy Gun - get as many packets as we can in one go. */

	packet_count = uml_vector_recvmmsg(
		vp->fds->rx_fd, qi->mmsg_vector, qi->max_depth, 0);

	if (packet_count < 0)
		vp->in_error = true;

	if (packet_count <= 0)
		return packet_count;

	/* We treat packet processing as enqueue, buffer refresh as dequeue
	 * The queue_depth tells us how many buffers have been used and how
	 * many do we need to prep the next time prep_queue_for_rx() is called.
	 */

	qi->queue_depth = packet_count;

	for (i = 0; i < packet_count; i++) {
		skb = (*skbuff_vector);
		if (mmsg_vector->msg_len > vp->header_size) {
			if (vp->header_size > 0) {
				header_check = vp->verify_header(
					mmsg_vector->msg_hdr.msg_iov->iov_base,
					skb,
					vp
				);
				if (header_check < 0) {
				/* Overlay header failed to verify - discard.
				 * We can actually keep this skb and reuse it,
				 * but that will make the prep logic too
				 * complex.
				 */
					dev_kfree_skb_irq(skb);
					vp->estats.rx_encaps_errors++;
					continue;
				}
				if (header_check > 0) {
					vp->estats.rx_csum_offload_good++;
					skb->ip_summed = CHECKSUM_UNNECESSARY;
				}
			}
			pskb_trim(skb,
				mmsg_vector->msg_len - vp->rx_header_size);
			skb->protocol = eth_type_trans(skb, skb->dev);
			/*
			 * We do not need to lock on updating stats here
			 * The interrupt loop is non-reentrant.
			 */
			vp->dev->stats.rx_bytes += skb->len;
			vp->dev->stats.rx_packets++;
			netif_rx(skb);
		} else {
			/* Overlay header too short to do anything - discard.
			 * We can actually keep this skb and reuse it,
			 * but that will make the prep logic too complex.
			 */
			if (skb != NULL)
				dev_kfree_skb_irq(skb);
		}
		(*skbuff_vector) = NULL;
		/* Move to the next buffer element */
		mmsg_vector++;
		skbuff_vector++;
	}
	if (packet_count > 0) {
		if (vp->estats.rx_queue_max < packet_count)
			vp->estats.rx_queue_max = packet_count;
		vp->estats.rx_queue_running_average =
			(vp->estats.rx_queue_running_average + packet_count) >> 1;
	}
	return packet_count;
}

static void vector_rx(struct vector_private *vp)
{
	int err;
	int iter = 0;

	if ((vp->options & VECTOR_RX) > 0)
		while (((err = vector_mmsg_rx(vp)) > 0) && (iter < MAX_ITERATIONS))
			iter++;
	else
		while (((err = vector_legacy_rx(vp)) > 0) && (iter < MAX_ITERATIONS))
			iter++;
	if ((err != 0) && net_ratelimit())
		netdev_err(vp->dev, "vector_rx: error(%d)\n", err);
	if (iter == MAX_ITERATIONS)
		netdev_err(vp->dev, "vector_rx: device stuck, remote end may have closed the connection\n");
}

static int vector_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct vector_private *vp = netdev_priv(dev);
	int queue_depth = 0;

	if (vp->in_error) {
		deactivate_fd(vp->fds->rx_fd, vp->rx_irq);
		if ((vp->fds->rx_fd != vp->fds->tx_fd) && (vp->tx_irq != 0))
			deactivate_fd(vp->fds->tx_fd, vp->tx_irq);
		return NETDEV_TX_BUSY;
	}

	if ((vp->options & VECTOR_TX) == 0) {
		writev_tx(vp, skb);
		return NETDEV_TX_OK;
	}

	/* We do BQL only in the vector path, no point doing it in
	 * packet at a time mode as there is no device queue
	 */

	netdev_sent_queue(vp->dev, skb->len);
	queue_depth = vector_enqueue(vp->tx_queue, skb);

	/* if the device queue is full, stop the upper layers and
	 * flush it.
	 */

	if (queue_depth >= vp->tx_queue->max_depth - 1) {
		vp->estats.tx_kicks++;
		netif_stop_queue(dev);
		vector_send(vp->tx_queue);
		return NETDEV_TX_OK;
	}
	if (netdev_xmit_more()) {
		mod_timer(&vp->tl, vp->coalesce);
		return NETDEV_TX_OK;
	}
	if (skb->len < TX_SMALL_PACKET) {
		vp->estats.tx_kicks++;
		vector_send(vp->tx_queue);
	} else
		tasklet_schedule(&vp->tx_poll);
	return NETDEV_TX_OK;
}

static irqreturn_t vector_rx_interrupt(int irq, void *dev_id)
{
	struct net_device *dev = dev_id;
	struct vector_private *vp = netdev_priv(dev);

	if (!netif_running(dev))
		return IRQ_NONE;
	vector_rx(vp);
	return IRQ_HANDLED;

}

static irqreturn_t vector_tx_interrupt(int irq, void *dev_id)
{
	struct net_device *dev = dev_id;
	struct vector_private *vp = netdev_priv(dev);

	if (!netif_running(dev))
		return IRQ_NONE;
	/* We need to pay attention to it only if we got
	 * -EAGAIN or -ENOBUFFS from sendmmsg. Otherwise
	 * we ignore it. In the future, it may be worth
	 * it to improve the IRQ controller a bit to make
	 * tweaking the IRQ mask less costly
	 */

	if (vp->in_write_poll)
		tasklet_schedule(&vp->tx_poll);
	return IRQ_HANDLED;

}

static int irq_rr;

static int vector_net_close(struct net_device *dev)
{
	struct vector_private *vp = netdev_priv(dev);
	unsigned long flags;

	netif_stop_queue(dev);
	del_timer(&vp->tl);

	if (vp->fds == NULL)
		return 0;

	/* Disable and free all IRQS */
	if (vp->rx_irq > 0) {
		um_free_irq(vp->rx_irq, dev);
		vp->rx_irq = 0;
	}
	if (vp->tx_irq > 0) {
		um_free_irq(vp->tx_irq, dev);
		vp->tx_irq = 0;
	}
	tasklet_kill(&vp->tx_poll);
	if (vp->fds->rx_fd > 0) {
		if (vp->bpf)
			uml_vector_detach_bpf(vp->fds->rx_fd, vp->bpf);
		os_close_file(vp->fds->rx_fd);
		vp->fds->rx_fd = -1;
	}
	if (vp->fds->tx_fd > 0) {
		os_close_file(vp->fds->tx_fd);
		vp->fds->tx_fd = -1;
	}
	if (vp->bpf != NULL)
		kfree(vp->bpf->filter);
	kfree(vp->bpf);
	vp->bpf = NULL;
	kfree(vp->fds->remote_addr);
	kfree(vp->transport_data);
	kfree(vp->header_rxbuffer);
	kfree(vp->header_txbuffer);
	if (vp->rx_queue != NULL)
		destroy_queue(vp->rx_queue);
	if (vp->tx_queue != NULL)
		destroy_queue(vp->tx_queue);
	kfree(vp->fds);
	vp->fds = NULL;
	spin_lock_irqsave(&vp->lock, flags);
	vp->opened = false;
	vp->in_error = false;
	spin_unlock_irqrestore(&vp->lock, flags);
	return 0;
}

/* TX tasklet */

static void vector_tx_poll(unsigned long data)
{
	struct vector_private *vp = (struct vector_private *)data;

	vp->estats.tx_kicks++;
	vector_send(vp->tx_queue);
}
static void vector_reset_tx(struct work_struct *work)
{
	struct vector_private *vp =
		container_of(work, struct vector_private, reset_tx);
	netdev_reset_queue(vp->dev);
	netif_start_queue(vp->dev);
	netif_wake_queue(vp->dev);
}

static int vector_net_open(struct net_device *dev)
{
	struct vector_private *vp = netdev_priv(dev);
	unsigned long flags;
	int err = -EINVAL;
	struct vector_device *vdevice;

	spin_lock_irqsave(&vp->lock, flags);
	if (vp->opened) {
		spin_unlock_irqrestore(&vp->lock, flags);
		return -ENXIO;
	}
	vp->opened = true;
	spin_unlock_irqrestore(&vp->lock, flags);

	vp->bpf = uml_vector_user_bpf(get_bpf_file(vp->parsed));

	vp->fds = uml_vector_user_open(vp->unit, vp->parsed);

	if (vp->fds == NULL)
		goto out_close;

	if (build_transport_data(vp) < 0)
		goto out_close;

	if ((vp->options & VECTOR_RX) > 0) {
		vp->rx_queue = create_queue(
			vp,
			get_depth(vp->parsed),
			vp->rx_header_size,
			MAX_IOV_SIZE
		);
		vp->rx_queue->queue_depth = get_depth(vp->parsed);
	} else {
		vp->header_rxbuffer = kmalloc(
			vp->rx_header_size,
			GFP_KERNEL
		);
		if (vp->header_rxbuffer == NULL)
			goto out_close;
	}
	if ((vp->options & VECTOR_TX) > 0) {
		vp->tx_queue = create_queue(
			vp,
			get_depth(vp->parsed),
			vp->header_size,
			MAX_IOV_SIZE
		);
	} else {
		vp->header_txbuffer = kmalloc(vp->header_size, GFP_KERNEL);
		if (vp->header_txbuffer == NULL)
			goto out_close;
	}

	/* READ IRQ */
	err = um_request_irq(
		irq_rr + VECTOR_BASE_IRQ, vp->fds->rx_fd,
			IRQ_READ, vector_rx_interrupt,
			IRQF_SHARED, dev->name, dev);
	if (err != 0) {
		netdev_err(dev, "vector_open: failed to get rx irq(%d)\n", err);
		err = -ENETUNREACH;
		goto out_close;
	}
	vp->rx_irq = irq_rr + VECTOR_BASE_IRQ;
	dev->irq = irq_rr + VECTOR_BASE_IRQ;
	irq_rr = (irq_rr + 1) % VECTOR_IRQ_SPACE;

	/* WRITE IRQ - we need it only if we have vector TX */
	if ((vp->options & VECTOR_TX) > 0) {
		err = um_request_irq(
			irq_rr + VECTOR_BASE_IRQ, vp->fds->tx_fd,
				IRQ_WRITE, vector_tx_interrupt,
				IRQF_SHARED, dev->name, dev);
		if (err != 0) {
			netdev_err(dev,
				"vector_open: failed to get tx irq(%d)\n", err);
			err = -ENETUNREACH;
			goto out_close;
		}
		vp->tx_irq = irq_rr + VECTOR_BASE_IRQ;
		irq_rr = (irq_rr + 1) % VECTOR_IRQ_SPACE;
	}

	if ((vp->options & VECTOR_QDISC_BYPASS) != 0) {
		if (!uml_raw_enable_qdisc_bypass(vp->fds->rx_fd))
			vp->options |= VECTOR_BPF;
	}
	if (((vp->options & VECTOR_BPF) != 0) && (vp->bpf == NULL))
		vp->bpf = uml_vector_default_bpf(dev->dev_addr);

	if (vp->bpf != NULL)
		uml_vector_attach_bpf(vp->fds->rx_fd, vp->bpf);

	netif_start_queue(dev);

	/* clear buffer - it can happen that the host side of the interface
	 * is full when we get here. In this case, new data is never queued,
	 * SIGIOs never arrive, and the net never works.
	 */

	vector_rx(vp);

	vector_reset_stats(vp);
	vdevice = find_device(vp->unit);
	vdevice->opened = 1;

	if ((vp->options & VECTOR_TX) != 0)
		add_timer(&vp->tl);
	return 0;
out_close:
	vector_net_close(dev);
	return err;
}


static void vector_net_set_multicast_list(struct net_device *dev)
{
	/* TODO: - we can do some BPF games here */
	return;
}

static void vector_net_tx_timeout(struct net_device *dev, unsigned int txqueue)
{
	struct vector_private *vp = netdev_priv(dev);

	vp->estats.tx_timeout_count++;
	netif_trans_update(dev);
	schedule_work(&vp->reset_tx);
}

static netdev_features_t vector_fix_features(struct net_device *dev,
	netdev_features_t features)
{
	features &= ~(NETIF_F_IP_CSUM|NETIF_F_IPV6_CSUM);
	return features;
}

static int vector_set_features(struct net_device *dev,
	netdev_features_t features)
{
	struct vector_private *vp = netdev_priv(dev);
	/* Adjust buffer sizes for GSO/GRO. Unfortunately, there is
	 * no way to negotiate it on raw sockets, so we can change
	 * only our side.
	 */
	if (features & NETIF_F_GRO)
		/* All new frame buffers will be GRO-sized */
		vp->req_size = 65536;
	else
		/* All new frame buffers will be normal sized */
		vp->req_size = vp->max_packet + vp->headroom + SAFETY_MARGIN;
	return 0;
}

#ifdef CONFIG_NET_POLL_CONTROLLER
static void vector_net_poll_controller(struct net_device *dev)
{
	disable_irq(dev->irq);
	vector_rx_interrupt(dev->irq, dev);
	enable_irq(dev->irq);
}
#endif

static void vector_net_get_drvinfo(struct net_device *dev,
				struct ethtool_drvinfo *info)
{
	strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver));
}

static int vector_net_load_bpf_flash(struct net_device *dev,
				struct ethtool_flash *efl)
{
	struct vector_private *vp = netdev_priv(dev);
	struct vector_device *vdevice;
	const struct firmware *fw;
	int result = 0;

	if (!(vp->options & VECTOR_BPF_FLASH)) {
		netdev_err(dev, "loading firmware not permitted: %s\n", efl->data);
		return -1;
	}

	spin_lock(&vp->lock);

	if (vp->bpf != NULL) {
		if (vp->opened)
			uml_vector_detach_bpf(vp->fds->rx_fd, vp->bpf);
		kfree(vp->bpf->filter);
		vp->bpf->filter = NULL;
	} else {
		vp->bpf = kmalloc(sizeof(struct sock_fprog), GFP_ATOMIC);
		if (vp->bpf == NULL) {
			netdev_err(dev, "failed to allocate memory for firmware\n");
			goto flash_fail;
		}
	}

	vdevice = find_device(vp->unit);

	if (request_firmware(&fw, efl->data, &vdevice->pdev.dev))
		goto flash_fail;

	vp->bpf->filter = kmemdup(fw->data, fw->size, GFP_ATOMIC);
	if (!vp->bpf->filter)
		goto free_buffer;

	vp->bpf->len = fw->size / sizeof(struct sock_filter);
	release_firmware(fw);

	if (vp->opened)
		result = uml_vector_attach_bpf(vp->fds->rx_fd, vp->bpf);

	spin_unlock(&vp->lock);

	return result;

free_buffer:
	release_firmware(fw);

flash_fail:
	spin_unlock(&vp->lock);
	if (vp->bpf != NULL)
		kfree(vp->bpf->filter);
	kfree(vp->bpf);
	vp->bpf = NULL;
	return -1;
}

static void vector_get_ringparam(struct net_device *netdev,
				struct ethtool_ringparam *ring)
{
	struct vector_private *vp = netdev_priv(netdev);

	ring->rx_max_pending = vp->rx_queue->max_depth;
	ring->tx_max_pending = vp->tx_queue->max_depth;
	ring->rx_pending = vp->rx_queue->max_depth;
	ring->tx_pending = vp->tx_queue->max_depth;
}

static void vector_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
{
	switch (stringset) {
	case ETH_SS_TEST:
		*buf = '\0';
		break;
	case ETH_SS_STATS:
		memcpy(buf, &ethtool_stats_keys, sizeof(ethtool_stats_keys));
		break;
	default:
		WARN_ON(1);
		break;
	}
}

static int vector_get_sset_count(struct net_device *dev, int sset)
{
	switch (sset) {
	case ETH_SS_TEST:
		return 0;
	case ETH_SS_STATS:
		return VECTOR_NUM_STATS;
	default:
		return -EOPNOTSUPP;
	}
}

static void vector_get_ethtool_stats(struct net_device *dev,
	struct ethtool_stats *estats,
	u64 *tmp_stats)
{
	struct vector_private *vp = netdev_priv(dev);

	memcpy(tmp_stats, &vp->estats, sizeof(struct vector_estats));
}

static int vector_get_coalesce(struct net_device *netdev,
					struct ethtool_coalesce *ec)
{
	struct vector_private *vp = netdev_priv(netdev);

	ec->tx_coalesce_usecs = (vp->coalesce * 1000000) / HZ;
	return 0;
}

static int vector_set_coalesce(struct net_device *netdev,
					struct ethtool_coalesce *ec)
{
	struct vector_private *vp = netdev_priv(netdev);

	vp->coalesce = (ec->tx_coalesce_usecs * HZ) / 1000000;
	if (vp->coalesce == 0)
		vp->coalesce = 1;
	return 0;
}

static const struct ethtool_ops vector_net_ethtool_ops = {
	.supported_coalesce_params = ETHTOOL_COALESCE_TX_USECS,
	.get_drvinfo	= vector_net_get_drvinfo,
	.get_link	= ethtool_op_get_link,
	.get_ts_info	= ethtool_op_get_ts_info,
	.get_ringparam	= vector_get_ringparam,
	.get_strings	= vector_get_strings,
	.get_sset_count	= vector_get_sset_count,
	.get_ethtool_stats = vector_get_ethtool_stats,
	.get_coalesce	= vector_get_coalesce,
	.set_coalesce	= vector_set_coalesce,
	.flash_device	= vector_net_load_bpf_flash,
};


static const struct net_device_ops vector_netdev_ops = {
	.ndo_open		= vector_net_open,
	.ndo_stop		= vector_net_close,
	.ndo_start_xmit		= vector_net_start_xmit,
	.ndo_set_rx_mode	= vector_net_set_multicast_list,
	.ndo_tx_timeout		= vector_net_tx_timeout,
	.ndo_set_mac_address	= eth_mac_addr,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_fix_features	= vector_fix_features,
	.ndo_set_features	= vector_set_features,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller = vector_net_poll_controller,
#endif
};


static void vector_timer_expire(struct timer_list *t)
{
	struct vector_private *vp = from_timer(vp, t, tl);

	vp->estats.tx_kicks++;
	vector_send(vp->tx_queue);
}

static void vector_eth_configure(
		int n,
		struct arglist *def
	)
{
	struct vector_device *device;
	struct net_device *dev;
	struct vector_private *vp;
	int err;

	device = kzalloc(sizeof(*device), GFP_KERNEL);
	if (device == NULL) {
		printk(KERN_ERR "eth_configure failed to allocate struct "
				 "vector_device\n");
		return;
	}
	dev = alloc_etherdev(sizeof(struct vector_private));
	if (dev == NULL) {
		printk(KERN_ERR "eth_configure: failed to allocate struct "
				 "net_device for vec%d\n", n);
		goto out_free_device;
	}

	dev->mtu = get_mtu(def);

	INIT_LIST_HEAD(&device->list);
	device->unit = n;

	/* If this name ends up conflicting with an existing registered
	 * netdevice, that is OK, register_netdev{,ice}() will notice this
	 * and fail.
	 */
	snprintf(dev->name, sizeof(dev->name), "vec%d", n);
	uml_net_setup_etheraddr(dev, uml_vector_fetch_arg(def, "mac"));
	vp = netdev_priv(dev);

	/* sysfs register */
	if (!driver_registered) {
		platform_driver_register(&uml_net_driver);
		driver_registered = 1;
	}
	device->pdev.id = n;
	device->pdev.name = DRIVER_NAME;
	device->pdev.dev.release = vector_device_release;
	dev_set_drvdata(&device->pdev.dev, device);
	if (platform_device_register(&device->pdev))
		goto out_free_netdev;
	SET_NETDEV_DEV(dev, &device->pdev.dev);

	device->dev = dev;

	*vp = ((struct vector_private)
		{
		.list			= LIST_HEAD_INIT(vp->list),
		.dev			= dev,
		.unit			= n,
		.options		= get_transport_options(def),
		.rx_irq			= 0,
		.tx_irq			= 0,
		.parsed			= def,
		.max_packet		= get_mtu(def) + ETH_HEADER_OTHER,
		/* TODO - we need to calculate headroom so that ip header
		 * is 16 byte aligned all the time
		 */
		.headroom		= get_headroom(def),
		.form_header		= NULL,
		.verify_header		= NULL,
		.header_rxbuffer	= NULL,
		.header_txbuffer	= NULL,
		.header_size		= 0,
		.rx_header_size		= 0,
		.rexmit_scheduled	= false,
		.opened			= false,
		.transport_data		= NULL,
		.in_write_poll		= false,
		.coalesce		= 2,
		.req_size		= get_req_size(def),
		.in_error		= false,
		.bpf			= NULL
	});

	dev->features = dev->hw_features = (NETIF_F_SG | NETIF_F_FRAGLIST);
	tasklet_init(&vp->tx_poll, vector_tx_poll, (unsigned long)vp);
	INIT_WORK(&vp->reset_tx, vector_reset_tx);

	timer_setup(&vp->tl, vector_timer_expire, 0);
	spin_lock_init(&vp->lock);

	/* FIXME */
	dev->netdev_ops = &vector_netdev_ops;
	dev->ethtool_ops = &vector_net_ethtool_ops;
	dev->watchdog_timeo = (HZ >> 1);
	/* primary IRQ - fixme */
	dev->irq = 0; /* we will adjust this once opened */

	rtnl_lock();
	err = register_netdevice(dev);
	rtnl_unlock();
	if (err)
		goto out_undo_user_init;

	spin_lock(&vector_devices_lock);
	list_add(&device->list, &vector_devices);
	spin_unlock(&vector_devices_lock);

	return;

out_undo_user_init:
	return;
out_free_netdev:
	free_netdev(dev);
out_free_device:
	kfree(device);
}




/*
 * Invoked late in the init
 */

static int __init vector_init(void)
{
	struct list_head *ele;
	struct vector_cmd_line_arg *def;
	struct arglist *parsed;

	list_for_each(ele, &vec_cmd_line) {
		def = list_entry(ele, struct vector_cmd_line_arg, list);
		parsed = uml_parse_vector_ifspec(def->arguments);
		if (parsed != NULL)
			vector_eth_configure(def->unit, parsed);
	}
	return 0;
}


/* Invoked at initial argument parsing, only stores
 * arguments until a proper vector_init is called
 * later
 */

static int __init vector_setup(char *str)
{
	char *error;
	int n, err;
	struct vector_cmd_line_arg *new;

	err = vector_parse(str, &n, &str, &error);
	if (err) {
		printk(KERN_ERR "vector_setup - Couldn't parse '%s' : %s\n",
				 str, error);
		return 1;
	}
	new = memblock_alloc(sizeof(*new), SMP_CACHE_BYTES);
	if (!new)
		panic("%s: Failed to allocate %zu bytes\n", __func__,
		      sizeof(*new));
	INIT_LIST_HEAD(&new->list);
	new->unit = n;
	new->arguments = str;
	list_add_tail(&new->list, &vec_cmd_line);
	return 1;
}

__setup("vec", vector_setup);
__uml_help(vector_setup,
"vec[0-9]+:<option>=<value>,<option>=<value>\n"
"	 Configure a vector io network device.\n\n"
);

late_initcall(vector_init);

static struct mc_device vector_mc = {
	.list		= LIST_HEAD_INIT(vector_mc.list),
	.name		= "vec",
	.config		= vector_config,
	.get_config	= NULL,
	.id		= vector_id,
	.remove		= vector_remove,
};

#ifdef CONFIG_INET
static int vector_inetaddr_event(
	struct notifier_block *this,
	unsigned long event,
	void *ptr)
{
	return NOTIFY_DONE;
}

static struct notifier_block vector_inetaddr_notifier = {
	.notifier_call		= vector_inetaddr_event,
};

static void inet_register(void)
{
	register_inetaddr_notifier(&vector_inetaddr_notifier);
}
#else
static inline void inet_register(void)
{
}
#endif

static int vector_net_init(void)
{
	mconsole_register_dev(&vector_mc);
	inet_register();
	return 0;
}

__initcall(vector_net_init);



