diff options
author | Frank Pavlic <pavlic@de.ibm.com> | 2005-05-12 14:37:53 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-05-15 18:06:17 -0400 |
commit | d801145d910cc4a0fb418dda1dee227cec993cbd (patch) | |
tree | 423eda6277d89e89348907e185a49523debb0389 /drivers/s390/net/qeth_tso.h | |
parent | 5e39f2933f6707fc824b5e419dcac8ced67a57b6 (diff) |
[PATCH] s390: qeth bug fixes
[patch 7/10] s390: qeth bug fixes.
From: Frank Pavlic <pavlic@de.ibm.com>
qeth network driver changes:
- Removed redundant code, use the same qeth_fill_buffer_frag
for TSO path either
- Using skb->frags solely is not correct since skb->data still
points to the beginning of the whole data, even when it is
a small portion we have to fill the qdio buffer with it.
Signed-off-by: Frank Pavlic <pavlic@de.ibm.com>
Diffstat (limited to 'drivers/s390/net/qeth_tso.h')
-rw-r--r-- | drivers/s390/net/qeth_tso.h | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/drivers/s390/net/qeth_tso.h b/drivers/s390/net/qeth_tso.h index 83504dee3f57..ff585ae49b6c 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 | |||
41 | static inline int | 40 | static inline int |
42 | qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb) | 41 | qeth_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 | |||
58 | static 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__ */ |