Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2019 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 : : static __rte_always_inline void
14 : : iavf_rxq_rearm(struct iavf_rx_queue *rxq)
15 : : {
16 : : return iavf_rxq_rearm_common(rxq, false);
17 : : }
18 : :
19 : : #define PKTLEN_SHIFT 10
20 : :
21 : : static __rte_always_inline uint16_t
22 : : _iavf_recv_raw_pkts_vec_avx2(struct iavf_rx_queue *rxq,
23 : : struct rte_mbuf **rx_pkts,
24 : : uint16_t nb_pkts, uint8_t *split_packet,
25 : : bool offload)
26 : : {
27 : : #define IAVF_DESCS_PER_LOOP_AVX 8
28 : :
29 : : /* const uint32_t *ptype_tbl = rxq->vsi->adapter->ptype_tbl; */
30 : 0 : const uint32_t *type_table = rxq->vsi->adapter->ptype_tbl;
31 : :
32 : 0 : const __m256i mbuf_init = _mm256_set_epi64x(0, 0,
33 : 0 : 0, rxq->mbuf_initializer);
34 : : /* struct iavf_rx_entry *sw_ring = &rxq->sw_ring[rxq->rx_tail]; */
35 : 0 : struct rte_mbuf **sw_ring = &rxq->sw_ring[rxq->rx_tail];
36 : 0 : volatile union iavf_rx_desc *rxdp = rxq->rx_ring + rxq->rx_tail;
37 : : const int avx_aligned = ((rxq->rx_tail & 1) == 0);
38 : :
39 : : rte_prefetch0(rxdp);
40 : :
41 : : /* nb_pkts has to be floor-aligned to IAVF_DESCS_PER_LOOP_AVX */
42 : 0 : nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, IAVF_DESCS_PER_LOOP_AVX);
43 : :
44 : : /* See if we need to rearm the RX queue - gives the prefetch a bit
45 : : * of time to act
46 : : */
47 [ # # # # : 0 : if (rxq->rxrearm_nb > IAVF_RXQ_REARM_THRESH)
# # # # #
# # # ]
48 : : iavf_rxq_rearm(rxq);
49 : :
50 : : /* Before we start moving massive data around, check to see if
51 : : * there is actually a packet available
52 : : */
53 [ # # # # : 0 : if (!(rxdp->wb.qword1.status_error_len &
# # # # #
# # # ]
54 : : rte_cpu_to_le_32(1 << IAVF_RX_DESC_STATUS_DD_SHIFT)))
55 : : return 0;
56 : :
57 : : /* constants used in processing loop */
58 : : const __m256i crc_adjust =
59 : 0 : _mm256_set_epi16
60 : : (/* first descriptor */
61 : : 0, 0, 0, /* ignore non-length fields */
62 : : -rxq->crc_len, /* sub crc on data_len */
63 : : 0, /* ignore high-16bits of pkt_len */
64 : : -rxq->crc_len, /* sub crc on pkt_len */
65 : : 0, 0, /* ignore pkt_type field */
66 : : /* second descriptor */
67 : : 0, 0, 0, /* ignore non-length fields */
68 : : -rxq->crc_len, /* sub crc on data_len */
69 : : 0, /* ignore high-16bits of pkt_len */
70 : 0 : -rxq->crc_len, /* sub crc on pkt_len */
71 : : 0, 0 /* ignore pkt_type field */
72 : : );
73 : :
74 : : /* 8 packets DD mask, LSB in each 32-bit value */
75 : : const __m256i dd_check = _mm256_set1_epi32(1);
76 : :
77 : : /* 8 packets EOP mask, second-LSB in each 32-bit value */
78 : : const __m256i eop_check = _mm256_slli_epi32(dd_check,
79 : : IAVF_RX_DESC_STATUS_EOF_SHIFT);
80 : :
81 : : /* mask to shuffle from desc. to mbuf (2 descriptors)*/
82 : : const __m256i shuf_msk =
83 : : _mm256_set_epi8
84 : : (/* first descriptor */
85 : : 7, 6, 5, 4, /* octet 4~7, 32bits rss */
86 : : 3, 2, /* octet 2~3, low 16 bits vlan_macip */
87 : : 15, 14, /* octet 15~14, 16 bits data_len */
88 : : 0xFF, 0xFF, /* skip high 16 bits pkt_len, zero out */
89 : : 15, 14, /* octet 15~14, low 16 bits pkt_len */
90 : : 0xFF, 0xFF, /* pkt_type set as unknown */
91 : : 0xFF, 0xFF, /*pkt_type set as unknown */
92 : : /* second descriptor */
93 : : 7, 6, 5, 4, /* octet 4~7, 32bits rss */
94 : : 3, 2, /* octet 2~3, low 16 bits vlan_macip */
95 : : 15, 14, /* octet 15~14, 16 bits data_len */
96 : : 0xFF, 0xFF, /* skip high 16 bits pkt_len, zero out */
97 : : 15, 14, /* octet 15~14, low 16 bits pkt_len */
98 : : 0xFF, 0xFF, /* pkt_type set as unknown */
99 : : 0xFF, 0xFF /*pkt_type set as unknown */
100 : : );
101 : : /**
102 : : * compile-time check the above crc and shuffle layout is correct.
103 : : * NOTE: the first field (lowest address) is given last in set_epi
104 : : * calls above.
105 : : */
106 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
107 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4);
108 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) !=
109 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 8);
110 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, vlan_tci) !=
111 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 10);
112 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, hash) !=
113 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 12);
114 : :
115 : : /* Status/Error flag masks */
116 : : /**
117 : : * mask everything except RSS, flow director and VLAN flags
118 : : * bit2 is for VLAN tag, bit11 for flow director indication
119 : : * bit13:12 for RSS indication. Bits 3-5 of error
120 : : * field (bits 22-24) are for IP/L4 checksum errors
121 : : */
122 : : const __m256i flags_mask =
123 : : _mm256_set1_epi32((1 << 2) | (1 << 11) |
124 : : (3 << 12) | (7 << 22));
125 : : /**
126 : : * data to be shuffled by result of flag mask. If VLAN bit is set,
127 : : * (bit 2), then position 4 in this array will be used in the
128 : : * destination
129 : : */
130 : : const __m256i vlan_flags_shuf =
131 : : _mm256_set_epi32(0, 0, RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED, 0,
132 : : 0, 0, RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED, 0);
133 : : /**
134 : : * data to be shuffled by result of flag mask, shifted down 11.
135 : : * If RSS/FDIR bits are set, shuffle moves appropriate flags in
136 : : * place.
137 : : */
138 : : const __m256i rss_flags_shuf =
139 : : _mm256_set_epi8(0, 0, 0, 0, 0, 0, 0, 0,
140 : : RTE_MBUF_F_RX_RSS_HASH | RTE_MBUF_F_RX_FDIR, RTE_MBUF_F_RX_RSS_HASH,
141 : : 0, 0, 0, 0, RTE_MBUF_F_RX_FDIR, 0,/* end up 128-bits */
142 : : 0, 0, 0, 0, 0, 0, 0, 0,
143 : : RTE_MBUF_F_RX_RSS_HASH | RTE_MBUF_F_RX_FDIR, RTE_MBUF_F_RX_RSS_HASH,
144 : : 0, 0, 0, 0, RTE_MBUF_F_RX_FDIR, 0);
145 : :
146 : : /**
147 : : * data to be shuffled by the result of the flags mask shifted by 22
148 : : * bits. This gives use the l3_l4 flags.
149 : : */
150 : : const __m256i l3_l4_flags_shuf = _mm256_set_epi8(0, 0, 0, 0, 0, 0, 0, 0,
151 : : /* shift right 1 bit to make sure it not exceed 255 */
152 : : (RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
153 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
154 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
155 : : RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1,
156 : : (RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
157 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD) >> 1,
158 : : (RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
159 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1,
160 : : RTE_MBUF_F_RX_IP_CKSUM_BAD >> 1,
161 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1,
162 : : /* second 128-bits */
163 : : 0, 0, 0, 0, 0, 0, 0, 0,
164 : : (RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
165 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
166 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
167 : : RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1,
168 : : (RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
169 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD) >> 1,
170 : : (RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
171 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_BAD) >> 1,
172 : : RTE_MBUF_F_RX_IP_CKSUM_BAD >> 1,
173 : : (RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_GOOD) >> 1);
174 : :
175 : : const __m256i cksum_mask =
176 : : _mm256_set1_epi32(RTE_MBUF_F_RX_IP_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD |
177 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
178 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD);
179 : :
180 : : RTE_SET_USED(avx_aligned); /* for 32B descriptors we don't use this */
181 : :
182 : : uint16_t i, received;
183 : :
184 [ # # # # : 0 : for (i = 0, received = 0; i < nb_pkts;
# # # # #
# # # ]
185 : 0 : i += IAVF_DESCS_PER_LOOP_AVX,
186 : 0 : rxdp += IAVF_DESCS_PER_LOOP_AVX) {
187 : : /* step 1, copy over 8 mbuf pointers to rx_pkts array */
188 : 0 : _mm256_storeu_si256((void *)&rx_pkts[i],
189 : 0 : _mm256_loadu_si256((void *)&sw_ring[i]));
190 : : #ifdef RTE_ARCH_X86_64
191 : : _mm256_storeu_si256
192 : 0 : ((void *)&rx_pkts[i + 4],
193 : 0 : _mm256_loadu_si256((void *)&sw_ring[i + 4]));
194 : : #endif
195 : :
196 : : __m256i raw_desc0_1, raw_desc2_3, raw_desc4_5, raw_desc6_7;
197 : : #ifdef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
198 : : /* for AVX we need alignment otherwise loads are not atomic */
199 : : if (avx_aligned) {
200 : : /* load in descriptors, 2 at a time, in reverse order */
201 : : raw_desc6_7 = _mm256_load_si256((void *)(rxdp + 6));
202 : : rte_compiler_barrier();
203 : : raw_desc4_5 = _mm256_load_si256((void *)(rxdp + 4));
204 : : rte_compiler_barrier();
205 : : raw_desc2_3 = _mm256_load_si256((void *)(rxdp + 2));
206 : : rte_compiler_barrier();
207 : : raw_desc0_1 = _mm256_load_si256((void *)(rxdp + 0));
208 : : } else
209 : : #endif
210 : : {
211 : : const __m128i raw_desc7 =
212 : : _mm_load_si128((void *)(rxdp + 7));
213 : 0 : rte_compiler_barrier();
214 : : const __m128i raw_desc6 =
215 : : _mm_load_si128((void *)(rxdp + 6));
216 : 0 : rte_compiler_barrier();
217 : : const __m128i raw_desc5 =
218 : : _mm_load_si128((void *)(rxdp + 5));
219 : 0 : rte_compiler_barrier();
220 : : const __m128i raw_desc4 =
221 : : _mm_load_si128((void *)(rxdp + 4));
222 : 0 : rte_compiler_barrier();
223 : : const __m128i raw_desc3 =
224 : : _mm_load_si128((void *)(rxdp + 3));
225 : 0 : rte_compiler_barrier();
226 : : const __m128i raw_desc2 =
227 : : _mm_load_si128((void *)(rxdp + 2));
228 : 0 : rte_compiler_barrier();
229 : : const __m128i raw_desc1 =
230 : : _mm_load_si128((void *)(rxdp + 1));
231 : 0 : rte_compiler_barrier();
232 : : const __m128i raw_desc0 =
233 : : _mm_load_si128((void *)(rxdp + 0));
234 : :
235 : : raw_desc6_7 =
236 : : _mm256_inserti128_si256
237 : : (_mm256_castsi128_si256(raw_desc6),
238 : : raw_desc7, 1);
239 : : raw_desc4_5 =
240 : : _mm256_inserti128_si256
241 : : (_mm256_castsi128_si256(raw_desc4),
242 : : raw_desc5, 1);
243 : : raw_desc2_3 =
244 : : _mm256_inserti128_si256
245 : : (_mm256_castsi128_si256(raw_desc2),
246 : : raw_desc3, 1);
247 : : raw_desc0_1 =
248 : : _mm256_inserti128_si256
249 : : (_mm256_castsi128_si256(raw_desc0),
250 : : raw_desc1, 1);
251 : : }
252 : :
253 [ # # # # : 0 : if (split_packet) {
# # # # ]
254 : : int j;
255 : :
256 [ # # # # : 0 : for (j = 0; j < IAVF_DESCS_PER_LOOP_AVX; j++)
# # # # ]
257 : 0 : rte_mbuf_prefetch_part2(rx_pkts[i + j]);
258 : : }
259 : :
260 : : /**
261 : : * convert descriptors 4-7 into mbufs, adjusting length and
262 : : * re-arranging fields. Then write into the mbuf
263 : : */
264 : : const __m256i len6_7 = _mm256_slli_epi32(raw_desc6_7,
265 : : PKTLEN_SHIFT);
266 : : const __m256i len4_5 = _mm256_slli_epi32(raw_desc4_5,
267 : : PKTLEN_SHIFT);
268 : : const __m256i desc6_7 = _mm256_blend_epi16(raw_desc6_7,
269 : : len6_7, 0x80);
270 : : const __m256i desc4_5 = _mm256_blend_epi16(raw_desc4_5,
271 : : len4_5, 0x80);
272 : : __m256i mb6_7 = _mm256_shuffle_epi8(desc6_7, shuf_msk);
273 : : __m256i mb4_5 = _mm256_shuffle_epi8(desc4_5, shuf_msk);
274 : :
275 : : mb6_7 = _mm256_add_epi16(mb6_7, crc_adjust);
276 : : mb4_5 = _mm256_add_epi16(mb4_5, crc_adjust);
277 : : /**
278 : : * to get packet types, shift 64-bit values down 30 bits
279 : : * and so ptype is in lower 8-bits in each
280 : : */
281 : : const __m256i ptypes6_7 = _mm256_srli_epi64(desc6_7, 30);
282 : : const __m256i ptypes4_5 = _mm256_srli_epi64(desc4_5, 30);
283 : : const uint8_t ptype7 = _mm256_extract_epi8(ptypes6_7, 24);
284 : : const uint8_t ptype6 = _mm256_extract_epi8(ptypes6_7, 8);
285 : : const uint8_t ptype5 = _mm256_extract_epi8(ptypes4_5, 24);
286 : : const uint8_t ptype4 = _mm256_extract_epi8(ptypes4_5, 8);
287 : :
288 [ # # # # : 0 : mb6_7 = _mm256_insert_epi32(mb6_7, type_table[ptype7], 4);
# # # # #
# # # ]
289 : 0 : mb6_7 = _mm256_insert_epi32(mb6_7, type_table[ptype6], 0);
290 : 0 : mb4_5 = _mm256_insert_epi32(mb4_5, type_table[ptype5], 4);
291 [ # # # # : 0 : mb4_5 = _mm256_insert_epi32(mb4_5, type_table[ptype4], 0);
# # # # #
# # # ]
292 : : /* merge the status bits into one register */
293 : : const __m256i status4_7 = _mm256_unpackhi_epi32(desc6_7,
294 : : desc4_5);
295 : :
296 : : /**
297 : : * convert descriptors 0-3 into mbufs, adjusting length and
298 : : * re-arranging fields. Then write into the mbuf
299 : : */
300 : : const __m256i len2_3 = _mm256_slli_epi32(raw_desc2_3,
301 : : PKTLEN_SHIFT);
302 : : const __m256i len0_1 = _mm256_slli_epi32(raw_desc0_1,
303 : : PKTLEN_SHIFT);
304 : : const __m256i desc2_3 = _mm256_blend_epi16(raw_desc2_3,
305 : : len2_3, 0x80);
306 : : const __m256i desc0_1 = _mm256_blend_epi16(raw_desc0_1,
307 : : len0_1, 0x80);
308 : : __m256i mb2_3 = _mm256_shuffle_epi8(desc2_3, shuf_msk);
309 : : __m256i mb0_1 = _mm256_shuffle_epi8(desc0_1, shuf_msk);
310 : :
311 : : mb2_3 = _mm256_add_epi16(mb2_3, crc_adjust);
312 : : mb0_1 = _mm256_add_epi16(mb0_1, crc_adjust);
313 : : /* get the packet types */
314 : : const __m256i ptypes2_3 = _mm256_srli_epi64(desc2_3, 30);
315 : : const __m256i ptypes0_1 = _mm256_srli_epi64(desc0_1, 30);
316 : : const uint8_t ptype3 = _mm256_extract_epi8(ptypes2_3, 24);
317 : : const uint8_t ptype2 = _mm256_extract_epi8(ptypes2_3, 8);
318 : : const uint8_t ptype1 = _mm256_extract_epi8(ptypes0_1, 24);
319 : : const uint8_t ptype0 = _mm256_extract_epi8(ptypes0_1, 8);
320 : :
321 : 0 : mb2_3 = _mm256_insert_epi32(mb2_3, type_table[ptype3], 4);
322 : 0 : mb2_3 = _mm256_insert_epi32(mb2_3, type_table[ptype2], 0);
323 : 0 : mb0_1 = _mm256_insert_epi32(mb0_1, type_table[ptype1], 4);
324 [ # # # # : 0 : mb0_1 = _mm256_insert_epi32(mb0_1, type_table[ptype0], 0);
# # # # #
# # # ]
325 : : /* merge the status bits into one register */
326 : : const __m256i status0_3 = _mm256_unpackhi_epi32(desc2_3,
327 : : desc0_1);
328 : :
329 : : /**
330 : : * take the two sets of status bits and merge to one
331 : : * After merge, the packets status flags are in the
332 : : * order (hi->lo): [1, 3, 5, 7, 0, 2, 4, 6]
333 : : */
334 : : __m256i status0_7 = _mm256_unpacklo_epi64(status4_7,
335 : : status0_3);
336 : : __m256i mbuf_flags = _mm256_set1_epi32(0);
337 : :
338 : : if (offload) {
339 : : /* now do flag manipulation */
340 : :
341 : : /* get only flag/error bits we want */
342 : : const __m256i flag_bits =
343 : : _mm256_and_si256(status0_7, flags_mask);
344 : : /* set vlan and rss flags */
345 : : const __m256i vlan_flags =
346 : : _mm256_shuffle_epi8(vlan_flags_shuf, flag_bits);
347 : : const __m256i rss_flags =
348 : : _mm256_shuffle_epi8(rss_flags_shuf,
349 : : _mm256_srli_epi32(flag_bits, 11));
350 : : /**
351 : : * l3_l4_error flags, shuffle, then shift to correct adjustment
352 : : * of flags in flags_shuf, and finally mask out extra bits
353 : : */
354 : : __m256i l3_l4_flags = _mm256_shuffle_epi8(l3_l4_flags_shuf,
355 : : _mm256_srli_epi32(flag_bits, 22));
356 : : l3_l4_flags = _mm256_slli_epi32(l3_l4_flags, 1);
357 : : l3_l4_flags = _mm256_and_si256(l3_l4_flags, cksum_mask);
358 : :
359 : : /* merge flags */
360 : : mbuf_flags = _mm256_or_si256(l3_l4_flags,
361 : : _mm256_or_si256(rss_flags, vlan_flags));
362 : : }
363 : :
364 : : /**
365 : : * At this point, we have the 8 sets of flags in the low 16-bits
366 : : * of each 32-bit value in vlan0.
367 : : * We want to extract these, and merge them with the mbuf init
368 : : * data so we can do a single write to the mbuf to set the flags
369 : : * and all the other initialization fields. Extracting the
370 : : * appropriate flags means that we have to do a shift and blend
371 : : * for each mbuf before we do the write. However, we can also
372 : : * add in the previously computed rx_descriptor fields to
373 : : * make a single 256-bit write per mbuf
374 : : */
375 : : /* check the structure matches expectations */
376 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=
377 : : offsetof(struct rte_mbuf, rearm_data) + 8);
378 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, rearm_data) !=
379 : : RTE_ALIGN(offsetof(struct rte_mbuf,
380 : : rearm_data),
381 : : 16));
382 : : /* build up data and do writes */
383 : : __m256i rearm0, rearm1, rearm2, rearm3, rearm4, rearm5,
384 : : rearm6, rearm7;
385 : : rearm6 = _mm256_blend_epi32(mbuf_init,
386 : : _mm256_slli_si256(mbuf_flags, 8),
387 : : 0x04);
388 : : rearm4 = _mm256_blend_epi32(mbuf_init,
389 : : _mm256_slli_si256(mbuf_flags, 4),
390 : : 0x04);
391 : : rearm2 = _mm256_blend_epi32(mbuf_init, mbuf_flags, 0x04);
392 : : rearm0 = _mm256_blend_epi32(mbuf_init,
393 : : _mm256_srli_si256(mbuf_flags, 4),
394 : : 0x04);
395 : : /* permute to add in the rx_descriptor e.g. rss fields */
396 : : rearm6 = _mm256_permute2f128_si256(rearm6, mb6_7, 0x20);
397 : : rearm4 = _mm256_permute2f128_si256(rearm4, mb4_5, 0x20);
398 : : rearm2 = _mm256_permute2f128_si256(rearm2, mb2_3, 0x20);
399 : : rearm0 = _mm256_permute2f128_si256(rearm0, mb0_1, 0x20);
400 : : /* write to mbuf */
401 [ # # # # : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 6]->rearm_data,
# # # # #
# # # ]
402 : : rearm6);
403 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 4]->rearm_data,
404 : : rearm4);
405 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 2]->rearm_data,
406 : : rearm2);
407 [ # # # # : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 0]->rearm_data,
# # # # #
# # # ]
408 : : rearm0);
409 : :
410 : : /* repeat for the odd mbufs */
411 : : const __m256i odd_flags =
412 : : _mm256_castsi128_si256
413 : : (_mm256_extracti128_si256(mbuf_flags, 1));
414 : : rearm7 = _mm256_blend_epi32(mbuf_init,
415 : : _mm256_slli_si256(odd_flags, 8),
416 : : 0x04);
417 : : rearm5 = _mm256_blend_epi32(mbuf_init,
418 : : _mm256_slli_si256(odd_flags, 4),
419 : : 0x04);
420 : : rearm3 = _mm256_blend_epi32(mbuf_init, odd_flags, 0x04);
421 : : rearm1 = _mm256_blend_epi32(mbuf_init,
422 : : _mm256_srli_si256(odd_flags, 4),
423 : : 0x04);
424 : : /* since odd mbufs are already in hi 128-bits use blend */
425 : : rearm7 = _mm256_blend_epi32(rearm7, mb6_7, 0xF0);
426 : : rearm5 = _mm256_blend_epi32(rearm5, mb4_5, 0xF0);
427 : : rearm3 = _mm256_blend_epi32(rearm3, mb2_3, 0xF0);
428 : : rearm1 = _mm256_blend_epi32(rearm1, mb0_1, 0xF0);
429 : : /* again write to mbufs */
430 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 7]->rearm_data,
431 : : rearm7);
432 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 5]->rearm_data,
433 : : rearm5);
434 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 3]->rearm_data,
435 : : rearm3);
436 [ # # # # ]: 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 1]->rearm_data,
437 : : rearm1);
438 : :
439 : : /* extract and record EOP bit */
440 [ # # # # : 0 : if (split_packet) {
# # # # ]
441 : : const __m128i eop_mask =
442 : : _mm_set1_epi16(1 << IAVF_RX_DESC_STATUS_EOF_SHIFT);
443 : : const __m256i eop_bits256 = _mm256_and_si256(status0_7,
444 : : eop_check);
445 : : /* pack status bits into a single 128-bit register */
446 : : const __m128i eop_bits =
447 : : _mm_packus_epi32
448 : : (_mm256_castsi256_si128(eop_bits256),
449 : : _mm256_extractf128_si256(eop_bits256,
450 : : 1));
451 : : /**
452 : : * flip bits, and mask out the EOP bit, which is now
453 : : * a split-packet bit i.e. !EOP, rather than EOP one.
454 : : */
455 : : __m128i split_bits = _mm_andnot_si128(eop_bits,
456 : : eop_mask);
457 : : /**
458 : : * eop bits are out of order, so we need to shuffle them
459 : : * back into order again. In doing so, only use low 8
460 : : * bits, which acts like another pack instruction
461 : : * The original order is (hi->lo): 1,3,5,7,0,2,4,6
462 : : * [Since we use epi8, the 16-bit positions are
463 : : * multiplied by 2 in the eop_shuffle value.]
464 : : */
465 : : __m128i eop_shuffle =
466 : : _mm_set_epi8(/* zero hi 64b */
467 : : 0xFF, 0xFF, 0xFF, 0xFF,
468 : : 0xFF, 0xFF, 0xFF, 0xFF,
469 : : /* move values to lo 64b */
470 : : 8, 0, 10, 2,
471 : : 12, 4, 14, 6);
472 : : split_bits = _mm_shuffle_epi8(split_bits, eop_shuffle);
473 : 0 : *(uint64_t *)split_packet =
474 : 0 : _mm_cvtsi128_si64(split_bits);
475 : 0 : split_packet += IAVF_DESCS_PER_LOOP_AVX;
476 : : }
477 : :
478 : : /* perform dd_check */
479 : : status0_7 = _mm256_and_si256(status0_7, dd_check);
480 : : status0_7 = _mm256_packs_epi32(status0_7,
481 : : _mm256_setzero_si256());
482 : :
483 [ # # # # : 0 : uint64_t burst = rte_popcount64
# # # # #
# # # ]
484 : : (_mm_cvtsi128_si64
485 : : (_mm256_extracti128_si256
486 : : (status0_7, 1)));
487 : 0 : burst += rte_popcount64
488 : : (_mm_cvtsi128_si64
489 : : (_mm256_castsi256_si128(status0_7)));
490 : 0 : received += burst;
491 [ # # # # : 0 : if (burst != IAVF_DESCS_PER_LOOP_AVX)
# # # # #
# # # ]
492 : : break;
493 : : }
494 : :
495 : : /* update tail pointers */
496 : 0 : rxq->rx_tail += received;
497 : 0 : rxq->rx_tail &= (rxq->nb_rx_desc - 1);
498 [ # # # # : 0 : if ((rxq->rx_tail & 1) == 1 && received > 1) { /* keep avx2 aligned */
# # # # #
# # # # #
# # # # #
# # # #
# ]
499 : 0 : rxq->rx_tail--;
500 : 0 : received--;
501 : : }
502 : 0 : rxq->rxrearm_nb += received;
503 : 0 : return received;
504 : : }
505 : :
506 : : static inline __m256i
507 : : flex_rxd_to_fdir_flags_vec_avx2(const __m256i fdir_id0_7)
508 : : {
509 : : #define FDID_MIS_MAGIC 0xFFFFFFFF
510 : : RTE_BUILD_BUG_ON(RTE_MBUF_F_RX_FDIR != (1 << 2));
511 : : RTE_BUILD_BUG_ON(RTE_MBUF_F_RX_FDIR_ID != (1 << 13));
512 : : const __m256i pkt_fdir_bit = _mm256_set1_epi32(RTE_MBUF_F_RX_FDIR |
513 : : RTE_MBUF_F_RX_FDIR_ID);
514 : : /* desc->flow_id field == 0xFFFFFFFF means fdir mismatch */
515 : : const __m256i fdir_mis_mask = _mm256_set1_epi32(FDID_MIS_MAGIC);
516 : : __m256i fdir_mask = _mm256_cmpeq_epi32(fdir_id0_7,
517 : : fdir_mis_mask);
518 : : /* this XOR op results to bit-reverse the fdir_mask */
519 : : fdir_mask = _mm256_xor_si256(fdir_mask, fdir_mis_mask);
520 : : const __m256i fdir_flags = _mm256_and_si256(fdir_mask, pkt_fdir_bit);
521 : :
522 : : return fdir_flags;
523 : : }
524 : :
525 : : static __rte_always_inline uint16_t
526 : : _iavf_recv_raw_pkts_vec_avx2_flex_rxd(struct iavf_rx_queue *rxq,
527 : : struct rte_mbuf **rx_pkts,
528 : : uint16_t nb_pkts, uint8_t *split_packet,
529 : : bool offload)
530 : : {
531 : : #define IAVF_DESCS_PER_LOOP_AVX 8
532 : :
533 : 0 : struct iavf_adapter *adapter = rxq->vsi->adapter;
534 : :
535 : : #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
536 : 0 : uint64_t offloads = adapter->dev_data->dev_conf.rxmode.offloads;
537 : : #endif
538 : 0 : const uint32_t *type_table = adapter->ptype_tbl;
539 : :
540 : 0 : const __m256i mbuf_init = _mm256_set_epi64x(0, 0,
541 : 0 : 0, rxq->mbuf_initializer);
542 : 0 : struct rte_mbuf **sw_ring = &rxq->sw_ring[rxq->rx_tail];
543 : 0 : volatile union iavf_rx_flex_desc *rxdp =
544 : 0 : (union iavf_rx_flex_desc *)rxq->rx_ring + rxq->rx_tail;
545 : :
546 : : rte_prefetch0(rxdp);
547 : :
548 : : /* nb_pkts has to be floor-aligned to IAVF_DESCS_PER_LOOP_AVX */
549 : 0 : nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, IAVF_DESCS_PER_LOOP_AVX);
550 : :
551 : : /* See if we need to rearm the RX queue - gives the prefetch a bit
552 : : * of time to act
553 : : */
554 [ # # # # : 0 : if (rxq->rxrearm_nb > IAVF_RXQ_REARM_THRESH)
# # # # #
# # # ]
555 : : iavf_rxq_rearm(rxq);
556 : :
557 : : /* Before we start moving massive data around, check to see if
558 : : * there is actually a packet available
559 : : */
560 [ # # # # : 0 : if (!(rxdp->wb.status_error0 &
# # # # #
# # # ]
561 : : rte_cpu_to_le_32(1 << IAVF_RX_FLEX_DESC_STATUS0_DD_S)))
562 : : return 0;
563 : : #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
564 : : bool is_tsinit = false;
565 : : uint8_t inflection_point = 0;
566 [ # # # # : 0 : __m256i hw_low_last = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, rxq->phc_time);
# # ]
567 [ # # # # : 0 : if (rxq->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) {
# # # # #
# # # ]
568 : 0 : uint64_t sw_cur_time = rte_get_timer_cycles() / (rte_get_timer_hz() / 1000);
569 : :
570 [ # # # # : 0 : if (unlikely(sw_cur_time - rxq->hw_time_update > 4)) {
# # ]
571 : : hw_low_last = _mm256_setzero_si256();
572 : : is_tsinit = 1;
573 : : } else {
574 : 0 : hw_low_last = _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, rxq->phc_time);
575 : : }
576 : : }
577 : : #endif
578 : :
579 : : /* constants used in processing loop */
580 : : const __m256i crc_adjust =
581 : 0 : _mm256_set_epi16
582 : : (/* first descriptor */
583 : : 0, 0, 0, /* ignore non-length fields */
584 : : -rxq->crc_len, /* sub crc on data_len */
585 : : 0, /* ignore high-16bits of pkt_len */
586 : : -rxq->crc_len, /* sub crc on pkt_len */
587 : : 0, 0, /* ignore pkt_type field */
588 : : /* second descriptor */
589 : : 0, 0, 0, /* ignore non-length fields */
590 : : -rxq->crc_len, /* sub crc on data_len */
591 : : 0, /* ignore high-16bits of pkt_len */
592 : 0 : -rxq->crc_len, /* sub crc on pkt_len */
593 : : 0, 0 /* ignore pkt_type field */
594 : : );
595 : :
596 : : /* 8 packets DD mask, LSB in each 32-bit value */
597 : : const __m256i dd_check = _mm256_set1_epi32(1);
598 : :
599 : : /* 8 packets EOP mask, second-LSB in each 32-bit value */
600 : : const __m256i eop_check = _mm256_slli_epi32(dd_check,
601 : : IAVF_RX_FLEX_DESC_STATUS0_EOF_S);
602 : :
603 : : /* mask to shuffle from desc. to mbuf (2 descriptors)*/
604 : : const __m256i shuf_msk =
605 : : _mm256_set_epi8
606 : : (/* first descriptor */
607 : : 0xFF, 0xFF,
608 : : 0xFF, 0xFF, /* rss hash parsed separately */
609 : : 11, 10, /* octet 10~11, 16 bits vlan_macip */
610 : : 5, 4, /* octet 4~5, 16 bits data_len */
611 : : 0xFF, 0xFF, /* skip hi 16 bits pkt_len, zero out */
612 : : 5, 4, /* octet 4~5, 16 bits pkt_len */
613 : : 0xFF, 0xFF, /* pkt_type set as unknown */
614 : : 0xFF, 0xFF, /*pkt_type set as unknown */
615 : : /* second descriptor */
616 : : 0xFF, 0xFF,
617 : : 0xFF, 0xFF, /* rss hash parsed separately */
618 : : 11, 10, /* octet 10~11, 16 bits vlan_macip */
619 : : 5, 4, /* octet 4~5, 16 bits data_len */
620 : : 0xFF, 0xFF, /* skip hi 16 bits pkt_len, zero out */
621 : : 5, 4, /* octet 4~5, 16 bits pkt_len */
622 : : 0xFF, 0xFF, /* pkt_type set as unknown */
623 : : 0xFF, 0xFF /*pkt_type set as unknown */
624 : : );
625 : : /**
626 : : * compile-time check the above crc and shuffle layout is correct.
627 : : * NOTE: the first field (lowest address) is given last in set_epi
628 : : * calls above.
629 : : */
630 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
631 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4);
632 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) !=
633 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 8);
634 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, vlan_tci) !=
635 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 10);
636 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, hash) !=
637 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 12);
638 : :
639 : : /* Status/Error flag masks */
640 : : /**
641 : : * mask everything except Checksum Reports, RSS indication
642 : : * and VLAN indication.
643 : : * bit6:4 for IP/L4 checksum errors.
644 : : * bit12 is for RSS indication.
645 : : * bit13 is for VLAN indication.
646 : : */
647 : : const __m256i flags_mask =
648 : : _mm256_set1_epi32((0xF << 4) | (1 << 12) | (1 << 13));
649 : : /**
650 : : * data to be shuffled by the result of the flags mask shifted by 4
651 : : * bits. This gives use the l3_l4 flags.
652 : : */
653 : : const __m256i l3_l4_flags_shuf =
654 : : _mm256_set_epi8((RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
655 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
656 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
657 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
658 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
659 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
660 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
661 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
662 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
663 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
664 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
665 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
666 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
667 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
668 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
669 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
670 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
671 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
672 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
673 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
674 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
675 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
676 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
677 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
678 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
679 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
680 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
681 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
682 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
683 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
684 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
685 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
686 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
687 : : /**
688 : : * second 128-bits
689 : : * shift right 20 bits to use the low two bits to indicate
690 : : * outer checksum status
691 : : * shift right 1 bit to make sure it not exceed 255
692 : : */
693 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
694 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
695 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
696 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
697 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
698 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
699 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
700 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
701 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
702 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
703 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
704 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
705 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
706 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
707 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
708 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
709 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
710 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
711 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
712 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
713 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
714 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
715 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
716 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
717 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
718 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
719 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
720 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
721 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
722 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
723 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
724 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1);
725 : : const __m256i cksum_mask =
726 : : _mm256_set1_epi32(RTE_MBUF_F_RX_IP_CKSUM_MASK |
727 : : RTE_MBUF_F_RX_L4_CKSUM_MASK |
728 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
729 : : RTE_MBUF_F_RX_OUTER_L4_CKSUM_MASK);
730 : : /**
731 : : * data to be shuffled by result of flag mask, shifted down 12.
732 : : * If RSS(bit12)/VLAN(bit13) are set,
733 : : * shuffle moves appropriate flags in place.
734 : : */
735 : : const __m256i rss_flags_shuf = _mm256_set_epi8(0, 0, 0, 0,
736 : : 0, 0, 0, 0,
737 : : 0, 0, 0, 0,
738 : : RTE_MBUF_F_RX_RSS_HASH, 0,
739 : : RTE_MBUF_F_RX_RSS_HASH, 0,
740 : : /* end up 128-bits */
741 : : 0, 0, 0, 0,
742 : : 0, 0, 0, 0,
743 : : 0, 0, 0, 0,
744 : : RTE_MBUF_F_RX_RSS_HASH, 0,
745 : : RTE_MBUF_F_RX_RSS_HASH, 0);
746 : :
747 : : const __m256i vlan_flags_shuf = _mm256_set_epi8(0, 0, 0, 0,
748 : : 0, 0, 0, 0,
749 : : 0, 0, 0, 0,
750 : : RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
751 : : RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
752 : : 0, 0,
753 : : /* end up 128-bits */
754 : : 0, 0, 0, 0,
755 : : 0, 0, 0, 0,
756 : : 0, 0, 0, 0,
757 : : RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
758 : : RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
759 : : 0, 0);
760 : :
761 : : uint16_t i, received;
762 : :
763 [ # # # # : 0 : for (i = 0, received = 0; i < nb_pkts;
# # # # #
# # # ]
764 : 0 : i += IAVF_DESCS_PER_LOOP_AVX,
765 : 0 : rxdp += IAVF_DESCS_PER_LOOP_AVX) {
766 : : /* step 1, copy over 8 mbuf pointers to rx_pkts array */
767 : 0 : _mm256_storeu_si256((void *)&rx_pkts[i],
768 : 0 : _mm256_loadu_si256((void *)&sw_ring[i]));
769 : : #ifdef RTE_ARCH_X86_64
770 : : _mm256_storeu_si256
771 : 0 : ((void *)&rx_pkts[i + 4],
772 : 0 : _mm256_loadu_si256((void *)&sw_ring[i + 4]));
773 : : #endif
774 : :
775 : : __m256i raw_desc0_1, raw_desc2_3, raw_desc4_5, raw_desc6_7;
776 : :
777 : : const __m128i raw_desc7 =
778 : : _mm_load_si128((void *)(rxdp + 7));
779 : 0 : rte_compiler_barrier();
780 : : const __m128i raw_desc6 =
781 : : _mm_load_si128((void *)(rxdp + 6));
782 : 0 : rte_compiler_barrier();
783 : : const __m128i raw_desc5 =
784 : : _mm_load_si128((void *)(rxdp + 5));
785 : 0 : rte_compiler_barrier();
786 : : const __m128i raw_desc4 =
787 : : _mm_load_si128((void *)(rxdp + 4));
788 : 0 : rte_compiler_barrier();
789 : : const __m128i raw_desc3 =
790 : : _mm_load_si128((void *)(rxdp + 3));
791 : 0 : rte_compiler_barrier();
792 : : const __m128i raw_desc2 =
793 : : _mm_load_si128((void *)(rxdp + 2));
794 : 0 : rte_compiler_barrier();
795 : : const __m128i raw_desc1 =
796 : : _mm_load_si128((void *)(rxdp + 1));
797 : 0 : rte_compiler_barrier();
798 : : const __m128i raw_desc0 =
799 : : _mm_load_si128((void *)(rxdp + 0));
800 : :
801 : : raw_desc6_7 =
802 : : _mm256_inserti128_si256
803 : : (_mm256_castsi128_si256(raw_desc6),
804 : : raw_desc7, 1);
805 : : raw_desc4_5 =
806 : : _mm256_inserti128_si256
807 : : (_mm256_castsi128_si256(raw_desc4),
808 : : raw_desc5, 1);
809 : : raw_desc2_3 =
810 : : _mm256_inserti128_si256
811 : : (_mm256_castsi128_si256(raw_desc2),
812 : : raw_desc3, 1);
813 : : raw_desc0_1 =
814 : : _mm256_inserti128_si256
815 : : (_mm256_castsi128_si256(raw_desc0),
816 : : raw_desc1, 1);
817 : :
818 [ # # # # : 0 : if (split_packet) {
# # # # ]
819 : : int j;
820 : :
821 [ # # # # : 0 : for (j = 0; j < IAVF_DESCS_PER_LOOP_AVX; j++)
# # # # ]
822 : 0 : rte_mbuf_prefetch_part2(rx_pkts[i + j]);
823 : : }
824 : :
825 : : /**
826 : : * convert descriptors 4-7 into mbufs, re-arrange fields.
827 : : * Then write into the mbuf.
828 : : */
829 : : __m256i mb6_7 = _mm256_shuffle_epi8(raw_desc6_7, shuf_msk);
830 : : __m256i mb4_5 = _mm256_shuffle_epi8(raw_desc4_5, shuf_msk);
831 : :
832 : : mb6_7 = _mm256_add_epi16(mb6_7, crc_adjust);
833 : : mb4_5 = _mm256_add_epi16(mb4_5, crc_adjust);
834 : :
835 : : /**
836 : : * to get packet types, ptype is located in bit16-25
837 : : * of each 128bits
838 : : */
839 : : const __m256i ptype_mask =
840 : : _mm256_set1_epi16(IAVF_RX_FLEX_DESC_PTYPE_M);
841 : : const __m256i ptypes6_7 =
842 : : _mm256_and_si256(raw_desc6_7, ptype_mask);
843 : : const __m256i ptypes4_5 =
844 : : _mm256_and_si256(raw_desc4_5, ptype_mask);
845 : : const uint16_t ptype7 = _mm256_extract_epi16(ptypes6_7, 9);
846 : : const uint16_t ptype6 = _mm256_extract_epi16(ptypes6_7, 1);
847 : : const uint16_t ptype5 = _mm256_extract_epi16(ptypes4_5, 9);
848 : : const uint16_t ptype4 = _mm256_extract_epi16(ptypes4_5, 1);
849 : :
850 [ # # # # : 0 : mb6_7 = _mm256_insert_epi32(mb6_7, type_table[ptype7], 4);
# # # # #
# # # ]
851 : 0 : mb6_7 = _mm256_insert_epi32(mb6_7, type_table[ptype6], 0);
852 : 0 : mb4_5 = _mm256_insert_epi32(mb4_5, type_table[ptype5], 4);
853 [ # # # # : 0 : mb4_5 = _mm256_insert_epi32(mb4_5, type_table[ptype4], 0);
# # # # #
# # # ]
854 : : /* merge the status bits into one register */
855 : : const __m256i status4_7 = _mm256_unpackhi_epi32(raw_desc6_7,
856 : : raw_desc4_5);
857 : :
858 : : /**
859 : : * convert descriptors 0-3 into mbufs, re-arrange fields.
860 : : * Then write into the mbuf.
861 : : */
862 : : __m256i mb2_3 = _mm256_shuffle_epi8(raw_desc2_3, shuf_msk);
863 : : __m256i mb0_1 = _mm256_shuffle_epi8(raw_desc0_1, shuf_msk);
864 : :
865 : : mb2_3 = _mm256_add_epi16(mb2_3, crc_adjust);
866 : : mb0_1 = _mm256_add_epi16(mb0_1, crc_adjust);
867 : : /**
868 : : * to get packet types, ptype is located in bit16-25
869 : : * of each 128bits
870 : : */
871 : : const __m256i ptypes2_3 =
872 : : _mm256_and_si256(raw_desc2_3, ptype_mask);
873 : : const __m256i ptypes0_1 =
874 : : _mm256_and_si256(raw_desc0_1, ptype_mask);
875 : : const uint16_t ptype3 = _mm256_extract_epi16(ptypes2_3, 9);
876 : : const uint16_t ptype2 = _mm256_extract_epi16(ptypes2_3, 1);
877 : : const uint16_t ptype1 = _mm256_extract_epi16(ptypes0_1, 9);
878 : : const uint16_t ptype0 = _mm256_extract_epi16(ptypes0_1, 1);
879 : :
880 : 0 : mb2_3 = _mm256_insert_epi32(mb2_3, type_table[ptype3], 4);
881 : 0 : mb2_3 = _mm256_insert_epi32(mb2_3, type_table[ptype2], 0);
882 : 0 : mb0_1 = _mm256_insert_epi32(mb0_1, type_table[ptype1], 4);
883 [ # # # # : 0 : mb0_1 = _mm256_insert_epi32(mb0_1, type_table[ptype0], 0);
# # # # #
# # # ]
884 : : /* merge the status bits into one register */
885 : : const __m256i status0_3 = _mm256_unpackhi_epi32(raw_desc2_3,
886 : : raw_desc0_1);
887 : :
888 : : /**
889 : : * take the two sets of status bits and merge to one
890 : : * After merge, the packets status flags are in the
891 : : * order (hi->lo): [1, 3, 5, 7, 0, 2, 4, 6]
892 : : */
893 : : __m256i status0_7 = _mm256_unpacklo_epi64(status4_7,
894 : : status0_3);
895 : : __m256i mbuf_flags = _mm256_set1_epi32(0);
896 : : __m256i vlan_flags = _mm256_setzero_si256();
897 : :
898 : : if (offload) {
899 : : /* now do flag manipulation */
900 : :
901 : : /* get only flag/error bits we want */
902 : : const __m256i flag_bits =
903 : : _mm256_and_si256(status0_7, flags_mask);
904 : : /**
905 : : * l3_l4_error flags, shuffle, then shift to correct adjustment
906 : : * of flags in flags_shuf, and finally mask out extra bits
907 : : */
908 : : __m256i l3_l4_flags = _mm256_shuffle_epi8(l3_l4_flags_shuf,
909 : : _mm256_srli_epi32(flag_bits, 4));
910 : : l3_l4_flags = _mm256_slli_epi32(l3_l4_flags, 1);
911 : : __m256i l4_outer_mask = _mm256_set1_epi32(0x6);
912 : : __m256i l4_outer_flags =
913 : : _mm256_and_si256(l3_l4_flags, l4_outer_mask);
914 : : l4_outer_flags = _mm256_slli_epi32(l4_outer_flags, 20);
915 : :
916 : : __m256i l3_l4_mask = _mm256_set1_epi32(~0x6);
917 : :
918 : : l3_l4_flags = _mm256_and_si256(l3_l4_flags, l3_l4_mask);
919 : : l3_l4_flags = _mm256_or_si256(l3_l4_flags, l4_outer_flags);
920 : : l3_l4_flags = _mm256_and_si256(l3_l4_flags, cksum_mask);
921 : :
922 : : /* set rss and vlan flags */
923 : : const __m256i rss_vlan_flag_bits =
924 : : _mm256_srli_epi32(flag_bits, 12);
925 : : const __m256i rss_flags =
926 : : _mm256_shuffle_epi8(rss_flags_shuf,
927 : : rss_vlan_flag_bits);
928 : :
929 [ # # # # : 0 : if (rxq->rx_flags == IAVF_RX_FLAGS_VLAN_TAG_LOC_L2TAG1)
# # ]
930 : : vlan_flags =
931 : : _mm256_shuffle_epi8(vlan_flags_shuf,
932 : : rss_vlan_flag_bits);
933 : :
934 : : const __m256i rss_vlan_flags =
935 : : _mm256_or_si256(rss_flags, vlan_flags);
936 : :
937 : : /* merge flags */
938 : : mbuf_flags = _mm256_or_si256(l3_l4_flags,
939 : : rss_vlan_flags);
940 : : }
941 : :
942 [ # # # # : 0 : if (rxq->fdir_enabled) {
# # # # #
# # # ]
943 : : const __m256i fdir_id4_7 =
944 : : _mm256_unpackhi_epi32(raw_desc6_7, raw_desc4_5);
945 : :
946 : : const __m256i fdir_id0_3 =
947 : : _mm256_unpackhi_epi32(raw_desc2_3, raw_desc0_1);
948 : :
949 : : const __m256i fdir_id0_7 =
950 : : _mm256_unpackhi_epi64(fdir_id4_7, fdir_id0_3);
951 : :
952 : : const __m256i fdir_flags =
953 : : flex_rxd_to_fdir_flags_vec_avx2(fdir_id0_7);
954 : :
955 : : /* merge with fdir_flags */
956 : : mbuf_flags = _mm256_or_si256(mbuf_flags, fdir_flags);
957 : :
958 : : /* write to mbuf: have to use scalar store here */
959 : 0 : rx_pkts[i + 0]->hash.fdir.hi =
960 : 0 : _mm256_extract_epi32(fdir_id0_7, 3);
961 : :
962 : 0 : rx_pkts[i + 1]->hash.fdir.hi =
963 : 0 : _mm256_extract_epi32(fdir_id0_7, 7);
964 : :
965 : 0 : rx_pkts[i + 2]->hash.fdir.hi =
966 : 0 : _mm256_extract_epi32(fdir_id0_7, 2);
967 : :
968 : 0 : rx_pkts[i + 3]->hash.fdir.hi =
969 : 0 : _mm256_extract_epi32(fdir_id0_7, 6);
970 : :
971 : 0 : rx_pkts[i + 4]->hash.fdir.hi =
972 : 0 : _mm256_extract_epi32(fdir_id0_7, 1);
973 : :
974 : 0 : rx_pkts[i + 5]->hash.fdir.hi =
975 : 0 : _mm256_extract_epi32(fdir_id0_7, 5);
976 : :
977 : 0 : rx_pkts[i + 6]->hash.fdir.hi =
978 : 0 : _mm256_extract_epi32(fdir_id0_7, 0);
979 : :
980 : 0 : rx_pkts[i + 7]->hash.fdir.hi =
981 : 0 : _mm256_extract_epi32(fdir_id0_7, 4);
982 : : } /* if() on fdir_enabled */
983 : :
984 : : if (offload) {
985 : : #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
986 : : /**
987 : : * needs to load 2nd 16B of each desc,
988 : : * will cause performance drop to get into this context.
989 : : */
990 [ # # # # : 0 : if (offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH ||
# # ]
991 [ # # # # : 0 : offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP ||
# # ]
992 : : rxq->rx_flags & IAVF_RX_FLAGS_VLAN_TAG_LOC_L2TAG2_2) {
993 : : /* load bottom half of every 32B desc */
994 : : const __m128i raw_desc_bh7 =
995 : : _mm_load_si128
996 : : ((void *)(&rxdp[7].wb.status_error1));
997 : 0 : rte_compiler_barrier();
998 : : const __m128i raw_desc_bh6 =
999 : : _mm_load_si128
1000 : : ((void *)(&rxdp[6].wb.status_error1));
1001 : 0 : rte_compiler_barrier();
1002 : : const __m128i raw_desc_bh5 =
1003 : : _mm_load_si128
1004 : : ((void *)(&rxdp[5].wb.status_error1));
1005 : 0 : rte_compiler_barrier();
1006 : : const __m128i raw_desc_bh4 =
1007 : : _mm_load_si128
1008 : : ((void *)(&rxdp[4].wb.status_error1));
1009 : 0 : rte_compiler_barrier();
1010 : : const __m128i raw_desc_bh3 =
1011 : : _mm_load_si128
1012 : : ((void *)(&rxdp[3].wb.status_error1));
1013 : 0 : rte_compiler_barrier();
1014 : : const __m128i raw_desc_bh2 =
1015 : : _mm_load_si128
1016 : : ((void *)(&rxdp[2].wb.status_error1));
1017 : 0 : rte_compiler_barrier();
1018 : : const __m128i raw_desc_bh1 =
1019 : : _mm_load_si128
1020 : : ((void *)(&rxdp[1].wb.status_error1));
1021 : 0 : rte_compiler_barrier();
1022 : : const __m128i raw_desc_bh0 =
1023 : : _mm_load_si128
1024 : : ((void *)(&rxdp[0].wb.status_error1));
1025 : :
1026 : : __m256i raw_desc_bh6_7 =
1027 : : _mm256_inserti128_si256
1028 : : (_mm256_castsi128_si256(raw_desc_bh6),
1029 : : raw_desc_bh7, 1);
1030 : : __m256i raw_desc_bh4_5 =
1031 : : _mm256_inserti128_si256
1032 : : (_mm256_castsi128_si256(raw_desc_bh4),
1033 : : raw_desc_bh5, 1);
1034 : : __m256i raw_desc_bh2_3 =
1035 : : _mm256_inserti128_si256
1036 : : (_mm256_castsi128_si256(raw_desc_bh2),
1037 : : raw_desc_bh3, 1);
1038 : : __m256i raw_desc_bh0_1 =
1039 : : _mm256_inserti128_si256
1040 : : (_mm256_castsi128_si256(raw_desc_bh0),
1041 : : raw_desc_bh1, 1);
1042 : :
1043 [ # # # # : 0 : if (offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH) {
# # ]
1044 : : /**
1045 : : * to shift the 32b RSS hash value to the
1046 : : * highest 32b of each 128b before mask
1047 : : */
1048 : : __m256i rss_hash6_7 =
1049 : : _mm256_slli_epi64(raw_desc_bh6_7, 32);
1050 : : __m256i rss_hash4_5 =
1051 : : _mm256_slli_epi64(raw_desc_bh4_5, 32);
1052 : : __m256i rss_hash2_3 =
1053 : : _mm256_slli_epi64(raw_desc_bh2_3, 32);
1054 : : __m256i rss_hash0_1 =
1055 : : _mm256_slli_epi64(raw_desc_bh0_1, 32);
1056 : :
1057 : : const __m256i rss_hash_msk =
1058 : : _mm256_set_epi32(0xFFFFFFFF, 0, 0, 0,
1059 : : 0xFFFFFFFF, 0, 0, 0);
1060 : :
1061 : : rss_hash6_7 = _mm256_and_si256
1062 : : (rss_hash6_7, rss_hash_msk);
1063 : : rss_hash4_5 = _mm256_and_si256
1064 : : (rss_hash4_5, rss_hash_msk);
1065 : : rss_hash2_3 = _mm256_and_si256
1066 : : (rss_hash2_3, rss_hash_msk);
1067 : : rss_hash0_1 = _mm256_and_si256
1068 : : (rss_hash0_1, rss_hash_msk);
1069 : :
1070 : : mb6_7 = _mm256_or_si256(mb6_7, rss_hash6_7);
1071 : : mb4_5 = _mm256_or_si256(mb4_5, rss_hash4_5);
1072 : : mb2_3 = _mm256_or_si256(mb2_3, rss_hash2_3);
1073 : : mb0_1 = _mm256_or_si256(mb0_1, rss_hash0_1);
1074 : : } /* if() on RSS hash parsing */
1075 : :
1076 [ # # # # : 0 : if (rxq->rx_flags & IAVF_RX_FLAGS_VLAN_TAG_LOC_L2TAG2_2) {
# # ]
1077 : : /* merge the status/error-1 bits into one register */
1078 : : const __m256i status1_4_7 =
1079 : : _mm256_unpacklo_epi32(raw_desc_bh6_7,
1080 : : raw_desc_bh4_5);
1081 : : const __m256i status1_0_3 =
1082 : : _mm256_unpacklo_epi32(raw_desc_bh2_3,
1083 : : raw_desc_bh0_1);
1084 : :
1085 : : const __m256i status1_0_7 =
1086 : : _mm256_unpacklo_epi64(status1_4_7,
1087 : : status1_0_3);
1088 : :
1089 : : const __m256i l2tag2p_flag_mask =
1090 : : _mm256_set1_epi32
1091 : : (1 << IAVF_RX_FLEX_DESC_STATUS1_L2TAG2P_S);
1092 : :
1093 : : __m256i l2tag2p_flag_bits =
1094 : : _mm256_and_si256
1095 : : (status1_0_7, l2tag2p_flag_mask);
1096 : :
1097 : : l2tag2p_flag_bits =
1098 : : _mm256_srli_epi32(l2tag2p_flag_bits,
1099 : : IAVF_RX_FLEX_DESC_STATUS1_L2TAG2P_S);
1100 : :
1101 : : const __m256i l2tag2_flags_shuf =
1102 : : _mm256_set_epi8(0, 0, 0, 0,
1103 : : 0, 0, 0, 0,
1104 : : 0, 0, 0, 0,
1105 : : 0, 0,
1106 : : RTE_MBUF_F_RX_VLAN |
1107 : : RTE_MBUF_F_RX_VLAN_STRIPPED,
1108 : : 0,
1109 : : /* end up 128-bits */
1110 : : 0, 0, 0, 0,
1111 : : 0, 0, 0, 0,
1112 : : 0, 0, 0, 0,
1113 : : 0, 0,
1114 : : RTE_MBUF_F_RX_VLAN |
1115 : : RTE_MBUF_F_RX_VLAN_STRIPPED,
1116 : : 0);
1117 : :
1118 : : vlan_flags =
1119 : : _mm256_shuffle_epi8(l2tag2_flags_shuf,
1120 : : l2tag2p_flag_bits);
1121 : :
1122 : : /* merge with vlan_flags */
1123 : : mbuf_flags = _mm256_or_si256
1124 : : (mbuf_flags, vlan_flags);
1125 : :
1126 : : /* L2TAG2_2 */
1127 : : __m256i vlan_tci6_7 =
1128 : : _mm256_slli_si256(raw_desc_bh6_7, 4);
1129 : : __m256i vlan_tci4_5 =
1130 : : _mm256_slli_si256(raw_desc_bh4_5, 4);
1131 : : __m256i vlan_tci2_3 =
1132 : : _mm256_slli_si256(raw_desc_bh2_3, 4);
1133 : : __m256i vlan_tci0_1 =
1134 : : _mm256_slli_si256(raw_desc_bh0_1, 4);
1135 : :
1136 : : const __m256i vlan_tci_msk =
1137 : : _mm256_set_epi32(0, 0xFFFF0000, 0, 0,
1138 : : 0, 0xFFFF0000, 0, 0);
1139 : :
1140 : : vlan_tci6_7 = _mm256_and_si256
1141 : : (vlan_tci6_7, vlan_tci_msk);
1142 : : vlan_tci4_5 = _mm256_and_si256
1143 : : (vlan_tci4_5, vlan_tci_msk);
1144 : : vlan_tci2_3 = _mm256_and_si256
1145 : : (vlan_tci2_3, vlan_tci_msk);
1146 : : vlan_tci0_1 = _mm256_and_si256
1147 : : (vlan_tci0_1, vlan_tci_msk);
1148 : :
1149 : : mb6_7 = _mm256_or_si256(mb6_7, vlan_tci6_7);
1150 : : mb4_5 = _mm256_or_si256(mb4_5, vlan_tci4_5);
1151 : : mb2_3 = _mm256_or_si256(mb2_3, vlan_tci2_3);
1152 : : mb0_1 = _mm256_or_si256(mb0_1, vlan_tci0_1);
1153 : : } /* if() on Vlan parsing */
1154 : :
1155 [ # # # # : 0 : if (offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) {
# # ]
1156 : : uint32_t mask = 0xFFFFFFFF;
1157 : : __m256i ts;
1158 : : __m256i ts_low = _mm256_setzero_si256();
1159 : : __m256i ts_low1;
1160 : : __m256i ts_low2;
1161 : : __m256i max_ret;
1162 : : __m256i cmp_ret;
1163 : : uint8_t ret = 0;
1164 : : uint8_t shift = 8;
1165 : : __m256i ts_desp_mask = _mm256_set_epi32(mask, 0, 0, 0, mask, 0, 0, 0);
1166 : : __m256i cmp_mask = _mm256_set1_epi32(mask);
1167 : : __m256i ts_permute_mask = _mm256_set_epi32(7, 3, 6, 2, 5, 1, 4, 0);
1168 : :
1169 : : ts = _mm256_and_si256(raw_desc_bh0_1, ts_desp_mask);
1170 : : ts_low = _mm256_or_si256(ts_low, _mm256_srli_si256(ts, 3 * 4));
1171 : : ts = _mm256_and_si256(raw_desc_bh2_3, ts_desp_mask);
1172 : : ts_low = _mm256_or_si256(ts_low, _mm256_srli_si256(ts, 2 * 4));
1173 : : ts = _mm256_and_si256(raw_desc_bh4_5, ts_desp_mask);
1174 : : ts_low = _mm256_or_si256(ts_low, _mm256_srli_si256(ts, 4));
1175 : : ts = _mm256_and_si256(raw_desc_bh6_7, ts_desp_mask);
1176 : : ts_low = _mm256_or_si256(ts_low, ts);
1177 : :
1178 : : ts_low1 = _mm256_permutevar8x32_epi32(ts_low, ts_permute_mask);
1179 : : ts_low2 = _mm256_permutevar8x32_epi32(ts_low1,
1180 : : _mm256_set_epi32(6, 5, 4, 3, 2, 1, 0, 7));
1181 : : ts_low2 = _mm256_and_si256(ts_low2,
1182 : : _mm256_set_epi32(mask, mask, mask, mask, mask, mask, mask, 0));
1183 : : ts_low2 = _mm256_or_si256(ts_low2, hw_low_last);
1184 : : hw_low_last = _mm256_and_si256(ts_low1,
1185 : : _mm256_set_epi32(0, 0, 0, 0, 0, 0, 0, mask));
1186 : :
1187 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 0],
1188 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 0);
1189 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 1],
1190 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 1);
1191 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 2],
1192 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 2);
1193 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 3],
1194 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 3);
1195 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 4],
1196 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 4);
1197 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 5],
1198 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 5);
1199 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 6],
1200 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 6);
1201 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 7],
1202 : 0 : iavf_timestamp_dynfield_offset, uint32_t *) = _mm256_extract_epi32(ts_low1, 7);
1203 : :
1204 [ # # # # : 0 : if (unlikely(is_tsinit)) {
# # ]
1205 : : uint32_t in_timestamp;
1206 [ # # # # : 0 : if (iavf_get_phc_time(rxq))
# # ]
1207 : 0 : PMD_DRV_LOG(ERR, "get physical time failed");
1208 : 0 : in_timestamp = *RTE_MBUF_DYNFIELD(rx_pkts[i + 0],
1209 : : iavf_timestamp_dynfield_offset, uint32_t *);
1210 [ # # # # : 0 : rxq->phc_time = iavf_tstamp_convert_32b_64b(rxq->phc_time, in_timestamp);
# # ]
1211 : : }
1212 : :
1213 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 0],
1214 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1215 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 1],
1216 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1217 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 2],
1218 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1219 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 3],
1220 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1221 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 4],
1222 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1223 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 5],
1224 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1225 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 6],
1226 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
1227 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 7],
1228 [ # # # # : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) = (uint32_t)(rxq->phc_time >> 32);
# # ]
1229 : :
1230 : : max_ret = _mm256_max_epu32(ts_low2, ts_low1);
1231 : : cmp_ret = _mm256_andnot_si256(_mm256_cmpeq_epi32(max_ret, ts_low1), cmp_mask);
1232 : :
1233 [ # # # # : 0 : if (_mm256_testz_si256(cmp_ret, cmp_mask)) {
# # ]
1234 : : inflection_point = 0;
1235 : : } else {
1236 : : inflection_point = 1;
1237 [ # # # # : 0 : while (shift > 1) {
# # ]
1238 : 0 : shift = shift >> 1;
1239 : : __m256i mask_low = _mm256_setzero_si256();
1240 : : __m256i mask_high = _mm256_setzero_si256();
1241 [ # # # # : 0 : switch (shift) {
# # # # #
# # # ]
1242 : 0 : case 4:
1243 : : mask_low = _mm256_set_epi32(0, 0, 0, 0, mask, mask, mask, mask);
1244 : : mask_high = _mm256_set_epi32(mask, mask, mask, mask, 0, 0, 0, 0);
1245 : 0 : break;
1246 : : case 2:
1247 : : mask_low = _mm256_srli_si256(cmp_mask, 2 * 4);
1248 : : mask_high = _mm256_slli_si256(cmp_mask, 2 * 4);
1249 : 0 : break;
1250 : : case 1:
1251 : : mask_low = _mm256_srli_si256(cmp_mask, 1 * 4);
1252 : : mask_high = _mm256_slli_si256(cmp_mask, 1 * 4);
1253 : 0 : break;
1254 : : }
1255 : 0 : ret = _mm256_testz_si256(cmp_ret, mask_low);
1256 [ # # # # : 0 : if (ret) {
# # ]
1257 : 0 : ret = _mm256_testz_si256(cmp_ret, mask_high);
1258 [ # # # # : 0 : inflection_point += ret ? 0 : shift;
# # ]
1259 : : cmp_mask = mask_high;
1260 : : } else {
1261 : : cmp_mask = mask_low;
1262 : : }
1263 : : }
1264 : : }
1265 : 0 : mbuf_flags = _mm256_or_si256(mbuf_flags, _mm256_set1_epi32(iavf_timestamp_dynflag));
1266 : : } /* if() on Timestamp parsing */
1267 : : }
1268 : : #endif
1269 : : }
1270 : :
1271 : : /**
1272 : : * At this point, we have the 8 sets of flags in the low 16-bits
1273 : : * of each 32-bit value in vlan0.
1274 : : * We want to extract these, and merge them with the mbuf init
1275 : : * data so we can do a single write to the mbuf to set the flags
1276 : : * and all the other initialization fields. Extracting the
1277 : : * appropriate flags means that we have to do a shift and blend
1278 : : * for each mbuf before we do the write. However, we can also
1279 : : * add in the previously computed rx_descriptor fields to
1280 : : * make a single 256-bit write per mbuf
1281 : : */
1282 : : /* check the structure matches expectations */
1283 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=
1284 : : offsetof(struct rte_mbuf, rearm_data) + 8);
1285 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, rearm_data) !=
1286 : : RTE_ALIGN(offsetof(struct rte_mbuf,
1287 : : rearm_data),
1288 : : 16));
1289 : : /* build up data and do writes */
1290 : : __m256i rearm0, rearm1, rearm2, rearm3, rearm4, rearm5,
1291 : : rearm6, rearm7;
1292 : : rearm6 = _mm256_blend_epi32(mbuf_init,
1293 : : _mm256_slli_si256(mbuf_flags, 8),
1294 : : 0x04);
1295 : : rearm4 = _mm256_blend_epi32(mbuf_init,
1296 : : _mm256_slli_si256(mbuf_flags, 4),
1297 : : 0x04);
1298 : : rearm2 = _mm256_blend_epi32(mbuf_init, mbuf_flags, 0x04);
1299 : : rearm0 = _mm256_blend_epi32(mbuf_init,
1300 : : _mm256_srli_si256(mbuf_flags, 4),
1301 : : 0x04);
1302 : : /* permute to add in the rx_descriptor e.g. rss fields */
1303 : : rearm6 = _mm256_permute2f128_si256(rearm6, mb6_7, 0x20);
1304 : : rearm4 = _mm256_permute2f128_si256(rearm4, mb4_5, 0x20);
1305 : : rearm2 = _mm256_permute2f128_si256(rearm2, mb2_3, 0x20);
1306 : : rearm0 = _mm256_permute2f128_si256(rearm0, mb0_1, 0x20);
1307 : : /* write to mbuf */
1308 [ # # # # : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 6]->rearm_data,
# # # # #
# # # ]
1309 : : rearm6);
1310 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 4]->rearm_data,
1311 : : rearm4);
1312 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 2]->rearm_data,
1313 : : rearm2);
1314 [ # # # # : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 0]->rearm_data,
# # # # #
# # # ]
1315 : : rearm0);
1316 : :
1317 : : /* repeat for the odd mbufs */
1318 : : const __m256i odd_flags =
1319 : : _mm256_castsi128_si256
1320 : : (_mm256_extracti128_si256(mbuf_flags, 1));
1321 : : rearm7 = _mm256_blend_epi32(mbuf_init,
1322 : : _mm256_slli_si256(odd_flags, 8),
1323 : : 0x04);
1324 : : rearm5 = _mm256_blend_epi32(mbuf_init,
1325 : : _mm256_slli_si256(odd_flags, 4),
1326 : : 0x04);
1327 : : rearm3 = _mm256_blend_epi32(mbuf_init, odd_flags, 0x04);
1328 : : rearm1 = _mm256_blend_epi32(mbuf_init,
1329 : : _mm256_srli_si256(odd_flags, 4),
1330 : : 0x04);
1331 : : /* since odd mbufs are already in hi 128-bits use blend */
1332 : : rearm7 = _mm256_blend_epi32(rearm7, mb6_7, 0xF0);
1333 : : rearm5 = _mm256_blend_epi32(rearm5, mb4_5, 0xF0);
1334 : : rearm3 = _mm256_blend_epi32(rearm3, mb2_3, 0xF0);
1335 : : rearm1 = _mm256_blend_epi32(rearm1, mb0_1, 0xF0);
1336 : : /* again write to mbufs */
1337 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 7]->rearm_data,
1338 : : rearm7);
1339 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 5]->rearm_data,
1340 : : rearm5);
1341 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 3]->rearm_data,
1342 : : rearm3);
1343 [ # # # # ]: 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 1]->rearm_data,
1344 : : rearm1);
1345 : :
1346 : : /* extract and record EOP bit */
1347 [ # # # # : 0 : if (split_packet) {
# # # # ]
1348 : : const __m128i eop_mask =
1349 : : _mm_set1_epi16(1 <<
1350 : : IAVF_RX_FLEX_DESC_STATUS0_EOF_S);
1351 : : const __m256i eop_bits256 = _mm256_and_si256(status0_7,
1352 : : eop_check);
1353 : : /* pack status bits into a single 128-bit register */
1354 : : const __m128i eop_bits =
1355 : : _mm_packus_epi32
1356 : : (_mm256_castsi256_si128(eop_bits256),
1357 : : _mm256_extractf128_si256(eop_bits256,
1358 : : 1));
1359 : : /**
1360 : : * flip bits, and mask out the EOP bit, which is now
1361 : : * a split-packet bit i.e. !EOP, rather than EOP one.
1362 : : */
1363 : : __m128i split_bits = _mm_andnot_si128(eop_bits,
1364 : : eop_mask);
1365 : : /**
1366 : : * eop bits are out of order, so we need to shuffle them
1367 : : * back into order again. In doing so, only use low 8
1368 : : * bits, which acts like another pack instruction
1369 : : * The original order is (hi->lo): 1,3,5,7,0,2,4,6
1370 : : * [Since we use epi8, the 16-bit positions are
1371 : : * multiplied by 2 in the eop_shuffle value.]
1372 : : */
1373 : : __m128i eop_shuffle =
1374 : : _mm_set_epi8(/* zero hi 64b */
1375 : : 0xFF, 0xFF, 0xFF, 0xFF,
1376 : : 0xFF, 0xFF, 0xFF, 0xFF,
1377 : : /* move values to lo 64b */
1378 : : 8, 0, 10, 2,
1379 : : 12, 4, 14, 6);
1380 : : split_bits = _mm_shuffle_epi8(split_bits, eop_shuffle);
1381 : 0 : *(uint64_t *)split_packet =
1382 : 0 : _mm_cvtsi128_si64(split_bits);
1383 : 0 : split_packet += IAVF_DESCS_PER_LOOP_AVX;
1384 : : }
1385 : :
1386 : : /* perform dd_check */
1387 : : status0_7 = _mm256_and_si256(status0_7, dd_check);
1388 : : status0_7 = _mm256_packs_epi32(status0_7,
1389 : : _mm256_setzero_si256());
1390 : :
1391 [ # # # # : 0 : uint64_t burst = rte_popcount64
# # # # #
# # # ]
1392 : : (_mm_cvtsi128_si64
1393 : : (_mm256_extracti128_si256
1394 : : (status0_7, 1)));
1395 : 0 : burst += rte_popcount64
1396 : : (_mm_cvtsi128_si64
1397 : : (_mm256_castsi256_si128(status0_7)));
1398 : 0 : received += burst;
1399 : : #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
1400 [ # # # # : 0 : if (rxq->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP) {
# # # # #
# # # ]
1401 [ # # # # : 0 : inflection_point = (inflection_point <= burst) ? inflection_point : 0;
# # ]
1402 [ # # # # : 0 : switch (inflection_point) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
1403 : 0 : case 1:
1404 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 0],
1405 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1406 : : /* fallthrough */
1407 : 0 : case 2:
1408 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 1],
1409 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1410 : : /* fallthrough */
1411 : 0 : case 3:
1412 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 2],
1413 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1414 : : /* fallthrough */
1415 : 0 : case 4:
1416 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 3],
1417 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1418 : : /* fallthrough */
1419 : 0 : case 5:
1420 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 4],
1421 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1422 : : /* fallthrough */
1423 : 0 : case 6:
1424 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 5],
1425 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1426 : : /* fallthrough */
1427 : 0 : case 7:
1428 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 6],
1429 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1430 : : /* fallthrough */
1431 : 0 : case 8:
1432 : 0 : *RTE_MBUF_DYNFIELD(rx_pkts[i + 7],
1433 : 0 : iavf_timestamp_dynfield_offset + 4, uint32_t *) += 1;
1434 : 0 : rxq->phc_time += (uint64_t)1 << 32;
1435 : : /* fallthrough */
1436 : : case 0:
1437 : : break;
1438 : 0 : default:
1439 : 0 : PMD_DRV_LOG(ERR, "invalid inflection point for rx timestamp");
1440 : 0 : break;
1441 : : }
1442 : :
1443 : 0 : rxq->hw_time_update = rte_get_timer_cycles() / (rte_get_timer_hz() / 1000);
1444 : : }
1445 : : #endif
1446 [ # # # # : 0 : if (burst != IAVF_DESCS_PER_LOOP_AVX)
# # # # #
# # # ]
1447 : : break;
1448 : : }
1449 : :
1450 : : #ifndef RTE_LIBRTE_IAVF_16BYTE_RX_DESC
1451 [ # # # # : 0 : if (received > 0 && (rxq->offloads & RTE_ETH_RX_OFFLOAD_TIMESTAMP))
# # # # #
# # # # #
# # # # #
# # # #
# ]
1452 : 0 : rxq->phc_time = *RTE_MBUF_DYNFIELD(rx_pkts[received - 1], iavf_timestamp_dynfield_offset, rte_mbuf_timestamp_t *);
1453 : : #endif
1454 : :
1455 : : /* update tail pointers */
1456 : 0 : rxq->rx_tail += received;
1457 : 0 : rxq->rx_tail &= (rxq->nb_rx_desc - 1);
1458 [ # # # # : 0 : if ((rxq->rx_tail & 1) == 1 && received > 1) { /* keep avx2 aligned */
# # # # #
# # # # #
# # # # #
# # # #
# ]
1459 : 0 : rxq->rx_tail--;
1460 : 0 : received--;
1461 : : }
1462 : 0 : rxq->rxrearm_nb += received;
1463 : 0 : return received;
1464 : : }
1465 : :
1466 : : /**
1467 : : * Notice:
1468 : : * - nb_pkts < IAVF_DESCS_PER_LOOP, just return no packet
1469 : : */
1470 : : uint16_t
1471 : 0 : iavf_recv_pkts_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts,
1472 : : uint16_t nb_pkts)
1473 : : {
1474 : 0 : return _iavf_recv_raw_pkts_vec_avx2(rx_queue, rx_pkts, nb_pkts,
1475 : : NULL, false);
1476 : : }
1477 : :
1478 : : uint16_t
1479 : 0 : iavf_recv_pkts_vec_avx2_offload(void *rx_queue, struct rte_mbuf **rx_pkts,
1480 : : uint16_t nb_pkts)
1481 : : {
1482 : 0 : return _iavf_recv_raw_pkts_vec_avx2(rx_queue, rx_pkts, nb_pkts,
1483 : : NULL, true);
1484 : : }
1485 : :
1486 : : /**
1487 : : * Notice:
1488 : : * - nb_pkts < IAVF_DESCS_PER_LOOP, just return no packet
1489 : : */
1490 : : uint16_t
1491 : 0 : iavf_recv_pkts_vec_avx2_flex_rxd(void *rx_queue, struct rte_mbuf **rx_pkts,
1492 : : uint16_t nb_pkts)
1493 : : {
1494 : 0 : return _iavf_recv_raw_pkts_vec_avx2_flex_rxd(rx_queue, rx_pkts,
1495 : : nb_pkts, NULL, false);
1496 : : }
1497 : :
1498 : : uint16_t
1499 : 0 : iavf_recv_pkts_vec_avx2_flex_rxd_offload(void *rx_queue, struct rte_mbuf **rx_pkts,
1500 : : uint16_t nb_pkts)
1501 : : {
1502 : 0 : return _iavf_recv_raw_pkts_vec_avx2_flex_rxd(rx_queue, rx_pkts,
1503 : : nb_pkts, NULL, true);
1504 : : }
1505 : :
1506 : : /**
1507 : : * vPMD receive routine that reassembles single burst of 32 scattered packets
1508 : : * Notice:
1509 : : * - nb_pkts < IAVF_DESCS_PER_LOOP, just return no packet
1510 : : */
1511 : : static __rte_always_inline uint16_t
1512 : : iavf_recv_scattered_burst_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts,
1513 : : uint16_t nb_pkts, bool offload)
1514 : : {
1515 : : struct iavf_rx_queue *rxq = rx_queue;
1516 : 0 : uint8_t split_flags[IAVF_VPMD_RX_MAX_BURST] = {0};
1517 : :
1518 : : /* get some new buffers */
1519 : : uint16_t nb_bufs = _iavf_recv_raw_pkts_vec_avx2(rxq, rx_pkts, nb_pkts,
1520 : : split_flags, offload);
1521 [ # # # # : 0 : if (nb_bufs == 0)
# # # # ]
1522 : : return 0;
1523 : :
1524 : : /* happy day case, full burst + no packets to be joined */
1525 : : const uint64_t *split_fl64 = (uint64_t *)split_flags;
1526 : :
1527 [ # # # # : 0 : if (!rxq->pkt_first_seg &&
# # # # ]
1528 [ # # # # : 0 : split_fl64[0] == 0 && split_fl64[1] == 0 &&
# # # # #
# # # # #
# # ]
1529 [ # # # # : 0 : split_fl64[2] == 0 && split_fl64[3] == 0)
# # # # #
# # # # #
# # ]
1530 : : return nb_bufs;
1531 : :
1532 : : /* reassemble any packets that need reassembly*/
1533 : : unsigned int i = 0;
1534 : :
1535 [ # # # # : 0 : if (!rxq->pkt_first_seg) {
# # # # ]
1536 : : /* find the first split flag, and only reassemble then*/
1537 [ # # # # : 0 : while (i < nb_bufs && !split_flags[i])
# # # # #
# # # # #
# # ]
1538 : 0 : i++;
1539 [ # # # # : 0 : if (i == nb_bufs)
# # # # ]
1540 : : return nb_bufs;
1541 : 0 : rxq->pkt_first_seg = rx_pkts[i];
1542 : : }
1543 : 0 : return i + reassemble_packets(rxq, &rx_pkts[i], nb_bufs - i,
1544 : : &split_flags[i]);
1545 : : }
1546 : :
1547 : : /**
1548 : : * vPMD receive routine that reassembles scattered packets.
1549 : : * Main receive routine that can handle arbitrary burst sizes
1550 : : * Notice:
1551 : : * - nb_pkts < IAVF_DESCS_PER_LOOP, just return no packet
1552 : : */
1553 : : static __rte_always_inline uint16_t
1554 : : iavf_recv_scattered_pkts_vec_avx2_common(void *rx_queue, struct rte_mbuf **rx_pkts,
1555 : : uint16_t nb_pkts, bool offload)
1556 : : {
1557 : : uint16_t retval = 0;
1558 : :
1559 [ # # # # ]: 0 : while (nb_pkts > IAVF_VPMD_RX_MAX_BURST) {
1560 : 0 : uint16_t burst = iavf_recv_scattered_burst_vec_avx2(rx_queue,
1561 : 0 : rx_pkts + retval, IAVF_VPMD_RX_MAX_BURST, offload);
1562 : 0 : retval += burst;
1563 : 0 : nb_pkts -= burst;
1564 [ # # # # ]: 0 : if (burst < IAVF_VPMD_RX_MAX_BURST)
1565 : : return retval;
1566 : : }
1567 : 0 : return retval + iavf_recv_scattered_burst_vec_avx2(rx_queue,
1568 : 0 : rx_pkts + retval, nb_pkts, offload);
1569 : : }
1570 : :
1571 : : uint16_t
1572 : 0 : iavf_recv_scattered_pkts_vec_avx2(void *rx_queue,
1573 : : struct rte_mbuf **rx_pkts,
1574 : : uint16_t nb_pkts)
1575 : : {
1576 : 0 : return iavf_recv_scattered_pkts_vec_avx2_common(rx_queue,
1577 : : rx_pkts,
1578 : : nb_pkts,
1579 : : false);
1580 : : }
1581 : :
1582 : : uint16_t
1583 : 0 : iavf_recv_scattered_pkts_vec_avx2_offload(void *rx_queue,
1584 : : struct rte_mbuf **rx_pkts,
1585 : : uint16_t nb_pkts)
1586 : : {
1587 : 0 : return iavf_recv_scattered_pkts_vec_avx2_common(rx_queue,
1588 : : rx_pkts,
1589 : : nb_pkts,
1590 : : true);
1591 : : }
1592 : :
1593 : : /**
1594 : : * vPMD receive routine that reassembles single burst of
1595 : : * 32 scattered packets for flex RxD
1596 : : * Notice:
1597 : : * - nb_pkts < IAVF_DESCS_PER_LOOP, just return no packet
1598 : : */
1599 : : static __rte_always_inline uint16_t
1600 : : iavf_recv_scattered_burst_vec_avx2_flex_rxd(void *rx_queue,
1601 : : struct rte_mbuf **rx_pkts,
1602 : : uint16_t nb_pkts, bool offload)
1603 : : {
1604 : : struct iavf_rx_queue *rxq = rx_queue;
1605 : 0 : uint8_t split_flags[IAVF_VPMD_RX_MAX_BURST] = {0};
1606 : :
1607 : : /* get some new buffers */
1608 : : uint16_t nb_bufs = _iavf_recv_raw_pkts_vec_avx2_flex_rxd(rxq,
1609 : : rx_pkts, nb_pkts, split_flags, offload);
1610 [ # # # # : 0 : if (nb_bufs == 0)
# # # # ]
1611 : : return 0;
1612 : :
1613 : : /* happy day case, full burst + no packets to be joined */
1614 : : const uint64_t *split_fl64 = (uint64_t *)split_flags;
1615 : :
1616 [ # # # # : 0 : if (!rxq->pkt_first_seg &&
# # # # ]
1617 [ # # # # : 0 : split_fl64[0] == 0 && split_fl64[1] == 0 &&
# # # # #
# # # # #
# # ]
1618 [ # # # # : 0 : split_fl64[2] == 0 && split_fl64[3] == 0)
# # # # #
# # # # #
# # ]
1619 : : return nb_bufs;
1620 : :
1621 : : /* reassemble any packets that need reassembly*/
1622 : : unsigned int i = 0;
1623 : :
1624 [ # # # # : 0 : if (!rxq->pkt_first_seg) {
# # # # ]
1625 : : /* find the first split flag, and only reassemble then*/
1626 [ # # # # : 0 : while (i < nb_bufs && !split_flags[i])
# # # # #
# # # # #
# # ]
1627 : 0 : i++;
1628 [ # # # # : 0 : if (i == nb_bufs)
# # # # ]
1629 : : return nb_bufs;
1630 : 0 : rxq->pkt_first_seg = rx_pkts[i];
1631 : : }
1632 : 0 : return i + reassemble_packets(rxq, &rx_pkts[i], nb_bufs - i,
1633 : : &split_flags[i]);
1634 : : }
1635 : :
1636 : : /**
1637 : : * vPMD receive routine that reassembles scattered packets for flex RxD.
1638 : : * Main receive routine that can handle arbitrary burst sizes
1639 : : * Notice:
1640 : : * - nb_pkts < IAVF_DESCS_PER_LOOP, just return no packet
1641 : : */
1642 : : static __rte_always_inline uint16_t
1643 : : iavf_recv_scattered_pkts_vec_avx2_flex_rxd_common(void *rx_queue,
1644 : : struct rte_mbuf **rx_pkts,
1645 : : uint16_t nb_pkts, bool offload)
1646 : : {
1647 : : uint16_t retval = 0;
1648 : :
1649 [ # # # # ]: 0 : while (nb_pkts > IAVF_VPMD_RX_MAX_BURST) {
1650 : : uint16_t burst =
1651 : 0 : iavf_recv_scattered_burst_vec_avx2_flex_rxd
1652 : 0 : (rx_queue, rx_pkts + retval, IAVF_VPMD_RX_MAX_BURST,
1653 : : offload);
1654 : 0 : retval += burst;
1655 : 0 : nb_pkts -= burst;
1656 [ # # # # ]: 0 : if (burst < IAVF_VPMD_RX_MAX_BURST)
1657 : : return retval;
1658 : : }
1659 : 0 : return retval + iavf_recv_scattered_burst_vec_avx2_flex_rxd(rx_queue,
1660 : 0 : rx_pkts + retval, nb_pkts, offload);
1661 : : }
1662 : :
1663 : : uint16_t
1664 : 0 : iavf_recv_scattered_pkts_vec_avx2_flex_rxd(void *rx_queue,
1665 : : struct rte_mbuf **rx_pkts,
1666 : : uint16_t nb_pkts)
1667 : : {
1668 : 0 : return iavf_recv_scattered_pkts_vec_avx2_flex_rxd_common(rx_queue,
1669 : : rx_pkts,
1670 : : nb_pkts,
1671 : : false);
1672 : : }
1673 : :
1674 : : uint16_t
1675 : 0 : iavf_recv_scattered_pkts_vec_avx2_flex_rxd_offload(void *rx_queue,
1676 : : struct rte_mbuf **rx_pkts,
1677 : : uint16_t nb_pkts)
1678 : : {
1679 : 0 : return iavf_recv_scattered_pkts_vec_avx2_flex_rxd_common(rx_queue,
1680 : : rx_pkts,
1681 : : nb_pkts,
1682 : : true);
1683 : : }
1684 : :
1685 : :
1686 : : static __rte_always_inline void
1687 : : iavf_vtx1(volatile struct iavf_tx_desc *txdp,
1688 : : struct rte_mbuf *pkt, uint64_t flags, bool offload)
1689 : : {
1690 : : uint64_t high_qw =
1691 : : (IAVF_TX_DESC_DTYPE_DATA |
1692 : 0 : ((uint64_t)flags << IAVF_TXD_QW1_CMD_SHIFT) |
1693 : 0 : ((uint64_t)pkt->data_len << IAVF_TXD_QW1_TX_BUF_SZ_SHIFT));
1694 : : if (offload)
1695 : : iavf_txd_enable_offload(pkt, &high_qw);
1696 : :
1697 : 0 : __m128i descriptor = _mm_set_epi64x(high_qw,
1698 : 0 : pkt->buf_iova + pkt->data_off);
1699 : : _mm_store_si128((__m128i *)txdp, descriptor);
1700 : : }
1701 : :
1702 : : static __rte_always_inline void
1703 : : iavf_vtx(volatile struct iavf_tx_desc *txdp,
1704 : : struct rte_mbuf **pkt, uint16_t nb_pkts, uint64_t flags, bool offload)
1705 : : {
1706 : : const uint64_t hi_qw_tmpl = (IAVF_TX_DESC_DTYPE_DATA |
1707 : : ((uint64_t)flags << IAVF_TXD_QW1_CMD_SHIFT));
1708 : :
1709 : : /* if unaligned on 32-bit boundary, do one to align */
1710 [ # # # # : 0 : if (((uintptr_t)txdp & 0x1F) != 0 && nb_pkts != 0) {
# # # # #
# # # ]
1711 [ # # # # ]: 0 : iavf_vtx1(txdp, *pkt, flags, offload);
1712 : 0 : nb_pkts--, txdp++, pkt++;
1713 : : }
1714 : :
1715 : : /* do two at a time while possible, in bursts */
1716 [ # # # # : 0 : for (; nb_pkts > 3; txdp += 4, pkt += 4, nb_pkts -= 4) {
# # # # ]
1717 : : uint64_t hi_qw3 =
1718 : 0 : hi_qw_tmpl |
1719 [ # # # # ]: 0 : ((uint64_t)pkt[3]->data_len <<
1720 : : IAVF_TXD_QW1_TX_BUF_SZ_SHIFT);
1721 : : if (offload)
1722 : : iavf_txd_enable_offload(pkt[3], &hi_qw3);
1723 : : uint64_t hi_qw2 =
1724 : 0 : hi_qw_tmpl |
1725 [ # # # # ]: 0 : ((uint64_t)pkt[2]->data_len <<
1726 : : IAVF_TXD_QW1_TX_BUF_SZ_SHIFT);
1727 : : if (offload)
1728 : : iavf_txd_enable_offload(pkt[2], &hi_qw2);
1729 : : uint64_t hi_qw1 =
1730 : 0 : hi_qw_tmpl |
1731 [ # # # # ]: 0 : ((uint64_t)pkt[1]->data_len <<
1732 : : IAVF_TXD_QW1_TX_BUF_SZ_SHIFT);
1733 : : if (offload)
1734 : : iavf_txd_enable_offload(pkt[1], &hi_qw1);
1735 : : uint64_t hi_qw0 =
1736 : 0 : hi_qw_tmpl |
1737 [ # # # # ]: 0 : ((uint64_t)pkt[0]->data_len <<
1738 : : IAVF_TXD_QW1_TX_BUF_SZ_SHIFT);
1739 : : if (offload)
1740 : : iavf_txd_enable_offload(pkt[0], &hi_qw0);
1741 : :
1742 : : __m256i desc2_3 =
1743 : 0 : _mm256_set_epi64x
1744 : : (hi_qw3,
1745 : 0 : pkt[3]->buf_iova + pkt[3]->data_off,
1746 : : hi_qw2,
1747 : 0 : pkt[2]->buf_iova + pkt[2]->data_off);
1748 : : __m256i desc0_1 =
1749 : 0 : _mm256_set_epi64x
1750 : : (hi_qw1,
1751 : 0 : pkt[1]->buf_iova + pkt[1]->data_off,
1752 : : hi_qw0,
1753 : 0 : pkt[0]->buf_iova + pkt[0]->data_off);
1754 : : _mm256_store_si256((void *)(txdp + 2), desc2_3);
1755 : : _mm256_store_si256((void *)txdp, desc0_1);
1756 : : }
1757 : :
1758 : : /* do any last ones */
1759 [ # # # # : 0 : while (nb_pkts) {
# # # # ]
1760 [ # # # # ]: 0 : iavf_vtx1(txdp, *pkt, flags, offload);
1761 : 0 : txdp++, pkt++, nb_pkts--;
1762 : : }
1763 : : }
1764 : :
1765 : : static __rte_always_inline uint16_t
1766 : : iavf_xmit_fixed_burst_vec_avx2(void *tx_queue, struct rte_mbuf **tx_pkts,
1767 : : uint16_t nb_pkts, bool offload)
1768 : : {
1769 : : struct iavf_tx_queue *txq = (struct iavf_tx_queue *)tx_queue;
1770 : : volatile struct iavf_tx_desc *txdp;
1771 : : struct iavf_tx_entry *txep;
1772 : : uint16_t n, nb_commit, tx_id;
1773 : : /* bit2 is reserved and must be set to 1 according to Spec */
1774 : : uint64_t flags = IAVF_TX_DESC_CMD_EOP | IAVF_TX_DESC_CMD_ICRC;
1775 : : uint64_t rs = IAVF_TX_DESC_CMD_RS | flags;
1776 : :
1777 : 0 : if (txq->nb_free < txq->free_thresh)
1778 : : iavf_tx_free_bufs(txq);
1779 : :
1780 : 0 : nb_commit = nb_pkts = (uint16_t)RTE_MIN(txq->nb_free, nb_pkts);
1781 [ # # # # ]: 0 : if (unlikely(nb_pkts == 0))
1782 : : return 0;
1783 : :
1784 : 0 : tx_id = txq->tx_tail;
1785 : 0 : txdp = &txq->tx_ring[tx_id];
1786 : 0 : txep = &txq->sw_ring[tx_id];
1787 : :
1788 : 0 : txq->nb_free = (uint16_t)(txq->nb_free - nb_pkts);
1789 : :
1790 : 0 : n = (uint16_t)(txq->nb_tx_desc - tx_id);
1791 [ # # # # ]: 0 : if (nb_commit >= n) {
1792 : 0 : tx_backlog_entry(txep, tx_pkts, n);
1793 : :
1794 [ # # # # ]: 0 : iavf_vtx(txdp, tx_pkts, n - 1, flags, offload);
1795 : 0 : tx_pkts += (n - 1);
1796 : 0 : txdp += (n - 1);
1797 : :
1798 [ # # ]: 0 : iavf_vtx1(txdp, *tx_pkts++, rs, offload);
1799 : :
1800 : 0 : nb_commit = (uint16_t)(nb_commit - n);
1801 : :
1802 : : tx_id = 0;
1803 : 0 : txq->next_rs = (uint16_t)(txq->rs_thresh - 1);
1804 : :
1805 : : /* avoid reach the end of ring */
1806 : 0 : txdp = &txq->tx_ring[tx_id];
1807 : 0 : txep = &txq->sw_ring[tx_id];
1808 : : }
1809 : :
1810 : 0 : tx_backlog_entry(txep, tx_pkts, nb_commit);
1811 : :
1812 : : iavf_vtx(txdp, tx_pkts, nb_commit, flags, offload);
1813 : :
1814 : 0 : tx_id = (uint16_t)(tx_id + nb_commit);
1815 [ # # # # ]: 0 : if (tx_id > txq->next_rs) {
1816 : 0 : txq->tx_ring[txq->next_rs].cmd_type_offset_bsz |=
1817 : : rte_cpu_to_le_64(((uint64_t)IAVF_TX_DESC_CMD_RS) <<
1818 : : IAVF_TXD_QW1_CMD_SHIFT);
1819 : 0 : txq->next_rs =
1820 : 0 : (uint16_t)(txq->next_rs + txq->rs_thresh);
1821 : : }
1822 : :
1823 : 0 : txq->tx_tail = tx_id;
1824 : :
1825 : 0 : IAVF_PCI_REG_WC_WRITE(txq->qtx_tail, txq->tx_tail);
1826 : :
1827 : : return nb_pkts;
1828 : : }
1829 : :
1830 : : static __rte_always_inline uint16_t
1831 : : iavf_xmit_pkts_vec_avx2_common(void *tx_queue, struct rte_mbuf **tx_pkts,
1832 : : uint16_t nb_pkts, bool offload)
1833 : : {
1834 : : uint16_t nb_tx = 0;
1835 : : struct iavf_tx_queue *txq = (struct iavf_tx_queue *)tx_queue;
1836 : :
1837 [ # # # # ]: 0 : while (nb_pkts) {
1838 : : uint16_t ret, num;
1839 : :
1840 : : /* cross rs_thresh boundary is not allowed */
1841 : 0 : num = (uint16_t)RTE_MIN(nb_pkts, txq->rs_thresh);
1842 [ # # # # ]: 0 : ret = iavf_xmit_fixed_burst_vec_avx2(tx_queue, &tx_pkts[nb_tx],
1843 : : num, offload);
1844 : 0 : nb_tx += ret;
1845 : 0 : nb_pkts -= ret;
1846 [ # # # # ]: 0 : if (ret < num)
1847 : : break;
1848 : : }
1849 : :
1850 : : return nb_tx;
1851 : : }
1852 : :
1853 : : uint16_t
1854 : 0 : iavf_xmit_pkts_vec_avx2(void *tx_queue, struct rte_mbuf **tx_pkts,
1855 : : uint16_t nb_pkts)
1856 : : {
1857 : 0 : return iavf_xmit_pkts_vec_avx2_common(tx_queue, tx_pkts, nb_pkts, false);
1858 : : }
1859 : :
1860 : : uint16_t
1861 : 0 : iavf_xmit_pkts_vec_avx2_offload(void *tx_queue, struct rte_mbuf **tx_pkts,
1862 : : uint16_t nb_pkts)
1863 : : {
1864 : 0 : return iavf_xmit_pkts_vec_avx2_common(tx_queue, tx_pkts, nb_pkts, true);
1865 : : }
|