common/cnxk: fix shift offset for TL3 length disable
[dpdk.git] / drivers / common / cnxk / roc_npa.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #include "roc_api.h"
6 #include "roc_priv.h"
7
8 static roc_npa_lf_init_cb_t lf_init_cb;
9
10 int
11 roc_npa_lf_init_cb_register(roc_npa_lf_init_cb_t cb)
12 {
13         if (lf_init_cb != NULL)
14                 return -EEXIST;
15
16         lf_init_cb = cb;
17         return 0;
18 }
19
20 void
21 roc_npa_aura_op_range_set(uint64_t aura_handle, uint64_t start_iova,
22                           uint64_t end_iova)
23 {
24         const uint64_t start = roc_npa_aura_handle_to_base(aura_handle) +
25                                NPA_LF_POOL_OP_PTR_START0;
26         const uint64_t end = roc_npa_aura_handle_to_base(aura_handle) +
27                              NPA_LF_POOL_OP_PTR_END0;
28         uint64_t reg = roc_npa_aura_handle_to_aura(aura_handle);
29         struct npa_lf *lf = idev_npa_obj_get();
30         struct npa_aura_lim *lim;
31
32         PLT_ASSERT(lf);
33         lim = lf->aura_lim;
34
35         lim[reg].ptr_start = PLT_MIN(lim[reg].ptr_start, start_iova);
36         lim[reg].ptr_end = PLT_MAX(lim[reg].ptr_end, end_iova);
37
38         roc_store_pair(lim[reg].ptr_start, reg, start);
39         roc_store_pair(lim[reg].ptr_end, reg, end);
40 }
41
42 static int
43 npa_aura_pool_init(struct mbox *mbox, uint32_t aura_id, struct npa_aura_s *aura,
44                    struct npa_pool_s *pool)
45 {
46         struct npa_aq_enq_req *aura_init_req, *pool_init_req;
47         struct npa_aq_enq_rsp *aura_init_rsp, *pool_init_rsp;
48         struct mbox_dev *mdev = &mbox->dev[0];
49         int rc = -ENOSPC, off;
50
51         aura_init_req = mbox_alloc_msg_npa_aq_enq(mbox);
52         if (aura_init_req == NULL)
53                 return rc;
54         aura_init_req->aura_id = aura_id;
55         aura_init_req->ctype = NPA_AQ_CTYPE_AURA;
56         aura_init_req->op = NPA_AQ_INSTOP_INIT;
57         mbox_memcpy(&aura_init_req->aura, aura, sizeof(*aura));
58
59         pool_init_req = mbox_alloc_msg_npa_aq_enq(mbox);
60         if (pool_init_req == NULL)
61                 return rc;
62         pool_init_req->aura_id = aura_id;
63         pool_init_req->ctype = NPA_AQ_CTYPE_POOL;
64         pool_init_req->op = NPA_AQ_INSTOP_INIT;
65         mbox_memcpy(&pool_init_req->pool, pool, sizeof(*pool));
66
67         rc = mbox_process(mbox);
68         if (rc < 0)
69                 return rc;
70
71         off = mbox->rx_start +
72               PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
73         aura_init_rsp = (struct npa_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
74         off = mbox->rx_start + aura_init_rsp->hdr.next_msgoff;
75         pool_init_rsp = (struct npa_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
76
77         if (aura_init_rsp->hdr.rc == 0 && pool_init_rsp->hdr.rc == 0)
78                 return 0;
79         else
80                 return NPA_ERR_AURA_POOL_INIT;
81 }
82
83 static int
84 npa_aura_pool_fini(struct mbox *mbox, uint32_t aura_id, uint64_t aura_handle)
85 {
86         struct npa_aq_enq_req *aura_req, *pool_req;
87         struct npa_aq_enq_rsp *aura_rsp, *pool_rsp;
88         struct mbox_dev *mdev = &mbox->dev[0];
89         struct ndc_sync_op *ndc_req;
90         int rc = -ENOSPC, off;
91         uint64_t ptr;
92
93         /* Procedure for disabling an aura/pool */
94         plt_delay_us(10);
95
96         /* Clear all the pointers from the aura */
97         do {
98                 ptr = roc_npa_aura_op_alloc(aura_handle, 0);
99         } while (ptr);
100
101         pool_req = mbox_alloc_msg_npa_aq_enq(mbox);
102         if (pool_req == NULL)
103                 return rc;
104         pool_req->aura_id = aura_id;
105         pool_req->ctype = NPA_AQ_CTYPE_POOL;
106         pool_req->op = NPA_AQ_INSTOP_WRITE;
107         pool_req->pool.ena = 0;
108         pool_req->pool_mask.ena = ~pool_req->pool_mask.ena;
109
110         aura_req = mbox_alloc_msg_npa_aq_enq(mbox);
111         if (aura_req == NULL)
112                 return rc;
113         aura_req->aura_id = aura_id;
114         aura_req->ctype = NPA_AQ_CTYPE_AURA;
115         aura_req->op = NPA_AQ_INSTOP_WRITE;
116         aura_req->aura.ena = 0;
117         aura_req->aura_mask.ena = ~aura_req->aura_mask.ena;
118
119         rc = mbox_process(mbox);
120         if (rc < 0)
121                 return rc;
122
123         off = mbox->rx_start +
124               PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
125         pool_rsp = (struct npa_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
126
127         off = mbox->rx_start + pool_rsp->hdr.next_msgoff;
128         aura_rsp = (struct npa_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
129
130         if (aura_rsp->hdr.rc != 0 || pool_rsp->hdr.rc != 0)
131                 return NPA_ERR_AURA_POOL_FINI;
132
133         /* Sync NDC-NPA for LF */
134         ndc_req = mbox_alloc_msg_ndc_sync_op(mbox);
135         if (ndc_req == NULL)
136                 return -ENOSPC;
137         ndc_req->npa_lf_sync = 1;
138         rc = mbox_process(mbox);
139         if (rc) {
140                 plt_err("Error on NDC-NPA LF sync, rc %d", rc);
141                 return NPA_ERR_AURA_POOL_FINI;
142         }
143         return 0;
144 }
145
146 int
147 roc_npa_pool_op_pc_reset(uint64_t aura_handle)
148 {
149         struct npa_lf *lf = idev_npa_obj_get();
150         struct npa_aq_enq_req *pool_req;
151         struct npa_aq_enq_rsp *pool_rsp;
152         struct ndc_sync_op *ndc_req;
153         struct mbox_dev *mdev;
154         int rc = -ENOSPC, off;
155         struct mbox *mbox;
156
157         if (lf == NULL)
158                 return NPA_ERR_PARAM;
159
160         mbox = lf->mbox;
161         mdev = &mbox->dev[0];
162         plt_npa_dbg("lf=%p aura_handle=0x%" PRIx64, lf, aura_handle);
163
164         pool_req = mbox_alloc_msg_npa_aq_enq(mbox);
165         if (pool_req == NULL)
166                 return rc;
167         pool_req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
168         pool_req->ctype = NPA_AQ_CTYPE_POOL;
169         pool_req->op = NPA_AQ_INSTOP_WRITE;
170         pool_req->pool.op_pc = 0;
171         pool_req->pool_mask.op_pc = ~pool_req->pool_mask.op_pc;
172
173         rc = mbox_process(mbox);
174         if (rc < 0)
175                 return rc;
176
177         off = mbox->rx_start +
178               PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
179         pool_rsp = (struct npa_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
180
181         if (pool_rsp->hdr.rc != 0)
182                 return NPA_ERR_AURA_POOL_FINI;
183
184         /* Sync NDC-NPA for LF */
185         ndc_req = mbox_alloc_msg_ndc_sync_op(mbox);
186         if (ndc_req == NULL)
187                 return -ENOSPC;
188         ndc_req->npa_lf_sync = 1;
189         rc = mbox_process(mbox);
190         if (rc) {
191                 plt_err("Error on NDC-NPA LF sync, rc %d", rc);
192                 return NPA_ERR_AURA_POOL_FINI;
193         }
194         return 0;
195 }
196 static inline char *
197 npa_stack_memzone_name(struct npa_lf *lf, int pool_id, char *name)
198 {
199         snprintf(name, PLT_MEMZONE_NAMESIZE, "roc_npa_stack_%x_%d", lf->pf_func,
200                  pool_id);
201         return name;
202 }
203
204 static inline const struct plt_memzone *
205 npa_stack_dma_alloc(struct npa_lf *lf, char *name, int pool_id, size_t size)
206 {
207         const char *mz_name = npa_stack_memzone_name(lf, pool_id, name);
208         size = PLT_ALIGN_CEIL(size, ROC_ALIGN);
209
210         return plt_memzone_reserve_aligned(mz_name, size, 0, ROC_ALIGN);
211 }
212
213 static inline int
214 npa_stack_dma_free(struct npa_lf *lf, char *name, int pool_id)
215 {
216         const struct plt_memzone *mz;
217
218         mz = plt_memzone_lookup(npa_stack_memzone_name(lf, pool_id, name));
219         if (mz == NULL)
220                 return NPA_ERR_PARAM;
221
222         return plt_memzone_free(mz);
223 }
224
225 static inline int
226 bitmap_ctzll(uint64_t slab)
227 {
228         if (slab == 0)
229                 return 0;
230
231         return __builtin_ctzll(slab);
232 }
233
234 static int
235 npa_aura_pool_pair_alloc(struct npa_lf *lf, const uint32_t block_size,
236                          const uint32_t block_count, struct npa_aura_s *aura,
237                          struct npa_pool_s *pool, uint64_t *aura_handle)
238 {
239         int rc, aura_id, pool_id, stack_size, alloc_size;
240         char name[PLT_MEMZONE_NAMESIZE];
241         const struct plt_memzone *mz;
242         uint64_t slab;
243         uint32_t pos;
244
245         /* Sanity check */
246         if (!lf || !block_size || !block_count || !pool || !aura ||
247             !aura_handle)
248                 return NPA_ERR_PARAM;
249
250         /* Block size should be cache line aligned and in range of 128B-128KB */
251         if (block_size % ROC_ALIGN || block_size < 128 ||
252             block_size > ROC_NPA_MAX_BLOCK_SZ)
253                 return NPA_ERR_INVALID_BLOCK_SZ;
254
255         pos = 0;
256         slab = 0;
257         /* Scan from the beginning */
258         plt_bitmap_scan_init(lf->npa_bmp);
259         /* Scan bitmap to get the free pool */
260         rc = plt_bitmap_scan(lf->npa_bmp, &pos, &slab);
261         /* Empty bitmap */
262         if (rc == 0) {
263                 plt_err("Mempools exhausted");
264                 return NPA_ERR_AURA_ID_ALLOC;
265         }
266
267         /* Get aura_id from resource bitmap */
268         aura_id = pos + bitmap_ctzll(slab);
269         /* Mark pool as reserved */
270         plt_bitmap_clear(lf->npa_bmp, aura_id);
271
272         /* Configuration based on each aura has separate pool(aura-pool pair) */
273         pool_id = aura_id;
274         rc = (aura_id < 0 || pool_id >= (int)lf->nr_pools ||
275               aura_id >= (int)BIT_ULL(6 + lf->aura_sz)) ?
276                            NPA_ERR_AURA_ID_ALLOC :
277                            0;
278         if (rc)
279                 goto exit;
280
281         /* Allocate stack memory */
282         stack_size = (block_count + lf->stack_pg_ptrs - 1) / lf->stack_pg_ptrs;
283         alloc_size = stack_size * lf->stack_pg_bytes;
284
285         mz = npa_stack_dma_alloc(lf, name, pool_id, alloc_size);
286         if (mz == NULL) {
287                 rc = NPA_ERR_ALLOC;
288                 goto aura_res_put;
289         }
290
291         /* Update aura fields */
292         aura->pool_addr = pool_id; /* AF will translate to associated poolctx */
293         aura->ena = 1;
294         aura->shift = plt_log2_u32(block_count);
295         aura->shift = aura->shift < 8 ? 0 : aura->shift - 8;
296         aura->limit = block_count;
297         aura->pool_caching = 1;
298         aura->err_int_ena = BIT(NPA_AURA_ERR_INT_AURA_ADD_OVER);
299         aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_AURA_ADD_UNDER);
300         aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_AURA_FREE_UNDER);
301         aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_POOL_DIS);
302         aura->avg_con = ROC_NPA_AVG_CONT;
303         /* Many to one reduction */
304         aura->err_qint_idx = aura_id % lf->qints;
305
306         /* Update pool fields */
307         pool->stack_base = mz->iova;
308         pool->ena = 1;
309         pool->buf_size = block_size / ROC_ALIGN;
310         pool->stack_max_pages = stack_size;
311         pool->shift = plt_log2_u32(block_count);
312         pool->shift = pool->shift < 8 ? 0 : pool->shift - 8;
313         pool->ptr_start = 0;
314         pool->ptr_end = ~0;
315         pool->stack_caching = 1;
316         pool->err_int_ena = BIT(NPA_POOL_ERR_INT_OVFLS);
317         pool->err_int_ena |= BIT(NPA_POOL_ERR_INT_RANGE);
318         pool->err_int_ena |= BIT(NPA_POOL_ERR_INT_PERR);
319         pool->avg_con = ROC_NPA_AVG_CONT;
320
321         /* Many to one reduction */
322         pool->err_qint_idx = pool_id % lf->qints;
323
324         /* Issue AURA_INIT and POOL_INIT op */
325         rc = npa_aura_pool_init(lf->mbox, aura_id, aura, pool);
326         if (rc)
327                 goto stack_mem_free;
328
329         *aura_handle = roc_npa_aura_handle_gen(aura_id, lf->base);
330         /* Update aura count */
331         roc_npa_aura_op_cnt_set(*aura_handle, 0, block_count);
332         /* Read it back to make sure aura count is updated */
333         roc_npa_aura_op_cnt_get(*aura_handle);
334
335         return 0;
336
337 stack_mem_free:
338         plt_memzone_free(mz);
339 aura_res_put:
340         plt_bitmap_set(lf->npa_bmp, aura_id);
341 exit:
342         return rc;
343 }
344
345 int
346 roc_npa_pool_create(uint64_t *aura_handle, uint32_t block_size,
347                     uint32_t block_count, struct npa_aura_s *aura,
348                     struct npa_pool_s *pool)
349 {
350         struct npa_aura_s defaura;
351         struct npa_pool_s defpool;
352         struct idev_cfg *idev;
353         struct npa_lf *lf;
354         int rc;
355
356         lf = idev_npa_obj_get();
357         if (lf == NULL) {
358                 rc = NPA_ERR_DEVICE_NOT_BOUNDED;
359                 goto error;
360         }
361
362         idev = idev_get_cfg();
363         if (idev == NULL) {
364                 rc = NPA_ERR_ALLOC;
365                 goto error;
366         }
367
368         if (aura == NULL) {
369                 memset(&defaura, 0, sizeof(struct npa_aura_s));
370                 aura = &defaura;
371         }
372         if (pool == NULL) {
373                 memset(&defpool, 0, sizeof(struct npa_pool_s));
374                 defpool.nat_align = 1;
375                 defpool.buf_offset = 1;
376                 pool = &defpool;
377         }
378
379         rc = npa_aura_pool_pair_alloc(lf, block_size, block_count, aura, pool,
380                                       aura_handle);
381         if (rc) {
382                 plt_err("Failed to alloc pool or aura rc=%d", rc);
383                 goto error;
384         }
385
386         plt_npa_dbg("lf=%p block_sz=%d block_count=%d aura_handle=0x%" PRIx64,
387                     lf, block_size, block_count, *aura_handle);
388
389         /* Just hold the reference of the object */
390         __atomic_fetch_add(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST);
391 error:
392         return rc;
393 }
394
395 int
396 roc_npa_aura_limit_modify(uint64_t aura_handle, uint16_t aura_limit)
397 {
398         struct npa_aq_enq_req *aura_req;
399         struct npa_lf *lf;
400         int rc;
401
402         lf = idev_npa_obj_get();
403         if (lf == NULL)
404                 return NPA_ERR_DEVICE_NOT_BOUNDED;
405
406         aura_req = mbox_alloc_msg_npa_aq_enq(lf->mbox);
407         if (aura_req == NULL)
408                 return -ENOMEM;
409         aura_req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
410         aura_req->ctype = NPA_AQ_CTYPE_AURA;
411         aura_req->op = NPA_AQ_INSTOP_WRITE;
412
413         aura_req->aura.limit = aura_limit;
414         aura_req->aura_mask.limit = ~(aura_req->aura_mask.limit);
415         rc = mbox_process(lf->mbox);
416
417         return rc;
418 }
419
420 static int
421 npa_aura_pool_pair_free(struct npa_lf *lf, uint64_t aura_handle)
422 {
423         char name[PLT_MEMZONE_NAMESIZE];
424         int aura_id, pool_id, rc;
425
426         if (!lf || !aura_handle)
427                 return NPA_ERR_PARAM;
428
429         aura_id = roc_npa_aura_handle_to_aura(aura_handle);
430         pool_id = aura_id;
431         rc = npa_aura_pool_fini(lf->mbox, aura_id, aura_handle);
432         rc |= npa_stack_dma_free(lf, name, pool_id);
433
434         plt_bitmap_set(lf->npa_bmp, aura_id);
435
436         return rc;
437 }
438
439 int
440 roc_npa_pool_destroy(uint64_t aura_handle)
441 {
442         struct npa_lf *lf = idev_npa_obj_get();
443         int rc = 0;
444
445         plt_npa_dbg("lf=%p aura_handle=0x%" PRIx64, lf, aura_handle);
446         rc = npa_aura_pool_pair_free(lf, aura_handle);
447         if (rc)
448                 plt_err("Failed to destroy pool or aura rc=%d", rc);
449
450         /* Release the reference of npa */
451         rc |= npa_lf_fini();
452         return rc;
453 }
454
455 int
456 roc_npa_pool_range_update_check(uint64_t aura_handle)
457 {
458         uint64_t aura_id = roc_npa_aura_handle_to_aura(aura_handle);
459         struct npa_lf *lf;
460         struct npa_aura_lim *lim;
461         __io struct npa_pool_s *pool;
462         struct npa_aq_enq_req *req;
463         struct npa_aq_enq_rsp *rsp;
464         int rc;
465
466         lf = idev_npa_obj_get();
467         if (lf == NULL)
468                 return NPA_ERR_PARAM;
469
470         lim = lf->aura_lim;
471
472         req = mbox_alloc_msg_npa_aq_enq(lf->mbox);
473         if (req == NULL)
474                 return -ENOSPC;
475
476         req->aura_id = aura_id;
477         req->ctype = NPA_AQ_CTYPE_POOL;
478         req->op = NPA_AQ_INSTOP_READ;
479
480         rc = mbox_process_msg(lf->mbox, (void *)&rsp);
481         if (rc) {
482                 plt_err("Failed to get pool(0x%" PRIx64 ") context", aura_id);
483                 return rc;
484         }
485
486         pool = &rsp->pool;
487         if (lim[aura_id].ptr_start != pool->ptr_start ||
488             lim[aura_id].ptr_end != pool->ptr_end) {
489                 plt_err("Range update failed on pool(0x%" PRIx64 ")", aura_id);
490                 return NPA_ERR_PARAM;
491         }
492
493         return 0;
494 }
495
496 static inline int
497 npa_attach(struct mbox *mbox)
498 {
499         struct rsrc_attach_req *req;
500
501         req = mbox_alloc_msg_attach_resources(mbox);
502         if (req == NULL)
503                 return -ENOSPC;
504         req->modify = true;
505         req->npalf = true;
506
507         return mbox_process(mbox);
508 }
509
510 static inline int
511 npa_detach(struct mbox *mbox)
512 {
513         struct rsrc_detach_req *req;
514
515         req = mbox_alloc_msg_detach_resources(mbox);
516         if (req == NULL)
517                 return -ENOSPC;
518         req->partial = true;
519         req->npalf = true;
520
521         return mbox_process(mbox);
522 }
523
524 static inline int
525 npa_get_msix_offset(struct mbox *mbox, uint16_t *npa_msixoff)
526 {
527         struct msix_offset_rsp *msix_rsp;
528         int rc;
529
530         /* Get NPA MSIX vector offsets */
531         mbox_alloc_msg_msix_offset(mbox);
532         rc = mbox_process_msg(mbox, (void *)&msix_rsp);
533         if (rc == 0)
534                 *npa_msixoff = msix_rsp->npa_msixoff;
535
536         return rc;
537 }
538
539 static inline int
540 npa_lf_alloc(struct npa_lf *lf)
541 {
542         struct mbox *mbox = lf->mbox;
543         struct npa_lf_alloc_req *req;
544         struct npa_lf_alloc_rsp *rsp;
545         int rc;
546
547         req = mbox_alloc_msg_npa_lf_alloc(mbox);
548         if (req == NULL)
549                 return -ENOSPC;
550         req->aura_sz = lf->aura_sz;
551         req->nr_pools = lf->nr_pools;
552
553         rc = mbox_process_msg(mbox, (void *)&rsp);
554         if (rc)
555                 return NPA_ERR_ALLOC;
556
557         lf->stack_pg_ptrs = rsp->stack_pg_ptrs;
558         lf->stack_pg_bytes = rsp->stack_pg_bytes;
559         lf->qints = rsp->qints;
560
561         return 0;
562 }
563
564 static int
565 npa_lf_free(struct mbox *mbox)
566 {
567         mbox_alloc_msg_npa_lf_free(mbox);
568         return mbox_process(mbox);
569 }
570
571 static inline uint32_t
572 aura_size_to_u32(uint8_t val)
573 {
574         if (val == NPA_AURA_SZ_0)
575                 return 128;
576         if (val >= NPA_AURA_SZ_MAX)
577                 return BIT_ULL(20);
578
579         return 1 << (val + 6);
580 }
581
582 static inline void
583 pool_count_aura_sz_get(uint32_t *nr_pools, uint8_t *aura_sz)
584 {
585         uint32_t val;
586
587         val = roc_idev_npa_maxpools_get();
588         if (val < aura_size_to_u32(NPA_AURA_SZ_128))
589                 val = 128;
590         if (val > aura_size_to_u32(NPA_AURA_SZ_1M))
591                 val = BIT_ULL(20);
592
593         roc_idev_npa_maxpools_set(val);
594         *nr_pools = val;
595         *aura_sz = plt_log2_u32(val) - 6;
596 }
597
598 static int
599 npa_dev_init(struct npa_lf *lf, uintptr_t base, struct mbox *mbox)
600 {
601         uint32_t i, bmp_sz, nr_pools;
602         uint8_t aura_sz;
603         int rc;
604
605         /* Sanity checks */
606         if (!lf || !base || !mbox)
607                 return NPA_ERR_PARAM;
608
609         if (base & ROC_AURA_ID_MASK)
610                 return NPA_ERR_BASE_INVALID;
611
612         pool_count_aura_sz_get(&nr_pools, &aura_sz);
613         if (aura_sz == NPA_AURA_SZ_0 || aura_sz >= NPA_AURA_SZ_MAX)
614                 return NPA_ERR_PARAM;
615
616         memset(lf, 0x0, sizeof(*lf));
617         lf->base = base;
618         lf->aura_sz = aura_sz;
619         lf->nr_pools = nr_pools;
620         lf->mbox = mbox;
621
622         rc = npa_lf_alloc(lf);
623         if (rc)
624                 goto exit;
625
626         bmp_sz = plt_bitmap_get_memory_footprint(nr_pools);
627
628         /* Allocate memory for bitmap */
629         lf->npa_bmp_mem = plt_zmalloc(bmp_sz, ROC_ALIGN);
630         if (lf->npa_bmp_mem == NULL) {
631                 rc = NPA_ERR_ALLOC;
632                 goto lf_free;
633         }
634
635         /* Initialize pool resource bitmap array */
636         lf->npa_bmp = plt_bitmap_init(nr_pools, lf->npa_bmp_mem, bmp_sz);
637         if (lf->npa_bmp == NULL) {
638                 rc = NPA_ERR_PARAM;
639                 goto bmap_mem_free;
640         }
641
642         /* Mark all pools available */
643         for (i = 0; i < nr_pools; i++)
644                 plt_bitmap_set(lf->npa_bmp, i);
645
646         /* Allocate memory for qint context */
647         lf->npa_qint_mem = plt_zmalloc(sizeof(struct npa_qint) * nr_pools, 0);
648         if (lf->npa_qint_mem == NULL) {
649                 rc = NPA_ERR_ALLOC;
650                 goto bmap_free;
651         }
652
653         /* Allocate memory for nap_aura_lim memory */
654         lf->aura_lim = plt_zmalloc(sizeof(struct npa_aura_lim) * nr_pools, 0);
655         if (lf->aura_lim == NULL) {
656                 rc = NPA_ERR_ALLOC;
657                 goto qint_free;
658         }
659
660         /* Init aura start & end limits */
661         for (i = 0; i < nr_pools; i++) {
662                 lf->aura_lim[i].ptr_start = UINT64_MAX;
663                 lf->aura_lim[i].ptr_end = 0x0ull;
664         }
665
666         return 0;
667
668 qint_free:
669         plt_free(lf->npa_qint_mem);
670 bmap_free:
671         plt_bitmap_free(lf->npa_bmp);
672 bmap_mem_free:
673         plt_free(lf->npa_bmp_mem);
674 lf_free:
675         npa_lf_free(lf->mbox);
676 exit:
677         return rc;
678 }
679
680 static int
681 npa_dev_fini(struct npa_lf *lf)
682 {
683         if (!lf)
684                 return NPA_ERR_PARAM;
685
686         plt_free(lf->aura_lim);
687         plt_free(lf->npa_qint_mem);
688         plt_bitmap_free(lf->npa_bmp);
689         plt_free(lf->npa_bmp_mem);
690
691         return npa_lf_free(lf->mbox);
692 }
693
694 int
695 npa_lf_init(struct dev *dev, struct plt_pci_device *pci_dev)
696 {
697         struct idev_cfg *idev;
698         uint16_t npa_msixoff;
699         struct npa_lf *lf;
700         int rc;
701
702         idev = idev_get_cfg();
703         if (idev == NULL)
704                 return NPA_ERR_ALLOC;
705
706         /* Not the first PCI device */
707         if (__atomic_fetch_add(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST) != 0)
708                 return 0;
709
710         if (lf_init_cb) {
711                 rc = (*lf_init_cb)(pci_dev);
712                 if (rc)
713                         goto fail;
714         }
715
716         rc = npa_attach(dev->mbox);
717         if (rc)
718                 goto fail;
719
720         rc = npa_get_msix_offset(dev->mbox, &npa_msixoff);
721         if (rc)
722                 goto npa_detach;
723
724         lf = &dev->npa;
725         rc = npa_dev_init(lf, dev->bar2 + (RVU_BLOCK_ADDR_NPA << 20),
726                           dev->mbox);
727         if (rc)
728                 goto npa_detach;
729
730         lf->pf_func = dev->pf_func;
731         lf->npa_msixoff = npa_msixoff;
732         lf->intr_handle = pci_dev->intr_handle;
733         lf->pci_dev = pci_dev;
734
735         idev->npa_pf_func = dev->pf_func;
736         idev->npa = lf;
737         plt_wmb();
738
739         rc = npa_register_irqs(lf);
740         if (rc)
741                 goto npa_fini;
742
743         plt_npa_dbg("npa=%p max_pools=%d pf_func=0x%x msix=0x%x", lf,
744                     roc_idev_npa_maxpools_get(), lf->pf_func, npa_msixoff);
745
746         return 0;
747
748 npa_fini:
749         npa_dev_fini(idev->npa);
750 npa_detach:
751         npa_detach(dev->mbox);
752 fail:
753         __atomic_fetch_sub(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST);
754         return rc;
755 }
756
757 int
758 npa_lf_fini(void)
759 {
760         struct idev_cfg *idev;
761         int rc = 0;
762
763         idev = idev_get_cfg();
764         if (idev == NULL)
765                 return NPA_ERR_ALLOC;
766
767         /* Not the last PCI device */
768         if (__atomic_sub_fetch(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST) != 0)
769                 return 0;
770
771         npa_unregister_irqs(idev->npa);
772         rc |= npa_dev_fini(idev->npa);
773         rc |= npa_detach(idev->npa->mbox);
774         idev_set_defaults(idev);
775
776         return rc;
777 }
778
779 int
780 roc_npa_dev_init(struct roc_npa *roc_npa)
781 {
782         struct plt_pci_device *pci_dev;
783         struct npa *npa;
784         struct dev *dev;
785         int rc;
786
787         if (roc_npa == NULL || roc_npa->pci_dev == NULL)
788                 return NPA_ERR_PARAM;
789
790         PLT_STATIC_ASSERT(sizeof(struct npa) <= ROC_NPA_MEM_SZ);
791         npa = roc_npa_to_npa_priv(roc_npa);
792         memset(npa, 0, sizeof(*npa));
793         pci_dev = roc_npa->pci_dev;
794         dev = &npa->dev;
795
796         /* Initialize device  */
797         rc = dev_init(dev, pci_dev);
798         if (rc) {
799                 plt_err("Failed to init roc device");
800                 goto fail;
801         }
802
803         npa->pci_dev = pci_dev;
804         dev->drv_inited = true;
805 fail:
806         return rc;
807 }
808
809 int
810 roc_npa_dev_fini(struct roc_npa *roc_npa)
811 {
812         struct npa *npa = roc_npa_to_npa_priv(roc_npa);
813
814         if (npa == NULL)
815                 return NPA_ERR_PARAM;
816
817         npa->dev.drv_inited = false;
818         return dev_fini(&npa->dev, npa->pci_dev);
819 }