1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2020 Intel Corporation
10 #include <rte_ethdev.h>
11 #include <rte_hexdump.h>
13 #include "rte_swx_port_ethdev.h"
15 #define CHECK(condition) \
26 #define TRACE(...) printf(__VA_ARGS__)
40 struct rte_swx_port_in_stats stats;
41 struct rte_mbuf **pkts;
47 reader_create(void *args)
49 struct rte_eth_dev_info info;
50 struct rte_swx_port_ethdev_reader_params *params = args;
55 /* Check input parameters. */
58 CHECK(params->dev_name);
59 status = rte_eth_dev_get_port_by_name(params->dev_name, &port_id);
62 status = rte_eth_dev_info_get(port_id, &info);
63 CHECK((status == -ENOTSUP) || (params->queue_id < info.nb_rx_queues));
65 CHECK(params->burst_size);
67 /* Memory allocation. */
68 p = calloc(1, sizeof(struct reader));
71 p->pkts = calloc(params->burst_size, sizeof(struct rte_mbuf *));
78 p->params.port_id = port_id;
79 p->params.queue_id = params->queue_id;
80 p->params.burst_size = params->burst_size;
86 reader_pkt_rx(void *port, struct rte_swx_pkt *pkt)
88 struct reader *p = port;
91 if (p->pos == p->n_pkts) {
94 n_pkts = rte_eth_rx_burst(p->params.port_id,
97 p->params.burst_size);
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,
112 m = p->pkts[p->pos++];
114 pkt->pkt = m->buf_addr;
115 pkt->offset = m->data_off;
116 pkt->length = m->pkt_len;
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,
127 &((uint8_t *)m->buf_addr)[m->data_off],
131 p->stats.n_bytes += pkt->length;
137 reader_free(void *port)
139 struct reader *p = port;
145 for (i = 0; i < p->n_pkts; i++) {
146 struct rte_mbuf *pkt = p->pkts[i];
148 rte_pktmbuf_free(pkt);
156 reader_stats_read(void *port, struct rte_swx_port_in_stats *stats)
158 struct reader *p = port;
160 memcpy(stats, &p->stats, sizeof(p->stats));
172 struct rte_swx_port_out_stats stats;
174 struct rte_mbuf **pkts;
179 writer_create(void *args)
181 struct rte_eth_dev_info info;
182 struct rte_swx_port_ethdev_writer_params *params = args;
187 /* Check input parameters. */
190 CHECK(params->dev_name);
191 status = rte_eth_dev_get_port_by_name(params->dev_name, &port_id);
194 status = rte_eth_dev_info_get(port_id, &info);
195 CHECK((status == -ENOTSUP) || (params->queue_id < info.nb_tx_queues));
197 CHECK(params->burst_size);
199 /* Memory allocation. */
200 p = calloc(1, sizeof(struct writer));
203 p->pkts = calloc(params->burst_size, sizeof(struct rte_mbuf *));
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;
218 __writer_flush(struct writer *p)
222 for (n_pkts = 0; ; ) {
223 n_pkts += rte_eth_tx_burst(p->params.port_id,
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,
233 if (n_pkts == p->n_pkts)
241 writer_pkt_tx(void *port, struct rte_swx_pkt *pkt)
243 struct writer *p = port;
244 struct rte_mbuf *m = pkt->handle;
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,
253 rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
255 m->pkt_len = pkt->length;
256 m->data_len = (uint16_t)pkt->length;
257 m->data_off = (uint16_t)pkt->offset;
260 p->stats.n_bytes += pkt->length;
262 p->pkts[p->n_pkts++] = m;
263 if (p->n_pkts == (int)p->params.burst_size)
268 writer_flush(void *port)
270 struct writer *p = port;
277 writer_free(void *port)
279 struct writer *p = port;
290 writer_stats_read(void *port, struct rte_swx_port_out_stats *stats)
292 struct writer *p = port;
294 memcpy(stats, &p->stats, sizeof(p->stats));
298 * Summary of port operations
300 struct rte_swx_port_in_ops rte_swx_port_ethdev_reader_ops = {
301 .create = reader_create,
303 .pkt_rx = reader_pkt_rx,
304 .stats_read = reader_stats_read,
307 struct rte_swx_port_out_ops rte_swx_port_ethdev_writer_ops = {
308 .create = writer_create,
310 .pkt_tx = writer_pkt_tx,
311 .flush = writer_flush,
312 .stats_read = writer_stats_read,