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 : :
20 : : /* Maximum number of supported VLANs in parsed form packet metadata. */
21 : : #define NFP_META_MAX_VLANS 2
22 : :
23 : : /* Record metadata parsed from packet */
24 : : struct nfp_meta_parsed {
25 : : uint32_t port_id; /**< Port id value */
26 : : uint32_t sa_idx; /**< IPsec SA index */
27 : : uint32_t hash; /**< RSS hash value */
28 : : uint8_t hash_type; /**< RSS hash type */
29 : : uint8_t ipsec_type; /**< IPsec type */
30 : : uint8_t vlan_layer; /**< The valid number of value in @vlan[] */
31 : : /**
32 : : * Holds information parses from NFP_NET_META_VLAN.
33 : : * The inner most vlan starts at position 0
34 : : */
35 : : struct {
36 : : uint8_t offload; /**< Flag indicates whether VLAN is offloaded */
37 : : uint8_t tpid; /**< Vlan TPID */
38 : : uint16_t tci; /**< Vlan TCI (PCP + Priority + VID) */
39 : : } vlan[NFP_META_MAX_VLANS];
40 : : };
41 : :
42 : : /*
43 : : * The bit format and map of nfp packet type for rxd.offload_info in Rx descriptor.
44 : : *
45 : : * Bit format about nfp packet type refers to the following:
46 : : * ---------------------------------
47 : : * 1 0
48 : : * 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
49 : : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 : : * | |ol3|tunnel | l3 | l4 |
51 : : * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 : : *
53 : : * Bit map about nfp packet type refers to the following:
54 : : *
55 : : * L4: bit 0~2, used for layer 4 or inner layer 4.
56 : : * 000: NFP_NET_PTYPE_L4_NONE
57 : : * 001: NFP_NET_PTYPE_L4_TCP
58 : : * 010: NFP_NET_PTYPE_L4_UDP
59 : : * 011: NFP_NET_PTYPE_L4_FRAG
60 : : * 100: NFP_NET_PTYPE_L4_NONFRAG
61 : : * 101: NFP_NET_PTYPE_L4_ICMP
62 : : * 110: NFP_NET_PTYPE_L4_SCTP
63 : : * 111: reserved
64 : : *
65 : : * L3: bit 3~5, used for layer 3 or inner layer 3.
66 : : * 000: NFP_NET_PTYPE_L3_NONE
67 : : * 001: NFP_NET_PTYPE_L3_IPV6
68 : : * 010: NFP_NET_PTYPE_L3_IPV4
69 : : * 011: NFP_NET_PTYPE_L3_IPV4_EXT
70 : : * 100: NFP_NET_PTYPE_L3_IPV6_EXT
71 : : * 101: NFP_NET_PTYPE_L3_IPV4_EXT_UNKNOWN
72 : : * 110: NFP_NET_PTYPE_L3_IPV6_EXT_UNKNOWN
73 : : * 111: reserved
74 : : *
75 : : * Tunnel: bit 6~9, used for tunnel.
76 : : * 0000: NFP_NET_PTYPE_TUNNEL_NONE
77 : : * 0001: NFP_NET_PTYPE_TUNNEL_VXLAN
78 : : * 0100: NFP_NET_PTYPE_TUNNEL_NVGRE
79 : : * 0101: NFP_NET_PTYPE_TUNNEL_GENEVE
80 : : * 0010, 0011, 0110~1111: reserved
81 : : *
82 : : * Outer L3: bit 10~11, used for outer layer 3.
83 : : * 00: NFP_NET_PTYPE_OUTER_L3_NONE
84 : : * 01: NFP_NET_PTYPE_OUTER_L3_IPV6
85 : : * 10: NFP_NET_PTYPE_OUTER_L3_IPV4
86 : : * 11: reserved
87 : : *
88 : : * Reserved: bit 10~15, used for extension.
89 : : */
90 : :
91 : : /* Mask and offset about nfp packet type based on the bit map above. */
92 : : #define NFP_NET_PTYPE_L4_MASK 0x0007
93 : : #define NFP_NET_PTYPE_L3_MASK 0x0038
94 : : #define NFP_NET_PTYPE_TUNNEL_MASK 0x03c0
95 : : #define NFP_NET_PTYPE_OUTER_L3_MASK 0x0c00
96 : :
97 : : #define NFP_NET_PTYPE_L4_OFFSET 0
98 : : #define NFP_NET_PTYPE_L3_OFFSET 3
99 : : #define NFP_NET_PTYPE_TUNNEL_OFFSET 6
100 : : #define NFP_NET_PTYPE_OUTER_L3_OFFSET 10
101 : :
102 : : /* Case about nfp packet type based on the bit map above. */
103 : : #define NFP_NET_PTYPE_L4_NONE 0
104 : : #define NFP_NET_PTYPE_L4_TCP 1
105 : : #define NFP_NET_PTYPE_L4_UDP 2
106 : : #define NFP_NET_PTYPE_L4_FRAG 3
107 : : #define NFP_NET_PTYPE_L4_NONFRAG 4
108 : : #define NFP_NET_PTYPE_L4_ICMP 5
109 : : #define NFP_NET_PTYPE_L4_SCTP 6
110 : :
111 : : #define NFP_NET_PTYPE_L3_NONE 0
112 : : #define NFP_NET_PTYPE_L3_IPV6 1
113 : : #define NFP_NET_PTYPE_L3_IPV4 2
114 : : #define NFP_NET_PTYPE_L3_IPV4_EXT 3
115 : : #define NFP_NET_PTYPE_L3_IPV6_EXT 4
116 : : #define NFP_NET_PTYPE_L3_IPV4_EXT_UNKNOWN 5
117 : : #define NFP_NET_PTYPE_L3_IPV6_EXT_UNKNOWN 6
118 : :
119 : : #define NFP_NET_PTYPE_TUNNEL_NONE 0
120 : : #define NFP_NET_PTYPE_TUNNEL_VXLAN 1
121 : : #define NFP_NET_PTYPE_TUNNEL_NVGRE 4
122 : : #define NFP_NET_PTYPE_TUNNEL_GENEVE 5
123 : :
124 : : #define NFP_NET_PTYPE_OUTER_L3_NONE 0
125 : : #define NFP_NET_PTYPE_OUTER_L3_IPV6 1
126 : : #define NFP_NET_PTYPE_OUTER_L3_IPV4 2
127 : :
128 : : #define NFP_PTYPE2RTE(tunnel, type) ((tunnel) ? RTE_PTYPE_INNER_##type : RTE_PTYPE_##type)
129 : :
130 : : /* Record NFP packet type parsed from rxd.offload_info. */
131 : : struct nfp_ptype_parsed {
132 : : uint8_t l4_ptype; /**< Packet type of layer 4, or inner layer 4. */
133 : : uint8_t l3_ptype; /**< Packet type of layer 3, or inner layer 3. */
134 : : uint8_t tunnel_ptype; /**< Packet type of tunnel. */
135 : : uint8_t outer_l3_ptype; /**< Packet type of outer layer 3. */
136 : : };
137 : :
138 : : /* Set mbuf checksum flags based on RX descriptor flags */
139 : : void
140 : 0 : nfp_net_rx_cksum(struct nfp_net_rxq *rxq,
141 : : struct nfp_net_rx_desc *rxd,
142 : : struct rte_mbuf *mb)
143 : : {
144 : 0 : struct nfp_net_hw *hw = rxq->hw;
145 : :
146 [ # # ]: 0 : if ((hw->super.ctrl & NFP_NET_CFG_CTRL_RXCSUM) == 0)
147 : : return;
148 : :
149 : : /* If IPv4 and IP checksum error, fail */
150 [ # # ]: 0 : if (unlikely((rxd->rxd.flags & PCIE_DESC_RX_IP4_CSUM) != 0 &&
151 : : (rxd->rxd.flags & PCIE_DESC_RX_IP4_CSUM_OK) == 0))
152 : 0 : mb->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_BAD;
153 : : else
154 : 0 : mb->ol_flags |= RTE_MBUF_F_RX_IP_CKSUM_GOOD;
155 : :
156 : : /* If neither UDP nor TCP return */
157 [ # # ]: 0 : if ((rxd->rxd.flags & PCIE_DESC_RX_TCP_CSUM) == 0 &&
158 : : (rxd->rxd.flags & PCIE_DESC_RX_UDP_CSUM) == 0)
159 : : return;
160 : :
161 [ # # ]: 0 : if (likely(rxd->rxd.flags & PCIE_DESC_RX_L4_CSUM_OK) != 0)
162 : 0 : mb->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_GOOD;
163 : : else
164 : 0 : mb->ol_flags |= RTE_MBUF_F_RX_L4_CKSUM_BAD;
165 : : }
166 : :
167 : : static int
168 : 0 : nfp_net_rx_fill_freelist(struct nfp_net_rxq *rxq)
169 : : {
170 : : uint16_t i;
171 : : uint64_t dma_addr;
172 : 0 : struct nfp_net_dp_buf *rxe = rxq->rxbufs;
173 : :
174 : : PMD_RX_LOG(DEBUG, "Fill Rx Freelist for %hu descriptors",
175 : : rxq->rx_count);
176 : :
177 [ # # ]: 0 : for (i = 0; i < rxq->rx_count; i++) {
178 : : struct nfp_net_rx_desc *rxd;
179 : 0 : struct rte_mbuf *mbuf = rte_pktmbuf_alloc(rxq->mem_pool);
180 : :
181 [ # # ]: 0 : if (mbuf == NULL) {
182 : 0 : PMD_DRV_LOG(ERR, "RX mbuf alloc failed queue_id=%hu",
183 : : rxq->qidx);
184 : 0 : return -ENOMEM;
185 : : }
186 : :
187 : : dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova_default(mbuf));
188 : :
189 : 0 : rxd = &rxq->rxds[i];
190 : 0 : rxd->fld.dd = 0;
191 : 0 : rxd->fld.dma_addr_hi = (dma_addr >> 32) & 0xffff;
192 : 0 : rxd->fld.dma_addr_lo = dma_addr & 0xffffffff;
193 : :
194 : 0 : rxe[i].mbuf = mbuf;
195 : : }
196 : :
197 : : /* Make sure all writes are flushed before telling the hardware */
198 : : rte_wmb();
199 : :
200 : : /* Not advertising the whole ring as the firmware gets confused if so */
201 : : PMD_RX_LOG(DEBUG, "Increment FL write pointer in %hu", rxq->rx_count - 1);
202 : :
203 : 0 : nfp_qcp_ptr_add(rxq->qcp_fl, NFP_QCP_WRITE_PTR, rxq->rx_count - 1);
204 : :
205 : 0 : return 0;
206 : : }
207 : :
208 : : int
209 : 0 : nfp_net_rx_freelist_setup(struct rte_eth_dev *dev)
210 : : {
211 : : uint16_t i;
212 : :
213 [ # # ]: 0 : for (i = 0; i < dev->data->nb_rx_queues; i++) {
214 [ # # ]: 0 : if (nfp_net_rx_fill_freelist(dev->data->rx_queues[i]) != 0)
215 : : return -1;
216 : : }
217 : :
218 : : return 0;
219 : : }
220 : :
221 : : uint32_t
222 : 0 : nfp_net_rx_queue_count(void *rx_queue)
223 : : {
224 : : uint32_t idx;
225 : : uint32_t count = 0;
226 : : struct nfp_net_rxq *rxq;
227 : : struct nfp_net_rx_desc *rxds;
228 : :
229 : : rxq = rx_queue;
230 : 0 : idx = rxq->rd_p;
231 : :
232 : : /*
233 : : * Other PMDs are just checking the DD bit in intervals of 4
234 : : * descriptors and counting all four if the first has the DD
235 : : * bit on. Of course, this is not accurate but can be good for
236 : : * performance. But ideally that should be done in descriptors
237 : : * chunks belonging to the same cache line.
238 : : */
239 [ # # ]: 0 : while (count < rxq->rx_count) {
240 : 0 : rxds = &rxq->rxds[idx];
241 [ # # ]: 0 : if ((rxds->rxd.meta_len_dd & PCIE_DESC_RX_DD) == 0)
242 : : break;
243 : :
244 : 0 : count++;
245 : 0 : idx++;
246 : :
247 : : /* Wrapping */
248 [ # # ]: 0 : if ((idx) == rxq->rx_count)
249 : : idx = 0;
250 : : }
251 : :
252 : 0 : return count;
253 : : }
254 : :
255 : : /* Parse the chained metadata from packet */
256 : : static bool
257 : 0 : nfp_net_parse_chained_meta(uint8_t *meta_base,
258 : : rte_be32_t meta_header,
259 : : struct nfp_meta_parsed *meta)
260 : : {
261 : : uint32_t meta_info;
262 : : uint32_t vlan_info;
263 : : uint8_t *meta_offset;
264 : :
265 [ # # ]: 0 : meta_info = rte_be_to_cpu_32(meta_header);
266 : 0 : meta_offset = meta_base + 4;
267 : :
268 [ # # ]: 0 : for (; meta_info != 0; meta_info >>= NFP_NET_META_FIELD_SIZE, meta_offset += 4) {
269 [ # # # # : 0 : switch (meta_info & NFP_NET_META_FIELD_MASK) {
# ]
270 : 0 : case NFP_NET_META_PORTID:
271 [ # # ]: 0 : meta->port_id = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
272 : 0 : break;
273 : 0 : case NFP_NET_META_HASH:
274 : : /* Next field type is about the hash type */
275 : 0 : meta_info >>= NFP_NET_META_FIELD_SIZE;
276 : : /* Hash value is in the data field */
277 [ # # ]: 0 : meta->hash = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
278 : 0 : meta->hash_type = meta_info & NFP_NET_META_FIELD_MASK;
279 : 0 : break;
280 : 0 : case NFP_NET_META_VLAN:
281 [ # # ]: 0 : vlan_info = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
282 : 0 : meta->vlan[meta->vlan_layer].offload =
283 : 0 : vlan_info >> NFP_NET_META_VLAN_OFFLOAD;
284 : 0 : meta->vlan[meta->vlan_layer].tci =
285 : : vlan_info & NFP_NET_META_VLAN_MASK;
286 : 0 : meta->vlan[meta->vlan_layer].tpid = NFP_NET_META_TPID(vlan_info);
287 : 0 : meta->vlan_layer++;
288 : 0 : break;
289 : 0 : case NFP_NET_META_IPSEC:
290 [ # # ]: 0 : meta->sa_idx = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
291 : 0 : meta->ipsec_type = meta_info & NFP_NET_META_FIELD_MASK;
292 : 0 : break;
293 : : default:
294 : : /* Unsupported metadata can be a performance issue */
295 : : return false;
296 : : }
297 : : }
298 : :
299 : : return true;
300 : : }
301 : :
302 : : /* Set mbuf hash data based on the metadata info */
303 : : static void
304 : : nfp_net_parse_meta_hash(const struct nfp_meta_parsed *meta,
305 : : struct nfp_net_rxq *rxq,
306 : : struct rte_mbuf *mbuf)
307 : : {
308 : 0 : struct nfp_net_hw *hw = rxq->hw;
309 : :
310 [ # # # # ]: 0 : if ((hw->super.ctrl & NFP_NET_CFG_CTRL_RSS_ANY) == 0)
311 : : return;
312 : :
313 : 0 : mbuf->hash.rss = meta->hash;
314 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
315 : : }
316 : :
317 : : /*
318 : : * Parse the single metadata
319 : : *
320 : : * The RSS hash and hash-type are prepended to the packet data.
321 : : * Get it from metadata area.
322 : : */
323 : : static inline void
324 : 0 : nfp_net_parse_single_meta(uint8_t *meta_base,
325 : : rte_be32_t meta_header,
326 : : struct nfp_meta_parsed *meta)
327 : : {
328 [ # # ]: 0 : meta->hash_type = rte_be_to_cpu_32(meta_header);
329 [ # # ]: 0 : meta->hash = rte_be_to_cpu_32(*(rte_be32_t *)(meta_base + 4));
330 : 0 : }
331 : :
332 : : /* Set mbuf vlan_strip data based on metadata info */
333 : : static void
334 : 0 : nfp_net_parse_meta_vlan(const struct nfp_meta_parsed *meta,
335 : : struct nfp_net_rx_desc *rxd,
336 : : struct nfp_net_rxq *rxq,
337 : : struct rte_mbuf *mb)
338 : : {
339 : 0 : uint32_t ctrl = rxq->hw->super.ctrl;
340 : :
341 : : /* Skip if hardware don't support setting vlan. */
342 [ # # ]: 0 : if ((ctrl & (NFP_NET_CFG_CTRL_RXVLAN | NFP_NET_CFG_CTRL_RXVLAN_V2)) == 0)
343 : : return;
344 : :
345 : : /*
346 : : * The firmware support two ways to send the VLAN info (with priority) :
347 : : * 1. Using the metadata when NFP_NET_CFG_CTRL_RXVLAN_V2 is set,
348 : : * 2. Using the descriptor when NFP_NET_CFG_CTRL_RXVLAN is set.
349 : : */
350 [ # # ]: 0 : if ((ctrl & NFP_NET_CFG_CTRL_RXVLAN_V2) != 0) {
351 [ # # # # ]: 0 : if (meta->vlan_layer > 0 && meta->vlan[0].offload != 0) {
352 : 0 : mb->vlan_tci = rte_cpu_to_le_32(meta->vlan[0].tci);
353 : 0 : mb->ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
354 : : }
355 [ # # ]: 0 : } else if ((ctrl & NFP_NET_CFG_CTRL_RXVLAN) != 0) {
356 [ # # ]: 0 : if ((rxd->rxd.flags & PCIE_DESC_RX_VLAN) != 0) {
357 : 0 : mb->vlan_tci = rte_cpu_to_le_32(rxd->rxd.offload_info);
358 : 0 : mb->ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
359 : : }
360 : : }
361 : : }
362 : :
363 : : /*
364 : : * Set mbuf qinq_strip data based on metadata info
365 : : *
366 : : * The out VLAN tci are prepended to the packet data.
367 : : * Extract and decode it and set the mbuf fields.
368 : : *
369 : : * If both RTE_MBUF_F_RX_VLAN and NFP_NET_CFG_CTRL_RXQINQ are set, the 2 VLANs
370 : : * have been stripped by the hardware and their TCIs are saved in
371 : : * mbuf->vlan_tci (inner) and mbuf->vlan_tci_outer (outer).
372 : : * If NFP_NET_CFG_CTRL_RXQINQ is set and RTE_MBUF_F_RX_VLAN is unset, only the
373 : : * outer VLAN is removed from packet data, but both tci are saved in
374 : : * mbuf->vlan_tci (inner) and mbuf->vlan_tci_outer (outer).
375 : : *
376 : : * qinq set & vlan set : meta->vlan_layer>=2, meta->vlan[0].offload=1, meta->vlan[1].offload=1
377 : : * qinq set & vlan not set: meta->vlan_layer>=2, meta->vlan[1].offload=1,meta->vlan[0].offload=0
378 : : * qinq not set & vlan set: meta->vlan_layer=1, meta->vlan[0].offload=1
379 : : * qinq not set & vlan not set: meta->vlan_layer=0
380 : : */
381 : : static void
382 : : nfp_net_parse_meta_qinq(const struct nfp_meta_parsed *meta,
383 : : struct nfp_net_rxq *rxq,
384 : : struct rte_mbuf *mb)
385 : : {
386 : : struct nfp_hw *hw = &rxq->hw->super;
387 : :
388 [ # # ]: 0 : if ((hw->ctrl & NFP_NET_CFG_CTRL_RXQINQ) == 0 ||
389 [ # # ]: 0 : (hw->cap & NFP_NET_CFG_CTRL_RXQINQ) == 0)
390 : : return;
391 : :
392 [ # # ]: 0 : if (meta->vlan_layer < NFP_META_MAX_VLANS)
393 : : return;
394 : :
395 [ # # ]: 0 : if (meta->vlan[0].offload == 0)
396 : 0 : mb->vlan_tci = rte_cpu_to_le_16(meta->vlan[0].tci);
397 : :
398 : 0 : mb->vlan_tci_outer = rte_cpu_to_le_16(meta->vlan[1].tci);
399 : : PMD_RX_LOG(DEBUG, "Received outer vlan TCI is %u inner vlan TCI is %u",
400 : : mb->vlan_tci_outer, mb->vlan_tci);
401 : 0 : mb->ol_flags |= RTE_MBUF_F_RX_QINQ | RTE_MBUF_F_RX_QINQ_STRIPPED;
402 : : }
403 : :
404 : : /*
405 : : * Set mbuf IPsec Offload features based on metadata info.
406 : : *
407 : : * The IPsec Offload features is prepended to the mbuf ol_flags.
408 : : * Extract and decode metadata info and set the mbuf ol_flags.
409 : : */
410 : : static void
411 : : nfp_net_parse_meta_ipsec(struct nfp_meta_parsed *meta,
412 : : struct nfp_net_rxq *rxq,
413 : : struct rte_mbuf *mbuf)
414 : : {
415 : : int offset;
416 : : uint32_t sa_idx;
417 : : struct nfp_net_hw *hw;
418 : : struct nfp_tx_ipsec_desc_msg *desc_md;
419 : :
420 : : hw = rxq->hw;
421 : 0 : sa_idx = meta->sa_idx;
422 : :
423 [ # # ]: 0 : if (meta->ipsec_type != NFP_NET_META_IPSEC)
424 : : return;
425 : :
426 [ # # ]: 0 : if (sa_idx >= NFP_NET_IPSEC_MAX_SA_CNT) {
427 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;
428 : : } else {
429 : 0 : mbuf->ol_flags |= RTE_MBUF_F_RX_SEC_OFFLOAD;
430 : 0 : offset = hw->ipsec_data->pkt_dynfield_offset;
431 : 0 : desc_md = RTE_MBUF_DYNFIELD(mbuf, offset, struct nfp_tx_ipsec_desc_msg *);
432 : 0 : desc_md->sa_idx = sa_idx;
433 : 0 : desc_md->enc = 0;
434 : : }
435 : : }
436 : :
437 : : /* Parse the metadata from packet */
438 : : static void
439 : 0 : nfp_net_parse_meta(struct nfp_net_rx_desc *rxds,
440 : : struct nfp_net_rxq *rxq,
441 : : struct nfp_net_hw *hw,
442 : : struct rte_mbuf *mb,
443 : : struct nfp_meta_parsed *meta)
444 : : {
445 : : uint8_t *meta_base;
446 : : rte_be32_t meta_header;
447 : :
448 [ # # ]: 0 : if (unlikely(NFP_DESC_META_LEN(rxds) == 0))
449 : : return;
450 : :
451 : 0 : meta_base = rte_pktmbuf_mtod_offset(mb, uint8_t *, -NFP_DESC_META_LEN(rxds));
452 : 0 : meta_header = *(rte_be32_t *)meta_base;
453 : :
454 [ # # # ]: 0 : switch (hw->meta_format) {
455 : 0 : case NFP_NET_METAFORMAT_CHAINED:
456 [ # # ]: 0 : if (nfp_net_parse_chained_meta(meta_base, meta_header, meta)) {
457 : : nfp_net_parse_meta_hash(meta, rxq, mb);
458 : 0 : nfp_net_parse_meta_vlan(meta, rxds, rxq, mb);
459 : : nfp_net_parse_meta_qinq(meta, rxq, mb);
460 : : nfp_net_parse_meta_ipsec(meta, rxq, mb);
461 : : } else {
462 : : PMD_RX_LOG(DEBUG, "RX chained metadata format is wrong!");
463 : : }
464 : : break;
465 : 0 : case NFP_NET_METAFORMAT_SINGLE:
466 [ # # ]: 0 : if ((rxds->rxd.flags & PCIE_DESC_RX_RSS) != 0) {
467 : 0 : nfp_net_parse_single_meta(meta_base, meta_header, meta);
468 : : nfp_net_parse_meta_hash(meta, rxq, mb);
469 : : }
470 : : break;
471 : 0 : default:
472 : : PMD_RX_LOG(DEBUG, "RX metadata do not exist.");
473 : : }
474 : : }
475 : :
476 : : /**
477 : : * Set packet type to mbuf based on parsed structure.
478 : : *
479 : : * @param nfp_ptype
480 : : * Packet type structure parsing from Rx descriptor.
481 : : * @param mb
482 : : * Mbuf to set the packet type.
483 : : */
484 : : static void
485 : 0 : nfp_net_set_ptype(const struct nfp_ptype_parsed *nfp_ptype,
486 : : struct rte_mbuf *mb)
487 : : {
488 : : uint32_t mbuf_ptype = RTE_PTYPE_L2_ETHER;
489 : 0 : uint8_t nfp_tunnel_ptype = nfp_ptype->tunnel_ptype;
490 : :
491 [ # # ]: 0 : if (nfp_tunnel_ptype != NFP_NET_PTYPE_TUNNEL_NONE)
492 : : mbuf_ptype |= RTE_PTYPE_INNER_L2_ETHER;
493 : :
494 [ # # # ]: 0 : switch (nfp_ptype->outer_l3_ptype) {
495 : : case NFP_NET_PTYPE_OUTER_L3_NONE:
496 : : break;
497 : 0 : case NFP_NET_PTYPE_OUTER_L3_IPV4:
498 : 0 : mbuf_ptype |= RTE_PTYPE_L3_IPV4;
499 : 0 : break;
500 : 0 : case NFP_NET_PTYPE_OUTER_L3_IPV6:
501 : 0 : mbuf_ptype |= RTE_PTYPE_L3_IPV6;
502 : 0 : break;
503 : : default:
504 : : PMD_RX_LOG(DEBUG, "Unrecognized nfp outer layer 3 packet type: %u",
505 : : nfp_ptype->outer_l3_ptype);
506 : : break;
507 : : }
508 : :
509 [ # # # # ]: 0 : switch (nfp_tunnel_ptype) {
510 : : case NFP_NET_PTYPE_TUNNEL_NONE:
511 : : break;
512 : 0 : case NFP_NET_PTYPE_TUNNEL_VXLAN:
513 : 0 : mbuf_ptype |= RTE_PTYPE_TUNNEL_VXLAN | RTE_PTYPE_L4_UDP;
514 : 0 : break;
515 : 0 : case NFP_NET_PTYPE_TUNNEL_NVGRE:
516 : 0 : mbuf_ptype |= RTE_PTYPE_TUNNEL_NVGRE;
517 : 0 : break;
518 : 0 : case NFP_NET_PTYPE_TUNNEL_GENEVE:
519 : 0 : mbuf_ptype |= RTE_PTYPE_TUNNEL_GENEVE | RTE_PTYPE_L4_UDP;
520 : 0 : break;
521 : : default:
522 : : PMD_RX_LOG(DEBUG, "Unrecognized nfp tunnel packet type: %u",
523 : : nfp_tunnel_ptype);
524 : : break;
525 : : }
526 : :
527 [ # # # # : 0 : switch (nfp_ptype->l4_ptype) {
# # # ]
528 : : case NFP_NET_PTYPE_L4_NONE:
529 : : break;
530 : 0 : case NFP_NET_PTYPE_L4_TCP:
531 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_TCP);
532 : 0 : break;
533 : 0 : case NFP_NET_PTYPE_L4_UDP:
534 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_UDP);
535 : 0 : break;
536 : 0 : case NFP_NET_PTYPE_L4_FRAG:
537 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_FRAG);
538 : 0 : break;
539 : 0 : case NFP_NET_PTYPE_L4_NONFRAG:
540 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_NONFRAG);
541 : 0 : break;
542 : 0 : case NFP_NET_PTYPE_L4_ICMP:
543 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_ICMP);
544 : 0 : break;
545 : 0 : case NFP_NET_PTYPE_L4_SCTP:
546 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L4_SCTP);
547 : 0 : break;
548 : : default:
549 : : PMD_RX_LOG(DEBUG, "Unrecognized nfp layer 4 packet type: %u",
550 : : nfp_ptype->l4_ptype);
551 : : break;
552 : : }
553 : :
554 [ # # # # : 0 : switch (nfp_ptype->l3_ptype) {
# # # ]
555 : : case NFP_NET_PTYPE_L3_NONE:
556 : : break;
557 : 0 : case NFP_NET_PTYPE_L3_IPV4:
558 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV4);
559 : 0 : break;
560 : 0 : case NFP_NET_PTYPE_L3_IPV6:
561 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV6);
562 : 0 : break;
563 : 0 : case NFP_NET_PTYPE_L3_IPV4_EXT:
564 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV4_EXT);
565 : 0 : break;
566 : 0 : case NFP_NET_PTYPE_L3_IPV6_EXT:
567 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV6_EXT);
568 : 0 : break;
569 : 0 : case NFP_NET_PTYPE_L3_IPV4_EXT_UNKNOWN:
570 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV4_EXT_UNKNOWN);
571 : 0 : break;
572 : 0 : case NFP_NET_PTYPE_L3_IPV6_EXT_UNKNOWN:
573 [ # # ]: 0 : mbuf_ptype |= NFP_PTYPE2RTE(nfp_tunnel_ptype, L3_IPV6_EXT_UNKNOWN);
574 : 0 : break;
575 : : default:
576 : : PMD_RX_LOG(DEBUG, "Unrecognized nfp layer 3 packet type: %u",
577 : : nfp_ptype->l3_ptype);
578 : : break;
579 : : }
580 : :
581 : 0 : mb->packet_type = mbuf_ptype;
582 : 0 : }
583 : :
584 : : /**
585 : : * Parse the packet type from Rx descriptor and set to mbuf.
586 : : *
587 : : * @param rxq
588 : : * Rx queue
589 : : * @param rxds
590 : : * Rx descriptor including the offloading info of packet type.
591 : : * @param mb
592 : : * Mbuf to set the packet type.
593 : : */
594 : : static void
595 : 0 : nfp_net_parse_ptype(struct nfp_net_rxq *rxq,
596 : : struct nfp_net_rx_desc *rxds,
597 : : struct rte_mbuf *mb)
598 : : {
599 : 0 : struct nfp_net_hw *hw = rxq->hw;
600 : : struct nfp_ptype_parsed nfp_ptype;
601 : 0 : uint16_t rxd_ptype = rxds->rxd.offload_info;
602 : :
603 [ # # ]: 0 : if ((hw->super.cap_ext & NFP_NET_CFG_CTRL_PKT_TYPE) == 0)
604 : 0 : return;
605 : :
606 [ # # # # ]: 0 : if (rxd_ptype == 0 || (rxds->rxd.flags & PCIE_DESC_RX_VLAN) != 0)
607 : : return;
608 : :
609 : 0 : nfp_ptype.l4_ptype = (rxd_ptype & NFP_NET_PTYPE_L4_MASK) >>
610 : : NFP_NET_PTYPE_L4_OFFSET;
611 : 0 : nfp_ptype.l3_ptype = (rxd_ptype & NFP_NET_PTYPE_L3_MASK) >>
612 : : NFP_NET_PTYPE_L3_OFFSET;
613 : 0 : nfp_ptype.tunnel_ptype = (rxd_ptype & NFP_NET_PTYPE_TUNNEL_MASK) >>
614 : : NFP_NET_PTYPE_TUNNEL_OFFSET;
615 : 0 : nfp_ptype.outer_l3_ptype = (rxd_ptype & NFP_NET_PTYPE_OUTER_L3_MASK) >>
616 : : NFP_NET_PTYPE_OUTER_L3_OFFSET;
617 : :
618 : 0 : nfp_net_set_ptype(&nfp_ptype, mb);
619 : : }
620 : :
621 : : /*
622 : : * RX path design:
623 : : *
624 : : * There are some decisions to take:
625 : : * 1) How to check DD RX descriptors bit
626 : : * 2) How and when to allocate new mbufs
627 : : *
628 : : * Current implementation checks just one single DD bit each loop. As each
629 : : * descriptor is 8 bytes, it is likely a good idea to check descriptors in
630 : : * a single cache line instead. Tests with this change have not shown any
631 : : * performance improvement but it requires further investigation. For example,
632 : : * depending on which descriptor is next, the number of descriptors could be
633 : : * less than 8 for just checking those in the same cache line. This implies
634 : : * extra work which could be counterproductive by itself. Indeed, last firmware
635 : : * changes are just doing this: writing several descriptors with the DD bit
636 : : * for saving PCIe bandwidth and DMA operations from the NFP.
637 : : *
638 : : * Mbuf allocation is done when a new packet is received. Then the descriptor
639 : : * is automatically linked with the new mbuf and the old one is given to the
640 : : * user. The main drawback with this design is mbuf allocation is heavier than
641 : : * using bulk allocations allowed by DPDK with rte_mempool_get_bulk. From the
642 : : * cache point of view it does not seem allocating the mbuf early on as we are
643 : : * doing now have any benefit at all. Again, tests with this change have not
644 : : * shown any improvement. Also, rte_mempool_get_bulk returns all or nothing
645 : : * so looking at the implications of this type of allocation should be studied
646 : : * deeply.
647 : : */
648 : : uint16_t
649 : 0 : nfp_net_recv_pkts(void *rx_queue,
650 : : struct rte_mbuf **rx_pkts,
651 : : uint16_t nb_pkts)
652 : : {
653 : : uint64_t dma_addr;
654 : : uint16_t avail = 0;
655 : : struct rte_mbuf *mb;
656 : : uint16_t nb_hold = 0;
657 : : struct nfp_net_hw *hw;
658 : : struct rte_mbuf *new_mb;
659 : : struct nfp_net_rxq *rxq;
660 : : struct nfp_net_dp_buf *rxb;
661 : : struct nfp_net_rx_desc *rxds;
662 : : uint16_t avail_multiplexed = 0;
663 : :
664 : : rxq = rx_queue;
665 [ # # ]: 0 : if (unlikely(rxq == NULL)) {
666 : : /*
667 : : * DPDK just checks the queue is lower than max queues
668 : : * enabled. But the queue needs to be configured.
669 : : */
670 : : PMD_RX_LOG(ERR, "RX Bad queue");
671 : : return 0;
672 : : }
673 : :
674 : 0 : hw = rxq->hw;
675 : :
676 [ # # ]: 0 : while (avail + avail_multiplexed < nb_pkts) {
677 : 0 : rxb = &rxq->rxbufs[rxq->rd_p];
678 [ # # ]: 0 : if (unlikely(rxb == NULL)) {
679 : : PMD_RX_LOG(ERR, "rxb does not exist!");
680 : 0 : break;
681 : : }
682 : :
683 : 0 : rxds = &rxq->rxds[rxq->rd_p];
684 [ # # ]: 0 : if ((rxds->rxd.meta_len_dd & PCIE_DESC_RX_DD) == 0)
685 : : break;
686 : :
687 : : /*
688 : : * Memory barrier to ensure that we won't do other
689 : : * reads before the DD bit.
690 : : */
691 : : rte_rmb();
692 : :
693 : : /*
694 : : * We got a packet. Let's alloc a new mbuf for refilling the
695 : : * free descriptor ring as soon as possible.
696 : : */
697 : 0 : new_mb = rte_pktmbuf_alloc(rxq->mem_pool);
698 [ # # ]: 0 : if (unlikely(new_mb == NULL)) {
699 : : PMD_RX_LOG(DEBUG, "RX mbuf alloc failed port_id=%u queue_id=%hu",
700 : : rxq->port_id, rxq->qidx);
701 : : nfp_net_mbuf_alloc_failed(rxq);
702 : : break;
703 : : }
704 : :
705 : : /*
706 : : * Grab the mbuf and refill the descriptor with the
707 : : * previously allocated mbuf.
708 : : */
709 : 0 : mb = rxb->mbuf;
710 : 0 : rxb->mbuf = new_mb;
711 : :
712 : : PMD_RX_LOG(DEBUG, "Packet len: %u, mbuf_size: %u",
713 : : rxds->rxd.data_len, rxq->mbuf_size);
714 : :
715 : : /* Size of this segment */
716 : 0 : mb->data_len = rxds->rxd.data_len - NFP_DESC_META_LEN(rxds);
717 : : /* Size of the whole packet. We just support 1 segment */
718 : 0 : mb->pkt_len = rxds->rxd.data_len - NFP_DESC_META_LEN(rxds);
719 : :
720 [ # # ]: 0 : if (unlikely((mb->data_len + hw->rx_offset) > rxq->mbuf_size)) {
721 : : /*
722 : : * This should not happen and the user has the
723 : : * responsibility of avoiding it. But we have
724 : : * to give some info about the error.
725 : : */
726 : : PMD_RX_LOG(ERR, "mbuf overflow likely due to the RX offset.");
727 : 0 : rte_pktmbuf_free(mb);
728 : 0 : break;
729 : : }
730 : :
731 : : /* Filling the received mbuf with packet info */
732 [ # # ]: 0 : if (hw->rx_offset != 0)
733 : 0 : mb->data_off = RTE_PKTMBUF_HEADROOM + hw->rx_offset;
734 : : else
735 : 0 : mb->data_off = RTE_PKTMBUF_HEADROOM + NFP_DESC_META_LEN(rxds);
736 : :
737 : : /* No scatter mode supported */
738 : 0 : mb->nb_segs = 1;
739 : 0 : mb->next = NULL;
740 : 0 : mb->port = rxq->port_id;
741 : :
742 : 0 : struct nfp_meta_parsed meta = {};
743 : 0 : nfp_net_parse_meta(rxds, rxq, hw, mb, &meta);
744 : :
745 : 0 : nfp_net_parse_ptype(rxq, rxds, mb);
746 : :
747 : : /* Checking the checksum flag */
748 : 0 : nfp_net_rx_cksum(rxq, rxds, mb);
749 : :
750 [ # # ]: 0 : if (meta.port_id == 0) {
751 : 0 : rx_pkts[avail++] = mb;
752 [ # # ]: 0 : } else if (nfp_flower_pf_dispatch_pkts(hw, mb, meta.port_id)) {
753 : 0 : avail_multiplexed++;
754 : : } else {
755 : 0 : rte_pktmbuf_free(mb);
756 : 0 : break;
757 : : }
758 : :
759 : : /* Now resetting and updating the descriptor */
760 [ # # ]: 0 : rxds->vals[0] = 0;
761 : : rxds->vals[1] = 0;
762 : : dma_addr = rte_cpu_to_le_64(rte_mbuf_data_iova_default(new_mb));
763 : : rxds->fld.dd = 0;
764 : 0 : rxds->fld.dma_addr_hi = (dma_addr >> 32) & 0xffff;
765 : 0 : rxds->fld.dma_addr_lo = dma_addr & 0xffffffff;
766 : 0 : nb_hold++;
767 : :
768 : 0 : rxq->rd_p++;
769 [ # # ]: 0 : if (unlikely(rxq->rd_p == rxq->rx_count)) /* Wrapping */
770 : 0 : rxq->rd_p = 0;
771 : : }
772 : :
773 [ # # ]: 0 : if (nb_hold == 0)
774 : : return nb_hold;
775 : :
776 : : PMD_RX_LOG(DEBUG, "RX port_id=%hu queue_id=%hu, %hu packets received",
777 : : rxq->port_id, rxq->qidx, avail);
778 : :
779 : 0 : nb_hold += rxq->nb_rx_hold;
780 : :
781 : : /*
782 : : * FL descriptors needs to be written before incrementing the
783 : : * FL queue WR pointer.
784 : : */
785 : : rte_wmb();
786 [ # # ]: 0 : if (nb_hold > rxq->rx_free_thresh) {
787 : : PMD_RX_LOG(DEBUG, "port=%hu queue=%hu nb_hold=%hu avail=%hu",
788 : : rxq->port_id, rxq->qidx, nb_hold, avail);
789 : 0 : nfp_qcp_ptr_add(rxq->qcp_fl, NFP_QCP_WRITE_PTR, nb_hold);
790 : : nb_hold = 0;
791 : : }
792 : 0 : rxq->nb_rx_hold = nb_hold;
793 : :
794 : 0 : return avail;
795 : : }
796 : :
797 : : static void
798 : 0 : nfp_net_rx_queue_release_mbufs(struct nfp_net_rxq *rxq)
799 : : {
800 : : uint16_t i;
801 : :
802 [ # # ]: 0 : if (rxq->rxbufs == NULL)
803 : : return;
804 : :
805 [ # # ]: 0 : for (i = 0; i < rxq->rx_count; i++) {
806 [ # # ]: 0 : if (rxq->rxbufs[i].mbuf != NULL) {
807 : : rte_pktmbuf_free_seg(rxq->rxbufs[i].mbuf);
808 : 0 : rxq->rxbufs[i].mbuf = NULL;
809 : : }
810 : : }
811 : : }
812 : :
813 : : void
814 : 0 : nfp_net_rx_queue_release(struct rte_eth_dev *dev,
815 : : uint16_t queue_idx)
816 : : {
817 : 0 : struct nfp_net_rxq *rxq = dev->data->rx_queues[queue_idx];
818 : :
819 [ # # ]: 0 : if (rxq != NULL) {
820 : 0 : nfp_net_rx_queue_release_mbufs(rxq);
821 : 0 : rte_eth_dma_zone_free(dev, "rx_ring", queue_idx);
822 : 0 : rte_free(rxq->rxbufs);
823 : 0 : rte_free(rxq);
824 : : }
825 : 0 : }
826 : :
827 : : void
828 : 0 : nfp_net_reset_rx_queue(struct nfp_net_rxq *rxq)
829 : : {
830 : 0 : nfp_net_rx_queue_release_mbufs(rxq);
831 : 0 : rxq->rd_p = 0;
832 : 0 : rxq->nb_rx_hold = 0;
833 : 0 : }
834 : :
835 : : int
836 : 0 : nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
837 : : uint16_t queue_idx,
838 : : uint16_t nb_desc,
839 : : unsigned int socket_id,
840 : : const struct rte_eth_rxconf *rx_conf,
841 : : struct rte_mempool *mp)
842 : : {
843 : : uint32_t rx_desc_sz;
844 : : uint16_t min_rx_desc;
845 : : uint16_t max_rx_desc;
846 : : struct nfp_net_hw *hw;
847 : : struct nfp_net_rxq *rxq;
848 : : const struct rte_memzone *tz;
849 : :
850 : 0 : hw = nfp_net_get_hw(dev);
851 : :
852 : 0 : nfp_net_rx_desc_limits(hw, &min_rx_desc, &max_rx_desc);
853 : :
854 : : /* Validating number of descriptors */
855 : 0 : rx_desc_sz = nb_desc * sizeof(struct nfp_net_rx_desc);
856 [ # # ]: 0 : if (rx_desc_sz % NFP_ALIGN_RING_DESC != 0 ||
857 [ # # # # ]: 0 : nb_desc > max_rx_desc || nb_desc < min_rx_desc) {
858 : 0 : PMD_DRV_LOG(ERR, "Wrong nb_desc value");
859 : 0 : return -EINVAL;
860 : : }
861 : :
862 : : /*
863 : : * Free memory prior to re-allocation if needed. This is the case after
864 : : * calling @nfp_net_stop().
865 : : */
866 [ # # ]: 0 : if (dev->data->rx_queues[queue_idx] != NULL) {
867 : 0 : nfp_net_rx_queue_release(dev, queue_idx);
868 : 0 : dev->data->rx_queues[queue_idx] = NULL;
869 : : }
870 : :
871 : : /* Allocating rx queue data structure */
872 : 0 : rxq = rte_zmalloc_socket("ethdev RX queue", sizeof(struct nfp_net_rxq),
873 : : RTE_CACHE_LINE_SIZE, socket_id);
874 [ # # ]: 0 : if (rxq == NULL)
875 : : return -ENOMEM;
876 : :
877 : 0 : dev->data->rx_queues[queue_idx] = rxq;
878 : :
879 : : /* Hw queues mapping based on firmware configuration */
880 : 0 : rxq->qidx = queue_idx;
881 : 0 : rxq->fl_qcidx = queue_idx * hw->stride_rx;
882 : 0 : rxq->qcp_fl = hw->rx_bar + NFP_QCP_QUEUE_OFF(rxq->fl_qcidx);
883 : :
884 : : /*
885 : : * Tracking mbuf size for detecting a potential mbuf overflow due to
886 : : * RX offset.
887 : : */
888 : 0 : rxq->mem_pool = mp;
889 : 0 : rxq->mbuf_size = rxq->mem_pool->elt_size;
890 : 0 : rxq->mbuf_size -= (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);
891 : 0 : hw->flbufsz = rxq->mbuf_size;
892 : :
893 : 0 : rxq->rx_count = nb_desc;
894 : 0 : rxq->port_id = dev->data->port_id;
895 : 0 : rxq->rx_free_thresh = rx_conf->rx_free_thresh;
896 : :
897 : : /*
898 : : * Allocate RX ring hardware descriptors. A memzone large enough to
899 : : * handle the maximum ring size is allocated in order to allow for
900 : : * resizing in later calls to the queue setup function.
901 : : */
902 : 0 : tz = rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
903 : : sizeof(struct nfp_net_rx_desc) * max_rx_desc,
904 : : NFP_MEMZONE_ALIGN, socket_id);
905 [ # # ]: 0 : if (tz == NULL) {
906 : 0 : PMD_DRV_LOG(ERR, "Error allocating rx dma");
907 : 0 : nfp_net_rx_queue_release(dev, queue_idx);
908 : 0 : dev->data->rx_queues[queue_idx] = NULL;
909 : 0 : return -ENOMEM;
910 : : }
911 : :
912 : : /* Saving physical and virtual addresses for the RX ring */
913 : 0 : rxq->dma = (uint64_t)tz->iova;
914 : 0 : rxq->rxds = tz->addr;
915 : :
916 : : /* Mbuf pointers array for referencing mbufs linked to RX descriptors */
917 : 0 : rxq->rxbufs = rte_zmalloc_socket("rxq->rxbufs",
918 : : sizeof(*rxq->rxbufs) * nb_desc, RTE_CACHE_LINE_SIZE,
919 : : socket_id);
920 [ # # ]: 0 : if (rxq->rxbufs == NULL) {
921 : 0 : nfp_net_rx_queue_release(dev, queue_idx);
922 : 0 : dev->data->rx_queues[queue_idx] = NULL;
923 : 0 : return -ENOMEM;
924 : : }
925 : :
926 : 0 : nfp_net_reset_rx_queue(rxq);
927 : :
928 : 0 : rxq->hw = hw;
929 : :
930 : : /*
931 : : * Telling the HW about the physical address of the RX ring and number
932 : : * of descriptors in log2 format.
933 : : */
934 : 0 : nn_cfg_writeq(&hw->super, NFP_NET_CFG_RXR_ADDR(queue_idx), rxq->dma);
935 : 0 : nn_cfg_writeb(&hw->super, NFP_NET_CFG_RXR_SZ(queue_idx), rte_log2_u32(nb_desc));
936 : :
937 : 0 : return 0;
938 : : }
939 : :
940 : : /**
941 : : * Check for descriptors with a complete status
942 : : *
943 : : * @param txq
944 : : * TX queue to work with
945 : : *
946 : : * @return
947 : : * Number of descriptors freed
948 : : */
949 : : uint32_t
950 : 0 : nfp_net_tx_free_bufs(struct nfp_net_txq *txq)
951 : : {
952 : : uint32_t todo;
953 : : uint32_t qcp_rd_p;
954 : :
955 : : PMD_TX_LOG(DEBUG, "queue %hu. Check for descriptor with a complete"
956 : : " status", txq->qidx);
957 : :
958 : : /* Work out how many packets have been sent */
959 : 0 : qcp_rd_p = nfp_qcp_read(txq->qcp_q, NFP_QCP_READ_PTR);
960 : :
961 [ # # ]: 0 : if (qcp_rd_p == txq->rd_p) {
962 : : PMD_TX_LOG(DEBUG, "queue %hu: It seems harrier is not sending "
963 : : "packets (%u, %u)", txq->qidx,
964 : : qcp_rd_p, txq->rd_p);
965 : : return 0;
966 : : }
967 : :
968 [ # # ]: 0 : if (qcp_rd_p > txq->rd_p)
969 : 0 : todo = qcp_rd_p - txq->rd_p;
970 : : else
971 : 0 : todo = qcp_rd_p + txq->tx_count - txq->rd_p;
972 : :
973 : : PMD_TX_LOG(DEBUG, "qcp_rd_p %u, txq->rd_p: %u, qcp->rd_p: %u",
974 : : qcp_rd_p, txq->rd_p, txq->rd_p);
975 : :
976 [ # # ]: 0 : if (todo == 0)
977 : : return todo;
978 : :
979 : 0 : txq->rd_p += todo;
980 [ # # ]: 0 : if (unlikely(txq->rd_p >= txq->tx_count))
981 : 0 : txq->rd_p -= txq->tx_count;
982 : :
983 : : return todo;
984 : : }
985 : :
986 : : static void
987 : 0 : nfp_net_tx_queue_release_mbufs(struct nfp_net_txq *txq)
988 : : {
989 : : uint32_t i;
990 : :
991 [ # # ]: 0 : if (txq->txbufs == NULL)
992 : : return;
993 : :
994 [ # # ]: 0 : for (i = 0; i < txq->tx_count; i++) {
995 [ # # ]: 0 : if (txq->txbufs[i].mbuf != NULL) {
996 : : rte_pktmbuf_free_seg(txq->txbufs[i].mbuf);
997 : 0 : txq->txbufs[i].mbuf = NULL;
998 : : }
999 : : }
1000 : : }
1001 : :
1002 : : void
1003 : 0 : nfp_net_tx_queue_release(struct rte_eth_dev *dev,
1004 : : uint16_t queue_idx)
1005 : : {
1006 : 0 : struct nfp_net_txq *txq = dev->data->tx_queues[queue_idx];
1007 : :
1008 [ # # ]: 0 : if (txq != NULL) {
1009 : 0 : nfp_net_tx_queue_release_mbufs(txq);
1010 : 0 : rte_eth_dma_zone_free(dev, "tx_ring", queue_idx);
1011 : 0 : rte_free(txq->txbufs);
1012 : 0 : rte_free(txq);
1013 : : }
1014 : 0 : }
1015 : :
1016 : : void
1017 : 0 : nfp_net_reset_tx_queue(struct nfp_net_txq *txq)
1018 : : {
1019 : 0 : nfp_net_tx_queue_release_mbufs(txq);
1020 : 0 : txq->wr_p = 0;
1021 : 0 : txq->rd_p = 0;
1022 : 0 : }
1023 : :
1024 : : void
1025 : 0 : nfp_net_set_meta_vlan(struct nfp_net_meta_raw *meta_data,
1026 : : struct rte_mbuf *pkt,
1027 : : uint8_t layer)
1028 : : {
1029 : : uint16_t tpid;
1030 : : uint16_t vlan_tci;
1031 : :
1032 : : tpid = RTE_ETHER_TYPE_VLAN;
1033 : 0 : vlan_tci = pkt->vlan_tci;
1034 : :
1035 [ # # ]: 0 : meta_data->data[layer] = rte_cpu_to_be_32(tpid << 16 | vlan_tci);
1036 : 0 : }
1037 : :
1038 : : void
1039 : 0 : nfp_net_set_meta_ipsec(struct nfp_net_meta_raw *meta_data,
1040 : : struct nfp_net_txq *txq,
1041 : : struct rte_mbuf *pkt,
1042 : : uint8_t layer,
1043 : : uint8_t ipsec_layer)
1044 : : {
1045 : : int offset;
1046 : : struct nfp_net_hw *hw;
1047 : : struct nfp_tx_ipsec_desc_msg *desc_md;
1048 : :
1049 : 0 : hw = txq->hw;
1050 : 0 : offset = hw->ipsec_data->pkt_dynfield_offset;
1051 : 0 : desc_md = RTE_MBUF_DYNFIELD(pkt, offset, struct nfp_tx_ipsec_desc_msg *);
1052 : :
1053 [ # # # # ]: 0 : switch (ipsec_layer) {
1054 : 0 : case NFP_IPSEC_META_SAIDX:
1055 : 0 : meta_data->data[layer] = desc_md->sa_idx;
1056 : 0 : break;
1057 : 0 : case NFP_IPSEC_META_SEQLOW:
1058 : 0 : meta_data->data[layer] = desc_md->esn.low;
1059 : 0 : break;
1060 : 0 : case NFP_IPSEC_META_SEQHI:
1061 : 0 : meta_data->data[layer] = desc_md->esn.hi;
1062 : 0 : break;
1063 : : default:
1064 : : break;
1065 : : }
1066 : 0 : }
1067 : :
1068 : : int
1069 : 0 : nfp_net_tx_queue_setup(struct rte_eth_dev *dev,
1070 : : uint16_t queue_idx,
1071 : : uint16_t nb_desc,
1072 : : unsigned int socket_id,
1073 : : const struct rte_eth_txconf *tx_conf)
1074 : : {
1075 : : struct nfp_net_hw *hw;
1076 : :
1077 : 0 : hw = nfp_net_get_hw(dev);
1078 : :
1079 [ # # ]: 0 : if (hw->ver.extend == NFP_NET_CFG_VERSION_DP_NFD3)
1080 : 0 : return nfp_net_nfd3_tx_queue_setup(dev, queue_idx,
1081 : : nb_desc, socket_id, tx_conf);
1082 : : else
1083 : 0 : return nfp_net_nfdk_tx_queue_setup(dev, queue_idx,
1084 : : nb_desc, socket_id, tx_conf);
1085 : : }
|