Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2017 Intel Corporation
3 : : */
4 : :
5 : : #ifndef _IAVF_RXTX_VEC_COMMON_H_
6 : : #define _IAVF_RXTX_VEC_COMMON_H_
7 : : #include <stdint.h>
8 : : #include <ethdev_driver.h>
9 : : #include <rte_malloc.h>
10 : :
11 : : #include "iavf.h"
12 : : #include "iavf_rxtx.h"
13 : :
14 : : #ifndef __INTEL_COMPILER
15 : : #pragma GCC diagnostic ignored "-Wcast-qual"
16 : : #endif
17 : :
18 : : static __rte_always_inline uint16_t
19 : : reassemble_packets(struct iavf_rx_queue *rxq, struct rte_mbuf **rx_bufs,
20 : : uint16_t nb_bufs, uint8_t *split_flags)
21 : : {
22 : : struct rte_mbuf *pkts[IAVF_VPMD_RX_MAX_BURST];
23 : 0 : struct rte_mbuf *start = rxq->pkt_first_seg;
24 : 0 : struct rte_mbuf *end = rxq->pkt_last_seg;
25 : : unsigned int pkt_idx, buf_idx;
26 : :
27 [ # # # # : 0 : for (buf_idx = 0, pkt_idx = 0; buf_idx < nb_bufs; buf_idx++) {
# # # # #
# # # # #
# # ]
28 [ # # # # : 0 : if (end) {
# # # # #
# # # # #
# # ]
29 : : /* processing a split packet */
30 : 0 : end->next = rx_bufs[buf_idx];
31 : 0 : rx_bufs[buf_idx]->data_len += rxq->crc_len;
32 : :
33 : 0 : start->nb_segs++;
34 : 0 : start->pkt_len += rx_bufs[buf_idx]->data_len;
35 : : end = end->next;
36 : :
37 [ # # # # : 0 : if (!split_flags[buf_idx]) {
# # # # #
# # # # #
# # ]
38 : : /* it's the last packet of the set */
39 : 0 : start->hash = end->hash;
40 : 0 : start->vlan_tci = end->vlan_tci;
41 : 0 : start->ol_flags = end->ol_flags;
42 : : /* we need to strip crc for the whole packet */
43 : 0 : start->pkt_len -= rxq->crc_len;
44 [ # # # # : 0 : if (end->data_len > rxq->crc_len) {
# # # # #
# # # # #
# # ]
45 : 0 : end->data_len -= rxq->crc_len;
46 : : } else {
47 : : /* free up last mbuf */
48 : : struct rte_mbuf *secondlast = start;
49 : :
50 : 0 : start->nb_segs--;
51 [ # # # # : 0 : while (secondlast->next != end)
# # # # #
# # # # #
# # ]
52 : : secondlast = secondlast->next;
53 : 0 : secondlast->data_len -= (rxq->crc_len -
54 : : end->data_len);
55 [ # # # # : 0 : secondlast->next = NULL;
# # # # #
# # # # #
# # ]
56 : : rte_pktmbuf_free_seg(end);
57 : : }
58 : 0 : pkts[pkt_idx++] = start;
59 : : start = NULL;
60 : : end = NULL;
61 : : }
62 : : } else {
63 : : /* not processing a split packet */
64 [ # # # # : 0 : if (!split_flags[buf_idx]) {
# # # # #
# # # # #
# # ]
65 : : /* not a split packet, save and skip */
66 : 0 : pkts[pkt_idx++] = rx_bufs[buf_idx];
67 : 0 : continue;
68 : : }
69 : 0 : end = start = rx_bufs[buf_idx];
70 : 0 : rx_bufs[buf_idx]->data_len += rxq->crc_len;
71 : 0 : rx_bufs[buf_idx]->pkt_len += rxq->crc_len;
72 : : }
73 : : }
74 : :
75 : : /* save the partial packet for next time */
76 : 0 : rxq->pkt_first_seg = start;
77 : 0 : rxq->pkt_last_seg = end;
78 : 0 : memcpy(rx_bufs, pkts, pkt_idx * (sizeof(*pkts)));
79 : 0 : return pkt_idx;
80 : : }
81 : :
82 : : static __rte_always_inline int
83 : : iavf_tx_free_bufs(struct iavf_tx_queue *txq)
84 : : {
85 : : struct iavf_tx_entry *txep;
86 : : uint32_t n;
87 : : uint32_t i;
88 : : int nb_free = 0;
89 : : struct rte_mbuf *m, *free[IAVF_VPMD_TX_MAX_FREE_BUF];
90 : :
91 : : /* check DD bits on threshold descriptor */
92 [ # # # # ]: 0 : if ((txq->tx_ring[txq->next_dd].cmd_type_offset_bsz &
93 : : rte_cpu_to_le_64(IAVF_TXD_QW1_DTYPE_MASK)) !=
94 : : rte_cpu_to_le_64(IAVF_TX_DESC_DTYPE_DESC_DONE))
95 : : return 0;
96 : :
97 : 0 : n = txq->rs_thresh;
98 : :
99 : : /* first buffer to free from S/W ring is at index
100 : : * tx_next_dd - (tx_rs_thresh-1)
101 : : */
102 : 0 : txep = &txq->sw_ring[txq->next_dd - (n - 1)];
103 [ # # # # ]: 0 : m = rte_pktmbuf_prefree_seg(txep[0].mbuf);
104 [ # # # # ]: 0 : if (likely(m != NULL)) {
105 : 0 : free[0] = m;
106 : : nb_free = 1;
107 [ # # # # ]: 0 : for (i = 1; i < n; i++) {
108 [ # # # # ]: 0 : m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
109 [ # # # # ]: 0 : if (likely(m != NULL)) {
110 [ # # # # ]: 0 : if (likely(m->pool == free[0]->pool)) {
111 : 0 : free[nb_free++] = m;
112 : : } else {
113 [ # # # # ]: 0 : rte_mempool_put_bulk(free[0]->pool,
114 : : (void *)free,
115 : : nb_free);
116 : 0 : free[0] = m;
117 : : nb_free = 1;
118 : : }
119 : : }
120 : : }
121 [ # # # # ]: 0 : rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free);
122 : : } else {
123 [ # # # # ]: 0 : for (i = 1; i < n; i++) {
124 [ # # # # ]: 0 : m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
125 [ # # # # ]: 0 : if (m)
126 [ # # # # ]: 0 : rte_mempool_put(m->pool, m);
127 : : }
128 : : }
129 : :
130 : : /* buffers were freed, update counters */
131 : 0 : txq->nb_free = (uint16_t)(txq->nb_free + txq->rs_thresh);
132 : 0 : txq->next_dd = (uint16_t)(txq->next_dd + txq->rs_thresh);
133 [ # # # # ]: 0 : if (txq->next_dd >= txq->nb_tx_desc)
134 : 0 : txq->next_dd = (uint16_t)(txq->rs_thresh - 1);
135 : :
136 : 0 : return txq->rs_thresh;
137 : : }
138 : :
139 : : static __rte_always_inline void
140 : : tx_backlog_entry(struct iavf_tx_entry *txep,
141 : : struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
142 : : {
143 : : int i;
144 : :
145 [ # # # # : 0 : for (i = 0; i < (int)nb_pkts; ++i)
# # # # ]
146 : 0 : txep[i].mbuf = tx_pkts[i];
147 : : }
148 : :
149 : : static inline void
150 : 0 : _iavf_rx_queue_release_mbufs_vec(struct iavf_rx_queue *rxq)
151 : : {
152 : 0 : const unsigned int mask = rxq->nb_rx_desc - 1;
153 : : unsigned int i;
154 : :
155 [ # # # # ]: 0 : if (!rxq->sw_ring || rxq->rxrearm_nb >= rxq->nb_rx_desc)
156 : : return;
157 : :
158 : : /* free all mbufs that are valid in the ring */
159 [ # # ]: 0 : if (rxq->rxrearm_nb == 0) {
160 [ # # ]: 0 : for (i = 0; i < rxq->nb_rx_desc; i++) {
161 [ # # ]: 0 : if (rxq->sw_ring[i])
162 : : rte_pktmbuf_free_seg(rxq->sw_ring[i]);
163 : : }
164 : : } else {
165 : 0 : for (i = rxq->rx_tail;
166 [ # # ]: 0 : i != rxq->rxrearm_start;
167 : 0 : i = (i + 1) & mask) {
168 [ # # ]: 0 : if (rxq->sw_ring[i])
169 : : rte_pktmbuf_free_seg(rxq->sw_ring[i]);
170 : : }
171 : : }
172 : :
173 : 0 : rxq->rxrearm_nb = rxq->nb_rx_desc;
174 : :
175 : : /* set all entries to NULL */
176 : 0 : memset(rxq->sw_ring, 0, sizeof(rxq->sw_ring[0]) * rxq->nb_rx_desc);
177 : : }
178 : :
179 : : static inline void
180 : 0 : _iavf_tx_queue_release_mbufs_vec(struct iavf_tx_queue *txq)
181 : : {
182 : : unsigned i;
183 : 0 : const uint16_t max_desc = (uint16_t)(txq->nb_tx_desc - 1);
184 : :
185 [ # # # # ]: 0 : if (!txq->sw_ring || txq->nb_free == max_desc)
186 : : return;
187 : :
188 : 0 : i = txq->next_dd - txq->rs_thresh + 1;
189 [ # # ]: 0 : while (i != txq->tx_tail) {
190 : 0 : rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
191 : 0 : txq->sw_ring[i].mbuf = NULL;
192 [ # # ]: 0 : if (++i == txq->nb_tx_desc)
193 : : i = 0;
194 : : }
195 : : }
196 : :
197 : : static inline int
198 : 0 : iavf_rxq_vec_setup_default(struct iavf_rx_queue *rxq)
199 : : {
200 : : uintptr_t p;
201 : 0 : struct rte_mbuf mb_def = { .buf_addr = 0 }; /* zeroed mbuf */
202 : :
203 : 0 : mb_def.nb_segs = 1;
204 : 0 : mb_def.data_off = RTE_PKTMBUF_HEADROOM;
205 : 0 : mb_def.port = rxq->port_id;
206 : : rte_mbuf_refcnt_set(&mb_def, 1);
207 : :
208 : : /* prevent compiler reordering: rearm_data covers previous fields */
209 : 0 : rte_compiler_barrier();
210 : : p = (uintptr_t)&mb_def.rearm_data;
211 : 0 : rxq->mbuf_initializer = *(uint64_t *)p;
212 : 0 : return 0;
213 : : }
214 : :
215 : : static inline int
216 : 0 : iavf_rx_vec_queue_default(struct iavf_rx_queue *rxq)
217 : : {
218 [ # # ]: 0 : if (!rxq)
219 : : return -1;
220 : :
221 [ # # ]: 0 : if (!rte_is_power_of_2(rxq->nb_rx_desc))
222 : : return -1;
223 : :
224 [ # # ]: 0 : if (rxq->rx_free_thresh < IAVF_VPMD_RX_MAX_BURST)
225 : : return -1;
226 : :
227 [ # # ]: 0 : if (rxq->nb_rx_desc % rxq->rx_free_thresh)
228 : : return -1;
229 : :
230 [ # # ]: 0 : if (rxq->proto_xtr != IAVF_PROTO_XTR_NONE)
231 : : return -1;
232 : :
233 [ # # ]: 0 : if (rxq->offloads & IAVF_RX_VECTOR_OFFLOAD)
234 : 0 : return IAVF_VECTOR_OFFLOAD_PATH;
235 : :
236 : : return IAVF_VECTOR_PATH;
237 : : }
238 : :
239 : : static inline int
240 : 0 : iavf_tx_vec_queue_default(struct iavf_tx_queue *txq)
241 : : {
242 [ # # ]: 0 : if (!txq)
243 : : return -1;
244 : :
245 [ # # ]: 0 : if (txq->rs_thresh < IAVF_VPMD_TX_MAX_BURST ||
246 : : txq->rs_thresh > IAVF_VPMD_TX_MAX_FREE_BUF)
247 : : return -1;
248 : :
249 [ # # ]: 0 : if (txq->offloads & IAVF_TX_NO_VECTOR_FLAGS)
250 : : return -1;
251 : :
252 : : /**
253 : : * Vlan tci needs to be inserted via ctx desc, if the vlan_flag is L2TAG2.
254 : : * Tunneling parameters and other fields need be configured in ctx desc
255 : : * if the outer checksum offload is enabled.
256 : : */
257 [ # # ]: 0 : if (txq->offloads & (IAVF_TX_VECTOR_OFFLOAD | IAVF_TX_VECTOR_OFFLOAD_CTX)) {
258 [ # # ]: 0 : if (txq->offloads & IAVF_TX_VECTOR_OFFLOAD_CTX) {
259 [ # # ]: 0 : if (txq->vlan_flag == IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG2) {
260 : 0 : txq->use_ctx = 1;
261 : 0 : return IAVF_VECTOR_CTX_OFFLOAD_PATH;
262 : : } else {
263 : : return -1;
264 : : }
265 : : } else {
266 : : return IAVF_VECTOR_OFFLOAD_PATH;
267 : : }
268 : : } else {
269 : : return IAVF_VECTOR_PATH;
270 : : }
271 : : }
272 : :
273 : : static inline int
274 : 0 : iavf_rx_vec_dev_check_default(struct rte_eth_dev *dev)
275 : : {
276 : : int i;
277 : : struct iavf_rx_queue *rxq;
278 : : int ret;
279 : : int result = 0;
280 : :
281 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
282 : 0 : rxq = dev->data->rx_queues[i];
283 : 0 : ret = iavf_rx_vec_queue_default(rxq);
284 : :
285 [ # # ]: 0 : if (ret < 0)
286 : : return -1;
287 : : if (ret > result)
288 : : result = ret;
289 : : }
290 : :
291 : : return result;
292 : : }
293 : :
294 : : static inline int
295 : 0 : iavf_tx_vec_dev_check_default(struct rte_eth_dev *dev)
296 : : {
297 : : int i;
298 : : struct iavf_tx_queue *txq;
299 : : int ret;
300 : : int result = 0;
301 : :
302 [ # # ]: 0 : for (i = 0; i < dev->data->nb_tx_queues; i++) {
303 : 0 : txq = dev->data->tx_queues[i];
304 : 0 : ret = iavf_tx_vec_queue_default(txq);
305 : :
306 [ # # ]: 0 : if (ret < 0)
307 : : return -1;
308 : : if (ret > result)
309 : : result = ret;
310 : : }
311 : :
312 : : return result;
313 : : }
314 : :
315 : : /******************************************************************************
316 : : * If user knows a specific offload is not enabled by APP,
317 : : * the macro can be commented to save the effort of fast path.
318 : : * Currently below 2 features are supported in TX path,
319 : : * 1, checksum offload
320 : : * 2, VLAN/QINQ insertion
321 : : ******************************************************************************/
322 : : #define IAVF_TX_CSUM_OFFLOAD
323 : : #define IAVF_TX_VLAN_QINQ_OFFLOAD
324 : :
325 : : static __rte_always_inline void
326 : : iavf_txd_enable_offload(__rte_unused struct rte_mbuf *tx_pkt,
327 : : uint64_t *txd_hi)
328 : : {
329 : : #if defined(IAVF_TX_CSUM_OFFLOAD) || defined(IAVF_TX_VLAN_QINQ_OFFLOAD)
330 : 0 : uint64_t ol_flags = tx_pkt->ol_flags;
331 : : #endif
332 : : uint32_t td_cmd = 0;
333 : : #ifdef IAVF_TX_CSUM_OFFLOAD
334 : : uint32_t td_offset = 0;
335 : : #endif
336 : :
337 : : #ifdef IAVF_TX_CSUM_OFFLOAD
338 : : /* Set MACLEN */
339 [ # # # # : 0 : if (ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
340 : 0 : td_offset |= (tx_pkt->outer_l2_len >> 1)
341 : 0 : << IAVF_TX_DESC_LENGTH_MACLEN_SHIFT;
342 : : else
343 : 0 : td_offset |= (tx_pkt->l2_len >> 1)
344 : 0 : << IAVF_TX_DESC_LENGTH_MACLEN_SHIFT;
345 : :
346 : : /* Enable L3 checksum offloads */
347 [ # # # # : 0 : if (ol_flags & RTE_MBUF_F_TX_IP_CKSUM) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
348 [ # # # # : 0 : if (ol_flags & RTE_MBUF_F_TX_IPV4) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
349 : : td_cmd |= IAVF_TX_DESC_CMD_IIPT_IPV4_CSUM;
350 : 0 : td_offset |= (tx_pkt->l3_len >> 2) <<
351 : : IAVF_TX_DESC_LENGTH_IPLEN_SHIFT;
352 : : }
353 [ # # # # : 0 : } else if (ol_flags & RTE_MBUF_F_TX_IPV4) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
354 : : td_cmd |= IAVF_TX_DESC_CMD_IIPT_IPV4;
355 : 0 : td_offset |= (tx_pkt->l3_len >> 2) <<
356 : : IAVF_TX_DESC_LENGTH_IPLEN_SHIFT;
357 [ # # # # : 0 : } else if (ol_flags & RTE_MBUF_F_TX_IPV6) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
358 : : td_cmd |= IAVF_TX_DESC_CMD_IIPT_IPV6;
359 : 0 : td_offset |= (tx_pkt->l3_len >> 2) <<
360 : : IAVF_TX_DESC_LENGTH_IPLEN_SHIFT;
361 : : }
362 : :
363 : : /* Enable L4 checksum offloads */
364 [ # # # # : 0 : switch (ol_flags & RTE_MBUF_F_TX_L4_MASK) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
365 : 0 : case RTE_MBUF_F_TX_TCP_CKSUM:
366 : 0 : td_cmd |= IAVF_TX_DESC_CMD_L4T_EOFT_TCP;
367 : 0 : td_offset |= (sizeof(struct rte_tcp_hdr) >> 2) <<
368 : : IAVF_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
369 : 0 : break;
370 : 0 : case RTE_MBUF_F_TX_SCTP_CKSUM:
371 : 0 : td_cmd |= IAVF_TX_DESC_CMD_L4T_EOFT_SCTP;
372 : 0 : td_offset |= (sizeof(struct rte_sctp_hdr) >> 2) <<
373 : : IAVF_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
374 : 0 : break;
375 : 0 : case RTE_MBUF_F_TX_UDP_CKSUM:
376 : 0 : td_cmd |= IAVF_TX_DESC_CMD_L4T_EOFT_UDP;
377 : 0 : td_offset |= (sizeof(struct rte_udp_hdr) >> 2) <<
378 : : IAVF_TX_DESC_LENGTH_L4_FC_LEN_SHIFT;
379 : 0 : break;
380 : : default:
381 : : break;
382 : : }
383 : :
384 : 0 : *txd_hi |= ((uint64_t)td_offset) << IAVF_TXD_QW1_OFFSET_SHIFT;
385 : : #endif
386 : :
387 : : #ifdef IAVF_TX_VLAN_QINQ_OFFLOAD
388 [ # # # # : 0 : if (ol_flags & (RTE_MBUF_F_TX_VLAN | RTE_MBUF_F_TX_QINQ)) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
389 : 0 : td_cmd |= IAVF_TX_DESC_CMD_IL2TAG1;
390 : 0 : *txd_hi |= ((uint64_t)tx_pkt->vlan_tci <<
391 : : IAVF_TXD_QW1_L2TAG1_SHIFT);
392 : : }
393 : : #endif
394 : :
395 [ # # # # : 0 : *txd_hi |= ((uint64_t)td_cmd) << IAVF_TXD_QW1_CMD_SHIFT;
# # # # #
# # # # #
# # ]
396 : : }
397 : :
398 : : #ifdef RTE_ARCH_X86
399 : : static __rte_always_inline void
400 : : iavf_rxq_rearm_common(struct iavf_rx_queue *rxq, __rte_unused bool avx512)
401 : : {
402 : : int i;
403 : : uint16_t rx_id;
404 : : volatile union iavf_rx_desc *rxdp;
405 : 0 : struct rte_mbuf **rxp = &rxq->sw_ring[rxq->rxrearm_start];
406 : :
407 : 0 : rxdp = rxq->rx_ring + rxq->rxrearm_start;
408 : :
409 : : /* Pull 'n' more MBUFs into the software ring */
410 [ # # # # : 0 : if (rte_mempool_get_bulk(rxq->mp,
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
411 : : (void *)rxp,
412 : : IAVF_RXQ_REARM_THRESH) < 0) {
413 : 0 : if (rxq->rxrearm_nb + IAVF_RXQ_REARM_THRESH >=
414 [ # # # # : 0 : rxq->nb_rx_desc) {
# # # # #
# # # # #
# # # # #
# # # #
# ]
415 : : __m128i dma_addr0;
416 : :
417 : : dma_addr0 = _mm_setzero_si128();
418 [ # # # # : 0 : for (i = 0; i < IAVF_VPMD_DESCS_PER_LOOP; i++) {
# # # # #
# # # # #
# # # # #
# # # #
# ]
419 : 0 : rxp[i] = &rxq->fake_mbuf;
420 : 0 : _mm_store_si128((__m128i *)&rxdp[i].read,
421 : : dma_addr0);
422 : : }
423 : : }
424 : 0 : rte_eth_devices[rxq->port_id].data->rx_mbuf_alloc_failed +=
425 : : IAVF_RXQ_REARM_THRESH;
426 : 0 : return;
427 : : }
428 : :
429 : : #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
430 : : struct rte_mbuf *mb0, *mb1;
431 : : __m128i dma_addr0, dma_addr1;
432 : : __m128i hdr_room = _mm_set_epi64x(RTE_PKTMBUF_HEADROOM,
433 : : RTE_PKTMBUF_HEADROOM);
434 : : /* Initialize the mbufs in vector, process 2 mbufs in one loop */
435 [ # # # # : 0 : for (i = 0; i < IAVF_RXQ_REARM_THRESH; i += 2, rxp += 2) {
# # # # #
# # # # #
# # # # #
# # # #
# ]
436 : : __m128i vaddr0, vaddr1;
437 : :
438 : 0 : mb0 = rxp[0];
439 : 0 : mb1 = rxp[1];
440 : :
441 : : /* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
442 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
443 : : offsetof(struct rte_mbuf, buf_addr) + 8);
444 : : vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
445 : : vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
446 : :
447 : : /* convert pa to dma_addr hdr/data */
448 : : dma_addr0 = _mm_unpackhi_epi64(vaddr0, vaddr0);
449 : : dma_addr1 = _mm_unpackhi_epi64(vaddr1, vaddr1);
450 : :
451 : : /* add headroom to pa values */
452 : : dma_addr0 = _mm_add_epi64(dma_addr0, hdr_room);
453 : : dma_addr1 = _mm_add_epi64(dma_addr1, hdr_room);
454 : :
455 : : /* flush desc with pa dma_addr */
456 : : _mm_store_si128((__m128i *)&rxdp++->read, dma_addr0);
457 : 0 : _mm_store_si128((__m128i *)&rxdp++->read, dma_addr1);
458 : : }
459 : : #else
460 : : #ifdef CC_AVX512_SUPPORT
461 : : if (avx512) {
462 : : struct rte_mbuf *mb0, *mb1, *mb2, *mb3;
463 : : struct rte_mbuf *mb4, *mb5, *mb6, *mb7;
464 : : __m512i dma_addr0_3, dma_addr4_7;
465 : : __m512i hdr_room = _mm512_set1_epi64(RTE_PKTMBUF_HEADROOM);
466 : : /* Initialize the mbufs in vector, process 8 mbufs in one loop */
467 : : for (i = 0; i < IAVF_RXQ_REARM_THRESH;
468 : : i += 8, rxp += 8, rxdp += 8) {
469 : : __m128i vaddr0, vaddr1, vaddr2, vaddr3;
470 : : __m128i vaddr4, vaddr5, vaddr6, vaddr7;
471 : : __m256i vaddr0_1, vaddr2_3;
472 : : __m256i vaddr4_5, vaddr6_7;
473 : : __m512i vaddr0_3, vaddr4_7;
474 : :
475 : : mb0 = rxp[0];
476 : : mb1 = rxp[1];
477 : : mb2 = rxp[2];
478 : : mb3 = rxp[3];
479 : : mb4 = rxp[4];
480 : : mb5 = rxp[5];
481 : : mb6 = rxp[6];
482 : : mb7 = rxp[7];
483 : :
484 : : /* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
485 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
486 : : offsetof(struct rte_mbuf, buf_addr) + 8);
487 : : vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
488 : : vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
489 : : vaddr2 = _mm_loadu_si128((__m128i *)&mb2->buf_addr);
490 : : vaddr3 = _mm_loadu_si128((__m128i *)&mb3->buf_addr);
491 : : vaddr4 = _mm_loadu_si128((__m128i *)&mb4->buf_addr);
492 : : vaddr5 = _mm_loadu_si128((__m128i *)&mb5->buf_addr);
493 : : vaddr6 = _mm_loadu_si128((__m128i *)&mb6->buf_addr);
494 : : vaddr7 = _mm_loadu_si128((__m128i *)&mb7->buf_addr);
495 : :
496 : : /**
497 : : * merge 0 & 1, by casting 0 to 256-bit and inserting 1
498 : : * into the high lanes. Similarly for 2 & 3, and so on.
499 : : */
500 : : vaddr0_1 =
501 : : _mm256_inserti128_si256(_mm256_castsi128_si256(vaddr0),
502 : : vaddr1, 1);
503 : : vaddr2_3 =
504 : : _mm256_inserti128_si256(_mm256_castsi128_si256(vaddr2),
505 : : vaddr3, 1);
506 : : vaddr4_5 =
507 : : _mm256_inserti128_si256(_mm256_castsi128_si256(vaddr4),
508 : : vaddr5, 1);
509 : : vaddr6_7 =
510 : : _mm256_inserti128_si256(_mm256_castsi128_si256(vaddr6),
511 : : vaddr7, 1);
512 : : vaddr0_3 =
513 : : _mm512_inserti64x4(_mm512_castsi256_si512(vaddr0_1),
514 : : vaddr2_3, 1);
515 : : vaddr4_7 =
516 : : _mm512_inserti64x4(_mm512_castsi256_si512(vaddr4_5),
517 : : vaddr6_7, 1);
518 : :
519 : : /* convert pa to dma_addr hdr/data */
520 : : dma_addr0_3 = _mm512_unpackhi_epi64(vaddr0_3, vaddr0_3);
521 : : dma_addr4_7 = _mm512_unpackhi_epi64(vaddr4_7, vaddr4_7);
522 : :
523 : : /* add headroom to pa values */
524 : : dma_addr0_3 = _mm512_add_epi64(dma_addr0_3, hdr_room);
525 : : dma_addr4_7 = _mm512_add_epi64(dma_addr4_7, hdr_room);
526 : :
527 : : /* flush desc with pa dma_addr */
528 : : _mm512_store_si512((__m512i *)&rxdp->read, dma_addr0_3);
529 : : _mm512_store_si512((__m512i *)&(rxdp + 4)->read, dma_addr4_7);
530 : : }
531 : : } else
532 : : #endif
533 : : {
534 : : struct rte_mbuf *mb0, *mb1, *mb2, *mb3;
535 : : __m256i dma_addr0_1, dma_addr2_3;
536 : : __m256i hdr_room = _mm256_set1_epi64x(RTE_PKTMBUF_HEADROOM);
537 : : /* Initialize the mbufs in vector, process 4 mbufs in one loop */
538 : : for (i = 0; i < IAVF_RXQ_REARM_THRESH;
539 : : i += 4, rxp += 4, rxdp += 4) {
540 : : __m128i vaddr0, vaddr1, vaddr2, vaddr3;
541 : : __m256i vaddr0_1, vaddr2_3;
542 : :
543 : : mb0 = rxp[0];
544 : : mb1 = rxp[1];
545 : : mb2 = rxp[2];
546 : : mb3 = rxp[3];
547 : :
548 : : /* load buf_addr(lo 64bit) and buf_iova(hi 64bit) */
549 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, buf_iova) !=
550 : : offsetof(struct rte_mbuf, buf_addr) + 8);
551 : : vaddr0 = _mm_loadu_si128((__m128i *)&mb0->buf_addr);
552 : : vaddr1 = _mm_loadu_si128((__m128i *)&mb1->buf_addr);
553 : : vaddr2 = _mm_loadu_si128((__m128i *)&mb2->buf_addr);
554 : : vaddr3 = _mm_loadu_si128((__m128i *)&mb3->buf_addr);
555 : :
556 : : /**
557 : : * merge 0 & 1, by casting 0 to 256-bit and inserting 1
558 : : * into the high lanes. Similarly for 2 & 3
559 : : */
560 : : vaddr0_1 =
561 : : _mm256_inserti128_si256(_mm256_castsi128_si256(vaddr0),
562 : : vaddr1, 1);
563 : : vaddr2_3 =
564 : : _mm256_inserti128_si256(_mm256_castsi128_si256(vaddr2),
565 : : vaddr3, 1);
566 : :
567 : : /* convert pa to dma_addr hdr/data */
568 : : dma_addr0_1 = _mm256_unpackhi_epi64(vaddr0_1, vaddr0_1);
569 : : dma_addr2_3 = _mm256_unpackhi_epi64(vaddr2_3, vaddr2_3);
570 : :
571 : : /* add headroom to pa values */
572 : : dma_addr0_1 = _mm256_add_epi64(dma_addr0_1, hdr_room);
573 : : dma_addr2_3 = _mm256_add_epi64(dma_addr2_3, hdr_room);
574 : :
575 : : /* flush desc with pa dma_addr */
576 : : _mm256_store_si256((__m256i *)&rxdp->read, dma_addr0_1);
577 : : _mm256_store_si256((__m256i *)&(rxdp + 2)->read, dma_addr2_3);
578 : : }
579 : : }
580 : :
581 : : #endif
582 : :
583 : 0 : rxq->rxrearm_start += IAVF_RXQ_REARM_THRESH;
584 [ # # # # : 0 : if (rxq->rxrearm_start >= rxq->nb_rx_desc)
# # # # #
# # # # #
# # # # #
# # # #
# ]
585 : 0 : rxq->rxrearm_start = 0;
586 : :
587 : 0 : rxq->rxrearm_nb -= IAVF_RXQ_REARM_THRESH;
588 : :
589 [ # # # # : 0 : rx_id = (uint16_t)((rxq->rxrearm_start == 0) ?
# # # # #
# # # # #
# # # # #
# # # #
# ]
590 : : (rxq->nb_rx_desc - 1) : (rxq->rxrearm_start - 1));
591 : :
592 : : /* Update the tail pointer on the NIC */
593 : 0 : IAVF_PCI_REG_WC_WRITE(rxq->qrx_tail, rx_id);
594 : : }
595 : : #endif
596 : :
597 : : #endif
|