X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fs390%2Fnet%2Fqeth.h;h=a755b57db46b359c9cb632919fc71ef7fd9c52fd;hb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;hp=96c4243a2c798ffccb63994416fc7b7422908bbf;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index 96c4243a2..a755b57db 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h @@ -15,7 +15,8 @@ #include -#include +#include + #include #include #include @@ -23,7 +24,7 @@ #include "qeth_mpc.h" -#define VERSION_QETH_H "$Revision: 1.110 $" +#define VERSION_QETH_H "$Revision: 1.139 $" #ifdef CONFIG_QETH_IPV6 #define QETH_VERSION_IPV6 ":IPv6" @@ -43,7 +44,7 @@ #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 @@ -61,13 +62,14 @@ #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 +extern debug_info_t *qeth_dbf_trace; #define QETH_DBF_SENSE_NAME "qeth_sense" #define QETH_DBF_SENSE_LEN 64 @@ -91,7 +93,7 @@ debug_event(qeth_dbf_##name,level,(void*)(addr),len); \ } while (0) -extern DEFINE_PER_CPU(char[256], qeth_dbf_txt_buf); +DECLARE_PER_CPU(char[256], qeth_dbf_txt_buf); #define QETH_DBF_TEXT_(name,level,text...) \ do { \ @@ -150,6 +152,8 @@ qeth_hex_dump(unsigned char *buf, size_t len) #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 */ @@ -203,6 +207,11 @@ struct qeth_perf_stats { __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; }; #endif /* CONFIG_QETH_PERF_STATS */ @@ -279,7 +288,8 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) #define QETH_TX_TIMEOUT 100 * HZ #define QETH_HEADER_SIZE 32 #define MAX_PORTNO 15 -#define QETH_FAKE_LL_LEN ETH_HLEN +#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*/ @@ -327,16 +337,12 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func) #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; - __u32 token; + __u16 inbound_checksum; /*TSO:__u16 seqno */ + __u32 token; /*TSO: __u32 reserved */ __u16 length; __u8 vlan_prio; __u8 ext_flags; @@ -345,6 +351,45 @@ struct qeth_hdr { __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)); + +/*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 @@ -357,11 +402,26 @@ enum qeth_cast_flags { 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, +}; /* 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 +#define QETH_HDR_EXT_UDP_TSO 0x40 /*bit off for TCP*/ static inline int qeth_is_last_sbale(struct qdio_buffer_element *sbale) @@ -416,21 +476,35 @@ struct qeth_qdio_q { 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; - spinlock_t lock; + atomic_t state; volatile int do_pack; /* * index of buffer to be filled by driver; state EMPTY or PACKING @@ -517,6 +591,7 @@ 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 { @@ -610,14 +685,14 @@ struct qeth_seqno { __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; @@ -629,14 +704,22 @@ struct qeth_reply { #define QETH_BROADCAST_WITH_ECHO 1 #define QETH_BROADCAST_WITHOUT_ECHO 2 +struct qeth_card_blkt { + int time_total; + int inter_packet; + int inter_packet_jumbo; +}; + + + struct qeth_card_info { - char if_name[IF_NAME_LEN]; 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]; @@ -647,6 +730,7 @@ struct qeth_card_info { int max_mtu; int broadcast_capable; int unique_id; + struct qeth_card_blkt blkt; __u32 csum_mask; }; @@ -664,6 +748,8 @@ struct qeth_card_options { int fake_broadcast; int add_hhlen; int fake_ll; + int layer2; + enum qeth_large_send_types large_send; }; /* @@ -671,8 +757,7 @@ struct qeth_card_options { */ enum qeth_threads { QETH_SET_IP_THREAD = 1, - QETH_SET_MC_THREAD = 2, - QETH_RECOVER_THREAD = 4, + QETH_RECOVER_THREAD = 2, }; struct qeth_card { @@ -706,7 +791,7 @@ 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 */ @@ -715,6 +800,8 @@ struct qeth_card { 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 { @@ -735,6 +822,8 @@ 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) { @@ -746,6 +835,58 @@ qeth_get_ipa_adp_type(enum qeth_link_types link_type) } } +inline static int +qeth_realloc_headroom(struct qeth_card *card, struct sk_buff **skb, int size) +{ + struct sk_buff *new_skb = NULL; + + if (skb_headroom(*skb) < size){ + new_skb = skb_realloc_headroom(*skb, size); + if (!new_skb) { + PRINT_ERR("qeth_prepare_skb: could " + "not realloc headroom for qeth_hdr " + "on interface %s", QETH_CARD_IFNAME(card)); + return -ENOMEM; + } + *skb = new_skb; + } + return 0; +} +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 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("qeth_prepare_skb: misaligned " + "packet on interface %s. Discarded.", + QETH_CARD_IFNAME(card)); + return NULL; + } + return hdr; +} + + inline static int qeth_get_hlen(__u8 link_type) { @@ -753,27 +894,29 @@ qeth_get_hlen(__u8 link_type) switch (link_type) { case QETH_LINK_TYPE_HSTR: case QETH_LINK_TYPE_LANE_TR: - return sizeof(struct qeth_hdr) + TR_HLEN; + return sizeof(struct qeth_hdr_tso) + TR_HLEN; default: #ifdef CONFIG_QETH_VLAN - return sizeof(struct qeth_hdr) + VLAN_ETH_HLEN; + return sizeof(struct qeth_hdr_tso) + VLAN_ETH_HLEN; #else - return sizeof(struct qeth_hdr) + ETH_HLEN; + return sizeof(struct qeth_hdr_tso) + ETH_HLEN; #endif } #else /* CONFIG_QETH_IPV6 */ #ifdef CONFIG_QETH_VLAN - return sizeof(struct qeth_hdr) + VLAN_HLEN; + return sizeof(struct qeth_hdr_tso) + VLAN_HLEN; #else - return sizeof(struct qeth_hdr); + return sizeof(struct qeth_hdr_tso); #endif #endif /* CONFIG_QETH_IPV6 */ } 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 @@ -1027,4 +1170,14 @@ 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 *); + +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); + #endif /* __QETH_H__ */