Commit d69678bd authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Linus Torvalds

[PATCH] s390: qeth network driver.

The qeth network device driver. Supports the OSA Express Gigabit cards,
HiperSockes and VM GuestLAN interfaces.
parent 6a1d9652
......@@ -269,7 +269,14 @@ CONFIG_NET_ETHERNET=y
CONFIG_LCS=m
CONFIG_CTC=m
CONFIG_IUCV=m
CONFIG_CCWGROUP=m
CONFIG_QETH=y
#
# Gigabit Ethernet default settings
#
# CONFIG_QETH_IPV6 is not set
# CONFIG_QETH_PERF_STATS is not set
CONFIG_CCWGROUP=y
#
# File systems
......
......@@ -30,9 +30,56 @@ config IUCV
vehicle networking under VM or VIF. This option is also available
as a module which will be called iucv.ko. If unsure, say "Y".
config QETH
tristate "Gigabit Ethernet device support"
depends on NETDEVICES && IP_MULTICAST && QDIO
help
This driver supports the IBM S/390 and zSeries OSA Express adapters
in QDIO mode (all media types), HiperSockets interfaces and VM GuestLAN
interfaces in QDIO and HIPER mode.
For details please refer to the documentation provided by IBM at
<http://www10.software.ibm.com/developerworks/opensource/linux390>
This driver is also available as a module (code which can be
inserted in and removed from the running kernel whenever you
want). If you want to compile it as a module, say 'M' here and
read file Documentation/modules.txt.
comment "Gigabit Ethernet default settings"
depends on QETH
# FIXME IPV6=m && QETH=y
config QETH_IPV6
bool "IPv6 support for gigabit ethernet"
depends on QETH && IPV6
help
If CONFIG_QETH is switched on, this option will include IPv6
support in the qeth device driver.
# FIXME VLAN_8021Q=m && QETH=y
config QETH_VLAN
bool "VLAN support for gigabit ethernet"
depends on QETH && VLAN_8021Q
help
If CONFIG_QETH is switched on, this option will include IEEE
802.1q VLAN support in the qeth device driver.
config QETH_PERF_STATS
bool "Performance statistics in /proc"
depends on QETH
help
When switched on, this option will add a file in the proc-fs
(/proc/qeth_perf_stats) containing performance statistics. It
may slightly impact performance, so this is only recommended for
internal tuning of the device driver.
config CCWGROUP
tristate
depends on LCS || CTC
default m if LCS!=y && CTC!=y
default y if LCS=y || CTC=y
depends on LCS || CTC || QETH
default m if LCS!=y && CTC!=y && QETH!=y
default y if LCS=y || CTC=y || QETH=y
endmenu
......@@ -8,3 +8,6 @@ obj-$(CONFIG_IUCV) += iucv.o fsm.o
obj-$(CONFIG_CTC) += ctc.o fsm.o cu3088.o
obj-$(CONFIG_IUCV) += netiucv.o
obj-$(CONFIG_LCS) += lcs.o cu3088.o
qeth_mod-objs := qeth.o qeth_mpc.o
obj-$(CONFIG_QETH) += qeth_mod.o
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* linux/drivers/s390/net/qeth.h
*
* Linux on zSeries OSA Express and HiperSockets support
*
* Copyright 2000,2003 IBM Corporation
* Author(s): Utz Bacher <utz.bacher@de.ibm.com>
*
*/
#ifndef __QETH_H__
#define __QETH_H__
#include <asm/qdio.h>
#define QETH_NAME " qeth"
#define VERSION_QETH_H "$Revision: 1.47 $"
/******************** CONFIG STUFF ***********************/
//#define QETH_DBF_LIKE_HELL
#ifdef CONFIG_QETH_IPV6
#define QETH_IPV6
#define QETH_VERSION_IPV6 ":IPv6"
#else
#define QETH_VERSION_IPV6 ""
#endif /* CONFIG_QETH_IPV6 */
#ifdef CONFIG_QETH_VLAN
#define QETH_VLAN
#define QETH_VERSION_VLAN ":VLAN"
#else
#define QETH_VERSION_VLAN ""
#endif /* CONFIG_QETH_VLAN */
/* these values match CHECKSUM_* in include/linux/skbuff.h */
#define SW_CHECKSUMMING 0
#define HW_CHECKSUMMING 1
#define NO_CHECKSUMMING 2
#define QETH_CHECKSUM_DEFAULT NO_CHECKSUMMING
#define QETH_PRIOQ_DEFAULT NO_PRIO_QUEUEING
#define QETH_DEFAULT_QUEUE 2
/******************** CONFIG STUFF END ***********************/
/********************* TUNING STUFF **************************/
#define HIGH_WATERMARK_PACK 5
#define LOW_WATERMARK_PACK 2
#define WATERMARK_FUZZ 2
#define QETH_MAX_INPUT_THRESHOLD 500
#define QETH_MAX_OUTPUT_THRESHOLD 300 /* ? */
/* only the MAX values are used */
#define QETH_MIN_INPUT_THRESHOLD 1
#define QETH_MIN_OUTPUT_THRESHOLD 1
#define QETH_REQUEUE_THRESHOLD (card->options.inbound_buffer_count/4)
#ifdef CONFIG_QETH_PERF_STATS
#define QETH_PERFORMANCE_STATS
#endif /* CONFIG_QETH_PERF_STATS */
#ifdef QETH_DBF_LIKE_HELL
#define QETH_VERBOSE_LEVEL 8
#else /* QETH_DBF_LIKE_HELL */
#define QETH_VERBOSE_LEVEL 5
#endif /* QETH_DBF_LIKE_HELL */
#define PCI_THRESHOLD_A (card->options.inbound_buffer_count+1)
/* buffers we have to be behind before we get a PCI */
#define PCI_THRESHOLD_B 0 /* enqueued free buffers left before we get a PCI */
#define PCI_TIMER_VALUE 3 /* not used, unless the microcode gets patched */
#define DEFAULT_SPARE_BUFFERS 0
#define MAX_SPARE_BUFFERS 1024
#define SPAREBUF_MASK 65536
#define MAX_PORTNO 15
#define QETH_PROCFILE_NAME "qeth"
#define QETH_PERF_PROCFILE_NAME "qeth_perf"
#define QETH_IPA_PROCFILE_NAME "qeth_ipa_takeover"
#define SEND_RETRIES_ALLOWED 5
#define QETH_ROUTING_ATTEMPTS 2
#define QETH_HARDSETUP_LAPS 5
#define QETH_HARDSETUP_CLEAR_LAPS 3
#define QETH_RECOVERY_HARDSETUP_RETRY 2
/************************* DEBUG FACILITY STUFF *********************/
#define QETH_DBF_HEX(ex,name,level,addr,len) \
do { \
if (ex) \
debug_exception(qeth_dbf_##name,level,(void*)addr,len); \
else \
debug_event(qeth_dbf_##name,level,(void*)addr,len); \
} while (0)
#define QETH_DBF_TEXT(ex,name,level,text) \
do { \
if (ex) \
debug_text_exception(qeth_dbf_##name,level,text); \
else \
debug_text_event(qeth_dbf_##name,level,text); \
} while (0)
#define QETH_DBF_HEX0(ex,name,addr,len) QETH_DBF_HEX(ex,name,0,addr,len)
#define QETH_DBF_HEX1(ex,name,addr,len) QETH_DBF_HEX(ex,name,1,addr,len)
#define QETH_DBF_HEX2(ex,name,addr,len) QETH_DBF_HEX(ex,name,2,addr,len)
#ifdef QETH_DBF_LIKE_HELL
#define QETH_DBF_HEX3(ex,name,addr,len) QETH_DBF_HEX(ex,name,3,addr,len)
#define QETH_DBF_HEX4(ex,name,addr,len) QETH_DBF_HEX(ex,name,4,addr,len)
#define QETH_DBF_HEX5(ex,name,addr,len) QETH_DBF_HEX(ex,name,5,addr,len)
#define QETH_DBF_HEX6(ex,name,addr,len) QETH_DBF_HEX(ex,name,6,addr,len)
#else /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_HEX3(ex,name,addr,len) do {} while (0)
#define QETH_DBF_HEX4(ex,name,addr,len) do {} while (0)
#define QETH_DBF_HEX5(ex,name,addr,len) do {} while (0)
#define QETH_DBF_HEX6(ex,name,addr,len) do {} while (0)
#endif /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_TEXT0(ex,name,text) QETH_DBF_TEXT(ex,name,0,text)
#define QETH_DBF_TEXT1(ex,name,text) QETH_DBF_TEXT(ex,name,1,text)
#define QETH_DBF_TEXT2(ex,name,text) QETH_DBF_TEXT(ex,name,2,text)
#ifdef QETH_DBF_LIKE_HELL
#define QETH_DBF_TEXT3(ex,name,text) QETH_DBF_TEXT(ex,name,3,text)
#define QETH_DBF_TEXT4(ex,name,text) QETH_DBF_TEXT(ex,name,4,text)
#define QETH_DBF_TEXT5(ex,name,text) QETH_DBF_TEXT(ex,name,5,text)
#define QETH_DBF_TEXT6(ex,name,text) QETH_DBF_TEXT(ex,name,6,text)
#else /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_TEXT3(ex,name,text) do {} while (0)
#define QETH_DBF_TEXT4(ex,name,text) do {} while (0)
#define QETH_DBF_TEXT5(ex,name,text) do {} while (0)
#define QETH_DBF_TEXT6(ex,name,text) do {} while (0)
#endif /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_SETUP_NAME "qeth_setup"
#define QETH_DBF_SETUP_LEN 8
#define QETH_DBF_SETUP_INDEX 3
#define QETH_DBF_SETUP_NR_AREAS 1
#ifdef QETH_DBF_LIKE_HELL
#define QETH_DBF_SETUP_LEVEL 6
#else /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_SETUP_LEVEL 3
#endif /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_MISC_NAME "qeth_misc"
#define QETH_DBF_MISC_LEN 128
#define QETH_DBF_MISC_INDEX 1
#define QETH_DBF_MISC_NR_AREAS 1
#ifdef QETH_DBF_LIKE_HELL
#define QETH_DBF_MISC_LEVEL 6
#else /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_MISC_LEVEL 2
#endif /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_DATA_NAME "qeth_data"
#define QETH_DBF_DATA_LEN 96
#define QETH_DBF_DATA_INDEX 3
#define QETH_DBF_DATA_NR_AREAS 1
#ifdef QETH_DBF_LIKE_HELL
#define QETH_DBF_DATA_LEVEL 6
#else /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_DATA_LEVEL 2
#endif /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_CONTROL_NAME "qeth_control"
/* buffers are 255 bytes long, but no prob */
#define QETH_DBF_CONTROL_LEN 256
#define QETH_DBF_CONTROL_INDEX 3
#define QETH_DBF_CONTROL_NR_AREAS 2
#ifdef QETH_DBF_LIKE_HELL
#define QETH_DBF_CONTROL_LEVEL 6
#else /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_CONTROL_LEVEL 2
#endif /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_TRACE_NAME "qeth_trace"
#define QETH_DBF_TRACE_LEN 8
#ifdef QETH_DBF_LIKE_HELL
#define QETH_DBF_TRACE_INDEX 3
#else /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_TRACE_INDEX 2
#endif /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_TRACE_NR_AREAS 2
#ifdef QETH_DBF_LIKE_HELL
#define QETH_DBF_TRACE_LEVEL 6
#else /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_TRACE_LEVEL 2
#endif /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_SENSE_NAME "qeth_sense"
#define QETH_DBF_SENSE_LEN 64
#define QETH_DBF_SENSE_INDEX 1
#define QETH_DBF_SENSE_NR_AREAS 1
#ifdef QETH_DBF_LIKE_HELL
#define QETH_DBF_SENSE_LEVEL 6
#else /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_SENSE_LEVEL 2
#endif /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_QERR_NAME "qeth_qerr"
#define QETH_DBF_QERR_LEN 8
#define QETH_DBF_QERR_INDEX 1
#define QETH_DBF_QERR_NR_AREAS 2
#ifdef QETH_DBF_LIKE_HELL
#define QETH_DBF_QERR_LEVEL 6
#else /* QETH_DBF_LIKE_HELL */
#define QETH_DBF_QERR_LEVEL 2
#endif /* QETH_DBF_LIKE_HELL */
/****************** END OF DEBUG FACILITY STUFF *********************/
/********************* CARD DATA STUFF **************************/
#define QETH_MAX_PARAMS 150
#define QETH_CARD_TYPE_UNKNOWN 0
#define QETH_CARD_TYPE_OSAE 10
#define QETH_CARD_TYPE_IQD 1234
#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_MAX_QUEUES 4
#define UNIQUE_ID_IF_CREATE_ADDR_FAILED 0xfffe
#define UNIQUE_ID_NOT_BY_CARD 0x10000
/*
* CU type & model, Dev type & model, card_type, odd_even_restriction,
* func level, no of queues, multicast is different (multicast-queue_no + 0x100)
*/
#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}, \
{0,0,0,0,0,0,0,0,0}}
#define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18
/* only the first two bytes are looked at in qeth_get_cardname_short */
#define QETH_MPC_LINK_TYPE_FAST_ETHERNET 0x01
#define QETH_MPC_LINK_TYPE_HSTR 0x02
#define QETH_MPC_LINK_TYPE_GIGABIT_ETHERNET 0x03
#define QETH_MPC_LINK_TYPE_10GIGABIT_ETHERNET 0x10
#define QETH_MPC_LINK_TYPE_LANE_ETH100 0x81
#define QETH_MPC_LINK_TYPE_LANE_TR 0x82
#define QETH_MPC_LINK_TYPE_LANE_ETH1000 0x83
#define QETH_MPC_LINK_TYPE_LANE 0x88
#define QETH_MPC_LINK_TYPE_ATM_NATIVE 0x90
#define DEFAULT_ADD_HHLEN 0
#define MAX_ADD_HHLEN 1024
#define QETH_HEADER_SIZE 32
#define QETH_IP_HEADER_SIZE 40
#define QETH_HEADER_LEN_POS 8
/* flags for the header: */
#define QETH_HEADER_PASSTHRU 0x10
#define QETH_HEADER_IPV6 0x80
#define QETH_CAST_FLAGS 0x07
#define QETH_CAST_UNICAST 6
#define QETH_CAST_MULTICAST 4
#define QETH_CAST_BROADCAST 5
#define QETH_CAST_ANYCAST 7
#define QETH_CAST_NOCAST 0
/* VLAN defines */
#define QETH_EXT_HEADER_VLAN_FRAME 0x01
#define QETH_EXT_HEADER_TOKEN_ID 0x02
#define QETH_EXT_HEADER_INCLUDE_VLAN_TAG 0x04
#define QETH_EXT_HEADER_SRC_MAC_ADDRESS 0x08
#define QETH_EXT_HEADER_CSUM_HDR_REQ 0x10
#define QETH_EXT_HEADER_CSUM_TRANSP_REQ 0x20
#define QETH_EXT_HEADER_CSUM_TRANSP_FRAME_TYPE 0x40
#define QETH_UDP_CSUM_OFFSET 6
#define QETH_TCP_CSUM_OFFSET 16
#define QETH_VERIFY_IS_REAL_DEV 1
#define QETH_VERIFY_IS_VLAN_DEV 2
inline static unsigned int
qeth_get_ipa_timeout(int cardtype)
{
switch (cardtype) {
case QETH_CARD_TYPE_IQD:
return 2000;
default:
return 20000;
}
}
inline static unsigned short
qeth_get_additional_dev_flags(int cardtype)
{
switch (cardtype) {
case QETH_CARD_TYPE_IQD:
return IFF_NOARP;
#ifdef QETH_IPV6
default:
return 0;
#else /* QETH_IPV6 */
default:
return IFF_NOARP;
#endif /* QETH_IPV6 */
}
}
inline static int
qeth_get_hlen(__u8 link_type)
{
#ifdef QETH_IPV6
switch (link_type) {
case QETH_MPC_LINK_TYPE_HSTR:
case QETH_MPC_LINK_TYPE_LANE_TR:
return QETH_HEADER_SIZE + TR_HLEN;
default:
#ifdef QETH_VLAN
return QETH_HEADER_SIZE + VLAN_ETH_HLEN;
#else
return QETH_HEADER_SIZE + ETH_HLEN;
#endif
}
#else /* QETH_IPV6 */
#ifdef QETH_VLAN
return QETH_HEADER_SIZE + VLAN_HLEN;
#else
return QETH_HEADER_SIZE;
#endif
#endif /* QETH_IPV6 */
}
static int (*qeth_my_eth_header) (struct sk_buff *, struct net_device *,
unsigned short, void *, void *, unsigned);
#ifdef CONFIG_TR
static int (*qeth_my_tr_header) (struct sk_buff *, struct net_device *,
unsigned short, void *, void *, unsigned);
#endif /* CONFIG_TR */
static int (*qeth_my_eth_rebuild_header) (struct sk_buff *);
#ifdef CONFIG_TR
static int (*qeth_my_tr_rebuild_header) (struct sk_buff *);
#endif /* CONFIG_TR */
static int (*qeth_my_eth_header_cache) (struct neighbour *, struct hh_cache *);
static void (*qeth_my_eth_header_cache_update) (struct hh_cache *,
struct net_device *,
unsigned char *);
#ifdef QETH_IPV6
typedef int (*__qeth_temp1) (struct sk_buff *, struct net_device *,
unsigned short, void *, void *, unsigned);
inline static __qeth_temp1
qeth_get_hard_header(__u8 link_type)
{
switch (link_type) {
#ifdef CONFIG_TR
case QETH_MPC_LINK_TYPE_HSTR:
case QETH_MPC_LINK_TYPE_LANE_TR:
return qeth_my_tr_header;
#endif /* CONFIG_TR */
default:
return qeth_my_eth_header;
}
}
typedef int (*__qeth_temp2) (struct sk_buff *);
inline static __qeth_temp2
qeth_get_rebuild_header(__u8 link_type)
{
switch (link_type) {
#ifdef CONFIG_TR
case QETH_MPC_LINK_TYPE_HSTR:
case QETH_MPC_LINK_TYPE_LANE_TR:
return qeth_my_tr_rebuild_header;
#endif /* CONFIG_TR */
default:
return qeth_my_eth_rebuild_header;
}
}
typedef int (*__qeth_temp3) (struct neighbour *, struct hh_cache *);
inline static __qeth_temp3
qeth_get_hard_header_cache(__u8 link_type)
{
switch (link_type) {
case QETH_MPC_LINK_TYPE_HSTR:
case QETH_MPC_LINK_TYPE_LANE_TR:
return NULL;
default:
return qeth_my_eth_header_cache;
}
}
typedef void (*__qeth_temp4) (struct hh_cache *, struct net_device *,
unsigned char *);
inline static __qeth_temp4
qeth_get_header_cache_update(__u8 link_type)
{
switch (link_type) {
case QETH_MPC_LINK_TYPE_HSTR:
case QETH_MPC_LINK_TYPE_LANE_TR:
return NULL;
default:
return qeth_my_eth_header_cache_update;
}
}
static unsigned short
qeth_eth_type_trans(struct sk_buff *skb, struct net_device *dev)
{
struct ethhdr *eth;
skb->mac.raw = skb->data;
skb_pull(skb, ETH_ALEN * 2 + sizeof (short));
eth = skb->mac.ethernet;
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 {
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);
}
typedef unsigned short (*__qeth_temp5) (struct sk_buff *, struct net_device *);
inline static __qeth_temp5
qeth_get_type_trans(__u8 link_type)
{
switch (link_type) {
#ifdef CONFIG_TR
case QETH_MPC_LINK_TYPE_HSTR:
case QETH_MPC_LINK_TYPE_LANE_TR:
return tr_type_trans;
#endif
default:
return qeth_eth_type_trans;
}
}
#endif /* QETH_IPV6 */
inline static const char *
qeth_get_link_type_name(int cardtype, __u8 linktype)
{
switch (cardtype) {
case QETH_CARD_TYPE_UNKNOWN:
return "unknown";
case QETH_CARD_TYPE_OSAE:
switch (linktype) {
case QETH_MPC_LINK_TYPE_FAST_ETHERNET:
return "Fast Eth";
case QETH_MPC_LINK_TYPE_HSTR:
return "HSTR";
case QETH_MPC_LINK_TYPE_GIGABIT_ETHERNET:
return "Gigabit Eth";
case QETH_MPC_LINK_TYPE_LANE_ETH100:
return "LANE Eth100";
case QETH_MPC_LINK_TYPE_LANE_TR:
return "LANE TR";
case QETH_MPC_LINK_TYPE_LANE_ETH1000:
return "LANE Eth1000";
default:
return "unknown";
}
case QETH_CARD_TYPE_IQD:
return "magic";
default:
return "unknown";
}
}
inline static const char *
qeth_get_dev_basename(int cardtype, __u8 link_type)
{
switch (cardtype) {
case QETH_CARD_TYPE_UNKNOWN:
return "eth";
case QETH_CARD_TYPE_OSAE:
switch (link_type) {
case QETH_MPC_LINK_TYPE_LANE_TR:
/* fallthrough */
case QETH_MPC_LINK_TYPE_HSTR:
return "tr";
default:
return "eth";
}
case QETH_CARD_TYPE_IQD:
return "hsi";
default:
return "eth";
}
}
/* inbound: */
#define DEFAULT_BUFFER_SIZE 65536
#define DEFAULT_BUFFER_COUNT 128
#define BUFCNT_MIN 8
#define BUFCNT_MAX 128
#define BUFFER_SIZE (card->inbound_buffer_size)
#define BUFFER_MAX_ELEMENTS (BUFFER_SIZE>>12)
/* 8k for each pair header-buffer: */
inline static int
qeth_sbal_packing_on_card(int cardtype)
{
switch (cardtype) {
case QETH_CARD_TYPE_IQD:
return 0;
default:
return 1;
}
}
/*
* do it this way round -> __MODULE_STRING needs with
* QETH_PRIO_NICE_LEVELS a single number
*/
#define QETH_MAX_PRIO_QUEUES QETH_PRIO_NICE_LEVELS+1
static inline int
qeth_sbalf15_in_retrieable_range(int sbalf15)
{
return ((sbalf15 >= 15) && (sbalf15 <= 31));
}
#define INBOUND_BUFFER_POS(card,bufno,sbale) \
( (bufno&SPAREBUF_MASK)? \
( \
(sparebufs[bufno&(~SPAREBUF_MASK)].buf+ \
PAGE_SIZE*sbale) \
):( \
(card->inbound_buffer_pool_entry[card-> \
inbound_buffer_entry_no[bufno]][sbale]) \
) )
#define SPAREBUF_UNAVAIL 0
#define SPAREBUF_FREE 1
#define SPAREBUF_USED 2
struct sparebufs {
char *buf;
atomic_t status;
};
#define SEND_STATE_INACTIVE 0
#define SEND_STATE_DONT_PACK 1
#define SEND_STATE_PACK 2
#define QETH_LOCK_UNLOCKED 0
#define QETH_LOCK_NORMAL 1
#define QETH_LOCK_FLUSH 2
#define QETH_MAX_DEVICES 16
/* DEPENDENCY ON QETH_MAX_DEVICES.
*__MOUDLE_STRING expects simple literals */
#define QETH_MAX_DEVICES_TIMES_4 64
#define QETH_MAX_DEVNAMES 16
#define QETH_DEVNAME "eth"
#define QETH_TX_TIMEOUT 100*HZ /* 100 seconds */
#define QETH_REMOVE_WAIT_TIME 200
#define QETH_WAIT_FOR_THREAD_TIME 20
#define QETH_IDLE_WAIT_TIME 10
#define QETH_WAIT_BEFORE_2ND_DOIO 1000
#define QETH_MAX_PARM_LEN 128
#define QETH_FAKE_LL_LEN ETH_HLEN /* 14 */
#define QETH_FAKE_LL_PROT_LEN 2
#define QETH_FAKE_LL_ADDR_LEN ETH_ALEN /* 6 */
#define QETH_FAKE_LL_DEST_MAC_POS 0
#define QETH_FAKE_LL_SRC_MAC_POS 6
#define QETH_FAKE_LL_SRC_MAC_POS_IN_QDIO_HDR 6
#define QETH_FAKE_LL_PROT_POS 12
#define QETH_FAKE_LL_V4_ADDR_POS 16
#define QETH_FAKE_LL_V6_ADDR_POS 24
#define DEV_NAME_LEN 16
#define IOCTL_MAX_TRANSFER_SIZE 65535
#define IP_TOS_LOWDELAY 0x10
#define IP_TOS_HIGHTHROUGHPUT 0x08
#define IP_TOS_HIGHRELIABILITY 0x04
#define IP_TOS_NOTIMPORTANT 0x02
#define QETH_RCD_LENGTH 128
#define __max(a,b) ( ((a)>(b))?(a):(b) )
#define __min(a,b) ( ((a)<(b))?(a):(b) )
#define QETH_BUFSIZE __max(__max(IPA_PDU_HEADER_SIZE+sizeof(struct arp_cmd), \
IPA_PDU_HEADER_SIZE+sizeof(struct ipa_cmd)), \
QETH_RCD_LENGTH)
#define QETH_FINAL_STATUS_TIMEOUT 1500
#define QETH_CLEAR_TIMEOUT 1500
#define QETH_RCD_TIMEOUT 1500
#define QETH_NOP_TIMEOUT 1500
#define QETH_QUIESCE_NETDEV_TIME 300
#define QETH_QUIESCE_WAIT_BEFORE_CLEAR 4000
#define QETH_QUIESCE_WAIT_AFTER_CLEAR 4000
#define NOP_STATE 0x1001
#define READ_CONF_DATA_STATE 0x1002
#define IDX_ACTIVATE_READ_STATE 0x1003
#define IDX_ACTIVATE_WRITE_STATE 0x1004
#define MPC_SETUP_STATE 0x1005
#define CLEAR_STATE 0x1006
#define IPA_CMD_STATE 0x1007
#define IPA_IOCTL_STATE 0x1009
#define IPA_SETIP_FLAG 0x100000
#define QETH_REMOVE_CARD_PROPER 1
#define QETH_REMOVE_CARD_QUICK 2
#define NO_PRIO_QUEUEING 0
#define PRIO_QUEUEING_PREC 1
#define PRIO_QUEUEING_TOS 2
#define NO_ROUTER 0
#define PRIMARY_ROUTER 1
#define SECONDARY_ROUTER 2
#define MULTICAST_ROUTER 3
#define PRIMARY_CONNECTOR 4
#define SECONDARY_CONNECTOR 5
#define ROUTER_MASK 0xf /* used to remove SET_ROUTING_FLAG
from routing_type */
#define RESET_ROUTING_FLAG 0x10 /* used to indicate, that setting
the routing type is desired */
#define BROADCAST_ALLRINGS 0
#define BROADCAST_LOCAL 1
#define MACADDR_NONCANONICAL 0
#define MACADDR_CANONICAL 1
#define MEMUSAGE_DISCONTIG 0
#define MEMUSAGE_CONTIG 1
#define ENABLE_TAKEOVER 0
#define DISABLE_TAKEOVER 1
#define FAKE_BROADCAST 0
#define DONT_FAKE_BROADCAST 1
#define FAKE_LL 0
#define DONT_FAKE_LL 1
#define SYNC_IQD 0
#define ASYNC_IQD 1
#define QETH_BREAKOUT_LEAVE 1
#define QETH_BREAKOUT_AGAIN 2
#define QETH_WAIT_FOR_LOCK 0
#define QETH_DONT_WAIT_FOR_LOCK 1
#define QETH_LOCK_ALREADY_HELD 2
#define PROBLEM_CARD_HAS_STARTLANED 1
#define PROBLEM_RECEIVED_IDX_TERMINATE 2
#define PROBLEM_ACTIVATE_CHECK_CONDITION 3
#define PROBLEM_RESETTING_EVENT_INDICATOR 4
#define PROBLEM_COMMAND_REJECT 5
#define PROBLEM_ZERO_SENSE_DATA 6
#define PROBLEM_GENERAL_CHECK 7
#define PROBLEM_BAD_SIGA_RESULT 8
#define PROBLEM_USER_TRIGGERED_RECOVERY 9
#define PROBLEM_AFFE 10
#define PROBLEM_MACHINE_CHECK 11
#define PROBLEM_TX_TIMEOUT 12
#define SENSE_COMMAND_REJECT_BYTE 0
#define SENSE_COMMAND_REJECT_FLAG 0x80
#define SENSE_RESETTING_EVENT_BYTE 1
#define SENSE_RESETTING_EVENT_FLAG 0x80
#define DEFAULT_RCD_CMD 0x72
#define DEFAULT_RCD_COUNT 0x80
#define BUFFER_USED 1
#define BUFFER_UNUSED -1
typedef int (*reg_notifier_t) (struct notifier_block *);
struct ipato_entry {
int version;
__u8 addr[16];
int mask_bits;
char dev_name[DEV_NAME_LEN];
struct ipato_entry *next;
};
struct qeth_vipa_entry {
int version;
__u8 ip[16];
int flag;
volatile int state;
struct qeth_vipa_entry *next;
};
struct ip_state {
struct in_ifaddr *ip_ifa; /* pointer to IPv4 adresses */
struct inet6_ifaddr *ip6_ifa;
};
struct qeth_ipm_mac {
__u8 mac[ETH_ALEN];
__u8 ip[16];
struct qeth_ipm_mac *next;
};
struct ip_mc_state {
struct qeth_ipm_mac *ipm_ifa;
struct qeth_ipm_mac *ipm6_ifa;
};
struct addr_request {
struct addr_request *next;
int request_type;
__u8 mac[ETH_ALEN];
__u8 ip[16];
};
struct qeth_card_options {
char devname[DEV_NAME_LEN];
volatile int routing_type4;
#ifdef QETH_IPV6
volatile int routing_type6;
#endif /* QETH_IPV6 */
int checksum_type;
int do_prio_queueing;
int default_queue;
int inbound_buffer_count;
int polltime;
char portname[9];
int portno;
int memusage;
int broadcast_mode;
int macaddr_mode;
int ena_ipat;
int fake_broadcast;
int add_hhlen;
int fake_ll;
int async_iqd;
};
struct qeth_hdr {
__u8 id;
__u8 flags;
__u16 inbound_checksum;
__u32 token;
__u16 length;
__u8 vlan_prio;
__u8 ext_flags;
__u16 vlan_id;
__u16 frame_offset;
__u8 dest_addr[16];
};
struct qeth_ringbuffer_element {
struct sk_buff_head skb_list;
int next_element_to_fill;
} __attribute__ ((packed));
struct qeth_ringbuffer {
struct qdio_buffer buffer[QDIO_MAX_BUFFERS_PER_Q];
struct qeth_ringbuffer_element ringbuf_element[QDIO_MAX_BUFFERS_PER_Q];
}__attribute__ ((packed, aligned(PAGE_SIZE)));
struct qeth_dma_stuff {
unsigned char *sendbuf;
unsigned char *recbuf;
struct ccw1 read_ccw;
struct ccw1 write_ccw;
}__attribute__ ((packed, aligned(PAGE_SIZE)));
struct qeth_perf_stats {
unsigned int skbs_rec;
unsigned int bufs_rec;
unsigned int skbs_sent;
unsigned int bufs_sent;
unsigned int skbs_sent_dont_pack;
unsigned int bufs_sent_dont_pack;
unsigned int skbs_sent_pack;
unsigned int bufs_sent_pack;
unsigned int skbs_sent_pack_better;
unsigned int bufs_sent_pack_better;
unsigned int sc_dp_p;
unsigned int sc_p_dp;
__u64 inbound_start_time;
unsigned int inbound_cnt;
unsigned int inbound_time;
__u64 outbound_start_time;
unsigned int outbound_cnt;
unsigned int outbound_time;
};
/* ugly. I know. */
struct qeth_card { /* pointed to by dev->priv */
int easy_copy_cap;
/* pointer to options (defaults + parameters) */
struct qeth_card_options options;
atomic_t is_startlaned; /* card did not get a stoplan */
/* also 0 when card is gone after a
* machine check */
__u8 link_type;
int is_guest_lan;
/* inbound buffer management */
atomic_t inbound_buffer_refcnt[QDIO_MAX_BUFFERS_PER_Q];
struct qdio_buffer inbound_qdio_buffers[QDIO_MAX_BUFFERS_PER_Q];
/* inbound data area */
void *inbound_buffer_pool_entry[QDIO_MAX_BUFFERS_PER_Q]
[QDIO_MAX_ELEMENTS_PER_BUFFER];
volatile int inbound_buffer_pool_entry_used[QDIO_MAX_BUFFERS_PER_Q];
int inbound_buffer_entry_no[QDIO_MAX_BUFFERS_PER_Q];
/* for requeueing of buffers */
spinlock_t requeue_input_lock;
atomic_t requeue_position;
atomic_t requeue_counter;
/* outbound QDIO stuff */
volatile int send_state[QETH_MAX_QUEUES];
volatile int outbound_first_free_buffer[QETH_MAX_QUEUES];
atomic_t outbound_used_buffers[QETH_MAX_QUEUES];
int outbound_buffer_send_state[QETH_MAX_QUEUES]
[QDIO_MAX_BUFFERS_PER_Q];
int send_retries[QETH_MAX_QUEUES][QDIO_MAX_BUFFERS_PER_Q];
volatile int outbound_bytes_in_buffer[QETH_MAX_QUEUES];
struct qeth_ringbuffer *outbound_ringbuffer[QETH_MAX_QUEUES];
atomic_t outbound_ringbuffer_lock[QETH_MAX_QUEUES];
atomic_t last_pci_pos[QETH_MAX_QUEUES];
#ifdef QETH_IPV6
int (*hard_header) (struct sk_buff *, struct net_device *,
unsigned short, void *, void *, unsigned);
int (*rebuild_header) (struct sk_buff *);
int (*hard_header_cache) (struct neighbour *, struct hh_cache *);
void (*header_cache_update) (struct hh_cache *, struct net_device *,
unsigned char *);
unsigned short (*type_trans) (struct sk_buff *, struct net_device *);
#endif /* QETH_IPV6 */
#ifdef QETH_VLAN
struct vlan_group *vlangrp;
spinlock_t vlan_lock;
#endif
char dev_name[DEV_NAME_LEN]; /* pointed to by dev->name */
struct net_device *dev;
struct net_device_stats *stats;
int no_queues;
#ifdef QETH_PERFORMANCE_STATS
struct qeth_perf_stats perf_stats;
#endif /* QETH_PERFORMANCE_STATS */
/* our state */
atomic_t is_registered; /* card registered as netdev? */
atomic_t is_hardsetup; /* card has gone through hardsetup */
atomic_t is_softsetup; /* card is setup by softsetup */
atomic_t is_open; /* card is in use */
/* prevents deadlocks :-O */
spinlock_t softsetup_lock;
spinlock_t hardsetup_lock;
spinlock_t ioctl_lock;
atomic_t softsetup_thread_is_running;
struct semaphore softsetup_thread_sem;
struct work_struct tqueue_sst;
atomic_t escape_softsetup; /* active, when recovery has to
wait for softsetup */
struct semaphore reinit_thread_sem;
atomic_t in_recovery;
atomic_t reinit_counter;
/* problem management */
atomic_t break_out;
atomic_t problem;
struct work_struct tqueue;
struct {
__u32 trans_hdr;
__u32 pdu_hdr;
__u32 pdu_hdr_ack;
__u32 ipa;
} seqno;
struct {
__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;
} token;
/* this is card-related */
int type;
__u16 func_level;
int initial_mtu;
int max_mtu;
int inbound_buffer_size;
int is_multicast_different; /* if multicast traffic is to be sent
on a different queue, this is the
queue+no_queues */
int can_do_async_iqd; /* 1 only on IQD that provides async
unicast sigas */
__u32 ipa_supported;
__u32 ipa_enabled;
__u32 ipa6_supported;
__u32 ipa6_enabled;
__u32 adp_supported;
atomic_t startlan_attempts;
atomic_t enable_routing_attempts4;
atomic_t rt4fld;
#ifdef QETH_IPV6
atomic_t enable_routing_attempts6;
atomic_t rt6fld;
#endif /* QETH_IPV6 */
int unique_id;
/* device and I/O data */
struct ccw_device *rdev;
struct ccw_device *wdev;
struct ccw_device *ddev;
unsigned short unit_addr2;
unsigned short cula;
unsigned short chpid;
unsigned char ipa_buf[QETH_BUFSIZE];
unsigned char send_buf[QETH_BUFSIZE];
/* IOCTL Stuff */
unsigned char *ioctl_data_buffer;
unsigned char *ioctl_buffer_pointer;
int ioctl_returncode;
int ioctl_buffersize;
int number_of_entries;
atomic_t ioctl_data_has_arrived;
wait_queue_head_t ioctl_wait_q;
atomic_t ioctl_wait_q_active;
spinlock_t ioctl_wait_q_lock;
/* stuff under 2 gb */
struct qeth_dma_stuff *dma_stuff;
unsigned int ipa_timeout;
atomic_t write_busy;
/* vipa stuff */
rwlock_t vipa_list_lock;
struct qeth_vipa_entry *vipa_list;
/* state information when doing I/O */
atomic_t shutdown_phase;
atomic_t data_has_arrived;
wait_queue_head_t wait_q;
atomic_t wait_q_active;
spinlock_t wait_q_lock; /* for wait_q_active and wait_q */
atomic_t clear_succeeded0;
atomic_t clear_succeeded1;
atomic_t clear_succeeded2;
/* bookkeeping of IP and multicast addresses */
struct ip_state ip_current_state;
struct ip_state ip_new_state;
struct ip_mc_state ip_mc_current_state;
struct ip_mc_state ip_mc_new_state;
int broadcast_capable;
int portname_required;
int realloc_message;
char level[QETH_MCL_LENGTH + 1];
volatile int saved_dev_flags;
/* for our linked list */
struct qeth_card *next;
};
inline static int
qeth_get_arphrd_type(int cardtype, int linktype)
{
switch (cardtype) {
case QETH_CARD_TYPE_OSAE:
switch (linktype) {
case QETH_MPC_LINK_TYPE_LANE_TR:
/* fallthrough */
case QETH_MPC_LINK_TYPE_HSTR:
return ARPHRD_IEEE802;
default:
return ARPHRD_ETHER;
}
case QETH_CARD_TYPE_IQD:
return ARPHRD_ETHER;
default:
return ARPHRD_ETHER;
}
}
inline static int
qeth_determine_easy_copy_cap(int cardtype)
{
switch (cardtype) {
case QETH_CARD_TYPE_UNKNOWN:
return 0; /* better be cautious */
case QETH_CARD_TYPE_OSAE:
return 1;
case QETH_CARD_TYPE_IQD:
return 0;
default:
return 0; /* ?? */
}
}
inline static __u8
qeth_get_adapter_type_for_ipa(int link_type)
{
switch (link_type) {
case QETH_MPC_LINK_TYPE_HSTR:
return 2;
default:
return 1;
}
}
inline static const char *
qeth_get_cardname(int cardtype, int is_guest_lan)
{
if (is_guest_lan) {
switch (cardtype) {
case QETH_CARD_TYPE_UNKNOWN:
return "n unknown";
case QETH_CARD_TYPE_OSAE:
return " Guest LAN QDIO";
case QETH_CARD_TYPE_IQD:
return " Guest LAN Hiper";
default: return
" strange";
}
} else {
switch (cardtype) {
case QETH_CARD_TYPE_UNKNOWN:
return "n unknown";
case QETH_CARD_TYPE_OSAE:
return "n OSD Express";
case QETH_CARD_TYPE_IQD:
return " HiperSockets";
default:
return " strange";
}
}
}
/* max length to be returned: 14 */
inline static const char *
qeth_get_cardname_short(int cardtype, __u8 link_type, int is_guest_lan)
{
switch (cardtype) {
case QETH_CARD_TYPE_UNKNOWN:
return "unknown";
case QETH_CARD_TYPE_OSAE:
if (is_guest_lan)
return "GuestLAN QDIO";
switch (link_type) {
case QETH_MPC_LINK_TYPE_FAST_ETHERNET:
return "OSD_100";
case QETH_MPC_LINK_TYPE_HSTR:
return "HSTR";
case QETH_MPC_LINK_TYPE_GIGABIT_ETHERNET:
return "OSD_1000";
case QETH_MPC_LINK_TYPE_LANE_ETH100:
return "OSD_FE_LANE";
case QETH_MPC_LINK_TYPE_LANE_TR:
return "OSD_TR_LANE";
case QETH_MPC_LINK_TYPE_LANE_ETH1000:
return "OSD_GbE_LANE";
case QETH_MPC_LINK_TYPE_LANE:
return "OSD_ATM_LANE";
default:
return "OSD_Express";
}
case QETH_CARD_TYPE_IQD:
return is_guest_lan ? "GuestLAN Hiper" : "HiperSockets";
default:
return " strange";
}
}
inline static int
qeth_mtu_is_valid(struct qeth_card * card, int mtu)
{
switch (card->type) {
case QETH_CARD_TYPE_UNKNOWN:
return 1;
case QETH_CARD_TYPE_OSAE:
return ((mtu >= 576) && (mtu <= 61440));
case QETH_CARD_TYPE_IQD:
return ((mtu >= 576) && (mtu <= card->max_mtu + 4096 - 32));
default:
return 1;
}
}
inline static int
qeth_get_initial_mtu_for_card(struct qeth_card * card)
{
switch (card->type) {
case QETH_CARD_TYPE_UNKNOWN:
return 1500;
case QETH_CARD_TYPE_IQD:
return card->max_mtu;
case QETH_CARD_TYPE_OSAE:
switch (card->link_type) {
case QETH_MPC_LINK_TYPE_HSTR:
case QETH_MPC_LINK_TYPE_LANE_TR:
return 2000;
default:
return 1492;
}
default:
return 1500;
}
}
inline static int
qeth_get_max_mtu_for_card(int cardtype)
{
switch (cardtype) {
case QETH_CARD_TYPE_UNKNOWN:
return 61440;
case QETH_CARD_TYPE_OSAE:
return 61440;
case QETH_CARD_TYPE_IQD:
return 57344;
default:
return 1500;
}
}
inline static int
qeth_get_mtu_out_of_mpc(int cardtype)
{
switch (cardtype) {
case QETH_CARD_TYPE_IQD:
return 1;
default:
return 0;
}
}
inline static 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;
}
}
inline static int
qeth_get_buffersize_for_card(int cardtype)
{
switch (cardtype) {
case QETH_CARD_TYPE_UNKNOWN:
return 65536;
case QETH_CARD_TYPE_OSAE:
return 65536;
case QETH_CARD_TYPE_IQD:
return 16384;
default:
return 65536;
}
}
inline static int
qeth_get_min_number_of_buffers(int cardtype)
{
switch (cardtype) {
case QETH_CARD_TYPE_UNKNOWN:
return 32;
case QETH_CARD_TYPE_OSAE:
return 32;
case QETH_CARD_TYPE_IQD:
return 64;
default:
return 64;
}
}
inline static int
qeth_get_q_format(int cardtype)
{
switch (cardtype) {
case QETH_CARD_TYPE_IQD:
return 2;
default:
return 0;
}
}
inline static int
qeth_get_device_tx_q_len(int cardtype)
{
return 100;
}
inline static int
qeth_get_max_number_of_buffers(int cardtype)
{
return 127;
}
/******************** OUTPUT FACILITIES **************************/
#ifdef PRINT_INFO
#undef PRINTK_HEADER
#undef PRINT_STUPID
#undef PRINT_ALL
#undef PRINT_INFO
#undef PRINT_WARN
#undef PRINT_ERR
#undef PRINT_CRIT
#undef PRINT_ALERT
#undef PRINT_EMERG
#endif /* PRINT_INFO */
#define PRINTK_HEADER QETH_NAME ": "
#if QETH_VERBOSE_LEVEL>8
#define PRINT_STUPID(x...) printk( KERN_DEBUG PRINTK_HEADER x)
#else
#define PRINT_STUPID(x...)
#endif
#if QETH_VERBOSE_LEVEL>7
#define PRINT_ALL(x...) printk( KERN_DEBUG PRINTK_HEADER x)
#else
#define PRINT_ALL(x...)
#endif
#if QETH_VERBOSE_LEVEL>6
#define PRINT_INFO(x...) printk( KERN_INFO PRINTK_HEADER x)
#else
#define PRINT_INFO(x...)
#endif
#if QETH_VERBOSE_LEVEL>5
#define PRINT_WARN(x...) printk( KERN_WARNING PRINTK_HEADER x)
#else
#define PRINT_WARN(x...)
#endif
#if QETH_VERBOSE_LEVEL>4
#define PRINT_ERR(x...) printk( KERN_ERR PRINTK_HEADER x)
#else
#define PRINT_ERR(x...)
#endif
#if QETH_VERBOSE_LEVEL>3
#define PRINT_CRIT(x...) printk( KERN_CRIT PRINTK_HEADER x)
#else
#define PRINT_CRIT(x...)
#endif
#if QETH_VERBOSE_LEVEL>2
#define PRINT_ALERT(x...) printk( KERN_ALERT PRINTK_HEADER x)
#else
#define PRINT_ALERT(x...)
#endif
#if QETH_VERBOSE_LEVEL>1
#define PRINT_EMERG(x...) printk( KERN_EMERG PRINTK_HEADER x)
#else
#define PRINT_EMERG(x...)
#endif
#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));
#endif /* __QETH_H__ */
/*
* linux/drivers/s390/net/qeth_mpc.c
*
* Linux on zSeries OSA Express and HiperSockets support
*
* Copyright 2000,2003 IBM Corporation
* Author(s): Utz Bacher <utz.bacher@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 ipa_cmd))/256,
(IPA_PDU_HEADER_SIZE+sizeof(struct 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,0x00,sizeof(struct ipa_cmd),
0x00,0x00,sizeof(struct ipa_cmd),0x05, 0x77,0x77,0x77,0x77,
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
0x01,0x00,sizeof(struct ipa_cmd)/256,sizeof(struct 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
};
/*
* 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>
*
*/
#ifndef __QETH_MPC_H__
#define __QETH_MPC_H__
#define VERSION_QETH_MPC_H "$Revision: 1.15 $"
#define QETH_IPA_TIMEOUT (card->ipa_timeout)
#define QETH_MPC_TIMEOUT 2000
#define QETH_ADDR_TIMEOUT 1000
#define QETH_SETIP_RETRIES 2
#define IDX_ACTIVATE_SIZE 0x22
#define CM_ENABLE_SIZE 0x63
#define CM_SETUP_SIZE 0x64
#define ULP_ENABLE_SIZE 0x6b
#define ULP_SETUP_SIZE 0x6c
#define DM_ACT_SIZE 0x55
#define QETH_MPC_TOKEN_LENGTH 4
#define QETH_SEQ_NO_LENGTH 4
#define QETH_IPA_SEQ_NO_LENGTH 2
#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 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_MCL_LENGTH 4
extern unsigned char CM_ENABLE[];
#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 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 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)
extern unsigned char ULP_SETUP[];
#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 QETH_DM_ACT_DEST_ADDR(buffer) (buffer+0x2c)
#define QETH_DM_ACT_CONNECTION_TOKEN(buffer) (buffer+0x51)
#define IPA_CMD_STARTLAN 0x01
#define IPA_CMD_STOPLAN 0x02
#define IPA_CMD_SETIP 0xb1
#define IPA_CMD_DELIP 0xb7
#define IPA_CMD_QIPASSIST 0xb2
#define IPA_CMD_SETASSPARMS 0xb3
#define IPA_CMD_SETIPM 0xb4
#define IPA_CMD_DELIPM 0xb5
#define IPA_CMD_SETRTG 0xb6
#define IPA_CMD_SETADAPTERPARMS 0xb8
#define IPA_CMD_ADD_ADDR_ENTRY 0xc1
#define IPA_CMD_DELETE_ADDR_ENTRY 0xc2
#define IPA_CMD_CREATE_ADDR 0xc3
#define IPA_CMD_DESTROY_ADDR 0xc4
#define IPA_CMD_REGISTER_LOCAL_ADDR 0xd1
#define IPA_CMD_UNREGISTER_LOCAL_ADDR 0xd2
#define INITIATOR_HOST 0
#define INITIATOR_HYDRA 1
#define PRIM_VERSION_IPA 1
#define PROT_VERSION_SNA 1 /* hahaha */
#define PROT_VERSION_IPv4 4
#define PROT_VERSION_IPv6 6
#define OSA_ADDR_LEN 6
#define IPA_SETADAPTERPARMS_IP_VERSION PROT_VERSION_IPv4
#define SR_INFO_LEN 16
#define IPA_ARP_PROCESSING 0x00000001L
#define IPA_INBOUND_CHECKSUM 0x00000002L
#define IPA_OUTBOUND_CHECKSUM 0x00000004L
#define IPA_IP_FRAGMENTATION 0x00000008L
#define IPA_FILTERING 0x00000010L
#define IPA_IPv6 0x00000020L
#define IPA_MULTICASTING 0x00000040L
#define IPA_IP_REASSEMBLY 0x00000080L
#define IPA_QUERY_ARP_COUNTERS 0x00000100L
#define IPA_QUERY_ARP_ADDR_INFO 0x00000200L
#define IPA_SETADAPTERPARMS 0x00000400L
#define IPA_VLAN_PRIO 0x00000800L
#define IPA_PASSTHRU 0x00001000L
#define IPA_FULL_VLAN 0x00004000L
#define IPA_SOURCE_MAC_AVAIL 0x00010000L
#define IPA_SETADP_QUERY_COMMANDS_SUPPORTED 0x01
#define IPA_SETADP_ALTER_MAC_ADDRESS 0x02
#define IPA_SETADP_ADD_DELETE_GROUP_ADDRESS 0x04
#define IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR 0x08
#define IPA_SETADP_SET_ADDRESSING_MODE 0x10
#define IPA_SETADP_SET_CONFIG_PARMS 0x20
#define IPA_SETADP_SET_CONFIG_PARMS_EXTENDED 0x40
#define IPA_SETADP_SET_BROADCAST_MODE 0x80
#define IPA_SETADP_SEND_OSA_MESSAGE 0x0100
#define IPA_SETADP_SET_SNMP_CONTROL 0x0200
#define IPA_SETADP_READ_SNMP_PARMS 0x0400
#define IPA_SETADP_WRITE_SNMP_PARMS 0x0800
#define IPA_SETADP_QUERY_CARD_INFO 0x1000
#define CHANGE_ADDR_READ_MAC 0
#define CHANGE_ADDR_REPLACE_MAC 1
#define CHANGE_ADDR_ADD_MAC 2
#define CHANGE_ADDR_DEL_MAC 4
#define CHANGE_ADDR_RESET_MAC 8
#define CHANGE_ADDR_READ_ADDR 0
#define CHANGE_ADDR_ADD_ADDR 1
#define CHANGE_ADDR_DEL_ADDR 2
#define CHANGE_ADDR_FLUSH_ADDR_TABLE 4
/* we assumed, that the card is named card */
#define qeth_is_supported(str) (card->ipa_supported&str)
#define qeth_is_supported6(str) (card->ipa6_supported&str)
#define qeth_is_adp_supported(str) (card->adp_supported&str)
/* the same for all assist parms: */
#define IPA_CMD_ASS_START 0x0001
#define IPA_CMD_ASS_STOP 0x0002
#define IPA_CMD_ASS_CONFIGURE 0x0003
#define IPA_CMD_ASS_ENABLE 0x0004
#define IPA_CMD_ASS_ARP_SET_NO_ENTRIES 0x0003
#define IPA_CMD_ASS_ARP_QUERY_CACHE 0x0004
#define IPA_CMD_ASS_ARP_ADD_ENTRY 0x0005
#define IPA_CMD_ASS_ARP_REMOVE_ENTRY 0x0006
#define IPA_CMD_ASS_ARP_FLUSH_CACHE 0x0007
#define IPA_CMD_ASS_ARP_QUERY_INFO 0x0104
#define IPA_CMD_ASS_ARP_QUERY_STATS 0x0204
#define IPA_CHECKSUM_ENABLE_MASK 0x001a
#define IPA_CMD_ASS_FILTER_SET_TYPES 0x0003
#define IPA_CMD_ASS_IPv6_SET_FUNCTIONS 0x0003
#define IPA_REPLY_SUCCESS 0
#define IPA_REPLY_FAILED 1
#define IPA_REPLY_OPNOTSUPP 2
#define IPA_REPLY_OPNOTSUPP2 4
#define IPA_REPLY_NOINFO 8
#define IPA_SETIP_FLAGS 0
#define IPA_SETIP_VIPA_FLAGS 1
#define IPA_SETIP_TAKEOVER_FLAGS 2
#define VIPA_2_B_ADDED 0
#define VIPA_ESTABLISHED 1
#define VIPA_2_B_REMOVED 2
#define IPA_DELIP_FLAGS 0
#define IPA_SETADP_CMDSIZE 40
struct ipa_setadp_cmd {
__u32 supp_hw_cmds;
__u32 reserved1;
__u16 cmdlength;
__u16 reserved2;
__u32 command_code;
__u16 return_code;
__u8 frames_used_total;
__u8 frame_seq_no;
__u32 reserved3;
union {
struct {
__u32 no_lantypes_supp;
__u8 lan_type;
__u8 reserved1[3];
__u32 supported_cmds;
__u8 reserved2[8];
} query_cmds_supp;
struct {
__u32 cmd;
__u32 addr_size;
__u32 no_macs;
__u8 addr[OSA_ADDR_LEN];
} change_addr;
__u32 mode;
} data;
};
struct ipa_cmd{
__u8 command;
__u8 initiator;
__u16 seq_no;
__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;
union {
struct {
__u8 ip[4];
__u8 netmask[4];
__u32 flags;
} setdelip4;
struct {
__u8 ip[16];
__u8 netmask[16];
__u32 flags;
} setdelip6;
struct {
__u32 assist_no;
__u16 length;
__u16 command_code;
__u16 return_code;
__u8 number_of_replies;
__u8 seq_no;
union {
__u32 flags_32bit;
struct {
__u8 mac[6];
__u8 reserved[2];
__u8 ip[16];
__u8 reserved2[32];
} add_arp_entry;
__u8 ip[16];
} data;
} setassparms;
struct {
__u8 mac[6];
__u8 padding[2];
__u8 ip6[12];
__u8 ip4_6[4];
} setdelipm;
struct {
__u8 type;
} setrtg;
struct ipa_setadp_cmd setadapterparms;
struct {
__u32 command;
#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
__u32 frame_type;
__u32 cmd_flags;
__u8 ip_addr[16];
__u32 tag_field;
__u8 mac_addr[6];
__u8 reserved[10];
__u32 sr_len;
__u8 sr_info[SR_INFO_LEN];
} add_addr_entry;
struct {
__u32 command;
__u32 cmd_flags;
__u8 ip_addr[16];
__u32 tag_field;
} delete_addr_entry;
struct {
__u8 unique_id[8];
} create_destroy_addr;
} data;
}__attribute__ ((packed));
#define QETH_IOC_MAGIC 0x22
#define QETH_IOCPROC_OSAEINTERFACES _IOWR(QETH_IOC_MAGIC, 1, arg)
#define QETH_IOCPROC_INTERFACECHANGES _IOWR(QETH_IOC_MAGIC, 2, arg)
#define SNMP_QUERY_CARD_INFO 0x00000002L
#define SNMP_REGISETER_MIB 0x00000004L
#define SNMP_GET_OID 0x00000010L
#define SNMP_SET_OID 0x00000011L
#define SNMP_GET_NEXT_OID 0x00000012L
#define SNMP_QUERY_ALERTS 0x00000020L
#define SNMP_SET_TRAP 0x00000021L
#define ARP_DATA_SIZE 3968
#define ARP_FLUSH -3
#define ARP_RETURNCODE_NOARPDATA -2
#define ARP_RETURNCODE_ERROR -1
#define ARP_RETURNCODE_SUCCESS 0
#define ARP_RETURNCODE_LASTREPLY 1
#define SNMP_BASE_CMDLENGTH 44
#define SNMP_SETADP_CMDLENGTH 16
#define SNMP_REQUEST_DATA_OFFSET 16
struct snmp_ipa_setadp_cmd {
__u32 supp_hw_cmds;
__u32 reserved1;
__u16 cmdlength;
__u16 reserved2;
__u32 command_code;
__u16 return_code;
__u8 frames_used_total;
__u8 frame_seq_no;
__u32 reserved3;
__u8 snmp_token[16];
union {
struct {
__u32 snmp_request;
__u32 snmp_interface;
__u32 snmp_returncode;
__u32 snmp_firmwarelevel;
__u32 snmp_seqno;
__u8 snmp_data[ARP_DATA_SIZE];
} snmp_subcommand;
} data;
}__attribute__ ((packed));
struct arp_cmd {
__u8 command;
__u8 initiator;
__u16 seq_no;
__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;
union {
struct {
__u32 assist_no;
__u16 length;
__u16 command_code;
__u16 return_code;
__u8 number_of_replies;
__u8 seq_no;
union {
struct {
__u16 tcpip_requestbitmask;
__u16 osa_setbitmask;
__u32 number_of_entries;
__u8 arp_data[ARP_DATA_SIZE];
} queryarp_data;
} data;
} setassparms;
struct snmp_ipa_setadp_cmd setadapterparms;
} data;
}__attribute__ ((packed));
#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+0x2a)
#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 PDU_ENCAPSULATION(buffer) \
(buffer+ \
*(buffer+ (*(buffer+0x0b))+ *(buffer+*(buffer+0x0b)+0x11) +0x07))
#define IS_IPA(buffer) ((buffer) && ( *(buffer+ ((*(buffer+0x0b))+4) )==0xc1) )
#define IS_IPA_REPLY(buffer) ( (buffer) && ( (*(PDU_ENCAPSULATION(buffer)+1))==INITIATOR_HOST ) )
#define CCW_NOP_CMD 0x03
#define CCW_NOP_COUNT 1
extern unsigned char WRITE_CCW[];
extern unsigned char READ_CCW[];
#endif /* __QETH_MPC_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment