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