xref: /dpdk/drivers/net/nfb/nfb_rx.c (revision 68a03efeed657e6e05f281479b33b51102797e15)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Cesnet
3  * Copyright(c) 2019 Netcope Technologies, a.s. <info@netcope.com>
4  * All rights reserved.
5  */
6 
7 #include <rte_kvargs.h>
8 
9 #include "nfb_rx.h"
10 #include "nfb.h"
11 
12 uint64_t nfb_timestamp_rx_dynflag;
13 int nfb_timestamp_dynfield_offset = -1;
14 
15 static int
16 timestamp_check_handler(__rte_unused const char *key,
17 	const char *value, __rte_unused void *opaque)
18 {
19 	if (strcmp(value, "1"))
20 		return -1;
21 
22 	return 0;
23 }
24 
25 
26 static int
27 nfb_check_timestamp(struct rte_devargs *devargs)
28 {
29 	struct rte_kvargs *kvlist;
30 	int ret;
31 
32 	if (devargs == NULL)
33 		return 0;
34 
35 	kvlist = rte_kvargs_parse(devargs->args, NULL);
36 	if (kvlist == NULL)
37 		return 0;
38 
39 	if (!rte_kvargs_count(kvlist, TIMESTAMP_ARG)) {
40 		rte_kvargs_free(kvlist);
41 		return 0;
42 	}
43 	/* Timestamps are enabled when there is
44 	 * key-value pair: enable_timestamp=1
45 	 * TODO: timestamp should be enabled with DEV_RX_OFFLOAD_TIMESTAMP
46 	 */
47 	if (rte_kvargs_process(kvlist, TIMESTAMP_ARG,
48 		timestamp_check_handler, NULL) < 0) {
49 		rte_kvargs_free(kvlist);
50 		return 0;
51 	}
52 	rte_kvargs_free(kvlist);
53 
54 	ret = rte_mbuf_dyn_rx_timestamp_register(
55 			&nfb_timestamp_dynfield_offset,
56 			&nfb_timestamp_rx_dynflag);
57 	if (ret != 0) {
58 		RTE_LOG(ERR, PMD, "Cannot register Rx timestamp field/flag\n");
59 		return -rte_errno;
60 	}
61 
62 	return 1;
63 }
64 
65 int
66 nfb_eth_rx_queue_start(struct rte_eth_dev *dev, uint16_t rxq_id)
67 {
68 	struct ndp_rx_queue *rxq = dev->data->rx_queues[rxq_id];
69 	int ret;
70 
71 	if (rxq->queue == NULL) {
72 		RTE_LOG(ERR, PMD, "RX NDP queue is NULL!\n");
73 		return -EINVAL;
74 	}
75 
76 	ret = ndp_queue_start(rxq->queue);
77 	if (ret != 0)
78 		goto err;
79 	dev->data->rx_queue_state[rxq_id] = RTE_ETH_QUEUE_STATE_STARTED;
80 	return 0;
81 
82 err:
83 	return -EINVAL;
84 }
85 
86 int
87 nfb_eth_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rxq_id)
88 {
89 	struct ndp_rx_queue *rxq = dev->data->rx_queues[rxq_id];
90 	int ret;
91 
92 	if (rxq->queue == NULL) {
93 		RTE_LOG(ERR, PMD, "RX NDP queue is NULL!\n");
94 		return -EINVAL;
95 	}
96 
97 	ret = ndp_queue_stop(rxq->queue);
98 	if (ret != 0)
99 		return -EINVAL;
100 
101 	dev->data->rx_queue_state[rxq_id] = RTE_ETH_QUEUE_STATE_STOPPED;
102 	return 0;
103 }
104 
105 int
106 nfb_eth_rx_queue_setup(struct rte_eth_dev *dev,
107 		uint16_t rx_queue_id,
108 		uint16_t nb_rx_desc __rte_unused,
109 		unsigned int socket_id,
110 		const struct rte_eth_rxconf *rx_conf __rte_unused,
111 		struct rte_mempool *mb_pool)
112 {
113 	struct pmd_internals *internals = dev->data->dev_private;
114 
115 	struct ndp_rx_queue *rxq;
116 	int ret;
117 
118 	rxq = rte_zmalloc_socket("ndp rx queue",
119 			sizeof(struct ndp_rx_queue),
120 			RTE_CACHE_LINE_SIZE, socket_id);
121 
122 	if (rxq == NULL) {
123 		RTE_LOG(ERR, PMD, "rte_zmalloc_socket() failed for rx queue id "
124 				"%" PRIu16 "!\n", rx_queue_id);
125 		return -ENOMEM;
126 	}
127 
128 	rxq->flags = 0;
129 
130 	ret = nfb_eth_rx_queue_init(internals->nfb,
131 		rx_queue_id,
132 		dev->data->port_id,
133 		mb_pool,
134 		rxq);
135 
136 	if (ret == 0)
137 		dev->data->rx_queues[rx_queue_id] = rxq;
138 	else
139 		rte_free(rxq);
140 
141 	if (nfb_check_timestamp(dev->device->devargs) > 0)
142 		rxq->flags |= NFB_TIMESTAMP_FLAG;
143 
144 	return ret;
145 }
146 
147 int
148 nfb_eth_rx_queue_init(struct nfb_device *nfb,
149 		uint16_t rx_queue_id,
150 		uint16_t port_id,
151 		struct rte_mempool *mb_pool,
152 		struct ndp_rx_queue *rxq)
153 {
154 	const struct rte_pktmbuf_pool_private *mbp_priv =
155 		rte_mempool_get_priv(mb_pool);
156 
157 	if (nfb == NULL)
158 		return -EINVAL;
159 
160 	rxq->queue = ndp_open_rx_queue(nfb, rx_queue_id);
161 	if (rxq->queue == NULL)
162 		return -EINVAL;
163 
164 	rxq->nfb = nfb;
165 	rxq->rx_queue_id = rx_queue_id;
166 	rxq->in_port = port_id;
167 	rxq->mb_pool = mb_pool;
168 	rxq->buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
169 		RTE_PKTMBUF_HEADROOM);
170 
171 	rxq->rx_pkts = 0;
172 	rxq->rx_bytes = 0;
173 	rxq->err_pkts = 0;
174 
175 	return 0;
176 }
177 
178 void
179 nfb_eth_rx_queue_release(void *q)
180 {
181 	struct ndp_rx_queue *rxq = (struct ndp_rx_queue *)q;
182 	if (rxq->queue != NULL) {
183 		ndp_close_rx_queue(rxq->queue);
184 		rte_free(rxq);
185 		rxq->queue = NULL;
186 	}
187 }
188