Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2020 Intel Corporation
3 : : */
4 : :
5 : : #include "iavf_rxtx_vec_common.h"
6 : :
7 : : #include <rte_vect.h>
8 : :
9 : : #ifndef __INTEL_COMPILER
10 : : #pragma GCC diagnostic ignored "-Wcast-qual"
11 : : #endif
12 : :
13 : : #define IAVF_DESCS_PER_LOOP_AVX 8
14 : : #define PKTLEN_SHIFT 10
15 : :
16 : : /******************************************************************************
17 : : * If user knows a specific offload is not enabled by APP,
18 : : * the macro can be commented to save the effort of fast path.
19 : : * Currently below 6 features are supported in RX path,
20 : : * 1, checksum offload
21 : : * 2, VLAN/QINQ stripping
22 : : * 3, RSS hash
23 : : * 4, packet type analysis
24 : : * 5, flow director ID report
25 : : * 6, timestamp offload
26 : : ******************************************************************************/
27 : : #define IAVF_RX_CSUM_OFFLOAD
28 : : #define IAVF_RX_VLAN_OFFLOAD
29 : : #define IAVF_RX_RSS_OFFLOAD
30 : : #define IAVF_RX_PTYPE_OFFLOAD
31 : : #define IAVF_RX_FDIR_OFFLOAD
32 : : #define IAVF_RX_TS_OFFLOAD
33 : :
34 : : static __rte_always_inline void
35 : : iavf_rxq_rearm(struct iavf_rx_queue *rxq)
36 : : {
37 : : iavf_rxq_rearm_common(rxq, true);
38 : : }
39 : :
40 : : #define IAVF_RX_LEN_MASK 0x80808080
41 : : static __rte_always_inline uint16_t
42 : : _iavf_recv_raw_pkts_vec_avx512(struct iavf_rx_queue *rxq,
43 : : struct rte_mbuf **rx_pkts,
44 : : uint16_t nb_pkts, uint8_t *split_packet,
45 : : bool offload)
46 : : {
47 : : #ifdef IAVF_RX_PTYPE_OFFLOAD
48 : 0 : const uint32_t *type_table = rxq->vsi->adapter->ptype_tbl;
49 : : #endif
50 : :
51 : 0 : const __m256i mbuf_init = _mm256_set_epi64x(0, 0, 0,
52 : 0 : rxq->mbuf_initializer);
53 : 0 : struct rte_mbuf **sw_ring = &rxq->sw_ring[rxq->rx_tail];
54 : 0 : volatile union iavf_rx_desc *rxdp = rxq->rx_ring + rxq->rx_tail;
55 : :
56 : : rte_prefetch0(rxdp);
57 : :
58 : : /* nb_pkts has to be floor-aligned to IAVF_DESCS_PER_LOOP_AVX */
59 : 0 : nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, IAVF_DESCS_PER_LOOP_AVX);
60 : :
61 : : /* See if we need to rearm the RX queue - gives the prefetch a bit
62 : : * of time to act
63 : : */
64 [ # # # # : 0 : if (rxq->rxrearm_nb > IAVF_RXQ_REARM_THRESH)
# # # # #
# # # ]
65 : : iavf_rxq_rearm(rxq);
66 : :
67 : : /* Before we start moving massive data around, check to see if
68 : : * there is actually a packet available
69 : : */
70 [ # # # # : 0 : if (!(rxdp->wb.qword1.status_error_len &
# # # # #
# # # ]
71 : : rte_cpu_to_le_32(1 << IAVF_RX_DESC_STATUS_DD_SHIFT)))
72 : : return 0;
73 : :
74 : : /* constants used in processing loop */
75 : : const __m512i crc_adjust =
76 : 0 : _mm512_set_epi32
77 : : (/* 1st descriptor */
78 : : 0, /* ignore non-length fields */
79 : : -rxq->crc_len, /* sub crc on data_len */
80 : : -rxq->crc_len, /* sub crc on pkt_len */
81 : : 0, /* ignore pkt_type field */
82 : : /* 2nd descriptor */
83 : : 0, /* ignore non-length fields */
84 : : -rxq->crc_len, /* sub crc on data_len */
85 : : -rxq->crc_len, /* sub crc on pkt_len */
86 : : 0, /* ignore pkt_type field */
87 : : /* 3rd descriptor */
88 : : 0, /* ignore non-length fields */
89 : : -rxq->crc_len, /* sub crc on data_len */
90 : : -rxq->crc_len, /* sub crc on pkt_len */
91 : : 0, /* ignore pkt_type field */
92 : : /* 4th descriptor */
93 : : 0, /* ignore non-length fields */
94 : : -rxq->crc_len, /* sub crc on data_len */
95 : 0 : -rxq->crc_len, /* sub crc on pkt_len */
96 : : 0 /* ignore pkt_type field */
97 : : );
98 : :
99 : : /* 8 packets DD mask, LSB in each 32-bit value */
100 : : const __m256i dd_check = _mm256_set1_epi32(1);
101 : :
102 : : /* 8 packets EOP mask, second-LSB in each 32-bit value */
103 : : const __m256i eop_check = _mm256_slli_epi32(dd_check,
104 : : IAVF_RX_DESC_STATUS_EOF_SHIFT);
105 : :
106 : : /* mask to shuffle from desc. to mbuf (4 descriptors)*/
107 : : const __m512i shuf_msk =
108 : : _mm512_set_epi32
109 : : (/* 1st descriptor */
110 : : 0x07060504, /* octet 4~7, 32bits rss */
111 : : 0x03020F0E, /* octet 2~3, low 16 bits vlan_macip */
112 : : /* octet 15~14, 16 bits data_len */
113 : : 0xFFFF0F0E, /* skip high 16 bits pkt_len, zero out */
114 : : /* octet 15~14, low 16 bits pkt_len */
115 : : 0xFFFFFFFF, /* pkt_type set as unknown */
116 : : /* 2nd descriptor */
117 : : 0x07060504, /* octet 4~7, 32bits rss */
118 : : 0x03020F0E, /* octet 2~3, low 16 bits vlan_macip */
119 : : /* octet 15~14, 16 bits data_len */
120 : : 0xFFFF0F0E, /* skip high 16 bits pkt_len, zero out */
121 : : /* octet 15~14, low 16 bits pkt_len */
122 : : 0xFFFFFFFF, /* pkt_type set as unknown */
123 : : /* 3rd descriptor */
124 : : 0x07060504, /* octet 4~7, 32bits rss */
125 : : 0x03020F0E, /* octet 2~3, low 16 bits vlan_macip */
126 : : /* octet 15~14, 16 bits data_len */
127 : : 0xFFFF0F0E, /* skip high 16 bits pkt_len, zero out */
128 : : /* octet 15~14, low 16 bits pkt_len */
129 : : 0xFFFFFFFF, /* pkt_type set as unknown */
130 : : /* 4th descriptor */
131 : : 0x07060504, /* octet 4~7, 32bits rss */
132 : : 0x03020F0E, /* octet 2~3, low 16 bits vlan_macip */
133 : : /* octet 15~14, 16 bits data_len */
134 : : 0xFFFF0F0E, /* skip high 16 bits pkt_len, zero out */
135 : : /* octet 15~14, low 16 bits pkt_len */
136 : : 0xFFFFFFFF /* pkt_type set as unknown */
137 : : );
138 : : /**
139 : : * compile-time check the above crc and shuffle layout is correct.
140 : : * NOTE: the first field (lowest address) is given last in set_epi
141 : : * calls above.
142 : : */
143 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
144 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4);
145 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) !=
146 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 8);
147 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, vlan_tci) !=
148 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 10);
149 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, hash) !=
150 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 12);
151 : :
152 : : uint16_t i, received;
153 : :
154 [ # # # # : 0 : for (i = 0, received = 0; i < nb_pkts;
# # # # #
# # # ]
155 : 0 : i += IAVF_DESCS_PER_LOOP_AVX,
156 : 0 : rxdp += IAVF_DESCS_PER_LOOP_AVX) {
157 : : /* step 1, copy over 8 mbuf pointers to rx_pkts array */
158 : 0 : _mm256_storeu_si256((void *)&rx_pkts[i],
159 : 0 : _mm256_loadu_si256((void *)&sw_ring[i]));
160 : : #ifdef RTE_ARCH_X86_64
161 : : _mm256_storeu_si256
162 : 0 : ((void *)&rx_pkts[i + 4],
163 : 0 : _mm256_loadu_si256((void *)&sw_ring[i + 4]));
164 : : #endif
165 : :
166 : : __m512i raw_desc0_3, raw_desc4_7;
167 : : const __m128i raw_desc7 =
168 : : _mm_load_si128((void *)(rxdp + 7));
169 : 0 : rte_compiler_barrier();
170 : : const __m128i raw_desc6 =
171 : : _mm_load_si128((void *)(rxdp + 6));
172 : 0 : rte_compiler_barrier();
173 : : const __m128i raw_desc5 =
174 : : _mm_load_si128((void *)(rxdp + 5));
175 : 0 : rte_compiler_barrier();
176 : : const __m128i raw_desc4 =
177 : : _mm_load_si128((void *)(rxdp + 4));
178 : 0 : rte_compiler_barrier();
179 : : const __m128i raw_desc3 =
180 : : _mm_load_si128((void *)(rxdp + 3));
181 : 0 : rte_compiler_barrier();
182 : : const __m128i raw_desc2 =
183 : : _mm_load_si128((void *)(rxdp + 2));
184 : 0 : rte_compiler_barrier();
185 : : const __m128i raw_desc1 =
186 : : _mm_load_si128((void *)(rxdp + 1));
187 : 0 : rte_compiler_barrier();
188 : : const __m128i raw_desc0 =
189 : : _mm_load_si128((void *)(rxdp + 0));
190 : :
191 : : raw_desc4_7 = _mm512_broadcast_i32x4(raw_desc4);
192 : : raw_desc4_7 = _mm512_inserti32x4(raw_desc4_7, raw_desc5, 1);
193 : : raw_desc4_7 = _mm512_inserti32x4(raw_desc4_7, raw_desc6, 2);
194 : : raw_desc4_7 = _mm512_inserti32x4(raw_desc4_7, raw_desc7, 3);
195 : : raw_desc0_3 = _mm512_broadcast_i32x4(raw_desc0);
196 : : raw_desc0_3 = _mm512_inserti32x4(raw_desc0_3, raw_desc1, 1);
197 : : raw_desc0_3 = _mm512_inserti32x4(raw_desc0_3, raw_desc2, 2);
198 : : raw_desc0_3 = _mm512_inserti32x4(raw_desc0_3, raw_desc3, 3);
199 : :
200 [ # # # # : 0 : if (split_packet) {
# # # # ]
201 : : int j;
202 : :
203 [ # # # # : 0 : for (j = 0; j < IAVF_DESCS_PER_LOOP_AVX; j++)
# # # # ]
204 : 0 : rte_mbuf_prefetch_part2(rx_pkts[i + j]);
205 : : }
206 : :
207 : : /**
208 : : * convert descriptors 4-7 into mbufs, adjusting length and
209 : : * re-arranging fields. Then write into the mbuf
210 : : */
211 : : const __m512i len4_7 = _mm512_slli_epi32(raw_desc4_7,
212 : : PKTLEN_SHIFT);
213 : : const __m512i desc4_7 = _mm512_mask_blend_epi16(IAVF_RX_LEN_MASK,
214 : : raw_desc4_7,
215 : : len4_7);
216 : : __m512i mb4_7 = _mm512_shuffle_epi8(desc4_7, shuf_msk);
217 : :
218 : : mb4_7 = _mm512_add_epi32(mb4_7, crc_adjust);
219 : : #ifdef IAVF_RX_PTYPE_OFFLOAD
220 : : /**
221 : : * to get packet types, shift 64-bit values down 30 bits
222 : : * and so ptype is in lower 8-bits in each
223 : : */
224 : : const __m512i ptypes4_7 = _mm512_srli_epi64(desc4_7, 30);
225 : : const __m256i ptypes6_7 = _mm512_extracti64x4_epi64(ptypes4_7, 1);
226 : : const __m256i ptypes4_5 = _mm512_extracti64x4_epi64(ptypes4_7, 0);
227 : : const uint8_t ptype7 = _mm256_extract_epi8(ptypes6_7, 24);
228 : : const uint8_t ptype6 = _mm256_extract_epi8(ptypes6_7, 8);
229 : : const uint8_t ptype5 = _mm256_extract_epi8(ptypes4_5, 24);
230 : : const uint8_t ptype4 = _mm256_extract_epi8(ptypes4_5, 8);
231 : :
232 : 0 : const __m512i ptype4_7 = _mm512_set_epi32
233 : 0 : (0, 0, 0, type_table[ptype7],
234 : 0 : 0, 0, 0, type_table[ptype6],
235 : 0 : 0, 0, 0, type_table[ptype5],
236 [ # # # # : 0 : 0, 0, 0, type_table[ptype4]);
# # # # #
# # # ]
237 : : mb4_7 = _mm512_mask_blend_epi32(0x1111, mb4_7, ptype4_7);
238 : : #endif
239 : :
240 : : /**
241 : : * convert descriptors 0-3 into mbufs, adjusting length and
242 : : * re-arranging fields. Then write into the mbuf
243 : : */
244 : : const __m512i len0_3 = _mm512_slli_epi32(raw_desc0_3,
245 : : PKTLEN_SHIFT);
246 : : const __m512i desc0_3 = _mm512_mask_blend_epi16(IAVF_RX_LEN_MASK,
247 : : raw_desc0_3,
248 : : len0_3);
249 : : __m512i mb0_3 = _mm512_shuffle_epi8(desc0_3, shuf_msk);
250 : :
251 : : mb0_3 = _mm512_add_epi32(mb0_3, crc_adjust);
252 : : #ifdef IAVF_RX_PTYPE_OFFLOAD
253 : : /* get the packet types */
254 : : const __m512i ptypes0_3 = _mm512_srli_epi64(desc0_3, 30);
255 : : const __m256i ptypes2_3 = _mm512_extracti64x4_epi64(ptypes0_3, 1);
256 : : const __m256i ptypes0_1 = _mm512_extracti64x4_epi64(ptypes0_3, 0);
257 : : const uint8_t ptype3 = _mm256_extract_epi8(ptypes2_3, 24);
258 : : const uint8_t ptype2 = _mm256_extract_epi8(ptypes2_3, 8);
259 : : const uint8_t ptype1 = _mm256_extract_epi8(ptypes0_1, 24);
260 : : const uint8_t ptype0 = _mm256_extract_epi8(ptypes0_1, 8);
261 : :
262 : 0 : const __m512i ptype0_3 = _mm512_set_epi32
263 : 0 : (0, 0, 0, type_table[ptype3],
264 : 0 : 0, 0, 0, type_table[ptype2],
265 : 0 : 0, 0, 0, type_table[ptype1],
266 [ # # # # : 0 : 0, 0, 0, type_table[ptype0]);
# # # # #
# # # ]
267 : : mb0_3 = _mm512_mask_blend_epi32(0x1111, mb0_3, ptype0_3);
268 : : #endif
269 : :
270 : : /**
271 : : * use permute/extract to get status content
272 : : * After the operations, the packets status flags are in the
273 : : * order (hi->lo): [1, 3, 5, 7, 0, 2, 4, 6]
274 : : */
275 : : /* merge the status bits into one register */
276 : : const __m512i status_permute_msk = _mm512_set_epi32
277 : : (0, 0, 0, 0,
278 : : 0, 0, 0, 0,
279 : : 22, 30, 6, 14,
280 : : 18, 26, 2, 10);
281 : : const __m512i raw_status0_7 = _mm512_permutex2var_epi32
282 : : (raw_desc4_7, status_permute_msk, raw_desc0_3);
283 : : __m256i status0_7 = _mm512_extracti64x4_epi64
284 : : (raw_status0_7, 0);
285 : :
286 : : /* now do flag manipulation */
287 : :
288 : : /* merge flags */
289 : : __m256i mbuf_flags = _mm256_set1_epi32(0);
290 : :
291 : : if (offload) {
292 : : #if defined(IAVF_RX_CSUM_OFFLOAD) || defined(IAVF_RX_VLAN_OFFLOAD) || defined(IAVF_RX_RSS_OFFLOAD)
293 : : /* Status/Error flag masks */
294 : : /**
295 : : * mask everything except RSS, flow director and VLAN flags
296 : : * bit2 is for VLAN tag, bit11 for flow director indication
297 : : * bit13:12 for RSS indication. Bits 3-5 of error
298 : : * field (bits 22-24) are for IP/L4 checksum errors
299 : : */
300 : : const __m256i flags_mask =
301 : : _mm256_set1_epi32((1 << 2) | (1 << 11) |
302 : : (3 << 12) | (7 << 22));
303 : : #endif
304 : :
305 : : #ifdef IAVF_RX_VLAN_OFFLOAD
306 : : /**
307 : : * data to be shuffled by result of flag mask. If VLAN bit is set,
308 : : * (bit 2), then position 4 in this array will be used in the
309 : : * destination
310 : : */
311 : : const __m256i vlan_flags_shuf =
312 : : _mm256_set_epi32(0, 0, RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED, 0,
313 : : 0, 0, RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED, 0);
314 : : #endif
315 : :
316 : : #ifdef IAVF_RX_RSS_OFFLOAD
317 : : /**
318 : : * data to be shuffled by result of flag mask, shifted down 11.
319 : : * If RSS/FDIR bits are set, shuffle moves appropriate flags in
320 : : * place.
321 : : */
322 : : const __m256i rss_flags_shuf =
323 : : _mm256_set_epi8(0, 0, 0, 0, 0, 0, 0, 0,
324 : : RTE_MBUF_F_RX_RSS_HASH | RTE_MBUF_F_RX_FDIR, RTE_MBUF_F_RX_RSS_HASH,
325 : : 0, 0, 0, 0, RTE_MBUF_F_RX_FDIR, 0,/* end up 128-bits */
326 : : 0, 0, 0, 0, 0, 0, 0, 0,
327 : : RTE_MBUF_F_RX_RSS_HASH | RTE_MBUF_F_RX_FDIR, RTE_MBUF_F_RX_RSS_HASH,
328 : : 0, 0, 0, 0, RTE_MBUF_F_RX_FDIR, 0);
329 : : #endif
330 : :
331 : : #ifdef IAVF_RX_CSUM_OFFLOAD
332 : : /**
333 : : * data to be shuffled by the result of the flags mask shifted by 22
334 : : * bits. This gives use the l3_l4 flags.
335 : : */
336 : : const __m256i l3_l4_flags_shuf = _mm256_set_epi8(0, 0, 0, 0, 0, 0, 0, 0,
337 : : /* shift right 1 bit to make sure it not exceed 255 */
338 : : (RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
339 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
340 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
341 : : RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1,
342 : : (RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
343 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD) >> 1,
344 : : (RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
345 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1,
346 : : RTE_MBUF_F_RX_IP_CKSUM_BAD >> 1,
347 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1,
348 : : /* second 128-bits */
349 : : 0, 0, 0, 0, 0, 0, 0, 0,
350 : : (RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
351 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
352 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
353 : : RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1,
354 : : (RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
355 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD) >> 1,
356 : : (RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
357 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1,
358 : : RTE_MBUF_F_RX_IP_CKSUM_BAD >> 1,
359 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1);
360 : :
361 : : const __m256i cksum_mask =
362 : : _mm256_set1_epi32(RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD |
363 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
364 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD);
365 : : #endif
366 : :
367 : : #if defined(IAVF_RX_CSUM_OFFLOAD) || defined(IAVF_RX_VLAN_OFFLOAD) || defined(IAVF_RX_RSS_OFFLOAD)
368 : : /* get only flag/error bits we want */
369 : : const __m256i flag_bits =
370 : : _mm256_and_si256(status0_7, flags_mask);
371 : : #endif
372 : : /* set vlan and rss flags */
373 : : #ifdef IAVF_RX_VLAN_OFFLOAD
374 : : const __m256i vlan_flags =
375 : : _mm256_shuffle_epi8(vlan_flags_shuf, flag_bits);
376 : : #endif
377 : : #ifdef IAVF_RX_RSS_OFFLOAD
378 : : const __m256i rss_flags =
379 : : _mm256_shuffle_epi8(rss_flags_shuf,
380 : : _mm256_srli_epi32(flag_bits, 11));
381 : : #endif
382 : : #ifdef IAVF_RX_CSUM_OFFLOAD
383 : : /**
384 : : * l3_l4_error flags, shuffle, then shift to correct adjustment
385 : : * of flags in flags_shuf, and finally mask out extra bits
386 : : */
387 : : __m256i l3_l4_flags = _mm256_shuffle_epi8(l3_l4_flags_shuf,
388 : : _mm256_srli_epi32(flag_bits, 22));
389 : : l3_l4_flags = _mm256_slli_epi32(l3_l4_flags, 1);
390 : : l3_l4_flags = _mm256_and_si256(l3_l4_flags, cksum_mask);
391 : : #endif
392 : :
393 : : #ifdef IAVF_RX_CSUM_OFFLOAD
394 : : mbuf_flags = _mm256_or_si256(mbuf_flags, l3_l4_flags);
395 : : #endif
396 : : #ifdef IAVF_RX_RSS_OFFLOAD
397 : : mbuf_flags = _mm256_or_si256(mbuf_flags, rss_flags);
398 : : #endif
399 : : #ifdef IAVF_RX_VLAN_OFFLOAD
400 : : mbuf_flags = _mm256_or_si256(mbuf_flags, vlan_flags);
401 : : #endif
402 : : }
403 : :
404 : : /**
405 : : * At this point, we have the 8 sets of flags in the low 16-bits
406 : : * of each 32-bit value in vlan0.
407 : : * We want to extract these, and merge them with the mbuf init
408 : : * data so we can do a single write to the mbuf to set the flags
409 : : * and all the other initialization fields. Extracting the
410 : : * appropriate flags means that we have to do a shift and blend
411 : : * for each mbuf before we do the write. However, we can also
412 : : * add in the previously computed rx_descriptor fields to
413 : : * make a single 256-bit write per mbuf
414 : : */
415 : : /* check the structure matches expectations */
416 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=
417 : : offsetof(struct rte_mbuf, rearm_data) + 8);
418 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, rearm_data) !=
419 : : RTE_ALIGN(offsetof(struct rte_mbuf,
420 : : rearm_data),
421 : : 16));
422 : : /* build up data and do writes */
423 : : __m256i rearm0, rearm1, rearm2, rearm3, rearm4, rearm5,
424 : : rearm6, rearm7;
425 : : const __m256i mb4_5 = _mm512_extracti64x4_epi64(mb4_7, 0);
426 : : const __m256i mb6_7 = _mm512_extracti64x4_epi64(mb4_7, 1);
427 : : const __m256i mb0_1 = _mm512_extracti64x4_epi64(mb0_3, 0);
428 : : const __m256i mb2_3 = _mm512_extracti64x4_epi64(mb0_3, 1);
429 : :
430 : : if (offload) {
431 : : rearm6 = _mm256_blend_epi32(mbuf_init,
432 : : _mm256_slli_si256(mbuf_flags, 8),
433 : : 0x04);
434 : : rearm4 = _mm256_blend_epi32(mbuf_init,
435 : : _mm256_slli_si256(mbuf_flags, 4),
436 : : 0x04);
437 : : rearm2 = _mm256_blend_epi32(mbuf_init, mbuf_flags, 0x04);
438 : : rearm0 = _mm256_blend_epi32(mbuf_init,
439 : : _mm256_srli_si256(mbuf_flags, 4),
440 : : 0x04);
441 : : /* permute to add in the rx_descriptor e.g. rss fields */
442 : : rearm6 = _mm256_permute2f128_si256(rearm6, mb6_7, 0x20);
443 : : rearm4 = _mm256_permute2f128_si256(rearm4, mb4_5, 0x20);
444 : : rearm2 = _mm256_permute2f128_si256(rearm2, mb2_3, 0x20);
445 : : rearm0 = _mm256_permute2f128_si256(rearm0, mb0_1, 0x20);
446 : : } else {
447 : : rearm6 = _mm256_permute2f128_si256(mbuf_init, mb6_7, 0x20);
448 : : rearm4 = _mm256_permute2f128_si256(mbuf_init, mb4_5, 0x20);
449 : : rearm2 = _mm256_permute2f128_si256(mbuf_init, mb2_3, 0x20);
450 : : rearm0 = _mm256_permute2f128_si256(mbuf_init, mb0_1, 0x20);
451 : : }
452 : : /* write to mbuf */
453 [ # # # # : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 6]->rearm_data,
# # # # #
# # # ]
454 : : rearm6);
455 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 4]->rearm_data,
456 : : rearm4);
457 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 2]->rearm_data,
458 : : rearm2);
459 [ # # # # : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 0]->rearm_data,
# # # # #
# # # ]
460 : : rearm0);
461 : :
462 : : /* repeat for the odd mbufs */
463 : : if (offload) {
464 : : const __m256i odd_flags =
465 : : _mm256_castsi128_si256
466 : : (_mm256_extracti128_si256(mbuf_flags, 1));
467 : : rearm7 = _mm256_blend_epi32(mbuf_init,
468 : : _mm256_slli_si256(odd_flags, 8),
469 : : 0x04);
470 : : rearm5 = _mm256_blend_epi32(mbuf_init,
471 : : _mm256_slli_si256(odd_flags, 4),
472 : : 0x04);
473 : : rearm3 = _mm256_blend_epi32(mbuf_init, odd_flags, 0x04);
474 : : rearm1 = _mm256_blend_epi32(mbuf_init,
475 : : _mm256_srli_si256(odd_flags, 4),
476 : : 0x04);
477 : : /* since odd mbufs are already in hi 128-bits use blend */
478 : : rearm7 = _mm256_blend_epi32(rearm7, mb6_7, 0xF0);
479 : : rearm5 = _mm256_blend_epi32(rearm5, mb4_5, 0xF0);
480 : : rearm3 = _mm256_blend_epi32(rearm3, mb2_3, 0xF0);
481 : : rearm1 = _mm256_blend_epi32(rearm1, mb0_1, 0xF0);
482 : : } else {
483 : : rearm7 = _mm256_blend_epi32(mbuf_init, mb6_7, 0xF0);
484 : : rearm5 = _mm256_blend_epi32(mbuf_init, mb4_5, 0xF0);
485 : : rearm3 = _mm256_blend_epi32(mbuf_init, mb2_3, 0xF0);
486 : : rearm1 = _mm256_blend_epi32(mbuf_init, mb0_1, 0xF0);
487 : : }
488 : : /* again write to mbufs */
489 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 7]->rearm_data,
490 : : rearm7);
491 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 5]->rearm_data,
492 : : rearm5);
493 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 3]->rearm_data,
494 : : rearm3);
495 [ # # # # ]: 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 1]->rearm_data,
496 : : rearm1);
497 : :
498 : : /* extract and record EOP bit */
499 [ # # # # : 0 : if (split_packet) {
# # # # ]
500 : : const __m128i eop_mask =
501 : : _mm_set1_epi16(1 << IAVF_RX_DESC_STATUS_EOF_SHIFT);
502 : : const __m256i eop_bits256 = _mm256_and_si256(status0_7,
503 : : eop_check);
504 : : /* pack status bits into a single 128-bit register */
505 : : const __m128i eop_bits =
506 : : _mm_packus_epi32
507 : : (_mm256_castsi256_si128(eop_bits256),
508 : : _mm256_extractf128_si256(eop_bits256,
509 : : 1));
510 : : /**
511 : : * flip bits, and mask out the EOP bit, which is now
512 : : * a split-packet bit i.e. !EOP, rather than EOP one.
513 : : */
514 : : __m128i split_bits = _mm_andnot_si128(eop_bits,
515 : : eop_mask);
516 : : /**
517 : : * eop bits are out of order, so we need to shuffle them
518 : : * back into order again. In doing so, only use low 8
519 : : * bits, which acts like another pack instruction
520 : : * The original order is (hi->lo): 1,3,5,7,0,2,4,6
521 : : * [Since we use epi8, the 16-bit positions are
522 : : * multiplied by 2 in the eop_shuffle value.]
523 : : */
524 : : __m128i eop_shuffle =
525 : : _mm_set_epi8(/* zero hi 64b */
526 : : 0xFF, 0xFF, 0xFF, 0xFF,
527 : : 0xFF, 0xFF, 0xFF, 0xFF,
528 : : /* move values to lo 64b */
529 : : 8, 0, 10, 2,
530 : : 12, 4, 14, 6);
531 : : split_bits = _mm_shuffle_epi8(split_bits, eop_shuffle);
532 : 0 : *(uint64_t *)split_packet =
533 : 0 : _mm_cvtsi128_si64(split_bits);
534 : 0 : split_packet += IAVF_DESCS_PER_LOOP_AVX;
535 : : }
536 : :
537 : : /* perform dd_check */
538 : : status0_7 = _mm256_and_si256(status0_7, dd_check);
539 : : status0_7 = _mm256_packs_epi32(status0_7,
540 : : _mm256_setzero_si256());
541 : :
542 [ # # # # : 0 : uint64_t burst = rte_popcount64
# # # # #
# # # ]
543 : : (_mm_cvtsi128_si64
544 : : (_mm256_extracti128_si256
545 : : (status0_7, 1)));
546 : 0 : burst += rte_popcount64
547 : : (_mm_cvtsi128_si64
548 : : (_mm256_castsi256_si128(status0_7)));
549 : 0 : received += burst;
550 [ # # # # : 0 : if (burst != IAVF_DESCS_PER_LOOP_AVX)
# # # # #
# # # ]
551 : : break;
552 : : }
553 : :
554 : : /* update tail pointers */
555 : 0 : rxq->rx_tail += received;
556 : 0 : rxq->rx_tail &= (rxq->nb_rx_desc - 1);
557 [ # # # # : 0 : if ((rxq->rx_tail & 1) == 1 && received > 1) { /* keep aligned */
# # # # #
# # # # #
# # # # #
# # # #
# ]
558 : 0 : rxq->rx_tail--;
559 : 0 : received--;
560 : : }
561 : 0 : rxq->rxrearm_nb += received;
562 : 0 : return received;
563 : : }
564 : :
565 : : static __rte_always_inline __m256i
566 : : flex_rxd_to_fdir_flags_vec_avx512(const __m256i fdir_id0_7)
567 : : {
568 : : #define FDID_MIS_MAGIC 0xFFFFFFFF
569 : : RTE_BUILD_BUG_ON(RTE_MBUF_F_RX_FDIR != (1 << 2));
570 : : RTE_BUILD_BUG_ON(RTE_MBUF_F_RX_FDIR_ID != (1 << 13));
571 : : const __m256i pkt_fdir_bit = _mm256_set1_epi32(RTE_MBUF_F_RX_FDIR |
572 : : RTE_MBUF_F_RX_FDIR_ID);
573 : : /* desc->flow_id field == 0xFFFFFFFF means fdir mismatch */
574 : : const __m256i fdir_mis_mask = _mm256_set1_epi32(FDID_MIS_MAGIC);
575 : : __m256i fdir_mask = _mm256_cmpeq_epi32(fdir_id0_7,
576 : : fdir_mis_mask);
577 : : /* this XOR op results to bit-reverse the fdir_mask */
578 : : fdir_mask = _mm256_xor_si256(fdir_mask, fdir_mis_mask);
579 : : const __m256i fdir_flags = _mm256_and_si256(fdir_mask, pkt_fdir_bit);
580 : :
581 : : return fdir_flags;
582 : : }
583 : :
584 : : static __rte_always_inline uint16_t
585 : : _iavf_recv_raw_pkts_vec_avx512_flex_rxd(struct iavf_rx_queue *rxq,
586 : : struct rte_mbuf **rx_pkts,
587 : : uint16_t nb_pkts,
588 : : uint8_t *split_packet,
589 : : bool offload)
590 : : {
591 : 0 : struct iavf_adapter *adapter = rxq->vsi->adapter;
592 : : #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
593 : 0 : uint64_t offloads = adapter->dev_data->dev_conf.rxmode.offloads;
594 : : #endif
595 : : #ifdef IAVF_RX_PTYPE_OFFLOAD
596 : 0 : const uint32_t *type_table = adapter->ptype_tbl;
597 : : #endif
598 : :
599 : 0 : const __m256i mbuf_init = _mm256_set_epi64x(0, 0, 0,
600 : 0 : rxq->mbuf_initializer);
601 : 0 : struct rte_mbuf **sw_ring = &rxq->sw_ring[rxq->rx_tail];
602 : 0 : volatile union iavf_rx_flex_desc *rxdp =
603 : 0 : (union iavf_rx_flex_desc *)rxq->rx_ring + rxq->rx_tail;
604 : :
605 : : rte_prefetch0(rxdp);
606 : :
607 : : /* nb_pkts has to be floor-aligned to IAVF_DESCS_PER_LOOP_AVX */
608 : 0 : nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, IAVF_DESCS_PER_LOOP_AVX);
609 : :
610 : : /* See if we need to rearm the RX queue - gives the prefetch a bit
611 : : * of time to act
612 : : */
613 [ # # # # : 0 : if (rxq->rxrearm_nb > IAVF_RXQ_REARM_THRESH)
# # # # #
# # # ]
614 : : iavf_rxq_rearm(rxq);
615 : :
616 : : /* Before we start moving massive data around, check to see if
617 : : * there is actually a packet available
618 : : */
619 [ # # # # : 0 : if (!(rxdp->wb.status_error0 &
# # # # #
# # # ]
620 : : rte_cpu_to_le_32(1 << IAVF_RX_FLEX_DESC_STATUS0_DD_S)))
621 : : return 0;
622 : :
623 : : #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
624 : : #ifdef IAVF_RX_TS_OFFLOAD
625 : : uint8_t inflection_point = 0;
626 : : bool is_tsinit = false;
627 [ # # # # : 0 : __m256i hw_low_last = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, (uint32_t)rxq->phc_time);
# # ]
628 : :
629 [ # # # # : 0 : if (rxq->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) {
# # # # #
# # # ]
630 : 0 : uint64_t sw_cur_time = rte_get_timer_cycles() / (rte_get_timer_hz() / 1000);
631 : :
632 [ # # # # : 0 : if (unlikely(sw_cur_time - rxq->hw_time_update > 4)) {
# # ]
633 : : hw_low_last = _mm256_setzero_si256();
634 : : is_tsinit = 1;
635 : : } else {
636 : 0 : hw_low_last = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, (uint32_t)rxq->phc_time);
637 : : }
638 : : }
639 : : #endif
640 : : #endif
641 : :
642 : : /* constants used in processing loop */
643 : : const __m512i crc_adjust =
644 : 0 : _mm512_set_epi32
645 : : (/* 1st descriptor */
646 : : 0, /* ignore non-length fields */
647 : : -rxq->crc_len, /* sub crc on data_len */
648 : : -rxq->crc_len, /* sub crc on pkt_len */
649 : : 0, /* ignore pkt_type field */
650 : : /* 2nd descriptor */
651 : : 0, /* ignore non-length fields */
652 : : -rxq->crc_len, /* sub crc on data_len */
653 : : -rxq->crc_len, /* sub crc on pkt_len */
654 : : 0, /* ignore pkt_type field */
655 : : /* 3rd descriptor */
656 : : 0, /* ignore non-length fields */
657 : : -rxq->crc_len, /* sub crc on data_len */
658 : : -rxq->crc_len, /* sub crc on pkt_len */
659 : : 0, /* ignore pkt_type field */
660 : : /* 4th descriptor */
661 : : 0, /* ignore non-length fields */
662 : : -rxq->crc_len, /* sub crc on data_len */
663 : 0 : -rxq->crc_len, /* sub crc on pkt_len */
664 : : 0 /* ignore pkt_type field */
665 : : );
666 : :
667 : : /* 8 packets DD mask, LSB in each 32-bit value */
668 : : const __m256i dd_check = _mm256_set1_epi32(1);
669 : :
670 : : /* 8 packets EOP mask, second-LSB in each 32-bit value */
671 : : const __m256i eop_check = _mm256_slli_epi32(dd_check,
672 : : IAVF_RX_FLEX_DESC_STATUS0_EOF_S);
673 : :
674 : : /* mask to shuffle from desc. to mbuf (4 descriptors)*/
675 : : const __m512i shuf_msk =
676 : : _mm512_set_epi32
677 : : (/* 1st descriptor */
678 : : 0xFFFFFFFF, /* rss hash parsed separately */
679 : : 0x0B0A0504, /* octet 10~11, 16 bits vlan_macip */
680 : : /* octet 4~5, 16 bits data_len */
681 : : 0xFFFF0504, /* skip hi 16 bits pkt_len, zero out */
682 : : /* octet 4~5, 16 bits pkt_len */
683 : : 0xFFFFFFFF, /* pkt_type set as unknown */
684 : : /* 2nd descriptor */
685 : : 0xFFFFFFFF, /* rss hash parsed separately */
686 : : 0x0B0A0504, /* octet 10~11, 16 bits vlan_macip */
687 : : /* octet 4~5, 16 bits data_len */
688 : : 0xFFFF0504, /* skip hi 16 bits pkt_len, zero out */
689 : : /* octet 4~5, 16 bits pkt_len */
690 : : 0xFFFFFFFF, /* pkt_type set as unknown */
691 : : /* 3rd descriptor */
692 : : 0xFFFFFFFF, /* rss hash parsed separately */
693 : : 0x0B0A0504, /* octet 10~11, 16 bits vlan_macip */
694 : : /* octet 4~5, 16 bits data_len */
695 : : 0xFFFF0504, /* skip hi 16 bits pkt_len, zero out */
696 : : /* octet 4~5, 16 bits pkt_len */
697 : : 0xFFFFFFFF, /* pkt_type set as unknown */
698 : : /* 4th descriptor */
699 : : 0xFFFFFFFF, /* rss hash parsed separately */
700 : : 0x0B0A0504, /* octet 10~11, 16 bits vlan_macip */
701 : : /* octet 4~5, 16 bits data_len */
702 : : 0xFFFF0504, /* skip hi 16 bits pkt_len, zero out */
703 : : /* octet 4~5, 16 bits pkt_len */
704 : : 0xFFFFFFFF /* pkt_type set as unknown */
705 : : );
706 : : /**
707 : : * compile-time check the above crc and shuffle layout is correct.
708 : : * NOTE: the first field (lowest address) is given last in set_epi
709 : : * calls above.
710 : : */
711 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
712 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4);
713 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) !=
714 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 8);
715 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, vlan_tci) !=
716 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 10);
717 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, hash) !=
718 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 12);
719 : :
720 : : uint16_t i, received;
721 : :
722 [ # # # # : 0 : for (i = 0, received = 0; i < nb_pkts;
# # # # #
# # # ]
723 : 0 : i += IAVF_DESCS_PER_LOOP_AVX,
724 : 0 : rxdp += IAVF_DESCS_PER_LOOP_AVX) {
725 : : /* step 1, copy over 8 mbuf pointers to rx_pkts array */
726 : 0 : _mm256_storeu_si256((void *)&rx_pkts[i],
727 : 0 : _mm256_loadu_si256((void *)&sw_ring[i]));
728 : : #ifdef RTE_ARCH_X86_64
729 : : _mm256_storeu_si256
730 : 0 : ((void *)&rx_pkts[i + 4],
731 : 0 : _mm256_loadu_si256((void *)&sw_ring[i + 4]));
732 : : #endif
733 : :
734 : : __m512i raw_desc0_3, raw_desc4_7;
735 : :
736 : : const __m128i raw_desc7 =
737 : : _mm_load_si128((void *)(rxdp + 7));
738 : 0 : rte_compiler_barrier();
739 : : const __m128i raw_desc6 =
740 : : _mm_load_si128((void *)(rxdp + 6));
741 : 0 : rte_compiler_barrier();
742 : : const __m128i raw_desc5 =
743 : : _mm_load_si128((void *)(rxdp + 5));
744 : 0 : rte_compiler_barrier();
745 : : const __m128i raw_desc4 =
746 : : _mm_load_si128((void *)(rxdp + 4));
747 : 0 : rte_compiler_barrier();
748 : : const __m128i raw_desc3 =
749 : : _mm_load_si128((void *)(rxdp + 3));
750 : 0 : rte_compiler_barrier();
751 : : const __m128i raw_desc2 =
752 : : _mm_load_si128((void *)(rxdp + 2));
753 : 0 : rte_compiler_barrier();
754 : : const __m128i raw_desc1 =
755 : : _mm_load_si128((void *)(rxdp + 1));
756 : 0 : rte_compiler_barrier();
757 : : const __m128i raw_desc0 =
758 : : _mm_load_si128((void *)(rxdp + 0));
759 : :
760 : : raw_desc4_7 = _mm512_broadcast_i32x4(raw_desc4);
761 : : raw_desc4_7 = _mm512_inserti32x4(raw_desc4_7, raw_desc5, 1);
762 : : raw_desc4_7 = _mm512_inserti32x4(raw_desc4_7, raw_desc6, 2);
763 : : raw_desc4_7 = _mm512_inserti32x4(raw_desc4_7, raw_desc7, 3);
764 : : raw_desc0_3 = _mm512_broadcast_i32x4(raw_desc0);
765 : : raw_desc0_3 = _mm512_inserti32x4(raw_desc0_3, raw_desc1, 1);
766 : : raw_desc0_3 = _mm512_inserti32x4(raw_desc0_3, raw_desc2, 2);
767 : : raw_desc0_3 = _mm512_inserti32x4(raw_desc0_3, raw_desc3, 3);
768 : :
769 [ # # # # : 0 : if (split_packet) {
# # # # ]
770 : : int j;
771 : :
772 [ # # # # : 0 : for (j = 0; j < IAVF_DESCS_PER_LOOP_AVX; j++)
# # # # ]
773 : 0 : rte_mbuf_prefetch_part2(rx_pkts[i + j]);
774 : : }
775 : :
776 : : /**
777 : : * convert descriptors 4-7 into mbufs, re-arrange fields.
778 : : * Then write into the mbuf.
779 : : */
780 : : __m512i mb4_7 = _mm512_shuffle_epi8(raw_desc4_7, shuf_msk);
781 : :
782 : : mb4_7 = _mm512_add_epi32(mb4_7, crc_adjust);
783 : : #ifdef IAVF_RX_PTYPE_OFFLOAD
784 : : /**
785 : : * to get packet types, ptype is located in bit16-25
786 : : * of each 128bits
787 : : */
788 : : const __m512i ptype_mask =
789 : : _mm512_set1_epi16(IAVF_RX_FLEX_DESC_PTYPE_M);
790 : : const __m512i ptypes4_7 =
791 : : _mm512_and_si512(raw_desc4_7, ptype_mask);
792 : : const __m256i ptypes6_7 = _mm512_extracti64x4_epi64(ptypes4_7, 1);
793 : : const __m256i ptypes4_5 = _mm512_extracti64x4_epi64(ptypes4_7, 0);
794 : : const uint16_t ptype7 = _mm256_extract_epi16(ptypes6_7, 9);
795 : : const uint16_t ptype6 = _mm256_extract_epi16(ptypes6_7, 1);
796 : : const uint16_t ptype5 = _mm256_extract_epi16(ptypes4_5, 9);
797 : : const uint16_t ptype4 = _mm256_extract_epi16(ptypes4_5, 1);
798 : :
799 : 0 : const __m512i ptype4_7 = _mm512_set_epi32
800 : 0 : (0, 0, 0, type_table[ptype7],
801 : 0 : 0, 0, 0, type_table[ptype6],
802 : 0 : 0, 0, 0, type_table[ptype5],
803 [ # # # # : 0 : 0, 0, 0, type_table[ptype4]);
# # # # #
# # # ]
804 : : mb4_7 = _mm512_mask_blend_epi32(0x1111, mb4_7, ptype4_7);
805 : : #endif
806 : :
807 : : /**
808 : : * convert descriptors 0-3 into mbufs, re-arrange fields.
809 : : * Then write into the mbuf.
810 : : */
811 : : __m512i mb0_3 = _mm512_shuffle_epi8(raw_desc0_3, shuf_msk);
812 : :
813 : : mb0_3 = _mm512_add_epi32(mb0_3, crc_adjust);
814 : : #ifdef IAVF_RX_PTYPE_OFFLOAD
815 : : /**
816 : : * to get packet types, ptype is located in bit16-25
817 : : * of each 128bits
818 : : */
819 : : const __m512i ptypes0_3 =
820 : : _mm512_and_si512(raw_desc0_3, ptype_mask);
821 : : const __m256i ptypes2_3 = _mm512_extracti64x4_epi64(ptypes0_3, 1);
822 : : const __m256i ptypes0_1 = _mm512_extracti64x4_epi64(ptypes0_3, 0);
823 : : const uint16_t ptype3 = _mm256_extract_epi16(ptypes2_3, 9);
824 : : const uint16_t ptype2 = _mm256_extract_epi16(ptypes2_3, 1);
825 : : const uint16_t ptype1 = _mm256_extract_epi16(ptypes0_1, 9);
826 : : const uint16_t ptype0 = _mm256_extract_epi16(ptypes0_1, 1);
827 : :
828 : 0 : const __m512i ptype0_3 = _mm512_set_epi32
829 : 0 : (0, 0, 0, type_table[ptype3],
830 : 0 : 0, 0, 0, type_table[ptype2],
831 : 0 : 0, 0, 0, type_table[ptype1],
832 [ # # # # : 0 : 0, 0, 0, type_table[ptype0]);
# # # # #
# # # ]
833 : : mb0_3 = _mm512_mask_blend_epi32(0x1111, mb0_3, ptype0_3);
834 : : #endif
835 : :
836 : : /**
837 : : * use permute/extract to get status content
838 : : * After the operations, the packets status flags are in the
839 : : * order (hi->lo): [1, 3, 5, 7, 0, 2, 4, 6]
840 : : */
841 : : /* merge the status bits into one register */
842 : : const __m512i status_permute_msk = _mm512_set_epi32
843 : : (0, 0, 0, 0,
844 : : 0, 0, 0, 0,
845 : : 22, 30, 6, 14,
846 : : 18, 26, 2, 10);
847 : : const __m512i raw_status0_7 = _mm512_permutex2var_epi32
848 : : (raw_desc4_7, status_permute_msk, raw_desc0_3);
849 : : __m256i status0_7 = _mm512_extracti64x4_epi64
850 : : (raw_status0_7, 0);
851 : :
852 : : /* now do flag manipulation */
853 : :
854 : : /* merge flags */
855 : : __m256i mbuf_flags = _mm256_set1_epi32(0);
856 : : __m256i vlan_flags = _mm256_setzero_si256();
857 : :
858 : : if (offload) {
859 : : #if defined(IAVF_RX_CSUM_OFFLOAD) || defined(IAVF_RX_VLAN_OFFLOAD) || defined(IAVF_RX_RSS_OFFLOAD)
860 : : /* Status/Error flag masks */
861 : : /**
862 : : * mask everything except Checksum Reports, RSS indication
863 : : * and VLAN indication.
864 : : * bit6:4 for IP/L4 checksum errors.
865 : : * bit12 is for RSS indication.
866 : : * bit13 is for VLAN indication.
867 : : */
868 : : const __m256i flags_mask =
869 : : _mm256_set1_epi32((0xF << 4) | (1 << 12) | (1 << 13));
870 : : #endif
871 : : #ifdef IAVF_RX_CSUM_OFFLOAD
872 : : /**
873 : : * data to be shuffled by the result of the flags mask shifted by 4
874 : : * bits. This gives use the l3_l4 flags.
875 : : */
876 : : const __m256i l3_l4_flags_shuf =
877 : : _mm256_set_epi8((RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
878 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
879 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
880 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
881 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
882 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
883 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
884 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
885 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
886 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
887 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
888 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
889 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
890 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
891 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
892 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
893 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
894 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
895 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
896 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
897 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
898 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
899 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
900 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
901 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
902 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
903 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
904 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
905 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
906 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
907 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
908 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
909 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
910 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
911 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
912 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
913 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
914 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
915 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
916 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
917 : : /**
918 : : * second 128-bits
919 : : * shift right 20 bits to use the low two bits to indicate
920 : : * outer checksum status
921 : : * shift right 1 bit to make sure it not exceed 255
922 : : */
923 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
924 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
925 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
926 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
927 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
928 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
929 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
930 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
931 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
932 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
933 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
934 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
935 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
936 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
937 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
938 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
939 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
940 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
941 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
942 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
943 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
944 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
945 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
946 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
947 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
948 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
949 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
950 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
951 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
952 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
953 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
954 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
955 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
956 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
957 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
958 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
959 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
960 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
961 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 |
962 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1);
963 : : const __m256i cksum_mask =
964 : : _mm256_set1_epi32(RTE_MBUF_F_RX_IP_CKSUM_MASK |
965 : : RTE_MBUF_F_RX_L4_CKSUM_MASK |
966 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
967 : : RTE_MBUF_F_RX_OUTER_L4_CKSUM_MASK);
968 : : #endif
969 : : #if defined(IAVF_RX_VLAN_OFFLOAD) || defined(IAVF_RX_RSS_OFFLOAD)
970 : : /**
971 : : * data to be shuffled by result of flag mask, shifted down 12.
972 : : * If RSS(bit12)/VLAN(bit13) are set,
973 : : * shuffle moves appropriate flags in place.
974 : : */
975 : : const __m256i rss_flags_shuf = _mm256_set_epi8
976 : : (0, 0, 0, 0,
977 : : 0, 0, 0, 0,
978 : : 0, 0, 0, 0,
979 : : RTE_MBUF_F_RX_RSS_HASH, 0,
980 : : RTE_MBUF_F_RX_RSS_HASH, 0,
981 : : /* end up 128-bits */
982 : : 0, 0, 0, 0,
983 : : 0, 0, 0, 0,
984 : : 0, 0, 0, 0,
985 : : RTE_MBUF_F_RX_RSS_HASH, 0,
986 : : RTE_MBUF_F_RX_RSS_HASH, 0);
987 : :
988 : : const __m256i vlan_flags_shuf = _mm256_set_epi8
989 : : (0, 0, 0, 0,
990 : : 0, 0, 0, 0,
991 : : 0, 0, 0, 0,
992 : : RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
993 : : RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
994 : : 0, 0,
995 : : /* end up 128-bits */
996 : : 0, 0, 0, 0,
997 : : 0, 0, 0, 0,
998 : : 0, 0, 0, 0,
999 : : RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
1000 : : RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
1001 : : 0, 0);
1002 : : #endif
1003 : :
1004 : : #if defined(IAVF_RX_CSUM_OFFLOAD) || defined(IAVF_RX_VLAN_OFFLOAD) || defined(IAVF_RX_RSS_OFFLOAD)
1005 : : /* get only flag/error bits we want */
1006 : : const __m256i flag_bits =
1007 : : _mm256_and_si256(status0_7, flags_mask);
1008 : : #endif
1009 : : #ifdef IAVF_RX_CSUM_OFFLOAD
1010 : : /**
1011 : : * l3_l4_error flags, shuffle, then shift to correct adjustment
1012 : : * of flags in flags_shuf, and finally mask out extra bits
1013 : : */
1014 : : __m256i l3_l4_flags = _mm256_shuffle_epi8(l3_l4_flags_shuf,
1015 : : _mm256_srli_epi32(flag_bits, 4));
1016 : : l3_l4_flags = _mm256_slli_epi32(l3_l4_flags, 1);
1017 : : __m256i l4_outer_mask = _mm256_set1_epi32(0x6);
1018 : : __m256i l4_outer_flags =
1019 : : _mm256_and_si256(l3_l4_flags, l4_outer_mask);
1020 : : l4_outer_flags = _mm256_slli_epi32(l4_outer_flags, 20);
1021 : :
1022 : : __m256i l3_l4_mask = _mm256_set1_epi32(~0x6);
1023 : :
1024 : : l3_l4_flags = _mm256_and_si256(l3_l4_flags, l3_l4_mask);
1025 : : l3_l4_flags = _mm256_or_si256(l3_l4_flags, l4_outer_flags);
1026 : : l3_l4_flags = _mm256_and_si256(l3_l4_flags, cksum_mask);
1027 : : #endif
1028 : : #if defined(IAVF_RX_VLAN_OFFLOAD) || defined(IAVF_RX_RSS_OFFLOAD)
1029 : : /* set rss and vlan flags */
1030 : : const __m256i rss_vlan_flag_bits =
1031 : : _mm256_srli_epi32(flag_bits, 12);
1032 : : const __m256i rss_flags =
1033 : : _mm256_shuffle_epi8(rss_flags_shuf,
1034 : : rss_vlan_flag_bits);
1035 : :
1036 [ # # # # : 0 : if (rxq->rx_flags == IAVF_RX_FLAGS_VLAN_TAG_LOC_L2TAG1)
# # ]
1037 : : vlan_flags =
1038 : : _mm256_shuffle_epi8(vlan_flags_shuf,
1039 : : rss_vlan_flag_bits);
1040 : :
1041 : : const __m256i rss_vlan_flags =
1042 : : _mm256_or_si256(rss_flags, vlan_flags);
1043 : :
1044 : : #endif
1045 : :
1046 : : #ifdef IAVF_RX_CSUM_OFFLOAD
1047 : : mbuf_flags = _mm256_or_si256(mbuf_flags, l3_l4_flags);
1048 : : #endif
1049 : : #if defined(IAVF_RX_VLAN_OFFLOAD) || defined(IAVF_RX_RSS_OFFLOAD)
1050 : : mbuf_flags = _mm256_or_si256(mbuf_flags, rss_vlan_flags);
1051 : : #endif
1052 : : }
1053 : :
1054 : : #ifdef IAVF_RX_FDIR_OFFLOAD
1055 [ # # # # : 0 : if (rxq->fdir_enabled) {
# # # # #
# # # ]
1056 : : const __m512i fdir_permute_mask = _mm512_set_epi32
1057 : : (0, 0, 0, 0,
1058 : : 0, 0, 0, 0,
1059 : : 7, 15, 23, 31,
1060 : : 3, 11, 19, 27);
1061 : : __m512i fdir_tmp = _mm512_permutex2var_epi32
1062 : : (raw_desc0_3, fdir_permute_mask, raw_desc4_7);
1063 : : const __m256i fdir_id0_7 = _mm512_extracti64x4_epi64
1064 : : (fdir_tmp, 0);
1065 : : const __m256i fdir_flags =
1066 : : flex_rxd_to_fdir_flags_vec_avx512(fdir_id0_7);
1067 : :
1068 : : /* merge with fdir_flags */
1069 : : mbuf_flags = _mm256_or_si256(mbuf_flags, fdir_flags);
1070 : :
1071 : : /* write to mbuf: have to use scalar store here */
1072 : 0 : rx_pkts[i + 0]->hash.fdir.hi =
1073 : 0 : _mm256_extract_epi32(fdir_id0_7, 3);
1074 : :
1075 : 0 : rx_pkts[i + 1]->hash.fdir.hi =
1076 : 0 : _mm256_extract_epi32(fdir_id0_7, 7);
1077 : :
1078 : 0 : rx_pkts[i + 2]->hash.fdir.hi =
1079 : 0 : _mm256_extract_epi32(fdir_id0_7, 2);
1080 : :
1081 : 0 : rx_pkts[i + 3]->hash.fdir.hi =
1082 : 0 : _mm256_extract_epi32(fdir_id0_7, 6);
1083 : :
1084 : 0 : rx_pkts[i + 4]->hash.fdir.hi =
1085 : 0 : _mm256_extract_epi32(fdir_id0_7, 1);
1086 : :
1087 : 0 : rx_pkts[i + 5]->hash.fdir.hi =
1088 : 0 : _mm256_extract_epi32(fdir_id0_7, 5);
1089 : :
1090 : 0 : rx_pkts[i + 6]->hash.fdir.hi =
1091 : 0 : _mm256_extract_epi32(fdir_id0_7, 0);
1092 : :
1093 : 0 : rx_pkts[i + 7]->hash.fdir.hi =
1094 : 0 : _mm256_extract_epi32(fdir_id0_7, 4);
1095 : : } /* if() on fdir_enabled */
1096 : : #endif
1097 : :
1098 : : __m256i mb4_5 = _mm512_extracti64x4_epi64(mb4_7, 0);
1099 : : __m256i mb6_7 = _mm512_extracti64x4_epi64(mb4_7, 1);
1100 : : __m256i mb0_1 = _mm512_extracti64x4_epi64(mb0_3, 0);
1101 : : __m256i mb2_3 = _mm512_extracti64x4_epi64(mb0_3, 1);
1102 : :
1103 : : #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
1104 : : if (offload) {
1105 : : #if defined(IAVF_RX_RSS_OFFLOAD) || defined(IAVF_RX_TS_OFFLOAD)
1106 : : /**
1107 : : * needs to load 2nd 16B of each desc for RSS hash parsing,
1108 : : * will cause performance drop to get into this context.
1109 : : */
1110 [ # # # # : 0 : if (offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH ||
# # ]
1111 [ # # # # : 0 : offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP ||
# # ]
1112 : : rxq->rx_flags & IAVF_RX_FLAGS_VLAN_TAG_LOC_L2TAG2_2) {
1113 : : /* load bottom half of every 32B desc */
1114 : : const __m128i raw_desc_bh7 =
1115 : : _mm_load_si128
1116 : : ((void *)(&rxdp[7].wb.status_error1));
1117 : 0 : rte_compiler_barrier();
1118 : : const __m128i raw_desc_bh6 =
1119 : : _mm_load_si128
1120 : : ((void *)(&rxdp[6].wb.status_error1));
1121 : 0 : rte_compiler_barrier();
1122 : : const __m128i raw_desc_bh5 =
1123 : : _mm_load_si128
1124 : : ((void *)(&rxdp[5].wb.status_error1));
1125 : 0 : rte_compiler_barrier();
1126 : : const __m128i raw_desc_bh4 =
1127 : : _mm_load_si128
1128 : : ((void *)(&rxdp[4].wb.status_error1));
1129 : 0 : rte_compiler_barrier();
1130 : : const __m128i raw_desc_bh3 =
1131 : : _mm_load_si128
1132 : : ((void *)(&rxdp[3].wb.status_error1));
1133 : 0 : rte_compiler_barrier();
1134 : : const __m128i raw_desc_bh2 =
1135 : : _mm_load_si128
1136 : : ((void *)(&rxdp[2].wb.status_error1));
1137 : 0 : rte_compiler_barrier();
1138 : : const __m128i raw_desc_bh1 =
1139 : : _mm_load_si128
1140 : : ((void *)(&rxdp[1].wb.status_error1));
1141 : 0 : rte_compiler_barrier();
1142 : : const __m128i raw_desc_bh0 =
1143 : : _mm_load_si128
1144 : : ((void *)(&rxdp[0].wb.status_error1));
1145 : :
1146 : : __m256i raw_desc_bh6_7 =
1147 : : _mm256_inserti128_si256
1148 : : (_mm256_castsi128_si256(raw_desc_bh6),
1149 : : raw_desc_bh7, 1);
1150 : : __m256i raw_desc_bh4_5 =
1151 : : _mm256_inserti128_si256
1152 : : (_mm256_castsi128_si256(raw_desc_bh4),
1153 : : raw_desc_bh5, 1);
1154 : : __m256i raw_desc_bh2_3 =
1155 : : _mm256_inserti128_si256
1156 : : (_mm256_castsi128_si256(raw_desc_bh2),
1157 : : raw_desc_bh3, 1);
1158 : : __m256i raw_desc_bh0_1 =
1159 : : _mm256_inserti128_si256
1160 : : (_mm256_castsi128_si256(raw_desc_bh0),
1161 : : raw_desc_bh1, 1);
1162 : :
1163 : : #ifdef IAVF_RX_RSS_OFFLOAD
1164 [ # # # # : 0 : if (offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH) {
# # ]
1165 : : /**
1166 : : * to shift the 32b RSS hash value to the
1167 : : * highest 32b of each 128b before mask
1168 : : */
1169 : : __m256i rss_hash6_7 =
1170 : : _mm256_slli_epi64
1171 : : (raw_desc_bh6_7, 32);
1172 : : __m256i rss_hash4_5 =
1173 : : _mm256_slli_epi64
1174 : : (raw_desc_bh4_5, 32);
1175 : : __m256i rss_hash2_3 =
1176 : : _mm256_slli_epi64
1177 : : (raw_desc_bh2_3, 32);
1178 : : __m256i rss_hash0_1 =
1179 : : _mm256_slli_epi64
1180 : : (raw_desc_bh0_1, 32);
1181 : :
1182 : : const __m256i rss_hash_msk =
1183 : : _mm256_set_epi32
1184 : : (0xFFFFFFFF, 0, 0, 0,
1185 : : 0xFFFFFFFF, 0, 0, 0);
1186 : :
1187 : : rss_hash6_7 = _mm256_and_si256
1188 : : (rss_hash6_7, rss_hash_msk);
1189 : : rss_hash4_5 = _mm256_and_si256
1190 : : (rss_hash4_5, rss_hash_msk);
1191 : : rss_hash2_3 = _mm256_and_si256
1192 : : (rss_hash2_3, rss_hash_msk);
1193 : : rss_hash0_1 = _mm256_and_si256
1194 : : (rss_hash0_1, rss_hash_msk);
1195 : :
1196 : : mb6_7 = _mm256_or_si256
1197 : : (mb6_7, rss_hash6_7);
1198 : : mb4_5 = _mm256_or_si256
1199 : : (mb4_5, rss_hash4_5);
1200 : : mb2_3 = _mm256_or_si256
1201 : : (mb2_3, rss_hash2_3);
1202 : : mb0_1 = _mm256_or_si256
1203 : : (mb0_1, rss_hash0_1);
1204 : : }
1205 : :
1206 [ # # # # : 0 : if (rxq->rx_flags & IAVF_RX_FLAGS_VLAN_TAG_LOC_L2TAG2_2) {
# # ]
1207 : : /* merge the status/error-1 bits into one register */
1208 : : const __m256i status1_4_7 =
1209 : : _mm256_unpacklo_epi32
1210 : : (raw_desc_bh6_7,
1211 : : raw_desc_bh4_5);
1212 : : const __m256i status1_0_3 =
1213 : : _mm256_unpacklo_epi32
1214 : : (raw_desc_bh2_3,
1215 : : raw_desc_bh0_1);
1216 : :
1217 : : const __m256i status1_0_7 =
1218 : : _mm256_unpacklo_epi64
1219 : : (status1_4_7, status1_0_3);
1220 : :
1221 : : const __m256i l2tag2p_flag_mask =
1222 : : _mm256_set1_epi32
1223 : : (1 << IAVF_RX_FLEX_DESC_STATUS1_L2TAG2P_S);
1224 : :
1225 : : __m256i l2tag2p_flag_bits =
1226 : : _mm256_and_si256
1227 : : (status1_0_7,
1228 : : l2tag2p_flag_mask);
1229 : :
1230 : : l2tag2p_flag_bits =
1231 : : _mm256_srli_epi32
1232 : : (l2tag2p_flag_bits,
1233 : : IAVF_RX_FLEX_DESC_STATUS1_L2TAG2P_S);
1234 : :
1235 : : const __m256i l2tag2_flags_shuf =
1236 : : _mm256_set_epi8
1237 : : (0, 0, 0, 0,
1238 : : 0, 0, 0, 0,
1239 : : 0, 0, 0, 0,
1240 : : 0, 0,
1241 : : RTE_MBUF_F_RX_VLAN |
1242 : : RTE_MBUF_F_RX_VLAN_STRIPPED,
1243 : : 0,
1244 : : /* end up 128-bits */
1245 : : 0, 0, 0, 0,
1246 : : 0, 0, 0, 0,
1247 : : 0, 0, 0, 0,
1248 : : 0, 0,
1249 : : RTE_MBUF_F_RX_VLAN |
1250 : : RTE_MBUF_F_RX_VLAN_STRIPPED,
1251 : : 0);
1252 : :
1253 : : vlan_flags =
1254 : : _mm256_shuffle_epi8
1255 : : (l2tag2_flags_shuf,
1256 : : l2tag2p_flag_bits);
1257 : :
1258 : : /* merge with vlan_flags */
1259 : : mbuf_flags = _mm256_or_si256
1260 : : (mbuf_flags,
1261 : : vlan_flags);
1262 : :
1263 : : /* L2TAG2_2 */
1264 : : __m256i vlan_tci6_7 =
1265 : : _mm256_slli_si256
1266 : : (raw_desc_bh6_7, 4);
1267 : : __m256i vlan_tci4_5 =
1268 : : _mm256_slli_si256
1269 : : (raw_desc_bh4_5, 4);
1270 : : __m256i vlan_tci2_3 =
1271 : : _mm256_slli_si256
1272 : : (raw_desc_bh2_3, 4);
1273 : : __m256i vlan_tci0_1 =
1274 : : _mm256_slli_si256
1275 : : (raw_desc_bh0_1, 4);
1276 : :
1277 : : const __m256i vlan_tci_msk =
1278 : : _mm256_set_epi32
1279 : : (0, 0xFFFF0000, 0, 0,
1280 : : 0, 0xFFFF0000, 0, 0);
1281 : :
1282 : : vlan_tci6_7 = _mm256_and_si256
1283 : : (vlan_tci6_7,
1284 : : vlan_tci_msk);
1285 : : vlan_tci4_5 = _mm256_and_si256
1286 : : (vlan_tci4_5,
1287 : : vlan_tci_msk);
1288 : : vlan_tci2_3 = _mm256_and_si256
1289 : : (vlan_tci2_3,
1290 : : vlan_tci_msk);
1291 : : vlan_tci0_1 = _mm256_and_si256
1292 : : (vlan_tci0_1,
1293 : : vlan_tci_msk);
1294 : :
1295 : : mb6_7 = _mm256_or_si256
1296 : : (mb6_7, vlan_tci6_7);
1297 : : mb4_5 = _mm256_or_si256
1298 : : (mb4_5, vlan_tci4_5);
1299 : : mb2_3 = _mm256_or_si256
1300 : : (mb2_3, vlan_tci2_3);
1301 : : mb0_1 = _mm256_or_si256
1302 : : (mb0_1, vlan_tci0_1);
1303 : : }
1304 : : #endif /* IAVF_RX_RSS_OFFLOAD */
1305 : :
1306 : : #ifdef IAVF_RX_TS_OFFLOAD
1307 [ # # # # : 0 : if (offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) {
# # ]
1308 : : uint32_t mask = 0xFFFFFFFF;
1309 : : __m256i ts;
1310 : : __m256i ts_low = _mm256_setzero_si256();
1311 : : __m256i ts_low1;
1312 : : __m256i ts_low2;
1313 : : __m256i max_ret;
1314 : : __m256i cmp_ret;
1315 : : uint8_t ret = 0;
1316 : : uint8_t shift = 8;
1317 : : __m256i ts_desp_mask = _mm256_set_epi32(mask, 0, 0, 0, mask, 0, 0, 0);
1318 : : __m256i cmp_mask = _mm256_set1_epi32(mask);
1319 : : __m256i ts_permute_mask = _mm256_set_epi32(7, 3, 6, 2, 5, 1, 4, 0);
1320 : :
1321 : : ts = _mm256_and_si256(raw_desc_bh0_1, ts_desp_mask);
1322 : : ts_low = _mm256_or_si256(ts_low, _mm256_srli_si256(ts, 3 * 4));
1323 : : ts = _mm256_and_si256(raw_desc_bh2_3, ts_desp_mask);
1324 : : ts_low = _mm256_or_si256(ts_low, _mm256_srli_si256(ts, 2 * 4));
1325 : : ts = _mm256_and_si256(raw_desc_bh4_5, ts_desp_mask);
1326 : : ts_low = _mm256_or_si256(ts_low, _mm256_srli_si256(ts, 4));
1327 : : ts = _mm256_and_si256(raw_desc_bh6_7, ts_desp_mask);
1328 : : ts_low = _mm256_or_si256(ts_low, ts);
1329 : :
1330 : : ts_low1 = _mm256_permutevar8x32_epi32(ts_low, ts_permute_mask);
1331 : : ts_low2 = _mm256_permutevar8x32_epi32(ts_low1,
1332 : : _mm256_set_epi32(6, 5, 4, 3, 2, 1, 0, 7));
1333 : : ts_low2 = _mm256_and_si256(ts_low2,
1334 : : _mm256_set_epi32(mask, mask, mask, mask, mask, mask, mask, 0));
1335 : : ts_low2 = _mm256_or_si256(ts_low2, hw_low_last);
1336 : : hw_low_last = _mm256_and_si256(ts_low1,
1337 : : _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, mask));
1338 : :
1339 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 0],
1340 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 0);
1341 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 1],
1342 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 1);
1343 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 2],
1344 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 2);
1345 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 3],
1346 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 3);
1347 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 4],
1348 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 4);
1349 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 5],
1350 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 5);
1351 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 6],
1352 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 6);
1353 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 7],
1354 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 7);
1355 : :
1356 [ # # # # : 0 : if (unlikely(is_tsinit)) {
# # ]
1357 : : uint32_t in_timestamp;
1358 : :
1359 [ # # # # : 0 : if (iavf_get_phc_time(rxq))
# # ]
1360 : 0 : PMD_DRV_LOG(ERR, "get physical time failed");
1361 : 0 : in_timestamp = *RTE_MBUF_DYNFIELD(rx_pkts[i + 0],
1362 : : iavf_timestamp_dynfield_offset, uint32_t *);
1363 [ # # # # : 0 : rxq->phc_time = iavf_tstamp_convert_32b_64b(rxq->phc_time, in_timestamp);
# # ]
1364 : : }
1365 : :
1366 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 0],
1367 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1368 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 1],
1369 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1370 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 2],
1371 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1372 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 3],
1373 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1374 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 4],
1375 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1376 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 5],
1377 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1378 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 6],
1379 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1380 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 7],
1381 [ # # # # : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
# # ]
1382 : :
1383 : : max_ret = _mm256_max_epu32(ts_low2, ts_low1);
1384 : : cmp_ret = _mm256_andnot_si256(_mm256_cmpeq_epi32(max_ret, ts_low1), cmp_mask);
1385 : :
1386 [ # # # # : 0 : if (_mm256_testz_si256(cmp_ret, cmp_mask)) {
# # ]
1387 : : inflection_point = 0;
1388 : : } else {
1389 : : inflection_point = 1;
1390 [ # # # # : 0 : while (shift > 1) {
# # ]
1391 : 0 : shift = shift >> 1;
1392 : : __m256i mask_low = _mm256_setzero_si256();
1393 : : __m256i mask_high = _mm256_setzero_si256();
1394 [ # # # # : 0 : switch (shift) {
# # # # #
# # # ]
1395 : 0 : case 4:
1396 : : mask_low = _mm256_set_epi32(0, 0, 0, 0, mask, mask, mask, mask);
1397 : : mask_high = _mm256_set_epi32(mask, mask, mask, mask, 0, 0, 0, 0);
1398 : 0 : break;
1399 : : case 2:
1400 : : mask_low = _mm256_srli_si256(cmp_mask, 2 * 4);
1401 : : mask_high = _mm256_slli_si256(cmp_mask, 2 * 4);
1402 : 0 : break;
1403 : : case 1:
1404 : : mask_low = _mm256_srli_si256(cmp_mask, 1 * 4);
1405 : : mask_high = _mm256_slli_si256(cmp_mask, 1 * 4);
1406 : 0 : break;
1407 : : }
1408 : 0 : ret = _mm256_testz_si256(cmp_ret, mask_low);
1409 [ # # # # : 0 : if (ret) {
# # ]
1410 : 0 : ret = _mm256_testz_si256(cmp_ret, mask_high);
1411 [ # # # # : 0 : inflection_point += ret ? 0 : shift;
# # ]
1412 : : cmp_mask = mask_high;
1413 : : } else {
1414 : : cmp_mask = mask_low;
1415 : : }
1416 : : }
1417 : : }
1418 : 0 : mbuf_flags = _mm256_or_si256(mbuf_flags,
1419 : : _mm256_set1_epi32(iavf_timestamp_dynflag));
1420 : : }
1421 : : #endif /* IAVF_RX_TS_OFFLOAD */
1422 : : } /* if() on RSS hash or RX timestamp parsing */
1423 : : #endif
1424 : : }
1425 : : #endif
1426 : :
1427 : : /**
1428 : : * At this point, we have the 8 sets of flags in the low 16-bits
1429 : : * of each 32-bit value in vlan0.
1430 : : * We want to extract these, and merge them with the mbuf init
1431 : : * data so we can do a single write to the mbuf to set the flags
1432 : : * and all the other initialization fields. Extracting the
1433 : : * appropriate flags means that we have to do a shift and blend
1434 : : * for each mbuf before we do the write. However, we can also
1435 : : * add in the previously computed rx_descriptor fields to
1436 : : * make a single 256-bit write per mbuf
1437 : : */
1438 : : /* check the structure matches expectations */
1439 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=
1440 : : offsetof(struct rte_mbuf, rearm_data) + 8);
1441 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, rearm_data) !=
1442 : : RTE_ALIGN(offsetof(struct rte_mbuf,
1443 : : rearm_data),
1444 : : 16));
1445 : : /* build up data and do writes */
1446 : : __m256i rearm0, rearm1, rearm2, rearm3, rearm4, rearm5,
1447 : : rearm6, rearm7;
1448 : : rearm6 = _mm256_blend_epi32(mbuf_init,
1449 : : _mm256_slli_si256(mbuf_flags, 8),
1450 : : 0x04);
1451 : : rearm4 = _mm256_blend_epi32(mbuf_init,
1452 : : _mm256_slli_si256(mbuf_flags, 4),
1453 : : 0x04);
1454 : : rearm2 = _mm256_blend_epi32(mbuf_init, mbuf_flags, 0x04);
1455 : : rearm0 = _mm256_blend_epi32(mbuf_init,
1456 : : _mm256_srli_si256(mbuf_flags, 4),
1457 : : 0x04);
1458 : : /* permute to add in the rx_descriptor e.g. rss fields */
1459 : : rearm6 = _mm256_permute2f128_si256(rearm6, mb6_7, 0x20);
1460 : : rearm4 = _mm256_permute2f128_si256(rearm4, mb4_5, 0x20);
1461 : : rearm2 = _mm256_permute2f128_si256(rearm2, mb2_3, 0x20);
1462 : : rearm0 = _mm256_permute2f128_si256(rearm0, mb0_1, 0x20);
1463 : : /* write to mbuf */
1464 [ # # # # : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 6]->rearm_data,
# # # # #
# # # ]
1465 : : rearm6);
1466 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 4]->rearm_data,
1467 : : rearm4);
1468 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 2]->rearm_data,
1469 : : rearm2);
1470 [ # # # # : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 0]->rearm_data,
# # # # #
# # # ]
1471 : : rearm0);
1472 : :
1473 : : /* repeat for the odd mbufs */
1474 : : const __m256i odd_flags =
1475 : : _mm256_castsi128_si256
1476 : : (_mm256_extracti128_si256(mbuf_flags, 1));
1477 : : rearm7 = _mm256_blend_epi32(mbuf_init,
1478 : : _mm256_slli_si256(odd_flags, 8),
1479 : : 0x04);
1480 : : rearm5 = _mm256_blend_epi32(mbuf_init,
1481 : : _mm256_slli_si256(odd_flags, 4),
1482 : : 0x04);
1483 : : rearm3 = _mm256_blend_epi32(mbuf_init, odd_flags, 0x04);
1484 : : rearm1 = _mm256_blend_epi32(mbuf_init,
1485 : : _mm256_srli_si256(odd_flags, 4),
1486 : : 0x04);
1487 : : /* since odd mbufs are already in hi 128-bits use blend */
1488 : : rearm7 = _mm256_blend_epi32(rearm7, mb6_7, 0xF0);
1489 : : rearm5 = _mm256_blend_epi32(rearm5, mb4_5, 0xF0);
1490 : : rearm3 = _mm256_blend_epi32(rearm3, mb2_3, 0xF0);
1491 : : rearm1 = _mm256_blend_epi32(rearm1, mb0_1, 0xF0);
1492 : : /* again write to mbufs */
1493 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 7]->rearm_data,
1494 : : rearm7);
1495 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 5]->rearm_data,
1496 : : rearm5);
1497 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 3]->rearm_data,
1498 : : rearm3);
1499 [ # # # # ]: 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 1]->rearm_data,
1500 : : rearm1);
1501 : :
1502 : : /* extract and record EOP bit */
1503 [ # # # # : 0 : if (split_packet) {
# # # # ]
1504 : : const __m128i eop_mask =
1505 : : _mm_set1_epi16(1 <<
1506 : : IAVF_RX_FLEX_DESC_STATUS0_EOF_S);
1507 : : const __m256i eop_bits256 = _mm256_and_si256(status0_7,
1508 : : eop_check);
1509 : : /* pack status bits into a single 128-bit register */
1510 : : const __m128i eop_bits =
1511 : : _mm_packus_epi32
1512 : : (_mm256_castsi256_si128(eop_bits256),
1513 : : _mm256_extractf128_si256(eop_bits256,
1514 : : 1));
1515 : : /**
1516 : : * flip bits, and mask out the EOP bit, which is now
1517 : : * a split-packet bit i.e. !EOP, rather than EOP one.
1518 : : */
1519 : : __m128i split_bits = _mm_andnot_si128(eop_bits,
1520 : : eop_mask);
1521 : : /**
1522 : : * eop bits are out of order, so we need to shuffle them
1523 : : * back into order again. In doing so, only use low 8
1524 : : * bits, which acts like another pack instruction
1525 : : * The original order is (hi->lo): 1,3,5,7,0,2,4,6
1526 : : * [Since we use epi8, the 16-bit positions are
1527 : : * multiplied by 2 in the eop_shuffle value.]
1528 : : */
1529 : : __m128i eop_shuffle =
1530 : : _mm_set_epi8(/* zero hi 64b */
1531 : : 0xFF, 0xFF, 0xFF, 0xFF,
1532 : : 0xFF, 0xFF, 0xFF, 0xFF,
1533 : : /* move values to lo 64b */
1534 : : 8, 0, 10, 2,
1535 : : 12, 4, 14, 6);
1536 : : split_bits = _mm_shuffle_epi8(split_bits, eop_shuffle);
1537 : 0 : *(uint64_t *)split_packet =
1538 : 0 : _mm_cvtsi128_si64(split_bits);
1539 : 0 : split_packet += IAVF_DESCS_PER_LOOP_AVX;
1540 : : }
1541 : :
1542 : : /* perform dd_check */
1543 : : status0_7 = _mm256_and_si256(status0_7, dd_check);
1544 : : status0_7 = _mm256_packs_epi32(status0_7,
1545 : : _mm256_setzero_si256());
1546 : :
1547 [ # # # # : 0 : uint64_t burst = rte_popcount64
# # # # #
# # # ]
1548 : : (_mm_cvtsi128_si64
1549 : : (_mm256_extracti128_si256
1550 : : (status0_7, 1)));
1551 : 0 : burst += rte_popcount64
1552 : : (_mm_cvtsi128_si64
1553 : : (_mm256_castsi256_si128(status0_7)));
1554 : 0 : received += burst;
1555 : : #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
1556 : : #ifdef IAVF_RX_TS_OFFLOAD
1557 [ # # # # : 0 : if (rxq->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) {
# # # # #
# # # ]
1558 [ # # # # : 0 : inflection_point = (inflection_point <= burst) ? inflection_point : 0;
# # ]
1559 [ # # # # : 0 : switch (inflection_point) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
1560 : 0 : case 1:
1561 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 0],
1562 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1563 : : /* fallthrough */
1564 : 0 : case 2:
1565 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 1],
1566 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1567 : : /* fallthrough */
1568 : 0 : case 3:
1569 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 2],
1570 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1571 : : /* fallthrough */
1572 : 0 : case 4:
1573 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 3],
1574 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1575 : : /* fallthrough */
1576 : 0 : case 5:
1577 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 4],
1578 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1579 : : /* fallthrough */
1580 : 0 : case 6:
1581 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 5],
1582 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1583 : : /* fallthrough */
1584 : 0 : case 7:
1585 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 6],
1586 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1587 : : /* fallthrough */
1588 : 0 : case 8:
1589 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 7],
1590 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1591 : 0 : rxq->phc_time += (uint64_t)1 << 32;
1592 : : /* fallthrough */
1593 : : case 0:
1594 : : break;
1595 : 0 : default:
1596 : 0 : PMD_DRV_LOG(ERR, "invalid inflection point for rx timestamp");
1597 : 0 : break;
1598 : : }
1599 : :
1600 : 0 : rxq->hw_time_update = rte_get_timer_cycles() / (rte_get_timer_hz() / 1000);
1601 : : }
1602 : : #endif
1603 : : #endif
1604 [ # # # # : 0 : if (burst != IAVF_DESCS_PER_LOOP_AVX)
# # # # #
# # # ]
1605 : : break;
1606 : : }
1607 : :
1608 : : #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
1609 : : #ifdef IAVF_RX_TS_OFFLOAD
1610 [ # # # # : 0 : if (received > 0 && (rxq->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP))
# # # # #
# # # # #
# # # # #
# # # #
# ]
1611 : 0 : rxq->phc_time = *RTE_MBUF_DYNFIELD(rx_pkts[received - 1],
1612 : : iavf_timestamp_dynfield_offset, rte_mbuf_timestamp_t *);
1613 : : #endif
1614 : : #endif
1615 : :
1616 : : /* update tail pointers */
1617 : 0 : rxq->rx_tail += received;
1618 : 0 : rxq->rx_tail &= (rxq->nb_rx_desc - 1);
1619 [ # # # # : 0 : if ((rxq->rx_tail & 1) == 1 && received > 1) { /* keep aligned */
# # # # #
# # # # #
# # # # #
# # # #
# ]
1620 : 0 : rxq->rx_tail--;
1621 : 0 : received--;
1622 : : }
1623 : 0 : rxq->rxrearm_nb += received;
1624 : 0 : return received;
1625 : : }
1626 : :
1627 : : /**
1628 : : * Notice:
1629 : : * - nb_pkts < IAVF_DESCS_PER_LOOP, just return no packet
1630 : : */
1631 : : uint16_t
1632 : 0 : iavf_recv_pkts_vec_avx512(void *rx_queue, struct rte_mbuf **rx_pkts,
1633 : : uint16_t nb_pkts)
1634 : : {
1635 : 0 : return _iavf_recv_raw_pkts_vec_avx512(rx_queue, rx_pkts, nb_pkts,
1636 : : NULL, false);
1637 : : }
1638 : :
1639 : : /**
1640 : : * Notice:
1641 : : * - nb_pkts < IAVF_DESCS_PER_LOOP, just return no packet
1642 : : */
1643 : : uint16_t
1644 : 0 : iavf_recv_pkts_vec_avx512_flex_rxd(void *rx_queue, struct rte_mbuf **rx_pkts,
1645 : : uint16_t nb_pkts)
1646 : : {
1647 : 0 : return _iavf_recv_raw_pkts_vec_avx512_flex_rxd(rx_queue, rx_pkts,
1648 : : nb_pkts, NULL, false);
1649 : : }
1650 : :
1651 : : /**
1652 : : * vPMD receive routine that reassembles single burst of 32 scattered packets
1653 : : * Notice:
1654 : : * - nb_pkts < IAVF_DESCS_PER_LOOP, just return no packet
1655 : : */
1656 : : static __rte_always_inline uint16_t
1657 : : iavf_recv_scattered_burst_vec_avx512(void *rx_queue, struct rte_mbuf **rx_pkts,
1658 : : uint16_t nb_pkts, bool offload)
1659 : : {
1660 : : struct iavf_rx_queue *rxq = rx_queue;
1661 : 0 : uint8_t split_flags[IAVF_VPMD_RX_MAX_BURST] = {0};
1662 : :
1663 : : /* get some new buffers */
1664 : : uint16_t nb_bufs = _iavf_recv_raw_pkts_vec_avx512(rxq, rx_pkts, nb_pkts,
1665 : : split_flags, offload);
1666 [ # # # # : 0 : if (nb_bufs == 0)
# # # # ]
1667 : : return 0;
1668 : :
1669 : : /* happy day case, full burst + no packets to be joined */
1670 : : const uint64_t *split_fl64 = (uint64_t *)split_flags;
1671 : :
1672 [ # # # # : 0 : if (!rxq->pkt_first_seg &&
# # # # ]
1673 [ # # # # : 0 : split_fl64[0] == 0 && split_fl64[1] == 0 &&
# # # # #
# # # # #
# # ]
1674 [ # # # # : 0 : split_fl64[2] == 0 && split_fl64[3] == 0)
# # # # #
# # # # #
# # ]
1675 : : return nb_bufs;
1676 : :
1677 : : /* reassemble any packets that need reassembly*/
1678 : : unsigned int i = 0;
1679 : :
1680 [ # # # # : 0 : if (!rxq->pkt_first_seg) {
# # # # ]
1681 : : /* find the first split flag, and only reassemble then*/
1682 [ # # # # : 0 : while (i < nb_bufs && !split_flags[i])
# # # # #
# # # # #
# # ]
1683 : 0 : i++;
1684 [ # # # # : 0 : if (i == nb_bufs)
# # # # ]
1685 : : return nb_bufs;
1686 : 0 : rxq->pkt_first_seg = rx_pkts[i];
1687 : : }
1688 : 0 : return i + reassemble_packets(rxq, &rx_pkts[i], nb_bufs - i,
1689 : : &split_flags[i]);
1690 : : }
1691 : :
1692 : : /**
1693 : : * vPMD receive routine that reassembles scattered packets.
1694 : : * Main receive routine that can handle arbitrary burst sizes
1695 : : * Notice:
1696 : : * - nb_pkts < IAVF_DESCS_PER_LOOP, just return no packet
1697 : : */
1698 : : static __rte_always_inline uint16_t
1699 : : iavf_recv_scattered_pkts_vec_avx512_cmn(void *rx_queue, struct rte_mbuf **rx_pkts,
1700 : : uint16_t nb_pkts, bool offload)
1701 : : {
1702 : : uint16_t retval = 0;
1703 : :
1704 [ # # # # ]: 0 : while (nb_pkts > IAVF_VPMD_RX_MAX_BURST) {
1705 : 0 : uint16_t burst = iavf_recv_scattered_burst_vec_avx512(rx_queue,
1706 : 0 : rx_pkts + retval, IAVF_VPMD_RX_MAX_BURST, offload);
1707 : 0 : retval += burst;
1708 : 0 : nb_pkts -= burst;
1709 [ # # # # ]: 0 : if (burst < IAVF_VPMD_RX_MAX_BURST)
1710 : : return retval;
1711 : : }
1712 : 0 : return retval + iavf_recv_scattered_burst_vec_avx512(rx_queue,
1713 : 0 : rx_pkts + retval, nb_pkts, offload);
1714 : : }
1715 : :
1716 : : uint16_t
1717 : 0 : iavf_recv_scattered_pkts_vec_avx512(void *rx_queue, struct rte_mbuf **rx_pkts,
1718 : : uint16_t nb_pkts)
1719 : : {
1720 : 0 : return iavf_recv_scattered_pkts_vec_avx512_cmn(rx_queue, rx_pkts,
1721 : : nb_pkts, false);
1722 : : }
1723 : :
1724 : : /**
1725 : : * vPMD receive routine that reassembles single burst of
1726 : : * 32 scattered packets for flex RxD
1727 : : * Notice:
1728 : : * - nb_pkts < IAVF_DESCS_PER_LOOP, just return no packet
1729 : : */
1730 : : static __rte_always_inline uint16_t
1731 : : iavf_recv_scattered_burst_vec_avx512_flex_rxd(void *rx_queue,
1732 : : struct rte_mbuf **rx_pkts,
1733 : : uint16_t nb_pkts,
1734 : : bool offload)
1735 : : {
1736 : : struct iavf_rx_queue *rxq = rx_queue;
1737 : 0 : uint8_t split_flags[IAVF_VPMD_RX_MAX_BURST] = {0};
1738 : :
1739 : : /* get some new buffers */
1740 : : uint16_t nb_bufs = _iavf_recv_raw_pkts_vec_avx512_flex_rxd(rxq,
1741 : : rx_pkts, nb_pkts, split_flags, offload);
1742 [ # # # # : 0 : if (nb_bufs == 0)
# # # # ]
1743 : : return 0;
1744 : :
1745 : : /* happy day case, full burst + no packets to be joined */
1746 : : const uint64_t *split_fl64 = (uint64_t *)split_flags;
1747 : :
1748 [ # # # # : 0 : if (!rxq->pkt_first_seg &&
# # # # ]
1749 [ # # # # : 0 : split_fl64[0] == 0 && split_fl64[1] == 0 &&
# # # # #
# # # # #
# # ]
1750 [ # # # # : 0 : split_fl64[2] == 0 && split_fl64[3] == 0)
# # # # #
# # # # #
# # ]
1751 : : return nb_bufs;
1752 : :
1753 : : /* reassemble any packets that need reassembly*/
1754 : : unsigned int i = 0;
1755 : :
1756 [ # # # # : 0 : if (!rxq->pkt_first_seg) {
# # # # ]
1757 : : /* find the first split flag, and only reassemble then*/
1758 [ # # # # : 0 : while (i < nb_bufs && !split_flags[i])
# # # # #
# # # # #
# # ]
1759 : 0 : i++;
1760 [ # # # # : 0 : if (i == nb_bufs)
# # # # ]
1761 : : return nb_bufs;
1762 : 0 : rxq->pkt_first_seg = rx_pkts[i];
1763 : : }
1764 : 0 : return i + reassemble_packets(rxq, &rx_pkts[i], nb_bufs - i,
1765 : : &split_flags[i]);
1766 : : }
1767 : :
1768 : : /**
1769 : : * vPMD receive routine that reassembles scattered packets for flex RxD.
1770 : : * Main receive routine that can handle arbitrary burst sizes
1771 : : * Notice:
1772 : : * - nb_pkts < IAVF_DESCS_PER_LOOP, just return no packet
1773 : : */
1774 : : static __rte_always_inline uint16_t
1775 : : iavf_recv_scattered_pkts_vec_avx512_flex_rxd_cmn(void *rx_queue,
1776 : : struct rte_mbuf **rx_pkts,
1777 : : uint16_t nb_pkts,
1778 : : bool offload)
1779 : : {
1780 : : uint16_t retval = 0;
1781 : :
1782 [ # # # # ]: 0 : while (nb_pkts > IAVF_VPMD_RX_MAX_BURST) {
1783 : : uint16_t burst =
1784 : 0 : iavf_recv_scattered_burst_vec_avx512_flex_rxd
1785 : 0 : (rx_queue, rx_pkts + retval,
1786 : : IAVF_VPMD_RX_MAX_BURST, offload);
1787 : 0 : retval += burst;
1788 : 0 : nb_pkts -= burst;
1789 [ # # # # ]: 0 : if (burst < IAVF_VPMD_RX_MAX_BURST)
1790 : : return retval;
1791 : : }
1792 : 0 : return retval + iavf_recv_scattered_burst_vec_avx512_flex_rxd(rx_queue,
1793 : 0 : rx_pkts + retval, nb_pkts, offload);
1794 : : }
1795 : :
1796 : : uint16_t
1797 : 0 : iavf_recv_scattered_pkts_vec_avx512_flex_rxd(void *rx_queue,
1798 : : struct rte_mbuf **rx_pkts,
1799 : : uint16_t nb_pkts)
1800 : : {
1801 : 0 : return iavf_recv_scattered_pkts_vec_avx512_flex_rxd_cmn(rx_queue,
1802 : : rx_pkts,
1803 : : nb_pkts,
1804 : : false);
1805 : : }
1806 : :
1807 : : uint16_t
1808 : 0 : iavf_recv_pkts_vec_avx512_offload(void *rx_queue, struct rte_mbuf **rx_pkts,
1809 : : uint16_t nb_pkts)
1810 : : {
1811 : 0 : return _iavf_recv_raw_pkts_vec_avx512(rx_queue, rx_pkts,
1812 : : nb_pkts, NULL, true);
1813 : : }
1814 : :
1815 : : uint16_t
1816 : 0 : iavf_recv_scattered_pkts_vec_avx512_offload(void *rx_queue,
1817 : : struct rte_mbuf **rx_pkts,
1818 : : uint16_t nb_pkts)
1819 : : {
1820 : 0 : return iavf_recv_scattered_pkts_vec_avx512_cmn(rx_queue, rx_pkts,
1821 : : nb_pkts, true);
1822 : : }
1823 : :
1824 : : uint16_t
1825 : 0 : iavf_recv_pkts_vec_avx512_flex_rxd_offload(void *rx_queue,
1826 : : struct rte_mbuf **rx_pkts,
1827 : : uint16_t nb_pkts)
1828 : : {
1829 : 0 : return _iavf_recv_raw_pkts_vec_avx512_flex_rxd(rx_queue,
1830 : : rx_pkts,
1831 : : nb_pkts,
1832 : : NULL,
1833 : : true);
1834 : : }
1835 : :
1836 : : uint16_t
1837 : 0 : iavf_recv_scattered_pkts_vec_avx512_flex_rxd_offload(void *rx_queue,
1838 : : struct rte_mbuf **rx_pkts,
1839 : : uint16_t nb_pkts)
1840 : : {
1841 : 0 : return iavf_recv_scattered_pkts_vec_avx512_flex_rxd_cmn(rx_queue,
1842 : : rx_pkts,
1843 : : nb_pkts,
1844 : : true);
1845 : : }
1846 : :
1847 : : static __rte_always_inline int
1848 : : iavf_tx_free_bufs_avx512(struct iavf_tx_queue *txq)
1849 : : {
1850 : : struct iavf_tx_vec_entry *txep;
1851 : : uint32_t n;
1852 : : uint32_t i;
1853 : : int nb_free = 0;
1854 : : struct rte_mbuf *m, *free[IAVF_VPMD_TX_MAX_FREE_BUF];
1855 : :
1856 : : /* check DD bits on threshold descriptor */
1857 [ # # # # : 0 : if ((txq->tx_ring[txq->next_dd].cmd_type_offset_bsz &
# # ]
1858 : : rte_cpu_to_le_64(IAVF_TXD_QW1_DTYPE_MASK)) !=
1859 : : rte_cpu_to_le_64(IAVF_TX_DESC_DTYPE_DESC_DONE))
1860 : : return 0;
1861 : :
1862 : 0 : n = txq->rs_thresh >> txq->use_ctx;
1863 : :
1864 : : /* first buffer to free from S/W ring is at index
1865 : : * tx_next_dd - (tx_rs_thresh-1)
1866 : : */
1867 : 0 : txep = (void *)txq->sw_ring;
1868 : 0 : txep += (txq->next_dd >> txq->use_ctx) - (n - 1);
1869 : :
1870 [ # # # # : 0 : if (txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE && (n & 31) == 0) {
# # # # #
# # # ]
1871 [ # # # # : 0 : struct rte_mempool *mp = txep[0].mbuf->pool;
# # ]
1872 : : struct rte_mempool_cache *cache = rte_mempool_default_cache(mp,
1873 : : rte_lcore_id());
1874 : : void **cache_objs;
1875 : :
1876 [ # # # # : 0 : if (!cache || cache->len == 0)
# # # # #
# # # ]
1877 : 0 : goto normal;
1878 : :
1879 : 0 : cache_objs = &cache->objs[cache->len];
1880 : :
1881 [ # # # # : 0 : if (n > RTE_MEMPOOL_CACHE_MAX_SIZE) {
# # ]
1882 : 0 : rte_mempool_ops_enqueue_bulk(mp, (void *)txep, n);
1883 : 0 : goto done;
1884 : : }
1885 : :
1886 : : /* The cache follows the following algorithm
1887 : : * 1. Add the objects to the cache
1888 : : * 2. Anything greater than the cache min value (if it crosses the
1889 : : * cache flush threshold) is flushed to the ring.
1890 : : */
1891 : : /* Add elements back into the cache */
1892 : : uint32_t copied = 0;
1893 : : /* n is multiple of 32 */
1894 [ # # # # : 0 : while (copied < n) {
# # ]
1895 : 0 : const __m512i a = _mm512_loadu_si512(&txep[copied]);
1896 : 0 : const __m512i b = _mm512_loadu_si512(&txep[copied + 8]);
1897 : 0 : const __m512i c = _mm512_loadu_si512(&txep[copied + 16]);
1898 : 0 : const __m512i d = _mm512_loadu_si512(&txep[copied + 24]);
1899 : :
1900 : 0 : _mm512_storeu_si512(&cache_objs[copied], a);
1901 : 0 : _mm512_storeu_si512(&cache_objs[copied + 8], b);
1902 : 0 : _mm512_storeu_si512(&cache_objs[copied + 16], c);
1903 : 0 : _mm512_storeu_si512(&cache_objs[copied + 24], d);
1904 : 0 : copied += 32;
1905 : : }
1906 : 0 : cache->len += n;
1907 : :
1908 [ # # # # : 0 : if (cache->len >= cache->flushthresh) {
# # ]
1909 : 0 : rte_mempool_ops_enqueue_bulk(mp,
1910 : 0 : &cache->objs[cache->size],
1911 : 0 : cache->len - cache->size);
1912 : 0 : cache->len = cache->size;
1913 : : }
1914 : 0 : goto done;
1915 : : }
1916 : :
1917 : 0 : normal:
1918 [ # # # # : 0 : m = rte_pktmbuf_prefree_seg(txep[0].mbuf);
# # ]
1919 [ # # # # : 0 : if (likely(m)) {
# # ]
1920 : 0 : free[0] = m;
1921 : : nb_free = 1;
1922 [ # # # # : 0 : for (i = 1; i < n; i++) {
# # ]
1923 [ # # # # : 0 : m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
# # ]
1924 [ # # # # : 0 : if (likely(m)) {
# # ]
1925 [ # # # # : 0 : if (likely(m->pool == free[0]->pool)) {
# # ]
1926 : 0 : free[nb_free++] = m;
1927 : : } else {
1928 [ # # # # : 0 : rte_mempool_put_bulk(free[0]->pool,
# # ]
1929 : : (void *)free,
1930 : : nb_free);
1931 : 0 : free[0] = m;
1932 : : nb_free = 1;
1933 : : }
1934 : : }
1935 : : }
1936 [ # # # # : 0 : rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free);
# # ]
1937 : : } else {
1938 [ # # # # : 0 : for (i = 1; i < n; i++) {
# # ]
1939 [ # # # # : 0 : m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
# # ]
1940 [ # # # # : 0 : if (m)
# # ]
1941 [ # # # # : 0 : rte_mempool_put(m->pool, m);
# # ]
1942 : : }
1943 : : }
1944 : :
1945 : 0 : done:
1946 : : /* buffers were freed, update counters */
1947 : 0 : txq->nb_free = (uint16_t)(txq->nb_free + txq->rs_thresh);
1948 : 0 : txq->next_dd = (uint16_t)(txq->next_dd + txq->rs_thresh);
1949 [ # # # # : 0 : if (txq->next_dd >= txq->nb_tx_desc)
# # ]
1950 : 0 : txq->next_dd = (uint16_t)(txq->rs_thresh - 1);
1951 : :
1952 : : return txq->rs_thresh;
1953 : : }
1954 : :
1955 : : static __rte_always_inline void
1956 : : tx_backlog_entry_avx512(struct iavf_tx_vec_entry *txep,
1957 : : struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
1958 : : {
1959 : : int i;
1960 : :
1961 [ # # # # : 0 : for (i = 0; i < (int)nb_pkts; ++i)
# # # # #
# # # ]
1962 : 0 : txep[i].mbuf = tx_pkts[i];
1963 : : }
1964 : :
1965 : : static __rte_always_inline void
1966 : : iavf_vtx1(volatile struct iavf_tx_desc *txdp,
1967 : : struct rte_mbuf *pkt, uint64_t flags,
1968 : : bool offload)
1969 : : {
1970 : : uint64_t high_qw =
1971 : : (IAVF_TX_DESC_DTYPE_DATA |
1972 : 0 : ((uint64_t)flags << IAVF_TXD_QW1_CMD_SHIFT) |
1973 : 0 : ((uint64_t)pkt->data_len << IAVF_TXD_QW1_TX_BUF_SZ_SHIFT));
1974 : : if (offload)
1975 : : iavf_txd_enable_offload(pkt, &high_qw);
1976 : :
1977 : 0 : __m128i descriptor = _mm_set_epi64x(high_qw,
1978 : 0 : pkt->buf_iova + pkt->data_off);
1979 : : _mm_storeu_si128((__m128i *)txdp, descriptor);
1980 : : }
1981 : :
1982 : : #define IAVF_TX_LEN_MASK 0xAA
1983 : : #define IAVF_TX_OFF_MASK 0x55
1984 : : static __rte_always_inline void
1985 : : iavf_vtx(volatile struct iavf_tx_desc *txdp,
1986 : : struct rte_mbuf **pkt, uint16_t nb_pkts, uint64_t flags,
1987 : : bool offload)
1988 : : {
1989 : : const uint64_t hi_qw_tmpl = (IAVF_TX_DESC_DTYPE_DATA |
1990 : : ((uint64_t)flags << IAVF_TXD_QW1_CMD_SHIFT));
1991 : :
1992 : : /* if unaligned on 32-bit boundary, do one to align */
1993 [ # # # # : 0 : if (((uintptr_t)txdp & 0x1F) != 0 && nb_pkts != 0) {
# # # # #
# # # ]
1994 [ # # # # ]: 0 : iavf_vtx1(txdp, *pkt, flags, offload);
1995 : 0 : nb_pkts--, txdp++, pkt++;
1996 : : }
1997 : :
1998 : : /* do 4 at a time while possible, in bursts */
1999 [ # # # # : 0 : for (; nb_pkts > 3; txdp += 4, pkt += 4, nb_pkts -= 4) {
# # # # ]
2000 : : uint64_t hi_qw3 =
2001 : 0 : hi_qw_tmpl |
2002 : 0 : ((uint64_t)pkt[3]->data_len <<
2003 : : IAVF_TXD_QW1_TX_BUF_SZ_SHIFT);
2004 : : uint64_t hi_qw2 =
2005 : 0 : hi_qw_tmpl |
2006 : 0 : ((uint64_t)pkt[2]->data_len <<
2007 : : IAVF_TXD_QW1_TX_BUF_SZ_SHIFT);
2008 : : uint64_t hi_qw1 =
2009 : 0 : hi_qw_tmpl |
2010 : 0 : ((uint64_t)pkt[1]->data_len <<
2011 : : IAVF_TXD_QW1_TX_BUF_SZ_SHIFT);
2012 : : uint64_t hi_qw0 =
2013 : 0 : hi_qw_tmpl |
2014 [ # # # # ]: 0 : ((uint64_t)pkt[0]->data_len <<
2015 : : IAVF_TXD_QW1_TX_BUF_SZ_SHIFT);
2016 : : if (offload) {
2017 : : iavf_txd_enable_offload(pkt[3], &hi_qw3);
2018 : : iavf_txd_enable_offload(pkt[2], &hi_qw2);
2019 : : iavf_txd_enable_offload(pkt[1], &hi_qw1);
2020 : : iavf_txd_enable_offload(pkt[0], &hi_qw0);
2021 : : }
2022 : :
2023 : : __m512i desc0_3 =
2024 : 0 : _mm512_set_epi64
2025 : : (hi_qw3,
2026 : 0 : pkt[3]->buf_iova + pkt[3]->data_off,
2027 : : hi_qw2,
2028 : 0 : pkt[2]->buf_iova + pkt[2]->data_off,
2029 : : hi_qw1,
2030 : 0 : pkt[1]->buf_iova + pkt[1]->data_off,
2031 : : hi_qw0,
2032 : 0 : pkt[0]->buf_iova + pkt[0]->data_off);
2033 : : _mm512_storeu_si512((void *)txdp, desc0_3);
2034 : : }
2035 : :
2036 : : /* do any last ones */
2037 [ # # # # : 0 : while (nb_pkts) {
# # # # ]
2038 [ # # # # ]: 0 : iavf_vtx1(txdp, *pkt, flags, offload);
2039 : 0 : txdp++, pkt++, nb_pkts--;
2040 : : }
2041 : : }
2042 : :
2043 : : static __rte_always_inline void
2044 : : iavf_fill_ctx_desc_tunneling_avx512(uint64_t *low_ctx_qw, struct rte_mbuf *pkt)
2045 : : {
2046 : 0 : if (pkt->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) {
2047 : : uint64_t eip_typ = IAVF_TX_CTX_DESC_EIPT_NONE;
2048 : : uint64_t eip_len = 0;
2049 : : uint64_t eip_noinc = 0;
2050 : : /* Default - IP_ID is increment in each segment of LSO */
2051 : :
2052 [ # # # # : 0 : switch (pkt->ol_flags & (RTE_MBUF_F_TX_OUTER_IPV4 |
# # # # #
# # # # #
# # # # #
# ]
2053 : : RTE_MBUF_F_TX_OUTER_IPV6 |
2054 : : RTE_MBUF_F_TX_OUTER_IP_CKSUM)) {
2055 : 0 : case RTE_MBUF_F_TX_OUTER_IPV4:
2056 : : eip_typ = IAVF_TX_CTX_DESC_EIPT_IPV4_NO_CHECKSUM_OFFLOAD;
2057 : 0 : eip_len = pkt->outer_l3_len >> 2;
2058 : 0 : break;
2059 : 0 : case RTE_MBUF_F_TX_OUTER_IPV4 | RTE_MBUF_F_TX_OUTER_IP_CKSUM:
2060 : : eip_typ = IAVF_TX_CTX_DESC_EIPT_IPV4_CHECKSUM_OFFLOAD;
2061 : 0 : eip_len = pkt->outer_l3_len >> 2;
2062 : 0 : break;
2063 : 0 : case RTE_MBUF_F_TX_OUTER_IPV6:
2064 : : eip_typ = IAVF_TX_CTX_DESC_EIPT_IPV6;
2065 : 0 : eip_len = pkt->outer_l3_len >> 2;
2066 : 0 : break;
2067 : : }
2068 : :
2069 : : /* L4TUNT: L4 Tunneling Type */
2070 [ # # # # : 0 : switch (pkt->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) {
# # # # #
# # # # #
# # # # #
# ]
2071 : : case RTE_MBUF_F_TX_TUNNEL_IPIP:
2072 : : /* for non UDP / GRE tunneling, set to 00b */
2073 : : break;
2074 : 0 : case RTE_MBUF_F_TX_TUNNEL_VXLAN:
2075 : : case RTE_MBUF_F_TX_TUNNEL_VXLAN_GPE:
2076 : : case RTE_MBUF_F_TX_TUNNEL_GTP:
2077 : : case RTE_MBUF_F_TX_TUNNEL_GENEVE:
2078 : 0 : eip_typ |= IAVF_TXD_CTX_UDP_TUNNELING;
2079 : 0 : break;
2080 : 0 : case RTE_MBUF_F_TX_TUNNEL_GRE:
2081 : 0 : eip_typ |= IAVF_TXD_CTX_GRE_TUNNELING;
2082 : 0 : break;
2083 : : default:
2084 : : PMD_TX_LOG(ERR, "Tunnel type not supported");
2085 : : return;
2086 : : }
2087 : :
2088 : : /* L4TUNLEN: L4 Tunneling Length, in Words
2089 : : *
2090 : : * We depend on app to set rte_mbuf.l2_len correctly.
2091 : : * For IP in GRE it should be set to the length of the GRE
2092 : : * header;
2093 : : * For MAC in GRE or MAC in UDP it should be set to the length
2094 : : * of the GRE or UDP headers plus the inner MAC up to including
2095 : : * its last Ethertype.
2096 : : * If MPLS labels exists, it should include them as well.
2097 : : */
2098 : 0 : eip_typ |= (pkt->l2_len >> 1) << IAVF_TXD_CTX_QW0_NATLEN_SHIFT;
2099 : :
2100 : : /**
2101 : : * Calculate the tunneling UDP checksum.
2102 : : * Shall be set only if L4TUNT = 01b and EIPT is not zero
2103 : : */
2104 [ # # # # : 0 : if ((eip_typ & (IAVF_TX_CTX_EXT_IP_IPV4 |
# # # # #
# ]
2105 : : IAVF_TX_CTX_EXT_IP_IPV6 |
2106 : 0 : IAVF_TX_CTX_EXT_IP_IPV4_NO_CSUM)) &&
2107 [ # # # # : 0 : (eip_typ & IAVF_TXD_CTX_UDP_TUNNELING) &&
# # # # #
# ]
2108 [ # # # # : 0 : (pkt->ol_flags & RTE_MBUF_F_TX_OUTER_UDP_CKSUM))
# # # # #
# ]
2109 : 0 : eip_typ |= IAVF_TXD_CTX_QW0_L4T_CS_MASK;
2110 : :
2111 : 0 : *low_ctx_qw = eip_typ << IAVF_TXD_CTX_QW0_TUN_PARAMS_EIPT_SHIFT |
2112 : 0 : eip_len << IAVF_TXD_CTX_QW0_TUN_PARAMS_EIPLEN_SHIFT |
2113 : : eip_noinc << IAVF_TXD_CTX_QW0_TUN_PARAMS_EIP_NOINC_SHIFT;
2114 : :
2115 : : } else {
2116 : : *low_ctx_qw = 0;
2117 : : }
2118 : : }
2119 : :
2120 : : static inline void
2121 : 0 : iavf_fill_ctx_desc_tunnelling_field(volatile uint64_t *qw0,
2122 : : const struct rte_mbuf *m)
2123 : : {
2124 : : uint64_t eip_typ = IAVF_TX_CTX_DESC_EIPT_NONE;
2125 : : uint64_t eip_len = 0;
2126 : : uint64_t eip_noinc = 0;
2127 : : /* Default - IP_ID is increment in each segment of LSO */
2128 : :
2129 [ # # # # ]: 0 : switch (m->ol_flags & (RTE_MBUF_F_TX_OUTER_IPV4 |
2130 : : RTE_MBUF_F_TX_OUTER_IPV6 |
2131 : : RTE_MBUF_F_TX_OUTER_IP_CKSUM)) {
2132 : 0 : case RTE_MBUF_F_TX_OUTER_IPV4:
2133 : : eip_typ = IAVF_TX_CTX_DESC_EIPT_IPV4_NO_CHECKSUM_OFFLOAD;
2134 : 0 : eip_len = m->outer_l3_len >> 2;
2135 : 0 : break;
2136 : 0 : case RTE_MBUF_F_TX_OUTER_IPV4 | RTE_MBUF_F_TX_OUTER_IP_CKSUM:
2137 : : eip_typ = IAVF_TX_CTX_DESC_EIPT_IPV4_CHECKSUM_OFFLOAD;
2138 : 0 : eip_len = m->outer_l3_len >> 2;
2139 : 0 : break;
2140 : 0 : case RTE_MBUF_F_TX_OUTER_IPV6:
2141 : : eip_typ = IAVF_TX_CTX_DESC_EIPT_IPV6;
2142 : 0 : eip_len = m->outer_l3_len >> 2;
2143 : 0 : break;
2144 : : }
2145 : :
2146 : : /* L4TUNT: L4 Tunneling Type */
2147 [ # # # # ]: 0 : switch (m->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) {
2148 : : case RTE_MBUF_F_TX_TUNNEL_IPIP:
2149 : : /* for non UDP / GRE tunneling, set to 00b */
2150 : : break;
2151 : 0 : case RTE_MBUF_F_TX_TUNNEL_VXLAN:
2152 : : case RTE_MBUF_F_TX_TUNNEL_VXLAN_GPE:
2153 : : case RTE_MBUF_F_TX_TUNNEL_GTP:
2154 : : case RTE_MBUF_F_TX_TUNNEL_GENEVE:
2155 : 0 : eip_typ |= IAVF_TXD_CTX_UDP_TUNNELING;
2156 : 0 : break;
2157 : 0 : case RTE_MBUF_F_TX_TUNNEL_GRE:
2158 : 0 : eip_typ |= IAVF_TXD_CTX_GRE_TUNNELING;
2159 : 0 : break;
2160 : : default:
2161 : : PMD_TX_LOG(ERR, "Tunnel type not supported");
2162 : : return;
2163 : : }
2164 : :
2165 : : /* L4TUNLEN: L4 Tunneling Length, in Words
2166 : : *
2167 : : * We depend on app to set rte_mbuf.l2_len correctly.
2168 : : * For IP in GRE it should be set to the length of the GRE
2169 : : * header;
2170 : : * For MAC in GRE or MAC in UDP it should be set to the length
2171 : : * of the GRE or UDP headers plus the inner MAC up to including
2172 : : * its last Ethertype.
2173 : : * If MPLS labels exists, it should include them as well.
2174 : : */
2175 : 0 : eip_typ |= (m->l2_len >> 1) << IAVF_TXD_CTX_QW0_NATLEN_SHIFT;
2176 : :
2177 : : /**
2178 : : * Calculate the tunneling UDP checksum.
2179 : : * Shall be set only if L4TUNT = 01b and EIPT is not zero
2180 : : */
2181 [ # # ]: 0 : if ((eip_typ & (IAVF_TX_CTX_EXT_IP_IPV6 |
2182 : : IAVF_TX_CTX_EXT_IP_IPV4 |
2183 : 0 : IAVF_TX_CTX_EXT_IP_IPV4_NO_CSUM)) &&
2184 [ # # ]: 0 : (eip_typ & IAVF_TXD_CTX_UDP_TUNNELING) &&
2185 [ # # ]: 0 : (m->ol_flags & RTE_MBUF_F_TX_OUTER_UDP_CKSUM))
2186 : 0 : eip_typ |= IAVF_TXD_CTX_QW0_L4T_CS_MASK;
2187 : :
2188 : 0 : *qw0 = eip_typ << IAVF_TXD_CTX_QW0_TUN_PARAMS_EIPT_SHIFT |
2189 : 0 : eip_len << IAVF_TXD_CTX_QW0_TUN_PARAMS_EIPLEN_SHIFT |
2190 : : eip_noinc << IAVF_TXD_CTX_QW0_TUN_PARAMS_EIP_NOINC_SHIFT;
2191 : : }
2192 : :
2193 : : static __rte_always_inline void
2194 : : ctx_vtx1(volatile struct iavf_tx_desc *txdp, struct rte_mbuf *pkt,
2195 : : uint64_t flags, bool offload, uint8_t vlan_flag)
2196 : : {
2197 : : uint64_t high_ctx_qw = IAVF_TX_DESC_DTYPE_CONTEXT;
2198 : : uint64_t low_ctx_qw = 0;
2199 : :
2200 : 0 : if (((pkt->ol_flags & RTE_MBUF_F_TX_VLAN) || offload)) {
2201 : : if (offload)
2202 : : iavf_fill_ctx_desc_tunneling_avx512(&low_ctx_qw, pkt);
2203 [ # # # # : 0 : if ((pkt->ol_flags & RTE_MBUF_F_TX_VLAN) ||
# # # # #
# # # # #
# # # # #
# ]
2204 : : (vlan_flag & IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG2)) {
2205 : : high_ctx_qw |= IAVF_TX_CTX_DESC_IL2TAG2 << IAVF_TXD_CTX_QW1_CMD_SHIFT;
2206 : 0 : low_ctx_qw |= (uint64_t)pkt->vlan_tci << IAVF_TXD_CTX_QW0_L2TAG2_PARAM;
2207 : : }
2208 : : }
2209 : : uint64_t high_data_qw = (IAVF_TX_DESC_DTYPE_DATA |
2210 : 0 : ((uint64_t)flags << IAVF_TXD_QW1_CMD_SHIFT) |
2211 [ # # # # : 0 : ((uint64_t)pkt->data_len << IAVF_TXD_QW1_TX_BUF_SZ_SHIFT));
# # # # #
# ]
2212 : : if (offload)
2213 : : iavf_txd_enable_offload(pkt, &high_data_qw);
2214 : :
2215 : 0 : __m256i ctx_data_desc = _mm256_set_epi64x(high_data_qw, pkt->buf_iova + pkt->data_off,
2216 : : high_ctx_qw, low_ctx_qw);
2217 : :
2218 : : _mm256_storeu_si256((__m256i *)txdp, ctx_data_desc);
2219 : 0 : }
2220 : :
2221 : : static __rte_always_inline void
2222 : : ctx_vtx(volatile struct iavf_tx_desc *txdp,
2223 : : struct rte_mbuf **pkt, uint16_t nb_pkts, uint64_t flags,
2224 : : bool offload, uint8_t vlan_flag)
2225 : : {
2226 : : uint64_t hi_data_qw_tmpl = (IAVF_TX_DESC_DTYPE_DATA |
2227 : : ((uint64_t)flags << IAVF_TXD_QW1_CMD_SHIFT));
2228 : :
2229 : : /* if unaligned on 32-bit boundary, do one to align */
2230 [ # # # # ]: 0 : if (((uintptr_t)txdp & 0x1F) != 0 && nb_pkts != 0) {
2231 [ # # # # ]: 0 : ctx_vtx1(txdp, *pkt, flags, offload, vlan_flag);
2232 : 0 : nb_pkts--, txdp++, pkt++;
2233 : : }
2234 : :
2235 [ # # # # ]: 0 : for (; nb_pkts > 1; txdp += 4, pkt += 2, nb_pkts -= 2) {
2236 : : uint64_t hi_ctx_qw1 = IAVF_TX_DESC_DTYPE_CONTEXT;
2237 : : uint64_t hi_ctx_qw0 = IAVF_TX_DESC_DTYPE_CONTEXT;
2238 : 0 : uint64_t low_ctx_qw1 = 0;
2239 : 0 : uint64_t low_ctx_qw0 = 0;
2240 : : uint64_t hi_data_qw1 = 0;
2241 : : uint64_t hi_data_qw0 = 0;
2242 : :
2243 : 0 : hi_data_qw1 = hi_data_qw_tmpl |
2244 : 0 : ((uint64_t)pkt[1]->data_len <<
2245 : : IAVF_TXD_QW1_TX_BUF_SZ_SHIFT);
2246 : 0 : hi_data_qw0 = hi_data_qw_tmpl |
2247 : 0 : ((uint64_t)pkt[0]->data_len <<
2248 : : IAVF_TXD_QW1_TX_BUF_SZ_SHIFT);
2249 : :
2250 [ # # # # ]: 0 : if (pkt[1]->ol_flags & RTE_MBUF_F_TX_VLAN) {
2251 [ # # # # ]: 0 : if (vlan_flag & IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG2) {
2252 : : hi_ctx_qw1 |=
2253 : : IAVF_TX_CTX_DESC_IL2TAG2 << IAVF_TXD_CTX_QW1_CMD_SHIFT;
2254 : 0 : low_ctx_qw1 |=
2255 : 0 : (uint64_t)pkt[1]->vlan_tci << IAVF_TXD_CTX_QW0_L2TAG2_PARAM;
2256 : : } else {
2257 : 0 : hi_data_qw1 |=
2258 : 0 : (uint64_t)pkt[1]->vlan_tci << IAVF_TXD_QW1_L2TAG1_SHIFT;
2259 : : }
2260 : : }
2261 : :
2262 [ # # # # ]: 0 : if (pkt[0]->ol_flags & RTE_MBUF_F_TX_VLAN) {
2263 [ # # # # ]: 0 : if (vlan_flag & IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG2) {
2264 : : hi_ctx_qw0 |=
2265 : : IAVF_TX_CTX_DESC_IL2TAG2 << IAVF_TXD_CTX_QW1_CMD_SHIFT;
2266 : 0 : low_ctx_qw0 |=
2267 : 0 : (uint64_t)pkt[0]->vlan_tci << IAVF_TXD_CTX_QW0_L2TAG2_PARAM;
2268 : : } else {
2269 : 0 : hi_data_qw0 |=
2270 : 0 : (uint64_t)pkt[0]->vlan_tci << IAVF_TXD_QW1_L2TAG1_SHIFT;
2271 : : }
2272 : : }
2273 : :
2274 : : if (offload) {
2275 : : iavf_txd_enable_offload(pkt[1], &hi_data_qw1);
2276 : : iavf_txd_enable_offload(pkt[0], &hi_data_qw0);
2277 : 0 : iavf_fill_ctx_desc_tunnelling_field(&low_ctx_qw1, pkt[1]);
2278 : 0 : iavf_fill_ctx_desc_tunnelling_field(&low_ctx_qw0, pkt[0]);
2279 : : }
2280 : :
2281 : : __m512i desc0_3 =
2282 : 0 : _mm512_set_epi64
2283 : 0 : (hi_data_qw1, pkt[1]->buf_iova + pkt[1]->data_off,
2284 : : hi_ctx_qw1, low_ctx_qw1,
2285 : 0 : hi_data_qw0, pkt[0]->buf_iova + pkt[0]->data_off,
2286 : : hi_ctx_qw0, low_ctx_qw0);
2287 : : _mm512_storeu_si512((void *)txdp, desc0_3);
2288 : : }
2289 : :
2290 [ # # # # ]: 0 : if (nb_pkts)
2291 [ # # # # ]: 0 : ctx_vtx1(txdp, *pkt, flags, offload, vlan_flag);
2292 : : }
2293 : :
2294 : : static __rte_always_inline uint16_t
2295 : : iavf_xmit_fixed_burst_vec_avx512(void *tx_queue, struct rte_mbuf **tx_pkts,
2296 : : uint16_t nb_pkts, bool offload)
2297 : : {
2298 : : struct iavf_tx_queue *txq = (struct iavf_tx_queue *)tx_queue;
2299 : : volatile struct iavf_tx_desc *txdp;
2300 : : struct iavf_tx_vec_entry *txep;
2301 : : uint16_t n, nb_commit, tx_id;
2302 : : /* bit2 is reserved and must be set to 1 according to Spec */
2303 : : uint64_t flags = IAVF_TX_DESC_CMD_EOP | IAVF_TX_DESC_CMD_ICRC;
2304 : : uint64_t rs = IAVF_TX_DESC_CMD_RS | flags;
2305 : :
2306 : 0 : if (txq->nb_free < txq->free_thresh)
2307 : : iavf_tx_free_bufs_avx512(txq);
2308 : :
2309 : 0 : nb_commit = nb_pkts = (uint16_t)RTE_MIN(txq->nb_free, nb_pkts);
2310 [ # # # # ]: 0 : if (unlikely(nb_pkts == 0))
2311 : : return 0;
2312 : :
2313 : 0 : tx_id = txq->tx_tail;
2314 : 0 : txdp = &txq->tx_ring[tx_id];
2315 : 0 : txep = (void *)txq->sw_ring;
2316 : 0 : txep += tx_id;
2317 : :
2318 : 0 : txq->nb_free = (uint16_t)(txq->nb_free - nb_pkts);
2319 : :
2320 : 0 : n = (uint16_t)(txq->nb_tx_desc - tx_id);
2321 [ # # # # ]: 0 : if (nb_commit >= n) {
2322 : 0 : tx_backlog_entry_avx512(txep, tx_pkts, n);
2323 : :
2324 [ # # # # ]: 0 : iavf_vtx(txdp, tx_pkts, n - 1, flags, offload);
2325 : 0 : tx_pkts += (n - 1);
2326 : 0 : txdp += (n - 1);
2327 : :
2328 [ # # ]: 0 : iavf_vtx1(txdp, *tx_pkts++, rs, offload);
2329 : :
2330 : 0 : nb_commit = (uint16_t)(nb_commit - n);
2331 : :
2332 : : tx_id = 0;
2333 : 0 : txq->next_rs = (uint16_t)(txq->rs_thresh - 1);
2334 : :
2335 : : /* avoid reach the end of ring */
2336 : 0 : txdp = &txq->tx_ring[tx_id];
2337 : 0 : txep = (void *)txq->sw_ring;
2338 : : txep += tx_id;
2339 : : }
2340 : :
2341 : 0 : tx_backlog_entry_avx512(txep, tx_pkts, nb_commit);
2342 : :
2343 : : iavf_vtx(txdp, tx_pkts, nb_commit, flags, offload);
2344 : :
2345 : 0 : tx_id = (uint16_t)(tx_id + nb_commit);
2346 [ # # # # ]: 0 : if (tx_id > txq->next_rs) {
2347 : 0 : txq->tx_ring[txq->next_rs].cmd_type_offset_bsz |=
2348 : : rte_cpu_to_le_64(((uint64_t)IAVF_TX_DESC_CMD_RS) <<
2349 : : IAVF_TXD_QW1_CMD_SHIFT);
2350 : 0 : txq->next_rs =
2351 : 0 : (uint16_t)(txq->next_rs + txq->rs_thresh);
2352 : : }
2353 : :
2354 : 0 : txq->tx_tail = tx_id;
2355 : :
2356 : 0 : IAVF_PCI_REG_WC_WRITE(txq->qtx_tail, txq->tx_tail);
2357 : :
2358 : : return nb_pkts;
2359 : : }
2360 : :
2361 : : static __rte_always_inline uint16_t
2362 : : iavf_xmit_fixed_burst_vec_avx512_ctx(void *tx_queue, struct rte_mbuf **tx_pkts,
2363 : : uint16_t nb_pkts, bool offload)
2364 : : {
2365 : : struct iavf_tx_queue *txq = (struct iavf_tx_queue *)tx_queue;
2366 : : volatile struct iavf_tx_desc *txdp;
2367 : : struct iavf_tx_vec_entry *txep;
2368 : : uint16_t n, nb_commit, nb_mbuf, tx_id;
2369 : : /* bit2 is reserved and must be set to 1 according to Spec */
2370 : : uint64_t flags = IAVF_TX_DESC_CMD_EOP | IAVF_TX_DESC_CMD_ICRC;
2371 : : uint64_t rs = IAVF_TX_DESC_CMD_RS | flags;
2372 : :
2373 : 0 : if (txq->nb_free < txq->free_thresh)
2374 : : iavf_tx_free_bufs_avx512(txq);
2375 : :
2376 : 0 : nb_commit = (uint16_t)RTE_MIN(txq->nb_free, nb_pkts << 1);
2377 : 0 : nb_commit &= 0xFFFE;
2378 [ # # ]: 0 : if (unlikely(nb_commit == 0))
2379 : : return 0;
2380 : :
2381 : 0 : nb_pkts = nb_commit >> 1;
2382 : 0 : tx_id = txq->tx_tail;
2383 : 0 : txdp = &txq->tx_ring[tx_id];
2384 : 0 : txep = (void *)txq->sw_ring;
2385 : 0 : txep += (tx_id >> 1);
2386 : :
2387 : 0 : txq->nb_free = (uint16_t)(txq->nb_free - nb_commit);
2388 : 0 : n = (uint16_t)(txq->nb_tx_desc - tx_id);
2389 : :
2390 [ # # ]: 0 : if (n != 0 && nb_commit >= n) {
2391 : 0 : nb_mbuf = n >> 1;
2392 : 0 : tx_backlog_entry_avx512(txep, tx_pkts, nb_mbuf);
2393 : :
2394 [ # # ]: 0 : ctx_vtx(txdp, tx_pkts, nb_mbuf - 1, flags, offload, txq->vlan_flag);
2395 : 0 : tx_pkts += (nb_mbuf - 1);
2396 : 0 : txdp += (n - 2);
2397 [ # # ]: 0 : ctx_vtx1(txdp, *tx_pkts++, rs, offload, txq->vlan_flag);
2398 : :
2399 : 0 : nb_commit = (uint16_t)(nb_commit - n);
2400 : :
2401 : 0 : txq->next_rs = (uint16_t)(txq->rs_thresh - 1);
2402 : : tx_id = 0;
2403 : : /* avoid reach the end of ring */
2404 : 0 : txdp = txq->tx_ring;
2405 : 0 : txep = (void *)txq->sw_ring;
2406 : : }
2407 : :
2408 : 0 : nb_mbuf = nb_commit >> 1;
2409 : 0 : tx_backlog_entry_avx512(txep, tx_pkts, nb_mbuf);
2410 : :
2411 [ # # ]: 0 : ctx_vtx(txdp, tx_pkts, nb_mbuf, flags, offload, txq->vlan_flag);
2412 : 0 : tx_id = (uint16_t)(tx_id + nb_commit);
2413 : :
2414 [ # # ]: 0 : if (tx_id > txq->next_rs) {
2415 : 0 : txq->tx_ring[txq->next_rs].cmd_type_offset_bsz |=
2416 : : rte_cpu_to_le_64(((uint64_t)IAVF_TX_DESC_CMD_RS) <<
2417 : : IAVF_TXD_QW1_CMD_SHIFT);
2418 : 0 : txq->next_rs =
2419 : 0 : (uint16_t)(txq->next_rs + txq->rs_thresh);
2420 : : }
2421 : :
2422 : 0 : txq->tx_tail = tx_id;
2423 : :
2424 : 0 : IAVF_PCI_REG_WC_WRITE(txq->qtx_tail, txq->tx_tail);
2425 : : return nb_pkts;
2426 : : }
2427 : :
2428 : : static __rte_always_inline uint16_t
2429 : : iavf_xmit_pkts_vec_avx512_cmn(void *tx_queue, struct rte_mbuf **tx_pkts,
2430 : : uint16_t nb_pkts, bool offload)
2431 : : {
2432 : : uint16_t nb_tx = 0;
2433 : : struct iavf_tx_queue *txq = (struct iavf_tx_queue *)tx_queue;
2434 : :
2435 [ # # # # ]: 0 : while (nb_pkts) {
2436 : : uint16_t ret, num;
2437 : :
2438 : : /* cross rs_thresh boundary is not allowed */
2439 : 0 : num = (uint16_t)RTE_MIN(nb_pkts, txq->rs_thresh);
2440 [ # # # # ]: 0 : ret = iavf_xmit_fixed_burst_vec_avx512(tx_queue, &tx_pkts[nb_tx],
2441 : : num, offload);
2442 : 0 : nb_tx += ret;
2443 : 0 : nb_pkts -= ret;
2444 [ # # # # ]: 0 : if (ret < num)
2445 : : break;
2446 : : }
2447 : :
2448 : : return nb_tx;
2449 : : }
2450 : :
2451 : : uint16_t
2452 : 0 : iavf_xmit_pkts_vec_avx512(void *tx_queue, struct rte_mbuf **tx_pkts,
2453 : : uint16_t nb_pkts)
2454 : : {
2455 : 0 : return iavf_xmit_pkts_vec_avx512_cmn(tx_queue, tx_pkts, nb_pkts, false);
2456 : : }
2457 : :
2458 : : void __rte_cold
2459 : 0 : iavf_tx_queue_release_mbufs_avx512(struct iavf_tx_queue *txq)
2460 : : {
2461 : : unsigned int i;
2462 : 0 : const uint16_t max_desc = (uint16_t)(txq->nb_tx_desc - 1);
2463 : 0 : const uint16_t end_desc = txq->tx_tail >> txq->use_ctx; /* next empty slot */
2464 : 0 : const uint16_t wrap_point = txq->nb_tx_desc >> txq->use_ctx; /* end of SW ring */
2465 : 0 : struct iavf_tx_vec_entry *swr = (void *)txq->sw_ring;
2466 : :
2467 [ # # # # ]: 0 : if (!txq->sw_ring || txq->nb_free == max_desc)
2468 : : return;
2469 : :
2470 : 0 : i = (txq->next_dd - txq->rs_thresh + 1) >> txq->use_ctx;
2471 [ # # ]: 0 : while (i != end_desc) {
2472 [ # # ]: 0 : rte_pktmbuf_free_seg(swr[i].mbuf);
2473 : 0 : swr[i].mbuf = NULL;
2474 [ # # ]: 0 : if (++i == wrap_point)
2475 : : i = 0;
2476 : : }
2477 : : }
2478 : :
2479 : : int __rte_cold
2480 : 0 : iavf_txq_vec_setup_avx512(struct iavf_tx_queue *txq)
2481 : : {
2482 : 0 : txq->rel_mbufs_type = IAVF_REL_MBUFS_AVX512_VEC;
2483 : 0 : return 0;
2484 : : }
2485 : :
2486 : : uint16_t
2487 : 0 : iavf_xmit_pkts_vec_avx512_offload(void *tx_queue, struct rte_mbuf **tx_pkts,
2488 : : uint16_t nb_pkts)
2489 : : {
2490 : 0 : return iavf_xmit_pkts_vec_avx512_cmn(tx_queue, tx_pkts, nb_pkts, true);
2491 : : }
2492 : :
2493 : : static __rte_always_inline uint16_t
2494 : : iavf_xmit_pkts_vec_avx512_ctx_cmn(void *tx_queue, struct rte_mbuf **tx_pkts,
2495 : : uint16_t nb_pkts, bool offload)
2496 : : {
2497 : : uint16_t nb_tx = 0;
2498 : : struct iavf_tx_queue *txq = (struct iavf_tx_queue *)tx_queue;
2499 : :
2500 [ # # ]: 0 : while (nb_pkts) {
2501 : : uint16_t ret, num;
2502 : :
2503 : : /* cross rs_thresh boundary is not allowed */
2504 : 0 : num = (uint16_t)RTE_MIN(nb_pkts << 1, txq->rs_thresh);
2505 : 0 : num = num >> 1;
2506 [ # # ]: 0 : ret = iavf_xmit_fixed_burst_vec_avx512_ctx(tx_queue, &tx_pkts[nb_tx],
2507 : : num, offload);
2508 : 0 : nb_tx += ret;
2509 : 0 : nb_pkts -= ret;
2510 [ # # ]: 0 : if (ret < num)
2511 : : break;
2512 : : }
2513 : :
2514 : : return nb_tx;
2515 : : }
2516 : :
2517 : : uint16_t
2518 : 0 : iavf_xmit_pkts_vec_avx512_ctx_offload(void *tx_queue, struct rte_mbuf **tx_pkts,
2519 : : uint16_t nb_pkts)
2520 : : {
2521 : 0 : return iavf_xmit_pkts_vec_avx512_ctx_cmn(tx_queue, tx_pkts, nb_pkts, true);
2522 : : }
|