Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : : #ifndef __CN9K_TX_H__
5 : : #define __CN9K_TX_H__
6 : :
7 : : #include <rte_vect.h>
8 : :
9 : : #define NIX_TX_OFFLOAD_NONE (0)
10 : : #define NIX_TX_OFFLOAD_L3_L4_CSUM_F BIT(0)
11 : : #define NIX_TX_OFFLOAD_OL3_OL4_CSUM_F BIT(1)
12 : : #define NIX_TX_OFFLOAD_VLAN_QINQ_F BIT(2)
13 : : #define NIX_TX_OFFLOAD_MBUF_NOFF_F BIT(3)
14 : : #define NIX_TX_OFFLOAD_TSO_F BIT(4)
15 : : #define NIX_TX_OFFLOAD_TSTAMP_F BIT(5)
16 : : #define NIX_TX_OFFLOAD_SECURITY_F BIT(6)
17 : : #define NIX_TX_OFFLOAD_MAX (NIX_TX_OFFLOAD_SECURITY_F << 1)
18 : :
19 : : /* Flags to control xmit_prepare function.
20 : : * Defining it from backwards to denote its been
21 : : * not used as offload flags to pick function
22 : : */
23 : : #define NIX_TX_MULTI_SEG_F BIT(15)
24 : :
25 : : #define NIX_TX_NEED_SEND_HDR_W1 \
26 : : (NIX_TX_OFFLOAD_L3_L4_CSUM_F | NIX_TX_OFFLOAD_OL3_OL4_CSUM_F | \
27 : : NIX_TX_OFFLOAD_VLAN_QINQ_F | NIX_TX_OFFLOAD_TSO_F)
28 : :
29 : : #define NIX_TX_NEED_EXT_HDR \
30 : : (NIX_TX_OFFLOAD_VLAN_QINQ_F | NIX_TX_OFFLOAD_TSTAMP_F | \
31 : : NIX_TX_OFFLOAD_TSO_F)
32 : :
33 : : #define NIX_XMIT_FC_OR_RETURN(txq, pkts) \
34 : : do { \
35 : : int64_t avail; \
36 : : /* Cached value is low, Update the fc_cache_pkts */ \
37 : : if (unlikely((txq)->fc_cache_pkts < (pkts))) { \
38 : : avail = txq->nb_sqb_bufs_adj - *txq->fc_mem; \
39 : : /* Multiply with sqe_per_sqb to express in pkts */ \
40 : : (txq)->fc_cache_pkts = \
41 : : (avail << (txq)->sqes_per_sqb_log2) - avail; \
42 : : /* Check it again for the room */ \
43 : : if (unlikely((txq)->fc_cache_pkts < (pkts))) \
44 : : return 0; \
45 : : } \
46 : : } while (0)
47 : :
48 : : /* Function to determine no of tx subdesc required in case ext
49 : : * sub desc is enabled.
50 : : */
51 : : static __rte_always_inline int
52 : : cn9k_nix_tx_ext_subs(const uint16_t flags)
53 : : {
54 : : return (flags & NIX_TX_OFFLOAD_TSTAMP_F)
55 : : ? 2
56 : : : ((flags &
57 : : (NIX_TX_OFFLOAD_VLAN_QINQ_F | NIX_TX_OFFLOAD_TSO_F))
58 : : ? 1
59 : : : 0);
60 : : }
61 : :
62 : : static __rte_always_inline void
63 : : cn9k_nix_tx_skeleton(struct cn9k_eth_txq *txq, uint64_t *cmd,
64 : : const uint16_t flags, const uint16_t static_sz)
65 : : {
66 : : if (static_sz)
67 : 0 : cmd[0] = txq->send_hdr_w0;
68 : : else
69 : 0 : cmd[0] = (txq->send_hdr_w0 & 0xFFFFF00000000000) |
70 : : ((uint64_t)(cn9k_nix_tx_ext_subs(flags) + 1) << 40);
71 : 0 : cmd[1] = 0;
72 : :
73 [ # # ]: 0 : if (flags & NIX_TX_NEED_EXT_HDR) {
74 [ # # ]: 0 : if (flags & NIX_TX_OFFLOAD_TSTAMP_F)
75 : 0 : cmd[2] = (NIX_SUBDC_EXT << 60) | BIT_ULL(15);
76 : : else
77 : 0 : cmd[2] = NIX_SUBDC_EXT << 60;
78 : 0 : cmd[3] = 0;
79 [ # # # # : 0 : cmd[4] = (NIX_SUBDC_SG << 60) | BIT_ULL(48);
# # # # ]
80 : : } else {
81 : 0 : cmd[2] = (NIX_SUBDC_SG << 60) | BIT_ULL(48);
82 : : }
83 : : }
84 : :
85 : : static __rte_always_inline void
86 : : cn9k_nix_free_extmbuf(struct rte_mbuf *m)
87 : : {
88 : : struct rte_mbuf *m_next;
89 : : while (m != NULL) {
90 : : m_next = m->next;
91 : : rte_pktmbuf_free_seg(m);
92 : : m = m_next;
93 : : }
94 : : }
95 : :
96 : : static __rte_always_inline uint64_t
97 : : cn9k_nix_prefree_seg(struct rte_mbuf *m, struct rte_mbuf **extm, struct cn9k_eth_txq *txq,
98 : : struct nix_send_hdr_s *send_hdr, uint64_t *aura)
99 : : {
100 : : struct rte_mbuf *prev;
101 : : uint32_t sqe_id;
102 : :
103 [ # # # # ]: 0 : if (RTE_MBUF_HAS_EXTBUF(m)) {
104 [ # # # # : 0 : if (unlikely(txq->tx_compl.ena == 0)) {
# # # # #
# # # # #
# # ]
105 : 0 : m->next = *extm;
106 : : *extm = m;
107 : 0 : return 1;
108 : : }
109 [ # # # # : 0 : if (send_hdr->w0.pnc) {
# # # # ]
110 : 0 : sqe_id = send_hdr->w1.sqe_id;
111 : 0 : prev = txq->tx_compl.ptr[sqe_id];
112 : 0 : m->next = prev;
113 : 0 : txq->tx_compl.ptr[sqe_id] = m;
114 : : } else {
115 : 0 : sqe_id = rte_atomic_fetch_add_explicit(&txq->tx_compl.sqe_id, 1,
116 : : rte_memory_order_relaxed);
117 : 0 : send_hdr->w0.pnc = 1;
118 : 0 : send_hdr->w1.sqe_id = sqe_id &
119 : 0 : txq->tx_compl.nb_desc_mask;
120 : 0 : txq->tx_compl.ptr[send_hdr->w1.sqe_id] = m;
121 : 0 : m->next = NULL;
122 : : }
123 : : return 1;
124 : : } else {
125 : : return cnxk_nix_prefree_seg(m, aura);
126 : : }
127 : : }
128 : :
129 : : #if defined(RTE_ARCH_ARM64)
130 : : /* Only called for first segments of single segmented mbufs */
131 : : static __rte_always_inline void
132 : : cn9k_nix_prefree_seg_vec(struct rte_mbuf **mbufs, struct rte_mbuf **extm, struct cn9k_eth_txq *txq,
133 : : uint64x2_t *senddesc01_w0, uint64x2_t *senddesc23_w0,
134 : : uint64x2_t *senddesc01_w1, uint64x2_t *senddesc23_w1)
135 : : {
136 : : struct rte_mbuf **tx_compl_ptr = txq->tx_compl.ptr;
137 : : uint32_t nb_desc_mask = txq->tx_compl.nb_desc_mask;
138 : : bool tx_compl_ena = txq->tx_compl.ena;
139 : : struct rte_mbuf *m0, *m1, *m2, *m3;
140 : : struct rte_mbuf *cookie;
141 : : uint64_t w0, w1, aura;
142 : : uint64_t sqe_id;
143 : :
144 : : m0 = mbufs[0];
145 : : m1 = mbufs[1];
146 : : m2 = mbufs[2];
147 : : m3 = mbufs[3];
148 : :
149 : : /* mbuf 0 */
150 : : w0 = vgetq_lane_u64(*senddesc01_w0, 0);
151 : : if (RTE_MBUF_HAS_EXTBUF(m0)) {
152 : : w0 |= BIT_ULL(19);
153 : : w1 = vgetq_lane_u64(*senddesc01_w1, 0);
154 : : w1 &= ~0xFFFF000000000000UL;
155 : : if (unlikely(!tx_compl_ena)) {
156 : : m0->next = *extm;
157 : : *extm = m0;
158 : : } else {
159 : : sqe_id = rte_atomic_fetch_add_explicit(&txq->tx_compl.sqe_id, 1,
160 : : rte_memory_order_relaxed);
161 : : sqe_id = sqe_id & nb_desc_mask;
162 : : /* Set PNC */
163 : : w0 |= BIT_ULL(43);
164 : : w1 |= sqe_id << 48;
165 : : tx_compl_ptr[sqe_id] = m0;
166 : : *senddesc01_w1 = vsetq_lane_u64(w1, *senddesc01_w1, 0);
167 : : }
168 : : } else {
169 : : cookie = RTE_MBUF_DIRECT(m0) ? m0 : rte_mbuf_from_indirect(m0);
170 : : aura = (w0 >> 20) & 0xFFFFF;
171 : : w0 &= ~0xFFFFF00000UL;
172 : : w0 |= cnxk_nix_prefree_seg(m0, &aura) << 19;
173 : : w0 |= aura << 20;
174 : :
175 : : if ((w0 & BIT_ULL(19)) == 0)
176 : : RTE_MEMPOOL_CHECK_COOKIES(cookie->pool, (void **)&cookie, 1, 0);
177 : : }
178 : : *senddesc01_w0 = vsetq_lane_u64(w0, *senddesc01_w0, 0);
179 : :
180 : : /* mbuf1 */
181 : : w0 = vgetq_lane_u64(*senddesc01_w0, 1);
182 : : if (RTE_MBUF_HAS_EXTBUF(m1)) {
183 : : w0 |= BIT_ULL(19);
184 : : w1 = vgetq_lane_u64(*senddesc01_w1, 1);
185 : : w1 &= ~0xFFFF000000000000UL;
186 : : if (unlikely(!tx_compl_ena)) {
187 : : m1->next = *extm;
188 : : *extm = m1;
189 : : } else {
190 : : sqe_id = rte_atomic_fetch_add_explicit(&txq->tx_compl.sqe_id, 1,
191 : : rte_memory_order_relaxed);
192 : : sqe_id = sqe_id & nb_desc_mask;
193 : : /* Set PNC */
194 : : w0 |= BIT_ULL(43);
195 : : w1 |= sqe_id << 48;
196 : : tx_compl_ptr[sqe_id] = m1;
197 : : *senddesc01_w1 = vsetq_lane_u64(w1, *senddesc01_w1, 1);
198 : : }
199 : : } else {
200 : : cookie = RTE_MBUF_DIRECT(m1) ? m1 : rte_mbuf_from_indirect(m1);
201 : : aura = (w0 >> 20) & 0xFFFFF;
202 : : w0 &= ~0xFFFFF00000UL;
203 : : w0 |= cnxk_nix_prefree_seg(m1, &aura) << 19;
204 : : w0 |= aura << 20;
205 : :
206 : : if ((w0 & BIT_ULL(19)) == 0)
207 : : RTE_MEMPOOL_CHECK_COOKIES(cookie->pool, (void **)&cookie, 1, 0);
208 : : }
209 : : *senddesc01_w0 = vsetq_lane_u64(w0, *senddesc01_w0, 1);
210 : :
211 : : /* mbuf 2 */
212 : : w0 = vgetq_lane_u64(*senddesc23_w0, 0);
213 : : if (RTE_MBUF_HAS_EXTBUF(m2)) {
214 : : w0 |= BIT_ULL(19);
215 : : w1 = vgetq_lane_u64(*senddesc23_w1, 0);
216 : : w1 &= ~0xFFFF000000000000UL;
217 : : if (unlikely(!tx_compl_ena)) {
218 : : m2->next = *extm;
219 : : *extm = m2;
220 : : } else {
221 : : sqe_id = rte_atomic_fetch_add_explicit(&txq->tx_compl.sqe_id, 1,
222 : : rte_memory_order_relaxed);
223 : : sqe_id = sqe_id & nb_desc_mask;
224 : : /* Set PNC */
225 : : w0 |= BIT_ULL(43);
226 : : w1 |= sqe_id << 48;
227 : : tx_compl_ptr[sqe_id] = m2;
228 : : *senddesc23_w1 = vsetq_lane_u64(w1, *senddesc23_w1, 0);
229 : : }
230 : : } else {
231 : : cookie = RTE_MBUF_DIRECT(m2) ? m2 : rte_mbuf_from_indirect(m2);
232 : : aura = (w0 >> 20) & 0xFFFFF;
233 : : w0 &= ~0xFFFFF00000UL;
234 : : w0 |= cnxk_nix_prefree_seg(m2, &aura) << 19;
235 : : w0 |= aura << 20;
236 : :
237 : : if ((w0 & BIT_ULL(19)) == 0)
238 : : RTE_MEMPOOL_CHECK_COOKIES(cookie->pool, (void **)&cookie, 1, 0);
239 : : }
240 : : *senddesc23_w0 = vsetq_lane_u64(w0, *senddesc23_w0, 0);
241 : :
242 : : /* mbuf3 */
243 : : w0 = vgetq_lane_u64(*senddesc23_w0, 1);
244 : : if (RTE_MBUF_HAS_EXTBUF(m3)) {
245 : : w0 |= BIT_ULL(19);
246 : : w1 = vgetq_lane_u64(*senddesc23_w1, 1);
247 : : w1 &= ~0xFFFF000000000000UL;
248 : : if (unlikely(!tx_compl_ena)) {
249 : : m3->next = *extm;
250 : : *extm = m3;
251 : : } else {
252 : : sqe_id = rte_atomic_fetch_add_explicit(&txq->tx_compl.sqe_id, 1,
253 : : rte_memory_order_relaxed);
254 : : sqe_id = sqe_id & nb_desc_mask;
255 : : /* Set PNC */
256 : : w0 |= BIT_ULL(43);
257 : : w1 |= sqe_id << 48;
258 : : tx_compl_ptr[sqe_id] = m3;
259 : : *senddesc23_w1 = vsetq_lane_u64(w1, *senddesc23_w1, 1);
260 : : }
261 : : } else {
262 : : cookie = RTE_MBUF_DIRECT(m3) ? m3 : rte_mbuf_from_indirect(m3);
263 : : aura = (w0 >> 20) & 0xFFFFF;
264 : : w0 &= ~0xFFFFF00000UL;
265 : : w0 |= cnxk_nix_prefree_seg(m3, &aura) << 19;
266 : : w0 |= aura << 20;
267 : :
268 : : if ((w0 & BIT_ULL(19)) == 0)
269 : : RTE_MEMPOOL_CHECK_COOKIES(cookie->pool, (void **)&cookie, 1, 0);
270 : : }
271 : : *senddesc23_w0 = vsetq_lane_u64(w0, *senddesc23_w0, 1);
272 : : #ifndef RTE_LIBRTE_MEMPOOL_DEBUG
273 : : RTE_SET_USED(cookie);
274 : : #endif
275 : : }
276 : : #endif
277 : :
278 : : static __rte_always_inline void
279 : : cn9k_nix_xmit_prepare_tso(struct rte_mbuf *m, const uint64_t flags)
280 : : {
281 : 0 : uint64_t mask, ol_flags = m->ol_flags;
282 : :
283 [ # # # # : 0 : if (flags & NIX_TX_OFFLOAD_TSO_F && (ol_flags & RTE_MBUF_F_TX_TCP_SEG)) {
# # # # ]
284 : 0 : uintptr_t mdata = rte_pktmbuf_mtod(m, uintptr_t);
285 : : uint16_t *iplen, *oiplen, *oudplen;
286 : : uint16_t lso_sb, paylen;
287 : :
288 : 0 : mask = -!!(ol_flags & (RTE_MBUF_F_TX_OUTER_IPV4 | RTE_MBUF_F_TX_OUTER_IPV6));
289 : 0 : lso_sb = (mask & (m->outer_l2_len + m->outer_l3_len)) +
290 : 0 : m->l2_len + m->l3_len + m->l4_len;
291 : :
292 : : /* Reduce payload len from base headers */
293 : 0 : paylen = m->pkt_len - lso_sb;
294 : :
295 : : /* Get iplen position assuming no tunnel hdr */
296 : 0 : iplen = (uint16_t *)(mdata + m->l2_len +
297 [ # # # # : 0 : (2 << !!(ol_flags & RTE_MBUF_F_TX_IPV6)));
# # # # ]
298 : : /* Handle tunnel tso */
299 [ # # ]: 0 : if ((flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F) &&
300 [ # # # # : 0 : (ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK)) {
# # # # ]
301 : 0 : const uint8_t is_udp_tun =
302 : 0 : (CNXK_NIX_UDP_TUN_BITMASK >>
303 : 0 : ((ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) >> 45)) &
304 : : 0x1;
305 : :
306 : 0 : oiplen = (uint16_t *)(mdata + m->outer_l2_len +
307 [ # # # # : 0 : (2 << !!(ol_flags &
# # # # ]
308 : : RTE_MBUF_F_TX_OUTER_IPV6)));
309 [ # # # # : 0 : *oiplen = rte_cpu_to_be_16(rte_be_to_cpu_16(*oiplen) -
# # # # ]
310 : : paylen);
311 : :
312 : : /* Update format for UDP tunneled packet */
313 [ # # # # : 0 : if (is_udp_tun) {
# # # # ]
314 : 0 : oudplen = (uint16_t *)(mdata + m->outer_l2_len +
315 : 0 : m->outer_l3_len + 4);
316 [ # # # # : 0 : *oudplen = rte_cpu_to_be_16(
# # # # ]
317 : : rte_be_to_cpu_16(*oudplen) - paylen);
318 : : }
319 : :
320 : : /* Update iplen position to inner ip hdr */
321 : 0 : iplen = (uint16_t *)(mdata + lso_sb - m->l3_len -
322 : 0 : m->l4_len +
323 : : (2 << !!(ol_flags & RTE_MBUF_F_TX_IPV6)));
324 : : }
325 : :
326 [ # # # # : 0 : *iplen = rte_cpu_to_be_16(rte_be_to_cpu_16(*iplen) - paylen);
# # # # ]
327 : : }
328 : : }
329 : :
330 : : static __rte_always_inline void
331 : : cn9k_nix_xmit_prepare(struct cn9k_eth_txq *txq, struct rte_mbuf *m, struct rte_mbuf **extm,
332 : : uint64_t *cmd, const uint16_t flags, const uint64_t lso_tun_fmt,
333 : : uint8_t mark_flag, uint64_t mark_fmt)
334 : : {
335 : : uint8_t mark_off = 0, mark_vlan = 0, markptr = 0;
336 : : struct nix_send_ext_s *send_hdr_ext;
337 : : struct nix_send_hdr_s *send_hdr;
338 : : uint64_t ol_flags = 0, mask;
339 : : union nix_send_hdr_w1_u w1;
340 : : union nix_send_sg_s *sg;
341 : : uint16_t mark_form = 0;
342 : :
343 : : send_hdr = (struct nix_send_hdr_s *)cmd;
344 : 0 : if (flags & NIX_TX_NEED_EXT_HDR) {
345 : : send_hdr_ext = (struct nix_send_ext_s *)(cmd + 2);
346 : : sg = (union nix_send_sg_s *)(cmd + 4);
347 : : /* Clear previous markings */
348 : 0 : send_hdr_ext->w0.lso = 0;
349 : 0 : send_hdr_ext->w0.mark_en = 0;
350 : 0 : send_hdr_ext->w1.u = 0;
351 : 0 : ol_flags = m->ol_flags;
352 : : } else {
353 : : sg = (union nix_send_sg_s *)(cmd + 2);
354 : : }
355 : :
356 [ # # ]: 0 : if (flags & NIX_TX_NEED_SEND_HDR_W1) {
357 : 0 : ol_flags = m->ol_flags;
358 : 0 : w1.u = 0;
359 : : }
360 [ # # ]: 0 : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F)
361 : 0 : send_hdr->w0.pnc = 0;
362 : :
363 [ # # ]: 0 : if (!(flags & NIX_TX_MULTI_SEG_F))
364 : 0 : send_hdr->w0.total = m->data_len;
365 : : else
366 : 0 : send_hdr->w0.total = m->pkt_len;
367 [ # # # # : 0 : send_hdr->w0.aura = roc_npa_aura_handle_to_aura(m->pool->pool_id);
# # # # ]
368 : :
369 : : /*
370 : : * L3type: 2 => IPV4
371 : : * 3 => IPV4 with csum
372 : : * 4 => IPV6
373 : : * L3type and L3ptr needs to be set for either
374 : : * L3 csum or L4 csum or LSO
375 : : *
376 : : */
377 : :
378 [ # # ]: 0 : if ((flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F) &&
379 : : (flags & NIX_TX_OFFLOAD_L3_L4_CSUM_F)) {
380 : 0 : const uint8_t csum = !!(ol_flags & RTE_MBUF_F_TX_OUTER_UDP_CKSUM);
381 : 0 : const uint8_t ol3type =
382 : 0 : ((!!(ol_flags & RTE_MBUF_F_TX_OUTER_IPV4)) << 1) +
383 : : ((!!(ol_flags & RTE_MBUF_F_TX_OUTER_IPV6)) << 2) +
384 : 0 : !!(ol_flags & RTE_MBUF_F_TX_OUTER_IP_CKSUM);
385 : :
386 : : /* Outer L3 */
387 : 0 : w1.ol3type = ol3type;
388 [ # # # # : 0 : mask = 0xffffull << ((!!ol3type) << 4);
# # # # ]
389 : 0 : w1.ol3ptr = ~mask & m->outer_l2_len;
390 : 0 : w1.ol4ptr = ~mask & (w1.ol3ptr + m->outer_l3_len);
391 : :
392 : : /* Outer L4 */
393 : 0 : w1.ol4type = csum + (csum << 1);
394 : :
395 : : /* Inner L3 */
396 : 0 : w1.il3type = ((!!(ol_flags & RTE_MBUF_F_TX_IPV4)) << 1) +
397 : : ((!!(ol_flags & RTE_MBUF_F_TX_IPV6)) << 2);
398 : 0 : w1.il3ptr = w1.ol4ptr + m->l2_len;
399 : 0 : w1.il4ptr = w1.il3ptr + m->l3_len;
400 : : /* Increment it by 1 if it is IPV4 as 3 is with csum */
401 : 0 : w1.il3type = w1.il3type + !!(ol_flags & RTE_MBUF_F_TX_IP_CKSUM);
402 : :
403 : : /* Inner L4 */
404 : 0 : w1.il4type = (ol_flags & RTE_MBUF_F_TX_L4_MASK) >> 52;
405 : :
406 : : /* In case of no tunnel header use only
407 : : * shift IL3/IL4 fields a bit to use
408 : : * OL3/OL4 for header checksum
409 : : */
410 : 0 : mask = !ol3type;
411 : 0 : w1.u = ((w1.u & 0xFFFFFFFF00000000) >> (mask << 3)) |
412 : 0 : ((w1.u & 0X00000000FFFFFFFF) >> (mask << 4));
413 : :
414 [ # # ]: 0 : } else if (flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F) {
415 : 0 : const uint8_t csum = !!(ol_flags & RTE_MBUF_F_TX_OUTER_UDP_CKSUM);
416 : 0 : const uint8_t outer_l2_len = m->outer_l2_len;
417 : :
418 : : /* Outer L3 */
419 : 0 : w1.ol3ptr = outer_l2_len;
420 : 0 : w1.ol4ptr = outer_l2_len + m->outer_l3_len;
421 : : /* Increment it by 1 if it is IPV4 as 3 is with csum */
422 : 0 : w1.ol3type = ((!!(ol_flags & RTE_MBUF_F_TX_OUTER_IPV4)) << 1) +
423 : 0 : ((!!(ol_flags & RTE_MBUF_F_TX_OUTER_IPV6)) << 2) +
424 : 0 : !!(ol_flags & RTE_MBUF_F_TX_OUTER_IP_CKSUM);
425 : :
426 : : /* Outer L4 */
427 : 0 : w1.ol4type = csum + (csum << 1);
428 : :
429 [ # # ]: 0 : } else if (flags & NIX_TX_OFFLOAD_L3_L4_CSUM_F) {
430 : 0 : const uint8_t l2_len = m->l2_len;
431 : :
432 : : /* Always use OLXPTR and OLXTYPE when only
433 : : * when one header is present
434 : : */
435 : :
436 : : /* Inner L3 */
437 : 0 : w1.ol3ptr = l2_len;
438 : 0 : w1.ol4ptr = l2_len + m->l3_len;
439 : : /* Increment it by 1 if it is IPV4 as 3 is with csum */
440 : 0 : w1.ol3type = ((!!(ol_flags & RTE_MBUF_F_TX_IPV4)) << 1) +
441 : 0 : ((!!(ol_flags & RTE_MBUF_F_TX_IPV6)) << 2) +
442 : 0 : !!(ol_flags & RTE_MBUF_F_TX_IP_CKSUM);
443 : :
444 : : /* Inner L4 */
445 : 0 : w1.ol4type = (ol_flags & RTE_MBUF_F_TX_L4_MASK) >> 52;
446 : : }
447 : :
448 [ # # # # ]: 0 : if (flags & NIX_TX_NEED_EXT_HDR && flags & NIX_TX_OFFLOAD_VLAN_QINQ_F) {
449 : 0 : const uint8_t ipv6 = !!(ol_flags & RTE_MBUF_F_TX_IPV6);
450 : 0 : const uint8_t ip = !!(ol_flags & (RTE_MBUF_F_TX_IPV4 |
451 : : RTE_MBUF_F_TX_IPV6));
452 : :
453 : 0 : send_hdr_ext->w1.vlan1_ins_ena = !!(ol_flags & RTE_MBUF_F_TX_VLAN);
454 : : /* HW will update ptr after vlan0 update */
455 : 0 : send_hdr_ext->w1.vlan1_ins_ptr = 12;
456 : 0 : send_hdr_ext->w1.vlan1_ins_tci = m->vlan_tci;
457 : :
458 : 0 : send_hdr_ext->w1.vlan0_ins_ena = !!(ol_flags & RTE_MBUF_F_TX_QINQ);
459 : : /* 2B before end of l2 header */
460 : 0 : send_hdr_ext->w1.vlan0_ins_ptr = 12;
461 : 0 : send_hdr_ext->w1.vlan0_ins_tci = m->vlan_tci_outer;
462 : : /* Fill for VLAN marking only when VLAN insertion enabled */
463 : 0 : mark_vlan = ((mark_flag & CNXK_TM_MARK_VLAN_DEI) &
464 : 0 : (send_hdr_ext->w1.vlan1_ins_ena ||
465 : : send_hdr_ext->w1.vlan0_ins_ena));
466 : : /* Mask requested flags with packet data information */
467 : 0 : mark_off = mark_flag & ((ip << 2) | (ip << 1) | mark_vlan);
468 : 0 : mark_off = ffs(mark_off & CNXK_TM_MARK_MASK);
469 : :
470 : 0 : mark_form = (mark_fmt >> ((mark_off - !!mark_off) << 4));
471 : 0 : mark_form = (mark_form >> (ipv6 << 3)) & 0xFF;
472 : 0 : markptr = m->l2_len + (mark_form >> 7) - (mark_vlan << 2);
473 : :
474 : 0 : send_hdr_ext->w0.mark_en = !!mark_off;
475 : 0 : send_hdr_ext->w0.markform = mark_form & 0x7F;
476 : 0 : send_hdr_ext->w0.markptr = markptr;
477 : : }
478 : :
479 [ # # # # : 0 : if (flags & NIX_TX_OFFLOAD_TSO_F && (ol_flags & RTE_MBUF_F_TX_TCP_SEG)) {
# # # # ]
480 : : uint16_t lso_sb;
481 : : uint64_t mask;
482 : :
483 : 0 : mask = -(!w1.il3type);
484 : 0 : lso_sb = (mask & w1.ol4ptr) + (~mask & w1.il4ptr) + m->l4_len;
485 : :
486 : 0 : send_hdr_ext->w0.lso_sb = lso_sb;
487 : 0 : send_hdr_ext->w0.lso = 1;
488 : 0 : send_hdr_ext->w0.lso_mps = m->tso_segsz;
489 : 0 : send_hdr_ext->w0.lso_format =
490 : 0 : NIX_LSO_FORMAT_IDX_TSOV4 + !!(ol_flags & RTE_MBUF_F_TX_IPV6);
491 : 0 : w1.ol4type = NIX_SENDL4TYPE_TCP_CKSUM;
492 : :
493 : : /* Handle tunnel tso */
494 [ # # ]: 0 : if ((flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F) &&
495 [ # # # # : 0 : (ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK)) {
# # # # ]
496 : 0 : const uint8_t is_udp_tun =
497 : 0 : (CNXK_NIX_UDP_TUN_BITMASK >>
498 : 0 : ((ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) >> 45)) &
499 : : 0x1;
500 [ # # # # : 0 : uint8_t shift = is_udp_tun ? 32 : 0;
# # # # ]
501 : :
502 : 0 : shift += (!!(ol_flags & RTE_MBUF_F_TX_OUTER_IPV6) << 4);
503 : 0 : shift += (!!(ol_flags & RTE_MBUF_F_TX_IPV6) << 3);
504 : :
505 : 0 : w1.il4type = NIX_SENDL4TYPE_TCP_CKSUM;
506 [ # # # # : 0 : w1.ol4type = is_udp_tun ? NIX_SENDL4TYPE_UDP_CKSUM : 0;
# # # # ]
507 : : /* Update format for UDP tunneled packet */
508 : 0 : send_hdr_ext->w0.lso_format = (lso_tun_fmt >> shift);
509 : : }
510 : : }
511 : :
512 [ # # ]: 0 : if (flags & NIX_TX_NEED_SEND_HDR_W1)
513 : 0 : send_hdr->w1.u = w1.u;
514 : :
515 [ # # ]: 0 : if (!(flags & NIX_TX_MULTI_SEG_F)) {
516 : : struct rte_mbuf *cookie;
517 : :
518 [ # # ]: 0 : sg->seg1_size = m->data_len;
519 : 0 : *(rte_iova_t *)(++sg) = rte_mbuf_data_iova(m);
520 : : cookie = RTE_MBUF_DIRECT(m) ? m : rte_mbuf_from_indirect(m);
521 : :
522 [ # # ]: 0 : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F) {
523 : : uint64_t aura;
524 : : /* DF bit = 1 if refcount of current mbuf or parent mbuf
525 : : * is greater than 1
526 : : * DF bit = 0 otherwise
527 : : */
528 : : aura = send_hdr->w0.aura;
529 : 0 : send_hdr->w0.df = cn9k_nix_prefree_seg(m, extm, txq, send_hdr, &aura);
530 : 0 : send_hdr->w0.aura = aura;
531 : : /* Ensuring mbuf fields which got updated in
532 : : * cnxk_nix_prefree_seg are written before LMTST.
533 : : */
534 : 0 : rte_io_wmb();
535 : : }
536 : : #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
537 : : /* Mark mempool object as "put" since it is freed by NIX */
538 : : if (!send_hdr->w0.df)
539 : : RTE_MEMPOOL_CHECK_COOKIES(cookie->pool, (void **)&cookie, 1, 0);
540 : : #else
541 : : RTE_SET_USED(cookie);
542 : : #endif
543 : : } else {
544 [ # # # # : 0 : sg->seg1_size = m->data_len;
# # # # ]
545 [ # # # # : 0 : *(rte_iova_t *)(sg + 1) = rte_mbuf_data_iova(m);
# # # # ]
546 : :
547 : : /* NOFF is handled later for multi-seg */
548 : : }
549 : : }
550 : :
551 : : static __rte_always_inline void
552 : : cn9k_nix_xmit_prepare_tstamp(struct cn9k_eth_txq *txq, uint64_t *cmd,
553 : : const uint64_t ol_flags, const uint16_t no_segdw,
554 : : const uint16_t flags)
555 : : {
556 : : if (flags & NIX_TX_OFFLOAD_TSTAMP_F) {
557 : : struct nix_send_mem_s *send_mem;
558 : 0 : uint16_t off = (no_segdw - 1) << 1;
559 : 0 : const uint8_t is_ol_tstamp =
560 : 0 : !(ol_flags & RTE_MBUF_F_TX_IEEE1588_TMST);
561 : :
562 : 0 : send_mem = (struct nix_send_mem_s *)(cmd + off);
563 : :
564 : : /* Packets for which RTE_MBUF_F_TX_IEEE1588_TMST is not set, Tx tstamp
565 : : * should not be recorded, hence changing the alg type to
566 : : * NIX_SENDMEMALG_SUB and also changing send mem addr field to
567 : : * next 8 bytes as it corrupts the actual Tx tstamp registered
568 : : * address.
569 : : */
570 : 0 : send_mem->w0.cn9k.subdc = NIX_SUBDC_MEM;
571 : 0 : send_mem->w0.cn9k.alg =
572 : 0 : NIX_SENDMEMALG_SETTSTMP + (is_ol_tstamp << 3);
573 : :
574 [ # # # # ]: 0 : send_mem->addr = (rte_iova_t)(((uint64_t *)txq->ts_mem) +
575 : : (is_ol_tstamp));
576 : : }
577 : : }
578 : :
579 : : static __rte_always_inline void
580 : : cn9k_nix_xmit_one(uint64_t *cmd, void *lmt_addr, const rte_iova_t io_addr,
581 : : const uint32_t flags)
582 : : {
583 : : uint64_t lmt_status;
584 : :
585 : : do {
586 : : roc_lmt_mov(lmt_addr, cmd, cn9k_nix_tx_ext_subs(flags));
587 : : lmt_status = roc_lmt_submit_ldeor(io_addr);
588 : : } while (lmt_status == 0);
589 : : }
590 : :
591 : : static __rte_always_inline void
592 : : cn9k_nix_xmit_prep_lmt(uint64_t *cmd, void *lmt_addr, const uint32_t flags)
593 : : {
594 : : roc_lmt_mov(lmt_addr, cmd, cn9k_nix_tx_ext_subs(flags));
595 : : }
596 : :
597 : : static __rte_always_inline void
598 : : cn9k_nix_sec_fc_wait_one(const struct cn9k_eth_txq *txq)
599 : : {
600 : : uint64_t nb_desc = txq->cpt_desc;
601 : : uint64_t __rte_atomic *fc = txq->cpt_fc;
602 : :
603 : : while (nb_desc <= rte_atomic_load_explicit(fc, rte_memory_order_relaxed))
604 : : ;
605 : : }
606 : :
607 : : static __rte_always_inline uint64_t
608 : : cn9k_nix_xmit_submit_lmt(const rte_iova_t io_addr)
609 : : {
610 : : return roc_lmt_submit_ldeor(io_addr);
611 : : }
612 : :
613 : : static __rte_always_inline uint64_t
614 : : cn9k_nix_xmit_submit_lmt_release(const rte_iova_t io_addr)
615 : : {
616 : : return roc_lmt_submit_ldeorl(io_addr);
617 : : }
618 : :
619 : : static __rte_always_inline uint16_t
620 : : cn9k_nix_prepare_mseg(struct cn9k_eth_txq *txq, struct rte_mbuf *m, struct rte_mbuf **extm,
621 : : uint64_t *cmd, const uint16_t flags)
622 : : {
623 : : struct nix_send_hdr_s *send_hdr;
624 : : uint64_t prefree = 0, aura;
625 : : struct rte_mbuf *cookie;
626 : : union nix_send_sg_s *sg;
627 : : struct rte_mbuf *m_next;
628 : : uint64_t *slist, sg_u;
629 : : uint64_t nb_segs;
630 : : uint64_t segdw;
631 : : uint8_t off, i;
632 : :
633 : : send_hdr = (struct nix_send_hdr_s *)cmd;
634 : :
635 : 0 : if (flags & NIX_TX_NEED_EXT_HDR)
636 : : off = 2;
637 : : else
638 : : off = 0;
639 : :
640 : 0 : sg = (union nix_send_sg_s *)&cmd[2 + off];
641 : :
642 : : /* Start from second segment, first segment is already there */
643 : : i = 1;
644 : 0 : sg_u = sg->u;
645 : 0 : sg_u &= 0xFC0000000000FFFF;
646 : 0 : nb_segs = m->nb_segs - 1;
647 [ # # # # : 0 : m_next = m->next;
# # # # ]
648 : 0 : slist = &cmd[3 + off + 1];
649 : :
650 : : cookie = RTE_MBUF_DIRECT(m) ? m : rte_mbuf_from_indirect(m);
651 : : /* Set invert df if buffer is not to be freed by H/W */
652 [ # # ]: 0 : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F) {
653 [ # # ]: 0 : aura = send_hdr->w0.aura;
654 : 0 : prefree = (cn9k_nix_prefree_seg(m, extm, txq, send_hdr, &aura) << 55);
655 : 0 : send_hdr->w0.aura = aura;
656 : 0 : sg_u |= prefree;
657 : 0 : rte_io_wmb();
658 : : }
659 : :
660 : : /* Mark mempool object as "put" since it is freed by NIX */
661 : : #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
662 : : if (!(sg_u & (1ULL << 55)))
663 : : RTE_MEMPOOL_CHECK_COOKIES(cookie->pool, (void **)&cookie, 1, 0);
664 : : rte_io_wmb();
665 : : #else
666 : : RTE_SET_USED(cookie);
667 : : #endif
668 : : #ifdef RTE_ENABLE_ASSERT
669 : : m->next = NULL;
670 : : m->nb_segs = 1;
671 : : #endif
672 : : m = m_next;
673 [ # # # # : 0 : if (!m)
# # # # ]
674 : 0 : goto done;
675 : :
676 : : /* Fill mbuf segments */
677 : : do {
678 : 0 : m_next = m->next;
679 [ # # # # : 0 : sg_u = sg_u | ((uint64_t)m->data_len << (i << 4));
# # # # ]
680 [ # # # # : 0 : *slist = rte_mbuf_data_iova(m);
# # # # ]
681 : : cookie = RTE_MBUF_DIRECT(m) ? m : rte_mbuf_from_indirect(m);
682 : : /* Set invert df if buffer is not to be freed by H/W */
683 [ # # ]: 0 : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F) {
684 : 0 : sg_u |= (cn9k_nix_prefree_seg(m, extm, txq, send_hdr, NULL) << (i + 55));
685 : : /* Commit changes to mbuf */
686 : 0 : rte_io_wmb();
687 : : }
688 : : /* Mark mempool object as "put" since it is freed by NIX */
689 : : #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
690 : : if (!(sg_u & (1ULL << (i + 55))))
691 : : RTE_MEMPOOL_CHECK_COOKIES(cookie->pool, (void **)&cookie, 1, 0);
692 : : rte_io_wmb();
693 : : #endif
694 : 0 : slist++;
695 : 0 : i++;
696 : 0 : nb_segs--;
697 [ # # # # : 0 : if (i > 2 && nb_segs) {
# # # # ]
698 : : i = 0;
699 : : /* Next SG subdesc */
700 : 0 : *(uint64_t *)slist = sg_u & 0xFC00000000000000;
701 : 0 : sg->u = sg_u;
702 : 0 : sg->segs = 3;
703 : : sg = (union nix_send_sg_s *)slist;
704 : 0 : sg_u = sg->u;
705 : 0 : slist++;
706 : : }
707 : : #ifdef RTE_ENABLE_ASSERT
708 : : m->next = NULL;
709 : : #endif
710 : : m = m_next;
711 [ # # # # : 0 : } while (nb_segs);
# # # # ]
712 : :
713 : 0 : done:
714 : 0 : sg->u = sg_u;
715 : 0 : sg->segs = i;
716 : 0 : segdw = (uint64_t *)slist - (uint64_t *)&cmd[2 + off];
717 : : /* Roundup extra dwords to multiple of 2 */
718 : 0 : segdw = (segdw >> 1) + (segdw & 0x1);
719 : : /* Default dwords */
720 : 0 : segdw += (off >> 1) + 1 + !!(flags & NIX_TX_OFFLOAD_TSTAMP_F);
721 [ # # # # ]: 0 : send_hdr->w0.sizem1 = segdw - 1;
722 : :
723 : : #ifdef RTE_ENABLE_ASSERT
724 : : rte_io_wmb();
725 : : #endif
726 [ # # # # ]: 0 : return segdw;
727 : : }
728 : :
729 : : static __rte_always_inline void
730 : : cn9k_nix_xmit_mseg_prep_lmt(uint64_t *cmd, void *lmt_addr, uint16_t segdw)
731 : : {
732 : : roc_lmt_mov_seg(lmt_addr, (const void *)cmd, segdw);
733 : : }
734 : :
735 : : static __rte_always_inline void
736 : : cn9k_nix_xmit_mseg_one(uint64_t *cmd, void *lmt_addr, rte_iova_t io_addr,
737 : : uint16_t segdw)
738 : : {
739 : : uint64_t lmt_status;
740 : :
741 : : do {
742 : : roc_lmt_mov_seg(lmt_addr, (const void *)cmd, segdw);
743 : : lmt_status = roc_lmt_submit_ldeor(io_addr);
744 : : } while (lmt_status == 0);
745 : : }
746 : :
747 : : static __rte_always_inline void
748 : : cn9k_nix_xmit_mseg_one_release(uint64_t *cmd, void *lmt_addr,
749 : : rte_iova_t io_addr, uint16_t segdw)
750 : : {
751 : : uint64_t lmt_status;
752 : :
753 : : rte_io_wmb();
754 : : do {
755 : : roc_lmt_mov_seg(lmt_addr, (const void *)cmd, segdw);
756 : : lmt_status = roc_lmt_submit_ldeor(io_addr);
757 : : } while (lmt_status == 0);
758 : : }
759 : :
760 : : static __rte_always_inline uint16_t
761 : : cn9k_nix_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t pkts,
762 : : uint64_t *cmd, const uint16_t flags)
763 : : {
764 : : struct cn9k_eth_txq *txq = tx_queue;
765 : : const rte_iova_t io_addr = txq->io_addr;
766 : : uint64_t lso_tun_fmt = 0, mark_fmt = 0;
767 : : void *lmt_addr = txq->lmt_addr;
768 : : struct rte_mbuf *extm = NULL;
769 : : uint8_t mark_flag = 0;
770 : : uint16_t i;
771 : :
772 : : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F && txq->tx_compl.ena)
773 : : handle_tx_completion_pkts(txq, 0);
774 : :
775 : : NIX_XMIT_FC_OR_RETURN(txq, pkts);
776 : :
777 : : cn9k_nix_tx_skeleton(txq, cmd, flags, 1);
778 : :
779 : : /* Perform header writes before barrier for TSO */
780 : : if (flags & NIX_TX_OFFLOAD_TSO_F) {
781 : : lso_tun_fmt = txq->lso_tun_fmt;
782 : :
783 : : for (i = 0; i < pkts; i++)
784 : : cn9k_nix_xmit_prepare_tso(tx_pkts[i], flags);
785 : : }
786 : :
787 : : if (flags & NIX_TX_OFFLOAD_VLAN_QINQ_F) {
788 : : mark_fmt = txq->mark_fmt;
789 : : mark_flag = txq->mark_flag;
790 : : }
791 : :
792 : : /* Lets commit any changes in the packet here as no further changes
793 : : * to the packet will be done unless no fast free is enabled.
794 : : */
795 : : if (!(flags & NIX_TX_OFFLOAD_MBUF_NOFF_F))
796 : : rte_io_wmb();
797 : :
798 : : for (i = 0; i < pkts; i++) {
799 : : cn9k_nix_xmit_prepare(txq, tx_pkts[i], &extm, cmd, flags, lso_tun_fmt,
800 : : mark_flag, mark_fmt);
801 : : cn9k_nix_xmit_prepare_tstamp(txq, cmd, tx_pkts[i]->ol_flags, 4,
802 : : flags);
803 : : cn9k_nix_xmit_one(cmd, lmt_addr, io_addr, flags);
804 : : }
805 : :
806 : : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F && !txq->tx_compl.ena)
807 : : cn9k_nix_free_extmbuf(extm);
808 : :
809 : : /* Reduce the cached count */
810 : : txq->fc_cache_pkts -= pkts;
811 : :
812 : : return pkts;
813 : : }
814 : :
815 : : static __rte_always_inline uint16_t
816 : : cn9k_nix_xmit_pkts_mseg(void *tx_queue, struct rte_mbuf **tx_pkts,
817 : : uint16_t pkts, uint64_t *cmd, const uint16_t flags)
818 : : {
819 : : struct cn9k_eth_txq *txq = tx_queue;
820 : : const rte_iova_t io_addr = txq->io_addr;
821 : : uint64_t lso_tun_fmt = 0, mark_fmt = 0;
822 : : void *lmt_addr = txq->lmt_addr;
823 : : struct rte_mbuf *extm = NULL;
824 : : uint8_t mark_flag = 0;
825 : : uint16_t segdw;
826 : : uint64_t i;
827 : :
828 [ # # # # ]: 0 : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F && txq->tx_compl.ena)
829 : 0 : handle_tx_completion_pkts(txq, 0);
830 : :
831 [ # # # # ]: 0 : NIX_XMIT_FC_OR_RETURN(txq, pkts);
832 : :
833 : : cn9k_nix_tx_skeleton(txq, cmd, flags, 1);
834 : :
835 : : /* Perform header writes before barrier for TSO */
836 [ # # ]: 0 : if (flags & NIX_TX_OFFLOAD_TSO_F) {
837 : 0 : lso_tun_fmt = txq->lso_tun_fmt;
838 : :
839 [ # # ]: 0 : for (i = 0; i < pkts; i++)
840 [ # # ]: 0 : cn9k_nix_xmit_prepare_tso(tx_pkts[i], flags);
841 : : }
842 : :
843 [ # # ]: 0 : if (flags & NIX_TX_OFFLOAD_VLAN_QINQ_F) {
844 : 0 : mark_fmt = txq->mark_fmt;
845 : 0 : mark_flag = txq->mark_flag;
846 : : }
847 : :
848 : : /* Lets commit any changes in the packet here as no further changes
849 : : * to the packet will be done unless no fast free is enabled.
850 : : */
851 [ # # ]: 0 : if (!(flags & NIX_TX_OFFLOAD_MBUF_NOFF_F))
852 : 0 : rte_io_wmb();
853 : :
854 [ # # ]: 0 : for (i = 0; i < pkts; i++) {
855 [ # # ]: 0 : cn9k_nix_xmit_prepare(txq, tx_pkts[i], &extm, cmd, flags, lso_tun_fmt,
856 : : mark_flag, mark_fmt);
857 [ # # ]: 0 : segdw = cn9k_nix_prepare_mseg(txq, tx_pkts[i], &extm, cmd, flags);
858 : : cn9k_nix_xmit_prepare_tstamp(txq, cmd, tx_pkts[i]->ol_flags,
859 : : segdw, flags);
860 : : cn9k_nix_xmit_mseg_one(cmd, lmt_addr, io_addr, segdw);
861 : : }
862 : :
863 : : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F && !txq->tx_compl.ena)
864 : : cn9k_nix_free_extmbuf(extm);
865 : :
866 : : /* Reduce the cached count */
867 : 0 : txq->fc_cache_pkts -= pkts;
868 : :
869 : 0 : return pkts;
870 : : }
871 : :
872 : : #if defined(RTE_ARCH_ARM64)
873 : :
874 : : static __rte_always_inline void
875 : : cn9k_nix_prepare_tso(struct rte_mbuf *m, union nix_send_hdr_w1_u *w1,
876 : : union nix_send_ext_w0_u *w0, uint64_t ol_flags,
877 : : uint64_t flags)
878 : : {
879 : : uint16_t lso_sb;
880 : : uint64_t mask;
881 : :
882 : : if (!(ol_flags & RTE_MBUF_F_TX_TCP_SEG))
883 : : return;
884 : :
885 : : mask = -(!w1->il3type);
886 : : lso_sb = (mask & w1->ol4ptr) + (~mask & w1->il4ptr) + m->l4_len;
887 : :
888 : : w0->u |= BIT(14);
889 : : w0->lso_sb = lso_sb;
890 : : w0->lso_mps = m->tso_segsz;
891 : : w0->lso_format = NIX_LSO_FORMAT_IDX_TSOV4 + !!(ol_flags & RTE_MBUF_F_TX_IPV6);
892 : : w1->ol4type = NIX_SENDL4TYPE_TCP_CKSUM;
893 : : w1->ol3type = ((!!(ol_flags & RTE_MBUF_F_TX_IPV4)) << 1) +
894 : : ((!!(ol_flags & RTE_MBUF_F_TX_IPV6)) << 2) +
895 : : !!(ol_flags & RTE_MBUF_F_TX_IP_CKSUM);
896 : :
897 : : /* Handle tunnel tso */
898 : : if ((flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F) &&
899 : : (ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK)) {
900 : : const uint8_t is_udp_tun =
901 : : (CNXK_NIX_UDP_TUN_BITMASK >>
902 : : ((ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) >> 45)) &
903 : : 0x1;
904 : :
905 : : w1->il4type = NIX_SENDL4TYPE_TCP_CKSUM;
906 : : w1->ol4type = is_udp_tun ? NIX_SENDL4TYPE_UDP_CKSUM : 0;
907 : : /* Update format for UDP tunneled packet */
908 : : w0->lso_format += is_udp_tun ? 2 : 6;
909 : :
910 : : w0->lso_format += !!(ol_flags & RTE_MBUF_F_TX_OUTER_IPV6) << 1;
911 : : }
912 : : }
913 : :
914 : : static __rte_always_inline uint8_t
915 : : cn9k_nix_prepare_mseg_vec_list(struct cn9k_eth_txq *txq,
916 : : struct rte_mbuf *m, struct rte_mbuf **extm, uint64_t *cmd,
917 : : struct nix_send_hdr_s *send_hdr,
918 : : union nix_send_sg_s *sg, const uint32_t flags)
919 : : {
920 : : struct rte_mbuf *m_next, *cookie;
921 : : uint64_t *slist, sg_u, aura;
922 : : uint16_t nb_segs;
923 : : uint64_t segdw;
924 : : int i = 1;
925 : :
926 : : send_hdr->w0.total = m->pkt_len;
927 : : /* Clear sg->u header before use */
928 : : sg->u &= 0xFC00000000000000;
929 : : sg_u = sg->u;
930 : : slist = &cmd[0];
931 : :
932 : : sg_u = sg_u | ((uint64_t)m->data_len);
933 : :
934 : : nb_segs = m->nb_segs - 1;
935 : : m_next = m->next;
936 : :
937 : : /* Set invert df if buffer is not to be freed by H/W */
938 : : cookie = RTE_MBUF_DIRECT(m) ? m : rte_mbuf_from_indirect(m);
939 : : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F) {
940 : : aura = send_hdr->w0.aura;
941 : : sg_u |= (cn9k_nix_prefree_seg(m, extm, txq, send_hdr, &aura) << 55);
942 : : send_hdr->w0.aura = aura;
943 : : }
944 : : /* Mark mempool object as "put" since it is freed by NIX */
945 : : #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
946 : : if (!(sg_u & (1ULL << 55)))
947 : : RTE_MEMPOOL_CHECK_COOKIES(cookie->pool, (void **)&cookie, 1, 0);
948 : : rte_io_wmb();
949 : : #else
950 : : RTE_SET_USED(cookie);
951 : : #endif
952 : :
953 : : #ifdef RTE_ENABLE_ASSERT
954 : : m->next = NULL;
955 : : m->nb_segs = 1;
956 : : #endif
957 : : m = m_next;
958 : : /* Fill mbuf segments */
959 : : do {
960 : : m_next = m->next;
961 : : sg_u = sg_u | ((uint64_t)m->data_len << (i << 4));
962 : : *slist = rte_mbuf_data_iova(m);
963 : : cookie = RTE_MBUF_DIRECT(m) ? m : rte_mbuf_from_indirect(m);
964 : : /* Set invert df if buffer is not to be freed by H/W */
965 : : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F)
966 : : sg_u |= (cn9k_nix_prefree_seg(m, extm, txq, send_hdr, &aura) << (i + 55));
967 : : /* Mark mempool object as "put" since it is freed by NIX
968 : : */
969 : : #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
970 : : if (!(sg_u & (1ULL << (i + 55))))
971 : : RTE_MEMPOOL_CHECK_COOKIES(cookie->pool, (void **)&cookie, 1, 0);
972 : : rte_io_wmb();
973 : : #endif
974 : : slist++;
975 : : i++;
976 : : nb_segs--;
977 : : if (i > 2 && nb_segs) {
978 : : i = 0;
979 : : /* Next SG subdesc */
980 : : *(uint64_t *)slist = sg_u & 0xFC00000000000000;
981 : : sg->u = sg_u;
982 : : sg->segs = 3;
983 : : sg = (union nix_send_sg_s *)slist;
984 : : sg_u = sg->u;
985 : : slist++;
986 : : }
987 : : #ifdef RTE_ENABLE_ASSERT
988 : : m->next = NULL;
989 : : #endif
990 : : m = m_next;
991 : : } while (nb_segs);
992 : :
993 : : sg->u = sg_u;
994 : : sg->segs = i;
995 : : segdw = (uint64_t *)slist - (uint64_t *)&cmd[0];
996 : :
997 : : segdw += 2;
998 : : /* Roundup extra dwords to multiple of 2 */
999 : : segdw = (segdw >> 1) + (segdw & 0x1);
1000 : : /* Default dwords */
1001 : : segdw += 1 + !!(flags & NIX_TX_NEED_EXT_HDR) +
1002 : : !!(flags & NIX_TX_OFFLOAD_TSTAMP_F);
1003 : : send_hdr->w0.sizem1 = segdw - 1;
1004 : :
1005 : : #ifdef RTE_ENABLE_ASSERT
1006 : : rte_io_wmb();
1007 : : #endif
1008 : : return segdw;
1009 : : }
1010 : :
1011 : : static __rte_always_inline uint8_t
1012 : : cn9k_nix_prepare_mseg_vec(struct cn9k_eth_txq *txq, struct rte_mbuf *m, struct rte_mbuf **extm,
1013 : : uint64_t *cmd, uint64x2_t *cmd0, uint64x2_t *cmd1, const uint32_t flags)
1014 : : {
1015 : : struct nix_send_hdr_s send_hdr;
1016 : : struct rte_mbuf *cookie;
1017 : : union nix_send_sg_s sg;
1018 : : uint64_t aura;
1019 : : uint8_t ret;
1020 : :
1021 : : if (m->nb_segs == 1) {
1022 : : cookie = RTE_MBUF_DIRECT(m) ? m : rte_mbuf_from_indirect(m);
1023 : : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F) {
1024 : : send_hdr.w0.u = vgetq_lane_u64(cmd0[0], 0);
1025 : : send_hdr.w1.u = vgetq_lane_u64(cmd0[0], 1);
1026 : : sg.u = vgetq_lane_u64(cmd1[0], 0);
1027 : : aura = send_hdr.w0.aura;
1028 : : sg.u |= (cn9k_nix_prefree_seg(m, extm, txq, &send_hdr, &aura) << 55);
1029 : : send_hdr.w0.aura = aura;
1030 : : cmd1[0] = vsetq_lane_u64(sg.u, cmd1[0], 0);
1031 : : cmd0[0] = vsetq_lane_u64(send_hdr.w0.u, cmd0[0], 0);
1032 : : cmd0[0] = vsetq_lane_u64(send_hdr.w1.u, cmd0[0], 1);
1033 : : }
1034 : :
1035 : : #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
1036 : : sg.u = vgetq_lane_u64(cmd1[0], 0);
1037 : : if (!(sg.u & (1ULL << 55)))
1038 : : RTE_MEMPOOL_CHECK_COOKIES(cookie->pool, (void **)&cookie, 1, 0);
1039 : : rte_io_wmb();
1040 : : #else
1041 : : RTE_SET_USED(cookie);
1042 : : #endif
1043 : : return 2 + !!(flags & NIX_TX_NEED_EXT_HDR) +
1044 : : !!(flags & NIX_TX_OFFLOAD_TSTAMP_F);
1045 : : }
1046 : :
1047 : : send_hdr.w0.u = vgetq_lane_u64(cmd0[0], 0);
1048 : : send_hdr.w1.u = vgetq_lane_u64(cmd0[0], 1);
1049 : : sg.u = vgetq_lane_u64(cmd1[0], 0);
1050 : :
1051 : : ret = cn9k_nix_prepare_mseg_vec_list(txq, m, extm, cmd, &send_hdr, &sg, flags);
1052 : :
1053 : : cmd0[0] = vsetq_lane_u64(send_hdr.w0.u, cmd0[0], 0);
1054 : : cmd0[0] = vsetq_lane_u64(send_hdr.w1.u, cmd0[0], 1);
1055 : : cmd1[0] = vsetq_lane_u64(sg.u, cmd1[0], 0);
1056 : : return ret;
1057 : : }
1058 : :
1059 : : #define NIX_DESCS_PER_LOOP 4
1060 : :
1061 : : static __rte_always_inline void
1062 : : cn9k_nix_xmit_pkts_mseg_vector(uint64x2_t *cmd0, uint64x2_t *cmd1,
1063 : : uint64x2_t *cmd2, uint64x2_t *cmd3,
1064 : : uint8_t *segdw,
1065 : : uint64_t slist[][CNXK_NIX_TX_MSEG_SG_DWORDS - 2],
1066 : : uint64_t *lmt_addr, rte_iova_t io_addr,
1067 : : const uint32_t flags)
1068 : : {
1069 : : uint64_t lmt_status;
1070 : : uint8_t j, off;
1071 : :
1072 : : if (!(flags & NIX_TX_NEED_EXT_HDR) &&
1073 : : !(flags & NIX_TX_OFFLOAD_TSTAMP_F)) {
1074 : : /* No segments in 4 consecutive packets. */
1075 : : if ((segdw[0] + segdw[1] + segdw[2] + segdw[3]) <= 8) {
1076 : : do {
1077 : : vst1q_u64(lmt_addr, cmd0[0]);
1078 : : vst1q_u64(lmt_addr + 2, cmd1[0]);
1079 : : vst1q_u64(lmt_addr + 4, cmd0[1]);
1080 : : vst1q_u64(lmt_addr + 6, cmd1[1]);
1081 : : vst1q_u64(lmt_addr + 8, cmd0[2]);
1082 : : vst1q_u64(lmt_addr + 10, cmd1[2]);
1083 : : vst1q_u64(lmt_addr + 12, cmd0[3]);
1084 : : vst1q_u64(lmt_addr + 14, cmd1[3]);
1085 : : lmt_status = roc_lmt_submit_ldeor(io_addr);
1086 : : } while (lmt_status == 0);
1087 : :
1088 : : return;
1089 : : }
1090 : : }
1091 : :
1092 : : for (j = 0; j < NIX_DESCS_PER_LOOP;) {
1093 : : /* Fit consecutive packets in same LMTLINE. */
1094 : : if ((segdw[j] + segdw[j + 1]) <= 8) {
1095 : : again0:
1096 : : if ((flags & NIX_TX_NEED_EXT_HDR) &&
1097 : : (flags & NIX_TX_OFFLOAD_TSTAMP_F)) {
1098 : : vst1q_u64(lmt_addr, cmd0[j]);
1099 : : vst1q_u64(lmt_addr + 2, cmd2[j]);
1100 : : vst1q_u64(lmt_addr + 4, cmd1[j]);
1101 : : /* Copy segs */
1102 : : off = segdw[j] - 4;
1103 : : roc_lmt_mov_seg(lmt_addr + 6, slist[j], off);
1104 : : off <<= 1;
1105 : : vst1q_u64(lmt_addr + 6 + off, cmd3[j]);
1106 : :
1107 : : vst1q_u64(lmt_addr + 8 + off, cmd0[j + 1]);
1108 : : vst1q_u64(lmt_addr + 10 + off, cmd2[j + 1]);
1109 : : vst1q_u64(lmt_addr + 12 + off, cmd1[j + 1]);
1110 : : roc_lmt_mov_seg(lmt_addr + 14 + off,
1111 : : slist[j + 1], segdw[j + 1] - 4);
1112 : : off += ((segdw[j + 1] - 4) << 1);
1113 : : vst1q_u64(lmt_addr + 14 + off, cmd3[j + 1]);
1114 : : } else if (flags & NIX_TX_NEED_EXT_HDR) {
1115 : : vst1q_u64(lmt_addr, cmd0[j]);
1116 : : vst1q_u64(lmt_addr + 2, cmd2[j]);
1117 : : vst1q_u64(lmt_addr + 4, cmd1[j]);
1118 : : /* Copy segs */
1119 : : off = segdw[j] - 3;
1120 : : roc_lmt_mov_seg(lmt_addr + 6, slist[j], off);
1121 : : off <<= 1;
1122 : : vst1q_u64(lmt_addr + 6 + off, cmd0[j + 1]);
1123 : : vst1q_u64(lmt_addr + 8 + off, cmd2[j + 1]);
1124 : : vst1q_u64(lmt_addr + 10 + off, cmd1[j + 1]);
1125 : : roc_lmt_mov_seg(lmt_addr + 12 + off,
1126 : : slist[j + 1], segdw[j + 1] - 3);
1127 : : } else {
1128 : : vst1q_u64(lmt_addr, cmd0[j]);
1129 : : vst1q_u64(lmt_addr + 2, cmd1[j]);
1130 : : /* Copy segs */
1131 : : off = segdw[j] - 2;
1132 : : roc_lmt_mov_seg(lmt_addr + 4, slist[j], off);
1133 : : off <<= 1;
1134 : : vst1q_u64(lmt_addr + 4 + off, cmd0[j + 1]);
1135 : : vst1q_u64(lmt_addr + 6 + off, cmd1[j + 1]);
1136 : : roc_lmt_mov_seg(lmt_addr + 8 + off,
1137 : : slist[j + 1], segdw[j + 1] - 2);
1138 : : }
1139 : : lmt_status = roc_lmt_submit_ldeor(io_addr);
1140 : : if (lmt_status == 0)
1141 : : goto again0;
1142 : : j += 2;
1143 : : } else {
1144 : : again1:
1145 : : if ((flags & NIX_TX_NEED_EXT_HDR) &&
1146 : : (flags & NIX_TX_OFFLOAD_TSTAMP_F)) {
1147 : : vst1q_u64(lmt_addr, cmd0[j]);
1148 : : vst1q_u64(lmt_addr + 2, cmd2[j]);
1149 : : vst1q_u64(lmt_addr + 4, cmd1[j]);
1150 : : /* Copy segs */
1151 : : off = segdw[j] - 4;
1152 : : roc_lmt_mov_seg(lmt_addr + 6, slist[j], off);
1153 : : off <<= 1;
1154 : : vst1q_u64(lmt_addr + 6 + off, cmd3[j]);
1155 : : } else if (flags & NIX_TX_NEED_EXT_HDR) {
1156 : : vst1q_u64(lmt_addr, cmd0[j]);
1157 : : vst1q_u64(lmt_addr + 2, cmd2[j]);
1158 : : vst1q_u64(lmt_addr + 4, cmd1[j]);
1159 : : /* Copy segs */
1160 : : off = segdw[j] - 3;
1161 : : roc_lmt_mov_seg(lmt_addr + 6, slist[j], off);
1162 : : } else {
1163 : : vst1q_u64(lmt_addr, cmd0[j]);
1164 : : vst1q_u64(lmt_addr + 2, cmd1[j]);
1165 : : /* Copy segs */
1166 : : off = segdw[j] - 2;
1167 : : roc_lmt_mov_seg(lmt_addr + 4, slist[j], off);
1168 : : }
1169 : : lmt_status = roc_lmt_submit_ldeor(io_addr);
1170 : : if (lmt_status == 0)
1171 : : goto again1;
1172 : : j += 1;
1173 : : }
1174 : : }
1175 : : }
1176 : :
1177 : : static __rte_always_inline uint16_t
1178 : : cn9k_nix_xmit_pkts_vector(void *tx_queue, struct rte_mbuf **tx_pkts,
1179 : : uint16_t pkts, uint64_t *cmd, const uint16_t flags)
1180 : : {
1181 : : uint64x2_t dataoff_iova0, dataoff_iova1, dataoff_iova2, dataoff_iova3;
1182 : : uint64x2_t len_olflags0, len_olflags1, len_olflags2, len_olflags3;
1183 : : uint64x2_t cmd0[NIX_DESCS_PER_LOOP], cmd1[NIX_DESCS_PER_LOOP],
1184 : : cmd2[NIX_DESCS_PER_LOOP], cmd3[NIX_DESCS_PER_LOOP];
1185 : : uint64x2_t sendext01_w0 = {0}, sendext23_w0 = {0};
1186 : : uint64x2_t sendext01_w1 = {0}, sendext23_w1 = {0};
1187 : : uint64x2_t sendmem01_w1 = {0}, sendmem23_w1 = {0};
1188 : : uint64_t *mbuf0, *mbuf1, *mbuf2, *mbuf3;
1189 : : uint64x2_t senddesc01_w0, senddesc23_w0;
1190 : : uint64x2_t senddesc01_w1, senddesc23_w1;
1191 : : uint64x2_t sendmem01_w0, sendmem23_w0;
1192 : : uint64x2_t sgdesc01_w0, sgdesc23_w0;
1193 : : uint64x2_t sgdesc01_w1, sgdesc23_w1;
1194 : : struct cn9k_eth_txq *txq = tx_queue;
1195 : : uint64_t *lmt_addr = txq->lmt_addr;
1196 : : rte_iova_t io_addr = txq->io_addr;
1197 : : uint64x2_t ltypes01, ltypes23;
1198 : : struct rte_mbuf *extm = NULL;
1199 : : uint64x2_t xtmp128, ytmp128;
1200 : : uint64x2_t xmask01, xmask23;
1201 : : uint64_t lmt_status, i;
1202 : : uint16_t pkts_left;
1203 : :
1204 : : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F && txq->tx_compl.ena)
1205 : : handle_tx_completion_pkts(txq, 0);
1206 : :
1207 : : NIX_XMIT_FC_OR_RETURN(txq, pkts);
1208 : :
1209 : : pkts_left = pkts & (NIX_DESCS_PER_LOOP - 1);
1210 : : pkts = RTE_ALIGN_FLOOR(pkts, NIX_DESCS_PER_LOOP);
1211 : :
1212 : : /* Reduce the cached count */
1213 : : txq->fc_cache_pkts -= pkts;
1214 : :
1215 : : /* Perform header writes before barrier for TSO */
1216 : : if (flags & NIX_TX_OFFLOAD_TSO_F) {
1217 : : for (i = 0; i < pkts; i++)
1218 : : cn9k_nix_xmit_prepare_tso(tx_pkts[i], flags);
1219 : : }
1220 : :
1221 : : /* Lets commit any changes in the packet here as no further changes
1222 : : * to the packet will be done unless no fast free is enabled.
1223 : : */
1224 : : if (!(flags & NIX_TX_OFFLOAD_MBUF_NOFF_F))
1225 : : rte_io_wmb();
1226 : :
1227 : : senddesc01_w0 = vld1q_dup_u64(&txq->send_hdr_w0);
1228 : : senddesc23_w0 = senddesc01_w0;
1229 : :
1230 : : senddesc01_w1 = vdupq_n_u64(0);
1231 : : senddesc23_w1 = senddesc01_w1;
1232 : : sgdesc01_w0 = vdupq_n_u64((NIX_SUBDC_SG << 60) | BIT_ULL(48));
1233 : : sgdesc23_w0 = sgdesc01_w0;
1234 : :
1235 : : if (flags & NIX_TX_NEED_EXT_HDR) {
1236 : : if (flags & NIX_TX_OFFLOAD_TSTAMP_F) {
1237 : : sendext01_w0 = vdupq_n_u64((NIX_SUBDC_EXT << 60) |
1238 : : BIT_ULL(15));
1239 : : sendmem01_w0 =
1240 : : vdupq_n_u64((NIX_SUBDC_MEM << 60) |
1241 : : (NIX_SENDMEMALG_SETTSTMP << 56));
1242 : : sendmem23_w0 = sendmem01_w0;
1243 : : sendmem01_w1 = vdupq_n_u64(txq->ts_mem);
1244 : : sendmem23_w1 = sendmem01_w1;
1245 : : } else {
1246 : : sendext01_w0 = vdupq_n_u64((NIX_SUBDC_EXT << 60));
1247 : : }
1248 : : sendext23_w0 = sendext01_w0;
1249 : :
1250 : : if (flags & NIX_TX_OFFLOAD_VLAN_QINQ_F)
1251 : : sendext01_w1 = vdupq_n_u64(12 | 12U << 24);
1252 : : else
1253 : : sendext01_w1 = vdupq_n_u64(0);
1254 : : sendext23_w1 = sendext01_w1;
1255 : : }
1256 : :
1257 : : for (i = 0; i < pkts; i += NIX_DESCS_PER_LOOP) {
1258 : : /* Clear lower 32bit of SEND_HDR_W0 and SEND_SG_W0 */
1259 : : senddesc01_w0 =
1260 : : vbicq_u64(senddesc01_w0, vdupq_n_u64(0x800FFFFFFFF));
1261 : : sgdesc01_w0 = vbicq_u64(sgdesc01_w0, vdupq_n_u64(0xFFFFFFFF));
1262 : :
1263 : : senddesc23_w0 = senddesc01_w0;
1264 : : sgdesc23_w0 = sgdesc01_w0;
1265 : :
1266 : : /* Clear vlan enables. */
1267 : : if (flags & NIX_TX_NEED_EXT_HDR) {
1268 : : sendext01_w1 = vbicq_u64(sendext01_w1,
1269 : : vdupq_n_u64(0x3FFFF00FFFF00));
1270 : : sendext23_w1 = sendext01_w1;
1271 : : }
1272 : :
1273 : : if (flags & NIX_TX_OFFLOAD_TSTAMP_F) {
1274 : : /* Reset send mem alg to SETTSTMP from SUB*/
1275 : : sendmem01_w0 = vbicq_u64(sendmem01_w0,
1276 : : vdupq_n_u64(BIT_ULL(59)));
1277 : : /* Reset send mem address to default. */
1278 : : sendmem01_w1 =
1279 : : vbicq_u64(sendmem01_w1, vdupq_n_u64(0xF));
1280 : : sendmem23_w0 = sendmem01_w0;
1281 : : sendmem23_w1 = sendmem01_w1;
1282 : : }
1283 : :
1284 : : if (flags & NIX_TX_OFFLOAD_TSO_F) {
1285 : : /* Clear the LSO enable bit. */
1286 : : sendext01_w0 = vbicq_u64(sendext01_w0,
1287 : : vdupq_n_u64(BIT_ULL(14)));
1288 : : sendext23_w0 = sendext01_w0;
1289 : : }
1290 : :
1291 : : /* Move mbufs to iova */
1292 : : mbuf0 = (uint64_t *)tx_pkts[0];
1293 : : mbuf1 = (uint64_t *)tx_pkts[1];
1294 : : mbuf2 = (uint64_t *)tx_pkts[2];
1295 : : mbuf3 = (uint64_t *)tx_pkts[3];
1296 : :
1297 : : /*
1298 : : * Get mbuf's, olflags, iova, pktlen, dataoff
1299 : : * dataoff_iovaX.D[0] = iova,
1300 : : * dataoff_iovaX.D[1](15:0) = mbuf->dataoff
1301 : : * len_olflagsX.D[0] = ol_flags,
1302 : : * len_olflagsX.D[1](63:32) = mbuf->pkt_len
1303 : : */
1304 : : dataoff_iova0 =
1305 : : vsetq_lane_u64(((struct rte_mbuf *)mbuf0)->data_off, vld1q_u64(mbuf0), 1);
1306 : : len_olflags0 = vld1q_u64(mbuf0 + 3);
1307 : : dataoff_iova1 =
1308 : : vsetq_lane_u64(((struct rte_mbuf *)mbuf1)->data_off, vld1q_u64(mbuf1), 1);
1309 : : len_olflags1 = vld1q_u64(mbuf1 + 3);
1310 : : dataoff_iova2 =
1311 : : vsetq_lane_u64(((struct rte_mbuf *)mbuf2)->data_off, vld1q_u64(mbuf2), 1);
1312 : : len_olflags2 = vld1q_u64(mbuf2 + 3);
1313 : : dataoff_iova3 =
1314 : : vsetq_lane_u64(((struct rte_mbuf *)mbuf3)->data_off, vld1q_u64(mbuf3), 1);
1315 : : len_olflags3 = vld1q_u64(mbuf3 + 3);
1316 : :
1317 : : /* Move mbufs to point pool */
1318 : : mbuf0 = (uint64_t *)((uintptr_t)mbuf0 + offsetof(struct rte_mbuf, pool));
1319 : : mbuf1 = (uint64_t *)((uintptr_t)mbuf1 + offsetof(struct rte_mbuf, pool));
1320 : : mbuf2 = (uint64_t *)((uintptr_t)mbuf2 + offsetof(struct rte_mbuf, pool));
1321 : : mbuf3 = (uint64_t *)((uintptr_t)mbuf3 + offsetof(struct rte_mbuf, pool));
1322 : :
1323 : : if (flags & (NIX_TX_OFFLOAD_OL3_OL4_CSUM_F |
1324 : : NIX_TX_OFFLOAD_L3_L4_CSUM_F)) {
1325 : : /* Get tx_offload for ol2, ol3, l2, l3 lengths */
1326 : : /*
1327 : : * E(8):OL2_LEN(7):OL3_LEN(9):E(24):L3_LEN(9):L2_LEN(7)
1328 : : * E(8):OL2_LEN(7):OL3_LEN(9):E(24):L3_LEN(9):L2_LEN(7)
1329 : : */
1330 : :
1331 : : asm volatile("LD1 {%[a].D}[0],[%[in]]\n\t"
1332 : : : [a] "+w"(senddesc01_w1)
1333 : : : [in] "r"(mbuf0 + 2)
1334 : : : "memory");
1335 : :
1336 : : asm volatile("LD1 {%[a].D}[1],[%[in]]\n\t"
1337 : : : [a] "+w"(senddesc01_w1)
1338 : : : [in] "r"(mbuf1 + 2)
1339 : : : "memory");
1340 : :
1341 : : asm volatile("LD1 {%[b].D}[0],[%[in]]\n\t"
1342 : : : [b] "+w"(senddesc23_w1)
1343 : : : [in] "r"(mbuf2 + 2)
1344 : : : "memory");
1345 : :
1346 : : asm volatile("LD1 {%[b].D}[1],[%[in]]\n\t"
1347 : : : [b] "+w"(senddesc23_w1)
1348 : : : [in] "r"(mbuf3 + 2)
1349 : : : "memory");
1350 : :
1351 : : /* Get pool pointer alone */
1352 : : mbuf0 = (uint64_t *)*mbuf0;
1353 : : mbuf1 = (uint64_t *)*mbuf1;
1354 : : mbuf2 = (uint64_t *)*mbuf2;
1355 : : mbuf3 = (uint64_t *)*mbuf3;
1356 : : } else {
1357 : : /* Get pool pointer alone */
1358 : : mbuf0 = (uint64_t *)*mbuf0;
1359 : : mbuf1 = (uint64_t *)*mbuf1;
1360 : : mbuf2 = (uint64_t *)*mbuf2;
1361 : : mbuf3 = (uint64_t *)*mbuf3;
1362 : : }
1363 : :
1364 : : const uint8x16_t shuf_mask2 = {
1365 : : 0x4, 0x5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1366 : : 0xc, 0xd, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1367 : : };
1368 : : xtmp128 = vzip2q_u64(len_olflags0, len_olflags1);
1369 : : ytmp128 = vzip2q_u64(len_olflags2, len_olflags3);
1370 : :
1371 : : /*
1372 : : * Pick only 16 bits of pktlen preset at bits 63:32
1373 : : * and place them at bits 15:0.
1374 : : */
1375 : : xtmp128 = vqtbl1q_u8(xtmp128, shuf_mask2);
1376 : : ytmp128 = vqtbl1q_u8(ytmp128, shuf_mask2);
1377 : :
1378 : : /* Add pairwise to get dataoff + iova in sgdesc_w1 */
1379 : : sgdesc01_w1 = vpaddq_u64(dataoff_iova0, dataoff_iova1);
1380 : : sgdesc23_w1 = vpaddq_u64(dataoff_iova2, dataoff_iova3);
1381 : :
1382 : : /* Orr both sgdesc_w0 and senddesc_w0 with 16 bits of
1383 : : * pktlen at 15:0 position.
1384 : : */
1385 : : sgdesc01_w0 = vorrq_u64(sgdesc01_w0, xtmp128);
1386 : : sgdesc23_w0 = vorrq_u64(sgdesc23_w0, ytmp128);
1387 : : senddesc01_w0 = vorrq_u64(senddesc01_w0, xtmp128);
1388 : : senddesc23_w0 = vorrq_u64(senddesc23_w0, ytmp128);
1389 : :
1390 : : /* Move mbuf to point to pool_id. */
1391 : : mbuf0 = (uint64_t *)((uintptr_t)mbuf0 +
1392 : : offsetof(struct rte_mempool, pool_id));
1393 : : mbuf1 = (uint64_t *)((uintptr_t)mbuf1 +
1394 : : offsetof(struct rte_mempool, pool_id));
1395 : : mbuf2 = (uint64_t *)((uintptr_t)mbuf2 +
1396 : : offsetof(struct rte_mempool, pool_id));
1397 : : mbuf3 = (uint64_t *)((uintptr_t)mbuf3 +
1398 : : offsetof(struct rte_mempool, pool_id));
1399 : :
1400 : : if ((flags & NIX_TX_OFFLOAD_L3_L4_CSUM_F) &&
1401 : : !(flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F)) {
1402 : : /*
1403 : : * Lookup table to translate ol_flags to
1404 : : * il3/il4 types. But we still use ol3/ol4 types in
1405 : : * senddesc_w1 as only one header processing is enabled.
1406 : : */
1407 : : const uint8x16_t tbl = {
1408 : : /* [0-15] = il4type:il3type */
1409 : : 0x00, /* none */
1410 : : 0x14, /* RTE_MBUF_F_TX_TCP_CKSUM (IPv6 assumed) */
1411 : : 0x24, /* RTE_MBUF_F_TX_SCTP_CKSUM (IPv6 assumed) */
1412 : : 0x34, /* RTE_MBUF_F_TX_UDP_CKSUM (IPv6 assumed) */
1413 : : 0x03, /* RTE_MBUF_F_TX_IP_CKSUM */
1414 : : 0x13, /* RTE_MBUF_F_TX_IP_CKSUM | RTE_MBUF_F_TX_TCP_CKSUM */
1415 : : 0x23, /* RTE_MBUF_F_TX_IP_CKSUM | RTE_MBUF_F_TX_SCTP_CKSUM */
1416 : : 0x33, /* RTE_MBUF_F_TX_IP_CKSUM | RTE_MBUF_F_TX_UDP_CKSUM */
1417 : : 0x02, /* RTE_MBUF_F_TX_IPV4 */
1418 : : 0x12, /* RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_TCP_CKSUM */
1419 : : 0x22, /* RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_SCTP_CKSUM */
1420 : : 0x32, /* RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_UDP_CKSUM */
1421 : : 0x03, /* RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_IP_CKSUM */
1422 : : 0x13, /* RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_IP_CKSUM |
1423 : : * RTE_MBUF_F_TX_TCP_CKSUM
1424 : : */
1425 : : 0x23, /* RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_IP_CKSUM |
1426 : : * RTE_MBUF_F_TX_SCTP_CKSUM
1427 : : */
1428 : : 0x33, /* RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_IP_CKSUM |
1429 : : * RTE_MBUF_F_TX_UDP_CKSUM
1430 : : */
1431 : : };
1432 : :
1433 : : /* Extract olflags to translate to iltypes */
1434 : : xtmp128 = vzip1q_u64(len_olflags0, len_olflags1);
1435 : : ytmp128 = vzip1q_u64(len_olflags2, len_olflags3);
1436 : :
1437 : : /*
1438 : : * E(47):L3_LEN(9):L2_LEN(7+z)
1439 : : * E(47):L3_LEN(9):L2_LEN(7+z)
1440 : : */
1441 : : senddesc01_w1 = vshlq_n_u64(senddesc01_w1, 1);
1442 : : senddesc23_w1 = vshlq_n_u64(senddesc23_w1, 1);
1443 : :
1444 : : /* Move OLFLAGS bits 55:52 to 51:48
1445 : : * with zeros preprended on the byte and rest
1446 : : * don't care
1447 : : */
1448 : : xtmp128 = vshrq_n_u8(xtmp128, 4);
1449 : : ytmp128 = vshrq_n_u8(ytmp128, 4);
1450 : : /*
1451 : : * E(48):L3_LEN(8):L2_LEN(z+7)
1452 : : * E(48):L3_LEN(8):L2_LEN(z+7)
1453 : : */
1454 : : const int8x16_t tshft3 = {
1455 : : -1, 0, 8, 8, 8, 8, 8, 8,
1456 : : -1, 0, 8, 8, 8, 8, 8, 8,
1457 : : };
1458 : :
1459 : : senddesc01_w1 = vshlq_u8(senddesc01_w1, tshft3);
1460 : : senddesc23_w1 = vshlq_u8(senddesc23_w1, tshft3);
1461 : :
1462 : : /* Do the lookup */
1463 : : ltypes01 = vqtbl1q_u8(tbl, xtmp128);
1464 : : ltypes23 = vqtbl1q_u8(tbl, ytmp128);
1465 : :
1466 : : /* Pick only relevant fields i.e Bit 48:55 of iltype
1467 : : * and place it in ol3/ol4type of senddesc_w1
1468 : : */
1469 : : const uint8x16_t shuf_mask0 = {
1470 : : 0xFF, 0xFF, 0xFF, 0xFF, 0x6, 0xFF, 0xFF, 0xFF,
1471 : : 0xFF, 0xFF, 0xFF, 0xFF, 0xE, 0xFF, 0xFF, 0xFF,
1472 : : };
1473 : :
1474 : : ltypes01 = vqtbl1q_u8(ltypes01, shuf_mask0);
1475 : : ltypes23 = vqtbl1q_u8(ltypes23, shuf_mask0);
1476 : :
1477 : : /* Prepare ol4ptr, ol3ptr from ol3len, ol2len.
1478 : : * a [E(32):E(16):OL3(8):OL2(8)]
1479 : : * a = a + (a << 8)
1480 : : * a [E(32):E(16):(OL3+OL2):OL2]
1481 : : * => E(32):E(16)::OL4PTR(8):OL3PTR(8)
1482 : : */
1483 : : senddesc01_w1 = vaddq_u8(senddesc01_w1,
1484 : : vshlq_n_u16(senddesc01_w1, 8));
1485 : : senddesc23_w1 = vaddq_u8(senddesc23_w1,
1486 : : vshlq_n_u16(senddesc23_w1, 8));
1487 : :
1488 : : /* Move ltypes to senddesc*_w1 */
1489 : : senddesc01_w1 = vorrq_u64(senddesc01_w1, ltypes01);
1490 : : senddesc23_w1 = vorrq_u64(senddesc23_w1, ltypes23);
1491 : : } else if (!(flags & NIX_TX_OFFLOAD_L3_L4_CSUM_F) &&
1492 : : (flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F)) {
1493 : : /*
1494 : : * Lookup table to translate ol_flags to
1495 : : * ol3/ol4 types.
1496 : : */
1497 : :
1498 : : const uint8x16_t tbl = {
1499 : : /* [0-15] = ol4type:ol3type */
1500 : : 0x00, /* none */
1501 : : 0x03, /* OUTER_IP_CKSUM */
1502 : : 0x02, /* OUTER_IPV4 */
1503 : : 0x03, /* OUTER_IPV4 | OUTER_IP_CKSUM */
1504 : : 0x04, /* OUTER_IPV6 */
1505 : : 0x00, /* OUTER_IPV6 | OUTER_IP_CKSUM */
1506 : : 0x00, /* OUTER_IPV6 | OUTER_IPV4 */
1507 : : 0x00, /* OUTER_IPV6 | OUTER_IPV4 |
1508 : : * OUTER_IP_CKSUM
1509 : : */
1510 : : 0x00, /* OUTER_UDP_CKSUM */
1511 : : 0x33, /* OUTER_UDP_CKSUM | OUTER_IP_CKSUM */
1512 : : 0x32, /* OUTER_UDP_CKSUM | OUTER_IPV4 */
1513 : : 0x33, /* OUTER_UDP_CKSUM | OUTER_IPV4 |
1514 : : * OUTER_IP_CKSUM
1515 : : */
1516 : : 0x34, /* OUTER_UDP_CKSUM | OUTER_IPV6 */
1517 : : 0x00, /* OUTER_UDP_CKSUM | OUTER_IPV6 |
1518 : : * OUTER_IP_CKSUM
1519 : : */
1520 : : 0x00, /* OUTER_UDP_CKSUM | OUTER_IPV6 |
1521 : : * OUTER_IPV4
1522 : : */
1523 : : 0x00, /* OUTER_UDP_CKSUM | OUTER_IPV6 |
1524 : : * OUTER_IPV4 | OUTER_IP_CKSUM
1525 : : */
1526 : : };
1527 : :
1528 : : /* Extract olflags to translate to iltypes */
1529 : : xtmp128 = vzip1q_u64(len_olflags0, len_olflags1);
1530 : : ytmp128 = vzip1q_u64(len_olflags2, len_olflags3);
1531 : :
1532 : : /*
1533 : : * E(47):OL3_LEN(9):OL2_LEN(7+z)
1534 : : * E(47):OL3_LEN(9):OL2_LEN(7+z)
1535 : : */
1536 : : const uint8x16_t shuf_mask5 = {
1537 : : 0x6, 0x5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1538 : : 0xE, 0xD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1539 : : };
1540 : : senddesc01_w1 = vqtbl1q_u8(senddesc01_w1, shuf_mask5);
1541 : : senddesc23_w1 = vqtbl1q_u8(senddesc23_w1, shuf_mask5);
1542 : :
1543 : : /* Extract outer ol flags only */
1544 : : const uint64x2_t o_cksum_mask = {
1545 : : 0x1C00020000000000,
1546 : : 0x1C00020000000000,
1547 : : };
1548 : :
1549 : : xtmp128 = vandq_u64(xtmp128, o_cksum_mask);
1550 : : ytmp128 = vandq_u64(ytmp128, o_cksum_mask);
1551 : :
1552 : : /* Extract OUTER_UDP_CKSUM bit 41 and
1553 : : * move it to bit 61
1554 : : */
1555 : :
1556 : : xtmp128 = xtmp128 | vshlq_n_u64(xtmp128, 20);
1557 : : ytmp128 = ytmp128 | vshlq_n_u64(ytmp128, 20);
1558 : :
1559 : : /* Shift oltype by 2 to start nibble from BIT(56)
1560 : : * instead of BIT(58)
1561 : : */
1562 : : xtmp128 = vshrq_n_u8(xtmp128, 2);
1563 : : ytmp128 = vshrq_n_u8(ytmp128, 2);
1564 : : /*
1565 : : * E(48):L3_LEN(8):L2_LEN(z+7)
1566 : : * E(48):L3_LEN(8):L2_LEN(z+7)
1567 : : */
1568 : : const int8x16_t tshft3 = {
1569 : : -1, 0, 8, 8, 8, 8, 8, 8,
1570 : : -1, 0, 8, 8, 8, 8, 8, 8,
1571 : : };
1572 : :
1573 : : senddesc01_w1 = vshlq_u8(senddesc01_w1, tshft3);
1574 : : senddesc23_w1 = vshlq_u8(senddesc23_w1, tshft3);
1575 : :
1576 : : /* Do the lookup */
1577 : : ltypes01 = vqtbl1q_u8(tbl, xtmp128);
1578 : : ltypes23 = vqtbl1q_u8(tbl, ytmp128);
1579 : :
1580 : : /* Pick only relevant fields i.e Bit 56:63 of oltype
1581 : : * and place it in ol3/ol4type of senddesc_w1
1582 : : */
1583 : : const uint8x16_t shuf_mask0 = {
1584 : : 0xFF, 0xFF, 0xFF, 0xFF, 0x7, 0xFF, 0xFF, 0xFF,
1585 : : 0xFF, 0xFF, 0xFF, 0xFF, 0xF, 0xFF, 0xFF, 0xFF,
1586 : : };
1587 : :
1588 : : ltypes01 = vqtbl1q_u8(ltypes01, shuf_mask0);
1589 : : ltypes23 = vqtbl1q_u8(ltypes23, shuf_mask0);
1590 : :
1591 : : /* Prepare ol4ptr, ol3ptr from ol3len, ol2len.
1592 : : * a [E(32):E(16):OL3(8):OL2(8)]
1593 : : * a = a + (a << 8)
1594 : : * a [E(32):E(16):(OL3+OL2):OL2]
1595 : : * => E(32):E(16)::OL4PTR(8):OL3PTR(8)
1596 : : */
1597 : : senddesc01_w1 = vaddq_u8(senddesc01_w1,
1598 : : vshlq_n_u16(senddesc01_w1, 8));
1599 : : senddesc23_w1 = vaddq_u8(senddesc23_w1,
1600 : : vshlq_n_u16(senddesc23_w1, 8));
1601 : :
1602 : : /* Move ltypes to senddesc*_w1 */
1603 : : senddesc01_w1 = vorrq_u64(senddesc01_w1, ltypes01);
1604 : : senddesc23_w1 = vorrq_u64(senddesc23_w1, ltypes23);
1605 : : } else if ((flags & NIX_TX_OFFLOAD_L3_L4_CSUM_F) &&
1606 : : (flags & NIX_TX_OFFLOAD_OL3_OL4_CSUM_F)) {
1607 : : /* Lookup table to translate ol_flags to
1608 : : * ol4type, ol3type, il4type, il3type of senddesc_w1
1609 : : */
1610 : : const uint8x16x2_t tbl = {{
1611 : : {
1612 : : /* [0-15] = il4type:il3type */
1613 : : 0x00, /* none */
1614 : : 0x14, /* RTE_MBUF_F_TX_TCP_CKSUM (IPv6) */
1615 : : 0x24, /* RTE_MBUF_F_TX_SCTP_CKSUM (IPv6) */
1616 : : 0x34, /* RTE_MBUF_F_TX_UDP_CKSUM (IPv6) */
1617 : : 0x03, /* RTE_MBUF_F_TX_IP_CKSUM */
1618 : : 0x13, /* RTE_MBUF_F_TX_IP_CKSUM |
1619 : : * RTE_MBUF_F_TX_TCP_CKSUM
1620 : : */
1621 : : 0x23, /* RTE_MBUF_F_TX_IP_CKSUM |
1622 : : * RTE_MBUF_F_TX_SCTP_CKSUM
1623 : : */
1624 : : 0x33, /* RTE_MBUF_F_TX_IP_CKSUM |
1625 : : * RTE_MBUF_F_TX_UDP_CKSUM
1626 : : */
1627 : : 0x02, /* RTE_MBUF_F_TX_IPV4 */
1628 : : 0x12, /* RTE_MBUF_F_TX_IPV4 |
1629 : : * RTE_MBUF_F_TX_TCP_CKSUM
1630 : : */
1631 : : 0x22, /* RTE_MBUF_F_TX_IPV4 |
1632 : : * RTE_MBUF_F_TX_SCTP_CKSUM
1633 : : */
1634 : : 0x32, /* RTE_MBUF_F_TX_IPV4 |
1635 : : * RTE_MBUF_F_TX_UDP_CKSUM
1636 : : */
1637 : : 0x03, /* RTE_MBUF_F_TX_IPV4 |
1638 : : * RTE_MBUF_F_TX_IP_CKSUM
1639 : : */
1640 : : 0x13, /* RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_IP_CKSUM |
1641 : : * RTE_MBUF_F_TX_TCP_CKSUM
1642 : : */
1643 : : 0x23, /* RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_IP_CKSUM |
1644 : : * RTE_MBUF_F_TX_SCTP_CKSUM
1645 : : */
1646 : : 0x33, /* RTE_MBUF_F_TX_IPV4 | RTE_MBUF_F_TX_IP_CKSUM |
1647 : : * RTE_MBUF_F_TX_UDP_CKSUM
1648 : : */
1649 : : },
1650 : :
1651 : : {
1652 : : /* [16-31] = ol4type:ol3type */
1653 : : 0x00, /* none */
1654 : : 0x03, /* OUTER_IP_CKSUM */
1655 : : 0x02, /* OUTER_IPV4 */
1656 : : 0x03, /* OUTER_IPV4 | OUTER_IP_CKSUM */
1657 : : 0x04, /* OUTER_IPV6 */
1658 : : 0x00, /* OUTER_IPV6 | OUTER_IP_CKSUM */
1659 : : 0x00, /* OUTER_IPV6 | OUTER_IPV4 */
1660 : : 0x00, /* OUTER_IPV6 | OUTER_IPV4 |
1661 : : * OUTER_IP_CKSUM
1662 : : */
1663 : : 0x00, /* OUTER_UDP_CKSUM */
1664 : : 0x33, /* OUTER_UDP_CKSUM |
1665 : : * OUTER_IP_CKSUM
1666 : : */
1667 : : 0x32, /* OUTER_UDP_CKSUM |
1668 : : * OUTER_IPV4
1669 : : */
1670 : : 0x33, /* OUTER_UDP_CKSUM |
1671 : : * OUTER_IPV4 | OUTER_IP_CKSUM
1672 : : */
1673 : : 0x34, /* OUTER_UDP_CKSUM |
1674 : : * OUTER_IPV6
1675 : : */
1676 : : 0x00, /* OUTER_UDP_CKSUM | OUTER_IPV6 |
1677 : : * OUTER_IP_CKSUM
1678 : : */
1679 : : 0x00, /* OUTER_UDP_CKSUM | OUTER_IPV6 |
1680 : : * OUTER_IPV4
1681 : : */
1682 : : 0x00, /* OUTER_UDP_CKSUM | OUTER_IPV6 |
1683 : : * OUTER_IPV4 | OUTER_IP_CKSUM
1684 : : */
1685 : : },
1686 : : }};
1687 : :
1688 : : /* Extract olflags to translate to oltype & iltype */
1689 : : xtmp128 = vzip1q_u64(len_olflags0, len_olflags1);
1690 : : ytmp128 = vzip1q_u64(len_olflags2, len_olflags3);
1691 : :
1692 : : /*
1693 : : * E(8):OL2_LN(7):OL3_LN(9):E(23):L3_LN(9):L2_LN(7+z)
1694 : : * E(8):OL2_LN(7):OL3_LN(9):E(23):L3_LN(9):L2_LN(7+z)
1695 : : */
1696 : : const uint32x4_t tshft_4 = {
1697 : : 1,
1698 : : 0,
1699 : : 1,
1700 : : 0,
1701 : : };
1702 : : senddesc01_w1 = vshlq_u32(senddesc01_w1, tshft_4);
1703 : : senddesc23_w1 = vshlq_u32(senddesc23_w1, tshft_4);
1704 : :
1705 : : /*
1706 : : * E(32):L3_LEN(8):L2_LEN(7+Z):OL3_LEN(8):OL2_LEN(7+Z)
1707 : : * E(32):L3_LEN(8):L2_LEN(7+Z):OL3_LEN(8):OL2_LEN(7+Z)
1708 : : */
1709 : : const uint8x16_t shuf_mask5 = {
1710 : : 0x6, 0x5, 0x0, 0x1, 0xFF, 0xFF, 0xFF, 0xFF,
1711 : : 0xE, 0xD, 0x8, 0x9, 0xFF, 0xFF, 0xFF, 0xFF,
1712 : : };
1713 : : senddesc01_w1 = vqtbl1q_u8(senddesc01_w1, shuf_mask5);
1714 : : senddesc23_w1 = vqtbl1q_u8(senddesc23_w1, shuf_mask5);
1715 : :
1716 : : /* Extract outer and inner header ol_flags */
1717 : : const uint64x2_t oi_cksum_mask = {
1718 : : 0x1CF0020000000000,
1719 : : 0x1CF0020000000000,
1720 : : };
1721 : :
1722 : : xtmp128 = vandq_u64(xtmp128, oi_cksum_mask);
1723 : : ytmp128 = vandq_u64(ytmp128, oi_cksum_mask);
1724 : :
1725 : : /* Extract OUTER_UDP_CKSUM bit 41 and
1726 : : * move it to bit 61
1727 : : */
1728 : :
1729 : : xtmp128 = xtmp128 | vshlq_n_u64(xtmp128, 20);
1730 : : ytmp128 = ytmp128 | vshlq_n_u64(ytmp128, 20);
1731 : :
1732 : : /* Shift right oltype by 2 and iltype by 4
1733 : : * to start oltype nibble from BIT(58)
1734 : : * instead of BIT(56) and iltype nibble from BIT(48)
1735 : : * instead of BIT(52).
1736 : : */
1737 : : const int8x16_t tshft5 = {
1738 : : 8, 8, 8, 8, 8, 8, -4, -2,
1739 : : 8, 8, 8, 8, 8, 8, -4, -2,
1740 : : };
1741 : :
1742 : : xtmp128 = vshlq_u8(xtmp128, tshft5);
1743 : : ytmp128 = vshlq_u8(ytmp128, tshft5);
1744 : : /*
1745 : : * E(32):L3_LEN(8):L2_LEN(8):OL3_LEN(8):OL2_LEN(8)
1746 : : * E(32):L3_LEN(8):L2_LEN(8):OL3_LEN(8):OL2_LEN(8)
1747 : : */
1748 : : const int8x16_t tshft3 = {
1749 : : -1, 0, -1, 0, 0, 0, 0, 0,
1750 : : -1, 0, -1, 0, 0, 0, 0, 0,
1751 : : };
1752 : :
1753 : : senddesc01_w1 = vshlq_u8(senddesc01_w1, tshft3);
1754 : : senddesc23_w1 = vshlq_u8(senddesc23_w1, tshft3);
1755 : :
1756 : : /* Mark Bit(4) of oltype */
1757 : : const uint64x2_t oi_cksum_mask2 = {
1758 : : 0x1000000000000000,
1759 : : 0x1000000000000000,
1760 : : };
1761 : :
1762 : : xtmp128 = vorrq_u64(xtmp128, oi_cksum_mask2);
1763 : : ytmp128 = vorrq_u64(ytmp128, oi_cksum_mask2);
1764 : :
1765 : : /* Do the lookup */
1766 : : ltypes01 = vqtbl2q_u8(tbl, xtmp128);
1767 : : ltypes23 = vqtbl2q_u8(tbl, ytmp128);
1768 : :
1769 : : /* Pick only relevant fields i.e Bit 48:55 of iltype and
1770 : : * Bit 56:63 of oltype and place it in corresponding
1771 : : * place in senddesc_w1.
1772 : : */
1773 : : const uint8x16_t shuf_mask0 = {
1774 : : 0xFF, 0xFF, 0xFF, 0xFF, 0x7, 0x6, 0xFF, 0xFF,
1775 : : 0xFF, 0xFF, 0xFF, 0xFF, 0xF, 0xE, 0xFF, 0xFF,
1776 : : };
1777 : :
1778 : : ltypes01 = vqtbl1q_u8(ltypes01, shuf_mask0);
1779 : : ltypes23 = vqtbl1q_u8(ltypes23, shuf_mask0);
1780 : :
1781 : : /* Prepare l4ptr, l3ptr, ol4ptr, ol3ptr from
1782 : : * l3len, l2len, ol3len, ol2len.
1783 : : * a [E(32):L3(8):L2(8):OL3(8):OL2(8)]
1784 : : * a = a + (a << 8)
1785 : : * a [E:(L3+L2):(L2+OL3):(OL3+OL2):OL2]
1786 : : * a = a + (a << 16)
1787 : : * a [E:(L3+L2+OL3+OL2):(L2+OL3+OL2):(OL3+OL2):OL2]
1788 : : * => E(32):IL4PTR(8):IL3PTR(8):OL4PTR(8):OL3PTR(8)
1789 : : */
1790 : : senddesc01_w1 = vaddq_u8(senddesc01_w1,
1791 : : vshlq_n_u32(senddesc01_w1, 8));
1792 : : senddesc23_w1 = vaddq_u8(senddesc23_w1,
1793 : : vshlq_n_u32(senddesc23_w1, 8));
1794 : :
1795 : : /* Continue preparing l4ptr, l3ptr, ol4ptr, ol3ptr */
1796 : : senddesc01_w1 = vaddq_u8(
1797 : : senddesc01_w1, vshlq_n_u32(senddesc01_w1, 16));
1798 : : senddesc23_w1 = vaddq_u8(
1799 : : senddesc23_w1, vshlq_n_u32(senddesc23_w1, 16));
1800 : :
1801 : : /* Move ltypes to senddesc*_w1 */
1802 : : senddesc01_w1 = vorrq_u64(senddesc01_w1, ltypes01);
1803 : : senddesc23_w1 = vorrq_u64(senddesc23_w1, ltypes23);
1804 : : }
1805 : :
1806 : : xmask01 = vdupq_n_u64(0);
1807 : : xmask23 = xmask01;
1808 : : asm volatile("LD1 {%[a].H}[0],[%[in]]\n\t"
1809 : : : [a] "+w"(xmask01)
1810 : : : [in] "r"(mbuf0)
1811 : : : "memory");
1812 : :
1813 : : asm volatile("LD1 {%[a].H}[4],[%[in]]\n\t"
1814 : : : [a] "+w"(xmask01)
1815 : : : [in] "r"(mbuf1)
1816 : : : "memory");
1817 : :
1818 : : asm volatile("LD1 {%[b].H}[0],[%[in]]\n\t"
1819 : : : [b] "+w"(xmask23)
1820 : : : [in] "r"(mbuf2)
1821 : : : "memory");
1822 : :
1823 : : asm volatile("LD1 {%[b].H}[4],[%[in]]\n\t"
1824 : : : [b] "+w"(xmask23)
1825 : : : [in] "r"(mbuf3)
1826 : : : "memory");
1827 : : xmask01 = vshlq_n_u64(xmask01, 20);
1828 : : xmask23 = vshlq_n_u64(xmask23, 20);
1829 : :
1830 : : senddesc01_w0 = vorrq_u64(senddesc01_w0, xmask01);
1831 : : senddesc23_w0 = vorrq_u64(senddesc23_w0, xmask23);
1832 : :
1833 : : if (flags & NIX_TX_OFFLOAD_VLAN_QINQ_F) {
1834 : : /* Tx ol_flag for vlan. */
1835 : : const uint64x2_t olv = {RTE_MBUF_F_TX_VLAN, RTE_MBUF_F_TX_VLAN};
1836 : : /* Bit enable for VLAN1 */
1837 : : const uint64x2_t mlv = {BIT_ULL(49), BIT_ULL(49)};
1838 : : /* Tx ol_flag for QnQ. */
1839 : : const uint64x2_t olq = {RTE_MBUF_F_TX_QINQ, RTE_MBUF_F_TX_QINQ};
1840 : : /* Bit enable for VLAN0 */
1841 : : const uint64x2_t mlq = {BIT_ULL(48), BIT_ULL(48)};
1842 : : /* Load vlan values from packet. outer is VLAN 0 */
1843 : : uint64x2_t ext01 = {
1844 : : ((uint32_t)tx_pkts[0]->vlan_tci_outer) << 8 |
1845 : : ((uint64_t)tx_pkts[0]->vlan_tci) << 32,
1846 : : ((uint32_t)tx_pkts[1]->vlan_tci_outer) << 8 |
1847 : : ((uint64_t)tx_pkts[1]->vlan_tci) << 32,
1848 : : };
1849 : : uint64x2_t ext23 = {
1850 : : ((uint32_t)tx_pkts[2]->vlan_tci_outer) << 8 |
1851 : : ((uint64_t)tx_pkts[2]->vlan_tci) << 32,
1852 : : ((uint32_t)tx_pkts[3]->vlan_tci_outer) << 8 |
1853 : : ((uint64_t)tx_pkts[3]->vlan_tci) << 32,
1854 : : };
1855 : :
1856 : : /* Get ol_flags of the packets. */
1857 : : xtmp128 = vzip1q_u64(len_olflags0, len_olflags1);
1858 : : ytmp128 = vzip1q_u64(len_olflags2, len_olflags3);
1859 : :
1860 : : /* ORR vlan outer/inner values into cmd. */
1861 : : sendext01_w1 = vorrq_u64(sendext01_w1, ext01);
1862 : : sendext23_w1 = vorrq_u64(sendext23_w1, ext23);
1863 : :
1864 : : /* Test for offload enable bits and generate masks. */
1865 : : xtmp128 = vorrq_u64(vandq_u64(vtstq_u64(xtmp128, olv),
1866 : : mlv),
1867 : : vandq_u64(vtstq_u64(xtmp128, olq),
1868 : : mlq));
1869 : : ytmp128 = vorrq_u64(vandq_u64(vtstq_u64(ytmp128, olv),
1870 : : mlv),
1871 : : vandq_u64(vtstq_u64(ytmp128, olq),
1872 : : mlq));
1873 : :
1874 : : /* Set vlan enable bits into cmd based on mask. */
1875 : : sendext01_w1 = vorrq_u64(sendext01_w1, xtmp128);
1876 : : sendext23_w1 = vorrq_u64(sendext23_w1, ytmp128);
1877 : : }
1878 : :
1879 : : if (flags & NIX_TX_OFFLOAD_TSTAMP_F) {
1880 : : /* Tx ol_flag for timestamp. */
1881 : : const uint64x2_t olf = {RTE_MBUF_F_TX_IEEE1588_TMST,
1882 : : RTE_MBUF_F_TX_IEEE1588_TMST};
1883 : : /* Set send mem alg to SUB. */
1884 : : const uint64x2_t alg = {BIT_ULL(59), BIT_ULL(59)};
1885 : : /* Increment send mem address by 8. */
1886 : : const uint64x2_t addr = {0x8, 0x8};
1887 : :
1888 : : xtmp128 = vzip1q_u64(len_olflags0, len_olflags1);
1889 : : ytmp128 = vzip1q_u64(len_olflags2, len_olflags3);
1890 : :
1891 : : /* Check if timestamp is requested and generate inverted
1892 : : * mask as we need not make any changes to default cmd
1893 : : * value.
1894 : : */
1895 : : xtmp128 = vmvnq_u32(vtstq_u64(olf, xtmp128));
1896 : : ytmp128 = vmvnq_u32(vtstq_u64(olf, ytmp128));
1897 : :
1898 : : /* Change send mem address to an 8 byte offset when
1899 : : * TSTMP is disabled.
1900 : : */
1901 : : sendmem01_w1 = vaddq_u64(sendmem01_w1,
1902 : : vandq_u64(xtmp128, addr));
1903 : : sendmem23_w1 = vaddq_u64(sendmem23_w1,
1904 : : vandq_u64(ytmp128, addr));
1905 : : /* Change send mem alg to SUB when TSTMP is disabled. */
1906 : : sendmem01_w0 = vorrq_u64(sendmem01_w0,
1907 : : vandq_u64(xtmp128, alg));
1908 : : sendmem23_w0 = vorrq_u64(sendmem23_w0,
1909 : : vandq_u64(ytmp128, alg));
1910 : :
1911 : : cmd3[0] = vzip1q_u64(sendmem01_w0, sendmem01_w1);
1912 : : cmd3[1] = vzip2q_u64(sendmem01_w0, sendmem01_w1);
1913 : : cmd3[2] = vzip1q_u64(sendmem23_w0, sendmem23_w1);
1914 : : cmd3[3] = vzip2q_u64(sendmem23_w0, sendmem23_w1);
1915 : : }
1916 : :
1917 : : if (flags & NIX_TX_OFFLOAD_TSO_F) {
1918 : : uint64_t sx_w0[NIX_DESCS_PER_LOOP];
1919 : : uint64_t sd_w1[NIX_DESCS_PER_LOOP];
1920 : :
1921 : : /* Extract SD W1 as we need to set L4 types. */
1922 : : vst1q_u64(sd_w1, senddesc01_w1);
1923 : : vst1q_u64(sd_w1 + 2, senddesc23_w1);
1924 : :
1925 : : /* Extract SX W0 as we need to set LSO fields. */
1926 : : vst1q_u64(sx_w0, sendext01_w0);
1927 : : vst1q_u64(sx_w0 + 2, sendext23_w0);
1928 : :
1929 : : /* Extract ol_flags. */
1930 : : xtmp128 = vzip1q_u64(len_olflags0, len_olflags1);
1931 : : ytmp128 = vzip1q_u64(len_olflags2, len_olflags3);
1932 : :
1933 : : /* Prepare individual mbufs. */
1934 : : cn9k_nix_prepare_tso(tx_pkts[0],
1935 : : (union nix_send_hdr_w1_u *)&sd_w1[0],
1936 : : (union nix_send_ext_w0_u *)&sx_w0[0],
1937 : : vgetq_lane_u64(xtmp128, 0), flags);
1938 : :
1939 : : cn9k_nix_prepare_tso(tx_pkts[1],
1940 : : (union nix_send_hdr_w1_u *)&sd_w1[1],
1941 : : (union nix_send_ext_w0_u *)&sx_w0[1],
1942 : : vgetq_lane_u64(xtmp128, 1), flags);
1943 : :
1944 : : cn9k_nix_prepare_tso(tx_pkts[2],
1945 : : (union nix_send_hdr_w1_u *)&sd_w1[2],
1946 : : (union nix_send_ext_w0_u *)&sx_w0[2],
1947 : : vgetq_lane_u64(ytmp128, 0), flags);
1948 : :
1949 : : cn9k_nix_prepare_tso(tx_pkts[3],
1950 : : (union nix_send_hdr_w1_u *)&sd_w1[3],
1951 : : (union nix_send_ext_w0_u *)&sx_w0[3],
1952 : : vgetq_lane_u64(ytmp128, 1), flags);
1953 : :
1954 : : senddesc01_w1 = vld1q_u64(sd_w1);
1955 : : senddesc23_w1 = vld1q_u64(sd_w1 + 2);
1956 : :
1957 : : sendext01_w0 = vld1q_u64(sx_w0);
1958 : : sendext23_w0 = vld1q_u64(sx_w0 + 2);
1959 : : }
1960 : :
1961 : : if ((flags & NIX_TX_OFFLOAD_MBUF_NOFF_F) &&
1962 : : !(flags & NIX_TX_MULTI_SEG_F)) {
1963 : : /* Set don't free bit if reference count > 1 */
1964 : : cn9k_nix_prefree_seg_vec(tx_pkts, &extm, txq, &senddesc01_w0,
1965 : : &senddesc23_w0, &senddesc01_w1, &senddesc23_w1);
1966 : : /* Ensuring mbuf fields which got updated in
1967 : : * cnxk_nix_prefree_seg are written before LMTST.
1968 : : */
1969 : : rte_io_wmb();
1970 : : } else if (!(flags & NIX_TX_MULTI_SEG_F)) {
1971 : : /* Move mbufs to iova */
1972 : : mbuf0 = (uint64_t *)tx_pkts[0];
1973 : : mbuf1 = (uint64_t *)tx_pkts[1];
1974 : : mbuf2 = (uint64_t *)tx_pkts[2];
1975 : : mbuf3 = (uint64_t *)tx_pkts[3];
1976 : :
1977 : : /* Mark mempool object as "put" since
1978 : : * it is freed by NIX
1979 : : */
1980 : : RTE_MEMPOOL_CHECK_COOKIES(
1981 : : ((struct rte_mbuf *)mbuf0)->pool,
1982 : : (void **)&mbuf0, 1, 0);
1983 : :
1984 : : RTE_MEMPOOL_CHECK_COOKIES(
1985 : : ((struct rte_mbuf *)mbuf1)->pool,
1986 : : (void **)&mbuf1, 1, 0);
1987 : :
1988 : : RTE_MEMPOOL_CHECK_COOKIES(
1989 : : ((struct rte_mbuf *)mbuf2)->pool,
1990 : : (void **)&mbuf2, 1, 0);
1991 : :
1992 : : RTE_MEMPOOL_CHECK_COOKIES(
1993 : : ((struct rte_mbuf *)mbuf3)->pool,
1994 : : (void **)&mbuf3, 1, 0);
1995 : : #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
1996 : : rte_io_wmb();
1997 : : #endif
1998 : : }
1999 : :
2000 : : /* Create 4W cmd for 4 mbufs (sendhdr, sgdesc) */
2001 : : cmd0[0] = vzip1q_u64(senddesc01_w0, senddesc01_w1);
2002 : : cmd0[1] = vzip2q_u64(senddesc01_w0, senddesc01_w1);
2003 : : cmd0[2] = vzip1q_u64(senddesc23_w0, senddesc23_w1);
2004 : : cmd0[3] = vzip2q_u64(senddesc23_w0, senddesc23_w1);
2005 : :
2006 : : cmd1[0] = vzip1q_u64(sgdesc01_w0, sgdesc01_w1);
2007 : : cmd1[1] = vzip2q_u64(sgdesc01_w0, sgdesc01_w1);
2008 : : cmd1[2] = vzip1q_u64(sgdesc23_w0, sgdesc23_w1);
2009 : : cmd1[3] = vzip2q_u64(sgdesc23_w0, sgdesc23_w1);
2010 : :
2011 : : if (flags & NIX_TX_NEED_EXT_HDR) {
2012 : : cmd2[0] = vzip1q_u64(sendext01_w0, sendext01_w1);
2013 : : cmd2[1] = vzip2q_u64(sendext01_w0, sendext01_w1);
2014 : : cmd2[2] = vzip1q_u64(sendext23_w0, sendext23_w1);
2015 : : cmd2[3] = vzip2q_u64(sendext23_w0, sendext23_w1);
2016 : : }
2017 : :
2018 : : if (flags & NIX_TX_MULTI_SEG_F) {
2019 : : uint64_t seg_list[NIX_DESCS_PER_LOOP]
2020 : : [CNXK_NIX_TX_MSEG_SG_DWORDS - 2];
2021 : : uint8_t j, segdw[NIX_DESCS_PER_LOOP + 1];
2022 : :
2023 : : /* Build mseg list for each packet individually. */
2024 : : for (j = 0; j < NIX_DESCS_PER_LOOP; j++)
2025 : : segdw[j] = cn9k_nix_prepare_mseg_vec(txq,
2026 : : tx_pkts[j], &extm,
2027 : : seg_list[j], &cmd0[j],
2028 : : &cmd1[j], flags);
2029 : : segdw[4] = 8;
2030 : :
2031 : : /* Commit all changes to mbuf before LMTST. */
2032 : : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F)
2033 : : rte_io_wmb();
2034 : :
2035 : : cn9k_nix_xmit_pkts_mseg_vector(cmd0, cmd1, cmd2, cmd3,
2036 : : segdw, seg_list,
2037 : : lmt_addr, io_addr,
2038 : : flags);
2039 : : } else if (flags & NIX_TX_NEED_EXT_HDR) {
2040 : : /* With ext header in the command we can no longer send
2041 : : * all 4 packets together since LMTLINE is 128bytes.
2042 : : * Split and Tx twice.
2043 : : */
2044 : : do {
2045 : : if (flags & NIX_TX_OFFLOAD_TSTAMP_F) {
2046 : : vst1q_u64(lmt_addr, cmd0[0]);
2047 : : vst1q_u64(lmt_addr + 2, cmd2[0]);
2048 : : vst1q_u64(lmt_addr + 4, cmd1[0]);
2049 : : vst1q_u64(lmt_addr + 6, cmd3[0]);
2050 : : vst1q_u64(lmt_addr + 8, cmd0[1]);
2051 : : vst1q_u64(lmt_addr + 10, cmd2[1]);
2052 : : vst1q_u64(lmt_addr + 12, cmd1[1]);
2053 : : vst1q_u64(lmt_addr + 14, cmd3[1]);
2054 : : } else {
2055 : : vst1q_u64(lmt_addr, cmd0[0]);
2056 : : vst1q_u64(lmt_addr + 2, cmd2[0]);
2057 : : vst1q_u64(lmt_addr + 4, cmd1[0]);
2058 : : vst1q_u64(lmt_addr + 6, cmd0[1]);
2059 : : vst1q_u64(lmt_addr + 8, cmd2[1]);
2060 : : vst1q_u64(lmt_addr + 10, cmd1[1]);
2061 : : }
2062 : : lmt_status = roc_lmt_submit_ldeor(io_addr);
2063 : : } while (lmt_status == 0);
2064 : :
2065 : : do {
2066 : : if (flags & NIX_TX_OFFLOAD_TSTAMP_F) {
2067 : : vst1q_u64(lmt_addr, cmd0[2]);
2068 : : vst1q_u64(lmt_addr + 2, cmd2[2]);
2069 : : vst1q_u64(lmt_addr + 4, cmd1[2]);
2070 : : vst1q_u64(lmt_addr + 6, cmd3[2]);
2071 : : vst1q_u64(lmt_addr + 8, cmd0[3]);
2072 : : vst1q_u64(lmt_addr + 10, cmd2[3]);
2073 : : vst1q_u64(lmt_addr + 12, cmd1[3]);
2074 : : vst1q_u64(lmt_addr + 14, cmd3[3]);
2075 : : } else {
2076 : : vst1q_u64(lmt_addr, cmd0[2]);
2077 : : vst1q_u64(lmt_addr + 2, cmd2[2]);
2078 : : vst1q_u64(lmt_addr + 4, cmd1[2]);
2079 : : vst1q_u64(lmt_addr + 6, cmd0[3]);
2080 : : vst1q_u64(lmt_addr + 8, cmd2[3]);
2081 : : vst1q_u64(lmt_addr + 10, cmd1[3]);
2082 : : }
2083 : : lmt_status = roc_lmt_submit_ldeor(io_addr);
2084 : : } while (lmt_status == 0);
2085 : : } else {
2086 : : do {
2087 : : vst1q_u64(lmt_addr, cmd0[0]);
2088 : : vst1q_u64(lmt_addr + 2, cmd1[0]);
2089 : : vst1q_u64(lmt_addr + 4, cmd0[1]);
2090 : : vst1q_u64(lmt_addr + 6, cmd1[1]);
2091 : : vst1q_u64(lmt_addr + 8, cmd0[2]);
2092 : : vst1q_u64(lmt_addr + 10, cmd1[2]);
2093 : : vst1q_u64(lmt_addr + 12, cmd0[3]);
2094 : : vst1q_u64(lmt_addr + 14, cmd1[3]);
2095 : : lmt_status = roc_lmt_submit_ldeor(io_addr);
2096 : : } while (lmt_status == 0);
2097 : : }
2098 : : tx_pkts = tx_pkts + NIX_DESCS_PER_LOOP;
2099 : : }
2100 : :
2101 : : if (flags & NIX_TX_OFFLOAD_MBUF_NOFF_F && !txq->tx_compl.ena)
2102 : : cn9k_nix_free_extmbuf(extm);
2103 : :
2104 : : if (unlikely(pkts_left)) {
2105 : : if (flags & NIX_TX_MULTI_SEG_F)
2106 : : pkts += cn9k_nix_xmit_pkts_mseg(tx_queue, tx_pkts,
2107 : : pkts_left, cmd, flags);
2108 : : else
2109 : : pkts += cn9k_nix_xmit_pkts(tx_queue, tx_pkts, pkts_left,
2110 : : cmd, flags);
2111 : : }
2112 : :
2113 : : return pkts;
2114 : : }
2115 : :
2116 : : #else
2117 : : static __rte_always_inline uint16_t
2118 : : cn9k_nix_xmit_pkts_vector(void *tx_queue, struct rte_mbuf **tx_pkts,
2119 : : uint16_t pkts, uint64_t *cmd, const uint16_t flags)
2120 : : {
2121 : : RTE_SET_USED(tx_queue);
2122 : : RTE_SET_USED(tx_pkts);
2123 : : RTE_SET_USED(pkts);
2124 : : RTE_SET_USED(cmd);
2125 : : RTE_SET_USED(flags);
2126 : : return 0;
2127 : : }
2128 : : #endif
2129 : :
2130 : : #define L3L4CSUM_F NIX_TX_OFFLOAD_L3_L4_CSUM_F
2131 : : #define OL3OL4CSUM_F NIX_TX_OFFLOAD_OL3_OL4_CSUM_F
2132 : : #define VLAN_F NIX_TX_OFFLOAD_VLAN_QINQ_F
2133 : : #define NOFF_F NIX_TX_OFFLOAD_MBUF_NOFF_F
2134 : : #define TSO_F NIX_TX_OFFLOAD_TSO_F
2135 : : #define TSP_F NIX_TX_OFFLOAD_TSTAMP_F
2136 : : #define T_SEC_F NIX_TX_OFFLOAD_SECURITY_F
2137 : :
2138 : : /* [T_SEC_F] [TSP] [TSO] [NOFF] [VLAN] [OL3OL4CSUM] [L3L4CSUM] */
2139 : : #define NIX_TX_FASTPATH_MODES_0_15 \
2140 : : T(no_offload, 6, NIX_TX_OFFLOAD_NONE) \
2141 : : T(l3l4csum, 6, L3L4CSUM_F) \
2142 : : T(ol3ol4csum, 6, OL3OL4CSUM_F) \
2143 : : T(ol3ol4csum_l3l4csum, 6, OL3OL4CSUM_F | L3L4CSUM_F) \
2144 : : T(vlan, 6, VLAN_F) \
2145 : : T(vlan_l3l4csum, 6, VLAN_F | L3L4CSUM_F) \
2146 : : T(vlan_ol3ol4csum, 6, VLAN_F | OL3OL4CSUM_F) \
2147 : : T(vlan_ol3ol4csum_l3l4csum, 6, VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2148 : : T(noff, 6, NOFF_F) \
2149 : : T(noff_l3l4csum, 6, NOFF_F | L3L4CSUM_F) \
2150 : : T(noff_ol3ol4csum, 6, NOFF_F | OL3OL4CSUM_F) \
2151 : : T(noff_ol3ol4csum_l3l4csum, 6, NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2152 : : T(noff_vlan, 6, NOFF_F | VLAN_F) \
2153 : : T(noff_vlan_l3l4csum, 6, NOFF_F | VLAN_F | L3L4CSUM_F) \
2154 : : T(noff_vlan_ol3ol4csum, 6, NOFF_F | VLAN_F | OL3OL4CSUM_F) \
2155 : : T(noff_vlan_ol3ol4csum_l3l4csum, 6, \
2156 : : NOFF_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)
2157 : :
2158 : : #define NIX_TX_FASTPATH_MODES_16_31 \
2159 : : T(tso, 6, TSO_F) \
2160 : : T(tso_l3l4csum, 6, TSO_F | L3L4CSUM_F) \
2161 : : T(tso_ol3ol4csum, 6, TSO_F | OL3OL4CSUM_F) \
2162 : : T(tso_ol3ol4csum_l3l4csum, 6, TSO_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2163 : : T(tso_vlan, 6, TSO_F | VLAN_F) \
2164 : : T(tso_vlan_l3l4csum, 6, TSO_F | VLAN_F | L3L4CSUM_F) \
2165 : : T(tso_vlan_ol3ol4csum, 6, TSO_F | VLAN_F | OL3OL4CSUM_F) \
2166 : : T(tso_vlan_ol3ol4csum_l3l4csum, 6, \
2167 : : TSO_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2168 : : T(tso_noff, 6, TSO_F | NOFF_F) \
2169 : : T(tso_noff_l3l4csum, 6, TSO_F | NOFF_F | L3L4CSUM_F) \
2170 : : T(tso_noff_ol3ol4csum, 6, TSO_F | NOFF_F | OL3OL4CSUM_F) \
2171 : : T(tso_noff_ol3ol4csum_l3l4csum, 6, \
2172 : : TSO_F | NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2173 : : T(tso_noff_vlan, 6, TSO_F | NOFF_F | VLAN_F) \
2174 : : T(tso_noff_vlan_l3l4csum, 6, TSO_F | NOFF_F | VLAN_F | L3L4CSUM_F) \
2175 : : T(tso_noff_vlan_ol3ol4csum, 6, TSO_F | NOFF_F | VLAN_F | OL3OL4CSUM_F) \
2176 : : T(tso_noff_vlan_ol3ol4csum_l3l4csum, 6, \
2177 : : TSO_F | NOFF_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)
2178 : :
2179 : : #define NIX_TX_FASTPATH_MODES_32_47 \
2180 : : T(ts, 8, TSP_F) \
2181 : : T(ts_l3l4csum, 8, TSP_F | L3L4CSUM_F) \
2182 : : T(ts_ol3ol4csum, 8, TSP_F | OL3OL4CSUM_F) \
2183 : : T(ts_ol3ol4csum_l3l4csum, 8, TSP_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2184 : : T(ts_vlan, 8, TSP_F | VLAN_F) \
2185 : : T(ts_vlan_l3l4csum, 8, TSP_F | VLAN_F | L3L4CSUM_F) \
2186 : : T(ts_vlan_ol3ol4csum, 8, TSP_F | VLAN_F | OL3OL4CSUM_F) \
2187 : : T(ts_vlan_ol3ol4csum_l3l4csum, 8, \
2188 : : TSP_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2189 : : T(ts_noff, 8, TSP_F | NOFF_F) \
2190 : : T(ts_noff_l3l4csum, 8, TSP_F | NOFF_F | L3L4CSUM_F) \
2191 : : T(ts_noff_ol3ol4csum, 8, TSP_F | NOFF_F | OL3OL4CSUM_F) \
2192 : : T(ts_noff_ol3ol4csum_l3l4csum, 8, \
2193 : : TSP_F | NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2194 : : T(ts_noff_vlan, 8, TSP_F | NOFF_F | VLAN_F) \
2195 : : T(ts_noff_vlan_l3l4csum, 8, TSP_F | NOFF_F | VLAN_F | L3L4CSUM_F) \
2196 : : T(ts_noff_vlan_ol3ol4csum, 8, TSP_F | NOFF_F | VLAN_F | OL3OL4CSUM_F) \
2197 : : T(ts_noff_vlan_ol3ol4csum_l3l4csum, 8, \
2198 : : TSP_F | NOFF_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)
2199 : :
2200 : : #define NIX_TX_FASTPATH_MODES_48_63 \
2201 : : T(ts_tso, 8, TSP_F | TSO_F) \
2202 : : T(ts_tso_l3l4csum, 8, TSP_F | TSO_F | L3L4CSUM_F) \
2203 : : T(ts_tso_ol3ol4csum, 8, TSP_F | TSO_F | OL3OL4CSUM_F) \
2204 : : T(ts_tso_ol3ol4csum_l3l4csum, 8, \
2205 : : TSP_F | TSO_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2206 : : T(ts_tso_vlan, 8, TSP_F | TSO_F | VLAN_F) \
2207 : : T(ts_tso_vlan_l3l4csum, 8, TSP_F | TSO_F | VLAN_F | L3L4CSUM_F) \
2208 : : T(ts_tso_vlan_ol3ol4csum, 8, TSP_F | TSO_F | VLAN_F | OL3OL4CSUM_F) \
2209 : : T(ts_tso_vlan_ol3ol4csum_l3l4csum, 8, \
2210 : : TSP_F | TSO_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2211 : : T(ts_tso_noff, 8, TSP_F | TSO_F | NOFF_F) \
2212 : : T(ts_tso_noff_l3l4csum, 8, TSP_F | TSO_F | NOFF_F | L3L4CSUM_F) \
2213 : : T(ts_tso_noff_ol3ol4csum, 8, TSP_F | TSO_F | NOFF_F | OL3OL4CSUM_F) \
2214 : : T(ts_tso_noff_ol3ol4csum_l3l4csum, 8, \
2215 : : TSP_F | TSO_F | NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2216 : : T(ts_tso_noff_vlan, 8, TSP_F | TSO_F | NOFF_F | VLAN_F) \
2217 : : T(ts_tso_noff_vlan_l3l4csum, 8, \
2218 : : TSP_F | TSO_F | NOFF_F | VLAN_F | L3L4CSUM_F) \
2219 : : T(ts_tso_noff_vlan_ol3ol4csum, 8, \
2220 : : TSP_F | TSO_F | NOFF_F | VLAN_F | OL3OL4CSUM_F) \
2221 : : T(ts_tso_noff_vlan_ol3ol4csum_l3l4csum, 8, \
2222 : : TSP_F | TSO_F | NOFF_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)
2223 : :
2224 : : #define NIX_TX_FASTPATH_MODES_64_79 \
2225 : : T(sec, 6, T_SEC_F) \
2226 : : T(sec_l3l4csum, 6, T_SEC_F | L3L4CSUM_F) \
2227 : : T(sec_ol3ol4csum, 6, T_SEC_F | OL3OL4CSUM_F) \
2228 : : T(sec_ol3ol4csum_l3l4csum, 6, T_SEC_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2229 : : T(sec_vlan, 6, T_SEC_F | VLAN_F) \
2230 : : T(sec_vlan_l3l4csum, 6, T_SEC_F | VLAN_F | L3L4CSUM_F) \
2231 : : T(sec_vlan_ol3ol4csum, 6, T_SEC_F | VLAN_F | OL3OL4CSUM_F) \
2232 : : T(sec_vlan_ol3ol4csum_l3l4csum, 6, \
2233 : : T_SEC_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2234 : : T(sec_noff, 6, T_SEC_F | NOFF_F) \
2235 : : T(sec_noff_l3l4csum, 6, T_SEC_F | NOFF_F | L3L4CSUM_F) \
2236 : : T(sec_noff_ol3ol4csum, 6, T_SEC_F | NOFF_F | OL3OL4CSUM_F) \
2237 : : T(sec_noff_ol3ol4csum_l3l4csum, 6, \
2238 : : T_SEC_F | NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2239 : : T(sec_noff_vlan, 6, T_SEC_F | NOFF_F | VLAN_F) \
2240 : : T(sec_noff_vlan_l3l4csum, 6, T_SEC_F | NOFF_F | VLAN_F | L3L4CSUM_F) \
2241 : : T(sec_noff_vlan_ol3ol4csum, 6, \
2242 : : T_SEC_F | NOFF_F | VLAN_F | OL3OL4CSUM_F) \
2243 : : T(sec_noff_vlan_ol3ol4csum_l3l4csum, 6, \
2244 : : T_SEC_F | NOFF_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)
2245 : :
2246 : : #define NIX_TX_FASTPATH_MODES_80_95 \
2247 : : T(sec_tso, 6, T_SEC_F | TSO_F) \
2248 : : T(sec_tso_l3l4csum, 6, T_SEC_F | TSO_F | L3L4CSUM_F) \
2249 : : T(sec_tso_ol3ol4csum, 6, T_SEC_F | TSO_F | OL3OL4CSUM_F) \
2250 : : T(sec_tso_ol3ol4csum_l3l4csum, 6, \
2251 : : T_SEC_F | TSO_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2252 : : T(sec_tso_vlan, 6, T_SEC_F | TSO_F | VLAN_F) \
2253 : : T(sec_tso_vlan_l3l4csum, 6, T_SEC_F | TSO_F | VLAN_F | L3L4CSUM_F) \
2254 : : T(sec_tso_vlan_ol3ol4csum, 6, T_SEC_F | TSO_F | VLAN_F | OL3OL4CSUM_F) \
2255 : : T(sec_tso_vlan_ol3ol4csum_l3l4csum, 6, \
2256 : : T_SEC_F | TSO_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2257 : : T(sec_tso_noff, 6, T_SEC_F | TSO_F | NOFF_F) \
2258 : : T(sec_tso_noff_l3l4csum, 6, T_SEC_F | TSO_F | NOFF_F | L3L4CSUM_F) \
2259 : : T(sec_tso_noff_ol3ol4csum, 6, T_SEC_F | TSO_F | NOFF_F | OL3OL4CSUM_F) \
2260 : : T(sec_tso_noff_ol3ol4csum_l3l4csum, 6, \
2261 : : T_SEC_F | TSO_F | NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2262 : : T(sec_tso_noff_vlan, 6, T_SEC_F | TSO_F | NOFF_F | VLAN_F) \
2263 : : T(sec_tso_noff_vlan_l3l4csum, 6, \
2264 : : T_SEC_F | TSO_F | NOFF_F | VLAN_F | L3L4CSUM_F) \
2265 : : T(sec_tso_noff_vlan_ol3ol4csum, 6, \
2266 : : T_SEC_F | TSO_F | NOFF_F | VLAN_F | OL3OL4CSUM_F) \
2267 : : T(sec_tso_noff_vlan_ol3ol4csum_l3l4csum, 6, \
2268 : : T_SEC_F | TSO_F | NOFF_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)
2269 : :
2270 : : #define NIX_TX_FASTPATH_MODES_96_111 \
2271 : : T(sec_ts, 8, T_SEC_F | TSP_F) \
2272 : : T(sec_ts_l3l4csum, 8, T_SEC_F | TSP_F | L3L4CSUM_F) \
2273 : : T(sec_ts_ol3ol4csum, 8, T_SEC_F | TSP_F | OL3OL4CSUM_F) \
2274 : : T(sec_ts_ol3ol4csum_l3l4csum, 8, \
2275 : : T_SEC_F | TSP_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2276 : : T(sec_ts_vlan, 8, T_SEC_F | TSP_F | VLAN_F) \
2277 : : T(sec_ts_vlan_l3l4csum, 8, T_SEC_F | TSP_F | VLAN_F | L3L4CSUM_F) \
2278 : : T(sec_ts_vlan_ol3ol4csum, 8, T_SEC_F | TSP_F | VLAN_F | OL3OL4CSUM_F) \
2279 : : T(sec_ts_vlan_ol3ol4csum_l3l4csum, 8, \
2280 : : T_SEC_F | TSP_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2281 : : T(sec_ts_noff, 8, T_SEC_F | TSP_F | NOFF_F) \
2282 : : T(sec_ts_noff_l3l4csum, 8, T_SEC_F | TSP_F | NOFF_F | L3L4CSUM_F) \
2283 : : T(sec_ts_noff_ol3ol4csum, 8, T_SEC_F | TSP_F | NOFF_F | OL3OL4CSUM_F) \
2284 : : T(sec_ts_noff_ol3ol4csum_l3l4csum, 8, \
2285 : : T_SEC_F | TSP_F | NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2286 : : T(sec_ts_noff_vlan, 8, T_SEC_F | TSP_F | NOFF_F | VLAN_F) \
2287 : : T(sec_ts_noff_vlan_l3l4csum, 8, \
2288 : : T_SEC_F | TSP_F | NOFF_F | VLAN_F | L3L4CSUM_F) \
2289 : : T(sec_ts_noff_vlan_ol3ol4csum, 8, \
2290 : : T_SEC_F | TSP_F | NOFF_F | VLAN_F | OL3OL4CSUM_F) \
2291 : : T(sec_ts_noff_vlan_ol3ol4csum_l3l4csum, 8, \
2292 : : T_SEC_F | TSP_F | NOFF_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F)
2293 : :
2294 : : #define NIX_TX_FASTPATH_MODES_112_127 \
2295 : : T(sec_ts_tso, 8, T_SEC_F | TSP_F | TSO_F) \
2296 : : T(sec_ts_tso_l3l4csum, 8, T_SEC_F | TSP_F | TSO_F | L3L4CSUM_F) \
2297 : : T(sec_ts_tso_ol3ol4csum, 8, T_SEC_F | TSP_F | TSO_F | OL3OL4CSUM_F) \
2298 : : T(sec_ts_tso_ol3ol4csum_l3l4csum, 8, \
2299 : : T_SEC_F | TSP_F | TSO_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2300 : : T(sec_ts_tso_vlan, 8, T_SEC_F | TSP_F | TSO_F | VLAN_F) \
2301 : : T(sec_ts_tso_vlan_l3l4csum, 8, \
2302 : : T_SEC_F | TSP_F | TSO_F | VLAN_F | L3L4CSUM_F) \
2303 : : T(sec_ts_tso_vlan_ol3ol4csum, 8, \
2304 : : T_SEC_F | TSP_F | TSO_F | VLAN_F | OL3OL4CSUM_F) \
2305 : : T(sec_ts_tso_vlan_ol3ol4csum_l3l4csum, 8, \
2306 : : T_SEC_F | TSP_F | TSO_F | VLAN_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2307 : : T(sec_ts_tso_noff, 8, T_SEC_F | TSP_F | TSO_F | NOFF_F) \
2308 : : T(sec_ts_tso_noff_l3l4csum, 8, \
2309 : : T_SEC_F | TSP_F | TSO_F | NOFF_F | L3L4CSUM_F) \
2310 : : T(sec_ts_tso_noff_ol3ol4csum, 8, \
2311 : : T_SEC_F | TSP_F | TSO_F | NOFF_F | OL3OL4CSUM_F) \
2312 : : T(sec_ts_tso_noff_ol3ol4csum_l3l4csum, 8, \
2313 : : T_SEC_F | TSP_F | TSO_F | NOFF_F | OL3OL4CSUM_F | L3L4CSUM_F) \
2314 : : T(sec_ts_tso_noff_vlan, 8, T_SEC_F | TSP_F | TSO_F | NOFF_F | VLAN_F) \
2315 : : T(sec_ts_tso_noff_vlan_l3l4csum, 8, \
2316 : : T_SEC_F | TSP_F | TSO_F | NOFF_F | VLAN_F | L3L4CSUM_F) \
2317 : : T(sec_ts_tso_noff_vlan_ol3ol4csum, 8, \
2318 : : T_SEC_F | TSP_F | TSO_F | NOFF_F | VLAN_F | OL3OL4CSUM_F) \
2319 : : T(sec_ts_tso_noff_vlan_ol3ol4csum_l3l4csum, 8, \
2320 : : T_SEC_F | TSP_F | TSO_F | NOFF_F | VLAN_F | OL3OL4CSUM_F | \
2321 : : L3L4CSUM_F)
2322 : :
2323 : : #define NIX_TX_FASTPATH_MODES \
2324 : : NIX_TX_FASTPATH_MODES_0_15 \
2325 : : NIX_TX_FASTPATH_MODES_16_31 \
2326 : : NIX_TX_FASTPATH_MODES_32_47 \
2327 : : NIX_TX_FASTPATH_MODES_48_63 \
2328 : : NIX_TX_FASTPATH_MODES_64_79 \
2329 : : NIX_TX_FASTPATH_MODES_80_95 \
2330 : : NIX_TX_FASTPATH_MODES_96_111 \
2331 : : NIX_TX_FASTPATH_MODES_112_127
2332 : :
2333 : : #define T(name, sz, flags) \
2334 : : uint16_t __rte_noinline __rte_hot cn9k_nix_xmit_pkts_##name( \
2335 : : void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t pkts); \
2336 : : uint16_t __rte_noinline __rte_hot cn9k_nix_xmit_pkts_mseg_##name( \
2337 : : void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t pkts); \
2338 : : uint16_t __rte_noinline __rte_hot cn9k_nix_xmit_pkts_vec_##name( \
2339 : : void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t pkts); \
2340 : : uint16_t __rte_noinline __rte_hot cn9k_nix_xmit_pkts_vec_mseg_##name( \
2341 : : void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t pkts);
2342 : :
2343 : : NIX_TX_FASTPATH_MODES
2344 : : #undef T
2345 : :
2346 : : #define NIX_TX_XMIT(fn, sz, flags) \
2347 : : uint16_t __rte_noinline __rte_hot fn( \
2348 : : void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t pkts) \
2349 : : { \
2350 : : uint64_t cmd[sz]; \
2351 : : /* For TSO inner checksum is a must */ \
2352 : : if (((flags) & NIX_TX_OFFLOAD_TSO_F) && \
2353 : : !((flags) & NIX_TX_OFFLOAD_L3_L4_CSUM_F)) \
2354 : : return 0; \
2355 : : return cn9k_nix_xmit_pkts(tx_queue, tx_pkts, pkts, cmd, \
2356 : : flags); \
2357 : : }
2358 : :
2359 : : #define NIX_TX_XMIT_MSEG(fn, sz, flags) \
2360 : : uint16_t __rte_noinline __rte_hot fn( \
2361 : : void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t pkts) \
2362 : : { \
2363 : : uint64_t cmd[(sz) + CNXK_NIX_TX_MSEG_SG_DWORDS - 2]; \
2364 : : /* For TSO inner checksum is a must */ \
2365 : : if (((flags) & NIX_TX_OFFLOAD_TSO_F) && \
2366 : : !((flags) & NIX_TX_OFFLOAD_L3_L4_CSUM_F)) \
2367 : : return 0; \
2368 : : return cn9k_nix_xmit_pkts_mseg(tx_queue, tx_pkts, pkts, cmd, \
2369 : : (flags) | NIX_TX_MULTI_SEG_F); \
2370 : : }
2371 : :
2372 : : #define NIX_TX_XMIT_VEC(fn, sz, flags) \
2373 : : uint16_t __rte_noinline __rte_hot fn( \
2374 : : void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t pkts) \
2375 : : { \
2376 : : uint64_t cmd[sz]; \
2377 : : /* For TSO inner checksum is a must */ \
2378 : : if (((flags) & NIX_TX_OFFLOAD_TSO_F) && \
2379 : : !((flags) & NIX_TX_OFFLOAD_L3_L4_CSUM_F)) \
2380 : : return 0; \
2381 : : return cn9k_nix_xmit_pkts_vector(tx_queue, tx_pkts, pkts, cmd, \
2382 : : (flags)); \
2383 : : }
2384 : :
2385 : : #define NIX_TX_XMIT_VEC_MSEG(fn, sz, flags) \
2386 : : uint16_t __rte_noinline __rte_hot fn( \
2387 : : void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t pkts) \
2388 : : { \
2389 : : uint64_t cmd[(sz) + CNXK_NIX_TX_MSEG_SG_DWORDS - 2]; \
2390 : : /* For TSO inner checksum is a must */ \
2391 : : if (((flags) & NIX_TX_OFFLOAD_TSO_F) && \
2392 : : !((flags) & NIX_TX_OFFLOAD_L3_L4_CSUM_F)) \
2393 : : return 0; \
2394 : : return cn9k_nix_xmit_pkts_vector(tx_queue, tx_pkts, pkts, cmd, \
2395 : : (flags) | \
2396 : : NIX_TX_MULTI_SEG_F); \
2397 : : }
2398 : :
2399 : : uint16_t __rte_noinline __rte_hot cn9k_nix_xmit_pkts_all_offload(void *tx_queue,
2400 : : struct rte_mbuf **tx_pkts,
2401 : : uint16_t pkts);
2402 : :
2403 : : uint16_t __rte_noinline __rte_hot cn9k_nix_xmit_pkts_vec_all_offload(void *tx_queue,
2404 : : struct rte_mbuf **tx_pkts,
2405 : : uint16_t pkts);
2406 : :
2407 : : #endif /* __CN9K_TX_H__ */
|