401bbe520ed1676415ad62444b1af51bed250383
[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 static void
40 otx_ep_droq_reset_indices(struct otx_ep_droq *droq)
41 {
42         droq->read_idx  = 0;
43         droq->write_idx = 0;
44         droq->refill_idx = 0;
45         droq->refill_count = 0;
46         droq->last_pkt_count = 0;
47         droq->pkts_pending = 0;
48 }
49
50 static void
51 otx_ep_droq_destroy_ring_buffers(struct otx_ep_droq *droq)
52 {
53         uint32_t idx;
54
55         for (idx = 0; idx < droq->nb_desc; idx++) {
56                 if (droq->recv_buf_list[idx]) {
57                         rte_pktmbuf_free(droq->recv_buf_list[idx]);
58                         droq->recv_buf_list[idx] = NULL;
59                 }
60         }
61
62         otx_ep_droq_reset_indices(droq);
63 }
64
65 /* Free OQs resources */
66 int
67 otx_ep_delete_oqs(struct otx_ep_device *otx_ep, uint32_t oq_no)
68 {
69         struct otx_ep_droq *droq;
70
71         droq = otx_ep->droq[oq_no];
72         if (droq == NULL) {
73                 otx_ep_err("Invalid droq[%d]\n", oq_no);
74                 return -EINVAL;
75         }
76
77         otx_ep_droq_destroy_ring_buffers(droq);
78         rte_free(droq->recv_buf_list);
79         droq->recv_buf_list = NULL;
80
81         if (droq->desc_ring_mz) {
82                 otx_ep_dmazone_free(droq->desc_ring_mz);
83                 droq->desc_ring_mz = NULL;
84         }
85
86         memset(droq, 0, OTX_EP_DROQ_SIZE);
87
88         rte_free(otx_ep->droq[oq_no]);
89         otx_ep->droq[oq_no] = NULL;
90
91         otx_ep->nb_rx_queues--;
92
93         otx_ep_info("OQ[%d] is deleted\n", oq_no);
94         return 0;
95 }
96
97 static int
98 otx_ep_droq_setup_ring_buffers(struct otx_ep_droq *droq)
99 {
100         struct otx_ep_droq_desc *desc_ring = droq->desc_ring;
101         struct otx_ep_droq_info *info;
102         struct rte_mbuf *buf;
103         uint32_t idx;
104
105         for (idx = 0; idx < droq->nb_desc; idx++) {
106                 buf = rte_pktmbuf_alloc(droq->mpool);
107                 if (buf == NULL) {
108                         otx_ep_err("OQ buffer alloc failed\n");
109                         droq->stats.rx_alloc_failure++;
110                         return -ENOMEM;
111                 }
112
113                 droq->recv_buf_list[idx] = buf;
114                 info = rte_pktmbuf_mtod(buf, struct otx_ep_droq_info *);
115                 memset(info, 0, sizeof(*info));
116                 desc_ring[idx].buffer_ptr = rte_mbuf_data_iova_default(buf);
117         }
118
119         otx_ep_droq_reset_indices(droq);
120
121         return 0;
122 }
123
124 /* OQ initialization */
125 static int
126 otx_ep_init_droq(struct otx_ep_device *otx_ep, uint32_t q_no,
127               uint32_t num_descs, uint32_t desc_size,
128               struct rte_mempool *mpool, unsigned int socket_id)
129 {
130         const struct otx_ep_config *conf = otx_ep->conf;
131         uint32_t c_refill_threshold;
132         struct otx_ep_droq *droq;
133         uint32_t desc_ring_size;
134
135         otx_ep_info("OQ[%d] Init start\n", q_no);
136
137         droq = otx_ep->droq[q_no];
138         droq->otx_ep_dev = otx_ep;
139         droq->q_no = q_no;
140         droq->mpool = mpool;
141
142         droq->nb_desc      = num_descs;
143         droq->buffer_size  = desc_size;
144         c_refill_threshold = RTE_MAX(conf->oq.refill_threshold,
145                                      droq->nb_desc / 2);
146
147         /* OQ desc_ring set up */
148         desc_ring_size = droq->nb_desc * OTX_EP_DROQ_DESC_SIZE;
149         droq->desc_ring_mz = rte_eth_dma_zone_reserve(otx_ep->eth_dev, "droq",
150                                                       q_no, desc_ring_size,
151                                                       OTX_EP_PCI_RING_ALIGN,
152                                                       socket_id);
153
154         if (droq->desc_ring_mz == NULL) {
155                 otx_ep_err("OQ:%d desc_ring allocation failed\n", q_no);
156                 goto init_droq_fail;
157         }
158
159         droq->desc_ring_dma = droq->desc_ring_mz->iova;
160         droq->desc_ring = (struct otx_ep_droq_desc *)droq->desc_ring_mz->addr;
161
162         otx_ep_dbg("OQ[%d]: desc_ring: virt: 0x%p, dma: %lx\n",
163                     q_no, droq->desc_ring, (unsigned long)droq->desc_ring_dma);
164         otx_ep_dbg("OQ[%d]: num_desc: %d\n", q_no, droq->nb_desc);
165
166         /* OQ buf_list set up */
167         droq->recv_buf_list = rte_zmalloc_socket("recv_buf_list",
168                                 (droq->nb_desc * sizeof(struct rte_mbuf *)),
169                                  RTE_CACHE_LINE_SIZE, socket_id);
170         if (droq->recv_buf_list == NULL) {
171                 otx_ep_err("OQ recv_buf_list alloc failed\n");
172                 goto init_droq_fail;
173         }
174
175         if (otx_ep_droq_setup_ring_buffers(droq))
176                 goto init_droq_fail;
177
178         droq->refill_threshold = c_refill_threshold;
179
180         /* Set up OQ registers */
181         otx_ep->fn_list.setup_oq_regs(otx_ep, q_no);
182
183         otx_ep->io_qmask.oq |= (1ull << q_no);
184
185         return 0;
186
187 init_droq_fail:
188         return -ENOMEM;
189 }
190
191 /* OQ configuration and setup */
192 int
193 otx_ep_setup_oqs(struct otx_ep_device *otx_ep, int oq_no, int num_descs,
194                  int desc_size, struct rte_mempool *mpool,
195                  unsigned int socket_id)
196 {
197         struct otx_ep_droq *droq;
198
199         /* Allocate new droq. */
200         droq = (struct otx_ep_droq *)rte_zmalloc("otx_ep_OQ",
201                                 sizeof(*droq), RTE_CACHE_LINE_SIZE);
202         if (droq == NULL) {
203                 otx_ep_err("Droq[%d] Creation Failed\n", oq_no);
204                 return -ENOMEM;
205         }
206         otx_ep->droq[oq_no] = droq;
207
208         if (otx_ep_init_droq(otx_ep, oq_no, num_descs, desc_size, mpool,
209                              socket_id)) {
210                 otx_ep_err("Droq[%d] Initialization failed\n", oq_no);
211                 goto delete_OQ;
212         }
213         otx_ep_info("OQ[%d] is created.\n", oq_no);
214
215         otx_ep->nb_rx_queues++;
216
217         return 0;
218
219 delete_OQ:
220         otx_ep_delete_oqs(otx_ep, oq_no);
221         return -ENOMEM;
222 }