/*
* Copyright (C) 2017 - 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.
* Licensed under the GPL.
*/
#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 <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"
#define DRIVER_VERSION "01"
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)
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)
return result;
}
return E
|