Branch data Line data Source code
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 <stddef.h> 9 : : #include <stdint.h> 10 : : #include <unistd.h> 11 : : #include <rte_mbuf.h> 12 : : #include <rte_ethdev.h> 13 : : 14 : : #include "desc.h" 15 : : 16 : : #define CI_RX_MAX_BURST 32 17 : : #define CI_RX_MAX_NSEG 2 18 : : #define CI_VPMD_RX_BURST 32 19 : : #define CI_VPMD_DESCS_PER_LOOP 4 20 : : #define CI_VPMD_DESCS_PER_LOOP_WIDE 8 21 : : #define CI_VPMD_RX_REARM_THRESH 64 22 : : 23 : : struct ci_rx_queue; 24 : : 25 : : struct ci_rx_entry { 26 : : struct rte_mbuf *mbuf; /* mbuf associated with RX descriptor. */ 27 : : }; 28 : : 29 : : struct ci_rx_entry_sc { 30 : : struct rte_mbuf *fbuf; /* First segment of the fragmented packet.*/ 31 : : }; 32 : : 33 : : typedef void (*ci_rx_release_mbufs_t)(struct ci_rx_queue *rxq); 34 : : 35 : : /** 36 : : * Structure associated with each RX queue. 37 : : */ 38 : : struct ci_rx_queue { 39 : : struct rte_mempool *mp; /**< mbuf pool to populate RX ring. */ 40 : : union { /* RX ring virtual address */ 41 : : volatile union ixgbe_adv_rx_desc *ixgbe_rx_ring; 42 : : volatile union ci_rx_desc *rx_ring; 43 : : volatile union ci_rx_flex_desc *rx_flex_ring; 44 : : }; 45 : : volatile uint8_t *qrx_tail; /**< register address of tail */ 46 : : struct ci_rx_entry *sw_ring; /**< address of RX software ring. */ 47 : : struct ci_rx_entry_sc *sw_sc_ring; /**< address of scattered Rx software ring. */ 48 : : rte_iova_t rx_ring_phys_addr; /**< RX ring DMA address. */ 49 : : struct rte_mbuf *pkt_first_seg; /**< First segment of current packet. */ 50 : : struct rte_mbuf *pkt_last_seg; /**< Last segment of current packet. */ 51 : : /** hold packets to return to application */ 52 : : struct rte_mbuf *rx_stage[CI_RX_MAX_BURST * 2]; 53 : : uint16_t nb_rx_desc; /**< number of RX descriptors. */ 54 : : uint16_t rx_tail; /**< current value of tail register. */ 55 : : uint16_t rx_nb_avail; /**< nr of staged pkts ready to ret to app */ 56 : : uint16_t nb_rx_hold; /**< number of held free RX desc. */ 57 : : uint16_t rx_next_avail; /**< idx of next staged pkt to ret to app */ 58 : : uint16_t rx_free_thresh; /**< max free RX desc to hold. */ 59 : : uint16_t rx_free_trigger; /**< triggers rx buffer allocation */ 60 : : uint16_t rxrearm_nb; /**< number of remaining to be re-armed */ 61 : : uint16_t rxrearm_start; /**< the idx we start the re-arming from */ 62 : : uint16_t queue_id; /**< RX queue index. */ 63 : : uint16_t port_id; /**< Device port identifier. */ 64 : : uint16_t reg_idx; /**< RX queue register index. */ 65 : : uint16_t rx_buf_len; /* The packet buffer size */ 66 : : uint16_t rx_hdr_len; /* The header buffer size */ 67 : : uint16_t max_pkt_len; /* Maximum packet length */ 68 : : uint8_t crc_len; /**< 0 if CRC stripped, 4 otherwise. */ 69 : : bool q_set; /**< indicate if rx queue has been configured */ 70 : : bool rx_deferred_start; /**< queue is not started on dev start. */ 71 : : bool fdir_enabled; /* 0 if FDIR disabled, 1 when enabled */ 72 : : bool vector_rx; /**< indicates that vector RX is in use */ 73 : : bool drop_en; /**< if 1, drop packets if no descriptors are available. */ 74 : : uint64_t mbuf_initializer; /**< value to init mbufs */ 75 : : uint64_t offloads; /**< Rx offloads with RTE_ETH_RX_OFFLOAD_* */ 76 : : uint32_t rxdid; /**< RX descriptor format ID. */ 77 : : uint32_t proto_xtr; /* protocol extraction type */ 78 : : uint64_t xtr_ol_flag; /* flexible descriptor metadata extraction offload flag */ 79 : : ptrdiff_t xtr_field_offs; /* Protocol extraction matedata offset*/ 80 : : uint64_t hw_time_update; /**< Last time HW timestamp was updated */ 81 : : /** need to alloc dummy mbuf, for wraparound when scanning hw ring */ 82 : : struct rte_mbuf fake_mbuf; 83 : : union { /* the VSI this queue belongs to */ 84 : : struct i40e_vsi *i40e_vsi; 85 : : struct ice_vsi *ice_vsi; 86 : : struct iavf_vsi *iavf_vsi; 87 : : }; 88 : : const struct rte_memzone *mz; 89 : : union { 90 : : struct { /* ixgbe specific values */ 91 : : /** flags to set in mbuf when a vlan is detected. */ 92 : : uint64_t vlan_flags; 93 : : /** Packet type mask for different NICs. */ 94 : : uint16_t pkt_type_mask; 95 : : /** indicates that IPsec RX feature is in use */ 96 : : uint8_t using_ipsec; 97 : : /** UDP frames with a 0 checksum can be marked as checksum errors. */ 98 : : uint8_t rx_udp_csum_zero_err; 99 : : }; 100 : : struct { /* i40e specific values */ 101 : : uint8_t hs_mode; /**< Header Split mode */ 102 : : uint8_t dcb_tc; /**< Traffic class of rx queue */ 103 : : }; 104 : : struct { /* ice specific values */ 105 : : ci_rx_release_mbufs_t rx_rel_mbufs; /**< release mbuf function */ 106 : : /** holds buffer split information */ 107 : : struct rte_eth_rxseg_split rxseg[CI_RX_MAX_NSEG]; 108 : : struct ci_rx_entry *sw_split_buf; /**< Buffer split SW ring */ 109 : : uint32_t rxseg_nb; /**< number of buffer split segments */ 110 : : uint32_t time_high; /* high 32 bits of hardware timestamp register */ 111 : : uint32_t hw_time_high; /* high 32 bits of timestamp */ 112 : : uint32_t hw_time_low; /* low 32 bits of timestamp */ 113 : : int ts_offset; /* dynamic mbuf timestamp field offset */ 114 : : uint64_t ts_flag; /* dynamic mbuf timestamp flag */ 115 : : }; 116 : : struct { /* iavf specific values */ 117 : : const struct iavf_rxq_ops *ops; /**< queue ops */ 118 : : struct iavf_rx_queue_stats *stats; /**< per-queue stats */ 119 : : uint64_t phc_time; /**< HW timestamp */ 120 : : uint8_t rel_mbufs_type; /**< type of release mbuf function */ 121 : : uint8_t rx_flags; /**< Rx VLAN tag location flags */ 122 : : #define IAVF_RX_FLAGS_VLAN_TAG_LOC_L2TAG1 BIT(0) 123 : : #define IAVF_RX_FLAGS_VLAN_TAG_LOC_L2TAG2_2 BIT(1) 124 : : }; 125 : : }; 126 : : }; 127 : : 128 : : static inline uint16_t 129 : 0 : ci_rx_reassemble_packets(struct rte_mbuf **rx_bufs, uint16_t nb_bufs, uint8_t *split_flags, 130 : : struct rte_mbuf **pkt_first_seg, struct rte_mbuf **pkt_last_seg, 131 : : const uint8_t crc_len) 132 : : { 133 : 0 : struct rte_mbuf *pkts[CI_RX_MAX_BURST] = {0}; /*finished pkts*/ 134 : 0 : struct rte_mbuf *start = *pkt_first_seg; 135 : 0 : struct rte_mbuf *end = *pkt_last_seg; 136 : : unsigned int pkt_idx, buf_idx; 137 : : 138 [ # # ]: 0 : for (buf_idx = 0, pkt_idx = 0; buf_idx < nb_bufs; buf_idx++) { 139 [ # # ]: 0 : if (end) { 140 : : /* processing a split packet */ 141 : 0 : end->next = rx_bufs[buf_idx]; 142 : 0 : rx_bufs[buf_idx]->data_len += crc_len; 143 : : 144 : 0 : start->nb_segs++; 145 : 0 : start->pkt_len += rx_bufs[buf_idx]->data_len; 146 : : end = end->next; 147 : : 148 [ # # ]: 0 : if (!split_flags[buf_idx]) { 149 : : /* it's the last packet of the set */ 150 : 0 : start->hash = end->hash; 151 : 0 : start->vlan_tci = end->vlan_tci; 152 : 0 : start->ol_flags = end->ol_flags; 153 : : /* we need to strip crc for the whole packet */ 154 : 0 : start->pkt_len -= crc_len; 155 [ # # ]: 0 : if (end->data_len > crc_len) { 156 : 0 : end->data_len -= crc_len; 157 : : } else { 158 : : /* free up last mbuf */ 159 : : struct rte_mbuf *secondlast = start; 160 : : 161 : 0 : start->nb_segs--; 162 [ # # ]: 0 : while (secondlast->next != end) 163 : : secondlast = secondlast->next; 164 : 0 : secondlast->data_len -= (crc_len - end->data_len); 165 : 0 : secondlast->next = NULL; 166 : : rte_pktmbuf_free_seg(end); 167 : : } 168 : 0 : pkts[pkt_idx++] = start; 169 : : start = NULL; 170 : : end = NULL; 171 : : } 172 : : } else { 173 : : /* not processing a split packet */ 174 [ # # ]: 0 : if (!split_flags[buf_idx]) { 175 : : /* not a split packet, save and skip */ 176 : 0 : pkts[pkt_idx++] = rx_bufs[buf_idx]; 177 : 0 : continue; 178 : : } 179 : 0 : start = rx_bufs[buf_idx]; 180 : : end = start; 181 : 0 : rx_bufs[buf_idx]->data_len += crc_len; 182 : 0 : rx_bufs[buf_idx]->pkt_len += crc_len; 183 : : } 184 : : } 185 : : 186 : : /* save the partial packet for next time */ 187 : 0 : *pkt_first_seg = start; 188 : 0 : *pkt_last_seg = end; 189 : 0 : memcpy(rx_bufs, pkts, pkt_idx * (sizeof(*pkts))); 190 : 0 : return pkt_idx; 191 : : } 192 : : 193 : : static inline uint64_t 194 : 0 : ci_rxq_mbuf_initializer(uint16_t port_id) 195 : : { 196 : 0 : struct rte_mbuf mb_def = { 197 : : .nb_segs = 1, 198 : : .data_off = RTE_PKTMBUF_HEADROOM, 199 : : .port = port_id, 200 : : }; 201 : : rte_mbuf_refcnt_set(&mb_def, 1); 202 : : 203 : 0 : return mb_def.rearm_data[0]; 204 : : } 205 : : 206 : : /* basic checks for a vector-driver capable queue. 207 : : * Individual drivers may have other further tests beyond this. 208 : : */ 209 : : static inline bool 210 : : ci_rxq_vec_capable(uint16_t nb_desc, uint16_t rx_free_thresh, uint64_t offloads) 211 : : { 212 [ # # # # ]: 0 : if (!rte_is_power_of_2(nb_desc) || 213 : 0 : rx_free_thresh < CI_RX_MAX_BURST || 214 [ # # ]: 0 : (nb_desc % rx_free_thresh) != 0) 215 : : return false; 216 : : 217 : : /* no driver supports timestamping or buffer split on vector path */ 218 [ # # ]: 0 : if ((offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) || 219 : : (offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT)) 220 : : return false; 221 : : 222 : : return true; 223 : : } 224 : : 225 : : #endif /* _COMMON_INTEL_RX_H_ */