#include <net/addrconf.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
+
#include <asm/debug.h>
#include <asm/qdio.h>
#include <asm/ccwdev.h>
#include "qeth_mpc.h"
-#define VERSION_QETH_H "$Revision: 1.102 $"
+#define VERSION_QETH_H "$Revision: 1.132 $"
#ifdef CONFIG_QETH_IPV6
#define QETH_VERSION_IPV6 ":IPv6"
#define QETH_DBF_SETUP_LEN 8
#define QETH_DBF_SETUP_INDEX 3
#define QETH_DBF_SETUP_NR_AREAS 1
-#define QETH_DBF_SETUP_LEVEL 3
+#define QETH_DBF_SETUP_LEVEL 5
#define QETH_DBF_MISC_NAME "qeth_misc"
#define QETH_DBF_MISC_LEN 128
#define QETH_DBF_CONTROL_LEN 256
#define QETH_DBF_CONTROL_INDEX 3
#define QETH_DBF_CONTROL_NR_AREAS 2
-#define QETH_DBF_CONTROL_LEVEL 2
+#define QETH_DBF_CONTROL_LEVEL 5
#define QETH_DBF_TRACE_NAME "qeth_trace"
#define QETH_DBF_TRACE_LEN 8
#define QETH_DBF_TRACE_INDEX 2
#define QETH_DBF_TRACE_NR_AREAS 2
-#define QETH_DBF_TRACE_LEVEL 3
+#define QETH_DBF_TRACE_LEVEL 5
#define QETH_DBF_SENSE_NAME "qeth_sense"
#define QETH_DBF_SENSE_LEN 64
debug_event(qeth_dbf_##name,level,(void*)(addr),len); \
} while (0)
-#define QETH_DBF_TEXT_(name,level,text...) \
- do { \
- sprintf(qeth_dbf_text_buf, text); \
- debug_text_event(qeth_dbf_##name,level,qeth_dbf_text_buf);\
+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...) \
#define SENSE_RESETTING_EVENT_BYTE 1
#define SENSE_RESETTING_EVENT_FLAG 0x80
+#define atomic_swap(a,b) xchg((int *)a.counter, b)
+
/*
* Common IO related definitions
*/
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;
};
#endif /* CONFIG_QETH_PERF_STATS */
#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 / 4)
+ ((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)
#define QETH_WATERMARK_PACK_FUZZ 1
#define QETH_IP_HEADER_SIZE 40
-/* VLAN defines */
-#define QETH_EXT_HDR_VLAN_FRAME 0x01
-#define QETH_EXT_HDR_TOKEN_ID 0x02
-#define QETH_EXT_HDR_INCLUDE_VLAN_TAG 0x04
-struct qeth_hdr {
+struct qeth_hdr_layer3 {
__u8 id;
__u8 flags;
__u16 inbound_checksum;
__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 {
+ union {
+ struct qeth_hdr_layer2 l2;
+ struct qeth_hdr_layer3 l3;
+ } hdr;
+} __attribute__ ((packed));
+
+
/* flags for qeth_hdr.flags */
#define QETH_HDR_PASSTHRU 0x10
#define QETH_HDR_IPV6 0x80
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,
+};
/* flags for qeth_hdr.ext_flags */
-#define QETH_HDR_EXT_VLAN_FRAME 0x01
-#define QETH_HDR_EXT_CSUM_HDR_REQ 0x10
-#define QETH_HDR_EXT_CSUM_TRANSP_REQ 0x20
-#define QETH_HDR_EXT_SRC_MAC_ADDR 0x08
+#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
static inline int
qeth_is_last_sbale(struct qdio_buffer_element *sbale)
* outbound: filled by driver; owned by hardware in order to be sent
*/
QETH_QDIO_BUF_PRIMED,
- /*
- * inbound only: an error condition has been detected for a buffer
- * the buffer will be discarded (not read out)
- */
- QETH_QDIO_BUF_ERROR,
};
enum qeth_qdio_info_states {
struct qeth_qdio_out_buffer {
struct qdio_buffer *buffer;
- volatile enum qeth_qdio_buffer_states state;
+ atomic_t state;
volatile int next_element_to_fill;
struct sk_buff_head skb_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;
- spinlock_t lock;
+ atomic_t state;
volatile int do_pack;
/*
* index of buffer to be filled by driver; state EMPTY or PACKING
QETH_IP_TYPE_NORMAL,
QETH_IP_TYPE_VIPA,
QETH_IP_TYPE_RXIP,
+ QETH_IP_TYPE_DEL_ALL_MC,
};
enum qeth_cmd_buffer_state {
__u32 trans_hdr;
__u32 pdu_hdr;
__u32 pdu_hdr_ack;
- __u32 ipa;
+ __u16 ipa;
};
struct qeth_reply {
struct list_head list;
wait_queue_head_t wait_q;
int (*callback)(struct qeth_card *,struct qeth_reply *,unsigned long);
- int seqno;
+ u32 seqno;
+ unsigned long offset;
int received;
int rc;
void *param;
atomic_t refcnt;
};
-struct qeth_card_info {
+#define QETH_BROADCAST_WITH_ECHO 1
+#define QETH_BROADCAST_WITHOUT_ECHO 2
- char if_name[IF_NAME_LEN];
+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 layer2_mac_registered;
int portname_required;
int portno;
char portname[9];
enum qeth_checksum_types checksum_type;
int broadcast_mode;
int macaddr_mode;
- int enable_takeover;
int fake_broadcast;
int add_hhlen;
int fake_ll;
+ int layer2;
};
/*
*/
enum qeth_threads {
QETH_SET_IP_THREAD = 1,
- QETH_SET_MC_THREAD = 2,
- QETH_RECOVER_THREAD = 4,
+ QETH_RECOVER_THREAD = 2,
};
struct qeth_card {
volatile unsigned long thread_running_mask;
spinlock_t ip_lock;
struct list_head ip_list;
- struct list_head ip_tbd_list;
+ struct list_head *ip_tbd_list;
struct qeth_ipato ipato;
struct list_head cmd_waiter_list;
/* QDIO buffer handling */
struct qeth_perf_stats perf_stats;
#endif /* CONFIG_QETH_PERF_STATS */
int use_hard_stop;
+ int (*orig_hard_header)(struct sk_buff *,struct net_device *,
+ unsigned short,void *,void *,unsigned);
};
struct qeth_card_list_struct {
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 : "")
+
inline static __u8
qeth_get_ipa_adp_type(enum qeth_link_types link_type)
{
}
inline static unsigned short
-qeth_get_netdev_flags(int cardtype)
+qeth_get_netdev_flags(struct qeth_card *card)
{
- switch (cardtype) {
+ if (card->options.layer2)
+ return 0;
+ switch (card->info.type) {
case QETH_CARD_TYPE_IQD:
return IFF_NOARP;
#ifdef CONFIG_QETH_IPV6
#endif
}
}
+static inline struct sk_buff *
+qeth_pskb_unshare(struct sk_buff *skb, int pri)
+{
+ struct sk_buff *nskb;
+ if (!skb_cloned(skb))
+ return skb;
+ nskb = skb_copy(skb, pri);
+ kfree_skb(skb); /* free our shared copy */
+ return nskb;
+}
+
inline static int
qeth_get_initial_mtu_for_card(struct qeth_card * card)
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);
+
#endif /* __QETH_H__ */