1 #include <linux/export.h>
5 /* Calculate expected number of TX descriptors */
6 int tso_count_descs(struct sk_buff
*skb
)
9 return skb_shinfo(skb
)->gso_segs
* 2 + skb_shinfo(skb
)->nr_frags
;
11 EXPORT_SYMBOL(tso_count_descs
);
13 void tso_build_hdr(struct sk_buff
*skb
, char *hdr
, struct tso_t
*tso
,
14 int size
, bool is_last
)
18 int hdr_len
= skb_transport_offset(skb
) + tcp_hdrlen(skb
);
19 int mac_hdr_len
= skb_network_offset(skb
);
21 memcpy(hdr
, skb
->data
, hdr_len
);
22 iph
= (struct iphdr
*)(hdr
+ mac_hdr_len
);
23 iph
->id
= htons(tso
->ip_id
);
24 iph
->tot_len
= htons(size
+ hdr_len
- mac_hdr_len
);
25 tcph
= (struct tcphdr
*)(hdr
+ skb_transport_offset(skb
));
26 tcph
->seq
= htonl(tso
->tcp_seq
);
30 /* Clear all special flags for not last packet */
36 EXPORT_SYMBOL(tso_build_hdr
);
38 void tso_build_data(struct sk_buff
*skb
, struct tso_t
*tso
, int size
)
44 if ((tso
->size
== 0) &&
45 (tso
->next_frag_idx
< skb_shinfo(skb
)->nr_frags
)) {
46 skb_frag_t
*frag
= &skb_shinfo(skb
)->frags
[tso
->next_frag_idx
];
48 /* Move to next segment */
49 tso
->size
= frag
->size
;
50 tso
->data
= page_address(frag
->page
.p
) + frag
->page_offset
;
54 EXPORT_SYMBOL(tso_build_data
);
56 void tso_start(struct sk_buff
*skb
, struct tso_t
*tso
)
58 int hdr_len
= skb_transport_offset(skb
) + tcp_hdrlen(skb
);
60 tso
->ip_id
= ntohs(ip_hdr(skb
)->id
);
61 tso
->tcp_seq
= ntohl(tcp_hdr(skb
)->seq
);
62 tso
->next_frag_idx
= 0;
64 /* Build first data */
65 tso
->size
= skb_headlen(skb
) - hdr_len
;
66 tso
->data
= skb
->data
+ hdr_len
;
67 if ((tso
->size
== 0) &&
68 (tso
->next_frag_idx
< skb_shinfo(skb
)->nr_frags
)) {
69 skb_frag_t
*frag
= &skb_shinfo(skb
)->frags
[tso
->next_frag_idx
];
71 /* Move to next segment */
72 tso
->size
= frag
->size
;
73 tso
->data
= page_address(frag
->page
.p
) + frag
->page_offset
;
77 EXPORT_SYMBOL(tso_start
);