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