Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
3 : : */
4 : :
5 : : #include <rte_common.h>
6 : : #include <rte_net.h>
7 : : #include <rte_vect.h>
8 : : #include <rte_malloc.h>
9 : : #include <rte_memzone.h>
10 : : #include <ethdev_driver.h>
11 : : #include "sxe2_osal.h"
12 : : #include "sxe2_txrx_common.h"
13 : : #include "sxe2_txrx_vec_common.h"
14 : : #include "sxe2_txrx_poll.h"
15 : : #include "sxe2_txrx.h"
16 : : #include "sxe2_txrx_vec.h"
17 : : #include "sxe2_queue.h"
18 : : #include "sxe2_ethdev.h"
19 : : #include "sxe2_common_log.h"
20 : : #include "sxe2_cmd_chnl.h"
21 : :
22 : : static __rte_always_inline int32_t
23 : 0 : sxe2_tx_bufs_free(struct sxe2_tx_queue *txq)
24 : : {
25 : 0 : struct sxe2_tx_buffer *buffer;
26 : 0 : struct rte_mbuf *mbuf;
27 : 0 : struct rte_mbuf *mbuf_free_arr[SXE2_TX_FREE_BUFFER_SIZE_MAX];
28 : 0 : int32_t ret;
29 : 0 : uint32_t i;
30 : 0 : uint16_t rs_thresh;
31 : 0 : uint16_t free_num;
32 : 0 : if ((txq->desc_ring[txq->next_dd].wb.dd &
33 : : rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_MASK)) !=
34 : : rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE)) {
35 : 0 : ret = 0;
36 : 0 : goto l_end;
37 : : }
38 : 0 : rs_thresh = txq->rs_thresh;
39 : 0 : buffer = &txq->buffer_ring[txq->next_dd - rs_thresh + 1];
40 [ # # # # ]: 0 : if (txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) {
41 [ # # # # ]: 0 : if (likely(rs_thresh <= SXE2_TX_FREE_BUFFER_SIZE_MAX)) {
42 : 0 : mbuf = buffer[0].mbuf;
43 : 0 : mbuf_free_arr[0] = mbuf;
44 : 0 : free_num = 1;
45 [ # # # # ]: 0 : for (i = 1; i < rs_thresh; ++i) {
46 : 0 : mbuf = buffer[i].mbuf;
47 [ # # # # ]: 0 : if (likely(mbuf->pool == mbuf_free_arr[0]->pool)) {
48 : 0 : mbuf_free_arr[free_num] = mbuf;
49 : 0 : free_num++;
50 : : } else {
51 [ # # # # ]: 0 : rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
52 : : (void *)mbuf_free_arr, free_num);
53 : 0 : mbuf_free_arr[0] = mbuf;
54 : 0 : free_num = 1;
55 : : }
56 : : }
57 [ # # # # ]: 0 : rte_mempool_put_bulk(mbuf_free_arr[0]->pool,
58 : : (void *)mbuf_free_arr, free_num);
59 : : } else {
60 [ # # # # ]: 0 : for (i = 0; i < rs_thresh; ++i, ++buffer) {
61 [ # # # # ]: 0 : rte_mempool_put(buffer->mbuf->pool, buffer->mbuf);
62 : 0 : buffer->mbuf = NULL;
63 : : }
64 : : }
65 : : } else {
66 [ # # # # ]: 0 : for (i = 0; i < rs_thresh; ++i, ++buffer) {
67 : 0 : mbuf = rte_pktmbuf_prefree_seg(buffer[i].mbuf);
68 : 0 : if (mbuf != NULL)
69 [ # # # # ]: 0 : rte_mempool_put(mbuf->pool, mbuf);
70 : 0 : buffer->mbuf = NULL;
71 : : }
72 : : }
73 : 0 : txq->desc_free_num += rs_thresh;
74 : 0 : txq->next_dd += rs_thresh;
75 [ # # # # ]: 0 : if (txq->next_dd >= txq->ring_depth)
76 : 0 : txq->next_dd = rs_thresh - 1;
77 : : ret = rs_thresh;
78 : 0 : l_end:
79 : 0 : return ret;
80 : : }
81 : :
82 : 0 : static inline int32_t sxe2_tx_cleanup(struct sxe2_tx_queue *txq)
83 : : {
84 : 0 : int32_t ret = 0;
85 : 0 : volatile union sxe2_tx_data_desc *desc_ring = txq->desc_ring;
86 : 0 : struct sxe2_tx_buffer *buffer_ring = txq->buffer_ring;
87 : 0 : uint16_t ring_depth = txq->ring_depth;
88 : 0 : uint16_t next_clean = txq->next_clean;
89 : 0 : uint16_t clean_last;
90 : 0 : uint16_t clean_num;
91 : :
92 : 0 : clean_last = next_clean + txq->rs_thresh;
93 [ # # ]: 0 : if (clean_last >= ring_depth)
94 : 0 : clean_last = clean_last - ring_depth;
95 : :
96 : 0 : clean_last = buffer_ring[clean_last].last_id;
97 : 0 : if (rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DESC_DONE) !=
98 [ # # ]: 0 : (txq->desc_ring[clean_last].wb.dd & rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_MASK))) {
99 : 0 : PMD_LOG_DEBUG(TX, "desc[%u] is not done.port_id=%u queue_id=%u val=0x%" PRIx64,
100 : : clean_last, txq->port_id,
101 : : txq->queue_id, txq->desc_ring[clean_last].wb.dd);
102 : 0 : ret = -1;
103 : 0 : goto l_end;
104 : : }
105 : :
106 [ # # ]: 0 : if (clean_last > next_clean)
107 : 0 : clean_num = clean_last - next_clean;
108 : : else
109 : 0 : clean_num = ring_depth - next_clean + clean_last;
110 : :
111 : 0 : desc_ring[clean_last].wb.dd = 0;
112 : :
113 : 0 : txq->next_clean = clean_last;
114 : 0 : txq->desc_free_num += clean_num;
115 : :
116 : 0 : ret = 0;
117 : :
118 : 0 : l_end:
119 : 0 : return ret;
120 : : }
121 : :
122 : 0 : static int32_t sxe2_tx_done_cleanup_simple(struct sxe2_tx_queue *txq, uint32_t free_cnt)
123 : : {
124 : 0 : uint32_t free_cnt_align;
125 : 0 : uint32_t free_cnt_once;
126 : 0 : uint32_t i;
127 : :
128 [ # # # # ]: 0 : if (free_cnt == 0 || free_cnt > txq->ring_depth)
129 : 0 : free_cnt = txq->ring_depth;
130 : :
131 : 0 : free_cnt_align = free_cnt - (free_cnt % txq->rs_thresh);
132 [ # # ]: 0 : for (i = 0; i < free_cnt_align; i += free_cnt_once) {
133 [ # # ]: 0 : if ((txq->ring_depth - txq->desc_free_num) < txq->rs_thresh)
134 : : break;
135 : :
136 [ # # ]: 0 : free_cnt_once = sxe2_tx_bufs_free(txq);
137 [ # # ]: 0 : if (free_cnt_once == 0)
138 : : break;
139 : : }
140 : :
141 : 0 : return i;
142 : : }
143 : :
144 : 0 : static int32_t sxe2_tx_done_cleanup_normal(struct sxe2_tx_queue *txq, uint32_t free_cnt)
145 : : {
146 : 0 : struct sxe2_tx_buffer *buffer_ring = txq->buffer_ring;
147 : 0 : int32_t ret;
148 : 0 : uint16_t clean_last_idx, clean_idx;
149 : 0 : uint16_t clean_last, clean_once;
150 : 0 : uint16_t pkt_cnt, i;
151 : :
152 [ # # # # ]: 0 : if (txq->desc_free_num == 0 && sxe2_tx_cleanup(txq) != 0) {
153 : 0 : ret = 0;
154 : 0 : goto l_end;
155 : : }
156 : :
157 [ # # ]: 0 : if (free_cnt == 0)
158 : 0 : free_cnt = txq->ring_depth;
159 : :
160 : 0 : clean_last_idx = txq->next_use;
161 : 0 : clean_idx = buffer_ring[clean_last_idx].next_id;
162 : 0 : clean_once = txq->desc_free_num;
163 : 0 : clean_last = txq->desc_free_num;
164 : :
165 [ # # ]: 0 : for (pkt_cnt = 0; pkt_cnt < free_cnt;) {
166 : 0 : for (i = 0; ((i < clean_once) &&
167 [ # # # # : 0 : (pkt_cnt < free_cnt) &&
# # ]
168 : 0 : clean_idx != clean_last_idx); ++i) {
169 [ # # ]: 0 : if (buffer_ring[clean_idx].mbuf != NULL) {
170 : 0 : rte_pktmbuf_free_seg(buffer_ring[clean_idx].mbuf);
171 : 0 : buffer_ring[clean_idx].mbuf = NULL;
172 [ # # ]: 0 : if (buffer_ring[clean_idx].last_id == clean_idx)
173 : 0 : pkt_cnt++;
174 : : }
175 : 0 : clean_idx = buffer_ring[clean_idx].next_id;
176 : : }
177 : :
178 [ # # # # ]: 0 : if ((txq->rs_thresh > (txq->ring_depth - txq->desc_free_num)) ||
179 : : clean_idx == clean_last_idx)
180 : : break;
181 : :
182 [ # # ]: 0 : if (pkt_cnt < free_cnt) {
183 [ # # ]: 0 : if (sxe2_tx_cleanup(txq) != 0)
184 : : break;
185 : :
186 : 0 : clean_once = txq->desc_free_num - clean_last;
187 : 0 : clean_last = txq->desc_free_num;
188 : : }
189 : : }
190 : :
191 : 0 : ret = pkt_cnt;
192 : 0 : l_end:
193 : 0 : return ret;
194 : : }
195 : :
196 : 0 : int32_t sxe2_tx_done_cleanup(void *tx_queue, uint32_t free_cnt)
197 : : {
198 : 0 : struct sxe2_tx_queue *txq = (struct sxe2_tx_queue *)tx_queue;
199 : 0 : struct sxe2_adapter *adapter;
200 : 0 : int32_t ret;
201 : :
202 [ # # ]: 0 : if (txq == NULL) {
203 : 0 : ret = 0;
204 : 0 : goto l_end;
205 : : }
206 : :
207 : 0 : adapter = txq->vsi->adapter;
208 [ # # ]: 0 : if (adapter->q_ctxt.tx_mode_flags & SXE2_TX_MODE_VEC_SET_MASK)
209 : : ret = -ENOTSUP;
210 [ # # ]: 0 : else if (adapter->q_ctxt.tx_mode_flags & SXE2_TX_MODE_SIMPLE_BATCH)
211 : 0 : ret = sxe2_tx_done_cleanup_simple(txq, free_cnt);
212 : : else
213 : 0 : ret = sxe2_tx_done_cleanup_normal(txq, free_cnt);
214 : :
215 : 0 : PMD_LOG_DEBUG(TX, "TX cleanup done desc queue_id=%u free_cnt=%d.",
216 : : txq->queue_id, ret);
217 : :
218 : 0 : l_end:
219 : 0 : return ret;
220 : : }
221 : :
222 : : static __rte_always_inline uint32_t
223 : : sxe2_tx_pkt_data_desc_count(struct rte_mbuf *tx_pkt)
224 : : {
225 : : struct rte_mbuf *m_seg = tx_pkt;
226 : : uint32_t count = 0;
227 : :
228 [ # # ]: 0 : while (m_seg != NULL) {
229 : 0 : count += SXE2_DIV_ROUND_UP(m_seg->data_len,
230 : : SXE2_TX_MAX_DATA_NUM_PER_DESC);
231 : 0 : m_seg = m_seg->next;
232 : : }
233 : :
234 : 0 : return count;
235 : : }
236 : :
237 : 0 : static __rte_always_inline void sxe2_tx_desc_tunneling_params_fill(uint64_t offloads,
238 : : union sxe2_tx_offload_info ol_info,
239 : : uint32_t *desc_tunneling_params)
240 : : {
241 : 0 : if (offloads & RTE_MBUF_F_TX_OUTER_IP_CKSUM)
242 : : *desc_tunneling_params |= SXE2_TX_CTXT_DESC_EIPT_IPV4;
243 [ # # ]: 0 : else if (offloads & RTE_MBUF_F_TX_OUTER_IPV4)
244 : : *desc_tunneling_params |= SXE2_TX_CTXT_DESC_EIPT_IPV4_NO_CSUM;
245 [ # # ]: 0 : else if (offloads & RTE_MBUF_F_TX_OUTER_IPV6)
246 : 0 : *desc_tunneling_params |= SXE2_TX_CTXT_DESC_EIPT_IPV6;
247 : :
248 : 0 : *desc_tunneling_params |=
249 : 0 : SXE2_TX_CTXT_DESC_EIPLEN_VAL(ol_info.outer_l3_len);
250 [ # # # # ]: 0 : switch (offloads & RTE_MBUF_F_TX_TUNNEL_MASK) {
251 : : case RTE_MBUF_F_TX_TUNNEL_IPIP:
252 : : break;
253 : 0 : case RTE_MBUF_F_TX_TUNNEL_VXLAN:
254 : : case RTE_MBUF_F_TX_TUNNEL_VXLAN_GPE:
255 : : case RTE_MBUF_F_TX_TUNNEL_GTP:
256 : : case RTE_MBUF_F_TX_TUNNEL_GENEVE:
257 : 0 : *desc_tunneling_params |= SXE2_TX_CTXT_DESC_UDP_TUNNE;
258 : 0 : break;
259 : 0 : case RTE_MBUF_F_TX_TUNNEL_GRE:
260 : 0 : *desc_tunneling_params |= SXE2_TX_CTXT_DESC_GRE_TUNNE;
261 : 0 : break;
262 : 0 : default:
263 : 0 : PMD_LOG_ERR(TX, "Tunnel type [0x%" PRIx64 "] is not supported.",
264 : : (uint64_t)(offloads & RTE_MBUF_F_TX_TUNNEL_MASK));
265 : 0 : return;
266 : : }
267 : 0 : *desc_tunneling_params |= SXE2_TX_CTXT_DESC_NATLEN_VAL(ol_info.l2_len);
268 : 0 : if (!(*desc_tunneling_params & SXE2_TX_CTXT_DESC_EIPT_NONE) &&
269 [ # # ]: 0 : (*desc_tunneling_params & SXE2_TX_CTXT_DESC_UDP_TUNNE) &&
270 [ # # ]: 0 : (offloads & RTE_MBUF_F_TX_OUTER_UDP_CKSUM)) {
271 : 0 : *desc_tunneling_params |= SXE2_TX_CTXT_DESC_L4T_CS_MASK;
272 : : }
273 : : }
274 : :
275 : : static __rte_always_inline void
276 : 0 : sxe2_tx_desc_checksum_fill(uint64_t offloads, uint32_t *desc_cmd, uint32_t *desc_offset,
277 : : union sxe2_tx_offload_info ol_info)
278 : : {
279 : 0 : if (offloads & RTE_MBUF_F_TX_IP_CKSUM) {
280 : 0 : *desc_cmd |= SXE2_TX_DATA_DESC_CMD_IIPT_IPV4_CSUM;
281 : 0 : *desc_offset |= SXE2_TX_DATA_DESC_IPLEN_VAL(ol_info.l3_len);
282 [ # # ]: 0 : } else if (offloads & RTE_MBUF_F_TX_IPV4) {
283 : 0 : *desc_cmd |= SXE2_TX_DATA_DESC_CMD_IIPT_IPV4;
284 : 0 : *desc_offset |= SXE2_TX_DATA_DESC_IPLEN_VAL(ol_info.l3_len);
285 [ # # ]: 0 : } else if (offloads & RTE_MBUF_F_TX_IPV6) {
286 : 0 : *desc_cmd |= SXE2_TX_DATA_DESC_CMD_IIPT_IPV6;
287 : 0 : *desc_offset |= SXE2_TX_DATA_DESC_IPLEN_VAL(ol_info.l3_len);
288 : : }
289 : :
290 [ # # ]: 0 : if (offloads & RTE_MBUF_F_TX_TCP_SEG) {
291 : 0 : *desc_cmd |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_TCP;
292 : 0 : *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
293 : 0 : goto l_end;
294 : : }
295 : :
296 [ # # ]: 0 : if (offloads & RTE_MBUF_F_TX_UDP_SEG) {
297 : 0 : *desc_cmd |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_UDP;
298 : 0 : *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
299 : 0 : goto l_end;
300 : : }
301 : :
302 [ # # # # ]: 0 : switch (offloads & RTE_MBUF_F_TX_L4_MASK) {
303 : 0 : case RTE_MBUF_F_TX_TCP_CKSUM:
304 : 0 : *desc_cmd |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_TCP;
305 : 0 : *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
306 : 0 : break;
307 : 0 : case RTE_MBUF_F_TX_SCTP_CKSUM:
308 : 0 : *desc_cmd |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_SCTP;
309 : 0 : *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
310 : 0 : break;
311 : 0 : case RTE_MBUF_F_TX_UDP_CKSUM:
312 : 0 : *desc_cmd |= SXE2_TX_DATA_DESC_CMD_L4T_EOFT_UDP;
313 : 0 : *desc_offset |= SXE2_TX_DATA_DESC_L4LEN_VAL(ol_info.l4_len);
314 : 0 : break;
315 : : default:
316 : :
317 : : break;
318 : : }
319 : :
320 : 0 : l_end:
321 : 0 : return;
322 : : }
323 : :
324 : 0 : static __rte_always_inline void sxe2_desc_tso_fill(struct rte_mbuf *tx_pkt,
325 : : uint64_t *desc_type_cmd_tso_mss,
326 : : union sxe2_tx_offload_info ol_info)
327 : : {
328 : 0 : uint32_t hdr_len;
329 : 0 : uint32_t tso_len;
330 : :
331 : 0 : if (!ol_info.l4_len) {
332 : 0 : PMD_LOG_DEBUG(TX, "TSO ERROR: L4 length is 0");
333 : 0 : goto l_end;
334 : : }
335 : 0 : hdr_len = ol_info.l2_len + ol_info.l3_len + ol_info.l4_len;
336 [ # # ]: 0 : if (tx_pkt->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK)
337 : 0 : hdr_len += ol_info.outer_l2_len + ol_info.outer_l3_len;
338 : :
339 : 0 : tso_len = tx_pkt->pkt_len - hdr_len;
340 : 0 : *desc_type_cmd_tso_mss |=
341 : : ((uint64_t)SXE2_TX_CTXT_DESC_CMD_TSO << SXE2_TX_CTXT_DESC_CMD_SHIFT) |
342 : 0 : ((uint64_t)tso_len << SXE2_TX_CTXT_DESC_TSO_LEN_SHIFT) |
343 : 0 : ((uint64_t)tx_pkt->tso_segsz << SXE2_TX_CTXT_DESC_MSS_SHIFT);
344 : 0 : l_end:
345 : 0 : return;
346 : : }
347 : :
348 : 0 : static __rte_always_inline void sxe2_desc_ipsec_fill(struct rte_mbuf *tx_pkt,
349 : : struct sxe2_tx_queue *txq, uint16_t *ipsec_offset,
350 : : uint64_t *desc_type_cmd_tso_mss)
351 : : {
352 : 0 : struct sxe2_ipsec_pkt_metadata *md = NULL;
353 : 0 : uint16_t ipsec_pkt_md_offset = txq->ipsec_pkt_md_offset;
354 : :
355 : 0 : md = RTE_MBUF_DYNFIELD(tx_pkt, ipsec_pkt_md_offset, struct sxe2_ipsec_pkt_metadata *);
356 : 0 : *ipsec_offset = md->esp_head_offset;
357 : 0 : *desc_type_cmd_tso_mss |= SXE2_TX_CTXT_DESC_IPSEC_EN;
358 : 0 : if (md->mode == SXE2_IPSEC_MODE_ONLY_ENCRYPT)
359 : 0 : *desc_type_cmd_tso_mss |= SXE2_TX_CTXT_DESC_IPSEC_MODE;
360 : :
361 [ # # ]: 0 : if (md->algo == SXE2_IPSEC_ALGO_SM4_CBC_AND_SM3_96_HMAC)
362 : 0 : *desc_type_cmd_tso_mss |= SXE2_TX_CTXT_DESC_IPSEC_ENGINE;
363 : :
364 : 0 : *desc_type_cmd_tso_mss |= (uint64_t)(md->sa_idx) << SXE2_TX_CTXT_DESC_IPSEC_SA_SHIFT;
365 : 0 : }
366 : :
367 : : static __rte_always_inline uint64_t
368 : 0 : sxe2_tx_data_desc_build_cobt(uint32_t cmd, uint32_t offset, uint16_t buf_size, uint16_t l2tag)
369 : : {
370 : 0 : return rte_cpu_to_le_64(SXE2_TX_DESC_DTYPE_DATA |
371 : : (((uint64_t)cmd) << SXE2_TX_DATA_DESC_CMD_SHIFT) |
372 : : (((uint64_t)offset) << SXE2_TX_DATA_DESC_OFFSET_SHIFT) |
373 : : (((uint64_t)buf_size) << SXE2_TX_DATA_DESC_BUF_SZ_SHIFT) |
374 : : (((uint64_t)l2tag) << SXE2_TX_DATA_DESC_L2TAG1_SHIFT));
375 : : }
376 : :
377 : 0 : uint16_t sxe2_tx_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
378 : : {
379 : 0 : struct sxe2_tx_queue *txq = tx_queue;
380 : 0 : struct sxe2_tx_buffer *buffer_ring;
381 : 0 : struct sxe2_tx_buffer *buffer;
382 : 0 : struct sxe2_tx_buffer *next_buffer;
383 : 0 : struct rte_mbuf *tx_pkt;
384 : 0 : struct rte_mbuf *m_seg;
385 : 0 : volatile union sxe2_tx_data_desc *desc_ring;
386 : 0 : volatile union sxe2_tx_data_desc *desc;
387 : 0 : volatile struct sxe2_tx_context_desc *ctxt_desc;
388 : 0 : union sxe2_tx_offload_info ol_info;
389 : 0 : struct sxe2_vsi *vsi = txq->vsi;
390 : 0 : rte_iova_t buf_dma_addr;
391 : 0 : uint64_t offloads;
392 : 0 : uint64_t desc_type_cmd_tso_mss;
393 : 0 : uint32_t desc_cmd;
394 : 0 : uint32_t desc_offset;
395 : 0 : uint32_t desc_tag;
396 : 0 : uint32_t desc_tunneling_params;
397 : 0 : uint16_t ipsec_offset;
398 : 0 : uint16_t ctxt_desc_num;
399 : 0 : uint32_t desc_sum_num;
400 : 0 : uint16_t tx_num;
401 : 0 : uint16_t seg_len;
402 : 0 : uint16_t next_use;
403 : 0 : uint16_t last_use;
404 : 0 : uint16_t desc_l2tag2;
405 : :
406 : 0 : buffer_ring = txq->buffer_ring;
407 : 0 : desc_ring = txq->desc_ring;
408 : 0 : next_use = txq->next_use;
409 : 0 : buffer = &buffer_ring[next_use];
410 : :
411 [ # # ]: 0 : if (txq->desc_free_num < txq->free_thresh)
412 : 0 : (void)sxe2_tx_cleanup(txq);
413 : :
414 [ # # ]: 0 : for (tx_num = 0; tx_num < nb_pkts; tx_num++) {
415 : 0 : tx_pkt = *tx_pkts++;
416 : 0 : desc_cmd = 0;
417 : 0 : desc_offset = 0;
418 : 0 : desc_tag = 0;
419 : 0 : desc_tunneling_params = 0;
420 : 0 : ipsec_offset = 0;
421 : 0 : offloads = tx_pkt->ol_flags;
422 : 0 : ol_info.l2_len = tx_pkt->l2_len;
423 : 0 : ol_info.l3_len = tx_pkt->l3_len;
424 : 0 : ol_info.l4_len = tx_pkt->l4_len;
425 : 0 : ol_info.tso_segsz = tx_pkt->tso_segsz;
426 : 0 : ol_info.outer_l2_len = tx_pkt->outer_l2_len;
427 : 0 : ol_info.outer_l3_len = tx_pkt->outer_l3_len;
428 : :
429 : 0 : ctxt_desc_num = (offloads &
430 : 0 : SXE2_TX_OFFLOAD_CTXT_NEEDCK_MASK) ? 1 : 0;
431 [ # # ]: 0 : if (unlikely(vsi->vsi_type == SXE2_VSI_T_DPDK_ESW))
432 : 0 : ctxt_desc_num = 1;
433 : :
434 [ # # ]: 0 : if (offloads & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG))
435 : 0 : desc_sum_num = sxe2_tx_pkt_data_desc_count(tx_pkt) + ctxt_desc_num;
436 : : else
437 : 0 : desc_sum_num = tx_pkt->nb_segs + ctxt_desc_num;
438 : :
439 : 0 : last_use = next_use + desc_sum_num - 1;
440 [ # # ]: 0 : if (last_use >= txq->ring_depth)
441 : 0 : last_use = last_use - txq->ring_depth;
442 : :
443 [ # # ]: 0 : if (desc_sum_num > txq->desc_free_num) {
444 [ # # ]: 0 : if (unlikely(sxe2_tx_cleanup(txq) != 0))
445 : 0 : goto l_cleanup_exit;
446 : :
447 [ # # ]: 0 : if (unlikely(desc_sum_num > txq->rs_thresh)) {
448 [ # # ]: 0 : while (desc_sum_num > txq->desc_free_num) {
449 [ # # ]: 0 : if (unlikely(sxe2_tx_cleanup(txq) != 0))
450 : 0 : goto l_cleanup_exit;
451 : : }
452 : : }
453 : : }
454 : :
455 [ # # # # ]: 0 : if ((offloads & RTE_MBUF_F_TX_TUNNEL_MASK) && ctxt_desc_num) {
456 : 0 : desc_offset |= SXE2_TX_DATA_DESC_MACLEN_VAL(ol_info.outer_l2_len);
457 [ # # ]: 0 : sxe2_tx_desc_tunneling_params_fill(offloads, ol_info,
458 : : &desc_tunneling_params);
459 : : } else {
460 : 0 : desc_offset |= SXE2_TX_DATA_DESC_MACLEN_VAL(ol_info.l2_len);
461 : : }
462 : :
463 [ # # ]: 0 : if (offloads & SXE2_TX_OFFLOAD_CKSUM_MASK) {
464 [ # # ]: 0 : sxe2_tx_desc_checksum_fill(offloads, &desc_cmd,
465 : : &desc_offset, ol_info);
466 : : }
467 : :
468 [ # # ]: 0 : if (offloads & (RTE_MBUF_F_TX_VLAN | RTE_MBUF_F_TX_QINQ)) {
469 : 0 : desc_cmd |= SXE2_TX_DATA_DESC_CMD_IL2TAG1;
470 : 0 : desc_tag = tx_pkt->vlan_tci;
471 : : }
472 : :
473 [ # # ]: 0 : if (ctxt_desc_num) {
474 : 0 : ctxt_desc = (volatile struct sxe2_tx_context_desc *)
475 : 0 : &desc_ring[next_use];
476 : 0 : desc_l2tag2 = 0;
477 : 0 : desc_type_cmd_tso_mss = SXE2_TX_DESC_DTYPE_CTXT;
478 : :
479 : 0 : next_buffer = &buffer_ring[buffer->next_id];
480 [ # # ]: 0 : RTE_MBUF_PREFETCH_TO_FREE(next_buffer->mbuf);
481 : :
482 [ # # ]: 0 : if (buffer->mbuf) {
483 [ # # ]: 0 : rte_pktmbuf_free_seg(buffer->mbuf);
484 : 0 : buffer->mbuf = NULL;
485 : : }
486 [ # # ]: 0 : if (offloads & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG))
487 [ # # ]: 0 : sxe2_desc_tso_fill(tx_pkt,
488 : : &desc_type_cmd_tso_mss, ol_info);
489 [ # # ]: 0 : else if (offloads & RTE_MBUF_F_TX_IEEE1588_TMST)
490 : 0 : desc_type_cmd_tso_mss |= SXE2_TX_CTXT_DESC_CMD_TSYN_MASK;
491 : :
492 [ # # ]: 0 : if (offloads & RTE_MBUF_F_TX_SEC_OFFLOAD) {
493 [ # # ]: 0 : sxe2_desc_ipsec_fill(tx_pkt, txq, &ipsec_offset,
494 : : &desc_type_cmd_tso_mss);
495 : : }
496 : :
497 [ # # ]: 0 : if (offloads & RTE_MBUF_F_TX_QINQ) {
498 : 0 : desc_l2tag2 = tx_pkt->vlan_tci_outer;
499 : 0 : desc_type_cmd_tso_mss |= SXE2_TX_CTXT_DESC_CMD_IL2TAG2_MASK;
500 : : }
501 [ # # ]: 0 : if (unlikely(vsi->vsi_type == SXE2_VSI_T_DPDK_ESW)) {
502 : 0 : desc_type_cmd_tso_mss |=
503 : : (SXE2_TX_CTXT_DESC_CMD_SWTCH_VSI <<
504 : : SXE2_TX_CTXT_DESC_CMD_SHIFT);
505 : 0 : desc_type_cmd_tso_mss |=
506 : 0 : ((vsi->adapter->repr_priv_data->repr_vf_vsi_id & 0x3FFULL)
507 : 0 : << SXE2_TX_CTXT_DESC_VSI_SHIFT);
508 : : }
509 : :
510 : 0 : ctxt_desc->tunneling_params =
511 : : rte_cpu_to_le_32(desc_tunneling_params);
512 : 0 : ctxt_desc->l2tag2 = rte_cpu_to_le_16(desc_l2tag2);
513 : 0 : ctxt_desc->type_cmd_tso_mss = rte_cpu_to_le_64(desc_type_cmd_tso_mss);
514 : 0 : ctxt_desc->ipsec_offset = rte_cpu_to_le_16(ipsec_offset);
515 : :
516 : 0 : buffer->last_id = last_use;
517 : 0 : next_use = buffer->next_id;
518 : 0 : buffer = next_buffer;
519 : : }
520 : :
521 : : m_seg = tx_pkt;
522 : :
523 : 0 : do {
524 : 0 : desc = &desc_ring[next_use];
525 : 0 : next_buffer = &buffer_ring[buffer->next_id];
526 [ # # ]: 0 : RTE_MBUF_PREFETCH_TO_FREE(next_buffer->mbuf);
527 [ # # ]: 0 : if (buffer->mbuf) {
528 [ # # ]: 0 : rte_pktmbuf_free_seg(buffer->mbuf);
529 : 0 : buffer->mbuf = NULL;
530 : : }
531 : :
532 : 0 : buffer->mbuf = m_seg;
533 : 0 : seg_len = m_seg->data_len;
534 : 0 : buf_dma_addr = rte_mbuf_data_iova(m_seg);
535 : 0 : while ((offloads & (RTE_MBUF_F_TX_TCP_SEG | RTE_MBUF_F_TX_UDP_SEG)) &&
536 [ # # ]: 0 : unlikely(seg_len > SXE2_TX_MAX_DATA_NUM_PER_DESC)) {
537 : 0 : desc->read.buf_addr = rte_cpu_to_le_64(buf_dma_addr);
538 : 0 : desc->read.type_cmd_off_bsz_l2t =
539 : 0 : sxe2_tx_data_desc_build_cobt(desc_cmd, desc_offset,
540 : : SXE2_TX_MAX_DATA_NUM_PER_DESC,
541 : : desc_tag);
542 : 0 : buf_dma_addr += SXE2_TX_MAX_DATA_NUM_PER_DESC;
543 : 0 : seg_len -= SXE2_TX_MAX_DATA_NUM_PER_DESC;
544 : 0 : buffer->last_id = last_use;
545 : 0 : next_use = buffer->next_id;
546 : 0 : buffer = next_buffer;
547 : 0 : desc = &desc_ring[next_use];
548 : 0 : next_buffer = &buffer_ring[buffer->next_id];
549 [ # # # # ]: 0 : RTE_MBUF_PREFETCH_TO_FREE(next_buffer->mbuf);
550 : : }
551 : :
552 : 0 : desc->read.buf_addr = rte_cpu_to_le_64(buf_dma_addr);
553 : 0 : desc->read.type_cmd_off_bsz_l2t =
554 : 0 : sxe2_tx_data_desc_build_cobt(desc_cmd,
555 : : desc_offset, seg_len, desc_tag);
556 : :
557 : 0 : buffer->last_id = last_use;
558 : 0 : next_use = buffer->next_id;
559 : 0 : buffer = next_buffer;
560 : :
561 : 0 : m_seg = m_seg->next;
562 [ # # ]: 0 : } while (m_seg);
563 : :
564 : 0 : desc_cmd |= SXE2_TX_DATA_DESC_CMD_EOP;
565 : 0 : txq->desc_used_num += desc_sum_num;
566 : 0 : txq->desc_free_num -= desc_sum_num;
567 : :
568 [ # # ]: 0 : if (txq->desc_used_num >= txq->rs_thresh) {
569 : 0 : PMD_LOG_DEBUG(TX, "Tx pkts set RS bit."
570 : : "last_use=%u port_id=%u, queue_id=%u",
571 : : last_use, txq->port_id, txq->queue_id);
572 : 0 : desc_cmd |= SXE2_TX_DATA_DESC_CMD_RS;
573 : 0 : txq->desc_used_num = 0;
574 : : }
575 : :
576 : 0 : desc->read.type_cmd_off_bsz_l2t |=
577 : 0 : rte_cpu_to_le_64(((uint64_t)desc_cmd) << SXE2_TX_DATA_DESC_CMD_SHIFT);
578 : : }
579 : 0 : goto l_end_of_tx;
580 : :
581 : 0 : l_cleanup_exit:
582 [ # # ]: 0 : if (tx_num == 0)
583 : : return 0;
584 : 0 : l_end_of_tx:
585 : 0 : SXE2_PCI_REG_WRITE_WC(txq->tdt_reg_addr, next_use);
586 : 0 : PMD_LOG_DEBUG(TX, "port_id=%u queue_id=%u next_use=%u send_pkts=%u",
587 : : txq->port_id, txq->queue_id, next_use, tx_num);
588 : :
589 : 0 : txq->next_use = next_use;
590 : 0 : return tx_num;
591 : : }
592 : :
593 : : static __rte_always_inline void
594 : 0 : sxe2_tx_data_desc_fill(volatile union sxe2_tx_data_desc *desc,
595 : : struct rte_mbuf **tx_pkts)
596 : : {
597 : 0 : rte_iova_t buf_dma_addr;
598 : 0 : uint32_t desc_offset;
599 : 0 : buf_dma_addr = rte_mbuf_data_iova(*tx_pkts);
600 : 0 : desc->read.buf_addr = rte_cpu_to_le_64(buf_dma_addr);
601 : 0 : desc_offset = SXE2_TX_DATA_DESC_MACLEN_VAL((*tx_pkts)->l2_len);
602 : 0 : desc->read.type_cmd_off_bsz_l2t =
603 : 0 : sxe2_tx_data_desc_build_cobt(SXE2_TX_DATA_DESC_CMD_EOP,
604 : 0 : desc_offset, (*tx_pkts)->data_len, 0);
605 : : }
606 : : static __rte_always_inline void
607 : 0 : sxe2_tx_data_desc_fill_batch(volatile union sxe2_tx_data_desc *desc,
608 : : struct rte_mbuf **tx_pkts)
609 : : {
610 : 0 : rte_iova_t buf_dma_addr;
611 : 0 : uint32_t i;
612 : 0 : uint32_t desc_offset;
613 [ # # ]: 0 : for (i = 0; i < SXE2_TX_FILL_PER_LOOP; ++i, ++desc, ++tx_pkts) {
614 : 0 : buf_dma_addr = rte_mbuf_data_iova(*tx_pkts);
615 : 0 : desc->read.buf_addr = rte_cpu_to_le_64(buf_dma_addr);
616 : 0 : desc_offset = SXE2_TX_DATA_DESC_MACLEN_VAL((*tx_pkts)->l2_len);
617 : 0 : desc->read.type_cmd_off_bsz_l2t =
618 : 0 : sxe2_tx_data_desc_build_cobt(SXE2_TX_DATA_DESC_CMD_EOP,
619 : : desc_offset,
620 : 0 : (*tx_pkts)->data_len,
621 : : 0);
622 : : }
623 : : }
624 : :
625 : 0 : static inline void sxe2_tx_ring_fill(struct sxe2_tx_queue *txq,
626 : : struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
627 : : {
628 : 0 : struct sxe2_tx_buffer *buffer = &txq->buffer_ring[txq->next_use];
629 : 0 : volatile union sxe2_tx_data_desc *desc = &txq->desc_ring[txq->next_use];
630 : 0 : uint32_t i, j;
631 : 0 : uint32_t mainpart;
632 : 0 : uint32_t leftover;
633 : 0 : mainpart = nb_pkts & ((uint32_t)~SXE2_TX_FILL_PER_LOOP_MASK);
634 : 0 : leftover = nb_pkts & ((uint32_t)SXE2_TX_FILL_PER_LOOP_MASK);
635 [ # # ]: 0 : for (i = 0; i < mainpart; i += SXE2_TX_FILL_PER_LOOP) {
636 [ # # ]: 0 : for (j = 0; j < SXE2_TX_FILL_PER_LOOP; ++j)
637 : 0 : (buffer + i + j)->mbuf = *(tx_pkts + i + j);
638 : 0 : sxe2_tx_data_desc_fill_batch(desc + i, tx_pkts + i);
639 : : }
640 [ # # ]: 0 : if (unlikely(leftover > 0)) {
641 [ # # ]: 0 : for (i = 0; i < leftover; ++i) {
642 : 0 : (buffer + mainpart + i)->mbuf = *(tx_pkts + mainpart + i);
643 : 0 : sxe2_tx_data_desc_fill(desc + mainpart + i,
644 : : tx_pkts + mainpart + i);
645 : : }
646 : : }
647 : 0 : }
648 : :
649 : 0 : static inline uint16_t sxe2_tx_pkts_batch(void *tx_queue,
650 : : struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
651 : : {
652 : 0 : struct sxe2_tx_queue *txq = (struct sxe2_tx_queue *)tx_queue;
653 : 0 : volatile union sxe2_tx_data_desc *desc_ring = txq->desc_ring;
654 : 0 : uint16_t res_num = 0;
655 [ # # ]: 0 : if (txq->desc_free_num < txq->free_thresh)
656 [ # # ]: 0 : (void)sxe2_tx_bufs_free(txq);
657 : 0 : nb_pkts = RTE_MIN(txq->desc_free_num, nb_pkts);
658 [ # # ]: 0 : if (unlikely(nb_pkts == 0)) {
659 : 0 : PMD_LOG_DEBUG(TX, "Tx batch: may not enough free desc, "
660 : : "free_desc=%u, need_tx_pkts=%u",
661 : : txq->desc_free_num, nb_pkts);
662 : 0 : goto l_end;
663 : : }
664 : 0 : txq->desc_free_num -= nb_pkts;
665 [ # # ]: 0 : if ((txq->next_use + nb_pkts) > txq->ring_depth) {
666 : 0 : res_num = txq->ring_depth - txq->next_use;
667 : 0 : sxe2_tx_ring_fill(txq, tx_pkts, res_num);
668 : 0 : desc_ring[txq->next_rs].read.type_cmd_off_bsz_l2t |=
669 : : rte_cpu_to_le_64(SXE2_TX_DATA_DESC_CMD_RS_MASK);
670 : 0 : txq->next_rs = txq->rs_thresh - 1;
671 : 0 : txq->next_use = 0;
672 : : }
673 : 0 : sxe2_tx_ring_fill(txq, tx_pkts + res_num, nb_pkts - res_num);
674 : 0 : txq->next_use = txq->next_use + (nb_pkts - res_num);
675 [ # # ]: 0 : if (txq->next_use > txq->next_rs) {
676 : 0 : desc_ring[txq->next_rs].read.type_cmd_off_bsz_l2t |=
677 : : rte_cpu_to_le_64(SXE2_TX_DATA_DESC_CMD_RS_MASK);
678 : 0 : txq->next_rs += txq->rs_thresh;
679 [ # # ]: 0 : if (txq->next_rs >= txq->ring_depth)
680 : 0 : txq->next_rs = txq->rs_thresh - 1;
681 : : }
682 [ # # ]: 0 : if (txq->next_use >= txq->ring_depth)
683 : 0 : txq->next_use = 0;
684 : 0 : PMD_LOG_DEBUG(TX, "port_id=%u queue_id=%u next_use=%u send_pkts=%u",
685 : : txq->port_id, txq->queue_id, txq->next_use, nb_pkts);
686 : 0 : SXE2_PCI_REG_WRITE_WC(txq->tdt_reg_addr, txq->next_use);
687 : 0 : l_end:
688 : 0 : return nb_pkts;
689 : : }
690 : :
691 : 0 : uint16_t sxe2_tx_pkts_simple(void *tx_queue,
692 : : struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
693 : : {
694 : 0 : uint16_t tx_done_num;
695 : 0 : uint16_t tx_once_num;
696 : 0 : uint16_t tx_need_num;
697 [ # # ]: 0 : if (likely(nb_pkts <= SXE2_TX_PKTS_BURST_BATCH_NUM)) {
698 : 0 : tx_done_num = sxe2_tx_pkts_batch(tx_queue,
699 : : tx_pkts, nb_pkts);
700 : 0 : goto l_end;
701 : : }
702 : : tx_done_num = 0;
703 [ # # ]: 0 : while (nb_pkts) {
704 : 0 : tx_need_num = RTE_MIN(nb_pkts, SXE2_TX_PKTS_BURST_BATCH_NUM);
705 : 0 : tx_once_num = sxe2_tx_pkts_batch(tx_queue,
706 : 0 : &tx_pkts[tx_done_num],
707 : : tx_need_num);
708 : 0 : nb_pkts -= tx_once_num;
709 : 0 : tx_done_num += tx_once_num;
710 [ # # ]: 0 : if (tx_once_num < tx_need_num)
711 : : break;
712 : : }
713 : 0 : l_end:
714 : 0 : return tx_done_num;
715 : : }
716 : :
717 : : static inline void
718 : 0 : sxe2_update_rx_tail(struct sxe2_rx_queue *rxq, uint16_t hold_num, uint16_t rx_id)
719 : : {
720 : 0 : hold_num += rxq->hold_num;
721 : :
722 [ # # ]: 0 : if (hold_num > rxq->rx_free_thresh) {
723 [ # # ]: 0 : rx_id = (uint16_t)((rx_id == 0) ? (rxq->ring_depth - 1) : (rx_id - 1));
724 : 0 : SXE2_PCI_REG_WRITE_WC(rxq->rdt_reg_addr, rx_id);
725 : : hold_num = 0;
726 : : }
727 : 0 : rxq->hold_num = hold_num;
728 : 0 : }
729 : :
730 : : static inline uint64_t
731 : 0 : sxe2_rx_desc_error_para(__rte_unused struct sxe2_rx_queue *rxq,
732 : : union sxe2_rx_desc *desc)
733 : : {
734 : 0 : uint64_t flags = 0;
735 : 0 : uint64_t desc_qw1 = rte_le_to_cpu_64(desc->wb.status_err_ptype_len);
736 : :
737 [ # # ]: 0 : if (unlikely(0 == (desc_qw1 & SXE2_RX_DESC_STATUS_L3L4_P_MASK)))
738 : 0 : goto l_end;
739 : :
740 [ # # ]: 0 : if (likely(0 == (desc->wb.rxdid_src & SXE2_RX_DESC_EUDPE_MASK)))
741 : : flags = RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD;
742 : : else
743 : 0 : flags = RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD;
744 : :
745 [ # # ]: 0 : if (likely(0 == (desc_qw1 & SXE2_RX_DESC_QW1_ERRORS_MASK))) {
746 : 0 : flags |= (RTE_MBUF_F_RX_IP_CKSUM_GOOD |
747 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD |
748 : : RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD);
749 : 0 : goto l_end;
750 : : }
751 : :
752 [ # # ]: 0 : if (likely(0 == (desc_qw1 & SXE2_RX_DESC_ERROR_CSUM_IPE_MASK)))
753 : 0 : flags |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
754 : : else
755 : 0 : flags |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
756 : :
757 [ # # ]: 0 : if (likely(0 == (desc_qw1 & SXE2_RX_DESC_ERROR_CSUM_L4_MASK)))
758 : 0 : flags |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
759 : : else
760 : 0 : flags |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
761 : :
762 [ # # ]: 0 : if (unlikely(0 != (desc_qw1 & SXE2_RX_DESC_ERROR_CSUM_EIP_MASK)))
763 : 0 : flags |= RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD;
764 : :
765 : 0 : l_end:
766 : 0 : return flags;
767 : : }
768 : :
769 : 0 : static inline void sxe2_rx_desc_vlan_para_fill(struct rte_mbuf *mbuf,
770 : : union sxe2_rx_desc *desc)
771 : : {
772 [ # # ]: 0 : if (0 == (rte_le_to_cpu_64(desc->wb.status_err_ptype_len) &
773 : : SXE2_RX_DESC_STATUS_L2TAG1_P_MASK)) {
774 : 0 : mbuf->vlan_tci = 0;
775 : : } else {
776 : 0 : mbuf->ol_flags |= (RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED);
777 : 0 : mbuf->vlan_tci = rte_le_to_cpu_16(desc->wb.l2tag1);
778 : 0 : PMD_LOG_DEBUG(RX, "Rx desc mbuf vlan, vlan_tci:%u",
779 : : mbuf->vlan_tci);
780 : : }
781 : : #ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
782 [ # # ]: 0 : if (0 == (rte_le_to_cpu_32(desc->wb.status_lrocnt_fdpf_id) &
783 : : SXE2_RX_DESC_EXT_STATUS_L2TAG2P_MASK)) {
784 : 0 : mbuf->vlan_tci_outer = 0;
785 : : } else {
786 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_QINQ_STRIPPED | RTE_MBUF_F_RX_QINQ |
787 : : RTE_MBUF_F_RX_VLAN_STRIPPED | RTE_MBUF_F_RX_VLAN;
788 : 0 : mbuf->vlan_tci_outer = mbuf->vlan_tci;
789 : 0 : mbuf->vlan_tci = rte_le_to_cpu_16(desc->wb.l2tag2_2nd);
790 : 0 : PMD_LOG_DEBUG(RX, "Rx desc out vlan, l2tag2_1st:%u l2tag2_2nd:%u.",
791 : : rte_le_to_cpu_16(desc->wb.l2tag2_1st),
792 : : rte_le_to_cpu_16(desc->wb.l2tag2_2nd));
793 : : }
794 : : #endif
795 : 0 : }
796 : :
797 : : static inline void
798 : 0 : sxe2_rx_desc_filter_para_fill(struct sxe2_rx_queue *rxq __rte_unused,
799 : : struct rte_mbuf *mbuf, union sxe2_rx_desc *desc)
800 : : {
801 : 0 : if (SXE2_RX_DESC_STATUS_RSS_VLD_MASK &
802 [ # # ]: 0 : rte_le_to_cpu_64(desc->wb.status_err_ptype_len)) {
803 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
804 : 0 : mbuf->hash.rss = rte_le_to_cpu_32(desc->wb.filter_status);
805 : 0 : PMD_LOG_DEBUG(RX, "rss id:%u", mbuf->hash.rss);
806 : : }
807 : : #ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
808 [ # # ]: 0 : if (SXE2_RX_DESC_FD_VLD_MASK & desc->wb.rxdid_src) {
809 : 0 : mbuf->ol_flags |= (RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID);
810 : 0 : mbuf->hash.fdir.hi = rte_le_to_cpu_32(desc->wb.fd_filter_id);
811 : 0 : PMD_LOG_DEBUG(RX, "fdir id:%u", mbuf->hash.fdir.hi);
812 : : }
813 : : #endif
814 : 0 : }
815 : :
816 : : #ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
817 : 0 : int32_t sxe2_rx_update_ptp_time(struct sxe2_rx_queue *rxq)
818 : : {
819 : 0 : struct sxe2_adapter *adapter;
820 : 0 : uint64_t cur_time_ms;
821 : 0 : int32_t ret = 0;
822 : 0 : cur_time_ms = rte_get_timer_cycles() / (rte_get_timer_hz() / 1000);
823 : :
824 [ # # ]: 0 : if (likely((cur_time_ms - rxq->update_time) < SXE2_RX_PKTS_TS_TIMEOUT_VAL))
825 : 0 : goto l_end;
826 : 0 : rxq->update_time = cur_time_ms;
827 : 0 : adapter = rxq->vsi->adapter;
828 : 0 : rxq->ts_need_update = true;
829 : 0 : ret = sxe2_drv_ptp_gettime(adapter, rxq);
830 [ # # ]: 0 : if (rxq->desc_ts < rxq->ts_low)
831 : 0 : rxq->ts_need_update = false;
832 : :
833 : 0 : PMD_LOG_INFO(RX, "rxq update time ret=%d, cur time=%" PRIu64 ", rxqh=%" PRIu64 ", rxql=%d",
834 : : ret, cur_time_ms, rxq->ts_high, rxq->ts_low);
835 : 0 : l_end:
836 : 0 : return ret;
837 : : }
838 : :
839 : 0 : static inline void sxe2_rx_desc_ptp_para_fill(struct sxe2_rx_queue *rxq,
840 : : struct rte_mbuf *mbuf,
841 : : union sxe2_rx_desc *desc)
842 : : {
843 : 0 : struct sxe2_adapter *adapter = rxq->vsi->adapter;
844 : 0 : uint64_t ts_ns;
845 : :
846 [ # # ]: 0 : if (adapter->ptp_ctxt.mbuf_rx_ts_flag != 0 &&
847 [ # # ]: 0 : (rxq->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) &&
848 [ # # ]: 0 : SXE2_RX_DESC_RXDID_VAL_GET(desc->wb.rxdid_src) == SXE2_RX_DESC_RXDID_1588) {
849 : 0 : rxq->desc_ts = rte_le_to_cpu_32(desc->wb_ts.ts_h);
850 : 0 : (void)sxe2_rx_update_ptp_time(rxq);
851 [ # # # # ]: 0 : if (rxq->ts_need_update && rxq->desc_ts < rxq->ts_low)
852 : 0 : rxq->ts_high += 1;
853 : :
854 : 0 : rxq->ts_need_update = true;
855 : 0 : rxq->ts_low = rxq->desc_ts;
856 : 0 : rxq->update_time = rte_get_timer_cycles() /
857 : 0 : (rte_get_timer_hz() / 1000);
858 : 0 : ts_ns = rxq->ts_high * NSEC_PER_SEC + rxq->ts_low;
859 : 0 : *RTE_MBUF_DYNFIELD(mbuf, adapter->ptp_ctxt.mbuf_rx_ts_offset, uint64_t *) = ts_ns;
860 : 0 : mbuf->ol_flags |= adapter->ptp_ctxt.mbuf_rx_ts_flag;
861 : 0 : PMD_LOG_INFO(RX, "receive ptp pkt,ts_s=%" PRIu64 ", ts_ns=%d", rxq->ts_high,
862 : : rxq->ts_low);
863 : : }
864 : 0 : }
865 : :
866 : 0 : static inline void sxe2_rx_desc_ipsec_para_fill(struct sxe2_rx_queue *rxq __rte_unused,
867 : : struct rte_mbuf *mbuf, union sxe2_rx_desc *desc)
868 : : {
869 : 0 : uint32_t status_lrocnt_fdpf_id = rte_le_to_cpu_32(desc->wb.status_lrocnt_fdpf_id);
870 : 0 : enum sxe2_rx_desc_ipsec_status ipsec_status;
871 : :
872 [ # # ]: 0 : if (status_lrocnt_fdpf_id & SXE2_RX_DESC_IPSEC_PKT_MASK) {
873 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD;
874 : 0 : ipsec_status = SXE2_RX_DESC_IPSEC_STATUS_VAL_GET(status_lrocnt_fdpf_id);
875 [ # # ]: 0 : switch (ipsec_status) {
876 : : case SXE2_RX_DESC_IPSEC_STATUS_SUCCESS:
877 : : break;
878 : 0 : case SXE2_RX_DESC_IPSEC_STATUS_PKG_OVER_2K:
879 : : case SXE2_RX_DESC_IPSEC_STATUS_SPI_IP_INVALID:
880 : : case SXE2_RX_DESC_IPSEC_STATUS_SA_INVALID:
881 : : case SXE2_RX_DESC_IPSEC_STATUS_NOT_ALIGN:
882 : : case SXE2_RX_DESC_IPSEC_STATUS_ICV_ERROR:
883 : : case SXE2_RX_DESC_IPSEC_STATUS_BY_PASSH:
884 : : case SXE2_RX_DESC_IPSEC_STATUS_MAC_BY_PASSH:
885 : 0 : PMD_LOG_INFO(RX, "IPsec status error:%d", ipsec_status);
886 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
887 : 0 : break;
888 : : default:
889 : : PMD_LOG_INFO(RX, "Invalid ipsec status:%d", ipsec_status);
890 : : mbuf->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
891 : : break;
892 : : }
893 : : }
894 : 0 : }
895 : : #endif
896 : :
897 : : static __rte_always_inline void
898 : 0 : sxe2_rx_mbuf_common_fields_fill(struct sxe2_rx_queue *rxq, struct rte_mbuf *mbuf,
899 : : union sxe2_rx_desc *rxd)
900 : : {
901 : 0 : uint64_t qword1;
902 : 0 : uint64_t pkt_flags;
903 : 0 : qword1 = rte_le_to_cpu_64(rxd->wb.status_err_ptype_len);
904 : :
905 : 0 : mbuf->ol_flags = 0;
906 : 0 : mbuf->packet_type = sxe2_ptype_tbl[SXE2_RX_DESC_PTYPE_VAL_GET(qword1)];
907 : 0 : pkt_flags = sxe2_rx_desc_error_para(rxq, rxd);
908 : 0 : sxe2_rx_desc_vlan_para_fill(mbuf, rxd);
909 : 0 : sxe2_rx_desc_filter_para_fill(rxq, mbuf, rxd);
910 : : #ifndef RTE_LIBRTE_SXE2_16BYTE_RX_DESC
911 : 0 : sxe2_rx_desc_ipsec_para_fill(rxq, mbuf, rxd);
912 : 0 : sxe2_rx_desc_ptp_para_fill(rxq, mbuf, rxd);
913 : : #endif
914 : :
915 : 0 : mbuf->ol_flags |= pkt_flags;
916 : : }
917 : :
918 : : static __rte_always_inline void
919 : 0 : sxe2_rx_sw_stats_update(struct sxe2_rx_queue *rxq, struct rte_mbuf *mbuf,
920 : : union sxe2_rx_desc *rxd)
921 : : {
922 : 0 : uint64_t qword1 = rte_le_to_cpu_64(rxd->wb.status_err_ptype_len);
923 : 0 : rxq->sw_stats.pkts += 1;
924 : 0 : rxq->sw_stats.bytes += mbuf->pkt_len + RTE_ETHER_CRC_LEN;
925 : 0 : switch (SXE2_RX_DESC_STATUS_UMBCAST_VAL_GET(qword1)) {
926 : 0 : case SXE2_RX_DESC_STATUS_UNICAST:
927 : 0 : rxq->sw_stats.unicast_pkts += 1;
928 : 0 : break;
929 : 0 : case SXE2_RX_DESC_STATUS_MULTICAST:
930 : 0 : rxq->sw_stats.multicast_pkts += 1;
931 : 0 : break;
932 : 0 : case SXE2_RX_DESC_STATUS_BROADCAST:
933 : 0 : rxq->sw_stats.broadcast_pkts += 1;
934 : 0 : break;
935 : : default:
936 : : break;
937 : : }
938 : : }
939 : :
940 : 0 : uint16_t sxe2_rx_pkts_scattered(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
941 : : {
942 : 0 : struct sxe2_rx_queue *rxq = (struct sxe2_rx_queue *)rx_queue;
943 : 0 : volatile union sxe2_rx_desc *desc_ring;
944 : 0 : volatile union sxe2_rx_desc *desc;
945 : 0 : union sxe2_rx_desc desc_tmp;
946 : 0 : struct rte_mbuf **buffer_ring;
947 : 0 : struct rte_mbuf **cur_buffer;
948 : 0 : struct rte_mbuf *cur_mbuf;
949 : 0 : struct rte_mbuf *new_mbuf;
950 : 0 : struct rte_mbuf *first_seg;
951 : 0 : struct rte_mbuf *last_seg;
952 : 0 : uint64_t qword1;
953 : 0 : uint16_t done_num;
954 : 0 : uint16_t hold_num;
955 : 0 : uint16_t cur_idx;
956 : 0 : uint16_t pkt_len;
957 : :
958 : 0 : desc_ring = rxq->desc_ring;
959 : 0 : buffer_ring = rxq->buffer_ring;
960 : 0 : cur_idx = rxq->processing_idx;
961 : 0 : first_seg = rxq->pkt_first_seg;
962 : 0 : last_seg = rxq->pkt_last_seg;
963 : 0 : done_num = 0;
964 : 0 : hold_num = 0;
965 [ # # ]: 0 : while (done_num < nb_pkts) {
966 : 0 : desc = &desc_ring[cur_idx];
967 : 0 : qword1 = rte_le_to_cpu_64(desc->wb.status_err_ptype_len);
968 [ # # ]: 0 : if (0 == (SXE2_RX_DESC_STATUS_DD_MASK & qword1))
969 : : break;
970 : :
971 : 0 : new_mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
972 [ # # ]: 0 : if (unlikely(new_mbuf == NULL)) {
973 : 0 : rxq->vsi->adapter->dev_info.dev_data->rx_mbuf_alloc_failed++;
974 : 0 : PMD_LOG_INFO(RX, "Rx new_mbuf alloc failed port_id:%u "
975 : : "queue_id:%u", rxq->port_id, rxq->queue_id);
976 : 0 : break;
977 : : }
978 : :
979 : 0 : hold_num++;
980 : 0 : desc_tmp = *desc;
981 : 0 : cur_buffer = &buffer_ring[cur_idx];
982 : 0 : cur_idx++;
983 [ # # ]: 0 : if (unlikely(cur_idx == rxq->ring_depth))
984 : 0 : cur_idx = 0;
985 : :
986 : 0 : rte_prefetch0(buffer_ring[cur_idx]);
987 : :
988 [ # # ]: 0 : if (0 == (cur_idx & 0x3)) {
989 : 0 : rte_prefetch0(&desc_ring[cur_idx]);
990 : 0 : rte_prefetch0(&buffer_ring[cur_idx]);
991 : : }
992 : :
993 : 0 : cur_mbuf = *cur_buffer;
994 : :
995 : 0 : *cur_buffer = new_mbuf;
996 : :
997 : 0 : desc->read.hdr_addr = 0;
998 [ # # ]: 0 : desc->read.pkt_addr =
999 : 0 : rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf));
1000 : :
1001 : 0 : pkt_len = SXE2_RX_DESC_PKT_LEN_VAL_GET(qword1);
1002 : 0 : cur_mbuf->data_len = pkt_len;
1003 : 0 : cur_mbuf->data_off = RTE_PKTMBUF_HEADROOM;
1004 : :
1005 [ # # ]: 0 : if (first_seg == NULL) {
1006 : 0 : first_seg = cur_mbuf;
1007 : 0 : first_seg->nb_segs = 1;
1008 : 0 : first_seg->pkt_len = pkt_len;
1009 : : } else {
1010 : 0 : first_seg->pkt_len += pkt_len;
1011 : 0 : first_seg->nb_segs++;
1012 : 0 : last_seg->next = cur_mbuf;
1013 : : }
1014 : :
1015 [ # # ]: 0 : if (0 == (qword1 & SXE2_RX_DESC_STATUS_EOP_MASK)) {
1016 : 0 : last_seg = cur_mbuf;
1017 : 0 : continue;
1018 : : }
1019 : :
1020 [ # # ]: 0 : if (unlikely(qword1 & SXE2_RX_DESC_ERROR_RXE_MASK) ||
1021 [ # # ]: 0 : unlikely(qword1 & SXE2_RX_DESC_ERROR_OVERSIZE_MASK)) {
1022 : 0 : rxq->sw_stats.drop_pkts += 1;
1023 : 0 : rxq->sw_stats.drop_bytes +=
1024 : 0 : first_seg->pkt_len - rxq->crc_len + RTE_ETHER_CRC_LEN;
1025 : 0 : rte_pktmbuf_free(first_seg);
1026 : 0 : first_seg = NULL;
1027 : 0 : continue;
1028 : : }
1029 : :
1030 : 0 : cur_mbuf->next = NULL;
1031 [ # # ]: 0 : if (unlikely(rxq->crc_len > 0)) {
1032 : 0 : first_seg->pkt_len -= RTE_ETHER_CRC_LEN;
1033 : :
1034 [ # # ]: 0 : if (pkt_len <= RTE_ETHER_CRC_LEN) {
1035 [ # # ]: 0 : rte_pktmbuf_free_seg(cur_mbuf);
1036 : 0 : first_seg->nb_segs--;
1037 : 0 : last_seg->data_len = last_seg->data_len + pkt_len -
1038 : : RTE_ETHER_CRC_LEN;
1039 : 0 : last_seg->next = NULL;
1040 : : } else {
1041 : 0 : cur_mbuf->data_len = pkt_len - RTE_ETHER_CRC_LEN;
1042 : : }
1043 : :
1044 [ # # ]: 0 : } else if (pkt_len == 0) {
1045 [ # # ]: 0 : rte_pktmbuf_free_seg(cur_mbuf);
1046 : 0 : first_seg->nb_segs--;
1047 : 0 : last_seg->next = NULL;
1048 : : }
1049 : :
1050 : 0 : rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr, first_seg->data_off));
1051 : 0 : first_seg->port = rxq->port_id;
1052 : :
1053 : 0 : sxe2_rx_mbuf_common_fields_fill(rxq, first_seg, &desc_tmp);
1054 : :
1055 [ # # # # ]: 0 : sxe2_rx_sw_stats_update(rxq, first_seg, &desc_tmp);
1056 : :
1057 : 0 : rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr, first_seg->data_off));
1058 : :
1059 : 0 : rx_pkts[done_num] = first_seg;
1060 : 0 : done_num++;
1061 : :
1062 : 0 : first_seg = NULL;
1063 : : }
1064 : :
1065 : 0 : rxq->processing_idx = cur_idx;
1066 : 0 : rxq->pkt_first_seg = first_seg;
1067 : 0 : rxq->pkt_last_seg = last_seg;
1068 : :
1069 : 0 : sxe2_update_rx_tail(rxq, hold_num, cur_idx);
1070 : :
1071 : 0 : return done_num;
1072 : : }
1073 : :
1074 : 0 : uint16_t sxe2_rx_pkts_scattered_split(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
1075 : : {
1076 : 0 : struct sxe2_rx_queue *rxq = (struct sxe2_rx_queue *)rx_queue;
1077 : 0 : volatile union sxe2_rx_desc *desc_ring;
1078 : 0 : volatile union sxe2_rx_desc *desc;
1079 : 0 : union sxe2_rx_desc desc_tmp;
1080 : 0 : struct rte_mbuf **buffer_ring;
1081 : 0 : struct rte_mbuf **cur_buffer;
1082 : 0 : struct rte_mbuf *cur_mbuf;
1083 : 0 : struct rte_mbuf *cur_mbuf_pay;
1084 : 0 : struct rte_mbuf *new_mbuf;
1085 : 0 : struct rte_mbuf *new_mbuf_pay = NULL;
1086 : 0 : struct rte_mbuf *first_seg;
1087 : 0 : struct rte_mbuf *last_seg;
1088 : 0 : uint64_t qword1;
1089 : 0 : uint16_t done_num;
1090 : 0 : uint16_t hold_num;
1091 : 0 : uint16_t cur_idx;
1092 : 0 : uint16_t pkt_len;
1093 : 0 : uint16_t hdr_len;
1094 : :
1095 : 0 : desc_ring = rxq->desc_ring;
1096 : 0 : buffer_ring = rxq->buffer_ring;
1097 : 0 : cur_idx = rxq->processing_idx;
1098 : 0 : first_seg = rxq->pkt_first_seg;
1099 : 0 : last_seg = rxq->pkt_last_seg;
1100 : 0 : done_num = 0;
1101 : 0 : hold_num = 0;
1102 : 0 : new_mbuf = NULL;
1103 : :
1104 [ # # ]: 0 : while (done_num < nb_pkts) {
1105 : 0 : desc = &desc_ring[cur_idx];
1106 : 0 : qword1 = rte_le_to_cpu_64(desc->wb.status_err_ptype_len);
1107 : :
1108 [ # # ]: 0 : if (0 == (SXE2_RX_DESC_STATUS_DD_MASK & qword1))
1109 : : break;
1110 : :
1111 [ # # # # ]: 0 : if ((rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) == 0 ||
1112 : : first_seg == NULL) {
1113 : 0 : new_mbuf = rte_mbuf_raw_alloc(rxq->mb_pool);
1114 [ # # ]: 0 : if (unlikely(new_mbuf == NULL)) {
1115 : 0 : rxq->vsi->adapter->dev_info.dev_data->rx_mbuf_alloc_failed++;
1116 : 0 : break;
1117 : : }
1118 : : }
1119 : :
1120 [ # # ]: 0 : if (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
1121 : 0 : new_mbuf_pay = rte_mbuf_raw_alloc(rxq->rx_seg[1].mp);
1122 [ # # ]: 0 : if (unlikely(new_mbuf_pay == NULL)) {
1123 : 0 : rxq->vsi->adapter->dev_info.dev_data->rx_mbuf_alloc_failed++;
1124 [ # # ]: 0 : if (new_mbuf != NULL)
1125 : 0 : rte_pktmbuf_free(new_mbuf);
1126 : 0 : new_mbuf = NULL;
1127 : : break;
1128 : : }
1129 : : }
1130 : :
1131 : 0 : hold_num++;
1132 : 0 : desc_tmp = *desc;
1133 : 0 : cur_buffer = &buffer_ring[cur_idx];
1134 : 0 : cur_idx++;
1135 [ # # ]: 0 : if (unlikely(cur_idx == rxq->ring_depth))
1136 : 0 : cur_idx = 0;
1137 : 0 : rte_prefetch0(buffer_ring[cur_idx]);
1138 [ # # ]: 0 : if (0 == (cur_idx & 0x3)) {
1139 : 0 : rte_prefetch0(&desc_ring[cur_idx]);
1140 : 0 : rte_prefetch0(&buffer_ring[cur_idx]);
1141 : : }
1142 : 0 : cur_mbuf = *cur_buffer;
1143 [ # # ]: 0 : if (0 == (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT)) {
1144 : 0 : *cur_buffer = new_mbuf;
1145 : 0 : desc->read.hdr_addr = 0;
1146 : 0 : desc->read.pkt_addr =
1147 : 0 : rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf));
1148 : : } else {
1149 [ # # ]: 0 : if (first_seg == NULL) {
1150 : 0 : *cur_buffer = new_mbuf;
1151 : 0 : new_mbuf->next = new_mbuf_pay;
1152 : 0 : new_mbuf->data_off = RTE_PKTMBUF_HEADROOM;
1153 : 0 : new_mbuf_pay->next = NULL;
1154 : 0 : new_mbuf_pay->data_off = RTE_PKTMBUF_HEADROOM;
1155 : 0 : desc->read.hdr_addr =
1156 : 0 : rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf));
1157 : 0 : desc->read.pkt_addr =
1158 : 0 : rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf_pay));
1159 : : } else {
1160 : 0 : cur_mbuf_pay = cur_mbuf->next;
1161 : 0 : new_mbuf_pay->next = NULL;
1162 : 0 : new_mbuf_pay->data_off = RTE_PKTMBUF_HEADROOM;
1163 : 0 : cur_mbuf->next = new_mbuf_pay;
1164 : 0 : desc->read.hdr_addr =
1165 : 0 : rte_cpu_to_le_64(rte_mbuf_data_iova_default(cur_mbuf));
1166 : 0 : desc->read.pkt_addr =
1167 : 0 : rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mbuf_pay));
1168 : 0 : cur_mbuf = cur_mbuf_pay;
1169 : : }
1170 : : }
1171 : 0 : new_mbuf = NULL;
1172 [ # # ]: 0 : if (0 == (rxq->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT)) {
1173 : 0 : pkt_len = SXE2_RX_DESC_PKT_LEN_VAL_GET(qword1);
1174 : 0 : cur_mbuf->data_len = pkt_len;
1175 : 0 : cur_mbuf->data_off = RTE_PKTMBUF_HEADROOM;
1176 [ # # ]: 0 : if (first_seg == NULL) {
1177 : 0 : first_seg = cur_mbuf;
1178 : 0 : first_seg->nb_segs = 1;
1179 : 0 : first_seg->pkt_len = pkt_len;
1180 : : } else {
1181 : 0 : first_seg->pkt_len += pkt_len;
1182 : 0 : first_seg->nb_segs++;
1183 : 0 : last_seg->next = cur_mbuf;
1184 : : }
1185 : : } else {
1186 [ # # ]: 0 : if (first_seg == NULL) {
1187 : 0 : cur_mbuf->nb_segs = 2;
1188 : 0 : cur_mbuf->next->next = NULL;
1189 : 0 : pkt_len = SXE2_RX_DESC_PKT_LEN_VAL_GET(qword1);
1190 : 0 : hdr_len = SXE2_RX_DESC_HDR_LEN_VAL_GET(qword1);
1191 : 0 : cur_mbuf->data_len = hdr_len;
1192 : 0 : cur_mbuf->pkt_len = hdr_len + pkt_len;
1193 : 0 : cur_mbuf->next->data_len = pkt_len;
1194 : 0 : first_seg = cur_mbuf;
1195 : 0 : cur_mbuf = cur_mbuf->next;
1196 : 0 : last_seg = cur_mbuf;
1197 : : } else {
1198 : 0 : cur_mbuf->nb_segs = 1;
1199 : 0 : cur_mbuf->next = NULL;
1200 : 0 : pkt_len = SXE2_RX_DESC_PKT_LEN_VAL_GET(qword1);
1201 : 0 : cur_mbuf->data_len = pkt_len;
1202 : :
1203 : 0 : first_seg->pkt_len += pkt_len;
1204 : 0 : first_seg->nb_segs++;
1205 : 0 : last_seg->next = cur_mbuf;
1206 : : }
1207 : : }
1208 : :
1209 : : #ifdef RTE_ETHDEV_DEBUG_RX
1210 : :
1211 : : rte_pktmbuf_dump(stdout, first_seg, rte_pktmbuf_pkt_len(first_seg));
1212 : : #endif
1213 : :
1214 [ # # ]: 0 : if (0 == (rte_le_to_cpu_64(desc_tmp.wb.status_err_ptype_len) &
1215 : : SXE2_RX_DESC_STATUS_EOP_MASK)) {
1216 : 0 : last_seg = cur_mbuf;
1217 : 0 : continue;
1218 : : }
1219 : :
1220 [ # # ]: 0 : if (unlikely(qword1 & SXE2_RX_DESC_ERROR_RXE_MASK) ||
1221 [ # # ]: 0 : unlikely(qword1 & SXE2_RX_DESC_ERROR_OVERSIZE_MASK)) {
1222 : 0 : rxq->sw_stats.drop_pkts += 1;
1223 : 0 : rxq->sw_stats.drop_bytes +=
1224 : 0 : first_seg->pkt_len - rxq->crc_len + RTE_ETHER_CRC_LEN;
1225 : 0 : rte_pktmbuf_free(first_seg);
1226 : 0 : first_seg = NULL;
1227 : 0 : continue;
1228 : : }
1229 : :
1230 : 0 : cur_mbuf->next = NULL;
1231 [ # # ]: 0 : if (unlikely(rxq->crc_len > 0)) {
1232 : 0 : first_seg->pkt_len -= RTE_ETHER_CRC_LEN;
1233 [ # # ]: 0 : if (pkt_len <= RTE_ETHER_CRC_LEN) {
1234 [ # # ]: 0 : rte_pktmbuf_free_seg(cur_mbuf);
1235 : 0 : cur_mbuf = NULL;
1236 : 0 : first_seg->nb_segs--;
1237 : 0 : last_seg->data_len = last_seg->data_len +
1238 : 0 : pkt_len - RTE_ETHER_CRC_LEN;
1239 : 0 : last_seg->next = NULL;
1240 : : } else {
1241 : 0 : cur_mbuf->data_len = pkt_len - RTE_ETHER_CRC_LEN;
1242 : : }
1243 [ # # ]: 0 : } else if (pkt_len == 0) {
1244 [ # # ]: 0 : rte_pktmbuf_free_seg(cur_mbuf);
1245 : 0 : cur_mbuf = NULL;
1246 : 0 : first_seg->nb_segs--;
1247 : 0 : last_seg->next = NULL;
1248 : : }
1249 : :
1250 : 0 : first_seg->port = rxq->port_id;
1251 : 0 : sxe2_rx_mbuf_common_fields_fill(rxq, first_seg, &desc_tmp);
1252 : :
1253 [ # # # # ]: 0 : sxe2_rx_sw_stats_update(rxq, first_seg, &desc_tmp);
1254 : :
1255 : 0 : rte_prefetch0(RTE_PTR_ADD(first_seg->buf_addr, first_seg->data_off));
1256 : :
1257 : 0 : rx_pkts[done_num] = first_seg;
1258 : 0 : done_num++;
1259 : :
1260 : 0 : first_seg = NULL;
1261 : : }
1262 : :
1263 : 0 : rxq->processing_idx = cur_idx;
1264 : 0 : rxq->pkt_first_seg = first_seg;
1265 : 0 : rxq->pkt_last_seg = last_seg;
1266 : :
1267 : 0 : sxe2_update_rx_tail(rxq, hold_num, cur_idx);
1268 : :
1269 : 0 : return done_num;
1270 : : }
|