summaryrefslogtreecommitdiffstats
path: root/src/seastar/dpdk/drivers/net/nfb/nfb_rx.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/seastar/dpdk/drivers/net/nfb/nfb_rx.h')
-rw-r--r--src/seastar/dpdk/drivers/net/nfb/nfb_rx.h202
1 files changed, 202 insertions, 0 deletions
diff --git a/src/seastar/dpdk/drivers/net/nfb/nfb_rx.h b/src/seastar/dpdk/drivers/net/nfb/nfb_rx.h
new file mode 100644
index 000000000..88a03074f
--- /dev/null
+++ b/src/seastar/dpdk/drivers/net/nfb/nfb_rx.h
@@ -0,0 +1,202 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Cesnet
+ * Copyright(c) 2019 Netcope Technologies, a.s. <info@netcope.com>
+ * All rights reserved.
+ */
+
+#ifndef _NFB_RX_H_
+#define _NFB_RX_H_
+
+#include <nfb/nfb.h>
+#include <nfb/ndp.h>
+
+#include <rte_mbuf.h>
+#include <rte_ethdev.h>
+
+struct ndp_rx_queue {
+ struct nfb_device *nfb; /* nfb dev structure */
+ struct ndp_queue *queue; /* rx queue */
+ uint16_t rx_queue_id; /* index */
+ uint8_t in_port; /* port */
+
+ struct rte_mempool *mb_pool; /* memory pool to allocate packets */
+ uint16_t buf_size; /* mbuf size */
+
+ volatile uint64_t rx_pkts; /* packets read */
+ volatile uint64_t rx_bytes; /* bytes read */
+ volatile uint64_t err_pkts; /* erroneous packets */
+};
+
+/**
+ * Initialize ndp_rx_queue structure
+ *
+ * @param nfb
+ * Pointer to nfb device structure.
+ * @param rx_queue_id
+ * RX queue index.
+ * @param port_id
+ * Device [external] port identifier.
+ * @param mb_pool
+ * Memory pool for buffer allocations.
+ * @param[out] rxq
+ * Pointer to ndp_rx_queue output structure
+ * @return
+ * 0 on success, a negative errno value otherwise.
+ */
+int
+nfb_eth_rx_queue_init(struct nfb_device *nfb,
+ uint16_t rx_queue_id,
+ uint16_t port_id,
+ struct rte_mempool *mb_pool,
+ struct ndp_rx_queue *rxq);
+
+/**
+ * DPDK callback to setup a RX queue for use.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param idx
+ * RX queue index.
+ * @param desc
+ * Number of descriptors to configure in queue.
+ * @param socket
+ * NUMA socket on which memory must be allocated.
+ * @param[in] conf
+ * Thresholds parameters.
+ * @param mb_pool
+ * Memory pool for buffer allocations.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise.
+ */
+int
+nfb_eth_rx_queue_setup(struct rte_eth_dev *dev,
+ uint16_t rx_queue_id,
+ uint16_t nb_rx_desc __rte_unused,
+ unsigned int socket_id,
+ const struct rte_eth_rxconf *rx_conf __rte_unused,
+ struct rte_mempool *mb_pool);
+
+/**
+ * DPDK callback to release a RX queue.
+ *
+ * @param dpdk_rxq
+ * Generic RX queue pointer.
+ */
+void
+nfb_eth_rx_queue_release(void *q);
+
+/**
+ * Start traffic on Rx queue.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param txq_id
+ * RX queue index.
+ * @return
+ * 0 on success, a negative errno value otherwise.
+ */
+int
+nfb_eth_rx_queue_start(struct rte_eth_dev *dev, uint16_t rxq_id);
+
+/**
+ * Stop traffic on Rx queue.
+ *
+ * @param dev
+ * Pointer to Ethernet device structure.
+ * @param txq_id
+ * RX queue index.
+ */
+int
+nfb_eth_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rxq_id);
+
+/**
+ * DPDK callback for RX.
+ *
+ * @param dpdk_rxq
+ * Generic pointer to RX queue structure.
+ * @param[out] bufs
+ * Array to store received packets.
+ * @param nb_pkts
+ * Maximum number of packets in array.
+ *
+ * @return
+ * Number of packets successfully received (<= nb_pkts).
+ */
+static __rte_always_inline uint16_t
+nfb_eth_ndp_rx(void *queue,
+ struct rte_mbuf **bufs,
+ uint16_t nb_pkts)
+{
+ struct ndp_rx_queue *ndp = queue;
+ uint16_t packet_size;
+ uint64_t num_bytes = 0;
+ uint16_t num_rx;
+ unsigned int i;
+
+ const uint16_t buf_size = ndp->buf_size;
+
+ struct rte_mbuf *mbuf;
+ struct ndp_packet packets[nb_pkts];
+
+ struct rte_mbuf *mbufs[nb_pkts];
+
+ if (unlikely(ndp->queue == NULL || nb_pkts == 0)) {
+ RTE_LOG(ERR, PMD, "RX invalid arguments!\n");
+ return 0;
+ }
+
+ /* returns either all or nothing */
+ i = rte_pktmbuf_alloc_bulk(ndp->mb_pool, mbufs, nb_pkts);
+ if (unlikely(i != 0))
+ return 0;
+
+ num_rx = ndp_rx_burst_get(ndp->queue, packets, nb_pkts);
+
+ if (unlikely(num_rx != nb_pkts)) {
+ for (i = num_rx; i < nb_pkts; i++)
+ rte_pktmbuf_free(mbufs[i]);
+ }
+
+ nb_pkts = num_rx;
+
+ num_rx = 0;
+ /*
+ * Reads the given number of packets from NDP queue given
+ * by queue and copies the packet data into a newly allocated mbuf
+ * to return.
+ */
+ for (i = 0; i < nb_pkts; ++i) {
+ mbuf = mbufs[i];
+
+ /* get the space available for data in the mbuf */
+ packet_size = packets[i].data_length;
+
+ if (likely(packet_size <= buf_size)) {
+ /* NDP packet will fit in one mbuf, go ahead and copy */
+ rte_memcpy(rte_pktmbuf_mtod(mbuf, void *),
+ packets[i].data, packet_size);
+
+ mbuf->data_len = (uint16_t)packet_size;
+
+ mbuf->pkt_len = packet_size;
+ mbuf->port = ndp->in_port;
+ bufs[num_rx++] = mbuf;
+ num_bytes += packet_size;
+ } else {
+ /*
+ * NDP packet will not fit in one mbuf,
+ * scattered mode is not enabled, drop packet
+ */
+ rte_pktmbuf_free(mbuf);
+ }
+ }
+
+ ndp_rx_burst_put(ndp->queue);
+
+ ndp->rx_pkts += num_rx;
+ ndp->rx_bytes += num_bytes;
+ return num_rx;
+}
+
+#endif /* _NFB_RX_H_ */