net/af_xdp: support unaligned umem chunks
[dpdk.git] / drivers / net / octeontx2 / otx2_tx.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #ifndef __OTX2_TX_H__
6 #define __OTX2_TX_H__
7
8 #define NIX_TX_OFFLOAD_NONE             (0)
9 #define NIX_TX_OFFLOAD_L3_L4_CSUM_F     BIT(0)
10 #define NIX_TX_OFFLOAD_OL3_OL4_CSUM_F   BIT(1)
11 #define NIX_TX_OFFLOAD_VLAN_QINQ_F      BIT(2)
12 #define NIX_TX_OFFLOAD_MBUF_NOFF_F      BIT(3)
13 #define NIX_TX_OFFLOAD_TSTAMP_F         BIT(4)
14 #define NIX_TX_OFFLOAD_TSO_F            BIT(5)
15
16 /* Flags to control xmit_prepare function.
17  * Defining it from backwards to denote its been
18  * not used as offload flags to pick function
19  */
20 #define NIX_TX_MULTI_SEG_F              BIT(15)
21
22 #define NIX_TX_NEED_SEND_HDR_W1 \
23         (NIX_TX_OFFLOAD_L3_L4_CSUM_F | NIX_TX_OFFLOAD_OL3_OL4_CSUM_F |  \
24          NIX_TX_OFFLOAD_VLAN_QINQ_F | NIX_TX_OFFLOAD_TSO_F)
25
26 #define NIX_TX_NEED_EXT_HDR \
27         (NIX_TX_OFFLOAD_VLAN_QINQ_F | NIX_TX_OFFLOAD_TSTAMP_F | \
28          NIX_TX_OFFLOAD_TSO_F)
29
30 #define NIX_UDP_TUN_BITMASK \
31         ((1ull << (PKT_TX_TUNNEL_VXLAN >> 45)) | \
32          (1ull << (PKT_TX_TUNNEL_GENEVE >> 45)))
33
34 #define NIX_LSO_FORMAT_IDX_TSOV4        (0)
35 #define NIX_LSO_FORMAT_IDX_TSOV6        (1)
36
37 /* Function to determine no of tx subdesc required in case ext
38  * sub desc is enabled.
39  */
40 static __rte_always_inline int
41 otx2_nix_tx_ext_subs(const uint16_t flags)
42 {
43         return (flags & NIX_TX_OFFLOAD_TSTAMP_F) ? 2 :
44                 ((flags & (NIX_TX_OFFLOAD_VLAN_QINQ_F | NIX_TX_OFFLOAD_TSO_F)) ?
45                  1 : 0);
46 }
47
48 static __rte_always_inline void
49 otx2_nix_xmit_prepare_tstamp(uint64_t *cmd,  const uint64_t *send_mem_desc,
50                              const uint64_t ol_flags, const uint16_t no_segdw,
51                              const uint16_t flags)
52 {
53         if (flags & NIX_TX_OFFLOAD_TSTAMP_F) {
54                 struct nix_send_mem_s *send_mem;
55                 uint16_t off = (no_segdw - 1) << 1;
56                 const uint8_t is_ol_tstamp = !(ol_flags & PKT_TX_IEEE1588_TMST);
57
58                 send_mem = (struct nix_send_mem_s *)(cmd + off);
59                 if (flags & NIX_TX_MULTI_SEG_F) {
60                         /* Retrieving the default desc values */
61                         cmd[off] = send_mem_desc[6];
62
63                         /* Using compiler barier to avoid voilation of C
64                          * aliasing rules.
65                          */
66                         rte_compiler_barrier();
67                 }
68
69                 /* Packets for which PKT_TX_IEEE1588_TMST is not set, tx tstamp
70                  * should not be recorded, hence changing the alg type to
71                  * NIX_SENDMEMALG_SET and also changing send mem addr field to
72                  * next 8 bytes as it corrpt the actual tx tstamp registered
73                  * address.
74                  */
75                 send_mem->alg = NIX_SENDMEMALG_SETTSTMP - (is_ol_tstamp);
76
77                 send_mem->addr = (rte_iova_t)((uint64_t *)send_mem_desc[7] +
78                                               (is_ol_tstamp));
79         }
80 }
81
82 static __rte_always_inline uint64_t
83 otx2_pktmbuf_detach(struct rte_mbuf *m)
84 {
85         struct rte_mempool *mp = m->pool;
86         uint32_t mbuf_size, buf_len;
87         struct rte_mbuf *md;
88         uint16_t priv_size;
89         uint16_t refcount;
90
91         /* Update refcount of direct mbuf */
92         md = rte_mbuf_from_indirect(m);
93         refcount = rte_mbuf_refcnt_update(md, -1);
94
95         priv_size = rte_pktmbuf_priv_size(mp);
96         mbuf_size = (uint32_t)(sizeof(struct rte_mbuf) + priv_size);
97         buf_len = rte_pktmbuf_data_room_size(mp);
98
99         m->priv_size = priv_size;
100         m->buf_addr = (char *)m + mbuf_size;
101         m->buf_iova = rte_mempool_virt2iova(m) + mbuf_size;
102         m->buf_len = (uint16_t)buf_len;
103         rte_pktmbuf_reset_headroom(m);
104         m->data_len = 0;
105         m->ol_flags = 0;
106         m->next = NULL;
107         m->nb_segs = 1;
108
109         /* Now indirect mbuf is safe to free */
110         rte_pktmbuf_free(m);
111
112         if (refcount == 0) {
113                 rte_mbuf_refcnt_set(md, 1);
114                 md->data_len = 0;
115                 md->ol_flags = 0;
116                 md->next = NULL;
117                 md->nb_segs = 1;
118                 return 0;
119         } else {
120                 return 1;
121         }
122 }
123
124 static __rte_always_inline uint64_t
125 otx2_nix_prefree_seg(struct rte_mbuf *m)
126 {
127         if (likely(rte_mbuf_refcnt_read(m) == 1)) {
128                 if (!RTE_MBUF_DIRECT(m))
129                         return otx2_pktmbuf_detach(m);
130
131                 m->next = NULL;
132                 m->nb_segs = 1;
133                 return 0;
134         } else if (rte_mbuf_refcnt_update(m, -1) == 0) {
135                 if (!RTE_MBUF_DIRECT(m))
136                         return otx2_pktmbuf_detach(m);
137
138                 rte_mbuf_refcnt_set(m, 1);
139                 m->next = NULL;
140                 m->nb_segs = 1;
141                 return 0;
142         }
143
144         /* Mbuf is having refcount more than 1 so need not to be freed */
145         return 1;
146 }
147
148 static __rte_always_inline void
149 otx2_nix_xmit_prepare_tso(struct rte_mbuf *m, const uint64_t flags)
150 {
151         uint64_t mask, ol_flags = m->ol_flags;
152
153         if (flags & NIX_TX_OFFLOAD_TSO_F &&
154             (ol_flags & PKT_TX_TCP_SEG)) {
155                 uintptr_t mdata = rte_pktmbuf_mtod(m, uintptr_t);
156                 uint16_t *iplen, *oiplen, *oudplen;
157                 uint16_t lso_sb, paylen;
158
159                 mask = -!!(ol_flags & (PKT_TX_OUTER_IPV4 | PKT_TX_OUTER_IPV6));
160                 lso_sb = (mask & (m->outer_l2_len + m->outer_l3_len)) +
161                         m->l2_len + m->l3_len + m->l4_len;
162
163                 /* Reduce payload len from base headers */
164                 paylen = m->pkt_len - lso_sb;
165
166                 /* Get iplen position assuming no tunnel hdr */
167                 iplen = (uint16_t *)(mdata + m->l2_len +
168                                      (2 << !!(ol_flags & PKT_TX_IPV6)));
169                 /* Handle tunnel tso */
170                 if ((flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F) &&
171                     (ol_flags & PKT_TX_TUNNEL_MASK)) {
172                         const uint8_t is_udp_tun = (NIX_UDP_TUN_BITMASK >>
173                                 ((ol_flags & PKT_TX_TUNNEL_MASK) >> 45)) & 0x1;
174
175                         oiplen = (uint16_t *)(mdata + m->outer_l2_len +
176                                 (2 << !!(ol_flags & PKT_TX_OUTER_IPV6)));
177                         *oiplen = rte_cpu_to_be_16(rte_be_to_cpu_16(*oiplen) -
178                                                    paylen);
179
180                         /* Update format for UDP tunneled packet */
181                         if (is_udp_tun) {
182                                 oudplen = (uint16_t *)(mdata + m->outer_l2_len +
183                                                        m->outer_l3_len + 4);
184                                 *oudplen =
185                                 rte_cpu_to_be_16(rte_be_to_cpu_16(*oudplen) -
186                                                  paylen);
187                         }
188
189                         /* Update iplen position to inner ip hdr */
190                         iplen = (uint16_t *)(mdata + lso_sb - m->l3_len -
191                                 m->l4_len + (2 << !!(ol_flags & PKT_TX_IPV6)));
192                 }
193
194                 *iplen = rte_cpu_to_be_16(rte_be_to_cpu_16(*iplen) - paylen);
195         }
196 }
197
198 static __rte_always_inline void
199 otx2_nix_xmit_prepare(struct rte_mbuf *m, uint64_t *cmd, const uint16_t flags)
200 {
201         struct nix_send_ext_s *send_hdr_ext;
202         struct nix_send_hdr_s *send_hdr;
203         uint64_t ol_flags = 0, mask;
204         union nix_send_hdr_w1_u w1;
205         union nix_send_sg_s *sg;
206
207         send_hdr = (struct nix_send_hdr_s *)cmd;
208         if (flags & NIX_TX_NEED_EXT_HDR) {
209                 send_hdr_ext = (struct nix_send_ext_s *)(cmd + 2);
210                 sg = (union nix_send_sg_s *)(cmd + 4);
211                 /* Clear previous markings */
212                 send_hdr_ext->w0.lso = 0;
213                 send_hdr_ext->w1.u = 0;
214         } else {
215                 sg = (union nix_send_sg_s *)(cmd + 2);
216         }
217
218         if (flags & NIX_TX_NEED_SEND_HDR_W1) {
219                 ol_flags = m->ol_flags;
220                 w1.u = 0;
221         }
222
223         if (!(flags & NIX_TX_MULTI_SEG_F)) {
224                 send_hdr->w0.total = m->data_len;
225                 send_hdr->w0.aura =
226                         npa_lf_aura_handle_to_aura(m->pool->pool_id);
227         }
228
229         /*
230          * L3type:  2 => IPV4
231          *          3 => IPV4 with csum
232          *          4 => IPV6
233          * L3type and L3ptr needs to be set for either
234          * L3 csum or L4 csum or LSO
235          *
236          */
237
238         if ((flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F) &&
239             (flags & NIX_TX_OFFLOAD_L3_L4_CSUM_F)) {
240                 const uint8_t csum = !!(ol_flags & PKT_TX_OUTER_UDP_CKSUM);
241                 const uint8_t ol3type =
242                         ((!!(ol_flags & PKT_TX_OUTER_IPV4)) << 1) +
243                         ((!!(ol_flags & PKT_TX_OUTER_IPV6)) << 2) +
244                         !!(ol_flags & PKT_TX_OUTER_IP_CKSUM);
245
246                 /* Outer L3 */
247                 w1.ol3type = ol3type;
248                 mask = 0xffffull << ((!!ol3type) << 4);
249                 w1.ol3ptr = ~mask & m->outer_l2_len;
250                 w1.ol4ptr = ~mask & (w1.ol3ptr + m->outer_l3_len);
251
252                 /* Outer L4 */
253                 w1.ol4type = csum + (csum << 1);
254
255                 /* Inner L3 */
256                 w1.il3type = ((!!(ol_flags & PKT_TX_IPV4)) << 1) +
257                         ((!!(ol_flags & PKT_TX_IPV6)) << 2);
258                 w1.il3ptr = w1.ol4ptr + m->l2_len;
259                 w1.il4ptr = w1.il3ptr + m->l3_len;
260                 /* Increment it by 1 if it is IPV4 as 3 is with csum */
261                 w1.il3type = w1.il3type + !!(ol_flags & PKT_TX_IP_CKSUM);
262
263                 /* Inner L4 */
264                 w1.il4type =  (ol_flags & PKT_TX_L4_MASK) >> 52;
265
266                 /* In case of no tunnel header use only
267                  * shift IL3/IL4 fields a bit to use
268                  * OL3/OL4 for header checksum
269                  */
270                 mask = !ol3type;
271                 w1.u = ((w1.u & 0xFFFFFFFF00000000) >> (mask << 3)) |
272                         ((w1.u & 0X00000000FFFFFFFF) >> (mask << 4));
273
274         } else if (flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F) {
275                 const uint8_t csum = !!(ol_flags & PKT_TX_OUTER_UDP_CKSUM);
276                 const uint8_t outer_l2_len = m->outer_l2_len;
277
278                 /* Outer L3 */
279                 w1.ol3ptr = outer_l2_len;
280                 w1.ol4ptr = outer_l2_len + m->outer_l3_len;
281                 /* Increment it by 1 if it is IPV4 as 3 is with csum */
282                 w1.ol3type = ((!!(ol_flags & PKT_TX_OUTER_IPV4)) << 1) +
283                         ((!!(ol_flags & PKT_TX_OUTER_IPV6)) << 2) +
284                         !!(ol_flags & PKT_TX_OUTER_IP_CKSUM);
285
286                 /* Outer L4 */
287                 w1.ol4type = csum + (csum << 1);
288
289         } else if (flags & NIX_TX_OFFLOAD_L3_L4_CSUM_F) {
290                 const uint8_t l2_len = m->l2_len;
291
292                 /* Always use OLXPTR and OLXTYPE when only
293                  * when one header is present
294                  */
295
296                 /* Inner L3 */
297                 w1.ol3ptr = l2_len;
298                 w1.ol4ptr = l2_len + m->l3_len;
299                 /* Increment it by 1 if it is IPV4 as 3 is with csum */
300                 w1.ol3type = ((!!(ol_flags & PKT_TX_IPV4)) << 1) +
301                         ((!!(ol_flags & PKT_TX_IPV6)) << 2) +
302                         !!(ol_flags & PKT_TX_IP_CKSUM);
303
304                 /* Inner L4 */
305                 w1.ol4type =  (ol_flags & PKT_TX_L4_MASK) >> 52;
306         }
307
308         if (flags & NIX_TX_NEED_EXT_HDR &&
309             flags & NIX_TX_OFFLOAD_VLAN_QINQ_F) {
310                 send_hdr_ext->w1.vlan1_ins_ena = !!(ol_flags & PKT_TX_VLAN);
311                 /* HW will update ptr after vlan0 update */
312                 send_hdr_ext->w1.vlan1_ins_ptr = 12;
313                 send_hdr_ext->w1.vlan1_ins_tci = m->vlan_tci;
314
315                 send_hdr_ext->w1.vlan0_ins_ena = !!(ol_flags & PKT_TX_QINQ);
316                 /* 2B before end of l2 header */
317                 send_hdr_ext->w1.vlan0_ins_ptr = 12;
318                 send_hdr_ext->w1.vlan0_ins_tci = m->vlan_tci_outer;
319         }
320
321         if (flags & NIX_TX_OFFLOAD_TSO_F &&
322             (ol_flags & PKT_TX_TCP_SEG)) {
323                 uint16_t lso_sb;
324                 uint64_t mask;
325
326                 mask = -(!w1.il3type);
327                 lso_sb = (mask & w1.ol4ptr) + (~mask & w1.il4ptr) + m->l4_len;
328
329                 send_hdr_ext->w0.lso_sb = lso_sb;
330                 send_hdr_ext->w0.lso = 1;
331                 send_hdr_ext->w0.lso_mps = m->tso_segsz;
332                 send_hdr_ext->w0.lso_format =
333                         NIX_LSO_FORMAT_IDX_TSOV4 + !!(ol_flags & PKT_TX_IPV6);
334                 w1.ol4type = NIX_SENDL4TYPE_TCP_CKSUM;
335
336                 /* Handle tunnel tso */
337                 if ((flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F) &&
338                     (ol_flags & PKT_TX_TUNNEL_MASK)) {
339                         const uint8_t is_udp_tun = (NIX_UDP_TUN_BITMASK >>
340                                 ((ol_flags & PKT_TX_TUNNEL_MASK) >> 45)) & 0x1;
341
342                         w1.il4type = NIX_SENDL4TYPE_TCP_CKSUM;
343                         w1.ol4type = is_udp_tun ? NIX_SENDL4TYPE_UDP_CKSUM : 0;
344                         /* Update format for UDP tunneled packet */
345                         send_hdr_ext->w0.lso_format += is_udp_tun ? 2 : 6;
346
347                         send_hdr_ext->w0.lso_format +=
348                                 !!(ol_flags & PKT_TX_OUTER_IPV6) << 1;
349                 }
350         }
351
352         if (flags & NIX_TX_NEED_SEND_HDR_W1)
353                 send_hdr->w1.u = w1.u;
354
355         if (!(flags & NIX_TX_MULTI_SEG_F)) {
356                 sg->seg1_size = m->data_len;
357                 *(rte_iova_t *)(++sg) = rte_mbuf_data_iova(m);
358
359                 if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F) {
360                         /* DF bit = 1 if refcount of current mbuf or parent mbuf
361                          *              is greater than 1
362                          * DF bit = 0 otherwise
363                          */
364                         send_hdr->w0.df = otx2_nix_prefree_seg(m);
365                 }
366                 /* Mark mempool object as "put" since it is freed by NIX */
367                 if (!send_hdr->w0.df)
368                         __mempool_check_cookies(m->pool, (void **)&m, 1, 0);
369         }
370 }
371
372
373 static __rte_always_inline void
374 otx2_nix_xmit_one(uint64_t *cmd, void *lmt_addr,
375                   const rte_iova_t io_addr, const uint32_t flags)
376 {
377         uint64_t lmt_status;
378
379         do {
380                 otx2_lmt_mov(lmt_addr, cmd, otx2_nix_tx_ext_subs(flags));
381                 lmt_status = otx2_lmt_submit(io_addr);
382         } while (lmt_status == 0);
383 }
384
385 static __rte_always_inline uint16_t
386 otx2_nix_prepare_mseg(struct rte_mbuf *m, uint64_t *cmd, const uint16_t flags)
387 {
388         struct nix_send_hdr_s *send_hdr;
389         union nix_send_sg_s *sg;
390         struct rte_mbuf *m_next;
391         uint64_t *slist, sg_u;
392         uint64_t nb_segs;
393         uint64_t segdw;
394         uint8_t off, i;
395
396         send_hdr = (struct nix_send_hdr_s *)cmd;
397         send_hdr->w0.total = m->pkt_len;
398         send_hdr->w0.aura = npa_lf_aura_handle_to_aura(m->pool->pool_id);
399
400         if (flags & NIX_TX_NEED_EXT_HDR)
401                 off = 2;
402         else
403                 off = 0;
404
405         sg = (union nix_send_sg_s *)&cmd[2 + off];
406         /* Clear sg->u header before use */
407         sg->u &= 0xFC00000000000000;
408         sg_u = sg->u;
409         slist = &cmd[3 + off];
410
411         i = 0;
412         nb_segs = m->nb_segs;
413
414         /* Fill mbuf segments */
415         do {
416                 m_next = m->next;
417                 sg_u = sg_u | ((uint64_t)m->data_len << (i << 4));
418                 *slist = rte_mbuf_data_iova(m);
419                 /* Set invert df if buffer is not to be freed by H/W */
420                 if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F)
421                         sg_u |= (otx2_nix_prefree_seg(m) << (i + 55));
422                 /* Mark mempool object as "put" since it is freed by NIX */
423                 if (!(sg_u & (1ULL << (i + 55)))) {
424                         m->next = NULL;
425                         __mempool_check_cookies(m->pool, (void **)&m, 1, 0);
426                 }
427                 slist++;
428                 i++;
429                 nb_segs--;
430                 if (i > 2 && nb_segs) {
431                         i = 0;
432                         /* Next SG subdesc */
433                         *(uint64_t *)slist = sg_u & 0xFC00000000000000;
434                         sg->u = sg_u;
435                         sg->segs = 3;
436                         sg = (union nix_send_sg_s *)slist;
437                         sg_u = sg->u;
438                         slist++;
439                 }
440                 m = m_next;
441         } while (nb_segs);
442
443         sg->u = sg_u;
444         sg->segs = i;
445         segdw = (uint64_t *)slist - (uint64_t *)&cmd[2 + off];
446         /* Roundup extra dwords to multiple of 2 */
447         segdw = (segdw >> 1) + (segdw & 0x1);
448         /* Default dwords */
449         segdw += (off >> 1) + 1 + !!(flags & NIX_TX_OFFLOAD_TSTAMP_F);
450         send_hdr->w0.sizem1 = segdw - 1;
451
452         return segdw;
453 }
454
455 static __rte_always_inline void
456 otx2_nix_xmit_mseg_one(uint64_t *cmd, void *lmt_addr,
457                        rte_iova_t io_addr, uint16_t segdw)
458 {
459         uint64_t lmt_status;
460
461         do {
462                 otx2_lmt_mov_seg(lmt_addr, (const void *)cmd, segdw);
463                 lmt_status = otx2_lmt_submit(io_addr);
464         } while (lmt_status == 0);
465 }
466
467 #define L3L4CSUM_F   NIX_TX_OFFLOAD_L3_L4_CSUM_F
468 #define OL3OL4CSUM_F NIX_TX_OFFLOAD_OL3_OL4_CSUM_F
469 #define VLAN_F       NIX_TX_OFFLOAD_VLAN_QINQ_F
470 #define NOFF_F       NIX_TX_OFFLOAD_MBUF_NOFF_F
471 #define TSP_F        NIX_TX_OFFLOAD_TSTAMP_F
472 #define TSO_F        NIX_TX_OFFLOAD_TSO_F
473
474 /* [TSO] [TSTMP] [NOFF] [VLAN] [OL3OL4CSUM] [L3L4CSUM] */
475 #define NIX_TX_FASTPATH_MODES                                           \
476 T(no_offload,                           0, 0, 0, 0, 0, 0,       4,      \
477                 NIX_TX_OFFLOAD_NONE)                                    \
478 T(l3l4csum,                             0, 0, 0, 0, 0, 1,       4,      \
479                 L3L4CSUM_F)                                             \
480 T(ol3ol4csum,                           0, 0, 0, 0, 1, 0,       4,      \
481                 OL3OL4CSUM_F)                                           \
482 T(ol3ol4csum_l3l4csum,                  0, 0, 0, 0, 1, 1,       4,      \
483                 OL3OL4CSUM_F | L3L4CSUM_F)                              \
484 T(vlan,                                 0, 0, 0, 1, 0, 0,       6,      \
485                 VLAN_F)                                                 \
486 T(vlan_l3l4csum,                        0, 0, 0, 1, 0, 1,       6,      \
487                 VLAN_F | L3L4CSUM_F)                                    \
488 T(vlan_ol3ol4csum,                      0, 0, 0, 1, 1, 0,       6,      \
489                 VLAN_F | OL3OL4CSUM_F)                                  \
490 T(vlan_ol3ol4csum_l3l4csum,             0, 0, 0, 1, 1, 1,       6,      \
491                 VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)                     \
492 T(noff,                                 0, 0, 1, 0, 0, 0,       4,      \
493                 NOFF_F)                                                 \
494 T(noff_l3l4csum,                        0, 0, 1, 0, 0, 1,       4,      \
495                 NOFF_F | L3L4CSUM_F)                                    \
496 T(noff_ol3ol4csum,                      0, 0, 1, 0, 1, 0,       4,      \
497                 NOFF_F | OL3OL4CSUM_F)                                  \
498 T(noff_ol3ol4csum_l3l4csum,             0, 0, 1, 0, 1, 1,       4,      \
499                 NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F)                     \
500 T(noff_vlan,                            0, 0, 1, 1, 0, 0,       6,      \
501                 NOFF_F | VLAN_F)                                        \
502 T(noff_vlan_l3l4csum,                   0, 0, 1, 1, 0, 1,       6,      \
503                 NOFF_F | VLAN_F | L3L4CSUM_F)                           \
504 T(noff_vlan_ol3ol4csum,                 0, 0, 1, 1, 1, 0,       6,      \
505                 NOFF_F | VLAN_F | OL3OL4CSUM_F)                         \
506 T(noff_vlan_ol3ol4csum_l3l4csum,        0, 0, 1, 1, 1, 1,       6,      \
507                 NOFF_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)            \
508 T(ts,                                   0, 1, 0, 0, 0, 0,       8,      \
509                 TSP_F)                                                  \
510 T(ts_l3l4csum,                          0, 1, 0, 0, 0, 1,       8,      \
511                 TSP_F | L3L4CSUM_F)                                     \
512 T(ts_ol3ol4csum,                        0, 1, 0, 0, 1, 0,       8,      \
513                 TSP_F | OL3OL4CSUM_F)                                   \
514 T(ts_ol3ol4csum_l3l4csum,               0, 1, 0, 0, 1, 1,       8,      \
515                 TSP_F | OL3OL4CSUM_F | L3L4CSUM_F)                      \
516 T(ts_vlan,                              0, 1, 0, 1, 0, 0,       8,      \
517                 TSP_F | VLAN_F)                                         \
518 T(ts_vlan_l3l4csum,                     0, 1, 0, 1, 0, 1,       8,      \
519                 TSP_F | VLAN_F | L3L4CSUM_F)                            \
520 T(ts_vlan_ol3ol4csum,                   0, 1, 0, 1, 1, 0,       8,      \
521                 TSP_F | VLAN_F | OL3OL4CSUM_F)                          \
522 T(ts_vlan_ol3ol4csum_l3l4csum,          0, 1, 0, 1, 1, 1,       8,      \
523                 TSP_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)             \
524 T(ts_noff,                              0, 1, 1, 0, 0, 0,       8,      \
525                 TSP_F | NOFF_F)                                         \
526 T(ts_noff_l3l4csum,                     0, 1, 1, 0, 0, 1,       8,      \
527                 TSP_F | NOFF_F | L3L4CSUM_F)                            \
528 T(ts_noff_ol3ol4csum,                   0, 1, 1, 0, 1, 0,       8,      \
529                 TSP_F | NOFF_F | OL3OL4CSUM_F)                          \
530 T(ts_noff_ol3ol4csum_l3l4csum,          0, 1, 1, 0, 1, 1,       8,      \
531                 TSP_F | NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F)             \
532 T(ts_noff_vlan,                         0, 1, 1, 1, 0, 0,       8,      \
533                 TSP_F | NOFF_F | VLAN_F)                                \
534 T(ts_noff_vlan_l3l4csum,                0, 1, 1, 1, 0, 1,       8,      \
535                 TSP_F | NOFF_F | VLAN_F | L3L4CSUM_F)                   \
536 T(ts_noff_vlan_ol3ol4csum,              0, 1, 1, 1, 1, 0,       8,      \
537                 TSP_F | NOFF_F | VLAN_F | OL3OL4CSUM_F)                 \
538 T(ts_noff_vlan_ol3ol4csum_l3l4csum,     0, 1, 1, 1, 1, 1,       8,      \
539                 TSP_F | NOFF_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)    \
540                                                                         \
541 T(tso,                                  1, 0, 0, 0, 0, 0,       6,      \
542                 TSO_F)                                                  \
543 T(tso_l3l4csum,                         1, 0, 0, 0, 0, 1,       6,      \
544                 TSO_F | L3L4CSUM_F)                                     \
545 T(tso_ol3ol4csum,                       1, 0, 0, 0, 1, 0,       6,      \
546                 TSO_F | OL3OL4CSUM_F)                                   \
547 T(tso_ol3ol4csum_l3l4csum,              1, 0, 0, 0, 1, 1,       6,      \
548                 TSO_F | OL3OL4CSUM_F | L3L4CSUM_F)                      \
549 T(tso_vlan,                             1, 0, 0, 1, 0, 0,       6,      \
550                 TSO_F | VLAN_F)                                         \
551 T(tso_vlan_l3l4csum,                    1, 0, 0, 1, 0, 1,       6,      \
552                 TSO_F | VLAN_F | L3L4CSUM_F)                            \
553 T(tso_vlan_ol3ol4csum,                  1, 0, 0, 1, 1, 0,       6,      \
554                 TSO_F | VLAN_F | OL3OL4CSUM_F)                          \
555 T(tso_vlan_ol3ol4csum_l3l4csum,         1, 0, 0, 1, 1, 1,       6,      \
556                 TSO_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)             \
557 T(tso_noff,                             1, 0, 1, 0, 0, 0,       6,      \
558                 TSO_F | NOFF_F)                                         \
559 T(tso_noff_l3l4csum,                    1, 0, 1, 0, 0, 1,       6,      \
560                 TSO_F | NOFF_F | L3L4CSUM_F)                            \
561 T(tso_noff_ol3ol4csum,                  1, 0, 1, 0, 1, 0,       6,      \
562                 TSO_F | NOFF_F | OL3OL4CSUM_F)                          \
563 T(tso_noff_ol3ol4csum_l3l4csum,         1, 0, 1, 0, 1, 1,       6,      \
564                 TSO_F | NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F)             \
565 T(tso_noff_vlan,                        1, 0, 1, 1, 0, 0,       6,      \
566                 TSO_F | NOFF_F | VLAN_F)                                \
567 T(tso_noff_vlan_l3l4csum,               1, 0, 1, 1, 0, 1,       6,      \
568                 TSO_F | NOFF_F | VLAN_F | L3L4CSUM_F)                   \
569 T(tso_noff_vlan_ol3ol4csum,             1, 0, 1, 1, 1, 0,       6,      \
570                 TSO_F | NOFF_F | VLAN_F | OL3OL4CSUM_F)                 \
571 T(tso_noff_vlan_ol3ol4csum_l3l4csum,    1, 0, 1, 1, 1, 1,       6,      \
572                 TSO_F | NOFF_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)    \
573 T(tso_ts,                               1, 1, 0, 0, 0, 0,       8,      \
574                 TSO_F | TSP_F)                                          \
575 T(tso_ts_l3l4csum,                      1, 1, 0, 0, 0, 1,       8,      \
576                 TSO_F | TSP_F | L3L4CSUM_F)                             \
577 T(tso_ts_ol3ol4csum,                    1, 1, 0, 0, 1, 0,       8,      \
578                 TSO_F | TSP_F | OL3OL4CSUM_F)                           \
579 T(tso_ts_ol3ol4csum_l3l4csum,           1, 1, 0, 0, 1, 1,       8,      \
580                 TSO_F | TSP_F | OL3OL4CSUM_F | L3L4CSUM_F)              \
581 T(tso_ts_vlan,                          1, 1, 0, 1, 0, 0,       8,      \
582                 TSO_F | TSP_F | VLAN_F)                                 \
583 T(tso_ts_vlan_l3l4csum,                 1, 1, 0, 1, 0, 1,       8,      \
584                 TSO_F | TSP_F | VLAN_F | L3L4CSUM_F)                    \
585 T(tso_ts_vlan_ol3ol4csum,               1, 1, 0, 1, 1, 0,       8,      \
586                 TSO_F | TSP_F | VLAN_F | OL3OL4CSUM_F)                  \
587 T(tso_ts_vlan_ol3ol4csum_l3l4csum,      1, 1, 0, 1, 1, 1,       8,      \
588                 TSO_F | TSP_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)     \
589 T(tso_ts_noff,                          1, 1, 1, 0, 0, 0,       8,      \
590                 TSO_F | TSP_F | NOFF_F)                                 \
591 T(tso_ts_noff_l3l4csum,                 1, 1, 1, 0, 0, 1,       8,      \
592                 TSO_F | TSP_F | NOFF_F | L3L4CSUM_F)                    \
593 T(tso_ts_noff_ol3ol4csum,               1, 1, 1, 0, 1, 0,       8,      \
594                 TSO_F | TSP_F | NOFF_F | OL3OL4CSUM_F)                  \
595 T(tso_ts_noff_ol3ol4csum_l3l4csum,      1, 1, 1, 0, 1, 1,       8,      \
596                 TSO_F | TSP_F | NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F)     \
597 T(tso_ts_noff_vlan,                     1, 1, 1, 1, 0, 0,       8,      \
598                 TSO_F | TSP_F | NOFF_F | VLAN_F)                        \
599 T(tso_ts_noff_vlan_l3l4csum,            1, 1, 1, 1, 0, 1,       8,      \
600                 TSO_F | TSP_F | NOFF_F | VLAN_F | L3L4CSUM_F)           \
601 T(tso_ts_noff_vlan_ol3ol4csum,          1, 1, 1, 1, 1, 0,       8,      \
602                 TSO_F | TSP_F | NOFF_F | VLAN_F | OL3OL4CSUM_F)         \
603 T(tso_ts_noff_vlan_ol3ol4csum_l3l4csum, 1, 1, 1, 1, 1, 1,       8,      \
604                 TSO_F | TSP_F | NOFF_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)
605 #endif /* __OTX2_TX_H__ */