1
2
3
4
5
6
7#ifndef _NFB_RX_H_
8#define _NFB_RX_H_
9
10#include <nfb/nfb.h>
11#include <nfb/ndp.h>
12
13#include <rte_mbuf.h>
14#include <rte_mbuf_dyn.h>
15#include <rte_ethdev.h>
16
17#define NFB_TIMESTAMP_FLAG (1 << 0)
18
19extern uint64_t nfb_timestamp_rx_dynflag;
20extern int nfb_timestamp_dynfield_offset;
21
22static inline rte_mbuf_timestamp_t *
23nfb_timestamp_dynfield(struct rte_mbuf *mbuf)
24{
25 return RTE_MBUF_DYNFIELD(mbuf,
26 nfb_timestamp_dynfield_offset, rte_mbuf_timestamp_t *);
27}
28
29struct ndp_rx_queue {
30 struct nfb_device *nfb;
31 struct ndp_queue *queue;
32 uint16_t rx_queue_id;
33 uint8_t in_port;
34 uint8_t flags;
35
36 struct rte_mempool *mb_pool;
37 uint16_t buf_size;
38
39 volatile uint64_t rx_pkts;
40 volatile uint64_t rx_bytes;
41 volatile uint64_t err_pkts;
42};
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60int
61nfb_eth_rx_queue_init(struct nfb_device *nfb,
62 uint16_t rx_queue_id,
63 uint16_t port_id,
64 struct rte_mempool *mb_pool,
65 struct ndp_rx_queue *rxq);
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86int
87nfb_eth_rx_queue_setup(struct rte_eth_dev *dev,
88 uint16_t rx_queue_id,
89 uint16_t nb_rx_desc __rte_unused,
90 unsigned int socket_id,
91 const struct rte_eth_rxconf *rx_conf __rte_unused,
92 struct rte_mempool *mb_pool);
93
94
95
96
97
98
99
100void
101nfb_eth_rx_queue_release(void *q);
102
103
104
105
106
107
108
109
110
111
112
113int
114nfb_eth_rx_queue_start(struct rte_eth_dev *dev, uint16_t rxq_id);
115
116
117
118
119
120
121
122
123
124int
125nfb_eth_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rxq_id);
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140static __rte_always_inline uint16_t
141nfb_eth_ndp_rx(void *queue,
142 struct rte_mbuf **bufs,
143 uint16_t nb_pkts)
144{
145 struct ndp_rx_queue *ndp = queue;
146 uint8_t timestamping_enabled;
147 uint16_t packet_size;
148 uint64_t num_bytes = 0;
149 uint16_t num_rx;
150 unsigned int i;
151
152 const uint16_t buf_size = ndp->buf_size;
153
154 struct rte_mbuf *mbuf;
155 struct ndp_packet packets[nb_pkts];
156
157 struct rte_mbuf *mbufs[nb_pkts];
158
159 if (unlikely(ndp->queue == NULL || nb_pkts == 0)) {
160 RTE_LOG(ERR, PMD, "RX invalid arguments!\n");
161 return 0;
162 }
163
164 timestamping_enabled = ndp->flags & NFB_TIMESTAMP_FLAG;
165
166
167 i = rte_pktmbuf_alloc_bulk(ndp->mb_pool, mbufs, nb_pkts);
168 if (unlikely(i != 0))
169 return 0;
170
171 num_rx = ndp_rx_burst_get(ndp->queue, packets, nb_pkts);
172
173 if (unlikely(num_rx != nb_pkts)) {
174 for (i = num_rx; i < nb_pkts; i++)
175 rte_pktmbuf_free(mbufs[i]);
176 }
177
178 nb_pkts = num_rx;
179
180 num_rx = 0;
181
182
183
184
185
186 for (i = 0; i < nb_pkts; ++i) {
187 mbuf = mbufs[i];
188
189
190 packet_size = packets[i].data_length;
191
192 if (likely(packet_size <= buf_size)) {
193
194 rte_memcpy(rte_pktmbuf_mtod(mbuf, void *),
195 packets[i].data, packet_size);
196
197 mbuf->data_len = (uint16_t)packet_size;
198
199 mbuf->pkt_len = packet_size;
200 mbuf->port = ndp->in_port;
201 mbuf->ol_flags = 0;
202
203 if (timestamping_enabled) {
204 rte_mbuf_timestamp_t timestamp;
205
206
207 timestamp =
208 rte_le_to_cpu_32(*((uint32_t *)
209 (packets[i].header + 4)));
210 timestamp <<= 32;
211
212 timestamp |=
213 rte_le_to_cpu_32(*((uint32_t *)
214 (packets[i].header + 8)));
215 *nfb_timestamp_dynfield(mbuf) = timestamp;
216 mbuf->ol_flags |= nfb_timestamp_rx_dynflag;
217 }
218
219 bufs[num_rx++] = mbuf;
220 num_bytes += packet_size;
221 } else {
222
223
224
225
226 rte_pktmbuf_free(mbuf);
227 }
228 }
229
230 ndp_rx_burst_put(ndp->queue);
231
232 ndp->rx_pkts += num_rx;
233 ndp->rx_bytes += num_bytes;
234 return num_rx;
235}
236
237#endif
238