Branch data Line data Source code
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_ethdev.h>
8 : : #include <rte_security_driver.h>
9 : : #include <rte_vect.h>
10 : : #include "cn10k_rxtx.h"
11 : :
12 : : #define NSEC_PER_SEC 1000000000L
13 : :
14 : : #define NIX_RX_OFFLOAD_NONE (0)
15 : : #define NIX_RX_OFFLOAD_RSS_F BIT(0)
16 : : #define NIX_RX_OFFLOAD_PTYPE_F BIT(1)
17 : : #define NIX_RX_OFFLOAD_CHECKSUM_F BIT(2)
18 : : #define NIX_RX_OFFLOAD_MARK_UPDATE_F BIT(3)
19 : : #define NIX_RX_OFFLOAD_TSTAMP_F BIT(4)
20 : : #define NIX_RX_OFFLOAD_VLAN_STRIP_F BIT(5)
21 : : #define NIX_RX_OFFLOAD_SECURITY_F BIT(6)
22 : : #define NIX_RX_OFFLOAD_MAX (NIX_RX_OFFLOAD_SECURITY_F << 1)
23 : :
24 : : /* Flags to control cqe_to_mbuf conversion function.
25 : : * Defining it from backwards to denote its been
26 : : * not used as offload flags to pick function
27 : : */
28 : : #define NIX_RX_REAS_F BIT(12)
29 : : #define NIX_RX_VWQE_F BIT(13)
30 : : #define NIX_RX_MULTI_SEG_F BIT(14)
31 : :
32 : : #define CNXK_NIX_CQ_ENTRY_SZ 128
33 : : #define NIX_DESCS_PER_LOOP 4
34 : : #define CQE_CAST(x) ((struct nix_cqe_hdr_s *)(x))
35 : : #define CQE_SZ(x) ((x) * CNXK_NIX_CQ_ENTRY_SZ)
36 : :
37 : : #define CQE_PTR_OFF(b, i, o, f) \
38 : : (((f) & NIX_RX_VWQE_F) ? \
39 : : (uint64_t *)(((uintptr_t)((uint64_t *)(b))[i]) + (o)) : \
40 : : (uint64_t *)(((uintptr_t)(b)) + CQE_SZ(i) + (o)))
41 : : #define CQE_PTR_DIFF(b, i, o, f) \
42 : : (((f) & NIX_RX_VWQE_F) ? \
43 : : (uint64_t *)(((uintptr_t)((uint64_t *)(b))[i]) - (o)) : \
44 : : (uint64_t *)(((uintptr_t)(b)) + CQE_SZ(i) - (o)))
45 : :
46 : : #define NIX_RX_SEC_UCC_CONST \
47 : : ((RTE_MBUF_F_RX_IP_CKSUM_BAD >> 1) | \
48 : : ((RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1) << 8 | \
49 : : ((RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1) << 16 | \
50 : : ((RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1) << 32 | \
51 : : ((RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1) << 48)
52 : :
53 : : #ifdef RTE_LIBRTE_MEMPOOL_DEBUG
54 : : static inline void
55 : : nix_mbuf_validate_next(struct rte_mbuf *m)
56 : : {
57 : : if (m->nb_segs == 1 && m->next) {
58 : : rte_panic("mbuf->next[%p] valid when mbuf->nb_segs is %d",
59 : : m->next, m->nb_segs);
60 : : }
61 : : }
62 : : #else
63 : : static inline void
64 : : nix_mbuf_validate_next(struct rte_mbuf *m)
65 : : {
66 : : RTE_SET_USED(m);
67 : : }
68 : : #endif
69 : :
70 : : #define NIX_RX_SEC_REASSEMBLY_F \
71 : : (NIX_RX_REAS_F | NIX_RX_OFFLOAD_SECURITY_F)
72 : :
73 : : static inline rte_eth_ip_reassembly_dynfield_t *
74 : : cnxk_ip_reassembly_dynfield(struct rte_mbuf *mbuf,
75 : : int ip_reassembly_dynfield_offset)
76 : : {
77 : 0 : return RTE_MBUF_DYNFIELD(mbuf, ip_reassembly_dynfield_offset,
78 : : rte_eth_ip_reassembly_dynfield_t *);
79 : : }
80 : :
81 : : union mbuf_initializer {
82 : : struct {
83 : : uint16_t data_off;
84 : : uint16_t refcnt;
85 : : uint16_t nb_segs;
86 : : uint16_t port;
87 : : } fields;
88 : : uint64_t value;
89 : : };
90 : :
91 : : static __rte_always_inline uint64_t
92 : : nix_clear_data_off(uint64_t oldval)
93 : : {
94 : : union mbuf_initializer mbuf_init = {.value = oldval};
95 : :
96 : : mbuf_init.fields.data_off = 0;
97 : : return mbuf_init.value;
98 : : }
99 : :
100 : : static __rte_always_inline struct rte_mbuf *
101 : : nix_get_mbuf_from_cqe(void *cq, const uint64_t data_off)
102 : : {
103 : : rte_iova_t buff;
104 : :
105 : : /* Skip CQE, NIX_RX_PARSE_S and SG HDR(9 DWORDs) and peek buff addr */
106 : : buff = *((rte_iova_t *)((uint64_t *)cq + 9));
107 : : return (struct rte_mbuf *)(buff - data_off);
108 : : }
109 : :
110 : : static __rte_always_inline void
111 : : nix_sec_flush_meta_burst(uint16_t lmt_id, uint64_t data, uint16_t lnum,
112 : : uintptr_t aura_handle)
113 : : {
114 : : uint64_t pa;
115 : :
116 : : /* Prepare PA and Data */
117 : : pa = roc_npa_aura_handle_to_base(aura_handle) + NPA_LF_AURA_BATCH_FREE0;
118 : : pa |= ((data & 0x7) << 4);
119 : :
120 : : data >>= 3;
121 : : data <<= 19;
122 : : data |= (uint64_t)lmt_id;
123 : : data |= (uint64_t)(lnum - 1) << 12;
124 : :
125 : : roc_lmt_submit_steorl(data, pa);
126 : : }
127 : :
128 : : static __rte_always_inline void
129 : : nix_sec_flush_meta(uintptr_t laddr, uint16_t lmt_id, uint8_t loff,
130 : : uintptr_t aura_handle)
131 : : {
132 : : uint64_t pa;
133 : :
134 : : /* laddr is pointing to first pointer */
135 : 0 : laddr -= 8;
136 : :
137 : : /* Trigger free either on lmtline full or different aura handle */
138 : : pa = roc_npa_aura_handle_to_base(aura_handle) + NPA_LF_AURA_BATCH_FREE0;
139 : :
140 : : /* Update aura handle */
141 : 0 : *(uint64_t *)laddr = (((uint64_t)(loff & 0x1) << 32) |
142 : : roc_npa_aura_handle_to_aura(aura_handle));
143 : :
144 : : pa |= ((uint64_t)(loff >> 1) << 4);
145 : : roc_lmt_submit_steorl(lmt_id, pa);
146 : : }
147 : :
148 : : #if defined(RTE_ARCH_ARM64)
149 : : static __rte_always_inline uint64_t
150 : : nix_sec_reass_frags_get(const struct cpt_cn10k_parse_hdr_s *hdr, struct rte_mbuf **next_mbufs)
151 : : {
152 : : const struct cpt_frag_info_s *finfo;
153 : : uint32_t offset = hdr->w2.fi_offset;
154 : : const uint64_t *frag_ptr;
155 : : uint64x2_t frags23;
156 : : uint16x4_t fsz_w1;
157 : :
158 : : /* offset of 0 implies 256B, otherwise it implies offset*8B */
159 : : offset = (((offset - 1) & 0x1f) + 1) * 8;
160 : : finfo = RTE_PTR_ADD(hdr, offset);
161 : : frag_ptr = (const uint64_t *)(finfo + 1);
162 : : frags23 = vrev64q_u8(vld1q_u64(frag_ptr));
163 : :
164 : : next_mbufs[0] = ((struct rte_mbuf *)rte_be_to_cpu_64(hdr->frag1_wqe_ptr) - 1);
165 : : next_mbufs[1] = ((struct rte_mbuf *)vgetq_lane_u64(frags23, 0) - 1);
166 : : next_mbufs[2] = ((struct rte_mbuf *)vgetq_lane_u64(frags23, 1) - 1);
167 : :
168 : : fsz_w1 = vreinterpret_u16_u64(vdup_n_u64(finfo->w1.u64));
169 : : fsz_w1 = vrev16_u8(fsz_w1);
170 : : return vget_lane_u64(vreinterpret_u64_u16(fsz_w1), 0);
171 : : }
172 : :
173 : : static __rte_always_inline void
174 : : nix_sec_reass_first_frag_update(struct rte_mbuf *head, const uint8_t *m_ipptr,
175 : : uint64_t fsz, uint64_t cq_w1, uint16_t *ihl)
176 : : {
177 : : union nix_rx_parse_u *rx = (union nix_rx_parse_u *)((uintptr_t)(head + 1) + 8);
178 : : uint16_t fragx_sum = vaddv_u16(vreinterpret_u16_u64(vdup_n_u64(fsz)));
179 : : uint8_t lcptr = rx->lcptr;
180 : : uint16_t tot_len;
181 : : uint32_t cksum;
182 : : uint8_t *ipptr;
183 : :
184 : : ipptr = (uint8_t *)head->buf_addr + head->data_off + lcptr;
185 : : /* Find the L3 header length and update inner pkt based on meta lc type */
186 : : if (((cq_w1 >> 40) & 0xF) == NPC_LT_LC_IP) {
187 : : const struct rte_ipv4_hdr *m_hdr = (const struct rte_ipv4_hdr *)m_ipptr;
188 : : struct rte_ipv4_hdr *hdr = (struct rte_ipv4_hdr *)ipptr;
189 : :
190 : : *ihl = (m_hdr->version_ihl & 0xf) << 2;
191 : :
192 : : hdr->fragment_offset = 0;
193 : : tot_len = rte_cpu_to_be_16(fragx_sum + *ihl);
194 : : hdr->total_length = tot_len;
195 : : /* Perform incremental checksum based on meta pkt ip hdr */
196 : : cksum = m_hdr->hdr_checksum;
197 : : cksum += m_hdr->fragment_offset;
198 : : cksum += 0xFFFF;
199 : : cksum += m_hdr->total_length;
200 : : cksum += (uint16_t)(~tot_len);
201 : : cksum = (cksum & 0xFFFF) + ((cksum & 0xFFFF0000) >> 16);
202 : : hdr->hdr_checksum = cksum;
203 : :
204 : : head->pkt_len = lcptr + *ihl + fragx_sum;
205 : : } else {
206 : : struct rte_ipv6_hdr *hdr = (struct rte_ipv6_hdr *)ipptr;
207 : : size_t ext_len = sizeof(struct rte_ipv6_hdr);
208 : : uint8_t *nxt_hdr = (uint8_t *)hdr;
209 : : uint8_t *nxt_proto = &hdr->proto;
210 : : int nh = hdr->proto;
211 : :
212 : : *ihl = 0;
213 : : tot_len = 0;
214 : : while (nh != -EINVAL) {
215 : : nxt_hdr += ext_len;
216 : : *ihl += ext_len;
217 : : if (nh == IPPROTO_FRAGMENT) {
218 : : *nxt_proto = *nxt_hdr;
219 : : tot_len = *ihl;
220 : : }
221 : : nh = rte_ipv6_get_next_ext(nxt_hdr, nh, &ext_len);
222 : : nxt_proto = nxt_hdr;
223 : : }
224 : :
225 : : /* Remove the frag header by moving header 8 bytes forward */
226 : : hdr->payload_len = rte_cpu_to_be_16(fragx_sum + *ihl -
227 : : 8 - sizeof(struct rte_ipv6_hdr));
228 : :
229 : : /* tot_len is sum of all IP header's length before fragment header */
230 : : rte_memcpy(rte_pktmbuf_mtod_offset(head, void *, 8),
231 : : rte_pktmbuf_mtod(head, void *),
232 : : lcptr + tot_len);
233 : :
234 : : head->data_len -= 8;
235 : : head->data_off += 8;
236 : : head->pkt_len = lcptr + *ihl - 8 + fragx_sum;
237 : : /* ihl l3hdr size value should be up to fragment header for next frags */
238 : : *ihl = tot_len + 8;
239 : : }
240 : : }
241 : :
242 : : #else
243 : : static __rte_always_inline uint64_t
244 : : nix_sec_reass_frags_get(const struct cpt_cn10k_parse_hdr_s *hdr, struct rte_mbuf **next_mbufs)
245 : : {
246 : : RTE_SET_USED(hdr);
247 : 0 : next_mbufs[0] = NULL;
248 : 0 : next_mbufs[1] = NULL;
249 : 0 : next_mbufs[2] = NULL;
250 : : return 0;
251 : : }
252 : :
253 : : static __rte_always_inline void
254 : : nix_sec_reass_first_frag_update(struct rte_mbuf *head, const uint8_t *m_ipptr,
255 : : uint64_t fsz, uint64_t cq_w1, uint16_t *ihl)
256 : : {
257 : : RTE_SET_USED(head);
258 : : RTE_SET_USED(m_ipptr);
259 : : RTE_SET_USED(fsz);
260 : : RTE_SET_USED(cq_w1);
261 : : *ihl = 0;
262 : : }
263 : : #endif
264 : :
265 : : static struct rte_mbuf *
266 : : nix_sec_attach_frags(const struct cpt_cn10k_parse_hdr_s *hdr,
267 : : struct rte_mbuf *head,
268 : : struct cn10k_inb_priv_data *inb_priv,
269 : : const uint64_t mbuf_init)
270 : : {
271 : : uint8_t num_frags = hdr->w0.num_frags;
272 : : struct rte_mbuf *next_mbufs[3];
273 : : union nix_rx_parse_u *frag_rx;
274 : : struct rte_mbuf *mbuf;
275 : : uint64_t ol_flags;
276 : : uint16_t frag_size;
277 : : uint8_t frag_i = 0;
278 : : uint16_t rlen;
279 : : uint64_t *wqe;
280 : : int off;
281 : :
282 : : off = inb_priv->reass_dynfield_off;
283 : : ol_flags = BIT_ULL(inb_priv->reass_dynflag_bit);
284 : : ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD;
285 : :
286 : : /* Get frags list */
287 : : nix_sec_reass_frags_get(hdr, next_mbufs);
288 : :
289 : : /* Frag-0: */
290 : : wqe = (uint64_t *)(head + 1);
291 : : rlen = ((*(wqe + 10)) >> 16) & 0xFFFF;
292 : :
293 : : frag_rx = (union nix_rx_parse_u *)(wqe + 1);
294 : :
295 : : head->ol_flags = ol_flags;
296 : : /* Update dynamic field with userdata */
297 : : *rte_security_dynfield(head) = (uint64_t)inb_priv->userdata;
298 : :
299 : : num_frags--;
300 : : mbuf = head;
301 : :
302 : : /* Frag-1+: */
303 : : while (num_frags) {
304 : : cnxk_ip_reassembly_dynfield(mbuf, off)->next_frag = next_mbufs[frag_i];
305 : : cnxk_ip_reassembly_dynfield(mbuf, off)->nb_frags = num_frags;
306 : : mbuf = next_mbufs[frag_i];
307 : : wqe = (uint64_t *)(mbuf + 1);
308 : : rlen = ((*(wqe + 10)) >> 16) & 0xFFFF;
309 : :
310 : : frag_rx = (union nix_rx_parse_u *)(wqe + 1);
311 : : frag_size = rlen + frag_rx->lcptr - frag_rx->laptr;
312 : :
313 : : *(uint64_t *)(&mbuf->rearm_data) = mbuf_init;
314 : : mbuf->data_len = frag_size;
315 : : mbuf->pkt_len = frag_size;
316 : : mbuf->ol_flags = ol_flags;
317 : :
318 : : /* Update dynamic field with userdata */
319 : : *rte_security_dynfield(mbuf) = (uint64_t)inb_priv->userdata;
320 : :
321 : : /* Mark frag as get */
322 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
323 : :
324 : : num_frags--;
325 : : frag_i++;
326 : : }
327 : : cnxk_ip_reassembly_dynfield(mbuf, off)->nb_frags = 0;
328 : : cnxk_ip_reassembly_dynfield(mbuf, off)->next_frag = NULL;
329 : :
330 : : return head;
331 : : }
332 : :
333 : : static __rte_always_inline struct rte_mbuf *
334 : : nix_sec_reassemble_frags(const struct cpt_cn10k_parse_hdr_s *hdr, struct rte_mbuf *head,
335 : : uint64_t cq_w1, uint64_t cq_w5, uint64_t mbuf_init)
336 : : {
337 : : uint8_t num_frags = hdr->w0.num_frags;
338 : : union nix_rx_parse_u *frag_rx;
339 : : struct rte_mbuf *next_mbufs[3];
340 : : uint16_t data_off, b_off;
341 : : const uint8_t *m_ipptr;
342 : : uint16_t l3_hdr_size;
343 : : struct rte_mbuf *mbuf;
344 : : uint16_t frag_size;
345 : : uint64_t fsz_w1;
346 : : uint64_t *wqe;
347 : :
348 : : /* Base data offset */
349 : : b_off = mbuf_init & 0xFFFFUL;
350 : : mbuf_init &= ~0xFFFFUL;
351 : :
352 : : /* Get list of all fragments and frag sizes */
353 : : fsz_w1 = nix_sec_reass_frags_get(hdr, next_mbufs);
354 : :
355 : : /* Frag-0: */
356 : : wqe = (uint64_t *)(head + 1);
357 : :
358 : : /* First fragment data len is already update by caller */
359 : : m_ipptr = ((const uint8_t *)hdr + ((cq_w5 >> 16) & 0xFF));
360 : : nix_sec_reass_first_frag_update(head, m_ipptr, fsz_w1, cq_w1, &l3_hdr_size);
361 : : fsz_w1 >>= 16;
362 : :
363 : : /* Frag-1: */
364 : : head->next = next_mbufs[0];
365 : : mbuf = next_mbufs[0];
366 : : wqe = (uint64_t *)(mbuf + 1);
367 : : frag_rx = (union nix_rx_parse_u *)(wqe + 1);
368 : : frag_size = fsz_w1 & 0xFFFF;
369 : : fsz_w1 >>= 16;
370 : :
371 : : data_off = b_off + frag_rx->lcptr + l3_hdr_size;
372 : : *(uint64_t *)(&mbuf->rearm_data) = mbuf_init | data_off;
373 : : mbuf->data_len = frag_size;
374 : :
375 : : /* Mark frag as get */
376 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
377 : :
378 : : /* Frag-2: */
379 : : if (num_frags > 2) {
380 : : mbuf->next = next_mbufs[1];
381 : : mbuf = next_mbufs[1];
382 : : wqe = (uint64_t *)(mbuf + 1);
383 : : frag_rx = (union nix_rx_parse_u *)(wqe + 1);
384 : : frag_size = fsz_w1 & 0xFFFF;
385 : : fsz_w1 >>= 16;
386 : :
387 : : data_off = b_off + frag_rx->lcptr + l3_hdr_size;
388 : : *(uint64_t *)(&mbuf->rearm_data) = mbuf_init | data_off;
389 : : mbuf->data_len = frag_size;
390 : :
391 : : /* Mark frag as get */
392 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
393 : : }
394 : :
395 : : /* Frag-3: */
396 : : if (num_frags > 3) {
397 : : mbuf->next = next_mbufs[2];
398 : : mbuf = next_mbufs[2];
399 : : wqe = (uint64_t *)(mbuf + 1);
400 : : frag_rx = (union nix_rx_parse_u *)(wqe + 1);
401 : : frag_size = fsz_w1 & 0xFFFF;
402 : : fsz_w1 >>= 16;
403 : :
404 : : data_off = b_off + frag_rx->lcptr + l3_hdr_size;
405 : : *(uint64_t *)(&mbuf->rearm_data) = mbuf_init | data_off;
406 : : mbuf->data_len = frag_size;
407 : :
408 : : /* Mark frag as get */
409 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
410 : : }
411 : :
412 : : head->nb_segs = num_frags;
413 : : return head;
414 : : }
415 : :
416 : : static inline struct rte_mbuf *
417 : 0 : nix_sec_oop_process(const struct cpt_cn10k_parse_hdr_s *hdr, struct rte_mbuf *mbuf,
418 : : uint64_t *mbuf_init)
419 : : {
420 [ # # ]: 0 : uintptr_t wqe = rte_be_to_cpu_64(hdr->wqe_ptr);
421 : : union nix_rx_parse_u *inner_rx;
422 : : struct rte_mbuf *inner;
423 : : uint16_t data_off;
424 : :
425 : 0 : inner = ((struct rte_mbuf *)wqe) - 1;
426 : :
427 : 0 : inner_rx = (union nix_rx_parse_u *)(wqe + 8);
428 : 0 : inner->pkt_len = inner_rx->pkt_lenm1 + 1;
429 : 0 : inner->data_len = inner_rx->pkt_lenm1 + 1;
430 : :
431 : : /* Mark inner mbuf as get */
432 : : RTE_MEMPOOL_CHECK_COOKIES(inner->pool,
433 : : (void **)&inner, 1, 1);
434 : : /* Update rearm data for full mbuf as it has
435 : : * cpt parse header that needs to be skipped.
436 : : *
437 : : * Since meta pool will not have private area while
438 : : * ethdev RQ's first skip would be considering private area
439 : : * calculate actual data off and update in meta mbuf.
440 : : */
441 : 0 : data_off = (uintptr_t)hdr - (uintptr_t)mbuf->buf_addr;
442 : 0 : data_off += sizeof(struct cpt_cn10k_parse_hdr_s);
443 : 0 : data_off += hdr->w0.pad_len;
444 : 0 : *mbuf_init &= ~0xFFFFUL;
445 : 0 : *mbuf_init |= (uint64_t)data_off;
446 : :
447 : 0 : *rte_security_oop_dynfield(mbuf) = inner;
448 : : /* Return outer instead of inner mbuf as inner mbuf would have original encrypted packet */
449 : 0 : return mbuf;
450 : : }
451 : :
452 : : static __rte_always_inline struct rte_mbuf *
453 : : nix_sec_meta_to_mbuf_sc(uint64_t cq_w1, uint64_t cq_w5, const uint64_t sa_base,
454 : : uintptr_t laddr, uint8_t *loff, struct rte_mbuf *mbuf,
455 : : uint16_t data_off, const uint16_t flags,
456 : : uint64_t mbuf_init)
457 : : {
458 : 0 : const void *__p = (void *)((uintptr_t)mbuf + (uint16_t)data_off);
459 : : const struct cpt_cn10k_parse_hdr_s *hdr = (const struct cpt_cn10k_parse_hdr_s *)__p;
460 : : struct cn10k_inb_priv_data *inb_priv;
461 : : struct rte_mbuf *inner = NULL;
462 : : uint32_t sa_idx;
463 : : uint16_t ucc;
464 : : uint32_t len;
465 : : uintptr_t ip;
466 : : void *inb_sa;
467 : : uint64_t w0;
468 : :
469 [ # # # # : 0 : if (!(cq_w1 & BIT(11)))
# # # # #
# # # ]
470 : : return mbuf;
471 : :
472 [ # # # # : 0 : if (flags & NIX_RX_REAS_F && hdr->w0.pkt_fmt == ROC_IE_OT_SA_PKT_FMT_FULL) {
# # # # #
# # # ]
473 : 0 : inner = nix_sec_oop_process(hdr, mbuf, &mbuf_init);
474 : : } else {
475 [ # # # # : 0 : inner = (struct rte_mbuf *)(rte_be_to_cpu_64(hdr->wqe_ptr) -
# # # # #
# # # ]
476 : : sizeof(struct rte_mbuf));
477 : :
478 : : /* Store meta in lmtline to free
479 : : * Assume all meta's from same aura.
480 : : */
481 : 0 : *(uint64_t *)(laddr + (*loff << 3)) = (uint64_t)mbuf;
482 : 0 : *loff = *loff + 1;
483 : : }
484 : :
485 : : /* Get SPI from CPT_PARSE_S's cookie(already swapped) */
486 : 0 : w0 = hdr->w0.u64;
487 [ # # # # : 0 : sa_idx = w0 >> 32;
# # # # #
# # # ]
488 : :
489 : : inb_sa = roc_nix_inl_ot_ipsec_inb_sa(sa_base, sa_idx);
490 : : inb_priv = roc_nix_inl_ot_ipsec_inb_sa_sw_rsvd(inb_sa);
491 : :
492 : : /* Cryptodev injected packet can be identified from SA IDX 0xFFFFFFFF, and
493 : : * Ethdev injected packet can be identified with match ID 0xFFFF.
494 : : */
495 [ # # # # : 0 : if (flags & NIX_RX_REAS_F && (sa_idx == 0xFFFFFFFF || hdr->w0.match_id == 0xFFFFU)) {
# # # # #
# # # # #
# # # # #
# # # #
# ]
496 : 0 : *(uint64_t *)(&inner->rearm_data) = (mbuf_init & ~(BIT_ULL(16) - 1)) |
497 : 0 : inner->data_off;
498 [ # # # # : 0 : if (hdr->w0.match_id == 0xFFFFU)
# # # # #
# # # ]
499 : 0 : *rte_security_dynfield(inner) = (uint64_t)inb_priv->userdata;
500 : : } else {
501 : : /* Update dynamic field with userdata */
502 : 0 : *rte_security_dynfield(inner) = (uint64_t)inb_priv->userdata;
503 : 0 : *(uint64_t *)(&inner->rearm_data) = mbuf_init;
504 : : }
505 : :
506 : : /* Get ucc from cpt parse header */
507 : 0 : ucc = hdr->w3.hw_ccode;
508 : :
509 : : /* Calculate inner packet length as IP total len + l2 len */
510 : 0 : ip = (uintptr_t)hdr + ((cq_w5 >> 16) & 0xFF);
511 : 0 : ip += ((cq_w1 >> 40) & 0x6);
512 [ # # # # : 0 : len = rte_be_to_cpu_16(*(uint16_t *)ip);
# # # # #
# # # ]
513 : 0 : len += ((cq_w5 >> 16) & 0xFF) - (cq_w5 & 0xFF);
514 [ # # # # : 0 : len += (cq_w1 & BIT(42)) ? 40 : 0;
# # # # #
# # # ]
515 : :
516 : 0 : inner->pkt_len = len;
517 : 0 : inner->data_len = len;
518 : :
519 : 0 : inner->ol_flags = ((CPT_COMP_HWGOOD_MASK & (1U << ucc)) ?
520 [ # # # # : 0 : RTE_MBUF_F_RX_SEC_OFFLOAD :
# # # # #
# # # ]
521 : : (RTE_MBUF_F_RX_SEC_OFFLOAD |
522 : : RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED));
523 : :
524 : 0 : ucc = hdr->w3.uc_ccode;
525 : :
526 [ # # # # : 0 : if (ucc && ucc < 0xED) {
# # # # #
# # # ]
527 : 0 : inner->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
528 : : } else {
529 : 0 : ucc += 3; /* To make codes in 0xFx series except 0 */
530 : 0 : inner->ol_flags |= ((ucc & 0xF0) == 0xF0) ?
531 : 0 : ((NIX_RX_SEC_UCC_CONST >> ((ucc & 0xF) << 3))
532 [ # # # # : 0 : & 0xFF) << 1 : RTE_MBUF_F_RX_IP_CKSUM_GOOD;
# # # # #
# # # ]
533 : : }
534 : :
535 : : if (!(flags & NIX_RX_REAS_F) || hdr->w0.pkt_fmt != ROC_IE_OT_SA_PKT_FMT_FULL) {
536 : : /* Mark meta mbuf as put */
537 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 0);
538 : :
539 : : /* Mark inner mbuf as get */
540 : : RTE_MEMPOOL_CHECK_COOKIES(inner->pool, (void **)&inner, 1, 1);
541 : : }
542 : :
543 : : /* Skip reassembly processing when multi-seg is enabled */
544 : : if (!(flags & NIX_RX_MULTI_SEG_F) && (flags & NIX_RX_REAS_F) && hdr->w0.num_frags) {
545 : : if ((!(hdr->w0.err_sum) || roc_ie_ot_ucc_is_success(hdr->w3.uc_ccode)) &&
546 : : !(hdr->w0.reas_sts)) {
547 : : /* Reassembly success */
548 : : nix_sec_reassemble_frags(hdr, inner, cq_w1, cq_w5, mbuf_init);
549 : :
550 : : /* Update dynamic field with userdata */
551 : : *rte_security_dynfield(inner) =
552 : : (uint64_t)inb_priv->userdata;
553 : :
554 : : /* Assume success */
555 : : inner->ol_flags = RTE_MBUF_F_RX_SEC_OFFLOAD;
556 : : } else {
557 : : /* Reassembly failure */
558 : : nix_sec_attach_frags(hdr, inner, inb_priv, mbuf_init);
559 : : }
560 : : }
561 : : return inner;
562 : : }
563 : :
564 : : #if defined(RTE_ARCH_ARM64)
565 : :
566 : : static __rte_always_inline void
567 : : nix_sec_meta_to_mbuf(uint64_t cq_w1, uint64_t cq_w5, uintptr_t inb_sa,
568 : : uintptr_t cpth, struct rte_mbuf *inner,
569 : : uint8x16_t *rx_desc_field1, uint64_t *ol_flags,
570 : : const uint16_t flags, uint64x2_t *rearm)
571 : : {
572 : : const struct cpt_cn10k_parse_hdr_s *hdr =
573 : : (const struct cpt_cn10k_parse_hdr_s *)cpth;
574 : : uint64_t mbuf_init = vgetq_lane_u64(*rearm, 0);
575 : : struct cn10k_inb_priv_data *inb_priv;
576 : : uintptr_t p;
577 : :
578 : : /* Clear checksum flags */
579 : : *ol_flags &= ~(RTE_MBUF_F_RX_L4_CKSUM_MASK |
580 : : RTE_MBUF_F_RX_IP_CKSUM_MASK);
581 : :
582 : :
583 : : if (flags & NIX_RX_REAS_F && !inb_sa) {
584 : : /* Clear and update original lower 16 bit of data offset */
585 : : *rearm = (*rearm & ~(BIT_ULL(16) - 1)) | inner->data_off;
586 : : } else {
587 : : /* Get SPI from CPT_PARSE_S's cookie(already swapped) */
588 : : inb_priv = roc_nix_inl_ot_ipsec_inb_sa_sw_rsvd((void *)inb_sa);
589 : : /* Update dynamic field with userdata */
590 : : *rte_security_dynfield(inner) = (uint64_t)inb_priv->userdata;
591 : : }
592 : :
593 : : /* Clear and update original lower 16 bit of data offset */
594 : : if (flags & NIX_RX_REAS_F && hdr->w0.match_id == 0xFFFFU)
595 : : *rearm = (*rearm & ~(BIT_ULL(16) - 1)) | inner->data_off;
596 : :
597 : : /* Mark inner mbuf as get */
598 : : if (!(flags & NIX_RX_REAS_F) ||
599 : : hdr->w0.pkt_fmt != ROC_IE_OT_SA_PKT_FMT_FULL)
600 : : RTE_MEMPOOL_CHECK_COOKIES(inner->pool, (void **)&inner, 1, 1);
601 : :
602 : : if (!(flags & NIX_RX_MULTI_SEG_F) && flags & NIX_RX_REAS_F && hdr->w0.num_frags) {
603 : : if ((!(hdr->w0.err_sum) || roc_ie_ot_ucc_is_success(hdr->w3.uc_ccode)) &&
604 : : !(hdr->w0.reas_sts)) {
605 : : /* First frag len */
606 : : inner->pkt_len = vgetq_lane_u16(*rx_desc_field1, 2);
607 : : inner->data_len = vgetq_lane_u16(*rx_desc_field1, 4);
608 : : p = (uintptr_t)&inner->rearm_data;
609 : : *(uint64_t *)p = mbuf_init;
610 : :
611 : : /* Reassembly success */
612 : : nix_sec_reassemble_frags(hdr, inner, cq_w1, cq_w5, mbuf_init);
613 : :
614 : : /* Assume success */
615 : : *ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD;
616 : :
617 : : /* Update pkt_len and data_len */
618 : : *rx_desc_field1 = vsetq_lane_u16(inner->pkt_len,
619 : : *rx_desc_field1, 2);
620 : : *rx_desc_field1 = vsetq_lane_u16(inner->data_len,
621 : : *rx_desc_field1, 4);
622 : :
623 : : /* Data offset might be updated */
624 : : mbuf_init = *(uint64_t *)p;
625 : : *rearm = vsetq_lane_u64(mbuf_init, *rearm, 0);
626 : : } else {
627 : : /* Reassembly failure */
628 : : if (inb_sa) {
629 : : nix_sec_attach_frags(hdr, inner, inb_priv, mbuf_init);
630 : : *ol_flags |= inner->ol_flags;
631 : : }
632 : : }
633 : : } else if (flags & NIX_RX_REAS_F) {
634 : : /* Without fragmentation but may have to handle OOP session */
635 : : if (hdr->w0.pkt_fmt == ROC_IE_OT_SA_PKT_FMT_FULL) {
636 : : uint64_t mbuf_init = 0;
637 : :
638 : : /* Caller has already prepared to return second pass
639 : : * mbuf and inner mbuf is actually outer.
640 : : * Store original buffer pointer in dynfield.
641 : : */
642 : : nix_sec_oop_process(hdr, inner, &mbuf_init);
643 : : /* Clear and update lower 16 bit of data offset */
644 : : *rearm = (*rearm & ~(BIT_ULL(16) - 1)) | mbuf_init;
645 : : }
646 : : }
647 : : }
648 : : #endif
649 : :
650 : : static __rte_always_inline uint32_t
651 : : nix_ptype_get(const void *const lookup_mem, const uint64_t in)
652 : : {
653 : : const uint16_t *const ptype = lookup_mem;
654 : 0 : const uint16_t lh_lg_lf = (in & 0xFFF0000000000000) >> 52;
655 : 0 : const uint16_t tu_l2 = ptype[(in & 0x000FFFF000000000) >> 36];
656 : 0 : const uint16_t il4_tu = ptype[PTYPE_NON_TUNNEL_ARRAY_SZ + lh_lg_lf];
657 : :
658 : 0 : return (il4_tu << PTYPE_NON_TUNNEL_WIDTH) | tu_l2;
659 : : }
660 : :
661 : : static __rte_always_inline uint32_t
662 : : nix_rx_olflags_get(const void *const lookup_mem, const uint64_t in)
663 : : {
664 : : const uint32_t *const ol_flags =
665 : : (const uint32_t *)((const uint8_t *)lookup_mem +
666 : : PTYPE_ARRAY_SZ);
667 : :
668 : 0 : return ol_flags[(in & 0xfff00000) >> 20];
669 : : }
670 : :
671 : : static inline uint64_t
672 : 0 : nix_update_match_id(const uint16_t match_id, uint64_t ol_flags,
673 : : struct rte_mbuf *mbuf)
674 : : {
675 : : /* There is no separate bit to check match_id
676 : : * is valid or not? and no flag to identify it is an
677 : : * RTE_FLOW_ACTION_TYPE_FLAG vs RTE_FLOW_ACTION_TYPE_MARK
678 : : * action. The former case addressed through 0 being invalid
679 : : * value and inc/dec match_id pair when MARK is activated.
680 : : * The later case addressed through defining
681 : : * CNXK_FLOW_MARK_DEFAULT as value for
682 : : * RTE_FLOW_ACTION_TYPE_MARK.
683 : : * This would translate to not use
684 : : * CNXK_FLOW_ACTION_FLAG_DEFAULT - 1 and
685 : : * CNXK_FLOW_ACTION_FLAG_DEFAULT for match_id.
686 : : * i.e valid mark_id's are from
687 : : * 0 to CNXK_FLOW_ACTION_FLAG_DEFAULT - 2
688 : : */
689 [ # # ]: 0 : if (likely(match_id)) {
690 : 0 : ol_flags |= RTE_MBUF_F_RX_FDIR;
691 [ # # ]: 0 : if (match_id != CNXK_FLOW_ACTION_FLAG_DEFAULT) {
692 : 0 : ol_flags |= RTE_MBUF_F_RX_FDIR_ID;
693 : 0 : mbuf->hash.fdir.hi = match_id - 1;
694 : : }
695 : : }
696 : :
697 : 0 : return ol_flags;
698 : : }
699 : :
700 : : static __rte_always_inline void
701 : : nix_cqe_xtract_mseg(const union nix_rx_parse_u *rx, struct rte_mbuf *mbuf,
702 : : uint64_t rearm, uintptr_t cpth, uintptr_t sa_base, const uint16_t flags)
703 : : {
704 : : const struct cpt_cn10k_parse_hdr_s *hdr = (const struct cpt_cn10k_parse_hdr_s *)cpth;
705 : : struct cn10k_inb_priv_data *inb_priv = NULL;
706 : : uint8_t num_frags = 0, frag_i = 0;
707 : : struct rte_mbuf *next_mbufs[3];
708 : : const rte_iova_t *iova_list;
709 : : bool reas_success = false;
710 : : uint16_t later_skip = 0;
711 : : struct rte_mbuf *head;
712 : : const rte_iova_t *eol;
713 : : bool rx_inj = false;
714 : : uint64_t cq_w5 = 0;
715 : : uint16_t ihl = 0;
716 : : uint64_t fsz = 0;
717 : : int dyn_off = 0;
718 : : uint8_t nb_segs;
719 : : uint16_t sg_len;
720 : : uint64_t cq_w1;
721 : : int64_t len;
722 : : uint64_t sg;
723 : : uintptr_t p;
724 : :
725 : 0 : cq_w1 = *(const uint64_t *)rx;
726 : : if (flags & NIX_RX_REAS_F)
727 : : cq_w5 = *((const uint64_t *)rx + 4);
728 : : /* Use inner rx parse for meta pkts sg list */
729 [ # # # # : 0 : if (cq_w1 & BIT(11) && flags & NIX_RX_OFFLOAD_SECURITY_F) {
# # # # #
# # # ]
730 : : const uint64_t *wqe;
731 : : /* Rx Inject packet must have Match ID 0xFFFF and for this
732 : : * wqe will get from address stored at mbuf+1 location
733 : : */
734 [ # # # # : 0 : rx_inj = ((flags & NIX_RX_REAS_F) && ((hdr->w0.match_id == 0xFFFFU) ||
# # # # #
# # # ]
735 [ # # # # : 0 : (hdr->w0.cookie == 0xFFFFFFFFU)));
# # # # #
# # # ]
736 [ # # # # : 0 : if (rx_inj)
# # # # #
# # # ]
737 : 0 : wqe = (const uint64_t *)*((uint64_t *)(mbuf + 1));
738 : : else
739 : 0 : wqe = (const uint64_t *)(mbuf + 1);
740 : :
741 [ # # # # : 0 : if (!(flags & NIX_RX_REAS_F) || hdr->w0.pkt_fmt != ROC_IE_OT_SA_PKT_FMT_FULL)
# # # # #
# # # ]
742 : 0 : rx = (const union nix_rx_parse_u *)(wqe + 1);
743 : : }
744 : :
745 : 0 : sg = *(const uint64_t *)(rx + 1);
746 : 0 : nb_segs = (sg >> 48) & 0x3;
747 : :
748 : : if (nb_segs == 1 && !(flags & NIX_RX_REAS_F))
749 : : return;
750 : :
751 : : /* For security we have already updated right pkt_len */
752 [ # # # # : 0 : if (cq_w1 & BIT(11) && flags & NIX_RX_OFFLOAD_SECURITY_F) {
# # # # #
# # # ]
753 : 0 : len = mbuf->pkt_len;
754 : :
755 : : /* Handle reassembly with multi segs */
756 [ # # # # : 0 : if (flags & NIX_RX_REAS_F && hdr->w0.num_frags) {
# # # # #
# # # ]
757 : : void *inb_sa;
758 : :
759 : 0 : num_frags = hdr->w0.num_frags;
760 [ # # # # : 0 : inb_sa = roc_nix_inl_ot_ipsec_inb_sa(sa_base, hdr->w0.u64 >> 32);
# # # # #
# # # ]
761 : : inb_priv = roc_nix_inl_ot_ipsec_inb_sa_sw_rsvd(inb_sa);
762 : : ihl = 0;
763 : :
764 : 0 : dyn_off = inb_priv->reass_dynfield_off;
765 : : fsz = nix_sec_reass_frags_get(hdr, next_mbufs);
766 : 0 : num_frags -= 1;
767 : :
768 [ # # # # : 0 : if (!(hdr->w0.reas_sts) &&
# # # # #
# # # ]
769 [ # # # # : 0 : (!(hdr->w0.err_sum) ||
# # # # #
# # # # #
# # # # #
# # # #
# ]
770 [ # # # # : 0 : roc_ie_ot_ucc_is_success(hdr->w3.uc_ccode)))
# # # # #
# # # ]
771 : : reas_success = true;
772 : : }
773 : : } else {
774 : 0 : len = rx->pkt_lenm1 + 1;
775 : : }
776 : :
777 : 0 : mbuf->pkt_len = len - (flags & NIX_RX_OFFLOAD_TSTAMP_F ? CNXK_NIX_TIMESYNC_RX_OFFSET : 0);
778 : 0 : mbuf->nb_segs = nb_segs;
779 : : head = mbuf;
780 : 0 : mbuf->data_len =
781 : 0 : (sg & 0xFFFF) - (flags & NIX_RX_OFFLOAD_TSTAMP_F ? CNXK_NIX_TIMESYNC_RX_OFFSET : 0);
782 : 0 : eol = ((const rte_iova_t *)(rx + 1) + ((rx->desc_sizem1 + 1) << 1));
783 : : again:
784 : 0 : len -= mbuf->data_len;
785 : 0 : sg = sg >> 16;
786 : : /* Skip SG_S and first IOVA*/
787 : 0 : iova_list = ((const rte_iova_t *)(rx + 1)) + 2;
788 : 0 : nb_segs--;
789 : :
790 : 0 : later_skip = (uintptr_t)mbuf->buf_addr - (uintptr_t)mbuf;
791 : :
792 [ # # # # : 0 : while (nb_segs) {
# # # # #
# # # ]
793 [ # # # # : 0 : if (!(flags & NIX_RX_REAS_F) || !rx_inj)
# # # # #
# # # ]
794 : 0 : mbuf->next = (struct rte_mbuf *)(*iova_list - later_skip);
795 : 0 : mbuf = mbuf->next;
796 : :
797 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
798 : :
799 : 0 : sg_len = sg & 0XFFFF;
800 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
801 : : /* Adjust last mbuf data length with negative offset for
802 : : * security pkts if needed.
803 : : */
804 : 0 : len -= sg_len;
805 [ # # # # : 0 : sg_len = (len > 0) ? sg_len : (sg_len + len);
# # # # #
# # # ]
806 : 0 : len = (len > 0) ? len : 0;
807 : : }
808 : :
809 : 0 : mbuf->data_len = sg_len;
810 : 0 : sg = sg >> 16;
811 : : p = (uintptr_t)&mbuf->rearm_data;
812 [ # # # # : 0 : if (!(flags & NIX_RX_REAS_F) || !rx_inj)
# # # # #
# # # ]
813 : 0 : *(uint64_t *)p = rearm & ~0xFFFF;
814 : 0 : nb_segs--;
815 : 0 : iova_list++;
816 : :
817 [ # # # # : 0 : if (!nb_segs && (iova_list + 1 < eol)) {
# # # # #
# # # # #
# # # # #
# # # #
# ]
818 : 0 : sg = *(const uint64_t *)(iova_list);
819 : 0 : nb_segs = (sg >> 48) & 0x3;
820 : 0 : head->nb_segs += nb_segs;
821 : : iova_list = (const rte_iova_t *)(iova_list + 1);
822 : : }
823 : : }
824 : :
825 [ # # # # : 0 : if ((flags & NIX_RX_REAS_F) && (cq_w1 & BIT(11)) && num_frags) {
# # # # #
# # # # #
# # # # #
# # # #
# ]
826 : 0 : struct rte_mbuf *next_frag = next_mbufs[frag_i];
827 : : uint16_t lcptr, ldptr = 0;
828 : :
829 : 0 : rx = (const union nix_rx_parse_u *)((uintptr_t)(next_frag + 1) + 8);
830 : 0 : lcptr = (*((const uint64_t *)rx + 4) >> 16) & 0xFF;
831 : 0 : eol = ((const rte_iova_t *)(rx + 1) + ((rx->desc_sizem1 + 1) << 1));
832 : 0 : sg = *(const uint64_t *)(rx + 1);
833 : 0 : nb_segs = (sg >> 48) & 0x3;
834 : :
835 [ # # # # : 0 : if (reas_success) {
# # # # #
# # # ]
836 : : /* Update first fragment info */
837 : : if (!frag_i) {
838 : : const uint8_t *ipptr;
839 : :
840 : : ipptr = ((const uint8_t *)hdr + ((cq_w5 >> 16) & 0xFF));
841 : : nix_sec_reass_first_frag_update(head, ipptr, fsz, cq_w1, &ihl);
842 : : fsz >>= 16;
843 : : }
844 : 0 : mbuf->next = next_frag;
845 : 0 : head->nb_segs += nb_segs;
846 : : len = fsz & 0xFFFF;
847 : : fsz >>= 16;
848 : : ldptr = ihl + lcptr;
849 : : } else {
850 : 0 : len = ((eol[0] >> 16) & 0xFFFF) + lcptr;
851 : 0 : head->ol_flags |= BIT_ULL(inb_priv->reass_dynflag_bit) |
852 : : RTE_MBUF_F_RX_SEC_OFFLOAD;
853 : 0 : cnxk_ip_reassembly_dynfield(head, dyn_off)->next_frag = next_frag;
854 : 0 : cnxk_ip_reassembly_dynfield(head, dyn_off)->nb_frags = num_frags;
855 : : /* Update dynamic field with userdata from prev head */
856 : 0 : *rte_security_dynfield(next_frag) = *rte_security_dynfield(head);
857 : : head = next_frag;
858 : 0 : head->pkt_len = len - (flags & NIX_RX_OFFLOAD_TSTAMP_F ?
859 : : CNXK_NIX_TIMESYNC_RX_OFFSET : 0);
860 : : head->nb_segs = nb_segs;
861 : : }
862 : : mbuf = next_frag;
863 : : p = (uintptr_t)&mbuf->rearm_data;
864 : 0 : *(uint64_t *)p = rearm + ldptr;
865 : 0 : mbuf->data_len = (sg & 0xFFFF) - ldptr -
866 : : (flags & NIX_RX_OFFLOAD_TSTAMP_F ?
867 : : CNXK_NIX_TIMESYNC_RX_OFFSET : 0);
868 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
869 : 0 : num_frags--;
870 : 0 : frag_i++;
871 : 0 : goto again;
872 [ # # # # : 0 : } else if ((flags & NIX_RX_REAS_F) && (cq_w1 & BIT(11)) && !reas_success &&
# # # # #
# # # # #
# # # # #
# # # #
# ]
873 [ # # # # : 0 : hdr->w0.pkt_fmt == ROC_IE_OT_SA_PKT_FMT_FULL) {
# # # # #
# # # ]
874 [ # # # # : 0 : uintptr_t wqe = rte_be_to_cpu_64(hdr->wqe_ptr);
# # # # #
# # # ]
875 : :
876 : : /* Process OOP packet inner buffer mseg. reas_success flag is used here only
877 : : * to avoid looping.
878 : : */
879 : 0 : mbuf = ((struct rte_mbuf *)wqe) - 1;
880 : 0 : rx = (const union nix_rx_parse_u *)(wqe + 8);
881 : 0 : eol = ((const rte_iova_t *)(rx + 1) + ((rx->desc_sizem1 + 1) << 1));
882 : 0 : sg = *(const uint64_t *)(rx + 1);
883 : 0 : nb_segs = (sg >> 48) & 0x3;
884 : :
885 : :
886 : 0 : len = mbuf->pkt_len;
887 : : p = (uintptr_t)&mbuf->rearm_data;
888 : 0 : *(uint64_t *)p = rearm;
889 : 0 : mbuf->data_len = (sg & 0xFFFF) -
890 : : (flags & NIX_RX_OFFLOAD_TSTAMP_F ?
891 : : CNXK_NIX_TIMESYNC_RX_OFFSET : 0);
892 : : head = mbuf;
893 : 0 : head->nb_segs = nb_segs;
894 : : /* Using this flag to avoid looping in case of OOP */
895 : : reas_success = true;
896 : 0 : goto again;
897 : : }
898 : :
899 : : /* Update for last failure fragment */
900 [ # # # # : 0 : if ((flags & NIX_RX_REAS_F) && frag_i && !reas_success) {
# # # # #
# # # ]
901 : 0 : cnxk_ip_reassembly_dynfield(head, dyn_off)->next_frag = NULL;
902 : 0 : cnxk_ip_reassembly_dynfield(head, dyn_off)->nb_frags = 0;
903 : : }
904 : : }
905 : :
906 : : static __rte_always_inline void
907 : : cn10k_nix_cqe_to_mbuf(const struct nix_cqe_hdr_s *cq, const uint32_t tag,
908 : : struct rte_mbuf *mbuf, const void *lookup_mem,
909 : : const uint64_t val, const uintptr_t cpth, const uintptr_t sa_base,
910 : : const uint16_t flag)
911 : : {
912 : 0 : const union nix_rx_parse_u *rx =
913 : : (const union nix_rx_parse_u *)((const uint64_t *)cq + 1);
914 : 0 : const uint64_t w1 = *(const uint64_t *)rx;
915 : 0 : uint16_t len = rx->pkt_lenm1 + 1;
916 : : uint64_t ol_flags = 0;
917 : : uintptr_t p;
918 : :
919 : : if (flag & NIX_RX_OFFLOAD_PTYPE_F)
920 : 0 : mbuf->packet_type = nix_ptype_get(lookup_mem, w1);
921 : : else
922 : : mbuf->packet_type = 0;
923 : :
924 : : if (flag & NIX_RX_OFFLOAD_RSS_F) {
925 : 0 : mbuf->hash.rss = tag;
926 : : ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
927 : : }
928 : :
929 : : /* Skip rx ol flags extraction for Security packets */
930 [ # # # # : 0 : if ((!(flag & NIX_RX_SEC_REASSEMBLY_F) || !(w1 & BIT(11))) &&
# # # # #
# # # ]
931 : : flag & NIX_RX_OFFLOAD_CHECKSUM_F)
932 : 0 : ol_flags |= (uint64_t)nix_rx_olflags_get(lookup_mem, w1);
933 : :
934 : : if (flag & NIX_RX_OFFLOAD_VLAN_STRIP_F) {
935 [ # # # # : 0 : if (rx->vtag0_gone) {
# # # # #
# # # ]
936 : 0 : ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
937 : 0 : mbuf->vlan_tci = rx->vtag0_tci;
938 : : }
939 [ # # # # : 0 : if (rx->vtag1_gone) {
# # # # #
# # # ]
940 : 0 : ol_flags |= RTE_MBUF_F_RX_QINQ | RTE_MBUF_F_RX_QINQ_STRIPPED;
941 : 0 : mbuf->vlan_tci_outer = rx->vtag1_tci;
942 : : }
943 : : }
944 : :
945 : : if (flag & NIX_RX_OFFLOAD_MARK_UPDATE_F)
946 : 0 : ol_flags = nix_update_match_id(rx->match_id, ol_flags, mbuf);
947 : :
948 : : /* Packet data length and ol flags is already updated for sec */
949 [ # # # # : 0 : if (flag & NIX_RX_SEC_REASSEMBLY_F && w1 & BIT_ULL(11)) {
# # # # #
# # # ]
950 : 0 : mbuf->ol_flags |= ol_flags;
951 : : } else {
952 : 0 : mbuf->ol_flags = ol_flags;
953 : 0 : mbuf->pkt_len = len;
954 : 0 : mbuf->data_len = len;
955 : : p = (uintptr_t)&mbuf->rearm_data;
956 : 0 : *(uint64_t *)p = val;
957 : : }
958 : :
959 : : if (flag & NIX_RX_MULTI_SEG_F)
960 : : /*
961 : : * For multi segment packets, mbuf length correction according
962 : : * to Rx timestamp length will be handled later during
963 : : * timestamp data process.
964 : : * Hence, timestamp flag argument is not required.
965 : : */
966 : : nix_cqe_xtract_mseg(rx, mbuf, val, cpth, sa_base, flag & ~NIX_RX_OFFLOAD_TSTAMP_F);
967 : : }
968 : :
969 : : static inline uint16_t
970 : : nix_rx_nb_pkts(struct cn10k_eth_rxq *rxq, const uint64_t wdata,
971 : : const uint16_t pkts, const uint32_t qmask)
972 : : {
973 : : uint32_t available = rxq->available;
974 : :
975 : : /* Update the available count if cached value is not enough */
976 : : if (unlikely(available < pkts)) {
977 : : uint64_t reg, head, tail;
978 : :
979 : : /* Use LDADDA version to avoid reorder */
980 : : reg = roc_atomic64_add_sync(wdata, rxq->cq_status);
981 : : /* CQ_OP_STATUS operation error */
982 : : if (reg & BIT_ULL(NIX_CQ_OP_STAT_OP_ERR) ||
983 : : reg & BIT_ULL(NIX_CQ_OP_STAT_CQ_ERR))
984 : : return 0;
985 : :
986 : : tail = reg & 0xFFFFF;
987 : : head = (reg >> 20) & 0xFFFFF;
988 : : if (tail < head)
989 : : available = tail - head + qmask + 1;
990 : : else
991 : : available = tail - head;
992 : :
993 : : rxq->available = available;
994 : : }
995 : :
996 : : return RTE_MIN(pkts, available);
997 : : }
998 : :
999 : : static __rte_always_inline void
1000 : : cn10k_nix_mbuf_to_tstamp(struct rte_mbuf *mbuf,
1001 : : struct cnxk_timesync_info *tstamp,
1002 : : const uint8_t ts_enable, uint64_t *tstamp_ptr)
1003 : : {
1004 : : if (ts_enable) {
1005 : 0 : mbuf->pkt_len -= CNXK_NIX_TIMESYNC_RX_OFFSET;
1006 : 0 : mbuf->data_len -= CNXK_NIX_TIMESYNC_RX_OFFSET;
1007 : :
1008 : : /* Reading the rx timestamp inserted by CGX, viz at
1009 : : * starting of the packet data.
1010 : : */
1011 : 0 : *tstamp_ptr = ((*tstamp_ptr >> 32) * NSEC_PER_SEC) +
1012 : 0 : (*tstamp_ptr & 0xFFFFFFFFUL);
1013 : 0 : *cnxk_nix_timestamp_dynfield(mbuf, tstamp) =
1014 [ # # ]: 0 : rte_be_to_cpu_64(*tstamp_ptr);
1015 : : /* RTE_MBUF_F_RX_IEEE1588_TMST flag needs to be set only in case
1016 : : * PTP packets are received.
1017 : : */
1018 [ # # ]: 0 : if (mbuf->packet_type == RTE_PTYPE_L2_ETHER_TIMESYNC) {
1019 : 0 : tstamp->rx_tstamp =
1020 : : *cnxk_nix_timestamp_dynfield(mbuf, tstamp);
1021 : 0 : tstamp->rx_ready = 1;
1022 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_IEEE1588_PTP |
1023 : : RTE_MBUF_F_RX_IEEE1588_TMST |
1024 : 0 : tstamp->rx_tstamp_dynflag;
1025 : : }
1026 : : }
1027 : : }
1028 : :
1029 : : static __rte_always_inline uint16_t
1030 : : cn10k_nix_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts,
1031 : : const uint16_t flags)
1032 : : {
1033 : : struct cn10k_eth_rxq *rxq = rx_queue;
1034 : : const uint64_t mbuf_init = rxq->mbuf_initializer;
1035 : : const void *lookup_mem = rxq->lookup_mem;
1036 : : const uint64_t data_off = rxq->data_off;
1037 : : struct rte_mempool *meta_pool = NULL;
1038 : : const uintptr_t desc = rxq->desc;
1039 : : const uint64_t wdata = rxq->wdata;
1040 : : const uint32_t qmask = rxq->qmask;
1041 : : uint64_t lbase = rxq->lmt_base;
1042 : : uint16_t packets = 0, nb_pkts;
1043 : : uint8_t loff = 0, lnum = 0;
1044 : : uint32_t head = rxq->head;
1045 : : struct nix_cqe_hdr_s *cq;
1046 : : struct rte_mbuf *mbuf;
1047 : : uint64_t aura_handle;
1048 : : uint64_t sa_base = 0;
1049 : : uintptr_t cpth = 0;
1050 : : uint16_t lmt_id;
1051 : : uint64_t laddr;
1052 : :
1053 : : nb_pkts = nix_rx_nb_pkts(rxq, wdata, pkts, qmask);
1054 : :
1055 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
1056 : : aura_handle = rxq->meta_aura;
1057 : : sa_base = rxq->sa_base;
1058 : : sa_base &= ~(ROC_NIX_INL_SA_BASE_ALIGN - 1);
1059 : : ROC_LMT_BASE_ID_GET(lbase, lmt_id);
1060 : : laddr = lbase;
1061 : : laddr += 8;
1062 : : if (flags & NIX_RX_REAS_F)
1063 : : meta_pool = (struct rte_mempool *)rxq->meta_pool;
1064 : : }
1065 : :
1066 : : while (packets < nb_pkts) {
1067 : : /* Prefetch N desc ahead */
1068 : : rte_prefetch_non_temporal(
1069 : : (void *)(desc + (CQE_SZ((head + 2) & qmask))));
1070 : : cq = (struct nix_cqe_hdr_s *)(desc + CQE_SZ(head));
1071 : :
1072 : : mbuf = nix_get_mbuf_from_cqe(cq, data_off);
1073 : :
1074 : : /* Mark mempool obj as "get" as it is alloc'ed by NIX */
1075 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
1076 : :
1077 : : /* Translate meta to mbuf */
1078 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
1079 : : const uint64_t cq_w1 = *((const uint64_t *)cq + 1);
1080 : : const uint64_t cq_w5 = *((const uint64_t *)cq + 5);
1081 : :
1082 : : cpth = ((uintptr_t)mbuf + (uint16_t)data_off);
1083 : :
1084 : : /* Update mempool pointer for full mode pkt */
1085 : : if ((flags & NIX_RX_REAS_F) && (cq_w1 & BIT(11)) &&
1086 : : !((*(uint64_t *)cpth) & BIT(15)))
1087 : : mbuf->pool = meta_pool;
1088 : :
1089 : : mbuf = nix_sec_meta_to_mbuf_sc(cq_w1, cq_w5, sa_base, laddr,
1090 : : &loff, mbuf, data_off,
1091 : : flags, mbuf_init);
1092 : : }
1093 : :
1094 : : cn10k_nix_cqe_to_mbuf(cq, cq->tag, mbuf, lookup_mem, mbuf_init,
1095 : : cpth, sa_base, flags);
1096 : : cn10k_nix_mbuf_to_tstamp(mbuf, rxq->tstamp,
1097 : : (flags & NIX_RX_OFFLOAD_TSTAMP_F),
1098 : : (uint64_t *)((uint8_t *)mbuf
1099 : : + data_off));
1100 : : rx_pkts[packets++] = mbuf;
1101 : : roc_prefetch_store_keep(mbuf);
1102 : : head++;
1103 : : head &= qmask;
1104 : :
1105 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
1106 : : /* Flush when we don't have space for 4 meta */
1107 : : if ((15 - loff) < 1) {
1108 : : nix_sec_flush_meta(laddr, lmt_id + lnum, loff,
1109 : : aura_handle);
1110 : : lnum++;
1111 : : lnum &= BIT_ULL(ROC_LMT_LINES_PER_CORE_LOG2) -
1112 : : 1;
1113 : : /* First pointer starts at 8B offset */
1114 : : laddr = (uintptr_t)LMT_OFF(lbase, lnum, 8);
1115 : : loff = 0;
1116 : : }
1117 : : }
1118 : : }
1119 : :
1120 : : rxq->head = head;
1121 : : rxq->available -= nb_pkts;
1122 : :
1123 : : /* Free all the CQs that we've processed */
1124 : : plt_write64((wdata | nb_pkts), rxq->cq_door);
1125 : :
1126 : : /* Free remaining meta buffers if any */
1127 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F && loff)
1128 : : nix_sec_flush_meta(laddr, lmt_id + lnum, loff, aura_handle);
1129 : :
1130 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F)
1131 : : rte_io_wmb();
1132 : :
1133 : : return nb_pkts;
1134 : : }
1135 : :
1136 : : static __rte_always_inline uint16_t
1137 : : cn10k_nix_flush_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts,
1138 : : const uint16_t flags)
1139 : : {
1140 : : struct cn10k_eth_rxq *rxq = rx_queue;
1141 : : const uint64_t mbuf_init = rxq->mbuf_initializer;
1142 : : const void *lookup_mem = rxq->lookup_mem;
1143 : : const uint64_t data_off = rxq->data_off;
1144 : : struct rte_mempool *meta_pool = NULL;
1145 : : const uint64_t wdata = rxq->wdata;
1146 : : const uint32_t qmask = rxq->qmask;
1147 : : const uintptr_t desc = rxq->desc;
1148 : : uint64_t lbase = rxq->lmt_base;
1149 : : uint16_t packets = 0, nb_pkts;
1150 : : uint16_t lmt_id __rte_unused;
1151 : : uint32_t head = rxq->head;
1152 : : struct nix_cqe_hdr_s *cq;
1153 : : struct rte_mbuf *mbuf;
1154 : : uint64_t sa_base = 0;
1155 : : uintptr_t cpth = 0;
1156 : : uint8_t loff = 0;
1157 : : uint64_t laddr;
1158 : :
1159 : : nb_pkts = nix_rx_nb_pkts(rxq, wdata, pkts, qmask);
1160 : :
1161 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
1162 : : sa_base = rxq->sa_base;
1163 : : sa_base &= ~(ROC_NIX_INL_SA_BASE_ALIGN - 1);
1164 : : ROC_LMT_BASE_ID_GET(lbase, lmt_id);
1165 : : laddr = lbase;
1166 : : laddr += 8;
1167 : : if (flags & NIX_RX_REAS_F)
1168 : : meta_pool = (struct rte_mempool *)rxq->meta_pool;
1169 : : }
1170 : :
1171 : : while (packets < nb_pkts) {
1172 : : /* Prefetch N desc ahead */
1173 : : rte_prefetch_non_temporal((void *)(desc + (CQE_SZ((head + 2) & qmask))));
1174 : : cq = (struct nix_cqe_hdr_s *)(desc + CQE_SZ(head));
1175 : :
1176 : : mbuf = nix_get_mbuf_from_cqe(cq, data_off);
1177 : :
1178 : : /* Mark mempool obj as "get" as it is alloc'ed by NIX */
1179 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
1180 : :
1181 : : /* Translate meta to mbuf */
1182 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
1183 : : const uint64_t cq_w1 = *((const uint64_t *)cq + 1);
1184 : : const uint64_t cq_w5 = *((const uint64_t *)cq + 5);
1185 : : struct rte_mbuf *meta_buf = mbuf;
1186 : :
1187 : : cpth = ((uintptr_t)meta_buf + (uint16_t)data_off);
1188 : :
1189 : : /* Update mempool pointer for full mode pkt */
1190 : : if ((flags & NIX_RX_REAS_F) && (cq_w1 & BIT(11)) &&
1191 : : !((*(uint64_t *)cpth) & BIT(15)))
1192 : : meta_buf->pool = meta_pool;
1193 : :
1194 : : mbuf = nix_sec_meta_to_mbuf_sc(cq_w1, cq_w5, sa_base, laddr, &loff,
1195 : : meta_buf, data_off, flags, mbuf_init);
1196 : : /* Free Meta mbuf, not use LMT line for flush as this will be called
1197 : : * from non-datapath i.e. dev_stop case.
1198 : : */
1199 : : if (loff) {
1200 : : roc_npa_aura_op_free(meta_buf->pool->pool_id, 0,
1201 : : (uint64_t)meta_buf);
1202 : : loff = 0;
1203 : : }
1204 : : }
1205 : :
1206 : : cn10k_nix_cqe_to_mbuf(cq, cq->tag, mbuf, lookup_mem, mbuf_init,
1207 : : cpth, sa_base, flags);
1208 : : cn10k_nix_mbuf_to_tstamp(mbuf, rxq->tstamp,
1209 : : (flags & NIX_RX_OFFLOAD_TSTAMP_F),
1210 : : (uint64_t *)((uint8_t *)mbuf + data_off));
1211 : : rx_pkts[packets++] = mbuf;
1212 : : roc_prefetch_store_keep(mbuf);
1213 : : head++;
1214 : : head &= qmask;
1215 : : }
1216 : :
1217 : : rxq->head = head;
1218 : : rxq->available -= nb_pkts;
1219 : :
1220 : : /* Free all the CQs that we've processed */
1221 : : plt_write64((wdata | nb_pkts), rxq->cq_door);
1222 : :
1223 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F)
1224 : : rte_io_wmb();
1225 : :
1226 : : return nb_pkts;
1227 : : }
1228 : :
1229 : : #if defined(RTE_ARCH_ARM64)
1230 : : static __rte_always_inline uint16_t
1231 : : cn10k_nix_rx_inj_prepare_mseg(struct rte_mbuf *m, uint64_t *cmd)
1232 : : {
1233 : : union nix_send_sg_s *sg, l_sg;
1234 : : struct rte_mbuf *m_next;
1235 : : uint16_t segdw, nb_segs;
1236 : : uint64_t len, dlen;
1237 : : uint64_t *slist;
1238 : :
1239 : : sg = (union nix_send_sg_s *)cmd;
1240 : : l_sg.u = sg->u;
1241 : : l_sg.u &= 0xC00000000000000; /* LD_TYPE */
1242 : : l_sg.subdc = NIX_SUBDC_SG;
1243 : : nb_segs = m->nb_segs;
1244 : : len = m->pkt_len;
1245 : : slist = &cmd[1];
1246 : :
1247 : : /* Fill mbuf segments */
1248 : : do {
1249 : : *slist = rte_pktmbuf_iova(m);
1250 : : dlen = m->data_len;
1251 : : len -= dlen;
1252 : :
1253 : : /* Set the segment length */
1254 : : l_sg.u |= ((uint64_t)dlen << (l_sg.segs << 4));
1255 : : l_sg.segs += 1;
1256 : : slist++;
1257 : : nb_segs--;
1258 : : if (l_sg.segs > 2 && nb_segs) {
1259 : : sg->u = l_sg.u;
1260 : : /* Next SG subdesc */
1261 : : sg = (union nix_send_sg_s *)slist;
1262 : : l_sg.u = sg->u;
1263 : : l_sg.u &= 0xC00000000000000; /* LD_TYPE */
1264 : : l_sg.subdc = NIX_SUBDC_SG;
1265 : : slist++;
1266 : : }
1267 : : m_next = m->next;
1268 : : m = m_next;
1269 : : } while (nb_segs);
1270 : :
1271 : : /* Add remaining bytes of data to last seg */
1272 : : if (len) {
1273 : : uint8_t shft = (l_sg.subdc == NIX_SUBDC_SG) ? ((l_sg.segs - 1) << 4) : 0;
1274 : : dlen = ((l_sg.u >> shft) & 0xFFFFULL) + len;
1275 : : l_sg.u = l_sg.u & ~(0xFFFFULL << shft);
1276 : : l_sg.u |= dlen << shft;
1277 : : }
1278 : : /* Write the last subdc out */
1279 : : sg->u = l_sg.u;
1280 : :
1281 : : segdw = (uint64_t *)slist - cmd;
1282 : : /* Roundup extra dwords to multiple of 2 */
1283 : : segdw = (segdw >> 1) + (segdw & 0x1);
1284 : : return segdw;
1285 : : }
1286 : :
1287 : : static __rte_always_inline uint16_t
1288 : : cn10k_nix_inj_pkts(struct rte_security_session **sess, struct cnxk_ethdev_inj_cfg *inj_cfg,
1289 : : struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
1290 : : {
1291 : : uintptr_t c_lbase = inj_cfg->lmt_base;
1292 : : struct cn10k_sec_sess_priv sess_priv;
1293 : : uint64_t sa_base = inj_cfg->sa_base;
1294 : : uint16_t c_lmt_id, burst, left, i;
1295 : : uintptr_t cptres, rxphdr, dptr;
1296 : : struct rte_mbuf *m, *last;
1297 : : uint8_t lnum, shft, loff;
1298 : : uint64x2_t cmd01, cmd23;
1299 : : uint64_t ucode_cmd[4];
1300 : : rte_iova_t c_io_addr;
1301 : : uint64_t *laddr;
1302 : : uint64_t sa, w0;
1303 : : uint16_t segdw;
1304 : :
1305 : : /* Get LMT base address and LMT ID as lcore id */
1306 : : ROC_LMT_CPT_BASE_ID_GET(c_lbase, c_lmt_id);
1307 : : c_io_addr = inj_cfg->io_addr;
1308 : :
1309 : : left = nb_pkts;
1310 : : again:
1311 : : burst = left > 32 ? 32 : left;
1312 : :
1313 : : lnum = 0;
1314 : : loff = 0;
1315 : : shft = 16;
1316 : :
1317 : : for (i = 0; i < burst; i++) {
1318 : : m = tx_pkts[i];
1319 : : sess_priv.u64 = sess[i]->fast_mdata;
1320 : : last = rte_pktmbuf_lastseg(m);
1321 : :
1322 : : cptres = rte_pktmbuf_mtod_offset(last, uintptr_t, last->data_len);
1323 : : cptres += BIT_ULL(7);
1324 : : cptres = (cptres - 1) & ~(BIT_ULL(7) - 1);
1325 : :
1326 : : if (m->nb_segs > 1) {
1327 : : /* Will reserve NIX Rx descriptor with SG list after end of
1328 : : * last mbuf data location. and pointer to this will be
1329 : : * stored at 1st mbuf space for Rx path multi-seg processing.
1330 : : */
1331 : : /* Pointer to WQE header */
1332 : : *(uint64_t *)(m + 1) = cptres;
1333 : : /* Reserve 8 Dwords of WQE Hdr + Rx Parse Hdr */
1334 : : rxphdr = cptres + 8;
1335 : : dptr = rxphdr + 7 * 8;
1336 : : /* Prepare Multiseg SG list */
1337 : : segdw = cn10k_nix_rx_inj_prepare_mseg(m, (uint64_t *)(dptr));
1338 : : *(uint64_t *)rxphdr = (uint64_t)(segdw - 1) << 12;
1339 : : cptres += 64 + segdw * 16;
1340 : : ucode_cmd[1] = dptr | ((uint64_t)m->nb_segs << 60);
1341 : : } else {
1342 : : dptr = (uint64_t)rte_pktmbuf_iova(m);
1343 : : ucode_cmd[1] = dptr;
1344 : : }
1345 : :
1346 : : /* Prepare CPT instruction */
1347 : : /* CPT word 0 and 1 */
1348 : : cmd01 = vdupq_n_u64(0);
1349 : : w0 = inj_cfg->cmd_w0 | ((uint64_t)m->l2_len - 2) << 24 | (uint64_t)m->l2_len << 16;
1350 : : cmd01 = vsetq_lane_u64(w0, cmd01, 0);
1351 : : cmd01 = vsetq_lane_u64(cptres, cmd01, 1);
1352 : :
1353 : : /* CPT word 2 and 3 */
1354 : : cmd23 = vdupq_n_u64(0);
1355 : : /* Set PF func */
1356 : : w0 &= 0xFFFF000000000000UL;
1357 : : cmd23 = vsetq_lane_u64(w0, cmd23, 0);
1358 : : cmd23 = vsetq_lane_u64(((uint64_t)m + sizeof(struct rte_mbuf)) | 1, cmd23, 1);
1359 : :
1360 : : sa_base &= ~0xFFFFUL;
1361 : : sa = (uintptr_t)roc_nix_inl_ot_ipsec_inb_sa(sa_base, sess_priv.sa_idx);
1362 : : ucode_cmd[0] = (ROC_IE_OT_MAJOR_OP_PROCESS_INBOUND_IPSEC << 48 | 1UL << 54 |
1363 : : ((uint64_t)sess_priv.chksum) << 32 |
1364 : : ((uint64_t)sess_priv.dec_ttl) << 34 | m->pkt_len);
1365 : :
1366 : : ucode_cmd[2] = 0;
1367 : : ucode_cmd[3] = (ROC_LEGACY_CPT_DFLT_ENG_GRP_SE_IE << 61 | 1UL << 60 | sa);
1368 : :
1369 : : /* Move to our line */
1370 : : laddr = LMT_OFF(c_lbase, lnum, loff ? 64 : 0);
1371 : :
1372 : : /* Write CPT instruction to lmt line */
1373 : : vst1q_u64(laddr, cmd01);
1374 : : vst1q_u64((laddr + 2), cmd23);
1375 : :
1376 : : *(__uint128_t *)(laddr + 4) = *(__uint128_t *)ucode_cmd;
1377 : : *(__uint128_t *)(laddr + 6) = *(__uint128_t *)(ucode_cmd + 2);
1378 : :
1379 : : loff = !loff;
1380 : : lnum = lnum + (loff ? 0 : 1);
1381 : : shft = shft + (loff ? 0 : 3);
1382 : : }
1383 : :
1384 : : left -= burst;
1385 : : tx_pkts += burst;
1386 : : sess += burst;
1387 : :
1388 : : cn10k_nix_sec_steorl(c_io_addr, c_lmt_id, lnum, loff, shft);
1389 : :
1390 : : rte_io_wmb();
1391 : : if (left)
1392 : : goto again;
1393 : :
1394 : : return nb_pkts;
1395 : : }
1396 : : #else
1397 : : static __rte_always_inline uint16_t
1398 : : cn10k_nix_inj_pkts(struct rte_security_session **sess, struct cnxk_ethdev_inj_cfg *inj_cfg,
1399 : : struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
1400 : : {
1401 : : RTE_SET_USED(sess);
1402 : : RTE_SET_USED(inj_cfg);
1403 : : RTE_SET_USED(tx_pkts);
1404 : : RTE_SET_USED(nb_pkts);
1405 : : return 0;
1406 : : }
1407 : : #endif
1408 : :
1409 : : #if defined(RTE_ARCH_ARM64)
1410 : :
1411 : : static __rte_always_inline uint64_t
1412 : : nix_vlan_update(const uint64_t w2, uint64_t ol_flags, uint8x16_t *f)
1413 : : {
1414 : : if (w2 & BIT_ULL(21) /* vtag0_gone */) {
1415 : : ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
1416 : : *f = vsetq_lane_u16((uint16_t)(w2 >> 32), *f, 5);
1417 : : }
1418 : :
1419 : : return ol_flags;
1420 : : }
1421 : :
1422 : : static __rte_always_inline uint64_t
1423 : : nix_qinq_update(const uint64_t w2, uint64_t ol_flags, struct rte_mbuf *mbuf)
1424 : : {
1425 : : if (w2 & BIT_ULL(23) /* vtag1_gone */) {
1426 : : ol_flags |= RTE_MBUF_F_RX_QINQ | RTE_MBUF_F_RX_QINQ_STRIPPED;
1427 : : mbuf->vlan_tci_outer = (uint16_t)(w2 >> 48);
1428 : : }
1429 : :
1430 : : return ol_flags;
1431 : : }
1432 : :
1433 : : #define NIX_PUSH_META_TO_FREE(_mbuf, _laddr, _loff_p) \
1434 : : do { \
1435 : : *(uint64_t *)((_laddr) + (*(_loff_p) << 3)) = (uint64_t)_mbuf; \
1436 : : *(_loff_p) = *(_loff_p) + 1; \
1437 : : /* Mark meta mbuf as put */ \
1438 : : RTE_MEMPOOL_CHECK_COOKIES(_mbuf->pool, (void **)&_mbuf, 1, 0); \
1439 : : } while (0)
1440 : :
1441 : : static __rte_always_inline uint16_t
1442 : : cn10k_nix_recv_pkts_vector(void *args, struct rte_mbuf **mbufs, uint16_t pkts,
1443 : : const uint16_t flags, void *lookup_mem,
1444 : : struct cnxk_timesync_info *tstamp,
1445 : : uintptr_t lmt_base, uint64_t meta_aura)
1446 : : {
1447 : : struct cn10k_eth_rxq *rxq = args;
1448 : : const uint64_t mbuf_initializer = (flags & NIX_RX_VWQE_F) ?
1449 : : *(uint64_t *)args :
1450 : : rxq->mbuf_initializer;
1451 : : const uint64x2_t data_off = flags & NIX_RX_VWQE_F ?
1452 : : vdupq_n_u64(RTE_PKTMBUF_HEADROOM) :
1453 : : vdupq_n_u64(rxq->data_off);
1454 : : const uint32_t qmask = flags & NIX_RX_VWQE_F ? 0 : rxq->qmask;
1455 : : const uint64_t wdata = flags & NIX_RX_VWQE_F ? 0 : rxq->wdata;
1456 : : const uintptr_t desc = flags & NIX_RX_VWQE_F ? 0 : rxq->desc;
1457 : : uint64x2_t cq0_w8, cq1_w8, cq2_w8, cq3_w8, mbuf01, mbuf23;
1458 : : uintptr_t cpth0 = 0, cpth1 = 0, cpth2 = 0, cpth3 = 0;
1459 : : uint64_t ol_flags0, ol_flags1, ol_flags2, ol_flags3;
1460 : : uint64x2_t rearm0 = vdupq_n_u64(mbuf_initializer);
1461 : : uint64x2_t rearm1 = vdupq_n_u64(mbuf_initializer);
1462 : : uint64x2_t rearm2 = vdupq_n_u64(mbuf_initializer);
1463 : : uint64x2_t rearm3 = vdupq_n_u64(mbuf_initializer);
1464 : : struct rte_mbuf *mbuf0, *mbuf1, *mbuf2, *mbuf3;
1465 : : uint8_t loff = 0, lnum = 0, shft = 0;
1466 : : struct rte_mempool *meta_pool = NULL;
1467 : : uint8x16_t f0, f1, f2, f3;
1468 : : uint16_t lmt_id, d_off;
1469 : : uint64_t lbase, laddr;
1470 : : uintptr_t sa_base = 0;
1471 : : uint16_t packets = 0;
1472 : : uint16_t pkts_left;
1473 : : uint32_t head;
1474 : : uintptr_t cq0;
1475 : :
1476 : : if (!(flags & NIX_RX_VWQE_F)) {
1477 : : lookup_mem = rxq->lookup_mem;
1478 : : head = rxq->head;
1479 : :
1480 : : pkts = nix_rx_nb_pkts(rxq, wdata, pkts, qmask);
1481 : : pkts_left = pkts & (NIX_DESCS_PER_LOOP - 1);
1482 : : /* Packets has to be floor-aligned to NIX_DESCS_PER_LOOP */
1483 : : pkts = RTE_ALIGN_FLOOR(pkts, NIX_DESCS_PER_LOOP);
1484 : : if (flags & NIX_RX_OFFLOAD_TSTAMP_F)
1485 : : tstamp = rxq->tstamp;
1486 : :
1487 : : cq0 = desc + CQE_SZ(head);
1488 : : rte_prefetch0(CQE_PTR_OFF(cq0, 0, 64, flags));
1489 : : rte_prefetch0(CQE_PTR_OFF(cq0, 1, 64, flags));
1490 : : rte_prefetch0(CQE_PTR_OFF(cq0, 2, 64, flags));
1491 : : rte_prefetch0(CQE_PTR_OFF(cq0, 3, 64, flags));
1492 : : } else {
1493 : : RTE_SET_USED(head);
1494 : : }
1495 : :
1496 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
1497 : : if (flags & NIX_RX_VWQE_F) {
1498 : : uint64_t sg_w1;
1499 : : uint16_t port;
1500 : :
1501 : : mbuf0 = (struct rte_mbuf *)((uintptr_t)mbufs[0] -
1502 : : sizeof(struct rte_mbuf));
1503 : : /* Pick first mbuf's aura handle assuming all
1504 : : * mbufs are from a vec and are from same RQ.
1505 : : */
1506 : : if (!meta_aura)
1507 : : meta_aura = mbuf0->pool->pool_id;
1508 : : /* Calculate offset from mbuf to actual data area */
1509 : : /* Zero aura's first skip i.e mbuf setup might not match the actual
1510 : : * offset as first skip is taken from second pass RQ. So compute
1511 : : * using diff b/w first SG pointer and mbuf addr.
1512 : : */
1513 : : sg_w1 = *(uint64_t *)((uintptr_t)mbufs[0] + 72);
1514 : : d_off = (sg_w1 - (uint64_t)mbuf0);
1515 : :
1516 : : /* Get SA Base from lookup tbl using port_id */
1517 : : port = mbuf_initializer >> 48;
1518 : : sa_base = cnxk_nix_sa_base_get(port, lookup_mem);
1519 : : if (flags & NIX_RX_REAS_F)
1520 : : meta_pool = (struct rte_mempool *)cnxk_nix_inl_metapool_get(port,
1521 : : lookup_mem);
1522 : :
1523 : : lbase = lmt_base;
1524 : : } else {
1525 : : meta_aura = rxq->meta_aura;
1526 : : d_off = rxq->data_off;
1527 : : sa_base = rxq->sa_base;
1528 : : lbase = rxq->lmt_base;
1529 : : if (flags & NIX_RX_REAS_F)
1530 : : meta_pool = (struct rte_mempool *)rxq->meta_pool;
1531 : : }
1532 : : sa_base &= ~(ROC_NIX_INL_SA_BASE_ALIGN - 1);
1533 : : ROC_LMT_BASE_ID_GET(lbase, lmt_id);
1534 : : lnum = 0;
1535 : : laddr = lbase;
1536 : : laddr += 8;
1537 : : }
1538 : :
1539 : : while (packets < pkts) {
1540 : : if (!(flags & NIX_RX_VWQE_F)) {
1541 : : /* Exit loop if head is about to wrap and become
1542 : : * unaligned.
1543 : : */
1544 : : if (((head + NIX_DESCS_PER_LOOP - 1) & qmask) <
1545 : : NIX_DESCS_PER_LOOP) {
1546 : : pkts_left += (pkts - packets);
1547 : : break;
1548 : : }
1549 : :
1550 : : cq0 = desc + CQE_SZ(head);
1551 : : } else {
1552 : : cq0 = (uintptr_t)&mbufs[packets];
1553 : : }
1554 : :
1555 : : if (flags & NIX_RX_VWQE_F) {
1556 : : if (pkts - packets > 4) {
1557 : : rte_prefetch_non_temporal(CQE_PTR_OFF(cq0,
1558 : : 4, 0, flags));
1559 : : rte_prefetch_non_temporal(CQE_PTR_OFF(cq0,
1560 : : 5, 0, flags));
1561 : : rte_prefetch_non_temporal(CQE_PTR_OFF(cq0,
1562 : : 6, 0, flags));
1563 : : rte_prefetch_non_temporal(CQE_PTR_OFF(cq0,
1564 : : 7, 0, flags));
1565 : :
1566 : : if (likely(pkts - packets > 8)) {
1567 : : rte_prefetch1(CQE_PTR_OFF(cq0,
1568 : : 8, 0, flags));
1569 : : rte_prefetch1(CQE_PTR_OFF(cq0,
1570 : : 9, 0, flags));
1571 : : rte_prefetch1(CQE_PTR_OFF(cq0,
1572 : : 10, 0, flags));
1573 : : rte_prefetch1(CQE_PTR_OFF(cq0,
1574 : : 11, 0, flags));
1575 : : if (pkts - packets > 12) {
1576 : : rte_prefetch1(CQE_PTR_OFF(cq0,
1577 : : 12, 0, flags));
1578 : : rte_prefetch1(CQE_PTR_OFF(cq0,
1579 : : 13, 0, flags));
1580 : : rte_prefetch1(CQE_PTR_OFF(cq0,
1581 : : 14, 0, flags));
1582 : : rte_prefetch1(CQE_PTR_OFF(cq0,
1583 : : 15, 0, flags));
1584 : : }
1585 : : }
1586 : :
1587 : : rte_prefetch0(CQE_PTR_DIFF(cq0,
1588 : : 4, RTE_PKTMBUF_HEADROOM, flags));
1589 : : rte_prefetch0(CQE_PTR_DIFF(cq0,
1590 : : 5, RTE_PKTMBUF_HEADROOM, flags));
1591 : : rte_prefetch0(CQE_PTR_DIFF(cq0,
1592 : : 6, RTE_PKTMBUF_HEADROOM, flags));
1593 : : rte_prefetch0(CQE_PTR_DIFF(cq0,
1594 : : 7, RTE_PKTMBUF_HEADROOM, flags));
1595 : :
1596 : : if (likely(pkts - packets > 8)) {
1597 : : rte_prefetch0(CQE_PTR_DIFF(cq0,
1598 : : 8, RTE_PKTMBUF_HEADROOM, flags));
1599 : : rte_prefetch0(CQE_PTR_DIFF(cq0,
1600 : : 9, RTE_PKTMBUF_HEADROOM, flags));
1601 : : rte_prefetch0(CQE_PTR_DIFF(cq0,
1602 : : 10, RTE_PKTMBUF_HEADROOM, flags));
1603 : : rte_prefetch0(CQE_PTR_DIFF(cq0,
1604 : : 11, RTE_PKTMBUF_HEADROOM, flags));
1605 : : }
1606 : : }
1607 : : } else {
1608 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F &&
1609 : : pkts - packets > 4) {
1610 : : /* Fetch cpt parse header */
1611 : : void *p0 =
1612 : : (void *)*CQE_PTR_OFF(cq0, 4, 72, flags);
1613 : : void *p1 =
1614 : : (void *)*CQE_PTR_OFF(cq0, 5, 72, flags);
1615 : : void *p2 =
1616 : : (void *)*CQE_PTR_OFF(cq0, 6, 72, flags);
1617 : : void *p3 =
1618 : : (void *)*CQE_PTR_OFF(cq0, 7, 72, flags);
1619 : : rte_prefetch0(p0);
1620 : : rte_prefetch0(p1);
1621 : : rte_prefetch0(p2);
1622 : : rte_prefetch0(p3);
1623 : : }
1624 : :
1625 : : if (pkts - packets > 8) {
1626 : : if (flags) {
1627 : : rte_prefetch0(CQE_PTR_OFF(cq0, 8, 0, flags));
1628 : : rte_prefetch0(CQE_PTR_OFF(cq0, 9, 0, flags));
1629 : : rte_prefetch0(CQE_PTR_OFF(cq0, 10, 0, flags));
1630 : : rte_prefetch0(CQE_PTR_OFF(cq0, 11, 0, flags));
1631 : : }
1632 : : rte_prefetch0(CQE_PTR_OFF(cq0, 8, 64, flags));
1633 : : rte_prefetch0(CQE_PTR_OFF(cq0, 9, 64, flags));
1634 : : rte_prefetch0(CQE_PTR_OFF(cq0, 10, 64, flags));
1635 : : rte_prefetch0(CQE_PTR_OFF(cq0, 11, 64, flags));
1636 : : }
1637 : : }
1638 : :
1639 : : if (!(flags & NIX_RX_VWQE_F)) {
1640 : : /* Get NIX_RX_SG_S for size and buffer pointer */
1641 : : cq0_w8 = vld1q_u64(CQE_PTR_OFF(cq0, 0, 64, flags));
1642 : : cq1_w8 = vld1q_u64(CQE_PTR_OFF(cq0, 1, 64, flags));
1643 : : cq2_w8 = vld1q_u64(CQE_PTR_OFF(cq0, 2, 64, flags));
1644 : : cq3_w8 = vld1q_u64(CQE_PTR_OFF(cq0, 3, 64, flags));
1645 : :
1646 : : /* Extract mbuf from NIX_RX_SG_S */
1647 : : mbuf01 = vzip2q_u64(cq0_w8, cq1_w8);
1648 : : mbuf23 = vzip2q_u64(cq2_w8, cq3_w8);
1649 : : mbuf01 = vqsubq_u64(mbuf01, data_off);
1650 : : mbuf23 = vqsubq_u64(mbuf23, data_off);
1651 : : } else {
1652 : : mbuf01 =
1653 : : vsubq_u64(vld1q_u64((uint64_t *)cq0),
1654 : : vdupq_n_u64(sizeof(struct rte_mbuf)));
1655 : : mbuf23 =
1656 : : vsubq_u64(vld1q_u64((uint64_t *)(cq0 + 16)),
1657 : : vdupq_n_u64(sizeof(struct rte_mbuf)));
1658 : : }
1659 : :
1660 : : /* Move mbufs to scalar registers for future use */
1661 : : mbuf0 = (struct rte_mbuf *)vgetq_lane_u64(mbuf01, 0);
1662 : : mbuf1 = (struct rte_mbuf *)vgetq_lane_u64(mbuf01, 1);
1663 : : mbuf2 = (struct rte_mbuf *)vgetq_lane_u64(mbuf23, 0);
1664 : : mbuf3 = (struct rte_mbuf *)vgetq_lane_u64(mbuf23, 1);
1665 : :
1666 : : /* Mark mempool obj as "get" as it is alloc'ed by NIX */
1667 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf0->pool, (void **)&mbuf0, 1, 1);
1668 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf1->pool, (void **)&mbuf1, 1, 1);
1669 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf2->pool, (void **)&mbuf2, 1, 1);
1670 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf3->pool, (void **)&mbuf3, 1, 1);
1671 : :
1672 : : if (!(flags & NIX_RX_VWQE_F)) {
1673 : : /* Mask to get packet len from NIX_RX_SG_S */
1674 : : const uint8x16_t shuf_msk = {
1675 : : 0xFF, 0xFF, /* pkt_type set as unknown */
1676 : : 0xFF, 0xFF, /* pkt_type set as unknown */
1677 : : 0, 1, /* octet 1~0, low 16 bits pkt_len */
1678 : : 0xFF, 0xFF, /* skip high 16it pkt_len, zero out */
1679 : : 0, 1, /* octet 1~0, 16 bits data_len */
1680 : : 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1681 : :
1682 : : /* Form the rx_descriptor_fields1 with pkt_len and data_len */
1683 : : f0 = vqtbl1q_u8(cq0_w8, shuf_msk);
1684 : : f1 = vqtbl1q_u8(cq1_w8, shuf_msk);
1685 : : f2 = vqtbl1q_u8(cq2_w8, shuf_msk);
1686 : : f3 = vqtbl1q_u8(cq3_w8, shuf_msk);
1687 : : }
1688 : :
1689 : : /* Load CQE word0 and word 1 */
1690 : : const uint64_t cq0_w0 = *CQE_PTR_OFF(cq0, 0, 0, flags);
1691 : : const uint64_t cq0_w1 = *CQE_PTR_OFF(cq0, 0, 8, flags);
1692 : : const uint64_t cq0_w2 = *CQE_PTR_OFF(cq0, 0, 16, flags);
1693 : : const uint64_t cq1_w0 = *CQE_PTR_OFF(cq0, 1, 0, flags);
1694 : : const uint64_t cq1_w1 = *CQE_PTR_OFF(cq0, 1, 8, flags);
1695 : : const uint64_t cq1_w2 = *CQE_PTR_OFF(cq0, 1, 16, flags);
1696 : : const uint64_t cq2_w0 = *CQE_PTR_OFF(cq0, 2, 0, flags);
1697 : : const uint64_t cq2_w1 = *CQE_PTR_OFF(cq0, 2, 8, flags);
1698 : : const uint64_t cq2_w2 = *CQE_PTR_OFF(cq0, 2, 16, flags);
1699 : : const uint64_t cq3_w0 = *CQE_PTR_OFF(cq0, 3, 0, flags);
1700 : : const uint64_t cq3_w1 = *CQE_PTR_OFF(cq0, 3, 8, flags);
1701 : : const uint64_t cq3_w2 = *CQE_PTR_OFF(cq0, 3, 16, flags);
1702 : :
1703 : : if (flags & NIX_RX_VWQE_F) {
1704 : : uint16_t psize0, psize1, psize2, psize3;
1705 : :
1706 : : psize0 = (cq0_w2 & 0xFFFF) + 1;
1707 : : psize1 = (cq1_w2 & 0xFFFF) + 1;
1708 : : psize2 = (cq2_w2 & 0xFFFF) + 1;
1709 : : psize3 = (cq3_w2 & 0xFFFF) + 1;
1710 : :
1711 : : f0 = vdupq_n_u64(0);
1712 : : f1 = vdupq_n_u64(0);
1713 : : f2 = vdupq_n_u64(0);
1714 : : f3 = vdupq_n_u64(0);
1715 : :
1716 : : f0 = vsetq_lane_u16(psize0, f0, 2);
1717 : : f0 = vsetq_lane_u16(psize0, f0, 4);
1718 : :
1719 : : f1 = vsetq_lane_u16(psize1, f1, 2);
1720 : : f1 = vsetq_lane_u16(psize1, f1, 4);
1721 : :
1722 : : f2 = vsetq_lane_u16(psize2, f2, 2);
1723 : : f2 = vsetq_lane_u16(psize2, f2, 4);
1724 : :
1725 : : f3 = vsetq_lane_u16(psize3, f3, 2);
1726 : : f3 = vsetq_lane_u16(psize3, f3, 4);
1727 : : }
1728 : :
1729 : : if (flags & NIX_RX_OFFLOAD_RSS_F) {
1730 : : /* Fill rss in the rx_descriptor_fields1 */
1731 : : f0 = vsetq_lane_u32(cq0_w0, f0, 3);
1732 : : f1 = vsetq_lane_u32(cq1_w0, f1, 3);
1733 : : f2 = vsetq_lane_u32(cq2_w0, f2, 3);
1734 : : f3 = vsetq_lane_u32(cq3_w0, f3, 3);
1735 : : ol_flags0 = RTE_MBUF_F_RX_RSS_HASH;
1736 : : ol_flags1 = RTE_MBUF_F_RX_RSS_HASH;
1737 : : ol_flags2 = RTE_MBUF_F_RX_RSS_HASH;
1738 : : ol_flags3 = RTE_MBUF_F_RX_RSS_HASH;
1739 : : } else {
1740 : : ol_flags0 = 0;
1741 : : ol_flags1 = 0;
1742 : : ol_flags2 = 0;
1743 : : ol_flags3 = 0;
1744 : : }
1745 : :
1746 : : if (flags & NIX_RX_OFFLOAD_PTYPE_F) {
1747 : : /* Fill packet_type in the rx_descriptor_fields1 */
1748 : : f0 = vsetq_lane_u32(nix_ptype_get(lookup_mem, cq0_w1),
1749 : : f0, 0);
1750 : : f1 = vsetq_lane_u32(nix_ptype_get(lookup_mem, cq1_w1),
1751 : : f1, 0);
1752 : : f2 = vsetq_lane_u32(nix_ptype_get(lookup_mem, cq2_w1),
1753 : : f2, 0);
1754 : : f3 = vsetq_lane_u32(nix_ptype_get(lookup_mem, cq3_w1),
1755 : : f3, 0);
1756 : : }
1757 : :
1758 : : if (flags & NIX_RX_OFFLOAD_CHECKSUM_F) {
1759 : : ol_flags0 |= (uint64_t)nix_rx_olflags_get(lookup_mem, cq0_w1);
1760 : : ol_flags1 |= (uint64_t)nix_rx_olflags_get(lookup_mem, cq1_w1);
1761 : : ol_flags2 |= (uint64_t)nix_rx_olflags_get(lookup_mem, cq2_w1);
1762 : : ol_flags3 |= (uint64_t)nix_rx_olflags_get(lookup_mem, cq3_w1);
1763 : : }
1764 : :
1765 : : /* Translate meta to mbuf */
1766 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
1767 : : uint64_t cq0_w5 = *CQE_PTR_OFF(cq0, 0, 40, flags);
1768 : : uint64_t cq1_w5 = *CQE_PTR_OFF(cq0, 1, 40, flags);
1769 : : uint64_t cq2_w5 = *CQE_PTR_OFF(cq0, 2, 40, flags);
1770 : : uint64_t cq3_w5 = *CQE_PTR_OFF(cq0, 3, 40, flags);
1771 : : uint8_t code;
1772 : :
1773 : : uint64x2_t inner0, inner1, inner2, inner3;
1774 : : uint64x2_t wqe01, wqe23, sa01, sa23;
1775 : : uint16x4_t lens, l2lens, ltypes;
1776 : : uint64x2_t mask01, mask23;
1777 : : uint8x8_t ucc;
1778 : :
1779 : : cpth0 = (uintptr_t)mbuf0 + d_off;
1780 : : cpth1 = (uintptr_t)mbuf1 + d_off;
1781 : : cpth2 = (uintptr_t)mbuf2 + d_off;
1782 : : cpth3 = (uintptr_t)mbuf3 + d_off;
1783 : :
1784 : : inner0 = vld1q_u64((const uint64_t *)cpth0);
1785 : : inner1 = vld1q_u64((const uint64_t *)cpth1);
1786 : : inner2 = vld1q_u64((const uint64_t *)cpth2);
1787 : : inner3 = vld1q_u64((const uint64_t *)cpth3);
1788 : :
1789 : : /* Extract and reverse wqe pointers */
1790 : : wqe01 = vzip2q_u64(inner0, inner1);
1791 : : wqe23 = vzip2q_u64(inner2, inner3);
1792 : : wqe01 = vrev64q_u8(wqe01);
1793 : : wqe23 = vrev64q_u8(wqe23);
1794 : : /* Adjust wqe pointers to point to mbuf */
1795 : : wqe01 = vsubq_u64(wqe01,
1796 : : vdupq_n_u64(sizeof(struct rte_mbuf)));
1797 : : wqe23 = vsubq_u64(wqe23,
1798 : : vdupq_n_u64(sizeof(struct rte_mbuf)));
1799 : :
1800 : : /* Extract sa idx from cookie area and add to sa_base */
1801 : : sa01 = vzip1q_u64(inner0, inner1);
1802 : : sa23 = vzip1q_u64(inner2, inner3);
1803 : :
1804 : : sa01 = vshrq_n_u64(sa01, 32);
1805 : : sa23 = vshrq_n_u64(sa23, 32);
1806 : :
1807 : : /* Crypto Look-aside Rx Inject case */
1808 : : mask01 = vceqq_u64(sa01, vdupq_n_u64(0xFFFFFFFF));
1809 : : mask23 = vceqq_u64(sa23, vdupq_n_u64(0xFFFFFFFF));
1810 : :
1811 : : sa01 = vshlq_n_u64(sa01,
1812 : : ROC_NIX_INL_OT_IPSEC_INB_SA_SZ_LOG2);
1813 : : sa23 = vshlq_n_u64(sa23,
1814 : : ROC_NIX_INL_OT_IPSEC_INB_SA_SZ_LOG2);
1815 : : sa01 = vaddq_u64(sa01, vdupq_n_u64(sa_base));
1816 : : sa23 = vaddq_u64(sa23, vdupq_n_u64(sa_base));
1817 : :
1818 : : if (flags & NIX_RX_REAS_F) {
1819 : : sa01 = vbicq_u64(sa01, mask01);
1820 : : sa23 = vbicq_u64(sa23, mask23);
1821 : : }
1822 : :
1823 : : const uint8x16x2_t tbl = {{
1824 : : {
1825 : : /* ROC_IE_OT_UCC_SUCCESS_PKT_IP_BADCSUM */
1826 : : RTE_MBUF_F_RX_IP_CKSUM_BAD >> 1,
1827 : : /* ROC_IE_OT_UCC_SUCCESS_PKT_L4_GOODCSUM */
1828 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD |
1829 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1,
1830 : : /* ROC_IE_OT_UCC_SUCCESS_PKT_L4_BADCSUM */
1831 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD |
1832 : : RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1,
1833 : : 1,
1834 : : /* ROC_IE_OT_UCC_SUCCESS_PKT_UDPESP_NZCSUM */
1835 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD |
1836 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1,
1837 : : 1,
1838 : : /* ROC_IE_OT_UCC_SUCCESS_PKT_UDP_ZEROCSUM */
1839 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD |
1840 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1,
1841 : : 3, 1, 3, 3, 3, 3, 1, 3, 1,
1842 : : },
1843 : : {
1844 : : 1, 1, 1,
1845 : : /* ROC_IE_OT_UCC_SUCCESS_PKT_IP_GOODCSUM */
1846 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD >> 1,
1847 : : /* Rest 0 to indicate RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED */
1848 : : 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1849 : : },
1850 : : }};
1851 : :
1852 : : const uint8x8_t err_off = {
1853 : : /* UCC */
1854 : : 0xED,
1855 : : /* HW_CCODE 0:6 -> 7:D */
1856 : : -7,
1857 : : 0xED,
1858 : : -7,
1859 : : 0xED,
1860 : : -7,
1861 : : 0xED,
1862 : : -7,
1863 : : };
1864 : :
1865 : : ucc = vdup_n_u8(0);
1866 : : ucc = vset_lane_u16(*(uint16_t *)(cpth0 + 30), ucc, 0);
1867 : : ucc = vset_lane_u16(*(uint16_t *)(cpth1 + 30), ucc, 1);
1868 : : ucc = vset_lane_u16(*(uint16_t *)(cpth2 + 30), ucc, 2);
1869 : : ucc = vset_lane_u16(*(uint16_t *)(cpth3 + 30), ucc, 3);
1870 : : ucc = vsub_u8(ucc, err_off);
1871 : :
1872 : : /* Table lookup to get the corresponding flags, Out of the range
1873 : : * from this lookup will have value 0 and consider as
1874 : : * RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED.
1875 : : */
1876 : : ucc = vqtbl2_u8(tbl, ucc);
1877 : :
1878 : : RTE_BUILD_BUG_ON(NPC_LT_LC_IP != 2);
1879 : : RTE_BUILD_BUG_ON(NPC_LT_LC_IP_OPT != 3);
1880 : : RTE_BUILD_BUG_ON(NPC_LT_LC_IP6 != 4);
1881 : : RTE_BUILD_BUG_ON(NPC_LT_LC_IP6_EXT != 5);
1882 : :
1883 : : ltypes = vdup_n_u16(0);
1884 : : ltypes = vset_lane_u16((cq0_w1 >> 40) & 0x6, ltypes, 0);
1885 : : ltypes = vset_lane_u16((cq1_w1 >> 40) & 0x6, ltypes, 1);
1886 : : ltypes = vset_lane_u16((cq2_w1 >> 40) & 0x6, ltypes, 2);
1887 : : ltypes = vset_lane_u16((cq3_w1 >> 40) & 0x6, ltypes, 3);
1888 : :
1889 : : /* Extract and reverse l3 length from IPv4/IPv6 hdr
1890 : : * that is in same cacheline most probably as cpth.
1891 : : */
1892 : : cpth0 += ((cq0_w5 >> 16) & 0xFF) +
1893 : : vget_lane_u16(ltypes, 0);
1894 : : cpth1 += ((cq1_w5 >> 16) & 0xFF) +
1895 : : vget_lane_u16(ltypes, 1);
1896 : : cpth2 += ((cq2_w5 >> 16) & 0xFF) +
1897 : : vget_lane_u16(ltypes, 2);
1898 : : cpth3 += ((cq3_w5 >> 16) & 0xFF) +
1899 : : vget_lane_u16(ltypes, 3);
1900 : : lens = vdup_n_u16(0);
1901 : : lens = vset_lane_u16(*(uint16_t *)cpth0, lens, 0);
1902 : : lens = vset_lane_u16(*(uint16_t *)cpth1, lens, 1);
1903 : : lens = vset_lane_u16(*(uint16_t *)cpth2, lens, 2);
1904 : : lens = vset_lane_u16(*(uint16_t *)cpth3, lens, 3);
1905 : : lens = vrev16_u8(lens);
1906 : :
1907 : : /* Add l2 length to l3 lengths */
1908 : : l2lens = vdup_n_u16(0);
1909 : : l2lens = vset_lane_u16(((cq0_w5 >> 16) & 0xFF) -
1910 : : (cq0_w5 & 0xFF),
1911 : : l2lens, 0);
1912 : : l2lens = vset_lane_u16(((cq1_w5 >> 16) & 0xFF) -
1913 : : (cq1_w5 & 0xFF),
1914 : : l2lens, 1);
1915 : : l2lens = vset_lane_u16(((cq2_w5 >> 16) & 0xFF) -
1916 : : (cq2_w5 & 0xFF),
1917 : : l2lens, 2);
1918 : : l2lens = vset_lane_u16(((cq3_w5 >> 16) & 0xFF) -
1919 : : (cq3_w5 & 0xFF),
1920 : : l2lens, 3);
1921 : : lens = vadd_u16(lens, l2lens);
1922 : :
1923 : : /* L3 header adjust */
1924 : : const int8x8_t l3adj = {
1925 : : 0, 0, 0, 0, 40, 0, 0, 0,
1926 : : };
1927 : : lens = vadd_u16(lens, vtbl1_u8(l3adj, ltypes));
1928 : :
1929 : : /* Initialize rearm data when reassembly is enabled as
1930 : : * data offset might change.
1931 : : */
1932 : : if (flags & NIX_RX_REAS_F) {
1933 : : rearm0 = vdupq_n_u64(mbuf_initializer);
1934 : : rearm1 = vdupq_n_u64(mbuf_initializer);
1935 : : rearm2 = vdupq_n_u64(mbuf_initializer);
1936 : : rearm3 = vdupq_n_u64(mbuf_initializer);
1937 : : }
1938 : :
1939 : : /* Checksum ol_flags will be cleared if mbuf is meta */
1940 : : if (cq0_w1 & BIT(11)) {
1941 : : uintptr_t wqe = vgetq_lane_u64(wqe01, 0);
1942 : : uintptr_t sa = vgetq_lane_u64(sa01, 0);
1943 : : uint16_t len = vget_lane_u16(lens, 0);
1944 : :
1945 : : cpth0 = (uintptr_t)mbuf0 + d_off;
1946 : :
1947 : : /* Free meta to aura */
1948 : : if (!(flags & NIX_RX_REAS_F) ||
1949 : : *(uint64_t *)cpth0 & BIT_ULL(15)) {
1950 : : /* Free meta to aura */
1951 : : NIX_PUSH_META_TO_FREE(mbuf0, laddr,
1952 : : &loff);
1953 : : mbuf01 = vsetq_lane_u64(wqe, mbuf01, 0);
1954 : : mbuf0 = (struct rte_mbuf *)wqe;
1955 : : } else if (flags & NIX_RX_REAS_F) {
1956 : : /* Update meta pool for full mode pkts */
1957 : : mbuf0->pool = meta_pool;
1958 : : }
1959 : :
1960 : : /* Update pkt_len and data_len */
1961 : : f0 = vsetq_lane_u16(len, f0, 2);
1962 : : f0 = vsetq_lane_u16(len, f0, 4);
1963 : :
1964 : : nix_sec_meta_to_mbuf(cq0_w1, cq0_w5, sa, cpth0,
1965 : : mbuf0, &f0, &ol_flags0,
1966 : : flags, &rearm0);
1967 : : code = vget_lane_u8(ucc, 0);
1968 : : ol_flags0 |= code ? (code > 1 ? ((uint64_t)code) << 1 : 0) :
1969 : : RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
1970 : :
1971 : : ol_flags0 |= ((uint64_t)(vget_lane_u8(ucc, 1)) << 18);
1972 : : }
1973 : :
1974 : : if (cq1_w1 & BIT(11)) {
1975 : : uintptr_t wqe = vgetq_lane_u64(wqe01, 1);
1976 : : uintptr_t sa = vgetq_lane_u64(sa01, 1);
1977 : : uint16_t len = vget_lane_u16(lens, 1);
1978 : :
1979 : : cpth1 = (uintptr_t)mbuf1 + d_off;
1980 : :
1981 : : /* Free meta to aura */
1982 : : if (!(flags & NIX_RX_REAS_F) ||
1983 : : *(uint64_t *)cpth1 & BIT_ULL(15)) {
1984 : : NIX_PUSH_META_TO_FREE(mbuf1, laddr,
1985 : : &loff);
1986 : : mbuf01 = vsetq_lane_u64(wqe, mbuf01, 1);
1987 : : mbuf1 = (struct rte_mbuf *)wqe;
1988 : : } else if (flags & NIX_RX_REAS_F) {
1989 : : /* Update meta pool for full mode pkts */
1990 : : mbuf1->pool = meta_pool;
1991 : : }
1992 : :
1993 : : /* Update pkt_len and data_len */
1994 : : f1 = vsetq_lane_u16(len, f1, 2);
1995 : : f1 = vsetq_lane_u16(len, f1, 4);
1996 : :
1997 : : nix_sec_meta_to_mbuf(cq1_w1, cq1_w5, sa, cpth1,
1998 : : mbuf1, &f1, &ol_flags1,
1999 : : flags, &rearm1);
2000 : : code = vget_lane_u8(ucc, 2);
2001 : : ol_flags1 |= code ? (code > 1 ? ((uint64_t)code) << 1 : 0) :
2002 : : RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
2003 : : ol_flags1 |= ((uint64_t)(vget_lane_u8(ucc, 3)) << 18);
2004 : : }
2005 : :
2006 : : if (cq2_w1 & BIT(11)) {
2007 : : uintptr_t wqe = vgetq_lane_u64(wqe23, 0);
2008 : : uintptr_t sa = vgetq_lane_u64(sa23, 0);
2009 : : uint16_t len = vget_lane_u16(lens, 2);
2010 : :
2011 : : cpth2 = (uintptr_t)mbuf2 + d_off;
2012 : :
2013 : : /* Free meta to aura */
2014 : : if (!(flags & NIX_RX_REAS_F) ||
2015 : : *(uint64_t *)cpth2 & BIT_ULL(15)) {
2016 : : NIX_PUSH_META_TO_FREE(mbuf2, laddr,
2017 : : &loff);
2018 : : mbuf23 = vsetq_lane_u64(wqe, mbuf23, 0);
2019 : : mbuf2 = (struct rte_mbuf *)wqe;
2020 : : } else if (flags & NIX_RX_REAS_F) {
2021 : : /* Update meta pool for full mode pkts */
2022 : : mbuf2->pool = meta_pool;
2023 : : }
2024 : :
2025 : : /* Update pkt_len and data_len */
2026 : : f2 = vsetq_lane_u16(len, f2, 2);
2027 : : f2 = vsetq_lane_u16(len, f2, 4);
2028 : :
2029 : : nix_sec_meta_to_mbuf(cq2_w1, cq2_w5, sa, cpth2,
2030 : : mbuf2, &f2, &ol_flags2,
2031 : : flags, &rearm2);
2032 : : code = vget_lane_u8(ucc, 4);
2033 : : ol_flags2 |= code ? (code > 1 ? ((uint64_t)code) << 1 : 0) :
2034 : : RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
2035 : : ol_flags2 |= ((uint64_t)(vget_lane_u8(ucc, 5)) << 18);
2036 : : }
2037 : :
2038 : : if (cq3_w1 & BIT(11)) {
2039 : : uintptr_t wqe = vgetq_lane_u64(wqe23, 1);
2040 : : uintptr_t sa = vgetq_lane_u64(sa23, 1);
2041 : : uint16_t len = vget_lane_u16(lens, 3);
2042 : :
2043 : : cpth3 = (uintptr_t)mbuf3 + d_off;
2044 : :
2045 : : /* Free meta to aura */
2046 : : if (!(flags & NIX_RX_REAS_F) ||
2047 : : *(uint64_t *)cpth3 & BIT_ULL(15)) {
2048 : : NIX_PUSH_META_TO_FREE(mbuf3, laddr,
2049 : : &loff);
2050 : : mbuf23 = vsetq_lane_u64(wqe, mbuf23, 1);
2051 : : mbuf3 = (struct rte_mbuf *)wqe;
2052 : : } else if (flags & NIX_RX_REAS_F) {
2053 : : /* Update meta pool for full mode pkts */
2054 : : mbuf3->pool = meta_pool;
2055 : : }
2056 : :
2057 : : /* Update pkt_len and data_len */
2058 : : f3 = vsetq_lane_u16(len, f3, 2);
2059 : : f3 = vsetq_lane_u16(len, f3, 4);
2060 : :
2061 : : nix_sec_meta_to_mbuf(cq3_w1, cq3_w5, sa, cpth3,
2062 : : mbuf3, &f3, &ol_flags3,
2063 : : flags, &rearm3);
2064 : : code = vget_lane_u8(ucc, 6);
2065 : : ol_flags3 |= code ? (code > 1 ? ((uint64_t)code) << 1 : 0) :
2066 : : RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
2067 : : ol_flags3 |= ((uint64_t)(vget_lane_u8(ucc, 7)) << 18);
2068 : : }
2069 : : }
2070 : :
2071 : : if (flags & NIX_RX_OFFLOAD_VLAN_STRIP_F) {
2072 : :
2073 : : ol_flags0 = nix_vlan_update(cq0_w2, ol_flags0, &f0);
2074 : : ol_flags1 = nix_vlan_update(cq1_w2, ol_flags1, &f1);
2075 : : ol_flags2 = nix_vlan_update(cq2_w2, ol_flags2, &f2);
2076 : : ol_flags3 = nix_vlan_update(cq3_w2, ol_flags3, &f3);
2077 : :
2078 : : ol_flags0 = nix_qinq_update(cq0_w2, ol_flags0, mbuf0);
2079 : : ol_flags1 = nix_qinq_update(cq1_w2, ol_flags1, mbuf1);
2080 : : ol_flags2 = nix_qinq_update(cq2_w2, ol_flags2, mbuf2);
2081 : : ol_flags3 = nix_qinq_update(cq3_w2, ol_flags3, mbuf3);
2082 : : }
2083 : :
2084 : : if (flags & NIX_RX_OFFLOAD_MARK_UPDATE_F) {
2085 : : ol_flags0 = nix_update_match_id(
2086 : : *(uint16_t *)CQE_PTR_OFF(cq0, 0, 38, flags),
2087 : : ol_flags0, mbuf0);
2088 : : ol_flags1 = nix_update_match_id(
2089 : : *(uint16_t *)CQE_PTR_OFF(cq0, 1, 38, flags),
2090 : : ol_flags1, mbuf1);
2091 : : ol_flags2 = nix_update_match_id(
2092 : : *(uint16_t *)CQE_PTR_OFF(cq0, 2, 38, flags),
2093 : : ol_flags2, mbuf2);
2094 : : ol_flags3 = nix_update_match_id(
2095 : : *(uint16_t *)CQE_PTR_OFF(cq0, 3, 38, flags),
2096 : : ol_flags3, mbuf3);
2097 : : }
2098 : :
2099 : : if ((flags & NIX_RX_OFFLOAD_TSTAMP_F) &&
2100 : : ((flags & NIX_RX_VWQE_F) && tstamp)) {
2101 : : const uint16x8_t len_off = {
2102 : : 0, /* ptype 0:15 */
2103 : : 0, /* ptype 16:32 */
2104 : : CNXK_NIX_TIMESYNC_RX_OFFSET, /* pktlen 0:15*/
2105 : : 0, /* pktlen 16:32 */
2106 : : CNXK_NIX_TIMESYNC_RX_OFFSET, /* datalen 0:15 */
2107 : : 0,
2108 : : 0,
2109 : : 0};
2110 : : const uint32x4_t ptype = {RTE_PTYPE_L2_ETHER_TIMESYNC,
2111 : : RTE_PTYPE_L2_ETHER_TIMESYNC,
2112 : : RTE_PTYPE_L2_ETHER_TIMESYNC,
2113 : : RTE_PTYPE_L2_ETHER_TIMESYNC};
2114 : : const uint64_t ts_olf = RTE_MBUF_F_RX_IEEE1588_PTP |
2115 : : RTE_MBUF_F_RX_IEEE1588_TMST |
2116 : : tstamp->rx_tstamp_dynflag;
2117 : : const uint32x4_t and_mask = {0x1, 0x2, 0x4, 0x8};
2118 : : uint64x2_t ts01, ts23, mask;
2119 : : uint64_t ts[4];
2120 : : uint8_t res;
2121 : :
2122 : : /* Subtract timesync length from total pkt length. */
2123 : : f0 = vsubq_u16(f0, len_off);
2124 : : f1 = vsubq_u16(f1, len_off);
2125 : : f2 = vsubq_u16(f2, len_off);
2126 : : f3 = vsubq_u16(f3, len_off);
2127 : :
2128 : : /* Get the address of actual timestamp. */
2129 : : ts01 = vaddq_u64(mbuf01, data_off);
2130 : : ts23 = vaddq_u64(mbuf23, data_off);
2131 : : /* Load timestamp from address. */
2132 : : ts01 = vsetq_lane_u64(*(uint64_t *)vgetq_lane_u64(ts01,
2133 : : 0),
2134 : : ts01, 0);
2135 : : ts01 = vsetq_lane_u64(*(uint64_t *)vgetq_lane_u64(ts01,
2136 : : 1),
2137 : : ts01, 1);
2138 : : ts23 = vsetq_lane_u64(*(uint64_t *)vgetq_lane_u64(ts23,
2139 : : 0),
2140 : : ts23, 0);
2141 : : ts23 = vsetq_lane_u64(*(uint64_t *)vgetq_lane_u64(ts23,
2142 : : 1),
2143 : : ts23, 1);
2144 : : /* Convert from be to cpu byteorder. */
2145 : : ts01 = vrev64q_u8(ts01);
2146 : : ts23 = vrev64q_u8(ts23);
2147 : : /* Store timestamp into scalar for later use. */
2148 : : ts[0] = vgetq_lane_u64(ts01, 0);
2149 : : ts[1] = vgetq_lane_u64(ts01, 1);
2150 : : ts[2] = vgetq_lane_u64(ts23, 0);
2151 : : ts[3] = vgetq_lane_u64(ts23, 1);
2152 : :
2153 : : /* Store timestamp into dynfield. */
2154 : : *cnxk_nix_timestamp_dynfield(mbuf0, tstamp) = ts[0];
2155 : : *cnxk_nix_timestamp_dynfield(mbuf1, tstamp) = ts[1];
2156 : : *cnxk_nix_timestamp_dynfield(mbuf2, tstamp) = ts[2];
2157 : : *cnxk_nix_timestamp_dynfield(mbuf3, tstamp) = ts[3];
2158 : :
2159 : : /* Generate ptype mask to filter L2 ether timesync */
2160 : : mask = vdupq_n_u32(vgetq_lane_u32(f0, 0));
2161 : : mask = vsetq_lane_u32(vgetq_lane_u32(f1, 0), mask, 1);
2162 : : mask = vsetq_lane_u32(vgetq_lane_u32(f2, 0), mask, 2);
2163 : : mask = vsetq_lane_u32(vgetq_lane_u32(f3, 0), mask, 3);
2164 : :
2165 : : /* Match against L2 ether timesync. */
2166 : : mask = vceqq_u32(mask, ptype);
2167 : : /* Convert from vector from scalar mask */
2168 : : res = vaddvq_u32(vandq_u32(mask, and_mask));
2169 : : res &= 0xF;
2170 : :
2171 : : if (res) {
2172 : : /* Fill in the ol_flags for any packets that
2173 : : * matched.
2174 : : */
2175 : : ol_flags0 |= ((res & 0x1) ? ts_olf : 0);
2176 : : ol_flags1 |= ((res & 0x2) ? ts_olf : 0);
2177 : : ol_flags2 |= ((res & 0x4) ? ts_olf : 0);
2178 : : ol_flags3 |= ((res & 0x8) ? ts_olf : 0);
2179 : :
2180 : : /* Update Rxq timestamp with the latest
2181 : : * timestamp.
2182 : : */
2183 : : tstamp->rx_ready = 1;
2184 : : tstamp->rx_tstamp = ts[31 - rte_clz32(res)];
2185 : : }
2186 : : }
2187 : :
2188 : : /* Form rearm_data with ol_flags */
2189 : : rearm0 = vsetq_lane_u64(ol_flags0, rearm0, 1);
2190 : : rearm1 = vsetq_lane_u64(ol_flags1, rearm1, 1);
2191 : : rearm2 = vsetq_lane_u64(ol_flags2, rearm2, 1);
2192 : : rearm3 = vsetq_lane_u64(ol_flags3, rearm3, 1);
2193 : :
2194 : : /* Update rx_descriptor_fields1 */
2195 : : vst1q_u64((uint64_t *)mbuf0->rx_descriptor_fields1, f0);
2196 : : vst1q_u64((uint64_t *)mbuf1->rx_descriptor_fields1, f1);
2197 : : vst1q_u64((uint64_t *)mbuf2->rx_descriptor_fields1, f2);
2198 : : vst1q_u64((uint64_t *)mbuf3->rx_descriptor_fields1, f3);
2199 : :
2200 : : /* Update rearm_data */
2201 : : vst1q_u64((uint64_t *)mbuf0->rearm_data, rearm0);
2202 : : vst1q_u64((uint64_t *)mbuf1->rearm_data, rearm1);
2203 : : vst1q_u64((uint64_t *)mbuf2->rearm_data, rearm2);
2204 : : vst1q_u64((uint64_t *)mbuf3->rearm_data, rearm3);
2205 : :
2206 : : if (flags & NIX_RX_MULTI_SEG_F) {
2207 : : /* Multi segment is enable build mseg list for
2208 : : * individual mbufs in scalar mode.
2209 : : */
2210 : : nix_cqe_xtract_mseg((union nix_rx_parse_u *)
2211 : : (CQE_PTR_OFF(cq0, 0, 8, flags)),
2212 : : mbuf0, mbuf_initializer, cpth0, sa_base, flags);
2213 : : nix_cqe_xtract_mseg((union nix_rx_parse_u *)
2214 : : (CQE_PTR_OFF(cq0, 1, 8, flags)),
2215 : : mbuf1, mbuf_initializer, cpth1, sa_base, flags);
2216 : : nix_cqe_xtract_mseg((union nix_rx_parse_u *)
2217 : : (CQE_PTR_OFF(cq0, 2, 8, flags)),
2218 : : mbuf2, mbuf_initializer, cpth2, sa_base, flags);
2219 : : nix_cqe_xtract_mseg((union nix_rx_parse_u *)
2220 : : (CQE_PTR_OFF(cq0, 3, 8, flags)),
2221 : : mbuf3, mbuf_initializer, cpth3, sa_base, flags);
2222 : : }
2223 : :
2224 : : /* Store the mbufs to rx_pkts */
2225 : : vst1q_u64((uint64_t *)&mbufs[packets], mbuf01);
2226 : : vst1q_u64((uint64_t *)&mbufs[packets + 2], mbuf23);
2227 : :
2228 : : nix_mbuf_validate_next(mbuf0);
2229 : : nix_mbuf_validate_next(mbuf1);
2230 : : nix_mbuf_validate_next(mbuf2);
2231 : : nix_mbuf_validate_next(mbuf3);
2232 : :
2233 : : packets += NIX_DESCS_PER_LOOP;
2234 : :
2235 : : if (!(flags & NIX_RX_VWQE_F)) {
2236 : : /* Advance head pointer and packets */
2237 : : head += NIX_DESCS_PER_LOOP;
2238 : : head &= qmask;
2239 : : }
2240 : :
2241 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F) {
2242 : : /* Check if lmtline border is crossed and adjust lnum */
2243 : : if (loff > 15) {
2244 : : /* Update aura handle */
2245 : : *(uint64_t *)(laddr - 8) =
2246 : : (((uint64_t)(15 & 0x1) << 32) |
2247 : : roc_npa_aura_handle_to_aura(meta_aura));
2248 : : loff = loff - 15;
2249 : : shft += 3;
2250 : :
2251 : : lnum++;
2252 : : laddr = (uintptr_t)LMT_OFF(lbase, lnum, 8);
2253 : : /* Pick the pointer from 16th index and put it
2254 : : * at end of this new line.
2255 : : */
2256 : : *(uint64_t *)(laddr + (loff << 3) - 8) =
2257 : : *(uint64_t *)(laddr - 8);
2258 : : }
2259 : :
2260 : : /* Flush it when we are in 16th line and might
2261 : : * overflow it
2262 : : */
2263 : : if (lnum >= 15 && loff >= 12) {
2264 : : /* 16 LMT Line size m1 */
2265 : : uint64_t data = BIT_ULL(48) - 1;
2266 : :
2267 : : /* Update aura handle */
2268 : : *(uint64_t *)(laddr - 8) =
2269 : : (((uint64_t)(loff & 0x1) << 32) |
2270 : : roc_npa_aura_handle_to_aura(meta_aura));
2271 : :
2272 : : data = (data & ~(0x7UL << shft)) |
2273 : : (((uint64_t)loff >> 1) << shft);
2274 : :
2275 : : /* Send up to 16 lmt lines of pointers */
2276 : : nix_sec_flush_meta_burst(lmt_id, data, lnum + 1,
2277 : : meta_aura);
2278 : : rte_io_wmb();
2279 : : lnum = 0;
2280 : : loff = 0;
2281 : : shft = 0;
2282 : : /* First pointer starts at 8B offset */
2283 : : laddr = (uintptr_t)LMT_OFF(lbase, lnum, 8);
2284 : : }
2285 : : }
2286 : : }
2287 : :
2288 : : if (flags & NIX_RX_OFFLOAD_SECURITY_F && loff) {
2289 : : /* 16 LMT Line size m1 */
2290 : : uint64_t data = BIT_ULL(48) - 1;
2291 : :
2292 : : /* Update aura handle */
2293 : : *(uint64_t *)(laddr - 8) =
2294 : : (((uint64_t)(loff & 0x1) << 32) |
2295 : : roc_npa_aura_handle_to_aura(meta_aura));
2296 : :
2297 : : data = (data & ~(0x7UL << shft)) |
2298 : : (((uint64_t)loff >> 1) << shft);
2299 : :
2300 : : /* Send up to 16 lmt lines of pointers */
2301 : : nix_sec_flush_meta_burst(lmt_id, data, lnum + 1, meta_aura);
2302 : : if (flags & NIX_RX_VWQE_F)
2303 : : plt_io_wmb();
2304 : : }
2305 : :
2306 : : if (flags & NIX_RX_VWQE_F)
2307 : : return packets;
2308 : :
2309 : : rxq->head = head;
2310 : : rxq->available -= packets;
2311 : :
2312 : : rte_io_wmb();
2313 : : /* Free all the CQs that we've processed */
2314 : : plt_write64((rxq->wdata | packets), rxq->cq_door);
2315 : :
2316 : : if (unlikely(pkts_left))
2317 : : packets += cn10k_nix_recv_pkts(args, &mbufs[packets], pkts_left,
2318 : : flags);
2319 : :
2320 : : return packets;
2321 : : }
2322 : :
2323 : : #else
2324 : :
2325 : : static inline uint16_t
2326 : : cn10k_nix_recv_pkts_vector(void *args, struct rte_mbuf **mbufs, uint16_t pkts,
2327 : : const uint16_t flags, void *lookup_mem,
2328 : : struct cnxk_timesync_info *tstamp,
2329 : : uintptr_t lmt_base, uint64_t meta_aura)
2330 : : {
2331 : : RTE_SET_USED(args);
2332 : : RTE_SET_USED(mbufs);
2333 : : RTE_SET_USED(pkts);
2334 : : RTE_SET_USED(flags);
2335 : : RTE_SET_USED(lookup_mem);
2336 : : RTE_SET_USED(tstamp);
2337 : : RTE_SET_USED(lmt_base);
2338 : : RTE_SET_USED(meta_aura);
2339 : :
2340 : : return 0;
2341 : : }
2342 : :
2343 : : #endif
2344 : :
2345 : :
2346 : : #define RSS_F NIX_RX_OFFLOAD_RSS_F
2347 : : #define PTYPE_F NIX_RX_OFFLOAD_PTYPE_F
2348 : : #define CKSUM_F NIX_RX_OFFLOAD_CHECKSUM_F
2349 : : #define MARK_F NIX_RX_OFFLOAD_MARK_UPDATE_F
2350 : : #define TS_F NIX_RX_OFFLOAD_TSTAMP_F
2351 : : #define RX_VLAN_F NIX_RX_OFFLOAD_VLAN_STRIP_F
2352 : : #define R_SEC_F NIX_RX_OFFLOAD_SECURITY_F
2353 : :
2354 : : /* [R_SEC_F] [RX_VLAN_F] [TS] [MARK] [CKSUM] [PTYPE] [RSS] */
2355 : : #define NIX_RX_FASTPATH_MODES_0_15 \
2356 : : R(no_offload, NIX_RX_OFFLOAD_NONE) \
2357 : : R(rss, RSS_F) \
2358 : : R(ptype, PTYPE_F) \
2359 : : R(ptype_rss, PTYPE_F | RSS_F) \
2360 : : R(cksum, CKSUM_F) \
2361 : : R(cksum_rss, CKSUM_F | RSS_F) \
2362 : : R(cksum_ptype, CKSUM_F | PTYPE_F) \
2363 : : R(cksum_ptype_rss, CKSUM_F | PTYPE_F | RSS_F) \
2364 : : R(mark, MARK_F) \
2365 : : R(mark_rss, MARK_F | RSS_F) \
2366 : : R(mark_ptype, MARK_F | PTYPE_F) \
2367 : : R(mark_ptype_rss, MARK_F | PTYPE_F | RSS_F) \
2368 : : R(mark_cksum, MARK_F | CKSUM_F) \
2369 : : R(mark_cksum_rss, MARK_F | CKSUM_F | RSS_F) \
2370 : : R(mark_cksum_ptype, MARK_F | CKSUM_F | PTYPE_F) \
2371 : : R(mark_cksum_ptype_rss, MARK_F | CKSUM_F | PTYPE_F | RSS_F)
2372 : :
2373 : : #define NIX_RX_FASTPATH_MODES_16_31 \
2374 : : R(ts, TS_F) \
2375 : : R(ts_rss, TS_F | RSS_F) \
2376 : : R(ts_ptype, TS_F | PTYPE_F) \
2377 : : R(ts_ptype_rss, TS_F | PTYPE_F | RSS_F) \
2378 : : R(ts_cksum, TS_F | CKSUM_F) \
2379 : : R(ts_cksum_rss, TS_F | CKSUM_F | RSS_F) \
2380 : : R(ts_cksum_ptype, TS_F | CKSUM_F | PTYPE_F) \
2381 : : R(ts_cksum_ptype_rss, TS_F | CKSUM_F | PTYPE_F | RSS_F) \
2382 : : R(ts_mark, TS_F | MARK_F) \
2383 : : R(ts_mark_rss, TS_F | MARK_F | RSS_F) \
2384 : : R(ts_mark_ptype, TS_F | MARK_F | PTYPE_F) \
2385 : : R(ts_mark_ptype_rss, TS_F | MARK_F | PTYPE_F | RSS_F) \
2386 : : R(ts_mark_cksum, TS_F | MARK_F | CKSUM_F) \
2387 : : R(ts_mark_cksum_rss, TS_F | MARK_F | CKSUM_F | RSS_F) \
2388 : : R(ts_mark_cksum_ptype, TS_F | MARK_F | CKSUM_F | PTYPE_F) \
2389 : : R(ts_mark_cksum_ptype_rss, TS_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
2390 : :
2391 : : #define NIX_RX_FASTPATH_MODES_32_47 \
2392 : : R(vlan, RX_VLAN_F) \
2393 : : R(vlan_rss, RX_VLAN_F | RSS_F) \
2394 : : R(vlan_ptype, RX_VLAN_F | PTYPE_F) \
2395 : : R(vlan_ptype_rss, RX_VLAN_F | PTYPE_F | RSS_F) \
2396 : : R(vlan_cksum, RX_VLAN_F | CKSUM_F) \
2397 : : R(vlan_cksum_rss, RX_VLAN_F | CKSUM_F | RSS_F) \
2398 : : R(vlan_cksum_ptype, RX_VLAN_F | CKSUM_F | PTYPE_F) \
2399 : : R(vlan_cksum_ptype_rss, RX_VLAN_F | CKSUM_F | PTYPE_F | RSS_F) \
2400 : : R(vlan_mark, RX_VLAN_F | MARK_F) \
2401 : : R(vlan_mark_rss, RX_VLAN_F | MARK_F | RSS_F) \
2402 : : R(vlan_mark_ptype, RX_VLAN_F | MARK_F | PTYPE_F) \
2403 : : R(vlan_mark_ptype_rss, RX_VLAN_F | MARK_F | PTYPE_F | RSS_F) \
2404 : : R(vlan_mark_cksum, RX_VLAN_F | MARK_F | CKSUM_F) \
2405 : : R(vlan_mark_cksum_rss, RX_VLAN_F | MARK_F | CKSUM_F | RSS_F) \
2406 : : R(vlan_mark_cksum_ptype, RX_VLAN_F | MARK_F | CKSUM_F | PTYPE_F) \
2407 : : R(vlan_mark_cksum_ptype_rss, \
2408 : : RX_VLAN_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
2409 : :
2410 : : #define NIX_RX_FASTPATH_MODES_48_63 \
2411 : : R(vlan_ts, RX_VLAN_F | TS_F) \
2412 : : R(vlan_ts_rss, RX_VLAN_F | TS_F | RSS_F) \
2413 : : R(vlan_ts_ptype, RX_VLAN_F | TS_F | PTYPE_F) \
2414 : : R(vlan_ts_ptype_rss, RX_VLAN_F | TS_F | PTYPE_F | RSS_F) \
2415 : : R(vlan_ts_cksum, RX_VLAN_F | TS_F | CKSUM_F) \
2416 : : R(vlan_ts_cksum_rss, RX_VLAN_F | TS_F | CKSUM_F | RSS_F) \
2417 : : R(vlan_ts_cksum_ptype, RX_VLAN_F | TS_F | CKSUM_F | PTYPE_F) \
2418 : : R(vlan_ts_cksum_ptype_rss, \
2419 : : RX_VLAN_F | TS_F | CKSUM_F | PTYPE_F | RSS_F) \
2420 : : R(vlan_ts_mark, RX_VLAN_F | TS_F | MARK_F) \
2421 : : R(vlan_ts_mark_rss, RX_VLAN_F | TS_F | MARK_F | RSS_F) \
2422 : : R(vlan_ts_mark_ptype, RX_VLAN_F | TS_F | MARK_F | PTYPE_F) \
2423 : : R(vlan_ts_mark_ptype_rss, RX_VLAN_F | TS_F | MARK_F | PTYPE_F | RSS_F) \
2424 : : R(vlan_ts_mark_cksum, RX_VLAN_F | TS_F | MARK_F | CKSUM_F) \
2425 : : R(vlan_ts_mark_cksum_rss, RX_VLAN_F | TS_F | MARK_F | CKSUM_F | RSS_F) \
2426 : : R(vlan_ts_mark_cksum_ptype, \
2427 : : RX_VLAN_F | TS_F | MARK_F | CKSUM_F | PTYPE_F) \
2428 : : R(vlan_ts_mark_cksum_ptype_rss, \
2429 : : RX_VLAN_F | TS_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
2430 : :
2431 : : #define NIX_RX_FASTPATH_MODES_64_79 \
2432 : : R(sec, R_SEC_F) \
2433 : : R(sec_rss, R_SEC_F | RSS_F) \
2434 : : R(sec_ptype, R_SEC_F | PTYPE_F) \
2435 : : R(sec_ptype_rss, R_SEC_F | PTYPE_F | RSS_F) \
2436 : : R(sec_cksum, R_SEC_F | CKSUM_F) \
2437 : : R(sec_cksum_rss, R_SEC_F | CKSUM_F | RSS_F) \
2438 : : R(sec_cksum_ptype, R_SEC_F | CKSUM_F | PTYPE_F) \
2439 : : R(sec_cksum_ptype_rss, R_SEC_F | CKSUM_F | PTYPE_F | RSS_F) \
2440 : : R(sec_mark, R_SEC_F | MARK_F) \
2441 : : R(sec_mark_rss, R_SEC_F | MARK_F | RSS_F) \
2442 : : R(sec_mark_ptype, R_SEC_F | MARK_F | PTYPE_F) \
2443 : : R(sec_mark_ptype_rss, R_SEC_F | MARK_F | PTYPE_F | RSS_F) \
2444 : : R(sec_mark_cksum, R_SEC_F | MARK_F | CKSUM_F) \
2445 : : R(sec_mark_cksum_rss, R_SEC_F | MARK_F | CKSUM_F | RSS_F) \
2446 : : R(sec_mark_cksum_ptype, R_SEC_F | MARK_F | CKSUM_F | PTYPE_F) \
2447 : : R(sec_mark_cksum_ptype_rss, \
2448 : : R_SEC_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
2449 : :
2450 : : #define NIX_RX_FASTPATH_MODES_80_95 \
2451 : : R(sec_ts, R_SEC_F | TS_F) \
2452 : : R(sec_ts_rss, R_SEC_F | TS_F | RSS_F) \
2453 : : R(sec_ts_ptype, R_SEC_F | TS_F | PTYPE_F) \
2454 : : R(sec_ts_ptype_rss, R_SEC_F | TS_F | PTYPE_F | RSS_F) \
2455 : : R(sec_ts_cksum, R_SEC_F | TS_F | CKSUM_F) \
2456 : : R(sec_ts_cksum_rss, R_SEC_F | TS_F | CKSUM_F | RSS_F) \
2457 : : R(sec_ts_cksum_ptype, R_SEC_F | TS_F | CKSUM_F | PTYPE_F) \
2458 : : R(sec_ts_cksum_ptype_rss, R_SEC_F | TS_F | CKSUM_F | PTYPE_F | RSS_F) \
2459 : : R(sec_ts_mark, R_SEC_F | TS_F | MARK_F) \
2460 : : R(sec_ts_mark_rss, R_SEC_F | TS_F | MARK_F | RSS_F) \
2461 : : R(sec_ts_mark_ptype, R_SEC_F | TS_F | MARK_F | PTYPE_F) \
2462 : : R(sec_ts_mark_ptype_rss, R_SEC_F | TS_F | MARK_F | PTYPE_F | RSS_F) \
2463 : : R(sec_ts_mark_cksum, R_SEC_F | TS_F | MARK_F | CKSUM_F) \
2464 : : R(sec_ts_mark_cksum_rss, R_SEC_F | TS_F | MARK_F | CKSUM_F | RSS_F) \
2465 : : R(sec_ts_mark_cksum_ptype, \
2466 : : R_SEC_F | TS_F | MARK_F | CKSUM_F | PTYPE_F) \
2467 : : R(sec_ts_mark_cksum_ptype_rss, \
2468 : : R_SEC_F | TS_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
2469 : :
2470 : : #define NIX_RX_FASTPATH_MODES_96_111 \
2471 : : R(sec_vlan, R_SEC_F | RX_VLAN_F) \
2472 : : R(sec_vlan_rss, R_SEC_F | RX_VLAN_F | RSS_F) \
2473 : : R(sec_vlan_ptype, R_SEC_F | RX_VLAN_F | PTYPE_F) \
2474 : : R(sec_vlan_ptype_rss, R_SEC_F | RX_VLAN_F | PTYPE_F | RSS_F) \
2475 : : R(sec_vlan_cksum, R_SEC_F | RX_VLAN_F | CKSUM_F) \
2476 : : R(sec_vlan_cksum_rss, R_SEC_F | RX_VLAN_F | CKSUM_F | RSS_F) \
2477 : : R(sec_vlan_cksum_ptype, R_SEC_F | RX_VLAN_F | CKSUM_F | PTYPE_F) \
2478 : : R(sec_vlan_cksum_ptype_rss, \
2479 : : R_SEC_F | RX_VLAN_F | CKSUM_F | PTYPE_F | RSS_F) \
2480 : : R(sec_vlan_mark, R_SEC_F | RX_VLAN_F | MARK_F) \
2481 : : R(sec_vlan_mark_rss, R_SEC_F | RX_VLAN_F | MARK_F | RSS_F) \
2482 : : R(sec_vlan_mark_ptype, R_SEC_F | RX_VLAN_F | MARK_F | PTYPE_F) \
2483 : : R(sec_vlan_mark_ptype_rss, \
2484 : : R_SEC_F | RX_VLAN_F | MARK_F | PTYPE_F | RSS_F) \
2485 : : R(sec_vlan_mark_cksum, R_SEC_F | RX_VLAN_F | MARK_F | CKSUM_F) \
2486 : : R(sec_vlan_mark_cksum_rss, \
2487 : : R_SEC_F | RX_VLAN_F | MARK_F | CKSUM_F | RSS_F) \
2488 : : R(sec_vlan_mark_cksum_ptype, \
2489 : : R_SEC_F | RX_VLAN_F | MARK_F | CKSUM_F | PTYPE_F) \
2490 : : R(sec_vlan_mark_cksum_ptype_rss, \
2491 : : R_SEC_F | RX_VLAN_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
2492 : :
2493 : : #define NIX_RX_FASTPATH_MODES_112_127 \
2494 : : R(sec_vlan_ts, R_SEC_F | RX_VLAN_F | TS_F) \
2495 : : R(sec_vlan_ts_rss, R_SEC_F | RX_VLAN_F | TS_F | RSS_F) \
2496 : : R(sec_vlan_ts_ptype, R_SEC_F | RX_VLAN_F | TS_F | PTYPE_F) \
2497 : : R(sec_vlan_ts_ptype_rss, R_SEC_F | RX_VLAN_F | TS_F | PTYPE_F | RSS_F) \
2498 : : R(sec_vlan_ts_cksum, R_SEC_F | RX_VLAN_F | TS_F | CKSUM_F) \
2499 : : R(sec_vlan_ts_cksum_rss, R_SEC_F | RX_VLAN_F | TS_F | CKSUM_F | RSS_F) \
2500 : : R(sec_vlan_ts_cksum_ptype, \
2501 : : R_SEC_F | RX_VLAN_F | TS_F | CKSUM_F | PTYPE_F) \
2502 : : R(sec_vlan_ts_cksum_ptype_rss, \
2503 : : R_SEC_F | RX_VLAN_F | TS_F | CKSUM_F | PTYPE_F | RSS_F) \
2504 : : R(sec_vlan_ts_mark, R_SEC_F | RX_VLAN_F | TS_F | MARK_F) \
2505 : : R(sec_vlan_ts_mark_rss, R_SEC_F | RX_VLAN_F | TS_F | MARK_F | RSS_F) \
2506 : : R(sec_vlan_ts_mark_ptype, \
2507 : : R_SEC_F | RX_VLAN_F | TS_F | MARK_F | PTYPE_F) \
2508 : : R(sec_vlan_ts_mark_ptype_rss, \
2509 : : R_SEC_F | RX_VLAN_F | TS_F | MARK_F | PTYPE_F | RSS_F) \
2510 : : R(sec_vlan_ts_mark_cksum, \
2511 : : R_SEC_F | RX_VLAN_F | TS_F | MARK_F | CKSUM_F) \
2512 : : R(sec_vlan_ts_mark_cksum_rss, \
2513 : : R_SEC_F | RX_VLAN_F | TS_F | MARK_F | CKSUM_F | RSS_F) \
2514 : : R(sec_vlan_ts_mark_cksum_ptype, \
2515 : : R_SEC_F | RX_VLAN_F | TS_F | MARK_F | CKSUM_F | PTYPE_F) \
2516 : : R(sec_vlan_ts_mark_cksum_ptype_rss, \
2517 : : R_SEC_F | RX_VLAN_F | TS_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
2518 : :
2519 : :
2520 : : #define NIX_RX_FASTPATH_MODES \
2521 : : NIX_RX_FASTPATH_MODES_0_15 \
2522 : : NIX_RX_FASTPATH_MODES_16_31 \
2523 : : NIX_RX_FASTPATH_MODES_32_47 \
2524 : : NIX_RX_FASTPATH_MODES_48_63 \
2525 : : NIX_RX_FASTPATH_MODES_64_79 \
2526 : : NIX_RX_FASTPATH_MODES_80_95 \
2527 : : NIX_RX_FASTPATH_MODES_96_111 \
2528 : : NIX_RX_FASTPATH_MODES_112_127 \
2529 : :
2530 : : #define R(name, flags) \
2531 : : uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_##name( \
2532 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
2533 : : uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_mseg_##name( \
2534 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
2535 : : uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_vec_##name( \
2536 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
2537 : : uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_vec_mseg_##name( \
2538 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
2539 : : uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_reas_##name( \
2540 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
2541 : : uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_reas_mseg_##name(\
2542 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
2543 : : uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_reas_vec_##name( \
2544 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
2545 : : uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_reas_vec_mseg_##name( \
2546 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts);
2547 : :
2548 : : NIX_RX_FASTPATH_MODES
2549 : : #undef R
2550 : :
2551 : : #define NIX_RX_RECV(fn, flags) \
2552 : : uint16_t __rte_noinline __rte_hot fn( \
2553 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts) \
2554 : : { \
2555 : : return cn10k_nix_recv_pkts(rx_queue, rx_pkts, pkts, (flags)); \
2556 : : }
2557 : :
2558 : : #define NIX_RX_RECV_MSEG(fn, flags) NIX_RX_RECV(fn, flags | NIX_RX_MULTI_SEG_F)
2559 : :
2560 : : #define NIX_RX_RECV_VEC(fn, flags) \
2561 : : uint16_t __rte_noinline __rte_hot fn( \
2562 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts) \
2563 : : { \
2564 : : return cn10k_nix_recv_pkts_vector(rx_queue, rx_pkts, pkts, \
2565 : : (flags), NULL, NULL, 0, 0); \
2566 : : }
2567 : :
2568 : : #define NIX_RX_RECV_VEC_MSEG(fn, flags) \
2569 : : NIX_RX_RECV_VEC(fn, flags | NIX_RX_MULTI_SEG_F)
2570 : :
2571 : : uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_all_offload(void *rx_queue,
2572 : : struct rte_mbuf **rx_pkts,
2573 : : uint16_t pkts);
2574 : :
2575 : : uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_vec_all_offload(void *rx_queue,
2576 : : struct rte_mbuf **rx_pkts,
2577 : : uint16_t pkts);
2578 : :
2579 : : uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_all_offload_tst(void *rx_queue,
2580 : : struct rte_mbuf **rx_pkts,
2581 : : uint16_t pkts);
2582 : :
2583 : : uint16_t __rte_noinline __rte_hot cn10k_nix_recv_pkts_vec_all_offload_tst(void *rx_queue,
2584 : : struct rte_mbuf **rx_pkts,
2585 : : uint16_t pkts);
2586 : :
2587 : : #endif /* __CN10K_RX_H__ */
|