common/cnxk: support waiting for pool filling
[dpdk.git] / drivers / common / cnxk / roc_npa.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4
5 #ifndef _ROC_NPA_H_
6 #define _ROC_NPA_H_
7
8 #define ROC_AURA_ID_MASK       (BIT_ULL(16) - 1)
9 #define ROC_AURA_OP_LIMIT_MASK (BIT_ULL(36) - 1)
10
11 #define ROC_NPA_MAX_BLOCK_SZ               (128 * 1024)
12 #define ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS 512
13 #define ROC_CN10K_NPA_BATCH_FREE_MAX_PTRS  15
14
15 /* This value controls how much of the present average resource level is used to
16  * calculate the new resource level.
17  */
18 #define ROC_NPA_AVG_CONT 0xE0
19
20 /* 16 CASP instructions can be outstanding in CN9k, but we use only 15
21  * outstanding CASPs as we run out of registers.
22  */
23 #define ROC_CN9K_NPA_BULK_ALLOC_MAX_PTRS 30
24
25 /*
26  * Generate 64bit handle to have optimized alloc and free aura operation.
27  * 0 - ROC_AURA_ID_MASK for storing the aura_id.
28  * [ROC_AURA_ID_MASK+1, (2^64 - 1)] for storing the lf base address.
29  * This scheme is valid when OS can give ROC_AURA_ID_MASK
30  * aligned address for lf base address.
31  */
32 static inline uint64_t
33 roc_npa_aura_handle_gen(uint32_t aura_id, uintptr_t addr)
34 {
35         uint64_t val;
36
37         val = aura_id & ROC_AURA_ID_MASK;
38         return (uint64_t)addr | val;
39 }
40
41 static inline uint64_t
42 roc_npa_aura_handle_to_aura(uint64_t aura_handle)
43 {
44         return aura_handle & ROC_AURA_ID_MASK;
45 }
46
47 static inline uintptr_t
48 roc_npa_aura_handle_to_base(uint64_t aura_handle)
49 {
50         return (uintptr_t)(aura_handle & ~ROC_AURA_ID_MASK);
51 }
52
53 static inline uint64_t
54 roc_npa_aura_op_alloc(uint64_t aura_handle, const int drop)
55 {
56         uint64_t wdata = roc_npa_aura_handle_to_aura(aura_handle);
57         int64_t *addr;
58
59         if (drop)
60                 wdata |= BIT_ULL(63); /* DROP */
61
62         addr = (int64_t *)(roc_npa_aura_handle_to_base(aura_handle) +
63                            NPA_LF_AURA_OP_ALLOCX(0));
64         return roc_atomic64_add_nosync(wdata, addr);
65 }
66
67 static inline void
68 roc_npa_aura_op_free(uint64_t aura_handle, const int fabs, uint64_t iova)
69 {
70         uint64_t reg = roc_npa_aura_handle_to_aura(aura_handle);
71         const uint64_t addr =
72                 roc_npa_aura_handle_to_base(aura_handle) + NPA_LF_AURA_OP_FREE0;
73         if (fabs)
74                 reg |= BIT_ULL(63); /* FABS */
75
76         roc_store_pair(iova, reg, addr);
77 }
78
79 static inline uint64_t
80 roc_npa_aura_op_cnt_get(uint64_t aura_handle)
81 {
82         uint64_t wdata;
83         int64_t *addr;
84         uint64_t reg;
85
86         wdata = roc_npa_aura_handle_to_aura(aura_handle) << 44;
87         addr = (int64_t *)(roc_npa_aura_handle_to_base(aura_handle) +
88                            NPA_LF_AURA_OP_CNT);
89         reg = roc_atomic64_add_nosync(wdata, addr);
90
91         if (reg & BIT_ULL(42) /* OP_ERR */)
92                 return 0;
93         else
94                 return reg & 0xFFFFFFFFF;
95 }
96
97 static inline void
98 roc_npa_aura_op_cnt_set(uint64_t aura_handle, const int sign, uint64_t count)
99 {
100         uint64_t reg = count & (BIT_ULL(36) - 1);
101
102         if (sign)
103                 reg |= BIT_ULL(43); /* CNT_ADD */
104
105         reg |= (roc_npa_aura_handle_to_aura(aura_handle) << 44);
106
107         plt_write64(reg, roc_npa_aura_handle_to_base(aura_handle) +
108                                  NPA_LF_AURA_OP_CNT);
109 }
110
111 static inline uint64_t
112 roc_npa_aura_op_limit_get(uint64_t aura_handle)
113 {
114         uint64_t wdata;
115         int64_t *addr;
116         uint64_t reg;
117
118         wdata = roc_npa_aura_handle_to_aura(aura_handle) << 44;
119         addr = (int64_t *)(roc_npa_aura_handle_to_base(aura_handle) +
120                            NPA_LF_AURA_OP_LIMIT);
121         reg = roc_atomic64_add_nosync(wdata, addr);
122
123         if (reg & BIT_ULL(42) /* OP_ERR */)
124                 return 0;
125         else
126                 return reg & ROC_AURA_OP_LIMIT_MASK;
127 }
128
129 static inline void
130 roc_npa_aura_op_limit_set(uint64_t aura_handle, uint64_t limit)
131 {
132         uint64_t reg = limit & ROC_AURA_OP_LIMIT_MASK;
133
134         reg |= (roc_npa_aura_handle_to_aura(aura_handle) << 44);
135
136         plt_write64(reg, roc_npa_aura_handle_to_base(aura_handle) +
137                                  NPA_LF_AURA_OP_LIMIT);
138 }
139
140 static inline uint64_t
141 roc_npa_aura_op_available(uint64_t aura_handle)
142 {
143         uint64_t wdata;
144         uint64_t reg;
145         int64_t *addr;
146
147         wdata = roc_npa_aura_handle_to_aura(aura_handle) << 44;
148         addr = (int64_t *)(roc_npa_aura_handle_to_base(aura_handle) +
149                            NPA_LF_POOL_OP_AVAILABLE);
150         reg = roc_atomic64_add_nosync(wdata, addr);
151
152         if (reg & BIT_ULL(42) /* OP_ERR */)
153                 return 0;
154         else
155                 return reg & 0xFFFFFFFFF;
156 }
157
158 /* Wait for a given timeout, repeatedly checking whether the available
159  * pointers has reached the given count. Returns the available pointer
160  * count if it has reached the given count or if timeout has expired
161  */
162 static inline uint32_t
163 roc_npa_aura_op_available_wait(uint64_t aura_handle, uint32_t count,
164                                uint32_t tmo_ms)
165 {
166 #define OP_AVAIL_WAIT_MS_DEFAULT   (100)
167 #define OP_AVAIL_CHECK_INTERVAL_MS (1)
168         uint32_t op_avail;
169         int retry;
170
171         tmo_ms = tmo_ms ? tmo_ms : OP_AVAIL_WAIT_MS_DEFAULT;
172
173         retry = tmo_ms / OP_AVAIL_CHECK_INTERVAL_MS;
174         op_avail = roc_npa_aura_op_available(aura_handle);
175         while (retry && (op_avail < count)) {
176                 plt_delay_ms(OP_AVAIL_CHECK_INTERVAL_MS);
177                 op_avail = roc_npa_aura_op_available(aura_handle);
178                 retry--;
179         }
180
181         return op_avail;
182 }
183
184 static inline uint64_t
185 roc_npa_pool_op_performance_counter(uint64_t aura_handle, const int drop)
186 {
187         union {
188                 uint64_t u;
189                 struct npa_aura_op_wdata_s s;
190         } op_wdata;
191         int64_t *addr;
192         uint64_t reg;
193
194         op_wdata.u = 0;
195         op_wdata.s.aura = roc_npa_aura_handle_to_aura(aura_handle);
196         if (drop)
197                 op_wdata.s.drop |= BIT_ULL(63); /* DROP */
198
199         addr = (int64_t *)(roc_npa_aura_handle_to_base(aura_handle) +
200                            NPA_LF_POOL_OP_PC);
201
202         reg = roc_atomic64_add_nosync(op_wdata.u, addr);
203         /*
204          * NPA_LF_POOL_OP_PC Read Data
205          *
206          * 63       49 48    48 47     0
207          * -----------------------------
208          * | Reserved | OP_ERR | OP_PC |
209          * -----------------------------
210          */
211
212         if (reg & BIT_ULL(48) /* OP_ERR */)
213                 return 0;
214         else
215                 return reg & 0xFFFFFFFFFFFF;
216 }
217
218 static inline int
219 roc_npa_aura_batch_alloc_issue(uint64_t aura_handle, uint64_t *buf,
220                                unsigned int num, const int dis_wait,
221                                const int drop)
222 {
223         unsigned int i;
224         int64_t *addr;
225         uint64_t res;
226         union {
227                 uint64_t u;
228                 struct npa_batch_alloc_compare_s compare_s;
229         } cmp;
230
231         if (num > ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS)
232                 return -1;
233
234         /* Zero first word of every cache line */
235         for (i = 0; i < num; i += (ROC_ALIGN / sizeof(uint64_t)))
236                 buf[i] = 0;
237
238         addr = (int64_t *)(roc_npa_aura_handle_to_base(aura_handle) +
239                            NPA_LF_AURA_BATCH_ALLOC);
240         cmp.u = 0;
241         cmp.compare_s.aura = roc_npa_aura_handle_to_aura(aura_handle);
242         cmp.compare_s.drop = drop;
243         cmp.compare_s.stype = ALLOC_STYPE_STF;
244         cmp.compare_s.dis_wait = dis_wait;
245         cmp.compare_s.count = num;
246
247         res = roc_atomic64_casl(cmp.u, (uint64_t)buf, addr);
248         if (res != ALLOC_RESULT_ACCEPTED && res != ALLOC_RESULT_NOCORE)
249                 return -1;
250
251         return 0;
252 }
253
254 static inline void
255 roc_npa_batch_alloc_wait(uint64_t *cache_line)
256 {
257         /* Batch alloc status code is updated in bits [5:6] of the first word
258          * of the 128 byte cache line.
259          */
260         while (((__atomic_load_n(cache_line, __ATOMIC_RELAXED) >> 5) & 0x3) ==
261                ALLOC_CCODE_INVAL)
262                 ;
263 }
264
265 static inline unsigned int
266 roc_npa_aura_batch_alloc_count(uint64_t *aligned_buf, unsigned int num)
267 {
268         unsigned int count, i;
269
270         if (num > ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS)
271                 return 0;
272
273         count = 0;
274         /* Check each ROC cache line one by one */
275         for (i = 0; i < num; i += (ROC_ALIGN >> 3)) {
276                 struct npa_batch_alloc_status_s *status;
277
278                 status = (struct npa_batch_alloc_status_s *)&aligned_buf[i];
279
280                 roc_npa_batch_alloc_wait(&aligned_buf[i]);
281                 count += status->count;
282         }
283
284         return count;
285 }
286
287 static inline unsigned int
288 roc_npa_aura_batch_alloc_extract(uint64_t *buf, uint64_t *aligned_buf,
289                                  unsigned int num)
290 {
291         unsigned int count, i;
292
293         if (num > ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS)
294                 return 0;
295
296         count = 0;
297         /* Check each ROC cache line one by one */
298         for (i = 0; i < num; i += (ROC_ALIGN >> 3)) {
299                 struct npa_batch_alloc_status_s *status;
300                 int line_count;
301
302                 status = (struct npa_batch_alloc_status_s *)&aligned_buf[i];
303
304                 roc_npa_batch_alloc_wait(&aligned_buf[i]);
305
306                 line_count = status->count;
307
308                 /* Clear the status from the cache line */
309                 status->ccode = 0;
310                 status->count = 0;
311
312                 /* 'Compress' the allocated buffers as there can
313                  * be 'holes' at the end of the 128 byte cache
314                  * lines.
315                  */
316                 memmove(&buf[count], &aligned_buf[i],
317                         line_count * sizeof(uint64_t));
318
319                 count += line_count;
320         }
321
322         return count;
323 }
324
325 static inline void
326 roc_npa_aura_op_bulk_free(uint64_t aura_handle, uint64_t const *buf,
327                           unsigned int num, const int fabs)
328 {
329         unsigned int i;
330
331         for (i = 0; i < num; i++) {
332                 const uint64_t inbuf = buf[i];
333
334                 roc_npa_aura_op_free(aura_handle, fabs, inbuf);
335         }
336 }
337
338 static inline unsigned int
339 roc_npa_aura_op_batch_alloc(uint64_t aura_handle, uint64_t *buf,
340                             uint64_t *aligned_buf, unsigned int num,
341                             const int dis_wait, const int drop,
342                             const int partial)
343 {
344         unsigned int count, chunk, num_alloc;
345
346         /* The buffer should be 128 byte cache line aligned */
347         if (((uint64_t)aligned_buf & (ROC_ALIGN - 1)) != 0)
348                 return 0;
349
350         count = 0;
351         while (num) {
352                 chunk = (num > ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS) ?
353                                       ROC_CN10K_NPA_BATCH_ALLOC_MAX_PTRS :
354                                       num;
355
356                 if (roc_npa_aura_batch_alloc_issue(aura_handle, aligned_buf,
357                                                    chunk, dis_wait, drop))
358                         break;
359
360                 num_alloc = roc_npa_aura_batch_alloc_extract(buf, aligned_buf,
361                                                              chunk);
362
363                 count += num_alloc;
364                 buf += num_alloc;
365                 num -= num_alloc;
366
367                 if (num_alloc != chunk)
368                         break;
369         }
370
371         /* If the requested number of pointers was not allocated and if partial
372          * alloc is not desired, then free allocated pointers.
373          */
374         if (unlikely(num != 0 && !partial)) {
375                 roc_npa_aura_op_bulk_free(aura_handle, buf - count, count, 1);
376                 count = 0;
377         }
378
379         return count;
380 }
381
382 static inline void
383 roc_npa_aura_batch_free(uint64_t aura_handle, uint64_t const *buf,
384                         unsigned int num, const int fabs, uint64_t lmt_addr,
385                         uint64_t lmt_id)
386 {
387         uint64_t addr, tar_addr, free0;
388         volatile uint64_t *lmt_data;
389         unsigned int i;
390
391         if (num > ROC_CN10K_NPA_BATCH_FREE_MAX_PTRS)
392                 return;
393
394         lmt_data = (uint64_t *)lmt_addr;
395
396         addr = roc_npa_aura_handle_to_base(aura_handle) +
397                NPA_LF_AURA_BATCH_FREE0;
398
399         /*
400          * NPA_LF_AURA_BATCH_FREE0
401          *
402          * 63   63 62  33 32       32 31  20 19    0
403          * -----------------------------------------
404          * | FABS | Rsvd | COUNT_EOT | Rsvd | AURA |
405          * -----------------------------------------
406          */
407         free0 = roc_npa_aura_handle_to_aura(aura_handle);
408         if (fabs)
409                 free0 |= (0x1UL << 63);
410         if (num & 0x1)
411                 free0 |= (0x1UL << 32);
412
413         /* tar_addr[4:6] is LMTST size-1 in units of 128b */
414         tar_addr = addr | ((num >> 1) << 4);
415
416         lmt_data[0] = free0;
417         for (i = 0; i < num; i++)
418                 lmt_data[i + 1] = buf[i];
419
420         roc_lmt_submit_steorl(lmt_id, tar_addr);
421         plt_io_wmb();
422 }
423
424 static inline void
425 roc_npa_aura_op_batch_free(uint64_t aura_handle, uint64_t const *buf,
426                            unsigned int num, const int fabs, uint64_t lmt_addr,
427                            uint64_t lmt_id)
428 {
429         unsigned int chunk;
430
431         while (num) {
432                 chunk = (num >= ROC_CN10K_NPA_BATCH_FREE_MAX_PTRS) ?
433                                       ROC_CN10K_NPA_BATCH_FREE_MAX_PTRS :
434                                       num;
435
436                 roc_npa_aura_batch_free(aura_handle, buf, chunk, fabs, lmt_addr,
437                                         lmt_id);
438
439                 buf += chunk;
440                 num -= chunk;
441         }
442 }
443
444 static inline unsigned int
445 roc_npa_aura_bulk_alloc(uint64_t aura_handle, uint64_t *buf, unsigned int num,
446                         const int drop)
447 {
448 #if defined(__aarch64__)
449         uint64_t wdata = roc_npa_aura_handle_to_aura(aura_handle);
450         unsigned int i, count;
451         uint64_t addr;
452
453         if (drop)
454                 wdata |= BIT_ULL(63); /* DROP */
455
456         addr = roc_npa_aura_handle_to_base(aura_handle) +
457                NPA_LF_AURA_OP_ALLOCX(0);
458
459         switch (num) {
460         case 30:
461                 asm volatile(
462                         ".arch_extension lse\n"
463                         "mov v18.d[0], %[dst]\n"
464                         "mov v18.d[1], %[loc]\n"
465                         "mov v19.d[0], %[wdata]\n"
466                         "mov v19.d[1], x30\n"
467                         "mov v20.d[0], x24\n"
468                         "mov v20.d[1], x25\n"
469                         "mov v21.d[0], x26\n"
470                         "mov v21.d[1], x27\n"
471                         "mov v22.d[0], x28\n"
472                         "mov v22.d[1], x29\n"
473                         "mov x28, v19.d[0]\n"
474                         "mov x29, v19.d[0]\n"
475                         "mov x30, v18.d[1]\n"
476                         "casp x0, x1, x28, x29, [x30]\n"
477                         "casp x2, x3, x28, x29, [x30]\n"
478                         "casp x4, x5, x28, x29, [x30]\n"
479                         "casp x6, x7, x28, x29, [x30]\n"
480                         "casp x8, x9, x28, x29, [x30]\n"
481                         "casp x10, x11, x28, x29, [x30]\n"
482                         "casp x12, x13, x28, x29, [x30]\n"
483                         "casp x14, x15, x28, x29, [x30]\n"
484                         "casp x16, x17, x28, x29, [x30]\n"
485                         "casp x18, x19, x28, x29, [x30]\n"
486                         "casp x20, x21, x28, x29, [x30]\n"
487                         "casp x22, x23, x28, x29, [x30]\n"
488                         "casp x24, x25, x28, x29, [x30]\n"
489                         "casp x26, x27, x28, x29, [x30]\n"
490                         "casp x28, x29, x28, x29, [x30]\n"
491                         "mov x30, v18.d[0]\n"
492                         "stp x0, x1, [x30]\n"
493                         "stp x2, x3, [x30, #16]\n"
494                         "stp x4, x5, [x30, #32]\n"
495                         "stp x6, x7, [x30, #48]\n"
496                         "stp x8, x9, [x30, #64]\n"
497                         "stp x10, x11, [x30, #80]\n"
498                         "stp x12, x13, [x30, #96]\n"
499                         "stp x14, x15, [x30, #112]\n"
500                         "stp x16, x17, [x30, #128]\n"
501                         "stp x18, x19, [x30, #144]\n"
502                         "stp x20, x21, [x30, #160]\n"
503                         "stp x22, x23, [x30, #176]\n"
504                         "stp x24, x25, [x30, #192]\n"
505                         "stp x26, x27, [x30, #208]\n"
506                         "stp x28, x29, [x30, #224]\n"
507                         "mov %[dst], v18.d[0]\n"
508                         "mov %[loc], v18.d[1]\n"
509                         "mov %[wdata], v19.d[0]\n"
510                         "mov x30, v19.d[1]\n"
511                         "mov x24, v20.d[0]\n"
512                         "mov x25, v20.d[1]\n"
513                         "mov x26, v21.d[0]\n"
514                         "mov x27, v21.d[1]\n"
515                         "mov x28, v22.d[0]\n"
516                         "mov x29, v22.d[1]\n"
517                         :
518                         : [wdata] "r"(wdata), [loc] "r"(addr), [dst] "r"(buf)
519                         : "memory", "x0", "x1", "x2", "x3", "x4", "x5", "x6",
520                           "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14",
521                           "x15", "x16", "x17", "x18", "x19", "x20", "x21",
522                           "x22", "x23", "v18", "v19", "v20", "v21", "v22");
523                 break;
524         case 16:
525                 asm volatile(
526                         ".arch_extension lse\n"
527                         "mov x16, %[wdata]\n"
528                         "mov x17, %[wdata]\n"
529                         "casp x0, x1, x16, x17, [%[loc]]\n"
530                         "casp x2, x3, x16, x17, [%[loc]]\n"
531                         "casp x4, x5, x16, x17, [%[loc]]\n"
532                         "casp x6, x7, x16, x17, [%[loc]]\n"
533                         "casp x8, x9, x16, x17, [%[loc]]\n"
534                         "casp x10, x11, x16, x17, [%[loc]]\n"
535                         "casp x12, x13, x16, x17, [%[loc]]\n"
536                         "casp x14, x15, x16, x17, [%[loc]]\n"
537                         "stp x0, x1, [%[dst]]\n"
538                         "stp x2, x3, [%[dst], #16]\n"
539                         "stp x4, x5, [%[dst], #32]\n"
540                         "stp x6, x7, [%[dst], #48]\n"
541                         "stp x8, x9, [%[dst], #64]\n"
542                         "stp x10, x11, [%[dst], #80]\n"
543                         "stp x12, x13, [%[dst], #96]\n"
544                         "stp x14, x15, [%[dst], #112]\n"
545                         :
546                         : [wdata] "r"(wdata), [dst] "r"(buf), [loc] "r"(addr)
547                         : "memory", "x0", "x1", "x2", "x3", "x4", "x5", "x6",
548                           "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14",
549                           "x15", "x16", "x17");
550                 break;
551         case 8:
552                 asm volatile(
553                         ".arch_extension lse\n"
554                         "mov x16, %[wdata]\n"
555                         "mov x17, %[wdata]\n"
556                         "casp x0, x1, x16, x17, [%[loc]]\n"
557                         "casp x2, x3, x16, x17, [%[loc]]\n"
558                         "casp x4, x5, x16, x17, [%[loc]]\n"
559                         "casp x6, x7, x16, x17, [%[loc]]\n"
560                         "stp x0, x1, [%[dst]]\n"
561                         "stp x2, x3, [%[dst], #16]\n"
562                         "stp x4, x5, [%[dst], #32]\n"
563                         "stp x6, x7, [%[dst], #48]\n"
564                         :
565                         : [wdata] "r"(wdata), [dst] "r"(buf), [loc] "r"(addr)
566                         : "memory", "x0", "x1", "x2", "x3", "x4", "x5", "x6",
567                           "x7", "x16", "x17");
568                 break;
569         case 4:
570                 asm volatile(
571                         ".arch_extension lse\n"
572                         "mov x16, %[wdata]\n"
573                         "mov x17, %[wdata]\n"
574                         "casp x0, x1, x16, x17, [%[loc]]\n"
575                         "casp x2, x3, x16, x17, [%[loc]]\n"
576                         "stp x0, x1, [%[dst]]\n"
577                         "stp x2, x3, [%[dst], #16]\n"
578                         :
579                         : [wdata] "r"(wdata), [dst] "r"(buf), [loc] "r"(addr)
580                         : "memory", "x0", "x1", "x2", "x3", "x16", "x17");
581                 break;
582         case 2:
583                 asm volatile(
584                         ".arch_extension lse\n"
585                         "mov x16, %[wdata]\n"
586                         "mov x17, %[wdata]\n"
587                         "casp x0, x1, x16, x17, [%[loc]]\n"
588                         "stp x0, x1, [%[dst]]\n"
589                         :
590                         : [wdata] "r"(wdata), [dst] "r"(buf), [loc] "r"(addr)
591                         : "memory", "x0", "x1", "x16", "x17");
592                 break;
593         case 1:
594                 buf[0] = roc_npa_aura_op_alloc(aura_handle, drop);
595                 return !!buf[0];
596         }
597
598         /* Pack the pointers */
599         for (i = 0, count = 0; i < num; i++)
600                 if (buf[i])
601                         buf[count++] = buf[i];
602
603         return count;
604 #else
605         unsigned int i, count;
606
607         for (i = 0, count = 0; i < num; i++) {
608                 buf[count] = roc_npa_aura_op_alloc(aura_handle, drop);
609                 if (buf[count])
610                         count++;
611         }
612
613         return count;
614 #endif
615 }
616
617 static inline unsigned int
618 roc_npa_aura_op_bulk_alloc(uint64_t aura_handle, uint64_t *buf,
619                            unsigned int num, const int drop, const int partial)
620 {
621         unsigned int chunk, count, num_alloc;
622
623         count = 0;
624         while (num) {
625                 chunk = (num >= ROC_CN9K_NPA_BULK_ALLOC_MAX_PTRS) ?
626                                       ROC_CN9K_NPA_BULK_ALLOC_MAX_PTRS :
627                                       plt_align32prevpow2(num);
628
629                 num_alloc =
630                         roc_npa_aura_bulk_alloc(aura_handle, buf, chunk, drop);
631
632                 count += num_alloc;
633                 buf += num_alloc;
634                 num -= num_alloc;
635
636                 if (unlikely(num_alloc != chunk))
637                         break;
638         }
639
640         /* If the requested number of pointers was not allocated and if partial
641          * alloc is not desired, then free allocated pointers.
642          */
643         if (unlikely(num != 0 && !partial)) {
644                 roc_npa_aura_op_bulk_free(aura_handle, buf - count, count, 1);
645                 count = 0;
646         }
647
648         return count;
649 }
650
651 struct roc_npa {
652         struct plt_pci_device *pci_dev;
653
654 #define ROC_NPA_MEM_SZ (1 * 1024)
655         uint8_t reserved[ROC_NPA_MEM_SZ] __plt_cache_aligned;
656 } __plt_cache_aligned;
657
658 int __roc_api roc_npa_dev_init(struct roc_npa *roc_npa);
659 int __roc_api roc_npa_dev_fini(struct roc_npa *roc_npa);
660
661 /* NPA pool */
662 int __roc_api roc_npa_pool_create(uint64_t *aura_handle, uint32_t block_size,
663                                   uint32_t block_count, struct npa_aura_s *aura,
664                                   struct npa_pool_s *pool);
665 int __roc_api roc_npa_aura_limit_modify(uint64_t aura_handle,
666                                         uint16_t aura_limit);
667 int __roc_api roc_npa_pool_destroy(uint64_t aura_handle);
668 int __roc_api roc_npa_pool_range_update_check(uint64_t aura_handle);
669 void __roc_api roc_npa_aura_op_range_set(uint64_t aura_handle,
670                                          uint64_t start_iova,
671                                          uint64_t end_iova);
672
673 /* Init callbacks */
674 typedef int (*roc_npa_lf_init_cb_t)(struct plt_pci_device *pci_dev);
675 int __roc_api roc_npa_lf_init_cb_register(roc_npa_lf_init_cb_t cb);
676
677 /* Debug */
678 int __roc_api roc_npa_ctx_dump(void);
679 int __roc_api roc_npa_dump(void);
680
681 /* Reset operation performance counter. */
682 int __roc_api roc_npa_pool_op_pc_reset(uint64_t aura_handle);
683
684 #endif /* _ROC_NPA_H_ */