14b634e401608f2f482ad7c6acd0a16e834e5ce2
[dpdk.git] / drivers / net / cnxk / cn10k_rx.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4 #ifndef __CN10K_RX_H__
5 #define __CN10K_RX_H__
6
7 #include <rte_ether.h>
8 #include <rte_vect.h>
9
10 #include <cnxk_ethdev.h>
11
12 #define NIX_RX_OFFLOAD_NONE          (0)
13 #define NIX_RX_OFFLOAD_RSS_F         BIT(0)
14 #define NIX_RX_OFFLOAD_PTYPE_F       BIT(1)
15 #define NIX_RX_OFFLOAD_CHECKSUM_F    BIT(2)
16 #define NIX_RX_OFFLOAD_MARK_UPDATE_F BIT(3)
17 #define NIX_RX_OFFLOAD_TSTAMP_F      BIT(4)
18 #define NIX_RX_OFFLOAD_VLAN_STRIP_F  BIT(5)
19 #define NIX_RX_OFFLOAD_SECURITY_F    BIT(6)
20 #define NIX_RX_OFFLOAD_MAX           (NIX_RX_OFFLOAD_SECURITY_F << 1)
21
22 /* Flags to control cqe_to_mbuf conversion function.
23  * Defining it from backwards to denote its been
24  * not used as offload flags to pick function
25  */
26 #define NIX_RX_REAS_F      BIT(12)
27 #define NIX_RX_VWQE_F      BIT(13)
28 #define NIX_RX_MULTI_SEG_F BIT(14)
29 #define CPT_RX_WQE_F       BIT(15)
30
31 #define CNXK_NIX_CQ_ENTRY_SZ 128
32 #define NIX_DESCS_PER_LOOP   4
33 #define CQE_CAST(x)          ((struct nix_cqe_hdr_s *)(x))
34 #define CQE_SZ(x)            ((x) * CNXK_NIX_CQ_ENTRY_SZ)
35
36 #define CQE_PTR_OFF(b, i, o, f)                                                \
37         (((f) & NIX_RX_VWQE_F) ?                                               \
38                        (uint64_t *)(((uintptr_t)((uint64_t *)(b))[i]) + (o)) : \
39                        (uint64_t *)(((uintptr_t)(b)) + CQE_SZ(i) + (o)))
40 #define CQE_PTR_DIFF(b, i, o, f)                                               \
41         (((f) & NIX_RX_VWQE_F) ?                                               \
42                  (uint64_t *)(((uintptr_t)((uint64_t *)(b))[i]) - (o)) :       \
43                        (uint64_t *)(((uintptr_t)(b)) + CQE_SZ(i) - (o)))
44
45 #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
46 static inline void
47 nix_mbuf_validate_next(struct rte_mbuf *m)
48 {
49         if (m->nb_segs == 1 && m->next) {
50                 rte_panic("mbuf->next[%p] valid when mbuf->nb_segs is %d",
51                         m->next, m->nb_segs);
52         }
53 }
54 #else
55 static inline void
56 nix_mbuf_validate_next(struct rte_mbuf *m)
57 {
58         RTE_SET_USED(m);
59 }
60 #endif
61
62 #define NIX_RX_SEC_REASSEMBLY_F \
63         (NIX_RX_REAS_F | NIX_RX_OFFLOAD_SECURITY_F)
64
65 static inline rte_eth_ip_reassembly_dynfield_t *
66 cnxk_ip_reassembly_dynfield(struct rte_mbuf *mbuf,
67                 int ip_reassembly_dynfield_offset)
68 {
69         return RTE_MBUF_DYNFIELD(mbuf, ip_reassembly_dynfield_offset,
70                                  rte_eth_ip_reassembly_dynfield_t *);
71 }
72
73 union mbuf_initializer {
74         struct {
75                 uint16_t data_off;
76                 uint16_t refcnt;
77                 uint16_t nb_segs;
78                 uint16_t port;
79         } fields;
80         uint64_t value;
81 };
82
83 static __rte_always_inline uint64_t
84 nix_clear_data_off(uint64_t oldval)
85 {
86         union mbuf_initializer mbuf_init = {.value = oldval};
87
88         mbuf_init.fields.data_off = 0;
89         return mbuf_init.value;
90 }
91
92 static __rte_always_inline struct rte_mbuf *
93 nix_get_mbuf_from_cqe(void *cq, const uint64_t data_off)
94 {
95         rte_iova_t buff;
96
97         /* Skip CQE, NIX_RX_PARSE_S and SG HDR(9 DWORDs) and peek buff addr */
98         buff = *((rte_iova_t *)((uint64_t *)cq + 9));
99         return (struct rte_mbuf *)(buff - data_off);
100 }
101
102 static __rte_always_inline void
103 nix_sec_flush_meta_burst(uint16_t lmt_id, uint64_t data, uint16_t lnum,
104                          uintptr_t aura_handle)
105 {
106         uint64_t pa;
107
108         /* Prepare PA and Data */
109         pa = roc_npa_aura_handle_to_base(aura_handle) + NPA_LF_AURA_BATCH_FREE0;
110         pa |= ((data & 0x7) << 4);
111
112         data >>= 3;
113         data <<= 19;
114         data |= (uint64_t)lmt_id;
115         data |= (uint64_t)(lnum - 1) << 12;
116
117         roc_lmt_submit_steorl(data, pa);
118 }
119
120 static __rte_always_inline void
121 nix_sec_flush_meta(uintptr_t laddr, uint16_t lmt_id, uint8_t loff,
122                    uintptr_t aura_handle)
123 {
124         uint64_t pa;
125
126         /* laddr is pointing to first pointer */
127         laddr -= 8;
128
129         /* Trigger free either on lmtline full or different aura handle */
130         pa = roc_npa_aura_handle_to_base(aura_handle) + NPA_LF_AURA_BATCH_FREE0;
131
132         /* Update aura handle */
133         *(uint64_t *)laddr = (((uint64_t)(loff & 0x1) << 32) |
134                               roc_npa_aura_handle_to_aura(aura_handle));
135
136         pa |= ((uint64_t)(loff >> 1) << 4);
137         roc_lmt_submit_steorl(lmt_id, pa);
138 }
139
140 static struct rte_mbuf *
141 nix_sec_attach_frags(const struct cpt_parse_hdr_s *hdr,
142                      struct cn10k_inb_priv_data *inb_priv,
143                      const uint64_t mbuf_init)
144 {
145         struct rte_mbuf *head, *mbuf, *mbuf_prev;
146         uint32_t offset = hdr->w2.fi_offset;
147         union nix_rx_parse_u *frag_rx;
148         struct cpt_frag_info_s *finfo;
149         uint64_t *frag_ptr = NULL;
150         uint64_t ol_flags;
151         uint16_t frag_size;
152         uint16_t rlen;
153         uint64_t *wqe;
154         int off;
155
156         off = inb_priv->reass_dynfield_off;
157         ol_flags = BIT_ULL(inb_priv->reass_dynflag_bit);
158         ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD;
159
160         /* offset of 0 implies 256B, otherwise it implies offset*8B */
161         offset = (((offset - 1) & 0x1f) + 1) * 8;
162         finfo = RTE_PTR_ADD(hdr, offset + hdr->w2.fi_pad);
163
164         /* Frag-0: */
165         wqe = (uint64_t *)(rte_be_to_cpu_64(hdr->wqe_ptr));
166         rlen = ((*(wqe + 10)) >> 16) & 0xFFFF;
167
168         frag_rx = (union nix_rx_parse_u *)(wqe + 1);
169         frag_size = rlen + frag_rx->lcptr - frag_rx->laptr;
170         frag_rx->pkt_lenm1 = frag_size - 1;
171
172         mbuf = (struct rte_mbuf *)((uintptr_t)wqe - sizeof(struct rte_mbuf));
173         *(uint64_t *)(&mbuf->rearm_data) = mbuf_init;
174         mbuf->data_len = frag_size;
175         mbuf->pkt_len = frag_size;
176         mbuf->ol_flags = ol_flags;
177         mbuf->next = NULL;
178         head = mbuf;
179         mbuf_prev = mbuf;
180         /* Update dynamic field with userdata */
181         *rte_security_dynfield(mbuf) = (uint64_t)inb_priv->userdata;
182
183         cnxk_ip_reassembly_dynfield(head, off)->nb_frags = hdr->w0.num_frags - 1;
184         cnxk_ip_reassembly_dynfield(head, off)->next_frag = NULL;
185
186         /* Frag-1: */
187         if (hdr->w0.num_frags > 1) {
188                 wqe = (uint64_t *)(rte_be_to_cpu_64(hdr->frag1_wqe_ptr));
189                 rlen = ((*(wqe + 10)) >> 16) & 0xFFFF;
190
191                 frag_rx = (union nix_rx_parse_u *)(wqe + 1);
192                 frag_size = rlen + frag_rx->lcptr - frag_rx->laptr;
193                 frag_rx->pkt_lenm1 = frag_size - 1;
194
195                 mbuf = (struct rte_mbuf *)((uintptr_t)wqe -
196                                 sizeof(struct rte_mbuf));
197                 *(uint64_t *)(&mbuf->rearm_data) = mbuf_init;
198                 mbuf->data_len = frag_size;
199                 mbuf->pkt_len = frag_size;
200                 mbuf->ol_flags = ol_flags;
201                 mbuf->next = NULL;
202
203                 /* Update dynamic field with userdata */
204                 *rte_security_dynfield(mbuf) = (uint64_t)inb_priv->userdata;
205
206                 cnxk_ip_reassembly_dynfield(mbuf, off)->nb_frags =
207                         hdr->w0.num_frags - 2;
208                 cnxk_ip_reassembly_dynfield(mbuf, off)->next_frag = NULL;
209                 cnxk_ip_reassembly_dynfield(mbuf_prev, off)->next_frag = mbuf;
210                 mbuf_prev = mbuf;
211         }
212
213         /* Frag-2: */
214         if (hdr->w0.num_frags > 2) {
215                 frag_ptr = (uint64_t *)(finfo + 1);
216                 wqe = (uint64_t *)(rte_be_to_cpu_64(*frag_ptr));
217                 rlen = ((*(wqe + 10)) >> 16) & 0xFFFF;
218
219                 frag_rx = (union nix_rx_parse_u *)(wqe + 1);
220                 frag_size = rlen + frag_rx->lcptr - frag_rx->laptr;
221                 frag_rx->pkt_lenm1 = frag_size - 1;
222
223                 mbuf = (struct rte_mbuf *)((uintptr_t)wqe -
224                                 sizeof(struct rte_mbuf));
225                 *(uint64_t *)(&mbuf->rearm_data) = mbuf_init;
226                 mbuf->data_len = frag_size;
227                 mbuf->pkt_len = frag_size;
228                 mbuf->ol_flags = ol_flags;
229                 mbuf->next = NULL;
230
231                 /* Update dynamic field with userdata */
232                 *rte_security_dynfield(mbuf) = (uint64_t)inb_priv->userdata;
233
234                 cnxk_ip_reassembly_dynfield(mbuf, off)->nb_frags =
235                         hdr->w0.num_frags - 3;
236                 cnxk_ip_reassembly_dynfield(mbuf, off)->next_frag = NULL;
237                 cnxk_ip_reassembly_dynfield(mbuf_prev, off)->next_frag = mbuf;
238                 mbuf_prev = mbuf;
239         }
240
241         /* Frag-3: */
242         if (hdr->w0.num_frags > 3) {
243                 wqe = (uint64_t *)(rte_be_to_cpu_64(*(frag_ptr + 1)));
244                 rlen = ((*(wqe + 10)) >> 16) & 0xFFFF;
245
246                 frag_rx = (union nix_rx_parse_u *)(wqe + 1);
247                 frag_size = rlen + frag_rx->lcptr - frag_rx->laptr;
248                 frag_rx->pkt_lenm1 = frag_size - 1;
249
250                 mbuf = (struct rte_mbuf *)((uintptr_t)wqe -
251                                 sizeof(struct rte_mbuf));
252                 *(uint64_t *)(&mbuf->rearm_data) = mbuf_init;
253                 mbuf->data_len = frag_size;
254                 mbuf->pkt_len = frag_size;
255                 mbuf->ol_flags = ol_flags;
256                 mbuf->next = NULL;
257
258                 /* Update dynamic field with userdata */
259                 *rte_security_dynfield(mbuf) = (uint64_t)inb_priv->userdata;
260
261                 cnxk_ip_reassembly_dynfield(mbuf, off)->nb_frags =
262                         hdr->w0.num_frags - 4;
263                 cnxk_ip_reassembly_dynfield(mbuf, off)->next_frag = NULL;
264                 cnxk_ip_reassembly_dynfield(mbuf_prev, off)->next_frag = mbuf;
265         }
266         return head;
267 }
268
269 static struct rte_mbuf *
270 nix_sec_reassemble_frags(const struct cpt_parse_hdr_s *hdr, uint64_t cq_w1,
271                         uint64_t cq_w5, uint64_t mbuf_init)
272 {
273         uint32_t fragx_sum, pkt_hdr_len, l3_hdr_size;
274         uint32_t offset = hdr->w2.fi_offset;
275         union nix_rx_parse_u *inner_rx;
276         uint16_t rlen, data_off, b_off;
277         union nix_rx_parse_u *frag_rx;
278         struct cpt_frag_info_s *finfo;
279         struct rte_mbuf *head, *mbuf;
280         uint64_t *frag_ptr = NULL;
281         rte_iova_t *inner_iova;
282         uint16_t frag_size;
283         uint64_t *wqe;
284
285         /* Base data offset */
286         b_off = mbuf_init & 0xFFFFUL;
287         mbuf_init &= ~0xFFFFUL;
288
289         /* offset of 0 implies 256B, otherwise it implies offset*8B */
290         offset = (((offset - 1) & 0x1f) + 1) * 8;
291         finfo = RTE_PTR_ADD(hdr, offset + hdr->w2.fi_pad);
292
293         /* Frag-0: */
294         wqe = (uint64_t *)rte_be_to_cpu_64(hdr->wqe_ptr);
295         inner_rx = (union nix_rx_parse_u *)(wqe + 1);
296         inner_iova = (rte_iova_t *)*(wqe + 9);
297
298         /* Update only the upper 28-bits from meta pkt parse info */
299         *((uint64_t *)inner_rx) = ((*((uint64_t *)inner_rx) & ((1ULL << 36) - 1)) |
300                                 (cq_w1 & ~((1ULL << 36) - 1)));
301
302         rlen = ((*(wqe + 10)) >> 16) & 0xFFFF;
303         frag_size = rlen + ((cq_w5 >> 16) & 0xFF) - (cq_w5 & 0xFF);
304         fragx_sum = rte_be_to_cpu_16(finfo->w1.frag_size0);
305         pkt_hdr_len = frag_size - fragx_sum;
306
307         mbuf = (struct rte_mbuf *)((uintptr_t)wqe - sizeof(struct rte_mbuf));
308         *(uint64_t *)(&mbuf->rearm_data) = mbuf_init | b_off;
309         mbuf->data_len = frag_size;
310         head = mbuf;
311
312         if (inner_rx->lctype == NPC_LT_LC_IP) {
313                 struct rte_ipv4_hdr *hdr = (struct rte_ipv4_hdr *)
314                                 RTE_PTR_ADD(inner_iova, inner_rx->lcptr);
315
316                 l3_hdr_size = (hdr->version_ihl & 0xf) << 2;
317         } else {
318                 struct rte_ipv6_hdr *hdr = (struct rte_ipv6_hdr *)
319                                 RTE_PTR_ADD(inner_iova, inner_rx->lcptr);
320                 size_t ext_len = sizeof(struct rte_ipv6_hdr);
321                 uint8_t *nxt_hdr = (uint8_t *)hdr;
322                 int nh = hdr->proto;
323
324                 l3_hdr_size = 0;
325                 while (nh != -EINVAL) {
326                         nxt_hdr += ext_len;
327                         l3_hdr_size += ext_len;
328                         nh = rte_ipv6_get_next_ext(nxt_hdr, nh, &ext_len);
329                 }
330         }
331
332         /* Frag-1: */
333         wqe = (uint64_t *)(rte_be_to_cpu_64(hdr->frag1_wqe_ptr));
334         frag_size = rte_be_to_cpu_16(finfo->w1.frag_size1);
335         frag_rx = (union nix_rx_parse_u *)(wqe + 1);
336
337         mbuf->next = (struct rte_mbuf *)((uintptr_t)wqe - sizeof(struct rte_mbuf));
338         mbuf = mbuf->next;
339         data_off = b_off + frag_rx->lcptr + l3_hdr_size;
340         *(uint64_t *)(&mbuf->rearm_data) = mbuf_init | data_off;
341         mbuf->data_len = frag_size;
342         fragx_sum += frag_size;
343
344         /* Mark frag as get */
345         RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
346
347         /* Frag-2: */
348         if (hdr->w0.num_frags > 2) {
349                 frag_ptr = (uint64_t *)(finfo + 1);
350                 wqe = (uint64_t *)(rte_be_to_cpu_64(*frag_ptr));
351                 frag_size = rte_be_to_cpu_16(finfo->w1.frag_size2);
352                 frag_rx = (union nix_rx_parse_u *)(wqe + 1);
353
354                 mbuf->next = (struct rte_mbuf *)((uintptr_t)wqe - sizeof(struct rte_mbuf));
355                 mbuf = mbuf->next;
356                 data_off = b_off + frag_rx->lcptr + l3_hdr_size;
357                 *(uint64_t *)(&mbuf->rearm_data) = mbuf_init | data_off;
358                 mbuf->data_len = frag_size;
359                 fragx_sum += frag_size;
360
361                 /* Mark frag as get */
362                 RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
363         }
364
365         /* Frag-3: */
366         if (hdr->w0.num_frags > 3) {
367                 wqe = (uint64_t *)(rte_be_to_cpu_64(*(frag_ptr + 1)));
368                 frag_size = rte_be_to_cpu_16(finfo->w1.frag_size3);
369                 frag_rx = (union nix_rx_parse_u *)(wqe + 1);
370
371                 mbuf->next = (struct rte_mbuf *)((uintptr_t)wqe - sizeof(struct rte_mbuf));
372                 mbuf = mbuf->next;
373                 data_off = b_off + frag_rx->lcptr + l3_hdr_size;
374                 *(uint64_t *)(&mbuf->rearm_data) = mbuf_init | data_off;
375                 mbuf->data_len = frag_size;
376                 fragx_sum += frag_size;
377
378                 /* Mark frag as get */
379                 RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
380         }
381
382         if (inner_rx->lctype == NPC_LT_LC_IP) {
383                 struct rte_ipv4_hdr *hdr = (struct rte_ipv4_hdr *)
384                                 RTE_PTR_ADD(inner_iova, inner_rx->lcptr);
385
386                 hdr->fragment_offset = 0;
387                 hdr->total_length = rte_cpu_to_be_16(fragx_sum + l3_hdr_size);
388                 hdr->hdr_checksum = 0;
389                 hdr->hdr_checksum = rte_ipv4_cksum(hdr);
390
391                 inner_rx->pkt_lenm1 = pkt_hdr_len + fragx_sum - 1;
392         } else {
393                 /* Remove the frag header by moving header 8 bytes forward */
394                 struct rte_ipv6_hdr *hdr = (struct rte_ipv6_hdr *)
395                                 RTE_PTR_ADD(inner_iova, inner_rx->lcptr);
396
397                 hdr->payload_len = rte_cpu_to_be_16(fragx_sum + l3_hdr_size -
398                                         8 - sizeof(struct rte_ipv6_hdr));
399
400                 rte_memcpy(rte_pktmbuf_mtod_offset(head, void *, 8),
401                            rte_pktmbuf_mtod(head, void *),
402                            inner_rx->lcptr + sizeof(struct rte_ipv6_hdr));
403
404                 inner_rx->pkt_lenm1 = pkt_hdr_len + fragx_sum - 8 - 1;
405                 head->data_len -= 8;
406                 head->data_off += 8;
407         }
408         mbuf->next = NULL;
409         head->pkt_len = inner_rx->pkt_lenm1 + 1;
410         head->nb_segs = hdr->w0.num_frags;
411
412         return head;
413 }
414
415 static __rte_always_inline struct rte_mbuf *
416 nix_sec_meta_to_mbuf_sc(uint64_t cq_w1, uint64_t cq_w5, const uint64_t sa_base,
417                         uintptr_t laddr, uint8_t *loff, struct rte_mbuf *mbuf,
418                         uint16_t data_off, const uint16_t flags,
419                         const uint64_t mbuf_init)
420 {
421         const void *__p = (void *)((uintptr_t)mbuf + (uint16_t)data_off);
422         const struct cpt_parse_hdr_s *hdr = (const struct cpt_parse_hdr_s *)__p;
423         struct cn10k_inb_priv_data *inb_priv;
424         struct rte_mbuf *inner = NULL;
425         uint32_t sa_idx;
426         uint16_t ucc;
427         uint32_t len;
428         uintptr_t ip;
429         void *inb_sa;
430         uint64_t w0;
431
432         if ((flags & NIX_RX_REAS_F) && (cq_w1 & BIT(11))) {
433                 /* Get SPI from CPT_PARSE_S's cookie(already swapped) */
434                 w0 = hdr->w0.u64;
435                 sa_idx = w0 >> 32;
436
437                 inb_sa = roc_nix_inl_ot_ipsec_inb_sa(sa_base, sa_idx);
438                 inb_priv = roc_nix_inl_ot_ipsec_inb_sa_sw_rsvd(inb_sa);
439
440                 if (!hdr->w0.num_frags) {
441                         /* No Reassembly or inbound error */
442                         inner = (struct rte_mbuf *)
443                                 (rte_be_to_cpu_64(hdr->wqe_ptr) -
444                                  sizeof(struct rte_mbuf));
445
446                         /* Update dynamic field with userdata */
447                         *rte_security_dynfield(inner) =
448                                 (uint64_t)inb_priv->userdata;
449
450                         /* Get ucc from cpt parse header */
451                         ucc = hdr->w3.hw_ccode;
452
453                         /* Calculate inner packet length as
454                          * IP total len + l2 len
455                          */
456                         ip = (uintptr_t)hdr + ((cq_w5 >> 16) & 0xFF);
457                         ip += ((cq_w1 >> 40) & 0x6);
458                         len = rte_be_to_cpu_16(*(uint16_t *)ip);
459                         len += ((cq_w5 >> 16) & 0xFF) - (cq_w5 & 0xFF);
460                         len += (cq_w1 & BIT(42)) ? 40 : 0;
461
462                         inner->pkt_len = len;
463                         inner->data_len = len;
464                         *(uint64_t *)(&inner->rearm_data) = mbuf_init;
465
466                         inner->ol_flags = ((ucc == CPT_COMP_WARN) ?
467                                            RTE_MBUF_F_RX_SEC_OFFLOAD :
468                                            (RTE_MBUF_F_RX_SEC_OFFLOAD |
469                                             RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED));
470                 } else if (!(hdr->w0.err_sum) && !(hdr->w0.reas_sts)) {
471                         /* Reassembly success */
472                         inner = nix_sec_reassemble_frags(hdr, cq_w1, cq_w5,
473                                                          mbuf_init);
474
475                         /* Update dynamic field with userdata */
476                         *rte_security_dynfield(inner) =
477                                 (uint64_t)inb_priv->userdata;
478
479                         /* Assume success */
480                         inner->ol_flags = RTE_MBUF_F_RX_SEC_OFFLOAD;
481                 } else {
482                         /* Reassembly failure */
483                         inner = nix_sec_attach_frags(hdr, inb_priv, mbuf_init);
484                 }
485
486                 /* Store meta in lmtline to free
487                  * Assume all meta's from same aura.
488                  */
489                 *(uint64_t *)(laddr + (*loff << 3)) = (uint64_t)mbuf;
490                 *loff = *loff + 1;
491
492                 /* Mark meta mbuf as put */
493                 RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 0);
494
495                 /* Mark inner mbuf as get */
496                 RTE_MEMPOOL_CHECK_COOKIES(inner->pool, (void **)&inner, 1, 1);
497
498                 return inner;
499         } else if (cq_w1 & BIT(11)) {
500                 inner = (struct rte_mbuf *)(rte_be_to_cpu_64(hdr->wqe_ptr) -
501                                             sizeof(struct rte_mbuf));
502
503                 /* Get SPI from CPT_PARSE_S's cookie(already swapped) */
504                 w0 = hdr->w0.u64;
505                 sa_idx = w0 >> 32;
506
507                 inb_sa = roc_nix_inl_ot_ipsec_inb_sa(sa_base, sa_idx);
508                 inb_priv = roc_nix_inl_ot_ipsec_inb_sa_sw_rsvd(inb_sa);
509
510                 /* Update dynamic field with userdata */
511                 *rte_security_dynfield(inner) = (uint64_t)inb_priv->userdata;
512
513                 /* Get ucc from cpt parse header */
514                 ucc = hdr->w3.hw_ccode;
515
516                 /* Calculate inner packet length as IP total len + l2 len */
517                 ip = (uintptr_t)hdr + ((cq_w5 >> 16) & 0xFF);
518                 ip += ((cq_w1 >> 40) & 0x6);
519                 len = rte_be_to_cpu_16(*(uint16_t *)ip);
520                 len += ((cq_w5 >> 16) & 0xFF) - (cq_w5 & 0xFF);
521                 len += (cq_w1 & BIT(42)) ? 40 : 0;
522
523                 inner->pkt_len = len;
524                 inner->data_len = len;
525                 *(uint64_t *)(&inner->rearm_data) = mbuf_init;
526
527                 inner->ol_flags = ((ucc == CPT_COMP_WARN) ?
528                                    RTE_MBUF_F_RX_SEC_OFFLOAD :
529                                    (RTE_MBUF_F_RX_SEC_OFFLOAD |
530                                     RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED));
531
532                 /* Store meta in lmtline to free
533                  * Assume all meta's from same aura.
534                  */
535                 *(uint64_t *)(laddr + (*loff << 3)) = (uint64_t)mbuf;
536                 *loff = *loff + 1;
537
538                 /* Mark meta mbuf as put */
539                 RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 0);
540
541                 /* Mark inner mbuf as get */
542                 RTE_MEMPOOL_CHECK_COOKIES(inner->pool, (void **)&inner, 1, 1);
543
544                 return inner;
545         }
546
547         return mbuf;
548 }
549
550 #if defined(RTE_ARCH_ARM64)
551
552 static __rte_always_inline void
553 nix_sec_meta_to_mbuf(uint64_t cq_w1, uint64_t cq_w5, uintptr_t inb_sa,
554                      uintptr_t cpth, struct rte_mbuf *inner,
555                      uint8x16_t *rx_desc_field1, uint64_t *ol_flags,
556                      const uint16_t flags, uint64x2_t *rearm)
557 {
558         const struct cpt_parse_hdr_s *hdr =
559                 (const struct cpt_parse_hdr_s *)cpth;
560         uint64_t mbuf_init = vgetq_lane_u64(*rearm, 0);
561         struct cn10k_inb_priv_data *inb_priv;
562
563         /* Clear checksum flags */
564         *ol_flags &= ~(RTE_MBUF_F_RX_L4_CKSUM_MASK |
565                        RTE_MBUF_F_RX_IP_CKSUM_MASK);
566
567         /* Get SPI from CPT_PARSE_S's cookie(already swapped) */
568         inb_priv = roc_nix_inl_ot_ipsec_inb_sa_sw_rsvd((void *)inb_sa);
569
570         /* Update dynamic field with userdata */
571         *rte_security_dynfield(inner) = (uint64_t)inb_priv->userdata;
572
573         /* Mark inner mbuf as get */
574         RTE_MEMPOOL_CHECK_COOKIES(inner->pool, (void **)&inner, 1, 1);
575
576         if (flags & NIX_RX_REAS_F && hdr->w0.num_frags) {
577                 if (!(hdr->w0.err_sum) && !(hdr->w0.reas_sts)) {
578                         /* Reassembly success */
579                         nix_sec_reassemble_frags(hdr, cq_w1, cq_w5, mbuf_init);
580
581                         /* Assume success */
582                         *ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD;
583
584                         /* Update pkt_len and data_len */
585                         *rx_desc_field1 = vsetq_lane_u16(inner->pkt_len,
586                                                          *rx_desc_field1, 2);
587                         *rx_desc_field1 = vsetq_lane_u16(inner->data_len,
588                                                          *rx_desc_field1, 4);
589
590                         /* Data offset might be updated */
591                         mbuf_init = *(uint64_t *)(&inner->rearm_data);
592                         *rearm = vsetq_lane_u64(mbuf_init, *rearm, 0);
593                 } else {
594                         /* Reassembly failure */
595                         nix_sec_attach_frags(hdr, inb_priv, mbuf_init);
596                         *ol_flags |= inner->ol_flags;
597
598                         /* Update pkt_len and data_len */
599                         *rx_desc_field1 = vsetq_lane_u16(inner->pkt_len,
600                                                          *rx_desc_field1, 2);
601                         *rx_desc_field1 = vsetq_lane_u16(inner->data_len,
602                                                          *rx_desc_field1, 4);
603                 }
604         }
605 }
606 #endif
607
608 static __rte_always_inline uint32_t
609 nix_ptype_get(const void *const lookup_mem, const uint64_t in)
610 {
611         const uint16_t *const ptype = lookup_mem;
612         const uint16_t lh_lg_lf = (in & 0xFFF0000000000000) >> 52;
613         const uint16_t tu_l2 = ptype[(in & 0x000FFFF000000000) >> 36];
614         const uint16_t il4_tu = ptype[PTYPE_NON_TUNNEL_ARRAY_SZ + lh_lg_lf];
615
616         return (il4_tu << PTYPE_NON_TUNNEL_WIDTH) | tu_l2;
617 }
618
619 static __rte_always_inline uint32_t
620 nix_rx_olflags_get(const void *const lookup_mem, const uint64_t in)
621 {
622         const uint32_t *const ol_flags =
623                 (const uint32_t *)((const uint8_t *)lookup_mem +
624                                    PTYPE_ARRAY_SZ);
625
626         return ol_flags[(in & 0xfff00000) >> 20];
627 }
628
629 static inline uint64_t
630 nix_update_match_id(const uint16_t match_id, uint64_t ol_flags,
631                     struct rte_mbuf *mbuf)
632 {
633         /* There is no separate bit to check match_id
634          * is valid or not? and no flag to identify it is an
635          * RTE_FLOW_ACTION_TYPE_FLAG vs RTE_FLOW_ACTION_TYPE_MARK
636          * action. The former case addressed through 0 being invalid
637          * value and inc/dec match_id pair when MARK is activated.
638          * The later case addressed through defining
639          * CNXK_FLOW_MARK_DEFAULT as value for
640          * RTE_FLOW_ACTION_TYPE_MARK.
641          * This would translate to not use
642          * CNXK_FLOW_ACTION_FLAG_DEFAULT - 1 and
643          * CNXK_FLOW_ACTION_FLAG_DEFAULT for match_id.
644          * i.e valid mark_id's are from
645          * 0 to CNXK_FLOW_ACTION_FLAG_DEFAULT - 2
646          */
647         if (likely(match_id)) {
648                 ol_flags |= RTE_MBUF_F_RX_FDIR;
649                 if (match_id != CNXK_FLOW_ACTION_FLAG_DEFAULT) {
650                         ol_flags |= RTE_MBUF_F_RX_FDIR_ID;
651                         mbuf->hash.fdir.hi = match_id - 1;
652                 }
653         }
654
655         return ol_flags;
656 }
657
658 static __rte_always_inline void
659 nix_cqe_xtract_mseg(const union nix_rx_parse_u *rx, struct rte_mbuf *mbuf,
660                     uint64_t rearm, const uint16_t flags)
661 {
662         const rte_iova_t *iova_list;
663         struct rte_mbuf *head;
664         const rte_iova_t *eol;
665         uint8_t nb_segs;
666         uint64_t sg;
667
668         sg = *(const uint64_t *)(rx + 1);
669         nb_segs = (sg >> 48) & 0x3;
670
671         if (nb_segs == 1 && !(flags & NIX_RX_SEC_REASSEMBLY_F)) {
672                 mbuf->next = NULL;
673                 return;
674         }
675
676         mbuf->pkt_len = (rx->pkt_lenm1 + 1) - (flags & NIX_RX_OFFLOAD_TSTAMP_F ?
677                                                CNXK_NIX_TIMESYNC_RX_OFFSET : 0);
678         mbuf->data_len = (sg & 0xFFFF) - (flags & NIX_RX_OFFLOAD_TSTAMP_F ?
679                                           CNXK_NIX_TIMESYNC_RX_OFFSET : 0);
680         mbuf->nb_segs = nb_segs;
681         sg = sg >> 16;
682
683         eol = ((const rte_iova_t *)(rx + 1) + ((rx->desc_sizem1 + 1) << 1));
684         /* Skip SG_S and first IOVA*/
685         iova_list = ((const rte_iova_t *)(rx + 1)) + 2;
686         nb_segs--;
687
688         rearm = rearm & ~0xFFFF;
689
690         head = mbuf;
691         while (nb_segs) {
692                 mbuf->next = ((struct rte_mbuf *)*iova_list) - 1;
693                 mbuf = mbuf->next;
694
695                 RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
696
697                 mbuf->data_len = sg & 0xFFFF;
698                 sg = sg >> 16;
699                 *(uint64_t *)(&mbuf->rearm_data) = rearm;
700                 nb_segs--;
701                 iova_list++;
702
703                 if (!nb_segs && (iova_list + 1 < eol)) {
704                         sg = *(const uint64_t *)(iova_list);
705                         nb_segs = (sg >> 48) & 0x3;
706                         head->nb_segs += nb_segs;
707                         iova_list = (const rte_iova_t *)(iova_list + 1);
708                 }
709         }
710         mbuf->next = NULL;
711 }
712
713 static __rte_always_inline void
714 cn10k_nix_cqe_to_mbuf(const struct nix_cqe_hdr_s *cq, const uint32_t tag,
715                       struct rte_mbuf *mbuf, const void *lookup_mem,
716                       const uint64_t val, const uint16_t flag)
717 {
718         const union nix_rx_parse_u *rx =
719                 (const union nix_rx_parse_u *)((const uint64_t *)cq + 1);
720         const uint64_t w1 = *(const uint64_t *)rx;
721         uint16_t len = rx->pkt_lenm1 + 1;
722         uint64_t ol_flags = 0;
723
724         if (flag & NIX_RX_OFFLOAD_PTYPE_F)
725                 mbuf->packet_type = nix_ptype_get(lookup_mem, w1);
726         else
727                 mbuf->packet_type = 0;
728
729         if (flag & NIX_RX_OFFLOAD_RSS_F) {
730                 mbuf->hash.rss = tag;
731                 ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
732         }
733
734         /* Skip rx ol flags extraction for Security packets */
735         if ((!(flag & NIX_RX_SEC_REASSEMBLY_F) || !(w1 & BIT(11))) &&
736                         flag & NIX_RX_OFFLOAD_CHECKSUM_F)
737                 ol_flags |= nix_rx_olflags_get(lookup_mem, w1);
738
739         if (flag & NIX_RX_OFFLOAD_VLAN_STRIP_F) {
740                 if (rx->vtag0_gone) {
741                         ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
742                         mbuf->vlan_tci = rx->vtag0_tci;
743                 }
744                 if (rx->vtag1_gone) {
745                         ol_flags |= RTE_MBUF_F_RX_QINQ | RTE_MBUF_F_RX_QINQ_STRIPPED;
746                         mbuf->vlan_tci_outer = rx->vtag1_tci;
747                 }
748         }
749
750         if (flag & NIX_RX_OFFLOAD_MARK_UPDATE_F)
751                 ol_flags = nix_update_match_id(rx->match_id, ol_flags, mbuf);
752
753         /* Packet data length and ol flags is already updated for sec */
754         if (flag & NIX_RX_SEC_REASSEMBLY_F && w1 & BIT_ULL(11)) {
755                 mbuf->ol_flags |= ol_flags;
756         } else {
757                 mbuf->ol_flags = ol_flags;
758                 mbuf->pkt_len = len;
759                 mbuf->data_len = len;
760                 *(uint64_t *)(&mbuf->rearm_data) = val;
761         }
762
763         if (flag & NIX_RX_MULTI_SEG_F)
764                 /*
765                  * For multi segment packets, mbuf length correction according
766                  * to Rx timestamp length will be handled later during
767                  * timestamp data process.
768                  * Hence, flag argument is not required.
769                  */
770                 nix_cqe_xtract_mseg(rx, mbuf, val, 0);
771 }
772
773 static inline uint16_t
774 nix_rx_nb_pkts(struct cn10k_eth_rxq *rxq, const uint64_t wdata,
775                const uint16_t pkts, const uint32_t qmask)
776 {
777         uint32_t available = rxq->available;
778
779         /* Update the available count if cached value is not enough */
780         if (unlikely(available < pkts)) {
781                 uint64_t reg, head, tail;
782
783                 /* Use LDADDA version to avoid reorder */
784                 reg = roc_atomic64_add_sync(wdata, rxq->cq_status);
785                 /* CQ_OP_STATUS operation error */
786                 if (reg & BIT_ULL(NIX_CQ_OP_STAT_OP_ERR) ||
787                     reg & BIT_ULL(NIX_CQ_OP_STAT_CQ_ERR))
788                         return 0;
789
790                 tail = reg & 0xFFFFF;
791                 head = (reg >> 20) & 0xFFFFF;
792                 if (tail < head)
793                         available = tail - head + qmask + 1;
794                 else
795                         available = tail - head;
796
797                 rxq->available = available;
798         }
799
800         return RTE_MIN(pkts, available);
801 }
802
803 static __rte_always_inline void
804 cn10k_nix_mbuf_to_tstamp(struct rte_mbuf *mbuf,
805                         struct cnxk_timesync_info *tstamp,
806                         const uint8_t ts_enable, uint64_t *tstamp_ptr)
807 {
808         if (ts_enable) {
809                 mbuf->pkt_len -= CNXK_NIX_TIMESYNC_RX_OFFSET;
810                 mbuf->data_len -= CNXK_NIX_TIMESYNC_RX_OFFSET;
811
812                 /* Reading the rx timestamp inserted by CGX, viz at
813                  * starting of the packet data.
814                  */
815                 *tstamp_ptr = ((*tstamp_ptr >> 32) * NSEC_PER_SEC) +
816                         (*tstamp_ptr & 0xFFFFFFFFUL);
817                 *cnxk_nix_timestamp_dynfield(mbuf, tstamp) =
818                         rte_be_to_cpu_64(*tstamp_ptr);
819                 /* RTE_MBUF_F_RX_IEEE1588_TMST flag needs to be set only in case
820                  * PTP packets are received.
821                  */
822                 if (mbuf->packet_type == RTE_PTYPE_L2_ETHER_TIMESYNC) {
823                         tstamp->rx_tstamp =
824                                 *cnxk_nix_timestamp_dynfield(mbuf, tstamp);
825                         tstamp->rx_ready = 1;
826                         mbuf->ol_flags |= RTE_MBUF_F_RX_IEEE1588_PTP |
827                                 RTE_MBUF_F_RX_IEEE1588_TMST |
828                                 tstamp->rx_tstamp_dynflag;
829                 }
830         }
831 }
832
833 static __rte_always_inline uint16_t
834 cn10k_nix_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts,
835                     const uint16_t flags)
836 {
837         struct cn10k_eth_rxq *rxq = rx_queue;
838         const uint64_t mbuf_init = rxq->mbuf_initializer;
839         const void *lookup_mem = rxq->lookup_mem;
840         const uint64_t data_off = rxq->data_off;
841         const uintptr_t desc = rxq->desc;
842         const uint64_t wdata = rxq->wdata;
843         const uint32_t qmask = rxq->qmask;
844         uint64_t lbase = rxq->lmt_base;
845         uint16_t packets = 0, nb_pkts;
846         uint8_t loff = 0, lnum = 0;
847         uint32_t head = rxq->head;
848         struct nix_cqe_hdr_s *cq;
849         struct rte_mbuf *mbuf;
850         uint64_t aura_handle;
851         uint64_t sa_base;
852         uint16_t lmt_id;
853         uint64_t laddr;
854
855         nb_pkts = nix_rx_nb_pkts(rxq, wdata, pkts, qmask);
856
857         if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
858                 aura_handle = rxq->aura_handle;
859                 sa_base = rxq->sa_base;
860                 sa_base &= ~(ROC_NIX_INL_SA_BASE_ALIGN - 1);
861                 ROC_LMT_BASE_ID_GET(lbase, lmt_id);
862                 laddr = lbase;
863                 laddr += 8;
864         }
865
866         while (packets < nb_pkts) {
867                 /* Prefetch N desc ahead */
868                 rte_prefetch_non_temporal(
869                         (void *)(desc + (CQE_SZ((head + 2) & qmask))));
870                 cq = (struct nix_cqe_hdr_s *)(desc + CQE_SZ(head));
871
872                 mbuf = nix_get_mbuf_from_cqe(cq, data_off);
873
874                 /* Mark mempool obj as "get" as it is alloc'ed by NIX */
875                 RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
876
877                 /* Translate meta to mbuf */
878                 if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
879                         const uint64_t cq_w1 = *((const uint64_t *)cq + 1);
880                         const uint64_t cq_w5 = *((const uint64_t *)cq + 5);
881
882                         mbuf = nix_sec_meta_to_mbuf_sc(cq_w1, cq_w5, sa_base, laddr,
883                                                        &loff, mbuf, data_off,
884                                                        flags, mbuf_init);
885                 }
886
887                 cn10k_nix_cqe_to_mbuf(cq, cq->tag, mbuf, lookup_mem, mbuf_init,
888                                       flags);
889                 cn10k_nix_mbuf_to_tstamp(mbuf, rxq->tstamp,
890                                         (flags & NIX_RX_OFFLOAD_TSTAMP_F),
891                                         (uint64_t *)((uint8_t *)mbuf
892                                                                 + data_off));
893                 rx_pkts[packets++] = mbuf;
894                 roc_prefetch_store_keep(mbuf);
895                 head++;
896                 head &= qmask;
897
898                 if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
899                         /* Flush when we don't have space for 4 meta */
900                         if ((15 - loff) < 1) {
901                                 nix_sec_flush_meta(laddr, lmt_id + lnum, loff,
902                                                    aura_handle);
903                                 lnum++;
904                                 lnum &= BIT_ULL(ROC_LMT_LINES_PER_CORE_LOG2) -
905                                         1;
906                                 /* First pointer starts at 8B offset */
907                                 laddr = (uintptr_t)LMT_OFF(lbase, lnum, 8);
908                                 loff = 0;
909                         }
910                 }
911         }
912
913         rxq->head = head;
914         rxq->available -= nb_pkts;
915
916         /* Free all the CQs that we've processed */
917         plt_write64((wdata | nb_pkts), rxq->cq_door);
918
919         /* Free remaining meta buffers if any */
920         if (flags & NIX_RX_OFFLOAD_SECURITY_F && loff)
921                 nix_sec_flush_meta(laddr, lmt_id + lnum, loff, aura_handle);
922
923         if (flags & NIX_RX_OFFLOAD_SECURITY_F)
924                 rte_io_wmb();
925
926         return nb_pkts;
927 }
928
929 #if defined(RTE_ARCH_ARM64)
930
931 static __rte_always_inline uint64_t
932 nix_vlan_update(const uint64_t w2, uint64_t ol_flags, uint8x16_t *f)
933 {
934         if (w2 & BIT_ULL(21) /* vtag0_gone */) {
935                 ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
936                 *f = vsetq_lane_u16((uint16_t)(w2 >> 32), *f, 5);
937         }
938
939         return ol_flags;
940 }
941
942 static __rte_always_inline uint64_t
943 nix_qinq_update(const uint64_t w2, uint64_t ol_flags, struct rte_mbuf *mbuf)
944 {
945         if (w2 & BIT_ULL(23) /* vtag1_gone */) {
946                 ol_flags |= RTE_MBUF_F_RX_QINQ | RTE_MBUF_F_RX_QINQ_STRIPPED;
947                 mbuf->vlan_tci_outer = (uint16_t)(w2 >> 48);
948         }
949
950         return ol_flags;
951 }
952
953 #define NIX_PUSH_META_TO_FREE(_mbuf, _laddr, _loff_p)                          \
954         do {                                                                   \
955                 *(uint64_t *)((_laddr) + (*(_loff_p) << 3)) = (uint64_t)_mbuf; \
956                 *(_loff_p) = *(_loff_p) + 1;                                   \
957                 /* Mark meta mbuf as put */                                    \
958                 RTE_MEMPOOL_CHECK_COOKIES(_mbuf->pool, (void **)&_mbuf, 1, 0); \
959         } while (0)
960
961 static __rte_always_inline uint16_t
962 cn10k_nix_recv_pkts_vector(void *args, struct rte_mbuf **mbufs, uint16_t pkts,
963                            const uint16_t flags, void *lookup_mem,
964                            struct cnxk_timesync_info *tstamp,
965                            uintptr_t lmt_base)
966 {
967         struct cn10k_eth_rxq *rxq = args;
968         const uint64_t mbuf_initializer = (flags & NIX_RX_VWQE_F) ?
969                                                         *(uint64_t *)args :
970                                                         rxq->mbuf_initializer;
971         const uint64x2_t data_off = flags & NIX_RX_VWQE_F ?
972                                         vdupq_n_u64(RTE_PKTMBUF_HEADROOM) :
973                                         vdupq_n_u64(rxq->data_off);
974         const uint32_t qmask = flags & NIX_RX_VWQE_F ? 0 : rxq->qmask;
975         const uint64_t wdata = flags & NIX_RX_VWQE_F ? 0 : rxq->wdata;
976         const uintptr_t desc = flags & NIX_RX_VWQE_F ? 0 : rxq->desc;
977         uint64x2_t cq0_w8, cq1_w8, cq2_w8, cq3_w8, mbuf01, mbuf23;
978         uint64_t ol_flags0, ol_flags1, ol_flags2, ol_flags3;
979         uint64x2_t rearm0 = vdupq_n_u64(mbuf_initializer);
980         uint64x2_t rearm1 = vdupq_n_u64(mbuf_initializer);
981         uint64x2_t rearm2 = vdupq_n_u64(mbuf_initializer);
982         uint64x2_t rearm3 = vdupq_n_u64(mbuf_initializer);
983         struct rte_mbuf *mbuf0, *mbuf1, *mbuf2, *mbuf3;
984         uint64_t aura_handle, lbase, laddr;
985         uint8_t loff = 0, lnum = 0, shft = 0;
986         uint8x16_t f0, f1, f2, f3;
987         uint16_t lmt_id, d_off;
988         uint16_t packets = 0;
989         uint16_t pkts_left;
990         uintptr_t sa_base;
991         uint32_t head;
992         uintptr_t cq0;
993
994         if (!(flags & NIX_RX_VWQE_F)) {
995                 lookup_mem = rxq->lookup_mem;
996                 head = rxq->head;
997
998                 pkts = nix_rx_nb_pkts(rxq, wdata, pkts, qmask);
999                 pkts_left = pkts & (NIX_DESCS_PER_LOOP - 1);
1000                 /* Packets has to be floor-aligned to NIX_DESCS_PER_LOOP */
1001                 pkts = RTE_ALIGN_FLOOR(pkts, NIX_DESCS_PER_LOOP);
1002                 if (flags & NIX_RX_OFFLOAD_TSTAMP_F)
1003                         tstamp = rxq->tstamp;
1004
1005                 cq0 = desc + CQE_SZ(head);
1006                 rte_prefetch0(CQE_PTR_OFF(cq0, 0, 64, flags));
1007                 rte_prefetch0(CQE_PTR_OFF(cq0, 1, 64, flags));
1008                 rte_prefetch0(CQE_PTR_OFF(cq0, 2, 64, flags));
1009                 rte_prefetch0(CQE_PTR_OFF(cq0, 3, 64, flags));
1010         } else {
1011                 RTE_SET_USED(head);
1012         }
1013
1014         if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
1015                 if (flags & NIX_RX_VWQE_F) {
1016                         uint16_t port;
1017
1018                         mbuf0 = (struct rte_mbuf *)((uintptr_t)mbufs[0] -
1019                                                     sizeof(struct rte_mbuf));
1020                         /* Pick first mbuf's aura handle assuming all
1021                          * mbufs are from a vec and are from same RQ.
1022                          */
1023                         aura_handle = mbuf0->pool->pool_id;
1024                         /* Calculate offset from mbuf to actual data area */
1025                         d_off = ((uintptr_t)mbuf0->buf_addr - (uintptr_t)mbuf0);
1026                         d_off += (mbuf_initializer & 0xFFFF);
1027
1028                         /* Get SA Base from lookup tbl using port_id */
1029                         port = mbuf_initializer >> 48;
1030                         sa_base = cnxk_nix_sa_base_get(port, lookup_mem);
1031
1032                         lbase = lmt_base;
1033                 } else {
1034                         aura_handle = rxq->aura_handle;
1035                         d_off = rxq->data_off;
1036                         sa_base = rxq->sa_base;
1037                         lbase = rxq->lmt_base;
1038                 }
1039                 sa_base &= ~(ROC_NIX_INL_SA_BASE_ALIGN - 1);
1040                 ROC_LMT_BASE_ID_GET(lbase, lmt_id);
1041                 lnum = 0;
1042                 laddr = lbase;
1043                 laddr += 8;
1044         }
1045
1046         while (packets < pkts) {
1047                 if (!(flags & NIX_RX_VWQE_F)) {
1048                         /* Exit loop if head is about to wrap and become
1049                          * unaligned.
1050                          */
1051                         if (((head + NIX_DESCS_PER_LOOP - 1) & qmask) <
1052                             NIX_DESCS_PER_LOOP) {
1053                                 pkts_left += (pkts - packets);
1054                                 break;
1055                         }
1056
1057                         cq0 = desc + CQE_SZ(head);
1058                 } else {
1059                         cq0 = (uintptr_t)&mbufs[packets];
1060                 }
1061
1062                 if (flags & NIX_RX_VWQE_F) {
1063                         if (pkts - packets > 4) {
1064                                 rte_prefetch_non_temporal(CQE_PTR_OFF(cq0,
1065                                         4, 0, flags));
1066                                 rte_prefetch_non_temporal(CQE_PTR_OFF(cq0,
1067                                         5, 0, flags));
1068                                 rte_prefetch_non_temporal(CQE_PTR_OFF(cq0,
1069                                         6, 0, flags));
1070                                 rte_prefetch_non_temporal(CQE_PTR_OFF(cq0,
1071                                         7, 0, flags));
1072
1073                                 if (likely(pkts - packets > 8)) {
1074                                         rte_prefetch1(CQE_PTR_OFF(cq0,
1075                                                 8, 0, flags));
1076                                         rte_prefetch1(CQE_PTR_OFF(cq0,
1077                                                 9, 0, flags));
1078                                         rte_prefetch1(CQE_PTR_OFF(cq0,
1079                                                 10, 0, flags));
1080                                         rte_prefetch1(CQE_PTR_OFF(cq0,
1081                                                 11, 0, flags));
1082                                         if (pkts - packets > 12) {
1083                                                 rte_prefetch1(CQE_PTR_OFF(cq0,
1084                                                         12, 0, flags));
1085                                                 rte_prefetch1(CQE_PTR_OFF(cq0,
1086                                                         13, 0, flags));
1087                                                 rte_prefetch1(CQE_PTR_OFF(cq0,
1088                                                         14, 0, flags));
1089                                                 rte_prefetch1(CQE_PTR_OFF(cq0,
1090                                                         15, 0, flags));
1091                                         }
1092                                 }
1093
1094                                 rte_prefetch0(CQE_PTR_DIFF(cq0,
1095                                         4, RTE_PKTMBUF_HEADROOM, flags));
1096                                 rte_prefetch0(CQE_PTR_DIFF(cq0,
1097                                         5, RTE_PKTMBUF_HEADROOM, flags));
1098                                 rte_prefetch0(CQE_PTR_DIFF(cq0,
1099                                         6, RTE_PKTMBUF_HEADROOM, flags));
1100                                 rte_prefetch0(CQE_PTR_DIFF(cq0,
1101                                         7, RTE_PKTMBUF_HEADROOM, flags));
1102
1103                                 if (likely(pkts - packets > 8)) {
1104                                         rte_prefetch0(CQE_PTR_DIFF(cq0,
1105                                                 8, RTE_PKTMBUF_HEADROOM, flags));
1106                                         rte_prefetch0(CQE_PTR_DIFF(cq0,
1107                                                 9, RTE_PKTMBUF_HEADROOM, flags));
1108                                         rte_prefetch0(CQE_PTR_DIFF(cq0,
1109                                                 10, RTE_PKTMBUF_HEADROOM, flags));
1110                                         rte_prefetch0(CQE_PTR_DIFF(cq0,
1111                                                 11, RTE_PKTMBUF_HEADROOM, flags));
1112                                 }
1113                         }
1114                 } else {
1115                         if (flags & NIX_RX_OFFLOAD_SECURITY_F &&
1116                             pkts - packets > 4) {
1117                                 /* Fetch cpt parse header */
1118                                 void *p0 =
1119                                         (void *)*CQE_PTR_OFF(cq0, 4, 72, flags);
1120                                 void *p1 =
1121                                         (void *)*CQE_PTR_OFF(cq0, 5, 72, flags);
1122                                 void *p2 =
1123                                         (void *)*CQE_PTR_OFF(cq0, 6, 72, flags);
1124                                 void *p3 =
1125                                         (void *)*CQE_PTR_OFF(cq0, 7, 72, flags);
1126                                 rte_prefetch0(p0);
1127                                 rte_prefetch0(p1);
1128                                 rte_prefetch0(p2);
1129                                 rte_prefetch0(p3);
1130                         }
1131
1132                         if (pkts - packets > 8) {
1133                                 if (flags) {
1134                                         rte_prefetch0(CQE_PTR_OFF(cq0, 8, 0, flags));
1135                                         rte_prefetch0(CQE_PTR_OFF(cq0, 9, 0, flags));
1136                                         rte_prefetch0(CQE_PTR_OFF(cq0, 10, 0, flags));
1137                                         rte_prefetch0(CQE_PTR_OFF(cq0, 11, 0, flags));
1138                                 }
1139                                 rte_prefetch0(CQE_PTR_OFF(cq0, 8, 64, flags));
1140                                 rte_prefetch0(CQE_PTR_OFF(cq0, 9, 64, flags));
1141                                 rte_prefetch0(CQE_PTR_OFF(cq0, 10, 64, flags));
1142                                 rte_prefetch0(CQE_PTR_OFF(cq0, 11, 64, flags));
1143                         }
1144                 }
1145
1146                 if (!(flags & NIX_RX_VWQE_F)) {
1147                         /* Get NIX_RX_SG_S for size and buffer pointer */
1148                         cq0_w8 = vld1q_u64(CQE_PTR_OFF(cq0, 0, 64, flags));
1149                         cq1_w8 = vld1q_u64(CQE_PTR_OFF(cq0, 1, 64, flags));
1150                         cq2_w8 = vld1q_u64(CQE_PTR_OFF(cq0, 2, 64, flags));
1151                         cq3_w8 = vld1q_u64(CQE_PTR_OFF(cq0, 3, 64, flags));
1152
1153                         /* Extract mbuf from NIX_RX_SG_S */
1154                         mbuf01 = vzip2q_u64(cq0_w8, cq1_w8);
1155                         mbuf23 = vzip2q_u64(cq2_w8, cq3_w8);
1156                         mbuf01 = vqsubq_u64(mbuf01, data_off);
1157                         mbuf23 = vqsubq_u64(mbuf23, data_off);
1158                 } else {
1159                         mbuf01 =
1160                                 vsubq_u64(vld1q_u64((uint64_t *)cq0), data_off);
1161                         mbuf23 = vsubq_u64(vld1q_u64((uint64_t *)(cq0 + 16)),
1162                                            data_off);
1163                 }
1164
1165                 /* Move mbufs to scalar registers for future use */
1166                 mbuf0 = (struct rte_mbuf *)vgetq_lane_u64(mbuf01, 0);
1167                 mbuf1 = (struct rte_mbuf *)vgetq_lane_u64(mbuf01, 1);
1168                 mbuf2 = (struct rte_mbuf *)vgetq_lane_u64(mbuf23, 0);
1169                 mbuf3 = (struct rte_mbuf *)vgetq_lane_u64(mbuf23, 1);
1170
1171                 if (!(flags & NIX_RX_VWQE_F)) {
1172                         /* Mask to get packet len from NIX_RX_SG_S */
1173                         const uint8x16_t shuf_msk = {
1174                                 0xFF, 0xFF, /* pkt_type set as unknown */
1175                                 0xFF, 0xFF, /* pkt_type set as unknown */
1176                                 0,    1,    /* octet 1~0, low 16 bits pkt_len */
1177                                 0xFF, 0xFF, /* skip high 16it pkt_len, zero out */
1178                                 0,    1,    /* octet 1~0, 16 bits data_len */
1179                                 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1180
1181                         /* Form the rx_descriptor_fields1 with pkt_len and data_len */
1182                         f0 = vqtbl1q_u8(cq0_w8, shuf_msk);
1183                         f1 = vqtbl1q_u8(cq1_w8, shuf_msk);
1184                         f2 = vqtbl1q_u8(cq2_w8, shuf_msk);
1185                         f3 = vqtbl1q_u8(cq3_w8, shuf_msk);
1186                 }
1187
1188                 /* Load CQE word0 and word 1 */
1189                 const uint64_t cq0_w0 = *CQE_PTR_OFF(cq0, 0, 0, flags);
1190                 const uint64_t cq0_w1 = *CQE_PTR_OFF(cq0, 0, 8, flags);
1191                 const uint64_t cq0_w2 = *CQE_PTR_OFF(cq0, 0, 16, flags);
1192                 const uint64_t cq1_w0 = *CQE_PTR_OFF(cq0, 1, 0, flags);
1193                 const uint64_t cq1_w1 = *CQE_PTR_OFF(cq0, 1, 8, flags);
1194                 const uint64_t cq1_w2 = *CQE_PTR_OFF(cq0, 1, 16, flags);
1195                 const uint64_t cq2_w0 = *CQE_PTR_OFF(cq0, 2, 0, flags);
1196                 const uint64_t cq2_w1 = *CQE_PTR_OFF(cq0, 2, 8, flags);
1197                 const uint64_t cq2_w2 = *CQE_PTR_OFF(cq0, 2, 16, flags);
1198                 const uint64_t cq3_w0 = *CQE_PTR_OFF(cq0, 3, 0, flags);
1199                 const uint64_t cq3_w1 = *CQE_PTR_OFF(cq0, 3, 8, flags);
1200                 const uint64_t cq3_w2 = *CQE_PTR_OFF(cq0, 3, 16, flags);
1201
1202                 if (flags & NIX_RX_VWQE_F) {
1203                         uint16_t psize0, psize1, psize2, psize3;
1204
1205                         psize0 = (cq0_w2 & 0xFFFF) + 1;
1206                         psize1 = (cq1_w2 & 0xFFFF) + 1;
1207                         psize2 = (cq2_w2 & 0xFFFF) + 1;
1208                         psize3 = (cq3_w2 & 0xFFFF) + 1;
1209
1210                         f0 = vdupq_n_u64(0);
1211                         f1 = vdupq_n_u64(0);
1212                         f2 = vdupq_n_u64(0);
1213                         f3 = vdupq_n_u64(0);
1214
1215                         f0 = vsetq_lane_u16(psize0, f0, 2);
1216                         f0 = vsetq_lane_u16(psize0, f0, 4);
1217
1218                         f1 = vsetq_lane_u16(psize1, f1, 2);
1219                         f1 = vsetq_lane_u16(psize1, f1, 4);
1220
1221                         f2 = vsetq_lane_u16(psize2, f2, 2);
1222                         f2 = vsetq_lane_u16(psize2, f2, 4);
1223
1224                         f3 = vsetq_lane_u16(psize3, f3, 2);
1225                         f3 = vsetq_lane_u16(psize3, f3, 4);
1226                 }
1227
1228                 if (flags & NIX_RX_OFFLOAD_RSS_F) {
1229                         /* Fill rss in the rx_descriptor_fields1 */
1230                         f0 = vsetq_lane_u32(cq0_w0, f0, 3);
1231                         f1 = vsetq_lane_u32(cq1_w0, f1, 3);
1232                         f2 = vsetq_lane_u32(cq2_w0, f2, 3);
1233                         f3 = vsetq_lane_u32(cq3_w0, f3, 3);
1234                         ol_flags0 = RTE_MBUF_F_RX_RSS_HASH;
1235                         ol_flags1 = RTE_MBUF_F_RX_RSS_HASH;
1236                         ol_flags2 = RTE_MBUF_F_RX_RSS_HASH;
1237                         ol_flags3 = RTE_MBUF_F_RX_RSS_HASH;
1238                 } else {
1239                         ol_flags0 = 0;
1240                         ol_flags1 = 0;
1241                         ol_flags2 = 0;
1242                         ol_flags3 = 0;
1243                 }
1244
1245                 if (flags & NIX_RX_OFFLOAD_PTYPE_F) {
1246                         /* Fill packet_type in the rx_descriptor_fields1 */
1247                         f0 = vsetq_lane_u32(nix_ptype_get(lookup_mem, cq0_w1),
1248                                             f0, 0);
1249                         f1 = vsetq_lane_u32(nix_ptype_get(lookup_mem, cq1_w1),
1250                                             f1, 0);
1251                         f2 = vsetq_lane_u32(nix_ptype_get(lookup_mem, cq2_w1),
1252                                             f2, 0);
1253                         f3 = vsetq_lane_u32(nix_ptype_get(lookup_mem, cq3_w1),
1254                                             f3, 0);
1255                 }
1256
1257                 if (flags & NIX_RX_OFFLOAD_CHECKSUM_F) {
1258                         ol_flags0 |= nix_rx_olflags_get(lookup_mem, cq0_w1);
1259                         ol_flags1 |= nix_rx_olflags_get(lookup_mem, cq1_w1);
1260                         ol_flags2 |= nix_rx_olflags_get(lookup_mem, cq2_w1);
1261                         ol_flags3 |= nix_rx_olflags_get(lookup_mem, cq3_w1);
1262                 }
1263
1264                 /* Mark mempool obj as "get" as it is alloc'ed by NIX */
1265                 RTE_MEMPOOL_CHECK_COOKIES(mbuf0->pool, (void **)&mbuf0, 1, 1);
1266                 RTE_MEMPOOL_CHECK_COOKIES(mbuf1->pool, (void **)&mbuf1, 1, 1);
1267                 RTE_MEMPOOL_CHECK_COOKIES(mbuf2->pool, (void **)&mbuf2, 1, 1);
1268                 RTE_MEMPOOL_CHECK_COOKIES(mbuf3->pool, (void **)&mbuf3, 1, 1);
1269
1270                 /* Translate meta to mbuf */
1271                 if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
1272                         uint64_t cq0_w5 = *CQE_PTR_OFF(cq0, 0, 40, flags);
1273                         uint64_t cq1_w5 = *CQE_PTR_OFF(cq0, 1, 40, flags);
1274                         uint64_t cq2_w5 = *CQE_PTR_OFF(cq0, 2, 40, flags);
1275                         uint64_t cq3_w5 = *CQE_PTR_OFF(cq0, 3, 40, flags);
1276                         uintptr_t cpth0 = (uintptr_t)mbuf0 + d_off;
1277                         uintptr_t cpth1 = (uintptr_t)mbuf1 + d_off;
1278                         uintptr_t cpth2 = (uintptr_t)mbuf2 + d_off;
1279                         uintptr_t cpth3 = (uintptr_t)mbuf3 + d_off;
1280
1281                         uint64x2_t inner0, inner1, inner2, inner3;
1282                         uint64x2_t wqe01, wqe23, sa01, sa23;
1283                         uint16x4_t lens, l2lens, ltypes;
1284                         uint8x8_t ucc;
1285
1286                         inner0 = vld1q_u64((const uint64_t *)cpth0);
1287                         inner1 = vld1q_u64((const uint64_t *)cpth1);
1288                         inner2 = vld1q_u64((const uint64_t *)cpth2);
1289                         inner3 = vld1q_u64((const uint64_t *)cpth3);
1290
1291                         /* Extract and reverse wqe pointers */
1292                         wqe01 = vzip2q_u64(inner0, inner1);
1293                         wqe23 = vzip2q_u64(inner2, inner3);
1294                         wqe01 = vrev64q_u8(wqe01);
1295                         wqe23 = vrev64q_u8(wqe23);
1296                         /* Adjust wqe pointers to point to mbuf */
1297                         wqe01 = vsubq_u64(wqe01,
1298                                           vdupq_n_u64(sizeof(struct rte_mbuf)));
1299                         wqe23 = vsubq_u64(wqe23,
1300                                           vdupq_n_u64(sizeof(struct rte_mbuf)));
1301
1302                         /* Extract sa idx from cookie area and add to sa_base */
1303                         sa01 = vzip1q_u64(inner0, inner1);
1304                         sa23 = vzip1q_u64(inner2, inner3);
1305
1306                         sa01 = vshrq_n_u64(sa01, 32);
1307                         sa23 = vshrq_n_u64(sa23, 32);
1308                         sa01 = vshlq_n_u64(sa01,
1309                                            ROC_NIX_INL_OT_IPSEC_INB_SA_SZ_LOG2);
1310                         sa23 = vshlq_n_u64(sa23,
1311                                            ROC_NIX_INL_OT_IPSEC_INB_SA_SZ_LOG2);
1312                         sa01 = vaddq_u64(sa01, vdupq_n_u64(sa_base));
1313                         sa23 = vaddq_u64(sa23, vdupq_n_u64(sa_base));
1314
1315                         const uint8x16_t tbl = {
1316                                 0, 0, 0, 0, 0, 0, 0, 0,
1317                                 /* HW_CCODE -> RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED */
1318                                 1, 0, 1, 1, 1, 1, 0, 1,
1319                         };
1320
1321                         const int8x8_t err_off = {
1322                                 /* UCC of significance starts from 0xF0 */
1323                                 0xF0,
1324                                 /* Move HW_CCODE from 0:6 -> 8:14 */
1325                                 -8,
1326                                 0xF0,
1327                                 -8,
1328                                 0xF0,
1329                                 -8,
1330                                 0xF0,
1331                                 -8,
1332                         };
1333
1334                         ucc = vdup_n_u8(0);
1335                         ucc = vset_lane_u16(*(uint16_t *)(cpth0 + 30), ucc, 0);
1336                         ucc = vset_lane_u16(*(uint16_t *)(cpth1 + 30), ucc, 1);
1337                         ucc = vset_lane_u16(*(uint16_t *)(cpth2 + 30), ucc, 2);
1338                         ucc = vset_lane_u16(*(uint16_t *)(cpth3 + 30), ucc, 3);
1339                         ucc = vsub_s8(ucc, err_off);
1340                         ucc = vqtbl1_u8(tbl, ucc);
1341
1342                         RTE_BUILD_BUG_ON(NPC_LT_LC_IP != 2);
1343                         RTE_BUILD_BUG_ON(NPC_LT_LC_IP_OPT != 3);
1344                         RTE_BUILD_BUG_ON(NPC_LT_LC_IP6 != 4);
1345                         RTE_BUILD_BUG_ON(NPC_LT_LC_IP6_EXT != 5);
1346
1347                         ltypes = vdup_n_u16(0);
1348                         ltypes = vset_lane_u16((cq0_w1 >> 40) & 0x6, ltypes, 0);
1349                         ltypes = vset_lane_u16((cq1_w1 >> 40) & 0x6, ltypes, 1);
1350                         ltypes = vset_lane_u16((cq2_w1 >> 40) & 0x6, ltypes, 2);
1351                         ltypes = vset_lane_u16((cq3_w1 >> 40) & 0x6, ltypes, 3);
1352
1353                         /* Extract and reverse l3 length from IPv4/IPv6 hdr
1354                          * that is in same cacheline most probably as cpth.
1355                          */
1356                         cpth0 += ((cq0_w5 >> 16) & 0xFF) +
1357                                  vget_lane_u16(ltypes, 0);
1358                         cpth1 += ((cq1_w5 >> 16) & 0xFF) +
1359                                  vget_lane_u16(ltypes, 1);
1360                         cpth2 += ((cq2_w5 >> 16) & 0xFF) +
1361                                  vget_lane_u16(ltypes, 2);
1362                         cpth3 += ((cq3_w5 >> 16) & 0xFF) +
1363                                  vget_lane_u16(ltypes, 3);
1364                         lens = vdup_n_u16(0);
1365                         lens = vset_lane_u16(*(uint16_t *)cpth0, lens, 0);
1366                         lens = vset_lane_u16(*(uint16_t *)cpth1, lens, 1);
1367                         lens = vset_lane_u16(*(uint16_t *)cpth2, lens, 2);
1368                         lens = vset_lane_u16(*(uint16_t *)cpth3, lens, 3);
1369                         lens = vrev16_u8(lens);
1370
1371                         /* Add l2 length to l3 lengths */
1372                         l2lens = vdup_n_u16(0);
1373                         l2lens = vset_lane_u16(((cq0_w5 >> 16) & 0xFF) -
1374                                                        (cq0_w5 & 0xFF),
1375                                                l2lens, 0);
1376                         l2lens = vset_lane_u16(((cq1_w5 >> 16) & 0xFF) -
1377                                                        (cq1_w5 & 0xFF),
1378                                                l2lens, 1);
1379                         l2lens = vset_lane_u16(((cq2_w5 >> 16) & 0xFF) -
1380                                                        (cq2_w5 & 0xFF),
1381                                                l2lens, 2);
1382                         l2lens = vset_lane_u16(((cq3_w5 >> 16) & 0xFF) -
1383                                                        (cq3_w5 & 0xFF),
1384                                                l2lens, 3);
1385                         lens = vadd_u16(lens, l2lens);
1386
1387                         /* L3 header adjust */
1388                         const int8x8_t l3adj = {
1389                                 0, 0, 0, 0, 40, 0, 0, 0,
1390                         };
1391                         lens = vadd_u16(lens, vtbl1_u8(l3adj, ltypes));
1392
1393                         /* Initialize rearm data when reassembly is enabled as
1394                          * data offset might change.
1395                          */
1396                         if (flags & NIX_RX_REAS_F) {
1397                                 rearm0 = vdupq_n_u64(mbuf_initializer);
1398                                 rearm1 = vdupq_n_u64(mbuf_initializer);
1399                                 rearm2 = vdupq_n_u64(mbuf_initializer);
1400                                 rearm3 = vdupq_n_u64(mbuf_initializer);
1401                         }
1402
1403                         /* Checksum ol_flags will be cleared if mbuf is meta */
1404                         if (cq0_w1 & BIT(11)) {
1405                                 uintptr_t wqe = vgetq_lane_u64(wqe01, 0);
1406                                 uintptr_t sa = vgetq_lane_u64(sa01, 0);
1407                                 uint16_t len = vget_lane_u16(lens, 0);
1408
1409                                 cpth0 = (uintptr_t)mbuf0 + d_off;
1410                                 /* Free meta to aura */
1411                                 NIX_PUSH_META_TO_FREE(mbuf0, laddr, &loff);
1412                                 mbuf01 = vsetq_lane_u64(wqe, mbuf01, 0);
1413                                 mbuf0 = (struct rte_mbuf *)wqe;
1414
1415                                 /* Update pkt_len and data_len */
1416                                 f0 = vsetq_lane_u16(len, f0, 2);
1417                                 f0 = vsetq_lane_u16(len, f0, 4);
1418
1419                                 nix_sec_meta_to_mbuf(cq0_w1, cq0_w5, sa, cpth0,
1420                                                      mbuf0, &f0, &ol_flags0,
1421                                                      flags, &rearm0);
1422                                 ol_flags0 |= (RTE_MBUF_F_RX_SEC_OFFLOAD |
1423                                         (uint64_t)vget_lane_u8(ucc, 1) << 19);
1424                         }
1425
1426                         if (cq1_w1 & BIT(11)) {
1427                                 uintptr_t wqe = vgetq_lane_u64(wqe01, 1);
1428                                 uintptr_t sa = vgetq_lane_u64(sa01, 1);
1429                                 uint16_t len = vget_lane_u16(lens, 1);
1430
1431                                 cpth1 = (uintptr_t)mbuf1 + d_off;
1432                                 /* Free meta to aura */
1433                                 NIX_PUSH_META_TO_FREE(mbuf1, laddr, &loff);
1434                                 mbuf01 = vsetq_lane_u64(wqe, mbuf01, 1);
1435                                 mbuf1 = (struct rte_mbuf *)wqe;
1436
1437                                 /* Update pkt_len and data_len */
1438                                 f1 = vsetq_lane_u16(len, f1, 2);
1439                                 f1 = vsetq_lane_u16(len, f1, 4);
1440
1441                                 nix_sec_meta_to_mbuf(cq1_w1, cq1_w5, sa, cpth1,
1442                                                      mbuf1, &f1, &ol_flags1,
1443                                                      flags, &rearm1);
1444                                 ol_flags1 |= (RTE_MBUF_F_RX_SEC_OFFLOAD |
1445                                         (uint64_t)vget_lane_u8(ucc, 3) << 19);
1446                         }
1447
1448                         if (cq2_w1 & BIT(11)) {
1449                                 uintptr_t wqe = vgetq_lane_u64(wqe23, 0);
1450                                 uintptr_t sa = vgetq_lane_u64(sa23, 0);
1451                                 uint16_t len = vget_lane_u16(lens, 2);
1452
1453                                 cpth2 = (uintptr_t)mbuf2 + d_off;
1454                                 /* Free meta to aura */
1455                                 NIX_PUSH_META_TO_FREE(mbuf2, laddr, &loff);
1456                                 mbuf23 = vsetq_lane_u64(wqe, mbuf23, 0);
1457                                 mbuf2 = (struct rte_mbuf *)wqe;
1458
1459                                 /* Update pkt_len and data_len */
1460                                 f2 = vsetq_lane_u16(len, f2, 2);
1461                                 f2 = vsetq_lane_u16(len, f2, 4);
1462
1463                                 nix_sec_meta_to_mbuf(cq2_w1, cq2_w5, sa, cpth2,
1464                                                      mbuf2, &f2, &ol_flags2,
1465                                                      flags, &rearm2);
1466                                 ol_flags2 |= (RTE_MBUF_F_RX_SEC_OFFLOAD |
1467                                         (uint64_t)vget_lane_u8(ucc, 5) << 19);
1468                         }
1469
1470                         if (cq3_w1 & BIT(11)) {
1471                                 uintptr_t wqe = vgetq_lane_u64(wqe23, 1);
1472                                 uintptr_t sa = vgetq_lane_u64(sa23, 1);
1473                                 uint16_t len = vget_lane_u16(lens, 3);
1474
1475                                 cpth3 = (uintptr_t)mbuf3 + d_off;
1476                                 /* Free meta to aura */
1477                                 NIX_PUSH_META_TO_FREE(mbuf3, laddr, &loff);
1478                                 mbuf23 = vsetq_lane_u64(wqe, mbuf23, 1);
1479                                 mbuf3 = (struct rte_mbuf *)wqe;
1480
1481                                 /* Update pkt_len and data_len */
1482                                 f3 = vsetq_lane_u16(len, f3, 2);
1483                                 f3 = vsetq_lane_u16(len, f3, 4);
1484
1485                                 nix_sec_meta_to_mbuf(cq3_w1, cq3_w5, sa, cpth3,
1486                                                      mbuf3, &f3, &ol_flags3,
1487                                                      flags, &rearm3);
1488                                 ol_flags3 |= (RTE_MBUF_F_RX_SEC_OFFLOAD |
1489                                         (uint64_t)vget_lane_u8(ucc, 7) << 19);
1490                         }
1491                 }
1492
1493                 if (flags & NIX_RX_OFFLOAD_VLAN_STRIP_F) {
1494
1495                         ol_flags0 = nix_vlan_update(cq0_w2, ol_flags0, &f0);
1496                         ol_flags1 = nix_vlan_update(cq1_w2, ol_flags1, &f1);
1497                         ol_flags2 = nix_vlan_update(cq2_w2, ol_flags2, &f2);
1498                         ol_flags3 = nix_vlan_update(cq3_w2, ol_flags3, &f3);
1499
1500                         ol_flags0 = nix_qinq_update(cq0_w2, ol_flags0, mbuf0);
1501                         ol_flags1 = nix_qinq_update(cq1_w2, ol_flags1, mbuf1);
1502                         ol_flags2 = nix_qinq_update(cq2_w2, ol_flags2, mbuf2);
1503                         ol_flags3 = nix_qinq_update(cq3_w2, ol_flags3, mbuf3);
1504                 }
1505
1506                 if (flags & NIX_RX_OFFLOAD_MARK_UPDATE_F) {
1507                         ol_flags0 = nix_update_match_id(
1508                                 *(uint16_t *)CQE_PTR_OFF(cq0, 0, 38, flags),
1509                                 ol_flags0, mbuf0);
1510                         ol_flags1 = nix_update_match_id(
1511                                 *(uint16_t *)CQE_PTR_OFF(cq0, 1, 38, flags),
1512                                 ol_flags1, mbuf1);
1513                         ol_flags2 = nix_update_match_id(
1514                                 *(uint16_t *)CQE_PTR_OFF(cq0, 2, 38, flags),
1515                                 ol_flags2, mbuf2);
1516                         ol_flags3 = nix_update_match_id(
1517                                 *(uint16_t *)CQE_PTR_OFF(cq0, 3, 38, flags),
1518                                 ol_flags3, mbuf3);
1519                 }
1520
1521                 if (flags & NIX_RX_OFFLOAD_TSTAMP_F) {
1522                         const uint16x8_t len_off = {
1523                                 0,                           /* ptype   0:15 */
1524                                 0,                           /* ptype  16:32 */
1525                                 CNXK_NIX_TIMESYNC_RX_OFFSET, /* pktlen  0:15*/
1526                                 0,                           /* pktlen 16:32 */
1527                                 CNXK_NIX_TIMESYNC_RX_OFFSET, /* datalen 0:15 */
1528                                 0,
1529                                 0,
1530                                 0};
1531                         const uint32x4_t ptype = {RTE_PTYPE_L2_ETHER_TIMESYNC,
1532                                                   RTE_PTYPE_L2_ETHER_TIMESYNC,
1533                                                   RTE_PTYPE_L2_ETHER_TIMESYNC,
1534                                                   RTE_PTYPE_L2_ETHER_TIMESYNC};
1535                         const uint64_t ts_olf = RTE_MBUF_F_RX_IEEE1588_PTP |
1536                                                 RTE_MBUF_F_RX_IEEE1588_TMST |
1537                                                 tstamp->rx_tstamp_dynflag;
1538                         const uint32x4_t and_mask = {0x1, 0x2, 0x4, 0x8};
1539                         uint64x2_t ts01, ts23, mask;
1540                         uint64_t ts[4];
1541                         uint8_t res;
1542
1543                         /* Subtract timesync length from total pkt length. */
1544                         f0 = vsubq_u16(f0, len_off);
1545                         f1 = vsubq_u16(f1, len_off);
1546                         f2 = vsubq_u16(f2, len_off);
1547                         f3 = vsubq_u16(f3, len_off);
1548
1549                         /* Get the address of actual timestamp. */
1550                         ts01 = vaddq_u64(mbuf01, data_off);
1551                         ts23 = vaddq_u64(mbuf23, data_off);
1552                         /* Load timestamp from address. */
1553                         ts01 = vsetq_lane_u64(*(uint64_t *)vgetq_lane_u64(ts01,
1554                                                                           0),
1555                                               ts01, 0);
1556                         ts01 = vsetq_lane_u64(*(uint64_t *)vgetq_lane_u64(ts01,
1557                                                                           1),
1558                                               ts01, 1);
1559                         ts23 = vsetq_lane_u64(*(uint64_t *)vgetq_lane_u64(ts23,
1560                                                                           0),
1561                                               ts23, 0);
1562                         ts23 = vsetq_lane_u64(*(uint64_t *)vgetq_lane_u64(ts23,
1563                                                                           1),
1564                                               ts23, 1);
1565                         /* Convert from be to cpu byteorder. */
1566                         ts01 = vrev64q_u8(ts01);
1567                         ts23 = vrev64q_u8(ts23);
1568                         /* Store timestamp into scalar for later use. */
1569                         ts[0] = vgetq_lane_u64(ts01, 0);
1570                         ts[1] = vgetq_lane_u64(ts01, 1);
1571                         ts[2] = vgetq_lane_u64(ts23, 0);
1572                         ts[3] = vgetq_lane_u64(ts23, 1);
1573
1574                         /* Store timestamp into dynfield. */
1575                         *cnxk_nix_timestamp_dynfield(mbuf0, tstamp) = ts[0];
1576                         *cnxk_nix_timestamp_dynfield(mbuf1, tstamp) = ts[1];
1577                         *cnxk_nix_timestamp_dynfield(mbuf2, tstamp) = ts[2];
1578                         *cnxk_nix_timestamp_dynfield(mbuf3, tstamp) = ts[3];
1579
1580                         /* Generate ptype mask to filter L2 ether timesync */
1581                         mask = vdupq_n_u32(vgetq_lane_u32(f0, 0));
1582                         mask = vsetq_lane_u32(vgetq_lane_u32(f1, 0), mask, 1);
1583                         mask = vsetq_lane_u32(vgetq_lane_u32(f2, 0), mask, 2);
1584                         mask = vsetq_lane_u32(vgetq_lane_u32(f3, 0), mask, 3);
1585
1586                         /* Match against L2 ether timesync. */
1587                         mask = vceqq_u32(mask, ptype);
1588                         /* Convert from vector from scalar mask */
1589                         res = vaddvq_u32(vandq_u32(mask, and_mask));
1590                         res &= 0xF;
1591
1592                         if (res) {
1593                                 /* Fill in the ol_flags for any packets that
1594                                  * matched.
1595                                  */
1596                                 ol_flags0 |= ((res & 0x1) ? ts_olf : 0);
1597                                 ol_flags1 |= ((res & 0x2) ? ts_olf : 0);
1598                                 ol_flags2 |= ((res & 0x4) ? ts_olf : 0);
1599                                 ol_flags3 |= ((res & 0x8) ? ts_olf : 0);
1600
1601                                 /* Update Rxq timestamp with the latest
1602                                  * timestamp.
1603                                  */
1604                                 tstamp->rx_ready = 1;
1605                                 tstamp->rx_tstamp = ts[31 - __builtin_clz(res)];
1606                         }
1607                 }
1608
1609                 /* Form rearm_data with ol_flags */
1610                 rearm0 = vsetq_lane_u64(ol_flags0, rearm0, 1);
1611                 rearm1 = vsetq_lane_u64(ol_flags1, rearm1, 1);
1612                 rearm2 = vsetq_lane_u64(ol_flags2, rearm2, 1);
1613                 rearm3 = vsetq_lane_u64(ol_flags3, rearm3, 1);
1614
1615                 /* Update rx_descriptor_fields1 */
1616                 vst1q_u64((uint64_t *)mbuf0->rx_descriptor_fields1, f0);
1617                 vst1q_u64((uint64_t *)mbuf1->rx_descriptor_fields1, f1);
1618                 vst1q_u64((uint64_t *)mbuf2->rx_descriptor_fields1, f2);
1619                 vst1q_u64((uint64_t *)mbuf3->rx_descriptor_fields1, f3);
1620
1621                 /* Update rearm_data */
1622                 vst1q_u64((uint64_t *)mbuf0->rearm_data, rearm0);
1623                 vst1q_u64((uint64_t *)mbuf1->rearm_data, rearm1);
1624                 vst1q_u64((uint64_t *)mbuf2->rearm_data, rearm2);
1625                 vst1q_u64((uint64_t *)mbuf3->rearm_data, rearm3);
1626
1627                 /* Store the mbufs to rx_pkts */
1628                 vst1q_u64((uint64_t *)&mbufs[packets], mbuf01);
1629                 vst1q_u64((uint64_t *)&mbufs[packets + 2], mbuf23);
1630
1631                 if (flags & NIX_RX_MULTI_SEG_F) {
1632                         /* Multi segment is enable build mseg list for
1633                          * individual mbufs in scalar mode.
1634                          */
1635                         nix_cqe_xtract_mseg((union nix_rx_parse_u *)
1636                                             (CQE_PTR_OFF(cq0, 0, 8, flags)),
1637                                             mbuf0, mbuf_initializer, flags);
1638                         nix_cqe_xtract_mseg((union nix_rx_parse_u *)
1639                                             (CQE_PTR_OFF(cq0, 1, 8, flags)),
1640                                             mbuf1, mbuf_initializer, flags);
1641                         nix_cqe_xtract_mseg((union nix_rx_parse_u *)
1642                                             (CQE_PTR_OFF(cq0, 2, 8, flags)),
1643                                             mbuf2, mbuf_initializer, flags);
1644                         nix_cqe_xtract_mseg((union nix_rx_parse_u *)
1645                                             (CQE_PTR_OFF(cq0, 3, 8, flags)),
1646                                             mbuf3, mbuf_initializer, flags);
1647                 }
1648
1649                 /* Mark mempool obj as "get" as it is alloc'ed by NIX */
1650                 RTE_MEMPOOL_CHECK_COOKIES(mbuf0->pool, (void **)&mbuf0, 1, 1);
1651                 RTE_MEMPOOL_CHECK_COOKIES(mbuf1->pool, (void **)&mbuf1, 1, 1);
1652                 RTE_MEMPOOL_CHECK_COOKIES(mbuf2->pool, (void **)&mbuf2, 1, 1);
1653                 RTE_MEMPOOL_CHECK_COOKIES(mbuf3->pool, (void **)&mbuf3, 1, 1);
1654
1655                 nix_mbuf_validate_next(mbuf0);
1656                 nix_mbuf_validate_next(mbuf1);
1657                 nix_mbuf_validate_next(mbuf2);
1658                 nix_mbuf_validate_next(mbuf3);
1659
1660                 packets += NIX_DESCS_PER_LOOP;
1661
1662                 if (!(flags & NIX_RX_VWQE_F)) {
1663                         /* Advance head pointer and packets */
1664                         head += NIX_DESCS_PER_LOOP;
1665                         head &= qmask;
1666                 }
1667
1668                 if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
1669                         /* Check if lmtline border is crossed and adjust lnum */
1670                         if (loff > 15) {
1671                                 /* Update aura handle */
1672                                 *(uint64_t *)(laddr - 8) =
1673                                         (((uint64_t)(15 & 0x1) << 32) |
1674                                     roc_npa_aura_handle_to_aura(aura_handle));
1675                                 loff = loff - 15;
1676                                 shft += 3;
1677
1678                                 lnum++;
1679                                 laddr = (uintptr_t)LMT_OFF(lbase, lnum, 8);
1680                                 /* Pick the pointer from 16th index and put it
1681                                  * at end of this new line.
1682                                  */
1683                                 *(uint64_t *)(laddr + (loff << 3) - 8) =
1684                                         *(uint64_t *)(laddr - 8);
1685                         }
1686
1687                         /* Flush it when we are in 16th line and might
1688                          * overflow it
1689                          */
1690                         if (lnum >= 15 && loff >= 12) {
1691                                 /* 16 LMT Line size m1 */
1692                                 uint64_t data = BIT_ULL(48) - 1;
1693
1694                                 /* Update aura handle */
1695                                 *(uint64_t *)(laddr - 8) =
1696                                         (((uint64_t)(loff & 0x1) << 32) |
1697                                     roc_npa_aura_handle_to_aura(aura_handle));
1698
1699                                 data = (data & ~(0x7UL << shft)) |
1700                                        (((uint64_t)loff >> 1) << shft);
1701
1702                                 /* Send up to 16 lmt lines of pointers */
1703                                 nix_sec_flush_meta_burst(lmt_id, data, lnum + 1,
1704                                                          aura_handle);
1705                                 rte_io_wmb();
1706                                 lnum = 0;
1707                                 loff = 0;
1708                                 shft = 0;
1709                                 /* First pointer starts at 8B offset */
1710                                 laddr = (uintptr_t)LMT_OFF(lbase, lnum, 8);
1711                         }
1712                 }
1713         }
1714
1715         if (flags & NIX_RX_OFFLOAD_SECURITY_F && loff) {
1716                 /* 16 LMT Line size m1 */
1717                 uint64_t data = BIT_ULL(48) - 1;
1718
1719                 /* Update aura handle */
1720                 *(uint64_t *)(laddr - 8) =
1721                         (((uint64_t)(loff & 0x1) << 32) |
1722                          roc_npa_aura_handle_to_aura(aura_handle));
1723
1724                 data = (data & ~(0x7UL << shft)) |
1725                        (((uint64_t)loff >> 1) << shft);
1726
1727                 /* Send up to 16 lmt lines of pointers */
1728                 nix_sec_flush_meta_burst(lmt_id, data, lnum + 1, aura_handle);
1729                 if (flags & NIX_RX_VWQE_F)
1730                         plt_io_wmb();
1731         }
1732
1733         if (flags & NIX_RX_VWQE_F)
1734                 return packets;
1735
1736         rxq->head = head;
1737         rxq->available -= packets;
1738
1739         rte_io_wmb();
1740         /* Free all the CQs that we've processed */
1741         plt_write64((rxq->wdata | packets), rxq->cq_door);
1742
1743         if (unlikely(pkts_left))
1744                 packets += cn10k_nix_recv_pkts(args, &mbufs[packets], pkts_left,
1745                                                flags);
1746
1747         return packets;
1748 }
1749
1750 #else
1751
1752 static inline uint16_t
1753 cn10k_nix_recv_pkts_vector(void *args, struct rte_mbuf **mbufs, uint16_t pkts,
1754                            const uint16_t flags, void *lookup_mem,
1755                            struct cnxk_timesync_info *tstamp,
1756                            uintptr_t lmt_base)
1757 {
1758         RTE_SET_USED(args);
1759         RTE_SET_USED(mbufs);
1760         RTE_SET_USED(pkts);
1761         RTE_SET_USED(flags);
1762         RTE_SET_USED(lookup_mem);
1763         RTE_SET_USED(tstamp);
1764         RTE_SET_USED(lmt_base);
1765
1766         return 0;
1767 }
1768
1769 #endif
1770
1771
1772 #define RSS_F     NIX_RX_OFFLOAD_RSS_F
1773 #define PTYPE_F   NIX_RX_OFFLOAD_PTYPE_F
1774 #define CKSUM_F   NIX_RX_OFFLOAD_CHECKSUM_F
1775 #define MARK_F    NIX_RX_OFFLOAD_MARK_UPDATE_F
1776 #define TS_F      NIX_RX_OFFLOAD_TSTAMP_F
1777 #define RX_VLAN_F NIX_RX_OFFLOAD_VLAN_STRIP_F
1778 #define R_SEC_F   NIX_RX_OFFLOAD_SECURITY_F
1779
1780 /* [R_SEC_F] [RX_VLAN_F] [TS] [MARK] [CKSUM] [PTYPE] [RSS] */
1781 #define NIX_RX_FASTPATH_MODES_0_15                                             \
1782         R(no_offload, NIX_RX_OFFLOAD_NONE)                                     \
1783         R(rss, RSS_F)                                                          \
1784         R(ptype, PTYPE_F)                                                      \
1785         R(ptype_rss, PTYPE_F | RSS_F)                                          \
1786         R(cksum, CKSUM_F)                                                      \
1787         R(cksum_rss, CKSUM_F | RSS_F)                                          \
1788         R(cksum_ptype, CKSUM_F | PTYPE_F)                                      \
1789         R(cksum_ptype_rss, CKSUM_F | PTYPE_F | RSS_F)                          \
1790         R(mark, MARK_F)                                                        \
1791         R(mark_rss, MARK_F | RSS_F)                                            \
1792         R(mark_ptype, MARK_F | PTYPE_F)                                        \
1793         R(mark_ptype_rss, MARK_F | PTYPE_F | RSS_F)                            \
1794         R(mark_cksum, MARK_F | CKSUM_F)                                        \
1795         R(mark_cksum_rss, MARK_F | CKSUM_F | RSS_F)                            \
1796         R(mark_cksum_ptype, MARK_F | CKSUM_F | PTYPE_F)                        \
1797         R(mark_cksum_ptype_rss, MARK_F | CKSUM_F | PTYPE_F | RSS_F)
1798
1799 #define NIX_RX_FASTPATH_MODES_16_31                                            \
1800         R(ts, TS_F)                                                            \
1801         R(ts_rss, TS_F | RSS_F)                                                \
1802         R(ts_ptype, TS_F | PTYPE_F)                                            \
1803         R(ts_ptype_rss, TS_F | PTYPE_F | RSS_F)                                \
1804         R(ts_cksum, TS_F | CKSUM_F)                                            \
1805         R(ts_cksum_rss, TS_F | CKSUM_F | RSS_F)                                \
1806         R(ts_cksum_ptype, TS_F | CKSUM_F | PTYPE_F)                            \
1807         R(ts_cksum_ptype_rss, TS_F | CKSUM_F | PTYPE_F | RSS_F)                \
1808         R(ts_mark, TS_F | MARK_F)                                              \
1809         R(ts_mark_rss, TS_F | MARK_F | RSS_F)                                  \
1810         R(ts_mark_ptype, TS_F | MARK_F | PTYPE_F)                              \
1811         R(ts_mark_ptype_rss, TS_F | MARK_F | PTYPE_F | RSS_F)                  \
1812         R(ts_mark_cksum, TS_F | MARK_F | CKSUM_F)                              \
1813         R(ts_mark_cksum_rss, TS_F | MARK_F | CKSUM_F | RSS_F)                  \
1814         R(ts_mark_cksum_ptype, TS_F | MARK_F | CKSUM_F | PTYPE_F)              \
1815         R(ts_mark_cksum_ptype_rss, TS_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
1816
1817 #define NIX_RX_FASTPATH_MODES_32_47                                            \
1818         R(vlan, RX_VLAN_F)                                                     \
1819         R(vlan_rss, RX_VLAN_F | RSS_F)                                         \
1820         R(vlan_ptype, RX_VLAN_F | PTYPE_F)                                     \
1821         R(vlan_ptype_rss, RX_VLAN_F | PTYPE_F | RSS_F)                         \
1822         R(vlan_cksum, RX_VLAN_F | CKSUM_F)                                     \
1823         R(vlan_cksum_rss, RX_VLAN_F | CKSUM_F | RSS_F)                         \
1824         R(vlan_cksum_ptype, RX_VLAN_F | CKSUM_F | PTYPE_F)                     \
1825         R(vlan_cksum_ptype_rss, RX_VLAN_F | CKSUM_F | PTYPE_F | RSS_F)         \
1826         R(vlan_mark, RX_VLAN_F | MARK_F)                                       \
1827         R(vlan_mark_rss, RX_VLAN_F | MARK_F | RSS_F)                           \
1828         R(vlan_mark_ptype, RX_VLAN_F | MARK_F | PTYPE_F)                       \
1829         R(vlan_mark_ptype_rss, RX_VLAN_F | MARK_F | PTYPE_F | RSS_F)           \
1830         R(vlan_mark_cksum, RX_VLAN_F | MARK_F | CKSUM_F)                       \
1831         R(vlan_mark_cksum_rss, RX_VLAN_F | MARK_F | CKSUM_F | RSS_F)           \
1832         R(vlan_mark_cksum_ptype, RX_VLAN_F | MARK_F | CKSUM_F | PTYPE_F)       \
1833         R(vlan_mark_cksum_ptype_rss,                                           \
1834           RX_VLAN_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
1835
1836 #define NIX_RX_FASTPATH_MODES_48_63                                            \
1837         R(vlan_ts, RX_VLAN_F | TS_F)                                           \
1838         R(vlan_ts_rss, RX_VLAN_F | TS_F | RSS_F)                               \
1839         R(vlan_ts_ptype, RX_VLAN_F | TS_F | PTYPE_F)                           \
1840         R(vlan_ts_ptype_rss, RX_VLAN_F | TS_F | PTYPE_F | RSS_F)               \
1841         R(vlan_ts_cksum, RX_VLAN_F | TS_F | CKSUM_F)                           \
1842         R(vlan_ts_cksum_rss, RX_VLAN_F | TS_F | CKSUM_F | RSS_F)               \
1843         R(vlan_ts_cksum_ptype, RX_VLAN_F | TS_F | CKSUM_F | PTYPE_F)           \
1844         R(vlan_ts_cksum_ptype_rss,                                             \
1845           RX_VLAN_F | TS_F | CKSUM_F | PTYPE_F | RSS_F)                        \
1846         R(vlan_ts_mark, RX_VLAN_F | TS_F | MARK_F)                             \
1847         R(vlan_ts_mark_rss, RX_VLAN_F | TS_F | MARK_F | RSS_F)                 \
1848         R(vlan_ts_mark_ptype, RX_VLAN_F | TS_F | MARK_F | PTYPE_F)             \
1849         R(vlan_ts_mark_ptype_rss, RX_VLAN_F | TS_F | MARK_F | PTYPE_F | RSS_F) \
1850         R(vlan_ts_mark_cksum, RX_VLAN_F | TS_F | MARK_F | CKSUM_F)             \
1851         R(vlan_ts_mark_cksum_rss, RX_VLAN_F | TS_F | MARK_F | CKSUM_F | RSS_F) \
1852         R(vlan_ts_mark_cksum_ptype,                                            \
1853           RX_VLAN_F | TS_F | MARK_F | CKSUM_F | PTYPE_F)                       \
1854         R(vlan_ts_mark_cksum_ptype_rss,                                        \
1855           RX_VLAN_F | TS_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
1856
1857 #define NIX_RX_FASTPATH_MODES_64_79                                            \
1858         R(sec, R_SEC_F)                                                        \
1859         R(sec_rss, R_SEC_F | RSS_F)                                            \
1860         R(sec_ptype, R_SEC_F | PTYPE_F)                                        \
1861         R(sec_ptype_rss, R_SEC_F | PTYPE_F | RSS_F)                            \
1862         R(sec_cksum, R_SEC_F | CKSUM_F)                                        \
1863         R(sec_cksum_rss, R_SEC_F | CKSUM_F | RSS_F)                            \
1864         R(sec_cksum_ptype, R_SEC_F | CKSUM_F | PTYPE_F)                        \
1865         R(sec_cksum_ptype_rss, R_SEC_F | CKSUM_F | PTYPE_F | RSS_F)            \
1866         R(sec_mark, R_SEC_F | MARK_F)                                          \
1867         R(sec_mark_rss, R_SEC_F | MARK_F | RSS_F)                              \
1868         R(sec_mark_ptype, R_SEC_F | MARK_F | PTYPE_F)                          \
1869         R(sec_mark_ptype_rss, R_SEC_F | MARK_F | PTYPE_F | RSS_F)              \
1870         R(sec_mark_cksum, R_SEC_F | MARK_F | CKSUM_F)                          \
1871         R(sec_mark_cksum_rss, R_SEC_F | MARK_F | CKSUM_F | RSS_F)              \
1872         R(sec_mark_cksum_ptype, R_SEC_F | MARK_F | CKSUM_F | PTYPE_F)          \
1873         R(sec_mark_cksum_ptype_rss,                                            \
1874           R_SEC_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
1875
1876 #define NIX_RX_FASTPATH_MODES_80_95                                            \
1877         R(sec_ts, R_SEC_F | TS_F)                                              \
1878         R(sec_ts_rss, R_SEC_F | TS_F | RSS_F)                                  \
1879         R(sec_ts_ptype, R_SEC_F | TS_F | PTYPE_F)                              \
1880         R(sec_ts_ptype_rss, R_SEC_F | TS_F | PTYPE_F | RSS_F)                  \
1881         R(sec_ts_cksum, R_SEC_F | TS_F | CKSUM_F)                              \
1882         R(sec_ts_cksum_rss, R_SEC_F | TS_F | CKSUM_F | RSS_F)                  \
1883         R(sec_ts_cksum_ptype, R_SEC_F | TS_F | CKSUM_F | PTYPE_F)              \
1884         R(sec_ts_cksum_ptype_rss, R_SEC_F | TS_F | CKSUM_F | PTYPE_F | RSS_F)  \
1885         R(sec_ts_mark, R_SEC_F | TS_F | MARK_F)                                \
1886         R(sec_ts_mark_rss, R_SEC_F | TS_F | MARK_F | RSS_F)                    \
1887         R(sec_ts_mark_ptype, R_SEC_F | TS_F | MARK_F | PTYPE_F)                \
1888         R(sec_ts_mark_ptype_rss, R_SEC_F | TS_F | MARK_F | PTYPE_F | RSS_F)    \
1889         R(sec_ts_mark_cksum, R_SEC_F | TS_F | MARK_F | CKSUM_F)                \
1890         R(sec_ts_mark_cksum_rss, R_SEC_F | TS_F | MARK_F | CKSUM_F | RSS_F)    \
1891         R(sec_ts_mark_cksum_ptype,                                             \
1892           R_SEC_F | TS_F | MARK_F | CKSUM_F | PTYPE_F)                         \
1893         R(sec_ts_mark_cksum_ptype_rss,                                         \
1894           R_SEC_F | TS_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
1895
1896 #define NIX_RX_FASTPATH_MODES_96_111                                           \
1897         R(sec_vlan, R_SEC_F | RX_VLAN_F)                                       \
1898         R(sec_vlan_rss, R_SEC_F | RX_VLAN_F | RSS_F)                           \
1899         R(sec_vlan_ptype, R_SEC_F | RX_VLAN_F | PTYPE_F)                       \
1900         R(sec_vlan_ptype_rss, R_SEC_F | RX_VLAN_F | PTYPE_F | RSS_F)           \
1901         R(sec_vlan_cksum, R_SEC_F | RX_VLAN_F | CKSUM_F)                       \
1902         R(sec_vlan_cksum_rss, R_SEC_F | RX_VLAN_F | CKSUM_F | RSS_F)           \
1903         R(sec_vlan_cksum_ptype, R_SEC_F | RX_VLAN_F | CKSUM_F | PTYPE_F)       \
1904         R(sec_vlan_cksum_ptype_rss,                                            \
1905           R_SEC_F | RX_VLAN_F | CKSUM_F | PTYPE_F | RSS_F)                     \
1906         R(sec_vlan_mark, R_SEC_F | RX_VLAN_F | MARK_F)                         \
1907         R(sec_vlan_mark_rss, R_SEC_F | RX_VLAN_F | MARK_F | RSS_F)             \
1908         R(sec_vlan_mark_ptype, R_SEC_F | RX_VLAN_F | MARK_F | PTYPE_F)         \
1909         R(sec_vlan_mark_ptype_rss,                                             \
1910           R_SEC_F | RX_VLAN_F | MARK_F | PTYPE_F | RSS_F)                      \
1911         R(sec_vlan_mark_cksum, R_SEC_F | RX_VLAN_F | MARK_F | CKSUM_F)         \
1912         R(sec_vlan_mark_cksum_rss,                                             \
1913           R_SEC_F | RX_VLAN_F | MARK_F | CKSUM_F | RSS_F)                      \
1914         R(sec_vlan_mark_cksum_ptype,                                           \
1915           R_SEC_F | RX_VLAN_F | MARK_F | CKSUM_F | PTYPE_F)                    \
1916         R(sec_vlan_mark_cksum_ptype_rss,                                       \
1917           R_SEC_F | RX_VLAN_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
1918
1919 #define NIX_RX_FASTPATH_MODES_112_127                                          \
1920         R(sec_vlan_ts, R_SEC_F | RX_VLAN_F | TS_F)                             \
1921         R(sec_vlan_ts_rss, R_SEC_F | RX_VLAN_F | TS_F | RSS_F)                 \
1922         R(sec_vlan_ts_ptype, R_SEC_F | RX_VLAN_F | TS_F | PTYPE_F)             \
1923         R(sec_vlan_ts_ptype_rss, R_SEC_F | RX_VLAN_F | TS_F | PTYPE_F | RSS_F) \
1924         R(sec_vlan_ts_cksum, R_SEC_F | RX_VLAN_F | TS_F | CKSUM_F)             \
1925         R(sec_vlan_ts_cksum_rss, R_SEC_F | RX_VLAN_F | TS_F | CKSUM_F | RSS_F) \
1926         R(sec_vlan_ts_cksum_ptype,                                             \
1927           R_SEC_F | RX_VLAN_F | TS_F | CKSUM_F | PTYPE_F)                      \
1928         R(sec_vlan_ts_cksum_ptype_rss,                                         \
1929           R_SEC_F | RX_VLAN_F | TS_F | CKSUM_F | PTYPE_F | RSS_F)              \
1930         R(sec_vlan_ts_mark, R_SEC_F | RX_VLAN_F | TS_F | MARK_F)               \
1931         R(sec_vlan_ts_mark_rss, R_SEC_F | RX_VLAN_F | TS_F | MARK_F | RSS_F)   \
1932         R(sec_vlan_ts_mark_ptype,                                              \
1933           R_SEC_F | RX_VLAN_F | TS_F | MARK_F | PTYPE_F)                       \
1934         R(sec_vlan_ts_mark_ptype_rss,                                          \
1935           R_SEC_F | RX_VLAN_F | TS_F | MARK_F | PTYPE_F | RSS_F)               \
1936         R(sec_vlan_ts_mark_cksum,                                              \
1937           R_SEC_F | RX_VLAN_F | TS_F | MARK_F | CKSUM_F)                       \
1938         R(sec_vlan_ts_mark_cksum_rss,                                          \
1939           R_SEC_F | RX_VLAN_F | TS_F | MARK_F | CKSUM_F | RSS_F)               \
1940         R(sec_vlan_ts_mark_cksum_ptype,                                        \
1941           R_SEC_F | RX_VLAN_F | TS_F | MARK_F | CKSUM_F | PTYPE_F)             \
1942         R(sec_vlan_ts_mark_cksum_ptype_rss,                                    \
1943           R_SEC_F | RX_VLAN_F | TS_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
1944
1945
1946 #define NIX_RX_FASTPATH_MODES                                                  \
1947         NIX_RX_FASTPATH_MODES_0_15                                             \
1948         NIX_RX_FASTPATH_MODES_16_31                                            \
1949         NIX_RX_FASTPATH_MODES_32_47                                            \
1950         NIX_RX_FASTPATH_MODES_48_63                                            \
1951         NIX_RX_FASTPATH_MODES_64_79                                            \
1952         NIX_RX_FASTPATH_MODES_80_95                                            \
1953         NIX_RX_FASTPATH_MODES_96_111                                           \
1954         NIX_RX_FASTPATH_MODES_112_127                                          \
1955
1956 #define R(name, flags)                                                         \
1957         uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_##name(          \
1958                 void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts);     \
1959         uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_mseg_##name(     \
1960                 void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts);     \
1961         uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_vec_##name(      \
1962                 void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts);     \
1963         uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_vec_mseg_##name( \
1964                 void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts);     \
1965         uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_reas_##name(     \
1966                 void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts);     \
1967         uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_reas_mseg_##name(\
1968                 void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts);     \
1969         uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_reas_vec_##name( \
1970                 void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts);     \
1971         uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_reas_vec_mseg_##name( \
1972                 void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts);
1973
1974 NIX_RX_FASTPATH_MODES
1975 #undef R
1976
1977 #define NIX_RX_RECV(fn, flags)                                                 \
1978         uint16_t __rte_noinline __rte_hot fn(                                  \
1979                 void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts)      \
1980         {                                                                      \
1981                 return cn10k_nix_recv_pkts(rx_queue, rx_pkts, pkts, (flags));  \
1982         }
1983
1984 #define NIX_RX_RECV_MSEG(fn, flags) NIX_RX_RECV(fn, flags | NIX_RX_MULTI_SEG_F)
1985
1986 #define NIX_RX_RECV_VEC(fn, flags)                                             \
1987         uint16_t __rte_noinline __rte_hot fn(                                  \
1988                 void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts)      \
1989         {                                                                      \
1990                 return cn10k_nix_recv_pkts_vector(rx_queue, rx_pkts, pkts,     \
1991                                                   (flags), NULL, NULL, 0);     \
1992         }
1993
1994 #define NIX_RX_RECV_VEC_MSEG(fn, flags)                                        \
1995         NIX_RX_RECV_VEC(fn, flags | NIX_RX_MULTI_SEG_F)
1996
1997 #endif /* __CN10K_RX_H__ */