Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2014-2021 Netronome Systems, Inc.
3 : : * All rights reserved.
4 : : *
5 : : * Small portions derived from code Copyright(c) 2010-2015 Intel Corporation.
6 : : */
7 : :
8 : : #include "nfp_rxtx.h"
9 : :
10 : : #include <ethdev_pci.h>
11 : : #include <rte_security.h>
12 : :
13 : : #include "nfd3/nfp_nfd3.h"
14 : : #include "nfdk/nfp_nfdk.h"
15 : : #include "nfdk/nfp_nfdk_vec.h"
16 : : #include "flower/nfp_flower.h"
17 : :
18 : : #include "nfp_ipsec.h"
19 : : #include "nfp_logs.h"
20 : : #include "nfp_net_meta.h"
21 : : #include "nfp_rxtx_vec.h"
22 : :
23 : : /*
24 : : * The bit format and map of nfp packet type for rxd.offload_info in Rx descriptor.
25 : : *
26 : : * Bit format about nfp packet type refers to the following:
27 : : * ---------------------------------
28 : : * 1 0
29 : : * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
30 : : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
31 : : * | |ol3|tunnel | l3 | l4 |
32 : : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
33 : : *
34 : : * Bit map about nfp packet type refers to the following:
35 : : *
36 : : * L4: bit 0~2, used for layer 4 or inner layer 4.
37 : : * 000: NFP_NET_PTYPE_L4_NONE
38 : : * 001: NFP_NET_PTYPE_L4_TCP
39 : : * 010: NFP_NET_PTYPE_L4_UDP
40 : : * 011: NFP_NET_PTYPE_L4_FRAG
41 : : * 100: NFP_NET_PTYPE_L4_NONFRAG
42 : : * 101: NFP_NET_PTYPE_L4_ICMP
43 : : * 110: NFP_NET_PTYPE_L4_SCTP
44 : : * 111: reserved
45 : : *
46 : : * L3: bit 3~5, used for layer 3 or inner layer 3.
47 : : * 000: NFP_NET_PTYPE_L3_NONE
48 : : * 001: NFP_NET_PTYPE_L3_IPV6
49 : : * 010: NFP_NET_PTYPE_L3_IPV4
50 : : * 011: NFP_NET_PTYPE_L3_IPV4_EXT
51 : : * 100: NFP_NET_PTYPE_L3_IPV6_EXT
52 : : * 101: NFP_NET_PTYPE_L3_IPV4_EXT_UNKNOWN
53 : : * 110: NFP_NET_PTYPE_L3_IPV6_EXT_UNKNOWN
54 : : * 111: reserved
55 : : *
56 : : * Tunnel: bit 6~9, used for tunnel.
57 : : * 0000: NFP_NET_PTYPE_TUNNEL_NONE
58 : : * 0001: NFP_NET_PTYPE_TUNNEL_VXLAN
59 : : * 0100: NFP_NET_PTYPE_TUNNEL_NVGRE
60 : : * 0101: NFP_NET_PTYPE_TUNNEL_GENEVE
61 : : * 0010, 0011, 0110~1111: reserved
62 : : *
63 : : * Outer L3: bit 10~11, used for outer layer 3.
64 : : * 00: NFP_NET_PTYPE_OUTER_L3_NONE
65 : : * 01: NFP_NET_PTYPE_OUTER_L3_IPV6
66 : : * 10: NFP_NET_PTYPE_OUTER_L3_IPV4
67 : : * 11: reserved
68 : : *
69 : : * Reserved: bit 10~15, used for extension.
70 : : */
71 : :
72 : : /* Mask and offset about nfp packet type based on the bit map above. */
73 : : #define NFP_NET_PTYPE_L4_MASK 0x0007
74 : : #define NFP_NET_PTYPE_L3_MASK 0x0038
75 : : #define NFP_NET_PTYPE_TUNNEL_MASK 0x03c0
76 : : #define NFP_NET_PTYPE_OUTER_L3_MASK 0x0c00
77 : :
78 : : #define NFP_NET_PTYPE_L4_OFFSET 0
79 : : #define NFP_NET_PTYPE_L3_OFFSET 3
80 : : #define NFP_NET_PTYPE_TUNNEL_OFFSET 6
81 : : #define NFP_NET_PTYPE_OUTER_L3_OFFSET 10
82 : :
83 : : /* Case about nfp packet type based on the bit map above. */
84 : : #define NFP_NET_PTYPE_L4_NONE 0
85 : : #define NFP_NET_PTYPE_L4_TCP 1
86 : : #define NFP_NET_PTYPE_L4_UDP 2
87 : : #define NFP_NET_PTYPE_L4_FRAG 3
88 : : #define NFP_NET_PTYPE_L4_NONFRAG 4
89 : : #define NFP_NET_PTYPE_L4_ICMP 5
90 : : #define NFP_NET_PTYPE_L4_SCTP 6
91 : :
92 : : #define NFP_NET_PTYPE_L3_NONE 0
93 : : #define NFP_NET_PTYPE_L3_IPV6 1
94 : : #define NFP_NET_PTYPE_L3_IPV4 2
95 : : #define NFP_NET_PTYPE_L3_IPV4_EXT 3
96 : : #define NFP_NET_PTYPE_L3_IPV6_EXT 4
97 : : #define NFP_NET_PTYPE_L3_IPV4_EXT_UNKNOWN 5
98 : : #define NFP_NET_PTYPE_L3_IPV6_EXT_UNKNOWN 6
99 : :
100 : : #define NFP_NET_PTYPE_TUNNEL_NONE 0
101 : : #define NFP_NET_PTYPE_TUNNEL_VXLAN 1
102 : : #define NFP_NET_PTYPE_TUNNEL_NVGRE 4
103 : : #define NFP_NET_PTYPE_TUNNEL_GENEVE 5
104 : :
105 : : #define NFP_NET_PTYPE_OUTER_L3_NONE 0
106 : : #define NFP_NET_PTYPE_OUTER_L3_IPV6 1
107 : : #define NFP_NET_PTYPE_OUTER_L3_IPV4 2
108 : :
109 : : #define NFP_PTYPE2RTE(tunnel, type) ((tunnel) ? RTE_PTYPE_INNER_##type : RTE_PTYPE_##type)
110 : :
111 : : /* Record NFP packet type parsed from rxd.offload_info. */
112 : : struct nfp_ptype_parsed {
113 : : uint8_t l4_ptype; /**< Packet type of layer 4, or inner layer 4. */
114 : : uint8_t l3_ptype; /**< Packet type of layer 3, or inner layer 3. */
115 : : uint8_t tunnel_ptype; /**< Packet type of tunnel. */
116 : : uint8_t outer_l3_ptype; /**< Packet type of outer layer 3. */
117 : : };
118 : :
119 : : /* Set mbuf checksum flags based on RX descriptor flags */
120 : : void
121 : 0 : nfp_net_rx_cksum(struct nfp_net_rxq *rxq,
122 : : struct nfp_net_rx_desc *rxd,
123 : : struct rte_mbuf *mb)
124 : : {
125 : : uint16_t flags;
126 : 0 : struct nfp_net_hw *hw = rxq->hw;
127 : :
128 [ # # ]: 0 : if ((hw->super.ctrl & NFP_NET_CFG_CTRL_RXCSUM) == 0)
129 : : return;
130 : :
131 : 0 : flags = rte_le_to_cpu_16(rxd->rxd.flags);
132 : :
133 : : /* If IPv4 and IP checksum error, fail */
134 [ # # ]: 0 : if (unlikely((flags & PCIE_DESC_RX_IP4_CSUM) != 0 &&
135 : : (flags & PCIE_DESC_RX_IP4_CSUM_OK) == 0))
136 : 0 : mb->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
137 : : else
138 : 0 : mb->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
139 : :
140 : : /* If neither UDP nor TCP return */
141 [ # # ]: 0 : if ((flags & PCIE_DESC_RX_TCP_CSUM) == 0 &&
142 : : (flags & PCIE_DESC_RX_UDP_CSUM) == 0)
143 : : return;
144 : :
145 [ # # ]: 0 : if (likely(flags & PCIE_DESC_RX_L4_CSUM_OK) != 0)
146 : 0 : mb->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
147 : : else
148 : 0 : mb->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
149 : : }
150 : :
151 : : static int
152 : 0 : nfp_net_rx_fill_freelist(struct nfp_net_rxq *rxq)
153 : : {
154 : : uint16_t i;
155 : : uint64_t dma_addr;
156 : 0 : struct nfp_net_dp_buf *rxe = rxq->rxbufs;
157 : :
158 : : PMD_RX_LOG(DEBUG, "Fill Rx Freelist for %hu descriptors.",
159 : : rxq->rx_count);
160 : :
161 [ # # ]: 0 : for (i = 0; i < rxq->rx_count; i++) {
162 : : struct nfp_net_rx_desc *rxd;
163 : 0 : struct rte_mbuf *mbuf = rte_pktmbuf_alloc(rxq->mem_pool);
164 : :
165 [ # # ]: 0 : if (mbuf == NULL) {
166 : 0 : PMD_DRV_LOG(ERR, "RX mbuf alloc failed queue_id=%hu.",
167 : : rxq->qidx);
168 : 0 : return -ENOMEM;
169 : : }
170 : :
171 : : dma_addr = rte_mbuf_data_iova_default(mbuf);
172 : :
173 : 0 : rxd = &rxq->rxds[i];
174 : 0 : rxd->fld.dd = 0;
175 : 0 : rxd->fld.dma_addr_hi = rte_cpu_to_le_16((dma_addr >> 32) & 0xffff);
176 : 0 : rxd->fld.dma_addr_lo = rte_cpu_to_le_32(dma_addr & 0xffffffff);
177 : :
178 : 0 : rxe[i].mbuf = mbuf;
179 : : }
180 : :
181 : : /* Make sure all writes are flushed before telling the hardware */
182 : : rte_wmb();
183 : :
184 : : /* Not advertising the whole ring as the firmware gets confused if so */
185 : : PMD_RX_LOG(DEBUG, "Increment FL write pointer in %hu.", rxq->rx_count - 1);
186 : :
187 : 0 : nfp_qcp_ptr_add(rxq->qcp_fl, NFP_QCP_WRITE_PTR, rxq->rx_count - 1);
188 : :
189 : 0 : return 0;
190 : : }
191 : :
192 : : int
193 : 0 : nfp_net_rx_freelist_setup(struct rte_eth_dev *dev)
194 : : {
195 : : uint16_t i;
196 : :
197 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
198 [ # # ]: 0 : if (nfp_net_rx_fill_freelist(dev->data->rx_queues[i]) != 0)
199 : : return -1;
200 : : }
201 : :
202 : : return 0;
203 : : }
204 : :
205 : : uint32_t
206 : 0 : nfp_net_rx_queue_count(void *rx_queue)
207 : : {
208 : : uint32_t idx;
209 : : uint32_t count = 0;
210 : : struct nfp_net_rxq *rxq;
211 : : struct nfp_net_rx_desc *rxds;
212 : :
213 : : rxq = rx_queue;
214 : 0 : idx = rxq->rd_p;
215 : :
216 : : /*
217 : : * Other PMDs are just checking the DD bit in intervals of 4
218 : : * descriptors and counting all four if the first has the DD
219 : : * bit on. Of course, this is not accurate but can be good for
220 : : * performance. But ideally that should be done in descriptors
221 : : * chunks belonging to the same cache line.
222 : : */
223 [ # # ]: 0 : while (count < rxq->rx_count) {
224 : 0 : rxds = &rxq->rxds[idx];
225 [ # # ]: 0 : if ((rxds->rxd.meta_len_dd & PCIE_DESC_RX_DD) == 0)
226 : : break;
227 : :
228 : 0 : count++;
229 : 0 : idx++;
230 : :
231 : : /* Wrapping */
232 [ # # ]: 0 : if ((idx) == rxq->rx_count)
233 : : idx = 0;
234 : : }
235 : :
236 : 0 : return count;
237 : : }
238 : :
239 : : /**
240 : : * Set packet type to mbuf based on parsed structure.
241 : : *
242 : : * @param nfp_ptype
243 : : * Packet type structure parsing from Rx descriptor.
244 : : * @param mb
245 : : * Mbuf to set the packet type.
246 : : */
247 : : static void
248 : 0 : nfp_net_set_ptype(const struct nfp_ptype_parsed *nfp_ptype,
249 : : struct rte_mbuf *mb)
250 : : {
251 : : uint32_t mbuf_ptype = RTE_PTYPE_L2_ETHER;
252 : 0 : uint8_t nfp_tunnel_ptype = nfp_ptype->tunnel_ptype;
253 : :
254 [ # # ]: 0 : if (nfp_tunnel_ptype != NFP_NET_PTYPE_TUNNEL_NONE)
255 : : mbuf_ptype |= RTE_PTYPE_INNER_L2_ETHER;
256 : :
257 [ # # # ]: 0 : switch (nfp_ptype->outer_l3_ptype) {
258 : : case NFP_NET_PTYPE_OUTER_L3_NONE:
259 : : break;
260 : 0 : case NFP_NET_PTYPE_OUTER_L3_IPV4:
261 : 0 : mbuf_ptype |= RTE_PTYPE_L3_IPV4;
262 : 0 : break;
263 : 0 : case NFP_NET_PTYPE_OUTER_L3_IPV6:
264 : 0 : mbuf_ptype |= RTE_PTYPE_L3_IPV6;
265 : 0 : break;
266 : : default:
267 : : PMD_RX_LOG(DEBUG, "Unrecognized nfp outer layer 3 packet type: %u.",
268 : : nfp_ptype->outer_l3_ptype);
269 : : break;
270 : : }
271 : :
272 [ # # # # ]: 0 : switch (nfp_tunnel_ptype) {
273 : : case NFP_NET_PTYPE_TUNNEL_NONE:
274 : : break;
275 : 0 : case NFP_NET_PTYPE_TUNNEL_VXLAN:
276 : 0 : mbuf_ptype |= RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L4_UDP;
277 : 0 : break;
278 : 0 : case NFP_NET_PTYPE_TUNNEL_NVGRE:
279 : 0 : mbuf_ptype |= RTE_PTYPE_TUNNEL_NVGRE;
280 : 0 : break;
281 : 0 : case NFP_NET_PTYPE_TUNNEL_GENEVE:
282 : 0 : mbuf_ptype |= RTE_PTYPE_TUNNEL_GENEVE | RTE_PTYPE_L4_UDP;
283 : 0 : break;
284 : : default:
285 : : PMD_RX_LOG(DEBUG, "Unrecognized nfp tunnel packet type: %u.",
286 : : nfp_tunnel_ptype);
287 : : break;
288 : : }
289 : :
290 [ # # # # : 0 : switch (nfp_ptype->l4_ptype) {
# # # ]
291 : : case NFP_NET_PTYPE_L4_NONE:
292 : : break;
293 : 0 : case NFP_NET_PTYPE_L4_TCP:
294 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_TCP);
295 : 0 : break;
296 : 0 : case NFP_NET_PTYPE_L4_UDP:
297 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_UDP);
298 : 0 : break;
299 : 0 : case NFP_NET_PTYPE_L4_FRAG:
300 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_FRAG);
301 : 0 : break;
302 : 0 : case NFP_NET_PTYPE_L4_NONFRAG:
303 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_NONFRAG);
304 : 0 : break;
305 : 0 : case NFP_NET_PTYPE_L4_ICMP:
306 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_ICMP);
307 : 0 : break;
308 : 0 : case NFP_NET_PTYPE_L4_SCTP:
309 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_SCTP);
310 : 0 : break;
311 : : default:
312 : : PMD_RX_LOG(DEBUG, "Unrecognized nfp layer 4 packet type: %u.",
313 : : nfp_ptype->l4_ptype);
314 : : break;
315 : : }
316 : :
317 [ # # # # : 0 : switch (nfp_ptype->l3_ptype) {
# # # ]
318 : : case NFP_NET_PTYPE_L3_NONE:
319 : : break;
320 : 0 : case NFP_NET_PTYPE_L3_IPV4:
321 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV4);
322 : 0 : break;
323 : 0 : case NFP_NET_PTYPE_L3_IPV6:
324 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV6);
325 : 0 : break;
326 : 0 : case NFP_NET_PTYPE_L3_IPV4_EXT:
327 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV4_EXT);
328 : 0 : break;
329 : 0 : case NFP_NET_PTYPE_L3_IPV6_EXT:
330 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV6_EXT);
331 : 0 : break;
332 : 0 : case NFP_NET_PTYPE_L3_IPV4_EXT_UNKNOWN:
333 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV4_EXT_UNKNOWN);
334 : 0 : break;
335 : 0 : case NFP_NET_PTYPE_L3_IPV6_EXT_UNKNOWN:
336 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV6_EXT_UNKNOWN);
337 : 0 : break;
338 : : default:
339 : : PMD_RX_LOG(DEBUG, "Unrecognized nfp layer 3 packet type: %u.",
340 : : nfp_ptype->l3_ptype);
341 : : break;
342 : : }
343 : :
344 : 0 : mb->packet_type = mbuf_ptype;
345 : 0 : }
346 : :
347 : : /**
348 : : * Parse the packet type from Rx descriptor and set to mbuf.
349 : : *
350 : : * @param rxq
351 : : * Rx queue
352 : : * @param rxds
353 : : * Rx descriptor including the offloading info of packet type.
354 : : * @param mb
355 : : * Mbuf to set the packet type.
356 : : */
357 : : void
358 : 0 : nfp_net_parse_ptype(struct nfp_net_rxq *rxq,
359 : : struct nfp_net_rx_desc *rxds,
360 : : struct rte_mbuf *mb)
361 : : {
362 : : uint16_t rxd_ptype;
363 : 0 : struct nfp_net_hw *hw = rxq->hw;
364 : : struct nfp_ptype_parsed nfp_ptype;
365 : :
366 [ # # ]: 0 : if ((hw->super.ctrl_ext & NFP_NET_CFG_CTRL_PKT_TYPE) == 0)
367 : 0 : return;
368 : :
369 : 0 : rxd_ptype = rte_le_to_cpu_16(rxds->rxd.offload_info);
370 [ # # # # ]: 0 : if (rxd_ptype == 0 || (rxds->rxd.flags & PCIE_DESC_RX_VLAN) != 0)
371 : : return;
372 : :
373 : 0 : nfp_ptype.l4_ptype = (rxd_ptype & NFP_NET_PTYPE_L4_MASK) >>
374 : : NFP_NET_PTYPE_L4_OFFSET;
375 : 0 : nfp_ptype.l3_ptype = (rxd_ptype & NFP_NET_PTYPE_L3_MASK) >>
376 : : NFP_NET_PTYPE_L3_OFFSET;
377 : 0 : nfp_ptype.tunnel_ptype = (rxd_ptype & NFP_NET_PTYPE_TUNNEL_MASK) >>
378 : : NFP_NET_PTYPE_TUNNEL_OFFSET;
379 : 0 : nfp_ptype.outer_l3_ptype = (rxd_ptype & NFP_NET_PTYPE_OUTER_L3_MASK) >>
380 : : NFP_NET_PTYPE_OUTER_L3_OFFSET;
381 : :
382 : 0 : nfp_net_set_ptype(&nfp_ptype, mb);
383 : : }
384 : :
385 : : /*
386 : : * RX path design:
387 : : *
388 : : * There are some decisions to take:
389 : : * 1) How to check DD RX descriptors bit
390 : : * 2) How and when to allocate new mbufs
391 : : *
392 : : * Current implementation checks just one single DD bit each loop. As each
393 : : * descriptor is 8 bytes, it is likely a good idea to check descriptors in
394 : : * a single cache line instead. Tests with this change have not shown any
395 : : * performance improvement but it requires further investigation. For example,
396 : : * depending on which descriptor is next, the number of descriptors could be
397 : : * less than 8 for just checking those in the same cache line. This implies
398 : : * extra work which could be counterproductive by itself. Indeed, last firmware
399 : : * changes are just doing this: writing several descriptors with the DD bit
400 : : * for saving PCIe bandwidth and DMA operations from the NFP.
401 : : *
402 : : * Mbuf allocation is done when a new packet is received. Then the descriptor
403 : : * is automatically linked with the new mbuf and the old one is given to the
404 : : * user. The main drawback with this design is mbuf allocation is heavier than
405 : : * using bulk allocations allowed by DPDK with rte_mempool_get_bulk. From the
406 : : * cache point of view it does not seem allocating the mbuf early on as we are
407 : : * doing now have any benefit at all. Again, tests with this change have not
408 : : * shown any improvement. Also, rte_mempool_get_bulk returns all or nothing
409 : : * so looking at the implications of this type of allocation should be studied
410 : : * deeply.
411 : : */
412 : : uint16_t
413 : 0 : nfp_net_recv_pkts(void *rx_queue,
414 : : struct rte_mbuf **rx_pkts,
415 : : uint16_t nb_pkts)
416 : : {
417 : : uint16_t data_len;
418 : : uint64_t dma_addr;
419 : : uint16_t avail = 0;
420 : : struct rte_mbuf *mb;
421 : : uint16_t nb_hold = 0;
422 : : struct nfp_net_hw *hw;
423 : : struct rte_mbuf *new_mb;
424 : : struct nfp_net_rxq *rxq;
425 : : struct nfp_pf_dev *pf_dev;
426 : : struct nfp_net_dp_buf *rxb;
427 : : struct nfp_net_rx_desc *rxds;
428 : : uint16_t avail_multiplexed = 0;
429 : :
430 : : rxq = rx_queue;
431 [ # # ]: 0 : if (unlikely(rxq == NULL)) {
432 : : /*
433 : : * DPDK just checks the queue is lower than max queues
434 : : * enabled. But the queue needs to be configured.
435 : : */
436 : : PMD_RX_LOG(ERR, "RX Bad queue.");
437 : : return 0;
438 : : }
439 : :
440 : 0 : hw = rxq->hw;
441 : 0 : pf_dev = rxq->hw_priv->pf_dev;
442 : :
443 [ # # ]: 0 : while (avail + avail_multiplexed < nb_pkts) {
444 : 0 : rxb = &rxq->rxbufs[rxq->rd_p];
445 [ # # ]: 0 : if (unlikely(rxb == NULL)) {
446 : : PMD_RX_LOG(ERR, "The rxb does not exist!");
447 : 0 : break;
448 : : }
449 : :
450 : 0 : rxds = &rxq->rxds[rxq->rd_p];
451 [ # # ]: 0 : if ((rxds->rxd.meta_len_dd & PCIE_DESC_RX_DD) == 0)
452 : : break;
453 : :
454 : : /*
455 : : * Memory barrier to ensure that we won't do other
456 : : * reads before the DD bit.
457 : : */
458 : : rte_rmb();
459 : :
460 : : /*
461 : : * We got a packet. Let's alloc a new mbuf for refilling the
462 : : * free descriptor ring as soon as possible.
463 : : */
464 : 0 : new_mb = rte_pktmbuf_alloc(rxq->mem_pool);
465 [ # # ]: 0 : if (unlikely(new_mb == NULL)) {
466 : : PMD_RX_LOG(DEBUG, "RX mbuf alloc failed port_id=%u queue_id=%hu.",
467 : : rxq->port_id, rxq->qidx);
468 : : nfp_net_mbuf_alloc_failed(rxq);
469 : : break;
470 : : }
471 : :
472 : : /*
473 : : * Grab the mbuf and refill the descriptor with the
474 : : * previously allocated mbuf.
475 : : */
476 : 0 : mb = rxb->mbuf;
477 : 0 : rxb->mbuf = new_mb;
478 : 0 : data_len = rte_le_to_cpu_16(rxds->rxd.data_len);
479 : :
480 : : PMD_RX_LOG(DEBUG, "Packet len: %u, mbuf_size: %u.",
481 : : data_len, rxq->mbuf_size);
482 : :
483 : : /* Size of this segment */
484 : 0 : mb->data_len = data_len - NFP_DESC_META_LEN(rxds);
485 : : /* Size of the whole packet. We just support 1 segment */
486 : 0 : mb->pkt_len = data_len - NFP_DESC_META_LEN(rxds);
487 : :
488 [ # # ]: 0 : if (unlikely((mb->data_len + hw->rx_offset) > rxq->mbuf_size)) {
489 : : /*
490 : : * This should not happen and the user has the
491 : : * responsibility of avoiding it. But we have
492 : : * to give some info about the error.
493 : : */
494 : : PMD_RX_LOG(ERR, "The mbuf overflow likely due to the RX offset.");
495 : 0 : rte_pktmbuf_free(mb);
496 : 0 : break;
497 : : }
498 : :
499 : : /* Filling the received mbuf with packet info */
500 [ # # ]: 0 : if (hw->rx_offset != 0)
501 : 0 : mb->data_off = RTE_PKTMBUF_HEADROOM + hw->rx_offset;
502 : : else
503 : 0 : mb->data_off = RTE_PKTMBUF_HEADROOM + NFP_DESC_META_LEN(rxds);
504 : :
505 : : /* No scatter mode supported */
506 : 0 : mb->nb_segs = 1;
507 : 0 : mb->next = NULL;
508 : 0 : mb->port = rxq->port_id;
509 : :
510 : : struct nfp_net_meta_parsed meta;
511 : 0 : nfp_net_meta_parse(rxds, rxq, hw, mb, &meta);
512 : :
513 : 0 : nfp_net_parse_ptype(rxq, rxds, mb);
514 : :
515 : : /* Checking the checksum flag */
516 : 0 : nfp_net_rx_cksum(rxq, rxds, mb);
517 : :
518 : : /* Now resetting and updating the descriptor */
519 [ # # ]: 0 : rxds->vals[0] = 0;
520 : : rxds->vals[1] = 0;
521 : : dma_addr = rte_mbuf_data_iova_default(new_mb);
522 : : rxds->fld.dd = 0;
523 : 0 : rxds->fld.dma_addr_hi = rte_cpu_to_le_16((dma_addr >> 32) & 0xffff);
524 : 0 : rxds->fld.dma_addr_lo = rte_cpu_to_le_32(dma_addr & 0xffffffff);
525 : 0 : nb_hold++;
526 : :
527 : 0 : rxq->rd_p++;
528 [ # # ]: 0 : if (unlikely(rxq->rd_p == rxq->rx_count)) /* Wrapping */
529 : 0 : rxq->rd_p = 0;
530 : :
531 [ # # ]: 0 : if (pf_dev->recv_pkt_meta_check_t(&meta)) {
532 : 0 : rx_pkts[avail++] = mb;
533 : : } else {
534 [ # # ]: 0 : if (nfp_flower_pf_dispatch_pkts(rxq, mb, meta.port_id)) {
535 : 0 : avail_multiplexed++;
536 : : } else {
537 : 0 : rte_pktmbuf_free(mb);
538 : 0 : break;
539 : : }
540 : : }
541 : : }
542 : :
543 [ # # ]: 0 : if (nb_hold == 0)
544 : : return nb_hold;
545 : :
546 : : PMD_RX_LOG(DEBUG, "RX port_id=%hu queue_id=%hu, %hu packets received.",
547 : : rxq->port_id, rxq->qidx, avail);
548 : :
549 : 0 : nb_hold += rxq->nb_rx_hold;
550 : :
551 : : /*
552 : : * FL descriptors needs to be written before incrementing the
553 : : * FL queue WR pointer.
554 : : */
555 : : rte_wmb();
556 [ # # ]: 0 : if (nb_hold > rxq->rx_free_thresh) {
557 : : PMD_RX_LOG(DEBUG, "The port=%hu queue=%hu nb_hold=%hu avail=%hu.",
558 : : rxq->port_id, rxq->qidx, nb_hold, avail);
559 : 0 : nfp_qcp_ptr_add(rxq->qcp_fl, NFP_QCP_WRITE_PTR, nb_hold);
560 : : nb_hold = 0;
561 : : }
562 : 0 : rxq->nb_rx_hold = nb_hold;
563 : :
564 : 0 : return avail;
565 : : }
566 : :
567 : : static void
568 : 0 : nfp_net_rx_queue_release_mbufs(struct nfp_net_rxq *rxq)
569 : : {
570 : : uint16_t i;
571 : :
572 [ # # ]: 0 : if (rxq->rxbufs == NULL)
573 : : return;
574 : :
575 [ # # ]: 0 : for (i = 0; i < rxq->rx_count; i++) {
576 [ # # ]: 0 : if (rxq->rxbufs[i].mbuf != NULL) {
577 : : rte_pktmbuf_free_seg(rxq->rxbufs[i].mbuf);
578 : 0 : rxq->rxbufs[i].mbuf = NULL;
579 : : }
580 : : }
581 : : }
582 : :
583 : : void
584 : 0 : nfp_net_rx_queue_release(struct rte_eth_dev *dev,
585 : : uint16_t queue_idx)
586 : : {
587 : 0 : struct nfp_net_rxq *rxq = dev->data->rx_queues[queue_idx];
588 : :
589 [ # # ]: 0 : if (rxq != NULL) {
590 : 0 : nfp_net_rx_queue_release_mbufs(rxq);
591 : 0 : rte_eth_dma_zone_free(dev, "rx_ring", queue_idx);
592 : 0 : rte_free(rxq->rxbufs);
593 : 0 : rte_free(rxq);
594 : : }
595 : 0 : }
596 : :
597 : : void
598 : 0 : nfp_net_reset_rx_queue(struct nfp_net_rxq *rxq)
599 : : {
600 : 0 : nfp_net_rx_queue_release_mbufs(rxq);
601 : 0 : rxq->rd_p = 0;
602 : 0 : rxq->nb_rx_hold = 0;
603 : 0 : }
604 : :
605 : : static void
606 : : nfp_rx_queue_setup_flbufsz(struct nfp_net_hw *hw,
607 : : struct nfp_net_rxq *rxq)
608 : : {
609 : 0 : if (!hw->flbufsz_set_flag) {
610 : 0 : hw->flbufsz_set_flag = true;
611 : 0 : hw->flbufsz = rxq->mbuf_size;
612 : 0 : return;
613 : : }
614 : :
615 [ # # ]: 0 : if (hw->flbufsz < rxq->mbuf_size)
616 : 0 : hw->flbufsz = rxq->mbuf_size;
617 : : }
618 : :
619 : : int
620 : 0 : nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
621 : : uint16_t queue_idx,
622 : : uint16_t nb_desc,
623 : : unsigned int socket_id,
624 : : const struct rte_eth_rxconf *rx_conf,
625 : : struct rte_mempool *mp)
626 : : {
627 : : uint32_t rx_desc_sz;
628 : : uint16_t min_rx_desc;
629 : : uint16_t max_rx_desc;
630 : : struct nfp_net_hw *hw;
631 : : struct nfp_net_rxq *rxq;
632 : : const struct rte_memzone *tz;
633 : : struct nfp_net_hw_priv *hw_priv;
634 : :
635 : 0 : hw = nfp_net_get_hw(dev);
636 : 0 : hw_priv = dev->process_private;
637 : :
638 : 0 : nfp_net_rx_desc_limits(hw_priv, &min_rx_desc, &max_rx_desc);
639 : :
640 : : /* Validating number of descriptors */
641 : 0 : rx_desc_sz = nb_desc * sizeof(struct nfp_net_rx_desc);
642 [ # # ]: 0 : if (rx_desc_sz % NFP_ALIGN_RING_DESC != 0 ||
643 [ # # # # ]: 0 : nb_desc > max_rx_desc || nb_desc < min_rx_desc) {
644 : 0 : PMD_DRV_LOG(ERR, "Wrong nb_desc value.");
645 : 0 : return -EINVAL;
646 : : }
647 : :
648 : : /*
649 : : * Free memory prior to re-allocation if needed. This is the case after
650 : : * calling @nfp_net_stop().
651 : : */
652 [ # # ]: 0 : if (dev->data->rx_queues[queue_idx] != NULL) {
653 : 0 : nfp_net_rx_queue_release(dev, queue_idx);
654 : 0 : dev->data->rx_queues[queue_idx] = NULL;
655 : : }
656 : :
657 : : /* Allocating rx queue data structure */
658 : 0 : rxq = rte_zmalloc_socket("ethdev RX queue", sizeof(struct nfp_net_rxq),
659 : : RTE_CACHE_LINE_SIZE, socket_id);
660 [ # # ]: 0 : if (rxq == NULL)
661 : : return -ENOMEM;
662 : :
663 : 0 : dev->data->rx_queues[queue_idx] = rxq;
664 : :
665 : : /* Hw queues mapping based on firmware configuration */
666 : 0 : rxq->qidx = queue_idx;
667 : 0 : rxq->fl_qcidx = queue_idx * hw->stride_rx;
668 : 0 : rxq->qcp_fl = hw->rx_bar + NFP_QCP_QUEUE_OFF(rxq->fl_qcidx);
669 : :
670 : : /*
671 : : * Tracking mbuf size for detecting a potential mbuf overflow due to
672 : : * RX offset.
673 : : */
674 : 0 : rxq->mem_pool = mp;
675 : 0 : rxq->mbuf_size = rxq->mem_pool->elt_size;
676 [ # # ]: 0 : rxq->mbuf_size -= (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);
677 : : nfp_rx_queue_setup_flbufsz(hw, rxq);
678 : :
679 : 0 : rxq->rx_count = nb_desc;
680 : 0 : rxq->port_id = dev->data->port_id;
681 : 0 : rxq->rx_free_thresh = rx_conf->rx_free_thresh;
682 : :
683 : : /*
684 : : * Allocate RX ring hardware descriptors. A memzone large enough to
685 : : * handle the maximum ring size is allocated in order to allow for
686 : : * resizing in later calls to the queue setup function.
687 : : */
688 : 0 : tz = rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
689 : : sizeof(struct nfp_net_rx_desc) * max_rx_desc,
690 : : NFP_MEMZONE_ALIGN, socket_id);
691 [ # # ]: 0 : if (tz == NULL) {
692 : 0 : PMD_DRV_LOG(ERR, "Error allocating rx dma.");
693 : 0 : nfp_net_rx_queue_release(dev, queue_idx);
694 : 0 : dev->data->rx_queues[queue_idx] = NULL;
695 : 0 : return -ENOMEM;
696 : : }
697 : :
698 : : /* Saving physical and virtual addresses for the RX ring */
699 : 0 : rxq->dma = (uint64_t)tz->iova;
700 : 0 : rxq->rxds = tz->addr;
701 : :
702 : : /* Mbuf pointers array for referencing mbufs linked to RX descriptors */
703 : 0 : rxq->rxbufs = rte_zmalloc_socket("rxq->rxbufs",
704 : : sizeof(*rxq->rxbufs) * nb_desc, RTE_CACHE_LINE_SIZE,
705 : : socket_id);
706 [ # # ]: 0 : if (rxq->rxbufs == NULL) {
707 : 0 : nfp_net_rx_queue_release(dev, queue_idx);
708 : 0 : dev->data->rx_queues[queue_idx] = NULL;
709 : 0 : return -ENOMEM;
710 : : }
711 : :
712 : 0 : nfp_net_reset_rx_queue(rxq);
713 : :
714 : 0 : rxq->hw = hw;
715 : 0 : rxq->hw_priv = dev->process_private;
716 : :
717 : : /*
718 : : * Telling the HW about the physical address of the RX ring and number
719 : : * of descriptors in log2 format.
720 : : */
721 : 0 : nn_cfg_writeq(&hw->super, NFP_NET_CFG_RXR_ADDR(queue_idx), rxq->dma);
722 : 0 : nn_cfg_writeb(&hw->super, NFP_NET_CFG_RXR_SZ(queue_idx), rte_log2_u32(nb_desc));
723 : :
724 : 0 : return 0;
725 : : }
726 : :
727 : : static inline uint32_t
728 : : nfp_net_read_tx_free_qcp(struct nfp_net_txq *txq)
729 : : {
730 : : /*
731 : : * If TX ring pointer write back is not supported, do a PCIe read.
732 : : * Otherwise read qcp value from write back dma address.
733 : : */
734 : 0 : if (txq->txrwb == NULL)
735 : 0 : return nfp_qcp_read(txq->qcp_q, NFP_QCP_READ_PTR);
736 : :
737 : : /*
738 : : * In most cases the TX count is a power of two and the costly modulus
739 : : * operation can be substituted with a subtraction and an AND operation.
740 : : */
741 [ # # ]: 0 : if (rte_is_power_of_2(txq->tx_count) == 1)
742 : 0 : return (*txq->txrwb) & (txq->tx_count - 1);
743 : : else
744 : 0 : return (*txq->txrwb) % txq->tx_count;
745 : : }
746 : :
747 : : /**
748 : : * Check for descriptors with a complete status
749 : : *
750 : : * @param txq
751 : : * TX queue to work with
752 : : *
753 : : * @return
754 : : * Number of descriptors freed
755 : : */
756 : : uint32_t
757 [ # # ]: 0 : nfp_net_tx_free_bufs(struct nfp_net_txq *txq)
758 : : {
759 : : uint32_t todo;
760 : : uint32_t qcp_rd_p;
761 : :
762 : : PMD_TX_LOG(DEBUG, "Queue %hu. Check for descriptor with a complete"
763 : : " status.", txq->qidx);
764 : :
765 : : /* Work out how many packets have been sent */
766 : : qcp_rd_p = nfp_net_read_tx_free_qcp(txq);
767 : :
768 [ # # ]: 0 : if (qcp_rd_p == txq->rd_p) {
769 : : PMD_TX_LOG(DEBUG, "Queue %hu: It seems harrier is not sending "
770 : : "packets (%u, %u).", txq->qidx,
771 : : qcp_rd_p, txq->rd_p);
772 : : return 0;
773 : : }
774 : :
775 [ # # ]: 0 : if (qcp_rd_p > txq->rd_p)
776 : 0 : todo = qcp_rd_p - txq->rd_p;
777 : : else
778 : 0 : todo = qcp_rd_p + txq->tx_count - txq->rd_p;
779 : :
780 : : PMD_TX_LOG(DEBUG, "The qcp_rd_p %u, txq->rd_p: %u, qcp->rd_p: %u.",
781 : : qcp_rd_p, txq->rd_p, txq->rd_p);
782 : :
783 [ # # ]: 0 : if (todo == 0)
784 : : return todo;
785 : :
786 : 0 : txq->rd_p += todo;
787 [ # # ]: 0 : if (unlikely(txq->rd_p >= txq->tx_count))
788 : 0 : txq->rd_p -= txq->tx_count;
789 : :
790 : : return todo;
791 : : }
792 : :
793 : : static void
794 : 0 : nfp_net_tx_queue_release_mbufs(struct nfp_net_txq *txq)
795 : : {
796 : : uint32_t i;
797 : :
798 [ # # ]: 0 : if (txq->txbufs == NULL)
799 : : return;
800 : :
801 [ # # ]: 0 : for (i = 0; i < txq->tx_count; i++) {
802 [ # # ]: 0 : if (txq->txbufs[i].mbuf != NULL) {
803 : : rte_pktmbuf_free_seg(txq->txbufs[i].mbuf);
804 : 0 : txq->txbufs[i].mbuf = NULL;
805 : : }
806 : : }
807 : : }
808 : :
809 : : void
810 : 0 : nfp_net_tx_queue_release(struct rte_eth_dev *dev,
811 : : uint16_t queue_idx)
812 : : {
813 : : struct nfp_net_hw *net_hw;
814 : 0 : struct nfp_net_txq *txq = dev->data->tx_queues[queue_idx];
815 : :
816 [ # # ]: 0 : if (txq != NULL) {
817 : 0 : net_hw = nfp_net_get_hw(dev);
818 [ # # ]: 0 : if (net_hw->txrwb_mz != NULL)
819 : 0 : nn_cfg_writeq(&net_hw->super, NFP_NET_CFG_TXR_WB_ADDR(queue_idx), 0);
820 : 0 : nfp_net_tx_queue_release_mbufs(txq);
821 : 0 : rte_eth_dma_zone_free(dev, "tx_ring", queue_idx);
822 : 0 : rte_free(txq->txbufs);
823 : 0 : rte_free(txq);
824 : : }
825 : 0 : }
826 : :
827 : : void
828 : 0 : nfp_net_reset_tx_queue(struct nfp_net_txq *txq)
829 : : {
830 : 0 : nfp_net_tx_queue_release_mbufs(txq);
831 : 0 : txq->wr_p = 0;
832 : 0 : txq->rd_p = 0;
833 [ # # ]: 0 : if (txq->txrwb != NULL)
834 : 0 : *txq->txrwb = 0;
835 : 0 : }
836 : :
837 : : int
838 : 0 : nfp_net_tx_queue_setup(struct rte_eth_dev *dev,
839 : : uint16_t queue_idx,
840 : : uint16_t nb_desc,
841 : : unsigned int socket_id,
842 : : const struct rte_eth_txconf *tx_conf)
843 : : {
844 : : struct nfp_net_hw_priv *hw_priv;
845 : :
846 : 0 : hw_priv = dev->process_private;
847 : :
848 [ # # ]: 0 : if (hw_priv->pf_dev->ver.extend == NFP_NET_CFG_VERSION_DP_NFD3)
849 : 0 : return nfp_net_nfd3_tx_queue_setup(dev, queue_idx,
850 : : nb_desc, socket_id, tx_conf);
851 : : else
852 : 0 : return nfp_net_nfdk_tx_queue_setup(dev, queue_idx,
853 : : nb_desc, socket_id, tx_conf);
854 : : }
855 : :
856 : : void
857 : 0 : nfp_net_rx_queue_info_get(struct rte_eth_dev *dev,
858 : : uint16_t queue_id,
859 : : struct rte_eth_rxq_info *info)
860 : : {
861 : : struct rte_eth_dev_info dev_info;
862 : 0 : struct nfp_net_rxq *rxq = dev->data->rx_queues[queue_id];
863 : :
864 : 0 : info->mp = rxq->mem_pool;
865 : 0 : info->nb_desc = rxq->rx_count;
866 : :
867 : 0 : info->conf.rx_free_thresh = rxq->rx_free_thresh;
868 : :
869 : 0 : nfp_net_infos_get(dev, &dev_info);
870 : 0 : info->conf.offloads = dev_info.rx_offload_capa &
871 : 0 : dev->data->dev_conf.rxmode.offloads;
872 : 0 : info->conf.rx_thresh = dev_info.default_rxconf.rx_thresh;
873 : 0 : }
874 : :
875 : : void
876 : 0 : nfp_net_tx_queue_info_get(struct rte_eth_dev *dev,
877 : : uint16_t queue_id,
878 : : struct rte_eth_txq_info *info)
879 : : {
880 : : struct rte_eth_dev_info dev_info;
881 : 0 : struct nfp_net_hw_priv *hw_priv = dev->process_private;
882 : 0 : struct nfp_net_txq *txq = dev->data->tx_queues[queue_id];
883 : :
884 [ # # ]: 0 : if (hw_priv->pf_dev->ver.extend == NFP_NET_CFG_VERSION_DP_NFD3)
885 : 0 : info->nb_desc = txq->tx_count / NFD3_TX_DESC_PER_PKT;
886 : : else
887 : 0 : info->nb_desc = txq->tx_count / NFDK_TX_DESC_PER_SIMPLE_PKT;
888 : :
889 : 0 : info->conf.tx_free_thresh = txq->tx_free_thresh;
890 : :
891 : 0 : nfp_net_infos_get(dev, &dev_info);
892 : 0 : info->conf.offloads = dev_info.tx_offload_capa &
893 : 0 : dev->data->dev_conf.txmode.offloads;
894 : 0 : info->conf.tx_thresh = dev_info.default_txconf.tx_thresh;
895 : 0 : }
896 : :
897 : : void
898 : 0 : nfp_net_recv_pkts_set(struct rte_eth_dev *eth_dev)
899 : : {
900 [ # # ]: 0 : if (nfp_net_get_avx2_supported())
901 : 0 : eth_dev->rx_pkt_burst = nfp_net_vec_avx2_recv_pkts;
902 : : else
903 : 0 : eth_dev->rx_pkt_burst = nfp_net_recv_pkts;
904 : 0 : }
905 : :
906 : : int
907 : 0 : nfp_net_rx_burst_mode_get(struct rte_eth_dev *eth_dev,
908 : : uint16_t queue_id __rte_unused,
909 : : struct rte_eth_burst_mode *mode)
910 : : {
911 : : eth_rx_burst_t pkt_burst;
912 : :
913 : 0 : pkt_burst = eth_dev->rx_pkt_burst;
914 [ # # ]: 0 : if (pkt_burst == nfp_net_recv_pkts) {
915 : 0 : strlcpy(mode->info, "Scalar",
916 : : RTE_ETH_BURST_MODE_INFO_SIZE);
917 [ # # ]: 0 : } else if (pkt_burst == nfp_net_vec_avx2_recv_pkts) {
918 : 0 : strlcpy(mode->info, "Vector AVX2",
919 : : RTE_ETH_BURST_MODE_INFO_SIZE);
920 : : } else {
921 : : return -EINVAL;
922 : : }
923 : :
924 : : return 0;
925 : : }
926 : :
927 : : int
928 : 0 : nfp_net_tx_burst_mode_get(struct rte_eth_dev *eth_dev,
929 : : uint16_t queue_id __rte_unused,
930 : : struct rte_eth_burst_mode *mode)
931 : : {
932 : : eth_tx_burst_t pkt_burst;
933 : :
934 : 0 : pkt_burst = eth_dev->tx_pkt_burst;
935 [ # # ]: 0 : if (pkt_burst == nfp_net_nfd3_xmit_pkts) {
936 : 0 : strlcpy(mode->info, "NFD3 Scalar",
937 : : RTE_ETH_BURST_MODE_INFO_SIZE);
938 [ # # ]: 0 : } else if (pkt_burst == nfp_net_nfdk_xmit_pkts) {
939 : 0 : strlcpy(mode->info, "NFDk Scalar",
940 : : RTE_ETH_BURST_MODE_INFO_SIZE);
941 [ # # ]: 0 : } else if (pkt_burst == nfp_net_nfdk_vec_avx2_xmit_pkts) {
942 : 0 : strlcpy(mode->info, "NFDk Vector AVX2",
943 : : RTE_ETH_BURST_MODE_INFO_SIZE);
944 : : } else {
945 : : return -EINVAL;
946 : : }
947 : :
948 : : return 0;
949 : : }
|