1*0aeed3e9SJustin Hibbits /******************************************************************************
2*0aeed3e9SJustin Hibbits
3*0aeed3e9SJustin Hibbits � 1995-2003, 2004, 2005-2011 Freescale Semiconductor, Inc.
4*0aeed3e9SJustin Hibbits All rights reserved.
5*0aeed3e9SJustin Hibbits
6*0aeed3e9SJustin Hibbits This is proprietary source code of Freescale Semiconductor Inc.,
7*0aeed3e9SJustin Hibbits and its use is subject to the NetComm Device Drivers EULA.
8*0aeed3e9SJustin Hibbits The copyright notice above does not evidence any actual or intended
9*0aeed3e9SJustin Hibbits publication of such source code.
10*0aeed3e9SJustin Hibbits
11*0aeed3e9SJustin Hibbits ALTERNATIVELY, redistribution and use in source and binary forms, with
12*0aeed3e9SJustin Hibbits or without modification, are permitted provided that the following
13*0aeed3e9SJustin Hibbits conditions are met:
14*0aeed3e9SJustin Hibbits * Redistributions of source code must retain the above copyright
15*0aeed3e9SJustin Hibbits notice, this list of conditions and the following disclaimer.
16*0aeed3e9SJustin Hibbits * Redistributions in binary form must reproduce the above copyright
17*0aeed3e9SJustin Hibbits notice, this list of conditions and the following disclaimer in the
18*0aeed3e9SJustin Hibbits documentation and/or other materials provided with the distribution.
19*0aeed3e9SJustin Hibbits * Neither the name of Freescale Semiconductor nor the
20*0aeed3e9SJustin Hibbits names of its contributors may be used to endorse or promote products
21*0aeed3e9SJustin Hibbits derived from this software without specific prior written permission.
22*0aeed3e9SJustin Hibbits
23*0aeed3e9SJustin Hibbits THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
24*0aeed3e9SJustin Hibbits EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25*0aeed3e9SJustin Hibbits WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26*0aeed3e9SJustin Hibbits DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
27*0aeed3e9SJustin Hibbits DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28*0aeed3e9SJustin Hibbits (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29*0aeed3e9SJustin Hibbits LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30*0aeed3e9SJustin Hibbits ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31*0aeed3e9SJustin Hibbits (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32*0aeed3e9SJustin Hibbits SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*0aeed3e9SJustin Hibbits *
34*0aeed3e9SJustin Hibbits
35*0aeed3e9SJustin Hibbits **************************************************************************/
36*0aeed3e9SJustin Hibbits /******************************************************************************
37*0aeed3e9SJustin Hibbits @File bm.c
38*0aeed3e9SJustin Hibbits
39*0aeed3e9SJustin Hibbits @Description BM
40*0aeed3e9SJustin Hibbits *//***************************************************************************/
41*0aeed3e9SJustin Hibbits #include "error_ext.h"
42*0aeed3e9SJustin Hibbits #include "std_ext.h"
43*0aeed3e9SJustin Hibbits #include "string_ext.h"
44*0aeed3e9SJustin Hibbits #include "mem_ext.h"
45*0aeed3e9SJustin Hibbits #include "core_ext.h"
46*0aeed3e9SJustin Hibbits
47*0aeed3e9SJustin Hibbits #include "bm.h"
48*0aeed3e9SJustin Hibbits
49*0aeed3e9SJustin Hibbits
50*0aeed3e9SJustin Hibbits #define __ERR_MODULE__ MODULE_BM
51*0aeed3e9SJustin Hibbits
52*0aeed3e9SJustin Hibbits
53*0aeed3e9SJustin Hibbits /****************************************/
54*0aeed3e9SJustin Hibbits /* static functions */
55*0aeed3e9SJustin Hibbits /****************************************/
56*0aeed3e9SJustin Hibbits
57*0aeed3e9SJustin Hibbits static uint32_t __poll_portal_slow(t_BmPortal *p);
58*0aeed3e9SJustin Hibbits static void __poll_portal_fast(t_BmPortal *p);
59*0aeed3e9SJustin Hibbits
60*0aeed3e9SJustin Hibbits /* Portal interrupt handler */
portal_isr(void * ptr)61*0aeed3e9SJustin Hibbits static void portal_isr(void *ptr)
62*0aeed3e9SJustin Hibbits {
63*0aeed3e9SJustin Hibbits t_BmPortal *portal = ptr;
64*0aeed3e9SJustin Hibbits /* Only do fast-path handling if it's required */
65*0aeed3e9SJustin Hibbits if (portal->flags & BMAN_PORTAL_FLAG_IRQ_FAST)
66*0aeed3e9SJustin Hibbits __poll_portal_fast(portal);
67*0aeed3e9SJustin Hibbits __poll_portal_slow(portal);
68*0aeed3e9SJustin Hibbits
69*0aeed3e9SJustin Hibbits }
70*0aeed3e9SJustin Hibbits
71*0aeed3e9SJustin Hibbits /**
72*0aeed3e9SJustin Hibbits * bman_create_portal - Manage a Bman s/w portal
73*0aeed3e9SJustin Hibbits * @portal: the s/w corenet portal to use
74*0aeed3e9SJustin Hibbits * @flags: bit-mask of BMAN_PORTAL_FLAG_*** options
75*0aeed3e9SJustin Hibbits * @pools: bit-array of buffer pools available to this portal
76*0aeed3e9SJustin Hibbits * @portal_ctx: opaque user-supplied data to be associated with the portal
77*0aeed3e9SJustin Hibbits *
78*0aeed3e9SJustin Hibbits * Creates a managed portal object. @irq is only used if @flags specifies
79*0aeed3e9SJustin Hibbits * BMAN_PORTAL_FLAG_IRQ. @pools is copied, so the caller can do as they please
80*0aeed3e9SJustin Hibbits * with it after the function returns. It will only be possible to configure
81*0aeed3e9SJustin Hibbits * buffer pool objects as "suppliers" if they are specified in @pools, and the
82*0aeed3e9SJustin Hibbits * driver will only track depletion state changes to the same subset of buffer
83*0aeed3e9SJustin Hibbits * pools. If @pools is NULL, buffer pool depletion state will not be tracked.
84*0aeed3e9SJustin Hibbits * If the BMAN_PORTAL_FLAG_RECOVER flag is specified, then the function will
85*0aeed3e9SJustin Hibbits * attempt to expire any existing RCR entries, otherwise the function will fail
86*0aeed3e9SJustin Hibbits * if RCR is non-empty. If the BMAN_PORTAL_FLAG_WAIT flag is set, the function
87*0aeed3e9SJustin Hibbits * is allowed to block waiting for expiration of RCR. BMAN_PORTAL_FLAG_WAIT_INT
88*0aeed3e9SJustin Hibbits * makes any blocking interruptible.
89*0aeed3e9SJustin Hibbits */
90*0aeed3e9SJustin Hibbits
bman_create_portal(t_BmPortal * p_BmPortal,uint32_t flags,const struct bman_depletion * pools)91*0aeed3e9SJustin Hibbits static t_Error bman_create_portal(t_BmPortal *p_BmPortal,
92*0aeed3e9SJustin Hibbits uint32_t flags,
93*0aeed3e9SJustin Hibbits const struct bman_depletion *pools)
94*0aeed3e9SJustin Hibbits {
95*0aeed3e9SJustin Hibbits int ret = 0;
96*0aeed3e9SJustin Hibbits uint8_t bpid = 0;
97*0aeed3e9SJustin Hibbits e_BmPortalRcrConsumeMode rcr_cmode;
98*0aeed3e9SJustin Hibbits e_BmPortalProduceMode pmode;
99*0aeed3e9SJustin Hibbits
100*0aeed3e9SJustin Hibbits pmode = e_BmPortalPVB;
101*0aeed3e9SJustin Hibbits rcr_cmode = (flags & BMAN_PORTAL_FLAG_CACHE) ? e_BmPortalRcrCCE : e_BmPortalRcrCCI;
102*0aeed3e9SJustin Hibbits
103*0aeed3e9SJustin Hibbits switch (pmode)
104*0aeed3e9SJustin Hibbits {
105*0aeed3e9SJustin Hibbits case e_BmPortalPCI:
106*0aeed3e9SJustin Hibbits p_BmPortal->cbs[BM_RCR_RING].f_BmCommitCb = bm_rcr_pci_commit;
107*0aeed3e9SJustin Hibbits break;
108*0aeed3e9SJustin Hibbits case e_BmPortalPCE:
109*0aeed3e9SJustin Hibbits p_BmPortal->cbs[BM_RCR_RING].f_BmCommitCb = bm_rcr_pce_commit;
110*0aeed3e9SJustin Hibbits break;
111*0aeed3e9SJustin Hibbits case e_BmPortalPVB:
112*0aeed3e9SJustin Hibbits p_BmPortal->cbs[BM_RCR_RING].f_BmCommitCb = bm_rcr_pvb_commit;
113*0aeed3e9SJustin Hibbits break;
114*0aeed3e9SJustin Hibbits }
115*0aeed3e9SJustin Hibbits switch (rcr_cmode)
116*0aeed3e9SJustin Hibbits {
117*0aeed3e9SJustin Hibbits case e_BmPortalRcrCCI:
118*0aeed3e9SJustin Hibbits p_BmPortal->cbs[BM_RCR_RING].f_BmUpdateCb = bm_rcr_cci_update;
119*0aeed3e9SJustin Hibbits p_BmPortal->cbs[BM_RCR_RING].f_BmPrefetchCb = NULL;
120*0aeed3e9SJustin Hibbits break;
121*0aeed3e9SJustin Hibbits case e_BmPortalRcrCCE:
122*0aeed3e9SJustin Hibbits p_BmPortal->cbs[BM_RCR_RING].f_BmUpdateCb = bm_rcr_cce_update;
123*0aeed3e9SJustin Hibbits p_BmPortal->cbs[BM_RCR_RING].f_BmPrefetchCb = bm_rcr_cce_prefetch;
124*0aeed3e9SJustin Hibbits break;
125*0aeed3e9SJustin Hibbits }
126*0aeed3e9SJustin Hibbits
127*0aeed3e9SJustin Hibbits if (bm_rcr_init(p_BmPortal->p_BmPortalLow, pmode, rcr_cmode)) {
128*0aeed3e9SJustin Hibbits REPORT_ERROR(MAJOR, E_INVALID_STATE, ("RCR initialization failed"));
129*0aeed3e9SJustin Hibbits goto fail_rcr;
130*0aeed3e9SJustin Hibbits }
131*0aeed3e9SJustin Hibbits if (bm_mc_init(p_BmPortal->p_BmPortalLow)) {
132*0aeed3e9SJustin Hibbits REPORT_ERROR(MAJOR, E_INVALID_STATE, ("MC initialization failed"));
133*0aeed3e9SJustin Hibbits goto fail_mc;
134*0aeed3e9SJustin Hibbits }
135*0aeed3e9SJustin Hibbits p_BmPortal->pools[0] = *pools;
136*0aeed3e9SJustin Hibbits bman_depletion_init(&p_BmPortal->pools[1]);
137*0aeed3e9SJustin Hibbits while (bpid < BM_MAX_NUM_OF_POOLS) {
138*0aeed3e9SJustin Hibbits /* Default to all BPIDs disabled, we enable as required
139*0aeed3e9SJustin Hibbits * at run-time. */
140*0aeed3e9SJustin Hibbits bm_isr_bscn_mask(p_BmPortal->p_BmPortalLow, bpid, 0);
141*0aeed3e9SJustin Hibbits bpid++;
142*0aeed3e9SJustin Hibbits }
143*0aeed3e9SJustin Hibbits p_BmPortal->flags = flags;
144*0aeed3e9SJustin Hibbits p_BmPortal->slowpoll = 0;
145*0aeed3e9SJustin Hibbits p_BmPortal->rcrProd = p_BmPortal->rcrCons = 0;
146*0aeed3e9SJustin Hibbits memset(&p_BmPortal->depletionPoolsTable, 0, sizeof(p_BmPortal->depletionPoolsTable));
147*0aeed3e9SJustin Hibbits /* Write-to-clear any stale interrupt status bits */
148*0aeed3e9SJustin Hibbits bm_isr_disable_write(p_BmPortal->p_BmPortalLow, 0xffffffff);
149*0aeed3e9SJustin Hibbits bm_isr_status_clear(p_BmPortal->p_BmPortalLow, 0xffffffff);
150*0aeed3e9SJustin Hibbits bm_isr_enable_write(p_BmPortal->p_BmPortalLow, BM_PIRQ_RCRI | BM_PIRQ_BSCN);
151*0aeed3e9SJustin Hibbits if (flags & BMAN_PORTAL_FLAG_IRQ)
152*0aeed3e9SJustin Hibbits {
153*0aeed3e9SJustin Hibbits XX_SetIntr(p_BmPortal->irq, portal_isr, p_BmPortal);
154*0aeed3e9SJustin Hibbits XX_EnableIntr(p_BmPortal->irq);
155*0aeed3e9SJustin Hibbits /* Enable the bits that make sense */
156*0aeed3e9SJustin Hibbits bm_isr_uninhibit(p_BmPortal->p_BmPortalLow);
157*0aeed3e9SJustin Hibbits } else
158*0aeed3e9SJustin Hibbits /* without IRQ, we can't block */
159*0aeed3e9SJustin Hibbits flags &= ~BMAN_PORTAL_FLAG_WAIT;
160*0aeed3e9SJustin Hibbits /* Need RCR to be empty before continuing */
161*0aeed3e9SJustin Hibbits bm_isr_disable_write(p_BmPortal->p_BmPortalLow, (uint32_t)~BM_PIRQ_RCRI);
162*0aeed3e9SJustin Hibbits if (!(flags & BMAN_PORTAL_FLAG_RECOVER) ||
163*0aeed3e9SJustin Hibbits !(flags & BMAN_PORTAL_FLAG_WAIT))
164*0aeed3e9SJustin Hibbits ret = bm_rcr_get_fill(p_BmPortal->p_BmPortalLow);
165*0aeed3e9SJustin Hibbits if (ret) {
166*0aeed3e9SJustin Hibbits REPORT_ERROR(MAJOR, E_INVALID_STATE, ("RCR unclean, need recovery"));
167*0aeed3e9SJustin Hibbits goto fail_rcr_empty;
168*0aeed3e9SJustin Hibbits }
169*0aeed3e9SJustin Hibbits bm_isr_disable_write(p_BmPortal->p_BmPortalLow, 0);
170*0aeed3e9SJustin Hibbits return E_OK;
171*0aeed3e9SJustin Hibbits fail_rcr_empty:
172*0aeed3e9SJustin Hibbits bm_mc_finish(p_BmPortal->p_BmPortalLow);
173*0aeed3e9SJustin Hibbits fail_mc:
174*0aeed3e9SJustin Hibbits bm_rcr_finish(p_BmPortal->p_BmPortalLow);
175*0aeed3e9SJustin Hibbits fail_rcr:
176*0aeed3e9SJustin Hibbits XX_Free(p_BmPortal);
177*0aeed3e9SJustin Hibbits return ERROR_CODE(E_INVALID_STATE);
178*0aeed3e9SJustin Hibbits }
179*0aeed3e9SJustin Hibbits
bman_destroy_portal(t_BmPortal * p_BmPortal)180*0aeed3e9SJustin Hibbits static void bman_destroy_portal(t_BmPortal* p_BmPortal)
181*0aeed3e9SJustin Hibbits {
182*0aeed3e9SJustin Hibbits BmUpdate(p_BmPortal, BM_RCR_RING);
183*0aeed3e9SJustin Hibbits if (p_BmPortal->flags & BMAN_PORTAL_FLAG_IRQ)
184*0aeed3e9SJustin Hibbits {
185*0aeed3e9SJustin Hibbits XX_DisableIntr(p_BmPortal->irq);
186*0aeed3e9SJustin Hibbits XX_FreeIntr(p_BmPortal->irq);
187*0aeed3e9SJustin Hibbits }
188*0aeed3e9SJustin Hibbits bm_mc_finish(p_BmPortal->p_BmPortalLow);
189*0aeed3e9SJustin Hibbits bm_rcr_finish(p_BmPortal->p_BmPortalLow);
190*0aeed3e9SJustin Hibbits XX_Free(p_BmPortal->p_BmPortalLow);
191*0aeed3e9SJustin Hibbits }
192*0aeed3e9SJustin Hibbits
193*0aeed3e9SJustin Hibbits /* When release logic waits on available RCR space, we need a global waitqueue
194*0aeed3e9SJustin Hibbits * in the case of "affine" use (as the waits wake on different cpus which means
195*0aeed3e9SJustin Hibbits * different portals - so we can't wait on any per-portal waitqueue). */
196*0aeed3e9SJustin Hibbits
__poll_portal_slow(t_BmPortal * p_BmPortal)197*0aeed3e9SJustin Hibbits static uint32_t __poll_portal_slow(t_BmPortal* p_BmPortal)
198*0aeed3e9SJustin Hibbits {
199*0aeed3e9SJustin Hibbits struct bman_depletion tmp;
200*0aeed3e9SJustin Hibbits t_BmPool *p_BmPool;
201*0aeed3e9SJustin Hibbits uint32_t ret,is = bm_isr_status_read(p_BmPortal->p_BmPortalLow);
202*0aeed3e9SJustin Hibbits ret = is;
203*0aeed3e9SJustin Hibbits
204*0aeed3e9SJustin Hibbits /* There is a gotcha to be aware of. If we do the query before clearing
205*0aeed3e9SJustin Hibbits * the status register, we may miss state changes that occur between the
206*0aeed3e9SJustin Hibbits * two. If we write to clear the status register before the query, the
207*0aeed3e9SJustin Hibbits * cache-enabled query command may overtake the status register write
208*0aeed3e9SJustin Hibbits * unless we use a heavyweight sync (which we don't want). Instead, we
209*0aeed3e9SJustin Hibbits * write-to-clear the status register then *read it back* before doing
210*0aeed3e9SJustin Hibbits * the query, hence the odd while loop with the 'is' accumulation. */
211*0aeed3e9SJustin Hibbits if (is & BM_PIRQ_BSCN) {
212*0aeed3e9SJustin Hibbits uint32_t i, j;
213*0aeed3e9SJustin Hibbits uint32_t __is;
214*0aeed3e9SJustin Hibbits bm_isr_status_clear(p_BmPortal->p_BmPortalLow, BM_PIRQ_BSCN);
215*0aeed3e9SJustin Hibbits while ((__is = bm_isr_status_read(p_BmPortal->p_BmPortalLow)) & BM_PIRQ_BSCN) {
216*0aeed3e9SJustin Hibbits is |= __is;
217*0aeed3e9SJustin Hibbits bm_isr_status_clear(p_BmPortal->p_BmPortalLow, BM_PIRQ_BSCN);
218*0aeed3e9SJustin Hibbits }
219*0aeed3e9SJustin Hibbits is &= ~BM_PIRQ_BSCN;
220*0aeed3e9SJustin Hibbits BmPortalQuery(p_BmPortal, &tmp, TRUE);
221*0aeed3e9SJustin Hibbits for (i = 0; i < 2; i++) {
222*0aeed3e9SJustin Hibbits uint32_t idx = i * 32;
223*0aeed3e9SJustin Hibbits /* tmp is a mask of currently-depleted pools.
224*0aeed3e9SJustin Hibbits * pools[0] is mask of those we care about.
225*0aeed3e9SJustin Hibbits * pools[1] is our previous view (we only want to
226*0aeed3e9SJustin Hibbits * be told about changes). */
227*0aeed3e9SJustin Hibbits tmp.__state[i] &= p_BmPortal->pools[0].__state[i];
228*0aeed3e9SJustin Hibbits if (tmp.__state[i] == p_BmPortal->pools[1].__state[i])
229*0aeed3e9SJustin Hibbits /* fast-path, nothing to see, move along */
230*0aeed3e9SJustin Hibbits continue;
231*0aeed3e9SJustin Hibbits for (j = 0; j <= 31; j++, idx++) {
232*0aeed3e9SJustin Hibbits int b4 = bman_depletion_get(&p_BmPortal->pools[1], (uint8_t)idx);
233*0aeed3e9SJustin Hibbits int af = bman_depletion_get(&tmp, (uint8_t)idx);
234*0aeed3e9SJustin Hibbits if (b4 == af)
235*0aeed3e9SJustin Hibbits continue;
236*0aeed3e9SJustin Hibbits p_BmPool = p_BmPortal->depletionPoolsTable[idx];
237*0aeed3e9SJustin Hibbits ASSERT_COND(p_BmPool->f_Depletion);
238*0aeed3e9SJustin Hibbits p_BmPool->f_Depletion(p_BmPool->h_App, (bool)af);
239*0aeed3e9SJustin Hibbits }
240*0aeed3e9SJustin Hibbits }
241*0aeed3e9SJustin Hibbits p_BmPortal->pools[1] = tmp;
242*0aeed3e9SJustin Hibbits }
243*0aeed3e9SJustin Hibbits
244*0aeed3e9SJustin Hibbits if (is & BM_PIRQ_RCRI) {
245*0aeed3e9SJustin Hibbits NCSW_PLOCK(p_BmPortal);
246*0aeed3e9SJustin Hibbits p_BmPortal->rcrCons += BmUpdate(p_BmPortal, BM_RCR_RING);
247*0aeed3e9SJustin Hibbits bm_rcr_set_ithresh(p_BmPortal->p_BmPortalLow, 0);
248*0aeed3e9SJustin Hibbits PUNLOCK(p_BmPortal);
249*0aeed3e9SJustin Hibbits bm_isr_status_clear(p_BmPortal->p_BmPortalLow, BM_PIRQ_RCRI);
250*0aeed3e9SJustin Hibbits is &= ~BM_PIRQ_RCRI;
251*0aeed3e9SJustin Hibbits }
252*0aeed3e9SJustin Hibbits
253*0aeed3e9SJustin Hibbits /* There should be no status register bits left undefined */
254*0aeed3e9SJustin Hibbits ASSERT_COND(!is);
255*0aeed3e9SJustin Hibbits return ret;
256*0aeed3e9SJustin Hibbits }
257*0aeed3e9SJustin Hibbits
__poll_portal_fast(t_BmPortal * p_BmPortal)258*0aeed3e9SJustin Hibbits static void __poll_portal_fast(t_BmPortal* p_BmPortal)
259*0aeed3e9SJustin Hibbits {
260*0aeed3e9SJustin Hibbits UNUSED(p_BmPortal);
261*0aeed3e9SJustin Hibbits /* nothing yet, this is where we'll put optimised RCR consumption
262*0aeed3e9SJustin Hibbits * tracking */
263*0aeed3e9SJustin Hibbits }
264*0aeed3e9SJustin Hibbits
265*0aeed3e9SJustin Hibbits
rel_set_thresh(t_BmPortal * p_BmPortal,int check)266*0aeed3e9SJustin Hibbits static __inline__ void rel_set_thresh(t_BmPortal *p_BmPortal, int check)
267*0aeed3e9SJustin Hibbits {
268*0aeed3e9SJustin Hibbits if (!check || !bm_rcr_get_ithresh(p_BmPortal->p_BmPortalLow))
269*0aeed3e9SJustin Hibbits bm_rcr_set_ithresh(p_BmPortal->p_BmPortalLow, RCR_ITHRESH);
270*0aeed3e9SJustin Hibbits }
271*0aeed3e9SJustin Hibbits
272*0aeed3e9SJustin Hibbits /* Used as a wait_event() expression. If it returns non-NULL, any lock will
273*0aeed3e9SJustin Hibbits * remain held. */
try_rel_start(t_BmPortal * p_BmPortal)274*0aeed3e9SJustin Hibbits static struct bm_rcr_entry *try_rel_start(t_BmPortal *p_BmPortal)
275*0aeed3e9SJustin Hibbits {
276*0aeed3e9SJustin Hibbits struct bm_rcr_entry *r;
277*0aeed3e9SJustin Hibbits
278*0aeed3e9SJustin Hibbits NCSW_PLOCK(p_BmPortal);
279*0aeed3e9SJustin Hibbits if (bm_rcr_get_avail((p_BmPortal)->p_BmPortalLow) < RCR_THRESH)
280*0aeed3e9SJustin Hibbits BmUpdate(p_BmPortal, BM_RCR_RING);
281*0aeed3e9SJustin Hibbits r = bm_rcr_start((p_BmPortal)->p_BmPortalLow);
282*0aeed3e9SJustin Hibbits if (!r) {
283*0aeed3e9SJustin Hibbits rel_set_thresh(p_BmPortal, 1);
284*0aeed3e9SJustin Hibbits PUNLOCK(p_BmPortal);
285*0aeed3e9SJustin Hibbits }
286*0aeed3e9SJustin Hibbits return r;
287*0aeed3e9SJustin Hibbits }
288*0aeed3e9SJustin Hibbits
wait_rel_start(t_BmPortal * p_BmPortal,struct bm_rcr_entry ** rel,uint32_t flags)289*0aeed3e9SJustin Hibbits static __inline__ t_Error wait_rel_start(t_BmPortal *p_BmPortal,
290*0aeed3e9SJustin Hibbits struct bm_rcr_entry **rel,
291*0aeed3e9SJustin Hibbits uint32_t flags)
292*0aeed3e9SJustin Hibbits {
293*0aeed3e9SJustin Hibbits int tries = 100;
294*0aeed3e9SJustin Hibbits
295*0aeed3e9SJustin Hibbits UNUSED(flags);
296*0aeed3e9SJustin Hibbits do {
297*0aeed3e9SJustin Hibbits *rel = try_rel_start(p_BmPortal);
298*0aeed3e9SJustin Hibbits XX_Sleep(1);
299*0aeed3e9SJustin Hibbits } while (!*rel && --tries);
300*0aeed3e9SJustin Hibbits
301*0aeed3e9SJustin Hibbits if (!(*rel))
302*0aeed3e9SJustin Hibbits return ERROR_CODE(E_BUSY);
303*0aeed3e9SJustin Hibbits
304*0aeed3e9SJustin Hibbits return E_OK;
305*0aeed3e9SJustin Hibbits }
306*0aeed3e9SJustin Hibbits
307*0aeed3e9SJustin Hibbits /* This copies Qman's eqcr_completed() routine, see that for details */
rel_completed(t_BmPortal * p_BmPortal,uint32_t rcr_poll)308*0aeed3e9SJustin Hibbits static int rel_completed(t_BmPortal *p_BmPortal, uint32_t rcr_poll)
309*0aeed3e9SJustin Hibbits {
310*0aeed3e9SJustin Hibbits uint32_t tr_cons = p_BmPortal->rcrCons;
311*0aeed3e9SJustin Hibbits if (rcr_poll & 0xc0000000) {
312*0aeed3e9SJustin Hibbits rcr_poll &= 0x7fffffff;
313*0aeed3e9SJustin Hibbits tr_cons ^= 0x80000000;
314*0aeed3e9SJustin Hibbits }
315*0aeed3e9SJustin Hibbits if (tr_cons >= rcr_poll)
316*0aeed3e9SJustin Hibbits return 1;
317*0aeed3e9SJustin Hibbits if ((rcr_poll - tr_cons) > BM_RCR_SIZE)
318*0aeed3e9SJustin Hibbits return 1;
319*0aeed3e9SJustin Hibbits if (!bm_rcr_get_fill(p_BmPortal->p_BmPortalLow))
320*0aeed3e9SJustin Hibbits /* If RCR is empty, we must have completed */
321*0aeed3e9SJustin Hibbits return 1;
322*0aeed3e9SJustin Hibbits rel_set_thresh(p_BmPortal, 0);
323*0aeed3e9SJustin Hibbits return 0;
324*0aeed3e9SJustin Hibbits }
325*0aeed3e9SJustin Hibbits
rel_commit(t_BmPortal * p_BmPortal,uint32_t flags,uint8_t num)326*0aeed3e9SJustin Hibbits static __inline__ void rel_commit(t_BmPortal *p_BmPortal, uint32_t flags,uint8_t num)
327*0aeed3e9SJustin Hibbits {
328*0aeed3e9SJustin Hibbits uint32_t rcr_poll;
329*0aeed3e9SJustin Hibbits
330*0aeed3e9SJustin Hibbits BmCommit(p_BmPortal, BM_RCR_RING, (uint8_t)(BM_RCR_VERB_CMD_BPID_SINGLE | (num & BM_RCR_VERB_BUFCOUNT_MASK)));
331*0aeed3e9SJustin Hibbits /* increment the producer count and capture it for SYNC */
332*0aeed3e9SJustin Hibbits rcr_poll = ++p_BmPortal->rcrProd;
333*0aeed3e9SJustin Hibbits if ((flags & BMAN_RELEASE_FLAG_WAIT_SYNC) ==
334*0aeed3e9SJustin Hibbits BMAN_RELEASE_FLAG_WAIT_SYNC)
335*0aeed3e9SJustin Hibbits rel_set_thresh(p_BmPortal, 1);
336*0aeed3e9SJustin Hibbits PUNLOCK(p_BmPortal);
337*0aeed3e9SJustin Hibbits if ((flags & BMAN_RELEASE_FLAG_WAIT_SYNC) !=
338*0aeed3e9SJustin Hibbits BMAN_RELEASE_FLAG_WAIT_SYNC)
339*0aeed3e9SJustin Hibbits return;
340*0aeed3e9SJustin Hibbits rel_completed(p_BmPortal, rcr_poll);
341*0aeed3e9SJustin Hibbits }
342*0aeed3e9SJustin Hibbits
343*0aeed3e9SJustin Hibbits
344*0aeed3e9SJustin Hibbits /****************************************/
345*0aeed3e9SJustin Hibbits /* Inter-Module functions */
346*0aeed3e9SJustin Hibbits /****************************************/
347*0aeed3e9SJustin Hibbits
348*0aeed3e9SJustin Hibbits /**
349*0aeed3e9SJustin Hibbits * bman_release - Release buffer(s) to the buffer pool
350*0aeed3e9SJustin Hibbits * @p_BmPool: the buffer pool object to release to
351*0aeed3e9SJustin Hibbits * @bufs: an array of buffers to release
352*0aeed3e9SJustin Hibbits * @num: the number of buffers in @bufs (1-8)
353*0aeed3e9SJustin Hibbits * @flags: bit-mask of BMAN_RELEASE_FLAG_*** options
354*0aeed3e9SJustin Hibbits *
355*0aeed3e9SJustin Hibbits * Adds the given buffers to RCR entries. If the portal @p_BmPortal was created with the
356*0aeed3e9SJustin Hibbits * "COMPACT" flag, then it will be using a compaction algorithm to improve
357*0aeed3e9SJustin Hibbits * utilization of RCR. As such, these buffers may join an existing ring entry
358*0aeed3e9SJustin Hibbits * and/or it may not be issued right away so as to allow future releases to join
359*0aeed3e9SJustin Hibbits * the same ring entry. Use the BMAN_RELEASE_FLAG_NOW flag to override this
360*0aeed3e9SJustin Hibbits * behavior by committing the RCR entry (or entries) right away. If the RCR
361*0aeed3e9SJustin Hibbits * ring is full, the function will return -EBUSY unless BMAN_RELEASE_FLAG_WAIT
362*0aeed3e9SJustin Hibbits * is selected, in which case it will sleep waiting for space to become
363*0aeed3e9SJustin Hibbits * available in RCR. If the function receives a signal before such time (and
364*0aeed3e9SJustin Hibbits * BMAN_RELEASE_FLAG_WAIT_INT is set), the function returns -EINTR. Otherwise,
365*0aeed3e9SJustin Hibbits * it returns zero.
366*0aeed3e9SJustin Hibbits */
367*0aeed3e9SJustin Hibbits
BmPortalRelease(t_Handle h_BmPortal,uint8_t bpid,struct bm_buffer * bufs,uint8_t num,uint32_t flags)368*0aeed3e9SJustin Hibbits t_Error BmPortalRelease(t_Handle h_BmPortal,
369*0aeed3e9SJustin Hibbits uint8_t bpid,
370*0aeed3e9SJustin Hibbits struct bm_buffer *bufs,
371*0aeed3e9SJustin Hibbits uint8_t num,
372*0aeed3e9SJustin Hibbits uint32_t flags)
373*0aeed3e9SJustin Hibbits {
374*0aeed3e9SJustin Hibbits t_BmPortal *p_BmPortal = (t_BmPortal *)h_BmPortal;
375*0aeed3e9SJustin Hibbits struct bm_rcr_entry *r;
376*0aeed3e9SJustin Hibbits uint8_t i;
377*0aeed3e9SJustin Hibbits
378*0aeed3e9SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_BmPortal, E_INVALID_HANDLE);
379*0aeed3e9SJustin Hibbits /* TODO: I'm ignoring BMAN_PORTAL_FLAG_COMPACT for now. */
380*0aeed3e9SJustin Hibbits r = try_rel_start(p_BmPortal);
381*0aeed3e9SJustin Hibbits if (!r) {
382*0aeed3e9SJustin Hibbits if (flags & BMAN_RELEASE_FLAG_WAIT) {
383*0aeed3e9SJustin Hibbits t_Error ret = wait_rel_start(p_BmPortal, &r, flags);
384*0aeed3e9SJustin Hibbits if (ret)
385*0aeed3e9SJustin Hibbits return ret;
386*0aeed3e9SJustin Hibbits } else
387*0aeed3e9SJustin Hibbits return ERROR_CODE(E_BUSY);
388*0aeed3e9SJustin Hibbits ASSERT_COND(r != NULL);
389*0aeed3e9SJustin Hibbits }
390*0aeed3e9SJustin Hibbits r->bpid = bpid;
391*0aeed3e9SJustin Hibbits for (i = 0; i < num; i++) {
392*0aeed3e9SJustin Hibbits r->bufs[i].hi = bufs[i].hi;
393*0aeed3e9SJustin Hibbits r->bufs[i].lo = bufs[i].lo;
394*0aeed3e9SJustin Hibbits }
395*0aeed3e9SJustin Hibbits /* Issue the release command and wait for sync if requested. NB: the
396*0aeed3e9SJustin Hibbits * commit can't fail, only waiting can. Don't propagate any failure if a
397*0aeed3e9SJustin Hibbits * signal arrives, otherwise the caller can't distinguish whether the
398*0aeed3e9SJustin Hibbits * release was issued or not. Code for user-space can check
399*0aeed3e9SJustin Hibbits * signal_pending() after we return. */
400*0aeed3e9SJustin Hibbits rel_commit(p_BmPortal, flags, num);
401*0aeed3e9SJustin Hibbits return E_OK;
402*0aeed3e9SJustin Hibbits }
403*0aeed3e9SJustin Hibbits
BmPortalAcquire(t_Handle h_BmPortal,uint8_t bpid,struct bm_buffer * bufs,uint8_t num)404*0aeed3e9SJustin Hibbits uint8_t BmPortalAcquire(t_Handle h_BmPortal,
405*0aeed3e9SJustin Hibbits uint8_t bpid,
406*0aeed3e9SJustin Hibbits struct bm_buffer *bufs,
407*0aeed3e9SJustin Hibbits uint8_t num)
408*0aeed3e9SJustin Hibbits {
409*0aeed3e9SJustin Hibbits t_BmPortal *p_BmPortal = (t_BmPortal *)h_BmPortal;
410*0aeed3e9SJustin Hibbits struct bm_mc_command *mcc;
411*0aeed3e9SJustin Hibbits struct bm_mc_result *mcr;
412*0aeed3e9SJustin Hibbits uint8_t ret = 0;
413*0aeed3e9SJustin Hibbits
414*0aeed3e9SJustin Hibbits SANITY_CHECK_RETURN_VALUE(p_BmPortal, E_INVALID_HANDLE, 0);
415*0aeed3e9SJustin Hibbits NCSW_PLOCK(p_BmPortal);
416*0aeed3e9SJustin Hibbits mcc = bm_mc_start(p_BmPortal->p_BmPortalLow);
417*0aeed3e9SJustin Hibbits mcc->acquire.bpid = bpid;
418*0aeed3e9SJustin Hibbits bm_mc_commit(p_BmPortal->p_BmPortalLow,
419*0aeed3e9SJustin Hibbits (uint8_t)(BM_MCC_VERB_CMD_ACQUIRE |
420*0aeed3e9SJustin Hibbits (num & BM_MCC_VERB_ACQUIRE_BUFCOUNT)));
421*0aeed3e9SJustin Hibbits while (!(mcr = bm_mc_result(p_BmPortal->p_BmPortalLow))) ;
422*0aeed3e9SJustin Hibbits ret = num = (uint8_t)(mcr->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT);
423*0aeed3e9SJustin Hibbits ASSERT_COND(num <= 8);
424*0aeed3e9SJustin Hibbits while (num--) {
425*0aeed3e9SJustin Hibbits bufs[num].bpid = bpid;
426*0aeed3e9SJustin Hibbits bufs[num].hi = mcr->acquire.bufs[num].hi;
427*0aeed3e9SJustin Hibbits bufs[num].lo = mcr->acquire.bufs[num].lo;
428*0aeed3e9SJustin Hibbits }
429*0aeed3e9SJustin Hibbits PUNLOCK(p_BmPortal);
430*0aeed3e9SJustin Hibbits return ret;
431*0aeed3e9SJustin Hibbits }
432*0aeed3e9SJustin Hibbits
BmPortalQuery(t_Handle h_BmPortal,struct bman_depletion * p_Pools,bool depletion)433*0aeed3e9SJustin Hibbits t_Error BmPortalQuery(t_Handle h_BmPortal, struct bman_depletion *p_Pools, bool depletion)
434*0aeed3e9SJustin Hibbits {
435*0aeed3e9SJustin Hibbits t_BmPortal *p_BmPortal = (t_BmPortal *)h_BmPortal;
436*0aeed3e9SJustin Hibbits struct bm_mc_result *mcr;
437*0aeed3e9SJustin Hibbits
438*0aeed3e9SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_BmPortal, E_INVALID_HANDLE);
439*0aeed3e9SJustin Hibbits
440*0aeed3e9SJustin Hibbits NCSW_PLOCK(p_BmPortal);
441*0aeed3e9SJustin Hibbits bm_mc_start(p_BmPortal->p_BmPortalLow);
442*0aeed3e9SJustin Hibbits bm_mc_commit(p_BmPortal->p_BmPortalLow, BM_MCC_VERB_CMD_QUERY);
443*0aeed3e9SJustin Hibbits while (!(mcr = bm_mc_result(p_BmPortal->p_BmPortalLow))) ;
444*0aeed3e9SJustin Hibbits if (depletion)
445*0aeed3e9SJustin Hibbits *p_Pools = mcr->query.ds.state;
446*0aeed3e9SJustin Hibbits else
447*0aeed3e9SJustin Hibbits *p_Pools = mcr->query.as.state;
448*0aeed3e9SJustin Hibbits PUNLOCK(p_BmPortal);
449*0aeed3e9SJustin Hibbits return E_OK;
450*0aeed3e9SJustin Hibbits }
451*0aeed3e9SJustin Hibbits
452*0aeed3e9SJustin Hibbits /****************************************/
453*0aeed3e9SJustin Hibbits /* API Init unit functions */
454*0aeed3e9SJustin Hibbits /****************************************/
455*0aeed3e9SJustin Hibbits
BM_PORTAL_Config(t_BmPortalParam * p_BmPortalParam)456*0aeed3e9SJustin Hibbits t_Handle BM_PORTAL_Config(t_BmPortalParam *p_BmPortalParam)
457*0aeed3e9SJustin Hibbits {
458*0aeed3e9SJustin Hibbits t_BmPortal *p_BmPortal;
459*0aeed3e9SJustin Hibbits
460*0aeed3e9SJustin Hibbits SANITY_CHECK_RETURN_VALUE(p_BmPortalParam, E_INVALID_HANDLE, NULL);
461*0aeed3e9SJustin Hibbits SANITY_CHECK_RETURN_VALUE(p_BmPortalParam->h_Bm, E_INVALID_HANDLE, NULL);
462*0aeed3e9SJustin Hibbits
463*0aeed3e9SJustin Hibbits p_BmPortal = (t_BmPortal *)XX_Malloc(sizeof(t_BmPortal));
464*0aeed3e9SJustin Hibbits if (!p_BmPortal)
465*0aeed3e9SJustin Hibbits {
466*0aeed3e9SJustin Hibbits REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm Portal obj!!!"));
467*0aeed3e9SJustin Hibbits return NULL;
468*0aeed3e9SJustin Hibbits }
469*0aeed3e9SJustin Hibbits memset(p_BmPortal, 0, sizeof(t_BmPortal));
470*0aeed3e9SJustin Hibbits
471*0aeed3e9SJustin Hibbits p_BmPortal->p_BmPortalLow = (struct bm_portal *)XX_Malloc(sizeof(struct bm_portal));
472*0aeed3e9SJustin Hibbits if (!p_BmPortal->p_BmPortalLow)
473*0aeed3e9SJustin Hibbits {
474*0aeed3e9SJustin Hibbits XX_Free(p_BmPortal);
475*0aeed3e9SJustin Hibbits REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Low bm portal obj!!!"));
476*0aeed3e9SJustin Hibbits return NULL;
477*0aeed3e9SJustin Hibbits }
478*0aeed3e9SJustin Hibbits memset(p_BmPortal->p_BmPortalLow, 0, sizeof(struct bm_portal));
479*0aeed3e9SJustin Hibbits
480*0aeed3e9SJustin Hibbits p_BmPortal->p_BmPortalDriverParams = (t_BmPortalDriverParams *)XX_Malloc(sizeof(t_BmPortalDriverParams));
481*0aeed3e9SJustin Hibbits if (!p_BmPortal->p_BmPortalDriverParams)
482*0aeed3e9SJustin Hibbits {
483*0aeed3e9SJustin Hibbits XX_Free(p_BmPortal);
484*0aeed3e9SJustin Hibbits XX_Free(p_BmPortal->p_BmPortalLow);
485*0aeed3e9SJustin Hibbits REPORT_ERROR(MAJOR, E_NO_MEMORY, ("Bm Portal driver parameters"));
486*0aeed3e9SJustin Hibbits return NULL;
487*0aeed3e9SJustin Hibbits }
488*0aeed3e9SJustin Hibbits memset(p_BmPortal->p_BmPortalDriverParams, 0, sizeof(t_BmPortalDriverParams));
489*0aeed3e9SJustin Hibbits
490*0aeed3e9SJustin Hibbits p_BmPortal->p_BmPortalLow->addr.addr_ce = UINT_TO_PTR(p_BmPortalParam->ceBaseAddress);
491*0aeed3e9SJustin Hibbits p_BmPortal->p_BmPortalLow->addr.addr_ci = UINT_TO_PTR(p_BmPortalParam->ciBaseAddress);
492*0aeed3e9SJustin Hibbits p_BmPortal->cpu = (int)p_BmPortalParam->swPortalId;
493*0aeed3e9SJustin Hibbits p_BmPortal->irq = p_BmPortalParam->irq;
494*0aeed3e9SJustin Hibbits
495*0aeed3e9SJustin Hibbits p_BmPortal->h_Bm = p_BmPortalParam->h_Bm;
496*0aeed3e9SJustin Hibbits
497*0aeed3e9SJustin Hibbits p_BmPortal->p_BmPortalDriverParams->hwExtStructsMemAttr = DEFAULT_memAttr;
498*0aeed3e9SJustin Hibbits bman_depletion_fill(&p_BmPortal->p_BmPortalDriverParams->mask);
499*0aeed3e9SJustin Hibbits
500*0aeed3e9SJustin Hibbits return p_BmPortal;
501*0aeed3e9SJustin Hibbits }
502*0aeed3e9SJustin Hibbits
BM_PORTAL_Init(t_Handle h_BmPortal)503*0aeed3e9SJustin Hibbits t_Error BM_PORTAL_Init(t_Handle h_BmPortal)
504*0aeed3e9SJustin Hibbits {
505*0aeed3e9SJustin Hibbits t_BmPortal *p_BmPortal = (t_BmPortal *)h_BmPortal;
506*0aeed3e9SJustin Hibbits uint32_t flags;
507*0aeed3e9SJustin Hibbits
508*0aeed3e9SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_BmPortal, E_INVALID_HANDLE);
509*0aeed3e9SJustin Hibbits
510*0aeed3e9SJustin Hibbits flags = (uint32_t)((p_BmPortal->irq != NO_IRQ) ? BMAN_PORTAL_FLAG_IRQ : 0);
511*0aeed3e9SJustin Hibbits flags |= ((p_BmPortal->p_BmPortalDriverParams->hwExtStructsMemAttr & MEMORY_ATTR_CACHEABLE) ?
512*0aeed3e9SJustin Hibbits BMAN_PORTAL_FLAG_CACHE : 0);
513*0aeed3e9SJustin Hibbits
514*0aeed3e9SJustin Hibbits if (bman_create_portal(p_BmPortal,flags,&p_BmPortal->p_BmPortalDriverParams->mask)!=E_OK)
515*0aeed3e9SJustin Hibbits {
516*0aeed3e9SJustin Hibbits BM_PORTAL_Free(p_BmPortal);
517*0aeed3e9SJustin Hibbits RETURN_ERROR(MAJOR, E_NULL_POINTER, ("create portal failed"));
518*0aeed3e9SJustin Hibbits }
519*0aeed3e9SJustin Hibbits BmSetPortalHandle(p_BmPortal->h_Bm, (t_Handle)p_BmPortal, (e_DpaaSwPortal)p_BmPortal->cpu);
520*0aeed3e9SJustin Hibbits
521*0aeed3e9SJustin Hibbits XX_Free(p_BmPortal->p_BmPortalDriverParams);
522*0aeed3e9SJustin Hibbits p_BmPortal->p_BmPortalDriverParams = NULL;
523*0aeed3e9SJustin Hibbits
524*0aeed3e9SJustin Hibbits DBG(TRACE,("Bman-Portal (%d) @ %p:%p\n",
525*0aeed3e9SJustin Hibbits p_BmPortal->cpu,
526*0aeed3e9SJustin Hibbits p_BmPortal->p_BmPortalLow->addr.addr_ce,
527*0aeed3e9SJustin Hibbits p_BmPortal->p_BmPortalLow->addr.addr_ci
528*0aeed3e9SJustin Hibbits ));
529*0aeed3e9SJustin Hibbits
530*0aeed3e9SJustin Hibbits DBG(TRACE,("Bman-Portal (%d) @ 0x%016llx:0x%016llx",
531*0aeed3e9SJustin Hibbits p_BmPortal->cpu,
532*0aeed3e9SJustin Hibbits (uint64_t)XX_VirtToPhys(p_BmPortal->p_BmPortalLow->addr.addr_ce),
533*0aeed3e9SJustin Hibbits (uint64_t)XX_VirtToPhys(p_BmPortal->p_BmPortalLow->addr.addr_ci)
534*0aeed3e9SJustin Hibbits ));
535*0aeed3e9SJustin Hibbits
536*0aeed3e9SJustin Hibbits return E_OK;
537*0aeed3e9SJustin Hibbits }
538*0aeed3e9SJustin Hibbits
BM_PORTAL_Free(t_Handle h_BmPortal)539*0aeed3e9SJustin Hibbits t_Error BM_PORTAL_Free(t_Handle h_BmPortal)
540*0aeed3e9SJustin Hibbits {
541*0aeed3e9SJustin Hibbits t_BmPortal *p_BmPortal = (t_BmPortal *)h_BmPortal;
542*0aeed3e9SJustin Hibbits
543*0aeed3e9SJustin Hibbits if (!p_BmPortal)
544*0aeed3e9SJustin Hibbits return ERROR_CODE(E_INVALID_HANDLE);
545*0aeed3e9SJustin Hibbits BmSetPortalHandle(p_BmPortal->h_Bm, NULL, (e_DpaaSwPortal)p_BmPortal->cpu);
546*0aeed3e9SJustin Hibbits bman_destroy_portal(p_BmPortal);
547*0aeed3e9SJustin Hibbits XX_Free(p_BmPortal);
548*0aeed3e9SJustin Hibbits return E_OK;
549*0aeed3e9SJustin Hibbits }
550*0aeed3e9SJustin Hibbits
BM_PORTAL_ConfigMemAttr(t_Handle h_BmPortal,uint32_t hwExtStructsMemAttr)551*0aeed3e9SJustin Hibbits t_Error BM_PORTAL_ConfigMemAttr(t_Handle h_BmPortal, uint32_t hwExtStructsMemAttr)
552*0aeed3e9SJustin Hibbits {
553*0aeed3e9SJustin Hibbits t_BmPortal *p_BmPortal = (t_BmPortal *)h_BmPortal;
554*0aeed3e9SJustin Hibbits
555*0aeed3e9SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_BmPortal, E_INVALID_HANDLE);
556*0aeed3e9SJustin Hibbits SANITY_CHECK_RETURN_ERROR(p_BmPortal->p_BmPortalDriverParams, E_INVALID_HANDLE);
557*0aeed3e9SJustin Hibbits
558*0aeed3e9SJustin Hibbits p_BmPortal->p_BmPortalDriverParams->hwExtStructsMemAttr = hwExtStructsMemAttr;
559*0aeed3e9SJustin Hibbits
560*0aeed3e9SJustin Hibbits return E_OK;
561*0aeed3e9SJustin Hibbits }
562