dpdk/drivers/net/nfb/nfb_tx.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_TX_H_
   8#define _NFB_TX_H_
   9
  10#include <nfb/nfb.h>
  11#include <nfb/ndp.h>
  12
  13#include <ethdev_driver.h>
  14#include <rte_ethdev.h>
  15#include <rte_malloc.h>
  16
  17struct ndp_tx_queue {
  18        struct nfb_device *nfb;     /* nfb dev structure */
  19        struct ndp_queue *queue;    /* tx queue */
  20        uint16_t          tx_queue_id;       /* index */
  21        volatile uint64_t tx_pkts;  /* packets transmitted */
  22        volatile uint64_t tx_bytes; /* bytes transmitted */
  23        volatile uint64_t err_pkts; /* erroneous packets */
  24};
  25
  26/**
  27 * DPDK callback to setup a TX queue for use.
  28 *
  29 * @param dev
  30 *   Pointer to Ethernet device structure.
  31 * @param idx
  32 *   RX queue index.
  33 * @param desc
  34 *   Number of descriptors to configure in queue.
  35 * @param socket
  36 *   NUMA socket on which memory must be allocated.
  37 * @param[in] conf
  38 *   Thresholds parameters.
  39 * @param mp
  40 *   Memory pool for buffer allocations.
  41 *
  42 * @return
  43 *   0 on success, a negative errno value otherwise.
  44 */
  45int
  46nfb_eth_tx_queue_setup(struct rte_eth_dev *dev,
  47        uint16_t tx_queue_id,
  48        uint16_t nb_tx_desc __rte_unused,
  49        unsigned int socket_id,
  50        const struct rte_eth_txconf *tx_conf __rte_unused);
  51
  52/**
  53 * Initialize ndp_tx_queue structure
  54 *
  55 * @param nfb
  56 *   Pointer to nfb device structure.
  57 * @param tx_queue_id
  58 *   TX queue index.
  59 * @param[out] txq
  60 *   Pointer to ndp_tx_queue output structure
  61 *
  62 * @return
  63 *   0 on success, a negative errno value otherwise.
  64 */
  65int
  66nfb_eth_tx_queue_init(struct nfb_device *nfb,
  67        uint16_t tx_queue_id,
  68        struct ndp_tx_queue *txq);
  69
  70/**
  71 * DPDK callback to release a RX queue.
  72 *
  73 * @param dpdk_rxq
  74 *   Generic RX queue pointer.
  75 */
  76void
  77nfb_eth_tx_queue_release(void *q);
  78
  79/**
  80 * Start traffic on Tx queue.
  81 *
  82 * @param dev
  83 *   Pointer to Ethernet device structure.
  84 * @param txq_id
  85 *   TX queue index.
  86 *
  87 * @return
  88 *   0 on success, a negative errno value otherwise.
  89 */
  90int
  91nfb_eth_tx_queue_start(struct rte_eth_dev *dev, uint16_t txq_id);
  92
  93/**
  94 * Stop traffic on Tx queue.
  95 *
  96 * @param dev
  97 *   Pointer to Ethernet device structure.
  98 * @param txq_id
  99 *   TX queue index.
 100 *
 101 * @return
 102 *   0 on success, a negative errno value otherwise.
 103 */
 104int
 105nfb_eth_tx_queue_stop(struct rte_eth_dev *dev, uint16_t txq_id);
 106
 107/**
 108 * DPDK callback for TX.
 109 *
 110 * @param dpdk_txq
 111 *   Generic pointer to TX queue structure.
 112 * @param bufs
 113 *   Packets to transmit.
 114 * @param nb_pkts
 115 *   Number of packets in array.
 116 *
 117 * @return
 118 *   Number of packets successfully transmitted (<= nb_pkts).
 119 */
 120static __rte_always_inline uint16_t
 121nfb_eth_ndp_tx(void *queue,
 122        struct rte_mbuf **bufs,
 123        uint16_t nb_pkts)
 124{
 125        int i;
 126        struct rte_mbuf *mbuf;
 127        struct ndp_tx_queue *ndp = queue;
 128        uint16_t num_tx = 0;
 129        uint64_t num_bytes = 0;
 130
 131        void *dst;
 132        uint32_t pkt_len;
 133        uint8_t mbuf_segs;
 134
 135        struct ndp_packet packets[nb_pkts];
 136
 137        if (unlikely(ndp->queue == NULL || nb_pkts == 0)) {
 138                RTE_LOG(ERR, PMD, "TX invalid arguments!\n");
 139                return 0;
 140        }
 141
 142        for (i = 0; i < nb_pkts; i++) {
 143                packets[i].data_length = bufs[i]->pkt_len;
 144                packets[i].header_length = 0;
 145        }
 146
 147        num_tx = ndp_tx_burst_get(ndp->queue, packets, nb_pkts);
 148
 149        if (unlikely(num_tx != nb_pkts))
 150                return 0;
 151
 152        for (i = 0; i < nb_pkts; ++i) {
 153                mbuf = bufs[i];
 154
 155                pkt_len = mbuf->pkt_len;
 156                mbuf_segs = mbuf->nb_segs;
 157
 158                num_bytes += pkt_len;
 159                if (mbuf_segs == 1) {
 160                        /*
 161                         * non-scattered packet,
 162                         * transmit from one mbuf
 163                         */
 164                        rte_memcpy(packets[i].data,
 165                                rte_pktmbuf_mtod(mbuf, const void *),
 166                                pkt_len);
 167                } else {
 168                        /* scattered packet, transmit from more mbufs */
 169                        struct rte_mbuf *m = mbuf;
 170                        while (m) {
 171                                dst = packets[i].data;
 172
 173                                rte_memcpy(dst,
 174                                        rte_pktmbuf_mtod(m,
 175                                        const void *),
 176                                        m->data_len);
 177                                dst = ((uint8_t *)(dst)) +
 178                                        m->data_len;
 179                                m = m->next;
 180                        }
 181                }
 182
 183                rte_pktmbuf_free(mbuf);
 184        }
 185
 186        ndp_tx_burst_flush(ndp->queue);
 187
 188        ndp->tx_pkts += num_tx;
 189        ndp->err_pkts += nb_pkts - num_tx;
 190        ndp->tx_bytes += num_bytes;
 191        return num_tx;
 192}
 193
 194#endif /* _NFB_TX_H_ */
 195