1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#include "bman_priv.h"
32
33#define IRQNAME "BMan portal %d"
34#define MAX_IRQNAME 16
35
36
37
38#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
39
40#define BM_REG_RCR_PI_CINH 0x3000
41#define BM_REG_RCR_CI_CINH 0x3100
42#define BM_REG_RCR_ITR 0x3200
43#define BM_REG_CFG 0x3300
44#define BM_REG_SCN(n) (0x3400 + ((n) << 6))
45#define BM_REG_ISR 0x3e00
46#define BM_REG_IER 0x3e40
47#define BM_REG_ISDR 0x3e80
48#define BM_REG_IIR 0x3ec0
49
50
51#define BM_CL_CR 0x0000
52#define BM_CL_RR0 0x0100
53#define BM_CL_RR1 0x0140
54#define BM_CL_RCR 0x1000
55#define BM_CL_RCR_PI_CENA 0x3000
56#define BM_CL_RCR_CI_CENA 0x3100
57
58#else
59
60#define BM_REG_RCR_PI_CINH 0x0000
61#define BM_REG_RCR_CI_CINH 0x0004
62#define BM_REG_RCR_ITR 0x0008
63#define BM_REG_CFG 0x0100
64#define BM_REG_SCN(n) (0x0200 + ((n) << 2))
65#define BM_REG_ISR 0x0e00
66#define BM_REG_IER 0x0e04
67#define BM_REG_ISDR 0x0e08
68#define BM_REG_IIR 0x0e0c
69
70
71#define BM_CL_CR 0x0000
72#define BM_CL_RR0 0x0100
73#define BM_CL_RR1 0x0140
74#define BM_CL_RCR 0x1000
75#define BM_CL_RCR_PI_CENA 0x3000
76#define BM_CL_RCR_CI_CENA 0x3100
77#endif
78
79
80
81
82
83
84
85
86
87
88
89
90enum bm_rcr_pmode {
91 bm_rcr_pci = 0,
92 bm_rcr_pce = 1,
93 bm_rcr_pvb = 2
94};
95enum bm_rcr_cmode {
96 bm_rcr_cci,
97 bm_rcr_cce
98};
99
100
101
102
103#define BM_RCR_SIZE 8
104
105
106struct bm_rcr_entry {
107 union {
108 struct {
109 u8 _ncw_verb;
110 u8 bpid;
111 u8 __reserved1[62];
112 };
113 struct bm_buffer bufs[8];
114 };
115};
116#define BM_RCR_VERB_VBIT 0x80
117#define BM_RCR_VERB_CMD_MASK 0x70
118#define BM_RCR_VERB_CMD_BPID_SINGLE 0x20
119#define BM_RCR_VERB_CMD_BPID_MULTI 0x30
120#define BM_RCR_VERB_BUFCOUNT_MASK 0x0f
121
122struct bm_rcr {
123 struct bm_rcr_entry *ring, *cursor;
124 u8 ci, available, ithresh, vbit;
125#ifdef CONFIG_FSL_DPAA_CHECKING
126 u32 busy;
127 enum bm_rcr_pmode pmode;
128 enum bm_rcr_cmode cmode;
129#endif
130};
131
132
133struct bm_mc_command {
134 u8 _ncw_verb;
135 u8 bpid;
136 u8 __reserved[62];
137};
138#define BM_MCC_VERB_VBIT 0x80
139#define BM_MCC_VERB_CMD_MASK 0x70
140#define BM_MCC_VERB_CMD_ACQUIRE 0x10
141#define BM_MCC_VERB_CMD_QUERY 0x40
142#define BM_MCC_VERB_ACQUIRE_BUFCOUNT 0x0f
143
144
145union bm_mc_result {
146 struct {
147 u8 verb;
148 u8 bpid;
149 u8 __reserved[62];
150 };
151 struct bm_buffer bufs[8];
152};
153#define BM_MCR_VERB_VBIT 0x80
154#define BM_MCR_VERB_CMD_MASK BM_MCC_VERB_CMD_MASK
155#define BM_MCR_VERB_CMD_ACQUIRE BM_MCC_VERB_CMD_ACQUIRE
156#define BM_MCR_VERB_CMD_QUERY BM_MCC_VERB_CMD_QUERY
157#define BM_MCR_VERB_CMD_ERR_INVALID 0x60
158#define BM_MCR_VERB_CMD_ERR_ECC 0x70
159#define BM_MCR_VERB_ACQUIRE_BUFCOUNT BM_MCC_VERB_ACQUIRE_BUFCOUNT
160#define BM_MCR_TIMEOUT 10000
161
162struct bm_mc {
163 struct bm_mc_command *cr;
164 union bm_mc_result *rr;
165 u8 rridx, vbit;
166#ifdef CONFIG_FSL_DPAA_CHECKING
167 enum {
168
169 mc_idle,
170
171 mc_user,
172
173 mc_hw
174 } state;
175#endif
176};
177
178struct bm_addr {
179 void *ce;
180 __be32 *ce_be;
181 void __iomem *ci;
182};
183
184struct bm_portal {
185 struct bm_addr addr;
186 struct bm_rcr rcr;
187 struct bm_mc mc;
188} ____cacheline_aligned;
189
190
191static inline u32 bm_in(struct bm_portal *p, u32 offset)
192{
193 return ioread32be(p->addr.ci + offset);
194}
195
196static inline void bm_out(struct bm_portal *p, u32 offset, u32 val)
197{
198 iowrite32be(val, p->addr.ci + offset);
199}
200
201
202static inline void bm_cl_invalidate(struct bm_portal *p, u32 offset)
203{
204 dpaa_invalidate(p->addr.ce + offset);
205}
206
207static inline void bm_cl_touch_ro(struct bm_portal *p, u32 offset)
208{
209 dpaa_touch_ro(p->addr.ce + offset);
210}
211
212static inline u32 bm_ce_in(struct bm_portal *p, u32 offset)
213{
214 return be32_to_cpu(*(p->addr.ce_be + (offset/4)));
215}
216
217struct bman_portal {
218 struct bm_portal p;
219
220 unsigned long irq_sources;
221
222 const struct bm_portal_config *config;
223 char irqname[MAX_IRQNAME];
224};
225
226static cpumask_t affine_mask;
227static DEFINE_SPINLOCK(affine_mask_lock);
228static DEFINE_PER_CPU(struct bman_portal, bman_affine_portal);
229
230static inline struct bman_portal *get_affine_portal(void)
231{
232 return &get_cpu_var(bman_affine_portal);
233}
234
235static inline void put_affine_portal(void)
236{
237 put_cpu_var(bman_affine_portal);
238}
239
240
241
242
243
244
245struct bman_pool {
246
247 u32 bpid;
248
249 struct bman_portal *portal;
250 struct bman_pool *next;
251};
252
253static u32 poll_portal_slow(struct bman_portal *p, u32 is);
254
255static irqreturn_t portal_isr(int irq, void *ptr)
256{
257 struct bman_portal *p = ptr;
258 struct bm_portal *portal = &p->p;
259 u32 clear = p->irq_sources;
260 u32 is = bm_in(portal, BM_REG_ISR) & p->irq_sources;
261
262 if (unlikely(!is))
263 return IRQ_NONE;
264
265 clear |= poll_portal_slow(p, is);
266 bm_out(portal, BM_REG_ISR, clear);
267 return IRQ_HANDLED;
268}
269
270
271
272#define RCR_SHIFT ilog2(sizeof(struct bm_rcr_entry))
273#define RCR_CARRY (uintptr_t)(BM_RCR_SIZE << RCR_SHIFT)
274
275
276static struct bm_rcr_entry *rcr_carryclear(struct bm_rcr_entry *p)
277{
278 uintptr_t addr = (uintptr_t)p;
279
280 addr &= ~RCR_CARRY;
281
282 return (struct bm_rcr_entry *)addr;
283}
284
285#ifdef CONFIG_FSL_DPAA_CHECKING
286
287static int rcr_ptr2idx(struct bm_rcr_entry *e)
288{
289 return ((uintptr_t)e >> RCR_SHIFT) & (BM_RCR_SIZE - 1);
290}
291#endif
292
293
294static inline void rcr_inc(struct bm_rcr *rcr)
295{
296
297 struct bm_rcr_entry *partial = rcr->cursor + 1;
298
299 rcr->cursor = rcr_carryclear(partial);
300 if (partial != rcr->cursor)
301 rcr->vbit ^= BM_RCR_VERB_VBIT;
302}
303
304static int bm_rcr_get_avail(struct bm_portal *portal)
305{
306 struct bm_rcr *rcr = &portal->rcr;
307
308 return rcr->available;
309}
310
311static int bm_rcr_get_fill(struct bm_portal *portal)
312{
313 struct bm_rcr *rcr = &portal->rcr;
314
315 return BM_RCR_SIZE - 1 - rcr->available;
316}
317
318static void bm_rcr_set_ithresh(struct bm_portal *portal, u8 ithresh)
319{
320 struct bm_rcr *rcr = &portal->rcr;
321
322 rcr->ithresh = ithresh;
323 bm_out(portal, BM_REG_RCR_ITR, ithresh);
324}
325
326static void bm_rcr_cce_prefetch(struct bm_portal *portal)
327{
328 __maybe_unused struct bm_rcr *rcr = &portal->rcr;
329
330 DPAA_ASSERT(rcr->cmode == bm_rcr_cce);
331 bm_cl_touch_ro(portal, BM_CL_RCR_CI_CENA);
332}
333
334static u8 bm_rcr_cce_update(struct bm_portal *portal)
335{
336 struct bm_rcr *rcr = &portal->rcr;
337 u8 diff, old_ci = rcr->ci;
338
339 DPAA_ASSERT(rcr->cmode == bm_rcr_cce);
340 rcr->ci = bm_ce_in(portal, BM_CL_RCR_CI_CENA) & (BM_RCR_SIZE - 1);
341 bm_cl_invalidate(portal, BM_CL_RCR_CI_CENA);
342 diff = dpaa_cyc_diff(BM_RCR_SIZE, old_ci, rcr->ci);
343 rcr->available += diff;
344 return diff;
345}
346
347static inline struct bm_rcr_entry *bm_rcr_start(struct bm_portal *portal)
348{
349 struct bm_rcr *rcr = &portal->rcr;
350
351 DPAA_ASSERT(!rcr->busy);
352 if (!rcr->available)
353 return NULL;
354#ifdef CONFIG_FSL_DPAA_CHECKING
355 rcr->busy = 1;
356#endif
357 dpaa_zero(rcr->cursor);
358 return rcr->cursor;
359}
360
361static inline void bm_rcr_pvb_commit(struct bm_portal *portal, u8 myverb)
362{
363 struct bm_rcr *rcr = &portal->rcr;
364 struct bm_rcr_entry *rcursor;
365
366 DPAA_ASSERT(rcr->busy);
367 DPAA_ASSERT(rcr->pmode == bm_rcr_pvb);
368 DPAA_ASSERT(rcr->available >= 1);
369 dma_wmb();
370 rcursor = rcr->cursor;
371 rcursor->_ncw_verb = myverb | rcr->vbit;
372 dpaa_flush(rcursor);
373 rcr_inc(rcr);
374 rcr->available--;
375#ifdef CONFIG_FSL_DPAA_CHECKING
376 rcr->busy = 0;
377#endif
378}
379
380static int bm_rcr_init(struct bm_portal *portal, enum bm_rcr_pmode pmode,
381 enum bm_rcr_cmode cmode)
382{
383 struct bm_rcr *rcr = &portal->rcr;
384 u32 cfg;
385 u8 pi;
386
387 rcr->ring = portal->addr.ce + BM_CL_RCR;
388 rcr->ci = bm_in(portal, BM_REG_RCR_CI_CINH) & (BM_RCR_SIZE - 1);
389 pi = bm_in(portal, BM_REG_RCR_PI_CINH) & (BM_RCR_SIZE - 1);
390 rcr->cursor = rcr->ring + pi;
391 rcr->vbit = (bm_in(portal, BM_REG_RCR_PI_CINH) & BM_RCR_SIZE) ?
392 BM_RCR_VERB_VBIT : 0;
393 rcr->available = BM_RCR_SIZE - 1
394 - dpaa_cyc_diff(BM_RCR_SIZE, rcr->ci, pi);
395 rcr->ithresh = bm_in(portal, BM_REG_RCR_ITR);
396#ifdef CONFIG_FSL_DPAA_CHECKING
397 rcr->busy = 0;
398 rcr->pmode = pmode;
399 rcr->cmode = cmode;
400#endif
401 cfg = (bm_in(portal, BM_REG_CFG) & 0xffffffe0)
402 | (pmode & 0x3);
403 bm_out(portal, BM_REG_CFG, cfg);
404 return 0;
405}
406
407static void bm_rcr_finish(struct bm_portal *portal)
408{
409#ifdef CONFIG_FSL_DPAA_CHECKING
410 struct bm_rcr *rcr = &portal->rcr;
411 int i;
412
413 DPAA_ASSERT(!rcr->busy);
414
415 i = bm_in(portal, BM_REG_RCR_PI_CINH) & (BM_RCR_SIZE - 1);
416 if (i != rcr_ptr2idx(rcr->cursor))
417 pr_crit("losing uncommitted RCR entries\n");
418
419 i = bm_in(portal, BM_REG_RCR_CI_CINH) & (BM_RCR_SIZE - 1);
420 if (i != rcr->ci)
421 pr_crit("missing existing RCR completions\n");
422 if (rcr->ci != rcr_ptr2idx(rcr->cursor))
423 pr_crit("RCR destroyed unquiesced\n");
424#endif
425}
426
427
428static int bm_mc_init(struct bm_portal *portal)
429{
430 struct bm_mc *mc = &portal->mc;
431
432 mc->cr = portal->addr.ce + BM_CL_CR;
433 mc->rr = portal->addr.ce + BM_CL_RR0;
434 mc->rridx = (mc->cr->_ncw_verb & BM_MCC_VERB_VBIT) ?
435 0 : 1;
436 mc->vbit = mc->rridx ? BM_MCC_VERB_VBIT : 0;
437#ifdef CONFIG_FSL_DPAA_CHECKING
438 mc->state = mc_idle;
439#endif
440 return 0;
441}
442
443static void bm_mc_finish(struct bm_portal *portal)
444{
445#ifdef CONFIG_FSL_DPAA_CHECKING
446 struct bm_mc *mc = &portal->mc;
447
448 DPAA_ASSERT(mc->state == mc_idle);
449 if (mc->state != mc_idle)
450 pr_crit("Losing incomplete MC command\n");
451#endif
452}
453
454static inline struct bm_mc_command *bm_mc_start(struct bm_portal *portal)
455{
456 struct bm_mc *mc = &portal->mc;
457
458 DPAA_ASSERT(mc->state == mc_idle);
459#ifdef CONFIG_FSL_DPAA_CHECKING
460 mc->state = mc_user;
461#endif
462 dpaa_zero(mc->cr);
463 return mc->cr;
464}
465
466static inline void bm_mc_commit(struct bm_portal *portal, u8 myverb)
467{
468 struct bm_mc *mc = &portal->mc;
469 union bm_mc_result *rr = mc->rr + mc->rridx;
470
471 DPAA_ASSERT(mc->state == mc_user);
472 dma_wmb();
473 mc->cr->_ncw_verb = myverb | mc->vbit;
474 dpaa_flush(mc->cr);
475 dpaa_invalidate_touch_ro(rr);
476#ifdef CONFIG_FSL_DPAA_CHECKING
477 mc->state = mc_hw;
478#endif
479}
480
481static inline union bm_mc_result *bm_mc_result(struct bm_portal *portal)
482{
483 struct bm_mc *mc = &portal->mc;
484 union bm_mc_result *rr = mc->rr + mc->rridx;
485
486 DPAA_ASSERT(mc->state == mc_hw);
487
488
489
490
491
492 if (!rr->verb) {
493 dpaa_invalidate_touch_ro(rr);
494 return NULL;
495 }
496 mc->rridx ^= 1;
497 mc->vbit ^= BM_MCC_VERB_VBIT;
498#ifdef CONFIG_FSL_DPAA_CHECKING
499 mc->state = mc_idle;
500#endif
501 return rr;
502}
503
504static inline int bm_mc_result_timeout(struct bm_portal *portal,
505 union bm_mc_result **mcr)
506{
507 int timeout = BM_MCR_TIMEOUT;
508
509 do {
510 *mcr = bm_mc_result(portal);
511 if (*mcr)
512 break;
513 udelay(1);
514 } while (--timeout);
515
516 return timeout;
517}
518
519
520static void bm_isr_bscn_disable(struct bm_portal *portal)
521{
522 bm_out(portal, BM_REG_SCN(0), 0);
523 bm_out(portal, BM_REG_SCN(1), 0);
524}
525
526static int bman_create_portal(struct bman_portal *portal,
527 const struct bm_portal_config *c)
528{
529 struct bm_portal *p;
530 int ret;
531
532 p = &portal->p;
533
534
535
536
537
538 p->addr.ce = c->addr_virt_ce;
539 p->addr.ce_be = c->addr_virt_ce;
540 p->addr.ci = c->addr_virt_ci;
541 if (bm_rcr_init(p, bm_rcr_pvb, bm_rcr_cce)) {
542 dev_err(c->dev, "RCR initialisation failed\n");
543 goto fail_rcr;
544 }
545 if (bm_mc_init(p)) {
546 dev_err(c->dev, "MC initialisation failed\n");
547 goto fail_mc;
548 }
549
550
551
552
553 bm_isr_bscn_disable(p);
554
555
556 bm_out(p, BM_REG_ISDR, 0xffffffff);
557 portal->irq_sources = 0;
558 bm_out(p, BM_REG_IER, 0);
559 bm_out(p, BM_REG_ISR, 0xffffffff);
560 snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, c->cpu);
561 if (request_irq(c->irq, portal_isr, 0, portal->irqname, portal)) {
562 dev_err(c->dev, "request_irq() failed\n");
563 goto fail_irq;
564 }
565 if (c->cpu != -1 && irq_can_set_affinity(c->irq) &&
566 irq_set_affinity(c->irq, cpumask_of(c->cpu))) {
567 dev_err(c->dev, "irq_set_affinity() failed\n");
568 goto fail_affinity;
569 }
570
571
572 ret = bm_rcr_get_fill(p);
573 if (ret) {
574 dev_err(c->dev, "RCR unclean\n");
575 goto fail_rcr_empty;
576 }
577
578 portal->config = c;
579
580 bm_out(p, BM_REG_ISDR, 0);
581 bm_out(p, BM_REG_IIR, 0);
582
583 return 0;
584
585fail_rcr_empty:
586fail_affinity:
587 free_irq(c->irq, portal);
588fail_irq:
589 bm_mc_finish(p);
590fail_mc:
591 bm_rcr_finish(p);
592fail_rcr:
593 return -EIO;
594}
595
596struct bman_portal *bman_create_affine_portal(const struct bm_portal_config *c)
597{
598 struct bman_portal *portal;
599 int err;
600
601 portal = &per_cpu(bman_affine_portal, c->cpu);
602 err = bman_create_portal(portal, c);
603 if (err)
604 return NULL;
605
606 spin_lock(&affine_mask_lock);
607 cpumask_set_cpu(c->cpu, &affine_mask);
608 spin_unlock(&affine_mask_lock);
609
610 return portal;
611}
612
613static u32 poll_portal_slow(struct bman_portal *p, u32 is)
614{
615 u32 ret = is;
616
617 if (is & BM_PIRQ_RCRI) {
618 bm_rcr_cce_update(&p->p);
619 bm_rcr_set_ithresh(&p->p, 0);
620 bm_out(&p->p, BM_REG_ISR, BM_PIRQ_RCRI);
621 is &= ~BM_PIRQ_RCRI;
622 }
623
624
625 DPAA_ASSERT(!is);
626 return ret;
627}
628
629int bman_p_irqsource_add(struct bman_portal *p, u32 bits)
630{
631 unsigned long irqflags;
632
633 local_irq_save(irqflags);
634 p->irq_sources |= bits & BM_PIRQ_VISIBLE;
635 bm_out(&p->p, BM_REG_IER, p->irq_sources);
636 local_irq_restore(irqflags);
637 return 0;
638}
639
640static int bm_shutdown_pool(u32 bpid)
641{
642 struct bm_mc_command *bm_cmd;
643 union bm_mc_result *bm_res;
644
645 while (1) {
646 struct bman_portal *p = get_affine_portal();
647
648 bm_cmd = bm_mc_start(&p->p);
649 bm_cmd->bpid = bpid;
650 bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE | 1);
651 if (!bm_mc_result_timeout(&p->p, &bm_res)) {
652 put_affine_portal();
653 pr_crit("BMan Acquire Command timedout\n");
654 return -ETIMEDOUT;
655 }
656 if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
657 put_affine_portal();
658
659 return 0;
660 }
661 put_affine_portal();
662 }
663
664 return 0;
665}
666
667struct gen_pool *bm_bpalloc;
668
669static int bm_alloc_bpid_range(u32 *result, u32 count)
670{
671 unsigned long addr;
672
673 addr = gen_pool_alloc(bm_bpalloc, count);
674 if (!addr)
675 return -ENOMEM;
676
677 *result = addr & ~DPAA_GENALLOC_OFF;
678
679 return 0;
680}
681
682static int bm_release_bpid(u32 bpid)
683{
684 int ret;
685
686 ret = bm_shutdown_pool(bpid);
687 if (ret) {
688 pr_debug("BPID %d leaked\n", bpid);
689 return ret;
690 }
691
692 gen_pool_free(bm_bpalloc, bpid | DPAA_GENALLOC_OFF, 1);
693 return 0;
694}
695
696struct bman_pool *bman_new_pool(void)
697{
698 struct bman_pool *pool = NULL;
699 u32 bpid;
700
701 if (bm_alloc_bpid_range(&bpid, 1))
702 return NULL;
703
704 pool = kmalloc(sizeof(*pool), GFP_KERNEL);
705 if (!pool)
706 goto err;
707
708 pool->bpid = bpid;
709
710 return pool;
711err:
712 bm_release_bpid(bpid);
713 kfree(pool);
714 return NULL;
715}
716EXPORT_SYMBOL(bman_new_pool);
717
718void bman_free_pool(struct bman_pool *pool)
719{
720 bm_release_bpid(pool->bpid);
721
722 kfree(pool);
723}
724EXPORT_SYMBOL(bman_free_pool);
725
726int bman_get_bpid(const struct bman_pool *pool)
727{
728 return pool->bpid;
729}
730EXPORT_SYMBOL(bman_get_bpid);
731
732static void update_rcr_ci(struct bman_portal *p, int avail)
733{
734 if (avail)
735 bm_rcr_cce_prefetch(&p->p);
736 else
737 bm_rcr_cce_update(&p->p);
738}
739
740int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num)
741{
742 struct bman_portal *p;
743 struct bm_rcr_entry *r;
744 unsigned long irqflags;
745 int avail, timeout = 1000;
746 int i = num - 1;
747
748 DPAA_ASSERT(num > 0 && num <= 8);
749
750 do {
751 p = get_affine_portal();
752 local_irq_save(irqflags);
753 avail = bm_rcr_get_avail(&p->p);
754 if (avail < 2)
755 update_rcr_ci(p, avail);
756 r = bm_rcr_start(&p->p);
757 local_irq_restore(irqflags);
758 put_affine_portal();
759 if (likely(r))
760 break;
761
762 udelay(1);
763 } while (--timeout);
764
765 if (unlikely(!timeout))
766 return -ETIMEDOUT;
767
768 p = get_affine_portal();
769 local_irq_save(irqflags);
770
771
772
773
774 bm_buffer_set64(r->bufs, bm_buffer_get64(bufs));
775 bm_buffer_set_bpid(r->bufs, pool->bpid);
776 if (i)
777 memcpy(&r->bufs[1], &bufs[1], i * sizeof(bufs[0]));
778
779 bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
780 (num & BM_RCR_VERB_BUFCOUNT_MASK));
781
782 local_irq_restore(irqflags);
783 put_affine_portal();
784 return 0;
785}
786EXPORT_SYMBOL(bman_release);
787
788int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num)
789{
790 struct bman_portal *p = get_affine_portal();
791 struct bm_mc_command *mcc;
792 union bm_mc_result *mcr;
793 int ret;
794
795 DPAA_ASSERT(num > 0 && num <= 8);
796
797 mcc = bm_mc_start(&p->p);
798 mcc->bpid = pool->bpid;
799 bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE |
800 (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT));
801 if (!bm_mc_result_timeout(&p->p, &mcr)) {
802 put_affine_portal();
803 pr_crit("BMan Acquire Timeout\n");
804 return -ETIMEDOUT;
805 }
806 ret = mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT;
807 if (bufs)
808 memcpy(&bufs[0], &mcr->bufs[0], num * sizeof(bufs[0]));
809
810 put_affine_portal();
811 if (ret != num)
812 ret = -ENOMEM;
813 return ret;
814}
815EXPORT_SYMBOL(bman_acquire);
816
817const struct bm_portal_config *
818bman_get_bm_portal_config(const struct bman_portal *portal)
819{
820 return portal->config;
821}
822