qeth_tso.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * linux/drivers/s390/net/qeth_tso.h
  3. *
  4. * Header file for qeth TCP Segmentation Offload support.
  5. *
  6. * Copyright 2004 IBM Corporation
  7. *
  8. * Author(s): Frank Pavlic <fpavlic@de.ibm.com>
  9. *
  10. */
  11. #ifndef __QETH_TSO_H__
  12. #define __QETH_TSO_H__
  13. #include <linux/skbuff.h>
  14. #include <linux/tcp.h>
  15. #include <linux/ip.h>
  16. #include <linux/ipv6.h>
  17. #include <net/ip6_checksum.h>
  18. #include "qeth.h"
  19. #include "qeth_mpc.h"
  20. static inline struct qeth_hdr_tso *
  21. qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb)
  22. {
  23. QETH_DBF_TEXT(trace, 5, "tsoprsk");
  24. return qeth_push_skb(card, skb, sizeof(struct qeth_hdr_tso));
  25. }
  26. /**
  27. * fill header for a TSO packet
  28. */
  29. static inline void
  30. qeth_tso_fill_header(struct qeth_card *card, struct sk_buff *skb)
  31. {
  32. struct qeth_hdr_tso *hdr;
  33. struct tcphdr *tcph;
  34. struct iphdr *iph;
  35. QETH_DBF_TEXT(trace, 5, "tsofhdr");
  36. hdr = (struct qeth_hdr_tso *) skb->data;
  37. iph = skb->nh.iph;
  38. tcph = skb->h.th;
  39. /*fix header to TSO values ...*/
  40. hdr->hdr.hdr.l3.id = QETH_HEADER_TYPE_TSO;
  41. /*set values which are fix for the first approach ...*/
  42. hdr->ext.hdr_tot_len = (__u16) sizeof(struct qeth_hdr_ext_tso);
  43. hdr->ext.imb_hdr_no = 1;
  44. hdr->ext.hdr_type = 1;
  45. hdr->ext.hdr_version = 1;
  46. hdr->ext.hdr_len = 28;
  47. /*insert non-fix values */
  48. hdr->ext.mss = skb_shinfo(skb)->tso_size;
  49. hdr->ext.dg_hdr_len = (__u16)(iph->ihl*4 + tcph->doff*4);
  50. hdr->ext.payload_len = (__u16)(skb->len - hdr->ext.dg_hdr_len -
  51. sizeof(struct qeth_hdr_tso));
  52. }
  53. /**
  54. * change some header values as requested by hardware
  55. */
  56. static inline void
  57. qeth_tso_set_tcpip_header(struct qeth_card *card, struct sk_buff *skb)
  58. {
  59. struct iphdr *iph;
  60. struct ipv6hdr *ip6h;
  61. struct tcphdr *tcph;
  62. iph = skb->nh.iph;
  63. ip6h = skb->nh.ipv6h;
  64. tcph = skb->h.th;
  65. tcph->check = 0;
  66. if (skb->protocol == ETH_P_IPV6) {
  67. ip6h->payload_len = 0;
  68. tcph->check = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
  69. 0, IPPROTO_TCP, 0);
  70. return;
  71. }
  72. /*OSA want us to set these values ...*/
  73. tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
  74. 0, IPPROTO_TCP, 0);
  75. iph->tot_len = 0;
  76. iph->check = 0;
  77. }
  78. static inline int
  79. qeth_tso_prepare_packet(struct qeth_card *card, struct sk_buff *skb,
  80. int ipv, int cast_type)
  81. {
  82. struct qeth_hdr_tso *hdr;
  83. QETH_DBF_TEXT(trace, 5, "tsoprep");
  84. hdr = (struct qeth_hdr_tso *) qeth_tso_prepare_skb(card, &skb);
  85. if (hdr == NULL) {
  86. QETH_DBF_TEXT(trace, 4, "tsoperr");
  87. return -ENOMEM;
  88. }
  89. memset(hdr, 0, sizeof(struct qeth_hdr_tso));
  90. /*fill first 32 bytes of qdio header as used
  91. *FIXME: TSO has two struct members
  92. * with different names but same size
  93. * */
  94. qeth_fill_header(card, &hdr->hdr, skb, ipv, cast_type);
  95. qeth_tso_fill_header(card, skb);
  96. qeth_tso_set_tcpip_header(card, skb);
  97. return 0;
  98. }
  99. static inline void
  100. __qeth_fill_buffer_frag(struct sk_buff *skb, struct qdio_buffer *buffer,
  101. int is_tso, int *next_element_to_fill)
  102. {
  103. struct skb_frag_struct *frag;
  104. int fragno;
  105. unsigned long addr;
  106. int element, cnt, dlen;
  107. fragno = skb_shinfo(skb)->nr_frags;
  108. element = *next_element_to_fill;
  109. dlen = 0;
  110. if (is_tso)
  111. buffer->element[element].flags =
  112. SBAL_FLAGS_MIDDLE_FRAG;
  113. else
  114. buffer->element[element].flags =
  115. SBAL_FLAGS_FIRST_FRAG;
  116. if ( (dlen = (skb->len - skb->data_len)) ) {
  117. buffer->element[element].addr = skb->data;
  118. buffer->element[element].length = dlen;
  119. element++;
  120. }
  121. for (cnt = 0; cnt < fragno; cnt++) {
  122. frag = &skb_shinfo(skb)->frags[cnt];
  123. addr = (page_to_pfn(frag->page) << PAGE_SHIFT) +
  124. frag->page_offset;
  125. buffer->element[element].addr = (char *)addr;
  126. buffer->element[element].length = frag->size;
  127. if (cnt < (fragno - 1))
  128. buffer->element[element].flags =
  129. SBAL_FLAGS_MIDDLE_FRAG;
  130. else
  131. buffer->element[element].flags =
  132. SBAL_FLAGS_LAST_FRAG;
  133. element++;
  134. }
  135. *next_element_to_fill = element;
  136. }
  137. #endif /* __QETH_TSO_H__ */