/*
 * linux/drivers/s390/net/qeth_main.c
 *
 * Linux on zSeries OSA Express and HiperSockets support
 *
 * Copyright 2000,2003 IBM Corporation
 *
 *    Author(s): Original Code written by
 *			  Utz Bacher (utz.bacher@de.ibm.com)
 *		 Rewritten by
 *			  Frank Pavlic (fpavlic@de.ibm.com) and
 *		 	  Thomas Spatzier <tspat@de.ibm.com>
 *
 * 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/ip.h>
#include <linux/inetdevice.h>
#include <linux/netdevice.h>
#include <linux/sched.h>
#include <linux/workqueue.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/tcp.h>
#include <linux/icmp.h>
#include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/igmp.h>
#include <linux/init.h>
#include <linux/reboot.h>
#include <linux/mii.h>
#include <linux/rcupdate.h>
#include <linux/ethtool.h>

#include <net/arp.h>
#include <net/ip.h>
#include <net/route.h>

#include <asm/ebcdic.h>
#include <asm/io.h>
#include <asm/qeth.h>
#include <asm/timex.h>
#include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <asm/s390_rdev.h>

#include "qeth.h"
#include "qeth_mpc.h"
#include "qeth_fs.h"
#include "qeth_eddp.h"
#include "qeth_tso.h"

static const char *version = "qeth S/390 OSA-Express driver";

/**
 * Debug Facility Stuff
 */
static debug_info_t *qeth_dbf_setup = NULL;
static debug_info_t *qeth_dbf_data = NULL;
static debug_info_t *qeth_dbf_misc = NULL;
static debug_info_t *qeth_dbf_control = NULL;
debug_info_t *qeth_dbf_trace = NULL;
static debug_info_t *qeth_dbf_sense = NULL;
static debug_info_t *qeth_dbf_qerr = NULL;

DEFINE_PER_CPU(char[256], qeth_dbf_txt_buf);

static struct lock_class_key qdio_out_skb_queue_key;

/**
 * some more definitions and declarations
 */
static unsigned int known_devices[][10] = QETH_MODELLIST_ARRAY;

/* list of our cards */
struct qeth_card_list_struct qeth_card_list;
/*process list want to be notified*/
spinlock_t qeth_notify_lock;
struct list_head qeth_notify_list;

static void qeth_send_control_data_cb(struct qeth_channel *,
				      struct qeth_cmd_buffer *);

/**
 * here we go with function implementation
 */
static void
qeth_init_qdio_info(struct qeth_card *card);

static int
qeth_init_qdio_queues(struct qeth_card *card);

static int
qeth_alloc_qdio_buffers(struct qeth_card *card);

static void
qeth_free_qdio_buffers(struct qeth_card *);

static void
qeth_clear_qdio_buffers(struct qeth_card *);

static void
qeth_clear_ip_list(struct qeth_card *, int, int);

static void
qeth_clear_ipacmd_list(struct qeth_card *);

static int
qeth_qdio_clear_card(struct qeth_card *, int);

static void
qeth_clear_working_pool_list(struct qeth_card *);

static void
qeth_clear_cmd_buffers(struct qeth_channel *);

static int
qeth_stop(struct net_device *);

static void
qeth_clear_ipato_list(struct qeth_card *);

static int
qeth_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *);

static void
qeth_irq_tasklet(unsigned long);

static int
qeth_set_online(struct ccwgroup_device *);

static int
__qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode);

static struct qeth_ipaddr *
qeth_get_addr_buffer(enum qeth_prot_versions);

static void
qeth_set_multicast_list(struct net_device *);

static void
qeth_setadp_promisc_mode(struct qeth_card *);

static void
qeth_notify_processes(void)
{
	/*notify all  registered processes */
	struct qeth_notify_list_struct *n_entry;

	QETH_DBF_TEXT(trace,3,"procnoti");
	spin_lock(&qeth_notify_lock);
	list_for_each_entry(n_entry, &qeth_notify_list, list) {
		send_sig(n_entry->signum, n_entry->task, 1);
	}
	spin_unlock(&qeth_notify_lock);

}
int
qeth_notifier_unregister(struct task_struct *p)
{
	struct qeth_notify_list_struct *n_entry, *tmp;

	QETH_DBF_TEXT(trace, 2, "notunreg");
	spin_lock(&qeth_notify_lock);
	list_for_each_entry_safe(n_entry, tmp, &qeth_notify_list, list) {
		if (n_entry->task == p) {
			list_del(&n_entry->list);
			kfree(n_entry);
			goto out;
		}
	}
out:
	spin_unlock(&qeth_notify_lock);
	return 0;
}
int
qeth_notifier_register(struct task_struct *p, int signum)
{
	struct qeth_notify_list_struct *n_entry;

	/*check first if entry already exists*/
	spin_lock(&qeth_notify_lock);
	list_for_each_entry(n_entry, &qeth_notify_list, list) {
		if (n_entry->task == p) {
			n_entry->signum = signum;
			spin_unlock(&qeth_notify_lock);
			return 0;
		}
	}
	spin_unlock(&qeth_notify_lock);

	n_entry = (struct qeth_notify_list_struct *)
		kmalloc(sizeof(struct qeth_notify_list_struct),GFP_KERNEL);
	if (!n_entry)
		return -ENOMEM;
	n_entry->task = p;
	n_entry->signum = signum;
	spin_lock(&qeth_notify_lock);
	list_add(&n_entry->list,&qeth_notify_list);
	spin_unlock(&qeth_notify_lock);
	return 0;
}


/**
 * free channel command buffers
 */
static void
qeth_clean_channel(struct qeth_channel *channel)
{
	int cnt;

	QETH_DBF_TEXT(setup, 2, "freech");
	for (cnt = 0; cnt < QETH_CMD_BUFFER_NO; cnt++)
		kfree(channel->iob[cnt].data);
}

/**
 * free card
 */
static void
qeth_free_card(struct qeth_card *card)
{

	QETH_DBF_TEXT(setup, 2, "freecrd");
	QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
	qeth_clean_channel(&card->read);
	qeth_clean_channel(&card->write);
	if (card->dev)
		free_netdev(card->dev);
	qeth_clear_ip_list(card, 0, 0);
	qeth_clear_ipato_list(card);
	kfree(card->ip_tbd_list);
	qeth_free_qdio_buffers(card);
	kfree(card);
}

/**
 * alloc memory for command buffer per channel
 */
static int
qeth_setup_channel(struct qeth_channel *channel)
{
	int cnt;

	QETH_DBF_TEXT(setup, 2, "setupch");
	for (cnt=0; cnt < QETH_CMD_BUFFER_NO; cnt++) {
		channel->iob[cnt].data = (char *)
			kmalloc(QETH_BUFSIZE, GFP_DMA|GFP_KERNEL);
		if (channel->iob[cnt].data == NULL)
			break;
		channel->iob[cnt].state = BUF_STATE_FREE;
		channel->iob[cnt].channel = channel;
		channel->iob[cnt].callback = qeth_send_control_data_cb;
		channel->iob[cnt].rc = 0;
	}
	if (cnt < QETH_CMD_BUFFER_NO) {
		while (cnt-- > 0)
			kfree(channel->iob[cnt].data);
		return -ENOMEM;
	}
	channel->buf_no = 0;
	channel->io_buf_no = 0;
	atomic_set(&channel->irq_pending, 0);
	spin_lock_init(&channel->iob_lock);

	init_waitqueue_head(&channel->wait_q);
	channel->irq_tasklet.data = (unsigned long) channel;
	channel->irq_tasklet.func = qeth_irq_tasklet;
	return 0;
}

/**
 * alloc memory for card structure
 */
static struct qeth_card *
qeth_alloc_card(void)
{
	struct qeth_card *card;

	QETH_DBF_TEXT(setup, 2, "alloccrd");
	card = kzalloc(sizeof(struct qeth_card), GFP_DMA|GFP_KERNEL);
	if (!card)
		return NULL;
	QETH_DBF_HEX(setup, 2, &card, sizeof(void *));
	if (qeth_setup_channel(&card->read)) {
		kfree(card);
		return NULL;
	}
	if (qeth_setup_channel(&card->write)) {
		qeth_clean_channel(&card->read);
		kfree(card);
		return NULL;
	}
	return card;
}

static long
__qeth_check_irb_error(struct ccw_device *cdev, unsigned long intparm,
		       struct irb *irb)
{
	if (!IS_ERR(irb))
		return 0;

	switch (PTR_ERR(irb)) {
	case -EIO:
		PRINT_WARN("i/o-error on device %s\n", cdev->dev.bus_id);
		QETH_DBF_TEXT(trace, 2, "ckirberr");
		QETH_DBF_TEXT_(trace, 2, "  rc%d", -EIO);
		break;
	case -ETIMEDOUT:
		PRINT_WARN("timeout on device %s\n", cdev->dev.bus_id);
		QETH_DBF_TEXT(trace, 2, "ckirberr");
		QETH_DBF_TEXT_(trace, 2, "  rc%d", -ETIMEDOUT);
		if (intparm == QETH_RCD_PARM) {
			struct qeth_card *card = CARD_FROM_CDEV(cdev);

			if (card && (card->data.ccwdev == cdev)) {
				card->data.state = CH_STATE_DOWN;
				wake_up(&card->wait_q);
			}
		}
		break;
	default:
		PRINT_WARN("unknown error %ld on device %s\n", PTR_ERR(irb),
			   cdev->dev.bus_id);
		QETH_DBF_TEXT(trace, 2, "ckirberr");
		QETH_DBF_TEXT(trace, 2, "  rc???");
	}
	return PTR_ERR(irb);
}

static int
qeth_get_problem(struct ccw_device *cdev, struct irb *irb)
{
	int dstat,cstat;
	char *sense;

	sense = (char *) irb->ecw;
	cstat = irb->scsw.cstat;
	dstat = irb->scsw.dstat;

	if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK |
		     SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK |
		     SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) {
		QETH_DBF_TEXT(trace,2, "CGENCHK");
		PRINT_WARN("check on device %s, dstat=x%x, cstat=x%x ",
			   cdev->dev.bus_id, dstat, cstat);
		HEXDUMP16(WARN, "irb: ", irb);
		HEXDUMP16(WARN, "irb: ", ((char *) irb) + 32);
		return 1;
	}

	if (dstat & DEV_STAT_UNIT_CHECK) {
		if (sense[SENSE_RESETTING_EVENT_BYTE] &
		    SENSE_RESETTING_EVENT_FLAG) {
			QETH_DBF_TEXT(trace,2,"REVIND");
			return 1;
		}
		if (sense[SENSE_COMMAND_REJECT_BYTE] &
		    SENSE_COMMAND_REJECT_FLAG) {
			QETH_DBF_TEXT(trace,2,"CMDREJi");
			return 0;
		}
		if ((sense[2] == 0xaf) && (sense[3] == 0xfe)) {
			QETH_DBF_TEXT(trace,2,"AFFE");
			return 1;
		}
		if ((!sense[0]) && (!sense[1]) && (!sense[2]) && (!sense[3])) {
			QETH_DBF_TEXT(trace,2,"ZEROSEN");
			return 0;
		}
		QETH_DBF_TEXT(trace,2,"DGENCHK");
			return 1;
	}
	return 0;
}
static int qeth_issue_next_read(struct qeth_card *);

/**
 * interrupt handler
 */
static void
qeth_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
{
	int rc;
	int cstat,dstat;
	struct qeth_cmd_buffer *buffer;
	struct qeth_channel *channel;
	struct qeth_card *card;

	QETH_DBF_TEXT(trace,5,"irq");

	if (__qeth_check_irb_error(cdev, intparm, irb))
		return;
	cstat = irb->scsw.cstat;
	dstat = irb->scsw.dstat;

	card = CARD_FROM_CDEV(cdev);
	if (!card)
		return;

	if (card->read.ccwdev == cdev){
		channel = &card->read;
		QETH_DBF_TEXT(trace,5,"read");
	} else if (card->write.ccwdev == cdev) {
		channel = &card->write;
		QETH_DBF_TEXT(trace,5,"write");
	} else {
		channel = &card->data;
		QETH_DBF_TEXT(trace,5,"data");
	}
	atomic_set(&channel->irq_pending, 0);

	if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC))
		channel->state = CH_STATE_STOPPED;

	if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC))
		channel->state = CH_STATE_HALTED;

	/*let's wake up immediately on data channel*/
	if ((channel == &card->data) && (intparm != 0) &&
	    (intparm != QETH_RCD_PARM))
		goto out;

	if (intparm == QETH_CLEAR_CHANNEL_PARM) {
		QETH_DBF_TEXT(trace, 6, "clrchpar");
		/* we don't have to handle this further */
		intparm = 0;
	}
	if (intparm == QETH_HALT_CHANNEL_PARM) {
		QETH_DBF_TEXT(trace, 6, "hltchpar");
		/* we don't have to handle this further */
		intparm = 0;
	}
	if ((dstat & DEV_STAT_UNIT_EXCEP) ||
	    (dstat & DEV_STAT_UNIT_CHECK) ||
	    (cstat)) {
		if (irb->esw.esw0.erw.cons) {
			/* TODO: we should make this s390dbf */
			PRINT_WARN("sense data available on channel %s.\n",
				   CHANNEL_ID(channel));
			PRINT_WARN(" cstat 0x%X\n dstat 0x%X\n", cstat, dstat);
			HEXDUMP16(WARN,"irb: ",irb);
			HEXDUMP16(WARN,"sense data: ",irb->ecw);
		}
		if (intparm == QETH_RCD_PARM) {
			channel->state = CH_STATE_DOWN;
			goto out;
		}
		rc = qeth_get_problem(cdev,irb);
		if (rc) {
			qeth_schedule_recovery(card);
			goto out;
		}
	}

	if (intparm == QETH_RCD_PARM) {
		channel->state = CH_STATE_RCD_DONE;
		goto out;
	}
	if (intparm) {
		buffer = (struct qeth_cmd_buffer *) __va((addr_t)intparm);
		buffer->state = BUF_STATE_PROCESSED;
	}
	if (channel == &card->data)
		return;

	if (channel == &card->read &&
	    channel->state == CH_STATE_UP)
		qeth_issue_next_read(card);

	qeth_irq_tasklet((unsigned long)channel);
	return;
out:
	wake_up(&card->wait_q);
}

/**
 * tasklet function scheduled from irq handler
 */
static void
qeth_irq_tasklet(unsigned long data)
{
	struct qeth_card *card;
	struct qeth_channel *channel;
	struct qeth_cmd_buffer *iob;
	__u8 index;

	QETH_DBF_TEXT(trace,5,"irqtlet");
	channel = (struct qeth_channel *) data;
	iob = channel->iob;
	index = channel->buf_no;
	card = CARD_FROM_CDEV(channel->ccwdev);
	while (iob[index].state == BUF_STATE_PROCESSED) {
		if (iob[index].callback !=NULL) {
			iob[index].callback(channel,iob + index);
		}
		index = (index + 1) % QETH_CMD_BUFFER_NO;
	}
	channel->buf_no = index;
	wake_up(&card->wait_q);
}

static int qeth_stop_card(struct qeth_card *, int);

static int
__qeth_set_offline(struct ccwgroup_device *cgdev, int recovery_mode)
{
	struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data;
	int rc = 0, rc2 = 0, rc3 = 0;
	enum qeth_card_states recover_flag;

	QETH_DBF_TEXT(setup, 3, "setoffl");
	QETH_DBF_HEX(setup, 3, &card, sizeof(void *));

	if (card->dev && netif_carrier_ok(card->dev))
		netif_carrier_off(card->dev);
	recover_flag = card->state;
	if (qeth_stop_card(card, recovery_mode) == -ERESTARTSYS){
		PRINT_WARN("Stopping card %s interrupted by user!\n",
			   CARD_BUS_ID(card));
		return -ERESTARTSYS;
	}
	rc  = ccw_device_set_offline(CARD_DDEV(card));
	rc2 = ccw_device_set_offline(CARD_WDEV(card));
	rc3 = ccw_device_set_offline(CARD_RDEV(card));
	if (!rc)
		rc = (rc2) ? rc2 : rc3;
	if (rc)
		QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
	if (recover_flag == CARD_STATE_UP)
		card->state = CARD_STATE_RECOVER;
	qeth_notify_processes();
	return 0;
}

static int
qeth_set_offline(struct ccwgroup_device *cgdev)
{
	return  __qeth_set_offline(cgdev, 0);
}

static int
qeth_wait_for_threads(struct qeth_card *card, unsigned long threads);


static void
qeth_remove_device(struct ccwgroup_device *cgdev)
{
	struct qeth_card *card = (struct qeth_card *) cgdev->dev.driver_data;
	unsigned long flags;

	QETH_DBF_TEXT(setup, 3, "rmdev");
	QETH_DBF_HEX(setup, 3, &card, sizeof(void *));

	if (!card)
		return;

	if (qeth_wait_for_threads(card, 0xffffffff))
		return;

	if (cgdev->state == CCWGROUP_ONLINE){
		card->use_hard_stop = 1;
		qeth_set_offline(cgdev);
	}
	/* remove form our internal list */
	write_lock_irqsave(&qeth_card_list.rwlock, flags);
	list_del(&card->list);
	write_unlock_irqrestore(&qeth_card_list.rwlock, flags);
	if (card->dev)
		unregister_netdev(card->dev);
	qeth_remove_device_attributes(&cgdev->dev);
	qeth_free_card(card);
	cgdev->dev.driver_data = NULL;
	put_device(&cgdev->dev);
}

static int
qeth_register_addr_entry(struct qeth_card *, struct qeth_ipaddr *);
static int
qeth_deregister_addr_entry(struct qeth_card *, struct qeth_ipaddr *);

/**
 * Add/remove address to/from card's ip list, i.e. try to add or remove
 * reference to/from an IP address that is already registered on the card.
 * Returns:
 * 	0  address was on card and its reference count has been adjusted,
 * 	   but is still > 0, so nothing has to be done
 * 	   also returns 0 if card was not on card and the todo was to delete
 * 	   the address -> there is also nothing to be done
 * 	1  address was not on card and the todo is to add it to the card's ip
 * 	   list
 * 	-1 address was on card and its reference count has been decremented
 * 	   to <= 0 by the todo -> address must be removed from card
 */
static int
__qeth_ref_ip_on_card(struct qeth_card *card, struct qeth_ipaddr *todo,
		      struct qeth_ipaddr **__addr)
{
	struct qeth_ipaddr *addr;
	int found = 0;

	list_for_each_entry(addr, &card->ip_list, entry) {
		if (card->options.layer2) {
			if ((addr->type == todo->type) &&
			    (memcmp(&addr->mac, &todo->mac,
				    OSA_ADDR_LEN) == 0)) {
				found = 1;
				break;
			}
			continue;
		}
		if ((addr->proto     == QETH_PROT_IPV4)  &&
		    (todo->proto     == QETH_PROT_IPV4)  &&
		    (addr->type      == todo->type)      &&
		    (addr->u.a4.addr == todo->u.a4.addr) &&
		    (addr->u.a4.mask == todo->u.a4.mask)) {
			found = 1;
			break;
		}
		if ((addr->proto       == QETH_PROT_IPV6)     &&
		    (todo->proto       == QETH_PROT_IPV6)     &&
		    (addr->type        == todo->type)         &&
		    (addr->u.a6.pfxlen == todo->u.a6.pfxlen)  &&
		    (memcmp(&addr->u.a6.addr, &todo->u.a6.addr,
			    sizeof(struct in6_addr)) == 0)) {
			found = 1;
			break;
		}
	}
	if (found) {
		addr->users += todo->users;
		if (addr->users <= 0){
			*__addr = addr;
			return -1;
		} else {
			/* for VIPA and RXIP limit refcount to 1 */
			if (addr->type != QETH_IP_TYPE_NORMAL)
				addr->users = 1;
			return 0;
		}
	}
	if (todo->users > 0) {
		/* for VIPA and RXIP limit refcount to 1 */
		if (todo->type != QETH_IP_TYPE_NORMAL)
			todo->users = 1;
		return 1;
	} else
		return 0;
}

static int
__qeth_address_exists_in_list(struct list_head *list, struct qeth_ipaddr *addr,
		              int same_type)
{
	struct qeth_ipaddr *tmp;

	list_for_each_entry(tmp, list, entry) {
		if ((tmp->proto     == QETH_PROT_IPV4)            &&
		    (addr->proto    == QETH_PROT_IPV4)            &&
		    ((same_type && (tmp->type == addr->type)) ||
		     (!same_type && (tmp->type != addr->type))  ) &&
		    (tmp->u.a4.addr == addr->u.a4.addr)             ){
			return 1;
		}
		if ((tmp->proto  == QETH_PROT_IPV6)               &&
		    (addr->proto == QETH_PROT_IPV6)               &&
		    ((same_type && (tmp->type == addr->type)) ||
		     (!same_type && (tmp->type != addr->type))  ) &&
		    (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,
			    sizeof(struct in6_addr)) == 0)          ) {
			return 1;
		}
	}
	return 0;
}

/*
 * Add IP to be added to todo list. If there is already an "add todo"
 * in this list we just incremenent the reference count.
 * Returns 0 if we  just incremented reference count.
 */
static int
__qeth_insert_ip_todo(struct qeth_card *card, struct qeth_ipaddr *addr, int add)
{
	struct qeth_ipaddr *tmp, *t;
	int found = 0;

	list_for_each_entry_safe(tmp, t, card->ip_tbd_list, entry) {
		if ((addr->type == QETH_IP_TYPE_DEL_ALL_MC) &&
		    (tmp->type == QETH_IP_TYPE_DEL_ALL_MC))
			return 0;
		if (card->options.layer2) {
			if ((tmp->type	== addr->type)	&&
			    (tmp->is_multicast == addr->is_multicast) &&
			    (memcmp(&tmp->mac, &addr->mac,
				    OSA_ADDR_LEN) == 0)) {
				found = 1;
				break;
			}
			continue;
		}
		if ((tmp->proto        == QETH_PROT_IPV4)     &&
		    (addr->proto       == QETH_PROT_IPV4)     &&
		    (tmp->type         == addr->type)         &&
		    (tmp->is_multicast == addr->is_multicast) &&
		    (tmp->u.a4.addr    == addr->u.a4.addr)    &&
		    (tmp->u.a4.mask    == addr->u.a4.mask)) {
			found = 1;
			break;
		}
		if ((tmp->proto        == QETH_PROT_IPV6)      &&
		    (addr->proto       == QETH_PROT_IPV6)      &&
		    (tmp->type         == addr->type)          &&
		    (tmp->is_multicast == addr->is_multicast)  &&
		    (tmp->u.a6.pfxlen  == addr->u.a6.pfxlen)   &&
		    (memcmp(&tmp->u.a6.addr, &addr->u.a6.addr,
			    sizeof(struct in6_addr)) == 0)) {
			found = 1;
			break;
		}
	}
	if (found){
		if (addr->users != 0)
			tmp->users += addr->users;
		else
			tmp->users += add? 1:-1;
		if (tmp->users == 0) {
			list_del(&tmp->entry);
			kfree(tmp);
		}
		return 0;
	} else {
		if (addr->type == QETH_IP_TYPE_DEL_ALL_MC)
			list_add(&addr->entry, card->ip_tbd_list);
		else {
			if (addr->users == 0)
				addr->users += add? 1:-1;
			if (add && (addr->type == QETH_IP_TYPE_NORMAL) &&
			    qeth_is_addr_covered_by_ipato(card, addr)){
				QETH_DBF_TEXT(trace, 2, "tkovaddr");
				addr->set_flags |= QETH_IPA_SETIP_TAKEOVER_FLAG;
			}
			list_add_tail(&addr->entry, card->ip_tbd_list);
		}
		return 1;
	}
}

/**
 * Remove IP address from list
 */
static int
qeth_delete_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
{
	unsigned long flags;
	int rc = 0;

	QETH_DBF_TEXT(trace, 4, "delip");

	if (card->options.layer2)
		QETH_DBF_HEX(trace, 4, &addr->mac, 6);
	else if (addr->proto == QETH_PROT_IPV4)
		QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
	else {
		QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
		QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
	}
	spin_lock_irqsave(&card->ip_lock, flags);
	rc = __qeth_insert_ip_todo(card, addr, 0);
	spin_unlock_irqrestore(&card->ip_lock, flags);
	return rc;
}

static int
qeth_add_ip(struct qeth_card *card, struct qeth_ipaddr *addr)
{
	unsigned long flags;
	int rc = 0;

	QETH_DBF_TEXT(trace, 4, "addip");
	if (card->options.layer2)
		QETH_DBF_HEX(trace, 4, &addr->mac, 6);
	else if (addr->proto == QETH_PROT_IPV4)
		QETH_DBF_HEX(trace, 4, &addr->u.a4.addr, 4);
	else {
		QETH_DBF_HEX(trace, 4, &addr->u.a6.addr, 8);
		QETH_DBF_HEX(trace, 4, ((char *)&addr->u.a6.addr) + 8, 8);
	}
	spin_lock_irqsave(&card->ip_lock, flags);
	rc = __qeth_insert_ip_todo(card, addr, 1);
	spin_unlock_irqrestore(&card->ip_lock, flags);
	return rc;
}

static void
__qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags)
{
	struct qeth_ipaddr *addr, *tmp;
	int rc;
again:
	list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) {
		if (addr->is_multicast) {
			spin_unlock_irqrestore(&card->ip_lock, *flags);
			rc = qeth_deregister_addr_entry(card, addr);
			spin_lock_irqsave(&card->ip_lock, *flags);
			if (!rc) {
				list_del(&addr->entry);
				kfree(addr);
				goto again;
			}
		}
	}
}

static void
qeth_set_ip_addr_list(struct qeth_card *card)
{
	struct list_head *tbd_list;
	struct qeth_ipaddr *todo, *addr;
	unsigned long flags;
	int rc;

	QETH_DBF_TEXT(trace, 2, "sdiplist");
	QETH_DBF_HEX(trace, 2, &card, sizeof(void *));

	spin_lock_irqsave(&card->ip_lock, flags);
	tbd_list = card->ip_tbd_list;
	card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC);
	if (!card->ip_tbd_list) {
		QETH_DBF_TEXT(trace, 0, "silnomem");
		card->ip_tbd_list = tbd_list;
		spin_unlock_irqrestore(&card->ip_lock, flags);
		return;
	} else
		INIT_LIST_HEAD(card->ip_tbd_list);

	while (!list_empty(tbd_list)){
		todo = list_entry(tbd_list->next, struct qeth_ipaddr, entry);
		list_del(&todo->entry);
		if (todo->type == QETH_IP_TYPE_DEL_ALL_MC){
			__qeth_delete_all_mc(card, &flags);
			kfree(todo);
			continue;
		}
		rc = __qeth_ref_ip_on_card(card, todo, &addr);
		if (rc == 0) {
			/* nothing to be done; only adjusted refcount */
			kfree(todo);
		} else if (rc == 1) {
			/* new entry to be added to on-card list */
			spin_unlock_irqrestore(&card->ip_lock, flags);
			rc = qeth_register_addr_entry(card, todo);
			spin_lock_irqsave(&card->ip_lock, flags);
			if (!rc)
				list_add_tail(&todo->entry, &card->ip_list);
			else
				kfree(todo);
		} else if (rc == -1) {
			/* on-card entry to be removed */
			list_del_init(&addr->entry);
			spin_unlock_irqrestore(&card->ip_lock, flags);
			rc = qeth_deregister_addr_entry(card, addr);
			spin_lock_irqsave(&card->ip_lock, flags);
			if (!rc)
				kfree(addr);
			else
				list_add_tail(&addr->entry, &card->ip_list);
			kfree(todo);
		}
	}
	spin_unlock_irqrestore(&card->ip_lock, flags);
	kfree(tbd_list);
}

static void qeth_delete_mc_addresses(struct qeth_card *);
static void qeth_add_multicast_ipv4(struct qeth_card *);
static void qeth_layer2_add_multicast(struct qeth_card *);
#ifdef CONFIG_QETH_IPV6
static void qeth_add_multicast_ipv6(struct qeth_card *);
#endif

static int
qeth_set_thread_start_bit(struct qeth_card *card, unsigned long thread)
{
	unsigned long flags;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	if ( !(card->thread_allowed_mask & thread) ||
	      (card->thread_start_mask & thread) ) {
		spin_unlock_irqrestore(&card->thread_mask_lock, flags);
		return -EPERM;
	}
	card->thread_start_mask |= thread;
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	return 0;
}

static void
qeth_clear_thread_start_bit(struct qeth_card *card, unsigned long thread)
{
	unsigned long flags;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	card->thread_start_mask &= ~thread;
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	wake_up(&card->wait_q);
}

static void
qeth_clear_thread_running_bit(struct qeth_card *card, unsigned long thread)
{
	unsigned long flags;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	card->thread_running_mask &= ~thread;
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	wake_up(&card->wait_q);
}

static int
__qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
{
	unsigned long flags;
	int rc = 0;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	if (card->thread_start_mask & thread){
		if ((card->thread_allowed_mask & thread) &&
		    !(card->thread_running_mask & thread)){
			rc = 1;
			card->thread_start_mask &= ~thread;
			card->thread_running_mask |= thread;
		} else
			rc = -EPERM;
	}
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	return rc;
}

static int
qeth_do_run_thread(struct qeth_card *card, unsigned long thread)
{
	int rc = 0;

	wait_event(card->wait_q,
		   (rc = __qeth_do_run_thread(card, thread)) >= 0);
	return rc;
}

static int
qeth_recover(void *ptr)
{
	struct qeth_card *card;
	int rc = 0;

	card = (struct qeth_card *) ptr;
	daemonize("qeth_recover");
	QETH_DBF_TEXT(trace,2,"recover1");
	QETH_DBF_HEX(trace, 2, &card, sizeof(void *));
	if (!qeth_do_run_thread(card, QETH_RECOVER_THREAD))
		return 0;
	QETH_DBF_TEXT(trace,2,"recover2");
	PRINT_WARN("Recovery of device %s started ...\n",
		   CARD_BUS_ID(card));
	card->use_hard_stop = 1;
	__qeth_set_offline(card->gdev,1);
	rc = __qeth_set_online(card->gdev,1);
	/* don't run another scheduled recovery */
	qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
	qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
	if (!rc)
		PRINT_INFO("Device %s successfully recovered!\n",
			   CARD_BUS_ID(card));
	else
		PRINT_INFO("Device %s could not be recovered!\n",
			   CARD_BUS_ID(card));
	return 0;
}

void
qeth_schedule_recovery(struct qeth_card *card)
{
	QETH_DBF_TEXT(trace,2,"startrec");
	if (qeth_set_thread_start_bit(card, QETH_RECOVER_THREAD) == 0)
		schedule_work(&card->kernel_thread_starter);
}

static int
qeth_do_start_thread(struct qeth_card *card, unsigned long thread)
{
	unsigned long flags;
	int rc = 0;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	QETH_DBF_TEXT_(trace, 4, "  %02x%02x%02x",
			(u8) card->thread_start_mask,
			(u8) card->thread_allowed_mask,
			(u8) card->thread_running_mask);
	rc = (card->thread_start_mask & thread);
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	return rc;
}

static void
qeth_start_kernel_thread(struct work_struct *work)
{
	struct qeth_card *card = container_of(work, struct qeth_card, kernel_thread_starter);
	QETH_DBF_TEXT(trace , 2, "strthrd");

	if (card->read.state != CH_STATE_UP &&
	    card->write.state != CH_STATE_UP)
		return;
	if (qeth_do_start_thread(card, QETH_RECOVER_THREAD))
		kernel_thread(qeth_recover, (void *) card, SIGCHLD);
}


static void
qeth_set_intial_options(struct qeth_card *card)
{
	card->options.route4.type = NO_ROUTER;
#ifdef CONFIG_QETH_IPV6
	card->options.route6.type = NO_ROUTER;
#endif /* QETH_IPV6 */
	card->options.checksum_type = QETH_CHECKSUM_DEFAULT;
	card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
	card->options.macaddr_mode = QETH_TR_MACADDR_NONCANONICAL;
	card->options.fake_broadcast = 0;
	card->options.add_hhlen = DEFAULT_ADD_HHLEN;
	card->options.fake_ll = 0;
	if (card->info.type == QETH_CARD_TYPE_OSN)
		card->options.layer2 = 1;
	else
		card->options.layer2 = 0;
	card->options.performance_stats = 0;
	card->options.rx_sg_cb = QETH_RX_SG_CB;
}

/**
 * initialize channels ,card and all state machines
 */
static int
qeth_setup_card(struct qeth_card *card)
{

	QETH_DBF_TEXT(setup, 2, "setupcrd");
	QETH_DBF_HEX(setup, 2, &card, sizeof(void *));

	card->read.state  = CH_STATE_DOWN;
	card->write.state = CH_STATE_DOWN;
	card->data.state  = CH_STATE_DOWN;
	card->state = CARD_STATE_DOWN;
	card->lan_online = 0;
	card->use_hard_stop = 0;
	card->dev = NULL;
#ifdef CONFIG_QETH_VLAN
	spin_lock_init(&card->vlanlock);
	card->vlangrp = NULL;
#endif
	spin_lock_init(&card->lock);
	spin_lock_init(&card->ip_lock);
	spin_lock_init(&card->thread_mask_lock);
	card->thread_start_mask = 0;
	card->thread_allowed_mask = 0;
	card->thread_running_mask = 0;
	INIT_WORK(&card->kernel_thread_starter, qeth_start_kernel_thread);
	INIT_LIST_HEAD(&card->ip_list);
	card->ip_tbd_list = kmalloc(sizeof(struct list_head), GFP_KERNEL);
	if (!card->ip_tbd_list) {
		QETH_DBF_TEXT(setup, 0, "iptbdnom");
		return -ENOMEM;
	}
	INIT_LIST_HEAD(card->ip_tbd_list);
	INIT_LIST_HEAD(&card->cmd_waiter_list);
	init_waitqueue_head(&card->wait_q);
	/* intial options */
	qeth_set_intial_options(card);
	/* IP address takeover */
	INIT_LIST_HEAD(&card->ipato.entries);
	card->ipato.enabled = 0;
	card->ipato.invert4 = 0;
	card->ipato.invert6 = 0;
	/* init QDIO stuff */
	qeth_init_qdio_info(card);
	return 0;
}

static int
is_1920_device (struct qeth_card *card)
{
	int single_queue = 0;
	struct ccw_device *ccwdev;
	struct channelPath_dsc {
		u8 flags;
		u8 lsn;
		u8 desc;
		u8 chpid;
		u8 swla;
		u8 zeroes;
		u8 chla;
		u8 chpp;
	} *chp_dsc;

	QETH_DBF_TEXT(setup, 2, "chk_1920");

	ccwdev = card->data.ccwdev;
	chp_dsc = (struct channelPath_dsc *)ccw_device_get_chp_desc(ccwdev, 0);
	if (chp_dsc != NULL) {
		/* CHPP field bit 6 == 1 -> single queue */
		single_queue = ((chp_dsc->chpp & 0x02) == 0x02);
		kfree(chp_dsc);
	}
	QETH_DBF_TEXT_(setup, 2, "rc:%x", single_queue);
	return single_queue;
}

static int
qeth_determine_card_type(struct qeth_card *card)
{
	int i = 0;

	QETH_DBF_TEXT(setup, 2, "detcdtyp");

	card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
	card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
	while (known_devices[i][4]) {
		if ((CARD_RDEV(card)->id.dev_type == known_devices[i][2]) &&
		    (CARD_RDEV(card)->id.dev_model == known_devices[i][3])) {
			card->info.type = known_devices[i][4];
			card->qdio.no_out_queues = known_devices[i][8];
			card->info.is_multicast_different = known_devices[i][9];
			if (is_1920_device(card)) {
				PRINT_INFO("Priority Queueing not able "
					   "due to hardware limitations!\n");
				card->qdio.no_out_queues = 1;
				card->qdio.default_out_queue = 0;
			}
			return 0;
		}
		i++;
	}
	card->info.type = QETH_CARD_TYPE_UNKNOWN;
	PRINT_ERR("unknown card type on device %s\n", CARD_BUS_ID(card));
	return -ENOENT;
}

static int
qeth_probe_device(struct ccwgroup_device *gdev)
{
	struct qeth_card *card;
	struct device *dev;
	unsigned long flags;
	int rc;

	QETH_DBF_TEXT(setup, 2, "probedev");

	dev = &gdev->dev;
	if (!get_device(dev))
		return -ENODEV;

	QETH_DBF_TEXT_(setup, 2, "%s", gdev->dev.bus_id);

	card = qeth_alloc_card();
	if (!card) {
		put_device(dev);
		QETH_DBF_TEXT_(setup, 2, "1err%d", -ENOMEM);
		return -ENOMEM;
	}
	card->read.ccwdev  = gdev->cdev[0];
	card->write.ccwdev = gdev->cdev[1];
	card->data.ccwdev  = gdev->cdev[2];
	gdev->dev.driver_data = card;
	card->gdev = gdev;
	gdev->cdev[0]->handler = qeth_irq;
	gdev->cdev[1]->handler = qeth_irq;
	gdev->cdev[2]->handler = qeth_irq;

	if ((rc = qeth_determine_card_type(card))){
		PRINT_WARN("%s: not a valid card type\n", __func__);
		QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
		put_device(dev);
		qeth_free_card(card);
		return rc;
	}
	if ((rc = qeth_setup_card(card))){
		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
		put_device(dev);
		qeth_free_card(card);
		return rc;
	}
	rc = qeth_create_device_attributes(dev);
	if (rc) {
		put_device(dev);
		qeth_free_card(card);
		return rc;
	}
	/* insert into our internal list */
	write_lock_irqsave(&qeth_card_list.rwlock, flags);
	list_add_tail(&card->list, &qeth_card_list.list);
	write_unlock_irqrestore(&qeth_card_list.rwlock, flags);
	return rc;
}


static int qeth_read_conf_data(struct qeth_card *card, void **buffer,
			       int *length)
{
	struct ciw *ciw;
	char *rcd_buf;
	int ret;
	struct qeth_channel *channel = &card->data;
	unsigned long flags;

	/*
	 * scan for RCD command in extended SenseID data
	 */
	ciw = ccw_device_get_ciw(channel->ccwdev, CIW_TYPE_RCD);
	if (!ciw || ciw->cmd == 0)
		return -EOPNOTSUPP;
	rcd_buf = kzalloc(ciw->count, GFP_KERNEL | GFP_DMA);
	if (!rcd_buf)
		return -ENOMEM;

	channel->ccw.cmd_code = ciw->cmd;
	channel->ccw.cda = (__u32) __pa (rcd_buf);
	channel->ccw.count = ciw->count;
	channel->ccw.flags = CCW_FLAG_SLI;
	channel->state = CH_STATE_RCD;
	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
	ret = ccw_device_start_timeout(channel->ccwdev, &channel->ccw,
				       QETH_RCD_PARM, LPM_ANYPATH, 0,
				       QETH_RCD_TIMEOUT);
	spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
	if (!ret)
		wait_event(card->wait_q,
			   (channel->state == CH_STATE_RCD_DONE ||
			    channel->state == CH_STATE_DOWN));
	if (channel->state == CH_STATE_DOWN)
		ret = -EIO;
	else
		channel->state = CH_STATE_DOWN;
	if (ret) {
		kfree(rcd_buf);
		*buffer = NULL;
		*length = 0;
	} else {
		*length = ciw->count;
		*buffer = rcd_buf;
	}
	return ret;
}

static int
qeth_get_unitaddr(struct qeth_card *card)
{
 	int length;
	char *prcd;
	int rc;

	QETH_DBF_TEXT(setup, 2, "getunit");
	rc = qeth_read_conf_data(card, (void **) &prcd, &length);
	if (rc) {
		PRINT_ERR("qeth_read_conf_data for device %s returned %i\n",
			  CARD_DDEV_ID(card), rc);
		return rc;
	}
	card->info.chpid = prcd[30];
	card->info.unit_addr2 = prcd[31];
	card->info.cula = prcd[63];
	card->info.guestlan = ((prcd[0x10] == _ascebc['V']) &&
			       (prcd[0x11] == _ascebc['M']));
	kfree(prcd);
	return 0;
}

static void
qeth_init_tokens(struct qeth_card *card)
{
	card->token.issuer_rm_w = 0x00010103UL;
	card->token.cm_filter_w = 0x00010108UL;
	card->token.cm_connection_w = 0x0001010aUL;
	card->token.ulp_filter_w = 0x0001010bUL;
	card->token.ulp_connection_w = 0x0001010dUL;
}

static inline __u16
raw_devno_from_bus_id(char *id)
{
        id += (strlen(id) - 4);
        return (__u16) simple_strtoul(id, &id, 16);
}
/**
 * setup channel
 */
static void
qeth_setup_ccw(struct qeth_channel *channel,unsigned char *iob, __u32 len)
{
	struct qeth_card *card;

	QETH_DBF_TEXT(trace, 4, "setupccw");
	card = CARD_FROM_CDEV(channel->ccwdev);
	if (channel == &card->read)
		memcpy(&channel->ccw, READ_CCW, sizeof(struct ccw1));
	else
		memcpy(&channel->ccw, WRITE_CCW, sizeof(struct ccw1));
	channel->ccw.count = len;
	channel->ccw.cda = (__u32) __pa(iob);
}

/**
 * get free buffer for ccws (IDX activation, lancmds,ipassists...)
 */
static struct qeth_cmd_buffer *
__qeth_get_buffer(struct qeth_channel *channel)
{
	__u8 index;

	QETH_DBF_TEXT(trace, 6, "getbuff");
	index = channel->io_buf_no;
	do {
		if (channel->iob[index].state == BUF_STATE_FREE) {
			channel->iob[index].state = BUF_STATE_LOCKED;
			channel->io_buf_no = (channel->io_buf_no + 1) %
				QETH_CMD_BUFFER_NO;
			memset(channel->iob[index].data, 0, QETH_BUFSIZE);
			return channel->iob + index;
		}
		index = (index + 1) % QETH_CMD_BUFFER_NO;
	} while(index != channel->io_buf_no);

	return NULL;
}

/**
 * release command buffer
 */
static void
qeth_release_buffer(struct qeth_channel *channel, struct qeth_cmd_buffer *iob)
{
	unsigned long flags;

	QETH_DBF_TEXT(trace, 6, "relbuff");
	spin_lock_irqsave(&channel->iob_lock, flags);
	memset(iob->data, 0, QETH_BUFSIZE);
	iob->state = BUF_STATE_FREE;
	iob->callback = qeth_send_control_data_cb;
	iob->rc = 0;
	spin_unlock_irqrestore(&channel->iob_lock, flags);
}

static struct qeth_cmd_buffer *
qeth_get_buffer(struct qeth_channel *channel)
{
	struct qeth_cmd_buffer *buffer = NULL;
	unsigned long flags;

	spin_lock_irqsave(&channel->iob_lock, flags);
	buffer = __qeth_get_buffer(channel);
	spin_unlock_irqrestore(&channel->iob_lock, flags);
	return buffer;
}

static struct qeth_cmd_buffer *
qeth_wait_for_buffer(struct qeth_channel *channel)
{
	struct qeth_cmd_buffer *buffer;
	wait_event(channel->wait_q,
		   ((buffer = qeth_get_buffer(channel)) != NULL));
	return buffer;
}

static void
qeth_clear_cmd_buffers(struct qeth_channel *channel)
{
	int cnt;

	for (cnt=0; cnt < QETH_CMD_BUFFER_NO; cnt++)
		qeth_release_buffer(channel,&channel->iob[cnt]);
	channel->buf_no = 0;
	channel->io_buf_no = 0;
}

/**
 * start IDX for read and write channel
 */
static int
qeth_idx_activate_get_answer(struct qeth_channel *channel,
			      void (*idx_reply_cb)(struct qeth_channel *,
						   struct qeth_cmd_buffer *))
{
	struct qeth_cmd_buffer *iob;
	unsigned long flags;
	int rc;
	struct qeth_card *card;

	QETH_DBF_TEXT(setup, 2, "idxanswr");
	card = CARD_FROM_CDEV(channel->ccwdev);
	iob = qeth_get_buffer(channel);
	iob->callback = idx_reply_cb;
	memcpy(&channel->ccw, READ_CCW, sizeof(struct ccw1));
	channel->ccw.count = QETH_BUFSIZE;
	channel->ccw.cda = (__u32) __pa(iob->data);

	wait_event(card->wait_q,
		   atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
	QETH_DBF_TEXT(setup, 6, "noirqpnd");
	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
	rc = ccw_device_start(channel->ccwdev,
			      &channel->ccw,(addr_t) iob, 0, 0);
	spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);

	if (rc) {
		PRINT_ERR("qeth: Error2 in activating channel rc=%d\n",rc);
		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
		atomic_set(&channel->irq_pending, 0);
		wake_up(&card->wait_q);
		return rc;
	}
	rc = wait_event_interruptible_timeout(card->wait_q,
			 channel->state == CH_STATE_UP, QETH_TIMEOUT);
	if (rc == -ERESTARTSYS)
		return rc;
	if (channel->state != CH_STATE_UP){
		rc = -ETIME;
		QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
		qeth_clear_cmd_buffers(channel);
	} else
		rc = 0;
	return rc;
}

static int
qeth_idx_activate_channel(struct qeth_channel *channel,
			   void (*idx_reply_cb)(struct qeth_channel *,
						struct qeth_cmd_buffer *))
{
	struct qeth_card *card;
	struct qeth_cmd_buffer *iob;
	unsigned long flags;
	__u16 temp;
	int rc;

	card = CARD_FROM_CDEV(channel->ccwdev);

	QETH_DBF_TEXT(setup, 2, "idxactch");

	iob = qeth_get_buffer(channel);
	iob->callback = idx_reply_cb;
	memcpy(&channel->ccw, WRITE_CCW, sizeof(struct ccw1));
	channel->ccw.count = IDX_ACTIVATE_SIZE;
	channel->ccw.cda = (__u32) __pa(iob->data);
	if (channel == &card->write) {
		memcpy(iob->data, IDX_ACTIVATE_WRITE, IDX_ACTIVATE_SIZE);
		memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
		       &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
		card->seqno.trans_hdr++;
	} else {
		memcpy(iob->data, IDX_ACTIVATE_READ, IDX_ACTIVATE_SIZE);
		memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
		       &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
	}
	memcpy(QETH_IDX_ACT_ISSUER_RM_TOKEN(iob->data),
	       &card->token.issuer_rm_w,QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_IDX_ACT_FUNC_LEVEL(iob->data),
	       &card->info.func_level,sizeof(__u16));
	temp = raw_devno_from_bus_id(CARD_DDEV_ID(card));
	memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(iob->data), &temp, 2);
	temp = (card->info.cula << 8) + card->info.unit_addr2;
	memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(iob->data), &temp, 2);

	wait_event(card->wait_q,
		   atomic_cmpxchg(&channel->irq_pending, 0, 1) == 0);
	QETH_DBF_TEXT(setup, 6, "noirqpnd");
	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
	rc = ccw_device_start(channel->ccwdev,
			      &channel->ccw,(addr_t) iob, 0, 0);
	spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);

	if (rc) {
		PRINT_ERR("qeth: Error1 in activating channel. rc=%d\n",rc);
		QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
		atomic_set(&channel->irq_pending, 0);
		wake_up(&card->wait_q);
		return rc;
	}
	rc = wait_event_interruptible_timeout(card->wait_q,
			channel->state == CH_STATE_ACTIVATING, QETH_TIMEOUT);
	if (rc == -ERESTARTSYS)
		return rc;
	if (channel->state != CH_STATE_ACTIVATING) {
		PRINT_WARN("qeth: IDX activate timed out!\n");
		QETH_DBF_TEXT_(setup, 2, "2err%d", -ETIME);
		qeth_clear_cmd_buffers(channel);
		return -ETIME;
	}
	return qeth_idx_activate_get_answer(channel,idx_reply_cb);
}

static int
qeth_peer_func_level(int level)
{
	if ((level & 0xff) == 8)
		return (level & 0xff) + 0x400;
	if (((level >> 8) & 3) == 1)
		return (level & 0xff) + 0x200;
	return level;
}

static void
qeth_idx_write_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob)
{
	struct qeth_card *card;
	__u16 temp;

	QETH_DBF_TEXT(setup ,2, "idxwrcb");

	if (channel->state == CH_STATE_DOWN) {
		channel->state = CH_STATE_ACTIVATING;
		goto out;
	}
	card = CARD_FROM_CDEV(channel->ccwdev);

	if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
		PRINT_ERR("IDX_ACTIVATE on write channel device %s: negative "
			  "reply\n", CARD_WDEV_ID(card));
		goto out;
	}
	memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
	if ((temp & ~0x0100) != qeth_peer_func_level(card->info.func_level)) {
		PRINT_WARN("IDX_ACTIVATE on write channel device %s: "
			   "function level mismatch "
			   "(sent: 0x%x, received: 0x%x)\n",
			   CARD_WDEV_ID(card), card->info.func_level, temp);
		goto out;
	}
	channel->state = CH_STATE_UP;
out:
	qeth_release_buffer(channel, iob);
}

static int
qeth_check_idx_response(unsigned char *buffer)
{
	if (!buffer)
		return 0;

	QETH_DBF_HEX(control, 2, buffer, QETH_DBF_CONTROL_LEN);
	if ((buffer[2] & 0xc0) == 0xc0) {
		PRINT_WARN("received an IDX TERMINATE "
			   "with cause code 0x%02x%s\n",
			   buffer[4],
			   ((buffer[4] == 0x22) ?
			    " -- try another portname" : ""));
		QETH_DBF_TEXT(trace, 2, "ckidxres");
		QETH_DBF_TEXT(trace, 2, " idxterm");
		QETH_DBF_TEXT_(trace, 2, "  rc%d", -EIO);
		return -EIO;
	}
	return 0;
}

static void
qeth_idx_read_cb(struct qeth_channel *channel, struct qeth_cmd_buffer *iob)
{
	struct qeth_card *card;
	__u16 temp;

	QETH_DBF_TEXT(setup , 2, "idxrdcb");
	if (channel->state == CH_STATE_DOWN) {
		channel->state = CH_STATE_ACTIVATING;
		goto out;
	}

	card = CARD_FROM_CDEV(channel->ccwdev);
	if (qeth_check_idx_response(iob->data)) {
			goto out;
	}
	if (!(QETH_IS_IDX_ACT_POS_REPLY(iob->data))) {
		PRINT_ERR("IDX_ACTIVATE on read channel device %s: negative "
			  "reply\n", CARD_RDEV_ID(card));
		goto out;
	}

/**
 * temporary fix for microcode bug
 * to revert it,replace OR by AND
 */
	if ( (!QETH_IDX_NO_PORTNAME_REQUIRED(iob->data)) ||
	     (card->info.type == QETH_CARD_TYPE_OSAE) )
		card->info.portname_required = 1;

	memcpy(&temp, QETH_IDX_ACT_FUNC_LEVEL(iob->data), 2);
	if (temp != qeth_peer_func_level(card->info.func_level)) {
		PRINT_WARN("IDX_ACTIVATE on read channel device %s: function "
			   "level mismatch (sent: 0x%x, received: 0x%x)\n",
			   CARD_RDEV_ID(card), card->info.func_level, temp);
		goto out;
	}
	memcpy(&card->token.issuer_rm_r,
	       QETH_IDX_ACT_ISSUER_RM_TOKEN(iob->data),
	       QETH_MPC_TOKEN_LENGTH);
	memcpy(&card->info.mcl_level[0],
	       QETH_IDX_REPLY_LEVEL(iob->data), QETH_MCL_LENGTH);
	channel->state = CH_STATE_UP;
out:
	qeth_release_buffer(channel,iob);
}

static int
qeth_issue_next_read(struct qeth_card *card)
{
	int rc;
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(trace,5,"issnxrd");
	if (card->read.state != CH_STATE_UP)
		return -EIO;
	iob = qeth_get_buffer(&card->read);
	if (!iob) {
		PRINT_WARN("issue_next_read failed: no iob available!\n");
		return -ENOMEM;
	}
	qeth_setup_ccw(&card->read, iob->data, QETH_BUFSIZE);
	QETH_DBF_TEXT(trace, 6, "noirqpnd");
	rc = ccw_device_start(card->read.ccwdev, &card->read.ccw,
			      (addr_t) iob, 0, 0);
	if (rc) {
		PRINT_ERR("Error in starting next read ccw! rc=%i\n", rc);
		atomic_set(&card->read.irq_pending, 0);
		qeth_schedule_recovery(card);
		wake_up(&card->wait_q);
	}
	return rc;
}

static struct qeth_reply *
qeth_alloc_reply(struct qeth_card *card)
{
	struct qeth_reply *reply;

	reply = kzalloc(sizeof(struct qeth_reply), GFP_ATOMIC);
	if (reply){
		atomic_set(&reply->refcnt, 1);
		atomic_set(&reply->received, 0);
		reply->card = card;
	};
	return reply;
}

static void
qeth_get_reply(struct qeth_reply *reply)
{
	WARN_ON(atomic_read(&reply->refcnt) <= 0);
	atomic_inc(&reply->refcnt);
}

static void
qeth_put_reply(struct qeth_reply *reply)
{
	WARN_ON(atomic_read(&reply->refcnt) <= 0);
	if (atomic_dec_and_test(&reply->refcnt))
		kfree(reply);
}

static void
qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, struct qeth_card *card)
{
	int rc;
	int com;
	char * ipa_name;

	com = cmd->hdr.command;
	rc  = cmd->hdr.return_code;
	ipa_name = qeth_get_ipa_cmd_name(com);

	PRINT_ERR("%s(x%X) for %s returned x%X \"%s\"\n", ipa_name, com,
		   QETH_CARD_IFNAME(card), rc, qeth_get_ipa_msg(rc));
}

static struct qeth_ipa_cmd *
qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
{
	struct qeth_ipa_cmd *cmd = NULL;

	QETH_DBF_TEXT(trace,5,"chkipad");
	if (IS_IPA(iob->data)){
		cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
		if (IS_IPA_REPLY(cmd)) {
			if (cmd->hdr.return_code)
				qeth_issue_ipa_msg(cmd, card);
			return cmd;
		}
		else {
			switch (cmd->hdr.command) {
			case IPA_CMD_STOPLAN:
				PRINT_WARN("Link failure on %s (CHPID 0x%X) - "
					   "there is a network problem or "
					   "someone pulled the cable or "
					   "disabled the port.\n",
					   QETH_CARD_IFNAME(card),
					   card->info.chpid);
				card->lan_online = 0;
				if (card->dev && netif_carrier_ok(card->dev))
					netif_carrier_off(card->dev);
				return NULL;
			case IPA_CMD_STARTLAN:
				PRINT_INFO("Link reestablished on %s "
					   "(CHPID 0x%X). Scheduling "
					   "IP address reset.\n",
					   QETH_CARD_IFNAME(card),
					   card->info.chpid);
				netif_carrier_on(card->dev);
				qeth_schedule_recovery(card);
				return NULL;
			case IPA_CMD_MODCCID:
				return cmd;
			case IPA_CMD_REGISTER_LOCAL_ADDR:
				QETH_DBF_TEXT(trace,3, "irla");
				break;
			case IPA_CMD_UNREGISTER_LOCAL_ADDR:
				QETH_DBF_TEXT(trace,3, "urla");
				break;
			default:
				PRINT_WARN("Received data is IPA "
					   "but not a reply!\n");
				break;
			}
		}
	}
	return cmd;
}

/**
 * wake all waiting ipa commands
 */
static void
qeth_clear_ipacmd_list(struct qeth_card *card)
{
	struct qeth_reply *reply, *r;
	unsigned long flags;

	QETH_DBF_TEXT(trace, 4, "clipalst");

	spin_lock_irqsave(&card->lock, flags);
	list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
		qeth_get_reply(reply);
		reply->rc = -EIO;
		atomic_inc(&reply->received);
		list_del_init(&reply->list);
		wake_up(&reply->wait_q);
		qeth_put_reply(reply);
	}
	spin_unlock_irqrestore(&card->lock, flags);
}

static void
qeth_send_control_data_cb(struct qeth_channel *channel,
			  struct qeth_cmd_buffer *iob)
{
	struct qeth_card *card;
	struct qeth_reply *reply, *r;
	struct qeth_ipa_cmd *cmd;
	unsigned long flags;
	int keep_reply;

	QETH_DBF_TEXT(trace,4,"sndctlcb");

	card = CARD_FROM_CDEV(channel->ccwdev);
	if (qeth_check_idx_response(iob->data)) {
		qeth_clear_ipacmd_list(card);
		qeth_schedule_recovery(card);
		goto out;
	}

	cmd = qeth_check_ipa_data(card, iob);
	if ((cmd == NULL) && (card->state != CARD_STATE_DOWN))
		goto out;
	/*in case of OSN : check if cmd is set */
	if (card->info.type == QETH_CARD_TYPE_OSN &&
	    cmd &&
	    cmd->hdr.command != IPA_CMD_STARTLAN &&
	    card->osn_info.assist_cb != NULL) {
		card->osn_info.assist_cb(card->dev, cmd);
		goto out;
	}

	spin_lock_irqsave(&card->lock, flags);
	list_for_each_entry_safe(reply, r, &card->cmd_waiter_list, list) {
		if ((reply->seqno == QETH_IDX_COMMAND_SEQNO) ||
		    ((cmd) && (reply->seqno == cmd->hdr.seqno))) {
			qeth_get_reply(reply);
			list_del_init(&reply->list);
			spin_unlock_irqrestore(&card->lock, flags);
			keep_reply = 0;
			if (reply->callback != NULL) {
				if (cmd) {
					reply->offset = (__u16)((char*)cmd -
								(char *)iob->data);
					keep_reply = reply->callback(card,
							reply,
							(unsigned long)cmd);
				} else
					keep_reply = reply->callback(card,
							reply,
							(unsigned long)iob);
			}
			if (cmd)
				reply->rc = (u16) cmd->hdr.return_code;
			else if (iob->rc)
				reply->rc = iob->rc;
			if (keep_reply) {
				spin_lock_irqsave(&card->lock, flags);
				list_add_tail(&reply->list,
					      &card->cmd_waiter_list);
				spin_unlock_irqrestore(&card->lock, flags);
			} else {
				atomic_inc(&reply->received);
				wake_up(&reply->wait_q);
			}
			qeth_put_reply(reply);
			goto out;
		}
	}
	spin_unlock_irqrestore(&card->lock, flags);
out:
	memcpy(&card->seqno.pdu_hdr_ack,
		QETH_PDU_HEADER_SEQ_NO(iob->data),
		QETH_SEQ_NO_LENGTH);
	qeth_release_buffer(channel,iob);
}

static void
qeth_prepare_control_data(struct qeth_card *card, int len,
			  struct qeth_cmd_buffer *iob)
{
	qeth_setup_ccw(&card->write,iob->data,len);
	iob->callback = qeth_release_buffer;

	memcpy(QETH_TRANSPORT_HEADER_SEQ_NO(iob->data),
	       &card->seqno.trans_hdr, QETH_SEQ_NO_LENGTH);
	card->seqno.trans_hdr++;
	memcpy(QETH_PDU_HEADER_SEQ_NO(iob->data),
	       &card->seqno.pdu_hdr, QETH_SEQ_NO_LENGTH);
	card->seqno.pdu_hdr++;
	memcpy(QETH_PDU_HEADER_ACK_SEQ_NO(iob->data),
	       &card->seqno.pdu_hdr_ack, QETH_SEQ_NO_LENGTH);
	QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);
}

static int
qeth_send_control_data(struct qeth_card *card, int len,
		       struct qeth_cmd_buffer *iob,
		       int (*reply_cb)
		       (struct qeth_card *, struct qeth_reply*, unsigned long),
		       void *reply_param)

{
	int rc;
	unsigned long flags;
	struct qeth_reply *reply = NULL;
	unsigned long timeout;

	QETH_DBF_TEXT(trace, 2, "sendctl");

	reply = qeth_alloc_reply(card);
	if (!reply) {
		PRINT_WARN("Could no alloc qeth_reply!\n");
		return -ENOMEM;
	}
	reply->callback = reply_cb;
	reply->param = reply_param;
	if (card->state == CARD_STATE_DOWN)
		reply->seqno = QETH_IDX_COMMAND_SEQNO;
	else
		reply->seqno = card->seqno.ipa++;
	init_waitqueue_head(&reply->wait_q);
	spin_lock_irqsave(&card->lock, flags);
	list_add_tail(&reply->list, &card->cmd_waiter_list);
	spin_unlock_irqrestore(&card->lock, flags);
	QETH_DBF_HEX(control, 2, iob->data, QETH_DBF_CONTROL_LEN);

	while (atomic_cmpxchg(&card->write.irq_pending, 0, 1)) ;
	qeth_prepare_control_data(card, len, iob);

	if (IS_IPA(iob->data))
		timeout = jiffies + QETH_IPA_TIMEOUT;
	else
		timeout = jiffies + QETH_TIMEOUT;

	QETH_DBF_TEXT(trace, 6, "noirqpnd");
	spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
	rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
			      (addr_t) iob, 0, 0);
	spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
	if (rc){
		PRINT_WARN("qeth_send_control_data: "
			   "ccw_device_start rc = %i\n", rc);
		QETH_DBF_TEXT_(trace, 2, " err%d", rc);
		spin_lock_irqsave(&card->lock, flags);
		list_del_init(&reply->list);
		qeth_put_reply(reply);
		spin_unlock_irqrestore(&card->lock, flags);
		qeth_release_buffer(iob->channel, iob);
		atomic_set(&card->write.irq_pending, 0);
		wake_up(&card->wait_q);
		return rc;
	}
	while (!atomic_read(&reply->received)) {
		if (time_after(jiffies, timeout)) {
			spin_lock_irqsave(&reply->card->lock, flags);
			list_del_init(&reply->list);
			spin_unlock_irqrestore(&reply->card->lock, flags);
			reply->rc = -ETIME;
			atomic_inc(&reply->received);
			wake_up(&reply->wait_q);
		}
		cpu_relax();
	};
	rc = reply->rc;
	qeth_put_reply(reply);
	return rc;
}

static int
qeth_osn_send_control_data(struct qeth_card *card, int len,
			   struct qeth_cmd_buffer *iob)
{
	unsigned long flags;
	int rc = 0;

	QETH_DBF_TEXT(trace, 5, "osndctrd");

	wait_event(card->wait_q,
		   atomic_cmpxchg(&card->write.irq_pending, 0, 1) == 0);
	qeth_prepare_control_data(card, len, iob);
	QETH_DBF_TEXT(trace, 6, "osnoirqp");
	spin_lock_irqsave(get_ccwdev_lock(card->write.ccwdev), flags);
	rc = ccw_device_start(card->write.ccwdev, &card->write.ccw,
			      (addr_t) iob, 0, 0);
	spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags);
	if (rc){
		PRINT_WARN("qeth_osn_send_control_data: "
			   "ccw_device_start rc = %i\n", rc);
		QETH_DBF_TEXT_(trace, 2, " err%d", rc);
		qeth_release_buffer(iob->channel, iob);
		atomic_set(&card->write.irq_pending, 0);
		wake_up(&card->wait_q);
	}
	return rc;
}

static inline void
qeth_prepare_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
		     char prot_type)
{
	memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
	memcpy(QETH_IPA_CMD_PROT_TYPE(iob->data),&prot_type,1);
	memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
	       &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
}

static int
qeth_osn_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
		      int data_len)
{
	u16 s1, s2;

	QETH_DBF_TEXT(trace,4,"osndipa");

	qeth_prepare_ipa_cmd(card, iob, QETH_PROT_OSN2);
	s1 = (u16)(IPA_PDU_HEADER_SIZE + data_len);
	s2 = (u16)data_len;
	memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
	memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
	memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
	memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
	return qeth_osn_send_control_data(card, s1, iob);
}

static int
qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
		  int (*reply_cb)
		  (struct qeth_card *,struct qeth_reply*, unsigned long),
		  void *reply_param)
{
	int rc;
	char prot_type;

	QETH_DBF_TEXT(trace,4,"sendipa");

	if (card->options.layer2)
		if (card->info.type == QETH_CARD_TYPE_OSN)
			prot_type = QETH_PROT_OSN2;
		else
			prot_type = QETH_PROT_LAYER2;
	else
		prot_type = QETH_PROT_TCPIP;
	qeth_prepare_ipa_cmd(card,iob,prot_type);
	rc = qeth_send_control_data(card, IPA_CMD_LENGTH, iob,
				    reply_cb, reply_param);
	return rc;
}


static int
qeth_cm_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
		  unsigned long data)
{
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(setup, 2, "cmenblcb");

	iob = (struct qeth_cmd_buffer *) data;
	memcpy(&card->token.cm_filter_r,
	       QETH_CM_ENABLE_RESP_FILTER_TOKEN(iob->data),
	       QETH_MPC_TOKEN_LENGTH);
	QETH_DBF_TEXT_(setup, 2, "  rc%d", iob->rc);
	return 0;
}

static int
qeth_cm_enable(struct qeth_card *card)
{
	int rc;
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(setup,2,"cmenable");

	iob = qeth_wait_for_buffer(&card->write);
	memcpy(iob->data, CM_ENABLE, CM_ENABLE_SIZE);
	memcpy(QETH_CM_ENABLE_ISSUER_RM_TOKEN(iob->data),
	       &card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_CM_ENABLE_FILTER_TOKEN(iob->data),
	       &card->token.cm_filter_w, QETH_MPC_TOKEN_LENGTH);

	rc = qeth_send_control_data(card, CM_ENABLE_SIZE, iob,
				    qeth_cm_enable_cb, NULL);
	return rc;
}

static int
qeth_cm_setup_cb(struct qeth_card *card, struct qeth_reply *reply,
		 unsigned long data)
{

	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(setup, 2, "cmsetpcb");

	iob = (struct qeth_cmd_buffer *) data;
	memcpy(&card->token.cm_connection_r,
	       QETH_CM_SETUP_RESP_DEST_ADDR(iob->data),
	       QETH_MPC_TOKEN_LENGTH);
	QETH_DBF_TEXT_(setup, 2, "  rc%d", iob->rc);
	return 0;
}

static int
qeth_cm_setup(struct qeth_card *card)
{
	int rc;
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(setup,2,"cmsetup");

	iob = qeth_wait_for_buffer(&card->write);
	memcpy(iob->data, CM_SETUP, CM_SETUP_SIZE);
	memcpy(QETH_CM_SETUP_DEST_ADDR(iob->data),
	       &card->token.issuer_rm_r, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_CM_SETUP_CONNECTION_TOKEN(iob->data),
	       &card->token.cm_connection_w, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_CM_SETUP_FILTER_TOKEN(iob->data),
	       &card->token.cm_filter_r, QETH_MPC_TOKEN_LENGTH);
	rc = qeth_send_control_data(card, CM_SETUP_SIZE, iob,
				    qeth_cm_setup_cb, NULL);
	return rc;

}

static int
qeth_ulp_enable_cb(struct qeth_card *card, struct qeth_reply *reply,
		   unsigned long data)
{

	__u16 mtu, framesize;
	__u16 len;
	__u8 link_type;
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(setup, 2, "ulpenacb");

	iob = (struct qeth_cmd_buffer *) data;
	memcpy(&card->token.ulp_filter_r,
	       QETH_ULP_ENABLE_RESP_FILTER_TOKEN(iob->data),
	       QETH_MPC_TOKEN_LENGTH);
	if (qeth_get_mtu_out_of_mpc(card->info.type)) {
		memcpy(&framesize, QETH_ULP_ENABLE_RESP_MAX_MTU(iob->data), 2);
		mtu = qeth_get_mtu_outof_framesize(framesize);
		if (!mtu) {
			iob->rc = -EINVAL;
			QETH_DBF_TEXT_(setup, 2, "  rc%d", iob->rc);
			return 0;
		}
		card->info.max_mtu = mtu;
		card->info.initial_mtu = mtu;
		card->qdio.in_buf_size = mtu + 2 * PAGE_SIZE;
	} else {
		card->info.initial_mtu = qeth_get_initial_mtu_for_card(card);
		card->info.max_mtu = qeth_get_max_mtu_for_card(card->info.type);
		card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT;
	}

	memcpy(&len, QETH_ULP_ENABLE_RESP_DIFINFO_LEN(iob->data), 2);
	if (len >= QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE) {
		memcpy(&link_type,
		       QETH_ULP_ENABLE_RESP_LINK_TYPE(iob->data), 1);
		card->info.link_type = link_type;
	} else
		card->info.link_type = 0;
	QETH_DBF_TEXT_(setup, 2, "  rc%d", iob->rc);
	return 0;
}

static int
qeth_ulp_enable(struct qeth_card *card)
{
	int rc;
	char prot_type;
	struct qeth_cmd_buffer *iob;

	/*FIXME: trace view callbacks*/
	QETH_DBF_TEXT(setup,2,"ulpenabl");

	iob = qeth_wait_for_buffer(&card->write);
	memcpy(iob->data, ULP_ENABLE, ULP_ENABLE_SIZE);

	*(QETH_ULP_ENABLE_LINKNUM(iob->data)) =
		(__u8) card->info.portno;
	if (card->options.layer2)
		if (card->info.type == QETH_CARD_TYPE_OSN)
			prot_type = QETH_PROT_OSN2;
		else
			prot_type = QETH_PROT_LAYER2;
	else
		prot_type = QETH_PROT_TCPIP;

	memcpy(QETH_ULP_ENABLE_PROT_TYPE(iob->data),&prot_type,1);
	memcpy(QETH_ULP_ENABLE_DEST_ADDR(iob->data),
	       &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_ULP_ENABLE_FILTER_TOKEN(iob->data),
	       &card->token.ulp_filter_w, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_ULP_ENABLE_PORTNAME_AND_LL(iob->data),
	       card->info.portname, 9);
	rc = qeth_send_control_data(card, ULP_ENABLE_SIZE, iob,
				    qeth_ulp_enable_cb, NULL);
	return rc;

}

static int
qeth_ulp_setup_cb(struct qeth_card *card, struct qeth_reply *reply,
		  unsigned long data)
{
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(setup, 2, "ulpstpcb");

	iob = (struct qeth_cmd_buffer *) data;
	memcpy(&card->token.ulp_connection_r,
	       QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(iob->data),
	       QETH_MPC_TOKEN_LENGTH);
	QETH_DBF_TEXT_(setup, 2, "  rc%d", iob->rc);
	return 0;
}

static int
qeth_ulp_setup(struct qeth_card *card)
{
	int rc;
	__u16 temp;
	struct qeth_cmd_buffer *iob;
	struct ccw_dev_id dev_id;

	QETH_DBF_TEXT(setup,2,"ulpsetup");

	iob = qeth_wait_for_buffer(&card->write);
	memcpy(iob->data, ULP_SETUP, ULP_SETUP_SIZE);

	memcpy(QETH_ULP_SETUP_DEST_ADDR(iob->data),
	       &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_ULP_SETUP_CONNECTION_TOKEN(iob->data),
	       &card->token.ulp_connection_w, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_ULP_SETUP_FILTER_TOKEN(iob->data),
	       &card->token.ulp_filter_r, QETH_MPC_TOKEN_LENGTH);

	ccw_device_get_id(CARD_DDEV(card), &dev_id);
	memcpy(QETH_ULP_SETUP_CUA(iob->data), &dev_id.devno, 2);
	temp = (card->info.cula << 8) + card->info.unit_addr2;
	memcpy(QETH_ULP_SETUP_REAL_DEVADDR(iob->data), &temp, 2);
	rc = qeth_send_control_data(card, ULP_SETUP_SIZE, iob,
				    qeth_ulp_setup_cb, NULL);
	return rc;
}

static inline int
qeth_check_qdio_errors(struct qdio_buffer *buf, unsigned int qdio_error,
		       unsigned int siga_error, const char *dbftext)
{
	if (qdio_error || siga_error) {
		QETH_DBF_TEXT(trace, 2, dbftext);
		QETH_DBF_TEXT(qerr, 2, dbftext);
		QETH_DBF_TEXT_(qerr, 2, " F15=%02X",
			       buf->element[15].flags & 0xff);
		QETH_DBF_TEXT_(qerr, 2, " F14=%02X",
			       buf->element[14].flags & 0xff);
		QETH_DBF_TEXT_(qerr, 2, " qerr=%X", qdio_error);
		QETH_DBF_TEXT_(qerr, 2, " serr=%X", siga_error);
		return 1;
	}
	return 0;
}

static struct sk_buff *
qeth_get_skb(unsigned int length, struct qeth_hdr *hdr)
{
	struct sk_buff* skb;
	int add_len;

	add_len = 0;
	if (hdr->hdr.osn.id == QETH_HEADER_TYPE_OSN)
		add_len = sizeof(struct qeth_hdr);
#ifdef CONFIG_QETH_VLAN
	else
		add_len = VLAN_HLEN;
#endif
	skb = dev_alloc_skb(length + add_len);
	if (skb && add_len)
		skb_reserve(skb, add_len);
	return skb;
}

static inline int
qeth_create_skb_frag(struct qdio_buffer_element *element,
		     struct sk_buff **pskb,
		     int offset, int *pfrag, int data_len)
{
	struct page *page = virt_to_page(element->addr);
	if (*pfrag == 0) {
		/* the upper protocol layers assume that there is data in the
		 * skb itself. Copy a small amount (64 bytes) to make them
		 * happy. */
		*pskb = dev_alloc_skb(64 + QETH_FAKE_LL_LEN_ETH);
		if (!(*pskb))
			return -ENOMEM;
		skb_reserve(*pskb, QETH_FAKE_LL_LEN_ETH);
		if (data_len <= 64) {
			memcpy(skb_put(*pskb, data_len), element->addr + offset,
				data_len);
		} else {
			get_page(page);
			memcpy(skb_put(*pskb, 64), element->addr + offset, 64);
			skb_fill_page_desc(*pskb, *pfrag, page, offset + 64,
				data_len - 64);
			(*pskb)->data_len += data_len - 64;
			(*pskb)->len	  += data_len - 64;
			(*pskb)->truesize += data_len - 64;
		}
	} else {
		get_page(page);
		skb_fill_page_desc(*pskb, *pfrag, page, offset, data_len);
		(*pskb)->data_len += data_len;
		(*pskb)->len	  += data_len;
		(*pskb)->truesize += data_len;
	}
	(*pfrag)++;
	return 0;
}

static inline struct qeth_buffer_pool_entry *
qeth_find_free_buffer_pool_entry(struct qeth_card *card)
{
	struct list_head *plh;
	struct qeth_buffer_pool_entry *entry;
	int i, free;
	struct page *page;

	if (list_empty(&card->qdio.in_buf_pool.entry_list))
		return NULL;

	list_for_each(plh, &card->qdio.in_buf_pool.entry_list) {
		entry = list_entry(plh, struct qeth_buffer_pool_entry, list);
		free = 1;
		for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
			if (page_count(virt_to_page(entry->elements[i])) > 1) {
				free = 0;
				break;
			}
		}
		if (free) {
			list_del_init(&entry->list);
			return entry;
		}
	}

	/* no free buffer in pool so take first one and swap pages */
	entry = list_entry(card->qdio.in_buf_pool.entry_list.next,
			struct qeth_buffer_pool_entry, list);
	for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
		if (page_count(virt_to_page(entry->elements[i])) > 1) {
			page = alloc_page(GFP_ATOMIC|GFP_DMA);
			if (!page) {
				return NULL;
			} else {
				free_page((unsigned long)entry->elements[i]);
				entry->elements[i] = page_address(page);
				if (card->options.performance_stats)
					card->perf_stats.sg_alloc_page_rx++;
			}
		}
	}
	list_del_init(&entry->list);
	return entry;
}

static struct sk_buff *
qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
		  struct qdio_buffer_element **__element, int *__offset,
		  struct qeth_hdr **hdr)
{
	struct qdio_buffer_element *element = *__element;
	int offset = *__offset;
	struct sk_buff *skb = NULL;
	int skb_len;
	void *data_ptr;
	int data_len;
	int use_rx_sg = 0;
	int frag = 0;

	QETH_DBF_TEXT(trace,6,"nextskb");
	/* qeth_hdr must not cross element boundaries */
	if (element->length < offset + sizeof(struct qeth_hdr)){
		if (qeth_is_last_sbale(element))
			return NULL;
		element++;
		offset = 0;
		if (element->length < sizeof(struct qeth_hdr))
			return NULL;
	}
	*hdr = element->addr + offset;

	offset += sizeof(struct qeth_hdr);
	if (card->options.layer2)
		if (card->info.type == QETH_CARD_TYPE_OSN)
			skb_len = (*hdr)->hdr.osn.pdu_length;
		else
			skb_len = (*hdr)->hdr.l2.pkt_length;
	else
		skb_len = (*hdr)->hdr.l3.length;

	if (!skb_len)
		return NULL;
	if ((skb_len >= card->options.rx_sg_cb) &&
	    (!(card->info.type == QETH_CARD_TYPE_OSN)) &&
	    (!atomic_read(&card->force_alloc_skb))) {
		use_rx_sg = 1;
	} else {
		if (card->options.fake_ll) {
			if (card->dev->type == ARPHRD_IEEE802_TR) {
				if (!(skb = qeth_get_skb(skb_len +
						QETH_FAKE_LL_LEN_TR, *hdr)))
					goto no_mem;
				skb_reserve(skb, QETH_FAKE_LL_LEN_TR);
			} else {
				if (!(skb = qeth_get_skb(skb_len +
						QETH_FAKE_LL_LEN_ETH, *hdr)))
					goto no_mem;
				skb_reserve(skb, QETH_FAKE_LL_LEN_ETH);
			}
		} else {
			skb = qeth_get_skb(skb_len, *hdr);
			if (!skb)
				goto no_mem;
		}
	}

	data_ptr = element->addr + offset;
	while (skb_len) {
		data_len = min(skb_len, (int)(element->length - offset));
		if (data_len) {
			if (use_rx_sg) {
				if (qeth_create_skb_frag(element, &skb, offset,
				    &frag, data_len))
					goto no_mem;
			} else {
				memcpy(skb_put(skb, data_len), data_ptr,
					data_len);
			}
		}
		skb_len -= data_len;
		if (skb_len){
			if (qeth_is_last_sbale(element)){
				QETH_DBF_TEXT(trace,4,"unexeob");
				QETH_DBF_TEXT_(trace,4,"%s",CARD_BUS_ID(card));
				QETH_DBF_TEXT(qerr,2,"unexeob");
				QETH_DBF_TEXT_(qerr,2,"%s",CARD_BUS_ID(card));
				QETH_DBF_HEX(misc,4,buffer,sizeof(*buffer));
				dev_kfree_skb_any(skb);
				card->stats.rx_errors++;
				return NULL;
			}
			element++;
			offset = 0;
			data_ptr = element->addr;
		} else {
			offset += data_len;
		}
	}
	*__element = element;
	*__offset = offset;
	if (use_rx_sg && card->options.performance_stats) {
		card->perf_stats.sg_skbs_rx++;
		card->perf_stats.sg_frags_rx += skb_shinfo(skb)->nr_frags;
	}
	return skb;
no_mem:
	if (net_ratelimit()){
		PRINT_WARN("No memory for packet received on %s.\n",
			   QETH_CARD_IFNAME(card));
		QETH_DBF_TEXT(trace,2,"noskbmem");
		QETH_DBF_TEXT_(trace,2,"%s",CARD_BUS_ID(card));
	}
	card->stats.rx_dropped++;
	return NULL;
}

static __be16
qeth_type_trans(struct sk_buff *skb, struct net_device *dev)
{
	struct qeth_card *card;
	struct ethhdr *eth;

	QETH_DBF_TEXT(trace,6,"typtrans");

	card = (struct qeth_card *)dev->priv;
#ifdef CONFIG_TR
	if ((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
	    (card->info.link_type == QETH_LINK_TYPE_LANE_TR))
	 	return tr_type_trans(skb,dev);
#endif /* CONFIG_TR */
	skb_reset_mac_header(skb);
	skb_pull(skb, ETH_HLEN );
	eth = eth_hdr(skb);

	if (*eth->h_dest & 1) {
		if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN) == 0)
			skb->pkt_type = PACKET_BROADCAST;
		else
			skb->pkt_type = PACKET_MULTICAST;
	} else if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN))
		skb->pkt_type = PACKET_OTHERHOST;

	if (ntohs(eth->h_proto) >= 1536)
		return eth->h_proto;
	if (*(unsigned short *) (skb->data) == 0xFFFF)
		return htons(ETH_P_802_3);
	return htons(ETH_P_802_2);
}

static void
qeth_rebuild_skb_fake_ll_tr(struct qeth_card *card, struct sk_buff *skb,
			 struct qeth_hdr *hdr)
{
	struct trh_hdr *fake_hdr;
	struct trllc *fake_llc;
	struct iphdr *ip_hdr;

	QETH_DBF_TEXT(trace,5,"skbfktr");
	skb_set_mac_header(skb, -QETH_FAKE_LL_LEN_TR);
	/* this is a fake ethernet header */
	fake_hdr = tr_hdr(skb);

	/* the destination MAC address */
	switch (skb->pkt_type){
	case PACKET_MULTICAST:
		switch (skb->protocol){
#ifdef CONFIG_QETH_IPV6
		case __constant_htons(ETH_P_IPV6):
			ndisc_mc_map((struct in6_addr *)
				     skb->data + QETH_FAKE_LL_V6_ADDR_POS,
				     fake_hdr->daddr, card->dev, 0);
			break;
#endif /* CONFIG_QETH_IPV6 */
		case __constant_htons(ETH_P_IP):
			ip_hdr = (struct iphdr *)skb->data;
			ip_tr_mc_map(ip_hdr->daddr, fake_hdr->daddr);
			break;
		default:
			memcpy(fake_hdr->daddr, card->dev->dev_addr, TR_ALEN);
		}
		break;
	case PACKET_BROADCAST:
		memset(fake_hdr->daddr, 0xff, TR_ALEN);
		break;
	default:
		memcpy(fake_hdr->daddr, card->dev->dev_addr, TR_ALEN);
	}
	/* the source MAC address */
	if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR)
		memcpy(fake_hdr->saddr, &hdr->hdr.l3.dest_addr[2], TR_ALEN);
	else
		memset(fake_hdr->saddr, 0, TR_ALEN);
	fake_hdr->rcf=0;
	fake_llc = (struct trllc*)&(fake_hdr->rcf);
	fake_llc->dsap = EXTENDED_SAP;
	fake_llc->ssap = EXTENDED_SAP;
	fake_llc->llc  = UI_CMD;
	fake_llc->protid[0] = 0;
	fake_llc->protid[1] = 0;
	fake_llc->protid[2] = 0;
	fake_llc->ethertype = ETH_P_IP;
}

static void
qeth_rebuild_skb_fake_ll_eth(struct qeth_card *card, struct sk_buff *skb,
			 struct qeth_hdr *hdr)
{
	struct ethhdr *fake_hdr;
	struct iphdr *ip_hdr;

	QETH_DBF_TEXT(trace,5,"skbfketh");
	skb_set_mac_header(skb, -QETH_FAKE_LL_LEN_ETH);
	/* this is a fake ethernet header */
	fake_hdr = eth_hdr(skb);

	/* the destination MAC address */
	switch (skb->pkt_type){
	case PACKET_MULTICAST:
		switch (skb->protocol){
#ifdef CONFIG_QETH_IPV6
		case __constant_htons(ETH_P_IPV6):
			ndisc_mc_map((struct in6_addr *)
				     skb->data + QETH_FAKE_LL_V6_ADDR_POS,
				     fake_hdr->h_dest, card->dev, 0);
			break;
#endif /* CONFIG_QETH_IPV6 */
		case __constant_htons(ETH_P_IP):
			ip_hdr = (struct iphdr *)skb->data;
			ip_eth_mc_map(ip_hdr->daddr, fake_hdr->h_dest);
			break;
		default:
			memcpy(fake_hdr->h_dest, card->dev->dev_addr, ETH_ALEN);
		}
		break;
	case PACKET_BROADCAST:
		memset(fake_hdr->h_dest, 0xff, ETH_ALEN);
		break;
	default:
		memcpy(fake_hdr->h_dest, card->dev->dev_addr, ETH_ALEN);
	}
	/* the source MAC address */
	if (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_SRC_MAC_ADDR)
		memcpy(fake_hdr->h_source, &hdr->hdr.l3.dest_addr[2], ETH_ALEN);
	else
		memset(fake_hdr->h_source, 0, ETH_ALEN);
	/* the protocol */
	fake_hdr->h_proto = skb->protocol;
}

static inline void
qeth_rebuild_skb_fake_ll(struct qeth_card *card, struct sk_buff *skb,
			struct qeth_hdr *hdr)
{
	if (card->dev->type == ARPHRD_IEEE802_TR)
		qeth_rebuild_skb_fake_ll_tr(card, skb, hdr);
	else
		qeth_rebuild_skb_fake_ll_eth(card, skb, hdr);
}

static inline void
qeth_layer2_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
			struct qeth_hdr *hdr)
{
	skb->pkt_type = PACKET_HOST;
	skb->protocol = qeth_type_trans(skb, skb->dev);
	if (card->options.checksum_type == NO_CHECKSUMMING)
		skb->ip_summed = CHECKSUM_UNNECESSARY;
	else
		skb->ip_summed = CHECKSUM_NONE;
	*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
}

static __u16
qeth_rebuild_skb(struct qeth_card *card, struct sk_buff *skb,
		 struct qeth_hdr *hdr)
{
	unsigned short vlan_id = 0;
#ifdef CONFIG_QETH_IPV6
	if (hdr->hdr.l3.flags & QETH_HDR_PASSTHRU) {
		skb->pkt_type = PACKET_HOST;
		skb->protocol = qeth_type_trans(skb, card->dev);
		return 0;
	}
#endif /* CONFIG_QETH_IPV6 */
	skb->protocol = htons((hdr->hdr.l3.flags & QETH_HDR_IPV6)? ETH_P_IPV6 :
			      ETH_P_IP);
	switch (hdr->hdr.l3.flags & QETH_HDR_CAST_MASK){
	case QETH_CAST_UNICAST:
		skb->pkt_type = PACKET_HOST;
		break;
	case QETH_CAST_MULTICAST:
		skb->pkt_type = PACKET_MULTICAST;
		card->stats.multicast++;
		break;
	case QETH_CAST_BROADCAST:
		skb->pkt_type = PACKET_BROADCAST;
		card->stats.multicast++;
		break;
	case QETH_CAST_ANYCAST:
	case QETH_CAST_NOCAST:
	default:
		skb->pkt_type = PACKET_HOST;
	}

	if (hdr->hdr.l3.ext_flags &
	    (QETH_HDR_EXT_VLAN_FRAME | QETH_HDR_EXT_INCLUDE_VLAN_TAG)) {
		vlan_id = (hdr->hdr.l3.ext_flags & QETH_HDR_EXT_VLAN_FRAME)?
			hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]);
	}

	if (card->options.fake_ll)
		qeth_rebuild_skb_fake_ll(card, skb, hdr);
	else
		skb_reset_mac_header(skb);
	skb->ip_summed = card->options.checksum_type;
	if (card->options.checksum_type == HW_CHECKSUMMING){
		if ( (hdr->hdr.l3.ext_flags &
		      (QETH_HDR_EXT_CSUM_HDR_REQ |
		       QETH_HDR_EXT_CSUM_TRANSP_REQ)) ==
		     (QETH_HDR_EXT_CSUM_HDR_REQ |
		      QETH_HDR_EXT_CSUM_TRANSP_REQ) )
			skb->ip_summed = CHECKSUM_UNNECESSARY;
		else
			skb->ip_summed = SW_CHECKSUMMING;
	}
	return vlan_id;
}

static void
qeth_process_inbound_buffer(struct qeth_card *card,
			    struct qeth_qdio_buffer *buf, int index)
{
	struct qdio_buffer_element *element;
	struct sk_buff *skb;
	struct qeth_hdr *hdr;
	int offset;
	int rxrc;
	__u16 vlan_tag = 0;

	/* get first element of current buffer */
	element = (struct qdio_buffer_element *)&buf->buffer->element[0];
	offset = 0;
	if (card->options.performance_stats)
		card->perf_stats.bufs_rec++;
	while((skb = qeth_get_next_skb(card, buf->buffer, &element,
				       &offset, &hdr))) {
		skb->dev = card->dev;
		if (hdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
			qeth_layer2_rebuild_skb(card, skb, hdr);
		else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)
			vlan_tag = qeth_rebuild_skb(card, skb, hdr);
		else { /*in case of OSN*/
			skb_push(skb, sizeof(struct qeth_hdr));
			skb_copy_to_linear_data(skb, hdr,
						sizeof(struct qeth_hdr));
		}
		/* is device UP ? */
		if (!(card->dev->flags & IFF_UP)){
			dev_kfree_skb_any(skb);
			continue;
		}
		if (card->info.type == QETH_CARD_TYPE_OSN)
			rxrc = card->osn_info.data_cb(skb);
		else
#ifdef CONFIG_QETH_VLAN
		if (vlan_tag)
			if (card->vlangrp)
				vlan_hwaccel_rx(skb, card->vlangrp, vlan_tag);
			else {
				dev_kfree_skb_any(skb);
				continue;
			}
		else
#endif
			rxrc = netif_rx(skb);
		card->dev->last_rx = jiffies;
		card->stats.rx_packets++;
		card->stats.rx_bytes += skb->len;
	}
}

static int
qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf)
{
	struct qeth_buffer_pool_entry *pool_entry;
	int i;

	pool_entry = qeth_find_free_buffer_pool_entry(card);
	if (!pool_entry)
		return 1;
	/*
	 * since the buffer is accessed only from the input_tasklet
	 * there shouldn't be a need to synchronize; also, since we use
	 * the QETH_IN_BUF_REQUEUE_THRESHOLD we should never run  out off
	 * buffers
	 */
	BUG_ON(!pool_entry);

	buf->pool_entry = pool_entry;
	for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i){
		buf->buffer->element[i].length = PAGE_SIZE;
		buf->buffer->element[i].addr =  pool_entry->elements[i];
		if (i == QETH_MAX_BUFFER_ELEMENTS(card) - 1)
			buf->buffer->element[i].flags = SBAL_FLAGS_LAST_ENTRY;
		else
			buf->buffer->element[i].flags = 0;
	}
	buf->state = QETH_QDIO_BUF_EMPTY;
	return 0;
}

static void
qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
			 struct qeth_qdio_out_buffer *buf)
{
	int i;
	struct sk_buff *skb;

	/* is PCI flag set on buffer? */
	if (buf->buffer->element[0].flags & 0x40)
		atomic_dec(&queue->set_pci_flags_count);

	while ((skb = skb_dequeue(&buf->skb_list))){
		atomic_dec(&skb->users);
		dev_kfree_skb_any(skb);
	}
	qeth_eddp_buf_release_contexts(buf);
	for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(queue->card); ++i){
		buf->buffer->element[i].length = 0;
		buf->buffer->element[i].addr = NULL;
		buf->buffer->element[i].flags = 0;
	}
	buf->next_element_to_fill = 0;
	atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
}

static void
qeth_queue_input_buffer(struct qeth_card *card, int index)
{
	struct qeth_qdio_q *queue = card->qdio.in_q;
	int count;
	int i;
	int rc;
	int newcount = 0;

	QETH_DBF_TEXT(trace,6,"queinbuf");
	count = (index < queue->next_buf_to_init)?
		card->qdio.in_buf_pool.buf_count -
		(queue->next_buf_to_init - index) :
		card->qdio.in_buf_pool.buf_count -
		(queue->next_buf_to_init + QDIO_MAX_BUFFERS_PER_Q - index);
	/* only requeue at a certain threshold to avoid SIGAs */
	if (count >= QETH_IN_BUF_REQUEUE_THRESHOLD(card)){
		for (i = queue->next_buf_to_init;
		     i < queue->next_buf_to_init + count; ++i) {
			if (qeth_init_input_buffer(card,
				&queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q])) {
				break;
			} else {
				newcount++;
			}
		}

		if (newcount < count) {
			/* we are in memory shortage so we switch back to
			   traditional skb allocation and drop packages */
			if (atomic_cmpxchg(&card->force_alloc_skb, 0, 1))
				printk(KERN_WARNING
					"qeth: switch to alloc skb\n");
			count = newcount;
		} else {
			if (atomic_cmpxchg(&card->force_alloc_skb, 1, 0))
				printk(KERN_WARNING "qeth: switch to sg\n");
		}

		/*
		 * according to old code it should be avoided to requeue all
		 * 128 buffers in order to benefit from PCI avoidance.
		 * this function keeps at least one buffer (the buffer at
		 * 'index') un-requeued -> this buffer is the first buffer that
		 * will be requeued the next time
		 */
		if (card->options.performance_stats) {
			card->perf_stats.inbound_do_qdio_cnt++;
			card->perf_stats.inbound_do_qdio_start_time =
				qeth_get_micros();
		}
		rc = do_QDIO(CARD_DDEV(card),
			     QDIO_FLAG_SYNC_INPUT | QDIO_FLAG_UNDER_INTERRUPT,
			     0, queue->next_buf_to_init, count, NULL);
		if (card->options.performance_stats)
			card->perf_stats.inbound_do_qdio_time +=
				qeth_get_micros() -
				card->perf_stats.inbound_do_qdio_start_time;
		if (rc){
			PRINT_WARN("qeth_queue_input_buffer's do_QDIO "
				   "return %i (device %s).\n",
				   rc, CARD_DDEV_ID(card));
			QETH_DBF_TEXT(trace,2,"qinberr");
			QETH_DBF_TEXT_(trace,2,"%s",CARD_BUS_ID(card));
		}
		queue->next_buf_to_init = (queue->next_buf_to_init + count) %
					  QDIO_MAX_BUFFERS_PER_Q;
	}
}

static inline void
qeth_put_buffer_pool_entry(struct qeth_card *card,
			   struct qeth_buffer_pool_entry *entry)
{
	QETH_DBF_TEXT(trace, 6, "ptbfplen");
	list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list);
}

static void
qeth_qdio_input_handler(struct ccw_device * ccwdev, unsigned int status,
		        unsigned int qdio_err, unsigned int siga_err,
			unsigned int queue, int first_element, int count,
			unsigned long card_ptr)
{
	struct net_device *net_dev;
	struct qeth_card *card;
	struct qeth_qdio_buffer *buffer;
	int index;
	int i;

	QETH_DBF_TEXT(trace, 6, "qdinput");
	card = (struct qeth_card *) card_ptr;
	net_dev = card->dev;
	if (card->options.performance_stats) {
		card->perf_stats.inbound_cnt++;
		card->perf_stats.inbound_start_time = qeth_get_micros();
	}
	if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
		if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){
			QETH_DBF_TEXT(trace, 1,"qdinchk");
			QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
			QETH_DBF_TEXT_(trace,1,"%04X%04X",first_element,count);
			QETH_DBF_TEXT_(trace,1,"%04X%04X", queue, status);
			qeth_schedule_recovery(card);
			return;
		}
	}
	for (i = first_element; i < (first_element + count); ++i) {
		index = i % QDIO_MAX_BUFFERS_PER_Q;
		buffer = &card->qdio.in_q->bufs[index];
		if (!((status & QDIO_STATUS_LOOK_FOR_ERROR) &&
		      qeth_check_qdio_errors(buffer->buffer,
					     qdio_err, siga_err,"qinerr")))
			qeth_process_inbound_buffer(card, buffer, index);
		/* clear buffer and give back to hardware */
		qeth_put_buffer_pool_entry(card, buffer->pool_entry);
		qeth_queue_input_buffer(card, index);
	}
	if (card->options.performance_stats)
		card->perf_stats.inbound_time += qeth_get_micros() -
			card->perf_stats.inbound_start_time;
}

static int
qeth_handle_send_error(struct qeth_card *card,
		       struct qeth_qdio_out_buffer *buffer,
		       unsigned int qdio_err, unsigned int siga_err)
{
	int sbalf15 = buffer->buffer->element[15].flags & 0xff;
	int cc = siga_err & 3;

	QETH_DBF_TEXT(trace, 6, "hdsnderr");
	qeth_check_qdio_errors(buffer->buffer, qdio_err, siga_err, "qouterr");
	switch (cc) {
	case 0:
		if (qdio_err){
			QETH_DBF_TEXT(trace, 1,"lnkfail");
			QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
			QETH_DBF_TEXT_(trace,1,"%04x %02x",
				       (u16)qdio_err, (u8)sbalf15);
			return QETH_SEND_ERROR_LINK_FAILURE;
		}
		return QETH_SEND_ERROR_NONE;
	case 2:
		if (siga_err & QDIO_SIGA_ERROR_B_BIT_SET) {
			QETH_DBF_TEXT(trace, 1, "SIGAcc2B");
			QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
			return QETH_SEND_ERROR_KICK_IT;
		}
		if ((sbalf15 >= 15) && (sbalf15 <= 31))
			return QETH_SEND_ERROR_RETRY;
		return QETH_SEND_ERROR_LINK_FAILURE;
		/* look at qdio_error and sbalf 15 */
	case 1:
		QETH_DBF_TEXT(trace, 1, "SIGAcc1");
		QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
		return QETH_SEND_ERROR_LINK_FAILURE;
	case 3:
	default:
		QETH_DBF_TEXT(trace, 1, "SIGAcc3");
		QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
		return QETH_SEND_ERROR_KICK_IT;
	}
}

void
qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
		   int index, int count)
{
	struct qeth_qdio_out_buffer *buf;
	int rc;
	int i;
	unsigned int qdio_flags;

	QETH_DBF_TEXT(trace, 6, "flushbuf");

	for (i = index; i < index + count; ++i) {
		buf = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
		buf->buffer->element[buf->next_element_to_fill - 1].flags |=
				SBAL_FLAGS_LAST_ENTRY;

		if (queue->card->info.type == QETH_CARD_TYPE_IQD)
			continue;

		if (!queue->do_pack){
			if ((atomic_read(&queue->used_buffers) >=
		    		(QETH_HIGH_WATERMARK_PACK -
				 QETH_WATERMARK_PACK_FUZZ)) &&
		    	    !atomic_read(&queue->set_pci_flags_count)){
				/* it's likely that we'll go to packing
				 * mode soon */
				atomic_inc(&queue->set_pci_flags_count);
				buf->buffer->element[0].flags |= 0x40;
			}
		} else {
			if (!atomic_read(&queue->set_pci_flags_count)){
				/*
				 * there's no outstanding PCI any more, so we
				 * have to request a PCI to be sure that the PCI
				 * will wake at some time in the future then we
				 * can flush packed buffers that might still be
				 * hanging around, which can happen if no
				 * further send was requested by the stack
				 */
				atomic_inc(&queue->set_pci_flags_count);
				buf->buffer->element[0].flags |= 0x40;
			}
		}
	}

	queue->card->dev->trans_start = jiffies;
	if (queue->card->options.performance_stats) {
		queue->card->perf_stats.outbound_do_qdio_cnt++;
		queue->card->perf_stats.outbound_do_qdio_start_time =
			qeth_get_micros();
	}
	qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
	if (under_int)
		qdio_flags |= QDIO_FLAG_UNDER_INTERRUPT;
	if (atomic_read(&queue->set_pci_flags_count))
		qdio_flags |= QDIO_FLAG_PCI_OUT;
	rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags,
		     queue->queue_no, index, count, NULL);
	if (queue->card->options.performance_stats)
		queue->card->perf_stats.outbound_do_qdio_time +=
			qeth_get_micros() -
			queue->card->perf_stats.outbound_do_qdio_start_time;
	if (rc){
		QETH_DBF_TEXT(trace, 2, "flushbuf");
		QETH_DBF_TEXT_(trace, 2, " err%d", rc);
		QETH_DBF_TEXT_(trace, 2, "%s", CARD_DDEV_ID(queue->card));
		queue->card->stats.tx_errors += count;
		/* this must not happen under normal circumstances. if it
		 * happens something is really wrong -> recover */
		qeth_schedule_recovery(queue->card);
		return;
	}
	atomic_add(count, &queue->used_buffers);
	if (queue->card->options.performance_stats)
		queue->card->perf_stats.bufs_sent += count;
}

/*
 * Switched to packing state if the number of used buffers on a queue
 * reaches a certain limit.
 */
static void
qeth_switch_to_packing_if_needed(struct qeth_qdio_out_q *queue)
{
	if (!queue->do_pack) {
		if (atomic_read(&queue->used_buffers)
		    >= QETH_HIGH_WATERMARK_PACK){
			/* switch non-PACKING -> PACKING */
			QETH_DBF_TEXT(trace, 6, "np->pack");
			if (queue->card->options.performance_stats)
				queue->card->perf_stats.sc_dp_p++;
			queue->do_pack = 1;
		}
	}
}

/*
 * Switches from packing to non-packing mode. If there is a packing
 * buffer on the queue this buffer will be prepared to be flushed.
 * In that case 1 is returned to inform the caller. If no buffer
 * has to be flushed, zero is returned.
 */
static int
qeth_switch_to_nonpacking_if_needed(struct qeth_qdio_out_q *queue)
{
	struct qeth_qdio_out_buffer *buffer;
	int flush_count = 0;

	if (queue->do_pack) {
		if (atomic_read(&queue->used_buffers)
		    <= QETH_LOW_WATERMARK_PACK) {
			/* switch PACKING -> non-PACKING */
			QETH_DBF_TEXT(trace, 6, "pack->np");
			if (queue->card->options.performance_stats)
				queue->card->perf_stats.sc_p_dp++;
			queue->do_pack = 0;
			/* flush packing buffers */
			buffer = &queue->bufs[queue->next_buf_to_fill];
			if ((atomic_read(&buffer->state) ==
						QETH_QDIO_BUF_EMPTY) &&
			    (buffer->next_element_to_fill > 0)) {
				atomic_set(&buffer->state,QETH_QDIO_BUF_PRIMED);
				flush_count++;
				queue->next_buf_to_fill =
					(queue->next_buf_to_fill + 1) %
					QDIO_MAX_BUFFERS_PER_Q;
			}
		}
	}
	return flush_count;
}

/*
 * Called to flush a packing buffer if no more pci flags are on the queue.
 * Checks if there is a packing buffer and prepares it to be flushed.
 * In that case returns 1, otherwise zero.
 */
static int
qeth_flush_buffers_on_no_pci(struct qeth_qdio_out_q *queue)
{
	struct qeth_qdio_out_buffer *buffer;

	buffer = &queue->bufs[queue->next_buf_to_fill];
	if((atomic_read(&buffer->state) == QETH_QDIO_BUF_EMPTY) &&
	   (buffer->next_element_to_fill > 0)){
		/* it's a packing buffer */
		atomic_set(&buffer->state, QETH_QDIO_BUF_PRIMED);
		queue->next_buf_to_fill =
			(queue->next_buf_to_fill + 1) % QDIO_MAX_BUFFERS_PER_Q;
		return 1;
	}
	return 0;
}

static void
qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
{
	int index;
	int flush_cnt = 0;
	int q_was_packing = 0;

	/*
	 * check if weed have to switch to non-packing mode or if
	 * we have to get a pci flag out on the queue
	 */
	if ((atomic_read(&queue->used_buffers) <= QETH_LOW_WATERMARK_PACK) ||
	    !atomic_read(&queue->set_pci_flags_count)){
		if (atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH) ==
				QETH_OUT_Q_UNLOCKED) {
			/*
			 * If we get in here, there was no action in
			 * do_send_packet. So, we check if there is a
			 * packing buffer to be flushed here.
			 */
			netif_stop_queue(queue->card->dev);
			index = queue->next_buf_to_fill;
			q_was_packing = queue->do_pack;
			flush_cnt += qeth_switch_to_nonpacking_if_needed(queue);
			if (!flush_cnt &&
			    !atomic_read(&queue->set_pci_flags_count))
				flush_cnt +=
					qeth_flush_buffers_on_no_pci(queue);
			if (queue->card->options.performance_stats &&
			    q_was_packing)
				queue->card->perf_stats.bufs_sent_pack +=
					flush_cnt;
			if (flush_cnt)
				qeth_flush_buffers(queue, 1, index, flush_cnt);
			atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
		}
	}
}

static void
qeth_qdio_output_handler(struct ccw_device * ccwdev, unsigned int status,
		        unsigned int qdio_error, unsigned int siga_error,
			unsigned int __queue, int first_element, int count,
			unsigned long card_ptr)
{
	struct qeth_card *card        = (struct qeth_card *) card_ptr;
	struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue];
	struct qeth_qdio_out_buffer *buffer;
	int i;

	QETH_DBF_TEXT(trace, 6, "qdouhdl");
	if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
		if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){
			QETH_DBF_TEXT(trace, 2, "achkcond");
			QETH_DBF_TEXT_(trace, 2, "%s", CARD_BUS_ID(card));
			QETH_DBF_TEXT_(trace, 2, "%08x", status);
			netif_stop_queue(card->dev);
			qeth_schedule_recovery(card);
			return;
		}
	}
	if (card->options.performance_stats) {
		card->perf_stats.outbound_handler_cnt++;
		card->perf_stats.outbound_handler_start_time =
			qeth_get_micros();
	}
	for(i = first_element; i < (first_element + count); ++i){
		buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
		/*we only handle the KICK_IT error by doing a recovery */
		if (qeth_handle_send_error(card, buffer,
					   qdio_error, siga_error)
				== QETH_SEND_ERROR_KICK_IT){
			netif_stop_queue(card->dev);
			qeth_schedule_recovery(card);
			return;
		}
		qeth_clear_output_buffer(queue, buffer);
	}
	atomic_sub(count, &queue->used_buffers);
	/* check if we need to do something on this outbound queue */
	if (card->info.type != QETH_CARD_TYPE_IQD)
		qeth_check_outbound_queue(queue);

	netif_wake_queue(queue->card->dev);
	if (card->options.performance_stats)
		card->perf_stats.outbound_handler_time += qeth_get_micros() -
			card->perf_stats.outbound_handler_start_time;
}

static void
qeth_create_qib_param_field(struct qeth_card *card, char *param_field)
{

	param_field[0] = _ascebc['P'];
	param_field[1] = _ascebc['C'];
	param_field[2] = _ascebc['I'];
	param_field[3] = _ascebc['T'];
	*((unsigned int *) (&param_field[4])) = QETH_PCI_THRESHOLD_A(card);
	*((unsigned int *) (&param_field[8])) = QETH_PCI_THRESHOLD_B(card);
	*((unsigned int *) (&param_field[12])) = QETH_PCI_TIMER_VALUE(card);
}

static void
qeth_create_qib_param_field_blkt(struct qeth_card *card, char *param_field)
{
	param_field[16] = _ascebc['B'];
        param_field[17] = _ascebc['L'];
        param_field[18] = _ascebc['K'];
        param_field[19] = _ascebc['T'];
        *((unsigned int *) (&param_field[20])) = card->info.blkt.time_total;
        *((unsigned int *) (&param_field[24])) = card->info.blkt.inter_packet;
        *((unsigned int *) (&param_field[28])) = card->info.blkt.inter_packet_jumbo;
}

static void
qeth_initialize_working_pool_list(struct qeth_card *card)
{
	struct qeth_buffer_pool_entry *entry;

	QETH_DBF_TEXT(trace,5,"inwrklst");

	list_for_each_entry(entry,
			    &card->qdio.init_pool.entry_list, init_list) {
		qeth_put_buffer_pool_entry(card,entry);
	}
}

static void
qeth_clear_working_pool_list(struct qeth_card *card)
{
	struct qeth_buffer_pool_entry *pool_entry, *tmp;

	QETH_DBF_TEXT(trace,5,"clwrklst");
	list_for_each_entry_safe(pool_entry, tmp,
			    &card->qdio.in_buf_pool.entry_list, list){
			list_del(&pool_entry->list);
	}
}

static void
qeth_free_buffer_pool(struct qeth_card *card)
{
	struct qeth_buffer_pool_entry *pool_entry, *tmp;
	int i=0;
	QETH_DBF_TEXT(trace,5,"freepool");
	list_for_each_entry_safe(pool_entry, tmp,
				 &card->qdio.init_pool.entry_list, init_list){
		for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i)
			free_page((unsigned long)pool_entry->elements[i]);
		list_del(&pool_entry->init_list);
		kfree(pool_entry);
	}
}

static int
qeth_alloc_buffer_pool(struct qeth_card *card)
{
	struct qeth_buffer_pool_entry *pool_entry;
	void *ptr;
	int i, j;

	QETH_DBF_TEXT(trace,5,"alocpool");
	for (i = 0; i < card->qdio.init_pool.buf_count; ++i){
	 	pool_entry = kmalloc(sizeof(*pool_entry), GFP_KERNEL);
		if (!pool_entry){
			qeth_free_buffer_pool(card);
			return -ENOMEM;
		}
		for(j = 0; j < QETH_MAX_BUFFER_ELEMENTS(card); ++j){
			ptr = (void *) __get_free_page(GFP_KERNEL|GFP_DMA);
			if (!ptr) {
				while (j > 0)
					free_page((unsigned long)
						  pool_entry->elements[--j]);
				kfree(pool_entry);
				qeth_free_buffer_pool(card);
				return -ENOMEM;
			}
			pool_entry->elements[j] = ptr;
		}
		list_add(&pool_entry->init_list,
			 &card->qdio.init_pool.entry_list);
	}
	return 0;
}

int
qeth_realloc_buffer_pool(struct qeth_card *card, int bufcnt)
{
	QETH_DBF_TEXT(trace, 2, "realcbp");

	if ((card->state != CARD_STATE_DOWN) &&
	    (card->state != CARD_STATE_RECOVER))
		return -EPERM;

	/* TODO: steel/add buffers from/to a running card's buffer pool (?) */
	qeth_clear_working_pool_list(card);
	qeth_free_buffer_pool(card);
	card->qdio.in_buf_pool.buf_count = bufcnt;
	card->qdio.init_pool.buf_count = bufcnt;
	return qeth_alloc_buffer_pool(card);
}

static int
qeth_alloc_qdio_buffers(struct qeth_card *card)
{
	int i, j;

	QETH_DBF_TEXT(setup, 2, "allcqdbf");

	if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED,
		QETH_QDIO_ALLOCATED) != QETH_QDIO_UNINITIALIZED)
		return 0;

	card->qdio.in_q = kmalloc(sizeof(struct qeth_qdio_q),
				  GFP_KERNEL|GFP_DMA);
	if (!card->qdio.in_q)
		goto out_nomem;
	QETH_DBF_TEXT(setup, 2, "inq");
	QETH_DBF_HEX(setup, 2, &card->qdio.in_q, sizeof(void *));
	memset(card->qdio.in_q, 0, sizeof(struct qeth_qdio_q));
	/* give inbound qeth_qdio_buffers their qdio_buffers */
	for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i)
		card->qdio.in_q->bufs[i].buffer =
			&card->qdio.in_q->qdio_bufs[i];
	/* inbound buffer pool */
	if (qeth_alloc_buffer_pool(card))
		goto out_freeinq;
	/* outbound */
	card->qdio.out_qs =
		kmalloc(card->qdio.no_out_queues *
			sizeof(struct qeth_qdio_out_q *), GFP_KERNEL);
	if (!card->qdio.out_qs)
		goto out_freepool;
	for (i = 0; i < card->qdio.no_out_queues; ++i) {
		card->qdio.out_qs[i] = kmalloc(sizeof(struct qeth_qdio_out_q),
					       GFP_KERNEL|GFP_DMA);
		if (!card->qdio.out_qs[i])
			goto out_freeoutq;
		QETH_DBF_TEXT_(setup, 2, "outq %i", i);
		QETH_DBF_HEX(setup, 2, &card->qdio.out_qs[i], sizeof(void *));
		memset(card->qdio.out_qs[i], 0, sizeof(struct qeth_qdio_out_q));
		card->qdio.out_qs[i]->queue_no = i;
		/* give outbound qeth_qdio_buffers their qdio_buffers */
		for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j){
			card->qdio.out_qs[i]->bufs[j].buffer =
				&card->qdio.out_qs[i]->qdio_bufs[j];
			skb_queue_head_init(&card->qdio.out_qs[i]->bufs[j].
					    skb_list);
			lockdep_set_class(
				&card->qdio.out_qs[i]->bufs[j].skb_list.lock,
				&qdio_out_skb_queue_key);
			INIT_LIST_HEAD(&card->qdio.out_qs[i]->bufs[j].ctx_list);
		}
	}
	return 0;

out_freeoutq:
	while (i > 0)
		kfree(card->qdio.out_qs[--i]);
	kfree(card->qdio.out_qs);
out_freepool:
	qeth_free_buffer_pool(card);
out_freeinq:
	kfree(card->qdio.in_q);
out_nomem:
	atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
	return -ENOMEM;
}

static void
qeth_free_qdio_buffers(struct qeth_card *card)
{
	int i, j;

	QETH_DBF_TEXT(trace, 2, "freeqdbf");
	if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
		QETH_QDIO_UNINITIALIZED)
		return;
	kfree(card->qdio.in_q);
	/* inbound buffer pool */
	qeth_free_buffer_pool(card);
	/* free outbound qdio_qs */
	for (i = 0; i < card->qdio.no_out_queues; ++i){
		for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
			qeth_clear_output_buffer(card->qdio.out_qs[i],
					&card->qdio.out_qs[i]->bufs[j]);
		kfree(card->qdio.out_qs[i]);
	}
	kfree(card->qdio.out_qs);
}

static void
qeth_clear_qdio_buffers(struct qeth_card *card)
{
	int i, j;

	QETH_DBF_TEXT(trace, 2, "clearqdbf");
	/* clear outbound buffers to free skbs */
	for (i = 0; i < card->qdio.no_out_queues; ++i)
		if (card->qdio.out_qs[i]){
			for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
				qeth_clear_output_buffer(card->qdio.out_qs[i],
						&card->qdio.out_qs[i]->bufs[j]);
		}
}

static void
qeth_init_qdio_info(struct qeth_card *card)
{
	QETH_DBF_TEXT(setup, 4, "intqdinf");
	atomic_set(&card->qdio.state, QETH_QDIO_UNINITIALIZED);
	/* inbound */
	card->qdio.in_buf_size = QETH_IN_BUF_SIZE_DEFAULT;
	card->qdio.init_pool.buf_count = QETH_IN_BUF_COUNT_DEFAULT;
	card->qdio.in_buf_pool.buf_count = card->qdio.init_pool.buf_count;
	INIT_LIST_HEAD(&card->qdio.in_buf_pool.entry_list);
	INIT_LIST_HEAD(&card->qdio.init_pool.entry_list);
}

static int
qeth_init_qdio_queues(struct qeth_card *card)
{
	int i, j;
	int rc;

	QETH_DBF_TEXT(setup, 2, "initqdqs");

	/* inbound queue */
	memset(card->qdio.in_q->qdio_bufs, 0,
	       QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
	qeth_initialize_working_pool_list(card);
	/*give only as many buffers to hardware as we have buffer pool entries*/
	for (i = 0; i < card->qdio.in_buf_pool.buf_count - 1; ++i)
		qeth_init_input_buffer(card, &card->qdio.in_q->bufs[i]);
	card->qdio.in_q->next_buf_to_init = card->qdio.in_buf_pool.buf_count - 1;
	rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0,
		     card->qdio.in_buf_pool.buf_count - 1, NULL);
	if (rc) {
		QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
		return rc;
	}
	rc = qdio_synchronize(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0);
	if (rc) {
		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
		return rc;
	}
	/* outbound queue */
	for (i = 0; i < card->qdio.no_out_queues; ++i){
		memset(card->qdio.out_qs[i]->qdio_bufs, 0,
		       QDIO_MAX_BUFFERS_PER_Q * sizeof(struct qdio_buffer));
		for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j){
			qeth_clear_output_buffer(card->qdio.out_qs[i],
					&card->qdio.out_qs[i]->bufs[j]);
		}
		card->qdio.out_qs[i]->card = card;
		card->qdio.out_qs[i]->next_buf_to_fill = 0;
		card->qdio.out_qs[i]->do_pack = 0;
		atomic_set(&card->qdio.out_qs[i]->used_buffers,0);
		atomic_set(&card->qdio.out_qs[i]->set_pci_flags_count, 0);
		atomic_set(&card->qdio.out_qs[i]->state,
			   QETH_OUT_Q_UNLOCKED);
	}
	return 0;
}

static int
qeth_qdio_establish(struct qeth_card *card)
{
	struct qdio_initialize init_data;
	char *qib_param_field;
	struct qdio_buffer **in_sbal_ptrs;
	struct qdio_buffer **out_sbal_ptrs;
	int i, j, k;
	int rc = 0;

	QETH_DBF_TEXT(setup, 2, "qdioest");

	qib_param_field = kzalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(char),
			      GFP_KERNEL);
 	if (!qib_param_field)
		return -ENOMEM;

	qeth_create_qib_param_field(card, qib_param_field);
	qeth_create_qib_param_field_blkt(card, qib_param_field);

	in_sbal_ptrs = kmalloc(QDIO_MAX_BUFFERS_PER_Q * sizeof(void *),
			       GFP_KERNEL);
	if (!in_sbal_ptrs) {
		kfree(qib_param_field);
		return -ENOMEM;
	}
	for(i = 0; i < QDIO_MAX_BUFFERS_PER_Q; ++i)
		in_sbal_ptrs[i] = (struct qdio_buffer *)
			virt_to_phys(card->qdio.in_q->bufs[i].buffer);

	out_sbal_ptrs =
		kmalloc(card->qdio.no_out_queues * QDIO_MAX_BUFFERS_PER_Q *
			sizeof(void *), GFP_KERNEL);
	if (!out_sbal_ptrs) {
		kfree(in_sbal_ptrs);
		kfree(qib_param_field);
		return -ENOMEM;
	}
	for(i = 0, k = 0; i < card->qdio.no_out_queues; ++i)
		for(j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j, ++k){
			out_sbal_ptrs[k] = (struct qdio_buffer *)
				virt_to_phys(card->qdio.out_qs[i]->
					     bufs[j].buffer);
		}

	memset(&init_data, 0, sizeof(struct qdio_initialize));
	init_data.cdev                   = CARD_DDEV(card);
	init_data.q_format               = qeth_get_qdio_q_format(card);
	init_data.qib_param_field_format = 0;
	init_data.qib_param_field        = qib_param_field;
	init_data.min_input_threshold    = QETH_MIN_INPUT_THRESHOLD;
	init_data.max_input_threshold    = QETH_MAX_INPUT_THRESHOLD;
	init_data.min_output_threshold   = QETH_MIN_OUTPUT_THRESHOLD;
	init_data.max_output_threshold   = QETH_MAX_OUTPUT_THRESHOLD;
	init_data.no_input_qs            = 1;
	init_data.no_output_qs           = card->qdio.no_out_queues;
	init_data.input_handler          = (qdio_handler_t *)
					   qeth_qdio_input_handler;
	init_data.output_handler         = (qdio_handler_t *)
					   qeth_qdio_output_handler;
	init_data.int_parm               = (unsigned long) card;
	init_data.flags                  = QDIO_INBOUND_0COPY_SBALS |
					   QDIO_OUTBOUND_0COPY_SBALS |
					   QDIO_USE_OUTBOUND_PCIS;
	init_data.input_sbal_addr_array  = (void **) in_sbal_ptrs;
	init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;

	if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
		QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED)
		if ((rc = qdio_initialize(&init_data)))
			atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);

	kfree(out_sbal_ptrs);
	kfree(in_sbal_ptrs);
	kfree(qib_param_field);
	return rc;
}

static int
qeth_qdio_activate(struct qeth_card *card)
{
	QETH_DBF_TEXT(setup,3,"qdioact");
	return qdio_activate(CARD_DDEV(card), 0);
}

static int
qeth_clear_channel(struct qeth_channel *channel)
{
	unsigned long flags;
	struct qeth_card *card;
	int rc;

	QETH_DBF_TEXT(trace,3,"clearch");
	card = CARD_FROM_CDEV(channel->ccwdev);
	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
	rc = ccw_device_clear(channel->ccwdev, QETH_CLEAR_CHANNEL_PARM);
	spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);

	if (rc)
		return rc;
	rc = wait_event_interruptible_timeout(card->wait_q,
			channel->state==CH_STATE_STOPPED, QETH_TIMEOUT);
	if (rc == -ERESTARTSYS)
		return rc;
	if (channel->state != CH_STATE_STOPPED)
		return -ETIME;
	channel->state = CH_STATE_DOWN;
	return 0;
}

static int
qeth_halt_channel(struct qeth_channel *channel)
{
	unsigned long flags;
	struct qeth_card *card;
	int rc;

	QETH_DBF_TEXT(trace,3,"haltch");
	card = CARD_FROM_CDEV(channel->ccwdev);
	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
	rc = ccw_device_halt(channel->ccwdev, QETH_HALT_CHANNEL_PARM);
	spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);

	if (rc)
		return rc;
	rc = wait_event_interruptible_timeout(card->wait_q,
			channel->state==CH_STATE_HALTED, QETH_TIMEOUT);
	if (rc == -ERESTARTSYS)
		return rc;
	if (channel->state != CH_STATE_HALTED)
		return -ETIME;
	return 0;
}

static int
qeth_halt_channels(struct qeth_card *card)
{
	int rc1 = 0, rc2=0, rc3 = 0;

	QETH_DBF_TEXT(trace,3,"haltchs");
	rc1 = qeth_halt_channel(&card->read);
	rc2 = qeth_halt_channel(&card->write);
	rc3 = qeth_halt_channel(&card->data);
	if (rc1)
		return rc1;
	if (rc2)
		return rc2;
	return rc3;
}
static int
qeth_clear_channels(struct qeth_card *card)
{
	int rc1 = 0, rc2=0, rc3 = 0;

	QETH_DBF_TEXT(trace,3,"clearchs");
	rc1 = qeth_clear_channel(&card->read);
	rc2 = qeth_clear_channel(&card->write);
	rc3 = qeth_clear_channel(&card->data);
	if (rc1)
		return rc1;
	if (rc2)
		return rc2;
	return rc3;
}

static int
qeth_clear_halt_card(struct qeth_card *card, int halt)
{
	int rc = 0;

	QETH_DBF_TEXT(trace,3,"clhacrd");
	QETH_DBF_HEX(trace, 3, &card, sizeof(void *));

	if (halt)
		rc = qeth_halt_channels(card);
	if (rc)
		return rc;
	return qeth_clear_channels(card);
}

static int
qeth_qdio_clear_card(struct qeth_card *card, int use_halt)
{
	int rc = 0;

	QETH_DBF_TEXT(trace,3,"qdioclr");
	switch (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ESTABLISHED,
		QETH_QDIO_CLEANING)) {
	case QETH_QDIO_ESTABLISHED:
		if ((rc = qdio_cleanup(CARD_DDEV(card),
				(card->info.type == QETH_CARD_TYPE_IQD) ?
				QDIO_FLAG_CLEANUP_USING_HALT :
				QDIO_FLAG_CLEANUP_USING_CLEAR)))
			QETH_DBF_TEXT_(trace, 3, "1err%d", rc);
		atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
		break;
	case QETH_QDIO_CLEANING:
		return rc;
	default:
		break;
	}
	if ((rc = qeth_clear_halt_card(card, use_halt)))
		QETH_DBF_TEXT_(trace, 3, "2err%d", rc);
	card->state = CARD_STATE_DOWN;
	return rc;
}

static int
qeth_dm_act(struct qeth_card *card)
{
	int rc;
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(setup,2,"dmact");

	iob = qeth_wait_for_buffer(&card->write);
	memcpy(iob->data, DM_ACT, DM_ACT_SIZE);

	memcpy(QETH_DM_ACT_DEST_ADDR(iob->data),
	       &card->token.cm_connection_r, QETH_MPC_TOKEN_LENGTH);
	memcpy(QETH_DM_ACT_CONNECTION_TOKEN(iob->data),
	       &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
	rc = qeth_send_control_data(card, DM_ACT_SIZE, iob, NULL, NULL);
	return rc;
}

static int
qeth_mpc_initialize(struct qeth_card *card)
{
	int rc;

	QETH_DBF_TEXT(setup,2,"mpcinit");

	if ((rc = qeth_issue_next_read(card))){
		QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
		return rc;
	}
	if ((rc = qeth_cm_enable(card))){
		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
		goto out_qdio;
	}
	if ((rc = qeth_cm_setup(card))){
		QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
		goto out_qdio;
	}
	if ((rc = qeth_ulp_enable(card))){
		QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
		goto out_qdio;
	}
	if ((rc = qeth_ulp_setup(card))){
		QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
		goto out_qdio;
	}
	if ((rc = qeth_alloc_qdio_buffers(card))){
		QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
		goto out_qdio;
	}
	if ((rc = qeth_qdio_establish(card))){
		QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
		qeth_free_qdio_buffers(card);
		goto out_qdio;
	}
 	if ((rc = qeth_qdio_activate(card))){
		QETH_DBF_TEXT_(setup, 2, "7err%d", rc);
		goto out_qdio;
	}
	if ((rc = qeth_dm_act(card))){
		QETH_DBF_TEXT_(setup, 2, "8err%d", rc);
		goto out_qdio;
	}

	return 0;
out_qdio:
	qeth_qdio_clear_card(card, card->info.type!=QETH_CARD_TYPE_IQD);
	return rc;
}

static struct net_device *
qeth_get_netdevice(enum qeth_card_types type, enum qeth_link_types linktype)
{
	struct net_device *dev = NULL;

	switch (type) {
	case QETH_CARD_TYPE_OSAE:
		switch (linktype) {
		case QETH_LINK_TYPE_LANE_TR:
		case QETH_LINK_TYPE_HSTR:
#ifdef CONFIG_TR
			dev = alloc_trdev(0);
#endif /* CONFIG_TR */
			break;
		default:
			dev = alloc_etherdev(0);
		}
		break;
	case QETH_CARD_TYPE_IQD:
		dev = alloc_netdev(0, "hsi%d", ether_setup);
		break;
	case QETH_CARD_TYPE_OSN:
		dev = alloc_netdev(0, "osn%d", ether_setup);
		break;
	default:
		dev = alloc_etherdev(0);
	}
	return dev;
}

/*hard_header fake function; used in case fake_ll is set */
static int
qeth_fake_header(struct sk_buff *skb, struct net_device *dev,
		     unsigned short type, void *daddr, void *saddr,
		     unsigned len)
{
	if(dev->type == ARPHRD_IEEE802_TR){
		struct trh_hdr *hdr;
        	hdr = (struct trh_hdr *)skb_push(skb, QETH_FAKE_LL_LEN_TR);
		memcpy(hdr->saddr, dev->dev_addr, TR_ALEN);
        	memcpy(hdr->daddr, "FAKELL", TR_ALEN);
		return QETH_FAKE_LL_LEN_TR;

	} else {
		struct ethhdr *hdr;
        	hdr = (struct ethhdr *)skb_push(skb, QETH_FAKE_LL_LEN_ETH);
		memcpy(hdr->h_source, dev->dev_addr, ETH_ALEN);
        	memcpy(hdr->h_dest, "FAKELL", ETH_ALEN);
        	if (type != ETH_P_802_3)
                	hdr->h_proto = htons(type);
        	else
                	hdr->h_proto = htons(len);
		return QETH_FAKE_LL_LEN_ETH;

	}
}

static int
qeth_send_packet(struct qeth_card *, struct sk_buff *);

static int
qeth_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	int rc;
	struct qeth_card *card;

	QETH_DBF_TEXT(trace, 6, "hrdstxmi");
	card = (struct qeth_card *)dev->priv;
	if (skb==NULL) {
		card->stats.tx_dropped++;
		card->stats.tx_errors++;
		/* return OK; otherwise ksoftirqd goes to 100% */
		return NETDEV_TX_OK;
	}
	if ((card->state != CARD_STATE_UP) || !card->lan_online) {
		card->stats.tx_dropped++;
		card->stats.tx_errors++;
		card->stats.tx_carrier_errors++;
		dev_kfree_skb_any(skb);
		/* return OK; otherwise ksoftirqd goes to 100% */
		return NETDEV_TX_OK;
	}
	if (card->options.performance_stats) {
		card->perf_stats.outbound_cnt++;
		card->perf_stats.outbound_start_time = qeth_get_micros();
	}
	netif_stop_queue(dev);
	if ((rc = qeth_send_packet(card, skb))) {
		if (rc == -EBUSY) {
			return NETDEV_TX_BUSY;
		} else {
			card->stats.tx_errors++;
			card->stats.tx_dropped++;
			dev_kfree_skb_any(skb);
			/*set to OK; otherwise ksoftirqd goes to 100% */
			rc = NETDEV_TX_OK;
		}
	}
	netif_wake_queue(dev);
	if (card->options.performance_stats)
		card->perf_stats.outbound_time += qeth_get_micros() -
			card->perf_stats.outbound_start_time;
	return rc;
}

static int
qeth_verify_vlan_dev(struct net_device *dev, struct qeth_card *card)
{
	int rc = 0;
#ifdef CONFIG_QETH_VLAN
	struct vlan_group *vg;
	int i;

	if (!(vg = card->vlangrp))
		return rc;

	for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++){
		if (vlan_group_get_device(vg, i) == dev){
			rc = QETH_VLAN_CARD;
			break;
		}
	}
	if (rc && !(VLAN_DEV_INFO(dev)->real_dev->priv == (void *)card))
		return 0;

#endif
	return rc;
}

static int
qeth_verify_dev(struct net_device *dev)
{
	struct qeth_card *card;
	unsigned long flags;
	int rc = 0;

	read_lock_irqsave(&qeth_card_list.rwlock, flags);
	list_for_each_entry(card, &qeth_card_list.list, list){
		if (card->dev == dev){
			rc = QETH_REAL_CARD;
			break;
		}
		rc = qeth_verify_vlan_dev(dev, card);
		if (rc)
			break;
	}
	read_unlock_irqrestore(&qeth_card_list.rwlock, flags);

	return rc;
}

static struct qeth_card *
qeth_get_card_from_dev(struct net_device *dev)
{
	struct qeth_card *card = NULL;
	int rc;

	rc = qeth_verify_dev(dev);
	if (rc == QETH_REAL_CARD)
		card = (struct qeth_card *)dev->priv;
	else if (rc == QETH_VLAN_CARD)
		card = (struct qeth_card *)
			VLAN_DEV_INFO(dev)->real_dev->priv;

	QETH_DBF_TEXT_(trace, 4, "%d", rc);
	return card ;
}

static void
qeth_tx_timeout(struct net_device *dev)
{
	struct qeth_card *card;

	card = (struct qeth_card *) dev->priv;
	card->stats.tx_errors++;
	qeth_schedule_recovery(card);
}

static int
qeth_open(struct net_device *dev)
{
	struct qeth_card *card;

	QETH_DBF_TEXT(trace, 4, "qethopen");

	card = (struct qeth_card *) dev->priv;

	if (card->state != CARD_STATE_SOFTSETUP)
		return -ENODEV;

	if ( (card->info.type != QETH_CARD_TYPE_OSN) &&
	     (card->options.layer2) &&
	     (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))) {
		QETH_DBF_TEXT(trace,4,"nomacadr");
		return -EPERM;
	}
	card->data.state = CH_STATE_UP;
	card->state = CARD_STATE_UP;
	card->dev->flags |= IFF_UP;
	netif_start_queue(dev);

	if (!card->lan_online && netif_carrier_ok(dev))
		netif_carrier_off(dev);
	return 0;
}

static int
qeth_stop(struct net_device *dev)
{
	struct qeth_card *card;

	QETH_DBF_TEXT(trace, 4, "qethstop");

	card = (struct qeth_card *) dev->priv;

	netif_tx_disable(dev);
	card->dev->flags &= ~IFF_UP;
	if (card->state == CARD_STATE_UP)
		card->state = CARD_STATE_SOFTSETUP;
	return 0;
}

static int
qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
{
	int cast_type = RTN_UNSPEC;

	if (card->info.type == QETH_CARD_TYPE_OSN)
		return cast_type;

	if (skb->dst && skb->dst->neighbour){
		cast_type = skb->dst->neighbour->type;
		if ((cast_type == RTN_BROADCAST) ||
		    (cast_type == RTN_MULTICAST) ||
		    (cast_type == RTN_ANYCAST))
			return cast_type;
		else
			return RTN_UNSPEC;
	}
	/* try something else */
	if (skb->protocol == ETH_P_IPV6)
		return (skb_network_header(skb)[24] == 0xff) ?
				RTN_MULTICAST : 0;
	else if (skb->protocol == ETH_P_IP)
		return ((skb_network_header(skb)[16] & 0xf0) == 0xe0) ?
				RTN_MULTICAST : 0;
	/* ... */
	if (!memcmp(skb->data, skb->dev->broadcast, 6))
		return RTN_BROADCAST;
	else {
		u16 hdr_mac;

	        hdr_mac = *((u16 *)skb->data);
	        /* tr multicast? */
	        switch (card->info.link_type) {
	        case QETH_LINK_TYPE_HSTR:
	        case QETH_LINK_TYPE_LANE_TR:
	        	if ((hdr_mac == QETH_TR_MAC_NC) ||
			    (hdr_mac == QETH_TR_MAC_C))
				return RTN_MULTICAST;
			break;
	        /* eth or so multicast? */
                default:
                      	if ((hdr_mac == QETH_ETH_MAC_V4) ||
			    (hdr_mac == QETH_ETH_MAC_V6))
			        return RTN_MULTICAST;
	        }
        }
	return cast_type;
}

static int
qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb,
		        int ipv, int cast_type)
{
	if (!ipv && (card->info.type == QETH_CARD_TYPE_OSAE))
		return card->qdio.default_out_queue;
	switch (card->qdio.no_out_queues) {
	case 4:
		if (cast_type && card->info.is_multicast_different)
			return card->info.is_multicast_different &
				(card->qdio.no_out_queues - 1);
		if (card->qdio.do_prio_queueing && (ipv == 4)) {
			const u8 tos = ip_hdr(skb)->tos;

			if (card->qdio.do_prio_queueing==QETH_PRIO_Q_ING_TOS){
				if (tos & IP_TOS_NOTIMPORTANT)
					return 3;
				if (tos & IP_TOS_HIGHRELIABILITY)
					return 2;
				if (tos & IP_TOS_HIGHTHROUGHPUT)
					return 1;
				if (tos & IP_TOS_LOWDELAY)
					return 0;
			}
			if (card->qdio.do_prio_queueing==QETH_PRIO_Q_ING_PREC)
				return 3 - (tos >> 6);
		} else if (card->qdio.do_prio_queueing && (ipv == 6)) {
			/* TODO: IPv6!!! */
		}
		return card->qdio.default_out_queue;
	case 1: /* fallthrough for single-out-queue 1920-device */
	default:
		return card->qdio.default_out_queue;
	}
}

static inline int
qeth_get_ip_version(struct sk_buff *skb)
{
	switch (skb->protocol) {
	case ETH_P_IPV6:
		return 6;
	case ETH_P_IP:
		return 4;
	default:
		return 0;
	}
}

static struct qeth_hdr *
__qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb, int ipv)
{
#ifdef CONFIG_QETH_VLAN
	u16 *tag;
	if (card->vlangrp && vlan_tx_tag_present(skb) &&
	    ((ipv == 6) || card->options.layer2) ) {
		/*
		 * Move the mac addresses (6 bytes src, 6 bytes dest)
		 * to the beginning of the new header.  We are using three
		 * memcpys instead of one memmove to save cycles.
		 */
		skb_push(skb, VLAN_HLEN);
		skb_copy_to_linear_data(skb, skb->data + 4, 4);
		skb_copy_to_linear_data_offset(skb, 4, skb->data + 8, 4);
		skb_copy_to_linear_data_offset(skb, 8, skb->data + 12, 4);
		tag = (u16 *)(skb->data + 12);
		/*
		 * first two bytes  = ETH_P_8021Q (0x8100)
		 * second two bytes = VLANID
		 */
		*tag = __constant_htons(ETH_P_8021Q);
		*(tag + 1) = htons(vlan_tx_tag_get(skb));
	}
#endif
	return ((struct qeth_hdr *)
		qeth_push_skb(card, skb, sizeof(struct qeth_hdr)));
}

static void
__qeth_free_new_skb(struct sk_buff *orig_skb, struct sk_buff *new_skb)
{
	if (orig_skb != new_skb)
		dev_kfree_skb_any(new_skb);
}

static struct sk_buff *
qeth_prepare_skb(struct qeth_card *card, struct sk_buff *skb,
		 struct qeth_hdr **hdr, int ipv)
{
	struct sk_buff *new_skb, *new_skb2;
	
	QETH_DBF_TEXT(trace, 6, "prepskb");
	new_skb = skb;
	new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC);
	if (!new_skb)
		return NULL;
	new_skb2 = qeth_realloc_headroom(card, new_skb,
					 sizeof(struct qeth_hdr));
	if (!new_skb2) {
		__qeth_free_new_skb(skb, new_skb);
		return NULL;
	}
	if (new_skb != skb)
		__qeth_free_new_skb(new_skb2, new_skb);
	new_skb = new_skb2;
	*hdr = __qeth_prepare_skb(card, new_skb, ipv);
	if (*hdr == NULL) {
		__qeth_free_new_skb(skb, new_skb);
		return NULL;
	}
	return new_skb;
}

static inline u8
qeth_get_qeth_hdr_flags4(int cast_type)
{
	if (cast_type == RTN_MULTICAST)
		return QETH_CAST_MULTICAST;
	if (cast_type == RTN_BROADCAST)
		return QETH_CAST_BROADCAST;
	return QETH_CAST_UNICAST;
}

static inline u8
qeth_get_qeth_hdr_flags6(int cast_type)
{
	u8 ct = QETH_HDR_PASSTHRU | QETH_HDR_IPV6;
	if (cast_type == RTN_MULTICAST)
		return ct | QETH_CAST_MULTICAST;
	if (cast_type == RTN_ANYCAST)
		return ct | QETH_CAST_ANYCAST;
	if (cast_type == RTN_BROADCAST)
		return ct | QETH_CAST_BROADCAST;
	return ct | QETH_CAST_UNICAST;
}

static void
qeth_layer2_get_packet_type(struct qeth_card *card, struct qeth_hdr *hdr,
			    struct sk_buff *skb)
{
	__u16 hdr_mac;

	if (!memcmp(skb->data+QETH_HEADER_SIZE,
		    skb->dev->broadcast,6)) { /* broadcast? */
		*(__u32 *)hdr->hdr.l2.flags |=
			 QETH_LAYER2_FLAG_BROADCAST << 8;
		return;
	}
	hdr_mac=*((__u16*)skb->data);
	/* tr multicast? */
	switch (card->info.link_type) {
	case QETH_LINK_TYPE_HSTR:
	case QETH_LINK_TYPE_LANE_TR:
		if ((hdr_mac == QETH_TR_MAC_NC) ||
		    (hdr_mac == QETH_TR_MAC_C) )
			*(__u32 *)hdr->hdr.l2.flags |=
				QETH_LAYER2_FLAG_MULTICAST << 8;
		else
			*(__u32 *)hdr->hdr.l2.flags |=
				QETH_LAYER2_FLAG_UNICAST << 8;
		break;
		/* eth or so multicast? */
	default:
		if ( (hdr_mac==QETH_ETH_MAC_V4) ||
		     (hdr_mac==QETH_ETH_MAC_V6) )
			*(__u32 *)hdr->hdr.l2.flags |=
				QETH_LAYER2_FLAG_MULTICAST << 8;
		else
			*(__u32 *)hdr->hdr.l2.flags |=
				QETH_LAYER2_FLAG_UNICAST << 8;
	}
}

static void
qeth_layer2_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
			struct sk_buff *skb, int cast_type)
{
	memset(hdr, 0, sizeof(struct qeth_hdr));
	hdr->hdr.l2.id = QETH_HEADER_TYPE_LAYER2;

	/* set byte 0 to "0x02" and byte 3 to casting flags */
	if (cast_type==RTN_MULTICAST)
		*(__u32 *)hdr->hdr.l2.flags |= QETH_LAYER2_FLAG_MULTICAST << 8;
	else if (cast_type==RTN_BROADCAST)
		*(__u32 *)hdr->hdr.l2.flags |= QETH_LAYER2_FLAG_BROADCAST << 8;
	 else
		qeth_layer2_get_packet_type(card, hdr, skb);

	hdr->hdr.l2.pkt_length = skb->len-QETH_HEADER_SIZE;
#ifdef CONFIG_QETH_VLAN
	/* VSWITCH relies on the VLAN
	 * information to be present in
	 * the QDIO header */
	if ((card->vlangrp != NULL) &&
	    vlan_tx_tag_present(skb)) {
		*(__u32 *)hdr->hdr.l2.flags |= QETH_LAYER2_FLAG_VLAN << 8;
		hdr->hdr.l2.vlan_id = vlan_tx_tag_get(skb);
	}
#endif
}

void
qeth_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
		struct sk_buff *skb, int ipv, int cast_type)
{
	QETH_DBF_TEXT(trace, 6, "fillhdr");

	memset(hdr, 0, sizeof(struct qeth_hdr));
	if (card->options.layer2) {
		qeth_layer2_fill_header(card, hdr, skb, cast_type);
		return;
	}
	hdr->hdr.l3.id = QETH_HEADER_TYPE_LAYER3;
	hdr->hdr.l3.ext_flags = 0;
#ifdef CONFIG_QETH_VLAN
	/*
	 * before we're going to overwrite this location with next hop ip.
	 * v6 uses passthrough, v4 sets the tag in the QDIO header.
	 */
	if (card->vlangrp && vlan_tx_tag_present(skb)) {
		hdr->hdr.l3.ext_flags = (ipv == 4) ?
			QETH_HDR_EXT_VLAN_FRAME :
			QETH_HDR_EXT_INCLUDE_VLAN_TAG;
		hdr->hdr.l3.vlan_id = vlan_tx_tag_get(skb);
	}
#endif /* CONFIG_QETH_VLAN */
	hdr->hdr.l3.length = skb->len - sizeof(struct qeth_hdr);
	if (ipv == 4) {	 /* IPv4 */
		hdr->hdr.l3.flags = qeth_get_qeth_hdr_flags4(cast_type);
		memset(hdr->hdr.l3.dest_addr, 0, 12);
		if ((skb->dst) && (skb->dst->neighbour)) {
			*((u32 *) (&hdr->hdr.l3.dest_addr[12])) =
			    *((u32 *) skb->dst->neighbour->primary_key);
		} else {
			/* fill in destination address used in ip header */
			*((u32 *)(&hdr->hdr.l3.dest_addr[12])) =
							   ip_hdr(skb)->daddr;
		}
	} else if (ipv == 6) { /* IPv6 or passthru */
		hdr->hdr.l3.flags = qeth_get_qeth_hdr_flags6(cast_type);
		if ((skb->dst) && (skb->dst->neighbour)) {
			memcpy(hdr->hdr.l3.dest_addr,
			       skb->dst->neighbour->primary_key, 16);
		} else {
			/* fill in destination address used in ip header */
			memcpy(hdr->hdr.l3.dest_addr,
			       &ipv6_hdr(skb)->daddr, 16);
		}
	} else { /* passthrough */
                if((skb->dev->type == ARPHRD_IEEE802_TR) &&
		    !memcmp(skb->data + sizeof(struct qeth_hdr) +
		    sizeof(__u16), skb->dev->broadcast, 6)) {
			hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
						QETH_HDR_PASSTHRU;
		} else if (!memcmp(skb->data + sizeof(struct qeth_hdr),
			    skb->dev->broadcast, 6)) {   /* broadcast? */
			hdr->hdr.l3.flags = QETH_CAST_BROADCAST |
						QETH_HDR_PASSTHRU;
		} else {
 			hdr->hdr.l3.flags = (cast_type == RTN_MULTICAST) ?
 				QETH_CAST_MULTICAST | QETH_HDR_PASSTHRU :
 				QETH_CAST_UNICAST | QETH_HDR_PASSTHRU;
		}
	}
}

static void
__qeth_fill_buffer(struct sk_buff *skb, struct qdio_buffer *buffer,
		   int is_tso, int *next_element_to_fill)
{
	int length = skb->len;
	int length_here;
	int element;
	char *data;
	int first_lap ;

	element = *next_element_to_fill;
	data = skb->data;
	first_lap = (is_tso == 0 ? 1 : 0);

	while (length > 0) {
		/* length_here is the remaining amount of data in this page */
		length_here = PAGE_SIZE - ((unsigned long) data % PAGE_SIZE);
		if (length < length_here)
			length_here = length;

		buffer->element[element].addr = data;
		buffer->element[element].length = length_here;
		length -= length_here;
		if (!length) {
			if (first_lap)
				buffer->element[element].flags = 0;
			else
				buffer->element[element].flags =
				    SBAL_FLAGS_LAST_FRAG;
		} else {
			if (first_lap)
				buffer->element[element].flags =
				    SBAL_FLAGS_FIRST_FRAG;
			else
				buffer->element[element].flags =
				    SBAL_FLAGS_MIDDLE_FRAG;
		}
		data += length_here;
		element++;
		first_lap = 0;
	}
	*next_element_to_fill = element;
}

static int
qeth_fill_buffer(struct qeth_qdio_out_q *queue,
		 struct qeth_qdio_out_buffer *buf,
		 struct sk_buff *skb)
{
	struct qdio_buffer *buffer;
	struct qeth_hdr_tso *hdr;
	int flush_cnt = 0, hdr_len, large_send = 0;

	QETH_DBF_TEXT(trace, 6, "qdfillbf");

	buffer = buf->buffer;
	atomic_inc(&skb->users);
	skb_queue_tail(&buf->skb_list, skb);

	hdr  = (struct qeth_hdr_tso *) skb->data;
	/*check first on TSO ....*/
	if (hdr->hdr.hdr.l3.id == QETH_HEADER_TYPE_TSO) {
		int element = buf->next_element_to_fill;

		hdr_len = sizeof(struct qeth_hdr_tso) + hdr->ext.dg_hdr_len;
		/*fill first buffer entry only with header information */
		buffer->element[element].addr = skb->data;
		buffer->element[element].length = hdr_len;
		buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG;
		buf->next_element_to_fill++;
		skb->data += hdr_len;
		skb->len  -= hdr_len;
		large_send = 1;
	}
	if (skb_shinfo(skb)->nr_frags == 0)
		__qeth_fill_buffer(skb, buffer, large_send,
				   (int *)&buf->next_element_to_fill);
	else
		__qeth_fill_buffer_frag(skb, buffer, large_send,
					(int *)&buf->next_element_to_fill);

	if (!queue->do_pack) {
		QETH_DBF_TEXT(trace, 6, "fillbfnp");
		/* set state to PRIMED -> will be flushed */
		atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
		flush_cnt = 1;
	} else {
		QETH_DBF_TEXT(trace, 6, "fillbfpa");
		if (queue->card->options.performance_stats)
			queue->card->perf_stats.skbs_sent_pack++;
		if (buf->next_element_to_fill >=
				QETH_MAX_BUFFER_ELEMENTS(queue->card)) {
			/*
			 * packed buffer if full -> set state PRIMED
			 * -> will be flushed
			 */
			atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
			flush_cnt = 1;
		}
	}
	return flush_cnt;
}

static int
qeth_do_send_packet_fast(struct qeth_card *card, struct qeth_qdio_out_q *queue,
			 struct sk_buff *skb, struct qeth_hdr *hdr,
			 int elements_needed,
			 struct qeth_eddp_context *ctx)
{
	struct qeth_qdio_out_buffer *buffer;
	int buffers_needed = 0;
	int flush_cnt = 0;
	int index;

	QETH_DBF_TEXT(trace, 6, "dosndpfa");

	/* spin until we get the queue ... */
	while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED,
			      QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED);
	/* ... now we've got the queue */
	index = queue->next_buf_to_fill;
	buffer = &queue->bufs[queue->next_buf_to_fill];
	/*
	 * check if buffer is empty to make sure that we do not 'overtake'
	 * ourselves and try to fill a buffer that is already primed
	 */
	if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) 
		goto out;
	if (ctx == NULL)
		queue->next_buf_to_fill = (queue->next_buf_to_fill + 1) %
					  QDIO_MAX_BUFFERS_PER_Q;
	else {
		buffers_needed = qeth_eddp_check_buffers_for_context(queue,ctx);
		if (buffers_needed < 0) 
			goto out;
		queue->next_buf_to_fill =
			(queue->next_buf_to_fill + buffers_needed) %
			QDIO_MAX_BUFFERS_PER_Q;
	}
	atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
	if (ctx == NULL) {
		qeth_fill_buffer(queue, buffer, skb);
		qeth_flush_buffers(queue, 0, index, 1);
	} else {
		flush_cnt = qeth_eddp_fill_buffer(queue, ctx, index);
		WARN_ON(buffers_needed != flush_cnt);
		qeth_flush_buffers(queue, 0, index, flush_cnt);
	}
	return 0;
out:
	atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
	return -EBUSY;
}

static int
qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
		    struct sk_buff *skb, struct qeth_hdr *hdr,
		    int elements_needed, struct qeth_eddp_context *ctx)
{
	struct qeth_qdio_out_buffer *buffer;
	int start_index;
	int flush_count = 0;
	int do_pack = 0;
	int tmp;
	int rc = 0;

	QETH_DBF_TEXT(trace, 6, "dosndpkt");

	/* spin until we get the queue ... */
	while (atomic_cmpxchg(&queue->state, QETH_OUT_Q_UNLOCKED,
			      QETH_OUT_Q_LOCKED) != QETH_OUT_Q_UNLOCKED);
	start_index = queue->next_buf_to_fill;
	buffer = &queue->bufs[queue->next_buf_to_fill];
	/*
	 * check if buffer is empty to make sure that we do not 'overtake'
	 * ourselves and try to fill a buffer that is already primed
	 */
	if (atomic_read(&buffer->state) != QETH_QDIO_BUF_EMPTY) {
		atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
		return -EBUSY;
	}
	/* check if we need to switch packing state of this queue */
	qeth_switch_to_packing_if_needed(queue);
	if (queue->do_pack){
		do_pack = 1;
		if (ctx == NULL) {
			/* does packet fit in current buffer? */
			if((QETH_MAX_BUFFER_ELEMENTS(card) -
			    buffer->next_element_to_fill) < elements_needed){
				/* ... no -> set state PRIMED */
				atomic_set(&buffer->state,QETH_QDIO_BUF_PRIMED);
				flush_count++;
				queue->next_buf_to_fill =
					(queue->next_buf_to_fill + 1) %
					QDIO_MAX_BUFFERS_PER_Q;
				buffer = &queue->bufs[queue->next_buf_to_fill];
				/* we did a step forward, so check buffer state
				 * again */
				if (atomic_read(&buffer->state) !=
						QETH_QDIO_BUF_EMPTY){
					qeth_flush_buffers(queue, 0, start_index, flush_count);
					atomic_set(&queue->state, QETH_OUT_Q_UNLOCKED);
					return -EBUSY;
				}
			}
		} else {
			/* check if we have enough elements (including following
			 * free buffers) to handle eddp context */
			if (qeth_eddp_check_buffers_for_context(queue,ctx) < 0){
				printk("eddp tx_dropped 1\n");
				rc = -EBUSY;
				goto out;
			}
		}
	}
	if (ctx == NULL)
		tmp = qeth_fill_buffer(queue, buffer, skb);
	else {
		tmp = qeth_eddp_fill_buffer(queue,ctx,queue->next_buf_to_fill);
		if (tmp < 0) {
			printk("eddp tx_dropped 2\n");
			rc = - EBUSY;
			goto out;
		}
	}
	queue->next_buf_to_fill = (queue->next_buf_to_fill + tmp) %
				  QDIO_MAX_BUFFERS_PER_Q;
	flush_count += tmp;
out:
	if (flush_count)
		qeth_flush_buffers(queue, 0, start_index, flush_count);
	else if (!atomic_read(&queue->set_pci_flags_count))
		atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH);
	/*
	 * queue->state will go from LOCKED -> UNLOCKED or from
	 * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us
	 * (switch packing state or flush buffer to get another pci flag out).
	 * In that case we will enter this loop
	 */
	while (atomic_dec_return(&queue->state)){
		flush_count = 0;
		start_index = queue->next_buf_to_fill;
		/* check if we can go back to non-packing state */
		flush_count += qeth_switch_to_nonpacking_if_needed(queue);
		/*
		 * check if we need to flush a packing buffer to get a pci
		 * flag out on the queue
		 */
		if (!flush_count && !atomic_read(&queue->set_pci_flags_count))
			flush_count += qeth_flush_buffers_on_no_pci(queue);
		if (flush_count)
			qeth_flush_buffers(queue, 0, start_index, flush_count);
	}
	/* at this point the queue is UNLOCKED again */
	if (queue->card->options.performance_stats && do_pack)
		queue->card->perf_stats.bufs_sent_pack += flush_count;

	return rc;
}

static int
qeth_get_elements_no(struct qeth_card *card, void *hdr,
		     struct sk_buff *skb, int elems)
{
	int elements_needed = 0;

        if (skb_shinfo(skb)->nr_frags > 0) 
                elements_needed = (skb_shinfo(skb)->nr_frags + 1);
        if (elements_needed == 0)
                elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE)
                                        + skb->len) >> PAGE_SHIFT);
	if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){
                PRINT_ERR("Invalid size of IP packet "
			  "(Number=%d / Length=%d). Discarded.\n",
                          (elements_needed+elems), skb->len);
                return 0;
        }
        return elements_needed;
}


static int
qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
{
	int ipv = 0;
	int cast_type;
	struct qeth_qdio_out_q *queue;
	struct qeth_hdr *hdr = NULL;
	int elements_needed = 0;
	enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
	struct qeth_eddp_context *ctx = NULL;
	int tx_bytes = skb->len;
	unsigned short nr_frags = skb_shinfo(skb)->nr_frags;
	unsigned short tso_size = skb_shinfo(skb)->gso_size;
	struct sk_buff *new_skb, *new_skb2;
	int rc;

	QETH_DBF_TEXT(trace, 6, "sendpkt");

	new_skb = skb;
	if ((card->info.type == QETH_CARD_TYPE_OSN) &&
	    (skb->protocol == htons(ETH_P_IPV6)))
		return -EPERM;
	cast_type = qeth_get_cast_type(card, skb);
	if ((cast_type == RTN_BROADCAST) &&
	    (card->info.broadcast_capable == 0))
		return -EPERM;
	queue = card->qdio.out_qs
		[qeth_get_priority_queue(card, skb, ipv, cast_type)];
	if (!card->options.layer2) {
		ipv = qeth_get_ip_version(skb);
		if ((card->dev->hard_header == qeth_fake_header) && ipv) {
			new_skb = qeth_pskb_unshare(skb, GFP_ATOMIC);
			if (!new_skb)
				return -ENOMEM;
			if(card->dev->type == ARPHRD_IEEE802_TR){
				skb_pull(new_skb, QETH_FAKE_LL_LEN_TR);
			} else {
				skb_pull(new_skb, QETH_FAKE_LL_LEN_ETH);
			}
		}
	}
	if (skb_is_gso(skb))
		large_send = card->options.large_send;
	/* check on OSN device*/
	if (card->info.type == QETH_CARD_TYPE_OSN)
		hdr = (struct qeth_hdr *)new_skb->data;
	/*are we able to do TSO ? */
	if ((large_send == QETH_LARGE_SEND_TSO) &&
	    (cast_type == RTN_UNSPEC)) {
		rc = qeth_tso_prepare_packet(card, new_skb, ipv, cast_type);
		if (rc) {
			__qeth_free_new_skb(skb, new_skb);
			return rc;
		}
		elements_needed++;
	} else if (card->info.type != QETH_CARD_TYPE_OSN) {
		new_skb2 = qeth_prepare_skb(card, new_skb, &hdr, ipv);
		if (!new_skb2) {
			__qeth_free_new_skb(skb, new_skb);
			return -EINVAL;
		}
		if (new_skb != skb)
			__qeth_free_new_skb(new_skb2, new_skb);
		new_skb = new_skb2;
		qeth_fill_header(card, hdr, new_skb, ipv, cast_type);
	}
	if (large_send == QETH_LARGE_SEND_EDDP) {
		ctx = qeth_eddp_create_context(card, new_skb, hdr,
					       skb->sk->sk_protocol);
		if (ctx == NULL) {
			__qeth_free_new_skb(skb, new_skb);
			PRINT_WARN("could not create eddp context\n");
			return -EINVAL;
		}
	} else {
		int elems = qeth_get_elements_no(card,(void*) hdr, new_skb,
						 elements_needed);
		if (!elems) {
			__qeth_free_new_skb(skb, new_skb);
			return -EINVAL;
		}
		elements_needed += elems;
	}

	if (card->info.type != QETH_CARD_TYPE_IQD)
		rc = qeth_do_send_packet(card, queue, new_skb, hdr,
					 elements_needed, ctx);
	else
		rc = qeth_do_send_packet_fast(card, queue, new_skb, hdr,
					      elements_needed, ctx);
	if (!rc) {
		card->stats.tx_packets++;
		card->stats.tx_bytes += tx_bytes;
		if (new_skb != skb)
			dev_kfree_skb_any(skb);
		if (card->options.performance_stats) {
			if (tso_size &&
			    !(large_send == QETH_LARGE_SEND_NO)) {
				card->perf_stats.large_send_bytes += tx_bytes;
				card->perf_stats.large_send_cnt++;
			}
			if (nr_frags > 0) {
				card->perf_stats.sg_skbs_sent++;
				/* nr_frags + skb->data */
				card->perf_stats.sg_frags_sent +=
					nr_frags + 1;
			}
		}
	} else {
		card->stats.tx_dropped++;
		__qeth_free_new_skb(skb, new_skb);
	}
	if (ctx != NULL) {
		/* drop creator's reference */
		qeth_eddp_put_context(ctx);
		/* free skb; it's not referenced by a buffer */
		if (!rc)
		       dev_kfree_skb_any(new_skb);
	}
	return rc;
}

static int
qeth_mdio_read(struct net_device *dev, int phy_id, int regnum)
{
	struct qeth_card *card = (struct qeth_card *) dev->priv;
	int rc = 0;

	switch(regnum){
	case MII_BMCR: /* Basic mode control register */
		rc = BMCR_FULLDPLX;
		if ((card->info.link_type != QETH_LINK_TYPE_GBIT_ETH)&&
		    (card->info.link_type != QETH_LINK_TYPE_OSN) &&
		    (card->info.link_type != QETH_LINK_TYPE_10GBIT_ETH))
			rc |= BMCR_SPEED100;
		break;
	case MII_BMSR: /* Basic mode status register */
		rc = BMSR_ERCAP | BMSR_ANEGCOMPLETE | BMSR_LSTATUS |
		     BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | BMSR_100FULL |
		     BMSR_100BASE4;
		break;
	case MII_PHYSID1: /* PHYS ID 1 */
		rc = (dev->dev_addr[0] << 16) | (dev->dev_addr[1] << 8) |
		     dev->dev_addr[2];
		rc = (rc >> 5) & 0xFFFF;
		break;
	case MII_PHYSID2: /* PHYS ID 2 */
		rc = (dev->dev_addr[2] << 10) & 0xFFFF;
		break;
	case MII_ADVERTISE: /* Advertisement control reg */
		rc = ADVERTISE_ALL;
		break;
	case MII_LPA: /* Link partner ability reg */
		rc = LPA_10HALF | LPA_10FULL | LPA_100HALF | LPA_100FULL |
		     LPA_100BASE4 | LPA_LPACK;
		break;
	case MII_EXPANSION: /* Expansion register */
		break;
	case MII_DCOUNTER: /* disconnect counter */
		break;
	case MII_FCSCOUNTER: /* false carrier counter */
		break;
	case MII_NWAYTEST: /* N-way auto-neg test register */
		break;
	case MII_RERRCOUNTER: /* rx error counter */
		rc = card->stats.rx_errors;
		break;
	case MII_SREVISION: /* silicon revision */
		break;
	case MII_RESV1: /* reserved 1 */
		break;
	case MII_LBRERROR: /* loopback, rx, bypass error */
		break;
	case MII_PHYADDR: /* physical address */
		break;
	case MII_RESV2: /* reserved 2 */
		break;
	case MII_TPISTATUS: /* TPI status for 10mbps */
		break;
	case MII_NCONFIG: /* network interface config */
		break;
	default:
		break;
	}
	return rc;
}


static const char *
qeth_arp_get_error_cause(int *rc)
{
	switch (*rc) {
	case QETH_IPA_ARP_RC_FAILED:
		*rc = -EIO;
		return "operation failed";
	case QETH_IPA_ARP_RC_NOTSUPP:
		*rc = -EOPNOTSUPP;
		return "operation not supported";
	case QETH_IPA_ARP_RC_OUT_OF_RANGE:
		*rc = -EINVAL;
		return "argument out of range";
	case QETH_IPA_ARP_RC_Q_NOTSUPP:
		*rc = -EOPNOTSUPP;
		return "query operation not supported";
	case QETH_IPA_ARP_RC_Q_NO_DATA:
		*rc = -ENOENT;
		return "no query data available";
	default:
		return "unknown error";
	}
}

static int
qeth_send_simple_setassparms(struct qeth_card *, enum qeth_ipa_funcs,
			     __u16, long);

static int
qeth_arp_set_no_entries(struct qeth_card *card, int no_entries)
{
	int tmp;
	int rc;

	QETH_DBF_TEXT(trace,3,"arpstnoe");

	/*
	 * currently GuestLAN only supports the ARP assist function
	 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_SET_NO_ENTRIES;
	 * thus we say EOPNOTSUPP for this ARP function
	 */
	if (card->info.guestlan)
		return -EOPNOTSUPP;
	if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
		PRINT_WARN("ARP processing not supported "
			   "on %s!\n", QETH_CARD_IFNAME(card));
		return -EOPNOTSUPP;
	}
	rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING,
					  IPA_CMD_ASS_ARP_SET_NO_ENTRIES,
					  no_entries);
	if (rc) {
		tmp = rc;
		PRINT_WARN("Could not set number of ARP entries on %s: "
			   "%s (0x%x/%d)\n",
			   QETH_CARD_IFNAME(card), qeth_arp_get_error_cause(&rc),
			   tmp, tmp);
	}
	return rc;
}

static void
qeth_copy_arp_entries_stripped(struct qeth_arp_query_info *qinfo,
		               struct qeth_arp_query_data *qdata,
			       int entry_size, int uentry_size)
{
	char *entry_ptr;
	char *uentry_ptr;
	int i;

	entry_ptr = (char *)&qdata->data;
	uentry_ptr = (char *)(qinfo->udata + qinfo->udata_offset);
	for (i = 0; i < qdata->no_entries; ++i){
		/* strip off 32 bytes "media specific information" */
		memcpy(uentry_ptr, (entry_ptr + 32), entry_size - 32);
		entry_ptr += entry_size;
		uentry_ptr += uentry_size;
	}
}

static int
qeth_arp_query_cb(struct qeth_card *card, struct qeth_reply *reply,
		  unsigned long data)
{
	struct qeth_ipa_cmd *cmd;
	struct qeth_arp_query_data *qdata;
	struct qeth_arp_query_info *qinfo;
	int entry_size;
	int uentry_size;
	int i;

	QETH_DBF_TEXT(trace,4,"arpquecb");

	qinfo = (struct qeth_arp_query_info *) reply->param;
	cmd = (struct qeth_ipa_cmd *) data;
	if (cmd->hdr.return_code) {
		QETH_DBF_TEXT_(trace,4,"qaer1%i", cmd->hdr.return_code);
		return 0;
	}
	if (cmd->data.setassparms.hdr.return_code) {
		cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code;
		QETH_DBF_TEXT_(trace,4,"qaer2%i", cmd->hdr.return_code);
		return 0;
	}
	qdata = &cmd->data.setassparms.data.query_arp;
	switch(qdata->reply_bits){
	case 5:
		uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry5);
		if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
			uentry_size = sizeof(struct qeth_arp_qi_entry5_short);
		break;
	case 7:
		/* fall through to default */
	default:
		/* tr is the same as eth -> entry7 */
		uentry_size = entry_size = sizeof(struct qeth_arp_qi_entry7);
		if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
			uentry_size = sizeof(struct qeth_arp_qi_entry7_short);
		break;
	}
	/* check if there is enough room in userspace */
	if ((qinfo->udata_len - qinfo->udata_offset) <
			qdata->no_entries * uentry_size){
		QETH_DBF_TEXT_(trace, 4, "qaer3%i", -ENOMEM);
		cmd->hdr.return_code = -ENOMEM;
		PRINT_WARN("query ARP user space buffer is too small for "
			   "the returned number of ARP entries. "
			   "Aborting query!\n");
		goto out_error;
	}
	QETH_DBF_TEXT_(trace, 4, "anore%i",
		       cmd->data.setassparms.hdr.number_of_replies);
	QETH_DBF_TEXT_(trace, 4, "aseqn%i", cmd->data.setassparms.hdr.seq_no);
	QETH_DBF_TEXT_(trace, 4, "anoen%i", qdata->no_entries);

	if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES) {
		/* strip off "media specific information" */
		qeth_copy_arp_entries_stripped(qinfo, qdata, entry_size,
					       uentry_size);
	} else
		/*copy entries to user buffer*/
		memcpy(qinfo->udata + qinfo->udata_offset,
		       (char *)&qdata->data, qdata->no_entries*uentry_size);

	qinfo->no_entries += qdata->no_entries;
	qinfo->udata_offset += (qdata->no_entries*uentry_size);
	/* check if all replies received ... */
	if (cmd->data.setassparms.hdr.seq_no <
	    cmd->data.setassparms.hdr.number_of_replies)
		return 1;
	memcpy(qinfo->udata, &qinfo->no_entries, 4);
	/* keep STRIP_ENTRIES flag so the user program can distinguish
	 * stripped entries from normal ones */
	if (qinfo->mask_bits & QETH_QARP_STRIP_ENTRIES)
		qdata->reply_bits |= QETH_QARP_STRIP_ENTRIES;
	memcpy(qinfo->udata + QETH_QARP_MASK_OFFSET,&qdata->reply_bits,2);
	return 0;
out_error:
	i = 0;
	memcpy(qinfo->udata, &i, 4);
	return 0;
}

static int
qeth_send_ipa_arp_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
		      int len, int (*reply_cb)(struct qeth_card *,
					       struct qeth_reply *,
					       unsigned long),
		      void *reply_param)
{
	QETH_DBF_TEXT(trace,4,"sendarp");

	memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
	memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
	       &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
	return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
				      reply_cb, reply_param);
}

static int
qeth_send_ipa_snmp_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
		      int len, int (*reply_cb)(struct qeth_card *,
					       struct qeth_reply *,
					       unsigned long),
		      void *reply_param)
{
	u16 s1, s2;

	QETH_DBF_TEXT(trace,4,"sendsnmp");

	memcpy(iob->data, IPA_PDU_HEADER, IPA_PDU_HEADER_SIZE);
	memcpy(QETH_IPA_CMD_DEST_ADDR(iob->data),
	       &card->token.ulp_connection_r, QETH_MPC_TOKEN_LENGTH);
	/* adjust PDU length fields in IPA_PDU_HEADER */
	s1 = (u32) IPA_PDU_HEADER_SIZE + len;
	s2 = (u32) len;
	memcpy(QETH_IPA_PDU_LEN_TOTAL(iob->data), &s1, 2);
	memcpy(QETH_IPA_PDU_LEN_PDU1(iob->data), &s2, 2);
	memcpy(QETH_IPA_PDU_LEN_PDU2(iob->data), &s2, 2);
	memcpy(QETH_IPA_PDU_LEN_PDU3(iob->data), &s2, 2);
	return qeth_send_control_data(card, IPA_PDU_HEADER_SIZE + len, iob,
				      reply_cb, reply_param);
}

static struct qeth_cmd_buffer *
qeth_get_setassparms_cmd(struct qeth_card *, enum qeth_ipa_funcs,
			 __u16, __u16, enum qeth_prot_versions);
static int
qeth_arp_query(struct qeth_card *card, char __user *udata)
{
	struct qeth_cmd_buffer *iob;
	struct qeth_arp_query_info qinfo = {0, };
	int tmp;
	int rc;

	QETH_DBF_TEXT(trace,3,"arpquery");

	if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/
			       IPA_ARP_PROCESSING)) {
		PRINT_WARN("ARP processing not supported "
			   "on %s!\n", QETH_CARD_IFNAME(card));
		return -EOPNOTSUPP;
	}
	/* get size of userspace buffer and mask_bits -> 6 bytes */
	if (copy_from_user(&qinfo, udata, 6))
		return -EFAULT;
	if (!(qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL)))
		return -ENOMEM;
	qinfo.udata_offset = QETH_QARP_ENTRIES_OFFSET;
	iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
				       IPA_CMD_ASS_ARP_QUERY_INFO,
				       sizeof(int),QETH_PROT_IPV4);

	rc = qeth_send_ipa_arp_cmd(card, iob,
				   QETH_SETASS_BASE_LEN+QETH_ARP_CMD_LEN,
				   qeth_arp_query_cb, (void *)&qinfo);
	if (rc) {
		tmp = rc;
		PRINT_WARN("Error while querying ARP cache on %s: %s "
			   "(0x%x/%d)\n",
			   QETH_CARD_IFNAME(card), qeth_arp_get_error_cause(&rc),
			   tmp, tmp);
		if (copy_to_user(udata, qinfo.udata, 4))
			rc = -EFAULT;
	} else {
		if (copy_to_user(udata, qinfo.udata, qinfo.udata_len))
			rc = -EFAULT;
	}
	kfree(qinfo.udata);
	return rc;
}

/**
 * SNMP command callback
 */
static int
qeth_snmp_command_cb(struct qeth_card *card, struct qeth_reply *reply,
		     unsigned long sdata)
{
	struct qeth_ipa_cmd *cmd;
	struct qeth_arp_query_info *qinfo;
	struct qeth_snmp_cmd *snmp;
	unsigned char *data;
	__u16 data_len;

	QETH_DBF_TEXT(trace,3,"snpcmdcb");

	cmd = (struct qeth_ipa_cmd *) sdata;
	data = (unsigned char *)((char *)cmd - reply->offset);
	qinfo = (struct qeth_arp_query_info *) reply->param;
	snmp = &cmd->data.setadapterparms.data.snmp;

	if (cmd->hdr.return_code) {
		QETH_DBF_TEXT_(trace,4,"scer1%i", cmd->hdr.return_code);
		return 0;
	}
	if (cmd->data.setadapterparms.hdr.return_code) {
		cmd->hdr.return_code = cmd->data.setadapterparms.hdr.return_code;
		QETH_DBF_TEXT_(trace,4,"scer2%i", cmd->hdr.return_code);
		return 0;
	}
	data_len = *((__u16*)QETH_IPA_PDU_LEN_PDU1(data));
	if (cmd->data.setadapterparms.hdr.seq_no == 1)
		data_len -= (__u16)((char *)&snmp->data - (char *)cmd);
	else
		data_len -= (__u16)((char*)&snmp->request - (char *)cmd);

	/* check if there is enough room in userspace */
	if ((qinfo->udata_len - qinfo->udata_offset) < data_len) {
		QETH_DBF_TEXT_(trace, 4, "scer3%i", -ENOMEM);
		cmd->hdr.return_code = -ENOMEM;
		return 0;
	}
	QETH_DBF_TEXT_(trace, 4, "snore%i",
		       cmd->data.setadapterparms.hdr.used_total);
	QETH_DBF_TEXT_(trace, 4, "sseqn%i", cmd->data.setadapterparms.hdr.seq_no);
	/*copy entries to user buffer*/
	if (cmd->data.setadapterparms.hdr.seq_no == 1) {
		memcpy(qinfo->udata + qinfo->udata_offset,
		       (char *)snmp,
		       data_len + offsetof(struct qeth_snmp_cmd,data));
		qinfo->udata_offset += offsetof(struct qeth_snmp_cmd, data);
	} else {
		memcpy(qinfo->udata + qinfo->udata_offset,
		       (char *)&snmp->request, data_len);
	}
	qinfo->udata_offset += data_len;
	/* check if all replies received ... */
		QETH_DBF_TEXT_(trace, 4, "srtot%i",
			       cmd->data.setadapterparms.hdr.used_total);
		QETH_DBF_TEXT_(trace, 4, "srseq%i",
			       cmd->data.setadapterparms.hdr.seq_no);
	if (cmd->data.setadapterparms.hdr.seq_no <
	    cmd->data.setadapterparms.hdr.used_total)
		return 1;
	return 0;
}

static struct qeth_cmd_buffer *
qeth_get_ipacmd_buffer(struct qeth_card *, enum qeth_ipa_cmds,
		       enum qeth_prot_versions );

static struct qeth_cmd_buffer *
qeth_get_adapter_cmd(struct qeth_card *card, __u32 command, __u32 cmdlen)
{
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

	iob = qeth_get_ipacmd_buffer(card,IPA_CMD_SETADAPTERPARMS,
				     QETH_PROT_IPV4);
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	cmd->data.setadapterparms.hdr.cmdlength = cmdlen;
	cmd->data.setadapterparms.hdr.command_code = command;
	cmd->data.setadapterparms.hdr.used_total = 1;
	cmd->data.setadapterparms.hdr.seq_no = 1;

	return iob;
}

/**
 * function to send SNMP commands to OSA-E card
 */
static int
qeth_snmp_command(struct qeth_card *card, char __user *udata)
{
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;
	struct qeth_snmp_ureq *ureq;
	int req_len;
	struct qeth_arp_query_info qinfo = {0, };
	int rc = 0;

	QETH_DBF_TEXT(trace,3,"snmpcmd");

	if (card->info.guestlan)
		return -EOPNOTSUPP;

	if ((!qeth_adp_supported(card,IPA_SETADP_SET_SNMP_CONTROL)) &&
	    (!card->options.layer2) ) {
		PRINT_WARN("SNMP Query MIBS not supported "
			   "on %s!\n", QETH_CARD_IFNAME(card));
		return -EOPNOTSUPP;
	}
	/* skip 4 bytes (data_len struct member) to get req_len */
	if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int)))
		return -EFAULT;
	ureq = kmalloc(req_len+sizeof(struct qeth_snmp_ureq_hdr), GFP_KERNEL);
	if (!ureq) {
		QETH_DBF_TEXT(trace, 2, "snmpnome");
		return -ENOMEM;
	}
	if (copy_from_user(ureq, udata,
			req_len+sizeof(struct qeth_snmp_ureq_hdr))){
		kfree(ureq);
		return -EFAULT;
	}
	qinfo.udata_len = ureq->hdr.data_len;
	if (!(qinfo.udata = kzalloc(qinfo.udata_len, GFP_KERNEL))){
		kfree(ureq);
		return -ENOMEM;
	}
	qinfo.udata_offset = sizeof(struct qeth_snmp_ureq_hdr);

	iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL,
				   QETH_SNMP_SETADP_CMDLENGTH + req_len);
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	memcpy(&cmd->data.setadapterparms.data.snmp, &ureq->cmd, req_len);
	rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len,
				    qeth_snmp_command_cb, (void *)&qinfo);
	if (rc)
		PRINT_WARN("SNMP command failed on %s: (0x%x)\n",
			   QETH_CARD_IFNAME(card), rc);
	else {
		if (copy_to_user(udata, qinfo.udata, qinfo.udata_len))
			rc = -EFAULT;
	}

	kfree(ureq);
	kfree(qinfo.udata);
	return rc;
}

static int
qeth_default_setassparms_cb(struct qeth_card *, struct qeth_reply *,
			    unsigned long);

static int
qeth_default_setadapterparms_cb(struct qeth_card *card,
                                struct qeth_reply *reply,
                                unsigned long data);
static int
qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *,
		      __u16, long,
		      int (*reply_cb)
		      (struct qeth_card *, struct qeth_reply *, unsigned long),
		      void *reply_param);

static int
qeth_arp_add_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry)
{
	struct qeth_cmd_buffer *iob;
	char buf[16];
	int tmp;
	int rc;

	QETH_DBF_TEXT(trace,3,"arpadent");

	/*
	 * currently GuestLAN only supports the ARP assist function
	 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_ADD_ENTRY;
	 * thus we say EOPNOTSUPP for this ARP function
	 */
	if (card->info.guestlan)
		return -EOPNOTSUPP;
	if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
		PRINT_WARN("ARP processing not supported "
			   "on %s!\n", QETH_CARD_IFNAME(card));
		return -EOPNOTSUPP;
	}

	iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
				       IPA_CMD_ASS_ARP_ADD_ENTRY,
				       sizeof(struct qeth_arp_cache_entry),
				       QETH_PROT_IPV4);
	rc = qeth_send_setassparms(card, iob,
				   sizeof(struct qeth_arp_cache_entry),
				   (unsigned long) entry,
				   qeth_default_setassparms_cb, NULL);
	if (rc) {
		tmp = rc;
		qeth_ipaddr4_to_string((u8 *)entry->ipaddr, buf);
		PRINT_WARN("Could not add ARP entry for address %s on %s: "
			   "%s (0x%x/%d)\n",
			   buf, QETH_CARD_IFNAME(card),
			   qeth_arp_get_error_cause(&rc), tmp, tmp);
	}
	return rc;
}

static int
qeth_arp_remove_entry(struct qeth_card *card, struct qeth_arp_cache_entry *entry)
{
	struct qeth_cmd_buffer *iob;
	char buf[16] = {0, };
	int tmp;
	int rc;

	QETH_DBF_TEXT(trace,3,"arprment");

	/*
	 * currently GuestLAN only supports the ARP assist function
	 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_REMOVE_ENTRY;
	 * thus we say EOPNOTSUPP for this ARP function
	 */
	if (card->info.guestlan)
		return -EOPNOTSUPP;
	if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
		PRINT_WARN("ARP processing not supported "
			   "on %s!\n", QETH_CARD_IFNAME(card));
		return -EOPNOTSUPP;
	}
	memcpy(buf, entry, 12);
	iob = qeth_get_setassparms_cmd(card, IPA_ARP_PROCESSING,
				       IPA_CMD_ASS_ARP_REMOVE_ENTRY,
				       12,
				       QETH_PROT_IPV4);
	rc = qeth_send_setassparms(card, iob,
				   12, (unsigned long)buf,
				   qeth_default_setassparms_cb, NULL);
	if (rc) {
		tmp = rc;
		memset(buf, 0, 16);
		qeth_ipaddr4_to_string((u8 *)entry->ipaddr, buf);
		PRINT_WARN("Could not delete ARP entry for address %s on %s: "
			   "%s (0x%x/%d)\n",
			   buf, QETH_CARD_IFNAME(card),
			   qeth_arp_get_error_cause(&rc), tmp, tmp);
	}
	return rc;
}

static int
qeth_arp_flush_cache(struct qeth_card *card)
{
	int rc;
	int tmp;

	QETH_DBF_TEXT(trace,3,"arpflush");

	/*
	 * currently GuestLAN only supports the ARP assist function
	 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_FLUSH_CACHE;
	 * thus we say EOPNOTSUPP for this ARP function
	*/
	if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD))
		return -EOPNOTSUPP;
	if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
		PRINT_WARN("ARP processing not supported "
			   "on %s!\n", QETH_CARD_IFNAME(card));
		return -EOPNOTSUPP;
	}
	rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING,
					  IPA_CMD_ASS_ARP_FLUSH_CACHE, 0);
	if (rc){
		tmp = rc;
		PRINT_WARN("Could not flush ARP cache on %s: %s (0x%x/%d)\n",
			   QETH_CARD_IFNAME(card), qeth_arp_get_error_cause(&rc),
			   tmp, tmp);
	}
	return rc;
}

static int
qeth_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
	struct qeth_card *card = (struct qeth_card *)dev->priv;
	struct qeth_arp_cache_entry arp_entry;
	struct mii_ioctl_data *mii_data;
	int rc = 0;

	if (!card)
		return -ENODEV;

	if ((card->state != CARD_STATE_UP) &&
            (card->state != CARD_STATE_SOFTSETUP))
		return -ENODEV;

	if (card->info.type == QETH_CARD_TYPE_OSN)
		return -EPERM;

	switch (cmd){
	case SIOC_QETH_ARP_SET_NO_ENTRIES:
		if ( !capable(CAP_NET_ADMIN) ||
		     (card->options.layer2) ) {
			rc = -EPERM;
			break;
		}
		rc = qeth_arp_set_no_entries(card, rq->ifr_ifru.ifru_ivalue);
		break;
	case SIOC_QETH_ARP_QUERY_INFO:
		if ( !capable(CAP_NET_ADMIN) ||
		     (card->options.layer2) ) {
			rc = -EPERM;
			break;
		}
		rc = qeth_arp_query(card, rq->ifr_ifru.ifru_data);
		break;
	case SIOC_QETH_ARP_ADD_ENTRY:
		if ( !capable(CAP_NET_ADMIN) ||
		     (card->options.layer2) ) {
			rc = -EPERM;
			break;
		}
		if (copy_from_user(&arp_entry, rq->ifr_ifru.ifru_data,
				   sizeof(struct qeth_arp_cache_entry)))
			rc = -EFAULT;
		else
			rc = qeth_arp_add_entry(card, &arp_entry);
		break;
	case SIOC_QETH_ARP_REMOVE_ENTRY:
		if ( !capable(CAP_NET_ADMIN) ||
		     (card->options.layer2) ) {
			rc = -EPERM;
			break;
		}
		if (copy_from_user(&arp_entry, rq->ifr_ifru.ifru_data,
				   sizeof(struct qeth_arp_cache_entry)))
			rc = -EFAULT;
		else
			rc = qeth_arp_remove_entry(card, &arp_entry);
		break;
	case SIOC_QETH_ARP_FLUSH_CACHE:
		if ( !capable(CAP_NET_ADMIN) ||
		     (card->options.layer2) ) {
			rc = -EPERM;
			break;
		}
		rc = qeth_arp_flush_cache(card);
		break;
	case SIOC_QETH_ADP_SET_SNMP_CONTROL:
		rc = qeth_snmp_command(card, rq->ifr_ifru.ifru_data);
		break;
	case SIOC_QETH_GET_CARD_TYPE:
		if ((card->info.type == QETH_CARD_TYPE_OSAE) &&
		    !card->info.guestlan)
			return 1;
		return 0;
		break;
	case SIOCGMIIPHY:
		mii_data = if_mii(rq);
		mii_data->phy_id = 0;
		break;
	case SIOCGMIIREG:
		mii_data = if_mii(rq);
		if (mii_data->phy_id != 0)
			rc = -EINVAL;
		else
			mii_data->val_out = qeth_mdio_read(dev,mii_data->phy_id,
							   mii_data->reg_num);
		break;
	default:
		rc = -EOPNOTSUPP;
	}
	if (rc)
		QETH_DBF_TEXT_(trace, 2, "ioce%d", rc);
	return rc;
}

static struct net_device_stats *
qeth_get_stats(struct net_device *dev)
{
	struct qeth_card *card;

	card = (struct qeth_card *) (dev->priv);

	QETH_DBF_TEXT(trace,5,"getstat");

	return &card->stats;
}

static int
qeth_change_mtu(struct net_device *dev, int new_mtu)
{
	struct qeth_card *card;
	char dbf_text[15];

	card = (struct qeth_card *) (dev->priv);

	QETH_DBF_TEXT(trace,4,"chgmtu");
	sprintf(dbf_text, "%8x", new_mtu);
	QETH_DBF_TEXT(trace,4,dbf_text);

	if (new_mtu < 64)
		return -EINVAL;
	if (new_mtu > 65535)
		return -EINVAL;
	if ((!qeth_is_supported(card,IPA_IP_FRAGMENTATION)) &&
	    (!qeth_mtu_is_valid(card, new_mtu)))
		return -EINVAL;
	dev->mtu = new_mtu;
	return 0;
}

#ifdef CONFIG_QETH_VLAN
static void
qeth_vlan_rx_register(struct net_device *dev, struct vlan_group *grp)
{
	struct qeth_card *card;
	unsigned long flags;

	QETH_DBF_TEXT(trace,4,"vlanreg");

	card = (struct qeth_card *) dev->priv;
	spin_lock_irqsave(&card->vlanlock, flags);
	card->vlangrp = grp;
	spin_unlock_irqrestore(&card->vlanlock, flags);
}

static void
qeth_free_vlan_buffer(struct qeth_card *card, struct qeth_qdio_out_buffer *buf,
		      unsigned short vid)
{
	int i;
	struct sk_buff *skb;
	struct sk_buff_head tmp_list;

	skb_queue_head_init(&tmp_list);
	lockdep_set_class(&tmp_list.lock, &qdio_out_skb_queue_key);
	for(i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i){
		while ((skb = skb_dequeue(&buf->skb_list))){
			if (vlan_tx_tag_present(skb) &&
			    (vlan_tx_tag_get(skb) == vid)) {
				atomic_dec(&skb->users);
				dev_kfree_skb(skb);
			} else
				skb_queue_tail(&tmp_list, skb);
		}
	}
	while ((skb = skb_dequeue(&tmp_list)))
		skb_queue_tail(&buf->skb_list, skb);
}

static void
qeth_free_vlan_skbs(struct qeth_card *card, unsigned short vid)
{
	int i, j;

	QETH_DBF_TEXT(trace, 4, "frvlskbs");
	for (i = 0; i < card->qdio.no_out_queues; ++i){
		for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; ++j)
			qeth_free_vlan_buffer(card, &card->qdio.
					      out_qs[i]->bufs[j], vid);
	}
}

static void
qeth_free_vlan_addresses4(struct qeth_card *card, unsigned short vid)
{
	struct in_device *in_dev;
	struct in_ifaddr *ifa;
	struct qeth_ipaddr *addr;

	QETH_DBF_TEXT(trace, 4, "frvaddr4");

	rcu_read_lock();
	in_dev = __in_dev_get_rcu(vlan_group_get_device(card->vlangrp, vid));
	if (!in_dev)
		goto out;
	for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) {
		addr = qeth_get_addr_buffer(QETH_PROT_IPV4);
		if (addr){
			addr->u.a4.addr = ifa->ifa_address;
			addr->u.a4.mask = ifa->ifa_mask;
			addr->type = QETH_IP_TYPE_NORMAL;
			if (!qeth_delete_ip(card, addr))
				kfree(addr);
		}
	}
out:
	rcu_read_unlock();
}

static void
qeth_free_vlan_addresses6(struct qeth_card *card, unsigned short vid)
{
#ifdef CONFIG_QETH_IPV6
	struct inet6_dev *in6_dev;
	struct inet6_ifaddr *ifa;
	struct qeth_ipaddr *addr;

	QETH_DBF_TEXT(trace, 4, "frvaddr6");

	in6_dev = in6_dev_get(vlan_group_get_device(card->vlangrp, vid));
	if (!in6_dev)
		return;
	for (ifa = in6_dev->addr_list; ifa; ifa = ifa->lst_next){
		addr = qeth_get_addr_buffer(QETH_PROT_IPV6);
		if (addr){
			memcpy(&addr->u.a6.addr, &ifa->addr,
			       sizeof(struct in6_addr));
			addr->u.a6.pfxlen = ifa->prefix_len;
			addr->type = QETH_IP_TYPE_NORMAL;
			if (!qeth_delete_ip(card, addr))
				kfree(addr);
		}
	}
	in6_dev_put(in6_dev);
#endif /* CONFIG_QETH_IPV6 */
}

static void
qeth_free_vlan_addresses(struct qeth_card *card, unsigned short vid)
{
	if (card->options.layer2 || !card->vlangrp)
		return;
	qeth_free_vlan_addresses4(card, vid);
	qeth_free_vlan_addresses6(card, vid);
}

static int
qeth_layer2_send_setdelvlan_cb(struct qeth_card *card,
                               struct qeth_reply *reply,
                               unsigned long data)
{
        struct qeth_ipa_cmd *cmd;

        QETH_DBF_TEXT(trace, 2, "L2sdvcb");
        cmd = (struct qeth_ipa_cmd *) data;
        if (cmd->hdr.return_code) {
		PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. "
			  "Continuing\n",cmd->data.setdelvlan.vlan_id,
			  QETH_CARD_IFNAME(card), cmd->hdr.return_code);
		QETH_DBF_TEXT_(trace, 2, "L2VL%4x", cmd->hdr.command);
		QETH_DBF_TEXT_(trace, 2, "L2%s", CARD_BUS_ID(card));
		QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
	}
        return 0;
}

static int
qeth_layer2_send_setdelvlan(struct qeth_card *card, __u16 i,
			    enum qeth_ipa_cmds ipacmd)
{
	struct qeth_ipa_cmd *cmd;
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT_(trace, 4, "L2sdv%x",ipacmd);
	iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
        cmd->data.setdelvlan.vlan_id = i;
	return qeth_send_ipa_cmd(card, iob,
				 qeth_layer2_send_setdelvlan_cb, NULL);
}

static void
qeth_layer2_process_vlans(struct qeth_card *card, int clear)
{
        unsigned short  i;

	QETH_DBF_TEXT(trace, 3, "L2prcvln");

	if (!card->vlangrp)
		return;
	for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
		if (vlan_group_get_device(card->vlangrp, i) == NULL)
			continue;
		if (clear)
			qeth_layer2_send_setdelvlan(card, i, IPA_CMD_DELVLAN);
		else
			qeth_layer2_send_setdelvlan(card, i, IPA_CMD_SETVLAN);
        }
}

/*add_vid is layer 2 used only ....*/
static void
qeth_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
{
	struct qeth_card *card;

	QETH_DBF_TEXT_(trace, 4, "aid:%d", vid);

	card = (struct qeth_card *) dev->priv;
	if (!card->options.layer2)
		return;
	qeth_layer2_send_setdelvlan(card, vid, IPA_CMD_SETVLAN);
}

/*... kill_vid used for both modes*/
static void
qeth_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
{
	struct qeth_card *card;
	unsigned long flags;

	QETH_DBF_TEXT_(trace, 4, "kid:%d", vid);

	card = (struct qeth_card *) dev->priv;
	/* free all skbs for the vlan device */
	qeth_free_vlan_skbs(card, vid);
	spin_lock_irqsave(&card->vlanlock, flags);
	/* unregister IP addresses of vlan device */
	qeth_free_vlan_addresses(card, vid);
	vlan_group_set_device(card->vlangrp, vid, NULL);
	spin_unlock_irqrestore(&card->vlanlock, flags);
	if (card->options.layer2)
		qeth_layer2_send_setdelvlan(card, vid, IPA_CMD_DELVLAN);
	qeth_set_multicast_list(card->dev);
}
#endif
/**
 * Examine hardware response to SET_PROMISC_MODE
 */
static int
qeth_setadp_promisc_mode_cb(struct qeth_card *card,
			    struct qeth_reply *reply,
			    unsigned long data)
{
	struct qeth_ipa_cmd *cmd;
	struct qeth_ipacmd_setadpparms *setparms;

	QETH_DBF_TEXT(trace,4,"prmadpcb");

	cmd = (struct qeth_ipa_cmd *) data;
	setparms = &(cmd->data.setadapterparms);

        qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
	if (cmd->hdr.return_code) {
		QETH_DBF_TEXT_(trace,4,"prmrc%2.2x",cmd->hdr.return_code);
		setparms->data.mode = SET_PROMISC_MODE_OFF;
	}
	card->info.promisc_mode = setparms->data.mode;
	return 0;
}
/*
 * Set promiscuous mode (on or off) (SET_PROMISC_MODE command)
 */
static void
qeth_setadp_promisc_mode(struct qeth_card *card)
{
	enum qeth_ipa_promisc_modes mode;
	struct net_device *dev = card->dev;
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace, 4, "setprom");

	if (((dev->flags & IFF_PROMISC) &&
	     (card->info.promisc_mode == SET_PROMISC_MODE_ON)) ||
	    (!(dev->flags & IFF_PROMISC) &&
	     (card->info.promisc_mode == SET_PROMISC_MODE_OFF)))
		return;
	mode = SET_PROMISC_MODE_OFF;
	if (dev->flags & IFF_PROMISC)
		mode = SET_PROMISC_MODE_ON;
	QETH_DBF_TEXT_(trace, 4, "mode:%x", mode);

	iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_PROMISC_MODE,
			sizeof(struct qeth_ipacmd_setadpparms));
	cmd = (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
	cmd->data.setadapterparms.data.mode = mode;
	qeth_send_ipa_cmd(card, iob, qeth_setadp_promisc_mode_cb, NULL);
}

/**
 * set multicast address on card
 */
static void
qeth_set_multicast_list(struct net_device *dev)
{
	struct qeth_card *card = (struct qeth_card *) dev->priv;

	if (card->info.type == QETH_CARD_TYPE_OSN)
		return ;

	QETH_DBF_TEXT(trace, 3, "setmulti");
	qeth_delete_mc_addresses(card);
	if (card->options.layer2) {
		qeth_layer2_add_multicast(card);
		goto out;
	}
	qeth_add_multicast_ipv4(card);
#ifdef CONFIG_QETH_IPV6
	qeth_add_multicast_ipv6(card);
#endif
out:
	qeth_set_ip_addr_list(card);
	if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
		return;
	qeth_setadp_promisc_mode(card);
}

static int
qeth_neigh_setup(struct net_device *dev, struct neigh_parms *np)
{
	return 0;
}

static void
qeth_get_mac_for_ipm(__u32 ipm, char *mac, struct net_device *dev)
{
	if (dev->type == ARPHRD_IEEE802_TR)
		ip_tr_mc_map(ipm, mac);
	else
		ip_eth_mc_map(ipm, mac);
}

static struct qeth_ipaddr *
qeth_get_addr_buffer(enum qeth_prot_versions prot)
{
	struct qeth_ipaddr *addr;

	addr = kzalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC);
	if (addr == NULL) {
		PRINT_WARN("Not enough memory to add address\n");
		return NULL;
	}
	addr->type = QETH_IP_TYPE_NORMAL;
	addr->proto = prot;
	return addr;
}

int
qeth_osn_assist(struct net_device *dev,
		void *data,
		int data_len)
{
	struct qeth_cmd_buffer *iob;
	struct qeth_card *card;
	int rc;

	QETH_DBF_TEXT(trace, 2, "osnsdmc");
	if (!dev)
		return -ENODEV;
	card = (struct qeth_card *)dev->priv;
	if (!card)
		return -ENODEV;
	if ((card->state != CARD_STATE_UP) &&
	    (card->state != CARD_STATE_SOFTSETUP))
		return -ENODEV;
	iob = qeth_wait_for_buffer(&card->write);
	memcpy(iob->data+IPA_PDU_HEADER_SIZE, data, data_len);
	rc = qeth_osn_send_ipa_cmd(card, iob, data_len);
	return rc;
}

static struct net_device *
qeth_netdev_by_devno(unsigned char *read_dev_no)
{
	struct qeth_card *card;
	struct net_device *ndev;
	unsigned char *readno;
	__u16 temp_dev_no, card_dev_no;
	char *endp;
	unsigned long flags;

	ndev = NULL;
	memcpy(&temp_dev_no, read_dev_no, 2);
	read_lock_irqsave(&qeth_card_list.rwlock, flags);
	list_for_each_entry(card, &qeth_card_list.list, list) {
		readno = CARD_RDEV_ID(card);
		readno += (strlen(readno) - 4);
		card_dev_no = simple_strtoul(readno, &endp, 16);
		if (card_dev_no == temp_dev_no) {
			ndev = card->dev;
			break;
		}
	}
	read_unlock_irqrestore(&qeth_card_list.rwlock, flags);
	return ndev;
}

int
qeth_osn_register(unsigned char *read_dev_no,
		  struct net_device **dev,
		  int (*assist_cb)(struct net_device *, void *),
		  int (*data_cb)(struct sk_buff *))
{
	struct qeth_card * card;

	QETH_DBF_TEXT(trace, 2, "osnreg");
	*dev = qeth_netdev_by_devno(read_dev_no);
	if (*dev == NULL)
		return -ENODEV;
	card = (struct qeth_card *)(*dev)->priv;
	if (!card)
		return -ENODEV;
	if ((assist_cb == NULL) || (data_cb == NULL))
		return -EINVAL;
	card->osn_info.assist_cb = assist_cb;
	card->osn_info.data_cb = data_cb;
	return 0;
}

void
qeth_osn_deregister(struct net_device * dev)
{
	struct qeth_card *card;

	QETH_DBF_TEXT(trace, 2, "osndereg");
	if (!dev)
		return;
	card = (struct qeth_card *)dev->priv;
	if (!card)
		return;
	card->osn_info.assist_cb = NULL;
	card->osn_info.data_cb = NULL;
	return;
}

static void
qeth_delete_mc_addresses(struct qeth_card *card)
{
	struct qeth_ipaddr *iptodo;
	unsigned long flags;

	QETH_DBF_TEXT(trace,4,"delmc");
	iptodo = qeth_get_addr_buffer(QETH_PROT_IPV4);
	if (!iptodo) {
		QETH_DBF_TEXT(trace, 2, "dmcnomem");
		return;
	}
	iptodo->type = QETH_IP_TYPE_DEL_ALL_MC;
	spin_lock_irqsave(&card->ip_lock, flags);
	if (!__qeth_insert_ip_todo(card, iptodo, 0))
		kfree(iptodo);
	spin_unlock_irqrestore(&card->ip_lock, flags);
}

static void
qeth_add_mc(struct qeth_card *card, struct in_device *in4_dev)
{
	struct qeth_ipaddr *ipm;
	struct ip_mc_list *im4;
	char buf[MAX_ADDR_LEN];

	QETH_DBF_TEXT(trace,4,"addmc");
	for (im4 = in4_dev->mc_list; im4; im4 = im4->next) {
		qeth_get_mac_for_ipm(im4->multiaddr, buf, in4_dev->dev);
		ipm = qeth_get_addr_buffer(QETH_PROT_IPV4);
		if (!ipm)
			continue;
		ipm->u.a4.addr = im4->multiaddr;
		memcpy(ipm->mac,buf,OSA_ADDR_LEN);
		ipm->is_multicast = 1;
		if (!qeth_add_ip(card,ipm))
			kfree(ipm);
	}
}

static inline void
qeth_add_vlan_mc(struct qeth_card *card)
{
#ifdef CONFIG_QETH_VLAN
	struct in_device *in_dev;
	struct vlan_group *vg;
	int i;

	QETH_DBF_TEXT(trace,4,"addmcvl");
	if ( ((card->options.layer2 == 0) &&
	      (!qeth_is_supported(card,IPA_FULL_VLAN))) ||
	     (card->vlangrp == NULL) )
		return ;

	vg = card->vlangrp;
	for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
		struct net_device *netdev = vlan_group_get_device(vg, i);
		if (netdev == NULL ||
		    !(netdev->flags & IFF_UP))
			continue;
		in_dev = in_dev_get(netdev);
		if (!in_dev)
			continue;
		read_lock(&in_dev->mc_list_lock);
		qeth_add_mc(card,in_dev);
		read_unlock(&in_dev->mc_list_lock);
		in_dev_put(in_dev);
	}
#endif
}

static void
qeth_add_multicast_ipv4(struct qeth_card *card)
{
	struct in_device *in4_dev;

	QETH_DBF_TEXT(trace,4,"chkmcv4");
	in4_dev = in_dev_get(card->dev);
	if (in4_dev == NULL)
		return;
	read_lock(&in4_dev->mc_list_lock);
	qeth_add_mc(card, in4_dev);
	qeth_add_vlan_mc(card);
	read_unlock(&in4_dev->mc_list_lock);
	in_dev_put(in4_dev);
}

static void
qeth_layer2_add_multicast(struct qeth_card *card)
{
	struct qeth_ipaddr *ipm;
	struct dev_mc_list *dm;

	QETH_DBF_TEXT(trace,4,"L2addmc");
	for (dm = card->dev->mc_list; dm; dm = dm->next) {
		ipm = qeth_get_addr_buffer(QETH_PROT_IPV4);
		if (!ipm)
			continue;
		memcpy(ipm->mac,dm->dmi_addr,MAX_ADDR_LEN);
		ipm->is_multicast = 1;
		if (!qeth_add_ip(card, ipm))
			kfree(ipm);
	}
}

#ifdef CONFIG_QETH_IPV6
static void
qeth_add_mc6(struct qeth_card *card, struct inet6_dev *in6_dev)
{
	struct qeth_ipaddr *ipm;
	struct ifmcaddr6 *im6;
	char buf[MAX_ADDR_LEN];

	QETH_DBF_TEXT(trace,4,"addmc6");
	for (im6 = in6_dev->mc_list; im6 != NULL; im6 = im6->next) {
		ndisc_mc_map(&im6->mca_addr, buf, in6_dev->dev, 0);
		ipm = qeth_get_addr_buffer(QETH_PROT_IPV6);
		if (!ipm)
			continue;
		ipm->is_multicast = 1;
		memcpy(ipm->mac,buf,OSA_ADDR_LEN);
		memcpy(&ipm->u.a6.addr,&im6->mca_addr.s6_addr,
		       sizeof(struct in6_addr));
		if (!qeth_add_ip(card,ipm))
			kfree(ipm);
	}
}

static inline void
qeth_add_vlan_mc6(struct qeth_card *card)
{
#ifdef CONFIG_QETH_VLAN
	struct inet6_dev *in_dev;
	struct vlan_group *vg;
	int i;

	QETH_DBF_TEXT(trace,4,"admc6vl");
	if ( ((card->options.layer2 == 0) &&
	      (!qeth_is_supported(card,IPA_FULL_VLAN))) ||
	     (card->vlangrp == NULL))
		return ;

	vg = card->vlangrp;
	for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
		struct net_device *netdev = vlan_group_get_device(vg, i);
		if (netdev == NULL ||
		    !(netdev->flags & IFF_UP))
			continue;
		in_dev = in6_dev_get(netdev);
		if (!in_dev)
			continue;
		read_lock_bh(&in_dev->lock);
		qeth_add_mc6(card,in_dev);
		read_unlock_bh(&in_dev->lock);
		in6_dev_put(in_dev);
	}
#endif /* CONFIG_QETH_VLAN */
}

static void
qeth_add_multicast_ipv6(struct qeth_card *card)
{
	struct inet6_dev *in6_dev;

	QETH_DBF_TEXT(trace,4,"chkmcv6");
	if (!qeth_is_supported(card, IPA_IPV6))
		return ;
	in6_dev = in6_dev_get(card->dev);
	if (in6_dev == NULL)
		return;
	read_lock_bh(&in6_dev->lock);
	qeth_add_mc6(card, in6_dev);
	qeth_add_vlan_mc6(card);
	read_unlock_bh(&in6_dev->lock);
	in6_dev_put(in6_dev);
}
#endif /* CONFIG_QETH_IPV6 */

static int
qeth_layer2_send_setdelmac(struct qeth_card *card, __u8 *mac,
			   enum qeth_ipa_cmds ipacmd,
			   int (*reply_cb) (struct qeth_card *,
					    struct qeth_reply*,
					    unsigned long))
{
	struct qeth_ipa_cmd *cmd;
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(trace, 2, "L2sdmac");
	iob = qeth_get_ipacmd_buffer(card, ipacmd, QETH_PROT_IPV4);
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
        cmd->data.setdelmac.mac_length = OSA_ADDR_LEN;
        memcpy(&cmd->data.setdelmac.mac, mac, OSA_ADDR_LEN);
	return qeth_send_ipa_cmd(card, iob, reply_cb, NULL);
}

static int
qeth_layer2_send_setgroupmac_cb(struct qeth_card *card,
				struct qeth_reply *reply,
				unsigned long data)
{
	struct qeth_ipa_cmd *cmd;
	__u8 *mac;

	QETH_DBF_TEXT(trace, 2, "L2Sgmacb");
	cmd = (struct qeth_ipa_cmd *) data;
	mac = &cmd->data.setdelmac.mac[0];
	/* MAC already registered, needed in couple/uncouple case */
	if (cmd->hdr.return_code == 0x2005) {
		PRINT_WARN("Group MAC %02x:%02x:%02x:%02x:%02x:%02x " \
			  "already existing on %s \n",
			  mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
			  QETH_CARD_IFNAME(card));
		cmd->hdr.return_code = 0;
	}
	if (cmd->hdr.return_code)
		PRINT_ERR("Could not set group MAC " \
			  "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n",
			  mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
			  QETH_CARD_IFNAME(card),cmd->hdr.return_code);
	return 0;
}

static int
qeth_layer2_send_setgroupmac(struct qeth_card *card, __u8 *mac)
{
	QETH_DBF_TEXT(trace, 2, "L2Sgmac");
	return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_SETGMAC,
					  qeth_layer2_send_setgroupmac_cb);
}

static int
qeth_layer2_send_delgroupmac_cb(struct qeth_card *card,
				struct qeth_reply *reply,
				unsigned long data)
{
	struct qeth_ipa_cmd *cmd;
	__u8 *mac;

	QETH_DBF_TEXT(trace, 2, "L2Dgmacb");
	cmd = (struct qeth_ipa_cmd *) data;
	mac = &cmd->data.setdelmac.mac[0];
	if (cmd->hdr.return_code)
		PRINT_ERR("Could not delete group MAC " \
			  "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n",
			  mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
			  QETH_CARD_IFNAME(card), cmd->hdr.return_code);
	return 0;
}

static int
qeth_layer2_send_delgroupmac(struct qeth_card *card, __u8 *mac)
{
	QETH_DBF_TEXT(trace, 2, "L2Dgmac");
	return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELGMAC,
					  qeth_layer2_send_delgroupmac_cb);
}

static int
qeth_layer2_send_setmac_cb(struct qeth_card *card,
			   struct qeth_reply *reply,
			   unsigned long data)
{
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace, 2, "L2Smaccb");
	cmd = (struct qeth_ipa_cmd *) data;
	if (cmd->hdr.return_code) {
		QETH_DBF_TEXT_(trace, 2, "L2er%x", cmd->hdr.return_code);
		card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
		cmd->hdr.return_code = -EIO;
	} else {
		card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
		memcpy(card->dev->dev_addr,cmd->data.setdelmac.mac,
		       OSA_ADDR_LEN);
		PRINT_INFO("MAC address %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
			   "successfully registered on device %s\n",
			   card->dev->dev_addr[0], card->dev->dev_addr[1],
			   card->dev->dev_addr[2], card->dev->dev_addr[3],
			   card->dev->dev_addr[4], card->dev->dev_addr[5],
			   card->dev->name);
	}
	return 0;
}

static int
qeth_layer2_send_setmac(struct qeth_card *card, __u8 *mac)
{
	QETH_DBF_TEXT(trace, 2, "L2Setmac");
	return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_SETVMAC,
					  qeth_layer2_send_setmac_cb);
}

static int
qeth_layer2_send_delmac_cb(struct qeth_card *card,
			   struct qeth_reply *reply,
			   unsigned long data)
{
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace, 2, "L2Dmaccb");
	cmd = (struct qeth_ipa_cmd *) data;
	if (cmd->hdr.return_code) {
		QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
		cmd->hdr.return_code = -EIO;
		return 0;
	}
	card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;

	return 0;
}
static int
qeth_layer2_send_delmac(struct qeth_card *card, __u8 *mac)
{
	QETH_DBF_TEXT(trace, 2, "L2Delmac");
	if (!(card->info.mac_bits & QETH_LAYER2_MAC_REGISTERED))
		return 0;
	return qeth_layer2_send_setdelmac(card, mac, IPA_CMD_DELVMAC,
					  qeth_layer2_send_delmac_cb);
}

static int
qeth_layer2_set_mac_address(struct net_device *dev, void *p)
{
	struct sockaddr *addr = p;
	struct qeth_card *card;
	int rc = 0;

	QETH_DBF_TEXT(trace, 3, "setmac");

	if (qeth_verify_dev(dev) != QETH_REAL_CARD) {
		QETH_DBF_TEXT(trace, 3, "setmcINV");
		return -EOPNOTSUPP;
	}
	card = (struct qeth_card *) dev->priv;

	if (!card->options.layer2) {
		PRINT_WARN("Setting MAC address on %s is not supported "
			   "in Layer 3 mode.\n", dev->name);
		QETH_DBF_TEXT(trace, 3, "setmcLY3");
		return -EOPNOTSUPP;
	}
	if (card->info.type == QETH_CARD_TYPE_OSN) {
		PRINT_WARN("Setting MAC address on %s is not supported.\n",
			   dev->name);
		QETH_DBF_TEXT(trace, 3, "setmcOSN");
		return -EOPNOTSUPP;
	}
	QETH_DBF_TEXT_(trace, 3, "%s", CARD_BUS_ID(card));
	QETH_DBF_HEX(trace, 3, addr->sa_data, OSA_ADDR_LEN);
	rc = qeth_layer2_send_delmac(card, &card->dev->dev_addr[0]);
	if (!rc)
		rc = qeth_layer2_send_setmac(card, addr->sa_data);
	return rc;
}

static void
qeth_fill_ipacmd_header(struct qeth_card *card, struct qeth_ipa_cmd *cmd,
			__u8 command, enum qeth_prot_versions prot)
{
	memset(cmd, 0, sizeof (struct qeth_ipa_cmd));
	cmd->hdr.command = command;
	cmd->hdr.initiator = IPA_CMD_INITIATOR_HOST;
	cmd->hdr.seqno = card->seqno.ipa;
	cmd->hdr.adapter_type = qeth_get_ipa_adp_type(card->info.link_type);
	cmd->hdr.rel_adapter_no = (__u8) card->info.portno;
	if (card->options.layer2)
		cmd->hdr.prim_version_no = 2;
	else
		cmd->hdr.prim_version_no = 1;
	cmd->hdr.param_count = 1;
	cmd->hdr.prot_version = prot;
	cmd->hdr.ipa_supported = 0;
	cmd->hdr.ipa_enabled = 0;
}

static struct qeth_cmd_buffer *
qeth_get_ipacmd_buffer(struct qeth_card *card, enum qeth_ipa_cmds ipacmd,
		       enum qeth_prot_versions prot)
{
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

	iob = qeth_wait_for_buffer(&card->write);
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	qeth_fill_ipacmd_header(card, cmd, ipacmd, prot);

	return iob;
}

static int
qeth_send_setdelmc(struct qeth_card *card, struct qeth_ipaddr *addr, int ipacmd)
{
	int rc;
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace,4,"setdelmc");

	iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	memcpy(&cmd->data.setdelipm.mac,addr->mac, OSA_ADDR_LEN);
	if (addr->proto == QETH_PROT_IPV6)
		memcpy(cmd->data.setdelipm.ip6, &addr->u.a6.addr,
		       sizeof(struct in6_addr));
	else
		memcpy(&cmd->data.setdelipm.ip4, &addr->u.a4.addr,4);

	rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);

	return rc;
}
static void
qeth_fill_netmask(u8 *netmask, unsigned int len)
{
	int i,j;
	for (i=0;i<16;i++) {
		j=(len)-(i*8);
		if (j >= 8)
			netmask[i] = 0xff;
		else if (j > 0)
			netmask[i] = (u8)(0xFF00>>j);
		else
			netmask[i] = 0;
	}
}

static int
qeth_send_setdelip(struct qeth_card *card, struct qeth_ipaddr *addr,
		   int ipacmd, unsigned int flags)
{
	int rc;
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;
	__u8 netmask[16];

	QETH_DBF_TEXT(trace,4,"setdelip");
	QETH_DBF_TEXT_(trace,4,"flags%02X", flags);

	iob = qeth_get_ipacmd_buffer(card, ipacmd, addr->proto);
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	if (addr->proto == QETH_PROT_IPV6) {
		memcpy(cmd->data.setdelip6.ip_addr, &addr->u.a6.addr,
		       sizeof(struct in6_addr));
		qeth_fill_netmask(netmask,addr->u.a6.pfxlen);
		memcpy(cmd->data.setdelip6.mask, netmask,
		       sizeof(struct in6_addr));
		cmd->data.setdelip6.flags = flags;
	} else {
		memcpy(cmd->data.setdelip4.ip_addr, &addr->u.a4.addr, 4);
		memcpy(cmd->data.setdelip4.mask, &addr->u.a4.mask, 4);
		cmd->data.setdelip4.flags = flags;
	}

	rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);

	return rc;
}

static int
qeth_layer2_register_addr_entry(struct qeth_card *card,
				struct qeth_ipaddr *addr)
{
	if (!addr->is_multicast)
		return 0;
	QETH_DBF_TEXT(trace, 2, "setgmac");
	QETH_DBF_HEX(trace,3,&addr->mac[0],OSA_ADDR_LEN);
	return qeth_layer2_send_setgroupmac(card, &addr->mac[0]);
}

static int
qeth_layer2_deregister_addr_entry(struct qeth_card *card,
				  struct qeth_ipaddr *addr)
{
	if (!addr->is_multicast)
		return 0;
	QETH_DBF_TEXT(trace, 2, "delgmac");
	QETH_DBF_HEX(trace,3,&addr->mac[0],OSA_ADDR_LEN);
	return qeth_layer2_send_delgroupmac(card, &addr->mac[0]);
}

static int
qeth_layer3_register_addr_entry(struct qeth_card *card,
				struct qeth_ipaddr *addr)
{
	char buf[50];
	int rc;
	int cnt = 3;

	if (addr->proto == QETH_PROT_IPV4) {
		QETH_DBF_TEXT(trace, 2,"setaddr4");
		QETH_DBF_HEX(trace, 3, &addr->u.a4.addr, sizeof(int));
	} else if (addr->proto == QETH_PROT_IPV6) {
		QETH_DBF_TEXT(trace, 2, "setaddr6");
		QETH_DBF_HEX(trace,3,&addr->u.a6.addr,8);
		QETH_DBF_HEX(trace,3,((char *)&addr->u.a6.addr)+8,8);
	} else {
		QETH_DBF_TEXT(trace, 2, "setaddr?");
		QETH_DBF_HEX(trace, 3, addr, sizeof(struct qeth_ipaddr));
	}
	do {
		if (addr->is_multicast)
			rc =  qeth_send_setdelmc(card, addr, IPA_CMD_SETIPM);
		else
			rc = qeth_send_setdelip(card, addr, IPA_CMD_SETIP,
					addr->set_flags);
		if (rc)
			QETH_DBF_TEXT(trace, 2, "failed");
	} while ((--cnt > 0) && rc);
	if (rc){
		QETH_DBF_TEXT(trace, 2, "FAILED");
		qeth_ipaddr_to_string(addr->proto, (u8 *)&addr->u, buf);
		PRINT_WARN("Could not register IP address %s (rc=0x%x/%d)\n",
			   buf, rc, rc);
	}
	return rc;
}

static int
qeth_layer3_deregister_addr_entry(struct qeth_card *card,
				  struct qeth_ipaddr *addr)
{
	//char buf[50];
	int rc;

	if (addr->proto == QETH_PROT_IPV4) {
		QETH_DBF_TEXT(trace, 2,"deladdr4");
		QETH_DBF_HEX(trace, 3, &addr->u.a4.addr, sizeof(int));
	} else if (addr->proto == QETH_PROT_IPV6) {
		QETH_DBF_TEXT(trace, 2, "deladdr6");
		QETH_DBF_HEX(trace,3,&addr->u.a6.addr,8);
		QETH_DBF_HEX(trace,3,((char *)&addr->u.a6.addr)+8,8);
	} else {
		QETH_DBF_TEXT(trace, 2, "deladdr?");
		QETH_DBF_HEX(trace, 3, addr, sizeof(struct qeth_ipaddr));
	}
	if (addr->is_multicast)
		rc = qeth_send_setdelmc(card, addr, IPA_CMD_DELIPM);
	else
		rc = qeth_send_setdelip(card, addr, IPA_CMD_DELIP,
					addr->del_flags);
	if (rc) {
		QETH_DBF_TEXT(trace, 2, "failed");
		/* TODO: re-activate this warning as soon as we have a
		 * clean mirco code
		qeth_ipaddr_to_string(addr->proto, (u8 *)&addr->u, buf);
		PRINT_WARN("Could not deregister IP address %s (rc=%x)\n",
			   buf, rc);
		*/
	}
	return rc;
}

static int
qeth_register_addr_entry(struct qeth_card *card, struct qeth_ipaddr *addr)
{
	if (card->options.layer2)
		return qeth_layer2_register_addr_entry(card, addr);

	return qeth_layer3_register_addr_entry(card, addr);
}

static int
qeth_deregister_addr_entry(struct qeth_card *card, struct qeth_ipaddr *addr)
{
	if (card->options.layer2)
		return qeth_layer2_deregister_addr_entry(card, addr);

	return qeth_layer3_deregister_addr_entry(card, addr);
}

static u32
qeth_ethtool_get_tx_csum(struct net_device *dev)
{
	/* We may need to say that we support tx csum offload if
	 * we do EDDP or TSO. There are discussions going on to
	 * enforce rules in the stack and in ethtool that make
	 * SG and TSO depend on HW_CSUM. At the moment there are
	 * no such rules....
	 * If we say yes here, we have to checksum outbound packets
	 * any time. */
	return 0;
}

static int
qeth_ethtool_set_tx_csum(struct net_device *dev, u32 data)
{
	return -EINVAL;
}

static u32
qeth_ethtool_get_rx_csum(struct net_device *dev)
{
	struct qeth_card *card = (struct qeth_card *)dev->priv;

	return (card->options.checksum_type == HW_CHECKSUMMING);
}

static int
qeth_ethtool_set_rx_csum(struct net_device *dev, u32 data)
{
	struct qeth_card *card = (struct qeth_card *)dev->priv;

	if ((card->state != CARD_STATE_DOWN) &&
	    (card->state != CARD_STATE_RECOVER))
		return -EPERM;
	if (data)
		card->options.checksum_type = HW_CHECKSUMMING;
	else
		card->options.checksum_type = SW_CHECKSUMMING;
	return 0;
}

static u32
qeth_ethtool_get_sg(struct net_device *dev)
{
	struct qeth_card *card = (struct qeth_card *)dev->priv;

	return ((card->options.large_send != QETH_LARGE_SEND_NO) &&
		(dev->features & NETIF_F_SG));
}

static int
qeth_ethtool_set_sg(struct net_device *dev, u32 data)
{
	struct qeth_card *card = (struct qeth_card *)dev->priv;

	if (data) {
		if (card->options.large_send != QETH_LARGE_SEND_NO)
			dev->features |= NETIF_F_SG;
		else {
			dev->features &= ~NETIF_F_SG;
			return -EINVAL;
		}
	} else
		dev->features &= ~NETIF_F_SG;
	return 0;
}

static u32
qeth_ethtool_get_tso(struct net_device *dev)
{
	struct qeth_card *card = (struct qeth_card *)dev->priv;

	return ((card->options.large_send != QETH_LARGE_SEND_NO) &&
		(dev->features & NETIF_F_TSO));
}

static int
qeth_ethtool_set_tso(struct net_device *dev, u32 data)
{
	struct qeth_card *card = (struct qeth_card *)dev->priv;

	if (data) {
		if (card->options.large_send != QETH_LARGE_SEND_NO)
			dev->features |= NETIF_F_TSO;
		else {
			dev->features &= ~NETIF_F_TSO;
			return -EINVAL;
		}
	} else
		dev->features &= ~NETIF_F_TSO;
	return 0;
}

static struct ethtool_ops qeth_ethtool_ops = {
	.get_tx_csum = qeth_ethtool_get_tx_csum,
	.set_tx_csum = qeth_ethtool_set_tx_csum,
	.get_rx_csum = qeth_ethtool_get_rx_csum,
	.set_rx_csum = qeth_ethtool_set_rx_csum,
	.get_sg      = qeth_ethtool_get_sg,
	.set_sg      = qeth_ethtool_set_sg,
	.get_tso     = qeth_ethtool_get_tso,
	.set_tso     = qeth_ethtool_set_tso,
};

static int
qeth_hard_header_parse(struct sk_buff *skb, unsigned char *haddr)
{
	struct qeth_card *card;
	struct ethhdr *eth;

	card = qeth_get_card_from_dev(skb->dev);
	if (card->options.layer2)
		goto haveheader;
#ifdef CONFIG_QETH_IPV6
	/* cause of the manipulated arp constructor and the ARP
	   flag for OSAE devices we have some nasty exceptions */
	if (card->info.type == QETH_CARD_TYPE_OSAE) {
		if (!card->options.fake_ll) {
			if ((skb->pkt_type==PACKET_OUTGOING) &&
			    (skb->protocol==ETH_P_IPV6))
				goto haveheader;
			else
				return 0;
		} else {
			if ((skb->pkt_type==PACKET_OUTGOING) &&
			    (skb->protocol==ETH_P_IP))
				return 0;
			else
				goto haveheader;
		}
	}
#endif
	if (!card->options.fake_ll)
		return 0;
haveheader:
	eth = eth_hdr(skb);
	memcpy(haddr, eth->h_source, ETH_ALEN);
	return ETH_ALEN;
}

static int
qeth_netdev_init(struct net_device *dev)
{
	struct qeth_card *card;

	card = (struct qeth_card *) dev->priv;

	QETH_DBF_TEXT(trace,3,"initdev");

	dev->tx_timeout = &qeth_tx_timeout;
	dev->watchdog_timeo = QETH_TX_TIMEOUT;
	dev->open = qeth_open;
	dev->stop = qeth_stop;
	dev->hard_start_xmit = qeth_hard_start_xmit;
	dev->do_ioctl = qeth_do_ioctl;
	dev->get_stats = qeth_get_stats;
	dev->change_mtu = qeth_change_mtu;
	dev->neigh_setup = qeth_neigh_setup;
	dev->set_multicast_list = qeth_set_multicast_list;
#ifdef CONFIG_QETH_VLAN
	dev->vlan_rx_register = qeth_vlan_rx_register;
	dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
	dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid;
#endif
	if (qeth_get_netdev_flags(card) & IFF_NOARP) {
		dev->rebuild_header = NULL;
		dev->hard_header = NULL;
		dev->header_cache_update = NULL;
		dev->hard_header_cache = NULL;
	}
#ifdef CONFIG_QETH_IPV6
	/*IPv6 address autoconfiguration stuff*/
	if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
		card->dev->dev_id = card->info.unique_id & 0xffff;
#endif
	if (card->options.fake_ll &&
		(qeth_get_netdev_flags(card) & IFF_NOARP))
			dev->hard_header = qeth_fake_header;
	if (dev->type == ARPHRD_IEEE802_TR)
		dev->hard_header_parse = NULL;
	else
		dev->hard_header_parse = qeth_hard_header_parse;
	dev->set_mac_address = qeth_layer2_set_mac_address;
	dev->flags |= qeth_get_netdev_flags(card);
	if ((card->options.fake_broadcast) ||
	    (card->info.broadcast_capable))
		dev->flags |= IFF_BROADCAST;
	dev->hard_header_len =
			qeth_get_hlen(card->info.link_type) + card->options.add_hhlen;
	dev->addr_len = OSA_ADDR_LEN;
	dev->mtu = card->info.initial_mtu;
	if (card->info.type != QETH_CARD_TYPE_OSN)
		SET_ETHTOOL_OPS(dev, &qeth_ethtool_ops);
	SET_MODULE_OWNER(dev);
	return 0;
}

static void
qeth_init_func_level(struct qeth_card *card)
{
	if (card->ipato.enabled) {
		if (card->info.type == QETH_CARD_TYPE_IQD)
				card->info.func_level =
					QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT;
		else
				card->info.func_level =
					QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT;
	} else {
		if (card->info.type == QETH_CARD_TYPE_IQD)
		/*FIXME:why do we have same values for  dis and ena for osae??? */
			card->info.func_level =
				QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT;
		else
			card->info.func_level =
				QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT;
	}
}

/**
 * hardsetup card, initialize MPC and QDIO stuff
 */
static int
qeth_hardsetup_card(struct qeth_card *card)
{
	int retries = 3;
	int rc;

	QETH_DBF_TEXT(setup, 2, "hrdsetup");

	atomic_set(&card->force_alloc_skb, 0);
retry:
	if (retries < 3){
		PRINT_WARN("Retrying to do IDX activates.\n");
		ccw_device_set_offline(CARD_DDEV(card));
		ccw_device_set_offline(CARD_WDEV(card));
		ccw_device_set_offline(CARD_RDEV(card));
		ccw_device_set_online(CARD_RDEV(card));
		ccw_device_set_online(CARD_WDEV(card));
		ccw_device_set_online(CARD_DDEV(card));
	}
	rc = qeth_qdio_clear_card(card,card->info.type!=QETH_CARD_TYPE_IQD);
	if (rc == -ERESTARTSYS) {
		QETH_DBF_TEXT(setup, 2, "break1");
		return rc;
	} else if (rc) {
		QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
		if (--retries < 0)
			goto out;
		else
			goto retry;
	}
	if ((rc = qeth_get_unitaddr(card))){
		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
		return rc;
	}
	qeth_init_tokens(card);
	qeth_init_func_level(card);
	rc = qeth_idx_activate_channel(&card->read, qeth_idx_read_cb);
	if (rc == -ERESTARTSYS) {
		QETH_DBF_TEXT(setup, 2, "break2");
		return rc;
	} else if (rc) {
		QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
		if (--retries < 0)
			goto out;
		else
			goto retry;
	}
	rc = qeth_idx_activate_channel(&card->write, qeth_idx_write_cb);
	if (rc == -ERESTARTSYS) {
		QETH_DBF_TEXT(setup, 2, "break3");
		return rc;
	} else if (rc) {
		QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
		if (--retries < 0)
			goto out;
		else
			goto retry;
	}
	if ((rc = qeth_mpc_initialize(card))){
		QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
		goto out;
	}
	/*network device will be recovered*/
	if (card->dev) {
		card->dev->hard_header = card->orig_hard_header;
		if (card->options.fake_ll &&
		    (qeth_get_netdev_flags(card) & IFF_NOARP))
			card->dev->hard_header = qeth_fake_header;
		return 0;
	}
	/* at first set_online allocate netdev */
	card->dev = qeth_get_netdevice(card->info.type,
				       card->info.link_type);
	if (!card->dev){
		qeth_qdio_clear_card(card, card->info.type !=
				     QETH_CARD_TYPE_IQD);
		rc = -ENODEV;
		QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
		goto out;
	}
	card->dev->priv = card;
	card->orig_hard_header = card->dev->hard_header;
	card->dev->type = qeth_get_arphdr_type(card->info.type,
					       card->info.link_type);
	card->dev->init = qeth_netdev_init;
	return 0;
out:
	PRINT_ERR("Initialization in hardsetup failed! rc=%d\n", rc);
	return rc;
}

static int
qeth_default_setassparms_cb(struct qeth_card *card, struct qeth_reply *reply,
			    unsigned long data)
{
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace,4,"defadpcb");

	cmd = (struct qeth_ipa_cmd *) data;
	if (cmd->hdr.return_code == 0){
		cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code;
		if (cmd->hdr.prot_version == QETH_PROT_IPV4)
			card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
#ifdef CONFIG_QETH_IPV6
		if (cmd->hdr.prot_version == QETH_PROT_IPV6)
			card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
#endif
	}
	if (cmd->data.setassparms.hdr.assist_no == IPA_INBOUND_CHECKSUM &&
	    cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) {
		card->info.csum_mask = cmd->data.setassparms.data.flags_32bit;
		QETH_DBF_TEXT_(trace, 3, "csum:%d", card->info.csum_mask);
	}
	return 0;
}

static int
qeth_default_setadapterparms_cb(struct qeth_card *card,
				struct qeth_reply *reply,
				unsigned long data)
{
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace,4,"defadpcb");

	cmd = (struct qeth_ipa_cmd *) data;
	if (cmd->hdr.return_code == 0)
		cmd->hdr.return_code = cmd->data.setadapterparms.hdr.return_code;
	return 0;
}



static int
qeth_query_setadapterparms_cb(struct qeth_card *card, struct qeth_reply *reply,
			      unsigned long data)
{
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace,3,"quyadpcb");

	cmd = (struct qeth_ipa_cmd *) data;
	if (cmd->data.setadapterparms.data.query_cmds_supp.lan_type & 0x7f)
		card->info.link_type =
		      cmd->data.setadapterparms.data.query_cmds_supp.lan_type;
	card->options.adp.supported_funcs =
		cmd->data.setadapterparms.data.query_cmds_supp.supported_cmds;
	return qeth_default_setadapterparms_cb(card, reply, (unsigned long)cmd);
}

static int
qeth_query_setadapterparms(struct qeth_card *card)
{
	int rc;
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(trace,3,"queryadp");
	iob = qeth_get_adapter_cmd(card, IPA_SETADP_QUERY_COMMANDS_SUPPORTED,
				   sizeof(struct qeth_ipacmd_setadpparms));
	rc = qeth_send_ipa_cmd(card, iob, qeth_query_setadapterparms_cb, NULL);
	return rc;
}

static int
qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
				   struct qeth_reply *reply,
				   unsigned long data)
{
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace,4,"chgmaccb");

	cmd = (struct qeth_ipa_cmd *) data;
	if (!card->options.layer2 ||
	    !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
		memcpy(card->dev->dev_addr,
		       &cmd->data.setadapterparms.data.change_addr.addr,
		       OSA_ADDR_LEN);
		card->info.mac_bits |= QETH_LAYER2_MAC_READ;
	}
	qeth_default_setadapterparms_cb(card, reply, (unsigned long) cmd);
	return 0;
}

static int
qeth_setadpparms_change_macaddr(struct qeth_card *card)
{
	int rc;
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace,4,"chgmac");

	iob = qeth_get_adapter_cmd(card,IPA_SETADP_ALTER_MAC_ADDRESS,
				   sizeof(struct qeth_ipacmd_setadpparms));
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	cmd->data.setadapterparms.data.change_addr.cmd = CHANGE_ADDR_READ_MAC;
	cmd->data.setadapterparms.data.change_addr.addr_size = OSA_ADDR_LEN;
	memcpy(&cmd->data.setadapterparms.data.change_addr.addr,
	       card->dev->dev_addr, OSA_ADDR_LEN);
	rc = qeth_send_ipa_cmd(card, iob, qeth_setadpparms_change_macaddr_cb,
			       NULL);
	return rc;
}

static int
qeth_send_setadp_mode(struct qeth_card *card, __u32 command, __u32 mode)
{
	int rc;
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace,4,"adpmode");

	iob = qeth_get_adapter_cmd(card, command,
				   sizeof(struct qeth_ipacmd_setadpparms));
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	cmd->data.setadapterparms.data.mode = mode;
	rc = qeth_send_ipa_cmd(card, iob, qeth_default_setadapterparms_cb,
			       NULL);
	return rc;
}

static int
qeth_setadapter_hstr(struct qeth_card *card)
{
	int rc;

	QETH_DBF_TEXT(trace,4,"adphstr");

	if (qeth_adp_supported(card,IPA_SETADP_SET_BROADCAST_MODE)) {
		rc = qeth_send_setadp_mode(card, IPA_SETADP_SET_BROADCAST_MODE,
					   card->options.broadcast_mode);
		if (rc)
			PRINT_WARN("couldn't set broadcast mode on "
				   "device %s: x%x\n",
				   CARD_BUS_ID(card), rc);
		rc = qeth_send_setadp_mode(card, IPA_SETADP_ALTER_MAC_ADDRESS,
					   card->options.macaddr_mode);
		if (rc)
			PRINT_WARN("couldn't set macaddr mode on "
				   "device %s: x%x\n", CARD_BUS_ID(card), rc);
		return rc;
	}
	if (card->options.broadcast_mode == QETH_TR_BROADCAST_LOCAL)
		PRINT_WARN("set adapter parameters not available "
			   "to set broadcast mode, using ALLRINGS "
			   "on device %s:\n", CARD_BUS_ID(card));
	if (card->options.macaddr_mode == QETH_TR_MACADDR_CANONICAL)
		PRINT_WARN("set adapter parameters not available "
			   "to set macaddr mode, using NONCANONICAL "
			   "on device %s:\n", CARD_BUS_ID(card));
	return 0;
}

static int
qeth_setadapter_parms(struct qeth_card *card)
{
	int rc;

	QETH_DBF_TEXT(setup, 2, "setadprm");

	if (!qeth_is_supported(card, IPA_SETADAPTERPARMS)){
		PRINT_WARN("set adapter parameters not supported "
			   "on device %s.\n",
			   CARD_BUS_ID(card));
		QETH_DBF_TEXT(setup, 2, " notsupp");
		return 0;
	}
	rc = qeth_query_setadapterparms(card);
	if (rc) {
		PRINT_WARN("couldn't set adapter parameters on device %s: "
			   "x%x\n", CARD_BUS_ID(card), rc);
		return rc;
	}
	if (qeth_adp_supported(card,IPA_SETADP_ALTER_MAC_ADDRESS)) {
		rc = qeth_setadpparms_change_macaddr(card);
		if (rc)
			PRINT_WARN("couldn't get MAC address on "
				   "device %s: x%x\n",
				   CARD_BUS_ID(card), rc);
	}

	if ((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
	    (card->info.link_type == QETH_LINK_TYPE_LANE_TR))
		rc = qeth_setadapter_hstr(card);

	return rc;
}

static int
qeth_layer2_initialize(struct qeth_card *card)
{
        int rc = 0;


        QETH_DBF_TEXT(setup, 2, "doL2init");
        QETH_DBF_TEXT_(setup, 2, "doL2%s", CARD_BUS_ID(card));

	rc = qeth_query_setadapterparms(card);
	if (rc) {
		PRINT_WARN("could not query adapter parameters on device %s: "
			   "x%x\n", CARD_BUS_ID(card), rc);
	}

	rc = qeth_setadpparms_change_macaddr(card);
	if (rc) {
		PRINT_WARN("couldn't get MAC address on "
			   "device %s: x%x\n",
			   CARD_BUS_ID(card), rc);
		QETH_DBF_TEXT_(setup, 2,"1err%d",rc);
		return rc;
        }
	QETH_DBF_HEX(setup,2, card->dev->dev_addr, OSA_ADDR_LEN);

	rc = qeth_layer2_send_setmac(card, &card->dev->dev_addr[0]);
        if (rc)
		QETH_DBF_TEXT_(setup, 2,"2err%d",rc);
        return 0;
}


static int
qeth_send_startstoplan(struct qeth_card *card, enum qeth_ipa_cmds ipacmd,
		       enum qeth_prot_versions prot)
{
	int rc;
	struct qeth_cmd_buffer *iob;

	iob = qeth_get_ipacmd_buffer(card,ipacmd,prot);
	rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);

	return rc;
}

static int
qeth_send_startlan(struct qeth_card *card, enum qeth_prot_versions prot)
{
	int rc;

	QETH_DBF_TEXT_(setup, 2, "strtlan%i", prot);

	rc = qeth_send_startstoplan(card, IPA_CMD_STARTLAN, prot);
	return rc;
}

static int
qeth_send_stoplan(struct qeth_card *card)
{
	int rc = 0;

	/*
	 * TODO: according to the IPA format document page 14,
	 * TCP/IP (we!) never issue a STOPLAN
	 * is this right ?!?
	 */
	QETH_DBF_TEXT(trace, 2, "stoplan");

	rc = qeth_send_startstoplan(card, IPA_CMD_STOPLAN, QETH_PROT_IPV4);
	return rc;
}

static int
qeth_query_ipassists_cb(struct qeth_card *card, struct qeth_reply *reply,
			unsigned long data)
{
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(setup, 2, "qipasscb");

	cmd = (struct qeth_ipa_cmd *) data;
	if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
		card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
		card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
		/* Disable IPV6 support hard coded for Hipersockets */
		if(card->info.type == QETH_CARD_TYPE_IQD)
			card->options.ipa4.supported_funcs &= ~IPA_IPV6;
	} else {
#ifdef CONFIG_QETH_IPV6
		card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
		card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
#endif
	}
	QETH_DBF_TEXT(setup, 2, "suppenbl");
	QETH_DBF_TEXT_(setup, 2, "%x",cmd->hdr.ipa_supported);
	QETH_DBF_TEXT_(setup, 2, "%x",cmd->hdr.ipa_enabled);
	return 0;
}

static int
qeth_query_ipassists(struct qeth_card *card, enum qeth_prot_versions prot)
{
	int rc;
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT_(setup, 2, "qipassi%i", prot);
	if (card->options.layer2) {
		QETH_DBF_TEXT(setup, 2, "noprmly2");
		return -EPERM;
	}

	iob = qeth_get_ipacmd_buffer(card,IPA_CMD_QIPASSIST,prot);
	rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL);
	return rc;
}

static struct qeth_cmd_buffer *
qeth_get_setassparms_cmd(struct qeth_card *card, enum qeth_ipa_funcs ipa_func,
			 __u16 cmd_code, __u16 len,
			 enum qeth_prot_versions prot)
{
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace,4,"getasscm");
	iob = qeth_get_ipacmd_buffer(card,IPA_CMD_SETASSPARMS,prot);

	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	cmd->data.setassparms.hdr.assist_no = ipa_func;
	cmd->data.setassparms.hdr.length = 8 + len;
	cmd->data.setassparms.hdr.command_code = cmd_code;
	cmd->data.setassparms.hdr.return_code = 0;
	cmd->data.setassparms.hdr.seq_no = 0;

	return iob;
}

static int
qeth_send_setassparms(struct qeth_card *card, struct qeth_cmd_buffer *iob,
		      __u16 len, long data,
		      int (*reply_cb)
		      (struct qeth_card *,struct qeth_reply *,unsigned long),
		      void *reply_param)
{
	int rc;
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace,4,"sendassp");

	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	if (len <= sizeof(__u32))
		cmd->data.setassparms.data.flags_32bit = (__u32) data;
	else   /* (len > sizeof(__u32)) */
		memcpy(&cmd->data.setassparms.data, (void *) data, len);

	rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param);
	return rc;
}

#ifdef CONFIG_QETH_IPV6
static int
qeth_send_simple_setassparms_ipv6(struct qeth_card *card,
				  enum qeth_ipa_funcs ipa_func, __u16 cmd_code)

{
	int rc;
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(trace,4,"simassp6");
	iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code,
				       0, QETH_PROT_IPV6);
	rc = qeth_send_setassparms(card, iob, 0, 0,
				   qeth_default_setassparms_cb, NULL);
	return rc;
}
#endif

static int
qeth_send_simple_setassparms(struct qeth_card *card,
			     enum qeth_ipa_funcs ipa_func,
			     __u16 cmd_code, long data)
{
	int rc;
	int length = 0;
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(trace,4,"simassp4");
	if (data)
		length = sizeof(__u32);
	iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code,
				       length, QETH_PROT_IPV4);
	rc = qeth_send_setassparms(card, iob, length, data,
				   qeth_default_setassparms_cb, NULL);
	return rc;
}

static int
qeth_start_ipa_arp_processing(struct qeth_card *card)
{
	int rc;

	QETH_DBF_TEXT(trace,3,"ipaarp");

	if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
		PRINT_WARN("ARP processing not supported "
			   "on %s!\n", QETH_CARD_IFNAME(card));
		return 0;
	}
	rc = qeth_send_simple_setassparms(card,IPA_ARP_PROCESSING,
					  IPA_CMD_ASS_START, 0);
	if (rc) {
		PRINT_WARN("Could not start ARP processing "
			   "assist on %s: 0x%x\n",
			   QETH_CARD_IFNAME(card), rc);
	}
	return rc;
}

static int
qeth_start_ipa_ip_fragmentation(struct qeth_card *card)
{
	int rc;

	QETH_DBF_TEXT(trace,3,"ipaipfrg");

	if (!qeth_is_supported(card, IPA_IP_FRAGMENTATION)) {
		PRINT_INFO("Hardware IP fragmentation not supported on %s\n",
			   QETH_CARD_IFNAME(card));
		return  -EOPNOTSUPP;
	}

	rc = qeth_send_simple_setassparms(card, IPA_IP_FRAGMENTATION,
					  IPA_CMD_ASS_START, 0);
	if (rc) {
		PRINT_WARN("Could not start Hardware IP fragmentation "
			   "assist on %s: 0x%x\n",
			   QETH_CARD_IFNAME(card), rc);
	} else
		PRINT_INFO("Hardware IP fragmentation enabled \n");
	return rc;
}

static int
qeth_start_ipa_source_mac(struct qeth_card *card)
{
	int rc;

	QETH_DBF_TEXT(trace,3,"stsrcmac");

	if (!card->options.fake_ll)
		return -EOPNOTSUPP;

	if (!qeth_is_supported(card, IPA_SOURCE_MAC)) {
		PRINT_INFO("Inbound source address not "
			   "supported on %s\n", QETH_CARD_IFNAME(card));
		return -EOPNOTSUPP;
	}

	rc = qeth_send_simple_setassparms(card, IPA_SOURCE_MAC,
					  IPA_CMD_ASS_START, 0);
	if (rc)
		PRINT_WARN("Could not start inbound source "
			   "assist on %s: 0x%x\n",
			   QETH_CARD_IFNAME(card), rc);
	return rc;
}

static int
qeth_start_ipa_vlan(struct qeth_card *card)
{
	int rc = 0;

	QETH_DBF_TEXT(trace,3,"strtvlan");

#ifdef CONFIG_QETH_VLAN
	if (!qeth_is_supported(card, IPA_FULL_VLAN)) {
		PRINT_WARN("VLAN not supported on %s\n", QETH_CARD_IFNAME(card));
		return -EOPNOTSUPP;
	}

	rc = qeth_send_simple_setassparms(card, IPA_VLAN_PRIO,
					  IPA_CMD_ASS_START,0);
	if (rc) {
		PRINT_WARN("Could not start vlan "
			   "assist on %s: 0x%x\n",
			   QETH_CARD_IFNAME(card), rc);
	} else {
		PRINT_INFO("VLAN enabled \n");
		card->dev->features |=
			NETIF_F_HW_VLAN_FILTER |
			NETIF_F_HW_VLAN_TX |
			NETIF_F_HW_VLAN_RX;
	}
#endif /* QETH_VLAN */
	return rc;
}

static int
qeth_start_ipa_multicast(struct qeth_card *card)
{
	int rc;

	QETH_DBF_TEXT(trace,3,"stmcast");

	if (!qeth_is_supported(card, IPA_MULTICASTING)) {
		PRINT_WARN("Multicast not supported on %s\n",
			   QETH_CARD_IFNAME(card));
		return -EOPNOTSUPP;
	}

	rc = qeth_send_simple_setassparms(card, IPA_MULTICASTING,
					  IPA_CMD_ASS_START,0);
	if (rc) {
		PRINT_WARN("Could not start multicast "
			   "assist on %s: rc=%i\n",
			   QETH_CARD_IFNAME(card), rc);
	} else {
		PRINT_INFO("Multicast enabled\n");
		card->dev->flags |= IFF_MULTICAST;
	}
	return rc;
}

#ifdef CONFIG_QETH_IPV6
static int
qeth_softsetup_ipv6(struct qeth_card *card)
{
	int rc;

	QETH_DBF_TEXT(trace,3,"softipv6");

	rc = qeth_send_startlan(card, QETH_PROT_IPV6);
	if (rc) {
		PRINT_ERR("IPv6 startlan failed on %s\n",
			  QETH_CARD_IFNAME(card));
		return rc;
	}
	rc = qeth_query_ipassists(card,QETH_PROT_IPV6);
	if (rc) {
		PRINT_ERR("IPv6 query ipassist failed on %s\n",
			  QETH_CARD_IFNAME(card));
		return rc;
	}
	rc = qeth_send_simple_setassparms(card, IPA_IPV6,
					  IPA_CMD_ASS_START, 3);
	if (rc) {
		PRINT_WARN("IPv6 start assist (version 4) failed "
			   "on %s: 0x%x\n",
			   QETH_CARD_IFNAME(card), rc);
		return rc;
	}
	rc = qeth_send_simple_setassparms_ipv6(card, IPA_IPV6,
					       IPA_CMD_ASS_START);
	if (rc) {
		PRINT_WARN("IPV6 start assist (version 6) failed  "
			   "on %s: 0x%x\n",
			   QETH_CARD_IFNAME(card), rc);
		return rc;
	}
	rc = qeth_send_simple_setassparms_ipv6(card, IPA_PASSTHRU,
					       IPA_CMD_ASS_START);
	if (rc) {
		PRINT_WARN("Could not enable passthrough "
			   "on %s: 0x%x\n",
			   QETH_CARD_IFNAME(card), rc);
		return rc;
	}
	PRINT_INFO("IPV6 enabled \n");
	return 0;
}

#endif

static int
qeth_start_ipa_ipv6(struct qeth_card *card)
{
	int rc = 0;
#ifdef CONFIG_QETH_IPV6
	QETH_DBF_TEXT(trace,3,"strtipv6");

	if (!qeth_is_supported(card, IPA_IPV6)) {
		PRINT_WARN("IPv6 not supported on %s\n",
			   QETH_CARD_IFNAME(card));
		return 0;
	}
	rc = qeth_softsetup_ipv6(card);
#endif
	return rc ;
}

static int
qeth_start_ipa_broadcast(struct qeth_card *card)
{
	int rc;

	QETH_DBF_TEXT(trace,3,"stbrdcst");
	card->info.broadcast_capable = 0;
	if (!qeth_is_supported(card, IPA_FILTERING)) {
		PRINT_WARN("Broadcast not supported on %s\n",
			   QETH_CARD_IFNAME(card));
		rc = -EOPNOTSUPP;
		goto out;
	}
	rc = qeth_send_simple_setassparms(card, IPA_FILTERING,
					  IPA_CMD_ASS_START, 0);
	if (rc) {
		PRINT_WARN("Could not enable broadcasting filtering "
			   "on %s: 0x%x\n",
			   QETH_CARD_IFNAME(card), rc);
		goto out;
	}

	rc = qeth_send_simple_setassparms(card, IPA_FILTERING,
					  IPA_CMD_ASS_CONFIGURE, 1);
	if (rc) {
		PRINT_WARN("Could not set up broadcast filtering on %s: 0x%x\n",
			   QETH_CARD_IFNAME(card), rc);
		goto out;
	}
	card->info.broadcast_capable = QETH_BROADCAST_WITH_ECHO;
	PRINT_INFO("Broadcast enabled \n");
	rc = qeth_send_simple_setassparms(card, IPA_FILTERING,
					  IPA_CMD_ASS_ENABLE, 1);
	if (rc) {
		PRINT_WARN("Could not set up broadcast echo filtering on "
			   "%s: 0x%x\n", QETH_CARD_IFNAME(card), rc);
		goto out;
	}
	card->info.broadcast_capable = QETH_BROADCAST_WITHOUT_ECHO;
out:
	if (card->info.broadcast_capable)
		card->dev->flags |= IFF_BROADCAST;
	else
		card->dev->flags &= ~IFF_BROADCAST;
	return rc;
}

static int
qeth_send_checksum_command(struct qeth_card *card)
{
	int rc;

	rc = qeth_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
					  IPA_CMD_ASS_START, 0);
	if (rc) {
		PRINT_WARN("Starting Inbound HW Checksumming failed on %s: "
			   "0x%x,\ncontinuing using Inbound SW Checksumming\n",
			   QETH_CARD_IFNAME(card), rc);
		return rc;
	}
	rc = qeth_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM,
					  IPA_CMD_ASS_ENABLE,
					  card->info.csum_mask);
	if (rc) {
		PRINT_WARN("Enabling Inbound HW Checksumming failed on %s: "
			   "0x%x,\ncontinuing using Inbound SW Checksumming\n",
			   QETH_CARD_IFNAME(card), rc);
		return rc;
	}
	return 0;
}

static int
qeth_start_ipa_checksum(struct qeth_card *card)
{
	int rc = 0;

	QETH_DBF_TEXT(trace,3,"strtcsum");

	if (card->options.checksum_type == NO_CHECKSUMMING) {
		PRINT_WARN("Using no checksumming on %s.\n",
			   QETH_CARD_IFNAME(card));
		return 0;
	}
	if (card->options.checksum_type == SW_CHECKSUMMING) {
		PRINT_WARN("Using SW checksumming on %s.\n",
			   QETH_CARD_IFNAME(card));
		return 0;
	}
	if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) {
		PRINT_WARN("Inbound HW Checksumming not "
			   "supported on %s,\ncontinuing "
			   "using Inbound SW Checksumming\n",
			   QETH_CARD_IFNAME(card));
		card->options.checksum_type = SW_CHECKSUMMING;
		return 0;
	}
	rc = qeth_send_checksum_command(card);
	if (!rc) {
		PRINT_INFO("HW Checksumming (inbound) enabled \n");
	}
	return rc;
}

static int
qeth_start_ipa_tso(struct qeth_card *card)
{
	int rc;

	QETH_DBF_TEXT(trace,3,"sttso");

	if (!qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
		PRINT_WARN("Outbound TSO not supported on %s\n",
			   QETH_CARD_IFNAME(card));
		rc = -EOPNOTSUPP;
	} else {
		rc = qeth_send_simple_setassparms(card, IPA_OUTBOUND_TSO,
						  IPA_CMD_ASS_START,0);
		if (rc)
			PRINT_WARN("Could not start outbound TSO "
				   "assist on %s: rc=%i\n",
				   QETH_CARD_IFNAME(card), rc);
		else
			PRINT_INFO("Outbound TSO enabled\n");
	}
	if (rc && (card->options.large_send == QETH_LARGE_SEND_TSO)){
		card->options.large_send = QETH_LARGE_SEND_NO;
		card->dev->features &= ~ (NETIF_F_TSO | NETIF_F_SG);
	}
	return rc;
}

static int
qeth_start_ipassists(struct qeth_card *card)
{
	QETH_DBF_TEXT(trace,3,"strtipas");
	qeth_start_ipa_arp_processing(card);	/* go on*/
	qeth_start_ipa_ip_fragmentation(card); 	/* go on*/
	qeth_start_ipa_source_mac(card);	/* go on*/
	qeth_start_ipa_vlan(card);		/* go on*/
	qeth_start_ipa_multicast(card);		/* go on*/
	qeth_start_ipa_ipv6(card);		/* go on*/
	qeth_start_ipa_broadcast(card);		/* go on*/
	qeth_start_ipa_checksum(card);		/* go on*/
	qeth_start_ipa_tso(card);		/* go on*/
	return 0;
}

static int
qeth_send_setrouting(struct qeth_card *card, enum qeth_routing_types type,
		     enum qeth_prot_versions prot)
{
	int rc;
	struct qeth_ipa_cmd *cmd;
	struct qeth_cmd_buffer *iob;

	QETH_DBF_TEXT(trace,4,"setroutg");
	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETRTG, prot);
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	cmd->data.setrtg.type = (type);
	rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);

	return rc;

}

static void
qeth_correct_routing_type(struct qeth_card *card, enum qeth_routing_types *type,
			enum qeth_prot_versions prot)
{
	if (card->info.type == QETH_CARD_TYPE_IQD) {
		switch (*type) {
		case NO_ROUTER:
		case PRIMARY_CONNECTOR:
		case SECONDARY_CONNECTOR:
		case MULTICAST_ROUTER:
			return;
		default:
			goto out_inval;
		}
	} else {
		switch (*type) {
		case NO_ROUTER:
		case PRIMARY_ROUTER:
		case SECONDARY_ROUTER:
			return;
		case MULTICAST_ROUTER:
			if (qeth_is_ipafunc_supported(card, prot,
						      IPA_OSA_MC_ROUTER))
				return;
		default:
			goto out_inval;
		}
	}
out_inval:
	PRINT_WARN("Routing type '%s' not supported for interface %s.\n"
		   "Router status set to 'no router'.\n",
		   ((*type == PRIMARY_ROUTER)? "primary router" :
		    (*type == SECONDARY_ROUTER)? "secondary router" :
		    (*type == PRIMARY_CONNECTOR)? "primary connector" :
		    (*type == SECONDARY_CONNECTOR)? "secondary connector" :
		    (*type == MULTICAST_ROUTER)? "multicast router" :
		    "unknown"),
		   card->dev->name);
	*type = NO_ROUTER;
}

int
qeth_setrouting_v4(struct qeth_card *card)
{
	int rc;

	QETH_DBF_TEXT(trace,3,"setrtg4");

	qeth_correct_routing_type(card, &card->options.route4.type,
				  QETH_PROT_IPV4);

	rc = qeth_send_setrouting(card, card->options.route4.type,
				  QETH_PROT_IPV4);
	if (rc) {
 		card->options.route4.type = NO_ROUTER;
		PRINT_WARN("Error (0x%04x) while setting routing type on %s. "
			   "Type set to 'no router'.\n",
			   rc, QETH_CARD_IFNAME(card));
	}
	return rc;
}

int
qeth_setrouting_v6(struct qeth_card *card)
{
	int rc = 0;

	QETH_DBF_TEXT(trace,3,"setrtg6");
#ifdef CONFIG_QETH_IPV6

	if (!qeth_is_supported(card, IPA_IPV6))
		return 0;
	qeth_correct_routing_type(card, &card->options.route6.type,
				  QETH_PROT_IPV6);

	rc = qeth_send_setrouting(card, card->options.route6.type,
				  QETH_PROT_IPV6);
	if (rc) {
	 	card->options.route6.type = NO_ROUTER;
		PRINT_WARN("Error (0x%04x) while setting routing type on %s. "
			   "Type set to 'no router'.\n",
			   rc, QETH_CARD_IFNAME(card));
	}
#endif
	return rc;
}

int
qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
{
	int rc = 0;

	if (card->dev == NULL) {
		card->options.large_send = type;
		return 0;
	}
	if (card->state == CARD_STATE_UP)
		netif_tx_disable(card->dev);
	card->options.large_send = type;
	switch (card->options.large_send) {
	case QETH_LARGE_SEND_EDDP:
		card->dev->features |= NETIF_F_TSO | NETIF_F_SG;
		break;
	case QETH_LARGE_SEND_TSO:
		if (qeth_is_supported(card, IPA_OUTBOUND_TSO)){
			card->dev->features |= NETIF_F_TSO | NETIF_F_SG;
		} else {
			PRINT_WARN("TSO not supported on %s. "
				   "large_send set to 'no'.\n",
				   card->dev->name);
			card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
			card->options.large_send = QETH_LARGE_SEND_NO;
			rc = -EOPNOTSUPP;
		}
		break;
	default: /* includes QETH_LARGE_SEND_NO */
		card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
		break;
	}
	if (card->state == CARD_STATE_UP)
		netif_wake_queue(card->dev);
	return rc;
}

/*
 * softsetup card: init IPA stuff
 */
static int
qeth_softsetup_card(struct qeth_card *card)
{
	int rc;

	QETH_DBF_TEXT(setup, 2, "softsetp");

	if ((rc = qeth_send_startlan(card, QETH_PROT_IPV4))){
		QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
		if (rc == 0xe080){
			PRINT_WARN("LAN on card %s if offline! "
				   "Waiting for STARTLAN from card.\n",
				   CARD_BUS_ID(card));
			card->lan_online = 0;
		}
		return rc;
	} else
		card->lan_online = 1;
	if (card->info.type==QETH_CARD_TYPE_OSN)
		goto out;
	qeth_set_large_send(card, card->options.large_send);
	if (card->options.layer2) {
		card->dev->features |=
			NETIF_F_HW_VLAN_FILTER |
			NETIF_F_HW_VLAN_TX |
			NETIF_F_HW_VLAN_RX;
		card->dev->flags|=IFF_MULTICAST|IFF_BROADCAST;
		card->info.broadcast_capable=1;
		if ((rc = qeth_layer2_initialize(card))) {
			QETH_DBF_TEXT_(setup, 2, "L2err%d", rc);
			return rc;
		}
#ifdef CONFIG_QETH_VLAN
		qeth_layer2_process_vlans(card, 0);
#endif
		goto out;
	}
	if ((rc = qeth_setadapter_parms(card)))
		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
	if ((rc = qeth_start_ipassists(card)))
		QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
	if ((rc = qeth_setrouting_v4(card)))
		QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
	if ((rc = qeth_setrouting_v6(card)))
		QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
out:
	netif_tx_disable(card->dev);
	return 0;
}

#ifdef CONFIG_QETH_IPV6
static int
qeth_get_unique_id_cb(struct qeth_card *card, struct qeth_reply *reply,
		      unsigned long data)
{
	struct qeth_ipa_cmd *cmd;

	cmd = (struct qeth_ipa_cmd *) data;
	if (cmd->hdr.return_code == 0)
		card->info.unique_id = *((__u16 *)
				&cmd->data.create_destroy_addr.unique_id[6]);
	else {
		card->info.unique_id =  UNIQUE_ID_IF_CREATE_ADDR_FAILED |
					UNIQUE_ID_NOT_BY_CARD;
		PRINT_WARN("couldn't get a unique id from the card on device "
			   "%s (result=x%x), using default id. ipv6 "
			   "autoconfig on other lpars may lead to duplicate "
			   "ip addresses. please use manually "
			   "configured ones.\n",
			   CARD_BUS_ID(card), cmd->hdr.return_code);
	}
	return 0;
}
#endif

static int
qeth_put_unique_id(struct qeth_card *card)
{

	int rc = 0;
#ifdef CONFIG_QETH_IPV6
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(trace,2,"puniqeid");

	if ((card->info.unique_id & UNIQUE_ID_NOT_BY_CARD) ==
	    	UNIQUE_ID_NOT_BY_CARD)
		return -1;
	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_DESTROY_ADDR,
				     QETH_PROT_IPV6);
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	*((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
		            card->info.unique_id;
	memcpy(&cmd->data.create_destroy_addr.unique_id[0],
	       card->dev->dev_addr, OSA_ADDR_LEN);
	rc = qeth_send_ipa_cmd(card, iob, NULL, NULL);
#else
	card->info.unique_id =  UNIQUE_ID_IF_CREATE_ADDR_FAILED |
				UNIQUE_ID_NOT_BY_CARD;
#endif
	return rc;
}

/**
 * Clear IP List
 */
static void
qeth_clear_ip_list(struct qeth_card *card, int clean, int recover)
{
	struct qeth_ipaddr *addr, *tmp;
	unsigned long flags;

	QETH_DBF_TEXT(trace,4,"clearip");
	spin_lock_irqsave(&card->ip_lock, flags);
	/* clear todo list */
	list_for_each_entry_safe(addr, tmp, card->ip_tbd_list, entry){
		list_del(&addr->entry);
		kfree(addr);
	}

	while (!list_empty(&card->ip_list)) {
		addr = list_entry(card->ip_list.next,
				  struct qeth_ipaddr, entry);
		list_del_init(&addr->entry);
		if (clean) {
			spin_unlock_irqrestore(&card->ip_lock, flags);
			qeth_deregister_addr_entry(card, addr);
			spin_lock_irqsave(&card->ip_lock, flags);
		}
		if (!recover || addr->is_multicast) {
			kfree(addr);
			continue;
		}
		list_add_tail(&addr->entry, card->ip_tbd_list);
	}
	spin_unlock_irqrestore(&card->ip_lock, flags);
}

static void
qeth_set_allowed_threads(struct qeth_card *card, unsigned long threads,
			 int clear_start_mask)
{
	unsigned long flags;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	card->thread_allowed_mask = threads;
	if (clear_start_mask)
		card->thread_start_mask &= threads;
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	wake_up(&card->wait_q);
}

static int
qeth_threads_running(struct qeth_card *card, unsigned long threads)
{
	unsigned long flags;
	int rc = 0;

	spin_lock_irqsave(&card->thread_mask_lock, flags);
	rc = (card->thread_running_mask & threads);
	spin_unlock_irqrestore(&card->thread_mask_lock, flags);
	return rc;
}

static int
qeth_wait_for_threads(struct qeth_card *card, unsigned long threads)
{
	return wait_event_interruptible(card->wait_q,
			qeth_threads_running(card, threads) == 0);
}

static int
qeth_stop_card(struct qeth_card *card, int recovery_mode)
{
	int rc = 0;

	QETH_DBF_TEXT(setup ,2,"stopcard");
	QETH_DBF_HEX(setup, 2, &card, sizeof(void *));

	qeth_set_allowed_threads(card, 0, 1);
	if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD))
		return -ERESTARTSYS;
	if (card->read.state == CH_STATE_UP &&
	    card->write.state == CH_STATE_UP &&
	    (card->state == CARD_STATE_UP)) {
		if (recovery_mode &&
		    card->info.type != QETH_CARD_TYPE_OSN) {
			qeth_stop(card->dev);
		} else {
			rtnl_lock();
			dev_close(card->dev);
			rtnl_unlock();
		}
		if (!card->use_hard_stop) {
			__u8 *mac = &card->dev->dev_addr[0];
			rc = qeth_layer2_send_delmac(card, mac);
			QETH_DBF_TEXT_(setup, 2, "Lerr%d", rc);
			if ((rc = qeth_send_stoplan(card)))
				QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
		}
		card->state = CARD_STATE_SOFTSETUP;
	}
	if (card->state == CARD_STATE_SOFTSETUP) {
#ifdef CONFIG_QETH_VLAN
		if (card->options.layer2)
			qeth_layer2_process_vlans(card, 1);
#endif
		qeth_clear_ip_list(card, !card->use_hard_stop, 1);
		qeth_clear_ipacmd_list(card);
		card->state = CARD_STATE_HARDSETUP;
	}
	if (card->state == CARD_STATE_HARDSETUP) {
		if ((!card->use_hard_stop) &&
		    (!card->options.layer2))
			if ((rc = qeth_put_unique_id(card)))
				QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
		qeth_qdio_clear_card(card, 0);
		qeth_clear_qdio_buffers(card);
		qeth_clear_working_pool_list(card);
		card->state = CARD_STATE_DOWN;
	}
	if (card->state == CARD_STATE_DOWN) {
		qeth_clear_cmd_buffers(&card->read);
		qeth_clear_cmd_buffers(&card->write);
	}
	card->use_hard_stop = 0;
	return rc;
}


static int
qeth_get_unique_id(struct qeth_card *card)
{
	int rc = 0;
#ifdef CONFIG_QETH_IPV6
	struct qeth_cmd_buffer *iob;
	struct qeth_ipa_cmd *cmd;

	QETH_DBF_TEXT(setup, 2, "guniqeid");

	if (!qeth_is_supported(card,IPA_IPV6)) {
		card->info.unique_id =  UNIQUE_ID_IF_CREATE_ADDR_FAILED |
					UNIQUE_ID_NOT_BY_CARD;
		return 0;
	}

	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_CREATE_ADDR,
				     QETH_PROT_IPV6);
	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
	*((__u16 *) &cmd->data.create_destroy_addr.unique_id[6]) =
		            card->info.unique_id;

	rc = qeth_send_ipa_cmd(card, iob, qeth_get_unique_id_cb, NULL);
#else
	card->info.unique_id =  UNIQUE_ID_IF_CREATE_ADDR_FAILED |
				UNIQUE_ID_NOT_BY_CARD;
#endif
	return rc;
}
static void
qeth_print_status_with_portname(struct qeth_card *card)
{
	char dbf_text[15];
	int i;

	sprintf(dbf_text, "%s", card->info.portname + 1);
	for (i = 0; i < 8; i++)
		dbf_text[i] =
			(char) _ebcasc[(__u8) dbf_text[i]];
	dbf_text[8] = 0;
	printk("qeth: Device %s/%s/%s is a%s card%s%s%s\n"
	       "with link type %s (portname: %s)\n",
	       CARD_RDEV_ID(card),
	       CARD_WDEV_ID(card),
	       CARD_DDEV_ID(card),
	       qeth_get_cardname(card),
	       (card->info.mcl_level[0]) ? " (level: " : "",
	       (card->info.mcl_level[0]) ? card->info.mcl_level : "",
	       (card->info.mcl_level[0]) ? ")" : "",
	       qeth_get_cardname_short(card),
	       dbf_text);

}

static void
qeth_print_status_no_portname(struct qeth_card *card)
{
	if (card->info.portname[0])
		printk("qeth: Device %s/%s/%s is a%s "
		       "card%s%s%s\nwith link type %s "
		       "(no portname needed by interface).\n",
		       CARD_RDEV_ID(card),
		       CARD_WDEV_ID(card),
		       CARD_DDEV_ID(card),
		       qeth_get_cardname(card),
		       (card->info.mcl_level[0]) ? " (level: " : "",
		       (card->info.mcl_level[0]) ? card->info.mcl_level : "",
		       (card->info.mcl_level[0]) ? ")" : "",
		       qeth_get_cardname_short(card));
	else
		printk("qeth: Device %s/%s/%s is a%s "
		       "card%s%s%s\nwith link type %s.\n",
		       CARD_RDEV_ID(card),
		       CARD_WDEV_ID(card),
		       CARD_DDEV_ID(card),
		       qeth_get_cardname(card),
		       (card->info.mcl_level[0]) ? " (level: " : "",
		       (card->info.mcl_level[0]) ? card->info.mcl_level : "",
		       (card->info.mcl_level[0]) ? ")" : "",
		       qeth_get_cardname_short(card));
}

static void
qeth_print_status_message(struct qeth_card *card)
{
	switch (card->info.type) {
	case QETH_CARD_TYPE_OSAE:
		/* VM will use a non-zero first character
		 * to indicate a HiperSockets like reporting
		 * of the level OSA sets the first character to zero
		 * */
		if (!card->info.mcl_level[0]) {
			sprintf(card->info.mcl_level,"%02x%02x",
				card->info.mcl_level[2],
				card->info.mcl_level[3]);

			card->info.mcl_level[QETH_MCL_LENGTH] = 0;
			break;
		}
		/* fallthrough */
	case QETH_CARD_TYPE_IQD:
		if (card->info.guestlan) {
			card->info.mcl_level[0] = (char) _ebcasc[(__u8)
				card->info.mcl_level[0]];
			card->info.mcl_level[1] = (char) _ebcasc[(__u8)
				card->info.mcl_level[1]];
			card->info.mcl_level[2] = (char) _ebcasc[(__u8)
				card->info.mcl_level[2]];
			card->info.mcl_level[3] = (char) _ebcasc[(__u8)
				card->info.mcl_level[3]];
			card->info.mcl_level[QETH_MCL_LENGTH] = 0;
		}
		break;
	default:
		memset(&card->info.mcl_level[0], 0, QETH_MCL_LENGTH + 1);
	}
	if (card->info.portname_required)
		qeth_print_status_with_portname(card);
	else
		qeth_print_status_no_portname(card);
}

static int
qeth_register_netdev(struct qeth_card *card)
{
	QETH_DBF_TEXT(setup, 3, "regnetd");
	if (card->dev->reg_state != NETREG_UNINITIALIZED)
		return 0;
	/* sysfs magic */
	SET_NETDEV_DEV(card->dev, &card->gdev->dev);
	return register_netdev(card->dev);
}

static void
qeth_start_again(struct qeth_card *card, int recovery_mode)
{
	QETH_DBF_TEXT(setup ,2, "startag");

	if (recovery_mode &&
	    card->info.type != QETH_CARD_TYPE_OSN) {
		qeth_open(card->dev);
	} else {
		rtnl_lock();
		dev_open(card->dev);
		rtnl_unlock();
	}
	/* this also sets saved unicast addresses */
	qeth_set_multicast_list(card->dev);
}


/* Layer 2 specific stuff */
#define IGNORE_PARAM_EQ(option,value,reset_value,msg) \
        if (card->options.option == value) { \
                PRINT_ERR("%s not supported with layer 2 " \
                          "functionality, ignoring option on read" \
			  "channel device %s .\n",msg,CARD_RDEV_ID(card)); \
                card->options.option = reset_value; \
        }
#define IGNORE_PARAM_NEQ(option,value,reset_value,msg) \
        if (card->options.option != value) { \
                PRINT_ERR("%s not supported with layer 2 " \
                          "functionality, ignoring option on read" \
			  "channel device %s .\n",msg,CARD_RDEV_ID(card)); \
                card->options.option = reset_value; \
        }


static void qeth_make_parameters_consistent(struct qeth_card *card)
{

	if (card->options.layer2 == 0)
		return;
	if (card->info.type == QETH_CARD_TYPE_OSN)
		return;
	if (card->info.type == QETH_CARD_TYPE_IQD) {
       		PRINT_ERR("Device %s does not support layer 2 functionality." \
	               	  " Ignoring layer2 option.\n",CARD_BUS_ID(card));
       		card->options.layer2 = 0;
		return;
	}
       	IGNORE_PARAM_NEQ(route4.type, NO_ROUTER, NO_ROUTER,
               	         "Routing options are");
#ifdef CONFIG_QETH_IPV6
       	IGNORE_PARAM_NEQ(route6.type, NO_ROUTER, NO_ROUTER,
               	         "Routing options are");
#endif
       	IGNORE_PARAM_EQ(checksum_type, HW_CHECKSUMMING,
                       	QETH_CHECKSUM_DEFAULT,
               	        "Checksumming options are");
       	IGNORE_PARAM_NEQ(broadcast_mode, QETH_TR_BROADCAST_ALLRINGS,
                       	 QETH_TR_BROADCAST_ALLRINGS,
               	         "Broadcast mode options are");
       	IGNORE_PARAM_NEQ(macaddr_mode, QETH_TR_MACADDR_NONCANONICAL,
                       	 QETH_TR_MACADDR_NONCANONICAL,
               	         "Canonical MAC addr options are");
       	IGNORE_PARAM_NEQ(fake_broadcast, 0, 0,
			 "Broadcast faking options are");
       	IGNORE_PARAM_NEQ(add_hhlen, DEFAULT_ADD_HHLEN,
       	                 DEFAULT_ADD_HHLEN,"Option add_hhlen is");
        IGNORE_PARAM_NEQ(fake_ll, 0, 0,"Option fake_ll is");
}


static int
__qeth_set_online(struct ccwgroup_device *gdev, int recovery_mode)
{
	struct qeth_card *card = gdev->dev.driver_data;
	int rc = 0;
	enum qeth_card_states recover_flag;

	BUG_ON(!card);
	QETH_DBF_TEXT(setup ,2, "setonlin");
	QETH_DBF_HEX(setup, 2, &card, sizeof(void *));

	qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
	if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD)){
		PRINT_WARN("set_online of card %s interrupted by user!\n",
			   CARD_BUS_ID(card));
		return -ERESTARTSYS;
	}

	recover_flag = card->state;
	if ((rc = ccw_device_set_online(CARD_RDEV(card))) ||
	    (rc = ccw_device_set_online(CARD_WDEV(card))) ||
	    (rc = ccw_device_set_online(CARD_DDEV(card)))){
		QETH_DBF_TEXT_(setup, 2, "1err%d", rc);
		return -EIO;
	}

	qeth_make_parameters_consistent(card);

	if ((rc = qeth_hardsetup_card(card))){
		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
		goto out_remove;
	}
	card->state = CARD_STATE_HARDSETUP;

	if (!(rc = qeth_query_ipassists(card,QETH_PROT_IPV4)))
		rc = qeth_get_unique_id(card);

	if (rc && card->options.layer2 == 0) {
		QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
		goto out_remove;
	}
	qeth_print_status_message(card);
	if ((rc = qeth_register_netdev(card))){
		QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
		goto out_remove;
	}
	if ((rc = qeth_softsetup_card(card))){
		QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
		goto out_remove;
	}

	if ((rc = qeth_init_qdio_queues(card))){
		QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
		goto out_remove;
	}
	card->state = CARD_STATE_SOFTSETUP;
	netif_carrier_on(card->dev);

	qeth_set_allowed_threads(card, 0xffffffff, 0);
	if (recover_flag == CARD_STATE_RECOVER)
		qeth_start_again(card, recovery_mode);
	qeth_notify_processes();
	return 0;
out_remove:
	card->use_hard_stop = 1;
	qeth_stop_card(card, 0);
	ccw_device_set_offline(CARD_DDEV(card));
	ccw_device_set_offline(CARD_WDEV(card));
	ccw_device_set_offline(CARD_RDEV(card));
	if (recover_flag == CARD_STATE_RECOVER)
		card->state = CARD_STATE_RECOVER;
	else
		card->state = CARD_STATE_DOWN;
	return -ENODEV;
}

static int
qeth_set_online(struct ccwgroup_device *gdev)
{
	return __qeth_set_online(gdev, 0);
}

static struct ccw_device_id qeth_ids[] = {
	{CCW_DEVICE(0x1731, 0x01), .driver_info = QETH_CARD_TYPE_OSAE},
	{CCW_DEVICE(0x1731, 0x05), .driver_info = QETH_CARD_TYPE_IQD},
	{CCW_DEVICE(0x1731, 0x06), .driver_info = QETH_CARD_TYPE_OSN},
	{},
};
MODULE_DEVICE_TABLE(ccw, qeth_ids);

struct device *qeth_root_dev = NULL;

struct ccwgroup_driver qeth_ccwgroup_driver = {
	.owner = THIS_MODULE,
	.name = "qeth",
	.driver_id = 0xD8C5E3C8,
	.probe = qeth_probe_device,
	.remove = qeth_remove_device,
	.set_online = qeth_set_online,
	.set_offline = qeth_set_offline,
};

struct ccw_driver qeth_ccw_driver = {
	.name = "qeth",
	.ids = qeth_ids,
	.probe = ccwgroup_probe_ccwdev,
	.remove = ccwgroup_remove_ccwdev,
};


static void
qeth_unregister_dbf_views(void)
{
	if (qeth_dbf_setup)
		debug_unregister(qeth_dbf_setup);
	if (qeth_dbf_qerr)
		debug_unregister(qeth_dbf_qerr);
	if (qeth_dbf_sense)
		debug_unregister(qeth_dbf_sense);
	if (qeth_dbf_misc)
		debug_unregister(qeth_dbf_misc);
	if (qeth_dbf_data)
		debug_unregister(qeth_dbf_data);
	if (qeth_dbf_control)
		debug_unregister(qeth_dbf_control);
	if (qeth_dbf_trace)
		debug_unregister(qeth_dbf_trace);
}
static int
qeth_register_dbf_views(void)
{
	qeth_dbf_setup = debug_register(QETH_DBF_SETUP_NAME,
					QETH_DBF_SETUP_PAGES,
					QETH_DBF_SETUP_NR_AREAS,
					QETH_DBF_SETUP_LEN);
	qeth_dbf_misc = debug_register(QETH_DBF_MISC_NAME,
				       QETH_DBF_MISC_PAGES,
				       QETH_DBF_MISC_NR_AREAS,
				       QETH_DBF_MISC_LEN);
	qeth_dbf_data = debug_register(QETH_DBF_DATA_NAME,
				       QETH_DBF_DATA_PAGES,
				       QETH_DBF_DATA_NR_AREAS,
				       QETH_DBF_DATA_LEN);
	qeth_dbf_control = debug_register(QETH_DBF_CONTROL_NAME,
					  QETH_DBF_CONTROL_PAGES,
					  QETH_DBF_CONTROL_NR_AREAS,
					  QETH_DBF_CONTROL_LEN);
	qeth_dbf_sense = debug_register(QETH_DBF_SENSE_NAME,
					QETH_DBF_SENSE_PAGES,
					QETH_DBF_SENSE_NR_AREAS,
					QETH_DBF_SENSE_LEN);
	qeth_dbf_qerr = debug_register(QETH_DBF_QERR_NAME,
				       QETH_DBF_QERR_PAGES,
				       QETH_DBF_QERR_NR_AREAS,
				       QETH_DBF_QERR_LEN);
	qeth_dbf_trace = debug_register(QETH_DBF_TRACE_NAME,
					QETH_DBF_TRACE_PAGES,
					QETH_DBF_TRACE_NR_AREAS,
					QETH_DBF_TRACE_LEN);

	if ((qeth_dbf_setup == NULL) || (qeth_dbf_misc == NULL)    ||
	    (qeth_dbf_data == NULL)  || (qeth_dbf_control == NULL) ||
	    (qeth_dbf_sense == NULL) || (qeth_dbf_qerr == NULL)    ||
	    (qeth_dbf_trace == NULL)) {
		qeth_unregister_dbf_views();
		return -ENOMEM;
	}
	debug_register_view(qeth_dbf_setup, &debug_hex_ascii_view);
	debug_set_level(qeth_dbf_setup, QETH_DBF_SETUP_LEVEL);

	debug_register_view(qeth_dbf_misc, &debug_hex_ascii_view);
	debug_set_level(qeth_dbf_misc, QETH_DBF_MISC_LEVEL);

	debug_register_view(qeth_dbf_data, &debug_hex_ascii_view);
	debug_set_level(qeth_dbf_data, QETH_DBF_DATA_LEVEL);

	debug_register_view(qeth_dbf_control, &debug_hex_ascii_view);
	debug_set_level(qeth_dbf_control, QETH_DBF_CONTROL_LEVEL);

	debug_register_view(qeth_dbf_sense, &debug_hex_ascii_view);
	debug_set_level(qeth_dbf_sense, QETH_DBF_SENSE_LEVEL);

	debug_register_view(qeth_dbf_qerr, &debug_hex_ascii_view);
	debug_set_level(qeth_dbf_qerr, QETH_DBF_QERR_LEVEL);

	debug_register_view(qeth_dbf_trace, &debug_hex_ascii_view);
	debug_set_level(qeth_dbf_trace, QETH_DBF_TRACE_LEVEL);

	return 0;
}

#ifdef CONFIG_QETH_IPV6
extern struct neigh_table arp_tbl;
static struct neigh_ops *arp_direct_ops;
static int (*qeth_old_arp_constructor) (struct neighbour *);

static struct neigh_ops arp_direct_ops_template = {
	.family = AF_INET,
	.solicit = NULL,
	.error_report = NULL,
	.output = dev_queue_xmit,
	.connected_output = dev_queue_xmit,
	.hh_output = dev_queue_xmit,
	.queue_xmit = dev_queue_xmit
};

static int
qeth_arp_constructor(struct neighbour *neigh)
{
	struct net_device *dev = neigh->dev;
	struct in_device *in_dev;
	struct neigh_parms *parms;
	struct qeth_card *card;

	card = qeth_get_card_from_dev(dev);
	if (card == NULL)
		goto out;
	if((card->options.layer2) ||
	   (card->dev->hard_header == qeth_fake_header))
		goto out;

	rcu_read_lock();
	in_dev = __in_dev_get_rcu(dev);
	if (in_dev == NULL) {
		rcu_read_unlock();
		return -EINVAL;
	}

	parms = in_dev->arp_parms;
	__neigh_parms_put(neigh->parms);
	neigh->parms = neigh_parms_clone(parms);
	rcu_read_unlock();

	neigh->type = inet_addr_type(*(__be32 *) neigh->primary_key);
	neigh->nud_state = NUD_NOARP;
	neigh->ops = arp_direct_ops;
	neigh->output = neigh->ops->queue_xmit;
	return 0;
out:
	return qeth_old_arp_constructor(neigh);
}
#endif  /*CONFIG_QETH_IPV6*/

/*
 * IP address takeover related functions
 */
static void
qeth_clear_ipato_list(struct qeth_card *card)
{
	struct qeth_ipato_entry *ipatoe, *tmp;
	unsigned long flags;

	spin_lock_irqsave(&card->ip_lock, flags);
	list_for_each_entry_safe(ipatoe, tmp, &card->ipato.entries, entry) {
		list_del(&ipatoe->entry);
		kfree(ipatoe);
	}
	spin_unlock_irqrestore(&card->ip_lock, flags);
}

int
qeth_add_ipato_entry(struct qeth_card *card, struct qeth_ipato_entry *new)
{
	struct qeth_ipato_entry *ipatoe;
	unsigned long flags;
	int rc = 0;

	QETH_DBF_TEXT(trace, 2, "addipato");
	spin_lock_irqsave(&card->ip_lock, flags);
	list_for_each_entry(ipatoe, &card->ipato.entries, entry){
		if (ipatoe->proto != new->proto)
			continue;
		if (!memcmp(ipatoe->addr, new->addr,
			    (ipatoe->proto == QETH_PROT_IPV4)? 4:16) &&
		    (ipatoe->mask_bits == new->mask_bits)){
			PRINT_WARN("ipato entry already exists!\n");
			rc = -EEXIST;
			break;
		}
	}
	if (!rc) {
		list_add_tail(&new->entry, &card->ipato.entries);
	}
	spin_unlock_irqrestore(&card->ip_lock, flags);
	return rc;
}

void
qeth_del_ipato_entry(struct qeth_card *card, enum qeth_prot_versions proto,
		     u8 *addr, int mask_bits)
{
	struct qeth_ipato_entry *ipatoe, *tmp;
	unsigned long flags;

	QETH_DBF_TEXT(trace, 2, "delipato");
	spin_lock_irqsave(&card->ip_lock, flags);
	list_for_each_entry_safe(ipatoe, tmp, &card->ipato.entries, entry){
		if (ipatoe->proto != proto)
			continue;
		if (!memcmp(ipatoe->addr, addr,
			    (proto == QETH_PROT_IPV4)? 4:16) &&
		    (ipatoe->mask_bits == mask_bits)){
			list_del(&ipatoe->entry);
			kfree(ipatoe);
		}
	}
	spin_unlock_irqrestore(&card->ip_lock, flags);
}

static void
qeth_convert_addr_to_bits(u8 *addr, u8 *bits, int len)
{
	int i, j;
	u8 octet;

	for (i = 0; i < len; ++i){
		octet = addr[i];
		for (j = 7; j >= 0; --j){
			bits[i*8 + j] = octet & 1;
			octet >>= 1;
		}
	}
}

static int
qeth_is_addr_covered_by_ipato(struct qeth_card *card, struct qeth_ipaddr *addr)
{
	struct qeth_ipato_entry *ipatoe;
	u8 addr_bits[128] = {0, };
	u8 ipatoe_bits[128] = {0, };
	int rc = 0;

	if (!card->ipato.enabled)
		return 0;

	qeth_convert_addr_to_bits((u8 *) &addr->u, addr_bits,
				  (addr->proto == QETH_PROT_IPV4)? 4:16);
	list_for_each_entry(ipatoe, &card->ipato.entries, entry){
		if (addr->proto != ipatoe->proto)
			continue;
		qeth_convert_addr_to_bits(ipatoe->addr, ipatoe_bits,
					  (ipatoe->proto==QETH_PROT_IPV4) ?
					  4:16);
		if (addr->proto == QETH_PROT_IPV4)
			rc = !memcmp(addr_bits, ipatoe_bits,
				     min(32, ipatoe->mask_bits));
		else
			rc = !memcmp(addr_bits, ipatoe_bits,
				     min(128, ipatoe->mask_bits));
		if (rc)
			break;
	}
	/* invert? */
	if ((addr->proto == QETH_PROT_IPV4) && card->ipato.invert4)
		rc = !rc;
	else if ((addr->proto == QETH_PROT_IPV6) && card->ipato.invert6)
		rc = !rc;

	return rc;
}

/*
 * VIPA related functions
 */
int
qeth_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
	      const u8 *addr)
{
	struct qeth_ipaddr *ipaddr;
	unsigned long flags;
	int rc = 0;

	ipaddr = qeth_get_addr_buffer(proto);
	if (ipaddr){
		if (proto == QETH_PROT_IPV4){
			QETH_DBF_TEXT(trace, 2, "addvipa4");
			memcpy(&ipaddr->u.a4.addr, addr, 4);
			ipaddr->u.a4.mask = 0;
#ifdef CONFIG_QETH_IPV6
		} else if (proto == QETH_PROT_IPV6){
			QETH_DBF_TEXT(trace, 2, "addvipa6");
			memcpy(&ipaddr->u.a6.addr, addr, 16);
			ipaddr->u.a6.pfxlen = 0;
#endif
		}
		ipaddr->type = QETH_IP_TYPE_VIPA;
		ipaddr->set_flags = QETH_IPA_SETIP_VIPA_FLAG;
		ipaddr->del_flags = QETH_IPA_DELIP_VIPA_FLAG;
	} else
		return -ENOMEM;
	spin_lock_irqsave(&card->ip_lock, flags);
	if (__qeth_address_exists_in_list(&card->ip_list, ipaddr, 0) ||
	    __qeth_address_exists_in_list(card->ip_tbd_list, ipaddr, 0))
		rc = -EEXIST;
	spin_unlock_irqrestore(&card->ip_lock, flags);
	if (rc){
		PRINT_WARN("Cannot add VIPA. Address already exists!\n");
		return rc;
	}
	if (!qeth_add_ip(card, ipaddr))
		kfree(ipaddr);
	qeth_set_ip_addr_list(card);
	return rc;
}

void
qeth_del_vipa(struct qeth_card *card, enum qeth_prot_versions proto,
	      const u8 *addr)
{
	struct qeth_ipaddr *ipaddr;

	ipaddr = qeth_get_addr_buffer(proto);
	if (ipaddr){
		if (proto == QETH_PROT_IPV4){
			QETH_DBF_TEXT(trace, 2, "delvipa4");
			memcpy(&ipaddr->u.a4.addr, addr, 4);
			ipaddr->u.a4.mask = 0;
#ifdef CONFIG_QETH_IPV6
		} else if (proto == QETH_PROT_IPV6){
			QETH_DBF_TEXT(trace, 2, "delvipa6");
			memcpy(&ipaddr->u.a6.addr, addr, 16);
			ipaddr->u.a6.pfxlen = 0;
#endif
		}
		ipaddr->type = QETH_IP_TYPE_VIPA;
	} else
		return;
	if (!qeth_delete_ip(card, ipaddr))
		kfree(ipaddr);
	qeth_set_ip_addr_list(card);
}

/*
 * proxy ARP related functions
 */
int
qeth_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
	      const u8 *addr)
{
	struct qeth_ipaddr *ipaddr;
	unsigned long flags;
	int rc = 0;

	ipaddr = qeth_get_addr_buffer(proto);
	if (ipaddr){
		if (proto == QETH_PROT_IPV4){
			QETH_DBF_TEXT(trace, 2, "addrxip4");
			memcpy(&ipaddr->u.a4.addr, addr, 4);
			ipaddr->u.a4.mask = 0;
#ifdef CONFIG_QETH_IPV6
		} else if (proto == QETH_PROT_IPV6){
			QETH_DBF_TEXT(trace, 2, "addrxip6");
			memcpy(&ipaddr->u.a6.addr, addr, 16);
			ipaddr->u.a6.pfxlen = 0;
#endif
		}
		ipaddr->type = QETH_IP_TYPE_RXIP;
		ipaddr->set_flags = QETH_IPA_SETIP_TAKEOVER_FLAG;
		ipaddr->del_flags = 0;
	} else
		return -ENOMEM;
	spin_lock_irqsave(&card->ip_lock, flags);
	if (__qeth_address_exists_in_list(&card->ip_list, ipaddr, 0) ||
	    __qeth_address_exists_in_list(card->ip_tbd_list, ipaddr, 0))
		rc = -EEXIST;
	spin_unlock_irqrestore(&card->ip_lock, flags);
	if (rc){
		PRINT_WARN("Cannot add RXIP. Address already exists!\n");
		return rc;
	}
	if (!qeth_add_ip(card, ipaddr))
		kfree(ipaddr);
	qeth_set_ip_addr_list(card);
	return 0;
}

void
qeth_del_rxip(struct qeth_card *card, enum qeth_prot_versions proto,
	      const u8 *addr)
{
	struct qeth_ipaddr *ipaddr;

	ipaddr = qeth_get_addr_buffer(proto);
	if (ipaddr){
		if (proto == QETH_PROT_IPV4){
			QETH_DBF_TEXT(trace, 2, "addrxip4");
			memcpy(&ipaddr->u.a4.addr, addr, 4);
			ipaddr->u.a4.mask = 0;
#ifdef CONFIG_QETH_IPV6
		} else if (proto == QETH_PROT_IPV6){
			QETH_DBF_TEXT(trace, 2, "addrxip6");
			memcpy(&ipaddr->u.a6.addr, addr, 16);
			ipaddr->u.a6.pfxlen = 0;
#endif
		}
		ipaddr->type = QETH_IP_TYPE_RXIP;
	} else
		return;
	if (!qeth_delete_ip(card, ipaddr))
		kfree(ipaddr);
	qeth_set_ip_addr_list(card);
}

/**
 * IP event handler
 */
static int
qeth_ip_event(struct notifier_block *this,
	      unsigned long event,void *ptr)
{
	struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
	struct net_device *dev =(struct net_device *) ifa->ifa_dev->dev;
	struct qeth_ipaddr *addr;
	struct qeth_card *card;

	QETH_DBF_TEXT(trace,3,"ipevent");
	card = qeth_get_card_from_dev(dev);
	if (!card)
		return NOTIFY_DONE;
	if (card->options.layer2)
		return NOTIFY_DONE;

	addr = qeth_get_addr_buffer(QETH_PROT_IPV4);
	if (addr != NULL) {
		addr->u.a4.addr = ifa->ifa_address;
		addr->u.a4.mask = ifa->ifa_mask;
		addr->type = QETH_IP_TYPE_NORMAL;
	} else
		goto out;

	switch(event) {
	case NETDEV_UP:
		if (!qeth_add_ip(card, addr))
			kfree(addr);
		break;
	case NETDEV_DOWN:
		if (!qeth_delete_ip(card, addr))
			kfree(addr);
		break;
	default:
		break;
	}
	qeth_set_ip_addr_list(card);
out:
	return NOTIFY_DONE;
}

static struct notifier_block qeth_ip_notifier = {
	qeth_ip_event,
	NULL,
};

#ifdef CONFIG_QETH_IPV6
/**
 * IPv6 event handler
 */
static int
qeth_ip6_event(struct notifier_block *this,
	      unsigned long event,void *ptr)
{

	struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
	struct net_device *dev = (struct net_device *)ifa->idev->dev;
	struct qeth_ipaddr *addr;
	struct qeth_card *card;

	QETH_DBF_TEXT(trace,3,"ip6event");

	card = qeth_get_card_from_dev(dev);
	if (!card)
		return NOTIFY_DONE;
	if (!qeth_is_supported(card, IPA_IPV6))
		return NOTIFY_DONE;

	addr = qeth_get_addr_buffer(QETH_PROT_IPV6);
	if (addr != NULL) {
		memcpy(&addr->u.a6.addr, &ifa->addr, sizeof(struct in6_addr));
		addr->u.a6.pfxlen = ifa->prefix_len;
		addr->type = QETH_IP_TYPE_NORMAL;
	} else
		goto out;

	switch(event) {
	case NETDEV_UP:
		if (!qeth_add_ip(card, addr))
			kfree(addr);
		break;
	case NETDEV_DOWN:
		if (!qeth_delete_ip(card, addr))
			kfree(addr);
		break;
	default:
		break;
	}
	qeth_set_ip_addr_list(card);
out:
	return NOTIFY_DONE;
}

static struct notifier_block qeth_ip6_notifier = {
	qeth_ip6_event,
	NULL,
};
#endif

static int
__qeth_reboot_event_card(struct device *dev, void *data)
{
	struct qeth_card *card;

	card = (struct qeth_card *) dev->driver_data;
	qeth_clear_ip_list(card, 0, 0);
	qeth_qdio_clear_card(card, 0);
	qeth_clear_qdio_buffers(card);
	return 0;
}

static int
qeth_reboot_event(struct notifier_block *this, unsigned long event, void *ptr)
{
	int ret;

	ret = driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
				     __qeth_reboot_event_card);
	return ret ? NOTIFY_BAD : NOTIFY_DONE;
}


static struct notifier_block qeth_reboot_notifier = {
	qeth_reboot_event,
	NULL,
};

static int
qeth_register_notifiers(void)
{
        int r;

	QETH_DBF_TEXT(trace,5,"regnotif");
	if ((r = register_reboot_notifier(&qeth_reboot_notifier)))
		return r;
	if ((r = register_inetaddr_notifier(&qeth_ip_notifier)))
		goto out_reboot;
#ifdef CONFIG_QETH_IPV6
	if ((r = register_inet6addr_notifier(&qeth_ip6_notifier)))
		goto out_ipv4;
#endif
	return 0;

#ifdef CONFIG_QETH_IPV6
out_ipv4:
	unregister_inetaddr_notifier(&qeth_ip_notifier);
#endif
out_reboot:
	unregister_reboot_notifier(&qeth_reboot_notifier);
	return r;
}

/**
 * unregister all event notifiers
 */
static void
qeth_unregister_notifiers(void)
{

	QETH_DBF_TEXT(trace,5,"unregnot");
	BUG_ON(unregister_reboot_notifier(&qeth_reboot_notifier));
	BUG_ON(unregister_inetaddr_notifier(&qeth_ip_notifier));
#ifdef CONFIG_QETH_IPV6
	BUG_ON(unregister_inet6addr_notifier(&qeth_ip6_notifier));
#endif /* QETH_IPV6 */

}

#ifdef CONFIG_QETH_IPV6
static int
qeth_ipv6_init(void)
{
	qeth_old_arp_constructor = arp_tbl.constructor;
	write_lock_bh(&arp_tbl.lock);
	arp_tbl.constructor = qeth_arp_constructor;
	write_unlock_bh(&arp_tbl.lock);

	arp_direct_ops = (struct neigh_ops*)
		kmalloc(sizeof(struct neigh_ops), GFP_KERNEL);
	if (!arp_direct_ops)
		return -ENOMEM;

	memcpy(arp_direct_ops, &arp_direct_ops_template,
	       sizeof(struct neigh_ops));

	return 0;
}

static void
qeth_ipv6_uninit(void)
{
	write_lock_bh(&arp_tbl.lock);
	arp_tbl.constructor = qeth_old_arp_constructor;
	write_unlock_bh(&arp_tbl.lock);
	kfree(arp_direct_ops);
}
#endif /* CONFIG_QETH_IPV6 */

static void
qeth_sysfs_unregister(void)
{
	s390_root_dev_unregister(qeth_root_dev);
	qeth_remove_driver_attributes();
	ccw_driver_unregister(&qeth_ccw_driver);
	ccwgroup_driver_unregister(&qeth_ccwgroup_driver);
}

/**
 * register qeth at sysfs
 */
static int
qeth_sysfs_register(void)
{
	int rc;

	rc = ccwgroup_driver_register(&qeth_ccwgroup_driver);
	if (rc)
		goto out;

	rc = ccw_driver_register(&qeth_ccw_driver);
	if (rc)
		goto out_ccw_driver;

	rc = qeth_create_driver_attributes();
	if (rc)
		goto out_qeth_attr;

	qeth_root_dev = s390_root_dev_register("qeth");
	rc = IS_ERR(qeth_root_dev) ? PTR_ERR(qeth_root_dev) : 0;
	if (!rc)
		goto out;

	qeth_remove_driver_attributes();
out_qeth_attr:
	ccw_driver_unregister(&qeth_ccw_driver);
out_ccw_driver:
	ccwgroup_driver_unregister(&qeth_ccwgroup_driver);
out:
	return rc;
}

/***
 * init function
 */
static int __init
qeth_init(void)
{
	int rc;

	PRINT_INFO("loading %s\n", version);

	INIT_LIST_HEAD(&qeth_card_list.list);
	INIT_LIST_HEAD(&qeth_notify_list);
	spin_lock_init(&qeth_notify_lock);
	rwlock_init(&qeth_card_list.rwlock);

	rc = qeth_register_dbf_views();
	if (rc)
		goto out_err;

	rc = qeth_sysfs_register();
	if (rc)
		goto out_dbf;

#ifdef CONFIG_QETH_IPV6
	rc = qeth_ipv6_init();
	if (rc) {
		PRINT_ERR("Out of memory during ipv6 init code = %d\n", rc);
		goto out_sysfs;
	}
#endif /* QETH_IPV6 */
	rc = qeth_register_notifiers();
	if (rc)
		goto out_ipv6;
	rc = qeth_create_procfs_entries();
	if (rc)
		goto out_notifiers;

	return rc;

out_notifiers:
	qeth_unregister_notifiers();
out_ipv6:
#ifdef CONFIG_QETH_IPV6
	qeth_ipv6_uninit();
out_sysfs:
#endif /* QETH_IPV6 */
	qeth_sysfs_unregister();
out_dbf:
	qeth_unregister_dbf_views();
out_err:
	PRINT_ERR("Initialization failed with code %d\n", rc);
	return rc;
}

static void
__exit qeth_exit(void)
{
	struct qeth_card *card, *tmp;
	unsigned long flags;

	QETH_DBF_TEXT(trace,1, "cleanup.");

	/*
	 * Weed would not need to clean up our devices here, because the
	 * common device layer calls qeth_remove_device for each device
	 * as soon as we unregister our driver (done in qeth_sysfs_unregister).
	 * But we do cleanup here so we can do a "soft" shutdown of our cards.
	 * qeth_remove_device called by the common device layer would otherwise
	 * do a "hard" shutdown (card->use_hard_stop is set to one in
	 * qeth_remove_device).
	 */
again:
	read_lock_irqsave(&qeth_card_list.rwlock, flags);
	list_for_each_entry_safe(card, tmp, &qeth_card_list.list, list){
		read_unlock_irqrestore(&qeth_card_list.rwlock, flags);
		qeth_set_offline(card->gdev);
		qeth_remove_device(card->gdev);
		goto again;
	}
	read_unlock_irqrestore(&qeth_card_list.rwlock, flags);
#ifdef CONFIG_QETH_IPV6
	qeth_ipv6_uninit();
#endif
	qeth_unregister_notifiers();
	qeth_remove_procfs_entries();
	qeth_sysfs_unregister();
	qeth_unregister_dbf_views();
	printk("qeth: removed\n");
}

EXPORT_SYMBOL(qeth_osn_register);
EXPORT_SYMBOL(qeth_osn_deregister);
EXPORT_SYMBOL(qeth_osn_assist);
module_init(qeth_init);
module_exit(qeth_exit);
MODULE_AUTHOR("Frank Pavlic <fpavlic@de.ibm.com>");
MODULE_DESCRIPTION("Linux on zSeries OSA Express and HiperSockets support\n" \
		                      "Copyright 2000,2003 IBM Corporation\n");

MODULE_LICENSE("GPL");
