1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2019 Cesnet
3 * Copyright(c) 2019 Netcope Technologies, a.s. <info@netcope.com>
14 #include <rte_mbuf_dyn.h>
15 #include <rte_ethdev.h>
17 #define NFB_TIMESTAMP_FLAG (1 << 0)
19 extern uint64_t nfb_timestamp_rx_dynflag;
20 extern int nfb_timestamp_dynfield_offset;
22 static inline rte_mbuf_timestamp_t *
23 nfb_timestamp_dynfield(struct rte_mbuf *mbuf)
25 return RTE_MBUF_DYNFIELD(mbuf,
26 nfb_timestamp_dynfield_offset, rte_mbuf_timestamp_t *);
30 struct nfb_device *nfb; /* nfb dev structure */
31 struct ndp_queue *queue; /* rx queue */
32 uint16_t rx_queue_id; /* index */
33 uint8_t in_port; /* port */
34 uint8_t flags; /* setup flags */
36 struct rte_mempool *mb_pool; /* memory pool to allocate packets */
37 uint16_t buf_size; /* mbuf size */
39 volatile uint64_t rx_pkts; /* packets read */
40 volatile uint64_t rx_bytes; /* bytes read */
41 volatile uint64_t err_pkts; /* erroneous packets */
45 * Initialize ndp_rx_queue structure
48 * Pointer to nfb device structure.
52 * Device [external] port identifier.
54 * Memory pool for buffer allocations.
56 * Pointer to ndp_rx_queue output structure
58 * 0 on success, a negative errno value otherwise.
61 nfb_eth_rx_queue_init(struct nfb_device *nfb,
64 struct rte_mempool *mb_pool,
65 struct ndp_rx_queue *rxq);
68 * DPDK callback to setup a RX queue for use.
71 * Pointer to Ethernet device structure.
75 * Number of descriptors to configure in queue.
77 * NUMA socket on which memory must be allocated.
79 * Thresholds parameters.
81 * Memory pool for buffer allocations.
84 * 0 on success, a negative errno value otherwise.
87 nfb_eth_rx_queue_setup(struct rte_eth_dev *dev,
89 uint16_t nb_rx_desc __rte_unused,
90 unsigned int socket_id,
91 const struct rte_eth_rxconf *rx_conf __rte_unused,
92 struct rte_mempool *mb_pool);
95 * DPDK callback to release a RX queue.
98 * Pointer to Ethernet device structure.
100 * Receive queue index.
103 nfb_eth_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid);
106 * Start traffic on Rx queue.
109 * Pointer to Ethernet device structure.
113 * 0 on success, a negative errno value otherwise.
116 nfb_eth_rx_queue_start(struct rte_eth_dev *dev, uint16_t rxq_id);
119 * Stop traffic on Rx queue.
122 * Pointer to Ethernet device structure.
127 nfb_eth_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rxq_id);
130 * DPDK callback for RX.
133 * Generic pointer to RX queue structure.
135 * Array to store received packets.
137 * Maximum number of packets in array.
140 * Number of packets successfully received (<= nb_pkts).
142 static __rte_always_inline uint16_t
143 nfb_eth_ndp_rx(void *queue,
144 struct rte_mbuf **bufs,
147 struct ndp_rx_queue *ndp = queue;
148 uint8_t timestamping_enabled;
149 uint16_t packet_size;
150 uint64_t num_bytes = 0;
154 const uint16_t buf_size = ndp->buf_size;
156 struct rte_mbuf *mbuf;
157 struct ndp_packet packets[nb_pkts];
159 struct rte_mbuf *mbufs[nb_pkts];
161 if (unlikely(ndp->queue == NULL || nb_pkts == 0)) {
162 RTE_LOG(ERR, PMD, "RX invalid arguments!\n");
166 timestamping_enabled = ndp->flags & NFB_TIMESTAMP_FLAG;
168 /* returns either all or nothing */
169 i = rte_pktmbuf_alloc_bulk(ndp->mb_pool, mbufs, nb_pkts);
170 if (unlikely(i != 0))
173 num_rx = ndp_rx_burst_get(ndp->queue, packets, nb_pkts);
175 if (unlikely(num_rx != nb_pkts)) {
176 for (i = num_rx; i < nb_pkts; i++)
177 rte_pktmbuf_free(mbufs[i]);
184 * Reads the given number of packets from NDP queue given
185 * by queue and copies the packet data into a newly allocated mbuf
188 for (i = 0; i < nb_pkts; ++i) {
191 /* get the space available for data in the mbuf */
192 packet_size = packets[i].data_length;
194 if (likely(packet_size <= buf_size)) {
195 /* NDP packet will fit in one mbuf, go ahead and copy */
196 rte_memcpy(rte_pktmbuf_mtod(mbuf, void *),
197 packets[i].data, packet_size);
199 mbuf->data_len = (uint16_t)packet_size;
201 mbuf->pkt_len = packet_size;
202 mbuf->port = ndp->in_port;
205 if (timestamping_enabled) {
206 rte_mbuf_timestamp_t timestamp;
210 rte_le_to_cpu_32(*((uint32_t *)
211 (packets[i].header + 4)));
215 rte_le_to_cpu_32(*((uint32_t *)
216 (packets[i].header + 8)));
217 *nfb_timestamp_dynfield(mbuf) = timestamp;
218 mbuf->ol_flags |= nfb_timestamp_rx_dynflag;
221 bufs[num_rx++] = mbuf;
222 num_bytes += packet_size;
225 * NDP packet will not fit in one mbuf,
226 * scattered mode is not enabled, drop packet
228 rte_pktmbuf_free(mbuf);
232 ndp_rx_burst_put(ndp->queue);
234 ndp->rx_pkts += num_rx;
235 ndp->rx_bytes += num_bytes;
239 #endif /* _NFB_RX_H_ */