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