All of lore.kernel.org
 help / color / mirror / Atom feed
From: frank.blaschka@de.ibm.com
To: jgarzik@pobox.com
Cc: netdev@vger.kernel.org, linux-s390@vger.kernel.org
Subject: [patch 2/2] qeth: remove old qeth files
Date: Fri, 15 Feb 2008 09:19:43 +0100	[thread overview]
Message-ID: <20080215082019.404274000@de.ibm.com> (raw)
In-Reply-To: 20080215081941.450161000@de.ibm.com

[-- Attachment #1: rem_old_qeth.patch --]
[-- Type: text/plain, Size: 396222 bytes --]

From: Frank Blaschka <frank.blaschka@de.ibm.com>

Remove all obsolete qeth files.

Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
---
 drivers/s390/net/qeth.h      | 1253 ------
 drivers/s390/net/qeth_eddp.c |  634 ---
 drivers/s390/net/qeth_eddp.h |   84 
 drivers/s390/net/qeth_fs.h   |  168 
 drivers/s390/net/qeth_main.c | 8956 -------------------------------------------
 drivers/s390/net/qeth_mpc.c  |  269 -
 drivers/s390/net/qeth_mpc.h  |  583 --
 drivers/s390/net/qeth_proc.c |  316 -
 drivers/s390/net/qeth_sys.c  | 1858 --------
 drivers/s390/net/qeth_tso.h  |  148 
 10 files changed, 14269 deletions(-)

Index: my_git/drivers/s390/net/qeth.h
===================================================================
--- my_git.orig/drivers/s390/net/qeth.h	2008-02-15 08:49:22.000000000 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,1253 +0,0 @@
-#ifndef __QETH_H__
-#define __QETH_H__
-
-#include <linux/if.h>
-#include <linux/if_arp.h>
-
-#include <linux/if_tr.h>
-#include <linux/trdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/if_vlan.h>
-#include <linux/ctype.h>
-
-#include <net/ipv6.h>
-#include <linux/in6.h>
-#include <net/if_inet6.h>
-#include <net/addrconf.h>
-
-
-#include <linux/bitops.h>
-
-#include <asm/debug.h>
-#include <asm/qdio.h>
-#include <asm/ccwdev.h>
-#include <asm/ccwgroup.h>
-
-#include "qeth_mpc.h"
-
-#ifdef CONFIG_QETH_IPV6
-#define QETH_VERSION_IPV6 	":IPv6"
-#else
-#define QETH_VERSION_IPV6 	""
-#endif
-#ifdef CONFIG_QETH_VLAN
-#define QETH_VERSION_VLAN 	":VLAN"
-#else
-#define QETH_VERSION_VLAN 	""
-#endif
-
-/**
- * Debug Facility stuff
- */
-#define QETH_DBF_SETUP_NAME "qeth_setup"
-#define QETH_DBF_SETUP_LEN 8
-#define QETH_DBF_SETUP_PAGES 8
-#define QETH_DBF_SETUP_NR_AREAS 1
-#define QETH_DBF_SETUP_LEVEL 5
-
-#define QETH_DBF_MISC_NAME "qeth_misc"
-#define QETH_DBF_MISC_LEN 128
-#define QETH_DBF_MISC_PAGES 2
-#define QETH_DBF_MISC_NR_AREAS 1
-#define QETH_DBF_MISC_LEVEL 2
-
-#define QETH_DBF_DATA_NAME "qeth_data"
-#define QETH_DBF_DATA_LEN 96
-#define QETH_DBF_DATA_PAGES 8
-#define QETH_DBF_DATA_NR_AREAS 1
-#define QETH_DBF_DATA_LEVEL 2
-
-#define QETH_DBF_CONTROL_NAME "qeth_control"
-#define QETH_DBF_CONTROL_LEN 256
-#define QETH_DBF_CONTROL_PAGES 8
-#define QETH_DBF_CONTROL_NR_AREAS 2
-#define QETH_DBF_CONTROL_LEVEL 5
-
-#define QETH_DBF_TRACE_NAME "qeth_trace"
-#define QETH_DBF_TRACE_LEN 8
-#define QETH_DBF_TRACE_PAGES 4
-#define QETH_DBF_TRACE_NR_AREAS 2
-#define QETH_DBF_TRACE_LEVEL 3
-extern debug_info_t *qeth_dbf_trace;
-
-#define QETH_DBF_SENSE_NAME "qeth_sense"
-#define QETH_DBF_SENSE_LEN 64
-#define QETH_DBF_SENSE_PAGES 2
-#define QETH_DBF_SENSE_NR_AREAS 1
-#define QETH_DBF_SENSE_LEVEL 2
-
-#define QETH_DBF_QERR_NAME "qeth_qerr"
-#define QETH_DBF_QERR_LEN 8
-#define QETH_DBF_QERR_PAGES 2
-#define QETH_DBF_QERR_NR_AREAS 2
-#define QETH_DBF_QERR_LEVEL 2
-
-#define QETH_DBF_TEXT(name,level,text) \
-	do { \
-		debug_text_event(qeth_dbf_##name,level,text); \
-	} while (0)
-
-#define QETH_DBF_HEX(name,level,addr,len) \
-	do { \
-		debug_event(qeth_dbf_##name,level,(void*)(addr),len); \
-	} while (0)
-
-DECLARE_PER_CPU(char[256], qeth_dbf_txt_buf);
-
-#define QETH_DBF_TEXT_(name,level,text...)				\
-	do {								\
-		char* dbf_txt_buf = get_cpu_var(qeth_dbf_txt_buf);	\
-		sprintf(dbf_txt_buf, text);			  	\
-		debug_text_event(qeth_dbf_##name,level,dbf_txt_buf);	\
-		put_cpu_var(qeth_dbf_txt_buf);				\
-	} while (0)
-
-#define QETH_DBF_SPRINTF(name,level,text...) \
-	do { \
-		debug_sprintf_event(qeth_dbf_trace, level, ##text ); \
-		debug_sprintf_event(qeth_dbf_trace, level, text ); \
-	} while (0)
-
-/**
- * some more debug stuff
- */
-#define PRINTK_HEADER 	"qeth: "
-
-#define HEXDUMP16(importance,header,ptr) \
-PRINT_##importance(header "%02x %02x %02x %02x  %02x %02x %02x %02x  " \
-		   "%02x %02x %02x %02x  %02x %02x %02x %02x\n", \
-		   *(((char*)ptr)),*(((char*)ptr)+1),*(((char*)ptr)+2), \
-		   *(((char*)ptr)+3),*(((char*)ptr)+4),*(((char*)ptr)+5), \
-		   *(((char*)ptr)+6),*(((char*)ptr)+7),*(((char*)ptr)+8), \
-		   *(((char*)ptr)+9),*(((char*)ptr)+10),*(((char*)ptr)+11), \
-		   *(((char*)ptr)+12),*(((char*)ptr)+13), \
-		   *(((char*)ptr)+14),*(((char*)ptr)+15)); \
-PRINT_##importance(header "%02x %02x %02x %02x  %02x %02x %02x %02x  " \
-		   "%02x %02x %02x %02x  %02x %02x %02x %02x\n", \
-		   *(((char*)ptr)+16),*(((char*)ptr)+17), \
-		   *(((char*)ptr)+18),*(((char*)ptr)+19), \
-		   *(((char*)ptr)+20),*(((char*)ptr)+21), \
-		   *(((char*)ptr)+22),*(((char*)ptr)+23), \
-		   *(((char*)ptr)+24),*(((char*)ptr)+25), \
-		   *(((char*)ptr)+26),*(((char*)ptr)+27), \
-		   *(((char*)ptr)+28),*(((char*)ptr)+29), \
-		   *(((char*)ptr)+30),*(((char*)ptr)+31));
-
-static inline void
-qeth_hex_dump(unsigned char *buf, size_t len)
-{
-	size_t i;
-
-	for (i = 0; i < len; i++) {
-		if (i && !(i % 16))
-			printk("\n");
-		printk("%02x ", *(buf + i));
-	}
-	printk("\n");
-}
-
-#define SENSE_COMMAND_REJECT_BYTE 0
-#define SENSE_COMMAND_REJECT_FLAG 0x80
-#define SENSE_RESETTING_EVENT_BYTE 1
-#define SENSE_RESETTING_EVENT_FLAG 0x80
-
-/*
- * Common IO related definitions
- */
-extern struct device *qeth_root_dev;
-extern struct ccw_driver qeth_ccw_driver;
-extern struct ccwgroup_driver qeth_ccwgroup_driver;
-
-#define CARD_RDEV(card) card->read.ccwdev
-#define CARD_WDEV(card) card->write.ccwdev
-#define CARD_DDEV(card) card->data.ccwdev
-#define CARD_BUS_ID(card) card->gdev->dev.bus_id
-#define CARD_RDEV_ID(card) card->read.ccwdev->dev.bus_id
-#define CARD_WDEV_ID(card) card->write.ccwdev->dev.bus_id
-#define CARD_DDEV_ID(card) card->data.ccwdev->dev.bus_id
-#define CHANNEL_ID(channel) channel->ccwdev->dev.bus_id
-
-#define CARD_FROM_CDEV(cdev) (struct qeth_card *) \
-		((struct ccwgroup_device *)cdev->dev.driver_data)\
-		->dev.driver_data;
-
-/**
- * card stuff
- */
-struct qeth_perf_stats {
-	unsigned int bufs_rec;
-	unsigned int bufs_sent;
-
-	unsigned int skbs_sent_pack;
-	unsigned int bufs_sent_pack;
-
-	unsigned int sc_dp_p;
-	unsigned int sc_p_dp;
-	/* qdio_input_handler: number of times called, time spent in */
-	__u64 inbound_start_time;
-	unsigned int inbound_cnt;
-	unsigned int inbound_time;
-	/* qeth_send_packet: number of times called, time spent in */
-	__u64 outbound_start_time;
-	unsigned int outbound_cnt;
-	unsigned int outbound_time;
-	/* qdio_output_handler: number of times called, time spent in */
-	__u64 outbound_handler_start_time;
-	unsigned int outbound_handler_cnt;
-	unsigned int outbound_handler_time;
-	/* number of calls to and time spent in do_QDIO for inbound queue */
-	__u64 inbound_do_qdio_start_time;
-	unsigned int inbound_do_qdio_cnt;
-	unsigned int inbound_do_qdio_time;
-	/* number of calls to and time spent in do_QDIO for outbound queues */
-	__u64 outbound_do_qdio_start_time;
-	unsigned int outbound_do_qdio_cnt;
-	unsigned int outbound_do_qdio_time;
-	/* eddp data */
-	unsigned int large_send_bytes;
-	unsigned int large_send_cnt;
-	unsigned int sg_skbs_sent;
-	unsigned int sg_frags_sent;
-	/* initial values when measuring starts */
-	unsigned long initial_rx_packets;
-	unsigned long initial_tx_packets;
-	/* inbound scatter gather data */
-	unsigned int sg_skbs_rx;
-	unsigned int sg_frags_rx;
-	unsigned int sg_alloc_page_rx;
-};
-
-/* Routing stuff */
-struct qeth_routing_info {
-	enum qeth_routing_types type;
-};
-
-/* IPA stuff */
-struct qeth_ipa_info {
-	__u32 supported_funcs;
-	__u32 enabled_funcs;
-};
-
-static inline int
-qeth_is_ipa_supported(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
-{
-	return (ipa->supported_funcs & func);
-}
-
-static inline int
-qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
-{
-	return (ipa->supported_funcs & ipa->enabled_funcs & func);
-}
-
-#define qeth_adp_supported(c,f) \
-	qeth_is_ipa_supported(&c->options.adp, f)
-#define qeth_adp_enabled(c,f) \
-	qeth_is_ipa_enabled(&c->options.adp, f)
-#define qeth_is_supported(c,f) \
-	qeth_is_ipa_supported(&c->options.ipa4, f)
-#define qeth_is_enabled(c,f) \
-	qeth_is_ipa_enabled(&c->options.ipa4, f)
-#ifdef CONFIG_QETH_IPV6
-#define qeth_is_supported6(c,f) \
-	qeth_is_ipa_supported(&c->options.ipa6, f)
-#define qeth_is_enabled6(c,f) \
-	qeth_is_ipa_enabled(&c->options.ipa6, f)
-#else /* CONFIG_QETH_IPV6 */
-#define qeth_is_supported6(c,f) 0
-#define qeth_is_enabled6(c,f) 0
-#endif /* CONFIG_QETH_IPV6 */
-#define qeth_is_ipafunc_supported(c,prot,f) \
-	 (prot==QETH_PROT_IPV6)? qeth_is_supported6(c,f):qeth_is_supported(c,f)
-#define qeth_is_ipafunc_enabled(c,prot,f) \
-	 (prot==QETH_PROT_IPV6)? qeth_is_enabled6(c,f):qeth_is_enabled(c,f)
-
-
-#define QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT 0x0101
-#define QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT 0x0101
-#define QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT 0x4108
-#define QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT 0x5108
-
-#define QETH_MODELLIST_ARRAY \
-	{{0x1731,0x01,0x1732,0x01,QETH_CARD_TYPE_OSAE,1, \
-	QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \
-	QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \
-	QETH_MAX_QUEUES,0}, \
-	{0x1731,0x05,0x1732,0x05,QETH_CARD_TYPE_IQD,0, \
-	QETH_IDX_FUNC_LEVEL_IQD_ENA_IPAT, \
-	QETH_IDX_FUNC_LEVEL_IQD_DIS_IPAT, \
-	QETH_MAX_QUEUES,0x103}, \
-	{0x1731,0x06,0x1732,0x06,QETH_CARD_TYPE_OSN,0, \
-	QETH_IDX_FUNC_LEVEL_OSAE_ENA_IPAT, \
-	QETH_IDX_FUNC_LEVEL_OSAE_DIS_IPAT, \
-	QETH_MAX_QUEUES,0}, \
-	{0,0,0,0,0,0,0,0,0}}
-
-#define QETH_REAL_CARD		1
-#define QETH_VLAN_CARD		2
-#define QETH_BUFSIZE	 	4096
-
-/**
- * some more defs
- */
-#define IF_NAME_LEN	 	16
-#define QETH_TX_TIMEOUT		100 * HZ
-#define QETH_RCD_TIMEOUT	60 * HZ
-#define QETH_HEADER_SIZE	32
-#define MAX_PORTNO 		15
-#define QETH_FAKE_LL_LEN_ETH	ETH_HLEN
-#define QETH_FAKE_LL_LEN_TR	(sizeof(struct trh_hdr)-TR_MAXRIFLEN+sizeof(struct trllc))
-#define QETH_FAKE_LL_V6_ADDR_POS 24
-
-/*IPv6 address autoconfiguration stuff*/
-#define UNIQUE_ID_IF_CREATE_ADDR_FAILED 0xfffe
-#define UNIQUE_ID_NOT_BY_CARD 		0x10000
-
-/*****************************************************************************/
-/* QDIO queue and buffer handling                                            */
-/*****************************************************************************/
-#define QETH_MAX_QUEUES 4
-#define QETH_IN_BUF_SIZE_DEFAULT 65536
-#define QETH_IN_BUF_COUNT_DEFAULT 16
-#define QETH_IN_BUF_COUNT_MIN 8
-#define QETH_IN_BUF_COUNT_MAX 128
-#define QETH_MAX_BUFFER_ELEMENTS(card) ((card)->qdio.in_buf_size >> 12)
-#define QETH_IN_BUF_REQUEUE_THRESHOLD(card) \
-		((card)->qdio.in_buf_pool.buf_count / 2)
-
-/* buffers we have to be behind before we get a PCI */
-#define QETH_PCI_THRESHOLD_A(card) ((card)->qdio.in_buf_pool.buf_count+1)
-/*enqueued free buffers left before we get a PCI*/
-#define QETH_PCI_THRESHOLD_B(card) 0
-/*not used unless the microcode gets patched*/
-#define QETH_PCI_TIMER_VALUE(card) 3
-
-#define QETH_MIN_INPUT_THRESHOLD 1
-#define QETH_MAX_INPUT_THRESHOLD 500
-#define QETH_MIN_OUTPUT_THRESHOLD 1
-#define QETH_MAX_OUTPUT_THRESHOLD 300
-
-/* priority queing */
-#define QETH_PRIOQ_DEFAULT QETH_NO_PRIO_QUEUEING
-#define QETH_DEFAULT_QUEUE    2
-#define QETH_NO_PRIO_QUEUEING 0
-#define QETH_PRIO_Q_ING_PREC  1
-#define QETH_PRIO_Q_ING_TOS   2
-#define IP_TOS_LOWDELAY 0x10
-#define IP_TOS_HIGHTHROUGHPUT 0x08
-#define IP_TOS_HIGHRELIABILITY 0x04
-#define IP_TOS_NOTIMPORTANT 0x02
-
-/* Packing */
-#define QETH_LOW_WATERMARK_PACK  2
-#define QETH_HIGH_WATERMARK_PACK 5
-#define QETH_WATERMARK_PACK_FUZZ 1
-
-#define QETH_IP_HEADER_SIZE 40
-
-/* large receive scatter gather copy break */
-#define QETH_RX_SG_CB (PAGE_SIZE >> 1)
-
-struct qeth_hdr_layer3 {
-	__u8  id;
-	__u8  flags;
-	__u16 inbound_checksum; /*TSO:__u16 seqno */
-	__u32 token;		/*TSO: __u32 reserved */
-	__u16 length;
-	__u8  vlan_prio;
-	__u8  ext_flags;
-	__u16 vlan_id;
-	__u16 frame_offset;
-	__u8  dest_addr[16];
-} __attribute__ ((packed));
-
-struct qeth_hdr_layer2 {
-	__u8 id;
-	__u8 flags[3];
-	__u8 port_no;
-	__u8 hdr_length;
-	__u16 pkt_length;
-	__u16 seq_no;
-	__u16 vlan_id;
-	__u32 reserved;
-	__u8 reserved2[16];
-} __attribute__ ((packed));
-
-struct qeth_hdr_osn {
-	__u8 id;
-	__u8 reserved;
-	__u16 seq_no;
-	__u16 reserved2;
-	__u16 control_flags;
-	__u16 pdu_length;
-	__u8 reserved3[18];
-	__u32 ccid;
-} __attribute__ ((packed));
-
-struct qeth_hdr {
-	union {
-		struct qeth_hdr_layer2 l2;
-		struct qeth_hdr_layer3 l3;
-		struct qeth_hdr_osn    osn;
-	} hdr;
-} __attribute__ ((packed));
-
-/*TCP Segmentation Offload header*/
-struct qeth_hdr_ext_tso {
-        __u16 hdr_tot_len;
-        __u8  imb_hdr_no;
-        __u8  reserved;
-        __u8  hdr_type;
-        __u8  hdr_version;
-        __u16 hdr_len;
-        __u32 payload_len;
-        __u16 mss;
-        __u16 dg_hdr_len;
-        __u8  padding[16];
-} __attribute__ ((packed));
-
-struct qeth_hdr_tso {
-        struct qeth_hdr hdr; 	/*hdr->hdr.l3.xxx*/
-	struct qeth_hdr_ext_tso ext;
-} __attribute__ ((packed));
-
-
-/* flags for qeth_hdr.flags */
-#define QETH_HDR_PASSTHRU 0x10
-#define QETH_HDR_IPV6     0x80
-#define QETH_HDR_CAST_MASK 0x07
-enum qeth_cast_flags {
-	QETH_CAST_UNICAST   = 0x06,
-	QETH_CAST_MULTICAST = 0x04,
-	QETH_CAST_BROADCAST = 0x05,
-	QETH_CAST_ANYCAST   = 0x07,
-	QETH_CAST_NOCAST    = 0x00,
-};
-
-enum qeth_layer2_frame_flags {
-	QETH_LAYER2_FLAG_MULTICAST = 0x01,
-	QETH_LAYER2_FLAG_BROADCAST = 0x02,
-	QETH_LAYER2_FLAG_UNICAST   = 0x04,
-	QETH_LAYER2_FLAG_VLAN      = 0x10,
-};
-
-enum qeth_header_ids {
-	QETH_HEADER_TYPE_LAYER3 = 0x01,
-	QETH_HEADER_TYPE_LAYER2 = 0x02,
-	QETH_HEADER_TYPE_TSO	= 0x03,
-	QETH_HEADER_TYPE_OSN    = 0x04,
-};
-/* flags for qeth_hdr.ext_flags */
-#define QETH_HDR_EXT_VLAN_FRAME       0x01
-#define QETH_HDR_EXT_TOKEN_ID         0x02
-#define QETH_HDR_EXT_INCLUDE_VLAN_TAG 0x04
-#define QETH_HDR_EXT_SRC_MAC_ADDR     0x08
-#define QETH_HDR_EXT_CSUM_HDR_REQ     0x10
-#define QETH_HDR_EXT_CSUM_TRANSP_REQ  0x20
-#define QETH_HDR_EXT_UDP_TSO          0x40 /*bit off for TCP*/
-
-static inline int
-qeth_is_last_sbale(struct qdio_buffer_element *sbale)
-{
-	return (sbale->flags & SBAL_FLAGS_LAST_ENTRY);
-}
-
-enum qeth_qdio_buffer_states {
-	/*
-	 * inbound: read out by driver; owned by hardware in order to be filled
-	 * outbound: owned by driver in order to be filled
-	 */
-	QETH_QDIO_BUF_EMPTY,
-	/*
-	 * inbound: filled by hardware; owned by driver in order to be read out
-	 * outbound: filled by driver; owned by hardware in order to be sent
-	 */
-	QETH_QDIO_BUF_PRIMED,
-};
-
-enum qeth_qdio_info_states {
-	QETH_QDIO_UNINITIALIZED,
-	QETH_QDIO_ALLOCATED,
-	QETH_QDIO_ESTABLISHED,
-	QETH_QDIO_CLEANING
-};
-
-struct qeth_buffer_pool_entry {
-	struct list_head list;
-	struct list_head init_list;
-	void *elements[QDIO_MAX_ELEMENTS_PER_BUFFER];
-};
-
-struct qeth_qdio_buffer_pool {
-	struct list_head entry_list;
-	int buf_count;
-};
-
-struct qeth_qdio_buffer {
-	struct qdio_buffer *buffer;
-	volatile enum qeth_qdio_buffer_states state;
-	/* the buffer pool entry currently associated to this buffer */
-	struct qeth_buffer_pool_entry *pool_entry;
-};
-
-struct qeth_qdio_q {
-	struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
-	struct qeth_qdio_buffer bufs[QDIO_MAX_BUFFERS_PER_Q];
-	/*
-	 * buf_to_init means "buffer must be initialized by driver and must
-	 * be made available for hardware" -> state is set to EMPTY
-	 */
-	volatile int next_buf_to_init;
-} __attribute__ ((aligned(256)));
-
-/* possible types of qeth large_send support */
-enum qeth_large_send_types {
-	QETH_LARGE_SEND_NO,
-	QETH_LARGE_SEND_EDDP,
-	QETH_LARGE_SEND_TSO,
-};
-
-struct qeth_qdio_out_buffer {
-	struct qdio_buffer *buffer;
-	atomic_t state;
-	volatile int next_element_to_fill;
-	struct sk_buff_head skb_list;
-	struct list_head ctx_list;
-};
-
-struct qeth_card;
-
-enum qeth_out_q_states {
-       QETH_OUT_Q_UNLOCKED,
-       QETH_OUT_Q_LOCKED,
-       QETH_OUT_Q_LOCKED_FLUSH,
-};
-
-struct qeth_qdio_out_q {
-	struct qdio_buffer qdio_bufs[QDIO_MAX_BUFFERS_PER_Q];
-	struct qeth_qdio_out_buffer bufs[QDIO_MAX_BUFFERS_PER_Q];
-	int queue_no;
-	struct qeth_card *card;
-	atomic_t state;
-	volatile int do_pack;
-	/*
-	 * index of buffer to be filled by driver; state EMPTY or PACKING
-	 */
-	volatile int next_buf_to_fill;
-	/*
-	 * number of buffers that are currently filled (PRIMED)
-	 * -> these buffers are hardware-owned
-	 */
-	atomic_t used_buffers;
-	/* indicates whether PCI flag must be set (or if one is outstanding) */
-	atomic_t set_pci_flags_count;
-} __attribute__ ((aligned(256)));
-
-struct qeth_qdio_info {
-	atomic_t state;
-	/* input */
-	struct qeth_qdio_q *in_q;
-	struct qeth_qdio_buffer_pool in_buf_pool;
-	struct qeth_qdio_buffer_pool init_pool;
-	int in_buf_size;
-
-	/* output */
-	int no_out_queues;
-	struct qeth_qdio_out_q **out_qs;
-
-	/* priority queueing */
-	int do_prio_queueing;
-	int default_out_queue;
-};
-
-enum qeth_send_errors {
-	QETH_SEND_ERROR_NONE,
-	QETH_SEND_ERROR_LINK_FAILURE,
-	QETH_SEND_ERROR_RETRY,
-	QETH_SEND_ERROR_KICK_IT,
-};
-
-#define QETH_ETH_MAC_V4      0x0100 /* like v4 */
-#define QETH_ETH_MAC_V6      0x3333 /* like v6 */
-/* tr mc mac is longer, but that will be enough to detect mc frames */
-#define QETH_TR_MAC_NC       0xc000 /* non-canonical */
-#define QETH_TR_MAC_C        0x0300 /* canonical */
-
-#define DEFAULT_ADD_HHLEN 0
-#define MAX_ADD_HHLEN 1024
-
-/**
- * buffer stuff for read channel
- */
-#define QETH_CMD_BUFFER_NO	8
-
-/**
- *  channel state machine
- */
-enum qeth_channel_states {
-	CH_STATE_UP,
-	CH_STATE_DOWN,
-	CH_STATE_ACTIVATING,
-	CH_STATE_HALTED,
-	CH_STATE_STOPPED,
-	CH_STATE_RCD,
-	CH_STATE_RCD_DONE,
-};
-/**
- * card state machine
- */
-enum qeth_card_states {
-	CARD_STATE_DOWN,
-	CARD_STATE_HARDSETUP,
-	CARD_STATE_SOFTSETUP,
-	CARD_STATE_UP,
-	CARD_STATE_RECOVER,
-};
-
-/**
- * Protocol versions
- */
-enum qeth_prot_versions {
-	QETH_PROT_IPV4 = 0x0004,
-	QETH_PROT_IPV6 = 0x0006,
-};
-
-enum qeth_ip_types {
-	QETH_IP_TYPE_NORMAL,
-	QETH_IP_TYPE_VIPA,
-	QETH_IP_TYPE_RXIP,
-	QETH_IP_TYPE_DEL_ALL_MC,
-};
-
-enum qeth_cmd_buffer_state {
-	BUF_STATE_FREE,
-	BUF_STATE_LOCKED,
-	BUF_STATE_PROCESSED,
-};
-/**
- * IP address and multicast list
- */
-struct qeth_ipaddr {
-	struct list_head entry;
-	enum qeth_ip_types type;
-	enum qeth_ipa_setdelip_flags set_flags;
-	enum qeth_ipa_setdelip_flags del_flags;
-	int is_multicast;
-	volatile int users;
-	enum qeth_prot_versions proto;
-	unsigned char mac[OSA_ADDR_LEN];
-	union {
-		struct {
-			unsigned int addr;
-			unsigned int mask;
-		} a4;
-		struct {
-			struct in6_addr addr;
-			unsigned int pfxlen;
-		} a6;
-	} u;
-};
-
-struct qeth_ipato_entry {
-	struct list_head entry;
-	enum qeth_prot_versions proto;
-	char addr[16];
-	int mask_bits;
-};
-
-struct qeth_ipato {
-	int enabled;
-	int invert4;
-	int invert6;
-	struct list_head entries;
-};
-
-struct qeth_channel;
-
-struct qeth_cmd_buffer {
-	enum qeth_cmd_buffer_state state;
-	struct qeth_channel *channel;
-	unsigned char *data;
-	int rc;
-	void (*callback) (struct qeth_channel *, struct qeth_cmd_buffer *);
-};
-
-
-/**
- * definition of a qeth channel, used for read and write
- */
-struct qeth_channel {
-	enum qeth_channel_states state;
-	struct ccw1 ccw;
-	spinlock_t iob_lock;
-	wait_queue_head_t wait_q;
-	struct tasklet_struct irq_tasklet;
-	struct ccw_device *ccwdev;
-/*command buffer for control data*/
-	struct qeth_cmd_buffer iob[QETH_CMD_BUFFER_NO];
-	atomic_t irq_pending;
-	volatile int io_buf_no;
-	volatile int buf_no;
-};
-
-/**
- *  OSA card related definitions
- */
-struct qeth_token {
-	__u32 issuer_rm_w;
-	__u32 issuer_rm_r;
-	__u32 cm_filter_w;
-	__u32 cm_filter_r;
-	__u32 cm_connection_w;
-	__u32 cm_connection_r;
-	__u32 ulp_filter_w;
-	__u32 ulp_filter_r;
-	__u32 ulp_connection_w;
-	__u32 ulp_connection_r;
-};
-
-struct qeth_seqno {
-	__u32 trans_hdr;
-	__u32 pdu_hdr;
-	__u32 pdu_hdr_ack;
-	__u16 ipa;
-	__u32 pkt_seqno;
-};
-
-struct qeth_reply {
-	struct list_head list;
-	wait_queue_head_t wait_q;
-	int (*callback)(struct qeth_card *,struct qeth_reply *,unsigned long);
- 	u32 seqno;
-	unsigned long offset;
-	atomic_t received;
-	int rc;
-	void *param;
-	struct qeth_card *card;
-	atomic_t refcnt;
-};
-
-
-struct qeth_card_blkt {
-	int time_total;
-	int inter_packet;
-	int inter_packet_jumbo;
-};
-
-#define QETH_BROADCAST_WITH_ECHO    0x01
-#define QETH_BROADCAST_WITHOUT_ECHO 0x02
-#define QETH_LAYER2_MAC_READ	    0x01
-#define QETH_LAYER2_MAC_REGISTERED  0x02
-struct qeth_card_info {
-	unsigned short unit_addr2;
-	unsigned short cula;
-	unsigned short chpid;
-	__u16 func_level;
-	char mcl_level[QETH_MCL_LENGTH + 1];
-	int guestlan;
-	int mac_bits;
-	int portname_required;
-	int portno;
-	char portname[9];
-	enum qeth_card_types type;
-	enum qeth_link_types link_type;
-	int is_multicast_different;
-	int initial_mtu;
-	int max_mtu;
-	int broadcast_capable;
-	int unique_id;
-	struct qeth_card_blkt blkt;
-	__u32 csum_mask;
-	enum qeth_ipa_promisc_modes promisc_mode;
-};
-
-struct qeth_card_options {
-	struct qeth_routing_info route4;
-	struct qeth_ipa_info ipa4;
-	struct qeth_ipa_info adp; /*Adapter parameters*/
-#ifdef CONFIG_QETH_IPV6
-	struct qeth_routing_info route6;
-	struct qeth_ipa_info ipa6;
-#endif /* QETH_IPV6 */
-	enum qeth_checksum_types checksum_type;
-	int broadcast_mode;
-	int macaddr_mode;
-	int fake_broadcast;
-	int add_hhlen;
-	int fake_ll;
-	int layer2;
-	enum qeth_large_send_types large_send;
-	int performance_stats;
-	int rx_sg_cb;
-};
-
-/*
- * thread bits for qeth_card thread masks
- */
-enum qeth_threads {
-	QETH_SET_IP_THREAD  = 1,
-	QETH_RECOVER_THREAD = 2,
-	QETH_SET_PROMISC_MODE_THREAD = 4,
-};
-
-struct qeth_osn_info {
-	int (*assist_cb)(struct net_device *dev, void *data);
-	int (*data_cb)(struct sk_buff *skb);
-};
-
-struct qeth_card {
-	struct list_head list;
-	enum qeth_card_states state;
-	int lan_online;
-	spinlock_t lock;
-/*hardware and sysfs stuff*/
-	struct ccwgroup_device *gdev;
-	struct qeth_channel read;
-	struct qeth_channel write;
-	struct qeth_channel data;
-
-	struct net_device *dev;
-	struct net_device_stats stats;
-
-	struct qeth_card_info info;
-	struct qeth_token token;
-	struct qeth_seqno seqno;
-	struct qeth_card_options options;
-
-	wait_queue_head_t wait_q;
-#ifdef CONFIG_QETH_VLAN
-	spinlock_t vlanlock;
-	struct vlan_group *vlangrp;
-#endif
-	struct work_struct kernel_thread_starter;
-	spinlock_t thread_mask_lock;
-	volatile unsigned long thread_start_mask;
-	volatile unsigned long thread_allowed_mask;
-	volatile unsigned long thread_running_mask;
-	spinlock_t ip_lock;
-	struct list_head ip_list;
-	struct list_head *ip_tbd_list;
-	struct qeth_ipato ipato;
-	struct list_head cmd_waiter_list;
-	/* QDIO buffer handling */
-	struct qeth_qdio_info qdio;
-	struct qeth_perf_stats perf_stats;
-	int use_hard_stop;
-	const struct header_ops *orig_header_ops;
-	struct qeth_osn_info osn_info;
-	atomic_t force_alloc_skb;
-};
-
-struct qeth_card_list_struct {
-	struct list_head list;
-	rwlock_t rwlock;
-};
-
-extern struct qeth_card_list_struct qeth_card_list;
-
-/*notifier list */
-struct qeth_notify_list_struct {
-	struct list_head list;
-	struct task_struct *task;
-	int signum;
-};
-extern spinlock_t qeth_notify_lock;
-extern struct list_head qeth_notify_list;
-
-/*some helper functions*/
-
-#define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "")
-
-static inline __u8
-qeth_get_ipa_adp_type(enum qeth_link_types link_type)
-{
-	switch (link_type) {
-	case QETH_LINK_TYPE_HSTR:
-		return 2;
-	default:
-		return 1;
-	}
-}
-
-static inline struct sk_buff *
-qeth_realloc_headroom(struct qeth_card *card, struct sk_buff *skb, int size)
-{
-	struct sk_buff *new_skb = skb;
-
-	if (skb_headroom(skb) >= size)
-		return skb;
-	new_skb = skb_realloc_headroom(skb, size);
-	if (!new_skb) 
-		PRINT_ERR("Could not realloc headroom for qeth_hdr "
-			  "on interface %s", QETH_CARD_IFNAME(card));
-	return new_skb;
-}
-
-static inline struct sk_buff *
-qeth_pskb_unshare(struct sk_buff *skb, gfp_t pri)
-{
-        struct sk_buff *nskb;
-        if (!skb_cloned(skb))
-                return skb;
-        nskb = skb_copy(skb, pri);
-        return nskb;
-}
-
-static inline void *
-qeth_push_skb(struct qeth_card *card, struct sk_buff *skb, int size)
-{
-        void *hdr;
-
-	hdr = (void *) skb_push(skb, size);
-        /*
-         * sanity check, the Linux memory allocation scheme should
-         * never present us cases like this one (the qdio header size plus
-         * the first 40 bytes of the paket cross a 4k boundary)
-         */
-        if ((((unsigned long) hdr) & (~(PAGE_SIZE - 1))) !=
-            (((unsigned long) hdr + size +
-              QETH_IP_HEADER_SIZE) & (~(PAGE_SIZE - 1)))) {
-                PRINT_ERR("Misaligned packet on interface %s. Discarded.",
-                          QETH_CARD_IFNAME(card));
-                return NULL;
-        }
-        return hdr;
-}
-
-
-static inline int
-qeth_get_hlen(__u8 link_type)
-{
-#ifdef CONFIG_QETH_IPV6
-	switch (link_type) {
-	case QETH_LINK_TYPE_HSTR:
-	case QETH_LINK_TYPE_LANE_TR:
-		return sizeof(struct qeth_hdr_tso) + TR_HLEN;
-	default:
-#ifdef CONFIG_QETH_VLAN
-		return sizeof(struct qeth_hdr_tso) + VLAN_ETH_HLEN;
-#else
-		return sizeof(struct qeth_hdr_tso) + ETH_HLEN;
-#endif
-	}
-#else  /* CONFIG_QETH_IPV6 */
-#ifdef CONFIG_QETH_VLAN
-	return sizeof(struct qeth_hdr_tso) + VLAN_HLEN;
-#else
-	return sizeof(struct qeth_hdr_tso);
-#endif
-#endif /* CONFIG_QETH_IPV6 */
-}
-
-static inline unsigned short
-qeth_get_netdev_flags(struct qeth_card *card)
-{
-	if (card->options.layer2 &&
-	   (card->info.type == QETH_CARD_TYPE_OSAE))
-		return 0;
-	switch (card->info.type) {
-	case QETH_CARD_TYPE_IQD:
-	case QETH_CARD_TYPE_OSN:
-		return IFF_NOARP;
-#ifdef CONFIG_QETH_IPV6
-	default:
-		return 0;
-#else
-	default:
-		return IFF_NOARP;
-#endif
-	}
-}
-
-static inline int
-qeth_get_initial_mtu_for_card(struct qeth_card * card)
-{
-	switch (card->info.type) {
-	case QETH_CARD_TYPE_UNKNOWN:
-		return 1500;
-	case QETH_CARD_TYPE_IQD:
-		return card->info.max_mtu;
-	case QETH_CARD_TYPE_OSAE:
-		switch (card->info.link_type) {
-		case QETH_LINK_TYPE_HSTR:
-		case QETH_LINK_TYPE_LANE_TR:
-			return 2000;
-		default:
-			return 1492;
-		}
-	default:
-		return 1500;
-	}
-}
-
-static inline int
-qeth_get_max_mtu_for_card(int cardtype)
-{
-	switch (cardtype) {
-
-	case QETH_CARD_TYPE_UNKNOWN:
-	case QETH_CARD_TYPE_OSAE:
-	case QETH_CARD_TYPE_OSN:
-		return 61440;
-	case QETH_CARD_TYPE_IQD:
-		return 57344;
-	default:
-		return 1500;
-	}
-}
-
-static inline int
-qeth_get_mtu_out_of_mpc(int cardtype)
-{
-	switch (cardtype) {
-	case QETH_CARD_TYPE_IQD:
-		return 1;
-	default:
-		return 0;
-	}
-}
-
-static inline int
-qeth_get_mtu_outof_framesize(int framesize)
-{
-	switch (framesize) {
-	case 0x4000:
-		return 8192;
-	case 0x6000:
-		return 16384;
-	case 0xa000:
-		return 32768;
-	case 0xffff:
-		return 57344;
-	default:
-		return 0;
-	}
-}
-
-static inline int
-qeth_mtu_is_valid(struct qeth_card * card, int mtu)
-{
-	switch (card->info.type) {
-	case QETH_CARD_TYPE_OSAE:
-		return ((mtu >= 576) && (mtu <= 61440));
-	case QETH_CARD_TYPE_IQD:
-		return ((mtu >= 576) &&
-			(mtu <= card->info.max_mtu + 4096 - 32));
-	case QETH_CARD_TYPE_OSN:
-	case QETH_CARD_TYPE_UNKNOWN:
-	default:
-		return 1;
-	}
-}
-
-static inline int
-qeth_get_arphdr_type(int cardtype, int linktype)
-{
-	switch (cardtype) {
-	case QETH_CARD_TYPE_OSAE:
-	case QETH_CARD_TYPE_OSN:
-		switch (linktype) {
-		case QETH_LINK_TYPE_LANE_TR:
-		case QETH_LINK_TYPE_HSTR:
-			return ARPHRD_IEEE802_TR;
-		default:
-			return ARPHRD_ETHER;
-		}
-	case QETH_CARD_TYPE_IQD:
-	default:
-		return ARPHRD_ETHER;
-	}
-}
-
-static inline int
-qeth_get_micros(void)
-{
-	return (int) (get_clock() >> 12);
-}
-
-static inline int
-qeth_get_qdio_q_format(struct qeth_card *card)
-{
-	switch (card->info.type) {
-	case QETH_CARD_TYPE_IQD:
-		return 2;
-	default:
-		return 0;
-	}
-}
-
-static inline int
-qeth_isxdigit(char * buf)
-{
-	while (*buf) {
-		if (!isxdigit(*buf++))
-			return 0;
-	}
-	return 1;
-}
-
-static inline void
-qeth_ipaddr4_to_string(const __u8 *addr, char *buf)
-{
-	sprintf(buf, "%i.%i.%i.%i", addr[0], addr[1], addr[2], addr[3]);
-}
-
-static inline int
-qeth_string_to_ipaddr4(const char *buf, __u8 *addr)
-{
-	int count = 0, rc = 0;
-	int in[4];
-	char c;
-
-	rc = sscanf(buf, "%u.%u.%u.%u%c",
-		    &in[0], &in[1], &in[2], &in[3], &c);
-	if (rc != 4 && (rc != 5 || c != '\n'))
-		return -EINVAL;
-	for (count = 0; count < 4; count++) {
-		if (in[count] > 255)
-			return -EINVAL;
-		addr[count] = in[count];
-	}
-	return 0;
-}
-
-static inline void
-qeth_ipaddr6_to_string(const __u8 *addr, char *buf)
-{
-	sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x"
-		     ":%02x%02x:%02x%02x:%02x%02x:%02x%02x",
-		     addr[0], addr[1], addr[2], addr[3],
-		     addr[4], addr[5], addr[6], addr[7],
-		     addr[8], addr[9], addr[10], addr[11],
-		     addr[12], addr[13], addr[14], addr[15]);
-}
-
-static inline int
-qeth_string_to_ipaddr6(const char *buf, __u8 *addr)
-{
-	const char *end, *end_tmp, *start;
-	__u16 *in;
-        char num[5];
-        int num2, cnt, out, found, save_cnt;
-        unsigned short in_tmp[8] = {0, };
-
-	cnt = out = found = save_cnt = num2 = 0;
-        end = start = buf;
-	in = (__u16 *) addr;
-	memset(in, 0, 16);
-        while (*end) {
-                end = strchr(start,':');
-                if (end == NULL) {
-                        end = buf + strlen(buf);
-			if ((end_tmp = strchr(start, '\n')) != NULL)
-				end = end_tmp;
-			out = 1;
-                }
-                if ((end - start)) {
-                        memset(num, 0, 5);
-			if ((end - start) > 4)
-				return -EINVAL;
-                        memcpy(num, start, end - start);
-			if (!qeth_isxdigit(num))
-				return -EINVAL;
-                        sscanf(start, "%x", &num2);
-                        if (found)
-                                in_tmp[save_cnt++] = num2;
-                        else
-                                in[cnt++] = num2;
-                        if (out)
-                                break;
-                } else {
-			if (found)
-				return -EINVAL;
-                        found = 1;
-		}
-		start = ++end;
-        }
-	if (cnt + save_cnt > 8)
-		return -EINVAL;
-        cnt = 7;
-	while (save_cnt)
-                in[cnt--] = in_tmp[--save_cnt];
-	return 0;
-}
-
-static inline void
-qeth_ipaddr_to_string(enum qeth_prot_versions proto, const __u8 *addr,
-		      char *buf)
-{
-	if (proto == QETH_PROT_IPV4)
-		qeth_ipaddr4_to_string(addr, buf);
-	else if (proto == QETH_PROT_IPV6)
-		qeth_ipaddr6_to_string(addr, buf);
-}
-
-static inline int
-qeth_string_to_ipaddr(const char *buf, enum qeth_prot_versions proto,
-		      __u8 *addr)
-{
-	if (proto == QETH_PROT_IPV4)
-		return qeth_string_to_ipaddr4(buf, addr);
-	else if (proto == QETH_PROT_IPV6)
-		return qeth_string_to_ipaddr6(buf, addr);
-	else
-		return -EINVAL;
-}
-
-extern int
-qeth_setrouting_v4(struct qeth_card *);
-extern int
-qeth_setrouting_v6(struct qeth_card *);
-
-extern int
-qeth_add_ipato_entry(struct qeth_card *, struct qeth_ipato_entry *);
-
-extern void
-qeth_del_ipato_entry(struct qeth_card *, enum qeth_prot_versions, u8 *, int);
-
-extern int
-qeth_add_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
-
-extern void
-qeth_del_vipa(struct qeth_card *, enum qeth_prot_versions, const u8 *);
-
-extern int
-qeth_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
-
-extern void
-qeth_del_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
-
-extern int
-qeth_notifier_register(struct task_struct *, int );
-
-extern int
-qeth_notifier_unregister(struct task_struct * );
-
-extern void
-qeth_schedule_recovery(struct qeth_card *);
-
-extern int
-qeth_realloc_buffer_pool(struct qeth_card *, int);
-
-extern int
-qeth_set_large_send(struct qeth_card *, enum qeth_large_send_types);
-
-extern void
-qeth_fill_header(struct qeth_card *, struct qeth_hdr *,
-		 struct sk_buff *, int, int);
-extern void
-qeth_flush_buffers(struct qeth_qdio_out_q *, int, int, int);
-
-extern int
-qeth_osn_assist(struct net_device *, void *, int);
-
-extern int
-qeth_osn_register(unsigned char *read_dev_no,
-                 struct net_device **,
-                 int (*assist_cb)(struct net_device *, void *),
-                 int (*data_cb)(struct sk_buff *));
-
-extern void
-qeth_osn_deregister(struct net_device *);
-
-#endif /* __QETH_H__ */
Index: my_git/drivers/s390/net/qeth_eddp.c
===================================================================
--- my_git.orig/drivers/s390/net/qeth_eddp.c	2008-02-15 08:49:22.000000000 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,634 +0,0 @@
-/*
- * linux/drivers/s390/net/qeth_eddp.c
- *
- * Enhanced Device Driver Packing (EDDP) support for the qeth driver.
- *
- * Copyright 2004 IBM Corporation
- *
- *    Author(s): Thomas Spatzier <tspat@de.ibm.com>
- *
- */
-#include <linux/errno.h>
-#include <linux/ip.h>
-#include <linux/inetdevice.h>
-#include <linux/netdevice.h>
-#include <linux/kernel.h>
-#include <linux/tcp.h>
-#include <net/tcp.h>
-#include <linux/skbuff.h>
-
-#include <net/ip.h>
-
-#include "qeth.h"
-#include "qeth_mpc.h"
-#include "qeth_eddp.h"
-
-int
-qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *queue,
-				    struct qeth_eddp_context *ctx)
-{
-	int index = queue->next_buf_to_fill;
-	int elements_needed = ctx->num_elements;
-	int elements_in_buffer;
-	int skbs_in_buffer;
-	int buffers_needed = 0;
-
-	QETH_DBF_TEXT(trace, 5, "eddpcbfc");
-	while(elements_needed > 0) {
-		buffers_needed++;
-		if (atomic_read(&queue->bufs[index].state) !=
-				QETH_QDIO_BUF_EMPTY)
-			return -EBUSY;
-
-		elements_in_buffer = QETH_MAX_BUFFER_ELEMENTS(queue->card) -
-				     queue->bufs[index].next_element_to_fill;
-		skbs_in_buffer = elements_in_buffer / ctx->elements_per_skb;
-		elements_needed -= skbs_in_buffer * ctx->elements_per_skb;
-		index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
-	}
-	return buffers_needed;
-}
-
-static void
-qeth_eddp_free_context(struct qeth_eddp_context *ctx)
-{
-	int i;
-
-	QETH_DBF_TEXT(trace, 5, "eddpfctx");
-	for (i = 0; i < ctx->num_pages; ++i)
-		free_page((unsigned long)ctx->pages[i]);
-	kfree(ctx->pages);
-	kfree(ctx->elements);
-	kfree(ctx);
-}
-
-
-static inline void
-qeth_eddp_get_context(struct qeth_eddp_context *ctx)
-{
-	atomic_inc(&ctx->refcnt);
-}
-
-void
-qeth_eddp_put_context(struct qeth_eddp_context *ctx)
-{
-	if (atomic_dec_return(&ctx->refcnt) == 0)
-		qeth_eddp_free_context(ctx);
-}
-
-void
-qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
-{
-	struct qeth_eddp_context_reference *ref;
-
-	QETH_DBF_TEXT(trace, 6, "eddprctx");
-	while (!list_empty(&buf->ctx_list)){
-		ref = list_entry(buf->ctx_list.next,
-				 struct qeth_eddp_context_reference, list);
-		qeth_eddp_put_context(ref->ctx);
-		list_del(&ref->list);
-		kfree(ref);
-	}
-}
-
-static int
-qeth_eddp_buf_ref_context(struct qeth_qdio_out_buffer *buf,
-			  struct qeth_eddp_context *ctx)
-{
-	struct qeth_eddp_context_reference *ref;
-
-	QETH_DBF_TEXT(trace, 6, "eddprfcx");
-	ref = kmalloc(sizeof(struct qeth_eddp_context_reference), GFP_ATOMIC);
-	if (ref == NULL)
-		return -ENOMEM;
-	qeth_eddp_get_context(ctx);
-	ref->ctx = ctx;
-	list_add_tail(&ref->list, &buf->ctx_list);
-	return 0;
-}
-
-int
-qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
-		      struct qeth_eddp_context *ctx,
-		      int index)
-{
-	struct qeth_qdio_out_buffer *buf = NULL;
-	struct qdio_buffer *buffer;
-	int elements = ctx->num_elements;
-	int element = 0;
-	int flush_cnt = 0;
-	int must_refcnt = 1;
-	int i;
-
-	QETH_DBF_TEXT(trace, 5, "eddpfibu");
-	while (elements > 0) {
-		buf = &queue->bufs[index];
-		if (atomic_read(&buf->state) != QETH_QDIO_BUF_EMPTY){
-			/* normally this should not happen since we checked for
-			 * available elements in qeth_check_elements_for_context
-			 */
-			if (element == 0)
-				return -EBUSY;
-			else {
-				PRINT_WARN("could only partially fill eddp "
-					   "buffer!\n");
-				goto out;
-			}
-		}
-		/* check if the whole next skb fits into current buffer */
-		if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) -
-					buf->next_element_to_fill)
-				< ctx->elements_per_skb){
-			/* no -> go to next buffer */
-			atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
-			index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
-			flush_cnt++;
-			/* new buffer, so we have to add ctx to buffer'ctx_list
-			 * and increment ctx's refcnt */
-			must_refcnt = 1;
-			continue;
-		}
-		if (must_refcnt){
-			must_refcnt = 0;
-			if (qeth_eddp_buf_ref_context(buf, ctx)){
-				PRINT_WARN("no memory to create eddp context "
-					   "reference\n");
-				goto out_check;
-			}
-		}
-		buffer = buf->buffer;
-		/* fill one skb into buffer */
-		for (i = 0; i < ctx->elements_per_skb; ++i){
-			if (ctx->elements[element].length != 0) {
-				buffer->element[buf->next_element_to_fill].
-				addr = ctx->elements[element].addr;
-				buffer->element[buf->next_element_to_fill].
-				length = ctx->elements[element].length;
-				buffer->element[buf->next_element_to_fill].
-				flags = ctx->elements[element].flags;
-				buf->next_element_to_fill++;
-			}
-			element++;
-			elements--;
-		}
-	}
-out_check:
-	if (!queue->do_pack) {
-		QETH_DBF_TEXT(trace, 6, "fillbfnp");
-		/* set state to PRIMED -> will be flushed */
-		if (buf->next_element_to_fill > 0){
-			atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
-			flush_cnt++;
-		}
-	} else {
-		if (queue->card->options.performance_stats)
-			queue->card->perf_stats.skbs_sent_pack++;
-		QETH_DBF_TEXT(trace, 6, "fillbfpa");
-		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++;
-		}
-	}
-out:
-	return flush_cnt;
-}
-
-static void
-qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
-			      struct qeth_eddp_data *eddp, int data_len)
-{
-	u8 *page;
-	int page_remainder;
-	int page_offset;
-	int pkt_len;
-	struct qeth_eddp_element *element;
-
-	QETH_DBF_TEXT(trace, 5, "eddpcrsh");
-	page = ctx->pages[ctx->offset >> PAGE_SHIFT];
-	page_offset = ctx->offset % PAGE_SIZE;
-	element = &ctx->elements[ctx->num_elements];
-	pkt_len = eddp->nhl + eddp->thl + data_len;
-	/* FIXME: layer2 and VLAN !!! */
-	if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
-		pkt_len += ETH_HLEN;
-	if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
-		pkt_len += VLAN_HLEN;
-	/* does complete packet fit in current page ? */
-	page_remainder = PAGE_SIZE - page_offset;
-	if (page_remainder < (sizeof(struct qeth_hdr) + pkt_len)){
-		/* no -> go to start of next page */
-		ctx->offset += page_remainder;
-		page = ctx->pages[ctx->offset >> PAGE_SHIFT];
-		page_offset = 0;
-	}
-	memcpy(page + page_offset, &eddp->qh, sizeof(struct qeth_hdr));
-	element->addr = page + page_offset;
-	element->length = sizeof(struct qeth_hdr);
-	ctx->offset += sizeof(struct qeth_hdr);
-	page_offset += sizeof(struct qeth_hdr);
-	/* add mac header (?) */
-	if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
-		memcpy(page + page_offset, &eddp->mac, ETH_HLEN);
-		element->length += ETH_HLEN;
-		ctx->offset += ETH_HLEN;
-		page_offset += ETH_HLEN;
-	}
-	/* add VLAN tag */
-	if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)){
-		memcpy(page + page_offset, &eddp->vlan, VLAN_HLEN);
-		element->length += VLAN_HLEN;
-		ctx->offset += VLAN_HLEN;
-		page_offset += VLAN_HLEN;
-	}
-	/* add network header */
-	memcpy(page + page_offset, (u8 *)&eddp->nh, eddp->nhl);
-	element->length += eddp->nhl;
-	eddp->nh_in_ctx = page + page_offset;
-	ctx->offset += eddp->nhl;
-	page_offset += eddp->nhl;
-	/* add transport header */
-	memcpy(page + page_offset, (u8 *)&eddp->th, eddp->thl);
-	element->length += eddp->thl;
-	eddp->th_in_ctx = page + page_offset;
-	ctx->offset += eddp->thl;
-}
-
-static void
-qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
-			__wsum *hcsum)
-{
-	struct skb_frag_struct *frag;
-	int left_in_frag;
-	int copy_len;
-	u8 *src;
-
-	QETH_DBF_TEXT(trace, 5, "eddpcdtc");
-	if (skb_shinfo(eddp->skb)->nr_frags == 0) {
-		skb_copy_from_linear_data_offset(eddp->skb, eddp->skb_offset,
-						 dst, len);
-		*hcsum = csum_partial(eddp->skb->data + eddp->skb_offset, len,
-				      *hcsum);
-		eddp->skb_offset += len;
-	} else {
-		while (len > 0) {
-			if (eddp->frag < 0) {
-				/* we're in skb->data */
-				left_in_frag = (eddp->skb->len - eddp->skb->data_len)
-						- eddp->skb_offset;
-				src = eddp->skb->data + eddp->skb_offset;
-			} else {
-				frag = &skb_shinfo(eddp->skb)->
-					frags[eddp->frag];
-				left_in_frag = frag->size - eddp->frag_offset;
-				src = (u8 *)(
-					(page_to_pfn(frag->page) << PAGE_SHIFT)+
-					frag->page_offset + eddp->frag_offset);
-			}
-			if (left_in_frag <= 0) {
-				eddp->frag++;
-				eddp->frag_offset = 0;
-				continue;
-			}
-			copy_len = min(left_in_frag, len);
-			memcpy(dst, src, copy_len);
-			*hcsum = csum_partial(src, copy_len, *hcsum);
-			dst += copy_len;
-			eddp->frag_offset += copy_len;
-			eddp->skb_offset += copy_len;
-			len -= copy_len;
-		}
-	}
-}
-
-static void
-qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
-				  struct qeth_eddp_data *eddp, int data_len,
-				  __wsum hcsum)
-{
-	u8 *page;
-	int page_remainder;
-	int page_offset;
-	struct qeth_eddp_element *element;
-	int first_lap = 1;
-
-	QETH_DBF_TEXT(trace, 5, "eddpcsdt");
-	page = ctx->pages[ctx->offset >> PAGE_SHIFT];
-	page_offset = ctx->offset % PAGE_SIZE;
-	element = &ctx->elements[ctx->num_elements];
-	while (data_len){
-		page_remainder = PAGE_SIZE - page_offset;
-		if (page_remainder < data_len){
-			qeth_eddp_copy_data_tcp(page + page_offset, eddp,
-						page_remainder, &hcsum);
-			element->length += page_remainder;
-			if (first_lap)
-				element->flags = SBAL_FLAGS_FIRST_FRAG;
-			else
-				element->flags = SBAL_FLAGS_MIDDLE_FRAG;
-			ctx->num_elements++;
-			element++;
-			data_len -= page_remainder;
-			ctx->offset += page_remainder;
-			page = ctx->pages[ctx->offset >> PAGE_SHIFT];
-			page_offset = 0;
-			element->addr = page + page_offset;
-		} else {
-			qeth_eddp_copy_data_tcp(page + page_offset, eddp,
-						data_len, &hcsum);
-			element->length += data_len;
-			if (!first_lap)
-				element->flags = SBAL_FLAGS_LAST_FRAG;
-			ctx->num_elements++;
-			ctx->offset += data_len;
-			data_len = 0;
-		}
-		first_lap = 0;
-	}
-	((struct tcphdr *)eddp->th_in_ctx)->check = csum_fold(hcsum);
-}
-
-static __wsum
-qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp, int data_len)
-{
-	__wsum phcsum; /* pseudo header checksum */
-
-	QETH_DBF_TEXT(trace, 5, "eddpckt4");
-	eddp->th.tcp.h.check = 0;
-	/* compute pseudo header checksum */
-	phcsum = csum_tcpudp_nofold(eddp->nh.ip4.h.saddr, eddp->nh.ip4.h.daddr,
-				    eddp->thl + data_len, IPPROTO_TCP, 0);
-	/* compute checksum of tcp header */
-	return csum_partial((u8 *)&eddp->th, eddp->thl, phcsum);
-}
-
-static __wsum
-qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp, int data_len)
-{
-	__be32 proto;
-	__wsum phcsum; /* pseudo header checksum */
-
-	QETH_DBF_TEXT(trace, 5, "eddpckt6");
-	eddp->th.tcp.h.check = 0;
-	/* compute pseudo header checksum */
-	phcsum = csum_partial((u8 *)&eddp->nh.ip6.h.saddr,
-			      sizeof(struct in6_addr), 0);
-	phcsum = csum_partial((u8 *)&eddp->nh.ip6.h.daddr,
-			      sizeof(struct in6_addr), phcsum);
-	proto = htonl(IPPROTO_TCP);
-	phcsum = csum_partial((u8 *)&proto, sizeof(u32), phcsum);
-	return phcsum;
-}
-
-static struct qeth_eddp_data *
-qeth_eddp_create_eddp_data(struct qeth_hdr *qh, u8 *nh, u8 nhl, u8 *th, u8 thl)
-{
-	struct qeth_eddp_data *eddp;
-
-	QETH_DBF_TEXT(trace, 5, "eddpcrda");
-	eddp = kzalloc(sizeof(struct qeth_eddp_data), GFP_ATOMIC);
-	if (eddp){
-		eddp->nhl = nhl;
-		eddp->thl = thl;
-		memcpy(&eddp->qh, qh, sizeof(struct qeth_hdr));
-		memcpy(&eddp->nh, nh, nhl);
-		memcpy(&eddp->th, th, thl);
-		eddp->frag = -1; /* initially we're in skb->data */
-	}
-	return eddp;
-}
-
-static void
-__qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
-			     struct qeth_eddp_data *eddp)
-{
-	struct tcphdr *tcph;
-	int data_len;
-	__wsum hcsum;
-
-	QETH_DBF_TEXT(trace, 5, "eddpftcp");
-	eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl;
-       if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
-               eddp->skb_offset += sizeof(struct ethhdr);
-#ifdef CONFIG_QETH_VLAN
-               if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
-                       eddp->skb_offset += VLAN_HLEN;
-#endif /* CONFIG_QETH_VLAN */
-       }
-	tcph = tcp_hdr(eddp->skb);
-	while (eddp->skb_offset < eddp->skb->len) {
-		data_len = min((int)skb_shinfo(eddp->skb)->gso_size,
-			       (int)(eddp->skb->len - eddp->skb_offset));
-		/* prepare qdio hdr */
-		if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
-			eddp->qh.hdr.l2.pkt_length = data_len + ETH_HLEN +
-						     eddp->nhl + eddp->thl;
-#ifdef CONFIG_QETH_VLAN
-			if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
-				eddp->qh.hdr.l2.pkt_length += VLAN_HLEN;
-#endif /* CONFIG_QETH_VLAN */
-		} else
-			eddp->qh.hdr.l3.length = data_len + eddp->nhl +
-						 eddp->thl;
-		/* prepare ip hdr */
-		if (eddp->skb->protocol == htons(ETH_P_IP)){
-			eddp->nh.ip4.h.tot_len = htons(data_len + eddp->nhl +
-						 eddp->thl);
-			eddp->nh.ip4.h.check = 0;
-			eddp->nh.ip4.h.check =
-				ip_fast_csum((u8 *)&eddp->nh.ip4.h,
-						eddp->nh.ip4.h.ihl);
-		} else
-			eddp->nh.ip6.h.payload_len = htons(data_len + eddp->thl);
-		/* prepare tcp hdr */
-		if (data_len == (eddp->skb->len - eddp->skb_offset)){
-			/* last segment -> set FIN and PSH flags */
-			eddp->th.tcp.h.fin = tcph->fin;
-			eddp->th.tcp.h.psh = tcph->psh;
-		}
-		if (eddp->skb->protocol == htons(ETH_P_IP))
-			hcsum = qeth_eddp_check_tcp4_hdr(eddp, data_len);
-		else
-			hcsum = qeth_eddp_check_tcp6_hdr(eddp, data_len);
-		/* fill the next segment into the context */
-		qeth_eddp_create_segment_hdrs(ctx, eddp, data_len);
-		qeth_eddp_create_segment_data_tcp(ctx, eddp, data_len, hcsum);
-		if (eddp->skb_offset >= eddp->skb->len)
-			break;
-		/* prepare headers for next round */
-		if (eddp->skb->protocol == htons(ETH_P_IP))
-			eddp->nh.ip4.h.id = htons(ntohs(eddp->nh.ip4.h.id) + 1);
-		eddp->th.tcp.h.seq = htonl(ntohl(eddp->th.tcp.h.seq) + data_len);
-	}
-}
-
-static int
-qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
-			   struct sk_buff *skb, struct qeth_hdr *qhdr)
-{
-	struct qeth_eddp_data *eddp = NULL;
-
-	QETH_DBF_TEXT(trace, 5, "eddpficx");
-	/* create our segmentation headers and copy original headers */
-	if (skb->protocol == htons(ETH_P_IP))
-		eddp = qeth_eddp_create_eddp_data(qhdr,
-						  skb_network_header(skb),
-						  ip_hdrlen(skb),
-						  skb_transport_header(skb),
-						  tcp_hdrlen(skb));
-	else
-		eddp = qeth_eddp_create_eddp_data(qhdr,
-						  skb_network_header(skb),
-						  sizeof(struct ipv6hdr),
-						  skb_transport_header(skb),
-						  tcp_hdrlen(skb));
-
-	if (eddp == NULL) {
-		QETH_DBF_TEXT(trace, 2, "eddpfcnm");
-		return -ENOMEM;
-	}
-	if (qhdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
-		skb_set_mac_header(skb, sizeof(struct qeth_hdr));
-		memcpy(&eddp->mac, eth_hdr(skb), ETH_HLEN);
-#ifdef CONFIG_QETH_VLAN
-		if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) {
-			eddp->vlan[0] = skb->protocol;
-			eddp->vlan[1] = htons(vlan_tx_tag_get(skb));
-		}
-#endif /* CONFIG_QETH_VLAN */
-	}
-	/* the next flags will only be set on the last segment */
-	eddp->th.tcp.h.fin = 0;
-	eddp->th.tcp.h.psh = 0;
-	eddp->skb = skb;
-	/* begin segmentation and fill context */
-	__qeth_eddp_fill_context_tcp(ctx, eddp);
-	kfree(eddp);
-	return 0;
-}
-
-static void
-qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb,
-			 int hdr_len)
-{
-	int skbs_per_page;
-
-	QETH_DBF_TEXT(trace, 5, "eddpcanp");
-	/* can we put multiple skbs in one page? */
-	skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
-	if (skbs_per_page > 1){
-		ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
-				 skbs_per_page + 1;
-		ctx->elements_per_skb = 1;
-	} else {
-		/* no -> how many elements per skb? */
-		ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len +
-				     PAGE_SIZE) >> PAGE_SHIFT;
-		ctx->num_pages = ctx->elements_per_skb *
-				 (skb_shinfo(skb)->gso_segs + 1);
-	}
-	ctx->num_elements = ctx->elements_per_skb *
-			    (skb_shinfo(skb)->gso_segs + 1);
-}
-
-static struct qeth_eddp_context *
-qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb,
-				 int hdr_len)
-{
-	struct qeth_eddp_context *ctx = NULL;
-	u8 *addr;
-	int i;
-
-	QETH_DBF_TEXT(trace, 5, "creddpcg");
-	/* create the context and allocate pages */
-	ctx = kzalloc(sizeof(struct qeth_eddp_context), GFP_ATOMIC);
-	if (ctx == NULL){
-		QETH_DBF_TEXT(trace, 2, "ceddpcn1");
-		return NULL;
-	}
-	ctx->type = QETH_LARGE_SEND_EDDP;
-	qeth_eddp_calc_num_pages(ctx, skb, hdr_len);
-	if (ctx->elements_per_skb > QETH_MAX_BUFFER_ELEMENTS(card)){
-		QETH_DBF_TEXT(trace, 2, "ceddpcis");
-		kfree(ctx);
-		return NULL;
-	}
-	ctx->pages = kcalloc(ctx->num_pages, sizeof(u8 *), GFP_ATOMIC);
-	if (ctx->pages == NULL){
-		QETH_DBF_TEXT(trace, 2, "ceddpcn2");
-		kfree(ctx);
-		return NULL;
-	}
-	for (i = 0; i < ctx->num_pages; ++i){
-		addr = (u8 *)__get_free_page(GFP_ATOMIC);
-		if (addr == NULL){
-			QETH_DBF_TEXT(trace, 2, "ceddpcn3");
-			ctx->num_pages = i;
-			qeth_eddp_free_context(ctx);
-			return NULL;
-		}
-		memset(addr, 0, PAGE_SIZE);
-		ctx->pages[i] = addr;
-	}
-	ctx->elements = kcalloc(ctx->num_elements,
-				sizeof(struct qeth_eddp_element), GFP_ATOMIC);
-	if (ctx->elements == NULL){
-		QETH_DBF_TEXT(trace, 2, "ceddpcn4");
-		qeth_eddp_free_context(ctx);
-		return NULL;
-	}
-	/* reset num_elements; will be incremented again in fill_buffer to
-	 * reflect number of actually used elements */
-	ctx->num_elements = 0;
-	return ctx;
-}
-
-static struct qeth_eddp_context *
-qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
-			     struct qeth_hdr *qhdr)
-{
-	struct qeth_eddp_context *ctx = NULL;
-
-	QETH_DBF_TEXT(trace, 5, "creddpct");
-	if (skb->protocol == htons(ETH_P_IP))
-		ctx = qeth_eddp_create_context_generic(card, skb,
-						       (sizeof(struct qeth_hdr) +
-						        ip_hdrlen(skb) +
-							tcp_hdrlen(skb)));
-	else if (skb->protocol == htons(ETH_P_IPV6))
-		ctx = qeth_eddp_create_context_generic(card, skb,
-			sizeof(struct qeth_hdr) + sizeof(struct ipv6hdr) +
-			tcp_hdrlen(skb));
-	else
-		QETH_DBF_TEXT(trace, 2, "cetcpinv");
-
-	if (ctx == NULL) {
-		QETH_DBF_TEXT(trace, 2, "creddpnl");
-		return NULL;
-	}
-	if (qeth_eddp_fill_context_tcp(ctx, skb, qhdr)){
-		QETH_DBF_TEXT(trace, 2, "ceddptfe");
-		qeth_eddp_free_context(ctx);
-		return NULL;
-	}
-	atomic_set(&ctx->refcnt, 1);
-	return ctx;
-}
-
-struct qeth_eddp_context *
-qeth_eddp_create_context(struct qeth_card *card, struct sk_buff *skb,
-			 struct qeth_hdr *qhdr, unsigned char sk_protocol)
-{
-	QETH_DBF_TEXT(trace, 5, "creddpc");
-	switch (sk_protocol) {
-	case IPPROTO_TCP:
-		return qeth_eddp_create_context_tcp(card, skb, qhdr);
-	default:
-		QETH_DBF_TEXT(trace, 2, "eddpinvp");
-	}
-	return NULL;
-}
Index: my_git/drivers/s390/net/qeth_eddp.h
===================================================================
--- my_git.orig/drivers/s390/net/qeth_eddp.h	2008-02-15 08:49:22.000000000 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,84 +0,0 @@
-/*
- * linux/drivers/s390/net/qeth_eddp.h
- *
- * Header file for qeth enhanced device driver packing.
- *
- * Copyright 2004 IBM Corporation
- *
- *    Author(s): Thomas Spatzier <tspat@de.ibm.com>
- *
- */
-#ifndef __QETH_EDDP_H__
-#define __QETH_EDDP_H__
-
-struct qeth_eddp_element {
-	u32 flags;
-	u32 length;
-	void *addr;
-};
-
-struct qeth_eddp_context {
-	atomic_t refcnt;
-	enum qeth_large_send_types type;
-	int num_pages;			    /* # of allocated pages */
-	u8 **pages;			    /* pointers to pages */
-	int offset;			    /* offset in ctx during creation */
-	int num_elements;		    /* # of required 'SBALEs' */
-	struct qeth_eddp_element *elements; /* array of 'SBALEs' */
-	int elements_per_skb;		    /* # of 'SBALEs' per skb **/
-};
-
-struct qeth_eddp_context_reference {
-	struct list_head list;
-	struct qeth_eddp_context *ctx;
-};
-
-extern struct qeth_eddp_context *
-qeth_eddp_create_context(struct qeth_card *,struct sk_buff *,
-			 struct qeth_hdr *, unsigned char);
-
-extern void
-qeth_eddp_put_context(struct qeth_eddp_context *);
-
-extern int
-qeth_eddp_fill_buffer(struct qeth_qdio_out_q *,struct qeth_eddp_context *,int);
-
-extern void
-qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *);
-
-extern int
-qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *,
-				    struct qeth_eddp_context *);
-/*
- * Data used for fragmenting a IP packet.
- */
-struct qeth_eddp_data {
-	struct qeth_hdr qh;
-	struct ethhdr mac;
-	__be16 vlan[2];
-	union {
-		struct {
-			struct iphdr h;
-			u8 options[40];
-		} ip4;
-		struct {
-			struct ipv6hdr h;
-		} ip6;
-	} nh;
-	u8 nhl;
-	void *nh_in_ctx;	/* address of nh within the ctx */
-	union {
-		struct {
-			struct tcphdr h;
-			u8 options[40];
-		} tcp;
-	} th;
-	u8 thl;
-	void *th_in_ctx;	/* address of th within the ctx */
-	struct sk_buff *skb;
-	int skb_offset;
-	int frag;
-	int frag_offset;
-} __attribute__ ((packed));
-
-#endif /* __QETH_EDDP_H__ */
Index: my_git/drivers/s390/net/qeth_fs.h
===================================================================
--- my_git.orig/drivers/s390/net/qeth_fs.h	2008-02-15 08:49:22.000000000 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,168 +0,0 @@
-/*
- * linux/drivers/s390/net/qeth_fs.h
- *
- * Linux on zSeries OSA Express and HiperSockets support.
- *
- * This header file contains definitions related to sysfs and procfs.
- *
- * Copyright 2000,2003 IBM Corporation
- * Author(s): Thomas Spatzier <tspat@de.ibm.com>
- *
- */
-#ifndef __QETH_FS_H__
-#define __QETH_FS_H__
-
-#ifdef CONFIG_PROC_FS
-extern int
-qeth_create_procfs_entries(void);
-
-extern void
-qeth_remove_procfs_entries(void);
-#else
-static inline int
-qeth_create_procfs_entries(void)
-{
-	return 0;
-}
-
-static inline void
-qeth_remove_procfs_entries(void)
-{
-}
-#endif /* CONFIG_PROC_FS */
-
-extern int
-qeth_create_device_attributes(struct device *dev);
-
-extern void
-qeth_remove_device_attributes(struct device *dev);
-
-extern int
-qeth_create_device_attributes_osn(struct device *dev);
-
-extern void
-qeth_remove_device_attributes_osn(struct device *dev);
-
-extern int
-qeth_create_driver_attributes(void);
-
-extern void
-qeth_remove_driver_attributes(void);
-
-/*
- * utility functions used in qeth_proc.c and qeth_sys.c
- */
-
-static inline const char *
-qeth_get_checksum_str(struct qeth_card *card)
-{
-	if (card->options.checksum_type == SW_CHECKSUMMING)
-		return "sw";
-	else if (card->options.checksum_type == HW_CHECKSUMMING)
-		return "hw";
-	else
-		return "no";
-}
-
-static inline const char *
-qeth_get_prioq_str(struct qeth_card *card, char *buf)
-{
-	if (card->qdio.do_prio_queueing == QETH_NO_PRIO_QUEUEING)
-		sprintf(buf, "always_q_%i", card->qdio.default_out_queue);
-	else
-		strcpy(buf, (card->qdio.do_prio_queueing ==
-					QETH_PRIO_Q_ING_PREC)?
-				"by_prec." : "by_ToS");
-	return buf;
-}
-
-static inline const char *
-qeth_get_bufsize_str(struct qeth_card *card)
-{
-	if (card->qdio.in_buf_size == 16384)
-		return "16k";
-	else if (card->qdio.in_buf_size == 24576)
-		return "24k";
-	else if (card->qdio.in_buf_size == 32768)
-		return "32k";
-	else if (card->qdio.in_buf_size == 40960)
-		return "40k";
-	else
-		return "64k";
-}
-
-static inline const char *
-qeth_get_cardname(struct qeth_card *card)
-{
- 	if (card->info.guestlan) {
- 		switch (card->info.type) {
- 		case QETH_CARD_TYPE_OSAE:
-			return " Guest LAN QDIO";
- 		case QETH_CARD_TYPE_IQD:
-			return " Guest LAN Hiper";
-		default:
-			return " unknown";
- 		}
-	} else {
-		switch (card->info.type) {
-		case QETH_CARD_TYPE_OSAE:
-			return " OSD Express";
-		case QETH_CARD_TYPE_IQD:
-			return " HiperSockets";
-		case QETH_CARD_TYPE_OSN:
-			return " OSN QDIO";
-		default:
-			return " unknown";
-		}
-	}
-	return " n/a";
-}
-
-/* max length to be returned: 14 */
-static inline const char *
-qeth_get_cardname_short(struct qeth_card *card)
-{
-	if (card->info.guestlan){
-		switch (card->info.type){
-		case QETH_CARD_TYPE_OSAE:
-			return "GuestLAN QDIO";
-		case QETH_CARD_TYPE_IQD:
-			return "GuestLAN Hiper";
-		default:
-			return "unknown";
-		}
-	} else {
-		switch (card->info.type) {
-		case QETH_CARD_TYPE_OSAE:
-			switch (card->info.link_type) {
-			case QETH_LINK_TYPE_FAST_ETH:
-				return "OSD_100";
-			case QETH_LINK_TYPE_HSTR:
-				return "HSTR";
-			case QETH_LINK_TYPE_GBIT_ETH:
-				return "OSD_1000";
-			case QETH_LINK_TYPE_10GBIT_ETH:
-				return "OSD_10GIG";
-			case QETH_LINK_TYPE_LANE_ETH100:
-				return "OSD_FE_LANE";
-			case QETH_LINK_TYPE_LANE_TR:
-				return "OSD_TR_LANE";
-			case QETH_LINK_TYPE_LANE_ETH1000:
-				return "OSD_GbE_LANE";
-			case QETH_LINK_TYPE_LANE:
-				return "OSD_ATM_LANE";
-			default:
-				return "OSD_Express";
-			}
-		case QETH_CARD_TYPE_IQD:
-			return "HiperSockets";
-		case QETH_CARD_TYPE_OSN:
-			return "OSN";
-		default:
-			return "unknown";
-		}
-	}
-	return "n/a";
-}
-
-#endif /* __QETH_FS_H__ */
Index: my_git/drivers/s390/net/qeth_main.c
===================================================================
--- my_git.orig/drivers/s390/net/qeth_main.c	2008-02-15 08:49:22.000000000 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,8956 +0,0 @@
-/*
- * 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 int
-qeth_hard_header_parse(const struct sk_buff *skb, unsigned char *haddr);
-
-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_threads_running(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;
-
-	wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
-
-	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) {
-			list_del(&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);
-				goto again;
-			} else
-				list_add(&addr->entry, &card->ip_list);
-		}
-	}
-}
-
-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))) {
-		if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19)
-			PRINT_ERR("IDX_ACTIVATE on write channel device %s: "
-				"adapter exclusively used by another host\n",
-				CARD_WDEV_ID(card));
-		else
-			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))) {
-		if (QETH_IDX_ACT_CAUSE_CODE(iob->data) == 0x19)
-			PRINT_ERR("IDX_ACTIVATE on read channel device %s: "
-				"adapter exclusively used by another host\n",
-				CARD_RDEV_ID(card));
-		else
-			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, (int)-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 if (hdr->hdr.osn.id == QETH_HEADER_TYPE_OSN) {
-			skb_push(skb, sizeof(struct qeth_hdr));
-			skb_copy_to_linear_data(skb, hdr,
-						sizeof(struct qeth_hdr));
-		} else { /* unknown header type */
-			dev_kfree_skb_any(skb);
-			QETH_DBF_TEXT(trace, 3, "inbunkno");
-			QETH_DBF_HEX(control, 3, hdr, QETH_DBF_CONTROL_LEN);
-			continue;
-		}
-		/* 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_read(&card->force_alloc_skb) &&
-			    net_ratelimit())
-				PRINT_WARN("Switch to alloc skb\n");
-			atomic_set(&card->force_alloc_skb, 3);
-			count = newcount;
-		} else {
-			if ((atomic_read(&card->force_alloc_skb) == 1) &&
-			    net_ratelimit())
-				PRINT_WARN("Switch to sg\n");
-			atomic_add_unless(&card->force_alloc_skb, -1, 0);
-		}
-
-		/*
-		 * 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);
-	card->qdio.out_qs = NULL;
-out_freepool:
-	qeth_free_buffer_pool(card);
-out_freeinq:
-	kfree(card->qdio.in_q);
-	card->qdio.in_q = NULL;
-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);
-	card->qdio.in_q = NULL;
-	/* inbound buffer pool */
-	qeth_free_buffer_pool(card);
-	/* free outbound qdio_qs */
-	if (card->qdio.out_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);
-		card->qdio.out_qs = NULL;
-	}
-}
-
-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 && 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, const void *daddr, const 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 const struct header_ops qeth_fake_ops = {
-	.create	= qeth_fake_header,
-	.parse  = qeth_hard_header_parse,
-};
-
-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){
-				if (net_ratelimit())
-					PRINT_WARN("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 void qeth_tx_csum(struct sk_buff *skb)
-{
-	int tlen;
-
-	if (skb->protocol == htons(ETH_P_IP)) {
-		tlen = ntohs(ip_hdr(skb)->tot_len) - (ip_hdr(skb)->ihl << 2);
-		switch (ip_hdr(skb)->protocol) {
-		case IPPROTO_TCP:
-			tcp_hdr(skb)->check = 0;
-			tcp_hdr(skb)->check = csum_tcpudp_magic(
-				ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
-				tlen, ip_hdr(skb)->protocol,
-				skb_checksum(skb, skb_transport_offset(skb),
-					tlen, 0));
-			break;
-		case IPPROTO_UDP:
-			udp_hdr(skb)->check = 0;
-			udp_hdr(skb)->check = csum_tcpudp_magic(
-				ip_hdr(skb)->saddr, ip_hdr(skb)->daddr,
-				tlen, ip_hdr(skb)->protocol,
-				skb_checksum(skb, skb_transport_offset(skb),
-					tlen, 0));
-			break;
-		}
-	} else if (skb->protocol == htons(ETH_P_IPV6)) {
-		switch (ipv6_hdr(skb)->nexthdr) {
-		case IPPROTO_TCP:
-			tcp_hdr(skb)->check = 0;
-			tcp_hdr(skb)->check = csum_ipv6_magic(
-				&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
-				ipv6_hdr(skb)->payload_len,
-				ipv6_hdr(skb)->nexthdr,
-				skb_checksum(skb, skb_transport_offset(skb),
-					ipv6_hdr(skb)->payload_len, 0));
-			break;
-		case IPPROTO_UDP:
-			udp_hdr(skb)->check = 0;
-			udp_hdr(skb)->check = csum_ipv6_magic(
-				&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
-				ipv6_hdr(skb)->payload_len,
-				ipv6_hdr(skb)->nexthdr,
-				skb_checksum(skb, skb_transport_offset(skb),
-					ipv6_hdr(skb)->payload_len, 0));
-			break;
-		}
-	}
-}
-
-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->header_ops == &qeth_fake_ops) && 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 ((large_send == QETH_LARGE_SEND_NO) &&
-	    (skb->ip_summed == CHECKSUM_PARTIAL))
-		qeth_tx_csum(new_skb);
-
-	if (card->info.type != QETH_CARD_TYPE_IQD)
-		rc = qeth_do_send_packet(card, queue, new_skb, hdr,
-					 elements_needed, ctx);
-	else {
-		if ((!card->options.layer2) &&
-		    (ipv == 0)) {
-			__qeth_free_new_skb(skb, new_skb);
-			return -EPERM;
-		}
-		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)
-{
-	return (dev->features & NETIF_F_HW_CSUM) != 0;
-}
-
-static int
-qeth_ethtool_set_tx_csum(struct net_device *dev, u32 data)
-{
-	if (data)
-		dev->features |= NETIF_F_HW_CSUM;
-	else
-		dev->features &= ~NETIF_F_HW_CSUM;
-
-	return 0;
-}
-
-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(const struct sk_buff *skb, unsigned char *haddr)
-{
-	const struct qeth_card *card;
-	const struct ethhdr *eth;
-	struct net_device *dev = skb->dev;
-
-	if (dev->type != ARPHRD_IEEE802_TR)
-		return 0;
-
-	card = qeth_get_card_from_dev(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 const struct header_ops qeth_null_ops = {
-	.parse = qeth_hard_header_parse,
-};
-
-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->header_ops = &qeth_null_ops;
-
-#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->header_ops = &qeth_fake_ops;
-
-	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);
-	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->header_ops = card->orig_header_ops;
-		if (card->options.fake_ll &&
-		    (qeth_get_netdev_flags(card) & IFF_NOARP))
-			card->dev->header_ops = &qeth_fake_ops;
-		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_header_ops = card->dev->header_ops;
-	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 |
-						NETIF_F_HW_CSUM);
-	}
-	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 |
-					NETIF_F_HW_CSUM;
-		break;
-	case QETH_LARGE_SEND_TSO:
-		if (qeth_is_supported(card, IPA_OUTBOUND_TSO)){
-			card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
-						NETIF_F_HW_CSUM;
-		} 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 |
-						NETIF_F_HW_CSUM);
-			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 |
-					NETIF_F_HW_CSUM);
-		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->header_ops == &qeth_fake_ops))
-		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(&init_net, *(__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");
Index: my_git/drivers/s390/net/qeth_mpc.c
===================================================================
--- my_git.orig/drivers/s390/net/qeth_mpc.c	2008-02-15 08:49:22.000000000 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,269 +0,0 @@
-/*
- * linux/drivers/s390/net/qeth_mpc.c
- *
- * Linux on zSeries OSA Express and HiperSockets support
- *
- * Copyright 2000,2003 IBM Corporation
- * Author(s): Frank Pavlic <fpavlic@de.ibm.com>
- * 	      Thomas Spatzier <tspat@de.ibm.com>
- *
- */
-#include <asm/cio.h>
-#include "qeth_mpc.h"
-
-unsigned char IDX_ACTIVATE_READ[]={
-	0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
-	0x19,0x01,0x01,0x80, 0x00,0x00,0x00,0x00,
-	0x00,0x00,0x00,0x00, 0x00,0x00,0xc8,0xc1,
-	0xd3,0xd3,0xd6,0xd3, 0xc5,0x40,0x00,0x00,
-	0x00,0x00
-};
-
-unsigned char IDX_ACTIVATE_WRITE[]={
-	0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
-	0x15,0x01,0x01,0x80, 0x00,0x00,0x00,0x00,
-	0xff,0xff,0x00,0x00, 0x00,0x00,0xc8,0xc1,
-	0xd3,0xd3,0xd6,0xd3, 0xc5,0x40,0x00,0x00,
-	0x00,0x00
-};
-
-unsigned char CM_ENABLE[]={
-	0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x01,
-	0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x63,
-	0x10,0x00,0x00,0x01,
-	0x00,0x00,0x00,0x00,
-	0x81,0x7e,0x00,0x01, 0x00,0x00,0x00,0x00,
-	0x00,0x00,0x00,0x00, 0x00,0x24,0x00,0x23,
-	0x00,0x00,0x23,0x05, 0x00,0x00,0x00,0x00,
-	0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
-	0x01,0x00,0x00,0x23, 0x00,0x00,0x00,0x40,
-	0x00,0x0c,0x41,0x02, 0x00,0x17,0x00,0x00,
-	0x00,0x00,0x00,0x00,
-	0x00,0x0b,0x04,0x01,
-	0x7e,0x04,0x05,0x00, 0x01,0x01,0x0f,
-	0x00,
-	0x0c,0x04,0x02,0xff, 0xff,0xff,0xff,0xff,
-	0xff,0xff,0xff
-};
-
-unsigned char CM_SETUP[]={
-	0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x02,
-	0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x64,
-	0x10,0x00,0x00,0x01,
-	0x00,0x00,0x00,0x00,
-	0x81,0x7e,0x00,0x01, 0x00,0x00,0x00,0x00,
-	0x00,0x00,0x00,0x00, 0x00,0x24,0x00,0x24,
-	0x00,0x00,0x24,0x05, 0x00,0x00,0x00,0x00,
-	0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
-	0x01,0x00,0x00,0x24, 0x00,0x00,0x00,0x40,
-	0x00,0x0c,0x41,0x04, 0x00,0x18,0x00,0x00,
-	0x00,0x00,0x00,0x00,
-	0x00,0x09,0x04,0x04,
-	0x05,0x00,0x01,0x01, 0x11,
-	0x00,0x09,0x04,
-	0x05,0x05,0x00,0x00, 0x00,0x00,
-	0x00,0x06,
-	0x04,0x06,0xc8,0x00
-};
-
-unsigned char ULP_ENABLE[]={
-	0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x03,
-	0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x6b,
-	0x10,0x00,0x00,0x01,
-	0x00,0x00,0x00,0x00,
-	0x41,0x7e,0x00,0x01, 0x00,0x00,0x00,0x01,
-	0x00,0x00,0x00,0x00, 0x00,0x24,0x00,0x2b,
-	0x00,0x00,0x2b,0x05, 0x20,0x01,0x00,0x00,
-	0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
-	0x01,0x00,0x00,0x2b, 0x00,0x00,0x00,0x40,
-	0x00,0x0c,0x41,0x02, 0x00,0x1f,0x00,0x00,
-	0x00,0x00,0x00,0x00,
-	0x00,0x0b,0x04,0x01,
-	0x03,0x04,0x05,0x00, 0x01,0x01,0x12,
-	0x00,
-	0x14,0x04,0x0a,0x00, 0x20,0x00,0x00,0xff,
-	0xff,0x00,0x08,0xc8, 0xe8,0xc4,0xf1,0xc7,
-	0xf1,0x00,0x00
-};
-
-unsigned char ULP_SETUP[]={
-	0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x04,
-	0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x6c,
-	0x10,0x00,0x00,0x01,
-	0x00,0x00,0x00,0x00,
-	0x41,0x7e,0x00,0x01, 0x00,0x00,0x00,0x02,
-	0x00,0x00,0x00,0x01, 0x00,0x24,0x00,0x2c,
-	0x00,0x00,0x2c,0x05, 0x20,0x01,0x00,0x00,
-	0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
-	0x01,0x00,0x00,0x2c, 0x00,0x00,0x00,0x40,
-	0x00,0x0c,0x41,0x04, 0x00,0x20,0x00,0x00,
-	0x00,0x00,0x00,0x00,
-	0x00,0x09,0x04,0x04,
-	0x05,0x00,0x01,0x01, 0x14,
-	0x00,0x09,0x04,
-	0x05,0x05,0x30,0x01, 0x00,0x00,
-	0x00,0x06,
-	0x04,0x06,0x40,0x00,
-	0x00,0x08,0x04,0x0b,
-	0x00,0x00,0x00,0x00
-};
-
-unsigned char DM_ACT[]={
-	0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x05,
-	0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x55,
-	0x10,0x00,0x00,0x01,
-	0x00,0x00,0x00,0x00,
-	0x41,0x7e,0x00,0x01, 0x00,0x00,0x00,0x03,
-	0x00,0x00,0x00,0x02, 0x00,0x24,0x00,0x15,
-	0x00,0x00,0x2c,0x05, 0x20,0x01,0x00,0x00,
-	0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
-	0x01,0x00,0x00,0x15, 0x00,0x00,0x00,0x40,
-	0x00,0x0c,0x43,0x60, 0x00,0x09,0x00,0x00,
-	0x00,0x00,0x00,0x00,
-	0x00,0x09,0x04,0x04,
-	0x05,0x40,0x01,0x01, 0x00
-};
-
-unsigned char IPA_PDU_HEADER[]={
-	0x00,0xe0,0x00,0x00, 0x77,0x77,0x77,0x77,
-	0x00,0x00,0x00,0x14, 0x00,0x00,
-		(IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd))/256,
-		(IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd))%256,
-	0x10,0x00,0x00,0x01, 0x00,0x00,0x00,0x00,
-	0xc1,0x03,0x00,0x01, 0x00,0x00,0x00,0x00,
-	0x00,0x00,0x00,0x00, 0x00,0x24,
-		sizeof(struct qeth_ipa_cmd)/256,
-		sizeof(struct qeth_ipa_cmd)%256,
-	0x00,
-		sizeof(struct qeth_ipa_cmd)/256,
-		sizeof(struct qeth_ipa_cmd)%256,
-	0x05,
-	0x77,0x77,0x77,0x77,
-	0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
-	0x01,0x00,
-		sizeof(struct qeth_ipa_cmd)/256,
-		sizeof(struct qeth_ipa_cmd)%256,
-	0x00,0x00,0x00,0x40,
-};
-
-unsigned char WRITE_CCW[]={
-	0x01,CCW_FLAG_SLI,0,0,
-	0,0,0,0
-};
-
-unsigned char READ_CCW[]={
-	0x02,CCW_FLAG_SLI,0,0,
-	0,0,0,0
-};
-
-
-struct ipa_rc_msg {
-	enum qeth_ipa_return_codes rc;
-	char *msg;
-};
-
-static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
-	{IPA_RC_SUCCESS,		"success"},
-	{IPA_RC_NOTSUPP,		"Command not supported"},
-	{IPA_RC_IP_TABLE_FULL,		"Add Addr IP Table Full - ipv6"},
-	{IPA_RC_UNKNOWN_ERROR,		"IPA command failed - reason unknown"},
-	{IPA_RC_UNSUPPORTED_COMMAND,	"Command not supported"},
-	{IPA_RC_DUP_IPV6_REMOTE,"ipv6 address already registered remote"},
-	{IPA_RC_DUP_IPV6_HOME,		"ipv6 address already registered"},
-	{IPA_RC_UNREGISTERED_ADDR,	"Address not registered"},
-	{IPA_RC_NO_ID_AVAILABLE,	"No identifiers available"},
-	{IPA_RC_ID_NOT_FOUND,		"Identifier not found"},
-	{IPA_RC_INVALID_IP_VERSION,	"IP version incorrect"},
-	{IPA_RC_LAN_FRAME_MISMATCH,	"LAN and frame mismatch"},
-	{IPA_RC_L2_UNSUPPORTED_CMD,	"Unsupported layer 2 command"},
-	{IPA_RC_L2_DUP_MAC,		"Duplicate MAC address"},
-	{IPA_RC_L2_ADDR_TABLE_FULL,	"Layer2 address table full"},
-	{IPA_RC_L2_DUP_LAYER3_MAC,	"Duplicate with layer 3 MAC"},
-	{IPA_RC_L2_GMAC_NOT_FOUND,	"GMAC not found"},
-	{IPA_RC_L2_MAC_NOT_FOUND,	"L2 mac address not found"},
-	{IPA_RC_L2_INVALID_VLAN_ID,	"L2 invalid vlan id"},
-	{IPA_RC_L2_DUP_VLAN_ID,		"L2 duplicate vlan id"},
-	{IPA_RC_L2_VLAN_ID_NOT_FOUND,	"L2 vlan id not found"},
-	{IPA_RC_DATA_MISMATCH,		"Data field mismatch (v4/v6 mixed)"},
-	{IPA_RC_INVALID_MTU_SIZE,	"Invalid MTU size"},
-	{IPA_RC_INVALID_LANTYPE,	"Invalid LAN type"},
-	{IPA_RC_INVALID_LANNUM,		"Invalid LAN num"},
-	{IPA_RC_DUPLICATE_IP_ADDRESS,	"Address already registered"},
-	{IPA_RC_IP_ADDR_TABLE_FULL,	"IP address table full"},
-	{IPA_RC_LAN_PORT_STATE_ERROR,	"LAN port state error"},
-	{IPA_RC_SETIP_NO_STARTLAN,	"Setip no startlan received"},
-	{IPA_RC_SETIP_ALREADY_RECEIVED,	"Setip already received"},
-	{IPA_RC_IP_ADDR_ALREADY_USED,	"IP address already in use on LAN"},
-	{IPA_RC_MULTICAST_FULL,		"No task available, multicast full"},
-	{IPA_RC_SETIP_INVALID_VERSION,	"SETIP invalid IP version"},
-	{IPA_RC_UNSUPPORTED_SUBCMD,	"Unsupported assist subcommand"},
-	{IPA_RC_ARP_ASSIST_NO_ENABLE,	"Only partial success, no enable"},
-	{IPA_RC_PRIMARY_ALREADY_DEFINED,"Primary already defined"},
-	{IPA_RC_SECOND_ALREADY_DEFINED,	"Secondary already defined"},
-	{IPA_RC_INVALID_SETRTG_INDICATOR,"Invalid SETRTG indicator"},
-	{IPA_RC_MC_ADDR_ALREADY_DEFINED,"Multicast address already defined"},
-	{IPA_RC_LAN_OFFLINE,		"STRTLAN_LAN_DISABLED - LAN offline"},
-	{IPA_RC_INVALID_IP_VERSION2,	"Invalid IP version"},
-	{IPA_RC_FFFF,			"Unknown Error"}
-};
-
-
-
-char *
-qeth_get_ipa_msg(enum qeth_ipa_return_codes rc)
-{
-	int x = 0;
-	qeth_ipa_rc_msg[sizeof(qeth_ipa_rc_msg) /
-			sizeof(struct ipa_rc_msg) - 1].rc = rc;
-	while(qeth_ipa_rc_msg[x].rc != rc)
-		x++;
-	return qeth_ipa_rc_msg[x].msg;
-}
-
-
-struct ipa_cmd_names {
-	enum qeth_ipa_cmds cmd;
-	char *name;
-};
-
-static struct ipa_cmd_names qeth_ipa_cmd_names[] = {
-	{IPA_CMD_STARTLAN,	"startlan"},
-	{IPA_CMD_STOPLAN,	"stoplan"},
-	{IPA_CMD_SETVMAC,	"setvmac"},
-	{IPA_CMD_DELVMAC,	"delvmca"},
-	{IPA_CMD_SETGMAC,	"setgmac"},
-	{IPA_CMD_DELGMAC,	"delgmac"},
-	{IPA_CMD_SETVLAN,	"setvlan"},
-	{IPA_CMD_DELVLAN,	"delvlan"},
-	{IPA_CMD_SETCCID,	"setccid"},
-	{IPA_CMD_DELCCID,	"delccid"},
-	{IPA_CMD_MODCCID,	"setip"},
-	{IPA_CMD_SETIP,		"setip"},
-	{IPA_CMD_QIPASSIST,	"qipassist"},
-	{IPA_CMD_SETASSPARMS,	"setassparms"},
-	{IPA_CMD_SETIPM,	"setipm"},
-	{IPA_CMD_DELIPM,	"delipm"},
-	{IPA_CMD_SETRTG,	"setrtg"},
-	{IPA_CMD_DELIP,		"delip"},
-	{IPA_CMD_SETADAPTERPARMS, "setadapterparms"},
-	{IPA_CMD_SET_DIAG_ASS,	"set_diag_ass"},
-	{IPA_CMD_CREATE_ADDR,	"create_addr"},
-	{IPA_CMD_DESTROY_ADDR,	"destroy_addr"},
-	{IPA_CMD_REGISTER_LOCAL_ADDR,	"register_local_addr"},
-	{IPA_CMD_UNREGISTER_LOCAL_ADDR,	"unregister_local_addr"},
-	{IPA_CMD_UNKNOWN,	"unknown"},
-};
-
-char *
-qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd)
-{
-	int x = 0;
-	qeth_ipa_cmd_names[
-		sizeof(qeth_ipa_cmd_names)/
-			sizeof(struct ipa_cmd_names)-1].cmd = cmd;
-	while(qeth_ipa_cmd_names[x].cmd != cmd)
-		x++;
-	return qeth_ipa_cmd_names[x].name;
-}
-
-
Index: my_git/drivers/s390/net/qeth_mpc.h
===================================================================
--- my_git.orig/drivers/s390/net/qeth_mpc.h	2008-02-15 08:49:22.000000000 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,583 +0,0 @@
-/*
- * linux/drivers/s390/net/qeth_mpc.h
- *
- * Linux on zSeries OSA Express and HiperSockets support
- *
- * Copyright 2000,2003 IBM Corporation
- * Author(s): Utz Bacher <utz.bacher@de.ibm.com>
- *            Thomas Spatzier <tspat@de.ibm.com>
- *            Frank Pavlic <fpavlic@de.ibm.com>
- *
- */
-#ifndef __QETH_MPC_H__
-#define __QETH_MPC_H__
-
-#include <asm/qeth.h>
-
-#define IPA_PDU_HEADER_SIZE	0x40
-#define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer+0x0e)
-#define QETH_IPA_PDU_LEN_PDU1(buffer) (buffer+0x26)
-#define QETH_IPA_PDU_LEN_PDU2(buffer) (buffer+0x29)
-#define QETH_IPA_PDU_LEN_PDU3(buffer) (buffer+0x3a)
-
-extern unsigned char IPA_PDU_HEADER[];
-#define QETH_IPA_CMD_DEST_ADDR(buffer) (buffer+0x2c)
-
-#define IPA_CMD_LENGTH	(IPA_PDU_HEADER_SIZE + sizeof(struct qeth_ipa_cmd))
-
-#define QETH_SEQ_NO_LENGTH	4
-#define QETH_MPC_TOKEN_LENGTH	4
-#define QETH_MCL_LENGTH		4
-#define OSA_ADDR_LEN		6
-
-#define QETH_TIMEOUT		(10 * HZ)
-#define QETH_IPA_TIMEOUT	(45 * HZ)
-#define QETH_IDX_COMMAND_SEQNO	0xffff0000
-#define SR_INFO_LEN		16
-
-#define QETH_CLEAR_CHANNEL_PARM	-10
-#define QETH_HALT_CHANNEL_PARM	-11
-#define QETH_RCD_PARM -12
-
-/*****************************************************************************/
-/* IP Assist related definitions                                             */
-/*****************************************************************************/
-#define IPA_CMD_INITIATOR_HOST  0x00
-#define IPA_CMD_INITIATOR_OSA   0x01
-#define IPA_CMD_INITIATOR_HOST_REPLY  0x80
-#define IPA_CMD_INITIATOR_OSA_REPLY   0x81
-#define IPA_CMD_PRIM_VERSION_NO 0x01
-
-enum qeth_card_types {
-	QETH_CARD_TYPE_UNKNOWN = 0,
-	QETH_CARD_TYPE_OSAE    = 10,
-	QETH_CARD_TYPE_IQD     = 1234,
-	QETH_CARD_TYPE_OSN     = 11,
-};
-
-#define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18
-/* only the first two bytes are looked at in qeth_get_cardname_short */
-enum qeth_link_types {
-	QETH_LINK_TYPE_FAST_ETH     = 0x01,
-	QETH_LINK_TYPE_HSTR         = 0x02,
-	QETH_LINK_TYPE_GBIT_ETH     = 0x03,
-	QETH_LINK_TYPE_OSN          = 0x04,
-	QETH_LINK_TYPE_10GBIT_ETH   = 0x10,
-	QETH_LINK_TYPE_LANE_ETH100  = 0x81,
-	QETH_LINK_TYPE_LANE_TR      = 0x82,
-	QETH_LINK_TYPE_LANE_ETH1000 = 0x83,
-	QETH_LINK_TYPE_LANE         = 0x88,
-	QETH_LINK_TYPE_ATM_NATIVE   = 0x90,
-};
-
-enum qeth_tr_macaddr_modes {
-	QETH_TR_MACADDR_NONCANONICAL = 0,
-	QETH_TR_MACADDR_CANONICAL    = 1,
-};
-
-enum qeth_tr_broadcast_modes {
-	QETH_TR_BROADCAST_ALLRINGS = 0,
-	QETH_TR_BROADCAST_LOCAL    = 1,
-};
-
-/* these values match CHECKSUM_* in include/linux/skbuff.h */
-enum qeth_checksum_types {
-	SW_CHECKSUMMING = 0, /* TODO: set to bit flag used in IPA Command */
-	HW_CHECKSUMMING = 1,
-	NO_CHECKSUMMING = 2,
-};
-#define QETH_CHECKSUM_DEFAULT SW_CHECKSUMMING
-
-/*
- * Routing stuff
- */
-#define RESET_ROUTING_FLAG 0x10 /* indicate that routing type shall be set */
-enum qeth_routing_types {
-	NO_ROUTER		= 0, /* TODO: set to bit flag used in IPA Command */
-	PRIMARY_ROUTER		= 1,
-	SECONDARY_ROUTER	= 2,
-	MULTICAST_ROUTER	= 3,
-	PRIMARY_CONNECTOR	= 4,
-	SECONDARY_CONNECTOR	= 5,
-};
-
-/* IPA Commands */
-enum qeth_ipa_cmds {
-	IPA_CMD_STARTLAN		= 0x01,
-	IPA_CMD_STOPLAN			= 0x02,
-	IPA_CMD_SETVMAC			= 0x21,
-	IPA_CMD_DELVMAC			= 0x22,
-	IPA_CMD_SETGMAC			= 0x23,
-	IPA_CMD_DELGMAC			= 0x24,
-	IPA_CMD_SETVLAN			= 0x25,
-	IPA_CMD_DELVLAN			= 0x26,
-	IPA_CMD_SETCCID			= 0x41,
-	IPA_CMD_DELCCID			= 0x42,
-	IPA_CMD_MODCCID			= 0x43,
-	IPA_CMD_SETIP			= 0xb1,
-	IPA_CMD_QIPASSIST		= 0xb2,
-	IPA_CMD_SETASSPARMS		= 0xb3,
-	IPA_CMD_SETIPM			= 0xb4,
-	IPA_CMD_DELIPM			= 0xb5,
-	IPA_CMD_SETRTG			= 0xb6,
-	IPA_CMD_DELIP			= 0xb7,
-	IPA_CMD_SETADAPTERPARMS		= 0xb8,
-	IPA_CMD_SET_DIAG_ASS		= 0xb9,
-	IPA_CMD_CREATE_ADDR		= 0xc3,
-	IPA_CMD_DESTROY_ADDR		= 0xc4,
-	IPA_CMD_REGISTER_LOCAL_ADDR	= 0xd1,
-	IPA_CMD_UNREGISTER_LOCAL_ADDR	= 0xd2,
-	IPA_CMD_UNKNOWN			= 0x00
-};
-
-enum qeth_ip_ass_cmds {
-	IPA_CMD_ASS_START	= 0x0001,
-	IPA_CMD_ASS_STOP	= 0x0002,
-	IPA_CMD_ASS_CONFIGURE	= 0x0003,
-	IPA_CMD_ASS_ENABLE	= 0x0004,
-};
-
-enum qeth_arp_process_subcmds {
-	IPA_CMD_ASS_ARP_SET_NO_ENTRIES	= 0x0003,
-	IPA_CMD_ASS_ARP_QUERY_CACHE	= 0x0004,
-	IPA_CMD_ASS_ARP_ADD_ENTRY	= 0x0005,
-	IPA_CMD_ASS_ARP_REMOVE_ENTRY	= 0x0006,
-	IPA_CMD_ASS_ARP_FLUSH_CACHE	= 0x0007,
-	IPA_CMD_ASS_ARP_QUERY_INFO	= 0x0104,
-	IPA_CMD_ASS_ARP_QUERY_STATS	= 0x0204,
-};
-
-
-/* Return Codes for IPA Commands
- * according to OSA card Specs */
-
-enum qeth_ipa_return_codes {
-	IPA_RC_SUCCESS			= 0x0000,
-	IPA_RC_NOTSUPP			= 0x0001,
-	IPA_RC_IP_TABLE_FULL		= 0x0002,
-	IPA_RC_UNKNOWN_ERROR		= 0x0003,
-	IPA_RC_UNSUPPORTED_COMMAND	= 0x0004,
-	IPA_RC_DUP_IPV6_REMOTE		= 0x0008,
-	IPA_RC_DUP_IPV6_HOME		= 0x0010,
-	IPA_RC_UNREGISTERED_ADDR	= 0x0011,
-	IPA_RC_NO_ID_AVAILABLE		= 0x0012,
-	IPA_RC_ID_NOT_FOUND		= 0x0013,
-	IPA_RC_INVALID_IP_VERSION	= 0x0020,
-	IPA_RC_LAN_FRAME_MISMATCH	= 0x0040,
-	IPA_RC_L2_UNSUPPORTED_CMD	= 0x2003,
-	IPA_RC_L2_DUP_MAC		= 0x2005,
-	IPA_RC_L2_ADDR_TABLE_FULL	= 0x2006,
-	IPA_RC_L2_DUP_LAYER3_MAC	= 0x200a,
-	IPA_RC_L2_GMAC_NOT_FOUND	= 0x200b,
-	IPA_RC_L2_MAC_NOT_FOUND		= 0x2010,
-	IPA_RC_L2_INVALID_VLAN_ID	= 0x2015,
-	IPA_RC_L2_DUP_VLAN_ID		= 0x2016,
-	IPA_RC_L2_VLAN_ID_NOT_FOUND	= 0x2017,
-	IPA_RC_DATA_MISMATCH		= 0xe001,
-	IPA_RC_INVALID_MTU_SIZE		= 0xe002,
-	IPA_RC_INVALID_LANTYPE		= 0xe003,
-	IPA_RC_INVALID_LANNUM		= 0xe004,
-	IPA_RC_DUPLICATE_IP_ADDRESS	= 0xe005,
-	IPA_RC_IP_ADDR_TABLE_FULL	= 0xe006,
-	IPA_RC_LAN_PORT_STATE_ERROR	= 0xe007,
-	IPA_RC_SETIP_NO_STARTLAN	= 0xe008,
-	IPA_RC_SETIP_ALREADY_RECEIVED	= 0xe009,
-	IPA_RC_IP_ADDR_ALREADY_USED	= 0xe00a,
-	IPA_RC_MULTICAST_FULL		= 0xe00b,
-	IPA_RC_SETIP_INVALID_VERSION	= 0xe00d,
-	IPA_RC_UNSUPPORTED_SUBCMD	= 0xe00e,
-	IPA_RC_ARP_ASSIST_NO_ENABLE	= 0xe00f,
-	IPA_RC_PRIMARY_ALREADY_DEFINED	= 0xe010,
-	IPA_RC_SECOND_ALREADY_DEFINED	= 0xe011,
-	IPA_RC_INVALID_SETRTG_INDICATOR	= 0xe012,
-	IPA_RC_MC_ADDR_ALREADY_DEFINED	= 0xe013,
-	IPA_RC_LAN_OFFLINE		= 0xe080,
-	IPA_RC_INVALID_IP_VERSION2	= 0xf001,
-	IPA_RC_FFFF			= 0xffff
-};
-
-/* IPA function flags; each flag marks availability of respective function */
-enum qeth_ipa_funcs {
-	IPA_ARP_PROCESSING      = 0x00000001L,
-	IPA_INBOUND_CHECKSUM    = 0x00000002L,
-	IPA_OUTBOUND_CHECKSUM   = 0x00000004L,
-	IPA_IP_FRAGMENTATION    = 0x00000008L,
-	IPA_FILTERING           = 0x00000010L,
-	IPA_IPV6                = 0x00000020L,
-	IPA_MULTICASTING        = 0x00000040L,
-	IPA_IP_REASSEMBLY       = 0x00000080L,
-	IPA_QUERY_ARP_COUNTERS  = 0x00000100L,
-	IPA_QUERY_ARP_ADDR_INFO = 0x00000200L,
-	IPA_SETADAPTERPARMS     = 0x00000400L,
-	IPA_VLAN_PRIO           = 0x00000800L,
-	IPA_PASSTHRU            = 0x00001000L,
-	IPA_FLUSH_ARP_SUPPORT   = 0x00002000L,
-	IPA_FULL_VLAN           = 0x00004000L,
-	IPA_INBOUND_PASSTHRU    = 0x00008000L,
-	IPA_SOURCE_MAC          = 0x00010000L,
-	IPA_OSA_MC_ROUTER       = 0x00020000L,
-	IPA_QUERY_ARP_ASSIST	= 0x00040000L,
-	IPA_INBOUND_TSO         = 0x00080000L,
-	IPA_OUTBOUND_TSO        = 0x00100000L,
-};
-
-/* SETIP/DELIP IPA Command: ***************************************************/
-enum qeth_ipa_setdelip_flags {
-	QETH_IPA_SETDELIP_DEFAULT          = 0x00L, /* default */
-	QETH_IPA_SETIP_VIPA_FLAG           = 0x01L, /* no grat. ARP */
-	QETH_IPA_SETIP_TAKEOVER_FLAG       = 0x02L, /* nofail on grat. ARP */
-	QETH_IPA_DELIP_ADDR_2_B_TAKEN_OVER = 0x20L,
-	QETH_IPA_DELIP_VIPA_FLAG           = 0x40L,
-	QETH_IPA_DELIP_ADDR_NEEDS_SETIP    = 0x80L,
-};
-
-/* SETADAPTER IPA Command: ****************************************************/
-enum qeth_ipa_setadp_cmd {
-	IPA_SETADP_QUERY_COMMANDS_SUPPORTED	= 0x01,
-	IPA_SETADP_ALTER_MAC_ADDRESS		= 0x02,
-	IPA_SETADP_ADD_DELETE_GROUP_ADDRESS	= 0x04,
-	IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR	= 0x08,
-	IPA_SETADP_SET_ADDRESSING_MODE		= 0x10,
-	IPA_SETADP_SET_CONFIG_PARMS		= 0x20,
-	IPA_SETADP_SET_CONFIG_PARMS_EXTENDED	= 0x40,
-	IPA_SETADP_SET_BROADCAST_MODE		= 0x80,
-	IPA_SETADP_SEND_OSA_MESSAGE		= 0x0100,
-	IPA_SETADP_SET_SNMP_CONTROL		= 0x0200,
-	IPA_SETADP_QUERY_CARD_INFO		= 0x0400,
-	IPA_SETADP_SET_PROMISC_MODE		= 0x0800,
-};
-enum qeth_ipa_mac_ops {
-	CHANGE_ADDR_READ_MAC		= 0,
-	CHANGE_ADDR_REPLACE_MAC		= 1,
-	CHANGE_ADDR_ADD_MAC		= 2,
-	CHANGE_ADDR_DEL_MAC		= 4,
-	CHANGE_ADDR_RESET_MAC		= 8,
-};
-enum qeth_ipa_addr_ops {
-	CHANGE_ADDR_READ_ADDR		= 0,
-	CHANGE_ADDR_ADD_ADDR		= 1,
-	CHANGE_ADDR_DEL_ADDR		= 2,
-	CHANGE_ADDR_FLUSH_ADDR_TABLE	= 4,
-};
-enum qeth_ipa_promisc_modes {
-	SET_PROMISC_MODE_OFF		= 0,
-	SET_PROMISC_MODE_ON		= 1,
-};
-
-/* (SET)DELIP(M) IPA stuff ***************************************************/
-struct qeth_ipacmd_setdelip4 {
-	__u8   ip_addr[4];
-	__u8   mask[4];
-	__u32  flags;
-} __attribute__ ((packed));
-
-struct qeth_ipacmd_setdelip6 {
-	__u8   ip_addr[16];
-	__u8   mask[16];
-	__u32  flags;
-} __attribute__ ((packed));
-
-struct qeth_ipacmd_setdelipm {
-	__u8 mac[6];
-	__u8 padding[2];
-	__u8 ip6[12];
-	__u8 ip4[4];
-} __attribute__ ((packed));
-
-struct qeth_ipacmd_layer2setdelmac {
-	__u32 mac_length;
-	__u8 mac[6];
-} __attribute__ ((packed));
-
-struct qeth_ipacmd_layer2setdelvlan {
-	__u16 vlan_id;
-} __attribute__ ((packed));
-
-
-struct qeth_ipacmd_setassparms_hdr {
-	__u32 assist_no;
-	__u16 length;
-	__u16 command_code;
-	__u16 return_code;
-	__u8 number_of_replies;
-	__u8 seq_no;
-} __attribute__((packed));
-
-struct qeth_arp_query_data {
-	__u16 request_bits;
-	__u16 reply_bits;
-	__u32 no_entries;
-	char data;
-} __attribute__((packed));
-
-/* used as parameter for arp_query reply */
-struct qeth_arp_query_info {
-	__u32 udata_len;
-	__u16 mask_bits;
-	__u32 udata_offset;
-	__u32 no_entries;
-	char *udata;
-};
-
-/* SETASSPARMS IPA Command: */
-struct qeth_ipacmd_setassparms {
-	struct qeth_ipacmd_setassparms_hdr hdr;
-	union {
-		__u32 flags_32bit;
-		struct qeth_arp_cache_entry add_arp_entry;
-		struct qeth_arp_query_data query_arp;
-		__u8 ip[16];
-	} data;
-} __attribute__ ((packed));
-
-
-/* SETRTG IPA Command:    ****************************************************/
-struct qeth_set_routing {
-	__u8 type;
-};
-
-/* SETADAPTERPARMS IPA Command:    *******************************************/
-struct qeth_query_cmds_supp {
-	__u32 no_lantypes_supp;
-	__u8 lan_type;
-	__u8 reserved1[3];
-	__u32 supported_cmds;
-	__u8 reserved2[8];
-} __attribute__ ((packed));
-
-struct qeth_change_addr {
-	__u32 cmd;
-	__u32 addr_size;
-	__u32 no_macs;
-	__u8 addr[OSA_ADDR_LEN];
-} __attribute__ ((packed));
-
-
-struct qeth_snmp_cmd {
-	__u8  token[16];
-	__u32 request;
-	__u32 interface;
-	__u32 returncode;
-	__u32 firmwarelevel;
-	__u32 seqno;
-	__u8  data;
-} __attribute__ ((packed));
-
-struct qeth_snmp_ureq_hdr {
-	__u32   data_len;
-	__u32   req_len;
-	__u32   reserved1;
-	__u32   reserved2;
-} __attribute__ ((packed));
-
-struct qeth_snmp_ureq {
-	struct qeth_snmp_ureq_hdr hdr;
-	struct qeth_snmp_cmd cmd;
-} __attribute__((packed));
-
-struct qeth_ipacmd_setadpparms_hdr {
-	__u32 supp_hw_cmds;
-	__u32 reserved1;
-	__u16 cmdlength;
-	__u16 reserved2;
-	__u32 command_code;
-	__u16 return_code;
-	__u8  used_total;
-	__u8  seq_no;
-	__u32 reserved3;
-} __attribute__ ((packed));
-
-struct qeth_ipacmd_setadpparms {
-	struct qeth_ipacmd_setadpparms_hdr hdr;
-	union {
-		struct qeth_query_cmds_supp query_cmds_supp;
-		struct qeth_change_addr change_addr;
-		struct qeth_snmp_cmd snmp;
-		__u32 mode;
-	} data;
-} __attribute__ ((packed));
-
-/* IPFRAME IPA Command:    ***************************************************/
-/* TODO: define in analogy to commands define above */
-
-/* ADD_ADDR_ENTRY IPA Command:    ********************************************/
-/* TODO: define in analogy to commands define above */
-
-/* DELETE_ADDR_ENTRY IPA Command:    *****************************************/
-/* TODO: define in analogy to commands define above */
-
-/* CREATE_ADDR IPA Command:    ***********************************************/
-struct qeth_create_destroy_address {
-	__u8 unique_id[8];
-} __attribute__ ((packed));
-
-/* REGISTER_LOCAL_ADDR IPA Command:    ***************************************/
-/* TODO: define in analogy to commands define above */
-
-/* UNREGISTER_LOCAL_ADDR IPA Command:    *************************************/
-/* TODO: define in analogy to commands define above */
-
-/* Header for each IPA command */
-struct qeth_ipacmd_hdr {
-	__u8   command;
-	__u8   initiator;
-	__u16  seqno;
-	__u16  return_code;
-	__u8   adapter_type;
-	__u8   rel_adapter_no;
-	__u8   prim_version_no;
-	__u8   param_count;
-	__u16  prot_version;
-	__u32  ipa_supported;
-	__u32  ipa_enabled;
-} __attribute__ ((packed));
-
-/* The IPA command itself */
-struct qeth_ipa_cmd {
-	struct qeth_ipacmd_hdr hdr;
-	union {
-		struct qeth_ipacmd_setdelip4		setdelip4;
-		struct qeth_ipacmd_setdelip6		setdelip6;
-		struct qeth_ipacmd_setdelipm		setdelipm;
-		struct qeth_ipacmd_setassparms		setassparms;
-		struct qeth_ipacmd_layer2setdelmac	setdelmac;
-		struct qeth_ipacmd_layer2setdelvlan	setdelvlan;
-		struct qeth_create_destroy_address	create_destroy_addr;
-		struct qeth_ipacmd_setadpparms		setadapterparms;
-		struct qeth_set_routing			setrtg;
-	} data;
-} __attribute__ ((packed));
-
-/*
- * special command for ARP processing.
- * this is not included in setassparms command before, because we get
- * problem with the size of struct qeth_ipacmd_setassparms otherwise
- */
-enum qeth_ipa_arp_return_codes {
-	QETH_IPA_ARP_RC_SUCCESS      = 0x0000,
-	QETH_IPA_ARP_RC_FAILED       = 0x0001,
-	QETH_IPA_ARP_RC_NOTSUPP      = 0x0002,
-	QETH_IPA_ARP_RC_OUT_OF_RANGE = 0x0003,
-	QETH_IPA_ARP_RC_Q_NOTSUPP    = 0x0004,
-	QETH_IPA_ARP_RC_Q_NO_DATA    = 0x0008,
-};
-
-
-extern char *
-qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
-extern char *
-qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
-
-#define QETH_SETASS_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
-			       sizeof(struct qeth_ipacmd_setassparms_hdr))
-#define QETH_IPA_ARP_DATA_POS(buffer) (buffer + IPA_PDU_HEADER_SIZE + \
-				       QETH_SETASS_BASE_LEN)
-#define QETH_SETADP_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
-			      sizeof(struct qeth_ipacmd_setadpparms_hdr))
-#define QETH_SNMP_SETADP_CMDLENGTH 16
-
-#define QETH_ARP_DATA_SIZE 3968
-#define QETH_ARP_CMD_LEN (QETH_ARP_DATA_SIZE + 8)
-/* Helper functions */
-#define IS_IPA_REPLY(cmd) ((cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST) || \
-			   (cmd->hdr.initiator == IPA_CMD_INITIATOR_OSA_REPLY))
-
-/*****************************************************************************/
-/* END OF   IP Assist related definitions                                    */
-/*****************************************************************************/
-
-
-extern unsigned char WRITE_CCW[];
-extern unsigned char READ_CCW[];
-
-extern unsigned char CM_ENABLE[];
-#define CM_ENABLE_SIZE 0x63
-#define QETH_CM_ENABLE_ISSUER_RM_TOKEN(buffer) (buffer+0x2c)
-#define QETH_CM_ENABLE_FILTER_TOKEN(buffer) (buffer+0x53)
-#define QETH_CM_ENABLE_USER_DATA(buffer) (buffer+0x5b)
-
-#define QETH_CM_ENABLE_RESP_FILTER_TOKEN(buffer) \
-		(PDU_ENCAPSULATION(buffer)+ 0x13)
-
-
-extern unsigned char CM_SETUP[];
-#define CM_SETUP_SIZE 0x64
-#define QETH_CM_SETUP_DEST_ADDR(buffer) (buffer+0x2c)
-#define QETH_CM_SETUP_CONNECTION_TOKEN(buffer) (buffer+0x51)
-#define QETH_CM_SETUP_FILTER_TOKEN(buffer) (buffer+0x5a)
-
-#define QETH_CM_SETUP_RESP_DEST_ADDR(buffer) \
-		(PDU_ENCAPSULATION(buffer) + 0x1a)
-
-extern unsigned char ULP_ENABLE[];
-#define ULP_ENABLE_SIZE 0x6b
-#define QETH_ULP_ENABLE_LINKNUM(buffer) (buffer+0x61)
-#define QETH_ULP_ENABLE_DEST_ADDR(buffer) (buffer+0x2c)
-#define QETH_ULP_ENABLE_FILTER_TOKEN(buffer) (buffer+0x53)
-#define QETH_ULP_ENABLE_PORTNAME_AND_LL(buffer) (buffer+0x62)
-#define QETH_ULP_ENABLE_RESP_FILTER_TOKEN(buffer) \
-		(PDU_ENCAPSULATION(buffer) + 0x13)
-#define QETH_ULP_ENABLE_RESP_MAX_MTU(buffer) \
-		(PDU_ENCAPSULATION(buffer)+ 0x1f)
-#define QETH_ULP_ENABLE_RESP_DIFINFO_LEN(buffer) \
-		(PDU_ENCAPSULATION(buffer) + 0x17)
-#define QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer) \
-		(PDU_ENCAPSULATION(buffer)+ 0x2b)
-/* Layer 2 defintions */
-#define QETH_PROT_LAYER2 0x08
-#define QETH_PROT_TCPIP  0x03
-#define QETH_PROT_OSN2   0x0a
-#define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer+0x50)
-#define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer+0x19)
-
-extern unsigned char ULP_SETUP[];
-#define ULP_SETUP_SIZE 0x6c
-#define QETH_ULP_SETUP_DEST_ADDR(buffer) (buffer+0x2c)
-#define QETH_ULP_SETUP_CONNECTION_TOKEN(buffer) (buffer+0x51)
-#define QETH_ULP_SETUP_FILTER_TOKEN(buffer) (buffer+0x5a)
-#define QETH_ULP_SETUP_CUA(buffer) (buffer+0x68)
-#define QETH_ULP_SETUP_REAL_DEVADDR(buffer) (buffer+0x6a)
-
-#define QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(buffer) \
-		(PDU_ENCAPSULATION(buffer)+0x1a)
-
-
-extern unsigned char DM_ACT[];
-#define DM_ACT_SIZE 0x55
-#define QETH_DM_ACT_DEST_ADDR(buffer) (buffer+0x2c)
-#define QETH_DM_ACT_CONNECTION_TOKEN(buffer) (buffer+0x51)
-
-
-
-#define QETH_TRANSPORT_HEADER_SEQ_NO(buffer) (buffer+4)
-#define QETH_PDU_HEADER_SEQ_NO(buffer) (buffer+0x1c)
-#define QETH_PDU_HEADER_ACK_SEQ_NO(buffer) (buffer+0x20)
-
-extern unsigned char IDX_ACTIVATE_READ[];
-extern unsigned char IDX_ACTIVATE_WRITE[];
-
-#define IDX_ACTIVATE_SIZE	0x22
-#define QETH_IDX_ACT_ISSUER_RM_TOKEN(buffer) (buffer+0x0c)
-#define QETH_IDX_NO_PORTNAME_REQUIRED(buffer) ((buffer)[0x0b]&0x80)
-#define QETH_IDX_ACT_FUNC_LEVEL(buffer) (buffer+0x10)
-#define QETH_IDX_ACT_DATASET_NAME(buffer) (buffer+0x16)
-#define QETH_IDX_ACT_QDIO_DEV_CUA(buffer) (buffer+0x1e)
-#define QETH_IDX_ACT_QDIO_DEV_REALADDR(buffer) (buffer+0x20)
-#define QETH_IS_IDX_ACT_POS_REPLY(buffer) (((buffer)[0x08]&3)==2)
-#define QETH_IDX_REPLY_LEVEL(buffer) (buffer+0x12)
-#define QETH_IDX_ACT_CAUSE_CODE(buffer) (buffer)[0x09]
-
-#define PDU_ENCAPSULATION(buffer) \
-	(buffer + *(buffer + (*(buffer+0x0b)) + \
-	 *(buffer + *(buffer+0x0b)+0x11) +0x07))
-
-#define IS_IPA(buffer) \
-	((buffer) && \
-	 ( *(buffer + ((*(buffer+0x0b))+4) )==0xc1) )
-
-#define ADDR_FRAME_TYPE_DIX 1
-#define ADDR_FRAME_TYPE_802_3 2
-#define ADDR_FRAME_TYPE_TR_WITHOUT_SR 0x10
-#define ADDR_FRAME_TYPE_TR_WITH_SR 0x20
-
-#endif
Index: my_git/drivers/s390/net/qeth_proc.c
===================================================================
--- my_git.orig/drivers/s390/net/qeth_proc.c	2008-02-15 08:49:22.000000000 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,316 +0,0 @@
-/*
- *
- * linux/drivers/s390/net/qeth_fs.c
- *
- * Linux on zSeries OSA Express and HiperSockets support
- * This file contains code related to procfs.
- *
- * Copyright 2000,2003 IBM Corporation
- *
- * Author(s): Thomas Spatzier <tspat@de.ibm.com>
- *
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/list.h>
-#include <linux/rwsem.h>
-
-#include "qeth.h"
-#include "qeth_mpc.h"
-#include "qeth_fs.h"
-
-/***** /proc/qeth *****/
-#define QETH_PROCFILE_NAME "qeth"
-static struct proc_dir_entry *qeth_procfile;
-
-static int
-qeth_procfile_seq_match(struct device *dev, void *data)
-{
-	return(dev ? 1 : 0);
-}
-
-static void *
-qeth_procfile_seq_start(struct seq_file *s, loff_t *offset)
-{
-	struct device *dev = NULL;
-	loff_t nr = 0;
-
-	if (*offset == 0)
-		return SEQ_START_TOKEN;
-	while (1) {
-		dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
-					 NULL, qeth_procfile_seq_match);
-		if (++nr == *offset)
-			break;
-		put_device(dev);
-	}
-	return dev;
-}
-
-static void
-qeth_procfile_seq_stop(struct seq_file *s, void* it)
-{
-}
-
-static void *
-qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
-{
-	struct device *prev, *next;
-
-	if (it == SEQ_START_TOKEN)
-		prev = NULL;
-	else
-		prev = (struct device *) it;
-	next = driver_find_device(&qeth_ccwgroup_driver.driver,
-				  prev, NULL, qeth_procfile_seq_match);
-	(*offset)++;
-	return (void *) next;
-}
-
-static inline const char *
-qeth_get_router_str(struct qeth_card *card, int ipv)
-{
-	enum qeth_routing_types routing_type = NO_ROUTER;
-
-	if (ipv == 4) {
-		routing_type = card->options.route4.type;
-	} else {
-#ifdef CONFIG_QETH_IPV6
-		routing_type = card->options.route6.type;
-#else
-		return "n/a";
-#endif /* CONFIG_QETH_IPV6 */
-	}
-
-	switch (routing_type){
-	case PRIMARY_ROUTER:
-		return "pri";
-	case SECONDARY_ROUTER:
-		return "sec";
-	case MULTICAST_ROUTER:
-		if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
-			return "mc+";
-		return "mc";
-	case PRIMARY_CONNECTOR:
-		if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
-			return "p+c";
-		return "p.c";
-	case SECONDARY_CONNECTOR:
-		if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
-			return "s+c";
-		return "s.c";
-	default:   /* NO_ROUTER */
-		return "no";
-	}
-}
-
-static int
-qeth_procfile_seq_show(struct seq_file *s, void *it)
-{
-	struct device *device;
-	struct qeth_card *card;
-	char tmp[12]; /* for qeth_get_prioq_str */
-
-	if (it == SEQ_START_TOKEN){
-		seq_printf(s, "devices                    CHPID interface  "
-		              "cardtype       port chksum prio-q'ing rtr4 "
-			      "rtr6 fsz   cnt\n");
-		seq_printf(s, "-------------------------- ----- ---------- "
-			      "-------------- ---- ------ ---------- ---- "
-			      "---- ----- -----\n");
-	} else {
-		device = (struct device *) it;
-		card = device->driver_data;
-		seq_printf(s, "%s/%s/%s x%02X   %-10s %-14s %-4i ",
-				CARD_RDEV_ID(card),
-				CARD_WDEV_ID(card),
-				CARD_DDEV_ID(card),
-				card->info.chpid,
-				QETH_CARD_IFNAME(card),
-				qeth_get_cardname_short(card),
-				card->info.portno);
-		if (card->lan_online)
-			seq_printf(s, "%-6s %-10s %-4s %-4s %-5s %-5i\n",
-					qeth_get_checksum_str(card),
-					qeth_get_prioq_str(card, tmp),
-					qeth_get_router_str(card, 4),
-					qeth_get_router_str(card, 6),
-					qeth_get_bufsize_str(card),
-					card->qdio.in_buf_pool.buf_count);
-		else
-			seq_printf(s, "  +++ LAN OFFLINE +++\n");
-		put_device(device);
-	}
-	return 0;
-}
-
-static const struct seq_operations qeth_procfile_seq_ops = {
-	.start = qeth_procfile_seq_start,
-	.stop  = qeth_procfile_seq_stop,
-	.next  = qeth_procfile_seq_next,
-	.show  = qeth_procfile_seq_show,
-};
-
-static int
-qeth_procfile_open(struct inode *inode, struct file *file)
-{
-	return seq_open(file, &qeth_procfile_seq_ops);
-}
-
-static const struct file_operations qeth_procfile_fops = {
-	.owner   = THIS_MODULE,
-	.open    = qeth_procfile_open,
-	.read    = seq_read,
-	.llseek  = seq_lseek,
-	.release = seq_release,
-};
-
-/***** /proc/qeth_perf *****/
-#define QETH_PERF_PROCFILE_NAME "qeth_perf"
-static struct proc_dir_entry *qeth_perf_procfile;
-
-static int
-qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
-{
-	struct device *device;
-	struct qeth_card *card;
-
-
-	if (it == SEQ_START_TOKEN)
-		return 0;
-
-	device = (struct device *) it;
-	card = device->driver_data;
-	seq_printf(s, "For card with devnos %s/%s/%s (%s):\n",
-			CARD_RDEV_ID(card),
-			CARD_WDEV_ID(card),
-			CARD_DDEV_ID(card),
-			QETH_CARD_IFNAME(card)
-		  );
-	if (!card->options.performance_stats)
-		seq_printf(s, "Performance statistics are deactivated.\n");
-	seq_printf(s, "  Skb's/buffers received                 : %lu/%u\n"
-		      "  Skb's/buffers sent                     : %lu/%u\n\n",
-		        card->stats.rx_packets -
-				card->perf_stats.initial_rx_packets,
-			card->perf_stats.bufs_rec,
-		        card->stats.tx_packets -
-				card->perf_stats.initial_tx_packets,
-			card->perf_stats.bufs_sent
-		  );
-	seq_printf(s, "  Skb's/buffers sent without packing     : %lu/%u\n"
-		      "  Skb's/buffers sent with packing        : %u/%u\n\n",
-		   card->stats.tx_packets - card->perf_stats.initial_tx_packets
-					  - card->perf_stats.skbs_sent_pack,
-		   card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack,
-		   card->perf_stats.skbs_sent_pack,
-		   card->perf_stats.bufs_sent_pack
-		  );
-	seq_printf(s, "  Skbs sent in SG mode                   : %u\n"
-		      "  Skb fragments sent in SG mode          : %u\n\n",
-		      card->perf_stats.sg_skbs_sent,
-		      card->perf_stats.sg_frags_sent);
-	seq_printf(s, "  Skbs received in SG mode               : %u\n"
-		      "  Skb fragments received in SG mode      : %u\n"
-		      "  Page allocations for rx SG mode        : %u\n\n",
-		      card->perf_stats.sg_skbs_rx,
-		      card->perf_stats.sg_frags_rx,
-		      card->perf_stats.sg_alloc_page_rx);
-	seq_printf(s, "  large_send tx (in Kbytes)              : %u\n"
-		      "  large_send count                       : %u\n\n",
-		      card->perf_stats.large_send_bytes >> 10,
-		      card->perf_stats.large_send_cnt);
-	seq_printf(s, "  Packing state changes no pkg.->packing : %u/%u\n"
-		      "  Watermarks L/H                         : %i/%i\n"
-		      "  Current buffer usage (outbound q's)    : "
-		      "%i/%i/%i/%i\n\n",
-		        card->perf_stats.sc_dp_p, card->perf_stats.sc_p_dp,
-			QETH_LOW_WATERMARK_PACK, QETH_HIGH_WATERMARK_PACK,
-			atomic_read(&card->qdio.out_qs[0]->used_buffers),
-			(card->qdio.no_out_queues > 1)?
-				atomic_read(&card->qdio.out_qs[1]->used_buffers)
-				: 0,
-			(card->qdio.no_out_queues > 2)?
-				atomic_read(&card->qdio.out_qs[2]->used_buffers)
-				: 0,
-			(card->qdio.no_out_queues > 3)?
-				atomic_read(&card->qdio.out_qs[3]->used_buffers)
-				: 0
-		  );
-	seq_printf(s, "  Inbound handler time (in us)           : %u\n"
-		      "  Inbound handler count                  : %u\n"
-		      "  Inbound do_QDIO time (in us)           : %u\n"
-		      "  Inbound do_QDIO count                  : %u\n\n"
-		      "  Outbound handler time (in us)          : %u\n"
-		      "  Outbound handler count                 : %u\n\n"
-		      "  Outbound time (in us, incl QDIO)       : %u\n"
-		      "  Outbound count                         : %u\n"
-		      "  Outbound do_QDIO time (in us)          : %u\n"
-		      "  Outbound do_QDIO count                 : %u\n\n",
-		        card->perf_stats.inbound_time,
-			card->perf_stats.inbound_cnt,
-		        card->perf_stats.inbound_do_qdio_time,
-			card->perf_stats.inbound_do_qdio_cnt,
-			card->perf_stats.outbound_handler_time,
-			card->perf_stats.outbound_handler_cnt,
-			card->perf_stats.outbound_time,
-			card->perf_stats.outbound_cnt,
-		        card->perf_stats.outbound_do_qdio_time,
-			card->perf_stats.outbound_do_qdio_cnt
-		  );
-	put_device(device);
-	return 0;
-}
-
-static const struct seq_operations qeth_perf_procfile_seq_ops = {
-	.start = qeth_procfile_seq_start,
-	.stop  = qeth_procfile_seq_stop,
-	.next  = qeth_procfile_seq_next,
-	.show  = qeth_perf_procfile_seq_show,
-};
-
-static int
-qeth_perf_procfile_open(struct inode *inode, struct file *file)
-{
-	return seq_open(file, &qeth_perf_procfile_seq_ops);
-}
-
-static const struct file_operations qeth_perf_procfile_fops = {
-	.owner   = THIS_MODULE,
-	.open    = qeth_perf_procfile_open,
-	.read    = seq_read,
-	.llseek  = seq_lseek,
-	.release = seq_release,
-};
-
-int __init
-qeth_create_procfs_entries(void)
-{
-	qeth_procfile = create_proc_entry(QETH_PROCFILE_NAME,
-					   S_IFREG | 0444, NULL);
-	if (qeth_procfile)
-		qeth_procfile->proc_fops = &qeth_procfile_fops;
-
-	qeth_perf_procfile = create_proc_entry(QETH_PERF_PROCFILE_NAME,
-					   S_IFREG | 0444, NULL);
-	if (qeth_perf_procfile)
-		qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops;
-
-	if (qeth_procfile &&
-	    qeth_perf_procfile)
-		return 0;
-	else
-		return -ENOMEM;
-}
-
-void __exit
-qeth_remove_procfs_entries(void)
-{
-	if (qeth_procfile)
-		remove_proc_entry(QETH_PROCFILE_NAME, NULL);
-	if (qeth_perf_procfile)
-		remove_proc_entry(QETH_PERF_PROCFILE_NAME, NULL);
-}
-
Index: my_git/drivers/s390/net/qeth_sys.c
===================================================================
--- my_git.orig/drivers/s390/net/qeth_sys.c	2008-02-15 08:49:22.000000000 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,1858 +0,0 @@
-/*
- *
- * linux/drivers/s390/net/qeth_sys.c
- *
- * Linux on zSeries OSA Express and HiperSockets support
- * This file contains code related to sysfs.
- *
- * Copyright 2000,2003 IBM Corporation
- *
- * Author(s): Thomas Spatzier <tspat@de.ibm.com>
- * 	      Frank Pavlic <fpavlic@de.ibm.com>
- *
- */
-#include <linux/list.h>
-#include <linux/rwsem.h>
-
-#include <asm/ebcdic.h>
-
-#include "qeth.h"
-#include "qeth_mpc.h"
-#include "qeth_fs.h"
-
-/*****************************************************************************/
-/*                                                                           */
-/*          /sys-fs stuff UNDER DEVELOPMENT !!!                              */
-/*                                                                           */
-/*****************************************************************************/
-//low/high watermark
-
-static ssize_t
-qeth_dev_state_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-	if (!card)
-		return -EINVAL;
-
-	switch (card->state) {
-	case CARD_STATE_DOWN:
-		return sprintf(buf, "DOWN\n");
-	case CARD_STATE_HARDSETUP:
-		return sprintf(buf, "HARDSETUP\n");
-	case CARD_STATE_SOFTSETUP:
-		return sprintf(buf, "SOFTSETUP\n");
-	case CARD_STATE_UP:
-		if (card->lan_online)
-		return sprintf(buf, "UP (LAN ONLINE)\n");
-		else
-			return sprintf(buf, "UP (LAN OFFLINE)\n");
-	case CARD_STATE_RECOVER:
-		return sprintf(buf, "RECOVER\n");
-	default:
-		return sprintf(buf, "UNKNOWN\n");
-	}
-}
-
-static DEVICE_ATTR(state, 0444, qeth_dev_state_show, NULL);
-
-static ssize_t
-qeth_dev_chpid_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-	if (!card)
-		return -EINVAL;
-
-	return sprintf(buf, "%02X\n", card->info.chpid);
-}
-
-static DEVICE_ATTR(chpid, 0444, qeth_dev_chpid_show, NULL);
-
-static ssize_t
-qeth_dev_if_name_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-	if (!card)
-		return -EINVAL;
-	return sprintf(buf, "%s\n", QETH_CARD_IFNAME(card));
-}
-
-static DEVICE_ATTR(if_name, 0444, qeth_dev_if_name_show, NULL);
-
-static ssize_t
-qeth_dev_card_type_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-	if (!card)
-		return -EINVAL;
-
-	return sprintf(buf, "%s\n", qeth_get_cardname_short(card));
-}
-
-static DEVICE_ATTR(card_type, 0444, qeth_dev_card_type_show, NULL);
-
-static ssize_t
-qeth_dev_portno_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-	if (!card)
-		return -EINVAL;
-
-	return sprintf(buf, "%i\n", card->info.portno);
-}
-
-static ssize_t
-qeth_dev_portno_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-	unsigned int portno;
-
-	if (!card)
-		return -EINVAL;
-
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
-	portno = simple_strtoul(buf, &tmp, 16);
-	if (portno > MAX_PORTNO){
-		PRINT_WARN("portno 0x%X is out of range\n", portno);
-		return -EINVAL;
-	}
-
-	card->info.portno = portno;
-	return count;
-}
-
-static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);
-
-static ssize_t
-qeth_dev_portname_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-	char portname[9] = {0, };
-
-	if (!card)
-		return -EINVAL;
-
-	if (card->info.portname_required) {
-		memcpy(portname, card->info.portname + 1, 8);
-		EBCASC(portname, 8);
-		return sprintf(buf, "%s\n", portname);
-	} else
-		return sprintf(buf, "no portname required\n");
-}
-
-static ssize_t
-qeth_dev_portname_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-	int i;
-
-	if (!card)
-		return -EINVAL;
-
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
-	tmp = strsep((char **) &buf, "\n");
-	if ((strlen(tmp) > 8) || (strlen(tmp) == 0))
-		return -EINVAL;
-
-	card->info.portname[0] = strlen(tmp);
-	/* for beauty reasons */
-	for (i = 1; i < 9; i++)
-		card->info.portname[i] = ' ';
-	strcpy(card->info.portname + 1, tmp);
-	ASCEBC(card->info.portname + 1, 8);
-
-	return count;
-}
-
-static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show,
-		qeth_dev_portname_store);
-
-static ssize_t
-qeth_dev_checksum_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return sprintf(buf, "%s checksumming\n", qeth_get_checksum_str(card));
-}
-
-static ssize_t
-qeth_dev_checksum_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-
-	if (!card)
-		return -EINVAL;
-
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
-	tmp = strsep((char **) &buf, "\n");
-	if (!strcmp(tmp, "sw_checksumming"))
-		card->options.checksum_type = SW_CHECKSUMMING;
-	else if (!strcmp(tmp, "hw_checksumming"))
-		card->options.checksum_type = HW_CHECKSUMMING;
-	else if (!strcmp(tmp, "no_checksumming"))
-		card->options.checksum_type = NO_CHECKSUMMING;
-	else {
-		PRINT_WARN("Unknown checksumming type '%s'\n", tmp);
-		return -EINVAL;
-	}
-	return count;
-}
-
-static DEVICE_ATTR(checksumming, 0644, qeth_dev_checksum_show,
-		qeth_dev_checksum_store);
-
-static ssize_t
-qeth_dev_prioqing_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	switch (card->qdio.do_prio_queueing) {
-	case QETH_PRIO_Q_ING_PREC:
-		return sprintf(buf, "%s\n", "by precedence");
-	case QETH_PRIO_Q_ING_TOS:
-		return sprintf(buf, "%s\n", "by type of service");
-	default:
-		return sprintf(buf, "always queue %i\n",
-			       card->qdio.default_out_queue);
-	}
-}
-
-static ssize_t
-qeth_dev_prioqing_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-
-	if (!card)
-		return -EINVAL;
-
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
-	/* check if 1920 devices are supported ,
-	 * if though we have to permit priority queueing
-	 */
-	if (card->qdio.no_out_queues == 1) {
-		PRINT_WARN("Priority queueing disabled due "
-			   "to hardware limitations!\n");
-		card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;
-		return -EPERM;
-	}
-
-	tmp = strsep((char **) &buf, "\n");
-	if (!strcmp(tmp, "prio_queueing_prec"))
-		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC;
-	else if (!strcmp(tmp, "prio_queueing_tos"))
-		card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS;
-	else if (!strcmp(tmp, "no_prio_queueing:0")) {
-		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
-		card->qdio.default_out_queue = 0;
-	} else if (!strcmp(tmp, "no_prio_queueing:1")) {
-		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
-		card->qdio.default_out_queue = 1;
-	} else if (!strcmp(tmp, "no_prio_queueing:2")) {
-		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
-		card->qdio.default_out_queue = 2;
-	} else if (!strcmp(tmp, "no_prio_queueing:3")) {
-		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
-		card->qdio.default_out_queue = 3;
-	} else if (!strcmp(tmp, "no_prio_queueing")) {
-		card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
-		card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
-	} else {
-		PRINT_WARN("Unknown queueing type '%s'\n", tmp);
-		return -EINVAL;
-	}
-	return count;
-}
-
-static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show,
-		qeth_dev_prioqing_store);
-
-static ssize_t
-qeth_dev_bufcnt_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return sprintf(buf, "%i\n", card->qdio.in_buf_pool.buf_count);
-}
-
-static ssize_t
-qeth_dev_bufcnt_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-	int cnt, old_cnt;
-	int rc;
-
-	if (!card)
-		return -EINVAL;
-
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
-	old_cnt = card->qdio.in_buf_pool.buf_count;
-	cnt = simple_strtoul(buf, &tmp, 10);
-	cnt = (cnt < QETH_IN_BUF_COUNT_MIN) ? QETH_IN_BUF_COUNT_MIN :
-		((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt);
-	if (old_cnt != cnt) {
-		if ((rc = qeth_realloc_buffer_pool(card, cnt)))
-			PRINT_WARN("Error (%d) while setting "
-				   "buffer count.\n", rc);
-	}
-	return count;
-}
-
-static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show,
-		qeth_dev_bufcnt_store);
-
-static ssize_t
-qeth_dev_route_show(struct qeth_card *card, struct qeth_routing_info *route,
-		    char *buf)
-{
-	switch (route->type) {
-	case PRIMARY_ROUTER:
-		return sprintf(buf, "%s\n", "primary router");
-	case SECONDARY_ROUTER:
-		return sprintf(buf, "%s\n", "secondary router");
-	case MULTICAST_ROUTER:
-		if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
-			return sprintf(buf, "%s\n", "multicast router+");
-		else
-			return sprintf(buf, "%s\n", "multicast router");
-	case PRIMARY_CONNECTOR:
-		if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
-			return sprintf(buf, "%s\n", "primary connector+");
-		else
-			return sprintf(buf, "%s\n", "primary connector");
-	case SECONDARY_CONNECTOR:
-		if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
-			return sprintf(buf, "%s\n", "secondary connector+");
-		else
-			return sprintf(buf, "%s\n", "secondary connector");
-	default:
-		return sprintf(buf, "%s\n", "no");
-	}
-}
-
-static ssize_t
-qeth_dev_route4_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_route_show(card, &card->options.route4, buf);
-}
-
-static ssize_t
-qeth_dev_route_store(struct qeth_card *card, struct qeth_routing_info *route,
-		enum qeth_prot_versions prot, const char *buf, size_t count)
-{
-	enum qeth_routing_types old_route_type = route->type;
-	char *tmp;
-	int rc;
-
-	tmp = strsep((char **) &buf, "\n");
-
-	if (!strcmp(tmp, "no_router")){
-		route->type = NO_ROUTER;
-	} else if (!strcmp(tmp, "primary_connector")) {
-		route->type = PRIMARY_CONNECTOR;
-	} else if (!strcmp(tmp, "secondary_connector")) {
-		route->type = SECONDARY_CONNECTOR;
-	} else if (!strcmp(tmp, "primary_router")) {
-		route->type = PRIMARY_ROUTER;
-	} else if (!strcmp(tmp, "secondary_router")) {
-		route->type = SECONDARY_ROUTER;
-	} else if (!strcmp(tmp, "multicast_router")) {
-		route->type = MULTICAST_ROUTER;
-	} else {
-		PRINT_WARN("Invalid routing type '%s'.\n", tmp);
-		return -EINVAL;
-	}
-	if (((card->state == CARD_STATE_SOFTSETUP) ||
-	     (card->state == CARD_STATE_UP)) &&
-	    (old_route_type != route->type)){
-		if (prot == QETH_PROT_IPV4)
-			rc = qeth_setrouting_v4(card);
-		else if (prot == QETH_PROT_IPV6)
-			rc = qeth_setrouting_v6(card);
-	}
-	return count;
-}
-
-static ssize_t
-qeth_dev_route4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_route_store(card, &card->options.route4,
-			            QETH_PROT_IPV4, buf, count);
-}
-
-static DEVICE_ATTR(route4, 0644, qeth_dev_route4_show, qeth_dev_route4_store);
-
-#ifdef CONFIG_QETH_IPV6
-static ssize_t
-qeth_dev_route6_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	if (!qeth_is_supported(card, IPA_IPV6))
-		return sprintf(buf, "%s\n", "n/a");
-
-	return qeth_dev_route_show(card, &card->options.route6, buf);
-}
-
-static ssize_t
-qeth_dev_route6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	if (!qeth_is_supported(card, IPA_IPV6)){
-		PRINT_WARN("IPv6 not supported for interface %s.\n"
-			   "Routing status no changed.\n",
-			   QETH_CARD_IFNAME(card));
-		return -ENOTSUPP;
-	}
-
-	return qeth_dev_route_store(card, &card->options.route6,
-			            QETH_PROT_IPV6, buf, count);
-}
-
-static DEVICE_ATTR(route6, 0644, qeth_dev_route6_show, qeth_dev_route6_store);
-#endif
-
-static ssize_t
-qeth_dev_add_hhlen_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return sprintf(buf, "%i\n", card->options.add_hhlen);
-}
-
-static ssize_t
-qeth_dev_add_hhlen_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-	int i;
-
-	if (!card)
-		return -EINVAL;
-
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
-	i = simple_strtoul(buf, &tmp, 10);
-	if ((i < 0) || (i > MAX_ADD_HHLEN)) {
-		PRINT_WARN("add_hhlen out of range\n");
-		return -EINVAL;
-	}
-	card->options.add_hhlen = i;
-
-	return count;
-}
-
-static DEVICE_ATTR(add_hhlen, 0644, qeth_dev_add_hhlen_show,
-		   qeth_dev_add_hhlen_store);
-
-static ssize_t
-qeth_dev_fake_ll_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return sprintf(buf, "%i\n", card->options.fake_ll? 1:0);
-}
-
-static ssize_t
-qeth_dev_fake_ll_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-	int i;
-
-	if (!card)
-		return -EINVAL;
-
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
-	i = simple_strtoul(buf, &tmp, 16);
-	if ((i != 0) && (i != 1)) {
-		PRINT_WARN("fake_ll: write 0 or 1 to this file!\n");
-		return -EINVAL;
-	}
-	card->options.fake_ll = i;
-	return count;
-}
-
-static DEVICE_ATTR(fake_ll, 0644, qeth_dev_fake_ll_show,
-		   qeth_dev_fake_ll_store);
-
-static ssize_t
-qeth_dev_fake_broadcast_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
-}
-
-static ssize_t
-qeth_dev_fake_broadcast_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-	int i;
-
-	if (!card)
-		return -EINVAL;
-
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
-	i = simple_strtoul(buf, &tmp, 16);
-	if ((i == 0) || (i == 1))
-		card->options.fake_broadcast = i;
-	else {
-		PRINT_WARN("fake_broadcast: write 0 or 1 to this file!\n");
-		return -EINVAL;
-	}
-	return count;
-}
-
-static DEVICE_ATTR(fake_broadcast, 0644, qeth_dev_fake_broadcast_show,
-		   qeth_dev_fake_broadcast_store);
-
-static ssize_t
-qeth_dev_recover_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-	int i;
-
-	if (!card)
-		return -EINVAL;
-
-	if (card->state != CARD_STATE_UP)
-		return -EPERM;
-
-	i = simple_strtoul(buf, &tmp, 16);
-	if (i == 1)
-		qeth_schedule_recovery(card);
-
-	return count;
-}
-
-static DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store);
-
-static ssize_t
-qeth_dev_broadcast_mode_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
-	      (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
-		return sprintf(buf, "n/a\n");
-
-	return sprintf(buf, "%s\n", (card->options.broadcast_mode ==
-				     QETH_TR_BROADCAST_ALLRINGS)?
-		       "all rings":"local");
-}
-
-static ssize_t
-qeth_dev_broadcast_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-
-	if (!card)
-		return -EINVAL;
-
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
-	if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
-	      (card->info.link_type == QETH_LINK_TYPE_LANE_TR))){
-		PRINT_WARN("Device is not a tokenring device!\n");
-		return -EINVAL;
-	}
-
-	tmp = strsep((char **) &buf, "\n");
-
-	if (!strcmp(tmp, "local")){
-		card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL;
-		return count;
-	} else if (!strcmp(tmp, "all_rings")) {
-		card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
-		return count;
-	} else {
-		PRINT_WARN("broadcast_mode: invalid mode %s!\n",
-			   tmp);
-		return -EINVAL;
-	}
-	return count;
-}
-
-static DEVICE_ATTR(broadcast_mode, 0644, qeth_dev_broadcast_mode_show,
-		   qeth_dev_broadcast_mode_store);
-
-static ssize_t
-qeth_dev_canonical_macaddr_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
-	      (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
-		return sprintf(buf, "n/a\n");
-
-	return sprintf(buf, "%i\n", (card->options.macaddr_mode ==
-				     QETH_TR_MACADDR_CANONICAL)? 1:0);
-}
-
-static ssize_t
-qeth_dev_canonical_macaddr_store(struct device *dev, struct device_attribute *attr, const char *buf,
-				  size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-	int i;
-
-	if (!card)
-		return -EINVAL;
-
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
-	if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
-	      (card->info.link_type == QETH_LINK_TYPE_LANE_TR))){
-		PRINT_WARN("Device is not a tokenring device!\n");
-		return -EINVAL;
-	}
-
-	i = simple_strtoul(buf, &tmp, 16);
-	if ((i == 0) || (i == 1))
-		card->options.macaddr_mode = i?
-			QETH_TR_MACADDR_CANONICAL :
-			QETH_TR_MACADDR_NONCANONICAL;
-	else {
-		PRINT_WARN("canonical_macaddr: write 0 or 1 to this file!\n");
-		return -EINVAL;
-	}
-	return count;
-}
-
-static DEVICE_ATTR(canonical_macaddr, 0644, qeth_dev_canonical_macaddr_show,
-		   qeth_dev_canonical_macaddr_store);
-
-static ssize_t
-qeth_dev_layer2_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return sprintf(buf, "%i\n", card->options.layer2 ? 1:0);
-}
-
-static ssize_t
-qeth_dev_layer2_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-	int i;
-
-	if (!card)
-		return -EINVAL;
-	if (card->info.type == QETH_CARD_TYPE_IQD) {
-                PRINT_WARN("Layer2 on Hipersockets is not supported! \n");
-                return -EPERM;
-        }
-
-	if (((card->state != CARD_STATE_DOWN) &&
-	     (card->state != CARD_STATE_RECOVER)))
-		return -EPERM;
-
-	i = simple_strtoul(buf, &tmp, 16);
-	if ((i == 0) || (i == 1))
-		card->options.layer2 = i;
-	else {
-		PRINT_WARN("layer2: write 0 or 1 to this file!\n");
-		return -EINVAL;
-	}
-	return count;
-}
-
-static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,
-		   qeth_dev_layer2_store);
-
-static ssize_t
-qeth_dev_performance_stats_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return sprintf(buf, "%i\n", card->options.performance_stats ? 1:0);
-}
-
-static ssize_t
-qeth_dev_performance_stats_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-	int i;
-
-	if (!card)
-		return -EINVAL;
-
-	i = simple_strtoul(buf, &tmp, 16);
-	if ((i == 0) || (i == 1)) {
-		if (i == card->options.performance_stats)
-			return count;
-		card->options.performance_stats = i;
-		if (i == 0)
-			memset(&card->perf_stats, 0,
-				sizeof(struct qeth_perf_stats));
-		card->perf_stats.initial_rx_packets = card->stats.rx_packets;
-		card->perf_stats.initial_tx_packets = card->stats.tx_packets;
-	} else {
-		PRINT_WARN("performance_stats: write 0 or 1 to this file!\n");
-		return -EINVAL;
-	}
-	return count;
-}
-
-static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show,
-		   qeth_dev_performance_stats_store);
-
-static ssize_t
-qeth_dev_large_send_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	switch (card->options.large_send) {
-	case QETH_LARGE_SEND_NO:
-		return sprintf(buf, "%s\n", "no");
-	case QETH_LARGE_SEND_EDDP:
-		return sprintf(buf, "%s\n", "EDDP");
-	case QETH_LARGE_SEND_TSO:
-		return sprintf(buf, "%s\n", "TSO");
-	default:
-		return sprintf(buf, "%s\n", "N/A");
-	}
-}
-
-static ssize_t
-qeth_dev_large_send_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	enum qeth_large_send_types type;
-	int rc = 0;
-	char *tmp;
-
-	if (!card)
-		return -EINVAL;
-	tmp = strsep((char **) &buf, "\n");
-	if (!strcmp(tmp, "no")){
-		type = QETH_LARGE_SEND_NO;
-	} else if (!strcmp(tmp, "EDDP")) {
-		type = QETH_LARGE_SEND_EDDP;
-	} else if (!strcmp(tmp, "TSO")) {
-		type = QETH_LARGE_SEND_TSO;
-	} else {
-		PRINT_WARN("large_send: invalid mode %s!\n", tmp);
-		return -EINVAL;
-	}
-	if (card->options.large_send == type)
-		return count;
-	if ((rc = qeth_set_large_send(card, type)))
-		return rc;
-	return count;
-}
-
-static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show,
-		   qeth_dev_large_send_store);
-
-static ssize_t
-qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value )
-{
-
-	if (!card)
-		return -EINVAL;
-
-	return sprintf(buf, "%i\n", value);
-}
-
-static ssize_t
-qeth_dev_blkt_store(struct qeth_card *card, const char *buf, size_t count,
-			  int *value, int max_value)
-{
-	char *tmp;
-	int i;
-
-	if (!card)
-		return -EINVAL;
-
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
-	i = simple_strtoul(buf, &tmp, 10);
-	if (i <= max_value) {
-		*value = i;
-	} else {
-		PRINT_WARN("blkt total time: write values between"
-			   " 0 and %d to this file!\n", max_value);
-		return -EINVAL;
-	}
-	return count;
-}
-
-static ssize_t
-qeth_dev_blkt_total_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	return qeth_dev_blkt_show(buf, card, card->info.blkt.time_total);
-}
-
-
-static ssize_t
-qeth_dev_blkt_total_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	return qeth_dev_blkt_store(card, buf, count,
-				   &card->info.blkt.time_total,1000);
-}
-
-
-
-static DEVICE_ATTR(total, 0644, qeth_dev_blkt_total_show,
-		   qeth_dev_blkt_total_store);
-
-static ssize_t
-qeth_dev_blkt_inter_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	return qeth_dev_blkt_show(buf, card, card->info.blkt.inter_packet);
-}
-
-
-static ssize_t
-qeth_dev_blkt_inter_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	return qeth_dev_blkt_store(card, buf, count,
-				   &card->info.blkt.inter_packet,100);
-}
-
-static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,
-		   qeth_dev_blkt_inter_store);
-
-static ssize_t
-qeth_dev_blkt_inter_jumbo_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	return qeth_dev_blkt_show(buf, card,
-				  card->info.blkt.inter_packet_jumbo);
-}
-
-
-static ssize_t
-qeth_dev_blkt_inter_jumbo_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	return qeth_dev_blkt_store(card, buf, count,
-				   &card->info.blkt.inter_packet_jumbo,100);
-}
-
-static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show,
-		   qeth_dev_blkt_inter_jumbo_store);
-
-static struct device_attribute * qeth_blkt_device_attrs[] = {
-	&dev_attr_total,
-	&dev_attr_inter,
-	&dev_attr_inter_jumbo,
-	NULL,
-};
-
-static struct attribute_group qeth_device_blkt_group = {
-	.name = "blkt",
-	.attrs = (struct attribute **)qeth_blkt_device_attrs,
-};
-
-static struct device_attribute * qeth_device_attrs[] = {
-	&dev_attr_state,
-	&dev_attr_chpid,
-	&dev_attr_if_name,
-	&dev_attr_card_type,
-	&dev_attr_portno,
-	&dev_attr_portname,
-	&dev_attr_checksumming,
-	&dev_attr_priority_queueing,
-	&dev_attr_buffer_count,
-	&dev_attr_route4,
-#ifdef CONFIG_QETH_IPV6
-	&dev_attr_route6,
-#endif
-	&dev_attr_add_hhlen,
-	&dev_attr_fake_ll,
-	&dev_attr_fake_broadcast,
-	&dev_attr_recover,
-	&dev_attr_broadcast_mode,
-	&dev_attr_canonical_macaddr,
-	&dev_attr_layer2,
-	&dev_attr_large_send,
-	&dev_attr_performance_stats,
-	NULL,
-};
-
-static struct attribute_group qeth_device_attr_group = {
-	.attrs = (struct attribute **)qeth_device_attrs,
-};
-
-static struct device_attribute * qeth_osn_device_attrs[] = {
-	&dev_attr_state,
-	&dev_attr_chpid,
-	&dev_attr_if_name,
-	&dev_attr_card_type,
-	&dev_attr_buffer_count,
-	&dev_attr_recover,
-	NULL,
-};
-
-static struct attribute_group qeth_osn_device_attr_group = {
-	.attrs = (struct attribute **)qeth_osn_device_attrs,
-};
-
-#define QETH_DEVICE_ATTR(_id,_name,_mode,_show,_store)			     \
-struct device_attribute dev_attr_##_id = {				     \
-	.attr = {.name=__stringify(_name), .mode=_mode, },\
-	.show	= _show,						     \
-	.store	= _store,						     \
-};
-
-static int
-qeth_check_layer2(struct qeth_card *card)
-{
-	if (card->options.layer2)
-		return -EPERM;
-	return 0;
-}
-
-
-static ssize_t
-qeth_dev_ipato_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-	return sprintf(buf, "%i\n", card->ipato.enabled? 1:0);
-}
-
-static ssize_t
-qeth_dev_ipato_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-
-	if (!card)
-		return -EINVAL;
-
-	if ((card->state != CARD_STATE_DOWN) &&
-	    (card->state != CARD_STATE_RECOVER))
-		return -EPERM;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-
-	tmp = strsep((char **) &buf, "\n");
-	if (!strcmp(tmp, "toggle")){
-		card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
-	} else if (!strcmp(tmp, "1")){
-		card->ipato.enabled = 1;
-	} else if (!strcmp(tmp, "0")){
-		card->ipato.enabled = 0;
-	} else {
-		PRINT_WARN("ipato_enable: write 0, 1 or 'toggle' to "
-			   "this file\n");
-		return -EINVAL;
-	}
-	return count;
-}
-
-static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
-			qeth_dev_ipato_enable_show,
-			qeth_dev_ipato_enable_store);
-
-static ssize_t
-qeth_dev_ipato_invert4_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-
-	return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
-}
-
-static ssize_t
-qeth_dev_ipato_invert4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-
-	if (!card)
-		return -EINVAL;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-
-	tmp = strsep((char **) &buf, "\n");
-	if (!strcmp(tmp, "toggle")){
-		card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
-	} else if (!strcmp(tmp, "1")){
-		card->ipato.invert4 = 1;
-	} else if (!strcmp(tmp, "0")){
-		card->ipato.invert4 = 0;
-	} else {
-		PRINT_WARN("ipato_invert4: write 0, 1 or 'toggle' to "
-			   "this file\n");
-		return -EINVAL;
-	}
-	return count;
-}
-
-static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
-			qeth_dev_ipato_invert4_show,
-			qeth_dev_ipato_invert4_store);
-
-static ssize_t
-qeth_dev_ipato_add_show(char *buf, struct qeth_card *card,
-			enum qeth_prot_versions proto)
-{
-	struct qeth_ipato_entry *ipatoe;
-	unsigned long flags;
-	char addr_str[40];
-	int entry_len; /* length of 1 entry string, differs between v4 and v6 */
-	int i = 0;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-
-	entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
-	/* add strlen for "/<mask>\n" */
-	entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
-	spin_lock_irqsave(&card->ip_lock, flags);
-	list_for_each_entry(ipatoe, &card->ipato.entries, entry){
-		if (ipatoe->proto != proto)
-			continue;
-		/* String must not be longer than PAGE_SIZE. So we check if
-		 * string length gets near PAGE_SIZE. Then we can savely display
-		 * the next IPv6 address (worst case, compared to IPv4) */
-		if ((PAGE_SIZE - i) <= entry_len)
-			break;
-		qeth_ipaddr_to_string(proto, ipatoe->addr, addr_str);
-		i += snprintf(buf + i, PAGE_SIZE - i,
-			      "%s/%i\n", addr_str, ipatoe->mask_bits);
-	}
-	spin_unlock_irqrestore(&card->ip_lock, flags);
-	i += snprintf(buf + i, PAGE_SIZE - i, "\n");
-
-	return i;
-}
-
-static ssize_t
-qeth_dev_ipato_add4_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
-}
-
-static int
-qeth_parse_ipatoe(const char* buf, enum qeth_prot_versions proto,
-		  u8 *addr, int *mask_bits)
-{
-	const char *start, *end;
-	char *tmp;
-	char buffer[40] = {0, };
-
-	start = buf;
-	/* get address string */
-	end = strchr(start, '/');
-	if (!end || (end - start >= 40)){
-		PRINT_WARN("Invalid format for ipato_addx/delx. "
-			   "Use <ip addr>/<mask bits>\n");
-		return -EINVAL;
-	}
-	strncpy(buffer, start, end - start);
-	if (qeth_string_to_ipaddr(buffer, proto, addr)){
-		PRINT_WARN("Invalid IP address format!\n");
-		return -EINVAL;
-	}
-	start = end + 1;
-	*mask_bits = simple_strtoul(start, &tmp, 10);
-	if (!strlen(start) ||
-	    (tmp == start) ||
-	    (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
-		PRINT_WARN("Invalid mask bits for ipato_addx/delx !\n");
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static ssize_t
-qeth_dev_ipato_add_store(const char *buf, size_t count,
-			 struct qeth_card *card, enum qeth_prot_versions proto)
-{
-	struct qeth_ipato_entry *ipatoe;
-	u8 addr[16];
-	int mask_bits;
-	int rc;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-	if ((rc = qeth_parse_ipatoe(buf, proto, addr, &mask_bits)))
-		return rc;
-
-	if (!(ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL))){
-		PRINT_WARN("No memory to allocate ipato entry\n");
-		return -ENOMEM;
-	}
-	ipatoe->proto = proto;
-	memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
-	ipatoe->mask_bits = mask_bits;
-
-	if ((rc = qeth_add_ipato_entry(card, ipatoe))){
-		kfree(ipatoe);
-		return rc;
-	}
-
-	return count;
-}
-
-static ssize_t
-qeth_dev_ipato_add4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
-}
-
-static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
-			qeth_dev_ipato_add4_show,
-			qeth_dev_ipato_add4_store);
-
-static ssize_t
-qeth_dev_ipato_del_store(const char *buf, size_t count,
-			 struct qeth_card *card, enum qeth_prot_versions proto)
-{
-	u8 addr[16];
-	int mask_bits;
-	int rc;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-	if ((rc = qeth_parse_ipatoe(buf, proto, addr, &mask_bits)))
-		return rc;
-
-	qeth_del_ipato_entry(card, proto, addr, mask_bits);
-
-	return count;
-}
-
-static ssize_t
-qeth_dev_ipato_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
-}
-
-static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
-			qeth_dev_ipato_del4_store);
-
-#ifdef CONFIG_QETH_IPV6
-static ssize_t
-qeth_dev_ipato_invert6_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-
-	return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
-}
-
-static ssize_t
-qeth_dev_ipato_invert6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-	char *tmp;
-
-	if (!card)
-		return -EINVAL;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-
-	tmp = strsep((char **) &buf, "\n");
-	if (!strcmp(tmp, "toggle")){
-		card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
-	} else if (!strcmp(tmp, "1")){
-		card->ipato.invert6 = 1;
-	} else if (!strcmp(tmp, "0")){
-		card->ipato.invert6 = 0;
-	} else {
-		PRINT_WARN("ipato_invert6: write 0, 1 or 'toggle' to "
-			   "this file\n");
-		return -EINVAL;
-	}
-	return count;
-}
-
-static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
-			qeth_dev_ipato_invert6_show,
-			qeth_dev_ipato_invert6_store);
-
-
-static ssize_t
-qeth_dev_ipato_add6_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
-}
-
-static ssize_t
-qeth_dev_ipato_add6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
-}
-
-static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
-			qeth_dev_ipato_add6_show,
-			qeth_dev_ipato_add6_store);
-
-static ssize_t
-qeth_dev_ipato_del6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
-}
-
-static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
-			qeth_dev_ipato_del6_store);
-#endif /* CONFIG_QETH_IPV6 */
-
-static struct device_attribute * qeth_ipato_device_attrs[] = {
-	&dev_attr_ipato_enable,
-	&dev_attr_ipato_invert4,
-	&dev_attr_ipato_add4,
-	&dev_attr_ipato_del4,
-#ifdef CONFIG_QETH_IPV6
-	&dev_attr_ipato_invert6,
-	&dev_attr_ipato_add6,
-	&dev_attr_ipato_del6,
-#endif
-	NULL,
-};
-
-static struct attribute_group qeth_device_ipato_group = {
-	.name = "ipa_takeover",
-	.attrs = (struct attribute **)qeth_ipato_device_attrs,
-};
-
-static ssize_t
-qeth_dev_vipa_add_show(char *buf, struct qeth_card *card,
-			enum qeth_prot_versions proto)
-{
-	struct qeth_ipaddr *ipaddr;
-	char addr_str[40];
-	int entry_len; /* length of 1 entry string, differs between v4 and v6 */
-	unsigned long flags;
-	int i = 0;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-
-	entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
-	entry_len += 2; /* \n + terminator */
-	spin_lock_irqsave(&card->ip_lock, flags);
-	list_for_each_entry(ipaddr, &card->ip_list, entry){
-		if (ipaddr->proto != proto)
-			continue;
-		if (ipaddr->type != QETH_IP_TYPE_VIPA)
-			continue;
-		/* String must not be longer than PAGE_SIZE. So we check if
-		 * string length gets near PAGE_SIZE. Then we can savely display
-		 * the next IPv6 address (worst case, compared to IPv4) */
-		if ((PAGE_SIZE - i) <= entry_len)
-			break;
-		qeth_ipaddr_to_string(proto, (const u8 *)&ipaddr->u, addr_str);
-		i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
-	}
-	spin_unlock_irqrestore(&card->ip_lock, flags);
-	i += snprintf(buf + i, PAGE_SIZE - i, "\n");
-
-	return i;
-}
-
-static ssize_t
-qeth_dev_vipa_add4_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
-}
-
-static int
-qeth_parse_vipae(const char* buf, enum qeth_prot_versions proto,
-		 u8 *addr)
-{
-	if (qeth_string_to_ipaddr(buf, proto, addr)){
-		PRINT_WARN("Invalid IP address format!\n");
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static ssize_t
-qeth_dev_vipa_add_store(const char *buf, size_t count,
-			 struct qeth_card *card, enum qeth_prot_versions proto)
-{
-	u8 addr[16] = {0, };
-	int rc;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-	if ((rc = qeth_parse_vipae(buf, proto, addr)))
-		return rc;
-
-	if ((rc = qeth_add_vipa(card, proto, addr)))
-		return rc;
-
-	return count;
-}
-
-static ssize_t
-qeth_dev_vipa_add4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
-}
-
-static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
-			qeth_dev_vipa_add4_show,
-			qeth_dev_vipa_add4_store);
-
-static ssize_t
-qeth_dev_vipa_del_store(const char *buf, size_t count,
-			 struct qeth_card *card, enum qeth_prot_versions proto)
-{
-	u8 addr[16];
-	int rc;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-	if ((rc = qeth_parse_vipae(buf, proto, addr)))
-		return rc;
-
-	qeth_del_vipa(card, proto, addr);
-
-	return count;
-}
-
-static ssize_t
-qeth_dev_vipa_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
-}
-
-static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
-			qeth_dev_vipa_del4_store);
-
-#ifdef CONFIG_QETH_IPV6
-static ssize_t
-qeth_dev_vipa_add6_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
-}
-
-static ssize_t
-qeth_dev_vipa_add6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
-}
-
-static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
-			qeth_dev_vipa_add6_show,
-			qeth_dev_vipa_add6_store);
-
-static ssize_t
-qeth_dev_vipa_del6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-
-	return qeth_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
-}
-
-static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
-			qeth_dev_vipa_del6_store);
-#endif /* CONFIG_QETH_IPV6 */
-
-static struct device_attribute * qeth_vipa_device_attrs[] = {
-	&dev_attr_vipa_add4,
-	&dev_attr_vipa_del4,
-#ifdef CONFIG_QETH_IPV6
-	&dev_attr_vipa_add6,
-	&dev_attr_vipa_del6,
-#endif
-	NULL,
-};
-
-static struct attribute_group qeth_device_vipa_group = {
-	.name = "vipa",
-	.attrs = (struct attribute **)qeth_vipa_device_attrs,
-};
-
-static ssize_t
-qeth_dev_rxip_add_show(char *buf, struct qeth_card *card,
-		       enum qeth_prot_versions proto)
-{
-	struct qeth_ipaddr *ipaddr;
-	char addr_str[40];
-	int entry_len; /* length of 1 entry string, differs between v4 and v6 */
-	unsigned long flags;
-	int i = 0;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-
-	entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
-	entry_len += 2; /* \n + terminator */
-	spin_lock_irqsave(&card->ip_lock, flags);
-	list_for_each_entry(ipaddr, &card->ip_list, entry){
-		if (ipaddr->proto != proto)
-			continue;
-		if (ipaddr->type != QETH_IP_TYPE_RXIP)
-			continue;
-		/* String must not be longer than PAGE_SIZE. So we check if
-		 * string length gets near PAGE_SIZE. Then we can savely display
-		 * the next IPv6 address (worst case, compared to IPv4) */
-		if ((PAGE_SIZE - i) <= entry_len)
-			break;
-		qeth_ipaddr_to_string(proto, (const u8 *)&ipaddr->u, addr_str);
-		i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
-	}
-	spin_unlock_irqrestore(&card->ip_lock, flags);
-	i += snprintf(buf + i, PAGE_SIZE - i, "\n");
-
-	return i;
-}
-
-static ssize_t
-qeth_dev_rxip_add4_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
-}
-
-static int
-qeth_parse_rxipe(const char* buf, enum qeth_prot_versions proto,
-		 u8 *addr)
-{
-	if (qeth_string_to_ipaddr(buf, proto, addr)){
-		PRINT_WARN("Invalid IP address format!\n");
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static ssize_t
-qeth_dev_rxip_add_store(const char *buf, size_t count,
-			struct qeth_card *card, enum qeth_prot_versions proto)
-{
-	u8 addr[16] = {0, };
-	int rc;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-	if ((rc = qeth_parse_rxipe(buf, proto, addr)))
-		return rc;
-
-	if ((rc = qeth_add_rxip(card, proto, addr)))
-		return rc;
-
-	return count;
-}
-
-static ssize_t
-qeth_dev_rxip_add4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
-}
-
-static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
-			qeth_dev_rxip_add4_show,
-			qeth_dev_rxip_add4_store);
-
-static ssize_t
-qeth_dev_rxip_del_store(const char *buf, size_t count,
-			struct qeth_card *card, enum qeth_prot_versions proto)
-{
-	u8 addr[16];
-	int rc;
-
-	if (qeth_check_layer2(card))
-		return -EPERM;
-	if ((rc = qeth_parse_rxipe(buf, proto, addr)))
-		return rc;
-
-	qeth_del_rxip(card, proto, addr);
-
-	return count;
-}
-
-static ssize_t
-qeth_dev_rxip_del4_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
-}
-
-static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
-			qeth_dev_rxip_del4_store);
-
-#ifdef CONFIG_QETH_IPV6
-static ssize_t
-qeth_dev_rxip_add6_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
-}
-
-static ssize_t
-qeth_dev_rxip_add6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
-}
-
-static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
-			qeth_dev_rxip_add6_show,
-			qeth_dev_rxip_add6_store);
-
-static ssize_t
-qeth_dev_rxip_del6_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (!card)
-		return -EINVAL;
-
-	return qeth_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
-}
-
-static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
-			qeth_dev_rxip_del6_store);
-#endif /* CONFIG_QETH_IPV6 */
-
-static struct device_attribute * qeth_rxip_device_attrs[] = {
-	&dev_attr_rxip_add4,
-	&dev_attr_rxip_del4,
-#ifdef CONFIG_QETH_IPV6
-	&dev_attr_rxip_add6,
-	&dev_attr_rxip_del6,
-#endif
-	NULL,
-};
-
-static struct attribute_group qeth_device_rxip_group = {
-	.name = "rxip",
-	.attrs = (struct attribute **)qeth_rxip_device_attrs,
-};
-
-int
-qeth_create_device_attributes(struct device *dev)
-{
-	int ret;
-	struct qeth_card *card = dev->driver_data;
-
-	if (card->info.type == QETH_CARD_TYPE_OSN)
-		return sysfs_create_group(&dev->kobj,
-					  &qeth_osn_device_attr_group);
-
-	if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group)))
-		return ret;
-	if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group))){
-		sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
-		return ret;
-	}
-	if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group))){
-		sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
-		sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
-		return ret;
-	}
-	if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group))){
-		sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
-		sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
-		sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
-		return ret;
-	}
-	if ((ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group))){
-		sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
-		sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
-		sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
-		sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
-		return ret;
-	}
-	return 0;
-}
-
-void
-qeth_remove_device_attributes(struct device *dev)
-{
-	struct qeth_card *card = dev->driver_data;
-
-	if (card->info.type == QETH_CARD_TYPE_OSN) {
-		sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group);
-		return;
-	}
-	sysfs_remove_group(&dev->kobj, &qeth_device_attr_group);
-	sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
-	sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
-	sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
-	sysfs_remove_group(&dev->kobj, &qeth_device_blkt_group);
-}
-
-/**********************/
-/* DRIVER ATTRIBUTES  */
-/**********************/
-static ssize_t
-qeth_driver_group_store(struct device_driver *ddrv, const char *buf,
-			size_t count)
-{
-	const char *start, *end;
-	char bus_ids[3][BUS_ID_SIZE], *argv[3];
-	int i;
-	int err;
-
-	start = buf;
-	for (i = 0; i < 3; i++) {
-		static const char delim[] = { ',', ',', '\n' };
-		int len;
-
-		if (!(end = strchr(start, delim[i])))
-			return -EINVAL;
-		len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start);
-		strncpy(bus_ids[i], start, len);
-		bus_ids[i][len] = '\0';
-		start = end + 1;
-		argv[i] = bus_ids[i];
-	}
-	err = ccwgroup_create(qeth_root_dev, qeth_ccwgroup_driver.driver_id,
-			&qeth_ccw_driver, 3, argv);
-	if (err)
-		return err;
-	else
-		return count;
-}
-
-
-static DRIVER_ATTR(group, 0200, NULL, qeth_driver_group_store);
-
-static ssize_t
-qeth_driver_notifier_register_store(struct device_driver *ddrv, const char *buf,
-				size_t count)
-{
-	int rc;
-	int signum;
-	char *tmp, *tmp2;
-
-	tmp = strsep((char **) &buf, "\n");
-	if (!strncmp(tmp, "unregister", 10)){
-		if ((rc = qeth_notifier_unregister(current)))
-			return rc;
-		return count;
-	}
-
-	signum = simple_strtoul(tmp, &tmp2, 10);
-	if ((signum < 0) || (signum > 32)){
-		PRINT_WARN("Signal number %d is out of range\n", signum);
-		return -EINVAL;
-	}
-	if ((rc = qeth_notifier_register(current, signum)))
-		return rc;
-
-	return count;
-}
-
-static DRIVER_ATTR(notifier_register, 0200, NULL,
-		   qeth_driver_notifier_register_store);
-
-int
-qeth_create_driver_attributes(void)
-{
-	int rc;
-
-	if ((rc = driver_create_file(&qeth_ccwgroup_driver.driver,
-				     &driver_attr_group)))
-		return rc;
-	return driver_create_file(&qeth_ccwgroup_driver.driver,
-				  &driver_attr_notifier_register);
-}
-
-void
-qeth_remove_driver_attributes(void)
-{
-	driver_remove_file(&qeth_ccwgroup_driver.driver,
-			&driver_attr_group);
-	driver_remove_file(&qeth_ccwgroup_driver.driver,
-			&driver_attr_notifier_register);
-}
Index: my_git/drivers/s390/net/qeth_tso.h
===================================================================
--- my_git.orig/drivers/s390/net/qeth_tso.h	2008-02-15 08:49:22.000000000 +0100
+++ /dev/null	1970-01-01 00:00:00.000000000 +0000
@@ -1,148 +0,0 @@
-/*
- * linux/drivers/s390/net/qeth_tso.h
- *
- * Header file for qeth TCP Segmentation Offload support.
- *
- * Copyright 2004 IBM Corporation
- *
- *    Author(s): Frank Pavlic <fpavlic@de.ibm.com>
- *
- */
-#ifndef __QETH_TSO_H__
-#define __QETH_TSO_H__
-
-#include <linux/skbuff.h>
-#include <linux/tcp.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <net/ip6_checksum.h>
-#include "qeth.h"
-#include "qeth_mpc.h"
-
-
-static inline struct qeth_hdr_tso *
-qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb)
-{
-	QETH_DBF_TEXT(trace, 5, "tsoprsk");
-	return qeth_push_skb(card, *skb, sizeof(struct qeth_hdr_tso));
-}
-
-/**
- * fill header for a TSO packet
- */
-static inline void
-qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb)
-{
-	struct qeth_hdr_tso *hdr;
-	struct tcphdr *tcph;
-	struct iphdr *iph;
-
-	QETH_DBF_TEXT(trace, 5, "tsofhdr");
-
-	hdr  = (struct qeth_hdr_tso *) skb->data;
-	iph  = ip_hdr(skb);
-	tcph = tcp_hdr(skb);
-	/*fix header to TSO values ...*/
-	hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
-	/*set values which are fix for the first approach ...*/
-	hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
-	hdr->ext.imb_hdr_no  = 1;
-	hdr->ext.hdr_type    = 1;
-	hdr->ext.hdr_version = 1;
-	hdr->ext.hdr_len     = 28;
-	/*insert non-fix values */
-	hdr->ext.mss = skb_shinfo(skb)->gso_size;
-	hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
-	hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
-				       sizeof(struct qeth_hdr_tso));
-}
-
-/**
- * change some header values as requested by hardware
- */
-static inline void
-qeth_tso_set_tcpip_header(struct qeth_card *card, struct sk_buff *skb)
-{
-	struct iphdr *iph    = ip_hdr(skb);
-	struct ipv6hdr *ip6h = ipv6_hdr(skb);
-	struct tcphdr *tcph  = tcp_hdr(skb);
-
-	tcph->check = 0;
-	if (skb->protocol == ETH_P_IPV6) {
-		ip6h->payload_len = 0;
-		tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
-					       0, IPPROTO_TCP, 0);
-		return;
-	}
-	/*OSA want us to set these values ...*/
-	tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
-					 0, IPPROTO_TCP, 0);
-	iph->tot_len = 0;
-	iph->check = 0;
-}
-
-static inline int
-qeth_tso_prepare_packet(struct qeth_card *card, struct sk_buff *skb,
-			int ipv, int cast_type)
-{
-	struct qeth_hdr_tso *hdr;
-
-	QETH_DBF_TEXT(trace, 5, "tsoprep");
-
-	hdr = (struct qeth_hdr_tso *) qeth_tso_prepare_skb(card, &skb);
-	if (hdr == NULL) {
-		QETH_DBF_TEXT(trace, 4, "tsoperr");
-		return -ENOMEM;
-	}
-	memset(hdr, 0, sizeof(struct qeth_hdr_tso));
-	/*fill first 32 bytes of  qdio header as used
-	 *FIXME: TSO has two struct members
-	 * with different names but same size
-	 * */
-	qeth_fill_header(card, &hdr->hdr, skb, ipv, cast_type);
-	qeth_tso_fill_header(card, skb);
-	qeth_tso_set_tcpip_header(card, skb);
-	return 0;
-}
-
-static inline void
-__qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer,
-			int is_tso, int *next_element_to_fill)
-{
-	struct skb_frag_struct *frag;
-	int fragno;
-	unsigned long addr;
-	int element, cnt, dlen;
-
-	fragno = skb_shinfo(skb)->nr_frags;
-	element = *next_element_to_fill;
-	dlen = 0;
-
-	if (is_tso)
-		buffer->element[element].flags =
-			SBAL_FLAGS_MIDDLE_FRAG;
-	else
-		buffer->element[element].flags =
-			SBAL_FLAGS_FIRST_FRAG;
-	if ( (dlen = (skb->len - skb->data_len)) ) {
-		buffer->element[element].addr = skb->data;
-		buffer->element[element].length = dlen;
-		element++;
-	}
-	for (cnt = 0; cnt < fragno; cnt++) {
-		frag = &skb_shinfo(skb)->frags[cnt];
-		addr = (page_to_pfn(frag->page) << PAGE_SHIFT) +
-			frag->page_offset;
-		buffer->element[element].addr = (char *)addr;
-		buffer->element[element].length = frag->size;
-		if (cnt < (fragno - 1))
-			buffer->element[element].flags =
-				SBAL_FLAGS_MIDDLE_FRAG;
-		else
-			buffer->element[element].flags =
-				SBAL_FLAGS_LAST_FRAG;
-		element++;
-	}
-	*next_element_to_fill = element;
-}
-#endif /* __QETH_TSO_H__ */

-- 

  parent reply	other threads:[~2008-02-15  8:19 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-15  8:19 [patch 0/2] [RESEND] s390: new qeth driver for 2.6.26 frank.blaschka
2008-02-15  8:19 ` [patch 1/2] qeth: new qeth device driver frank.blaschka
2008-03-05 11:14   ` Jeff Garzik
2008-02-15  8:19 ` frank.blaschka [this message]
  -- strict thread matches above, loose matches on Subject: below --
2008-02-08 14:09 [patch 0/2] s390: new qeth driver for 2.6.25 Frank.Blaschka
2008-02-08 14:10 ` [patch 2/2] qeth: remove old qeth files Frank.Blaschka

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080215082019.404274000@de.ibm.com \
    --to=frank.blaschka@de.ibm.com \
    --cc=jgarzik@pobox.com \
    --cc=linux-s390@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.