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_TX_H_
86435f9a0SRastislav Cernay #define _NFB_TX_H_
96435f9a0SRastislav Cernay
106435f9a0SRastislav Cernay #include <nfb/nfb.h>
116435f9a0SRastislav Cernay #include <nfb/ndp.h>
126435f9a0SRastislav Cernay
13df96fd0dSBruce Richardson #include <ethdev_driver.h>
146435f9a0SRastislav Cernay #include <rte_ethdev.h>
156435f9a0SRastislav Cernay #include <rte_malloc.h>
166435f9a0SRastislav Cernay
176435f9a0SRastislav Cernay struct ndp_tx_queue {
186435f9a0SRastislav Cernay struct nfb_device *nfb; /* nfb dev structure */
196435f9a0SRastislav Cernay struct ndp_queue *queue; /* tx queue */
206435f9a0SRastislav Cernay uint16_t tx_queue_id; /* index */
216435f9a0SRastislav Cernay volatile uint64_t tx_pkts; /* packets transmitted */
226435f9a0SRastislav Cernay volatile uint64_t tx_bytes; /* bytes transmitted */
236435f9a0SRastislav Cernay volatile uint64_t err_pkts; /* erroneous packets */
246435f9a0SRastislav Cernay };
256435f9a0SRastislav Cernay
266435f9a0SRastislav Cernay /**
276435f9a0SRastislav Cernay * DPDK callback to setup a TX queue for use.
286435f9a0SRastislav Cernay *
296435f9a0SRastislav Cernay * @param dev
306435f9a0SRastislav Cernay * Pointer to Ethernet device structure.
316435f9a0SRastislav Cernay * @param idx
326435f9a0SRastislav Cernay * RX queue index.
336435f9a0SRastislav Cernay * @param desc
346435f9a0SRastislav Cernay * Number of descriptors to configure in queue.
356435f9a0SRastislav Cernay * @param socket
366435f9a0SRastislav Cernay * NUMA socket on which memory must be allocated.
376435f9a0SRastislav Cernay * @param[in] conf
386435f9a0SRastislav Cernay * Thresholds parameters.
396435f9a0SRastislav Cernay * @param mp
406435f9a0SRastislav Cernay * Memory pool for buffer allocations.
416435f9a0SRastislav Cernay *
426435f9a0SRastislav Cernay * @return
436435f9a0SRastislav Cernay * 0 on success, a negative errno value otherwise.
446435f9a0SRastislav Cernay */
456435f9a0SRastislav Cernay int
466435f9a0SRastislav Cernay nfb_eth_tx_queue_setup(struct rte_eth_dev *dev,
476435f9a0SRastislav Cernay uint16_t tx_queue_id,
486435f9a0SRastislav Cernay uint16_t nb_tx_desc __rte_unused,
496435f9a0SRastislav Cernay unsigned int socket_id,
506435f9a0SRastislav Cernay const struct rte_eth_txconf *tx_conf __rte_unused);
516435f9a0SRastislav Cernay
526435f9a0SRastislav Cernay /**
536435f9a0SRastislav Cernay * Initialize ndp_tx_queue structure
546435f9a0SRastislav Cernay *
556435f9a0SRastislav Cernay * @param nfb
566435f9a0SRastislav Cernay * Pointer to nfb device structure.
576435f9a0SRastislav Cernay * @param tx_queue_id
586435f9a0SRastislav Cernay * TX queue index.
596435f9a0SRastislav Cernay * @param[out] txq
606435f9a0SRastislav Cernay * Pointer to ndp_tx_queue output structure
616435f9a0SRastislav Cernay *
626435f9a0SRastislav Cernay * @return
636435f9a0SRastislav Cernay * 0 on success, a negative errno value otherwise.
646435f9a0SRastislav Cernay */
656435f9a0SRastislav Cernay int
666435f9a0SRastislav Cernay nfb_eth_tx_queue_init(struct nfb_device *nfb,
676435f9a0SRastislav Cernay uint16_t tx_queue_id,
686435f9a0SRastislav Cernay struct ndp_tx_queue *txq);
696435f9a0SRastislav Cernay
706435f9a0SRastislav Cernay /**
716435f9a0SRastislav Cernay * DPDK callback to release a RX queue.
726435f9a0SRastislav Cernay *
737483341aSXueming Li * @param dev
747483341aSXueming Li * Pointer to Ethernet device structure.
757483341aSXueming Li * @param qid
767483341aSXueming Li * Receive queue index.
776435f9a0SRastislav Cernay */
786435f9a0SRastislav Cernay void
797483341aSXueming Li nfb_eth_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid);
806435f9a0SRastislav Cernay
816435f9a0SRastislav Cernay /**
826435f9a0SRastislav Cernay * Start traffic on Tx queue.
836435f9a0SRastislav Cernay *
846435f9a0SRastislav Cernay * @param dev
856435f9a0SRastislav Cernay * Pointer to Ethernet device structure.
866435f9a0SRastislav Cernay * @param txq_id
876435f9a0SRastislav Cernay * TX queue index.
886435f9a0SRastislav Cernay *
896435f9a0SRastislav Cernay * @return
906435f9a0SRastislav Cernay * 0 on success, a negative errno value otherwise.
916435f9a0SRastislav Cernay */
926435f9a0SRastislav Cernay int
936435f9a0SRastislav Cernay nfb_eth_tx_queue_start(struct rte_eth_dev *dev, uint16_t txq_id);
946435f9a0SRastislav Cernay
956435f9a0SRastislav Cernay /**
966435f9a0SRastislav Cernay * Stop traffic on Tx queue.
976435f9a0SRastislav Cernay *
986435f9a0SRastislav Cernay * @param dev
996435f9a0SRastislav Cernay * Pointer to Ethernet device structure.
1006435f9a0SRastislav Cernay * @param txq_id
1016435f9a0SRastislav Cernay * TX queue index.
1026435f9a0SRastislav Cernay *
1036435f9a0SRastislav Cernay * @return
1046435f9a0SRastislav Cernay * 0 on success, a negative errno value otherwise.
1056435f9a0SRastislav Cernay */
1066435f9a0SRastislav Cernay int
1076435f9a0SRastislav Cernay nfb_eth_tx_queue_stop(struct rte_eth_dev *dev, uint16_t txq_id);
1086435f9a0SRastislav Cernay
1096435f9a0SRastislav Cernay /**
1106435f9a0SRastislav Cernay * DPDK callback for TX.
1116435f9a0SRastislav Cernay *
1126435f9a0SRastislav Cernay * @param dpdk_txq
1136435f9a0SRastislav Cernay * Generic pointer to TX queue structure.
1146435f9a0SRastislav Cernay * @param bufs
1156435f9a0SRastislav Cernay * Packets to transmit.
1166435f9a0SRastislav Cernay * @param nb_pkts
1176435f9a0SRastislav Cernay * Number of packets in array.
1186435f9a0SRastislav Cernay *
1196435f9a0SRastislav Cernay * @return
1206435f9a0SRastislav Cernay * Number of packets successfully transmitted (<= nb_pkts).
1216435f9a0SRastislav Cernay */
1226435f9a0SRastislav Cernay static __rte_always_inline uint16_t
nfb_eth_ndp_tx(void * queue,struct rte_mbuf ** bufs,uint16_t nb_pkts)1236435f9a0SRastislav Cernay nfb_eth_ndp_tx(void *queue,
1246435f9a0SRastislav Cernay struct rte_mbuf **bufs,
1256435f9a0SRastislav Cernay uint16_t nb_pkts)
1266435f9a0SRastislav Cernay {
1276435f9a0SRastislav Cernay int i;
1286435f9a0SRastislav Cernay struct rte_mbuf *mbuf;
1296435f9a0SRastislav Cernay struct ndp_tx_queue *ndp = queue;
1306435f9a0SRastislav Cernay uint16_t num_tx = 0;
1316435f9a0SRastislav Cernay uint64_t num_bytes = 0;
1326435f9a0SRastislav Cernay
1336435f9a0SRastislav Cernay void *dst;
1346435f9a0SRastislav Cernay uint32_t pkt_len;
1356435f9a0SRastislav Cernay uint8_t mbuf_segs;
1366435f9a0SRastislav Cernay
1376435f9a0SRastislav Cernay struct ndp_packet packets[nb_pkts];
1386435f9a0SRastislav Cernay
139f95a6c34SMartin Spinler if (unlikely(nb_pkts == 0))
140f95a6c34SMartin Spinler return 0;
141f95a6c34SMartin Spinler
142f95a6c34SMartin Spinler if (unlikely(ndp->queue == NULL)) {
143*ad616a80SStephen Hemminger NFB_LOG(ERR, "TX invalid arguments");
1446435f9a0SRastislav Cernay return 0;
1456435f9a0SRastislav Cernay }
1466435f9a0SRastislav Cernay
1476435f9a0SRastislav Cernay for (i = 0; i < nb_pkts; i++) {
1486435f9a0SRastislav Cernay packets[i].data_length = bufs[i]->pkt_len;
1496435f9a0SRastislav Cernay packets[i].header_length = 0;
1506435f9a0SRastislav Cernay }
1516435f9a0SRastislav Cernay
1526435f9a0SRastislav Cernay num_tx = ndp_tx_burst_get(ndp->queue, packets, nb_pkts);
1536435f9a0SRastislav Cernay
1546435f9a0SRastislav Cernay if (unlikely(num_tx != nb_pkts))
1556435f9a0SRastislav Cernay return 0;
1566435f9a0SRastislav Cernay
1576435f9a0SRastislav Cernay for (i = 0; i < nb_pkts; ++i) {
1586435f9a0SRastislav Cernay mbuf = bufs[i];
1596435f9a0SRastislav Cernay
1606435f9a0SRastislav Cernay pkt_len = mbuf->pkt_len;
1616435f9a0SRastislav Cernay mbuf_segs = mbuf->nb_segs;
1626435f9a0SRastislav Cernay
1636435f9a0SRastislav Cernay num_bytes += pkt_len;
1646435f9a0SRastislav Cernay if (mbuf_segs == 1) {
1656435f9a0SRastislav Cernay /*
1666435f9a0SRastislav Cernay * non-scattered packet,
1676435f9a0SRastislav Cernay * transmit from one mbuf
1686435f9a0SRastislav Cernay */
1696435f9a0SRastislav Cernay rte_memcpy(packets[i].data,
1706435f9a0SRastislav Cernay rte_pktmbuf_mtod(mbuf, const void *),
1716435f9a0SRastislav Cernay pkt_len);
1726435f9a0SRastislav Cernay } else {
1736435f9a0SRastislav Cernay /* scattered packet, transmit from more mbufs */
1746435f9a0SRastislav Cernay struct rte_mbuf *m = mbuf;
1756435f9a0SRastislav Cernay while (m) {
1766435f9a0SRastislav Cernay dst = packets[i].data;
1776435f9a0SRastislav Cernay
1786435f9a0SRastislav Cernay rte_memcpy(dst,
1796435f9a0SRastislav Cernay rte_pktmbuf_mtod(m,
1806435f9a0SRastislav Cernay const void *),
1816435f9a0SRastislav Cernay m->data_len);
1826435f9a0SRastislav Cernay dst = ((uint8_t *)(dst)) +
1836435f9a0SRastislav Cernay m->data_len;
1846435f9a0SRastislav Cernay m = m->next;
1856435f9a0SRastislav Cernay }
1866435f9a0SRastislav Cernay }
1876435f9a0SRastislav Cernay
1886435f9a0SRastislav Cernay rte_pktmbuf_free(mbuf);
1896435f9a0SRastislav Cernay }
1906435f9a0SRastislav Cernay
1916435f9a0SRastislav Cernay ndp_tx_burst_flush(ndp->queue);
1926435f9a0SRastislav Cernay
1936435f9a0SRastislav Cernay ndp->tx_pkts += num_tx;
1946435f9a0SRastislav Cernay ndp->err_pkts += nb_pkts - num_tx;
1956435f9a0SRastislav Cernay ndp->tx_bytes += num_bytes;
1966435f9a0SRastislav Cernay return num_tx;
1976435f9a0SRastislav Cernay }
1986435f9a0SRastislav Cernay
1996435f9a0SRastislav Cernay #endif /* _NFB_TX_H_ */
200