net/mlx5: implement CQ for Rx using DevX API
[dpdk.git] / 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_ */