net/ena: fix build with GCC 12
[dpdk.git] / drivers / net / nfb / nfb_tx.h
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 dev
74  *   Pointer to Ethernet device structure.
75  * @param qid
76  *   Receive queue index.
77  */
78 void
79 nfb_eth_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid);
80
81 /**
82  * Start traffic on Tx queue.
83  *
84  * @param dev
85  *   Pointer to Ethernet device structure.
86  * @param txq_id
87  *   TX queue index.
88  *
89  * @return
90  *   0 on success, a negative errno value otherwise.
91  */
92 int
93 nfb_eth_tx_queue_start(struct rte_eth_dev *dev, uint16_t txq_id);
94
95 /**
96  * Stop traffic on Tx queue.
97  *
98  * @param dev
99  *   Pointer to Ethernet device structure.
100  * @param txq_id
101  *   TX queue index.
102  *
103  * @return
104  *   0 on success, a negative errno value otherwise.
105  */
106 int
107 nfb_eth_tx_queue_stop(struct rte_eth_dev *dev, uint16_t txq_id);
108
109 /**
110  * DPDK callback for TX.
111  *
112  * @param dpdk_txq
113  *   Generic pointer to TX queue structure.
114  * @param bufs
115  *   Packets to transmit.
116  * @param nb_pkts
117  *   Number of packets in array.
118  *
119  * @return
120  *   Number of packets successfully transmitted (<= nb_pkts).
121  */
122 static __rte_always_inline uint16_t
123 nfb_eth_ndp_tx(void *queue,
124         struct rte_mbuf **bufs,
125         uint16_t nb_pkts)
126 {
127         int i;
128         struct rte_mbuf *mbuf;
129         struct ndp_tx_queue *ndp = queue;
130         uint16_t num_tx = 0;
131         uint64_t num_bytes = 0;
132
133         void *dst;
134         uint32_t pkt_len;
135         uint8_t mbuf_segs;
136
137         struct ndp_packet packets[nb_pkts];
138
139         if (unlikely(nb_pkts == 0))
140                 return 0;
141
142         if (unlikely(ndp->queue == NULL)) {
143                 RTE_LOG(ERR, PMD, "TX invalid arguments!\n");
144                 return 0;
145         }
146
147         for (i = 0; i < nb_pkts; i++) {
148                 packets[i].data_length = bufs[i]->pkt_len;
149                 packets[i].header_length = 0;
150         }
151
152         num_tx = ndp_tx_burst_get(ndp->queue, packets, nb_pkts);
153
154         if (unlikely(num_tx != nb_pkts))
155                 return 0;
156
157         for (i = 0; i < nb_pkts; ++i) {
158                 mbuf = bufs[i];
159
160                 pkt_len = mbuf->pkt_len;
161                 mbuf_segs = mbuf->nb_segs;
162
163                 num_bytes += pkt_len;
164                 if (mbuf_segs == 1) {
165                         /*
166                          * non-scattered packet,
167                          * transmit from one mbuf
168                          */
169                         rte_memcpy(packets[i].data,
170                                 rte_pktmbuf_mtod(mbuf, const void *),
171                                 pkt_len);
172                 } else {
173                         /* scattered packet, transmit from more mbufs */
174                         struct rte_mbuf *m = mbuf;
175                         while (m) {
176                                 dst = packets[i].data;
177
178                                 rte_memcpy(dst,
179                                         rte_pktmbuf_mtod(m,
180                                         const void *),
181                                         m->data_len);
182                                 dst = ((uint8_t *)(dst)) +
183                                         m->data_len;
184                                 m = m->next;
185                         }
186                 }
187
188                 rte_pktmbuf_free(mbuf);
189         }
190
191         ndp_tx_burst_flush(ndp->queue);
192
193         ndp->tx_pkts += num_tx;
194         ndp->err_pkts += nb_pkts - num_tx;
195         ndp->tx_bytes += num_bytes;
196         return num_tx;
197 }
198
199 #endif /* _NFB_TX_H_ */