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