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