common/cnxk: support CPT CTX sync mailbox
[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
209         return plt_memzone_reserve_aligned(mz_name, size, 0, ROC_ALIGN);
210 }
211
212 static inline int
213 npa_stack_dma_free(struct npa_lf *lf, char *name, int pool_id)
214 {
215         const struct plt_memzone *mz;
216
217         mz = plt_memzone_lookup(npa_stack_memzone_name(lf, pool_id, name));
218         if (mz == NULL)
219                 return NPA_ERR_PARAM;
220
221         return plt_memzone_free(mz);
222 }
223
224 static inline int
225 bitmap_ctzll(uint64_t slab)
226 {
227         if (slab == 0)
228                 return 0;
229
230         return __builtin_ctzll(slab);
231 }
232
233 static int
234 npa_aura_pool_pair_alloc(struct npa_lf *lf, const uint32_t block_size,
235                          const uint32_t block_count, struct npa_aura_s *aura,
236                          struct npa_pool_s *pool, uint64_t *aura_handle)
237 {
238         int rc, aura_id, pool_id, stack_size, alloc_size;
239         char name[PLT_MEMZONE_NAMESIZE];
240         const struct plt_memzone *mz;
241         uint64_t slab;
242         uint32_t pos;
243
244         /* Sanity check */
245         if (!lf || !block_size || !block_count || !pool || !aura ||
246             !aura_handle)
247                 return NPA_ERR_PARAM;
248
249         /* Block size should be cache line aligned and in range of 128B-128KB */
250         if (block_size % ROC_ALIGN || block_size < 128 ||
251             block_size > ROC_NPA_MAX_BLOCK_SZ)
252                 return NPA_ERR_INVALID_BLOCK_SZ;
253
254         pos = 0;
255         slab = 0;
256         /* Scan from the beginning */
257         plt_bitmap_scan_init(lf->npa_bmp);
258         /* Scan bitmap to get the free pool */
259         rc = plt_bitmap_scan(lf->npa_bmp, &pos, &slab);
260         /* Empty bitmap */
261         if (rc == 0) {
262                 plt_err("Mempools exhausted");
263                 return NPA_ERR_AURA_ID_ALLOC;
264         }
265
266         /* Get aura_id from resource bitmap */
267         aura_id = pos + bitmap_ctzll(slab);
268         /* Mark pool as reserved */
269         plt_bitmap_clear(lf->npa_bmp, aura_id);
270
271         /* Configuration based on each aura has separate pool(aura-pool pair) */
272         pool_id = aura_id;
273         rc = (aura_id < 0 || pool_id >= (int)lf->nr_pools ||
274               aura_id >= (int)BIT_ULL(6 + lf->aura_sz)) ?
275                            NPA_ERR_AURA_ID_ALLOC :
276                            0;
277         if (rc)
278                 goto exit;
279
280         /* Allocate stack memory */
281         stack_size = (block_count + lf->stack_pg_ptrs - 1) / lf->stack_pg_ptrs;
282         alloc_size = stack_size * lf->stack_pg_bytes;
283
284         mz = npa_stack_dma_alloc(lf, name, pool_id, alloc_size);
285         if (mz == NULL) {
286                 rc = NPA_ERR_ALLOC;
287                 goto aura_res_put;
288         }
289
290         /* Update aura fields */
291         aura->pool_addr = pool_id; /* AF will translate to associated poolctx */
292         aura->ena = 1;
293         aura->shift = plt_log2_u32(block_count);
294         aura->shift = aura->shift < 8 ? 0 : aura->shift - 8;
295         aura->limit = block_count;
296         aura->pool_caching = 1;
297         aura->err_int_ena = BIT(NPA_AURA_ERR_INT_AURA_ADD_OVER);
298         aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_AURA_ADD_UNDER);
299         aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_AURA_FREE_UNDER);
300         aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_POOL_DIS);
301         aura->avg_con = ROC_NPA_AVG_CONT;
302         /* Many to one reduction */
303         aura->err_qint_idx = aura_id % lf->qints;
304
305         /* Update pool fields */
306         pool->stack_base = mz->iova;
307         pool->ena = 1;
308         pool->buf_size = block_size / ROC_ALIGN;
309         pool->stack_max_pages = stack_size;
310         pool->shift = plt_log2_u32(block_count);
311         pool->shift = pool->shift < 8 ? 0 : pool->shift - 8;
312         pool->ptr_start = 0;
313         pool->ptr_end = ~0;
314         pool->stack_caching = 1;
315         pool->err_int_ena = BIT(NPA_POOL_ERR_INT_OVFLS);
316         pool->err_int_ena |= BIT(NPA_POOL_ERR_INT_RANGE);
317         pool->err_int_ena |= BIT(NPA_POOL_ERR_INT_PERR);
318         pool->avg_con = ROC_NPA_AVG_CONT;
319
320         /* Many to one reduction */
321         pool->err_qint_idx = pool_id % lf->qints;
322
323         /* Issue AURA_INIT and POOL_INIT op */
324         rc = npa_aura_pool_init(lf->mbox, aura_id, aura, pool);
325         if (rc)
326                 goto stack_mem_free;
327
328         *aura_handle = roc_npa_aura_handle_gen(aura_id, lf->base);
329         /* Update aura count */
330         roc_npa_aura_op_cnt_set(*aura_handle, 0, block_count);
331         /* Read it back to make sure aura count is updated */
332         roc_npa_aura_op_cnt_get(*aura_handle);
333
334         return 0;
335
336 stack_mem_free:
337         plt_memzone_free(mz);
338 aura_res_put:
339         plt_bitmap_set(lf->npa_bmp, aura_id);
340 exit:
341         return rc;
342 }
343
344 int
345 roc_npa_pool_create(uint64_t *aura_handle, uint32_t block_size,
346                     uint32_t block_count, struct npa_aura_s *aura,
347                     struct npa_pool_s *pool)
348 {
349         struct npa_aura_s defaura;
350         struct npa_pool_s defpool;
351         struct idev_cfg *idev;
352         struct npa_lf *lf;
353         int rc;
354
355         lf = idev_npa_obj_get();
356         if (lf == NULL) {
357                 rc = NPA_ERR_DEVICE_NOT_BOUNDED;
358                 goto error;
359         }
360
361         idev = idev_get_cfg();
362         if (idev == NULL) {
363                 rc = NPA_ERR_ALLOC;
364                 goto error;
365         }
366
367         if (aura == NULL) {
368                 memset(&defaura, 0, sizeof(struct npa_aura_s));
369                 aura = &defaura;
370         }
371         if (pool == NULL) {
372                 memset(&defpool, 0, sizeof(struct npa_pool_s));
373                 defpool.nat_align = 1;
374                 defpool.buf_offset = 1;
375                 pool = &defpool;
376         }
377
378         rc = npa_aura_pool_pair_alloc(lf, block_size, block_count, aura, pool,
379                                       aura_handle);
380         if (rc) {
381                 plt_err("Failed to alloc pool or aura rc=%d", rc);
382                 goto error;
383         }
384
385         plt_npa_dbg("lf=%p block_sz=%d block_count=%d aura_handle=0x%" PRIx64,
386                     lf, block_size, block_count, *aura_handle);
387
388         /* Just hold the reference of the object */
389         __atomic_fetch_add(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST);
390 error:
391         return rc;
392 }
393
394 int
395 roc_npa_aura_limit_modify(uint64_t aura_handle, uint16_t aura_limit)
396 {
397         struct npa_aq_enq_req *aura_req;
398         struct npa_lf *lf;
399         int rc;
400
401         lf = idev_npa_obj_get();
402         if (lf == NULL)
403                 return NPA_ERR_DEVICE_NOT_BOUNDED;
404
405         aura_req = mbox_alloc_msg_npa_aq_enq(lf->mbox);
406         if (aura_req == NULL)
407                 return -ENOMEM;
408         aura_req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
409         aura_req->ctype = NPA_AQ_CTYPE_AURA;
410         aura_req->op = NPA_AQ_INSTOP_WRITE;
411
412         aura_req->aura.limit = aura_limit;
413         aura_req->aura_mask.limit = ~(aura_req->aura_mask.limit);
414         rc = mbox_process(lf->mbox);
415
416         return rc;
417 }
418
419 static int
420 npa_aura_pool_pair_free(struct npa_lf *lf, uint64_t aura_handle)
421 {
422         char name[PLT_MEMZONE_NAMESIZE];
423         int aura_id, pool_id, rc;
424
425         if (!lf || !aura_handle)
426                 return NPA_ERR_PARAM;
427
428         aura_id = roc_npa_aura_handle_to_aura(aura_handle);
429         pool_id = aura_id;
430         rc = npa_aura_pool_fini(lf->mbox, aura_id, aura_handle);
431         rc |= npa_stack_dma_free(lf, name, pool_id);
432
433         plt_bitmap_set(lf->npa_bmp, aura_id);
434
435         return rc;
436 }
437
438 int
439 roc_npa_pool_destroy(uint64_t aura_handle)
440 {
441         struct npa_lf *lf = idev_npa_obj_get();
442         int rc = 0;
443
444         plt_npa_dbg("lf=%p aura_handle=0x%" PRIx64, lf, aura_handle);
445         rc = npa_aura_pool_pair_free(lf, aura_handle);
446         if (rc)
447                 plt_err("Failed to destroy pool or aura rc=%d", rc);
448
449         /* Release the reference of npa */
450         rc |= npa_lf_fini();
451         return rc;
452 }
453
454 int
455 roc_npa_pool_range_update_check(uint64_t aura_handle)
456 {
457         uint64_t aura_id = roc_npa_aura_handle_to_aura(aura_handle);
458         struct npa_lf *lf;
459         struct npa_aura_lim *lim;
460         __io struct npa_pool_s *pool;
461         struct npa_aq_enq_req *req;
462         struct npa_aq_enq_rsp *rsp;
463         int rc;
464
465         lf = idev_npa_obj_get();
466         if (lf == NULL)
467                 return NPA_ERR_PARAM;
468
469         lim = lf->aura_lim;
470
471         req = mbox_alloc_msg_npa_aq_enq(lf->mbox);
472         if (req == NULL)
473                 return -ENOSPC;
474
475         req->aura_id = aura_id;
476         req->ctype = NPA_AQ_CTYPE_POOL;
477         req->op = NPA_AQ_INSTOP_READ;
478
479         rc = mbox_process_msg(lf->mbox, (void *)&rsp);
480         if (rc) {
481                 plt_err("Failed to get pool(0x%" PRIx64 ") context", aura_id);
482                 return rc;
483         }
484
485         pool = &rsp->pool;
486         if (lim[aura_id].ptr_start != pool->ptr_start ||
487             lim[aura_id].ptr_end != pool->ptr_end) {
488                 plt_err("Range update failed on pool(0x%" PRIx64 ")", aura_id);
489                 return NPA_ERR_PARAM;
490         }
491
492         return 0;
493 }
494
495 static inline int
496 npa_attach(struct mbox *mbox)
497 {
498         struct rsrc_attach_req *req;
499
500         req = mbox_alloc_msg_attach_resources(mbox);
501         if (req == NULL)
502                 return -ENOSPC;
503         req->modify = true;
504         req->npalf = true;
505
506         return mbox_process(mbox);
507 }
508
509 static inline int
510 npa_detach(struct mbox *mbox)
511 {
512         struct rsrc_detach_req *req;
513
514         req = mbox_alloc_msg_detach_resources(mbox);
515         if (req == NULL)
516                 return -ENOSPC;
517         req->partial = true;
518         req->npalf = true;
519
520         return mbox_process(mbox);
521 }
522
523 static inline int
524 npa_get_msix_offset(struct mbox *mbox, uint16_t *npa_msixoff)
525 {
526         struct msix_offset_rsp *msix_rsp;
527         int rc;
528
529         /* Get NPA MSIX vector offsets */
530         mbox_alloc_msg_msix_offset(mbox);
531         rc = mbox_process_msg(mbox, (void *)&msix_rsp);
532         if (rc == 0)
533                 *npa_msixoff = msix_rsp->npa_msixoff;
534
535         return rc;
536 }
537
538 static inline int
539 npa_lf_alloc(struct npa_lf *lf)
540 {
541         struct mbox *mbox = lf->mbox;
542         struct npa_lf_alloc_req *req;
543         struct npa_lf_alloc_rsp *rsp;
544         int rc;
545
546         req = mbox_alloc_msg_npa_lf_alloc(mbox);
547         if (req == NULL)
548                 return -ENOSPC;
549         req->aura_sz = lf->aura_sz;
550         req->nr_pools = lf->nr_pools;
551
552         rc = mbox_process_msg(mbox, (void *)&rsp);
553         if (rc)
554                 return NPA_ERR_ALLOC;
555
556         lf->stack_pg_ptrs = rsp->stack_pg_ptrs;
557         lf->stack_pg_bytes = rsp->stack_pg_bytes;
558         lf->qints = rsp->qints;
559
560         return 0;
561 }
562
563 static int
564 npa_lf_free(struct mbox *mbox)
565 {
566         mbox_alloc_msg_npa_lf_free(mbox);
567         return mbox_process(mbox);
568 }
569
570 static inline uint32_t
571 aura_size_to_u32(uint8_t val)
572 {
573         if (val == NPA_AURA_SZ_0)
574                 return 128;
575         if (val >= NPA_AURA_SZ_MAX)
576                 return BIT_ULL(20);
577
578         return 1 << (val + 6);
579 }
580
581 static inline void
582 pool_count_aura_sz_get(uint32_t *nr_pools, uint8_t *aura_sz)
583 {
584         uint32_t val;
585
586         val = roc_idev_npa_maxpools_get();
587         if (val < aura_size_to_u32(NPA_AURA_SZ_128))
588                 val = 128;
589         if (val > aura_size_to_u32(NPA_AURA_SZ_1M))
590                 val = BIT_ULL(20);
591
592         roc_idev_npa_maxpools_set(val);
593         *nr_pools = val;
594         *aura_sz = plt_log2_u32(val) - 6;
595 }
596
597 static int
598 npa_dev_init(struct npa_lf *lf, uintptr_t base, struct mbox *mbox)
599 {
600         uint32_t i, bmp_sz, nr_pools;
601         uint8_t aura_sz;
602         int rc;
603
604         /* Sanity checks */
605         if (!lf || !base || !mbox)
606                 return NPA_ERR_PARAM;
607
608         if (base & ROC_AURA_ID_MASK)
609                 return NPA_ERR_BASE_INVALID;
610
611         pool_count_aura_sz_get(&nr_pools, &aura_sz);
612         if (aura_sz == NPA_AURA_SZ_0 || aura_sz >= NPA_AURA_SZ_MAX)
613                 return NPA_ERR_PARAM;
614
615         memset(lf, 0x0, sizeof(*lf));
616         lf->base = base;
617         lf->aura_sz = aura_sz;
618         lf->nr_pools = nr_pools;
619         lf->mbox = mbox;
620
621         rc = npa_lf_alloc(lf);
622         if (rc)
623                 goto exit;
624
625         bmp_sz = plt_bitmap_get_memory_footprint(nr_pools);
626
627         /* Allocate memory for bitmap */
628         lf->npa_bmp_mem = plt_zmalloc(bmp_sz, ROC_ALIGN);
629         if (lf->npa_bmp_mem == NULL) {
630                 rc = NPA_ERR_ALLOC;
631                 goto lf_free;
632         }
633
634         /* Initialize pool resource bitmap array */
635         lf->npa_bmp = plt_bitmap_init(nr_pools, lf->npa_bmp_mem, bmp_sz);
636         if (lf->npa_bmp == NULL) {
637                 rc = NPA_ERR_PARAM;
638                 goto bmap_mem_free;
639         }
640
641         /* Mark all pools available */
642         for (i = 0; i < nr_pools; i++)
643                 plt_bitmap_set(lf->npa_bmp, i);
644
645         /* Allocate memory for qint context */
646         lf->npa_qint_mem = plt_zmalloc(sizeof(struct npa_qint) * nr_pools, 0);
647         if (lf->npa_qint_mem == NULL) {
648                 rc = NPA_ERR_ALLOC;
649                 goto bmap_free;
650         }
651
652         /* Allocate memory for nap_aura_lim memory */
653         lf->aura_lim = plt_zmalloc(sizeof(struct npa_aura_lim) * nr_pools, 0);
654         if (lf->aura_lim == NULL) {
655                 rc = NPA_ERR_ALLOC;
656                 goto qint_free;
657         }
658
659         /* Init aura start & end limits */
660         for (i = 0; i < nr_pools; i++) {
661                 lf->aura_lim[i].ptr_start = UINT64_MAX;
662                 lf->aura_lim[i].ptr_end = 0x0ull;
663         }
664
665         return 0;
666
667 qint_free:
668         plt_free(lf->npa_qint_mem);
669 bmap_free:
670         plt_bitmap_free(lf->npa_bmp);
671 bmap_mem_free:
672         plt_free(lf->npa_bmp_mem);
673 lf_free:
674         npa_lf_free(lf->mbox);
675 exit:
676         return rc;
677 }
678
679 static int
680 npa_dev_fini(struct npa_lf *lf)
681 {
682         if (!lf)
683                 return NPA_ERR_PARAM;
684
685         plt_free(lf->aura_lim);
686         plt_free(lf->npa_qint_mem);
687         plt_bitmap_free(lf->npa_bmp);
688         plt_free(lf->npa_bmp_mem);
689
690         return npa_lf_free(lf->mbox);
691 }
692
693 int
694 npa_lf_init(struct dev *dev, struct plt_pci_device *pci_dev)
695 {
696         struct idev_cfg *idev;
697         uint16_t npa_msixoff;
698         struct npa_lf *lf;
699         int rc;
700
701         idev = idev_get_cfg();
702         if (idev == NULL)
703                 return NPA_ERR_ALLOC;
704
705         /* Not the first PCI device */
706         if (__atomic_fetch_add(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST) != 0)
707                 return 0;
708
709         if (lf_init_cb) {
710                 rc = (*lf_init_cb)(pci_dev);
711                 if (rc)
712                         goto fail;
713         }
714
715         rc = npa_attach(dev->mbox);
716         if (rc)
717                 goto fail;
718
719         rc = npa_get_msix_offset(dev->mbox, &npa_msixoff);
720         if (rc)
721                 goto npa_detach;
722
723         lf = &dev->npa;
724         rc = npa_dev_init(lf, dev->bar2 + (RVU_BLOCK_ADDR_NPA << 20),
725                           dev->mbox);
726         if (rc)
727                 goto npa_detach;
728
729         lf->pf_func = dev->pf_func;
730         lf->npa_msixoff = npa_msixoff;
731         lf->intr_handle = pci_dev->intr_handle;
732         lf->pci_dev = pci_dev;
733
734         idev->npa_pf_func = dev->pf_func;
735         idev->npa = lf;
736         plt_wmb();
737
738         rc = npa_register_irqs(lf);
739         if (rc)
740                 goto npa_fini;
741
742         plt_npa_dbg("npa=%p max_pools=%d pf_func=0x%x msix=0x%x", lf,
743                     roc_idev_npa_maxpools_get(), lf->pf_func, npa_msixoff);
744
745         return 0;
746
747 npa_fini:
748         npa_dev_fini(idev->npa);
749 npa_detach:
750         npa_detach(dev->mbox);
751 fail:
752         __atomic_fetch_sub(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST);
753         return rc;
754 }
755
756 int
757 npa_lf_fini(void)
758 {
759         struct idev_cfg *idev;
760         int rc = 0;
761
762         idev = idev_get_cfg();
763         if (idev == NULL)
764                 return NPA_ERR_ALLOC;
765
766         /* Not the last PCI device */
767         if (__atomic_sub_fetch(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST) != 0)
768                 return 0;
769
770         npa_unregister_irqs(idev->npa);
771         rc |= npa_dev_fini(idev->npa);
772         rc |= npa_detach(idev->npa->mbox);
773         idev_set_defaults(idev);
774
775         return rc;
776 }
777
778 int
779 roc_npa_dev_init(struct roc_npa *roc_npa)
780 {
781         struct plt_pci_device *pci_dev;
782         struct npa *npa;
783         struct dev *dev;
784         int rc;
785
786         if (roc_npa == NULL || roc_npa->pci_dev == NULL)
787                 return NPA_ERR_PARAM;
788
789         PLT_STATIC_ASSERT(sizeof(struct npa) <= ROC_NPA_MEM_SZ);
790         npa = roc_npa_to_npa_priv(roc_npa);
791         memset(npa, 0, sizeof(*npa));
792         pci_dev = roc_npa->pci_dev;
793         dev = &npa->dev;
794
795         /* Initialize device  */
796         rc = dev_init(dev, pci_dev);
797         if (rc) {
798                 plt_err("Failed to init roc device");
799                 goto fail;
800         }
801
802         npa->pci_dev = pci_dev;
803         dev->drv_inited = true;
804 fail:
805         return rc;
806 }
807
808 int
809 roc_npa_dev_fini(struct roc_npa *roc_npa)
810 {
811         struct npa *npa = roc_npa_to_npa_priv(roc_npa);
812
813         if (npa == NULL)
814                 return NPA_ERR_PARAM;
815
816         npa->dev.drv_inited = false;
817         return dev_fini(&npa->dev, npa->pci_dev);
818 }