cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bman.c (20343B)


      1/* Copyright 2008 - 2016 Freescale Semiconductor, Inc.
      2 *
      3 * Redistribution and use in source and binary forms, with or without
      4 * modification, are permitted provided that the following conditions are met:
      5 *     * Redistributions of source code must retain the above copyright
      6 *	 notice, this list of conditions and the following disclaimer.
      7 *     * Redistributions in binary form must reproduce the above copyright
      8 *	 notice, this list of conditions and the following disclaimer in the
      9 *	 documentation and/or other materials provided with the distribution.
     10 *     * Neither the name of Freescale Semiconductor nor the
     11 *	 names of its contributors may be used to endorse or promote products
     12 *	 derived from this software without specific prior written permission.
     13 *
     14 * ALTERNATIVELY, this software may be distributed under the terms of the
     15 * GNU General Public License ("GPL") as published by the Free Software
     16 * Foundation, either version 2 of that License or (at your option) any
     17 * later version.
     18 *
     19 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
     20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
     23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 */
     30
     31#include "bman_priv.h"
     32
     33#define IRQNAME		"BMan portal %d"
     34#define MAX_IRQNAME	16	/* big enough for "BMan portal %d" */
     35
     36/* Portal register assists */
     37
     38#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
     39/* Cache-inhibited register offsets */
     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/* Cache-enabled register offsets */
     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/* Cache-inhibited register offsets */
     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/* Cache-enabled register offsets */
     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 * Portal modes.
     81 *   Enum types;
     82 *     pmode == production mode
     83 *     cmode == consumption mode,
     84 *   Enum values use 3 letter codes. First letter matches the portal mode,
     85 *   remaining two letters indicate;
     86 *     ci == cache-inhibited portal register
     87 *     ce == cache-enabled portal register
     88 *     vb == in-band valid-bit (cache-enabled)
     89 */
     90enum bm_rcr_pmode {		/* matches BCSP_CFG::RPM */
     91	bm_rcr_pci = 0,		/* PI index, cache-inhibited */
     92	bm_rcr_pce = 1,		/* PI index, cache-enabled */
     93	bm_rcr_pvb = 2		/* valid-bit */
     94};
     95enum bm_rcr_cmode {		/* s/w-only */
     96	bm_rcr_cci,		/* CI index, cache-inhibited */
     97	bm_rcr_cce		/* CI index, cache-enabled */
     98};
     99
    100
    101/* --- Portal structures --- */
    102
    103#define BM_RCR_SIZE		8
    104
    105/* Release Command */
    106struct bm_rcr_entry {
    107	union {
    108		struct {
    109			u8 _ncw_verb; /* writes to this are non-coherent */
    110			u8 bpid; /* used with BM_RCR_VERB_CMD_BPID_SINGLE */
    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	/* one of two values; */
    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	/* values 1..8 */
    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/* MC (Management Command) command */
    133struct bm_mc_command {
    134	u8 _ncw_verb; /* writes to this are non-coherent */
    135	u8 bpid; /* used by acquire command */
    136	u8 __reserved[62];
    137};
    138#define BM_MCC_VERB_VBIT		0x80
    139#define BM_MCC_VERB_CMD_MASK		0x70	/* where the verb contains; */
    140#define BM_MCC_VERB_CMD_ACQUIRE		0x10
    141#define BM_MCC_VERB_CMD_QUERY		0x40
    142#define BM_MCC_VERB_ACQUIRE_BUFCOUNT	0x0f	/* values 1..8 go here */
    143
    144/* MC result, Acquire and Query Response */
    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 /* 0..8 */
    160#define BM_MCR_TIMEOUT			10000 /* us */
    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		/* Can only be _mc_start()ed */
    169		mc_idle,
    170		/* Can only be _mc_commit()ed or _mc_abort()ed */
    171		mc_user,
    172		/* Can only be _mc_retry()ed */
    173		mc_hw
    174	} state;
    175#endif
    176};
    177
    178struct bm_addr {
    179	void *ce;		/* cache-enabled */
    180	__be32 *ce_be;		/* Same as above but for direct access */
    181	void __iomem *ci;	/* cache-inhibited */
    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/* Cache-inhibited register access. */
    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/* Cache Enabled Portal Access */
    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	/* interrupt sources processed by portal_isr(), configurable */
    220	unsigned long irq_sources;
    221	/* probing time config params for cpu-affine portals */
    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 * This object type refers to a pool, it isn't *the* pool. There may be
    242 * more than one such object per BMan buffer pool, eg. if different users of the
    243 * pool are operating via different portals.
    244 */
    245struct bman_pool {
    246	/* index of the buffer pool to encapsulate (0-63) */
    247	u32 bpid;
    248	/* Used for hash-table admin when using depletion notifications. */
    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/* --- RCR API --- */
    271
    272#define RCR_SHIFT	ilog2(sizeof(struct bm_rcr_entry))
    273#define RCR_CARRY	(uintptr_t)(BM_RCR_SIZE << RCR_SHIFT)
    274
    275/* Bit-wise logic to wrap a ring pointer by clearing the "carry bit" */
    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/* Bit-wise logic to convert a ring pointer to a ring index */
    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/* Increment the 'cursor' ring pointer, taking 'vbit' into account */
    294static inline void rcr_inc(struct bm_rcr *rcr)
    295{
    296	/* increment to the next RCR pointer and handle overflow and 'vbit' */
    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); /* BCSP_CFG::RPM */
    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/* --- Management command API --- */
    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	 * The inactive response register's verb byte always returns zero until
    489	 * its command is submitted and completed. This includes the valid-bit,
    490	 * in case you were wondering...
    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/* Disable all BSCN interrupts for the portal */
    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	 * prep the low-level portal struct with the mapped addresses from the
    535	 * config, everything that follows depends on it and "config" is more
    536	 * for (de)reference...
    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	 * Default to all BPIDs disabled, we enable as required at
    551	 * run-time.
    552	 */
    553	bm_isr_bscn_disable(p);
    554
    555	/* Write-to-clear any stale interrupt status bits */
    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
    566	if (dpaa_set_portal_irq_affinity(c->dev, c->irq, c->cpu))
    567		goto fail_affinity;
    568
    569	/* Need RCR to be empty before continuing */
    570	ret = bm_rcr_get_fill(p);
    571	if (ret) {
    572		dev_err(c->dev, "RCR unclean\n");
    573		goto fail_rcr_empty;
    574	}
    575	/* Success */
    576	portal->config = c;
    577
    578	bm_out(p, BM_REG_ISDR, 0);
    579	bm_out(p, BM_REG_IIR, 0);
    580
    581	return 0;
    582
    583fail_rcr_empty:
    584fail_affinity:
    585	free_irq(c->irq, portal);
    586fail_irq:
    587	bm_mc_finish(p);
    588fail_mc:
    589	bm_rcr_finish(p);
    590fail_rcr:
    591	return -EIO;
    592}
    593
    594struct bman_portal *bman_create_affine_portal(const struct bm_portal_config *c)
    595{
    596	struct bman_portal *portal;
    597	int err;
    598
    599	portal = &per_cpu(bman_affine_portal, c->cpu);
    600	err = bman_create_portal(portal, c);
    601	if (err)
    602		return NULL;
    603
    604	spin_lock(&affine_mask_lock);
    605	cpumask_set_cpu(c->cpu, &affine_mask);
    606	spin_unlock(&affine_mask_lock);
    607
    608	return portal;
    609}
    610
    611static u32 poll_portal_slow(struct bman_portal *p, u32 is)
    612{
    613	u32 ret = is;
    614
    615	if (is & BM_PIRQ_RCRI) {
    616		bm_rcr_cce_update(&p->p);
    617		bm_rcr_set_ithresh(&p->p, 0);
    618		bm_out(&p->p, BM_REG_ISR, BM_PIRQ_RCRI);
    619		is &= ~BM_PIRQ_RCRI;
    620	}
    621
    622	/* There should be no status register bits left undefined */
    623	DPAA_ASSERT(!is);
    624	return ret;
    625}
    626
    627int bman_p_irqsource_add(struct bman_portal *p, u32 bits)
    628{
    629	unsigned long irqflags;
    630
    631	local_irq_save(irqflags);
    632	p->irq_sources |= bits & BM_PIRQ_VISIBLE;
    633	bm_out(&p->p, BM_REG_IER, p->irq_sources);
    634	local_irq_restore(irqflags);
    635	return 0;
    636}
    637
    638int bm_shutdown_pool(u32 bpid)
    639{
    640	int err = 0;
    641	struct bm_mc_command *bm_cmd;
    642	union bm_mc_result *bm_res;
    643
    644
    645	struct bman_portal *p = get_affine_portal();
    646	while (1) {
    647		/* Acquire buffers until empty */
    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			pr_crit("BMan Acquire Command timedout\n");
    653			err = -ETIMEDOUT;
    654			goto done;
    655		}
    656		if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
    657			/* Pool is empty */
    658			goto done;
    659		}
    660	}
    661done:
    662	put_affine_portal();
    663	return err;
    664}
    665
    666struct gen_pool *bm_bpalloc;
    667
    668static int bm_alloc_bpid_range(u32 *result, u32 count)
    669{
    670	unsigned long addr;
    671
    672	addr = gen_pool_alloc(bm_bpalloc, count);
    673	if (!addr)
    674		return -ENOMEM;
    675
    676	*result = addr & ~DPAA_GENALLOC_OFF;
    677
    678	return 0;
    679}
    680
    681static int bm_release_bpid(u32 bpid)
    682{
    683	int ret;
    684
    685	ret = bm_shutdown_pool(bpid);
    686	if (ret) {
    687		pr_debug("BPID %d leaked\n", bpid);
    688		return ret;
    689	}
    690
    691	gen_pool_free(bm_bpalloc, bpid | DPAA_GENALLOC_OFF, 1);
    692	return 0;
    693}
    694
    695struct bman_pool *bman_new_pool(void)
    696{
    697	struct bman_pool *pool = NULL;
    698	u32 bpid;
    699
    700	if (bm_alloc_bpid_range(&bpid, 1))
    701		return NULL;
    702
    703	pool = kmalloc(sizeof(*pool), GFP_KERNEL);
    704	if (!pool)
    705		goto err;
    706
    707	pool->bpid = bpid;
    708
    709	return pool;
    710err:
    711	bm_release_bpid(bpid);
    712	return NULL;
    713}
    714EXPORT_SYMBOL(bman_new_pool);
    715
    716void bman_free_pool(struct bman_pool *pool)
    717{
    718	bm_release_bpid(pool->bpid);
    719
    720	kfree(pool);
    721}
    722EXPORT_SYMBOL(bman_free_pool);
    723
    724int bman_get_bpid(const struct bman_pool *pool)
    725{
    726	return pool->bpid;
    727}
    728EXPORT_SYMBOL(bman_get_bpid);
    729
    730static void update_rcr_ci(struct bman_portal *p, int avail)
    731{
    732	if (avail)
    733		bm_rcr_cce_prefetch(&p->p);
    734	else
    735		bm_rcr_cce_update(&p->p);
    736}
    737
    738int bman_release(struct bman_pool *pool, const struct bm_buffer *bufs, u8 num)
    739{
    740	struct bman_portal *p;
    741	struct bm_rcr_entry *r;
    742	unsigned long irqflags;
    743	int avail, timeout = 1000; /* 1ms */
    744	int i = num - 1;
    745
    746	DPAA_ASSERT(num > 0 && num <= 8);
    747
    748	do {
    749		p = get_affine_portal();
    750		local_irq_save(irqflags);
    751		avail = bm_rcr_get_avail(&p->p);
    752		if (avail < 2)
    753			update_rcr_ci(p, avail);
    754		r = bm_rcr_start(&p->p);
    755		local_irq_restore(irqflags);
    756		put_affine_portal();
    757		if (likely(r))
    758			break;
    759
    760		udelay(1);
    761	} while (--timeout);
    762
    763	if (unlikely(!timeout))
    764		return -ETIMEDOUT;
    765
    766	p = get_affine_portal();
    767	local_irq_save(irqflags);
    768	/*
    769	 * we can copy all but the first entry, as this can trigger badness
    770	 * with the valid-bit
    771	 */
    772	bm_buffer_set64(r->bufs, bm_buffer_get64(bufs));
    773	bm_buffer_set_bpid(r->bufs, pool->bpid);
    774	if (i)
    775		memcpy(&r->bufs[1], &bufs[1], i * sizeof(bufs[0]));
    776
    777	bm_rcr_pvb_commit(&p->p, BM_RCR_VERB_CMD_BPID_SINGLE |
    778			  (num & BM_RCR_VERB_BUFCOUNT_MASK));
    779
    780	local_irq_restore(irqflags);
    781	put_affine_portal();
    782	return 0;
    783}
    784EXPORT_SYMBOL(bman_release);
    785
    786int bman_acquire(struct bman_pool *pool, struct bm_buffer *bufs, u8 num)
    787{
    788	struct bman_portal *p = get_affine_portal();
    789	struct bm_mc_command *mcc;
    790	union bm_mc_result *mcr;
    791	int ret;
    792
    793	DPAA_ASSERT(num > 0 && num <= 8);
    794
    795	mcc = bm_mc_start(&p->p);
    796	mcc->bpid = pool->bpid;
    797	bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE |
    798		     (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT));
    799	if (!bm_mc_result_timeout(&p->p, &mcr)) {
    800		put_affine_portal();
    801		pr_crit("BMan Acquire Timeout\n");
    802		return -ETIMEDOUT;
    803	}
    804	ret = mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT;
    805	if (bufs)
    806		memcpy(&bufs[0], &mcr->bufs[0], num * sizeof(bufs[0]));
    807
    808	put_affine_portal();
    809	if (ret != num)
    810		ret = -ENOMEM;
    811	return ret;
    812}
    813EXPORT_SYMBOL(bman_acquire);
    814
    815const struct bm_portal_config *
    816bman_get_bm_portal_config(const struct bman_portal *portal)
    817{
    818	return portal->config;
    819}