net/nfb: add new netcope driver
[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 <rte_ethdev.h>
14 #include <rte_malloc.h>
15
16 struct ndp_tx_queue {
17         struct nfb_device *nfb;     /* nfb dev structure */
18         struct ndp_queue *queue;    /* tx queue */
19         uint16_t          tx_queue_id;       /* index */
20         volatile uint64_t tx_pkts;  /* packets transmitted */
21         volatile uint64_t tx_bytes; /* bytes transmitted */
22         volatile uint64_t err_pkts; /* erroneous packets */
23 };
24
25 /**
26  * DPDK callback to setup a TX queue for use.
27  *
28  * @param dev
29  *   Pointer to Ethernet device structure.
30  * @param idx
31  *   RX queue index.
32  * @param desc
33  *   Number of descriptors to configure in queue.
34  * @param socket
35  *   NUMA socket on which memory must be allocated.
36  * @param[in] conf
37  *   Thresholds parameters.
38  * @param mp
39  *   Memory pool for buffer allocations.
40  *
41  * @return
42  *   0 on success, a negative errno value otherwise.
43  */
44 int
45 nfb_eth_tx_queue_setup(struct rte_eth_dev *dev,
46         uint16_t tx_queue_id,
47         uint16_t nb_tx_desc __rte_unused,
48         unsigned int socket_id,
49         const struct rte_eth_txconf *tx_conf __rte_unused);
50
51 /**
52  * Initialize ndp_tx_queue structure
53  *
54  * @param nfb
55  *   Pointer to nfb device structure.
56  * @param tx_queue_id
57  *   TX queue index.
58  * @param[out] txq
59  *   Pointer to ndp_tx_queue output structure
60  *
61  * @return
62  *   0 on success, a negative errno value otherwise.
63  */
64 int
65 nfb_eth_tx_queue_init(struct nfb_device *nfb,
66         uint16_t tx_queue_id,
67         struct ndp_tx_queue *txq);
68
69 /**
70  * DPDK callback to release a RX queue.
71  *
72  * @param dpdk_rxq
73  *   Generic RX queue pointer.
74  */
75 void
76 nfb_eth_tx_queue_release(void *q);
77
78 /**
79  * Start traffic on Tx queue.
80  *
81  * @param dev
82  *   Pointer to Ethernet device structure.
83  * @param txq_id
84  *   TX queue index.
85  *
86  * @return
87  *   0 on success, a negative errno value otherwise.
88  */
89 int
90 nfb_eth_tx_queue_start(struct rte_eth_dev *dev, uint16_t txq_id);
91
92 /**
93  * Stop traffic on Tx queue.
94  *
95  * @param dev
96  *   Pointer to Ethernet device structure.
97  * @param txq_id
98  *   TX queue index.
99  *
100  * @return
101  *   0 on success, a negative errno value otherwise.
102  */
103 int
104 nfb_eth_tx_queue_stop(struct rte_eth_dev *dev, uint16_t txq_id);
105
106 /**
107  * DPDK callback for TX.
108  *
109  * @param dpdk_txq
110  *   Generic pointer to TX queue structure.
111  * @param bufs
112  *   Packets to transmit.
113  * @param nb_pkts
114  *   Number of packets in array.
115  *
116  * @return
117  *   Number of packets successfully transmitted (<= nb_pkts).
118  */
119 static __rte_always_inline uint16_t
120 nfb_eth_ndp_tx(void *queue,
121         struct rte_mbuf **bufs,
122         uint16_t nb_pkts)
123 {
124         int i;
125         struct rte_mbuf *mbuf;
126         struct ndp_tx_queue *ndp = queue;
127         uint16_t num_tx = 0;
128         uint64_t num_bytes = 0;
129
130         void *dst;
131         uint32_t pkt_len;
132         uint8_t mbuf_segs;
133
134         struct ndp_packet packets[nb_pkts];
135
136         if (unlikely(ndp->queue == NULL || nb_pkts == 0)) {
137                 RTE_LOG(ERR, PMD, "TX invalid arguments!\n");
138                 return 0;
139         }
140
141         for (i = 0; i < nb_pkts; i++) {
142                 packets[i].data_length = bufs[i]->pkt_len;
143                 packets[i].header_length = 0;
144         }
145
146         num_tx = ndp_tx_burst_get(ndp->queue, packets, nb_pkts);
147
148         if (unlikely(num_tx != nb_pkts))
149                 return 0;
150
151         for (i = 0; i < nb_pkts; ++i) {
152                 mbuf = bufs[i];
153
154                 pkt_len = mbuf->pkt_len;
155                 mbuf_segs = mbuf->nb_segs;
156
157                 num_bytes += pkt_len;
158                 if (mbuf_segs == 1) {
159                         /*
160                          * non-scattered packet,
161                          * transmit from one mbuf
162                          */
163                         rte_memcpy(packets[i].data,
164                                 rte_pktmbuf_mtod(mbuf, const void *),
165                                 pkt_len);
166                 } else {
167                         /* scattered packet, transmit from more mbufs */
168                         struct rte_mbuf *m = mbuf;
169                         while (m) {
170                                 dst = packets[i].data;
171
172                                 rte_memcpy(dst,
173                                         rte_pktmbuf_mtod(m,
174                                         const void *),
175                                         m->data_len);
176                                 dst = ((uint8_t *)(dst)) +
177                                         m->data_len;
178                                 m = m->next;
179                         }
180                 }
181
182                 rte_pktmbuf_free(mbuf);
183         }
184
185         ndp_tx_burst_flush(ndp->queue);
186
187         ndp->tx_pkts += num_tx;
188         ndp->err_pkts += nb_pkts - num_tx;
189         ndp->tx_bytes += num_bytes;
190         return num_tx;
191 }
192
193 #endif /* _NFB_TX_H_ */