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 uint64_t
86 : : nix_clear_data_off(uint64_t oldval)
87 : : {
88 : : union mbuf_initializer mbuf_init = {.value = oldval};
89 : :
90 : : mbuf_init.fields.data_off = 0;
91 : : return mbuf_init.value;
92 : : }
93 : :
94 : : static __rte_always_inline struct rte_mbuf *
95 : : nix_get_mbuf_from_cqe(void *cq, const uint64_t data_off)
96 : : {
97 : : rte_iova_t buff;
98 : :
99 : : /* Skip CQE, NIX_RX_PARSE_S and SG HDR(9 DWORDs) and peek buff addr */
100 : : buff = *((rte_iova_t *)((uint64_t *)cq + 9));
101 : : return (struct rte_mbuf *)(buff - data_off);
102 : : }
103 : :
104 : : static __rte_always_inline uint32_t
105 : : nix_ptype_get(const void *const lookup_mem, const uint64_t in)
106 : : {
107 : : const uint16_t *const ptype = lookup_mem;
108 : 0 : const uint16_t lh_lg_lf = (in & 0xFFF0000000000000) >> 52;
109 : 0 : const uint16_t tu_l2 = ptype[(in & 0x000FFFF000000000) >> 36];
110 : 0 : const uint16_t il4_tu = ptype[PTYPE_NON_TUNNEL_ARRAY_SZ + lh_lg_lf];
111 : :
112 : 0 : return (il4_tu << PTYPE_NON_TUNNEL_WIDTH) | tu_l2;
113 : : }
114 : :
115 : : static __rte_always_inline uint32_t
116 : : nix_rx_olflags_get(const void *const lookup_mem, const uint64_t in)
117 : : {
118 : : const uint32_t *const ol_flags =
119 : : (const uint32_t *)((const uint8_t *)lookup_mem + PTYPE_ARRAY_SZ);
120 : :
121 : 0 : return ol_flags[(in & 0xfff00000) >> 20];
122 : : }
123 : :
124 : : static inline uint64_t
125 : 0 : nix_update_match_id(const uint16_t match_id, uint64_t ol_flags, struct rte_mbuf *mbuf)
126 : : {
127 : : /* There is no separate bit to check match_id
128 : : * is valid or not? and no flag to identify it is an
129 : : * RTE_FLOW_ACTION_TYPE_FLAG vs RTE_FLOW_ACTION_TYPE_MARK
130 : : * action. The former case addressed through 0 being invalid
131 : : * value and inc/dec match_id pair when MARK is activated.
132 : : * The later case addressed through defining
133 : : * CNXK_FLOW_MARK_DEFAULT as value for
134 : : * RTE_FLOW_ACTION_TYPE_MARK.
135 : : * This would translate to not use
136 : : * CNXK_FLOW_ACTION_FLAG_DEFAULT - 1 and
137 : : * CNXK_FLOW_ACTION_FLAG_DEFAULT for match_id.
138 : : * i.e valid mark_id's are from
139 : : * 0 to CNXK_FLOW_ACTION_FLAG_DEFAULT - 2
140 : : */
141 [ # # ]: 0 : if (likely(match_id)) {
142 : 0 : ol_flags |= RTE_MBUF_F_RX_FDIR;
143 [ # # ]: 0 : if (match_id != CNXK_FLOW_ACTION_FLAG_DEFAULT) {
144 : 0 : ol_flags |= RTE_MBUF_F_RX_FDIR_ID;
145 : 0 : mbuf->hash.fdir.hi = match_id - 1;
146 : : }
147 : : }
148 : :
149 : 0 : return ol_flags;
150 : : }
151 : :
152 : : static __rte_always_inline void
153 : : nix_cqe_xtract_mseg(const union nix_rx_parse_u *rx, struct rte_mbuf *mbuf, uint64_t rearm,
154 : : uintptr_t cpth, uintptr_t sa_base, const uint16_t flags)
155 : : {
156 : : const rte_iova_t *iova_list;
157 : : uint16_t later_skip = 0;
158 : : struct rte_mbuf *head;
159 : : const rte_iova_t *eol;
160 : : uint8_t nb_segs;
161 : : uint16_t sg_len;
162 : : int64_t len;
163 : : uint64_t sg;
164 : : uintptr_t p;
165 : :
166 : : (void)cpth;
167 : : (void)sa_base;
168 : :
169 : 0 : sg = *(const uint64_t *)(rx + 1);
170 : 0 : nb_segs = (sg >> 48) & 0x3;
171 : :
172 : 0 : if (nb_segs == 1)
173 : : return;
174 : :
175 : 0 : len = rx->pkt_lenm1 + 1;
176 : :
177 : 0 : mbuf->pkt_len = len - (flags & NIX_RX_OFFLOAD_TSTAMP_F ? CNXK_NIX_TIMESYNC_RX_OFFSET : 0);
178 : 0 : mbuf->nb_segs = nb_segs;
179 : : head = mbuf;
180 : 0 : mbuf->data_len =
181 : 0 : (sg & 0xFFFF) - (flags & NIX_RX_OFFLOAD_TSTAMP_F ? CNXK_NIX_TIMESYNC_RX_OFFSET : 0);
182 : 0 : eol = ((const rte_iova_t *)(rx + 1) + ((rx->desc_sizem1 + 1) << 1));
183 : :
184 : : len -= mbuf->data_len;
185 : 0 : sg = sg >> 16;
186 : : /* Skip SG_S and first IOVA*/
187 : 0 : iova_list = ((const rte_iova_t *)(rx + 1)) + 2;
188 : 0 : nb_segs--;
189 : :
190 : 0 : later_skip = (uintptr_t)mbuf->buf_addr - (uintptr_t)mbuf;
191 : :
192 [ # # # # : 0 : while (nb_segs) {
# # # # ]
193 : 0 : mbuf->next = (struct rte_mbuf *)(*iova_list - later_skip);
194 : : mbuf = mbuf->next;
195 : :
196 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
197 : :
198 : 0 : sg_len = sg & 0XFFFF;
199 : :
200 : 0 : mbuf->data_len = sg_len;
201 : 0 : sg = sg >> 16;
202 : : p = (uintptr_t)&mbuf->rearm_data;
203 : 0 : *(uint64_t *)p = rearm & ~0xFFFF;
204 : 0 : nb_segs--;
205 : 0 : iova_list++;
206 : :
207 [ # # # # : 0 : if (!nb_segs && (iova_list + 1 < eol)) {
# # # # #
# # # # #
# # ]
208 : 0 : sg = *(const uint64_t *)(iova_list);
209 : 0 : nb_segs = (sg >> 48) & 0x3;
210 : 0 : head->nb_segs += nb_segs;
211 : : iova_list = (const rte_iova_t *)(iova_list + 1);
212 : : }
213 : : }
214 : : }
215 : :
216 : : static __rte_always_inline void
217 : : cn20k_nix_cqe_to_mbuf(const struct nix_cqe_hdr_s *cq, const uint32_t tag, struct rte_mbuf *mbuf,
218 : : const void *lookup_mem, const uint64_t val, const uintptr_t cpth,
219 : : const uintptr_t sa_base, const uint16_t flag)
220 : : {
221 : : const union nix_rx_parse_u *rx = (const union nix_rx_parse_u *)((const uint64_t *)cq + 1);
222 : 0 : const uint64_t w1 = *(const uint64_t *)rx;
223 : 0 : uint16_t len = rx->pkt_lenm1 + 1;
224 : : uint64_t ol_flags = 0;
225 : : uintptr_t p;
226 : :
227 : : if (flag & NIX_RX_OFFLOAD_PTYPE_F)
228 : 0 : mbuf->packet_type = nix_ptype_get(lookup_mem, w1);
229 : : else
230 : 0 : mbuf->packet_type = 0;
231 : :
232 : : if (flag & NIX_RX_OFFLOAD_RSS_F) {
233 : 0 : mbuf->hash.rss = tag;
234 : : ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
235 : : }
236 : :
237 : : /* Skip rx ol flags extraction for Security packets */
238 : 0 : ol_flags |= (uint64_t)nix_rx_olflags_get(lookup_mem, w1);
239 : :
240 : : if (flag & NIX_RX_OFFLOAD_VLAN_STRIP_F) {
241 [ # # # # : 0 : if (rx->vtag0_gone) {
# # # # ]
242 : 0 : ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
243 : 0 : mbuf->vlan_tci = rx->vtag0_tci;
244 : : }
245 [ # # # # : 0 : if (rx->vtag1_gone) {
# # # # ]
246 : 0 : ol_flags |= RTE_MBUF_F_RX_QINQ | RTE_MBUF_F_RX_QINQ_STRIPPED;
247 : 0 : mbuf->vlan_tci_outer = rx->vtag1_tci;
248 : : }
249 : : }
250 : :
251 : : if (flag & NIX_RX_OFFLOAD_MARK_UPDATE_F)
252 : 0 : ol_flags = nix_update_match_id(rx->match_id, ol_flags, mbuf);
253 : :
254 : 0 : mbuf->ol_flags = ol_flags;
255 : 0 : mbuf->pkt_len = len;
256 : 0 : mbuf->data_len = len;
257 : : p = (uintptr_t)&mbuf->rearm_data;
258 [ # # # # : 0 : *(uint64_t *)p = val;
# # # # ]
259 : :
260 : : if (flag & NIX_RX_MULTI_SEG_F)
261 : : /*
262 : : * For multi segment packets, mbuf length correction according
263 : : * to Rx timestamp length will be handled later during
264 : : * timestamp data process.
265 : : * Hence, timestamp flag argument is not required.
266 : : */
267 : : nix_cqe_xtract_mseg(rx, mbuf, val, cpth, sa_base, flag & ~NIX_RX_OFFLOAD_TSTAMP_F);
268 : : }
269 : :
270 : : static inline uint16_t
271 : : nix_rx_nb_pkts(struct cn20k_eth_rxq *rxq, const uint64_t wdata, const uint16_t pkts,
272 : : const uint32_t qmask)
273 : : {
274 : : uint32_t available = rxq->available;
275 : :
276 : : /* Update the available count if cached value is not enough */
277 : : if (unlikely(available < pkts)) {
278 : : uint64_t reg, head, tail;
279 : :
280 : : /* Use LDADDA version to avoid reorder */
281 : : reg = roc_atomic64_add_sync(wdata, rxq->cq_status);
282 : : /* CQ_OP_STATUS operation error */
283 : : if (reg & BIT_ULL(NIX_CQ_OP_STAT_OP_ERR) || reg & BIT_ULL(NIX_CQ_OP_STAT_CQ_ERR))
284 : : return 0;
285 : :
286 : : tail = reg & 0xFFFFF;
287 : : head = (reg >> 20) & 0xFFFFF;
288 : : if (tail < head)
289 : : available = tail - head + qmask + 1;
290 : : else
291 : : available = tail - head;
292 : :
293 : : rxq->available = available;
294 : : }
295 : :
296 : : return RTE_MIN(pkts, available);
297 : : }
298 : :
299 : : static __rte_always_inline void
300 : : cn20k_nix_mbuf_to_tstamp(struct rte_mbuf *mbuf, struct cnxk_timesync_info *tstamp,
301 : : const uint8_t ts_enable, uint64_t *tstamp_ptr)
302 : : {
303 : : if (ts_enable) {
304 : 0 : mbuf->pkt_len -= CNXK_NIX_TIMESYNC_RX_OFFSET;
305 : 0 : mbuf->data_len -= CNXK_NIX_TIMESYNC_RX_OFFSET;
306 : :
307 : : /* Reading the rx timestamp inserted by CGX, viz at
308 : : * starting of the packet data.
309 : : */
310 : 0 : *tstamp_ptr = ((*tstamp_ptr >> 32) * NSEC_PER_SEC) + (*tstamp_ptr & 0xFFFFFFFFUL);
311 [ # # ]: 0 : *cnxk_nix_timestamp_dynfield(mbuf, tstamp) = rte_be_to_cpu_64(*tstamp_ptr);
312 : : /* RTE_MBUF_F_RX_IEEE1588_TMST flag needs to be set only in case
313 : : * PTP packets are received.
314 : : */
315 [ # # ]: 0 : if (mbuf->packet_type == RTE_PTYPE_L2_ETHER_TIMESYNC) {
316 : 0 : tstamp->rx_tstamp = *cnxk_nix_timestamp_dynfield(mbuf, tstamp);
317 : 0 : tstamp->rx_ready = 1;
318 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_IEEE1588_PTP | RTE_MBUF_F_RX_IEEE1588_TMST |
319 : 0 : tstamp->rx_tstamp_dynflag;
320 : : }
321 : : }
322 : : }
323 : :
324 : : static __rte_always_inline uint16_t
325 : : cn20k_nix_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts, const uint16_t flags)
326 : : {
327 : : struct cn20k_eth_rxq *rxq = rx_queue;
328 : : const uint64_t mbuf_init = rxq->mbuf_initializer;
329 : : const void *lookup_mem = rxq->lookup_mem;
330 : : const uint64_t data_off = rxq->data_off;
331 : : const uintptr_t desc = rxq->desc;
332 : : const uint64_t wdata = rxq->wdata;
333 : : const uint32_t qmask = rxq->qmask;
334 : : uint16_t packets = 0, nb_pkts;
335 : : uint32_t head = rxq->head;
336 : : struct nix_cqe_hdr_s *cq;
337 : : struct rte_mbuf *mbuf;
338 : : uint64_t sa_base = 0;
339 : : uintptr_t cpth = 0;
340 : :
341 : : nb_pkts = nix_rx_nb_pkts(rxq, wdata, pkts, qmask);
342 : :
343 : : while (packets < nb_pkts) {
344 : : /* Prefetch N desc ahead */
345 : : rte_prefetch_non_temporal((void *)(desc + (CQE_SZ((head + 2) & qmask))));
346 : : cq = (struct nix_cqe_hdr_s *)(desc + CQE_SZ(head));
347 : :
348 : : mbuf = nix_get_mbuf_from_cqe(cq, data_off);
349 : :
350 : : /* Mark mempool obj as "get" as it is alloc'ed by NIX */
351 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
352 : :
353 : : cn20k_nix_cqe_to_mbuf(cq, cq->tag, mbuf, lookup_mem, mbuf_init, cpth, sa_base,
354 : : flags);
355 : : cn20k_nix_mbuf_to_tstamp(mbuf, rxq->tstamp, (flags & NIX_RX_OFFLOAD_TSTAMP_F),
356 : : (uint64_t *)((uint8_t *)mbuf + data_off));
357 : : rx_pkts[packets++] = mbuf;
358 : : roc_prefetch_store_keep(mbuf);
359 : : head++;
360 : : head &= qmask;
361 : : }
362 : :
363 : : rxq->head = head;
364 : : rxq->available -= nb_pkts;
365 : :
366 : : /* Free all the CQs that we've processed */
367 : : plt_write64((wdata | nb_pkts), rxq->cq_door);
368 : :
369 : : return nb_pkts;
370 : : }
371 : :
372 : : static __rte_always_inline uint16_t
373 : : cn20k_nix_flush_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts,
374 : : const uint16_t flags)
375 : : {
376 : : struct cn20k_eth_rxq *rxq = rx_queue;
377 : : const uint64_t mbuf_init = rxq->mbuf_initializer;
378 : : const void *lookup_mem = rxq->lookup_mem;
379 : : const uint64_t data_off = rxq->data_off;
380 : : const uint64_t wdata = rxq->wdata;
381 : : const uint32_t qmask = rxq->qmask;
382 : : const uintptr_t desc = rxq->desc;
383 : : uint16_t packets = 0, nb_pkts;
384 : : uint16_t lmt_id __rte_unused;
385 : : uint32_t head = rxq->head;
386 : : struct nix_cqe_hdr_s *cq;
387 : : struct rte_mbuf *mbuf;
388 : : uint64_t sa_base = 0;
389 : : uintptr_t cpth = 0;
390 : :
391 : : nb_pkts = nix_rx_nb_pkts(rxq, wdata, pkts, qmask);
392 : :
393 : : while (packets < nb_pkts) {
394 : : /* Prefetch N desc ahead */
395 : : rte_prefetch_non_temporal((void *)(desc + (CQE_SZ((head + 2) & qmask))));
396 : : cq = (struct nix_cqe_hdr_s *)(desc + CQE_SZ(head));
397 : :
398 : : mbuf = nix_get_mbuf_from_cqe(cq, data_off);
399 : :
400 : : /* Mark mempool obj as "get" as it is alloc'ed by NIX */
401 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf->pool, (void **)&mbuf, 1, 1);
402 : :
403 : : cn20k_nix_cqe_to_mbuf(cq, cq->tag, mbuf, lookup_mem, mbuf_init, cpth, sa_base,
404 : : flags);
405 : : cn20k_nix_mbuf_to_tstamp(mbuf, rxq->tstamp, (flags & NIX_RX_OFFLOAD_TSTAMP_F),
406 : : (uint64_t *)((uint8_t *)mbuf + data_off));
407 : : rx_pkts[packets++] = mbuf;
408 : : roc_prefetch_store_keep(mbuf);
409 : : head++;
410 : : head &= qmask;
411 : : }
412 : :
413 : : rxq->head = head;
414 : : rxq->available -= nb_pkts;
415 : :
416 : : /* Free all the CQs that we've processed */
417 : : plt_write64((wdata | nb_pkts), rxq->cq_door);
418 : :
419 : : return nb_pkts;
420 : : }
421 : :
422 : : #if defined(RTE_ARCH_ARM64)
423 : :
424 : : static __rte_always_inline uint64_t
425 : : nix_vlan_update(const uint64_t w2, uint64_t ol_flags, uint8x16_t *f)
426 : : {
427 : : if (w2 & BIT_ULL(21) /* vtag0_gone */) {
428 : : ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
429 : : *f = vsetq_lane_u16((uint16_t)(w2 >> 32), *f, 5);
430 : : }
431 : :
432 : : return ol_flags;
433 : : }
434 : :
435 : : static __rte_always_inline uint64_t
436 : : nix_qinq_update(const uint64_t w2, uint64_t ol_flags, struct rte_mbuf *mbuf)
437 : : {
438 : : if (w2 & BIT_ULL(23) /* vtag1_gone */) {
439 : : ol_flags |= RTE_MBUF_F_RX_QINQ | RTE_MBUF_F_RX_QINQ_STRIPPED;
440 : : mbuf->vlan_tci_outer = (uint16_t)(w2 >> 48);
441 : : }
442 : :
443 : : return ol_flags;
444 : : }
445 : :
446 : : #define NIX_PUSH_META_TO_FREE(_mbuf, _laddr, _loff_p) \
447 : : do { \
448 : : *(uint64_t *)((_laddr) + (*(_loff_p) << 3)) = (uint64_t)_mbuf; \
449 : : *(_loff_p) = *(_loff_p) + 1; \
450 : : /* Mark meta mbuf as put */ \
451 : : RTE_MEMPOOL_CHECK_COOKIES(_mbuf->pool, (void **)&_mbuf, 1, 0); \
452 : : } while (0)
453 : :
454 : : static __rte_always_inline uint16_t
455 : : cn20k_nix_recv_pkts_vector(void *args, struct rte_mbuf **mbufs, uint16_t pkts, const uint16_t flags,
456 : : void *lookup_mem, struct cnxk_timesync_info *tstamp, uintptr_t lmt_base,
457 : : uint64_t meta_aura)
458 : : {
459 : : struct cn20k_eth_rxq *rxq = args;
460 : : const uint64_t mbuf_initializer =
461 : : (flags & NIX_RX_VWQE_F) ? *(uint64_t *)args : rxq->mbuf_initializer;
462 : : const uint64x2_t data_off = flags & NIX_RX_VWQE_F ? vdupq_n_u64(RTE_PKTMBUF_HEADROOM) :
463 : : vdupq_n_u64(rxq->data_off);
464 : : const uint32_t qmask = flags & NIX_RX_VWQE_F ? 0 : rxq->qmask;
465 : : const uint64_t wdata = flags & NIX_RX_VWQE_F ? 0 : rxq->wdata;
466 : : const uintptr_t desc = flags & NIX_RX_VWQE_F ? 0 : rxq->desc;
467 : : uint64x2_t cq0_w8, cq1_w8, cq2_w8, cq3_w8, mbuf01, mbuf23;
468 : : uintptr_t cpth0 = 0, cpth1 = 0, cpth2 = 0, cpth3 = 0;
469 : : uint64_t ol_flags0, ol_flags1, ol_flags2, ol_flags3;
470 : : uint64x2_t rearm0 = vdupq_n_u64(mbuf_initializer);
471 : : uint64x2_t rearm1 = vdupq_n_u64(mbuf_initializer);
472 : : uint64x2_t rearm2 = vdupq_n_u64(mbuf_initializer);
473 : : uint64x2_t rearm3 = vdupq_n_u64(mbuf_initializer);
474 : : struct rte_mbuf *mbuf0, *mbuf1, *mbuf2, *mbuf3;
475 : : uint8x16_t f0, f1, f2, f3;
476 : : uintptr_t sa_base = 0;
477 : : uint16_t packets = 0;
478 : : uint16_t pkts_left;
479 : : uint32_t head;
480 : : uintptr_t cq0;
481 : :
482 : : (void)lmt_base;
483 : : (void)meta_aura;
484 : :
485 : : if (!(flags & NIX_RX_VWQE_F)) {
486 : : lookup_mem = rxq->lookup_mem;
487 : : head = rxq->head;
488 : :
489 : : pkts = nix_rx_nb_pkts(rxq, wdata, pkts, qmask);
490 : : pkts_left = pkts & (NIX_DESCS_PER_LOOP - 1);
491 : : /* Packets has to be floor-aligned to NIX_DESCS_PER_LOOP */
492 : : pkts = RTE_ALIGN_FLOOR(pkts, NIX_DESCS_PER_LOOP);
493 : : if (flags & NIX_RX_OFFLOAD_TSTAMP_F)
494 : : tstamp = rxq->tstamp;
495 : :
496 : : cq0 = desc + CQE_SZ(head);
497 : : rte_prefetch0(CQE_PTR_OFF(cq0, 0, 64, flags));
498 : : rte_prefetch0(CQE_PTR_OFF(cq0, 1, 64, flags));
499 : : rte_prefetch0(CQE_PTR_OFF(cq0, 2, 64, flags));
500 : : rte_prefetch0(CQE_PTR_OFF(cq0, 3, 64, flags));
501 : : } else {
502 : : RTE_SET_USED(head);
503 : : }
504 : :
505 : : while (packets < pkts) {
506 : : if (!(flags & NIX_RX_VWQE_F)) {
507 : : /* Exit loop if head is about to wrap and become
508 : : * unaligned.
509 : : */
510 : : if (((head + NIX_DESCS_PER_LOOP - 1) & qmask) < NIX_DESCS_PER_LOOP) {
511 : : pkts_left += (pkts - packets);
512 : : break;
513 : : }
514 : :
515 : : cq0 = desc + CQE_SZ(head);
516 : : } else {
517 : : cq0 = (uintptr_t)&mbufs[packets];
518 : : }
519 : :
520 : : if (flags & NIX_RX_VWQE_F) {
521 : : if (pkts - packets > 4) {
522 : : rte_prefetch_non_temporal(CQE_PTR_OFF(cq0, 4, 0, flags));
523 : : rte_prefetch_non_temporal(CQE_PTR_OFF(cq0, 5, 0, flags));
524 : : rte_prefetch_non_temporal(CQE_PTR_OFF(cq0, 6, 0, flags));
525 : : rte_prefetch_non_temporal(CQE_PTR_OFF(cq0, 7, 0, flags));
526 : :
527 : : if (likely(pkts - packets > 8)) {
528 : : rte_prefetch1(CQE_PTR_OFF(cq0, 8, 0, flags));
529 : : rte_prefetch1(CQE_PTR_OFF(cq0, 9, 0, flags));
530 : : rte_prefetch1(CQE_PTR_OFF(cq0, 10, 0, flags));
531 : : rte_prefetch1(CQE_PTR_OFF(cq0, 11, 0, flags));
532 : : if (pkts - packets > 12) {
533 : : rte_prefetch1(CQE_PTR_OFF(cq0, 12, 0, flags));
534 : : rte_prefetch1(CQE_PTR_OFF(cq0, 13, 0, flags));
535 : : rte_prefetch1(CQE_PTR_OFF(cq0, 14, 0, flags));
536 : : rte_prefetch1(CQE_PTR_OFF(cq0, 15, 0, flags));
537 : : }
538 : : }
539 : :
540 : : rte_prefetch0(CQE_PTR_DIFF(cq0, 4, RTE_PKTMBUF_HEADROOM, flags));
541 : : rte_prefetch0(CQE_PTR_DIFF(cq0, 5, RTE_PKTMBUF_HEADROOM, flags));
542 : : rte_prefetch0(CQE_PTR_DIFF(cq0, 6, RTE_PKTMBUF_HEADROOM, flags));
543 : : rte_prefetch0(CQE_PTR_DIFF(cq0, 7, RTE_PKTMBUF_HEADROOM, flags));
544 : :
545 : : if (likely(pkts - packets > 8)) {
546 : : rte_prefetch0(
547 : : CQE_PTR_DIFF(cq0, 8, RTE_PKTMBUF_HEADROOM, flags));
548 : : rte_prefetch0(
549 : : CQE_PTR_DIFF(cq0, 9, RTE_PKTMBUF_HEADROOM, flags));
550 : : rte_prefetch0(
551 : : CQE_PTR_DIFF(cq0, 10, RTE_PKTMBUF_HEADROOM, flags));
552 : : rte_prefetch0(
553 : : CQE_PTR_DIFF(cq0, 11, RTE_PKTMBUF_HEADROOM, flags));
554 : : }
555 : : }
556 : : } else {
557 : : if (pkts - packets > 8) {
558 : : if (flags) {
559 : : rte_prefetch0(CQE_PTR_OFF(cq0, 8, 0, flags));
560 : : rte_prefetch0(CQE_PTR_OFF(cq0, 9, 0, flags));
561 : : rte_prefetch0(CQE_PTR_OFF(cq0, 10, 0, flags));
562 : : rte_prefetch0(CQE_PTR_OFF(cq0, 11, 0, flags));
563 : : }
564 : : rte_prefetch0(CQE_PTR_OFF(cq0, 8, 64, flags));
565 : : rte_prefetch0(CQE_PTR_OFF(cq0, 9, 64, flags));
566 : : rte_prefetch0(CQE_PTR_OFF(cq0, 10, 64, flags));
567 : : rte_prefetch0(CQE_PTR_OFF(cq0, 11, 64, flags));
568 : : }
569 : : }
570 : :
571 : : if (!(flags & NIX_RX_VWQE_F)) {
572 : : /* Get NIX_RX_SG_S for size and buffer pointer */
573 : : cq0_w8 = vld1q_u64(CQE_PTR_OFF(cq0, 0, 64, flags));
574 : : cq1_w8 = vld1q_u64(CQE_PTR_OFF(cq0, 1, 64, flags));
575 : : cq2_w8 = vld1q_u64(CQE_PTR_OFF(cq0, 2, 64, flags));
576 : : cq3_w8 = vld1q_u64(CQE_PTR_OFF(cq0, 3, 64, flags));
577 : :
578 : : /* Extract mbuf from NIX_RX_SG_S */
579 : : mbuf01 = vzip2q_u64(cq0_w8, cq1_w8);
580 : : mbuf23 = vzip2q_u64(cq2_w8, cq3_w8);
581 : : mbuf01 = vqsubq_u64(mbuf01, data_off);
582 : : mbuf23 = vqsubq_u64(mbuf23, data_off);
583 : : } else {
584 : : mbuf01 = vsubq_u64(vld1q_u64((uint64_t *)cq0),
585 : : vdupq_n_u64(sizeof(struct rte_mbuf)));
586 : : mbuf23 = vsubq_u64(vld1q_u64((uint64_t *)(cq0 + 16)),
587 : : vdupq_n_u64(sizeof(struct rte_mbuf)));
588 : : }
589 : :
590 : : /* Move mbufs to scalar registers for future use */
591 : : mbuf0 = (struct rte_mbuf *)vgetq_lane_u64(mbuf01, 0);
592 : : mbuf1 = (struct rte_mbuf *)vgetq_lane_u64(mbuf01, 1);
593 : : mbuf2 = (struct rte_mbuf *)vgetq_lane_u64(mbuf23, 0);
594 : : mbuf3 = (struct rte_mbuf *)vgetq_lane_u64(mbuf23, 1);
595 : :
596 : : /* Mark mempool obj as "get" as it is alloc'ed by NIX */
597 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf0->pool, (void **)&mbuf0, 1, 1);
598 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf1->pool, (void **)&mbuf1, 1, 1);
599 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf2->pool, (void **)&mbuf2, 1, 1);
600 : : RTE_MEMPOOL_CHECK_COOKIES(mbuf3->pool, (void **)&mbuf3, 1, 1);
601 : :
602 : : if (!(flags & NIX_RX_VWQE_F)) {
603 : : /* Mask to get packet len from NIX_RX_SG_S */
604 : : const uint8x16_t shuf_msk = {
605 : : 0xFF, 0xFF, /* pkt_type set as unknown */
606 : : 0xFF, 0xFF, /* pkt_type set as unknown */
607 : : 0, 1, /* octet 1~0, low 16 bits pkt_len */
608 : : 0xFF, 0xFF, /* skip high 16it pkt_len, zero out */
609 : : 0, 1, /* octet 1~0, 16 bits data_len */
610 : : 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
611 : :
612 : : /* Form the rx_descriptor_fields1 with pkt_len and data_len */
613 : : f0 = vqtbl1q_u8(cq0_w8, shuf_msk);
614 : : f1 = vqtbl1q_u8(cq1_w8, shuf_msk);
615 : : f2 = vqtbl1q_u8(cq2_w8, shuf_msk);
616 : : f3 = vqtbl1q_u8(cq3_w8, shuf_msk);
617 : : }
618 : :
619 : : /* Load CQE word0 and word 1 */
620 : : const uint64_t cq0_w0 = *CQE_PTR_OFF(cq0, 0, 0, flags);
621 : : const uint64_t cq0_w1 = *CQE_PTR_OFF(cq0, 0, 8, flags);
622 : : const uint64_t cq0_w2 = *CQE_PTR_OFF(cq0, 0, 16, flags);
623 : : const uint64_t cq1_w0 = *CQE_PTR_OFF(cq0, 1, 0, flags);
624 : : const uint64_t cq1_w1 = *CQE_PTR_OFF(cq0, 1, 8, flags);
625 : : const uint64_t cq1_w2 = *CQE_PTR_OFF(cq0, 1, 16, flags);
626 : : const uint64_t cq2_w0 = *CQE_PTR_OFF(cq0, 2, 0, flags);
627 : : const uint64_t cq2_w1 = *CQE_PTR_OFF(cq0, 2, 8, flags);
628 : : const uint64_t cq2_w2 = *CQE_PTR_OFF(cq0, 2, 16, flags);
629 : : const uint64_t cq3_w0 = *CQE_PTR_OFF(cq0, 3, 0, flags);
630 : : const uint64_t cq3_w1 = *CQE_PTR_OFF(cq0, 3, 8, flags);
631 : : const uint64_t cq3_w2 = *CQE_PTR_OFF(cq0, 3, 16, flags);
632 : :
633 : : if (flags & NIX_RX_VWQE_F) {
634 : : uint16_t psize0, psize1, psize2, psize3;
635 : :
636 : : psize0 = (cq0_w2 & 0xFFFF) + 1;
637 : : psize1 = (cq1_w2 & 0xFFFF) + 1;
638 : : psize2 = (cq2_w2 & 0xFFFF) + 1;
639 : : psize3 = (cq3_w2 & 0xFFFF) + 1;
640 : :
641 : : f0 = vdupq_n_u64(0);
642 : : f1 = vdupq_n_u64(0);
643 : : f2 = vdupq_n_u64(0);
644 : : f3 = vdupq_n_u64(0);
645 : :
646 : : f0 = vsetq_lane_u16(psize0, f0, 2);
647 : : f0 = vsetq_lane_u16(psize0, f0, 4);
648 : :
649 : : f1 = vsetq_lane_u16(psize1, f1, 2);
650 : : f1 = vsetq_lane_u16(psize1, f1, 4);
651 : :
652 : : f2 = vsetq_lane_u16(psize2, f2, 2);
653 : : f2 = vsetq_lane_u16(psize2, f2, 4);
654 : :
655 : : f3 = vsetq_lane_u16(psize3, f3, 2);
656 : : f3 = vsetq_lane_u16(psize3, f3, 4);
657 : : }
658 : :
659 : : if (flags & NIX_RX_OFFLOAD_RSS_F) {
660 : : /* Fill rss in the rx_descriptor_fields1 */
661 : : f0 = vsetq_lane_u32(cq0_w0, f0, 3);
662 : : f1 = vsetq_lane_u32(cq1_w0, f1, 3);
663 : : f2 = vsetq_lane_u32(cq2_w0, f2, 3);
664 : : f3 = vsetq_lane_u32(cq3_w0, f3, 3);
665 : : ol_flags0 = RTE_MBUF_F_RX_RSS_HASH;
666 : : ol_flags1 = RTE_MBUF_F_RX_RSS_HASH;
667 : : ol_flags2 = RTE_MBUF_F_RX_RSS_HASH;
668 : : ol_flags3 = RTE_MBUF_F_RX_RSS_HASH;
669 : : } else {
670 : : ol_flags0 = 0;
671 : : ol_flags1 = 0;
672 : : ol_flags2 = 0;
673 : : ol_flags3 = 0;
674 : : }
675 : :
676 : : if (flags & NIX_RX_OFFLOAD_PTYPE_F) {
677 : : /* Fill packet_type in the rx_descriptor_fields1 */
678 : : f0 = vsetq_lane_u32(nix_ptype_get(lookup_mem, cq0_w1), f0, 0);
679 : : f1 = vsetq_lane_u32(nix_ptype_get(lookup_mem, cq1_w1), f1, 0);
680 : : f2 = vsetq_lane_u32(nix_ptype_get(lookup_mem, cq2_w1), f2, 0);
681 : : f3 = vsetq_lane_u32(nix_ptype_get(lookup_mem, cq3_w1), f3, 0);
682 : : }
683 : :
684 : : if (flags & NIX_RX_OFFLOAD_CHECKSUM_F) {
685 : : ol_flags0 |= (uint64_t)nix_rx_olflags_get(lookup_mem, cq0_w1);
686 : : ol_flags1 |= (uint64_t)nix_rx_olflags_get(lookup_mem, cq1_w1);
687 : : ol_flags2 |= (uint64_t)nix_rx_olflags_get(lookup_mem, cq2_w1);
688 : : ol_flags3 |= (uint64_t)nix_rx_olflags_get(lookup_mem, cq3_w1);
689 : : }
690 : :
691 : : if (flags & NIX_RX_OFFLOAD_VLAN_STRIP_F) {
692 : : ol_flags0 = nix_vlan_update(cq0_w2, ol_flags0, &f0);
693 : : ol_flags1 = nix_vlan_update(cq1_w2, ol_flags1, &f1);
694 : : ol_flags2 = nix_vlan_update(cq2_w2, ol_flags2, &f2);
695 : : ol_flags3 = nix_vlan_update(cq3_w2, ol_flags3, &f3);
696 : :
697 : : ol_flags0 = nix_qinq_update(cq0_w2, ol_flags0, mbuf0);
698 : : ol_flags1 = nix_qinq_update(cq1_w2, ol_flags1, mbuf1);
699 : : ol_flags2 = nix_qinq_update(cq2_w2, ol_flags2, mbuf2);
700 : : ol_flags3 = nix_qinq_update(cq3_w2, ol_flags3, mbuf3);
701 : : }
702 : :
703 : : if (flags & NIX_RX_OFFLOAD_MARK_UPDATE_F) {
704 : : ol_flags0 = nix_update_match_id(*(uint16_t *)CQE_PTR_OFF(cq0, 0, 38, flags),
705 : : ol_flags0, mbuf0);
706 : : ol_flags1 = nix_update_match_id(*(uint16_t *)CQE_PTR_OFF(cq0, 1, 38, flags),
707 : : ol_flags1, mbuf1);
708 : : ol_flags2 = nix_update_match_id(*(uint16_t *)CQE_PTR_OFF(cq0, 2, 38, flags),
709 : : ol_flags2, mbuf2);
710 : : ol_flags3 = nix_update_match_id(*(uint16_t *)CQE_PTR_OFF(cq0, 3, 38, flags),
711 : : ol_flags3, mbuf3);
712 : : }
713 : :
714 : : if ((flags & NIX_RX_OFFLOAD_TSTAMP_F) && ((flags & NIX_RX_VWQE_F) && tstamp)) {
715 : : const uint16x8_t len_off = {0, /* ptype 0:15 */
716 : : 0, /* ptype 16:32 */
717 : : CNXK_NIX_TIMESYNC_RX_OFFSET, /* pktlen 0:15*/
718 : : 0, /* pktlen 16:32 */
719 : : CNXK_NIX_TIMESYNC_RX_OFFSET, /* datalen 0:15 */
720 : : 0,
721 : : 0,
722 : : 0};
723 : : const uint32x4_t ptype = {
724 : : RTE_PTYPE_L2_ETHER_TIMESYNC, RTE_PTYPE_L2_ETHER_TIMESYNC,
725 : : RTE_PTYPE_L2_ETHER_TIMESYNC, RTE_PTYPE_L2_ETHER_TIMESYNC};
726 : : const uint64_t ts_olf = RTE_MBUF_F_RX_IEEE1588_PTP |
727 : : RTE_MBUF_F_RX_IEEE1588_TMST |
728 : : tstamp->rx_tstamp_dynflag;
729 : : const uint32x4_t and_mask = {0x1, 0x2, 0x4, 0x8};
730 : : uint64x2_t ts01, ts23, mask;
731 : : uint64_t ts[4];
732 : : uint8_t res;
733 : :
734 : : /* Subtract timesync length from total pkt length. */
735 : : f0 = vsubq_u16(f0, len_off);
736 : : f1 = vsubq_u16(f1, len_off);
737 : : f2 = vsubq_u16(f2, len_off);
738 : : f3 = vsubq_u16(f3, len_off);
739 : :
740 : : /* Get the address of actual timestamp. */
741 : : ts01 = vaddq_u64(mbuf01, data_off);
742 : : ts23 = vaddq_u64(mbuf23, data_off);
743 : : /* Load timestamp from address. */
744 : : ts01 = vsetq_lane_u64(*(uint64_t *)vgetq_lane_u64(ts01, 0), ts01, 0);
745 : : ts01 = vsetq_lane_u64(*(uint64_t *)vgetq_lane_u64(ts01, 1), ts01, 1);
746 : : ts23 = vsetq_lane_u64(*(uint64_t *)vgetq_lane_u64(ts23, 0), ts23, 0);
747 : : ts23 = vsetq_lane_u64(*(uint64_t *)vgetq_lane_u64(ts23, 1), ts23, 1);
748 : : /* Convert from be to cpu byteorder. */
749 : : ts01 = vrev64q_u8(ts01);
750 : : ts23 = vrev64q_u8(ts23);
751 : : /* Store timestamp into scalar for later use. */
752 : : ts[0] = vgetq_lane_u64(ts01, 0);
753 : : ts[1] = vgetq_lane_u64(ts01, 1);
754 : : ts[2] = vgetq_lane_u64(ts23, 0);
755 : : ts[3] = vgetq_lane_u64(ts23, 1);
756 : :
757 : : /* Store timestamp into dynfield. */
758 : : *cnxk_nix_timestamp_dynfield(mbuf0, tstamp) = ts[0];
759 : : *cnxk_nix_timestamp_dynfield(mbuf1, tstamp) = ts[1];
760 : : *cnxk_nix_timestamp_dynfield(mbuf2, tstamp) = ts[2];
761 : : *cnxk_nix_timestamp_dynfield(mbuf3, tstamp) = ts[3];
762 : :
763 : : /* Generate ptype mask to filter L2 ether timesync */
764 : : mask = vdupq_n_u32(vgetq_lane_u32(f0, 0));
765 : : mask = vsetq_lane_u32(vgetq_lane_u32(f1, 0), mask, 1);
766 : : mask = vsetq_lane_u32(vgetq_lane_u32(f2, 0), mask, 2);
767 : : mask = vsetq_lane_u32(vgetq_lane_u32(f3, 0), mask, 3);
768 : :
769 : : /* Match against L2 ether timesync. */
770 : : mask = vceqq_u32(mask, ptype);
771 : : /* Convert from vector from scalar mask */
772 : : res = vaddvq_u32(vandq_u32(mask, and_mask));
773 : : res &= 0xF;
774 : :
775 : : if (res) {
776 : : /* Fill in the ol_flags for any packets that
777 : : * matched.
778 : : */
779 : : ol_flags0 |= ((res & 0x1) ? ts_olf : 0);
780 : : ol_flags1 |= ((res & 0x2) ? ts_olf : 0);
781 : : ol_flags2 |= ((res & 0x4) ? ts_olf : 0);
782 : : ol_flags3 |= ((res & 0x8) ? ts_olf : 0);
783 : :
784 : : /* Update Rxq timestamp with the latest
785 : : * timestamp.
786 : : */
787 : : tstamp->rx_ready = 1;
788 : : tstamp->rx_tstamp = ts[31 - rte_clz32(res)];
789 : : }
790 : : }
791 : :
792 : : /* Form rearm_data with ol_flags */
793 : : rearm0 = vsetq_lane_u64(ol_flags0, rearm0, 1);
794 : : rearm1 = vsetq_lane_u64(ol_flags1, rearm1, 1);
795 : : rearm2 = vsetq_lane_u64(ol_flags2, rearm2, 1);
796 : : rearm3 = vsetq_lane_u64(ol_flags3, rearm3, 1);
797 : :
798 : : /* Update rx_descriptor_fields1 */
799 : : vst1q_u64((uint64_t *)mbuf0->rx_descriptor_fields1, f0);
800 : : vst1q_u64((uint64_t *)mbuf1->rx_descriptor_fields1, f1);
801 : : vst1q_u64((uint64_t *)mbuf2->rx_descriptor_fields1, f2);
802 : : vst1q_u64((uint64_t *)mbuf3->rx_descriptor_fields1, f3);
803 : :
804 : : /* Update rearm_data */
805 : : vst1q_u64((uint64_t *)mbuf0->rearm_data, rearm0);
806 : : vst1q_u64((uint64_t *)mbuf1->rearm_data, rearm1);
807 : : vst1q_u64((uint64_t *)mbuf2->rearm_data, rearm2);
808 : : vst1q_u64((uint64_t *)mbuf3->rearm_data, rearm3);
809 : :
810 : : if (flags & NIX_RX_MULTI_SEG_F) {
811 : : /* Multi segment is enable build mseg list for
812 : : * individual mbufs in scalar mode.
813 : : */
814 : : nix_cqe_xtract_mseg((union nix_rx_parse_u *)(CQE_PTR_OFF(cq0, 0, 8, flags)),
815 : : mbuf0, mbuf_initializer, cpth0, sa_base, flags);
816 : : nix_cqe_xtract_mseg((union nix_rx_parse_u *)(CQE_PTR_OFF(cq0, 1, 8, flags)),
817 : : mbuf1, mbuf_initializer, cpth1, sa_base, flags);
818 : : nix_cqe_xtract_mseg((union nix_rx_parse_u *)(CQE_PTR_OFF(cq0, 2, 8, flags)),
819 : : mbuf2, mbuf_initializer, cpth2, sa_base, flags);
820 : : nix_cqe_xtract_mseg((union nix_rx_parse_u *)(CQE_PTR_OFF(cq0, 3, 8, flags)),
821 : : mbuf3, mbuf_initializer, cpth3, sa_base, flags);
822 : : }
823 : :
824 : : /* Store the mbufs to rx_pkts */
825 : : vst1q_u64((uint64_t *)&mbufs[packets], mbuf01);
826 : : vst1q_u64((uint64_t *)&mbufs[packets + 2], mbuf23);
827 : :
828 : : nix_mbuf_validate_next(mbuf0);
829 : : nix_mbuf_validate_next(mbuf1);
830 : : nix_mbuf_validate_next(mbuf2);
831 : : nix_mbuf_validate_next(mbuf3);
832 : :
833 : : packets += NIX_DESCS_PER_LOOP;
834 : :
835 : : if (!(flags & NIX_RX_VWQE_F)) {
836 : : /* Advance head pointer and packets */
837 : : head += NIX_DESCS_PER_LOOP;
838 : : head &= qmask;
839 : : }
840 : : }
841 : :
842 : : if (flags & NIX_RX_VWQE_F)
843 : : return packets;
844 : :
845 : : rxq->head = head;
846 : : rxq->available -= packets;
847 : :
848 : : rte_io_wmb();
849 : : /* Free all the CQs that we've processed */
850 : : plt_write64((rxq->wdata | packets), rxq->cq_door);
851 : :
852 : : if (unlikely(pkts_left))
853 : : packets += cn20k_nix_recv_pkts(args, &mbufs[packets], pkts_left, flags);
854 : :
855 : : return packets;
856 : : }
857 : :
858 : : #else
859 : :
860 : : static inline uint16_t
861 : : cn20k_nix_recv_pkts_vector(void *args, struct rte_mbuf **mbufs, uint16_t pkts, const uint16_t flags,
862 : : void *lookup_mem, struct cnxk_timesync_info *tstamp, uintptr_t lmt_base,
863 : : uint64_t meta_aura)
864 : : {
865 : : RTE_SET_USED(args);
866 : : RTE_SET_USED(mbufs);
867 : : RTE_SET_USED(pkts);
868 : : RTE_SET_USED(flags);
869 : : RTE_SET_USED(lookup_mem);
870 : : RTE_SET_USED(tstamp);
871 : : RTE_SET_USED(lmt_base);
872 : : RTE_SET_USED(meta_aura);
873 : :
874 : : return 0;
875 : : }
876 : :
877 : : #endif
878 : :
879 : : #define RSS_F NIX_RX_OFFLOAD_RSS_F
880 : : #define PTYPE_F NIX_RX_OFFLOAD_PTYPE_F
881 : : #define CKSUM_F NIX_RX_OFFLOAD_CHECKSUM_F
882 : : #define MARK_F NIX_RX_OFFLOAD_MARK_UPDATE_F
883 : : #define TS_F NIX_RX_OFFLOAD_TSTAMP_F
884 : : #define RX_VLAN_F NIX_RX_OFFLOAD_VLAN_STRIP_F
885 : : #define R_SEC_F NIX_RX_OFFLOAD_SECURITY_F
886 : :
887 : : /* [R_SEC_F] [RX_VLAN_F] [TS] [MARK] [CKSUM] [PTYPE] [RSS] */
888 : : #define NIX_RX_FASTPATH_MODES_0_15 \
889 : : R(no_offload, NIX_RX_OFFLOAD_NONE) \
890 : : R(rss, RSS_F) \
891 : : R(ptype, PTYPE_F) \
892 : : R(ptype_rss, PTYPE_F | RSS_F) \
893 : : R(cksum, CKSUM_F) \
894 : : R(cksum_rss, CKSUM_F | RSS_F) \
895 : : R(cksum_ptype, CKSUM_F | PTYPE_F) \
896 : : R(cksum_ptype_rss, CKSUM_F | PTYPE_F | RSS_F) \
897 : : R(mark, MARK_F) \
898 : : R(mark_rss, MARK_F | RSS_F) \
899 : : R(mark_ptype, MARK_F | PTYPE_F) \
900 : : R(mark_ptype_rss, MARK_F | PTYPE_F | RSS_F) \
901 : : R(mark_cksum, MARK_F | CKSUM_F) \
902 : : R(mark_cksum_rss, MARK_F | CKSUM_F | RSS_F) \
903 : : R(mark_cksum_ptype, MARK_F | CKSUM_F | PTYPE_F) \
904 : : R(mark_cksum_ptype_rss, MARK_F | CKSUM_F | PTYPE_F | RSS_F)
905 : :
906 : : #define NIX_RX_FASTPATH_MODES_16_31 \
907 : : R(ts, TS_F) \
908 : : R(ts_rss, TS_F | RSS_F) \
909 : : R(ts_ptype, TS_F | PTYPE_F) \
910 : : R(ts_ptype_rss, TS_F | PTYPE_F | RSS_F) \
911 : : R(ts_cksum, TS_F | CKSUM_F) \
912 : : R(ts_cksum_rss, TS_F | CKSUM_F | RSS_F) \
913 : : R(ts_cksum_ptype, TS_F | CKSUM_F | PTYPE_F) \
914 : : R(ts_cksum_ptype_rss, TS_F | CKSUM_F | PTYPE_F | RSS_F) \
915 : : R(ts_mark, TS_F | MARK_F) \
916 : : R(ts_mark_rss, TS_F | MARK_F | RSS_F) \
917 : : R(ts_mark_ptype, TS_F | MARK_F | PTYPE_F) \
918 : : R(ts_mark_ptype_rss, TS_F | MARK_F | PTYPE_F | RSS_F) \
919 : : R(ts_mark_cksum, TS_F | MARK_F | CKSUM_F) \
920 : : R(ts_mark_cksum_rss, TS_F | MARK_F | CKSUM_F | RSS_F) \
921 : : R(ts_mark_cksum_ptype, TS_F | MARK_F | CKSUM_F | PTYPE_F) \
922 : : R(ts_mark_cksum_ptype_rss, TS_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
923 : :
924 : : #define NIX_RX_FASTPATH_MODES_32_47 \
925 : : R(vlan, RX_VLAN_F) \
926 : : R(vlan_rss, RX_VLAN_F | RSS_F) \
927 : : R(vlan_ptype, RX_VLAN_F | PTYPE_F) \
928 : : R(vlan_ptype_rss, RX_VLAN_F | PTYPE_F | RSS_F) \
929 : : R(vlan_cksum, RX_VLAN_F | CKSUM_F) \
930 : : R(vlan_cksum_rss, RX_VLAN_F | CKSUM_F | RSS_F) \
931 : : R(vlan_cksum_ptype, RX_VLAN_F | CKSUM_F | PTYPE_F) \
932 : : R(vlan_cksum_ptype_rss, RX_VLAN_F | CKSUM_F | PTYPE_F | RSS_F) \
933 : : R(vlan_mark, RX_VLAN_F | MARK_F) \
934 : : R(vlan_mark_rss, RX_VLAN_F | MARK_F | RSS_F) \
935 : : R(vlan_mark_ptype, RX_VLAN_F | MARK_F | PTYPE_F) \
936 : : R(vlan_mark_ptype_rss, RX_VLAN_F | MARK_F | PTYPE_F | RSS_F) \
937 : : R(vlan_mark_cksum, RX_VLAN_F | MARK_F | CKSUM_F) \
938 : : R(vlan_mark_cksum_rss, RX_VLAN_F | MARK_F | CKSUM_F | RSS_F) \
939 : : R(vlan_mark_cksum_ptype, RX_VLAN_F | MARK_F | CKSUM_F | PTYPE_F) \
940 : : R(vlan_mark_cksum_ptype_rss, RX_VLAN_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
941 : :
942 : : #define NIX_RX_FASTPATH_MODES_48_63 \
943 : : R(vlan_ts, RX_VLAN_F | TS_F) \
944 : : R(vlan_ts_rss, RX_VLAN_F | TS_F | RSS_F) \
945 : : R(vlan_ts_ptype, RX_VLAN_F | TS_F | PTYPE_F) \
946 : : R(vlan_ts_ptype_rss, RX_VLAN_F | TS_F | PTYPE_F | RSS_F) \
947 : : R(vlan_ts_cksum, RX_VLAN_F | TS_F | CKSUM_F) \
948 : : R(vlan_ts_cksum_rss, RX_VLAN_F | TS_F | CKSUM_F | RSS_F) \
949 : : R(vlan_ts_cksum_ptype, RX_VLAN_F | TS_F | CKSUM_F | PTYPE_F) \
950 : : R(vlan_ts_cksum_ptype_rss, RX_VLAN_F | TS_F | CKSUM_F | PTYPE_F | RSS_F) \
951 : : R(vlan_ts_mark, RX_VLAN_F | TS_F | MARK_F) \
952 : : R(vlan_ts_mark_rss, RX_VLAN_F | TS_F | MARK_F | RSS_F) \
953 : : R(vlan_ts_mark_ptype, RX_VLAN_F | TS_F | MARK_F | PTYPE_F) \
954 : : R(vlan_ts_mark_ptype_rss, RX_VLAN_F | TS_F | MARK_F | PTYPE_F | RSS_F) \
955 : : R(vlan_ts_mark_cksum, RX_VLAN_F | TS_F | MARK_F | CKSUM_F) \
956 : : R(vlan_ts_mark_cksum_rss, RX_VLAN_F | TS_F | MARK_F | CKSUM_F | RSS_F) \
957 : : R(vlan_ts_mark_cksum_ptype, RX_VLAN_F | TS_F | MARK_F | CKSUM_F | PTYPE_F) \
958 : : R(vlan_ts_mark_cksum_ptype_rss, RX_VLAN_F | TS_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
959 : :
960 : : #define NIX_RX_FASTPATH_MODES_64_79 \
961 : : R(sec, R_SEC_F) \
962 : : R(sec_rss, R_SEC_F | RSS_F) \
963 : : R(sec_ptype, R_SEC_F | PTYPE_F) \
964 : : R(sec_ptype_rss, R_SEC_F | PTYPE_F | RSS_F) \
965 : : R(sec_cksum, R_SEC_F | CKSUM_F) \
966 : : R(sec_cksum_rss, R_SEC_F | CKSUM_F | RSS_F) \
967 : : R(sec_cksum_ptype, R_SEC_F | CKSUM_F | PTYPE_F) \
968 : : R(sec_cksum_ptype_rss, R_SEC_F | CKSUM_F | PTYPE_F | RSS_F) \
969 : : R(sec_mark, R_SEC_F | MARK_F) \
970 : : R(sec_mark_rss, R_SEC_F | MARK_F | RSS_F) \
971 : : R(sec_mark_ptype, R_SEC_F | MARK_F | PTYPE_F) \
972 : : R(sec_mark_ptype_rss, R_SEC_F | MARK_F | PTYPE_F | RSS_F) \
973 : : R(sec_mark_cksum, R_SEC_F | MARK_F | CKSUM_F) \
974 : : R(sec_mark_cksum_rss, R_SEC_F | MARK_F | CKSUM_F | RSS_F) \
975 : : R(sec_mark_cksum_ptype, R_SEC_F | MARK_F | CKSUM_F | PTYPE_F) \
976 : : R(sec_mark_cksum_ptype_rss, R_SEC_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
977 : :
978 : : #define NIX_RX_FASTPATH_MODES_80_95 \
979 : : R(sec_ts, R_SEC_F | TS_F) \
980 : : R(sec_ts_rss, R_SEC_F | TS_F | RSS_F) \
981 : : R(sec_ts_ptype, R_SEC_F | TS_F | PTYPE_F) \
982 : : R(sec_ts_ptype_rss, R_SEC_F | TS_F | PTYPE_F | RSS_F) \
983 : : R(sec_ts_cksum, R_SEC_F | TS_F | CKSUM_F) \
984 : : R(sec_ts_cksum_rss, R_SEC_F | TS_F | CKSUM_F | RSS_F) \
985 : : R(sec_ts_cksum_ptype, R_SEC_F | TS_F | CKSUM_F | PTYPE_F) \
986 : : R(sec_ts_cksum_ptype_rss, R_SEC_F | TS_F | CKSUM_F | PTYPE_F | RSS_F) \
987 : : R(sec_ts_mark, R_SEC_F | TS_F | MARK_F) \
988 : : R(sec_ts_mark_rss, R_SEC_F | TS_F | MARK_F | RSS_F) \
989 : : R(sec_ts_mark_ptype, R_SEC_F | TS_F | MARK_F | PTYPE_F) \
990 : : R(sec_ts_mark_ptype_rss, R_SEC_F | TS_F | MARK_F | PTYPE_F | RSS_F) \
991 : : R(sec_ts_mark_cksum, R_SEC_F | TS_F | MARK_F | CKSUM_F) \
992 : : R(sec_ts_mark_cksum_rss, R_SEC_F | TS_F | MARK_F | CKSUM_F | RSS_F) \
993 : : R(sec_ts_mark_cksum_ptype, R_SEC_F | TS_F | MARK_F | CKSUM_F | PTYPE_F) \
994 : : R(sec_ts_mark_cksum_ptype_rss, R_SEC_F | TS_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
995 : :
996 : : #define NIX_RX_FASTPATH_MODES_96_111 \
997 : : R(sec_vlan, R_SEC_F | RX_VLAN_F) \
998 : : R(sec_vlan_rss, R_SEC_F | RX_VLAN_F | RSS_F) \
999 : : R(sec_vlan_ptype, R_SEC_F | RX_VLAN_F | PTYPE_F) \
1000 : : R(sec_vlan_ptype_rss, R_SEC_F | RX_VLAN_F | PTYPE_F | RSS_F) \
1001 : : R(sec_vlan_cksum, R_SEC_F | RX_VLAN_F | CKSUM_F) \
1002 : : R(sec_vlan_cksum_rss, R_SEC_F | RX_VLAN_F | CKSUM_F | RSS_F) \
1003 : : R(sec_vlan_cksum_ptype, R_SEC_F | RX_VLAN_F | CKSUM_F | PTYPE_F) \
1004 : : R(sec_vlan_cksum_ptype_rss, R_SEC_F | RX_VLAN_F | CKSUM_F | PTYPE_F | RSS_F) \
1005 : : R(sec_vlan_mark, R_SEC_F | RX_VLAN_F | MARK_F) \
1006 : : R(sec_vlan_mark_rss, R_SEC_F | RX_VLAN_F | MARK_F | RSS_F) \
1007 : : R(sec_vlan_mark_ptype, R_SEC_F | RX_VLAN_F | MARK_F | PTYPE_F) \
1008 : : R(sec_vlan_mark_ptype_rss, R_SEC_F | RX_VLAN_F | MARK_F | PTYPE_F | RSS_F) \
1009 : : R(sec_vlan_mark_cksum, R_SEC_F | RX_VLAN_F | MARK_F | CKSUM_F) \
1010 : : R(sec_vlan_mark_cksum_rss, R_SEC_F | RX_VLAN_F | MARK_F | CKSUM_F | RSS_F) \
1011 : : R(sec_vlan_mark_cksum_ptype, R_SEC_F | RX_VLAN_F | MARK_F | CKSUM_F | PTYPE_F) \
1012 : : R(sec_vlan_mark_cksum_ptype_rss, R_SEC_F | RX_VLAN_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
1013 : :
1014 : : #define NIX_RX_FASTPATH_MODES_112_127 \
1015 : : R(sec_vlan_ts, R_SEC_F | RX_VLAN_F | TS_F) \
1016 : : R(sec_vlan_ts_rss, R_SEC_F | RX_VLAN_F | TS_F | RSS_F) \
1017 : : R(sec_vlan_ts_ptype, R_SEC_F | RX_VLAN_F | TS_F | PTYPE_F) \
1018 : : R(sec_vlan_ts_ptype_rss, R_SEC_F | RX_VLAN_F | TS_F | PTYPE_F | RSS_F) \
1019 : : R(sec_vlan_ts_cksum, R_SEC_F | RX_VLAN_F | TS_F | CKSUM_F) \
1020 : : R(sec_vlan_ts_cksum_rss, R_SEC_F | RX_VLAN_F | TS_F | CKSUM_F | RSS_F) \
1021 : : R(sec_vlan_ts_cksum_ptype, R_SEC_F | RX_VLAN_F | TS_F | CKSUM_F | PTYPE_F) \
1022 : : R(sec_vlan_ts_cksum_ptype_rss, R_SEC_F | RX_VLAN_F | TS_F | CKSUM_F | PTYPE_F | RSS_F) \
1023 : : R(sec_vlan_ts_mark, R_SEC_F | RX_VLAN_F | TS_F | MARK_F) \
1024 : : R(sec_vlan_ts_mark_rss, R_SEC_F | RX_VLAN_F | TS_F | MARK_F | RSS_F) \
1025 : : R(sec_vlan_ts_mark_ptype, R_SEC_F | RX_VLAN_F | TS_F | MARK_F | PTYPE_F) \
1026 : : R(sec_vlan_ts_mark_ptype_rss, R_SEC_F | RX_VLAN_F | TS_F | MARK_F | PTYPE_F | RSS_F) \
1027 : : R(sec_vlan_ts_mark_cksum, R_SEC_F | RX_VLAN_F | TS_F | MARK_F | CKSUM_F) \
1028 : : R(sec_vlan_ts_mark_cksum_rss, R_SEC_F | RX_VLAN_F | TS_F | MARK_F | CKSUM_F | RSS_F) \
1029 : : R(sec_vlan_ts_mark_cksum_ptype, R_SEC_F | RX_VLAN_F | TS_F | MARK_F | CKSUM_F | PTYPE_F) \
1030 : : R(sec_vlan_ts_mark_cksum_ptype_rss, \
1031 : : R_SEC_F | RX_VLAN_F | TS_F | MARK_F | CKSUM_F | PTYPE_F | RSS_F)
1032 : :
1033 : : #define NIX_RX_FASTPATH_MODES \
1034 : : NIX_RX_FASTPATH_MODES_0_15 \
1035 : : NIX_RX_FASTPATH_MODES_16_31 \
1036 : : NIX_RX_FASTPATH_MODES_32_47 \
1037 : : NIX_RX_FASTPATH_MODES_48_63 \
1038 : : NIX_RX_FASTPATH_MODES_64_79 \
1039 : : NIX_RX_FASTPATH_MODES_80_95 \
1040 : : NIX_RX_FASTPATH_MODES_96_111 \
1041 : : NIX_RX_FASTPATH_MODES_112_127
1042 : :
1043 : : #define R(name, flags) \
1044 : : uint16_t __rte_noinline __rte_hot cn20k_nix_recv_pkts_##name( \
1045 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
1046 : : uint16_t __rte_noinline __rte_hot cn20k_nix_recv_pkts_mseg_##name( \
1047 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
1048 : : uint16_t __rte_noinline __rte_hot cn20k_nix_recv_pkts_vec_##name( \
1049 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
1050 : : uint16_t __rte_noinline __rte_hot cn20k_nix_recv_pkts_vec_mseg_##name( \
1051 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
1052 : : uint16_t __rte_noinline __rte_hot cn20k_nix_recv_pkts_reas_##name( \
1053 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
1054 : : uint16_t __rte_noinline __rte_hot cn20k_nix_recv_pkts_reas_mseg_##name( \
1055 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
1056 : : uint16_t __rte_noinline __rte_hot cn20k_nix_recv_pkts_reas_vec_##name( \
1057 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts); \
1058 : : uint16_t __rte_noinline __rte_hot cn20k_nix_recv_pkts_reas_vec_mseg_##name( \
1059 : : void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t pkts);
1060 : :
1061 : : NIX_RX_FASTPATH_MODES
1062 : : #undef R
1063 : :
1064 : : #define NIX_RX_RECV(fn, flags) \
1065 : : uint16_t __rte_noinline __rte_hot fn(void *rx_queue, struct rte_mbuf **rx_pkts, \
1066 : : uint16_t pkts) \
1067 : : { \
1068 : : return cn20k_nix_recv_pkts(rx_queue, rx_pkts, pkts, (flags)); \
1069 : : }
1070 : :
1071 : : #define NIX_RX_RECV_MSEG(fn, flags) NIX_RX_RECV(fn, flags | NIX_RX_MULTI_SEG_F)
1072 : :
1073 : : #define NIX_RX_RECV_VEC(fn, flags) \
1074 : : uint16_t __rte_noinline __rte_hot fn(void *rx_queue, struct rte_mbuf **rx_pkts, \
1075 : : uint16_t pkts) \
1076 : : { \
1077 : : return cn20k_nix_recv_pkts_vector(rx_queue, rx_pkts, pkts, (flags), NULL, NULL, 0, \
1078 : : 0); \
1079 : : }
1080 : :
1081 : : #define NIX_RX_RECV_VEC_MSEG(fn, flags) NIX_RX_RECV_VEC(fn, flags | NIX_RX_MULTI_SEG_F)
1082 : :
1083 : : uint16_t __rte_noinline __rte_hot cn20k_nix_recv_pkts_all_offload(void *rx_queue,
1084 : : struct rte_mbuf **rx_pkts,
1085 : : uint16_t pkts);
1086 : :
1087 : : uint16_t __rte_noinline __rte_hot cn20k_nix_recv_pkts_vec_all_offload(void *rx_queue,
1088 : : struct rte_mbuf **rx_pkts,
1089 : : uint16_t pkts);
1090 : :
1091 : : uint16_t __rte_noinline __rte_hot cn20k_nix_recv_pkts_all_offload_tst(void *rx_queue,
1092 : : struct rte_mbuf **rx_pkts,
1093 : : uint16_t pkts);
1094 : :
1095 : : uint16_t __rte_noinline __rte_hot cn20k_nix_recv_pkts_vec_all_offload_tst(void *rx_queue,
1096 : : struct rte_mbuf **rx_pkts,
1097 : : uint16_t pkts);
1098 : :
1099 : : #endif /* __CN20K_RX_H__ */
|