lib: remove librte_ prefix from directory names
[dpdk.git] / lib / port / rte_swx_port_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2020 Intel Corporation
3  */
4 #include <string.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <stdint.h>
8
9 #include <rte_mbuf.h>
10 #include <rte_ethdev.h>
11 #include <rte_hexdump.h>
12
13 #include "rte_swx_port_ethdev.h"
14
15 #define CHECK(condition)                                                       \
16 do {                                                                           \
17         if (!(condition))                                                      \
18                 return NULL;                                                   \
19 } while (0)
20
21 #ifndef TRACE_LEVEL
22 #define TRACE_LEVEL 0
23 #endif
24
25 #if TRACE_LEVEL
26 #define TRACE(...) printf(__VA_ARGS__)
27 #else
28 #define TRACE(...)
29 #endif
30
31 /*
32  * Port ETHDEV Reader
33  */
34 struct reader {
35         struct {
36                 uint16_t port_id;
37                 uint16_t queue_id;
38                 uint32_t burst_size;
39         } params;
40         struct rte_swx_port_in_stats stats;
41         struct rte_mbuf **pkts;
42         int n_pkts;
43         int pos;
44 };
45
46 static void *
47 reader_create(void *args)
48 {
49         struct rte_eth_dev_info info;
50         struct rte_swx_port_ethdev_reader_params *params = args;
51         struct reader *p;
52         int status;
53         uint16_t port_id;
54
55         /* Check input parameters. */
56         CHECK(params);
57
58         CHECK(params->dev_name);
59         status = rte_eth_dev_get_port_by_name(params->dev_name, &port_id);
60         CHECK(!status);
61
62         status = rte_eth_dev_info_get(port_id, &info);
63         CHECK((status == -ENOTSUP) || (params->queue_id < info.nb_rx_queues));
64
65         CHECK(params->burst_size);
66
67         /* Memory allocation. */
68         p = calloc(1, sizeof(struct reader));
69         CHECK(p);
70
71         p->pkts = calloc(params->burst_size, sizeof(struct rte_mbuf *));
72         if (!p->pkts) {
73                 free(p);
74                 CHECK(0);
75         }
76
77         /* Initialization. */
78         p->params.port_id = port_id;
79         p->params.queue_id = params->queue_id;
80         p->params.burst_size = params->burst_size;
81
82         return p;
83 }
84
85 static int
86 reader_pkt_rx(void *port, struct rte_swx_pkt *pkt)
87 {
88         struct reader *p = port;
89         struct rte_mbuf *m;
90
91         if (p->pos == p->n_pkts) {
92                 int n_pkts;
93
94                 n_pkts = rte_eth_rx_burst(p->params.port_id,
95                                           p->params.queue_id,
96                                           p->pkts,
97                                           p->params.burst_size);
98                 if (!n_pkts) {
99                         p->stats.n_empty++;
100                         return 0;
101                 }
102
103                 TRACE("[Ethdev RX port %u queue %u] %d packets in\n",
104                       (uint32_t)p->params.port_id,
105                       (uint32_t)p->params.queue_id,
106                       n_pkts);
107
108                 p->n_pkts = n_pkts;
109                 p->pos = 0;
110         }
111
112         m = p->pkts[p->pos++];
113         pkt->handle = m;
114         pkt->pkt = m->buf_addr;
115         pkt->offset = m->data_off;
116         pkt->length = m->pkt_len;
117
118         TRACE("[Ethdev RX port %u queue %u] Pkt %d (%u bytes at offset %u)\n",
119               (uint32_t)p->params.port_id,
120               (uint32_t)p->params.queue_id,
121               p->pos - 1,
122               pkt->length,
123               pkt->offset);
124         if (TRACE_LEVEL)
125                 rte_hexdump(stdout,
126                             NULL,
127                             &((uint8_t *)m->buf_addr)[m->data_off],
128                             m->data_len);
129
130         p->stats.n_pkts++;
131         p->stats.n_bytes += pkt->length;
132
133         return 1;
134 }
135
136 static void
137 reader_free(void *port)
138 {
139         struct reader *p = port;
140         int i;
141
142         if (!p)
143                 return;
144
145         for (i = 0; i < p->n_pkts; i++) {
146                 struct rte_mbuf *pkt = p->pkts[i];
147
148                 rte_pktmbuf_free(pkt);
149         }
150
151         free(p->pkts);
152         free(p);
153 }
154
155 static void
156 reader_stats_read(void *port, struct rte_swx_port_in_stats *stats)
157 {
158         struct reader *p = port;
159
160         memcpy(stats, &p->stats, sizeof(p->stats));
161 }
162
163 /*
164  * Port ETHDEV Writer
165  */
166 struct writer {
167         struct {
168                 uint16_t port_id;
169                 uint16_t queue_id;
170                 uint32_t burst_size;
171         } params;
172         struct rte_swx_port_out_stats stats;
173
174         struct rte_mbuf **pkts;
175         int n_pkts;
176 };
177
178 static void *
179 writer_create(void *args)
180 {
181         struct rte_eth_dev_info info;
182         struct rte_swx_port_ethdev_writer_params *params = args;
183         struct writer *p;
184         int status;
185         uint16_t port_id;
186
187         /* Check input parameters. */
188         CHECK(params);
189
190         CHECK(params->dev_name);
191         status = rte_eth_dev_get_port_by_name(params->dev_name, &port_id);
192         CHECK(!status);
193
194         status = rte_eth_dev_info_get(port_id, &info);
195         CHECK((status == -ENOTSUP) || (params->queue_id < info.nb_tx_queues));
196
197         CHECK(params->burst_size);
198
199         /* Memory allocation. */
200         p = calloc(1, sizeof(struct writer));
201         CHECK(p);
202
203         p->pkts = calloc(params->burst_size, sizeof(struct rte_mbuf *));
204         if (!p->pkts) {
205                 free(p);
206                 CHECK(0);
207         }
208
209         /* Initialization. */
210         p->params.port_id = port_id;
211         p->params.queue_id = params->queue_id;
212         p->params.burst_size = params->burst_size;
213
214         return p;
215 }
216
217 static void
218 __writer_flush(struct writer *p)
219 {
220         int n_pkts;
221
222         for (n_pkts = 0; ; ) {
223                 n_pkts += rte_eth_tx_burst(p->params.port_id,
224                                            p->params.queue_id,
225                                            p->pkts + n_pkts,
226                                            p->n_pkts - n_pkts);
227
228                 TRACE("[Ethdev TX port %u queue %u] %d packets out\n",
229                       (uint32_t)p->params.port_id,
230                       (uint32_t)p->params.queue_id,
231                       n_pkts);
232
233                 if (n_pkts == p->n_pkts)
234                         break;
235         }
236
237         p->n_pkts = 0;
238 }
239
240 static void
241 writer_pkt_tx(void *port, struct rte_swx_pkt *pkt)
242 {
243         struct writer *p = port;
244         struct rte_mbuf *m = pkt->handle;
245
246         TRACE("[Ethdev TX port %u queue %u] Pkt %d (%u bytes at offset %u)\n",
247               (uint32_t)p->params.port_id,
248               (uint32_t)p->params.queue_id,
249               p->n_pkts - 1,
250               pkt->length,
251               pkt->offset);
252         if (TRACE_LEVEL)
253                 rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
254
255         m->pkt_len = pkt->length;
256         m->data_len = (uint16_t)pkt->length;
257         m->data_off = (uint16_t)pkt->offset;
258
259         p->stats.n_pkts++;
260         p->stats.n_bytes += pkt->length;
261
262         p->pkts[p->n_pkts++] = m;
263         if (p->n_pkts ==  (int)p->params.burst_size)
264                 __writer_flush(p);
265 }
266
267 static void
268 writer_flush(void *port)
269 {
270         struct writer *p = port;
271
272         if (p->n_pkts)
273                 __writer_flush(p);
274 }
275
276 static void
277 writer_free(void *port)
278 {
279         struct writer *p = port;
280
281         if (!p)
282                 return;
283
284         writer_flush(p);
285         free(p->pkts);
286         free(port);
287 }
288
289 static void
290 writer_stats_read(void *port, struct rte_swx_port_out_stats *stats)
291 {
292         struct writer *p = port;
293
294         memcpy(stats, &p->stats, sizeof(p->stats));
295 }
296
297 /*
298  * Summary of port operations
299  */
300 struct rte_swx_port_in_ops rte_swx_port_ethdev_reader_ops = {
301         .create = reader_create,
302         .free = reader_free,
303         .pkt_rx = reader_pkt_rx,
304         .stats_read = reader_stats_read,
305 };
306
307 struct rte_swx_port_out_ops rte_swx_port_ethdev_writer_ops = {
308         .create = writer_create,
309         .free = writer_free,
310         .pkt_tx = writer_pkt_tx,
311         .flush = writer_flush,
312         .stats_read = writer_stats_read,
313 };