net/octeontx_ep: add Tx queue setup and release
[dpdk.git] / drivers / net / octeontx_ep / otx_ep_rxtx.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #include <unistd.h>
6
7 #include <rte_eal.h>
8 #include <rte_mempool.h>
9 #include <rte_mbuf.h>
10 #include <ethdev_pci.h>
11
12 #include "otx_ep_common.h"
13 #include "otx_ep_vf.h"
14 #include "otx2_ep_vf.h"
15 #include "otx_ep_rxtx.h"
16
17 static void
18 otx_ep_dmazone_free(const struct rte_memzone *mz)
19 {
20         const struct rte_memzone *mz_tmp;
21         int ret = 0;
22
23         if (mz == NULL) {
24                 otx_ep_err("Memzone %s : NULL\n", mz->name);
25                 return;
26         }
27
28         mz_tmp = rte_memzone_lookup(mz->name);
29         if (mz_tmp == NULL) {
30                 otx_ep_err("Memzone %s Not Found\n", mz->name);
31                 return;
32         }
33
34         ret = rte_memzone_free(mz);
35         if (ret)
36                 otx_ep_err("Memzone free failed : ret = %d\n", ret);
37 }
38
39 /* Free IQ resources */
40 int
41 otx_ep_delete_iqs(struct otx_ep_device *otx_ep, uint32_t iq_no)
42 {
43         struct otx_ep_instr_queue *iq;
44
45         iq = otx_ep->instr_queue[iq_no];
46         if (iq == NULL) {
47                 otx_ep_err("Invalid IQ[%d]\n", iq_no);
48                 return -EINVAL;
49         }
50
51         rte_free(iq->req_list);
52         iq->req_list = NULL;
53
54         if (iq->iq_mz) {
55                 otx_ep_dmazone_free(iq->iq_mz);
56                 iq->iq_mz = NULL;
57         }
58
59         rte_free(otx_ep->instr_queue[iq_no]);
60         otx_ep->instr_queue[iq_no] = NULL;
61
62         otx_ep->nb_tx_queues--;
63
64         otx_ep_info("IQ[%d] is deleted\n", iq_no);
65
66         return 0;
67 }
68
69 /* IQ initialization */
70 static int
71 otx_ep_init_instr_queue(struct otx_ep_device *otx_ep, int iq_no, int num_descs,
72                      unsigned int socket_id)
73 {
74         const struct otx_ep_config *conf;
75         struct otx_ep_instr_queue *iq;
76         uint32_t q_size;
77
78         conf = otx_ep->conf;
79         iq = otx_ep->instr_queue[iq_no];
80         q_size = conf->iq.instr_type * num_descs;
81
82         /* IQ memory creation for Instruction submission to OCTEON TX2 */
83         iq->iq_mz = rte_eth_dma_zone_reserve(otx_ep->eth_dev,
84                                              "instr_queue", iq_no, q_size,
85                                              OTX_EP_PCI_RING_ALIGN,
86                                              socket_id);
87         if (iq->iq_mz == NULL) {
88                 otx_ep_err("IQ[%d] memzone alloc failed\n", iq_no);
89                 goto iq_init_fail;
90         }
91
92         iq->base_addr_dma = iq->iq_mz->iova;
93         iq->base_addr = (uint8_t *)iq->iq_mz->addr;
94
95         if (num_descs & (num_descs - 1)) {
96                 otx_ep_err("IQ[%d] descs not in power of 2\n", iq_no);
97                 goto iq_init_fail;
98         }
99
100         iq->nb_desc = num_descs;
101
102         /* Create a IQ request list to hold requests that have been
103          * posted to OCTEON TX2. This list will be used for freeing the IQ
104          * data buffer(s) later once the OCTEON TX2 fetched the requests.
105          */
106         iq->req_list = rte_zmalloc_socket("request_list",
107                         (iq->nb_desc * OTX_EP_IQREQ_LIST_SIZE),
108                         RTE_CACHE_LINE_SIZE,
109                         rte_socket_id());
110         if (iq->req_list == NULL) {
111                 otx_ep_err("IQ[%d] req_list alloc failed\n", iq_no);
112                 goto iq_init_fail;
113         }
114
115         otx_ep_info("IQ[%d]: base: %p basedma: %lx count: %d\n",
116                      iq_no, iq->base_addr, (unsigned long)iq->base_addr_dma,
117                      iq->nb_desc);
118
119         iq->otx_ep_dev = otx_ep;
120         iq->q_no = iq_no;
121         iq->fill_cnt = 0;
122         iq->host_write_index = 0;
123         iq->otx_read_index = 0;
124         iq->flush_index = 0;
125         iq->instr_pending = 0;
126
127         otx_ep->io_qmask.iq |= (1ull << iq_no);
128
129         /* Set 32B/64B mode for each input queue */
130         if (conf->iq.instr_type == 64)
131                 otx_ep->io_qmask.iq64B |= (1ull << iq_no);
132
133         iq->iqcmd_64B = (conf->iq.instr_type == 64);
134
135         /* Set up IQ registers */
136         otx_ep->fn_list.setup_iq_regs(otx_ep, iq_no);
137
138         return 0;
139
140 iq_init_fail:
141         return -ENOMEM;
142 }
143
144 int
145 otx_ep_setup_iqs(struct otx_ep_device *otx_ep, uint32_t iq_no, int num_descs,
146                  unsigned int socket_id)
147 {
148         struct otx_ep_instr_queue *iq;
149
150         iq = (struct otx_ep_instr_queue *)rte_zmalloc("otx_ep_IQ", sizeof(*iq),
151                                                 RTE_CACHE_LINE_SIZE);
152         if (iq == NULL)
153                 return -ENOMEM;
154
155         otx_ep->instr_queue[iq_no] = iq;
156
157         if (otx_ep_init_instr_queue(otx_ep, iq_no, num_descs, socket_id)) {
158                 otx_ep_err("IQ init is failed\n");
159                 goto delete_IQ;
160         }
161         otx_ep->nb_tx_queues++;
162
163         otx_ep_info("IQ[%d] is created.\n", iq_no);
164
165         return 0;
166
167 delete_IQ:
168         otx_ep_delete_iqs(otx_ep, iq_no);
169         return -ENOMEM;
170 }
171
172 static void
173 otx_ep_droq_reset_indices(struct otx_ep_droq *droq)
174 {
175         droq->read_idx  = 0;
176         droq->write_idx = 0;
177         droq->refill_idx = 0;
178         droq->refill_count = 0;
179         droq->last_pkt_count = 0;
180         droq->pkts_pending = 0;
181 }
182
183 static void
184 otx_ep_droq_destroy_ring_buffers(struct otx_ep_droq *droq)
185 {
186         uint32_t idx;
187
188         for (idx = 0; idx < droq->nb_desc; idx++) {
189                 if (droq->recv_buf_list[idx]) {
190                         rte_pktmbuf_free(droq->recv_buf_list[idx]);
191                         droq->recv_buf_list[idx] = NULL;
192                 }
193         }
194
195         otx_ep_droq_reset_indices(droq);
196 }
197
198 /* Free OQs resources */
199 int
200 otx_ep_delete_oqs(struct otx_ep_device *otx_ep, uint32_t oq_no)
201 {
202         struct otx_ep_droq *droq;
203
204         droq = otx_ep->droq[oq_no];
205         if (droq == NULL) {
206                 otx_ep_err("Invalid droq[%d]\n", oq_no);
207                 return -EINVAL;
208         }
209
210         otx_ep_droq_destroy_ring_buffers(droq);
211         rte_free(droq->recv_buf_list);
212         droq->recv_buf_list = NULL;
213
214         if (droq->desc_ring_mz) {
215                 otx_ep_dmazone_free(droq->desc_ring_mz);
216                 droq->desc_ring_mz = NULL;
217         }
218
219         memset(droq, 0, OTX_EP_DROQ_SIZE);
220
221         rte_free(otx_ep->droq[oq_no]);
222         otx_ep->droq[oq_no] = NULL;
223
224         otx_ep->nb_rx_queues--;
225
226         otx_ep_info("OQ[%d] is deleted\n", oq_no);
227         return 0;
228 }
229
230 static int
231 otx_ep_droq_setup_ring_buffers(struct otx_ep_droq *droq)
232 {
233         struct otx_ep_droq_desc *desc_ring = droq->desc_ring;
234         struct otx_ep_droq_info *info;
235         struct rte_mbuf *buf;
236         uint32_t idx;
237
238         for (idx = 0; idx < droq->nb_desc; idx++) {
239                 buf = rte_pktmbuf_alloc(droq->mpool);
240                 if (buf == NULL) {
241                         otx_ep_err("OQ buffer alloc failed\n");
242                         droq->stats.rx_alloc_failure++;
243                         return -ENOMEM;
244                 }
245
246                 droq->recv_buf_list[idx] = buf;
247                 info = rte_pktmbuf_mtod(buf, struct otx_ep_droq_info *);
248                 memset(info, 0, sizeof(*info));
249                 desc_ring[idx].buffer_ptr = rte_mbuf_data_iova_default(buf);
250         }
251
252         otx_ep_droq_reset_indices(droq);
253
254         return 0;
255 }
256
257 /* OQ initialization */
258 static int
259 otx_ep_init_droq(struct otx_ep_device *otx_ep, uint32_t q_no,
260               uint32_t num_descs, uint32_t desc_size,
261               struct rte_mempool *mpool, unsigned int socket_id)
262 {
263         const struct otx_ep_config *conf = otx_ep->conf;
264         uint32_t c_refill_threshold;
265         struct otx_ep_droq *droq;
266         uint32_t desc_ring_size;
267
268         otx_ep_info("OQ[%d] Init start\n", q_no);
269
270         droq = otx_ep->droq[q_no];
271         droq->otx_ep_dev = otx_ep;
272         droq->q_no = q_no;
273         droq->mpool = mpool;
274
275         droq->nb_desc      = num_descs;
276         droq->buffer_size  = desc_size;
277         c_refill_threshold = RTE_MAX(conf->oq.refill_threshold,
278                                      droq->nb_desc / 2);
279
280         /* OQ desc_ring set up */
281         desc_ring_size = droq->nb_desc * OTX_EP_DROQ_DESC_SIZE;
282         droq->desc_ring_mz = rte_eth_dma_zone_reserve(otx_ep->eth_dev, "droq",
283                                                       q_no, desc_ring_size,
284                                                       OTX_EP_PCI_RING_ALIGN,
285                                                       socket_id);
286
287         if (droq->desc_ring_mz == NULL) {
288                 otx_ep_err("OQ:%d desc_ring allocation failed\n", q_no);
289                 goto init_droq_fail;
290         }
291
292         droq->desc_ring_dma = droq->desc_ring_mz->iova;
293         droq->desc_ring = (struct otx_ep_droq_desc *)droq->desc_ring_mz->addr;
294
295         otx_ep_dbg("OQ[%d]: desc_ring: virt: 0x%p, dma: %lx\n",
296                     q_no, droq->desc_ring, (unsigned long)droq->desc_ring_dma);
297         otx_ep_dbg("OQ[%d]: num_desc: %d\n", q_no, droq->nb_desc);
298
299         /* OQ buf_list set up */
300         droq->recv_buf_list = rte_zmalloc_socket("recv_buf_list",
301                                 (droq->nb_desc * sizeof(struct rte_mbuf *)),
302                                  RTE_CACHE_LINE_SIZE, socket_id);
303         if (droq->recv_buf_list == NULL) {
304                 otx_ep_err("OQ recv_buf_list alloc failed\n");
305                 goto init_droq_fail;
306         }
307
308         if (otx_ep_droq_setup_ring_buffers(droq))
309                 goto init_droq_fail;
310
311         droq->refill_threshold = c_refill_threshold;
312
313         /* Set up OQ registers */
314         otx_ep->fn_list.setup_oq_regs(otx_ep, q_no);
315
316         otx_ep->io_qmask.oq |= (1ull << q_no);
317
318         return 0;
319
320 init_droq_fail:
321         return -ENOMEM;
322 }
323
324 /* OQ configuration and setup */
325 int
326 otx_ep_setup_oqs(struct otx_ep_device *otx_ep, int oq_no, int num_descs,
327                  int desc_size, struct rte_mempool *mpool,
328                  unsigned int socket_id)
329 {
330         struct otx_ep_droq *droq;
331
332         /* Allocate new droq. */
333         droq = (struct otx_ep_droq *)rte_zmalloc("otx_ep_OQ",
334                                 sizeof(*droq), RTE_CACHE_LINE_SIZE);
335         if (droq == NULL) {
336                 otx_ep_err("Droq[%d] Creation Failed\n", oq_no);
337                 return -ENOMEM;
338         }
339         otx_ep->droq[oq_no] = droq;
340
341         if (otx_ep_init_droq(otx_ep, oq_no, num_descs, desc_size, mpool,
342                              socket_id)) {
343                 otx_ep_err("Droq[%d] Initialization failed\n", oq_no);
344                 goto delete_OQ;
345         }
346         otx_ep_info("OQ[%d] is created.\n", oq_no);
347
348         otx_ep->nb_rx_queues++;
349
350         return 0;
351
352 delete_OQ:
353         otx_ep_delete_oqs(otx_ep, oq_no);
354         return -ENOMEM;
355 }