xref: /dpdk/drivers/net/nfb/nfb_tx.h (revision 68a03efeed657e6e05f281479b33b51102797e15)
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 
17 struct 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  */
45 int
46 nfb_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  */
65 int
66 nfb_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  */
76 void
77 nfb_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  */
90 int
91 nfb_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  */
104 int
105 nfb_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  */
120 static __rte_always_inline uint16_t
121 nfb_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