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