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