dpdk/drivers/net/nfb/nfb_rx.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: BSD-3-Clause
   2 * Copyright(c) 2019 Cesnet
   3 * Copyright(c) 2019 Netcope Technologies, a.s. <info@netcope.com>
   4 * All rights reserved.
   5 */
   6
   7#ifndef _NFB_RX_H_
   8#define _NFB_RX_H_
   9
  10#include <nfb/nfb.h>
  11#include <nfb/ndp.h>
  12
  13#include <rte_mbuf.h>
  14#include <rte_mbuf_dyn.h>
  15#include <rte_ethdev.h>
  16
  17#define NFB_TIMESTAMP_FLAG (1 << 0)
  18
  19extern uint64_t nfb_timestamp_rx_dynflag;
  20extern int nfb_timestamp_dynfield_offset;
  21
  22static inline rte_mbuf_timestamp_t *
  23nfb_timestamp_dynfield(struct rte_mbuf *mbuf)
  24{
  25        return RTE_MBUF_DYNFIELD(mbuf,
  26                nfb_timestamp_dynfield_offset, rte_mbuf_timestamp_t *);
  27}
  28
  29struct ndp_rx_queue {
  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 */
  35
  36        struct rte_mempool *mb_pool; /* memory pool to allocate packets */
  37        uint16_t buf_size;           /* mbuf size */
  38
  39        volatile uint64_t rx_pkts;   /* packets read */
  40        volatile uint64_t rx_bytes;  /* bytes read */
  41        volatile uint64_t err_pkts;  /* erroneous packets */
  42};
  43
  44/**
  45 * Initialize ndp_rx_queue structure
  46 *
  47 * @param nfb
  48 *   Pointer to nfb device structure.
  49 * @param rx_queue_id
  50 *   RX queue index.
  51 * @param port_id
  52 *   Device [external] port identifier.
  53 * @param mb_pool
  54 *   Memory pool for buffer allocations.
  55 * @param[out] rxq
  56 *   Pointer to ndp_rx_queue output structure
  57 * @return
  58 *   0 on success, a negative errno value otherwise.
  59 */
  60int
  61nfb_eth_rx_queue_init(struct nfb_device *nfb,
  62        uint16_t rx_queue_id,
  63        uint16_t port_id,
  64        struct rte_mempool *mb_pool,
  65        struct ndp_rx_queue *rxq);
  66
  67/**
  68 * DPDK callback to setup a RX queue for use.
  69 *
  70 * @param dev
  71 *   Pointer to Ethernet device structure.
  72 * @param idx
  73 *   RX queue index.
  74 * @param desc
  75 *   Number of descriptors to configure in queue.
  76 * @param socket
  77 *   NUMA socket on which memory must be allocated.
  78 * @param[in] conf
  79 *   Thresholds parameters.
  80 * @param mb_pool
  81 *   Memory pool for buffer allocations.
  82 *
  83 * @return
  84 *   0 on success, a negative errno value otherwise.
  85 */
  86int
  87nfb_eth_rx_queue_setup(struct rte_eth_dev *dev,
  88        uint16_t rx_queue_id,
  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);
  93
  94/**
  95 * DPDK callback to release a RX queue.
  96 *
  97 * @param dpdk_rxq
  98 *   Generic RX queue pointer.
  99 */
 100void
 101nfb_eth_rx_queue_release(void *q);
 102
 103/**
 104 * Start traffic on Rx queue.
 105 *
 106 * @param dev
 107 *   Pointer to Ethernet device structure.
 108 * @param txq_id
 109 *   RX queue index.
 110 * @return
 111 *   0 on success, a negative errno value otherwise.
 112 */
 113int
 114nfb_eth_rx_queue_start(struct rte_eth_dev *dev, uint16_t rxq_id);
 115
 116/**
 117 * Stop traffic on Rx queue.
 118 *
 119 * @param dev
 120 *   Pointer to Ethernet device structure.
 121 * @param txq_id
 122 *   RX queue index.
 123 */
 124int
 125nfb_eth_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rxq_id);
 126
 127/**
 128 * DPDK callback for RX.
 129 *
 130 * @param dpdk_rxq
 131 *   Generic pointer to RX queue structure.
 132 * @param[out] bufs
 133 *   Array to store received packets.
 134 * @param nb_pkts
 135 *   Maximum number of packets in array.
 136 *
 137 * @return
 138 *   Number of packets successfully received (<= nb_pkts).
 139 */
 140static __rte_always_inline uint16_t
 141nfb_eth_ndp_rx(void *queue,
 142        struct rte_mbuf **bufs,
 143        uint16_t nb_pkts)
 144{
 145        struct ndp_rx_queue *ndp = queue;
 146        uint8_t timestamping_enabled;
 147        uint16_t packet_size;
 148        uint64_t num_bytes = 0;
 149        uint16_t num_rx;
 150        unsigned int i;
 151
 152        const uint16_t buf_size = ndp->buf_size;
 153
 154        struct rte_mbuf *mbuf;
 155        struct ndp_packet packets[nb_pkts];
 156
 157        struct rte_mbuf *mbufs[nb_pkts];
 158
 159        if (unlikely(ndp->queue == NULL || nb_pkts == 0)) {
 160                RTE_LOG(ERR, PMD, "RX invalid arguments!\n");
 161                return 0;
 162        }
 163
 164        timestamping_enabled = ndp->flags & NFB_TIMESTAMP_FLAG;
 165
 166        /* returns either all or nothing */
 167        i = rte_pktmbuf_alloc_bulk(ndp->mb_pool, mbufs, nb_pkts);
 168        if (unlikely(i != 0))
 169                return 0;
 170
 171        num_rx = ndp_rx_burst_get(ndp->queue, packets, nb_pkts);
 172
 173        if (unlikely(num_rx != nb_pkts)) {
 174                for (i = num_rx; i < nb_pkts; i++)
 175                        rte_pktmbuf_free(mbufs[i]);
 176        }
 177
 178        nb_pkts = num_rx;
 179
 180        num_rx = 0;
 181        /*
 182         * Reads the given number of packets from NDP queue given
 183         * by queue and copies the packet data into a newly allocated mbuf
 184         * to return.
 185         */
 186        for (i = 0; i < nb_pkts; ++i) {
 187                mbuf = mbufs[i];
 188
 189                /* get the space available for data in the mbuf */
 190                packet_size = packets[i].data_length;
 191
 192                if (likely(packet_size <= buf_size)) {
 193                        /* NDP packet will fit in one mbuf, go ahead and copy */
 194                        rte_memcpy(rte_pktmbuf_mtod(mbuf, void *),
 195                                packets[i].data, packet_size);
 196
 197                        mbuf->data_len = (uint16_t)packet_size;
 198
 199                        mbuf->pkt_len = packet_size;
 200                        mbuf->port = ndp->in_port;
 201                        mbuf->ol_flags = 0;
 202
 203                        if (timestamping_enabled) {
 204                                rte_mbuf_timestamp_t timestamp;
 205
 206                                /* nanoseconds */
 207                                timestamp =
 208                                        rte_le_to_cpu_32(*((uint32_t *)
 209                                        (packets[i].header + 4)));
 210                                timestamp <<= 32;
 211                                /* seconds */
 212                                timestamp |=
 213                                        rte_le_to_cpu_32(*((uint32_t *)
 214                                        (packets[i].header + 8)));
 215                                *nfb_timestamp_dynfield(mbuf) = timestamp;
 216                                mbuf->ol_flags |= nfb_timestamp_rx_dynflag;
 217                        }
 218
 219                        bufs[num_rx++] = mbuf;
 220                        num_bytes += packet_size;
 221                } else {
 222                        /*
 223                         * NDP packet will not fit in one mbuf,
 224                         * scattered mode is not enabled, drop packet
 225                         */
 226                        rte_pktmbuf_free(mbuf);
 227                }
 228        }
 229
 230        ndp_rx_burst_put(ndp->queue);
 231
 232        ndp->rx_pkts += num_rx;
 233        ndp->rx_bytes += num_bytes;
 234        return num_rx;
 235}
 236
 237#endif /* _NFB_RX_H_ */
 238