xref: /dpdk/lib/port/rte_swx_port_ring.c (revision f8b0c950a58f62b9247832b0ff8e716fdabddfb6)
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