]> git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/dpdk/drivers/net/nfb/nfb_rx.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / dpdk / drivers / net / nfb / nfb_rx.h
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 #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_ethdev.h>
15
16 #define NFB_TIMESTAMP_FLAG (1 << 0)
17
18 struct ndp_rx_queue {
19 struct nfb_device *nfb; /* nfb dev structure */
20 struct ndp_queue *queue; /* rx queue */
21 uint16_t rx_queue_id; /* index */
22 uint8_t in_port; /* port */
23 uint8_t flags; /* setup flags */
24
25 struct rte_mempool *mb_pool; /* memory pool to allocate packets */
26 uint16_t buf_size; /* mbuf size */
27
28 volatile uint64_t rx_pkts; /* packets read */
29 volatile uint64_t rx_bytes; /* bytes read */
30 volatile uint64_t err_pkts; /* erroneous packets */
31 };
32
33 /**
34 * Initialize ndp_rx_queue structure
35 *
36 * @param nfb
37 * Pointer to nfb device structure.
38 * @param rx_queue_id
39 * RX queue index.
40 * @param port_id
41 * Device [external] port identifier.
42 * @param mb_pool
43 * Memory pool for buffer allocations.
44 * @param[out] rxq
45 * Pointer to ndp_rx_queue output structure
46 * @return
47 * 0 on success, a negative errno value otherwise.
48 */
49 int
50 nfb_eth_rx_queue_init(struct nfb_device *nfb,
51 uint16_t rx_queue_id,
52 uint16_t port_id,
53 struct rte_mempool *mb_pool,
54 struct ndp_rx_queue *rxq);
55
56 /**
57 * DPDK callback to setup a RX queue for use.
58 *
59 * @param dev
60 * Pointer to Ethernet device structure.
61 * @param idx
62 * RX queue index.
63 * @param desc
64 * Number of descriptors to configure in queue.
65 * @param socket
66 * NUMA socket on which memory must be allocated.
67 * @param[in] conf
68 * Thresholds parameters.
69 * @param mb_pool
70 * Memory pool for buffer allocations.
71 *
72 * @return
73 * 0 on success, a negative errno value otherwise.
74 */
75 int
76 nfb_eth_rx_queue_setup(struct rte_eth_dev *dev,
77 uint16_t rx_queue_id,
78 uint16_t nb_rx_desc __rte_unused,
79 unsigned int socket_id,
80 const struct rte_eth_rxconf *rx_conf __rte_unused,
81 struct rte_mempool *mb_pool);
82
83 /**
84 * DPDK callback to release a RX queue.
85 *
86 * @param dpdk_rxq
87 * Generic RX queue pointer.
88 */
89 void
90 nfb_eth_rx_queue_release(void *q);
91
92 /**
93 * Start traffic on Rx queue.
94 *
95 * @param dev
96 * Pointer to Ethernet device structure.
97 * @param txq_id
98 * RX queue index.
99 * @return
100 * 0 on success, a negative errno value otherwise.
101 */
102 int
103 nfb_eth_rx_queue_start(struct rte_eth_dev *dev, uint16_t rxq_id);
104
105 /**
106 * Stop traffic on Rx queue.
107 *
108 * @param dev
109 * Pointer to Ethernet device structure.
110 * @param txq_id
111 * RX queue index.
112 */
113 int
114 nfb_eth_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rxq_id);
115
116 /**
117 * DPDK callback for RX.
118 *
119 * @param dpdk_rxq
120 * Generic pointer to RX queue structure.
121 * @param[out] bufs
122 * Array to store received packets.
123 * @param nb_pkts
124 * Maximum number of packets in array.
125 *
126 * @return
127 * Number of packets successfully received (<= nb_pkts).
128 */
129 static __rte_always_inline uint16_t
130 nfb_eth_ndp_rx(void *queue,
131 struct rte_mbuf **bufs,
132 uint16_t nb_pkts)
133 {
134 struct ndp_rx_queue *ndp = queue;
135 uint8_t timestamping_enabled;
136 uint16_t packet_size;
137 uint64_t num_bytes = 0;
138 uint16_t num_rx;
139 unsigned int i;
140
141 const uint16_t buf_size = ndp->buf_size;
142
143 struct rte_mbuf *mbuf;
144 struct ndp_packet packets[nb_pkts];
145
146 struct rte_mbuf *mbufs[nb_pkts];
147
148 if (unlikely(ndp->queue == NULL || nb_pkts == 0)) {
149 RTE_LOG(ERR, PMD, "RX invalid arguments!\n");
150 return 0;
151 }
152
153 timestamping_enabled = ndp->flags & NFB_TIMESTAMP_FLAG;
154
155 /* returns either all or nothing */
156 i = rte_pktmbuf_alloc_bulk(ndp->mb_pool, mbufs, nb_pkts);
157 if (unlikely(i != 0))
158 return 0;
159
160 num_rx = ndp_rx_burst_get(ndp->queue, packets, nb_pkts);
161
162 if (unlikely(num_rx != nb_pkts)) {
163 for (i = num_rx; i < nb_pkts; i++)
164 rte_pktmbuf_free(mbufs[i]);
165 }
166
167 nb_pkts = num_rx;
168
169 num_rx = 0;
170 /*
171 * Reads the given number of packets from NDP queue given
172 * by queue and copies the packet data into a newly allocated mbuf
173 * to return.
174 */
175 for (i = 0; i < nb_pkts; ++i) {
176 mbuf = mbufs[i];
177
178 /* get the space available for data in the mbuf */
179 packet_size = packets[i].data_length;
180
181 if (likely(packet_size <= buf_size)) {
182 /* NDP packet will fit in one mbuf, go ahead and copy */
183 rte_memcpy(rte_pktmbuf_mtod(mbuf, void *),
184 packets[i].data, packet_size);
185
186 mbuf->data_len = (uint16_t)packet_size;
187
188 mbuf->pkt_len = packet_size;
189 mbuf->port = ndp->in_port;
190 mbuf->ol_flags = 0;
191
192 if (timestamping_enabled) {
193 /* nanoseconds */
194 mbuf->timestamp =
195 rte_le_to_cpu_32(*((uint32_t *)
196 (packets[i].header + 4)));
197 mbuf->timestamp <<= 32;
198 /* seconds */
199 mbuf->timestamp |=
200 rte_le_to_cpu_32(*((uint32_t *)
201 (packets[i].header + 8)));
202 mbuf->ol_flags |= PKT_RX_TIMESTAMP;
203 }
204
205 bufs[num_rx++] = mbuf;
206 num_bytes += packet_size;
207 } else {
208 /*
209 * NDP packet will not fit in one mbuf,
210 * scattered mode is not enabled, drop packet
211 */
212 rte_pktmbuf_free(mbuf);
213 }
214 }
215
216 ndp_rx_burst_put(ndp->queue);
217
218 ndp->rx_pkts += num_rx;
219 ndp->rx_bytes += num_bytes;
220 return num_rx;
221 }
222
223 #endif /* _NFB_RX_H_ */