f95a6c34bb
Zero-sized TX burst floods the log no more. Signed-off-by: Martin Spinler <spinler@cesnet.cz>
200 lines
4.1 KiB
C
200 lines
4.1 KiB
C
/* 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_TX_H_
|
|
#define _NFB_TX_H_
|
|
|
|
#include <nfb/nfb.h>
|
|
#include <nfb/ndp.h>
|
|
|
|
#include <ethdev_driver.h>
|
|
#include <rte_ethdev.h>
|
|
#include <rte_malloc.h>
|
|
|
|
struct ndp_tx_queue {
|
|
struct nfb_device *nfb; /* nfb dev structure */
|
|
struct ndp_queue *queue; /* tx queue */
|
|
uint16_t tx_queue_id; /* index */
|
|
volatile uint64_t tx_pkts; /* packets transmitted */
|
|
volatile uint64_t tx_bytes; /* bytes transmitted */
|
|
volatile uint64_t err_pkts; /* erroneous packets */
|
|
};
|
|
|
|
/**
|
|
* DPDK callback to setup a TX 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 mp
|
|
* Memory pool for buffer allocations.
|
|
*
|
|
* @return
|
|
* 0 on success, a negative errno value otherwise.
|
|
*/
|
|
int
|
|
nfb_eth_tx_queue_setup(struct rte_eth_dev *dev,
|
|
uint16_t tx_queue_id,
|
|
uint16_t nb_tx_desc __rte_unused,
|
|
unsigned int socket_id,
|
|
const struct rte_eth_txconf *tx_conf __rte_unused);
|
|
|
|
/**
|
|
* Initialize ndp_tx_queue structure
|
|
*
|
|
* @param nfb
|
|
* Pointer to nfb device structure.
|
|
* @param tx_queue_id
|
|
* TX queue index.
|
|
* @param[out] txq
|
|
* Pointer to ndp_tx_queue output structure
|
|
*
|
|
* @return
|
|
* 0 on success, a negative errno value otherwise.
|
|
*/
|
|
int
|
|
nfb_eth_tx_queue_init(struct nfb_device *nfb,
|
|
uint16_t tx_queue_id,
|
|
struct ndp_tx_queue *txq);
|
|
|
|
/**
|
|
* DPDK callback to release a RX queue.
|
|
*
|
|
* @param dev
|
|
* Pointer to Ethernet device structure.
|
|
* @param qid
|
|
* Receive queue index.
|
|
*/
|
|
void
|
|
nfb_eth_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid);
|
|
|
|
/**
|
|
* Start traffic on Tx queue.
|
|
*
|
|
* @param dev
|
|
* Pointer to Ethernet device structure.
|
|
* @param txq_id
|
|
* TX queue index.
|
|
*
|
|
* @return
|
|
* 0 on success, a negative errno value otherwise.
|
|
*/
|
|
int
|
|
nfb_eth_tx_queue_start(struct rte_eth_dev *dev, uint16_t txq_id);
|
|
|
|
/**
|
|
* Stop traffic on Tx queue.
|
|
*
|
|
* @param dev
|
|
* Pointer to Ethernet device structure.
|
|
* @param txq_id
|
|
* TX queue index.
|
|
*
|
|
* @return
|
|
* 0 on success, a negative errno value otherwise.
|
|
*/
|
|
int
|
|
nfb_eth_tx_queue_stop(struct rte_eth_dev *dev, uint16_t txq_id);
|
|
|
|
/**
|
|
* DPDK callback for TX.
|
|
*
|
|
* @param dpdk_txq
|
|
* Generic pointer to TX queue structure.
|
|
* @param bufs
|
|
* Packets to transmit.
|
|
* @param nb_pkts
|
|
* Number of packets in array.
|
|
*
|
|
* @return
|
|
* Number of packets successfully transmitted (<= nb_pkts).
|
|
*/
|
|
static __rte_always_inline uint16_t
|
|
nfb_eth_ndp_tx(void *queue,
|
|
struct rte_mbuf **bufs,
|
|
uint16_t nb_pkts)
|
|
{
|
|
int i;
|
|
struct rte_mbuf *mbuf;
|
|
struct ndp_tx_queue *ndp = queue;
|
|
uint16_t num_tx = 0;
|
|
uint64_t num_bytes = 0;
|
|
|
|
void *dst;
|
|
uint32_t pkt_len;
|
|
uint8_t mbuf_segs;
|
|
|
|
struct ndp_packet packets[nb_pkts];
|
|
|
|
if (unlikely(nb_pkts == 0))
|
|
return 0;
|
|
|
|
if (unlikely(ndp->queue == NULL)) {
|
|
RTE_LOG(ERR, PMD, "TX invalid arguments!\n");
|
|
return 0;
|
|
}
|
|
|
|
for (i = 0; i < nb_pkts; i++) {
|
|
packets[i].data_length = bufs[i]->pkt_len;
|
|
packets[i].header_length = 0;
|
|
}
|
|
|
|
num_tx = ndp_tx_burst_get(ndp->queue, packets, nb_pkts);
|
|
|
|
if (unlikely(num_tx != nb_pkts))
|
|
return 0;
|
|
|
|
for (i = 0; i < nb_pkts; ++i) {
|
|
mbuf = bufs[i];
|
|
|
|
pkt_len = mbuf->pkt_len;
|
|
mbuf_segs = mbuf->nb_segs;
|
|
|
|
num_bytes += pkt_len;
|
|
if (mbuf_segs == 1) {
|
|
/*
|
|
* non-scattered packet,
|
|
* transmit from one mbuf
|
|
*/
|
|
rte_memcpy(packets[i].data,
|
|
rte_pktmbuf_mtod(mbuf, const void *),
|
|
pkt_len);
|
|
} else {
|
|
/* scattered packet, transmit from more mbufs */
|
|
struct rte_mbuf *m = mbuf;
|
|
while (m) {
|
|
dst = packets[i].data;
|
|
|
|
rte_memcpy(dst,
|
|
rte_pktmbuf_mtod(m,
|
|
const void *),
|
|
m->data_len);
|
|
dst = ((uint8_t *)(dst)) +
|
|
m->data_len;
|
|
m = m->next;
|
|
}
|
|
}
|
|
|
|
rte_pktmbuf_free(mbuf);
|
|
}
|
|
|
|
ndp_tx_burst_flush(ndp->queue);
|
|
|
|
ndp->tx_pkts += num_tx;
|
|
ndp->err_pkts += nb_pkts - num_tx;
|
|
ndp->tx_bytes += num_bytes;
|
|
return num_tx;
|
|
}
|
|
|
|
#endif /* _NFB_TX_H_ */
|