/* File veth.c created by Kyle A. Lucke on Mon Aug  7 2000. */
/*
 * IBM eServer iSeries Virtual Ethernet Device Driver
 * Copyright (C) 2001 Kyle A. Lucke (klucke@us.ibm.com), IBM Corp.
 * Substantially cleaned up by:
 * Copyright (C) 2003 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
 * Copyright (C) 2004-2005 Michael Ellerman, IBM Corporation.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 *
 * This module implements the virtual ethernet device for iSeries LPAR
 * Linux.  It uses hypervisor message passing to implement an
 * ethernet-like network device communicating between partitions on
 * the iSeries.
 *
 * The iSeries LPAR hypervisor currently allows for up to 16 different
 * virtual ethernets.  These are all dynamically configurable on
 * OS/400 partitions, but dynamic configuration is not supported under
 * Linux yet.  An ethXX network device will be created for each
 * virtual ethernet this partition is connected to.
 *
 * - This driver is responsible for routing packets to and from other
 *   partitions.  The MAC addresses used by the virtual ethernets
 *   contains meaning and must not be modified.
 *
 * - Having 2 virtual ethernets to the same remote partition DOES NOT
 *   double the available bandwidth.  The 2 devices will share the
 *   available hypervisor bandwidth.
 *
 * - If you send a packet to your own mac address, it will just be
 *   dropped, you won't get it on the receive side.
 *
 * - Multicast is implemented by sending the frame frame to every
 *   other partition.  It is the responsibility of the receiving
 *   partition to filter the addresses desired.
 *
 * Tunable parameters:
 *
 * VETH_NUMBUFFERS: This compile time option defaults to 120.  It
 * controls how much memory Linux will allocate per remote partition
 * it is communicating with.  It can be thought of as the maximum
 * number of packets outstanding to a remote partition at a time.
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/ethtool.h>
#include <linux/if_ether.h>

#include <asm/abs_addr.h>
#include <asm/iseries/mf.h>
#include <asm/uaccess.h>
#include <asm/firmware.h>
#include <asm/iseries/hv_lp_config.h>
#include <asm/iseries/hv_types.h>
#include <asm/iseries/hv_lp_event.h>
#include <asm/iommu.h>
#include <asm/vio.h>

#undef DEBUG

MODULE_AUTHOR("Kyle Lucke <klucke@us.ibm.com>");
MODULE_DESCRIPTION("iSeries Virtual ethernet driver");
MODULE_LICENSE("GPL");

#define VETH_EVENT_CAP	(0)
#define VETH_EVENT_FRAMES	(1)
#define VETH_EVENT_MONITOR	(2)
#define VETH_EVENT_FRAMES_ACK	(3)

#define VETH_MAX_ACKS_PER_MSG	(20)
#define VETH_MAX_FRAMES_PER_MSG	(6)

struct veth_frames_data {
	u32 addr[VETH_MAX_FRAMES_PER_MSG];
	u16 len[VETH_MAX_FRAMES_PER_MSG];
	u32 eofmask;
};
#define VETH_EOF_SHIFT		(32-VETH_MAX_FRAMES_PER_MSG)

struct veth_frames_ack_data {
	u16 token[VETH_MAX_ACKS_PER_MSG];
};

struct veth_cap_data {
	u8 caps_version;
	u8 rsvd1;
	u16 num_buffers;
	u16 ack_threshold;
	u16 rsvd2;
	u32 ack_timeout;
	u32 rsvd3;
	u64 rsvd4[3];
};

struct veth_lpevent {
	struct HvLpEvent base_event;
	union {
		struct veth_cap_data caps_data;
		struct veth_frames_data frames_data;
		struct veth_frames_ack_data frames_ack_data;
	} u;

};

#define DRV_NAME	"iseries_veth"
#define DRV_VERSION	"2.0"

#define VETH_NUMBUFFERS		(120)
#define VETH_ACKTIMEOUT 	(1000000) /* microseconds */
#define VETH_MAX_MCAST		(12)

#define VETH_MAX_MTU		(9000)

#if VETH_NUMBUFFERS < 10
#define ACK_THRESHOLD 		(1)
#elif VETH_NUMBUFFERS < 20
#define ACK_THRESHOLD 		(4)
#elif VETH_NUMBUFFERS < 40
#define ACK_THRESHOLD 		(10)
#else
#define ACK_THRESHOLD 		(20)
#endif

#define	VETH_STATE_SHUTDOWN	(0x0001)
#define VETH_STATE_OPEN		(0x0002)
#define VETH_STATE_RESET	(0x0004)
#define VETH_STATE_SENTMON	(0x0008)
#define VETH_STATE_SENTCAPS	(0x0010)
#define VETH_STATE_GOTCAPACK	(0x0020)
#define VETH_STATE_GOTCAPS	(0x0040)
#define VETH_STATE_SENTCAPACK	(0x0080)
#define VETH_STATE_READY	(0x0100)

struct veth_msg {
	struct veth_msg *next;
	struct veth_frames_data data;
	int token;
	int in_use;
	struct sk_buff *skb;
	struct device *dev;
};

struct veth_lpar_connection {
	HvLpIndex remote_lp;
	struct delayed_work statemachine_wq;
	struct veth_msg *msgs;
	int num_events;
	struct veth_cap_data local_caps;

	struct kobject kobject;
	struct timer_list ack_timer;

	struct timer_list reset_timer;
	unsigned int reset_timeout;
	unsigned long last_contact;
	int outstanding_tx;

	spinlock_t lock;
	unsigned long state;
	HvLpInstanceId src_inst;
	HvLpInstanceId dst_inst;
	struct veth_lpevent cap_event, cap_ack_event;
	u16 pending_acks[VETH_MAX_ACKS_PER_MSG];
	u32 num_pending_acks;

	int num_ack_events;
	struct veth_cap_data remote_caps;
	u32 ack_timeout;

	struct veth_msg *msg_stack_head;
};

struct veth_port {
	struct device *dev;
	struct net_device_stats stats;
	u64 mac_addr;
	HvLpIndexMap lpar_map;

	/* queue_lock protects the stopped_map and dev's queue. */
	spinlock_t queue_lock;
	HvLpIndexMap stopped_map;

	/* mcast_gate protects promiscuous, num_mcast & mcast_addr. */
	rwlock_t mcast_gate;
	int promiscuous;
	int num_mcast;
	u64 mcast_addr[VETH_MAX_MCAST];

	struct kobject kobject;
};

static HvLpIndex this_lp;
static struct veth_lpar_connection *veth_cnx[HVMAXARCHITECTEDLPS]; /* = 0 */
static struct net_device *veth_dev[HVMAXARCHITECTEDVIRTUALLANS]; /* = 0 */

static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev);
static void veth_recycle_msg(struct veth_lpar_connection *, struct veth_msg *);
static void veth_wake_queues(struct veth_lpar_connection *cnx);
static void veth_stop_queues(struct veth_lpar_connection *cnx);
static void veth_receive(struct veth_lpar_connection *, struct veth_lpevent *);
static void veth_release_connection(struct kobject *kobject);
static void veth_timed_ack(unsigned long ptr);
static void veth_timed_reset(unsigned long ptr);

/*
 * Utility functions
 */

#define veth_info(fmt, args...) \
	printk(KERN_INFO DRV_NAME ": " fmt, ## args)

#define veth_error(fmt, args...) \
	printk(KERN_ERR DRV_NAME ": Error: " fmt, ## args)

#ifdef DEBUG
#define veth_debug(fmt, args...) \
	printk(KERN_DEBUG DRV_NAME ": " fmt, ## args)
#else
#define veth_debug(fmt, args...) do {} while (0)
#endif

/* You must hold the connection's lock when you call this function. */
static inline void veth_stack_push(struct veth_lpar_connection *cnx,
				   struct veth_msg *msg)
{
	msg->next = cnx->msg_stack_head;
	cnx->msg_stack_head = msg;
}

/* You must hold the connection's lock when you call this function. */
static inline struct veth_msg *veth_stack_pop(struct veth_lpar_connection *cnx)
{
	struct veth_msg *msg;

	msg = cnx->msg_stack_head;
	if (msg)
		cnx->msg_stack_head = cnx->msg_stack_head->next;

	return msg;
}

/* You must hold the connection's lock when you call this function. */
static inline int veth_stack_is_empty(struct veth_lpar_connection *cnx)
{
	return cnx->msg_stack_head == NULL;
}

static inline HvLpEvent_Rc
veth_signalevent(struct veth_lpar_connection *cnx, u16 subtype,
		 HvLpEvent_AckInd ackind, HvLpEvent_AckType acktype,
		 u64 token,
		 u64 data1, u64 data2, u64 data3, u64 data4, u64 data5)
{
	return HvCallEvent_signalLpEventFast(cnx->remote_lp,
					     HvLpEvent_Type_VirtualLan,
					     subtype, ackind, acktype,
					     cnx->src_inst,
					     cnx->dst_inst,
					     token, data1, data2, data3,
					     data4, data5);
}

static inline HvLpEvent_Rc veth_signaldata(struct veth_lpar_connection *cnx,
					   u16 subtype, u64 token, void *data)
{
	u64 *p = (u64 *) data;

	return veth_signalevent(cnx, subtype, HvLpEvent_AckInd_NoAck,
				HvLpEvent_AckType_ImmediateAck,
				token, p[0], p[1], p[2], p[3], p[4]);
}

struct veth_allocation {
	struct completion c;
	int num;
};

static void veth_complete_allocation(void *parm, int number)
{
	struct veth_allocation *vc = (struct veth_allocation *)parm;

	vc->num = number;
	complete(&vc->c);
}

static int veth_allocate_events(HvLpIndex rlp, int number)
{
	struct veth_allocation vc = { COMPLETION_INITIALIZER(vc.c), 0 };

	mf_allocate_lp_events(rlp, HvLpEvent_Type_VirtualLan,
			    sizeof(struct veth_lpevent), number,
			    &veth_complete_allocation, &vc);
	wait_for_completion(&vc.c);

	return vc.num;
}

/*
 * sysfs support
 */

struct veth_cnx_attribute {
	struct attribute attr;
	ssize_t (*show)(struct veth_lpar_connection *, char *buf);
	ssize_t (*store)(struct veth_lpar_connection *, const char *buf);
};

static ssize_t veth_cnx_attribute_show(struct kobject *kobj,
		struct attribute *attr, char *buf)
{
	struct veth_cnx_attribute *cnx_attr;
	struct veth_lpar_connection *cnx;

	cnx_attr = container_of(attr, struct veth_cnx_attribute, attr);
	cnx = container_of(kobj, struct veth_lpar_connection, kobject);

	if (!cnx_attr->show)
		return -EIO;

	return cnx_attr->show(cnx, buf);
}

#define CUSTOM_CNX_ATTR(_name, _format, _expression)			\
static ssize_t _name##_show(struct veth_lpar_connection *cnx, char *buf)\
{									\
	return sprintf(buf, _format, _expression);			\
}									\
struct veth_cnx_attribute veth_cnx_attr_##_name = __ATTR_RO(_name)

#define SIMPLE_CNX_ATTR(_name)	\
	CUSTOM_CNX_ATTR(_name, "%lu\n", (unsigned long)cnx->_name)

SIMPLE_CNX_ATTR(outstanding_tx);
SIMPLE_CNX_ATTR(remote_lp);
SIMPLE_CNX_ATTR(num_events);
SIMPLE_CNX_ATTR(src_inst);
SIMPLE_CNX_ATTR(dst_inst);
SIMPLE_CNX_ATTR(num_pending_acks);
SIMPLE_CNX_ATTR(num_ack_events);
CUSTOM_CNX_ATTR(ack_timeout, "%d\n", jiffies_to_msecs(cnx->ack_timeout));
CUSTOM_CNX_ATTR(reset_timeout, "%d\n", jiffies_to_msecs(cnx->reset_timeout));
CUSTOM_CNX_ATTR(state, "0x%.4lX\n", cnx->state);
CUSTOM_CNX_ATTR(last_contact, "%d\n", cnx->last_contact ?
		jiffies_to_msecs(jiffies - cnx->last_contact) : 0);

#define GET_CNX_ATTR(_name)	(&veth_cnx_attr_##_name.attr)

static struct attribute *veth_cnx_default_attrs[] = {
	GET_CNX_ATTR(outstanding_tx),
	GET_CNX_ATTR(remote_lp),
	GET_CNX_ATTR(num_events),
	GET_CNX_ATTR(reset_timeout),
	GET_CNX_ATTR(last_contact),
	GET_CNX_ATTR(state),
	GET_CNX_ATTR(src_inst),
	GET_CNX_ATTR(dst_inst),
	GET_CNX_ATTR(num_pending_acks),
	GET_CNX_ATTR(num_ack_events),
	GET_CNX_ATTR(ack_timeout),
	NULL
};

static struct sysfs_ops veth_cnx_sysfs_ops = {
		.show = veth_cnx_attribute_show
};

static struct kobj_type veth_lpar_connection_ktype = {
	.release	= veth_release_connection,
	.sysfs_ops	= &veth_cnx_sysfs_ops,
	.default_attrs	= veth_cnx_default_attrs
};

struct veth_port_attribute {
	struct attribute attr;
	ssize_t (*show)(struct veth_port *, char *buf);
	ssize_t (*store)(struct veth_port *, const char *buf);
};

static ssize_t veth_port_attribute_show(struct kobject *kobj,
		struct attribute *attr, char *buf)
{
	struct veth_port_attribute *port_attr;
	struct veth_port *port;

	port_attr = container_of(attr, struct veth_port_attribute, attr);
	port = container_of(kobj, struct veth_port, kobject);

	if (!port_attr->show)
		return -EIO;

	return port_attr->show(port, buf);
}

#define CUSTOM_PORT_ATTR(_name, _format, _expression)			\
static ssize_t _name##_show(struct veth_port *port, char *buf)		\
{									\
	return sprintf(buf, _format, _expression);			\
}									\
struct veth_port_attribute veth_port_attr_##_name = __ATTR_RO(_name)

#define SIMPLE_PORT_ATTR(_name)	\
	CUSTOM_PORT_ATTR(_name, "%lu\n", (unsigned long)port->_name)

SIMPLE_PORT_ATTR(promiscuous);
SIMPLE_PORT_ATTR(num_mcast);
CUSTOM_PORT_ATTR(lpar_map, "0x%X\n", port->lpar_map);
CUSTOM_PORT_ATTR(stopped_map, "0x%X\n", port->stopped_map);
CUSTOM_PORT_ATTR(mac_addr, "0x%lX\n", port->mac_addr);

#define GET_PORT_ATTR(_name)	(&veth_port_attr_##_name.attr)
static struct attribute *veth_port_default_attrs[] = {
	GET_PORT_ATTR(mac_addr),
	GET_PORT_ATTR(lpar_map),
	GET_PORT_ATTR(stopped_map),
	GET_PORT_ATTR(promiscuous),
	GET_PORT_ATTR(num_mcast),
	NULL
};

static struct sysfs_ops veth_port_sysfs_ops = {
	.show = veth_port_attribute_show
};

static struct kobj_type veth_port_ktype = {
	.sysfs_ops	= &veth_port_sysfs_ops,
	.default_attrs	= veth_port_default_attrs
};

/*
 * LPAR connection code
 */

static inline void veth_kick_statemachine(struct veth_lpar_connection *cnx)
{
	schedule_delayed_work(&cnx->statemachine_wq, 0);
}

static void veth_take_cap(struct veth_lpar_connection *cnx,
			  struct veth_lpevent *event)
{
	unsigned long flags;

	spin_lock_irqsave(&cnx->lock, flags);
	/* Receiving caps may mean the other end has just come up, so
	 * we need to reload the instance ID of the far end */
	cnx->dst_inst =
		HvCallEvent_getTargetLpInstanceId(cnx->remote_lp,
						  HvLpEvent_Type_VirtualLan);

	if (cnx->state & VETH_STATE_GOTCAPS) {
		veth_error("Received a second capabilities from LPAR %d.\n",
			   cnx->remote_lp);
		event->base_event.xRc = HvLpEvent_Rc_BufferNotAvailable;
		HvCallEvent_ackLpEvent((struct HvLpEvent *) event);
	} else {
		memcpy(&cnx->cap_event, event, sizeof(cnx->cap_event));
		cnx->state |= VETH_STATE_GOTCAPS;
		veth_kick_statemachine(cnx);
	}
	spin_unlock_irqrestore(&cnx->lock, flags);
}

static void veth_take_cap_ack(struct veth_lpar_connection *cnx,
			      struct veth_lpevent *event)
{
	unsigned long flags;

	spin_lock_irqsave(&cnx->lock, flags);
	if (cnx->state & VETH_STATE_GOTCAPACK) {
		veth_error("Received a second capabilities ack from LPAR %d.\n",
			   cnx->remote_lp);
	} else {
		memcpy(&cnx->cap_ack_event, event,
		       sizeof(&cnx->cap_ack_event));
		cnx->state |= VETH_STATE_GOTCAPACK;
		veth_kick_statemachine(cnx);
	}
	spin_unlock_irqrestore(&cnx->lock, flags);
}

static void veth_take_monitor_ack(struct veth_lpar_connection *cnx,
				  struct veth_lpevent *event)
{
	unsigned long flags;

	spin_lock_irqsave(&cnx->lock, flags);
	veth_debug("cnx %d: lost connection.\n", cnx->remote_lp);

	/* Avoid kicking the statemachine once we're shutdown.
	 * It's unnecessary and it could break veth_stop_connection(). */

	if (! (cnx->state & VETH_STATE_SHUTDOWN)) {
		cnx->state |= VETH_STATE_RESET;
		veth_kick_statemachine(cnx);
	}
	spin_unlock_irqrestore(&cnx->lock, flags);
}

static void veth_handle_ack(struct veth_lpevent *event)
{
	HvLpIndex rlp = event->base_event.xTargetLp;
	struct veth_lpar_connection *cnx = veth_cnx[rlp];

	BUG_ON(! cnx);

	switch (event->base_event.xSubtype) {
	case VETH_EVENT_CAP:
		veth_take_cap_ack(cnx, event);
		break;
	case VETH_EVENT_MONITOR:
		veth_take_monitor_ack(cnx, event);
		break;
	default:
		veth_error("Unknown ack type %d from LPAR %d.\n",
				event->base_event.xSubtype, rlp);
	};
}

static void veth_handle_int(struct veth_lpevent *event)
{
	HvLpIndex rlp = event->base_event.xSourceLp;
	struct veth_lpar_connection *cnx = veth_cnx[rlp];
	unsigned long flags;
	int i, acked = 0;

	BUG_ON(! cnx);

	switch (event->base_event.xSubtype) {
	case VETH_EVENT_CAP:
		veth_take_cap(cnx, event);
		break;
	case VETH_EVENT_MONITOR:
		/* do nothing... this'll hang out here til we're dead,
		 * and the hypervisor will return it for us. */
		break;
	case VETH_EVENT_FRAMES_ACK:
		spin_lock_irqsave(&cnx->lock, flags);

		for (i = 0; i < VETH_MAX_ACKS_PER_MSG; ++i) {
			u16 msgnum = event->u.frames_ack_data.token[i];

			if (msgnum < VETH_NUMBUFFERS) {
				veth_recycle_msg(cnx, cnx->msgs + msgnum);
				cnx->outstanding_tx--;
				acked++;
			}
		}

		if (acked > 0) {
			cnx->last_contact = jiffies;
			veth_wake_queues(cnx);
		}

		spin_unlock_irqrestore(&cnx->lock, flags);
		break;
	case VETH_EVENT_FRAMES:
		veth_receive(cnx, event);
		break;
	default:
		veth_error("Unknown interrupt type %d from LPAR %d.\n",
				event->base_event.xSubtype, rlp);
	};
}

static void veth_handle_event(struct HvLpEvent *event)
{
	struct veth_lpevent *veth_event = (struct veth_lpevent *)event;

	if (hvlpevent_is_ack(event))
		veth_handle_ack(veth_event);
	else
		veth_handle_int(veth_event);
}

static int veth_process_caps(struct veth_lpar_connection *cnx)
{
	struct veth_cap_data *remote_caps = &cnx->remote_caps;
	int num_acks_needed;

	/* Convert timer to jiffies */
	cnx->ack_timeout = remote_caps->ack_timeout * HZ / 1000000;

	if ( (remote_caps->num_buffers == 0)
	     || (remote_caps->ack_threshold > VETH_MAX_ACKS_PER_MSG)
	     || (remote_caps->ack_threshold == 0)
	     || (cnx->ack_timeout == 0) ) {
		veth_error("Received incompatible capabilities from LPAR %d.\n",
				cnx->remote_lp);
		return HvLpEvent_Rc_InvalidSubtypeData;
	}

	num_acks_needed = (remote_caps->num_buffers
			   / remote_caps->ack_threshold) + 1;

	/* FIXME: locking on num_ack_events? */
	if (cnx->num_ack_events < num_acks_needed) {
		int num;

		num = veth_allocate_events(cnx->remote_lp,
					   num_acks_needed-cnx->num_ack_events);
		if (num > 0)
			cnx->num_ack_events += num;

		if (cnx->num_ack_events < num_acks_needed) {
			veth_error("Couldn't allocate enough ack events "
					"for LPAR %d.\n", cnx->remote_lp);

			return HvLpEvent_Rc_BufferNotAvailable;
		}
	}


	return HvLpEvent_Rc_Good;
}

/* FIXME: The gotos here are a bit dubious */
static void veth_statemachine(struct work_struct *work)
{
	struct veth_lpar_connection *cnx =
		container_of(work, struct veth_lpar_connection,
			     statemachine_wq.work);
	int rlp = cnx->remote_lp;
	int rc;

	spin_lock_irq(&cnx->lock);

 restart:
	if (cnx->state & VETH_STATE_RESET) {
		if (cnx->state & VETH_STATE_OPEN)
			HvCallEvent_closeLpEventPath(cnx->remote_lp,
						     HvLpEvent_Type_VirtualLan);

		/*
		 * Reset ack data. This prevents the ack_timer actually
		 * doing anything, even if it runs one more time when
		 * we drop the lock below.
		 */
		memset(&cnx->pending_acks, 0xff, sizeof (cnx->pending_acks));
		cnx->num_pending_acks = 0;

		cnx->state &= ~(VETH_STATE_RESET | VETH_STATE_SENTMON
				| VETH_STATE_OPEN | VETH_STATE_SENTCAPS
				| VETH_STATE_GOTCAPACK | VETH_STATE_GOTCAPS
				| VETH_STATE_SENTCAPACK | VETH_STATE_READY);

		/* Clean up any leftover messages */
		if (cnx->msgs) {
			int i;
			for (i = 0; i < VETH_NUMBUFFERS; ++i)
				veth_recycle_msg(cnx, cnx->msgs + i);
		}

		cnx->outstanding_tx = 0;
		veth_wake_queues(cnx);

		/* Drop the lock so we can do stuff that might sleep or
		 * take other locks. */
		spin_unlock_irq(&cnx->lock);

		del_timer_sync(&cnx->ack_timer);
		del_timer_sync(&cnx->reset_timer);

		spin_lock_irq(&cnx->lock);

		if (cnx->state & VETH_STATE_RESET)
			goto restart;

		/* Hack, wait for the other end to reset itself. */
		if (! (cnx->state & VETH_STATE_SHUTDOWN)) {
			schedule_delayed_work(&cnx->statemachine_wq, 5 * HZ);
			goto out;
		}
	}

	if (cnx->state & VETH_STATE_SHUTDOWN)
		/* It's all over, do nothing */
		goto out;

	if ( !(cnx->state & VETH_STATE_OPEN) ) {
		if (! cnx->msgs || (cnx->num_events < (2 + VETH_NUMBUFFERS)) )
			goto cant_cope;

		HvCallEvent_openLpEventPath(rlp, HvLpEvent_Type_VirtualLan);
		cnx->src_inst =
			HvCallEvent_getSourceLpInstanceId(rlp,
							  HvLpEvent_Type_VirtualLan);
		cnx->dst_inst =
			HvCallEvent_getTargetLpInstanceId(rlp,
							  HvLpEvent_Type_VirtualLan);
		cnx->state |= VETH_STATE_OPEN;
	}

	if ( (cnx->state & VETH_STATE_OPEN)
	     && !(cnx->state & VETH_STATE_SENTMON) ) {
		rc = veth_signalevent(cnx, VETH_EVENT_MONITOR,
				      HvLpEvent_AckInd_DoAck,
				      HvLpEvent_AckType_DeferredAck,
				      0, 0, 0, 0, 0, 0);

		if (rc == HvLpEvent_Rc_Good) {
			cnx->state |= VETH_STATE_SENTMON;
		} else {
			if ( (rc != HvLpEvent_Rc_PartitionDead)
			     && (rc != HvLpEvent_Rc_PathClosed) )
				veth_error("Error sending monitor to LPAR %d, "
						"rc = %d\n", rlp, rc);

			/* Oh well, hope we get a cap from the other
			 * end and do better when that kicks us */
			goto out;
		}
	}

	if ( (cnx->state & VETH_STATE_OPEN)
	     && !(cnx->state & VETH_STATE_SENTCAPS)) {
		u64 *rawcap = (u64 *)&cnx->local_caps;

		rc = veth_signalevent(cnx, VETH_EVENT_CAP,
				      HvLpEvent_AckInd_DoAck,
				      HvLpEvent_AckType_ImmediateAck,
				      0, rawcap[0], rawcap[1], rawcap[2],
				      rawcap[3], rawcap[4]);

		if (rc == HvLpEvent_Rc_Good) {
			cnx->state |= VETH_STATE_SENTCAPS;
		} else {
			if ( (rc != HvLpEvent_Rc_PartitionDead)
			     && (rc != HvLpEvent_Rc_PathClosed) )
				veth_error("Error sending caps to LPAR %d, "
						"rc = %d\n", rlp, rc);

			/* Oh well, hope we get a cap from the other
			 * end and do better when that kicks us */
			goto out;
		}
	}

	if ((cnx->state & VETH_STATE_GOTCAPS)
	    && !(cnx->state & VETH_STATE_SENTCAPACK)) {
		struct veth_cap_data *remote_caps = &cnx->remote_caps;

		memcpy(remote_caps, &cnx->cap_event.u.caps_data,
		       sizeof(*remote_caps));

		spin_unlock_irq(&cnx->lock);
		rc = veth_process_caps(cnx);
		spin_lock_irq(&cnx->lock);

		/* We dropped the lock, so recheck for anything which
		 * might mess us up */
		if (cnx->state & (VETH_STATE_RESET|VETH_STATE_SHUTDOWN))
			goto restart;

		cnx->cap_event.base_event.xRc = rc;
		HvCallEvent_ackLpEvent((struct HvLpEvent *)&cnx->cap_event);
		if (rc == HvLpEvent_Rc_Good)
			cnx->state |= VETH_STATE_SENTCAPACK;
		else
			goto cant_cope;
	}

	if ((cnx->state & VETH_STATE_GOTCAPACK)
	    && (cnx->state & VETH_STATE_GOTCAPS)
	    && !(cnx->state & VETH_STATE_READY)) {
		if (cnx->cap_ack_event.base_event.xRc == HvLpEvent_Rc_Good) {
			/* Start the ACK timer */
			cnx->ack_timer.expires = jiffies + cnx->ack_timeout;
			add_timer(&cnx->ack_timer);
			cnx->state |= VETH_STATE_READY;
		} else {
			veth_error("Caps rejected by LPAR %d, rc = %d\n",
					rlp, cnx->cap_ack_event.base_event.xRc);
			goto cant_cope;
		}
	}

 out:
	spin_unlock_irq(&cnx->lock);
	return;

 cant_cope:
	/* FIXME: we get here if something happens we really can't
	 * cope with.  The link will never work once we get here, and
	 * all we can do is not lock the rest of the system up */
	veth_error("Unrecoverable error on connection to LPAR %d, shutting down"
			" (state = 0x%04lx)\n", rlp, cnx->state);
	cnx->state |= VETH_STATE_SHUTDOWN;
	spin_unlock_irq(&cnx->lock);
}

static int veth_init_connection(u8 rlp)
{
	struct veth_lpar_connection *cnx;
	struct veth_msg *msgs;
	int i, rc;

	if ( (rlp == this_lp)
	     || ! HvLpConfig_doLpsCommunicateOnVirtualLan(this_lp, rlp) )
		return 0;

	cnx = kmalloc(sizeof(*cnx), GFP_KERNEL);
	if (! cnx)
		return -ENOMEM;
	memset(cnx, 0, sizeof(*cnx));

	cnx->remote_lp = rlp;
	spin_lock_init(&cnx->lock);
	INIT_DELAYED_WORK(&cnx->statemachine_wq, veth_statemachine);

	init_timer(&cnx->ack_timer);
	cnx->ack_timer.function = veth_timed_ack;
	cnx->ack_timer.data = (unsigned long) cnx;

	init_timer(&cnx->reset_timer);
	cnx->reset_timer.function = veth_timed_reset;
	cnx->reset_timer.data = (unsigned long) cnx;
	cnx->reset_timeout = 5 * HZ * (VETH_ACKTIMEOUT / 1000000);

	memset(&cnx->pending_acks, 0xff, sizeof (cnx->pending_acks));

	veth_cnx[rlp] = cnx;

	/* This gets us 1 reference, which is held on behalf of the driver
	 * infrastructure. It's released at module unload. */
	kobject_init(&cnx->kobject);
	cnx->kobject.ktype = &veth_lpar_connection_ktype;
	rc = kobject_set_name(&cnx->kobject, "cnx%.2d", rlp);
	if (rc != 0)
		return rc;

	msgs = kmalloc(VETH_NUMBUFFERS * sizeof(struct veth_msg), GFP_KERNEL);
	if (! msgs) {
		veth_error("Can't allocate buffers for LPAR %d.\n", rlp);
		return -ENOMEM;
	}

	cnx->msgs = msgs;
	memset(msgs, 0, VETH_NUMBUFFERS * sizeof(struct veth_msg));

	for (i = 0; i < VETH_NUMBUFFERS; i++) {
		msgs[i].token = i;
		veth_stack_push(cnx, msgs + i);
	}

	cnx->num_events = veth_allocate_events(rlp, 2 + VETH_NUMBUFFERS);

	if (cnx->num_events < (2 + VETH_NUMBUFFERS)) {
		veth_error("Can't allocate enough events for LPAR %d.\n", rlp);
		return -ENOMEM;
	}

	cnx->local_caps.num_buffers = VETH_NUMBUFFERS;
	cnx->local_caps.ack_threshold = ACK_THRESHOLD;
	cnx->local_caps.ack_timeout = VETH_ACKTIMEOUT;

	return 0;
}

static void veth_stop_connection(struct veth_lpar_connection *cnx)
{
	if (!cnx)
		return;

	spin_lock_irq(&cnx->lock);
	cnx->state |= VETH_STATE_RESET | VETH_STATE_SHUTDOWN;
	veth_kick_statemachine(cnx);
	spin_unlock_irq(&cnx->lock);

	/* There's a slim chance the reset code has just queued the
	 * statemachine to run in five seconds. If so we need to cancel
	 * that and requeue the work to run now. */
	if (cancel_delayed_work(&cnx->statemachine_wq)) {
		spin_lock_irq(&cnx->lock);
		veth_kick_statemachine(cnx);
		spin_unlock_irq(&cnx->lock);
	}

	/* Wait for the state machine to run. */
	flush_scheduled_work();
}

static void veth_destroy_connection(struct veth_lpar_connection *cnx)
{
	if (!cnx)
		return;

	if (cnx->num_events > 0)
		mf_deallocate_lp_events(cnx->remote_lp,
				      HvLpEvent_Type_VirtualLan,
				      cnx->num_events,
				      NULL, NULL);
	if (cnx->num_ack_events > 0)
		mf_deallocate_lp_events(cnx->remote_lp,
				      HvLpEvent_Type_VirtualLan,
				      cnx->num_ack_events,
				      NULL, NULL);

	kfree(cnx->msgs);
	veth_cnx[cnx->remote_lp] = NULL;
	kfree(cnx);
}

static void veth_release_connection(struct kobject *kobj)
{
	struct veth_lpar_connection *cnx;
	cnx = container_of(kobj, struct veth_lpar_connection, kobject);
	veth_stop_connection(cnx);
	veth_destroy_connection(cnx);
}

/*
 * net_device code
 */

static int veth_open(struct net_device *dev)
{
	struct veth_port *port = (struct veth_port *) dev->priv;

	memset(&port->stats, 0, sizeof (port->stats));
	netif_start_queue(dev);
	return 0;
}

static int veth_close(struct net_device *dev)
{
	netif_stop_queue(dev);
	return 0;
}

static struct net_device_stats *veth_get_stats(struct net_device *dev)
{
	struct veth_port *port = (struct veth_port *) dev->priv;

	return &port->stats;
}

static int veth_change_mtu(struct net_device *dev, int new_mtu)
{
	if ((new_mtu < 68) || (new_mtu > VETH_MAX_MTU))
		return -EINVAL;
	dev->mtu = new_mtu;
	return 0;
}

static void veth_set_multicast_list(struct net_device *dev)
{
	struct veth_port *port = (struct veth_port *) dev->priv;
	unsigned long flags;

	write_lock_irqsave(&port->mcast_gate, flags);

	if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI) ||
			(dev->mc_count > VETH_MAX_MCAST)) {
		port->promiscuous = 1;
	} else {
		struct dev_mc_list *dmi = dev->mc_list;
		int i;

		port->promiscuous = 0;

		/* Update table */
		port->num_mcast = 0;

		for (i = 0; i < dev->mc_count; i++) {
			u8 *addr = dmi->dmi_addr;
			u64 xaddr = 0;

			if (addr[0] & 0x01) {/* multicast address? */
				memcpy(&xaddr, addr, ETH_ALEN);
				port->mcast_addr[port->num_mcast] = xaddr;
				port->num_mcast++;
			}
			dmi = dmi->next;
		}
	}

	write_unlock_irqrestore(&port->mcast_gate, flags);
}

static void veth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
	strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1);
	info->driver[sizeof(info->driver) - 1] = '\0';
	strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1);
	info->version[sizeof(info->version) - 1] = '\0';
}

static int veth_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
{
	ecmd->supported = (SUPPORTED_1000baseT_Full
			  | SUPPORTED_Autoneg | SUPPORTED_FIBRE);
	ecmd->advertising = (SUPPORTED_1000baseT_Full
			    | SUPPORTED_Autoneg | SUPPORTED_FIBRE);
	ecmd->port = PORT_FIBRE;
	ecmd->transceiver = XCVR_INTERNAL;
	ecmd->phy_address = 0;
	ecmd->speed = SPEED_1000;
	ecmd->duplex = DUPLEX_FULL;
	ecmd->autoneg = AUTONEG_ENABLE;
	ecmd->maxtxpkt = 120;
	ecmd->maxrxpkt = 120;
	return 0;
}

static u32 veth_get_link(struct net_device *dev)
{
	return 1;
}

static const struct ethtool_ops ops = {
	.get_drvinfo = veth_get_drvinfo,
	.get_settings = veth_get_settings,
	.get_link = veth_get_link,
};

static struct net_device * __init veth_probe_one(int vlan,
		struct vio_dev *vio_dev)
{
	struct net_device *dev;
	struct veth_port *port;
	struct device *vdev = &vio_dev->dev;
	int i, rc;
	const unsigned char *mac_addr;

	mac_addr = vio_get_attribute(vio_dev, "local-mac-address", NULL);
	if (mac_addr == NULL)
		mac_addr = vio_get_attribute(vio_dev, "mac-address", NULL);
	if (mac_addr == NULL) {
		veth_error("Unable to fetch MAC address from device tree.\n");
		return NULL;
	}

	dev = alloc_etherdev(sizeof (struct veth_port));
	if (! dev) {
		veth_error("Unable to allocate net_device structure!\n");
		return NULL;
	}

	port = (struct veth_port *) dev->priv;

	spin_lock_init(&port->queue_lock);
	rwlock_init(&port->mcast_gate);
	port->stopped_map = 0;

	for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
		HvLpVirtualLanIndexMap map;

		if (i == this_lp)
			continue;
		map = HvLpConfig_getVirtualLanIndexMapForLp(i);
		if (map & (0x8000 >> vlan))
			port->lpar_map |= (1 << i);
	}
	port->dev = vdev;

	memcpy(dev->dev_addr, mac_addr, ETH_ALEN);

	dev->mtu = VETH_MAX_MTU;

	memcpy(&port->mac_addr, mac_addr, ETH_ALEN);

	dev->open = veth_open;
	dev->hard_start_xmit = veth_start_xmit;
	dev->stop = veth_close;
	dev->get_stats = veth_get_stats;
	dev->change_mtu = veth_change_mtu;
	dev->set_mac_address = NULL;
	dev->set_multicast_list = veth_set_multicast_list;
	SET_ETHTOOL_OPS(dev, &ops);

	SET_NETDEV_DEV(dev, vdev);

	rc = register_netdev(dev);
	if (rc != 0) {
		veth_error("Failed registering net device for vlan%d.\n", vlan);
		free_netdev(dev);
		return NULL;
	}

	kobject_init(&port->kobject);
	port->kobject.parent = &dev->class_dev.kobj;
	port->kobject.ktype  = &veth_port_ktype;
	kobject_set_name(&port->kobject, "veth_port");
	if (0 != kobject_add(&port->kobject))
		veth_error("Failed adding port for %s to sysfs.\n", dev->name);

	veth_info("%s attached to iSeries vlan %d (LPAR map = 0x%.4X)\n",
			dev->name, vlan, port->lpar_map);

	return dev;
}

/*
 * Tx path
 */

static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp,
				struct net_device *dev)
{
	struct veth_lpar_connection *cnx = veth_cnx[rlp];
	struct veth_port *port = (struct veth_port *) dev->priv;
	HvLpEvent_Rc rc;
	struct veth_msg *msg = NULL;
	unsigned long flags;

	if (! cnx)
		return 0;

	spin_lock_irqsave(&cnx->lock, flags);

	if (! (cnx->state & VETH_STATE_READY))
		goto no_error;

	if ((skb->len - ETH_HLEN) > VETH_MAX_MTU)
		goto drop;

	msg = veth_stack_pop(cnx);
	if (! msg)
		goto drop;

	msg->in_use = 1;
	msg->skb = skb_get(skb);

	msg->data.addr[0] = dma_map_single(port->dev, skb->data,
				skb->len, DMA_TO_DEVICE);

	if (dma_mapping_error(msg->data.addr[0]))
		goto recycle_and_drop;

	msg->dev = port->dev;
	msg->data.len[0] = skb->len;
	msg->data.eofmask = 1 << VETH_EOF_SHIFT;

	rc = veth_signaldata(cnx, VETH_EVENT_FRAMES, msg->token, &msg->data);

	if (rc != HvLpEvent_Rc_Good)
		goto recycle_and_drop;

	/* If the timer's not already running, start it now. */
	if (0 == cnx->outstanding_tx)
		mod_timer(&cnx->reset_timer, jiffies + cnx->reset_timeout);

	cnx->last_contact = jiffies;
	cnx->outstanding_tx++;

	if (veth_stack_is_empty(cnx))
		veth_stop_queues(cnx);

 no_error:
	spin_unlock_irqrestore(&cnx->lock, flags);
	return 0;

 recycle_and_drop:
	veth_recycle_msg(cnx, msg);
 drop:
	spin_unlock_irqrestore(&cnx->lock, flags);
	return 1;
}

static void veth_transmit_to_many(struct sk_buff *skb,
					  HvLpIndexMap lpmask,
					  struct net_device *dev)
{
	struct veth_port *port = (struct veth_port *) dev->priv;
	int i, success, error;

	success = error = 0;

	for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
		if ((lpmask & (1 << i)) == 0)
			continue;

		if (veth_transmit_to_one(skb, i, dev))
			error = 1;
		else
			success = 1;
	}

	if (error)
		port->stats.tx_errors++;

	if (success) {
		port->stats.tx_packets++;
		port->stats.tx_bytes += skb->len;
	}
}

static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	unsigned char *frame = skb->data;
	struct veth_port *port = (struct veth_port *) dev->priv;
	HvLpIndexMap lpmask;

	if (! (frame[0] & 0x01)) {
		/* unicast packet */
		HvLpIndex rlp = frame[5];

		if ( ! ((1 << rlp) & port->lpar_map) ) {
			dev_kfree_skb(skb);
			return 0;
		}

		lpmask = 1 << rlp;
	} else {
		lpmask = port->lpar_map;
	}

	veth_transmit_to_many(skb, lpmask, dev);

	dev_kfree_skb(skb);

	return 0;
}

/* You must hold the connection's lock when you call this function. */
static void veth_recycle_msg(struct veth_lpar_connection *cnx,
			     struct veth_msg *msg)
{
	u32 dma_address, dma_length;

	if (msg->in_use) {
		msg->in_use = 0;
		dma_address = msg->data.addr[0];
		dma_length = msg->data.len[0];

		if (!dma_mapping_error(dma_address))
			dma_unmap_single(msg->dev, dma_address, dma_length,
					DMA_TO_DEVICE);

		if (msg->skb) {
			dev_kfree_skb_any(msg->skb);
			msg->skb = NULL;
		}

		memset(&msg->data, 0, sizeof(msg->data));
		veth_stack_push(cnx, msg);
	} else if (cnx->state & VETH_STATE_OPEN) {
		veth_error("Non-pending frame (# %d) acked by LPAR %d.\n",
				cnx->remote_lp, msg->token);
	}
}

static void veth_wake_queues(struct veth_lpar_connection *cnx)
{
	int i;

	for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
		struct net_device *dev = veth_dev[i];
		struct veth_port *port;
		unsigned long flags;

		if (! dev)
			continue;

		port = (struct veth_port *)dev->priv;

		if (! (port->lpar_map & (1<<cnx->remote_lp)))
			continue;

		spin_lock_irqsave(&port->queue_lock, flags);

		port->stopped_map &= ~(1 << cnx->remote_lp);

		if (0 == port->stopped_map && netif_queue_stopped(dev)) {
			veth_debug("cnx %d: woke queue for %s.\n",
					cnx->remote_lp, dev->name);
			netif_wake_queue(dev);
		}
		spin_unlock_irqrestore(&port->queue_lock, flags);
	}
}

static void veth_stop_queues(struct veth_lpar_connection *cnx)
{
	int i;

	for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) {
		struct net_device *dev = veth_dev[i];
		struct veth_port *port;

		if (! dev)
			continue;

		port = (struct veth_port *)dev->priv;

		/* If this cnx is not on the vlan for this port, continue */
		if (! (port->lpar_map & (1 << cnx->remote_lp)))
			continue;

		spin_lock(&port->queue_lock);

		netif_stop_queue(dev);
		port->stopped_map |= (1 << cnx->remote_lp);

		veth_debug("cnx %d: stopped queue for %s, map = 0x%x.\n",
				cnx->remote_lp, dev->name, port->stopped_map);

		spin_unlock(&port->queue_lock);
	}
}

static void veth_timed_reset(unsigned long ptr)
{
	struct veth_lpar_connection *cnx = (struct veth_lpar_connection *)ptr;
	unsigned long trigger_time, flags;

	/* FIXME is it possible this fires after veth_stop_connection()?
	 * That would reschedule the statemachine for 5 seconds and probably
	 * execute it after the module's been unloaded. Hmm. */

	spin_lock_irqsave(&cnx->lock, flags);

	if (cnx->outstanding_tx > 0) {
		trigger_time = cnx->last_contact + cnx->reset_timeout;

		if (trigger_time < jiffies) {
			cnx->state |= VETH_STATE_RESET;
			veth_kick_statemachine(cnx);
			veth_error("%d packets not acked by LPAR %d within %d "
					"seconds, resetting.\n",
					cnx->outstanding_tx, cnx->remote_lp,
					cnx->reset_timeout / HZ);
		} else {
			/* Reschedule the timer */
			trigger_time = jiffies + cnx->reset_timeout;
			mod_timer(&cnx->reset_timer, trigger_time);
		}
	}

	spin_unlock_irqrestore(&cnx->lock, flags);
}

/*
 * Rx path
 */

static inline int veth_frame_wanted(struct veth_port *port, u64 mac_addr)
{
	int wanted = 0;
	int i;
	unsigned long flags;

	if ( (mac_addr == port->mac_addr) || (mac_addr == 0xffffffffffff0000) )
		return 1;

	read_lock_irqsave(&port->mcast_gate, flags);

	if (port->promiscuous) {
		wanted = 1;
		goto out;
	}

	for (i = 0; i < port->num_mcast; ++i) {
		if (port->mcast_addr[i] == mac_addr) {
			wanted = 1;
			break;
		}
	}

 out:
	read_unlock_irqrestore(&port->mcast_gate, flags);

	return wanted;
}

struct dma_chunk {
	u64 addr;
	u64 size;
};

#define VETH_MAX_PAGES_PER_FRAME ( (VETH_MAX_MTU+PAGE_SIZE-2)/PAGE_SIZE + 1 )

static inline void veth_build_dma_list(struct dma_chunk *list,
				       unsigned char *p, unsigned long length)
{
	unsigned long done;
	int i = 1;

	/* FIXME: skbs are continguous in real addresses.  Do we
	 * really need to break it into PAGE_SIZE chunks, or can we do
	 * it just at the granularity of iSeries real->absolute
	 * mapping?  Indeed, given the way the allocator works, can we
	 * count on them being absolutely contiguous? */
	list[0].addr = iseries_hv_addr(p);
	list[0].size = min(length,
			   PAGE_SIZE - ((unsigned long)p & ~PAGE_MASK));

	done = list[0].size;
	while (done < length) {
		list[i].addr = iseries_hv_addr(p + done);
		list[i].size = min(length-done, PAGE_SIZE);
		done += list[i].size;
		i++;
	}
}

static void veth_flush_acks(struct veth_lpar_connection *cnx)
{
	HvLpEvent_Rc rc;

	rc = veth_signaldata(cnx, VETH_EVENT_FRAMES_ACK,
			     0, &cnx->pending_acks);

	if (rc != HvLpEvent_Rc_Good)
		veth_error("Failed acking frames from LPAR %d, rc = %d\n",
				cnx->remote_lp, (int)rc);

	cnx->num_pending_acks = 0;
	memset(&cnx->pending_acks, 0xff, sizeof(cnx->pending_acks));
}

static void veth_receive(struct veth_lpar_connection *cnx,
			 struct veth_lpevent *event)
{
	struct veth_frames_data *senddata = &event->u.frames_data;
	int startchunk = 0;
	int nchunks;
	unsigned long flags;
	HvLpDma_Rc rc;

	do {
		u16 length = 0;
		struct sk_buff *skb;
		struct dma_chunk local_list[VETH_MAX_PAGES_PER_FRAME];
		struct dma_chunk remote_list[VETH_MAX_FRAMES_PER_MSG];
		u64 dest;
		HvLpVirtualLanIndex vlan;
		struct net_device *dev;
		struct veth_port *port;

		/* FIXME: do we need this? */
		memset(local_list, 0, sizeof(local_list));
		memset(remote_list, 0, sizeof(VETH_MAX_FRAMES_PER_MSG));

		/* a 0 address marks the end of the valid entries */
		if (senddata->addr[startchunk] == 0)
			break;

		/* make sure that we have at least 1 EOF entry in the
		 * remaining entries */
		if (! (senddata->eofmask >> (startchunk + VETH_EOF_SHIFT))) {
			veth_error("Missing EOF fragment in event "
					"eofmask = 0x%x startchunk = %d\n",
					(unsigned)senddata->eofmask,
					startchunk);
			break;
		}

		/* build list of chunks in this frame */
		nchunks = 0;
		do {
			remote_list[nchunks].addr =
				(u64) senddata->addr[startchunk+nchunks] << 32;
			remote_list[nchunks].size =
				senddata->len[startchunk+nchunks];
			length += remote_list[nchunks].size;
		} while (! (senddata->eofmask &
			    (1 << (VETH_EOF_SHIFT + startchunk + nchunks++))));

		/* length == total length of all chunks */
		/* nchunks == # of chunks in this frame */

		if ((length - ETH_HLEN) > VETH_MAX_MTU) {
			veth_error("Received oversize frame from LPAR %d "
					"(length = %d)\n",
					cnx->remote_lp, length);
			continue;
		}

		skb = alloc_skb(length, GFP_ATOMIC);
		if (!skb)
			continue;

		veth_build_dma_list(local_list, skb->data, length);

		rc = HvCallEvent_dmaBufList(HvLpEvent_Type_VirtualLan,
					    event->base_event.xSourceLp,
					    HvLpDma_Direction_RemoteToLocal,
					    cnx->src_inst,
					    cnx->dst_inst,
					    HvLpDma_AddressType_RealAddress,
					    HvLpDma_AddressType_TceIndex,
					    iseries_hv_addr(&local_list),
					    iseries_hv_addr(&remote_list),
					    length);
		if (rc != HvLpDma_Rc_Good) {
			dev_kfree_skb_irq(skb);
			continue;
		}

		vlan = skb->data[9];
		dev = veth_dev[vlan];
		if (! dev) {
			/*
			 * Some earlier versions of the driver sent
			 * broadcasts down all connections, even to lpars
			 * that weren't on the relevant vlan. So ignore
			 * packets belonging to a vlan we're not on.
			 * We can also be here if we receive packets while
			 * the driver is going down, because then dev is NULL.
			 */
			dev_kfree_skb_irq(skb);
			continue;
		}

		port = (struct veth_port *)dev->priv;
		dest = *((u64 *) skb->data) & 0xFFFFFFFFFFFF0000;

		if ((vlan > HVMAXARCHITECTEDVIRTUALLANS) || !port) {
			dev_kfree_skb_irq(skb);
			continue;
		}
		if (! veth_frame_wanted(port, dest)) {
			dev_kfree_skb_irq(skb);
			continue;
		}

		skb_put(skb, length);
		skb->dev = dev;
		skb->protocol = eth_type_trans(skb, dev);
		skb->ip_summed = CHECKSUM_NONE;
		netif_rx(skb);	/* send it up */
		port->stats.rx_packets++;
		port->stats.rx_bytes += length;
	} while (startchunk += nchunks, startchunk < VETH_MAX_FRAMES_PER_MSG);

	/* Ack it */
	spin_lock_irqsave(&cnx->lock, flags);
	BUG_ON(cnx->num_pending_acks > VETH_MAX_ACKS_PER_MSG);

	cnx->pending_acks[cnx->num_pending_acks++] =
		event->base_event.xCorrelationToken;

	if ( (cnx->num_pending_acks >= cnx->remote_caps.ack_threshold)
	     || (cnx->num_pending_acks >= VETH_MAX_ACKS_PER_MSG) )
		veth_flush_acks(cnx);

	spin_unlock_irqrestore(&cnx->lock, flags);
}

static void veth_timed_ack(unsigned long ptr)
{
	struct veth_lpar_connection *cnx = (struct veth_lpar_connection *) ptr;
	unsigned long flags;

	/* Ack all the events */
	spin_lock_irqsave(&cnx->lock, flags);
	if (cnx->num_pending_acks > 0)
		veth_flush_acks(cnx);

	/* Reschedule the timer */
	cnx->ack_timer.expires = jiffies + cnx->ack_timeout;
	add_timer(&cnx->ack_timer);
	spin_unlock_irqrestore(&cnx->lock, flags);
}

static int veth_remove(struct vio_dev *vdev)
{
	struct veth_lpar_connection *cnx;
	struct net_device *dev;
	struct veth_port *port;
	int i;

	dev = veth_dev[vdev->unit_address];

	if (! dev)
		return 0;

	port = netdev_priv(dev);

	for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
		cnx = veth_cnx[i];

		if (cnx && (port->lpar_map & (1 << i))) {
			/* Drop our reference to connections on our VLAN */
			kobject_put(&cnx->kobject);
		}
	}

	veth_dev[vdev->unit_address] = NULL;
	kobject_del(&port->kobject);
	kobject_put(&port->kobject);
	unregister_netdev(dev);
	free_netdev(dev);

	return 0;
}

static int veth_probe(struct vio_dev *vdev, const struct vio_device_id *id)
{
	int i = vdev->unit_address;
	struct net_device *dev;
	struct veth_port *port;

	dev = veth_probe_one(i, vdev);
	if (dev == NULL) {
		veth_remove(vdev);
		return 1;
	}
	veth_dev[i] = dev;

	port = (struct veth_port*)netdev_priv(dev);

	/* Start the state machine on each connection on this vlan. If we're
	 * the first dev to do so this will commence link negotiation */
	for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
		struct veth_lpar_connection *cnx;

		if (! (port->lpar_map & (1 << i)))
			continue;

		cnx = veth_cnx[i];
		if (!cnx)
			continue;

		kobject_get(&cnx->kobject);
		veth_kick_statemachine(cnx);
	}

	return 0;
}

/**
 * veth_device_table: Used by vio.c to match devices that we
 * support.
 */
static struct vio_device_id veth_device_table[] __devinitdata = {
	{ "network", "IBM,iSeries-l-lan" },
	{ "", "" }
};
MODULE_DEVICE_TABLE(vio, veth_device_table);

static struct vio_driver veth_driver = {
	.id_table = veth_device_table,
	.probe = veth_probe,
	.remove = veth_remove,
	.driver = {
		.name = DRV_NAME,
		.owner = THIS_MODULE,
	}
};

/*
 * Module initialization/cleanup
 */

static void __exit veth_module_cleanup(void)
{
	int i;
	struct veth_lpar_connection *cnx;

	/* Disconnect our "irq" to stop events coming from the Hypervisor. */
	HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan);

	/* Make sure any work queued from Hypervisor callbacks is finished. */
	flush_scheduled_work();

	for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
		cnx = veth_cnx[i];

		if (!cnx)
			continue;

		/* Remove the connection from sysfs */
		kobject_del(&cnx->kobject);
		/* Drop the driver's reference to the connection */
		kobject_put(&cnx->kobject);
	}

	/* Unregister the driver, which will close all the netdevs and stop
	 * the connections when they're no longer referenced. */
	vio_unregister_driver(&veth_driver);
}
module_exit(veth_module_cleanup);

static int __init veth_module_init(void)
{
	int i;
	int rc;

	if (!firmware_has_feature(FW_FEATURE_ISERIES))
		return -ENODEV;

	this_lp = HvLpConfig_getLpIndex_outline();

	for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
		rc = veth_init_connection(i);
		if (rc != 0)
			goto error;
	}

	HvLpEvent_registerHandler(HvLpEvent_Type_VirtualLan,
				  &veth_handle_event);

	rc = vio_register_driver(&veth_driver);
	if (rc != 0)
		goto error;

	for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
		struct kobject *kobj;

		if (!veth_cnx[i])
			continue;

		kobj = &veth_cnx[i]->kobject;
		kobj->parent = &veth_driver.driver.kobj;
		/* If the add failes, complain but otherwise continue */
		if (0 != kobject_add(kobj))
			veth_error("cnx %d: Failed adding to sysfs.\n", i);
	}

	return 0;

error:
	for (i = 0; i < HVMAXARCHITECTEDLPS; ++i) {
		veth_destroy_connection(veth_cnx[i]);
	}

	return rc;
}
module_init(veth_module_init);
