/* 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/config.h>
#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 <asm/abs_addr.h>
#include <asm/iseries/mf.h>
#include <asm/uaccess.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 work_struct 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_work(&cnx->statemachine_wq);
}

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 pt_regs *regs)
{
	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(void *p)
{
	struct veth_lpar_connection *cnx = (struct veth_lpar_connection *)p;
	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_WORK(&cnx->statemachine_wq, veth_statemachine, cnx);

	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 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 device *vdev)
{
	struct net_device *dev;
	struct veth_port *port;
	int i, rc;

	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;

	dev->dev_addr[0] = 0x02;
	dev->dev_addr[1] = 0x01;
	dev->dev_addr[2] = 0xff;
	dev->dev_addr[3] = vlan;
	dev->dev_addr[4] = 0xff;
	dev->dev_addr[5] = this_lp;

	dev->mtu = VETH_MAX_MTU;

	memcpy(&port->mac_addr, dev->dev_addr, 6);

	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->dev);
	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 = {
	{ "vlan", "" },
	{ "", "" }
};
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
 */

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);

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

	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);
