xref: /dpdk/drivers/net/nfb/nfb_tx.h (revision ad616a807c560ab1efdca14984fd8c3294bce65b)
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