xref: /dpdk/drivers/net/intel/common/rx.h (revision 9eb60580d155f5e3a36927dbb1e59ef9623231ce)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2024 Intel Corporation
3  */
4 
5 #ifndef _COMMON_INTEL_RX_H_
6 #define _COMMON_INTEL_RX_H_
7 
8 #include <stdint.h>
9 #include <unistd.h>
10 #include <rte_mbuf.h>
11 #include <rte_ethdev.h>
12 
13 #define CI_RX_BURST 32
14 
15 static inline uint16_t
16 ci_rx_reassemble_packets(struct rte_mbuf **rx_bufs, uint16_t nb_bufs, uint8_t *split_flags,
17 		struct rte_mbuf **pkt_first_seg, struct rte_mbuf **pkt_last_seg,
18 		const uint8_t crc_len)
19 {
20 	struct rte_mbuf *pkts[CI_RX_BURST] = {0}; /*finished pkts*/
21 	struct rte_mbuf *start = *pkt_first_seg;
22 	struct rte_mbuf *end = *pkt_last_seg;
23 	unsigned int pkt_idx, buf_idx;
24 
25 	for (buf_idx = 0, pkt_idx = 0; buf_idx < nb_bufs; buf_idx++) {
26 		if (end) {
27 			/* processing a split packet */
28 			end->next = rx_bufs[buf_idx];
29 			rx_bufs[buf_idx]->data_len += crc_len;
30 
31 			start->nb_segs++;
32 			start->pkt_len += rx_bufs[buf_idx]->data_len;
33 			end = end->next;
34 
35 			if (!split_flags[buf_idx]) {
36 				/* it's the last packet of the set */
37 				start->hash = end->hash;
38 				start->vlan_tci = end->vlan_tci;
39 				start->ol_flags = end->ol_flags;
40 				/* we need to strip crc for the whole packet */
41 				start->pkt_len -= crc_len;
42 				if (end->data_len > crc_len) {
43 					end->data_len -= crc_len;
44 				} else {
45 					/* free up last mbuf */
46 					struct rte_mbuf *secondlast = start;
47 
48 					start->nb_segs--;
49 					while (secondlast->next != end)
50 						secondlast = secondlast->next;
51 					secondlast->data_len -= (crc_len - end->data_len);
52 					secondlast->next = NULL;
53 					rte_pktmbuf_free_seg(end);
54 				}
55 				pkts[pkt_idx++] = start;
56 				start = NULL;
57 				end = NULL;
58 			}
59 		} else {
60 			/* not processing a split packet */
61 			if (!split_flags[buf_idx]) {
62 				/* not a split packet, save and skip */
63 				pkts[pkt_idx++] = rx_bufs[buf_idx];
64 				continue;
65 			}
66 			start = rx_bufs[buf_idx];
67 			end = start;
68 			rx_bufs[buf_idx]->data_len += crc_len;
69 			rx_bufs[buf_idx]->pkt_len += crc_len;
70 		}
71 	}
72 
73 	/* save the partial packet for next time */
74 	*pkt_first_seg = start;
75 	*pkt_last_seg = end;
76 	memcpy(rx_bufs, pkts, pkt_idx * (sizeof(*pkts)));
77 	return pkt_idx;
78 }
79 
80 static inline uint64_t
81 ci_rxq_mbuf_initializer(uint16_t port_id)
82 {
83 	struct rte_mbuf mb_def = {
84 		.nb_segs = 1,
85 		.data_off = RTE_PKTMBUF_HEADROOM,
86 		.port = port_id,
87 	};
88 	rte_mbuf_refcnt_set(&mb_def, 1);
89 
90 	return mb_def.rearm_data[0];
91 }
92 
93 /* basic checks for a vector-driver capable queue.
94  * Individual drivers may have other further tests beyond this.
95  */
96 static inline bool
97 ci_rxq_vec_capable(uint16_t nb_desc, uint16_t rx_free_thresh, uint64_t offloads)
98 {
99 	if (!rte_is_power_of_2(nb_desc) ||
100 			rx_free_thresh < CI_RX_BURST ||
101 			(nb_desc % rx_free_thresh) != 0)
102 		return false;
103 
104 	/* no driver supports timestamping or buffer split on vector path */
105 	if ((offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) ||
106 			(offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT))
107 		return false;
108 
109 	return true;
110 }
111 
112 #endif /* _COMMON_INTEL_RX_H_ */
113