aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/net/qeth_tso.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/net/qeth_tso.h')
-rw-r--r--drivers/s390/net/qeth_tso.h71
1 files changed, 58 insertions, 13 deletions
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h
index 83504dee3f5..ff585ae49b6 100644
--- a/drivers/s390/net/qeth_tso.h
+++ b/drivers/s390/net/qeth_tso.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.4 $) 2 * linux/drivers/s390/net/qeth_tso.h ($Revision: 1.5 $)
3 * 3 *
4 * Header file for qeth TCP Segmentation Offload support. 4 * Header file for qeth TCP Segmentation Offload support.
5 * 5 *
@@ -7,7 +7,7 @@
7 * 7 *
8 * Author(s): Frank Pavlic <pavlic@de.ibm.com> 8 * Author(s): Frank Pavlic <pavlic@de.ibm.com>
9 * 9 *
10 * $Revision: 1.4 $ $Date: 2005/03/24 09:04:18 $ 10 * $Revision: 1.5 $ $Date: 2005/04/01 21:40:41 $
11 * 11 *
12 */ 12 */
13#ifndef __QETH_TSO_H__ 13#ifndef __QETH_TSO_H__
@@ -37,22 +37,67 @@ struct qeth_hdr_tso {
37} __attribute__ ((packed)); 37} __attribute__ ((packed));
38 38
39/*some helper functions*/ 39/*some helper functions*/
40
41static inline int 40static inline int
42qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) 41qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb)
43{ 42{
44 int elements_needed = 0; 43 int elements_needed = 0;
45 44
46 if (skb_shinfo(skb)->nr_frags > 0) 45 if (skb_shinfo(skb)->nr_frags > 0)
47 elements_needed = (skb_shinfo(skb)->nr_frags + 1); 46 elements_needed = (skb_shinfo(skb)->nr_frags + 1);
48 if (elements_needed == 0 ) 47 if (elements_needed == 0 )
49 elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) 48 elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE)
50 + skb->len) >> PAGE_SHIFT); 49 + skb->len) >> PAGE_SHIFT);
51 if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){ 50 if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){
52 PRINT_ERR("qeth_do_send_packet: invalid size of " 51 PRINT_ERR("qeth_do_send_packet: invalid size of "
53 "IP packet. Discarded."); 52 "IP packet. Discarded.");
54 return 0; 53 return 0;
54 }
55 return elements_needed;
56}
57
58static inline void
59__qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer,
60 int is_tso, int *next_element_to_fill)
61{
62 int length = skb->len;
63 struct skb_frag_struct *frag;
64 int fragno;
65 unsigned long addr;
66 int element;
67 int first_lap = 1;
68
69 fragno = skb_shinfo(skb)->nr_frags; /* start with last frag */
70 element = *next_element_to_fill + fragno;
71 while (length > 0) {
72 if (fragno > 0) {
73 frag = &skb_shinfo(skb)->frags[fragno - 1];
74 addr = (page_to_pfn(frag->page) << PAGE_SHIFT) +
75 frag->page_offset;
76 buffer->element[element].addr = (char *)addr;
77 buffer->element[element].length = frag->size;
78 length -= frag->size;
79 if (first_lap)
80 buffer->element[element].flags =
81 SBAL_FLAGS_LAST_FRAG;
82 else
83 buffer->element[element].flags =
84 SBAL_FLAGS_MIDDLE_FRAG;
85 } else {
86 buffer->element[element].addr = skb->data;
87 buffer->element[element].length = length;
88 length = 0;
89 if (is_tso)
90 buffer->element[element].flags =
91 SBAL_FLAGS_MIDDLE_FRAG;
92 else
93 buffer->element[element].flags =
94 SBAL_FLAGS_FIRST_FRAG;
95 }
96 element--;
97 fragno--;
98 first_lap = 0;
55 } 99 }
56 return elements_needed; 100 *next_element_to_fill += skb_shinfo(skb)->nr_frags + 1;
57} 101}
102
58#endif /* __QETH_TSO_H__ */ 103#endif /* __QETH_TSO_H__ */