1195972f6Sopenharmony_ciFrom af8ac36acb103aa27b498dafa0ae8ba4332faac8 Mon Sep 17 00:00:00 2001
2195972f6Sopenharmony_ciFrom: wu-changsheng <wuchangsheng2@huawei.com>
3195972f6Sopenharmony_ciDate: Sat, 3 Dec 2022 21:38:09 +0800
4195972f6Sopenharmony_ciSubject: [PATCH] add-tso
5195972f6Sopenharmony_ci
6195972f6Sopenharmony_ci---
7195972f6Sopenharmony_ci src/core/ipv4/etharp.c   |  17 +++-
8195972f6Sopenharmony_ci src/core/ipv4/ip4.c      |  10 ++-
9195972f6Sopenharmony_ci src/core/tcp.c           |   6 ++
10195972f6Sopenharmony_ci src/core/tcp_out.c       | 178 +++++++++++++++++++++++++++++++++++++--
11195972f6Sopenharmony_ci src/include/dpdk_cksum.h |   2 +-
12195972f6Sopenharmony_ci src/include/lwip/pbuf.h  |   8 +-
13195972f6Sopenharmony_ci src/include/lwipopts.h   |   4 +
14195972f6Sopenharmony_ci 7 files changed, 211 insertions(+), 14 deletions(-)
15195972f6Sopenharmony_ci
16195972f6Sopenharmony_cidiff --git a/src/core/ipv4/etharp.c b/src/core/ipv4/etharp.c
17195972f6Sopenharmony_ciindex effb7db..f1903e4 100644
18195972f6Sopenharmony_ci--- a/src/core/ipv4/etharp.c
19195972f6Sopenharmony_ci+++ b/src/core/ipv4/etharp.c
20195972f6Sopenharmony_ci@@ -482,6 +482,13 @@ etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct et
21195972f6Sopenharmony_ci     struct pbuf *p = arp_table[i].q;
22195972f6Sopenharmony_ci     arp_table[i].q = NULL;
23195972f6Sopenharmony_ci #endif /* ARP_QUEUEING */
24195972f6Sopenharmony_ci+#if USE_LIBOS
25195972f6Sopenharmony_ci+    struct pbuf *tmp = p->next;
26195972f6Sopenharmony_ci+    while (tmp != NULL) {
27195972f6Sopenharmony_ci+       tmp->ref--;
28195972f6Sopenharmony_ci+       tmp = tmp->next;
29195972f6Sopenharmony_ci+    }
30195972f6Sopenharmony_ci+#endif
31195972f6Sopenharmony_ci     /* send the queued IP packet */
32195972f6Sopenharmony_ci     ethernet_output(netif, p, (struct eth_addr *)(netif->hwaddr), ethaddr, ETHTYPE_IP);
33195972f6Sopenharmony_ci     /* free the queued IP packet */
34195972f6Sopenharmony_ci@@ -1027,7 +1034,15 @@ etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q)
35195972f6Sopenharmony_ci     } else {
36195972f6Sopenharmony_ci       /* referencing the old pbuf is enough */
37195972f6Sopenharmony_ci       p = q;
38195972f6Sopenharmony_ci-      pbuf_ref(p);
39195972f6Sopenharmony_ci+#if USE_LIBOS
40195972f6Sopenharmony_ci+      struct pbuf *tmp = p;
41195972f6Sopenharmony_ci+      while (tmp != NULL) {
42195972f6Sopenharmony_ci+        pbuf_ref(tmp);
43195972f6Sopenharmony_ci+        tmp = tmp->next;
44195972f6Sopenharmony_ci+      }
45195972f6Sopenharmony_ci+#else
46195972f6Sopenharmony_ci+       pbuf_ref(p);
47195972f6Sopenharmony_ci+#endif
48195972f6Sopenharmony_ci     }
49195972f6Sopenharmony_ci     /* packet could be taken over? */
50195972f6Sopenharmony_ci     if (p != NULL) {
51195972f6Sopenharmony_cidiff --git a/src/core/ipv4/ip4.c b/src/core/ipv4/ip4.c
52195972f6Sopenharmony_ciindex 1334cdc..d823491 100644
53195972f6Sopenharmony_ci--- a/src/core/ipv4/ip4.c
54195972f6Sopenharmony_ci+++ b/src/core/ipv4/ip4.c
55195972f6Sopenharmony_ci@@ -1034,9 +1034,15 @@ ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *d
56195972f6Sopenharmony_ci #endif /* ENABLE_LOOPBACK */
57195972f6Sopenharmony_ci #if IP_FRAG
58195972f6Sopenharmony_ci   /* don't fragment if interface has mtu set to 0 [loopif] */
59195972f6Sopenharmony_ci-  if (netif->mtu && (p->tot_len > netif->mtu)) {
60195972f6Sopenharmony_ci-    return ip4_frag(p, netif, dest);
61195972f6Sopenharmony_ci+#if USE_LIBOS
62195972f6Sopenharmony_ci+  if (!(get_eth_params_tx_ol() & DEV_TX_OFFLOAD_TCP_TSO)) {
63195972f6Sopenharmony_ci+#endif
64195972f6Sopenharmony_ci+    if (netif->mtu && (p->tot_len > netif->mtu)) {
65195972f6Sopenharmony_ci+      return ip4_frag(p, netif, dest);
66195972f6Sopenharmony_ci+    }
67195972f6Sopenharmony_ci+#if USE_LIBOS
68195972f6Sopenharmony_ci   }
69195972f6Sopenharmony_ci+#endif
70195972f6Sopenharmony_ci #endif /* IP_FRAG */
71195972f6Sopenharmony_ci 
72195972f6Sopenharmony_ci   LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: call netif->output()\n"));
73195972f6Sopenharmony_cidiff --git a/src/core/tcp.c b/src/core/tcp.c
74195972f6Sopenharmony_ciindex 7c18408..51ada38 100644
75195972f6Sopenharmony_ci--- a/src/core/tcp.c
76195972f6Sopenharmony_ci+++ b/src/core/tcp.c
77195972f6Sopenharmony_ci@@ -1756,7 +1756,9 @@ tcp_seg_free(struct tcp_seg *seg)
78195972f6Sopenharmony_ci       seg->p = NULL;
79195972f6Sopenharmony_ci #endif /* TCP_DEBUG */
80195972f6Sopenharmony_ci     }
81195972f6Sopenharmony_ci+#if !USE_LIBOS
82195972f6Sopenharmony_ci     memp_free(MEMP_TCP_SEG, seg);
83195972f6Sopenharmony_ci+#endif
84195972f6Sopenharmony_ci   }
85195972f6Sopenharmony_ci }
86195972f6Sopenharmony_ci 
87195972f6Sopenharmony_ci@@ -1792,10 +1794,14 @@ tcp_seg_copy(struct tcp_seg *seg)
88195972f6Sopenharmony_ci 
89195972f6Sopenharmony_ci   LWIP_ASSERT("tcp_seg_copy: invalid seg", seg != NULL);
90195972f6Sopenharmony_ci 
91195972f6Sopenharmony_ci+#if USE_LIBOS
92195972f6Sopenharmony_ci+  cseg = (struct tcp_seg *)((uint8_t *)seg->p + sizeof(struct pbuf_custom));
93195972f6Sopenharmony_ci+#else
94195972f6Sopenharmony_ci   cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG);
95195972f6Sopenharmony_ci   if (cseg == NULL) {
96195972f6Sopenharmony_ci     return NULL;
97195972f6Sopenharmony_ci   }
98195972f6Sopenharmony_ci+#endif
99195972f6Sopenharmony_ci   SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg));
100195972f6Sopenharmony_ci   pbuf_ref(cseg->p);
101195972f6Sopenharmony_ci   return cseg;
102195972f6Sopenharmony_cidiff --git a/src/core/tcp_out.c b/src/core/tcp_out.c
103195972f6Sopenharmony_ciindex 2834ba3..ee6f40b 100644
104195972f6Sopenharmony_ci--- a/src/core/tcp_out.c
105195972f6Sopenharmony_ci+++ b/src/core/tcp_out.c
106195972f6Sopenharmony_ci@@ -161,6 +161,40 @@ tcp_route(const struct tcp_pcb *pcb, const ip_addr_t *src, const ip_addr_t *dst)
107195972f6Sopenharmony_ci  * The TCP header is filled in except ackno and wnd.
108195972f6Sopenharmony_ci  * p is freed on failure.
109195972f6Sopenharmony_ci  */
110195972f6Sopenharmony_ci+#if USE_LIBOS
111195972f6Sopenharmony_ci+void tcp_init_segment(struct tcp_seg *seg, const struct tcp_pcb *pcb, struct pbuf *p, u8_t hdrflags,
112195972f6Sopenharmony_ci+  u32_t seqno, u8_t optflags)
113195972f6Sopenharmony_ci+{
114195972f6Sopenharmony_ci+  u8_t optlen = LWIP_TCP_OPT_LENGTH_SEGMENT(optflags, pcb);
115195972f6Sopenharmony_ci+
116195972f6Sopenharmony_ci+  seg->flags = optflags;
117195972f6Sopenharmony_ci+  seg->next = NULL;
118195972f6Sopenharmony_ci+  seg->p = p;
119195972f6Sopenharmony_ci+  seg->len = p->tot_len - optlen;
120195972f6Sopenharmony_ci+
121195972f6Sopenharmony_ci+  /* build TCP header */
122195972f6Sopenharmony_ci+  pbuf_add_header(p, TCP_HLEN);
123195972f6Sopenharmony_ci+  seg->tcphdr = (struct tcp_hdr *)seg->p->payload;
124195972f6Sopenharmony_ci+  seg->tcphdr->src = lwip_htons(pcb->local_port);
125195972f6Sopenharmony_ci+  seg->tcphdr->dest = lwip_htons(pcb->remote_port);
126195972f6Sopenharmony_ci+  seg->tcphdr->seqno = lwip_htonl(seqno);
127195972f6Sopenharmony_ci+
128195972f6Sopenharmony_ci+  TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (TCP_HLEN + optlen) / 4, hdrflags);
129195972f6Sopenharmony_ci+  seg->tcphdr->urgp = 0;
130195972f6Sopenharmony_ci+}
131195972f6Sopenharmony_ci+
132195972f6Sopenharmony_ci+static struct tcp_seg *
133195972f6Sopenharmony_ci+tcp_create_segment(const struct tcp_pcb *pcb, struct pbuf *p, u8_t hdrflags, u32_t seqno, u8_t optflags)
134195972f6Sopenharmony_ci+{
135195972f6Sopenharmony_ci+  struct tcp_seg *seg;
136195972f6Sopenharmony_ci+
137195972f6Sopenharmony_ci+  seg = (struct tcp_seg *)((uint8_t *)p + sizeof(struct pbuf_custom));
138195972f6Sopenharmony_ci+
139195972f6Sopenharmony_ci+  tcp_init_segment(seg, pcb, p, hdrflags, seqno, optflags);  
140195972f6Sopenharmony_ci+
141195972f6Sopenharmony_ci+  return seg;
142195972f6Sopenharmony_ci+}
143195972f6Sopenharmony_ci+#else
144195972f6Sopenharmony_ci static struct tcp_seg *
145195972f6Sopenharmony_ci tcp_create_segment(const struct tcp_pcb *pcb, struct pbuf *p, u8_t hdrflags, u32_t seqno, u8_t optflags)
146195972f6Sopenharmony_ci {
147195972f6Sopenharmony_ci@@ -210,6 +244,7 @@ tcp_create_segment(const struct tcp_pcb *pcb, struct pbuf *p, u8_t hdrflags, u32
148195972f6Sopenharmony_ci   seg->tcphdr->urgp = 0;
149195972f6Sopenharmony_ci   return seg;
150195972f6Sopenharmony_ci }
151195972f6Sopenharmony_ci+#endif
152195972f6Sopenharmony_ci 
153195972f6Sopenharmony_ci /**
154195972f6Sopenharmony_ci  * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end.
155195972f6Sopenharmony_ci@@ -1272,6 +1307,60 @@ tcp_build_wnd_scale_option(u32_t *opts)
156195972f6Sopenharmony_ci }
157195972f6Sopenharmony_ci #endif
158195972f6Sopenharmony_ci 
159195972f6Sopenharmony_ci+#if USE_LIBOS
160195972f6Sopenharmony_ci+static struct tcp_seg *tcp_output_over(struct tcp_pcb *pcb, struct tcp_seg *seg, struct tcp_seg *useg)
161195972f6Sopenharmony_ci+{
162195972f6Sopenharmony_ci+  if (TCP_TCPLEN(seg) > 0) {
163195972f6Sopenharmony_ci+    seg->next = NULL;
164195972f6Sopenharmony_ci+    if (useg == NULL) {
165195972f6Sopenharmony_ci+      pcb->unacked = seg;
166195972f6Sopenharmony_ci+      useg = seg;
167195972f6Sopenharmony_ci+    } else {
168195972f6Sopenharmony_ci+      if (TCP_SEQ_LT(lwip_ntohl(seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) {
169195972f6Sopenharmony_ci+        /* add segment to before tail of unacked list, keeping the list sorted */
170195972f6Sopenharmony_ci+        struct tcp_seg **cur_seg = &(pcb->unacked);
171195972f6Sopenharmony_ci+        while (*cur_seg &&
172195972f6Sopenharmony_ci+              TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) {
173195972f6Sopenharmony_ci+          cur_seg = &((*cur_seg)->next );
174195972f6Sopenharmony_ci+        }
175195972f6Sopenharmony_ci+        seg->next = (*cur_seg);
176195972f6Sopenharmony_ci+        (*cur_seg) = seg;
177195972f6Sopenharmony_ci+      } else {
178195972f6Sopenharmony_ci+        /* add segment to tail of unacked list */
179195972f6Sopenharmony_ci+        useg->next = seg;
180195972f6Sopenharmony_ci+        useg = seg;
181195972f6Sopenharmony_ci+      }
182195972f6Sopenharmony_ci+    }
183195972f6Sopenharmony_ci+  } else {
184195972f6Sopenharmony_ci+    tcp_seg_free(seg);
185195972f6Sopenharmony_ci+  }
186195972f6Sopenharmony_ci+
187195972f6Sopenharmony_ci+  return useg;
188195972f6Sopenharmony_ci+}
189195972f6Sopenharmony_ci+static err_t tcp_output_seg(struct tcp_pcb *pcb, struct tcp_seg *seg, struct netif *netif, u32_t snd_nxt)
190195972f6Sopenharmony_ci+{
191195972f6Sopenharmony_ci+  if (pcb->state != SYN_SENT) {
192195972f6Sopenharmony_ci+    TCPH_SET_FLAG(seg->tcphdr, TCP_ACK);
193195972f6Sopenharmony_ci+  }
194195972f6Sopenharmony_ci+
195195972f6Sopenharmony_ci+  err_t err = tcp_output_segment(seg, pcb, netif);
196195972f6Sopenharmony_ci+  if (err != ERR_OK) {
197195972f6Sopenharmony_ci+    /* segment could not be sent, for whatever reason */
198195972f6Sopenharmony_ci+    tcp_set_flags(pcb, TF_NAGLEMEMERR);
199195972f6Sopenharmony_ci+    return err;
200195972f6Sopenharmony_ci+  }
201195972f6Sopenharmony_ci+
202195972f6Sopenharmony_ci+  if (pcb->state != SYN_SENT) {
203195972f6Sopenharmony_ci+    tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW);
204195972f6Sopenharmony_ci+  }
205195972f6Sopenharmony_ci+
206195972f6Sopenharmony_ci+  if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) {
207195972f6Sopenharmony_ci+      pcb->snd_nxt = snd_nxt;
208195972f6Sopenharmony_ci+  }
209195972f6Sopenharmony_ci+
210195972f6Sopenharmony_ci+  return ERR_OK;
211195972f6Sopenharmony_ci+}
212195972f6Sopenharmony_ci+#endif
213195972f6Sopenharmony_ci /**
214195972f6Sopenharmony_ci  * @ingroup tcp_raw
215195972f6Sopenharmony_ci  * Find out what we can send and send it
216195972f6Sopenharmony_ci@@ -1376,16 +1465,88 @@ tcp_output(struct tcp_pcb *pcb)
217195972f6Sopenharmony_ci     for (; useg->next != NULL; useg = useg->next);
218195972f6Sopenharmony_ci   }
219195972f6Sopenharmony_ci   /* data available and window allows it to be sent? */
220195972f6Sopenharmony_ci+
221195972f6Sopenharmony_ci #if USE_LIBOS
222195972f6Sopenharmony_ci-  /* avoid send cose too much time, limit send pkts num max 10 */
223195972f6Sopenharmony_ci-  uint16_t send_pkt = 0;
224195972f6Sopenharmony_ci-  while (seg != NULL && send_pkt < 10 &&
225195972f6Sopenharmony_ci-         lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
226195972f6Sopenharmony_ci-    send_pkt++;
227195972f6Sopenharmony_ci-#else
228195972f6Sopenharmony_ci+  if (get_eth_params_tx_ol() & DEV_TX_OFFLOAD_TCP_TSO) {
229195972f6Sopenharmony_ci+    while(seg) {
230195972f6Sopenharmony_ci+      /**
231195972f6Sopenharmony_ci+       * 1)遍历unsent队列,找到所有的待发送seg. 将seg的buf串起来
232195972f6Sopenharmony_ci+       * 2) 生成新的seg, 调用tcp_output_segment, 新的seg释放掉
233195972f6Sopenharmony_ci+       * 3) 若成功,则更新snd_nxt, unacked队列,和unsent队列。 
234195972f6Sopenharmony_ci+       */
235195972f6Sopenharmony_ci+      struct tcp_seg *start_seg = seg;
236195972f6Sopenharmony_ci+      struct pbuf *first_pbuf = NULL;
237195972f6Sopenharmony_ci+      struct pbuf *pre_pbuf = NULL;
238195972f6Sopenharmony_ci+      u8_t pbuf_chain_len = 0;
239195972f6Sopenharmony_ci+      u32_t next_seqno = lwip_ntohl(seg->tcphdr->seqno);
240195972f6Sopenharmony_ci+      while (seg != NULL && pbuf_chain_len < MAX_PBUF_CHAIN_LEN) {
241195972f6Sopenharmony_ci+        u32_t seg_seqno = lwip_ntohl(seg->tcphdr->seqno);
242195972f6Sopenharmony_ci+        if (seg_seqno - pcb->lastack + seg->len > wnd) {
243195972f6Sopenharmony_ci+          if (first_pbuf)
244195972f6Sopenharmony_ci+            break;
245195972f6Sopenharmony_ci+          else
246195972f6Sopenharmony_ci+            goto output_done;
247195972f6Sopenharmony_ci+        }
248195972f6Sopenharmony_ci+
249195972f6Sopenharmony_ci+        if ((tcp_do_output_nagle(pcb) == 0) && ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)) {
250195972f6Sopenharmony_ci+          if (first_pbuf)
251195972f6Sopenharmony_ci+            break;
252195972f6Sopenharmony_ci+          else
253195972f6Sopenharmony_ci+            goto output_done;
254195972f6Sopenharmony_ci+        }
255195972f6Sopenharmony_ci+
256195972f6Sopenharmony_ci+        if (seg->len < TCP_MSS || next_seqno != seg_seqno || pbuf_chain_len >= MAX_PBUF_CHAIN_LEN) {
257195972f6Sopenharmony_ci+          break;
258195972f6Sopenharmony_ci+        }
259195972f6Sopenharmony_ci+        if (first_pbuf == NULL && (seg->next == NULL || seg->next->len < TCP_MSS)) {
260195972f6Sopenharmony_ci+          break;
261195972f6Sopenharmony_ci+        }
262195972f6Sopenharmony_ci+
263195972f6Sopenharmony_ci+        pbuf_remove_header(seg->p, seg->p->tot_len - seg->len);
264195972f6Sopenharmony_ci+        if (first_pbuf == NULL) {
265195972f6Sopenharmony_ci+          first_pbuf = seg->p;
266195972f6Sopenharmony_ci+        } else {
267195972f6Sopenharmony_ci+          first_pbuf->tot_len += seg->p->len;
268195972f6Sopenharmony_ci+          pre_pbuf->next = seg->p;
269195972f6Sopenharmony_ci+        }
270195972f6Sopenharmony_ci+
271195972f6Sopenharmony_ci+        pre_pbuf = seg->p;
272195972f6Sopenharmony_ci+        next_seqno = seg_seqno + TCP_TCPLEN(seg);
273195972f6Sopenharmony_ci+        seg = seg->next;
274195972f6Sopenharmony_ci+        pcb->unsent = seg;
275195972f6Sopenharmony_ci+        pbuf_chain_len++;
276195972f6Sopenharmony_ci+      }
277195972f6Sopenharmony_ci+
278195972f6Sopenharmony_ci+      if (first_pbuf == NULL) {
279195972f6Sopenharmony_ci+        err = tcp_output_seg(pcb, seg, netif, next_seqno + seg->len);
280195972f6Sopenharmony_ci+        if (err != ERR_OK)
281195972f6Sopenharmony_ci+          return err;
282195972f6Sopenharmony_ci+        pcb->unsent = seg->next;
283195972f6Sopenharmony_ci+        useg = tcp_output_over(pcb, seg, useg);
284195972f6Sopenharmony_ci+        seg = pcb->unsent;
285195972f6Sopenharmony_ci+        continue;
286195972f6Sopenharmony_ci+      }
287195972f6Sopenharmony_ci+
288195972f6Sopenharmony_ci+      struct tcp_seg new_seg;
289195972f6Sopenharmony_ci+      tcp_init_segment(&new_seg, pcb, first_pbuf, 0, lwip_ntohl(start_seg->tcphdr->seqno), 0);
290195972f6Sopenharmony_ci+
291195972f6Sopenharmony_ci+      err = tcp_output_seg(pcb, &new_seg, netif, next_seqno);
292195972f6Sopenharmony_ci+
293195972f6Sopenharmony_ci+      for (u32_t i = 0; i < pbuf_chain_len; i++) {
294195972f6Sopenharmony_ci+        struct tcp_seg *next_seg = start_seg->next;
295195972f6Sopenharmony_ci+        start_seg->p->next = NULL;
296195972f6Sopenharmony_ci+        useg = tcp_output_over(pcb, start_seg, useg);
297195972f6Sopenharmony_ci+        start_seg = next_seg;
298195972f6Sopenharmony_ci+      }
299195972f6Sopenharmony_ci+
300195972f6Sopenharmony_ci+      pbuf_remove_header(new_seg.p, new_seg.p->tot_len - new_seg.len - TCPH_HDRLEN_BYTES(new_seg.tcphdr));
301195972f6Sopenharmony_ci+      new_seg.p->tot_len = new_seg.p->len;
302195972f6Sopenharmony_ci+    }
303195972f6Sopenharmony_ci+  } else
304195972f6Sopenharmony_ci+#endif
305195972f6Sopenharmony_ci+{
306195972f6Sopenharmony_ci   while (seg != NULL &&
307195972f6Sopenharmony_ci          lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {
308195972f6Sopenharmony_ci-#endif
309195972f6Sopenharmony_ci     LWIP_ASSERT("RST not expected here!",
310195972f6Sopenharmony_ci                 (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0);
311195972f6Sopenharmony_ci     /* Stop sending if the nagle algorithm would prevent it
312195972f6Sopenharmony_ci@@ -1462,6 +1623,7 @@ tcp_output(struct tcp_pcb *pcb)
313195972f6Sopenharmony_ci     }
314195972f6Sopenharmony_ci     seg = pcb->unsent;
315195972f6Sopenharmony_ci   }
316195972f6Sopenharmony_ci+}
317195972f6Sopenharmony_ci #if TCP_OVERSIZE
318195972f6Sopenharmony_ci   if (pcb->unsent == NULL) {
319195972f6Sopenharmony_ci     /* last unsent has been removed, reset unsent_oversize */
320195972f6Sopenharmony_ci@@ -1627,7 +1789,7 @@ tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif
321195972f6Sopenharmony_ci   IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) {
322195972f6Sopenharmony_ci #if CHECKSUM_GEN_TCP_HW
323195972f6Sopenharmony_ci   if (get_eth_params_tx_ol() & DEV_TX_OFFLOAD_TCP_CKSUM) {
324195972f6Sopenharmony_ci-    tcph_cksum_set(seg->p, TCP_HLEN);
325195972f6Sopenharmony_ci+    tcph_cksum_set(seg->p, TCPH_HDRLEN_BYTES(seg->tcphdr));
326195972f6Sopenharmony_ci     seg->tcphdr->chksum = ip_chksum_pseudo_offload(IP_PROTO_TCP,seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip);
327195972f6Sopenharmony_ci   } else {
328195972f6Sopenharmony_ci #if TCP_CHECKSUM_ON_COPY
329195972f6Sopenharmony_cidiff --git a/src/include/dpdk_cksum.h b/src/include/dpdk_cksum.h
330195972f6Sopenharmony_ciindex e57be4d..83c9c38 100644
331195972f6Sopenharmony_ci--- a/src/include/dpdk_cksum.h
332195972f6Sopenharmony_ci+++ b/src/include/dpdk_cksum.h
333195972f6Sopenharmony_ci@@ -78,7 +78,7 @@ static inline void iph_cksum_set(struct pbuf *p, u16_t len, bool do_ipcksum) {
334195972f6Sopenharmony_ci #include <rte_ip.h>
335195972f6Sopenharmony_ci 
336195972f6Sopenharmony_ci static inline void tcph_cksum_set(struct pbuf *p, u16_t len) {
337195972f6Sopenharmony_ci-    (void)len;
338195972f6Sopenharmony_ci+    p->l4_len = len;
339195972f6Sopenharmony_ci     p->ol_flags |= RTE_MBUF_F_TX_TCP_CKSUM;
340195972f6Sopenharmony_ci }
341195972f6Sopenharmony_ci 
342195972f6Sopenharmony_cidiff --git a/src/include/lwip/pbuf.h b/src/include/lwip/pbuf.h
343195972f6Sopenharmony_ciindex 87cd960..ef879da 100644
344195972f6Sopenharmony_ci--- a/src/include/lwip/pbuf.h
345195972f6Sopenharmony_ci+++ b/src/include/lwip/pbuf.h
346195972f6Sopenharmony_ci@@ -223,10 +223,14 @@ struct pbuf {
347195972f6Sopenharmony_ci #if USE_LIBOS && CHECKSUM_OFFLOAD_ALL
348195972f6Sopenharmony_ci   /** checksum offload ol_flags */
349195972f6Sopenharmony_ci   u64_t ol_flags;
350195972f6Sopenharmony_ci-  /** checksum offload l2_len */
351195972f6Sopenharmony_ci+  /* < L2 (MAC) Header Length for non-tunneling pkt. */
352195972f6Sopenharmony_ci   u64_t l2_len:7;
353195972f6Sopenharmony_ci-  /** checksum offload l3_len */
354195972f6Sopenharmony_ci+  /* < L3 (IP) Header Length. */
355195972f6Sopenharmony_ci   u64_t l3_len:9;
356195972f6Sopenharmony_ci+  /* < L4 (TCP/UDP) Header Length. */
357195972f6Sopenharmony_ci+  u64_t l4_len:8;
358195972f6Sopenharmony_ci+  u16_t header_off;
359195972f6Sopenharmony_ci+  u8_t rexmit;
360195972f6Sopenharmony_ci #endif /* USE_LIBOS CHECKSUM_OFFLOAD_SWITCH */
361195972f6Sopenharmony_ci 
362195972f6Sopenharmony_ci   /** In case the user needs to store data custom data on a pbuf */
363195972f6Sopenharmony_cidiff --git a/src/include/lwipopts.h b/src/include/lwipopts.h
364195972f6Sopenharmony_ciindex a5add21..7c819d0 100644
365195972f6Sopenharmony_ci--- a/src/include/lwipopts.h
366195972f6Sopenharmony_ci+++ b/src/include/lwipopts.h
367195972f6Sopenharmony_ci@@ -173,6 +173,10 @@
368195972f6Sopenharmony_ci 
369195972f6Sopenharmony_ci #define ARP_QUEUE_LEN 32
370195972f6Sopenharmony_ci 
371195972f6Sopenharmony_ci+#define MAX_PBUF_CHAIN_LEN 40
372195972f6Sopenharmony_ci+
373195972f6Sopenharmony_ci+#define MIN_TSO_SEG_LEN 256
374195972f6Sopenharmony_ci+
375195972f6Sopenharmony_ci /*  ---------------------------------------
376195972f6Sopenharmony_ci  *  -------      NIC offloads      --------
377195972f6Sopenharmony_ci  *  ---------------------------------------
378195972f6Sopenharmony_ci-- 
379195972f6Sopenharmony_ci2.23.0
380195972f6Sopenharmony_ci
381