~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/core/tso.c

Version: ~ [ linux-5.15-rc6 ] ~ [ linux-5.14.14 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.75 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.155 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.213 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.252 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.287 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.289 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #include <linux/export.h>
  3 #include <linux/if_vlan.h>
  4 #include <net/ip.h>
  5 #include <net/tso.h>
  6 #include <asm/unaligned.h>
  7 
  8 /* Calculate expected number of TX descriptors */
  9 int tso_count_descs(struct sk_buff *skb)
 10 {
 11         /* The Marvell Way */
 12         return skb_shinfo(skb)->gso_segs * 2 + skb_shinfo(skb)->nr_frags;
 13 }
 14 EXPORT_SYMBOL(tso_count_descs);
 15 
 16 void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso,
 17                    int size, bool is_last)
 18 {
 19         struct tcphdr *tcph;
 20         int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
 21         int mac_hdr_len = skb_network_offset(skb);
 22 
 23         memcpy(hdr, skb->data, hdr_len);
 24         if (!tso->ipv6) {
 25                 struct iphdr *iph = (void *)(hdr + mac_hdr_len);
 26 
 27                 iph->id = htons(tso->ip_id);
 28                 iph->tot_len = htons(size + hdr_len - mac_hdr_len);
 29                 tso->ip_id++;
 30         } else {
 31                 struct ipv6hdr *iph = (void *)(hdr + mac_hdr_len);
 32 
 33                 iph->payload_len = htons(size + tcp_hdrlen(skb));
 34         }
 35         tcph = (struct tcphdr *)(hdr + skb_transport_offset(skb));
 36         put_unaligned_be32(tso->tcp_seq, &tcph->seq);
 37 
 38         if (!is_last) {
 39                 /* Clear all special flags for not last packet */
 40                 tcph->psh = 0;
 41                 tcph->fin = 0;
 42                 tcph->rst = 0;
 43         }
 44 }
 45 EXPORT_SYMBOL(tso_build_hdr);
 46 
 47 void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size)
 48 {
 49         tso->tcp_seq += size;
 50         tso->size -= size;
 51         tso->data += size;
 52 
 53         if ((tso->size == 0) &&
 54             (tso->next_frag_idx < skb_shinfo(skb)->nr_frags)) {
 55                 skb_frag_t *frag = &skb_shinfo(skb)->frags[tso->next_frag_idx];
 56 
 57                 /* Move to next segment */
 58                 tso->size = frag->size;
 59                 tso->data = page_address(frag->page.p) + frag->page_offset;
 60                 tso->next_frag_idx++;
 61         }
 62 }
 63 EXPORT_SYMBOL(tso_build_data);
 64 
 65 void tso_start(struct sk_buff *skb, struct tso_t *tso)
 66 {
 67         int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
 68 
 69         tso->ip_id = ntohs(ip_hdr(skb)->id);
 70         tso->tcp_seq = ntohl(tcp_hdr(skb)->seq);
 71         tso->next_frag_idx = 0;
 72         tso->ipv6 = vlan_get_protocol(skb) == htons(ETH_P_IPV6);
 73 
 74         /* Build first data */
 75         tso->size = skb_headlen(skb) - hdr_len;
 76         tso->data = skb->data + hdr_len;
 77         if ((tso->size == 0) &&
 78             (tso->next_frag_idx < skb_shinfo(skb)->nr_frags)) {
 79                 skb_frag_t *frag = &skb_shinfo(skb)->frags[tso->next_frag_idx];
 80 
 81                 /* Move to next segment */
 82                 tso->size = frag->size;
 83                 tso->data = page_address(frag->page.p) + frag->page_offset;
 84                 tso->next_frag_idx++;
 85         }
 86 }
 87 EXPORT_SYMBOL(tso_start);
 88 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp