mempool/octeontx2: add devargs for max pool selection
[dpdk.git] / drivers / mempool / octeontx2 / otx2_mempool.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <rte_atomic.h>
6 #include <rte_bus_pci.h>
7 #include <rte_common.h>
8 #include <rte_eal.h>
9 #include <rte_io.h>
10 #include <rte_kvargs.h>
11 #include <rte_malloc.h>
12 #include <rte_mbuf_pool_ops.h>
13 #include <rte_pci.h>
14
15 #include "otx2_common.h"
16 #include "otx2_dev.h"
17 #include "otx2_mempool.h"
18
19 #define OTX2_NPA_DEV_NAME       RTE_STR(otx2_npa_dev_)
20 #define OTX2_NPA_DEV_NAME_LEN   (sizeof(OTX2_NPA_DEV_NAME) + PCI_PRI_STR_SIZE)
21
22 static inline int
23 npa_lf_alloc(struct otx2_npa_lf *lf)
24 {
25         struct otx2_mbox *mbox = lf->mbox;
26         struct npa_lf_alloc_req *req;
27         struct npa_lf_alloc_rsp *rsp;
28         int rc;
29
30         req = otx2_mbox_alloc_msg_npa_lf_alloc(mbox);
31         req->aura_sz = lf->aura_sz;
32         req->nr_pools = lf->nr_pools;
33
34         rc = otx2_mbox_process_msg(mbox, (void *)&rsp);
35         if (rc)
36                 return NPA_LF_ERR_ALLOC;
37
38         lf->stack_pg_ptrs = rsp->stack_pg_ptrs;
39         lf->stack_pg_bytes = rsp->stack_pg_bytes;
40         lf->qints = rsp->qints;
41
42         return 0;
43 }
44
45 static int
46 npa_lf_free(struct otx2_mbox *mbox)
47 {
48         otx2_mbox_alloc_msg_npa_lf_free(mbox);
49
50         return otx2_mbox_process(mbox);
51 }
52
53 static int
54 npa_lf_init(struct otx2_npa_lf *lf, uintptr_t base, uint8_t aura_sz,
55             uint32_t nr_pools, struct otx2_mbox *mbox)
56 {
57         uint32_t i, bmp_sz;
58         int rc;
59
60         /* Sanity checks */
61         if (!lf || !base || !mbox || !nr_pools)
62                 return NPA_LF_ERR_PARAM;
63
64         if (base & AURA_ID_MASK)
65                 return NPA_LF_ERR_BASE_INVALID;
66
67         if (aura_sz == NPA_AURA_SZ_0 || aura_sz >= NPA_AURA_SZ_MAX)
68                 return NPA_LF_ERR_PARAM;
69
70         memset(lf, 0x0, sizeof(*lf));
71         lf->base = base;
72         lf->aura_sz = aura_sz;
73         lf->nr_pools = nr_pools;
74         lf->mbox = mbox;
75
76         rc = npa_lf_alloc(lf);
77         if (rc)
78                 goto exit;
79
80         bmp_sz = rte_bitmap_get_memory_footprint(nr_pools);
81
82         /* Allocate memory for bitmap */
83         lf->npa_bmp_mem = rte_zmalloc("npa_bmp_mem", bmp_sz,
84                                         RTE_CACHE_LINE_SIZE);
85         if (lf->npa_bmp_mem == NULL) {
86                 rc = -ENOMEM;
87                 goto lf_free;
88         }
89
90         /* Initialize pool resource bitmap array */
91         lf->npa_bmp = rte_bitmap_init(nr_pools, lf->npa_bmp_mem, bmp_sz);
92         if (lf->npa_bmp == NULL) {
93                 rc = -EINVAL;
94                 goto bmap_mem_free;
95         }
96
97         /* Mark all pools available */
98         for (i = 0; i < nr_pools; i++)
99                 rte_bitmap_set(lf->npa_bmp, i);
100
101         /* Allocate memory for qint context */
102         lf->npa_qint_mem = rte_zmalloc("npa_qint_mem",
103                         sizeof(struct otx2_npa_qint) * nr_pools, 0);
104         if (lf->npa_qint_mem == NULL) {
105                 rc = -ENOMEM;
106                 goto bmap_free;
107         }
108
109         /* Allocate memory for nap_aura_lim memory */
110         lf->aura_lim = rte_zmalloc("npa_aura_lim_mem",
111                         sizeof(struct npa_aura_lim) * nr_pools, 0);
112         if (lf->aura_lim == NULL) {
113                 rc = -ENOMEM;
114                 goto qint_free;
115         }
116
117         /* Init aura start & end limits */
118         for (i = 0; i < nr_pools; i++) {
119                 lf->aura_lim[i].ptr_start = UINT64_MAX;
120                 lf->aura_lim[i].ptr_end = 0x0ull;
121         }
122
123         return 0;
124
125 qint_free:
126         rte_free(lf->npa_qint_mem);
127 bmap_free:
128         rte_bitmap_free(lf->npa_bmp);
129 bmap_mem_free:
130         rte_free(lf->npa_bmp_mem);
131 lf_free:
132         npa_lf_free(lf->mbox);
133 exit:
134         return rc;
135 }
136
137 static int
138 npa_lf_fini(struct otx2_npa_lf *lf)
139 {
140         if (!lf)
141                 return NPA_LF_ERR_PARAM;
142
143         rte_free(lf->aura_lim);
144         rte_free(lf->npa_qint_mem);
145         rte_bitmap_free(lf->npa_bmp);
146         rte_free(lf->npa_bmp_mem);
147
148         return npa_lf_free(lf->mbox);
149
150 }
151
152 static inline uint32_t
153 otx2_aura_size_to_u32(uint8_t val)
154 {
155         if (val == NPA_AURA_SZ_0)
156                 return 128;
157         if (val >= NPA_AURA_SZ_MAX)
158                 return BIT_ULL(20);
159
160         return 1 << (val + 6);
161 }
162
163 static int
164 parse_max_pools(const char *key, const char *value, void *extra_args)
165 {
166         RTE_SET_USED(key);
167         uint32_t val;
168
169         val = atoi(value);
170         if (val < otx2_aura_size_to_u32(NPA_AURA_SZ_128))
171                 val = 128;
172         if (val > otx2_aura_size_to_u32(NPA_AURA_SZ_1M))
173                 val = BIT_ULL(20);
174
175         *(uint8_t *)extra_args = rte_log2_u32(val) - 6;
176         return 0;
177 }
178
179 #define OTX2_MAX_POOLS "max_pools"
180
181 static uint8_t
182 otx2_parse_aura_size(struct rte_devargs *devargs)
183 {
184         uint8_t aura_sz = NPA_AURA_SZ_128;
185         struct rte_kvargs *kvlist;
186
187         if (devargs == NULL)
188                 goto exit;
189         kvlist = rte_kvargs_parse(devargs->args, NULL);
190         if (kvlist == NULL)
191                 goto exit;
192
193         rte_kvargs_process(kvlist, OTX2_MAX_POOLS, &parse_max_pools, &aura_sz);
194         rte_kvargs_free(kvlist);
195 exit:
196         return aura_sz;
197 }
198
199 static inline int
200 npa_lf_attach(struct otx2_mbox *mbox)
201 {
202         struct rsrc_attach_req *req;
203
204         req = otx2_mbox_alloc_msg_attach_resources(mbox);
205         req->npalf = true;
206
207         return otx2_mbox_process(mbox);
208 }
209
210 static inline int
211 npa_lf_detach(struct otx2_mbox *mbox)
212 {
213         struct rsrc_detach_req *req;
214
215         req = otx2_mbox_alloc_msg_detach_resources(mbox);
216         req->npalf = true;
217
218         return otx2_mbox_process(mbox);
219 }
220
221 static inline int
222 npa_lf_get_msix_offset(struct otx2_mbox *mbox, uint16_t *npa_msixoff)
223 {
224         struct msix_offset_rsp *msix_rsp;
225         int rc;
226
227         /* Get NPA and NIX MSIX vector offsets */
228         otx2_mbox_alloc_msg_msix_offset(mbox);
229
230         rc = otx2_mbox_process_msg(mbox, (void *)&msix_rsp);
231
232         *npa_msixoff = msix_rsp->npa_msixoff;
233
234         return rc;
235 }
236
237 /**
238  * @internal
239  * Finalize NPA LF.
240  */
241 int
242 otx2_npa_lf_fini(void)
243 {
244         struct otx2_idev_cfg *idev;
245         int rc = 0;
246
247         idev = otx2_intra_dev_get_cfg();
248         if (idev == NULL)
249                 return -ENOMEM;
250
251         if (rte_atomic16_add_return(&idev->npa_refcnt, -1) == 0) {
252                 otx2_npa_unregister_irqs(idev->npa_lf);
253                 rc |= npa_lf_fini(idev->npa_lf);
254                 rc |= npa_lf_detach(idev->npa_lf->mbox);
255                 otx2_npa_set_defaults(idev);
256         }
257
258         return rc;
259 }
260
261 /**
262  * @internal
263  * Initialize NPA LF.
264  */
265 int
266 otx2_npa_lf_init(struct rte_pci_device *pci_dev, void *otx2_dev)
267 {
268         struct otx2_dev *dev = otx2_dev;
269         struct otx2_idev_cfg *idev;
270         struct otx2_npa_lf *lf;
271         uint16_t npa_msixoff;
272         uint32_t nr_pools;
273         uint8_t aura_sz;
274         int rc;
275
276         idev = otx2_intra_dev_get_cfg();
277         if (idev == NULL)
278                 return -ENOMEM;
279
280         /* Is NPA LF initialized by any another driver? */
281         if (rte_atomic16_add_return(&idev->npa_refcnt, 1) == 1) {
282
283                 rc = npa_lf_attach(dev->mbox);
284                 if (rc)
285                         goto fail;
286
287                 rc = npa_lf_get_msix_offset(dev->mbox, &npa_msixoff);
288                 if (rc)
289                         goto npa_detach;
290
291                 aura_sz = otx2_parse_aura_size(pci_dev->device.devargs);
292                 nr_pools = otx2_aura_size_to_u32(aura_sz);
293
294                 lf = &dev->npalf;
295                 rc = npa_lf_init(lf, dev->bar2 + (RVU_BLOCK_ADDR_NPA << 20),
296                                         aura_sz, nr_pools, dev->mbox);
297
298                 if (rc)
299                         goto npa_detach;
300
301                 lf->pf_func = dev->pf_func;
302                 lf->npa_msixoff = npa_msixoff;
303                 lf->intr_handle = &pci_dev->intr_handle;
304                 lf->pci_dev = pci_dev;
305
306                 idev->npa_pf_func = dev->pf_func;
307                 idev->npa_lf = lf;
308                 rte_smp_wmb();
309                 rc = otx2_npa_register_irqs(lf);
310                 if (rc)
311                         goto npa_fini;
312
313                 rte_mbuf_set_platform_mempool_ops("octeontx2_npa");
314                 otx2_npa_dbg("npa_lf=%p pools=%d sz=%d pf_func=0x%x msix=0x%x",
315                              lf, nr_pools, aura_sz, lf->pf_func, npa_msixoff);
316         }
317
318         return 0;
319
320 npa_fini:
321         npa_lf_fini(idev->npa_lf);
322 npa_detach:
323         npa_lf_detach(dev->mbox);
324 fail:
325         rte_atomic16_dec(&idev->npa_refcnt);
326         return rc;
327 }
328
329 static inline char*
330 otx2_npa_dev_to_name(struct rte_pci_device *pci_dev, char *name)
331 {
332         snprintf(name, OTX2_NPA_DEV_NAME_LEN,
333                  OTX2_NPA_DEV_NAME  PCI_PRI_FMT,
334                  pci_dev->addr.domain, pci_dev->addr.bus,
335                  pci_dev->addr.devid, pci_dev->addr.function);
336
337         return name;
338 }
339
340 static int
341 otx2_npa_init(struct rte_pci_device *pci_dev)
342 {
343         char name[OTX2_NPA_DEV_NAME_LEN];
344         const struct rte_memzone *mz;
345         struct otx2_dev *dev;
346         int rc = -ENOMEM;
347
348         mz = rte_memzone_reserve_aligned(otx2_npa_dev_to_name(pci_dev, name),
349                                          sizeof(*dev), SOCKET_ID_ANY,
350                                          0, OTX2_ALIGN);
351         if (mz == NULL)
352                 goto error;
353
354         dev = mz->addr;
355
356         /* Initialize the base otx2_dev object */
357         rc = otx2_dev_init(pci_dev, dev);
358         if (rc)
359                 goto malloc_fail;
360
361         /* Grab the NPA LF if required */
362         rc = otx2_npa_lf_init(pci_dev, dev);
363         if (rc)
364                 goto dev_uninit;
365
366         dev->drv_inited = true;
367         return 0;
368
369 dev_uninit:
370         otx2_npa_lf_fini();
371         otx2_dev_fini(pci_dev, dev);
372 malloc_fail:
373         rte_memzone_free(mz);
374 error:
375         otx2_err("Failed to initialize npa device rc=%d", rc);
376         return rc;
377 }
378
379 static int
380 otx2_npa_fini(struct rte_pci_device *pci_dev)
381 {
382         char name[OTX2_NPA_DEV_NAME_LEN];
383         const struct rte_memzone *mz;
384         struct otx2_dev *dev;
385
386         mz = rte_memzone_lookup(otx2_npa_dev_to_name(pci_dev, name));
387         if (mz == NULL)
388                 return -EINVAL;
389
390         dev = mz->addr;
391         if (!dev->drv_inited)
392                 goto dev_fini;
393
394         dev->drv_inited = false;
395         otx2_npa_lf_fini();
396
397 dev_fini:
398         if (otx2_npa_lf_active(dev)) {
399                 otx2_info("%s: common resource in use by other devices",
400                           pci_dev->name);
401                 return -EAGAIN;
402         }
403
404         otx2_dev_fini(pci_dev, dev);
405         rte_memzone_free(mz);
406
407         return 0;
408 }
409
410 static int
411 npa_remove(struct rte_pci_device *pci_dev)
412 {
413         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
414                 return 0;
415
416         return otx2_npa_fini(pci_dev);
417 }
418
419 static int
420 npa_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
421 {
422         RTE_SET_USED(pci_drv);
423
424         if (rte_eal_process_type() != RTE_PROC_PRIMARY)
425                 return 0;
426
427         return otx2_npa_init(pci_dev);
428 }
429
430 static const struct rte_pci_id pci_npa_map[] = {
431         {
432                 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
433                                         PCI_DEVID_OCTEONTX2_RVU_NPA_PF)
434         },
435         {
436                 RTE_PCI_DEVICE(PCI_VENDOR_ID_CAVIUM,
437                                         PCI_DEVID_OCTEONTX2_RVU_NPA_VF)
438         },
439         {
440                 .vendor_id = 0,
441         },
442 };
443
444 static struct rte_pci_driver pci_npa = {
445         .id_table = pci_npa_map,
446         .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_IOVA_AS_VA,
447         .probe = npa_probe,
448         .remove = npa_remove,
449 };
450
451 RTE_PMD_REGISTER_PCI(mempool_octeontx2, pci_npa);
452 RTE_PMD_REGISTER_PCI_TABLE(mempool_octeontx2, pci_npa_map);
453 RTE_PMD_REGISTER_KMOD_DEP(mempool_octeontx2, "vfio-pci");
454 RTE_PMD_REGISTER_PARAM_STRING(mempool_octeontx2,
455                               OTX2_MAX_POOLS "=<128-1048576>");