199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson * Copyright(c) 2021 Intel Corporation
399a2dd95SBruce Richardson */
499a2dd95SBruce Richardson #include <string.h>
599a2dd95SBruce Richardson #include <stdint.h>
672b452c5SDmitry Kozlyuk #include <stdlib.h>
799a2dd95SBruce Richardson
899a2dd95SBruce Richardson #include <rte_mbuf.h>
999a2dd95SBruce Richardson #include <rte_ring.h>
1099a2dd95SBruce Richardson #include <rte_hexdump.h>
1199a2dd95SBruce Richardson
1299a2dd95SBruce Richardson #include "rte_swx_port_ring.h"
1399a2dd95SBruce Richardson
1499a2dd95SBruce Richardson #ifndef TRACE_LEVEL
1599a2dd95SBruce Richardson #define TRACE_LEVEL 0
1699a2dd95SBruce Richardson #endif
1799a2dd95SBruce Richardson
1899a2dd95SBruce Richardson #if TRACE_LEVEL
1999a2dd95SBruce Richardson #define TRACE(...) printf(__VA_ARGS__)
2099a2dd95SBruce Richardson #else
2199a2dd95SBruce Richardson #define TRACE(...)
2299a2dd95SBruce Richardson #endif
2399a2dd95SBruce Richardson
2499a2dd95SBruce Richardson /*
2599a2dd95SBruce Richardson * Reader
2699a2dd95SBruce Richardson */
2799a2dd95SBruce Richardson struct reader {
2899a2dd95SBruce Richardson struct {
2999a2dd95SBruce Richardson struct rte_ring *ring;
3099a2dd95SBruce Richardson char *name;
3199a2dd95SBruce Richardson uint32_t burst_size;
3299a2dd95SBruce Richardson } params;
3399a2dd95SBruce Richardson struct rte_swx_port_in_stats stats;
3499a2dd95SBruce Richardson struct rte_mbuf **pkts;
3599a2dd95SBruce Richardson int n_pkts;
3699a2dd95SBruce Richardson int pos;
3799a2dd95SBruce Richardson };
3899a2dd95SBruce Richardson
3999a2dd95SBruce Richardson static void *
reader_create(void * args)4099a2dd95SBruce Richardson reader_create(void *args)
4199a2dd95SBruce Richardson {
4299a2dd95SBruce Richardson struct rte_swx_port_ring_reader_params *params = args;
4399a2dd95SBruce Richardson struct rte_ring *ring;
4499a2dd95SBruce Richardson struct reader *p = NULL;
4599a2dd95SBruce Richardson
4699a2dd95SBruce Richardson /* Check input parameters. */
4799a2dd95SBruce Richardson if (!params || !params->name || !params->burst_size)
4899a2dd95SBruce Richardson goto error;
4999a2dd95SBruce Richardson
5099a2dd95SBruce Richardson ring = rte_ring_lookup(params->name);
5199a2dd95SBruce Richardson if (!ring)
5299a2dd95SBruce Richardson goto error;
5399a2dd95SBruce Richardson
5499a2dd95SBruce Richardson /* Memory allocation. */
5599a2dd95SBruce Richardson p = calloc(1, sizeof(struct reader));
5699a2dd95SBruce Richardson if (!p)
5799a2dd95SBruce Richardson goto error;
5899a2dd95SBruce Richardson
5999a2dd95SBruce Richardson p->params.name = strdup(params->name);
6099a2dd95SBruce Richardson if (!p->params.name)
6199a2dd95SBruce Richardson goto error;
6299a2dd95SBruce Richardson
6399a2dd95SBruce Richardson p->pkts = calloc(params->burst_size, sizeof(struct rte_mbuf *));
6499a2dd95SBruce Richardson if (!p->pkts)
6599a2dd95SBruce Richardson goto error;
6699a2dd95SBruce Richardson
6799a2dd95SBruce Richardson /* Initialization. */
6899a2dd95SBruce Richardson p->params.ring = ring;
6999a2dd95SBruce Richardson p->params.burst_size = params->burst_size;
7099a2dd95SBruce Richardson
7199a2dd95SBruce Richardson return p;
7299a2dd95SBruce Richardson
7399a2dd95SBruce Richardson error:
7499a2dd95SBruce Richardson if (!p)
7599a2dd95SBruce Richardson return NULL;
7699a2dd95SBruce Richardson
7799a2dd95SBruce Richardson free(p->pkts);
7899a2dd95SBruce Richardson free(p->params.name);
7999a2dd95SBruce Richardson free(p);
8099a2dd95SBruce Richardson return NULL;
8199a2dd95SBruce Richardson }
8299a2dd95SBruce Richardson
8399a2dd95SBruce Richardson static int
reader_pkt_rx(void * port,struct rte_swx_pkt * pkt)8499a2dd95SBruce Richardson reader_pkt_rx(void *port, struct rte_swx_pkt *pkt)
8599a2dd95SBruce Richardson {
8699a2dd95SBruce Richardson struct reader *p = port;
8799a2dd95SBruce Richardson struct rte_mbuf *m;
8899a2dd95SBruce Richardson
8999a2dd95SBruce Richardson if (p->pos == p->n_pkts) {
9099a2dd95SBruce Richardson int n_pkts;
9199a2dd95SBruce Richardson
9299a2dd95SBruce Richardson n_pkts = rte_ring_sc_dequeue_burst(p->params.ring,
9399a2dd95SBruce Richardson (void **) p->pkts,
9499a2dd95SBruce Richardson p->params.burst_size,
9599a2dd95SBruce Richardson NULL);
9699a2dd95SBruce Richardson if (!n_pkts) {
9799a2dd95SBruce Richardson p->stats.n_empty++;
9899a2dd95SBruce Richardson return 0;
9999a2dd95SBruce Richardson }
10099a2dd95SBruce Richardson
10199a2dd95SBruce Richardson TRACE("[Ring %s] %d packets in\n",
10299a2dd95SBruce Richardson p->params.name,
10399a2dd95SBruce Richardson n_pkts);
10499a2dd95SBruce Richardson
10599a2dd95SBruce Richardson p->n_pkts = n_pkts;
10699a2dd95SBruce Richardson p->pos = 0;
10799a2dd95SBruce Richardson }
10899a2dd95SBruce Richardson
10999a2dd95SBruce Richardson m = p->pkts[p->pos++];
11099a2dd95SBruce Richardson pkt->handle = m;
11199a2dd95SBruce Richardson pkt->pkt = m->buf_addr;
11299a2dd95SBruce Richardson pkt->offset = m->data_off;
11399a2dd95SBruce Richardson pkt->length = m->pkt_len;
11499a2dd95SBruce Richardson
11599a2dd95SBruce Richardson TRACE("[Ring %s] Pkt %d (%u bytes at offset %u)\n",
11699a2dd95SBruce Richardson (uint32_t)p->params.name,
11799a2dd95SBruce Richardson p->pos - 1,
11899a2dd95SBruce Richardson pkt->length,
11999a2dd95SBruce Richardson pkt->offset);
12099a2dd95SBruce Richardson if (TRACE_LEVEL)
12199a2dd95SBruce Richardson rte_hexdump(stdout,
12299a2dd95SBruce Richardson NULL,
12399a2dd95SBruce Richardson &((uint8_t *)m->buf_addr)[m->data_off],
12499a2dd95SBruce Richardson m->data_len);
12599a2dd95SBruce Richardson
12699a2dd95SBruce Richardson p->stats.n_pkts++;
12799a2dd95SBruce Richardson p->stats.n_bytes += pkt->length;
12899a2dd95SBruce Richardson
12999a2dd95SBruce Richardson return 1;
13099a2dd95SBruce Richardson }
13199a2dd95SBruce Richardson
13299a2dd95SBruce Richardson static void
reader_free(void * port)13399a2dd95SBruce Richardson reader_free(void *port)
13499a2dd95SBruce Richardson {
13599a2dd95SBruce Richardson struct reader *p = port;
13699a2dd95SBruce Richardson int i;
13799a2dd95SBruce Richardson
13899a2dd95SBruce Richardson if (!p)
13999a2dd95SBruce Richardson return;
14099a2dd95SBruce Richardson
14199a2dd95SBruce Richardson for (i = 0; i < p->n_pkts; i++) {
14299a2dd95SBruce Richardson struct rte_mbuf *pkt = p->pkts[i];
14399a2dd95SBruce Richardson
14499a2dd95SBruce Richardson rte_pktmbuf_free(pkt);
14599a2dd95SBruce Richardson }
14699a2dd95SBruce Richardson
14799a2dd95SBruce Richardson free(p->pkts);
14899a2dd95SBruce Richardson free(p->params.name);
14999a2dd95SBruce Richardson free(p);
15099a2dd95SBruce Richardson }
15199a2dd95SBruce Richardson
15299a2dd95SBruce Richardson static void
reader_stats_read(void * port,struct rte_swx_port_in_stats * stats)15399a2dd95SBruce Richardson reader_stats_read(void *port, struct rte_swx_port_in_stats *stats)
15499a2dd95SBruce Richardson {
15599a2dd95SBruce Richardson struct reader *p = port;
15699a2dd95SBruce Richardson
15799a2dd95SBruce Richardson if (!stats)
15899a2dd95SBruce Richardson return;
15999a2dd95SBruce Richardson
16099a2dd95SBruce Richardson memcpy(stats, &p->stats, sizeof(p->stats));
16199a2dd95SBruce Richardson }
16299a2dd95SBruce Richardson
16399a2dd95SBruce Richardson /*
16499a2dd95SBruce Richardson * Writer
16599a2dd95SBruce Richardson */
16699a2dd95SBruce Richardson struct writer {
16799a2dd95SBruce Richardson struct {
16899a2dd95SBruce Richardson struct rte_ring *ring;
16999a2dd95SBruce Richardson char *name;
17099a2dd95SBruce Richardson uint32_t burst_size;
17199a2dd95SBruce Richardson } params;
17299a2dd95SBruce Richardson struct rte_swx_port_out_stats stats;
17399a2dd95SBruce Richardson
17499a2dd95SBruce Richardson struct rte_mbuf **pkts;
17599a2dd95SBruce Richardson int n_pkts;
17687eda689SCristian Dumitrescu uint32_t n_bytes;
177*f8b0c950SCristian Dumitrescu int flush_flag;
17899a2dd95SBruce Richardson };
17999a2dd95SBruce Richardson
18099a2dd95SBruce Richardson static void *
writer_create(void * args)18199a2dd95SBruce Richardson writer_create(void *args)
18299a2dd95SBruce Richardson {
18399a2dd95SBruce Richardson struct rte_swx_port_ring_writer_params *params = args;
18499a2dd95SBruce Richardson struct rte_ring *ring;
18599a2dd95SBruce Richardson struct writer *p = NULL;
18699a2dd95SBruce Richardson
18799a2dd95SBruce Richardson /* Check input parameters. */
18899a2dd95SBruce Richardson if (!params || !params->name || !params->burst_size)
18999a2dd95SBruce Richardson goto error;
19099a2dd95SBruce Richardson
19199a2dd95SBruce Richardson ring = rte_ring_lookup(params->name);
19299a2dd95SBruce Richardson if (!ring)
19399a2dd95SBruce Richardson goto error;
19499a2dd95SBruce Richardson
19599a2dd95SBruce Richardson /* Memory allocation. */
19699a2dd95SBruce Richardson p = calloc(1, sizeof(struct writer));
19799a2dd95SBruce Richardson if (!p)
19899a2dd95SBruce Richardson goto error;
19999a2dd95SBruce Richardson
20099a2dd95SBruce Richardson p->params.name = strdup(params->name);
20199a2dd95SBruce Richardson if (!p->params.name)
20299a2dd95SBruce Richardson goto error;
20399a2dd95SBruce Richardson
20499a2dd95SBruce Richardson p->pkts = calloc(params->burst_size, sizeof(struct rte_mbuf *));
20599a2dd95SBruce Richardson if (!p->pkts)
20699a2dd95SBruce Richardson goto error;
20799a2dd95SBruce Richardson
20899a2dd95SBruce Richardson /* Initialization. */
20999a2dd95SBruce Richardson p->params.ring = ring;
21099a2dd95SBruce Richardson p->params.burst_size = params->burst_size;
21199a2dd95SBruce Richardson
21299a2dd95SBruce Richardson return p;
21399a2dd95SBruce Richardson
21499a2dd95SBruce Richardson error:
21599a2dd95SBruce Richardson if (!p)
21699a2dd95SBruce Richardson return NULL;
21799a2dd95SBruce Richardson
21899a2dd95SBruce Richardson free(p->params.name);
21999a2dd95SBruce Richardson free(p->pkts);
22099a2dd95SBruce Richardson free(p);
22199a2dd95SBruce Richardson return NULL;
22299a2dd95SBruce Richardson }
22399a2dd95SBruce Richardson
22487eda689SCristian Dumitrescu static inline void
__writer_flush(struct writer * p)22599a2dd95SBruce Richardson __writer_flush(struct writer *p)
22699a2dd95SBruce Richardson {
22787eda689SCristian Dumitrescu struct rte_mbuf **pkts = p->pkts;
22887eda689SCristian Dumitrescu uint64_t n_pkts_total = p->stats.n_pkts;
22987eda689SCristian Dumitrescu uint64_t n_bytes_total = p->stats.n_bytes;
23087eda689SCristian Dumitrescu uint64_t n_pkts_drop_total = p->stats.n_pkts_drop;
23187eda689SCristian Dumitrescu uint64_t n_bytes_drop_total = p->stats.n_bytes_drop;
23287eda689SCristian Dumitrescu int n_pkts = p->n_pkts, n_pkts_drop, n_pkts_tx;
23387eda689SCristian Dumitrescu uint32_t n_bytes = p->n_bytes, n_bytes_drop = 0;
23499a2dd95SBruce Richardson
23587eda689SCristian Dumitrescu /* Packet TX. */
23687eda689SCristian Dumitrescu n_pkts_tx = rte_ring_sp_enqueue_burst(p->params.ring,
23787eda689SCristian Dumitrescu (void **)pkts,
23887eda689SCristian Dumitrescu n_pkts,
23999a2dd95SBruce Richardson NULL);
24099a2dd95SBruce Richardson
24187eda689SCristian Dumitrescu /* Packet drop. */
24287eda689SCristian Dumitrescu n_pkts_drop = n_pkts - n_pkts_tx;
24399a2dd95SBruce Richardson
24487eda689SCristian Dumitrescu for ( ; n_pkts_tx < n_pkts; n_pkts_tx++) {
24587eda689SCristian Dumitrescu struct rte_mbuf *m = pkts[n_pkts_tx];
24687eda689SCristian Dumitrescu
24787eda689SCristian Dumitrescu n_bytes_drop += m->pkt_len;
24887eda689SCristian Dumitrescu rte_pktmbuf_free(m);
24999a2dd95SBruce Richardson }
25099a2dd95SBruce Richardson
25187eda689SCristian Dumitrescu /* Port update. */
25287eda689SCristian Dumitrescu p->stats.n_pkts = n_pkts_total + n_pkts - n_pkts_drop;
25387eda689SCristian Dumitrescu p->stats.n_bytes = n_bytes_total + n_bytes - n_bytes_drop;
25487eda689SCristian Dumitrescu p->stats.n_pkts_drop = n_pkts_drop_total + n_pkts_drop;
25587eda689SCristian Dumitrescu p->stats.n_bytes_drop = n_bytes_drop_total + n_bytes_drop;
25699a2dd95SBruce Richardson p->n_pkts = 0;
25787eda689SCristian Dumitrescu p->n_bytes = 0;
258*f8b0c950SCristian Dumitrescu p->flush_flag = 0;
25987eda689SCristian Dumitrescu
26087eda689SCristian Dumitrescu TRACE("[Ring %s] Buffered packets flushed: %d out, %d dropped\n",
26187eda689SCristian Dumitrescu p->params.name,
26287eda689SCristian Dumitrescu n_pkts - n_pkts_drop,
26387eda689SCristian Dumitrescu n_pkts_drop);
26499a2dd95SBruce Richardson }
26599a2dd95SBruce Richardson
26699a2dd95SBruce Richardson static void
writer_pkt_tx(void * port,struct rte_swx_pkt * pkt)26799a2dd95SBruce Richardson writer_pkt_tx(void *port, struct rte_swx_pkt *pkt)
26899a2dd95SBruce Richardson {
26999a2dd95SBruce Richardson struct writer *p = port;
27087eda689SCristian Dumitrescu int n_pkts = p->n_pkts;
27187eda689SCristian Dumitrescu uint32_t n_bytes = p->n_bytes;
27299a2dd95SBruce Richardson struct rte_mbuf *m = pkt->handle;
27387eda689SCristian Dumitrescu uint32_t pkt_length = pkt->length;
27499a2dd95SBruce Richardson
27599a2dd95SBruce Richardson TRACE("[Ring %s] Pkt %d (%u bytes at offset %u)\n",
27699a2dd95SBruce Richardson p->params.name,
27799a2dd95SBruce Richardson p->n_pkts - 1,
27899a2dd95SBruce Richardson pkt->length,
27999a2dd95SBruce Richardson pkt->offset);
28099a2dd95SBruce Richardson if (TRACE_LEVEL)
28199a2dd95SBruce Richardson rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
28299a2dd95SBruce Richardson
28387eda689SCristian Dumitrescu m->data_len = (uint16_t)(pkt_length + m->data_len - m->pkt_len);
28487eda689SCristian Dumitrescu m->pkt_len = pkt_length;
28599a2dd95SBruce Richardson m->data_off = (uint16_t)pkt->offset;
28699a2dd95SBruce Richardson
28787eda689SCristian Dumitrescu p->pkts[n_pkts++] = m;
28887eda689SCristian Dumitrescu p->n_pkts = n_pkts;
28987eda689SCristian Dumitrescu p->n_bytes = n_bytes + pkt_length;
29099a2dd95SBruce Richardson
29187eda689SCristian Dumitrescu if (n_pkts == (int)p->params.burst_size)
29299a2dd95SBruce Richardson __writer_flush(p);
29399a2dd95SBruce Richardson }
29499a2dd95SBruce Richardson
29599a2dd95SBruce Richardson static void
writer_pkt_fast_clone_tx(void * port,struct rte_swx_pkt * pkt)296b94eb6cdSCristian Dumitrescu writer_pkt_fast_clone_tx(void *port, struct rte_swx_pkt *pkt)
297b94eb6cdSCristian Dumitrescu {
298b94eb6cdSCristian Dumitrescu struct writer *p = port;
29987eda689SCristian Dumitrescu int n_pkts = p->n_pkts;
30087eda689SCristian Dumitrescu uint32_t n_bytes = p->n_bytes;
30187eda689SCristian Dumitrescu uint64_t n_pkts_clone = p->stats.n_pkts_clone;
302b94eb6cdSCristian Dumitrescu struct rte_mbuf *m = pkt->handle;
30387eda689SCristian Dumitrescu uint32_t pkt_length = pkt->length;
304b94eb6cdSCristian Dumitrescu
305b94eb6cdSCristian Dumitrescu TRACE("[Ring %s] Pkt %d (%u bytes at offset %u) (fast clone)\n",
306b94eb6cdSCristian Dumitrescu p->params.name,
307b94eb6cdSCristian Dumitrescu p->n_pkts - 1,
308b94eb6cdSCristian Dumitrescu pkt->length,
309b94eb6cdSCristian Dumitrescu pkt->offset);
310b94eb6cdSCristian Dumitrescu if (TRACE_LEVEL)
311b94eb6cdSCristian Dumitrescu rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
312b94eb6cdSCristian Dumitrescu
31387eda689SCristian Dumitrescu m->data_len = (uint16_t)(pkt_length + m->data_len - m->pkt_len);
31487eda689SCristian Dumitrescu m->pkt_len = pkt_length;
315b94eb6cdSCristian Dumitrescu m->data_off = (uint16_t)pkt->offset;
316b94eb6cdSCristian Dumitrescu rte_pktmbuf_refcnt_update(m, 1);
317b94eb6cdSCristian Dumitrescu
31887eda689SCristian Dumitrescu p->pkts[n_pkts++] = m;
31987eda689SCristian Dumitrescu p->n_pkts = n_pkts;
32087eda689SCristian Dumitrescu p->n_bytes = n_bytes + pkt_length;
32187eda689SCristian Dumitrescu p->stats.n_pkts_clone = n_pkts_clone + 1;
322b94eb6cdSCristian Dumitrescu
32387eda689SCristian Dumitrescu if (n_pkts == (int)p->params.burst_size)
324b94eb6cdSCristian Dumitrescu __writer_flush(p);
325b94eb6cdSCristian Dumitrescu }
326b94eb6cdSCristian Dumitrescu
327b94eb6cdSCristian Dumitrescu static void
writer_pkt_clone_tx(void * port,struct rte_swx_pkt * pkt,uint32_t truncation_length)328b94eb6cdSCristian Dumitrescu writer_pkt_clone_tx(void *port, struct rte_swx_pkt *pkt, uint32_t truncation_length)
329b94eb6cdSCristian Dumitrescu {
330b94eb6cdSCristian Dumitrescu struct writer *p = port;
33187eda689SCristian Dumitrescu int n_pkts = p->n_pkts;
33287eda689SCristian Dumitrescu uint32_t n_bytes = p->n_bytes;
33387eda689SCristian Dumitrescu uint64_t n_pkts_clone = p->stats.n_pkts_clone;
334b94eb6cdSCristian Dumitrescu struct rte_mbuf *m = pkt->handle, *m_clone;
33587eda689SCristian Dumitrescu uint32_t pkt_length = pkt->length;
336b94eb6cdSCristian Dumitrescu
337b94eb6cdSCristian Dumitrescu TRACE("[Ring %s] Pkt %d (%u bytes at offset %u) (clone)\n",
338b94eb6cdSCristian Dumitrescu p->params.name,
339b94eb6cdSCristian Dumitrescu p->n_pkts - 1,
340b94eb6cdSCristian Dumitrescu pkt->length,
341b94eb6cdSCristian Dumitrescu pkt->offset);
342b94eb6cdSCristian Dumitrescu if (TRACE_LEVEL)
343b94eb6cdSCristian Dumitrescu rte_hexdump(stdout, NULL, &pkt->pkt[pkt->offset], pkt->length);
344b94eb6cdSCristian Dumitrescu
34587eda689SCristian Dumitrescu m->data_len = (uint16_t)(pkt_length + m->data_len - m->pkt_len);
34687eda689SCristian Dumitrescu m->pkt_len = pkt_length;
347b94eb6cdSCristian Dumitrescu m->data_off = (uint16_t)pkt->offset;
348b94eb6cdSCristian Dumitrescu
349b94eb6cdSCristian Dumitrescu m_clone = rte_pktmbuf_copy(m, m->pool, 0, truncation_length);
350b94eb6cdSCristian Dumitrescu if (!m_clone) {
351b94eb6cdSCristian Dumitrescu p->stats.n_pkts_clone_err++;
352b94eb6cdSCristian Dumitrescu return;
353b94eb6cdSCristian Dumitrescu }
354b94eb6cdSCristian Dumitrescu
35587eda689SCristian Dumitrescu p->pkts[n_pkts++] = m_clone;
35687eda689SCristian Dumitrescu p->n_pkts = n_pkts;
35787eda689SCristian Dumitrescu p->n_bytes = n_bytes + pkt_length;
35887eda689SCristian Dumitrescu p->stats.n_pkts_clone = n_pkts_clone + 1;
359b94eb6cdSCristian Dumitrescu
36087eda689SCristian Dumitrescu if (n_pkts == (int)p->params.burst_size)
361b94eb6cdSCristian Dumitrescu __writer_flush(p);
362b94eb6cdSCristian Dumitrescu }
363b94eb6cdSCristian Dumitrescu
364b94eb6cdSCristian Dumitrescu static void
writer_flush(void * port)36599a2dd95SBruce Richardson writer_flush(void *port)
36699a2dd95SBruce Richardson {
36799a2dd95SBruce Richardson struct writer *p = port;
36899a2dd95SBruce Richardson
369*f8b0c950SCristian Dumitrescu if (p->n_pkts && p->flush_flag)
37099a2dd95SBruce Richardson __writer_flush(p);
371*f8b0c950SCristian Dumitrescu
372*f8b0c950SCristian Dumitrescu p->flush_flag = 1;
37399a2dd95SBruce Richardson }
37499a2dd95SBruce Richardson
37599a2dd95SBruce Richardson static void
writer_free(void * port)37699a2dd95SBruce Richardson writer_free(void *port)
37799a2dd95SBruce Richardson {
37899a2dd95SBruce Richardson struct writer *p = port;
3790b5122dcSCristian Dumitrescu int i;
38099a2dd95SBruce Richardson
38199a2dd95SBruce Richardson if (!p)
38299a2dd95SBruce Richardson return;
38399a2dd95SBruce Richardson
3840b5122dcSCristian Dumitrescu for (i = 0; i < p->n_pkts; i++) {
3850b5122dcSCristian Dumitrescu struct rte_mbuf *m = p->pkts[i];
3860b5122dcSCristian Dumitrescu
3870b5122dcSCristian Dumitrescu rte_pktmbuf_free(m);
3880b5122dcSCristian Dumitrescu }
3890b5122dcSCristian Dumitrescu
39099a2dd95SBruce Richardson free(p->pkts);
39199a2dd95SBruce Richardson free(p->params.name);
39299a2dd95SBruce Richardson free(port);
39399a2dd95SBruce Richardson }
39499a2dd95SBruce Richardson
39599a2dd95SBruce Richardson static void
writer_stats_read(void * port,struct rte_swx_port_out_stats * stats)39699a2dd95SBruce Richardson writer_stats_read(void *port, struct rte_swx_port_out_stats *stats)
39799a2dd95SBruce Richardson {
39899a2dd95SBruce Richardson struct writer *p = port;
39999a2dd95SBruce Richardson
40099a2dd95SBruce Richardson if (!stats)
40199a2dd95SBruce Richardson return;
40299a2dd95SBruce Richardson
40399a2dd95SBruce Richardson memcpy(stats, &p->stats, sizeof(p->stats));
40499a2dd95SBruce Richardson }
40599a2dd95SBruce Richardson
40699a2dd95SBruce Richardson /*
40799a2dd95SBruce Richardson * Summary of port operations
40899a2dd95SBruce Richardson */
40999a2dd95SBruce Richardson struct rte_swx_port_in_ops rte_swx_port_ring_reader_ops = {
41099a2dd95SBruce Richardson .create = reader_create,
41199a2dd95SBruce Richardson .free = reader_free,
41299a2dd95SBruce Richardson .pkt_rx = reader_pkt_rx,
41399a2dd95SBruce Richardson .stats_read = reader_stats_read,
41499a2dd95SBruce Richardson };
41599a2dd95SBruce Richardson
41699a2dd95SBruce Richardson struct rte_swx_port_out_ops rte_swx_port_ring_writer_ops = {
41799a2dd95SBruce Richardson .create = writer_create,
41899a2dd95SBruce Richardson .free = writer_free,
41999a2dd95SBruce Richardson .pkt_tx = writer_pkt_tx,
420b94eb6cdSCristian Dumitrescu .pkt_fast_clone_tx = writer_pkt_fast_clone_tx,
421b94eb6cdSCristian Dumitrescu .pkt_clone_tx = writer_pkt_clone_tx,
42299a2dd95SBruce Richardson .flush = writer_flush,
42399a2dd95SBruce Richardson .stats_read = writer_stats_read,
42499a2dd95SBruce Richardson };
425