xref: /dpdk/drivers/net/nfb/nfb_rx.h (revision ad616a807c560ab1efdca14984fd8c3294bce65b)
16435f9a0SRastislav Cernay /* SPDX-License-Identifier: BSD-3-Clause
26435f9a0SRastislav Cernay  * Copyright(c) 2019 Cesnet
36435f9a0SRastislav Cernay  * Copyright(c) 2019 Netcope Technologies, a.s. <info@netcope.com>
46435f9a0SRastislav Cernay  * All rights reserved.
56435f9a0SRastislav Cernay  */
66435f9a0SRastislav Cernay 
76435f9a0SRastislav Cernay #ifndef _NFB_RX_H_
86435f9a0SRastislav Cernay #define _NFB_RX_H_
96435f9a0SRastislav Cernay 
106435f9a0SRastislav Cernay #include <nfb/nfb.h>
116435f9a0SRastislav Cernay #include <nfb/ndp.h>
126435f9a0SRastislav Cernay 
136435f9a0SRastislav Cernay #include <rte_mbuf.h>
14bd063651SFerruh Yigit #include <rte_mbuf_dyn.h>
156435f9a0SRastislav Cernay #include <rte_ethdev.h>
166435f9a0SRastislav Cernay 
17*ad616a80SStephen Hemminger #include "nfb.h"
18*ad616a80SStephen Hemminger 
19f6800febSThomas Monjalon extern uint64_t nfb_timestamp_rx_dynflag;
20f6800febSThomas Monjalon extern int nfb_timestamp_dynfield_offset;
21f6800febSThomas Monjalon 
22f6800febSThomas Monjalon static inline rte_mbuf_timestamp_t *
nfb_timestamp_dynfield(struct rte_mbuf * mbuf)23f6800febSThomas Monjalon nfb_timestamp_dynfield(struct rte_mbuf *mbuf)
24f6800febSThomas Monjalon {
25f6800febSThomas Monjalon 	return RTE_MBUF_DYNFIELD(mbuf,
26f6800febSThomas Monjalon 		nfb_timestamp_dynfield_offset, rte_mbuf_timestamp_t *);
27f6800febSThomas Monjalon }
28f6800febSThomas Monjalon 
296435f9a0SRastislav Cernay struct ndp_rx_queue {
306435f9a0SRastislav Cernay 	struct nfb_device *nfb;	     /* nfb dev structure */
316435f9a0SRastislav Cernay 	struct ndp_queue *queue;     /* rx queue */
326435f9a0SRastislav Cernay 	uint16_t rx_queue_id;	     /* index */
336435f9a0SRastislav Cernay 	uint8_t in_port;	     /* port */
349c7fd48fSRastislav Cernay 	uint8_t flags;               /* setup flags */
356435f9a0SRastislav Cernay 
366435f9a0SRastislav Cernay 	struct rte_mempool *mb_pool; /* memory pool to allocate packets */
376435f9a0SRastislav Cernay 	uint16_t buf_size;           /* mbuf size */
386435f9a0SRastislav Cernay 
396435f9a0SRastislav Cernay 	volatile uint64_t rx_pkts;   /* packets read */
406435f9a0SRastislav Cernay 	volatile uint64_t rx_bytes;  /* bytes read */
416435f9a0SRastislav Cernay 	volatile uint64_t err_pkts;  /* erroneous packets */
426435f9a0SRastislav Cernay };
436435f9a0SRastislav Cernay 
446435f9a0SRastislav Cernay /**
456435f9a0SRastislav Cernay  * Initialize ndp_rx_queue structure
466435f9a0SRastislav Cernay  *
476435f9a0SRastislav Cernay  * @param nfb
486435f9a0SRastislav Cernay  *   Pointer to nfb device structure.
496435f9a0SRastislav Cernay  * @param rx_queue_id
506435f9a0SRastislav Cernay  *   RX queue index.
516435f9a0SRastislav Cernay  * @param port_id
526435f9a0SRastislav Cernay  *   Device [external] port identifier.
536435f9a0SRastislav Cernay  * @param mb_pool
546435f9a0SRastislav Cernay  *   Memory pool for buffer allocations.
556435f9a0SRastislav Cernay  * @param[out] rxq
566435f9a0SRastislav Cernay  *   Pointer to ndp_rx_queue output structure
576435f9a0SRastislav Cernay  * @return
586435f9a0SRastislav Cernay  *   0 on success, a negative errno value otherwise.
596435f9a0SRastislav Cernay  */
606435f9a0SRastislav Cernay int
616435f9a0SRastislav Cernay nfb_eth_rx_queue_init(struct nfb_device *nfb,
626435f9a0SRastislav Cernay 	uint16_t rx_queue_id,
636435f9a0SRastislav Cernay 	uint16_t port_id,
646435f9a0SRastislav Cernay 	struct rte_mempool *mb_pool,
656435f9a0SRastislav Cernay 	struct ndp_rx_queue *rxq);
666435f9a0SRastislav Cernay 
676435f9a0SRastislav Cernay /**
686435f9a0SRastislav Cernay  * DPDK callback to setup a RX queue for use.
696435f9a0SRastislav Cernay  *
706435f9a0SRastislav Cernay  * @param dev
716435f9a0SRastislav Cernay  *   Pointer to Ethernet device structure.
726435f9a0SRastislav Cernay  * @param idx
736435f9a0SRastislav Cernay  *   RX queue index.
746435f9a0SRastislav Cernay  * @param desc
756435f9a0SRastislav Cernay  *   Number of descriptors to configure in queue.
766435f9a0SRastislav Cernay  * @param socket
776435f9a0SRastislav Cernay  *   NUMA socket on which memory must be allocated.
786435f9a0SRastislav Cernay  * @param[in] conf
796435f9a0SRastislav Cernay  *   Thresholds parameters.
806435f9a0SRastislav Cernay  * @param mb_pool
816435f9a0SRastislav Cernay  *   Memory pool for buffer allocations.
826435f9a0SRastislav Cernay  *
836435f9a0SRastislav Cernay  * @return
846435f9a0SRastislav Cernay  *   0 on success, a negative errno value otherwise.
856435f9a0SRastislav Cernay  */
866435f9a0SRastislav Cernay int
876435f9a0SRastislav Cernay nfb_eth_rx_queue_setup(struct rte_eth_dev *dev,
886435f9a0SRastislav Cernay 	uint16_t rx_queue_id,
896435f9a0SRastislav Cernay 	uint16_t nb_rx_desc __rte_unused,
906435f9a0SRastislav Cernay 	unsigned int socket_id,
916435f9a0SRastislav Cernay 	const struct rte_eth_rxconf *rx_conf __rte_unused,
926435f9a0SRastislav Cernay 	struct rte_mempool *mb_pool);
936435f9a0SRastislav Cernay 
946435f9a0SRastislav Cernay /**
956435f9a0SRastislav Cernay  * DPDK callback to release a RX queue.
966435f9a0SRastislav Cernay  *
977483341aSXueming Li  * @param dev
987483341aSXueming Li  *   Pointer to Ethernet device structure.
997483341aSXueming Li  * @param qid
1007483341aSXueming Li  *   Receive queue index.
1016435f9a0SRastislav Cernay  */
1026435f9a0SRastislav Cernay void
1037483341aSXueming Li nfb_eth_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid);
1046435f9a0SRastislav Cernay 
1056435f9a0SRastislav Cernay /**
1066435f9a0SRastislav Cernay  * Start traffic on Rx queue.
1076435f9a0SRastislav Cernay  *
1086435f9a0SRastislav Cernay  * @param dev
1096435f9a0SRastislav Cernay  *   Pointer to Ethernet device structure.
1106435f9a0SRastislav Cernay  * @param txq_id
1116435f9a0SRastislav Cernay  *   RX queue index.
1126435f9a0SRastislav Cernay  * @return
1136435f9a0SRastislav Cernay  *   0 on success, a negative errno value otherwise.
1146435f9a0SRastislav Cernay  */
1156435f9a0SRastislav Cernay int
1166435f9a0SRastislav Cernay nfb_eth_rx_queue_start(struct rte_eth_dev *dev, uint16_t rxq_id);
1176435f9a0SRastislav Cernay 
1186435f9a0SRastislav Cernay /**
1196435f9a0SRastislav Cernay  * Stop traffic on Rx queue.
1206435f9a0SRastislav Cernay  *
1216435f9a0SRastislav Cernay  * @param dev
1226435f9a0SRastislav Cernay  *   Pointer to Ethernet device structure.
1236435f9a0SRastislav Cernay  * @param txq_id
1246435f9a0SRastislav Cernay  *   RX queue index.
1256435f9a0SRastislav Cernay  */
1266435f9a0SRastislav Cernay int
1276435f9a0SRastislav Cernay nfb_eth_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rxq_id);
1286435f9a0SRastislav Cernay 
1296435f9a0SRastislav Cernay /**
1306435f9a0SRastislav Cernay  * DPDK callback for RX.
1316435f9a0SRastislav Cernay  *
1326435f9a0SRastislav Cernay  * @param dpdk_rxq
1336435f9a0SRastislav Cernay  *   Generic pointer to RX queue structure.
1346435f9a0SRastislav Cernay  * @param[out] bufs
1356435f9a0SRastislav Cernay  *   Array to store received packets.
1366435f9a0SRastislav Cernay  * @param nb_pkts
1376435f9a0SRastislav Cernay  *   Maximum number of packets in array.
1386435f9a0SRastislav Cernay  *
1396435f9a0SRastislav Cernay  * @return
1406435f9a0SRastislav Cernay  *   Number of packets successfully received (<= nb_pkts).
1416435f9a0SRastislav Cernay  */
1426435f9a0SRastislav Cernay static __rte_always_inline uint16_t
nfb_eth_ndp_rx(void * queue,struct rte_mbuf ** bufs,uint16_t nb_pkts)1436435f9a0SRastislav Cernay nfb_eth_ndp_rx(void *queue,
1446435f9a0SRastislav Cernay 	struct rte_mbuf **bufs,
1456435f9a0SRastislav Cernay 	uint16_t nb_pkts)
1466435f9a0SRastislav Cernay {
1476435f9a0SRastislav Cernay 	struct ndp_rx_queue *ndp = queue;
1486435f9a0SRastislav Cernay 	uint16_t packet_size;
1496435f9a0SRastislav Cernay 	uint64_t num_bytes = 0;
1506435f9a0SRastislav Cernay 	uint16_t num_rx;
1516435f9a0SRastislav Cernay 	unsigned int i;
1526435f9a0SRastislav Cernay 
1536435f9a0SRastislav Cernay 	const uint16_t buf_size = ndp->buf_size;
1546435f9a0SRastislav Cernay 
1556435f9a0SRastislav Cernay 	struct rte_mbuf *mbuf;
1566435f9a0SRastislav Cernay 	struct ndp_packet packets[nb_pkts];
1576435f9a0SRastislav Cernay 
1586435f9a0SRastislav Cernay 	struct rte_mbuf *mbufs[nb_pkts];
1596435f9a0SRastislav Cernay 
1606435f9a0SRastislav Cernay 	if (unlikely(ndp->queue == NULL || nb_pkts == 0)) {
161*ad616a80SStephen Hemminger 		NFB_LOG(ERR, "RX invalid arguments");
1626435f9a0SRastislav Cernay 		return 0;
1636435f9a0SRastislav Cernay 	}
1646435f9a0SRastislav Cernay 
1656435f9a0SRastislav Cernay 	/* returns either all or nothing */
1666435f9a0SRastislav Cernay 	i = rte_pktmbuf_alloc_bulk(ndp->mb_pool, mbufs, nb_pkts);
1676435f9a0SRastislav Cernay 	if (unlikely(i != 0))
1686435f9a0SRastislav Cernay 		return 0;
1696435f9a0SRastislav Cernay 
1706435f9a0SRastislav Cernay 	num_rx = ndp_rx_burst_get(ndp->queue, packets, nb_pkts);
1716435f9a0SRastislav Cernay 
1726435f9a0SRastislav Cernay 	if (unlikely(num_rx != nb_pkts)) {
1736435f9a0SRastislav Cernay 		for (i = num_rx; i < nb_pkts; i++)
1746435f9a0SRastislav Cernay 			rte_pktmbuf_free(mbufs[i]);
1756435f9a0SRastislav Cernay 	}
1766435f9a0SRastislav Cernay 
1776435f9a0SRastislav Cernay 	nb_pkts = num_rx;
1786435f9a0SRastislav Cernay 
1796435f9a0SRastislav Cernay 	num_rx = 0;
1806435f9a0SRastislav Cernay 	/*
1816435f9a0SRastislav Cernay 	 * Reads the given number of packets from NDP queue given
1826435f9a0SRastislav Cernay 	 * by queue and copies the packet data into a newly allocated mbuf
1836435f9a0SRastislav Cernay 	 * to return.
1846435f9a0SRastislav Cernay 	 */
1856435f9a0SRastislav Cernay 	for (i = 0; i < nb_pkts; ++i) {
1866435f9a0SRastislav Cernay 		mbuf = mbufs[i];
1876435f9a0SRastislav Cernay 
1886435f9a0SRastislav Cernay 		/* get the space available for data in the mbuf */
1896435f9a0SRastislav Cernay 		packet_size = packets[i].data_length;
1906435f9a0SRastislav Cernay 
1916435f9a0SRastislav Cernay 		if (likely(packet_size <= buf_size)) {
1926435f9a0SRastislav Cernay 			/* NDP packet will fit in one mbuf, go ahead and copy */
1936435f9a0SRastislav Cernay 			rte_memcpy(rte_pktmbuf_mtod(mbuf, void *),
1946435f9a0SRastislav Cernay 				packets[i].data, packet_size);
1956435f9a0SRastislav Cernay 
1966435f9a0SRastislav Cernay 			mbuf->data_len = (uint16_t)packet_size;
1976435f9a0SRastislav Cernay 
1986435f9a0SRastislav Cernay 			mbuf->pkt_len = packet_size;
1996435f9a0SRastislav Cernay 			mbuf->port = ndp->in_port;
2009c7fd48fSRastislav Cernay 			mbuf->ol_flags = 0;
2019c7fd48fSRastislav Cernay 
2021b408187SMartin Spinler 			if (nfb_timestamp_dynfield_offset >= 0) {
203f6800febSThomas Monjalon 				rte_mbuf_timestamp_t timestamp;
204f6800febSThomas Monjalon 
2059c7fd48fSRastislav Cernay 				/* nanoseconds */
206f6800febSThomas Monjalon 				timestamp =
2079c7fd48fSRastislav Cernay 					rte_le_to_cpu_32(*((uint32_t *)
2089c7fd48fSRastislav Cernay 					(packets[i].header + 4)));
209f6800febSThomas Monjalon 				timestamp <<= 32;
2109c7fd48fSRastislav Cernay 				/* seconds */
211f6800febSThomas Monjalon 				timestamp |=
2129c7fd48fSRastislav Cernay 					rte_le_to_cpu_32(*((uint32_t *)
2139c7fd48fSRastislav Cernay 					(packets[i].header + 8)));
214f6800febSThomas Monjalon 				*nfb_timestamp_dynfield(mbuf) = timestamp;
215f6800febSThomas Monjalon 				mbuf->ol_flags |= nfb_timestamp_rx_dynflag;
2169c7fd48fSRastislav Cernay 			}
2179c7fd48fSRastislav Cernay 
2186435f9a0SRastislav Cernay 			bufs[num_rx++] = mbuf;
2196435f9a0SRastislav Cernay 			num_bytes += packet_size;
2206435f9a0SRastislav Cernay 		} else {
2216435f9a0SRastislav Cernay 			/*
2226435f9a0SRastislav Cernay 			 * NDP packet will not fit in one mbuf,
2236435f9a0SRastislav Cernay 			 * scattered mode is not enabled, drop packet
2246435f9a0SRastislav Cernay 			 */
2256435f9a0SRastislav Cernay 			rte_pktmbuf_free(mbuf);
2266435f9a0SRastislav Cernay 		}
2276435f9a0SRastislav Cernay 	}
2286435f9a0SRastislav Cernay 
2296435f9a0SRastislav Cernay 	ndp_rx_burst_put(ndp->queue);
2306435f9a0SRastislav Cernay 
2316435f9a0SRastislav Cernay 	ndp->rx_pkts += num_rx;
2326435f9a0SRastislav Cernay 	ndp->rx_bytes += num_bytes;
2336435f9a0SRastislav Cernay 	return num_rx;
2346435f9a0SRastislav Cernay }
2356435f9a0SRastislav Cernay 
2366435f9a0SRastislav Cernay #endif /* _NFB_RX_H_ */
237