Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2019 Intel Corporation
3 : : */
4 : :
5 : : #include "ice_rxtx_vec_common.h"
6 : : #include "ice_rxtx_common_avx.h"
7 : :
8 : : #include <rte_vect.h>
9 : :
10 : : #ifndef __INTEL_COMPILER
11 : : #pragma GCC diagnostic ignored "-Wcast-qual"
12 : : #endif
13 : :
14 : : static __rte_always_inline void
15 : : ice_rxq_rearm(struct ice_rx_queue *rxq)
16 : : {
17 : : return ice_rxq_rearm_common(rxq, false);
18 : : }
19 : :
20 : : static __rte_always_inline __m256i
21 : : ice_flex_rxd_to_fdir_flags_vec_avx2(const __m256i fdir_id0_7)
22 : : {
23 : : #define FDID_MIS_MAGIC 0xFFFFFFFF
24 : : RTE_BUILD_BUG_ON(RTE_MBUF_F_RX_FDIR != (1 << 2));
25 : : RTE_BUILD_BUG_ON(RTE_MBUF_F_RX_FDIR_ID != (1 << 13));
26 : : const __m256i pkt_fdir_bit = _mm256_set1_epi32(RTE_MBUF_F_RX_FDIR |
27 : : RTE_MBUF_F_RX_FDIR_ID);
28 : : /* desc->flow_id field == 0xFFFFFFFF means fdir mismatch */
29 : : const __m256i fdir_mis_mask = _mm256_set1_epi32(FDID_MIS_MAGIC);
30 : : __m256i fdir_mask = _mm256_cmpeq_epi32(fdir_id0_7,
31 : : fdir_mis_mask);
32 : : /* this XOR op results to bit-reverse the fdir_mask */
33 : : fdir_mask = _mm256_xor_si256(fdir_mask, fdir_mis_mask);
34 : : const __m256i fdir_flags = _mm256_and_si256(fdir_mask, pkt_fdir_bit);
35 : :
36 : : return fdir_flags;
37 : : }
38 : :
39 : : static __rte_always_inline uint16_t
40 : : _ice_recv_raw_pkts_vec_avx2(struct ice_rx_queue *rxq, struct rte_mbuf **rx_pkts,
41 : : uint16_t nb_pkts, uint8_t *split_packet,
42 : : bool offload)
43 : : {
44 : : #define ICE_DESCS_PER_LOOP_AVX 8
45 : :
46 : 0 : const uint32_t *ptype_tbl = rxq->vsi->adapter->ptype_tbl;
47 : 0 : const __m256i mbuf_init = _mm256_set_epi64x(0, 0,
48 : 0 : 0, rxq->mbuf_initializer);
49 : 0 : struct ice_rx_entry *sw_ring = &rxq->sw_ring[rxq->rx_tail];
50 : 0 : volatile union ice_rx_flex_desc *rxdp = rxq->rx_ring + rxq->rx_tail;
51 : : const int avx_aligned = ((rxq->rx_tail & 1) == 0);
52 : :
53 : : rte_prefetch0(rxdp);
54 : :
55 : : /* nb_pkts has to be floor-aligned to ICE_DESCS_PER_LOOP_AVX */
56 : 0 : nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, ICE_DESCS_PER_LOOP_AVX);
57 : :
58 : : /* See if we need to rearm the RX queue - gives the prefetch a bit
59 : : * of time to act
60 : : */
61 [ # # # # : 0 : if (rxq->rxrearm_nb > ICE_RXQ_REARM_THRESH)
# # # # #
# # # ]
62 : : ice_rxq_rearm(rxq);
63 : :
64 : : /* Before we start moving massive data around, check to see if
65 : : * there is actually a packet available
66 : : */
67 [ # # # # : 0 : if (!(rxdp->wb.status_error0 &
# # # # #
# # # ]
68 : : rte_cpu_to_le_32(1 << ICE_RX_FLEX_DESC_STATUS0_DD_S)))
69 : : return 0;
70 : :
71 : : /* constants used in processing loop */
72 : : const __m256i crc_adjust =
73 : 0 : _mm256_set_epi16
74 : : (/* first descriptor */
75 : : 0, 0, 0, /* ignore non-length fields */
76 : : -rxq->crc_len, /* sub crc on data_len */
77 : : 0, /* ignore high-16bits of pkt_len */
78 : : -rxq->crc_len, /* sub crc on pkt_len */
79 : : 0, 0, /* ignore pkt_type field */
80 : : /* second descriptor */
81 : : 0, 0, 0, /* ignore non-length fields */
82 : : -rxq->crc_len, /* sub crc on data_len */
83 : : 0, /* ignore high-16bits of pkt_len */
84 : 0 : -rxq->crc_len, /* sub crc on pkt_len */
85 : : 0, 0 /* ignore pkt_type field */
86 : : );
87 : :
88 : : /* 8 packets DD mask, LSB in each 32-bit value */
89 : : const __m256i dd_check = _mm256_set1_epi32(1);
90 : :
91 : : /* 8 packets EOP mask, second-LSB in each 32-bit value */
92 : : const __m256i eop_check = _mm256_slli_epi32(dd_check,
93 : : ICE_RX_DESC_STATUS_EOF_S);
94 : :
95 : : /* mask to shuffle from desc. to mbuf (2 descriptors)*/
96 : : const __m256i shuf_msk =
97 : : _mm256_set_epi8
98 : : (/* first descriptor */
99 : : 0xFF, 0xFF,
100 : : 0xFF, 0xFF, /* rss hash parsed separately */
101 : : 11, 10, /* octet 10~11, 16 bits vlan_macip */
102 : : 5, 4, /* octet 4~5, 16 bits data_len */
103 : : 0xFF, 0xFF, /* skip hi 16 bits pkt_len, zero out */
104 : : 5, 4, /* octet 4~5, 16 bits pkt_len */
105 : : 0xFF, 0xFF, /* pkt_type set as unknown */
106 : : 0xFF, 0xFF, /*pkt_type set as unknown */
107 : : /* second descriptor */
108 : : 0xFF, 0xFF,
109 : : 0xFF, 0xFF, /* rss hash parsed separately */
110 : : 11, 10, /* octet 10~11, 16 bits vlan_macip */
111 : : 5, 4, /* octet 4~5, 16 bits data_len */
112 : : 0xFF, 0xFF, /* skip hi 16 bits pkt_len, zero out */
113 : : 5, 4, /* octet 4~5, 16 bits pkt_len */
114 : : 0xFF, 0xFF, /* pkt_type set as unknown */
115 : : 0xFF, 0xFF /*pkt_type set as unknown */
116 : : );
117 : : /**
118 : : * compile-time check the above crc and shuffle layout is correct.
119 : : * NOTE: the first field (lowest address) is given last in set_epi
120 : : * calls above.
121 : : */
122 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, pkt_len) !=
123 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 4);
124 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, data_len) !=
125 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 8);
126 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, vlan_tci) !=
127 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 10);
128 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, hash) !=
129 : : offsetof(struct rte_mbuf, rx_descriptor_fields1) + 12);
130 : :
131 : : /* Status/Error flag masks */
132 : : /**
133 : : * mask everything except Checksum Reports, RSS indication
134 : : * and VLAN indication.
135 : : * bit6:4 for IP/L4 checksum errors.
136 : : * bit12 is for RSS indication.
137 : : * bit13 is for VLAN indication.
138 : : */
139 : : const __m256i flags_mask =
140 : : _mm256_set1_epi32((0xF << 4) | (1 << 12) | (1 << 13));
141 : : /**
142 : : * data to be shuffled by the result of the flags mask shifted by 4
143 : : * bits. This gives use the l3_l4 flags.
144 : : */
145 : : const __m256i l3_l4_flags_shuf =
146 : : _mm256_set_epi8((RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 |
147 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD | RTE_MBUF_F_RX_L4_CKSUM_BAD |
148 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
149 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
150 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
151 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
152 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
153 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
154 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
155 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
156 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
157 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
158 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
159 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
160 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
161 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
162 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
163 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
164 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
165 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
166 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
167 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
168 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
169 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
170 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
171 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
172 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
173 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
174 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
175 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
176 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
177 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
178 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
179 : : /**
180 : : * second 128-bits
181 : : * shift right 20 bits to use the low two bits to indicate
182 : : * outer checksum status
183 : : * shift right 1 bit to make sure it not exceed 255
184 : : */
185 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
186 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
187 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
188 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
189 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
190 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
191 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
192 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
193 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
194 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
195 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
196 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
197 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
198 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
199 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_BAD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
200 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
201 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
202 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
203 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
204 : : RTE_MBUF_F_RX_L4_CKSUM_BAD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
205 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
206 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
207 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
208 : : RTE_MBUF_F_RX_L4_CKSUM_GOOD | RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
209 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
210 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
211 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_BAD |
212 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1,
213 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
214 : : RTE_MBUF_F_RX_IP_CKSUM_BAD) >> 1,
215 : : (RTE_MBUF_F_RX_OUTER_L4_CKSUM_GOOD >> 20 | RTE_MBUF_F_RX_L4_CKSUM_GOOD |
216 : : RTE_MBUF_F_RX_IP_CKSUM_GOOD) >> 1);
217 : : const __m256i cksum_mask =
218 : : _mm256_set1_epi32(RTE_MBUF_F_RX_IP_CKSUM_MASK |
219 : : RTE_MBUF_F_RX_L4_CKSUM_MASK |
220 : : RTE_MBUF_F_RX_OUTER_IP_CKSUM_BAD |
221 : : RTE_MBUF_F_RX_OUTER_L4_CKSUM_MASK);
222 : : /**
223 : : * data to be shuffled by result of flag mask, shifted down 12.
224 : : * If RSS(bit12)/VLAN(bit13) are set,
225 : : * shuffle moves appropriate flags in place.
226 : : */
227 : : const __m256i rss_vlan_flags_shuf = _mm256_set_epi8(0, 0, 0, 0,
228 : : 0, 0, 0, 0,
229 : : 0, 0, 0, 0,
230 : : RTE_MBUF_F_RX_RSS_HASH | RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
231 : : RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
232 : : RTE_MBUF_F_RX_RSS_HASH, 0,
233 : : /* end up 128-bits */
234 : : 0, 0, 0, 0,
235 : : 0, 0, 0, 0,
236 : : 0, 0, 0, 0,
237 : : RTE_MBUF_F_RX_RSS_HASH | RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
238 : : RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED,
239 : : RTE_MBUF_F_RX_RSS_HASH, 0);
240 : :
241 : : RTE_SET_USED(avx_aligned); /* for 32B descriptors we don't use this */
242 : :
243 : : uint16_t i, received;
244 : :
245 [ # # # # : 0 : for (i = 0, received = 0; i < nb_pkts;
# # # # #
# # # ]
246 : 0 : i += ICE_DESCS_PER_LOOP_AVX,
247 : 0 : rxdp += ICE_DESCS_PER_LOOP_AVX) {
248 : : /* step 1, copy over 8 mbuf pointers to rx_pkts array */
249 : 0 : _mm256_storeu_si256((void *)&rx_pkts[i],
250 : 0 : _mm256_loadu_si256((void *)&sw_ring[i]));
251 : : #ifdef RTE_ARCH_X86_64
252 : : _mm256_storeu_si256
253 : 0 : ((void *)&rx_pkts[i + 4],
254 : 0 : _mm256_loadu_si256((void *)&sw_ring[i + 4]));
255 : : #endif
256 : :
257 : : const __m128i raw_desc7 = _mm_load_si128((void *)(rxdp + 7));
258 : 0 : rte_compiler_barrier();
259 : : const __m128i raw_desc6 = _mm_load_si128((void *)(rxdp + 6));
260 : 0 : rte_compiler_barrier();
261 : : const __m128i raw_desc5 = _mm_load_si128((void *)(rxdp + 5));
262 : 0 : rte_compiler_barrier();
263 : : const __m128i raw_desc4 = _mm_load_si128((void *)(rxdp + 4));
264 : 0 : rte_compiler_barrier();
265 : : const __m128i raw_desc3 = _mm_load_si128((void *)(rxdp + 3));
266 : 0 : rte_compiler_barrier();
267 : : const __m128i raw_desc2 = _mm_load_si128((void *)(rxdp + 2));
268 : 0 : rte_compiler_barrier();
269 : : const __m128i raw_desc1 = _mm_load_si128((void *)(rxdp + 1));
270 : 0 : rte_compiler_barrier();
271 : : const __m128i raw_desc0 = _mm_load_si128((void *)(rxdp + 0));
272 : :
273 : : const __m256i raw_desc6_7 =
274 : : _mm256_inserti128_si256(_mm256_castsi128_si256(raw_desc6), raw_desc7, 1);
275 : : const __m256i raw_desc4_5 =
276 : : _mm256_inserti128_si256(_mm256_castsi128_si256(raw_desc4), raw_desc5, 1);
277 : : const __m256i raw_desc2_3 =
278 : : _mm256_inserti128_si256(_mm256_castsi128_si256(raw_desc2), raw_desc3, 1);
279 : : const __m256i raw_desc0_1 =
280 : : _mm256_inserti128_si256(_mm256_castsi128_si256(raw_desc0), raw_desc1, 1);
281 : :
282 [ # # # # : 0 : if (split_packet) {
# # # # ]
283 : : int j;
284 : :
285 [ # # # # : 0 : for (j = 0; j < ICE_DESCS_PER_LOOP_AVX; j++)
# # # # ]
286 : 0 : rte_mbuf_prefetch_part2(rx_pkts[i + j]);
287 : : }
288 : :
289 : : /**
290 : : * convert descriptors 4-7 into mbufs, re-arrange fields.
291 : : * Then write into the mbuf.
292 : : */
293 : : __m256i mb6_7 = _mm256_shuffle_epi8(raw_desc6_7, shuf_msk);
294 : : __m256i mb4_5 = _mm256_shuffle_epi8(raw_desc4_5, shuf_msk);
295 : :
296 : : mb6_7 = _mm256_add_epi16(mb6_7, crc_adjust);
297 : : mb4_5 = _mm256_add_epi16(mb4_5, crc_adjust);
298 : : /**
299 : : * to get packet types, ptype is located in bit16-25
300 : : * of each 128bits
301 : : */
302 : : const __m256i ptype_mask =
303 : : _mm256_set1_epi16(ICE_RX_FLEX_DESC_PTYPE_M);
304 : : const __m256i ptypes6_7 =
305 : : _mm256_and_si256(raw_desc6_7, ptype_mask);
306 : : const __m256i ptypes4_5 =
307 : : _mm256_and_si256(raw_desc4_5, ptype_mask);
308 : : const uint16_t ptype7 = _mm256_extract_epi16(ptypes6_7, 9);
309 : : const uint16_t ptype6 = _mm256_extract_epi16(ptypes6_7, 1);
310 : : const uint16_t ptype5 = _mm256_extract_epi16(ptypes4_5, 9);
311 : : const uint16_t ptype4 = _mm256_extract_epi16(ptypes4_5, 1);
312 : :
313 [ # # # # : 0 : mb6_7 = _mm256_insert_epi32(mb6_7, ptype_tbl[ptype7], 4);
# # # # #
# # # ]
314 : 0 : mb6_7 = _mm256_insert_epi32(mb6_7, ptype_tbl[ptype6], 0);
315 : 0 : mb4_5 = _mm256_insert_epi32(mb4_5, ptype_tbl[ptype5], 4);
316 [ # # # # : 0 : mb4_5 = _mm256_insert_epi32(mb4_5, ptype_tbl[ptype4], 0);
# # # # #
# # # ]
317 : : /* merge the status bits into one register */
318 : : const __m256i status4_7 = _mm256_unpackhi_epi32(raw_desc6_7,
319 : : raw_desc4_5);
320 : :
321 : : /**
322 : : * convert descriptors 0-3 into mbufs, re-arrange fields.
323 : : * Then write into the mbuf.
324 : : */
325 : : __m256i mb2_3 = _mm256_shuffle_epi8(raw_desc2_3, shuf_msk);
326 : : __m256i mb0_1 = _mm256_shuffle_epi8(raw_desc0_1, shuf_msk);
327 : :
328 : : mb2_3 = _mm256_add_epi16(mb2_3, crc_adjust);
329 : : mb0_1 = _mm256_add_epi16(mb0_1, crc_adjust);
330 : : /**
331 : : * to get packet types, ptype is located in bit16-25
332 : : * of each 128bits
333 : : */
334 : : const __m256i ptypes2_3 =
335 : : _mm256_and_si256(raw_desc2_3, ptype_mask);
336 : : const __m256i ptypes0_1 =
337 : : _mm256_and_si256(raw_desc0_1, ptype_mask);
338 : : const uint16_t ptype3 = _mm256_extract_epi16(ptypes2_3, 9);
339 : : const uint16_t ptype2 = _mm256_extract_epi16(ptypes2_3, 1);
340 : : const uint16_t ptype1 = _mm256_extract_epi16(ptypes0_1, 9);
341 : : const uint16_t ptype0 = _mm256_extract_epi16(ptypes0_1, 1);
342 : :
343 : 0 : mb2_3 = _mm256_insert_epi32(mb2_3, ptype_tbl[ptype3], 4);
344 : 0 : mb2_3 = _mm256_insert_epi32(mb2_3, ptype_tbl[ptype2], 0);
345 : 0 : mb0_1 = _mm256_insert_epi32(mb0_1, ptype_tbl[ptype1], 4);
346 [ # # # # : 0 : mb0_1 = _mm256_insert_epi32(mb0_1, ptype_tbl[ptype0], 0);
# # # # #
# # # ]
347 : : /* merge the status bits into one register */
348 : : const __m256i status0_3 = _mm256_unpackhi_epi32(raw_desc2_3,
349 : : raw_desc0_1);
350 : :
351 : : /**
352 : : * take the two sets of status bits and merge to one
353 : : * After merge, the packets status flags are in the
354 : : * order (hi->lo): [1, 3, 5, 7, 0, 2, 4, 6]
355 : : */
356 : : __m256i status0_7 = _mm256_unpacklo_epi64(status4_7,
357 : : status0_3);
358 : : __m256i mbuf_flags = _mm256_set1_epi32(0);
359 : :
360 : : if (offload) {
361 : : /* now do flag manipulation */
362 : :
363 : : /* get only flag/error bits we want */
364 : : const __m256i flag_bits =
365 : : _mm256_and_si256(status0_7, flags_mask);
366 : : /**
367 : : * l3_l4_error flags, shuffle, then shift to correct adjustment
368 : : * of flags in flags_shuf, and finally mask out extra bits
369 : : */
370 : : __m256i l3_l4_flags = _mm256_shuffle_epi8(l3_l4_flags_shuf,
371 : : _mm256_srli_epi32(flag_bits, 4));
372 : : l3_l4_flags = _mm256_slli_epi32(l3_l4_flags, 1);
373 : :
374 : : __m256i l4_outer_mask = _mm256_set1_epi32(0x6);
375 : : __m256i l4_outer_flags =
376 : : _mm256_and_si256(l3_l4_flags, l4_outer_mask);
377 : : l4_outer_flags = _mm256_slli_epi32(l4_outer_flags, 20);
378 : :
379 : : __m256i l3_l4_mask = _mm256_set1_epi32(~0x6);
380 : :
381 : : l3_l4_flags = _mm256_and_si256(l3_l4_flags, l3_l4_mask);
382 : : l3_l4_flags = _mm256_or_si256(l3_l4_flags, l4_outer_flags);
383 : : l3_l4_flags = _mm256_and_si256(l3_l4_flags, cksum_mask);
384 : : /* set rss and vlan flags */
385 : : const __m256i rss_vlan_flag_bits =
386 : : _mm256_srli_epi32(flag_bits, 12);
387 : : const __m256i rss_vlan_flags =
388 : : _mm256_shuffle_epi8(rss_vlan_flags_shuf,
389 : : rss_vlan_flag_bits);
390 : :
391 : : /* merge flags */
392 : : mbuf_flags = _mm256_or_si256(l3_l4_flags,
393 : : rss_vlan_flags);
394 : : }
395 : :
396 [ # # # # : 0 : if (rxq->fdir_enabled) {
# # # # #
# # # ]
397 : : const __m256i fdir_id4_7 =
398 : : _mm256_unpackhi_epi32(raw_desc6_7, raw_desc4_5);
399 : :
400 : : const __m256i fdir_id0_3 =
401 : : _mm256_unpackhi_epi32(raw_desc2_3, raw_desc0_1);
402 : :
403 : : const __m256i fdir_id0_7 =
404 : : _mm256_unpackhi_epi64(fdir_id4_7, fdir_id0_3);
405 : :
406 : : const __m256i fdir_flags =
407 : : ice_flex_rxd_to_fdir_flags_vec_avx2(fdir_id0_7);
408 : :
409 : : /* merge with fdir_flags */
410 : : mbuf_flags = _mm256_or_si256(mbuf_flags, fdir_flags);
411 : :
412 : : /* write to mbuf: have to use scalar store here */
413 : 0 : rx_pkts[i + 0]->hash.fdir.hi =
414 : 0 : _mm256_extract_epi32(fdir_id0_7, 3);
415 : :
416 : 0 : rx_pkts[i + 1]->hash.fdir.hi =
417 : 0 : _mm256_extract_epi32(fdir_id0_7, 7);
418 : :
419 : 0 : rx_pkts[i + 2]->hash.fdir.hi =
420 : 0 : _mm256_extract_epi32(fdir_id0_7, 2);
421 : :
422 : 0 : rx_pkts[i + 3]->hash.fdir.hi =
423 : 0 : _mm256_extract_epi32(fdir_id0_7, 6);
424 : :
425 : 0 : rx_pkts[i + 4]->hash.fdir.hi =
426 : 0 : _mm256_extract_epi32(fdir_id0_7, 1);
427 : :
428 : 0 : rx_pkts[i + 5]->hash.fdir.hi =
429 : 0 : _mm256_extract_epi32(fdir_id0_7, 5);
430 : :
431 : 0 : rx_pkts[i + 6]->hash.fdir.hi =
432 : 0 : _mm256_extract_epi32(fdir_id0_7, 0);
433 : :
434 : 0 : rx_pkts[i + 7]->hash.fdir.hi =
435 : 0 : _mm256_extract_epi32(fdir_id0_7, 4);
436 : : } /* if() on fdir_enabled */
437 : :
438 : : if (offload) {
439 : : #ifndef RTE_LIBRTE_ICE_16BYTE_RX_DESC
440 : : /**
441 : : * needs to load 2nd 16B of each desc for RSS hash parsing,
442 : : * will cause performance drop to get into this context.
443 : : */
444 [ # # # # : 0 : if (rxq->vsi->adapter->pf.dev_data->dev_conf.rxmode.offloads &
# # ]
445 : : RTE_ETH_RX_OFFLOAD_RSS_HASH) {
446 : : /* load bottom half of every 32B desc */
447 : : const __m128i raw_desc_bh7 =
448 : : _mm_load_si128
449 : : ((void *)(&rxdp[7].wb.status_error1));
450 : 0 : rte_compiler_barrier();
451 : : const __m128i raw_desc_bh6 =
452 : : _mm_load_si128
453 : : ((void *)(&rxdp[6].wb.status_error1));
454 : 0 : rte_compiler_barrier();
455 : : const __m128i raw_desc_bh5 =
456 : : _mm_load_si128
457 : : ((void *)(&rxdp[5].wb.status_error1));
458 : 0 : rte_compiler_barrier();
459 : : const __m128i raw_desc_bh4 =
460 : : _mm_load_si128
461 : : ((void *)(&rxdp[4].wb.status_error1));
462 : 0 : rte_compiler_barrier();
463 : : const __m128i raw_desc_bh3 =
464 : : _mm_load_si128
465 : : ((void *)(&rxdp[3].wb.status_error1));
466 : 0 : rte_compiler_barrier();
467 : : const __m128i raw_desc_bh2 =
468 : : _mm_load_si128
469 : : ((void *)(&rxdp[2].wb.status_error1));
470 : 0 : rte_compiler_barrier();
471 : : const __m128i raw_desc_bh1 =
472 : : _mm_load_si128
473 : : ((void *)(&rxdp[1].wb.status_error1));
474 : 0 : rte_compiler_barrier();
475 : : const __m128i raw_desc_bh0 =
476 : : _mm_load_si128
477 : : ((void *)(&rxdp[0].wb.status_error1));
478 : :
479 : : __m256i raw_desc_bh6_7 =
480 : : _mm256_inserti128_si256
481 : : (_mm256_castsi128_si256(raw_desc_bh6),
482 : : raw_desc_bh7, 1);
483 : : __m256i raw_desc_bh4_5 =
484 : : _mm256_inserti128_si256
485 : : (_mm256_castsi128_si256(raw_desc_bh4),
486 : : raw_desc_bh5, 1);
487 : : __m256i raw_desc_bh2_3 =
488 : : _mm256_inserti128_si256
489 : : (_mm256_castsi128_si256(raw_desc_bh2),
490 : : raw_desc_bh3, 1);
491 : : __m256i raw_desc_bh0_1 =
492 : : _mm256_inserti128_si256
493 : : (_mm256_castsi128_si256(raw_desc_bh0),
494 : : raw_desc_bh1, 1);
495 : :
496 : : /**
497 : : * to shift the 32b RSS hash value to the
498 : : * highest 32b of each 128b before mask
499 : : */
500 : : __m256i rss_hash6_7 =
501 : : _mm256_slli_epi64(raw_desc_bh6_7, 32);
502 : : __m256i rss_hash4_5 =
503 : : _mm256_slli_epi64(raw_desc_bh4_5, 32);
504 : : __m256i rss_hash2_3 =
505 : : _mm256_slli_epi64(raw_desc_bh2_3, 32);
506 : : __m256i rss_hash0_1 =
507 : : _mm256_slli_epi64(raw_desc_bh0_1, 32);
508 : :
509 : : __m256i rss_hash_msk =
510 : : _mm256_set_epi32(0xFFFFFFFF, 0, 0, 0,
511 : : 0xFFFFFFFF, 0, 0, 0);
512 : :
513 : : rss_hash6_7 = _mm256_and_si256
514 : : (rss_hash6_7, rss_hash_msk);
515 : : rss_hash4_5 = _mm256_and_si256
516 : : (rss_hash4_5, rss_hash_msk);
517 : : rss_hash2_3 = _mm256_and_si256
518 : : (rss_hash2_3, rss_hash_msk);
519 : : rss_hash0_1 = _mm256_and_si256
520 : : (rss_hash0_1, rss_hash_msk);
521 : :
522 : : mb6_7 = _mm256_or_si256(mb6_7, rss_hash6_7);
523 : : mb4_5 = _mm256_or_si256(mb4_5, rss_hash4_5);
524 : : mb2_3 = _mm256_or_si256(mb2_3, rss_hash2_3);
525 : : mb0_1 = _mm256_or_si256(mb0_1, rss_hash0_1);
526 : : } /* if() on RSS hash parsing */
527 : : #endif
528 : : }
529 : :
530 : : /**
531 : : * At this point, we have the 8 sets of flags in the low 16-bits
532 : : * of each 32-bit value in vlan0.
533 : : * We want to extract these, and merge them with the mbuf init
534 : : * data so we can do a single write to the mbuf to set the flags
535 : : * and all the other initialization fields. Extracting the
536 : : * appropriate flags means that we have to do a shift and blend
537 : : * for each mbuf before we do the write. However, we can also
538 : : * add in the previously computed rx_descriptor fields to
539 : : * make a single 256-bit write per mbuf
540 : : */
541 : : /* check the structure matches expectations */
542 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, ol_flags) !=
543 : : offsetof(struct rte_mbuf, rearm_data) + 8);
544 : : RTE_BUILD_BUG_ON(offsetof(struct rte_mbuf, rearm_data) !=
545 : : RTE_ALIGN(offsetof(struct rte_mbuf,
546 : : rearm_data),
547 : : 16));
548 : : /* build up data and do writes */
549 : : __m256i rearm0, rearm1, rearm2, rearm3, rearm4, rearm5,
550 : : rearm6, rearm7;
551 : : rearm6 = _mm256_blend_epi32(mbuf_init,
552 : : _mm256_slli_si256(mbuf_flags, 8),
553 : : 0x04);
554 : : rearm4 = _mm256_blend_epi32(mbuf_init,
555 : : _mm256_slli_si256(mbuf_flags, 4),
556 : : 0x04);
557 : : rearm2 = _mm256_blend_epi32(mbuf_init, mbuf_flags, 0x04);
558 : : rearm0 = _mm256_blend_epi32(mbuf_init,
559 : : _mm256_srli_si256(mbuf_flags, 4),
560 : : 0x04);
561 : : /* permute to add in the rx_descriptor e.g. rss fields */
562 : : rearm6 = _mm256_permute2f128_si256(rearm6, mb6_7, 0x20);
563 : : rearm4 = _mm256_permute2f128_si256(rearm4, mb4_5, 0x20);
564 : : rearm2 = _mm256_permute2f128_si256(rearm2, mb2_3, 0x20);
565 : : rearm0 = _mm256_permute2f128_si256(rearm0, mb0_1, 0x20);
566 : : /* write to mbuf */
567 [ # # # # : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 6]->rearm_data,
# # # # #
# # # ]
568 : : rearm6);
569 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 4]->rearm_data,
570 : : rearm4);
571 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 2]->rearm_data,
572 : : rearm2);
573 [ # # # # : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 0]->rearm_data,
# # # # #
# # # ]
574 : : rearm0);
575 : :
576 : : /* repeat for the odd mbufs */
577 : : const __m256i odd_flags =
578 : : _mm256_castsi128_si256
579 : : (_mm256_extracti128_si256(mbuf_flags, 1));
580 : : rearm7 = _mm256_blend_epi32(mbuf_init,
581 : : _mm256_slli_si256(odd_flags, 8),
582 : : 0x04);
583 : : rearm5 = _mm256_blend_epi32(mbuf_init,
584 : : _mm256_slli_si256(odd_flags, 4),
585 : : 0x04);
586 : : rearm3 = _mm256_blend_epi32(mbuf_init, odd_flags, 0x04);
587 : : rearm1 = _mm256_blend_epi32(mbuf_init,
588 : : _mm256_srli_si256(odd_flags, 4),
589 : : 0x04);
590 : : /* since odd mbufs are already in hi 128-bits use blend */
591 : : rearm7 = _mm256_blend_epi32(rearm7, mb6_7, 0xF0);
592 : : rearm5 = _mm256_blend_epi32(rearm5, mb4_5, 0xF0);
593 : : rearm3 = _mm256_blend_epi32(rearm3, mb2_3, 0xF0);
594 : : rearm1 = _mm256_blend_epi32(rearm1, mb0_1, 0xF0);
595 : : /* again write to mbufs */
596 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 7]->rearm_data,
597 : : rearm7);
598 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 5]->rearm_data,
599 : : rearm5);
600 : 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 3]->rearm_data,
601 : : rearm3);
602 [ # # # # ]: 0 : _mm256_storeu_si256((__m256i *)&rx_pkts[i + 1]->rearm_data,
603 : : rearm1);
604 : :
605 : : /* extract and record EOP bit */
606 [ # # # # : 0 : if (split_packet) {
# # # # ]
607 : : const __m128i eop_mask =
608 : : _mm_set1_epi16(1 << ICE_RX_DESC_STATUS_EOF_S);
609 : : const __m256i eop_bits256 = _mm256_and_si256(status0_7,
610 : : eop_check);
611 : : /* pack status bits into a single 128-bit register */
612 : : const __m128i eop_bits =
613 : : _mm_packus_epi32
614 : : (_mm256_castsi256_si128(eop_bits256),
615 : : _mm256_extractf128_si256(eop_bits256,
616 : : 1));
617 : : /**
618 : : * flip bits, and mask out the EOP bit, which is now
619 : : * a split-packet bit i.e. !EOP, rather than EOP one.
620 : : */
621 : : __m128i split_bits = _mm_andnot_si128(eop_bits,
622 : : eop_mask);
623 : : /**
624 : : * eop bits are out of order, so we need to shuffle them
625 : : * back into order again. In doing so, only use low 8
626 : : * bits, which acts like another pack instruction
627 : : * The original order is (hi->lo): 1,3,5,7,0,2,4,6
628 : : * [Since we use epi8, the 16-bit positions are
629 : : * multiplied by 2 in the eop_shuffle value.]
630 : : */
631 : : __m128i eop_shuffle =
632 : : _mm_set_epi8(/* zero hi 64b */
633 : : 0xFF, 0xFF, 0xFF, 0xFF,
634 : : 0xFF, 0xFF, 0xFF, 0xFF,
635 : : /* move values to lo 64b */
636 : : 8, 0, 10, 2,
637 : : 12, 4, 14, 6);
638 : : split_bits = _mm_shuffle_epi8(split_bits, eop_shuffle);
639 : 0 : *(uint64_t *)split_packet =
640 : 0 : _mm_cvtsi128_si64(split_bits);
641 : 0 : split_packet += ICE_DESCS_PER_LOOP_AVX;
642 : : }
643 : :
644 : : /* perform dd_check */
645 : : status0_7 = _mm256_and_si256(status0_7, dd_check);
646 : : status0_7 = _mm256_packs_epi32(status0_7,
647 : : _mm256_setzero_si256());
648 : :
649 [ # # # # : 0 : uint64_t burst = rte_popcount64
# # # # #
# # # ]
650 : : (_mm_cvtsi128_si64
651 : : (_mm256_extracti128_si256
652 : : (status0_7, 1)));
653 : 0 : burst += rte_popcount64
654 : : (_mm_cvtsi128_si64
655 : : (_mm256_castsi256_si128(status0_7)));
656 : 0 : received += burst;
657 [ # # # # : 0 : if (burst != ICE_DESCS_PER_LOOP_AVX)
# # # # #
# # # ]
658 : : break;
659 : : }
660 : :
661 : : /* update tail pointers */
662 : 0 : rxq->rx_tail += received;
663 : 0 : rxq->rx_tail &= (rxq->nb_rx_desc - 1);
664 [ # # # # : 0 : if ((rxq->rx_tail & 1) == 1 && received > 1) { /* keep avx2 aligned */
# # # # #
# # # # #
# # # # #
# # # #
# ]
665 : 0 : rxq->rx_tail--;
666 : 0 : received--;
667 : : }
668 : 0 : rxq->rxrearm_nb += received;
669 : 0 : return received;
670 : : }
671 : :
672 : : /**
673 : : * Notice:
674 : : * - nb_pkts < ICE_DESCS_PER_LOOP, just return no packet
675 : : */
676 : : uint16_t
677 : 0 : ice_recv_pkts_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts,
678 : : uint16_t nb_pkts)
679 : : {
680 : 0 : return _ice_recv_raw_pkts_vec_avx2(rx_queue, rx_pkts,
681 : : nb_pkts, NULL, false);
682 : : }
683 : :
684 : : uint16_t
685 : 0 : ice_recv_pkts_vec_avx2_offload(void *rx_queue, struct rte_mbuf **rx_pkts,
686 : : uint16_t nb_pkts)
687 : : {
688 : 0 : return _ice_recv_raw_pkts_vec_avx2(rx_queue, rx_pkts,
689 : : nb_pkts, NULL, true);
690 : : }
691 : :
692 : : /**
693 : : * vPMD receive routine that reassembles single burst of 32 scattered packets
694 : : * Notice:
695 : : * - nb_pkts < ICE_DESCS_PER_LOOP, just return no packet
696 : : */
697 : : static __rte_always_inline uint16_t
698 : : ice_recv_scattered_burst_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts,
699 : : uint16_t nb_pkts, bool offload)
700 : : {
701 : : struct ice_rx_queue *rxq = rx_queue;
702 : 0 : uint8_t split_flags[ICE_VPMD_RX_BURST] = {0};
703 : :
704 : : /* get some new buffers */
705 : : uint16_t nb_bufs = _ice_recv_raw_pkts_vec_avx2(rxq, rx_pkts, nb_pkts,
706 : : split_flags, offload);
707 [ # # # # : 0 : if (nb_bufs == 0)
# # # # ]
708 : : return 0;
709 : :
710 : : /* happy day case, full burst + no packets to be joined */
711 : : const uint64_t *split_fl64 = (uint64_t *)split_flags;
712 : :
713 [ # # # # : 0 : if (!rxq->pkt_first_seg &&
# # # # ]
714 [ # # # # : 0 : split_fl64[0] == 0 && split_fl64[1] == 0 &&
# # # # #
# # # # #
# # ]
715 [ # # # # : 0 : split_fl64[2] == 0 && split_fl64[3] == 0)
# # # # #
# # # # #
# # ]
716 : : return nb_bufs;
717 : :
718 : : /* reassemble any packets that need reassembly*/
719 : : unsigned int i = 0;
720 : :
721 [ # # # # : 0 : if (!rxq->pkt_first_seg) {
# # # # ]
722 : : /* find the first split flag, and only reassemble then*/
723 [ # # # # : 0 : while (i < nb_bufs && !split_flags[i])
# # # # #
# # # # #
# # ]
724 : 0 : i++;
725 [ # # # # : 0 : if (i == nb_bufs)
# # # # ]
726 : : return nb_bufs;
727 : 0 : rxq->pkt_first_seg = rx_pkts[i];
728 : : }
729 : 0 : return i + ice_rx_reassemble_packets(rxq, &rx_pkts[i], nb_bufs - i,
730 : : &split_flags[i]);
731 : : }
732 : :
733 : : /**
734 : : * vPMD receive routine that reassembles scattered packets.
735 : : * Main receive routine that can handle arbitrary burst sizes
736 : : * Notice:
737 : : * - nb_pkts < ICE_DESCS_PER_LOOP, just return no packet
738 : : */
739 : : static __rte_always_inline uint16_t
740 : : ice_recv_scattered_pkts_vec_avx2_common(void *rx_queue,
741 : : struct rte_mbuf **rx_pkts,
742 : : uint16_t nb_pkts,
743 : : bool offload)
744 : : {
745 : : uint16_t retval = 0;
746 : :
747 [ # # # # ]: 0 : while (nb_pkts > ICE_VPMD_RX_BURST) {
748 : 0 : uint16_t burst = ice_recv_scattered_burst_vec_avx2(rx_queue,
749 : 0 : rx_pkts + retval, ICE_VPMD_RX_BURST, offload);
750 : 0 : retval += burst;
751 : 0 : nb_pkts -= burst;
752 [ # # # # ]: 0 : if (burst < ICE_VPMD_RX_BURST)
753 : : return retval;
754 : : }
755 : 0 : return retval + ice_recv_scattered_burst_vec_avx2(rx_queue,
756 : 0 : rx_pkts + retval, nb_pkts, offload);
757 : : }
758 : :
759 : : uint16_t
760 : 0 : ice_recv_scattered_pkts_vec_avx2(void *rx_queue,
761 : : struct rte_mbuf **rx_pkts,
762 : : uint16_t nb_pkts)
763 : : {
764 : 0 : return ice_recv_scattered_pkts_vec_avx2_common(rx_queue,
765 : : rx_pkts,
766 : : nb_pkts,
767 : : false);
768 : : }
769 : :
770 : : uint16_t
771 : 0 : ice_recv_scattered_pkts_vec_avx2_offload(void *rx_queue,
772 : : struct rte_mbuf **rx_pkts,
773 : : uint16_t nb_pkts)
774 : : {
775 : 0 : return ice_recv_scattered_pkts_vec_avx2_common(rx_queue,
776 : : rx_pkts,
777 : : nb_pkts,
778 : : true);
779 : : }
780 : :
781 : : static __rte_always_inline void
782 : : ice_vtx1(volatile struct ice_tx_desc *txdp,
783 : : struct rte_mbuf *pkt, uint64_t flags, bool offload)
784 : : {
785 : 0 : uint64_t high_qw =
786 : : (ICE_TX_DESC_DTYPE_DATA |
787 : 0 : ((uint64_t)flags << ICE_TXD_QW1_CMD_S) |
788 : 0 : ((uint64_t)pkt->data_len << ICE_TXD_QW1_TX_BUF_SZ_S));
789 : : if (offload)
790 : 0 : ice_txd_enable_offload(pkt, &high_qw);
791 : :
792 : 0 : __m128i descriptor = _mm_set_epi64x(high_qw, rte_pktmbuf_iova(pkt));
793 : : _mm_store_si128((__m128i *)txdp, descriptor);
794 : : }
795 : :
796 : : static __rte_always_inline void
797 : : ice_vtx(volatile struct ice_tx_desc *txdp,
798 : : struct rte_mbuf **pkt, uint16_t nb_pkts, uint64_t flags, bool offload)
799 : : {
800 : : const uint64_t hi_qw_tmpl = (ICE_TX_DESC_DTYPE_DATA |
801 : : ((uint64_t)flags << ICE_TXD_QW1_CMD_S));
802 : :
803 : : /* if unaligned on 32-bit boundary, do one to align */
804 [ # # # # : 0 : if (((uintptr_t)txdp & 0x1F) != 0 && nb_pkts != 0) {
# # # # #
# # # ]
805 : 0 : ice_vtx1(txdp, *pkt, flags, offload);
806 : 0 : nb_pkts--, txdp++, pkt++;
807 : : }
808 : :
809 : : /* do two at a time while possible, in bursts */
810 [ # # # # : 0 : for (; nb_pkts > 3; txdp += 4, pkt += 4, nb_pkts -= 4) {
# # # # ]
811 : 0 : uint64_t hi_qw3 =
812 : 0 : hi_qw_tmpl |
813 : 0 : ((uint64_t)pkt[3]->data_len <<
814 : : ICE_TXD_QW1_TX_BUF_SZ_S);
815 : : if (offload)
816 : 0 : ice_txd_enable_offload(pkt[3], &hi_qw3);
817 : 0 : uint64_t hi_qw2 =
818 : 0 : hi_qw_tmpl |
819 : 0 : ((uint64_t)pkt[2]->data_len <<
820 : : ICE_TXD_QW1_TX_BUF_SZ_S);
821 : : if (offload)
822 : 0 : ice_txd_enable_offload(pkt[2], &hi_qw2);
823 : 0 : uint64_t hi_qw1 =
824 : 0 : hi_qw_tmpl |
825 : 0 : ((uint64_t)pkt[1]->data_len <<
826 : : ICE_TXD_QW1_TX_BUF_SZ_S);
827 : : if (offload)
828 : 0 : ice_txd_enable_offload(pkt[1], &hi_qw1);
829 : 0 : uint64_t hi_qw0 =
830 : 0 : hi_qw_tmpl |
831 : 0 : ((uint64_t)pkt[0]->data_len <<
832 : : ICE_TXD_QW1_TX_BUF_SZ_S);
833 : : if (offload)
834 : 0 : ice_txd_enable_offload(pkt[0], &hi_qw0);
835 : :
836 : : __m256i desc2_3 =
837 : 0 : _mm256_set_epi64x
838 : 0 : (hi_qw3, rte_pktmbuf_iova(pkt[3]),
839 : 0 : hi_qw2, rte_pktmbuf_iova(pkt[2]));
840 : : __m256i desc0_1 =
841 : 0 : _mm256_set_epi64x
842 : 0 : (hi_qw1, rte_pktmbuf_iova(pkt[1]),
843 : 0 : hi_qw0, rte_pktmbuf_iova(pkt[0]));
844 : : _mm256_store_si256((void *)(txdp + 2), desc2_3);
845 : : _mm256_store_si256((void *)txdp, desc0_1);
846 : : }
847 : :
848 : : /* do any last ones */
849 [ # # # # : 0 : while (nb_pkts) {
# # # # ]
850 : 0 : ice_vtx1(txdp, *pkt, flags, offload);
851 : 0 : txdp++, pkt++, nb_pkts--;
852 : : }
853 : : }
854 : :
855 : : static __rte_always_inline uint16_t
856 : : ice_xmit_fixed_burst_vec_avx2(void *tx_queue, struct rte_mbuf **tx_pkts,
857 : : uint16_t nb_pkts, bool offload)
858 : : {
859 : : struct ice_tx_queue *txq = (struct ice_tx_queue *)tx_queue;
860 : : volatile struct ice_tx_desc *txdp;
861 : : struct ice_tx_entry *txep;
862 : : uint16_t n, nb_commit, tx_id;
863 : : uint64_t flags = ICE_TD_CMD;
864 : : uint64_t rs = ICE_TX_DESC_CMD_RS | ICE_TD_CMD;
865 : :
866 : : /* cross rx_thresh boundary is not allowed */
867 : 0 : nb_pkts = RTE_MIN(nb_pkts, txq->tx_rs_thresh);
868 : :
869 : 0 : if (txq->nb_tx_free < txq->tx_free_thresh)
870 : : ice_tx_free_bufs_vec(txq);
871 : :
872 : 0 : nb_commit = nb_pkts = (uint16_t)RTE_MIN(txq->nb_tx_free, nb_pkts);
873 [ # # # # ]: 0 : if (unlikely(nb_pkts == 0))
874 : : return 0;
875 : :
876 : 0 : tx_id = txq->tx_tail;
877 : 0 : txdp = &txq->tx_ring[tx_id];
878 : 0 : txep = &txq->sw_ring[tx_id];
879 : :
880 : 0 : txq->nb_tx_free = (uint16_t)(txq->nb_tx_free - nb_pkts);
881 : :
882 : 0 : n = (uint16_t)(txq->nb_tx_desc - tx_id);
883 [ # # # # ]: 0 : if (nb_commit >= n) {
884 : 0 : ice_tx_backlog_entry(txep, tx_pkts, n);
885 : :
886 [ # # # # ]: 0 : ice_vtx(txdp, tx_pkts, n - 1, flags, offload);
887 : 0 : tx_pkts += (n - 1);
888 : 0 : txdp += (n - 1);
889 : :
890 : 0 : ice_vtx1(txdp, *tx_pkts++, rs, offload);
891 : :
892 : 0 : nb_commit = (uint16_t)(nb_commit - n);
893 : :
894 : : tx_id = 0;
895 : 0 : txq->tx_next_rs = (uint16_t)(txq->tx_rs_thresh - 1);
896 : :
897 : : /* avoid reach the end of ring */
898 : 0 : txdp = &txq->tx_ring[tx_id];
899 : 0 : txep = &txq->sw_ring[tx_id];
900 : : }
901 : :
902 : 0 : ice_tx_backlog_entry(txep, tx_pkts, nb_commit);
903 : :
904 : : ice_vtx(txdp, tx_pkts, nb_commit, flags, offload);
905 : :
906 : 0 : tx_id = (uint16_t)(tx_id + nb_commit);
907 [ # # # # ]: 0 : if (tx_id > txq->tx_next_rs) {
908 : 0 : txq->tx_ring[txq->tx_next_rs].cmd_type_offset_bsz |=
909 : : rte_cpu_to_le_64(((uint64_t)ICE_TX_DESC_CMD_RS) <<
910 : : ICE_TXD_QW1_CMD_S);
911 : 0 : txq->tx_next_rs =
912 : 0 : (uint16_t)(txq->tx_next_rs + txq->tx_rs_thresh);
913 : : }
914 : :
915 : 0 : txq->tx_tail = tx_id;
916 : :
917 : 0 : ICE_PCI_REG_WC_WRITE(txq->qtx_tail, txq->tx_tail);
918 : :
919 : : return nb_pkts;
920 : : }
921 : :
922 : : static __rte_always_inline uint16_t
923 : : ice_xmit_pkts_vec_avx2_common(void *tx_queue, struct rte_mbuf **tx_pkts,
924 : : uint16_t nb_pkts, bool offload)
925 : : {
926 : : uint16_t nb_tx = 0;
927 : : struct ice_tx_queue *txq = (struct ice_tx_queue *)tx_queue;
928 : :
929 [ # # # # ]: 0 : while (nb_pkts) {
930 : : uint16_t ret, num;
931 : :
932 : 0 : num = (uint16_t)RTE_MIN(nb_pkts, txq->tx_rs_thresh);
933 [ # # # # ]: 0 : ret = ice_xmit_fixed_burst_vec_avx2(tx_queue, &tx_pkts[nb_tx],
934 : : num, offload);
935 : 0 : nb_tx += ret;
936 : 0 : nb_pkts -= ret;
937 [ # # # # ]: 0 : if (ret < num)
938 : : break;
939 : : }
940 : :
941 : : return nb_tx;
942 : : }
943 : :
944 : : uint16_t
945 : 0 : ice_xmit_pkts_vec_avx2(void *tx_queue, struct rte_mbuf **tx_pkts,
946 : : uint16_t nb_pkts)
947 : : {
948 : 0 : return ice_xmit_pkts_vec_avx2_common(tx_queue, tx_pkts, nb_pkts, false);
949 : : }
950 : :
951 : : uint16_t
952 : 0 : ice_xmit_pkts_vec_avx2_offload(void *tx_queue, struct rte_mbuf **tx_pkts,
953 : : uint16_t nb_pkts)
954 : : {
955 : 0 : return ice_xmit_pkts_vec_avx2_common(tx_queue, tx_pkts, nb_pkts, true);
956 : : }
|