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